diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..1ff0c42 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,63 @@ +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Set default behavior for command prompt diff. +# +# This is need for earlier builds of msysgit that does not have it on by +# default for csharp files. +# Note: This is only used by command line +############################################################################### +#*.cs diff=csharp + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just uncomment the entries below +############################################################################### +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +############################################################################### +# behavior for image files +# +# image files are treated as binary by default. +############################################################################### +#*.jpg binary +#*.png binary +#*.gif binary + +############################################################################### +# diff behavior for common document formats +# +# Convert binary document formats to text before diffing them. This feature +# is only available from the command line. Turn it on by uncommenting the +# entries below. +############################################################################### +#*.doc diff=astextplain +#*.DOC diff=astextplain +#*.docx diff=astextplain +#*.DOCX diff=astextplain +#*.dot diff=astextplain +#*.DOT diff=astextplain +#*.pdf diff=astextplain +#*.PDF diff=astextplain +#*.rtf diff=astextplain +#*.RTF diff=astextplain diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d97503a --- /dev/null +++ b/.gitignore @@ -0,0 +1,224 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +build/ +bld/ +[Bb]in/ +[Oo]bj/ + +# Visual Studo 2015 cache/options directory +.vs/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf +*.cachefile + +# Visual Studio profiler +*.psess +*.vsp +*.vspx + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding addin-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +_NCrunch_* +.*crunch*.local.xml + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# TODO: Comment the next line if you want to checkin your web deploy settings +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# NuGet Packages +*.nupkg +*/nuget/* +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/packages/repositories.config + +# Windows Azure Build Output +csx/ +*.build.csdef + +# Windows Store app package directory +AppPackages/ + +# Others +*.[Cc]ache +ClientBin/ +[Ss]tyle[Cc]op.* +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.pfx +*.publishsettings +node_modules/ +bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Custom +obj +bin/ +deploy +deploy/* +_ReSharper.* +*.csproj.user +*.resharper.user +*.ReSharper.user +*.resharper +*.suo +*.cache +~$* +*.suo +LPRun.5.1.ReSharper.user +LPRun.5.1.ReSharper.user +LPRun.suo +LPRun.5.1.ReSharper.user +*/packages/* +*/packages +/*.user +*/obj/* +*/bin/* +.nuget/* +*/*.scc +*.scc \ No newline at end of file diff --git a/Documents/Images/readme_1.jpg b/Documents/Images/readme_1.jpg new file mode 100644 index 0000000..5c84ece Binary files /dev/null and b/Documents/Images/readme_1.jpg differ diff --git a/Documents/Images/readme_2.jpg b/Documents/Images/readme_2.jpg new file mode 100644 index 0000000..ea65927 Binary files /dev/null and b/Documents/Images/readme_2.jpg differ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..02bbb60 --- /dev/null +++ b/LICENSE @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..35e6112 --- /dev/null +++ b/README.md @@ -0,0 +1,31 @@ +# Kalman.Studio +开发辅助工具,内置基于T4的代码生成器。 + +作者博客:http://www.cnblogs.com/lingyun_k + +## 软件主要功能如下: + + 1、基于T4的代码生成工具,根据数据库元数据信息生成代码,支持多数据库,支持批量代码生成; + 2、支持根据PowerDesigner物理模型文件来生成代码; + 3、内置了一个简单的文本编辑器,支持代码高亮显示; + 4、数据库元数据信息浏览工具; + 5、数据库文档生成工具,支持输出word及pdf文件格式; + 6、IIS日志解析器,小网站可以用用; + 7、其他工具,字符串相关操作等。 +![软件界面](https://images.cnblogs.com/cnblogs_com/lingyun_k/244874/o_ks1.png) + +## 一、配置编译 + + 代码由Visual Studio 2013编译通过。Nuget配置: +![Nuget配置](https://raw.githubusercontent.com/don59/Kalman.Studio/master/Documents/Images/readme_1.jpg) + +![Nuget配置](https://raw.githubusercontent.com/don59/Kalman.Studio/master/Documents/Images/readme_2.jpg) + +## 二、更新日志 + +2017-09-15 + + * 升级.Net Framework到4.6; + * 升级某些依赖项; + * 修正生成代码报错的问题; + * 调整一些界面细节; diff --git a/src/.nuget/NuGet.Config b/src/.nuget/NuGet.Config new file mode 100644 index 0000000..67f8ea0 --- /dev/null +++ b/src/.nuget/NuGet.Config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/.nuget/NuGet.exe b/src/.nuget/NuGet.exe new file mode 100644 index 0000000..c296edf Binary files /dev/null and b/src/.nuget/NuGet.exe differ diff --git a/src/.nuget/NuGet.targets b/src/.nuget/NuGet.targets new file mode 100644 index 0000000..46a1b6c --- /dev/null +++ b/src/.nuget/NuGet.targets @@ -0,0 +1,133 @@ + + + + $(MSBuildProjectDirectory)\..\ + + + false + + + false + + + true + + + false + + + + + + + + + + + $([System.IO.Path]::Combine($(SolutionDir), ".nuget")) + $([System.IO.Path]::Combine($(ProjectDir), "packages.config")) + + + + + $(SolutionDir).nuget + packages.config + + + + + $(NuGetToolsPath)\NuGet.exe + @(PackageSource) + + "$(NuGetExePath)" + mono --runtime=v4.0.30319 $(NuGetExePath) + + $(TargetDir.Trim('\\')) + + -RequireConsent + -NonInteractive + + + $(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)" $(NonInteractiveSwitch) $(RequireConsentSwitch) -solutionDir "$(SolutionDir) " + $(NuGetCommand) pack "$(ProjectPath)" -Properties Configuration=$(Configuration) $(NonInteractiveSwitch) -OutputDirectory "$(PackageOutputDir)" -symbols + + + + RestorePackages; + $(BuildDependsOn); + + + + + $(BuildDependsOn); + BuildPackage; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Kalman.Studio.sln b/src/Kalman.Studio.sln new file mode 100644 index 0000000..2f0a0d7 --- /dev/null +++ b/src/Kalman.Studio.sln @@ -0,0 +1,38 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26730.12 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kalman.Studio", "Kalman.Studio\Kalman.Studio.csproj", "{0F3959EA-16FB-4232-827E-E557E0426104}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kalman", "Kalman\Kalman.csproj", "{65FED08B-D2B2-4B49-9257-3DE1954D1675}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{EE3BCA77-BC17-4C34-893F-A6B3F8DE1928}" + ProjectSection(SolutionItems) = preProject + ..\LICENSE = ..\LICENSE + NuGet.config = NuGet.config + ..\README.md = ..\README.md + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {0F3959EA-16FB-4232-827E-E557E0426104}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0F3959EA-16FB-4232-827E-E557E0426104}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0F3959EA-16FB-4232-827E-E557E0426104}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0F3959EA-16FB-4232-827E-E557E0426104}.Release|Any CPU.Build.0 = Release|Any CPU + {65FED08B-D2B2-4B49-9257-3DE1954D1675}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {65FED08B-D2B2-4B49-9257-3DE1954D1675}.Debug|Any CPU.Build.0 = Debug|Any CPU + {65FED08B-D2B2-4B49-9257-3DE1954D1675}.Release|Any CPU.ActiveCfg = Release|Any CPU + {65FED08B-D2B2-4B49-9257-3DE1954D1675}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {A983604A-BA19-49B9-81C8-9E876B56F822} + EndGlobalSection +EndGlobal diff --git a/src/Kalman.Studio/About.Designer.cs b/src/Kalman.Studio/About.Designer.cs new file mode 100644 index 0000000..487220c --- /dev/null +++ b/src/Kalman.Studio/About.Designer.cs @@ -0,0 +1,135 @@ +namespace Kalman.Studio +{ + partial class About + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(About)); + this.pictureBox1 = new System.Windows.Forms.PictureBox(); + this.lblAbout = new System.Windows.Forms.Label(); + this.lblCopyRight = new System.Windows.Forms.Label(); + this.linkLabel1 = new System.Windows.Forms.LinkLabel(); + this.label3 = new System.Windows.Forms.Label(); + this.label1 = new System.Windows.Forms.Label(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); + this.SuspendLayout(); + // + // pictureBox1 + // + this.pictureBox1.Image = ((System.Drawing.Image)(resources.GetObject("pictureBox1.Image"))); + this.pictureBox1.Location = new System.Drawing.Point(24, 24); + this.pictureBox1.Name = "pictureBox1"; + this.pictureBox1.Size = new System.Drawing.Size(59, 50); + this.pictureBox1.TabIndex = 0; + this.pictureBox1.TabStop = false; + // + // lblAbout + // + this.lblAbout.AutoSize = true; + this.lblAbout.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.lblAbout.Location = new System.Drawing.Point(89, 24); + this.lblAbout.Name = "lblAbout"; + this.lblAbout.Size = new System.Drawing.Size(83, 12); + this.lblAbout.TabIndex = 1; + this.lblAbout.Text = "Kalman Studio"; + // + // lblCopyRight + // + this.lblCopyRight.AutoSize = true; + this.lblCopyRight.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.lblCopyRight.Location = new System.Drawing.Point(89, 50); + this.lblCopyRight.Name = "lblCopyRight"; + this.lblCopyRight.Size = new System.Drawing.Size(221, 12); + this.lblCopyRight.TabIndex = 2; + this.lblCopyRight.Text = "Copyright ©2009-2011 Kalman 版权所有"; + // + // linkLabel1 + // + this.linkLabel1.AutoSize = true; + this.linkLabel1.LinkArea = new System.Windows.Forms.LinkArea(3, 31); + this.linkLabel1.Location = new System.Drawing.Point(24, 103); + this.linkLabel1.Name = "linkLabel1"; + this.linkLabel1.Size = new System.Drawing.Size(215, 19); + this.linkLabel1.TabIndex = 3; + this.linkLabel1.TabStop = true; + this.linkLabel1.Text = "博客:http://lingyun_k.cnblogs.com"; + this.linkLabel1.UseCompatibleTextRendering = true; + this.linkLabel1.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel1_LinkClicked); + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.label3.Location = new System.Drawing.Point(24, 127); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(77, 12); + this.label3.TabIndex = 5; + this.label3.Text = "QQ:17516515"; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.label1.Location = new System.Drawing.Point(24, 151); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(95, 12); + this.label1.TabIndex = 6; + this.label1.Text = "QQ群:122161138"; + // + // About + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(323, 183); + this.Controls.Add(this.label1); + this.Controls.Add(this.label3); + this.Controls.Add(this.linkLabel1); + this.Controls.Add(this.lblCopyRight); + this.Controls.Add(this.lblAbout); + this.Controls.Add(this.pictureBox1); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "About"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "关于Kalman Studio"; + this.Load += new System.EventHandler(this.About_Load); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.PictureBox pictureBox1; + private System.Windows.Forms.Label lblAbout; + private System.Windows.Forms.Label lblCopyRight; + private System.Windows.Forms.LinkLabel linkLabel1; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Label label1; + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/About.cs b/src/Kalman.Studio/About.cs new file mode 100644 index 0000000..9446830 --- /dev/null +++ b/src/Kalman.Studio/About.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace Kalman.Studio +{ + public partial class About : Form + { + public About() + { + InitializeComponent(); + } + + private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + Help.ShowHelp(this, "http://lingyun_k.cnblogs.com"); + } + + private void About_Load(object sender, EventArgs e) + { + lblAbout.Text += " " + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version; + lblCopyRight.Text = string.Format("Copyright ©2009-{0} Kalman 版权所有", DateTime.Now.Year); + } + } +} diff --git a/src/Kalman.Studio/About.resx b/src/Kalman.Studio/About.resx new file mode 100644 index 0000000..1ded9ef --- /dev/null +++ b/src/Kalman.Studio/About.resx @@ -0,0 +1,188 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + wgAADsIBFShKgAAADktJREFUaEPtWGlQVFmWrl6qoiq6Y6amYjqi/3TPRHVMz8yPnlJRS8WSQlspLLUQ + FFmUfV9SdhVQFin2TLDYxSm3AktEtFr2LUmUJMkEEpKEBJMtgWTfQZI177zvmQ/TcumejsGpH34RN3i8 + vMt3zv3uOee+d97iLd4gGjtn/o19X2HlfaXD3yqhNeri993OD1smP9H8vI7JSfKPmsefDggh75rHSxP8 + M7s7OHeVkzXS2dXz13v7gm52Omu6oM971yqGj1hypKlpRQOm8oGF32l++v/H1BT58ERsc9r4zCpZWFTT + 7Wbl2IJpeFPI0NDQr9Dn27LhrxwS27nC9pk1z1S5xCxOkppZPnSYnuBNgvLkzwtEE7qVkmkdzSsaJ+Mk + EZlF/UvLa4Q2QD6gUhuebcw7FNyYZMNpDbNkt+WIu5+sMQbyJLOrxyOa71a8RGYbisslyqO2HFn5KXZb + ITuv9+Qj6dSmsNs9LsejxA/u8sdXFpefEkQbnVkh9e1za7nV4yqedHaFeb+6qiaFoiliFyPuY6XIXDRT + bzwgA8qT9xSjy0Q5ukJY6Z3tZrEtOcHXe/unFlaJNvlXNewQXzZPQm4qiUWYcMQyrN5LM/3GQqJQfXyS + 3ZrdophfY2SCBi9rE0SDIeij3U/7N0nvAgnLGiBHAuuaXL9uMk7L7dUtFI5t0yy1MfiWOnAGATzRfcEU + Tfpl5NDwfmpulXQqFwl2al61+kJfGJGW36/a4Vh9Ud+z9ppxqLj8VExbUVbliIFmuf97VEsm/2ufF/eH + U3Gd5My3faRnZPGlRpTUT5PwbCU5d7WP+F3uI5G3Bomsf+GFvqNTK+QvtZNLyvEVsrRCSA51TozDxXFU + kPgZ1kOwGB9X/0NJ0/in90Rjn1P/v08T+XsxMkJ+bRgkSDkS1LDmkdJLBieXnyMFT2dXTZILNwZo4jDy + dHovcU3uoZu4a4E+vNpGMA070kZFrf1n6pKamoZ+JeyY/tiS0xxvwZGmWLPbim3ZMp55nGTdOOQQ5BJZ + j+pfaXJ/CzCIc0f+1R6P6sxjQTVj2uRBrKZ1jiYfQXmfldpJvjrz6ImBN3fmZLRkzTxKTq6WjFLrvygl + GE5LbniR7POuvXOzqPvfY3K6LO04TbLHigX1rGqN3BeML5lFNYdTw39Z2zH7nzCOWkNiwW7Jjs5TWDd1 + zfxRQ/PluFKuNDJnt92wipeVnYxrFaU/GJjTJgJjbvMmyPkbCvKFV+XQZuvSa7scqkL2OFUHbraqSP7E + /AdJ6NWu5w4/niEtdt4QHZFYGT1Ex6agLP6GfFfkLfmJfd7l0vGZ5ae706tSG/gLr30ZVM9xSZUFBlzr + 6sIcbX0qNSv1sfx4VFMCZdy7GrovwjK+JbqF8sb8K0IldoDbNEd0nYu6DTxqWL5hjesRJT6l5XeGrFrf + c5mdY9pjAQQEx8Qe4pmqIN/cGybb7AsaTse3nHBKkPoY+PLEkCkzpp8K28WiqeX0/KGZydlnGf82b5Ic + OFObLlFM/5NmyRdhxZFGFIsmluE1kAW0vYk2Pr1MDP0EdUa+AqfT0U0G8ddkOsEZ7UaWkU0+9vEy8dDU + 8nP9Z1UrJObOEHGIaVNnFg6qQTSHN7piHSeRRt/uG2XOGNZjmva6+FvdMkfcOW3qXW7VyVzuyK81dF+E + V0a7d/h3vSPdwyoi7JijIw1C5I+N6BtbJP7pnb0W0VL+8a8lhU4JHY3Rd/rGnqie9WEadJ/FHVEfPiMS + PpTO0OwwH+NxEEa4xtm6+3CK6jtBrTtLwAG/oV/38BI5FFAjsQ0RHbOPFTu7pcp8ixsndmloPwMnT2H6 + uWe5BKHRK0NBXJJ66C3XlsSP2wwlt5e91x4DwpQ0yc2KCVLeNPNcHxBNuD9Ey4uJZlgXEa5BvkD3QePc + HZiyiGwR+V/pVsTn9I+zMmW+GtrPcL92/NM9HuXFGMw0O3Y3rWF4g1n4dQ2LoS8OJiIPwLyjKld6TuwK + jIJ8onMGiV9a2+r+09ze7baFNVutC6t3OpS0H/DmzuPcIABor425ELG+DBLFamg/A3LAwcC65P2siok9 + TkXKbTYPGvXcKpoftsyvywh/MaG2DLQnBzloNi53kE50qIfQF7I4nSxTeya10occc2A33DmN8zudH948 + 4l3r6HxetN81TKR/zF9wSseuKmG7zYPBW9ThBZg14Jg66Sz5zLM2RkP7eVwvVOw2Dqz3P+zL9zjkxXc5 + 8989/cigGAwiKB2wtQNjyzRZbfKY/ErJGJ0nEDLhQWT0jMIxehdvcUfI9eLhRcYZGYX9a1vteJdAXLP8 + OiKSJFs/d3sU4pPS9gTGosEx/pkK4pPZSyijX9wBbfjGNRvuZfFqQRjABEPUlsOz0Cj0CpJUjF7fjcnZ + Ffp3GGARUb+o51o6geSG/0EYYMijJeUqZve4VgdplnwOXPHUh8bB9ecS7yqnMTdaXK6SGAXVr+1lVUzv + c+ef03R9OVA57nAsKkc5Ae/Bu9AwZIFIwZPM0ZGqpeepRtGAK0WD6v2nq2Q7HKrC9V0e+f/J7N6j4+fr + V5jdgpEgg2fknL1edbmnE1qMi4UT9NWTmuIXKDFi7vSY28TLBLgwoS/CsUkQv3+rXVWUnjPv3Oko8ec0 + 0Vfh8ePZ3xwIqMk0jZDRMmDKB1eOdPUOFcdBFocUeuwaWqQNQZIrF0+qL+cPzh0NaX603fEh2zWi4fCn + Ttxr7HtKOqIhwuGSw+xEnWx2zY7KHyYRzTfsL8lCqbKBbRHfessrtbN1gjIWfRiDcWnySpP36rnXXo9K + 6/jrN7zY7M6jum7lNUbBtcvQM3WhITr25bdd2a39jGwK+eNraYVDdDWaWjCyHmHwm1log8w5RmK524Mf + ZxJYu+QcL1N/FcRfMr3YohY9nqd3DcTQkG++504sPBBOLg1TFSzeMUYyZT36YwfNQur77CIbXn/D6xmZ + /23Id502nild8qBvO8f3syr79npUSo6FNjUIW2dXmYWZRUAcO8J4CxHmxIWahUNnhSHn0zu+1HWpyt7m + yM2AtPZ6VInkShXdlyEGaBuEBqMgW1S8qIBBPo8/Sfa5l/VbRzS93gDcid1TO8WIQFgkt3JMdblgeB7P + zKIgrB3vGWPwLjy7n+x2LpU5XBRbIv1n5Ss+zsyUfrTDgZdytXh4Tk1xRn9K4zQ5yAohF1qHYSAbmztE + gq72EPMQ4YJppJwEUzL2TJCubrUrz4q9LN2kofoiKC6/PBEr4XDy+pbhWcaraCCOBISDjQwKTWMhEABx + kEL/hHv9i7oOvDB9z5rQAwF1KYaBQk7WX3r+Q8+zKhdSQxiG4WmFo8T5my7ilPA0++I91kCyCsxsW6BK + 73xUvJ85l4uNgmpXttuX1lgFC49oqL4clAE/M41pjtNzK58Puj5Ap3vG8wibII5Sw4NK+6ZhwmXLi81q + h4Ru+qAzNziUGDfLRuep8lsl63+itmPLBAl3egwPn29MNrnQqGbKFJMgweKfLAuKdKgsvN02X14inKQd + APmYBImbTp0TGscmS39rG1h/VMeem+gQXH8oOUf66oKOwfWygT/vdiv74c+syhmGFDwM8q6J0rUddkXi + TVbFtzZbVSZsti7L3GxVUPapXfHc9bIxWk7MjmEcPHqWqmHcL0mdwm/IjQzP1t09Gvho3C6maRVBwTFQ + aOgaIjqwy7k63DJStISAAN3reZQokVA1lN7JyZG+p3l8PVDpsdJlvkYXGkO+8BcULSyt0iQQ9y1ChYs6 + NmU5pwKExiEcyccZGfXvZmS0/zMrrGGfnhsv+Au/qmHtqhRywzUzMuvxk4MBghDMH3u1Xfegn8BPx6Yi + w+rsMzkYBdX56LuWjpmF1q8a+nHndWzya1Gya37+2yBVLvz+ZHzbzdjcgbHsqvGF+sdPv7LBAMT5zdYF + JfCYpvtzCElu3WMYIORCPuiPQgypHxWmXWyreqdLVVJJydNPkEDmbelHmkca6Xk9O/VZ/EvbHXiJnznx + gl3O1xvk5HT97z4S495pEdeSA9LQIojgL6RQIhpf07GtikM00XRfR1+f+gOPlDa34Gvd/RgL5D6aJKYX + BIvG52r6t9rmS3c4VSdKpa+XAZ/f98HVqz1//5cJtVr9wbGo5kvi3idqbD8+TkH7MAJn4Vhoc539xUbr + vLKBP/b0kPcpnu+3KFR/YOf1n7Rmy6ol1DjG+CzuKNlmx8046F3jZh5QaxaX3PovmmU2DhShnx8NE8c7 + xjQsIgKhaEPtgx0AMYQ3z6R2uXGk5JZZnCTRgi1NROr3udzZzlxuQJ7p+8095fR+P+E9j+jGl8puQ+Bz + We6u51asPBHesLLbsWBQ16V0kieZpeUEYmhI9/iQW90yu6Kd+kEeSQjPAJ6jvuta3OsrYOfkkF9olthY + FPFHt+z34ydSWTPxC0++5y6Xqjuijvn1s8CA2RWmQWJI9cgHKAFQwyDBsS5Jl/W8+WxqyJsxAJBKyXu3 + b/d99JkbP6NKMrMM74MwUn9O9SRd6+B8gDgMQ8bGXQDp/mggX2US0qxGZsU3pC3WDwQeUeIvNVO/OeQV + Kv6w2437PW5U8CZSP7Knu+bijTICB5yRFiuhWbXFtrR0J1VCfHKqOFvXqWRil2OB3MSXb01Flg810745 + YBcOnW9I3OtRsQDP4rOhB1VM6ZwqKt9kVVC9w65QxpNM01EHqd/Qv05gHyw6iLE+0fW7D3jW+JkE1FlH + JjW9/pPgRuJyUZ+Bvjc/cZv1A6VFZOPaNsrDyJ64fOu7PzxnGVY3zaR+fY/SocM+fE/N0J8O0u/2bjl6 + RuC+2boyVTv1m18QuVIy6beMal4z8Kma3mJdIGDFNNI78JPEj9P6d/kDm2y/bnTd5fowGvdUyCcrS/Hq + b5dv8RZvsQF4553/AULqst0QfH6cAAAAAElFTkSuQmCC + + + \ No newline at end of file diff --git a/src/Kalman.Studio/App.ICO b/src/Kalman.Studio/App.ICO new file mode 100644 index 0000000..3d6e53e Binary files /dev/null and b/src/Kalman.Studio/App.ICO differ diff --git a/src/Kalman.Studio/App.config b/src/Kalman.Studio/App.config new file mode 100644 index 0000000..51003af --- /dev/null +++ b/src/Kalman.Studio/App.config @@ -0,0 +1,133 @@ + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Kalman.Studio/CodeBuilder/BatchBuildCode.cs b/src/Kalman.Studio/CodeBuilder/BatchBuildCode.cs new file mode 100644 index 0000000..0fd72c4 --- /dev/null +++ b/src/Kalman.Studio/CodeBuilder/BatchBuildCode.cs @@ -0,0 +1,395 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using WeifenLuo.WinFormsUI.Docking; +using Microsoft.VisualStudio.TextTemplating; +using System.IO; +using System.Net.Mail; +using System.Net; +using System.Diagnostics; +using System.CodeDom.Compiler; +using Kalman.Data.SchemaObject; +using Kalman.Utilities; +using Kalman.Extensions; +using Kalman.Studio.T4TemplateEngineHost; +using ICSharpCode.TextEditor.Document; +using ICSharpCode.TextEditor; + +namespace Kalman.Studio +{ + public partial class BatchBuildCode : DockableForm + { + string _CodeType = CodeType.CSHARP; + SODatabase currentDatabase; + List tableList = new List(); + //string templatePath = Path.Combine(Application.StartupPath, "T4Template\\SP"); + + public BatchBuildCode(SODatabase db) + { + InitializeComponent(); + currentDatabase = db; + tableList = db.TableList; + } + + private void BatchBuildCode_Load(object sender, EventArgs e) + { + gbTableSelect.Text = string.Format("当前数据库[{0}]", currentDatabase); + + foreach (SOTable t in tableList) + { + listBox1.Items.Add(t); + } + + folderBrowserDialog1.RootFolder = Environment.SpecialFolder.MyComputer; + txtOutputPath.Text = Path.Combine(Application.StartupPath, "Output"); + + SetDocumentCodeType(textEditorControl1, CodeType.CSHARP); + LoadTemplateTree(); + } + //选择代码输出目录 + private void btnBrowser_Click(object sender, EventArgs e) + { + DialogResult result = folderBrowserDialog1.ShowDialog(); + if (result == DialogResult.OK) + { + txtOutputPath.Text = folderBrowserDialog1.SelectedPath; + } + } + + //处理窗体关闭事件 + protected override void OnClosing(CancelEventArgs e) + { + if (backgroundWorker1.IsBusy == false) + { + base.OnClosing(e); + } + else + { + e.Cancel = true; + MessageBox.Show("正在生成代码,请不要关闭窗口"); + } + } + + #region 模板树相关代码 + + private void LoadTemplateTree() + { + string templatePath = Path.Combine(Application.StartupPath, "T4Template"); + + TreeNode root = new TreeNode("T4Templates", 0, 0); + root.ContextMenuStrip = cmsTree; + tvTemplate.Nodes.Add(root); + + DirectoryInfo dirInfo = new DirectoryInfo(templatePath); + ExpentTemplateDir(dirInfo, root); + } + + //展开模板文件夹 + private void ExpentTemplateDir(DirectoryInfo rootDirInfo, TreeNode root) + { + DirectoryInfo[] dirs = rootDirInfo.GetDirectories(); + foreach (DirectoryInfo dir in dirs) + { + TreeNode node = new TreeNode(dir.Name, 1, 1); + node.Tag = dir; + node.Name = dir.Name; + if (root.Nodes.ContainsKey(node.Name) == false) root.Nodes.Add(node); + } + + FileInfo[] files = rootDirInfo.GetFiles(); + foreach (FileInfo file in files) + { + TreeNode node = new TreeNode(file.Name, 2, 2); + node.Tag = file; + node.Name = file.Name; + if (root.Nodes.ContainsKey(node.Name) == false) root.Nodes.Add(node); + } + + root.Expand(); + } + + private void tvTemplate_MouseClick(object sender, MouseEventArgs e) + { + if (e.Button == MouseButtons.Right) + { + TreeView tv = sender as TreeView; + TreeNode tn = tv.GetNodeAt(e.X, e.Y); + tv.SelectedNode = tn; + } + } + + private void tvTemplate_MouseDoubleClick(object sender, MouseEventArgs e) + { + TreeView tv = sender as TreeView; + TreeNode tn = tv.GetNodeAt(e.X, e.Y); + + if (tn.Tag is DirectoryInfo) + { + DirectoryInfo dir = (DirectoryInfo)tn.Tag; + if (Directory.Exists(dir.FullName) == false) + { + MessageBox.Show("目标可能被删除、移动、改名,请刷新模板树"); + return; + } + ExpentTemplateDir(dir, tn); + } + if (tn.Tag is FileInfo) + { + FileInfo fi = tn.Tag as FileInfo; + if (File.Exists(fi.FullName) == false) + { + MessageBox.Show("目标可能被删除、移动、改名,请刷新模板树"); + return; + } + textEditorControl1.LoadFile(fi.FullName); + gbTemplateFile.Text = fi.FullName; + } + SetDocumentCodeType(textEditorControl1, CodeType.CSHARP); + } + + void SetDocumentCodeType(TextEditorControl editor, string codeType) + { + IHighlightingStrategy strategy = HighlightingStrategyFactory.CreateHighlightingStrategy(codeType); + editor.Document.HighlightingStrategy = strategy; + _CodeType = codeType; + } + + //右键菜单项命令:刷新模板树 + private void menuItemRefresh_Click(object sender, EventArgs e) + { + tvTemplate.Nodes.Clear(); + LoadTemplateTree(); + } + + //右键菜单项命令:模板管理 + private void menuItemManage_Click(object sender, EventArgs e) + { + base.MainForm.ShowTemplateExplorer(); + } + + + #endregion + + #region 处理编辑命令 + private void menuItemUndo_Click(object sender, EventArgs e) { Undo(textEditorControl1); } + private void menuItemRedo_Click(object sender, EventArgs e) { Redo(textEditorControl1); } + private void menuItemCut_Click(object sender, EventArgs e) { Cut(sender, e); } + private void menuItemCopy_Click(object sender, EventArgs e) { Copy(sender, e); } + private void menuItemPaste_Click(object sender, EventArgs e) { Paste(sender, e); } + private void menuItemDelete_Click(object sender, EventArgs e) { Delete(sender, e); } + private void menuItemSelectAll_Click(object sender, EventArgs e) { SelectAll(sender, e); } + + public void Undo(TextEditorControl editor) { editor.Undo(); } + public void Redo(TextEditorControl editor) { editor.Redo(); } + public void Cut(object sender, EventArgs e) { textEditorControl1.ActiveTextAreaControl.TextArea.ClipboardHandler.Cut(sender, e); } + public void Copy(object sender, EventArgs e) { textEditorControl1.ActiveTextAreaControl.TextArea.ClipboardHandler.Copy(sender, e); } + public void Paste(object sender, EventArgs e) { textEditorControl1.ActiveTextAreaControl.TextArea.ClipboardHandler.Paste(sender, e); } + public void Delete(object sender, EventArgs e) { textEditorControl1.ActiveTextAreaControl.TextArea.ClipboardHandler.Delete(sender, e); } + public void SelectAll(object sender, EventArgs e) { textEditorControl1.ActiveTextAreaControl.TextArea.ClipboardHandler.SelectAll(sender, e); } + #endregion + + private void menuItemSave_Click(object sender, EventArgs e) + { + textEditorControl1.SaveFile(gbTemplateFile.Text); + } + + #region 列表选择相关 + private void listBox1_MouseDoubleClick(object sender, MouseEventArgs e) + { + SelectOne(); + } + + private void listBox2_MouseDoubleClick(object sender, MouseEventArgs e) + { + RemoveOne(); + } + + private void btnSelectAll_Click(object sender, EventArgs e) + { + SelectAll(); + } + private void btnSelectOne_Click(object sender, EventArgs e) + { + SelectOne(); + } + private void btnRemoveOne_Click(object sender, EventArgs e) + { + RemoveOne(); + } + private void btnRemoveAll_Click(object sender, EventArgs e) + { + RemoveAll(); + } + + private void SelectAll() + { + if (backgroundWorker1.IsBusy) return; + if (listBox1.Items.Count > 0) + { + listBox2.Items.AddRange(listBox1.Items); + listBox1.Items.Clear(); + } + } + + private void SelectOne() + { + if (backgroundWorker1.IsBusy) return; + object[] items = new object[listBox1.SelectedItems.Count]; + listBox1.SelectedItems.CopyTo(items, 0); + listBox2.Items.AddRange(items); + + foreach (var item in items) + { + listBox1.Items.Remove(item); + } + } + + private void RemoveOne() + { + if (backgroundWorker1.IsBusy) return; + object[] items = new object[listBox2.SelectedItems.Count]; + listBox2.SelectedItems.CopyTo(items, 0); + listBox1.Items.AddRange(items); + + foreach (var item in items) + { + listBox2.Items.Remove(item); + } + } + + private void RemoveAll() + { + if (backgroundWorker1.IsBusy) return; + if (listBox2.Items.Count > 0) + { + listBox1.Items.AddRange(listBox2.Items); + listBox2.Items.Clear(); + } + } + #endregion + + #region 代码生成相关 + string nameSpace = "Kalman"; + string tablePrefix = string.Empty; + int prefixLevel = 1; + string templateFile = string.Empty; + string outputPath = string.Empty; + + private void btnBuildCode_Click(object sender, EventArgs e) + { + templateFile = gbTemplateFile.Text; + if (!File.Exists(templateFile)) return; + if (listBox2.Items.Count == 0) return; + + textEditorControl1.SaveFile(templateFile); + outputPath = txtOutputPath.Text; + if (txtNameSpace.Text.Trim() != "") nameSpace = txtNameSpace.Text.Trim(); + + if (cbDeleteTablePrifix.Checked && txtTablePrefix.Text.Trim().Length > 0) tablePrefix = txtTablePrefix.Text.Trim(); + prefixLevel = ConvertUtil.ToInt32(txtPrefixLevel.Text, 1); + + btnBuildCode.Enabled = false; + backgroundWorker1.RunWorkerAsync(); + } + + private void DoBuild() + { + int finish = 0; + int total = listBox2.Items.Count; + + //遍历选中的表,一张表对应生成一个代码文件 + foreach (object item in listBox2.Items) + { + SOTable table = item as SOTable; + string className = table.Name; + if (cbDeleteTablePrifix.Checked)className = table.Name.RemovePrefix(tablePrefix, prefixLevel).Replace(" ", ""); + if (cbClassNamePascal.Checked) className = className.InitialToUpperMulti(); + if (cbClassNameRemovePlural.Checked) className = className.EndsWith("s") ? className.TrimEnd('s') : className.Trim(); + if (cbAddSuffix.Checked) className = txtClassPrefix.Text.Trim() + className + txtClassSuffix.Text.Trim(); + + templateFile = gbTemplateFile.Text; + + List columnList = table.ColumnList;//可能传入的是从PDObject对象转换过来的SODatabase对象 + if (columnList == null || columnList.Count == 0) columnList = DbSchemaHelper.Instance.CurrentSchema.GetTableColumnList(table); + + //生成代码文件 + TableHost host = new TableHost(); + host.Table = table; + host.ColumnList = columnList; + host.TemplateFile = templateFile; + host.SetValue("NameSpace", nameSpace); + host.SetValue("ClassName", className); + host.SetValue("TablePrefix", tablePrefix); + //host.SetValue("ColumnPrefix", columnPrefix); + host.SetValue("PrefixLevel", prefixLevel); + + Engine engine = new Engine(); + + string outputContent = engine.ProcessTemplate(File.ReadAllText(templateFile), host); + //string outputFile = Path.Combine(outputPath, string.Format("{0}.cs", className)); + string outputFile = Path.Combine(outputPath, string.Format("{0}{1}", table.Name, host.FileExtention)); + if(cbClassNameIsFileName.Checked)outputFile = Path.Combine(outputPath, string.Format("{0}{1}", className, host.FileExtention)); + + StringBuilder sb = new StringBuilder(); + if (host.ErrorCollection.HasErrors) + { + foreach (CompilerError err in host.ErrorCollection) + { + sb.AppendLine(err.ToString()); + } + outputContent = outputContent + Environment.NewLine + sb.ToString(); + outputFile = outputFile + ".error"; + } + + if (Directory.Exists(outputPath) == false) Directory.CreateDirectory(outputPath); + File.WriteAllText(outputFile, outputContent, Encoding.UTF8); + + finish = finish + 1; + int percent = ConvertUtil.ToInt32(finish * 100 / total, 0); + + backgroundWorker1.ReportProgress(percent, table); + }//end build code foreach + } + + private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) + { + DoBuild(); + } + + private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) + { + progressBar1.Value = e.ProgressPercentage; + SOTable table = e.UserState as SOTable; + + if (e.ProgressPercentage == 100) + { + lblMsg.Text = "代码已全部生成"; + } + else + { + lblMsg.Text = string.Format("已完成:{0}%,正在处理:{1}", e.ProgressPercentage, table.Name); + } + } + + private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) + { + DialogResult result = MessageBox.Show("代码生成成功,是否打开输出目录", "代码生成消息提示", MessageBoxButtons.YesNo, MessageBoxIcon.Information); + if (result == DialogResult.Yes) + { + //string cmd = "explorer.exe " + outputPath; + //Kalman.Command.CmdHelper.Execute(cmd); + Process p = new Process(); + p.StartInfo = new ProcessStartInfo(outputPath); + p.Start(); + } + btnBuildCode.Enabled = true; + } + #endregion + + } +} diff --git a/src/Kalman.Studio/CodeBuilder/BatchBuildCode.designer.cs b/src/Kalman.Studio/CodeBuilder/BatchBuildCode.designer.cs new file mode 100644 index 0000000..cbb89ea --- /dev/null +++ b/src/Kalman.Studio/CodeBuilder/BatchBuildCode.designer.cs @@ -0,0 +1,729 @@ +namespace Kalman.Studio +{ + partial class BatchBuildCode + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(BatchBuildCode)); + this.listBox1 = new System.Windows.Forms.ListBox(); + this.gbTableSelect = new System.Windows.Forms.GroupBox(); + this.btnRemoveOne = new System.Windows.Forms.Button(); + this.btnRemoveAll = new System.Windows.Forms.Button(); + this.btnSelectOne = new System.Windows.Forms.Button(); + this.listBox2 = new System.Windows.Forms.ListBox(); + this.btnSelectAll = new System.Windows.Forms.Button(); + this.label1 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.txtTablePrefix = new System.Windows.Forms.TextBox(); + this.txtNameSpace = new System.Windows.Forms.TextBox(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.cbClassNameIsFileName = new System.Windows.Forms.CheckBox(); + this.cbAddSuffix = new System.Windows.Forms.CheckBox(); + this.cbClassNamePascal = new System.Windows.Forms.CheckBox(); + this.cbDeleteTablePrifix = new System.Windows.Forms.CheckBox(); + this.txtClassSuffix = new System.Windows.Forms.TextBox(); + this.lblMsg = new System.Windows.Forms.Label(); + this.progressBar1 = new System.Windows.Forms.ProgressBar(); + this.btnBuildCode = new System.Windows.Forms.Button(); + this.txtPrefixLevel = new System.Windows.Forms.TextBox(); + this.label8 = new System.Windows.Forms.Label(); + this.btnBrowser = new System.Windows.Forms.Button(); + this.txtOutputPath = new System.Windows.Forms.TextBox(); + this.label5 = new System.Windows.Forms.Label(); + this.folderBrowserDialog1 = new System.Windows.Forms.FolderBrowserDialog(); + this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker(); + this.splitContainer1 = new System.Windows.Forms.SplitContainer(); + this.splitContainer3 = new System.Windows.Forms.SplitContainer(); + this.splitContainer2 = new System.Windows.Forms.SplitContainer(); + this.gbTemplateList = new System.Windows.Forms.GroupBox(); + this.tvTemplate = new System.Windows.Forms.TreeView(); + this.imgList = new System.Windows.Forms.ImageList(this.components); + this.gbTemplateFile = new System.Windows.Forms.GroupBox(); + this.textEditorControl1 = new ICSharpCode.TextEditor.TextEditorControl(); + this.cms = new System.Windows.Forms.ContextMenuStrip(this.components); + this.menuItemUndo = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemRedo = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator(); + this.menuItemCut = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemCopy = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemPaste = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemDelete = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); + this.menuItemSelectAll = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); + this.menuItemSave = new System.Windows.Forms.ToolStripMenuItem(); + this.cmsTree = new System.Windows.Forms.ContextMenuStrip(this.components); + this.menuItemRefresh = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemManage = new System.Windows.Forms.ToolStripMenuItem(); + this.txtClassPrefix = new System.Windows.Forms.TextBox(); + this.label3 = new System.Windows.Forms.Label(); + this.cbClassNameRemovePlural = new System.Windows.Forms.CheckBox(); + this.gbTableSelect.SuspendLayout(); + this.groupBox1.SuspendLayout(); + this.splitContainer1.Panel1.SuspendLayout(); + this.splitContainer1.Panel2.SuspendLayout(); + this.splitContainer1.SuspendLayout(); + this.splitContainer3.Panel1.SuspendLayout(); + this.splitContainer3.Panel2.SuspendLayout(); + this.splitContainer3.SuspendLayout(); + this.splitContainer2.Panel1.SuspendLayout(); + this.splitContainer2.Panel2.SuspendLayout(); + this.splitContainer2.SuspendLayout(); + this.gbTemplateList.SuspendLayout(); + this.gbTemplateFile.SuspendLayout(); + this.cms.SuspendLayout(); + this.cmsTree.SuspendLayout(); + this.SuspendLayout(); + // + // listBox1 + // + this.listBox1.FormattingEnabled = true; + this.listBox1.ItemHeight = 12; + this.listBox1.Location = new System.Drawing.Point(12, 20); + this.listBox1.Name = "listBox1"; + this.listBox1.SelectionMode = System.Windows.Forms.SelectionMode.MultiExtended; + this.listBox1.Size = new System.Drawing.Size(180, 196); + this.listBox1.TabIndex = 0; + this.listBox1.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.listBox1_MouseDoubleClick); + // + // gbTableSelect + // + this.gbTableSelect.Controls.Add(this.btnRemoveOne); + this.gbTableSelect.Controls.Add(this.btnRemoveAll); + this.gbTableSelect.Controls.Add(this.btnSelectOne); + this.gbTableSelect.Controls.Add(this.listBox2); + this.gbTableSelect.Controls.Add(this.btnSelectAll); + this.gbTableSelect.Controls.Add(this.listBox1); + this.gbTableSelect.Dock = System.Windows.Forms.DockStyle.Fill; + this.gbTableSelect.Location = new System.Drawing.Point(0, 0); + this.gbTableSelect.Name = "gbTableSelect"; + this.gbTableSelect.Size = new System.Drawing.Size(421, 230); + this.gbTableSelect.TabIndex = 1; + this.gbTableSelect.TabStop = false; + this.gbTableSelect.Text = "groupBox1"; + // + // btnRemoveOne + // + this.btnRemoveOne.FlatStyle = System.Windows.Forms.FlatStyle.Popup; + this.btnRemoveOne.Location = new System.Drawing.Point(198, 132); + this.btnRemoveOne.Name = "btnRemoveOne"; + this.btnRemoveOne.Size = new System.Drawing.Size(28, 25); + this.btnRemoveOne.TabIndex = 9; + this.btnRemoveOne.Text = "<"; + this.btnRemoveOne.UseVisualStyleBackColor = true; + this.btnRemoveOne.Click += new System.EventHandler(this.btnRemoveOne_Click); + // + // btnRemoveAll + // + this.btnRemoveAll.FlatStyle = System.Windows.Forms.FlatStyle.Popup; + this.btnRemoveAll.Location = new System.Drawing.Point(198, 182); + this.btnRemoveAll.Name = "btnRemoveAll"; + this.btnRemoveAll.Size = new System.Drawing.Size(28, 25); + this.btnRemoveAll.TabIndex = 8; + this.btnRemoveAll.Text = "<<"; + this.btnRemoveAll.UseVisualStyleBackColor = true; + this.btnRemoveAll.Click += new System.EventHandler(this.btnRemoveAll_Click); + // + // btnSelectOne + // + this.btnSelectOne.FlatStyle = System.Windows.Forms.FlatStyle.Popup; + this.btnSelectOne.Location = new System.Drawing.Point(198, 82); + this.btnSelectOne.Name = "btnSelectOne"; + this.btnSelectOne.Size = new System.Drawing.Size(28, 25); + this.btnSelectOne.TabIndex = 7; + this.btnSelectOne.Text = ">"; + this.btnSelectOne.UseVisualStyleBackColor = true; + this.btnSelectOne.Click += new System.EventHandler(this.btnSelectOne_Click); + // + // listBox2 + // + this.listBox2.FormattingEnabled = true; + this.listBox2.ItemHeight = 12; + this.listBox2.Location = new System.Drawing.Point(232, 20); + this.listBox2.Name = "listBox2"; + this.listBox2.SelectionMode = System.Windows.Forms.SelectionMode.MultiExtended; + this.listBox2.Size = new System.Drawing.Size(180, 196); + this.listBox2.TabIndex = 6; + this.listBox2.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.listBox2_MouseDoubleClick); + // + // btnSelectAll + // + this.btnSelectAll.FlatStyle = System.Windows.Forms.FlatStyle.Popup; + this.btnSelectAll.Location = new System.Drawing.Point(198, 32); + this.btnSelectAll.Name = "btnSelectAll"; + this.btnSelectAll.Size = new System.Drawing.Size(28, 25); + this.btnSelectAll.TabIndex = 2; + this.btnSelectAll.Text = ">>"; + this.btnSelectAll.UseVisualStyleBackColor = true; + this.btnSelectAll.Click += new System.EventHandler(this.btnSelectAll_Click); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(9, 27); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(53, 12); + this.label1.TabIndex = 2; + this.label1.Text = "命名空间"; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(153, 54); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(65, 12); + this.label2.TabIndex = 3; + this.label2.Text = "前缀分隔符"; + // + // txtTablePrefix + // + this.txtTablePrefix.Location = new System.Drawing.Point(224, 50); + this.txtTablePrefix.Name = "txtTablePrefix"; + this.txtTablePrefix.Size = new System.Drawing.Size(30, 21); + this.txtTablePrefix.TabIndex = 5; + this.txtTablePrefix.Text = "_"; + // + // txtNameSpace + // + this.txtNameSpace.Location = new System.Drawing.Point(68, 23); + this.txtNameSpace.Name = "txtNameSpace"; + this.txtNameSpace.Size = new System.Drawing.Size(285, 21); + this.txtNameSpace.TabIndex = 9; + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.cbClassNameRemovePlural); + this.groupBox1.Controls.Add(this.label3); + this.groupBox1.Controls.Add(this.txtClassPrefix); + this.groupBox1.Controls.Add(this.cbClassNameIsFileName); + this.groupBox1.Controls.Add(this.cbAddSuffix); + this.groupBox1.Controls.Add(this.cbClassNamePascal); + this.groupBox1.Controls.Add(this.cbDeleteTablePrifix); + this.groupBox1.Controls.Add(this.txtClassSuffix); + this.groupBox1.Controls.Add(this.lblMsg); + this.groupBox1.Controls.Add(this.progressBar1); + this.groupBox1.Controls.Add(this.btnBuildCode); + this.groupBox1.Controls.Add(this.txtPrefixLevel); + this.groupBox1.Controls.Add(this.label8); + this.groupBox1.Controls.Add(this.btnBrowser); + this.groupBox1.Controls.Add(this.txtOutputPath); + this.groupBox1.Controls.Add(this.label5); + this.groupBox1.Controls.Add(this.txtTablePrefix); + this.groupBox1.Controls.Add(this.txtNameSpace); + this.groupBox1.Controls.Add(this.label1); + this.groupBox1.Controls.Add(this.label2); + this.groupBox1.Dock = System.Windows.Forms.DockStyle.Fill; + this.groupBox1.Location = new System.Drawing.Point(0, 0); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(450, 230); + this.groupBox1.TabIndex = 10; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "参数设置"; + // + // cbClassNameIsFileName + // + this.cbClassNameIsFileName.AutoSize = true; + this.cbClassNameIsFileName.Checked = true; + this.cbClassNameIsFileName.CheckState = System.Windows.Forms.CheckState.Checked; + this.cbClassNameIsFileName.Location = new System.Drawing.Point(9, 127); + this.cbClassNameIsFileName.Name = "cbClassNameIsFileName"; + this.cbClassNameIsFileName.Size = new System.Drawing.Size(108, 16); + this.cbClassNameIsFileName.TabIndex = 27; + this.cbClassNameIsFileName.Text = "类名作为文件名"; + this.cbClassNameIsFileName.UseVisualStyleBackColor = true; + // + // cbAddSuffix + // + this.cbAddSuffix.AutoSize = true; + this.cbAddSuffix.Location = new System.Drawing.Point(9, 102); + this.cbAddSuffix.Name = "cbAddSuffix"; + this.cbAddSuffix.Size = new System.Drawing.Size(108, 16); + this.cbAddSuffix.TabIndex = 26; + this.cbAddSuffix.Text = "类名添加前后缀"; + this.cbAddSuffix.UseVisualStyleBackColor = true; + // + // cbClassNamePascal + // + this.cbClassNamePascal.AutoSize = true; + this.cbClassNamePascal.Location = new System.Drawing.Point(9, 77); + this.cbClassNamePascal.Name = "cbClassNamePascal"; + this.cbClassNamePascal.Size = new System.Drawing.Size(180, 16); + this.cbClassNamePascal.TabIndex = 25; + this.cbClassNamePascal.Text = "规范化类名,按Pascal大小写"; + this.cbClassNamePascal.UseVisualStyleBackColor = true; + // + // cbDeleteTablePrifix + // + this.cbDeleteTablePrifix.AutoSize = true; + this.cbDeleteTablePrifix.Location = new System.Drawing.Point(9, 52); + this.cbDeleteTablePrifix.Name = "cbDeleteTablePrifix"; + this.cbDeleteTablePrifix.Size = new System.Drawing.Size(96, 16); + this.cbDeleteTablePrifix.TabIndex = 24; + this.cbDeleteTablePrifix.Text = "删除表名前缀"; + this.cbDeleteTablePrifix.UseVisualStyleBackColor = true; + // + // txtClassSuffix + // + this.txtClassSuffix.Location = new System.Drawing.Point(242, 100); + this.txtClassSuffix.Name = "txtClassSuffix"; + this.txtClassSuffix.Size = new System.Drawing.Size(76, 21); + this.txtClassSuffix.TabIndex = 23; + // + // lblMsg + // + this.lblMsg.AutoSize = true; + this.lblMsg.ForeColor = System.Drawing.Color.Red; + this.lblMsg.Location = new System.Drawing.Point(6, 191); + this.lblMsg.Name = "lblMsg"; + this.lblMsg.Size = new System.Drawing.Size(101, 12); + this.lblMsg.TabIndex = 21; + this.lblMsg.Text = "代码生成进度显示"; + // + // progressBar1 + // + this.progressBar1.Dock = System.Windows.Forms.DockStyle.Bottom; + this.progressBar1.ForeColor = System.Drawing.Color.ForestGreen; + this.progressBar1.Location = new System.Drawing.Point(3, 209); + this.progressBar1.Name = "progressBar1"; + this.progressBar1.Size = new System.Drawing.Size(444, 18); + this.progressBar1.Step = 2; + this.progressBar1.TabIndex = 20; + // + // btnBuildCode + // + this.btnBuildCode.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.btnBuildCode.Location = new System.Drawing.Point(368, 182); + this.btnBuildCode.Name = "btnBuildCode"; + this.btnBuildCode.Size = new System.Drawing.Size(75, 23); + this.btnBuildCode.TabIndex = 18; + this.btnBuildCode.Text = "生成代码"; + this.btnBuildCode.UseVisualStyleBackColor = true; + this.btnBuildCode.Click += new System.EventHandler(this.btnBuildCode_Click); + // + // txtPrefixLevel + // + this.txtPrefixLevel.Location = new System.Drawing.Point(323, 50); + this.txtPrefixLevel.Name = "txtPrefixLevel"; + this.txtPrefixLevel.Size = new System.Drawing.Size(30, 21); + this.txtPrefixLevel.TabIndex = 16; + this.txtPrefixLevel.Text = "1"; + // + // label8 + // + this.label8.AutoSize = true; + this.label8.Location = new System.Drawing.Point(268, 54); + this.label8.Name = "label8"; + this.label8.Size = new System.Drawing.Size(53, 12); + this.label8.TabIndex = 15; + this.label8.Text = "前缀层次"; + // + // btnBrowser + // + this.btnBrowser.Location = new System.Drawing.Point(368, 151); + this.btnBrowser.Name = "btnBrowser"; + this.btnBrowser.Size = new System.Drawing.Size(75, 23); + this.btnBrowser.TabIndex = 12; + this.btnBrowser.Text = "浏览..."; + this.btnBrowser.UseVisualStyleBackColor = true; + this.btnBrowser.Click += new System.EventHandler(this.btnBrowser_Click); + // + // txtOutputPath + // + this.txtOutputPath.Location = new System.Drawing.Point(83, 152); + this.txtOutputPath.Name = "txtOutputPath"; + this.txtOutputPath.Size = new System.Drawing.Size(282, 21); + this.txtOutputPath.TabIndex = 11; + // + // label5 + // + this.label5.AutoSize = true; + this.label5.Location = new System.Drawing.Point(6, 156); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(77, 12); + this.label5.TabIndex = 10; + this.label5.Text = "代码输出路径"; + // + // backgroundWorker1 + // + this.backgroundWorker1.WorkerReportsProgress = true; + this.backgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker1_DoWork); + this.backgroundWorker1.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.backgroundWorker1_ProgressChanged); + this.backgroundWorker1.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted); + // + // splitContainer1 + // + this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill; + this.splitContainer1.FixedPanel = System.Windows.Forms.FixedPanel.Panel1; + this.splitContainer1.IsSplitterFixed = true; + this.splitContainer1.Location = new System.Drawing.Point(0, 0); + this.splitContainer1.Name = "splitContainer1"; + this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal; + // + // splitContainer1.Panel1 + // + this.splitContainer1.Panel1.Controls.Add(this.splitContainer3); + this.splitContainer1.Panel1.Margin = new System.Windows.Forms.Padding(5); + this.splitContainer1.Panel1.Padding = new System.Windows.Forms.Padding(5); + // + // splitContainer1.Panel2 + // + this.splitContainer1.Panel2.Controls.Add(this.splitContainer2); + this.splitContainer1.Size = new System.Drawing.Size(885, 543); + this.splitContainer1.SplitterDistance = 240; + this.splitContainer1.TabIndex = 11; + // + // splitContainer3 + // + this.splitContainer3.Dock = System.Windows.Forms.DockStyle.Fill; + this.splitContainer3.FixedPanel = System.Windows.Forms.FixedPanel.Panel1; + this.splitContainer3.IsSplitterFixed = true; + this.splitContainer3.Location = new System.Drawing.Point(5, 5); + this.splitContainer3.Name = "splitContainer3"; + // + // splitContainer3.Panel1 + // + this.splitContainer3.Panel1.Controls.Add(this.gbTableSelect); + // + // splitContainer3.Panel2 + // + this.splitContainer3.Panel2.Controls.Add(this.groupBox1); + this.splitContainer3.Size = new System.Drawing.Size(875, 230); + this.splitContainer3.SplitterDistance = 421; + this.splitContainer3.TabIndex = 11; + // + // splitContainer2 + // + this.splitContainer2.Dock = System.Windows.Forms.DockStyle.Fill; + this.splitContainer2.FixedPanel = System.Windows.Forms.FixedPanel.Panel1; + this.splitContainer2.Location = new System.Drawing.Point(0, 0); + this.splitContainer2.Name = "splitContainer2"; + // + // splitContainer2.Panel1 + // + this.splitContainer2.Panel1.Controls.Add(this.gbTemplateList); + // + // splitContainer2.Panel2 + // + this.splitContainer2.Panel2.Controls.Add(this.gbTemplateFile); + this.splitContainer2.Size = new System.Drawing.Size(885, 299); + this.splitContainer2.SplitterDistance = 192; + this.splitContainer2.TabIndex = 1; + // + // gbTemplateList + // + this.gbTemplateList.Controls.Add(this.tvTemplate); + this.gbTemplateList.Dock = System.Windows.Forms.DockStyle.Fill; + this.gbTemplateList.Location = new System.Drawing.Point(0, 0); + this.gbTemplateList.Name = "gbTemplateList"; + this.gbTemplateList.Size = new System.Drawing.Size(192, 299); + this.gbTemplateList.TabIndex = 1; + this.gbTemplateList.TabStop = false; + this.gbTemplateList.Text = "选择代码模板"; + // + // tvTemplate + // + this.tvTemplate.Dock = System.Windows.Forms.DockStyle.Fill; + this.tvTemplate.ImageIndex = 0; + this.tvTemplate.ImageList = this.imgList; + this.tvTemplate.Location = new System.Drawing.Point(3, 17); + this.tvTemplate.Name = "tvTemplate"; + this.tvTemplate.SelectedImageIndex = 0; + this.tvTemplate.Size = new System.Drawing.Size(186, 279); + this.tvTemplate.TabIndex = 0; + this.tvTemplate.MouseClick += new System.Windows.Forms.MouseEventHandler(this.tvTemplate_MouseClick); + this.tvTemplate.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.tvTemplate_MouseDoubleClick); + // + // imgList + // + this.imgList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imgList.ImageStream"))); + this.imgList.TransparentColor = System.Drawing.Color.Transparent; + this.imgList.Images.SetKeyName(0, "templateRoot.png"); + this.imgList.Images.SetKeyName(1, "templateDir.png"); + this.imgList.Images.SetKeyName(2, "templateFile.png"); + // + // gbTemplateFile + // + this.gbTemplateFile.Controls.Add(this.textEditorControl1); + this.gbTemplateFile.Dock = System.Windows.Forms.DockStyle.Fill; + this.gbTemplateFile.Location = new System.Drawing.Point(0, 0); + this.gbTemplateFile.Name = "gbTemplateFile"; + this.gbTemplateFile.Size = new System.Drawing.Size(689, 299); + this.gbTemplateFile.TabIndex = 2; + this.gbTemplateFile.TabStop = false; + this.gbTemplateFile.Text = "模板预览"; + // + // textEditorControl1 + // + this.textEditorControl1.ContextMenuStrip = this.cms; + this.textEditorControl1.Dock = System.Windows.Forms.DockStyle.Fill; + this.textEditorControl1.IsReadOnly = false; + this.textEditorControl1.Location = new System.Drawing.Point(3, 17); + this.textEditorControl1.Name = "textEditorControl1"; + this.textEditorControl1.Size = new System.Drawing.Size(683, 279); + this.textEditorControl1.TabIndex = 1; + // + // cms + // + this.cms.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.menuItemUndo, + this.menuItemRedo, + this.toolStripSeparator5, + this.menuItemCut, + this.menuItemCopy, + this.menuItemPaste, + this.menuItemDelete, + this.toolStripSeparator1, + this.menuItemSelectAll, + this.toolStripSeparator2, + this.menuItemSave}); + this.cms.Name = "cms"; + this.cms.Size = new System.Drawing.Size(163, 198); + // + // menuItemUndo + // + this.menuItemUndo.Image = ((System.Drawing.Image)(resources.GetObject("menuItemUndo.Image"))); + this.menuItemUndo.Name = "menuItemUndo"; + this.menuItemUndo.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Z))); + this.menuItemUndo.Size = new System.Drawing.Size(162, 22); + this.menuItemUndo.Text = "撤销(&Z)"; + this.menuItemUndo.Click += new System.EventHandler(this.menuItemUndo_Click); + // + // menuItemRedo + // + this.menuItemRedo.Image = ((System.Drawing.Image)(resources.GetObject("menuItemRedo.Image"))); + this.menuItemRedo.Name = "menuItemRedo"; + this.menuItemRedo.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Y))); + this.menuItemRedo.Size = new System.Drawing.Size(162, 22); + this.menuItemRedo.Text = "重复(&R)"; + this.menuItemRedo.Click += new System.EventHandler(this.menuItemRedo_Click); + // + // toolStripSeparator5 + // + this.toolStripSeparator5.Name = "toolStripSeparator5"; + this.toolStripSeparator5.Size = new System.Drawing.Size(159, 6); + // + // menuItemCut + // + this.menuItemCut.Image = ((System.Drawing.Image)(resources.GetObject("menuItemCut.Image"))); + this.menuItemCut.Name = "menuItemCut"; + this.menuItemCut.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.X))); + this.menuItemCut.Size = new System.Drawing.Size(162, 22); + this.menuItemCut.Text = "剪切(&X)"; + this.menuItemCut.Click += new System.EventHandler(this.menuItemCut_Click); + // + // menuItemCopy + // + this.menuItemCopy.Image = ((System.Drawing.Image)(resources.GetObject("menuItemCopy.Image"))); + this.menuItemCopy.Name = "menuItemCopy"; + this.menuItemCopy.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.C))); + this.menuItemCopy.Size = new System.Drawing.Size(162, 22); + this.menuItemCopy.Text = "复制(&C)"; + this.menuItemCopy.Click += new System.EventHandler(this.menuItemCopy_Click); + // + // menuItemPaste + // + this.menuItemPaste.Image = ((System.Drawing.Image)(resources.GetObject("menuItemPaste.Image"))); + this.menuItemPaste.Name = "menuItemPaste"; + this.menuItemPaste.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.V))); + this.menuItemPaste.Size = new System.Drawing.Size(162, 22); + this.menuItemPaste.Text = "粘贴(&V)"; + this.menuItemPaste.Click += new System.EventHandler(this.menuItemPaste_Click); + // + // menuItemDelete + // + this.menuItemDelete.Image = ((System.Drawing.Image)(resources.GetObject("menuItemDelete.Image"))); + this.menuItemDelete.Name = "menuItemDelete"; + this.menuItemDelete.ShortcutKeys = System.Windows.Forms.Keys.Delete; + this.menuItemDelete.Size = new System.Drawing.Size(162, 22); + this.menuItemDelete.Text = "删除(&D)"; + this.menuItemDelete.Click += new System.EventHandler(this.menuItemDelete_Click); + // + // toolStripSeparator1 + // + this.toolStripSeparator1.Name = "toolStripSeparator1"; + this.toolStripSeparator1.Size = new System.Drawing.Size(159, 6); + // + // menuItemSelectAll + // + this.menuItemSelectAll.Name = "menuItemSelectAll"; + this.menuItemSelectAll.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.A))); + this.menuItemSelectAll.Size = new System.Drawing.Size(162, 22); + this.menuItemSelectAll.Text = "全选(&A)"; + this.menuItemSelectAll.Click += new System.EventHandler(this.menuItemSelectAll_Click); + // + // toolStripSeparator2 + // + this.toolStripSeparator2.Name = "toolStripSeparator2"; + this.toolStripSeparator2.Size = new System.Drawing.Size(159, 6); + // + // menuItemSave + // + this.menuItemSave.Image = ((System.Drawing.Image)(resources.GetObject("menuItemSave.Image"))); + this.menuItemSave.Name = "menuItemSave"; + this.menuItemSave.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.S))); + this.menuItemSave.Size = new System.Drawing.Size(162, 22); + this.menuItemSave.Text = "保存(&S)"; + this.menuItemSave.Click += new System.EventHandler(this.menuItemSave_Click); + // + // cmsTree + // + this.cmsTree.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.menuItemRefresh, + this.menuItemManage}); + this.cmsTree.Name = "cmsTree"; + this.cmsTree.Size = new System.Drawing.Size(125, 48); + // + // menuItemRefresh + // + this.menuItemRefresh.Name = "menuItemRefresh"; + this.menuItemRefresh.Size = new System.Drawing.Size(124, 22); + this.menuItemRefresh.Text = "刷新"; + this.menuItemRefresh.Click += new System.EventHandler(this.menuItemRefresh_Click); + // + // menuItemManage + // + this.menuItemManage.Name = "menuItemManage"; + this.menuItemManage.Size = new System.Drawing.Size(124, 22); + this.menuItemManage.Text = "模板管理"; + this.menuItemManage.Click += new System.EventHandler(this.menuItemManage_Click); + // + // txtClassPrefix + // + this.txtClassPrefix.Location = new System.Drawing.Point(118, 100); + this.txtClassPrefix.Name = "txtClassPrefix"; + this.txtClassPrefix.Size = new System.Drawing.Size(71, 21); + this.txtClassPrefix.TabIndex = 28; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(195, 104); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(41, 12); + this.label3.TabIndex = 29; + this.label3.Text = "+类名+"; + // + // cbClassNameRemovePlural + // + this.cbClassNameRemovePlural.AutoSize = true; + this.cbClassNameRemovePlural.Location = new System.Drawing.Point(134, 127); + this.cbClassNameRemovePlural.Name = "cbClassNameRemovePlural"; + this.cbClassNameRemovePlural.Size = new System.Drawing.Size(96, 16); + this.cbClassNameRemovePlural.TabIndex = 30; + this.cbClassNameRemovePlural.Text = "去掉类名复数"; + this.cbClassNameRemovePlural.UseVisualStyleBackColor = true; + // + // BatchBuildCode + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(885, 543); + this.Controls.Add(this.splitContainer1); + this.MaximizeBox = false; + this.Name = "BatchBuildCode"; + this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "批量生成代码"; + this.Load += new System.EventHandler(this.BatchBuildCode_Load); + this.gbTableSelect.ResumeLayout(false); + this.groupBox1.ResumeLayout(false); + this.groupBox1.PerformLayout(); + this.splitContainer1.Panel1.ResumeLayout(false); + this.splitContainer1.Panel2.ResumeLayout(false); + this.splitContainer1.ResumeLayout(false); + this.splitContainer3.Panel1.ResumeLayout(false); + this.splitContainer3.Panel2.ResumeLayout(false); + this.splitContainer3.ResumeLayout(false); + this.splitContainer2.Panel1.ResumeLayout(false); + this.splitContainer2.Panel2.ResumeLayout(false); + this.splitContainer2.ResumeLayout(false); + this.gbTemplateList.ResumeLayout(false); + this.gbTemplateFile.ResumeLayout(false); + this.cms.ResumeLayout(false); + this.cmsTree.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Label lblMsg; + private System.Windows.Forms.ProgressBar progressBar1; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.Button btnBuildCode; + private System.Windows.Forms.TextBox txtPrefixLevel; + private System.Windows.Forms.Label label8; + private System.Windows.Forms.Button btnBrowser; + private System.Windows.Forms.TextBox txtOutputPath; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.TextBox txtTablePrefix; + private System.Windows.Forms.TextBox txtNameSpace; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.FolderBrowserDialog folderBrowserDialog1; + private System.Windows.Forms.Button btnRemoveOne; + private System.Windows.Forms.Button btnRemoveAll; + private System.Windows.Forms.Button btnSelectOne; + private System.Windows.Forms.ListBox listBox2; + private System.Windows.Forms.GroupBox gbTableSelect; + private System.Windows.Forms.Button btnSelectAll; + private System.Windows.Forms.ListBox listBox1; + private System.ComponentModel.BackgroundWorker backgroundWorker1; + private System.Windows.Forms.SplitContainer splitContainer1; + private System.Windows.Forms.SplitContainer splitContainer2; + private System.Windows.Forms.GroupBox gbTemplateList; + private System.Windows.Forms.TreeView tvTemplate; + private System.Windows.Forms.GroupBox gbTemplateFile; + private ICSharpCode.TextEditor.TextEditorControl textEditorControl1; + private System.Windows.Forms.SplitContainer splitContainer3; + private System.Windows.Forms.ContextMenuStrip cmsTree; + private System.Windows.Forms.ToolStripMenuItem menuItemRefresh; + private System.Windows.Forms.ToolStripMenuItem menuItemManage; + private System.Windows.Forms.ContextMenuStrip cms; + private System.Windows.Forms.ToolStripMenuItem menuItemUndo; + private System.Windows.Forms.ToolStripMenuItem menuItemRedo; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator5; + private System.Windows.Forms.ToolStripMenuItem menuItemCut; + private System.Windows.Forms.ToolStripMenuItem menuItemCopy; + private System.Windows.Forms.ToolStripMenuItem menuItemPaste; + private System.Windows.Forms.ToolStripMenuItem menuItemDelete; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; + private System.Windows.Forms.ToolStripMenuItem menuItemSelectAll; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator2; + private System.Windows.Forms.ToolStripMenuItem menuItemSave; + private System.Windows.Forms.ImageList imgList; + private System.Windows.Forms.TextBox txtClassSuffix; + private System.Windows.Forms.CheckBox cbDeleteTablePrifix; + private System.Windows.Forms.CheckBox cbClassNamePascal; + private System.Windows.Forms.CheckBox cbClassNameIsFileName; + private System.Windows.Forms.CheckBox cbAddSuffix; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.TextBox txtClassPrefix; + private System.Windows.Forms.CheckBox cbClassNameRemovePlural; + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/CodeBuilder/BatchBuildCode.resx b/src/Kalman.Studio/CodeBuilder/BatchBuildCode.resx new file mode 100644 index 0000000..c0a3aa2 --- /dev/null +++ b/src/Kalman.Studio/CodeBuilder/BatchBuildCode.resx @@ -0,0 +1,279 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + 197, 17 + + + 547, 17 + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj0yLjAuMC4w + LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 + ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAACK + CgAAAk1TRnQBSQFMAgEBAwEAAWQBAAFkAQABEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo + AwABQAMAARADAAEBAQABCAYAAQQYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA + AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5 + AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA + AWYDAAGZAwABzAIAATMDAAIzAgABMwFmAgABMwGZAgABMwHMAgABMwH/AgABZgMAAWYBMwIAAmYCAAFm + AZkCAAFmAcwCAAFmAf8CAAGZAwABmQEzAgABmQFmAgACmQIAAZkBzAIAAZkB/wIAAcwDAAHMATMCAAHM + AWYCAAHMAZkCAALMAgABzAH/AgAB/wFmAgAB/wGZAgAB/wHMAQABMwH/AgAB/wEAATMBAAEzAQABZgEA + ATMBAAGZAQABMwEAAcwBAAEzAQAB/wEAAf8BMwIAAzMBAAIzAWYBAAIzAZkBAAIzAcwBAAIzAf8BAAEz + AWYCAAEzAWYBMwEAATMCZgEAATMBZgGZAQABMwFmAcwBAAEzAWYB/wEAATMBmQIAATMBmQEzAQABMwGZ + AWYBAAEzApkBAAEzAZkBzAEAATMBmQH/AQABMwHMAgABMwHMATMBAAEzAcwBZgEAATMBzAGZAQABMwLM + AQABMwHMAf8BAAEzAf8BMwEAATMB/wFmAQABMwH/AZkBAAEzAf8BzAEAATMC/wEAAWYDAAFmAQABMwEA + AWYBAAFmAQABZgEAAZkBAAFmAQABzAEAAWYBAAH/AQABZgEzAgABZgIzAQABZgEzAWYBAAFmATMBmQEA + AWYBMwHMAQABZgEzAf8BAAJmAgACZgEzAQADZgEAAmYBmQEAAmYBzAEAAWYBmQIAAWYBmQEzAQABZgGZ + AWYBAAFmApkBAAFmAZkBzAEAAWYBmQH/AQABZgHMAgABZgHMATMBAAFmAcwBmQEAAWYCzAEAAWYBzAH/ + AQABZgH/AgABZgH/ATMBAAFmAf8BmQEAAWYB/wHMAQABzAEAAf8BAAH/AQABzAEAApkCAAGZATMBmQEA + AZkBAAGZAQABmQEAAcwBAAGZAwABmQIzAQABmQEAAWYBAAGZATMBzAEAAZkBAAH/AQABmQFmAgABmQFm + ATMBAAGZATMBZgEAAZkBZgGZAQABmQFmAcwBAAGZATMB/wEAApkBMwEAApkBZgEAA5kBAAKZAcwBAAKZ + Af8BAAGZAcwCAAGZAcwBMwEAAWYBzAFmAQABmQHMAZkBAAGZAswBAAGZAcwB/wEAAZkB/wIAAZkB/wEz + AQABmQHMAWYBAAGZAf8BmQEAAZkB/wHMAQABmQL/AQABzAMAAZkBAAEzAQABzAEAAWYBAAHMAQABmQEA + AcwBAAHMAQABmQEzAgABzAIzAQABzAEzAWYBAAHMATMBmQEAAcwBMwHMAQABzAEzAf8BAAHMAWYCAAHM + AWYBMwEAAZkCZgEAAcwBZgGZAQABzAFmAcwBAAGZAWYB/wEAAcwBmQIAAcwBmQEzAQABzAGZAWYBAAHM + ApkBAAHMAZkBzAEAAcwBmQH/AQACzAIAAswBMwEAAswBZgEAAswBmQEAA8wBAALMAf8BAAHMAf8CAAHM + Af8BMwEAAZkB/wFmAQABzAH/AZkBAAHMAf8BzAEAAcwC/wEAAcwBAAEzAQAB/wEAAWYBAAH/AQABmQEA + AcwBMwIAAf8CMwEAAf8BMwFmAQAB/wEzAZkBAAH/ATMBzAEAAf8BMwH/AQAB/wFmAgAB/wFmATMBAAHM + AmYBAAH/AWYBmQEAAf8BZgHMAQABzAFmAf8BAAH/AZkCAAH/AZkBMwEAAf8BmQFmAQAB/wKZAQAB/wGZ + AcwBAAH/AZkB/wEAAf8BzAIAAf8BzAEzAQAB/wHMAWYBAAH/AcwBmQEAAf8CzAEAAf8BzAH/AQAC/wEz + AQABzAH/AWYBAAL/AZkBAAL/AcwBAAJmAf8BAAFmAf8BZgEAAWYC/wEAAf8CZgEAAf8BZgH/AQAC/wFm + AQABIQEAAaUBAANfAQADdwEAA4YBAAOWAQADywEAA7IBAAPXAQAD3QEAA+MBAAPqAQAD8QEAA/gBAAHw + AfsB/wEAAaQCoAEAA4ADAAH/AgAB/wMAAv8BAAH/AwAB/wEAAf8BAAL/AgAD/wsAASoBKRkAAioB8QEH + AZIBrgFsARIDZhcAAVEBKQEcATEBMAF0ASkBcxMAAyoBmgF6AyoB8wEJAbsCtQFmEAABBwOuAewB7wG8 + ASkBegEpAnoBKQGgASkB7wcAAbUIZgEAAUsBeQExASoBmgF6ASoBMQF5ASoB8wEZAd0BtQFmEAAB9wH/ + BPMB9AGZASkBegIqAaABKQGZAfEHAAG1Af8F9AEZAWYBAAFLAXkBMQEqAZoBegEqATEBeQEqAfMBBwG7 + AbUBZhAAAfcF/wEwASkBegEpAv8BKgGgATABKQQAAbUCZgG1Af8CtQH/AbUBtAH0AWYCSwGaAXoBUgF6 + AXkBUgJ6AioB8wEZAbUBZhAAAfcF/wExATABegEpAv8BKgF6ATEBMAQAAbUB/wH0AbUE/wP0AWYBSwEx + ASoBmgGgBJoBKgExASoB8AEHAbUBZhAAAfcG/wGZASkBegIpAXoBKQGZAfEBAAG1AmYBtQH/AbUB7wH/ + AbsB7wH/ArUB9AFmAUsEoAJ0AZoDoAEqAfMBGQG7AWYQAAH3Bv8BKQF6ASkCegEpAXoBKQG8AQABtQH/ + AfQBtQL/Ae8H/wFmARwCSwF5AXQCegF0AXkBKgFLAQcB8wEZAQkBZhAAAfcG/wF0ASkBmQEwASkBmQEp + AXQBBwEAAbUB/wG1Ae8B/wK7Af8CBwH/AbsBtQH/AWYBAAFLAnkBoAJ0AaACeQEqAf8C8wEJAWYQAAH3 + Cf8BMQEwAv8BGQH3AQABtQL/Ae8C/wG7B/8BZgEAARwDSwGgAZoDSwGZAf8C8wG8AWYQAAH3DP8B9AEZ + AewBAAHvAf8CuwH/AQcCuwTvA7UCAAHwAf8BBwJLARwC8AL/AfQB8wG8AWYQAAH3Dv8BrgEAAe8C/wG7 + B/8BZgUAAe8B/wTwAfcB6wRtAfABZhAAAQcB9wT/Ca4B9wEAAbsB/wEHArsE7wO1BQAB7wv/ARkBZhEA + AfcE/wH3AQAB9wQJAesDAAG7B/8BZggAAbsB/wVtBf8BGQFmEQABBwT3AQcBAAEHBPcBBwMAArsE7wO1 + CAABuwz/AWYyAAW7BO8EtQH3EAABQgFNAT4HAAE+AwABKAMAAUADAAEQAwABAQEAAQEFAAGAFwAD/wEA + Af8BzwL/AfgDAAH+AQEC/wHABQAB/gEAAYAFAAH+AQABgAUAAfAHAAHwBwABgAcAAYAHAAGAAQABgAUA + AYABAAGABQABgAEAAcAFAAGAAQcBwAUAAYABBwHAAwABgQEDAYABPwHAAwABgQEDAYABPwHAAwAE/wHA + AwAL + + + + 472, 17 + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAURJREFUOE+1kDFy + gzAQRX2E3CDcAG6AuqSD0qlQ6Q51phNlOijpUGc61Dmd1aYyN7BuwN5gs4uTGRg7cVxYMzsqdv/7f3e1 + euSr9qOsLDjzAb514PoD1P1hDP7lycLaAtLvdXcuBlkHcBVSd4Dt5xgxverBsDirAYQaUGwshpmFuPBg + 9gAE8YsURHwqCWAcDHo3liyWtUehHIkdi12cWy+kwfR9mlsCmKYaj6oBVObbWVoUVGHWK+4nug/CtZlS + 6B24izuwY1qy8xkSvlaWxGI+yGl+BaSlx0idIZyEgbodLwCJpgQd2IsEouCd+WAOI4oeranSGn8GKU3A + Pb5B3pymtf58fNj5wPNLJdiEV7ylvdqPN25g90Qfb7vPCVk1BnF+lJO4GOBu92R7EixOiwHDtz69G0AJ + ZLw9lnTExU3uBj1M8AXZCvHw6pRRNAAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAUhJREFUOE/FkTFu + wkAQRTkCN4Ab2Dewu9CtSzpvSWd3cbfpQmeXdN4udN4upGLbVPgG7A3232AzY6TIyEEEKVJG2mrnv/9n + Zjb7q+qOftkd0bQWVh/g6s5L1fr5r/gsNhZgodqPngYIIu9CSOz0O5BUDlFukG5MSAqLvAEKghStzxjS + fvo4LfswAWoCZFuEeK1JaBxBLINiaYJsEPIdHEEk9fXpxgZKfD2aeoNl98VT7YTqluwQ5V0ZrTXiTAfx + CldqhHJHJgSdJBgB7PiTIGm0qg2LOUn2ckk5BexhhAIiSjD+rD983BwuzoO4dCHOmimg2J3Lyw5MWCTq + ez5eGM/MsdmZxcvVDwB25Yhp5QLtIR2nmCzs1k2FOg0pko3t7979JqTqMUCKk8xrP1zjoYpEOxeV68UW + EM/nq1EeAgnlM0ogHxL9W/MXM4DmfcnD838AAAAASUVORK5CYII= + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAWVJREFUOE+lkzFS + wzAQRXOD5AbODawupVyllSpSygUD6eKCCXRWwQQ6qSOdXEFp3cAu6Zwb2B2l1VEuWgMzBDshGYqdsT3/ + v/27skYAMPpP9cx5Xmjzkjc/oKSua5dulB1q1AMokxO9zSB9MFM0tO8grS1BrNL4JACK9NaCB2X+eVK/ + tS5OJIzH4w74uwbn92M4rTOoqkqWrzvgcXIewDwXFsdQT6ZMpAbGhDu06MEESpkIjRgdu9M5G1wgQg8e + oV+aQzNfSmBieIGDAHHfErFpLZcNsHVl+d0O2G3lfGX0quBHl9iZVetYWju6MC5kqqGrwiEkWpZAhdFH + AWxTW/7YeLEFwjV4wHeCKb3OY/x2FIBm353Qy5x8ASbdCDcVoRcqIVHyBwDnRrHAbrITs3Wxi2KfKIoh + CMLece6dgl/ap9hHDWasuw8YPZwJF/gKWYoR9jx7L514oRo0hPO++ORf+Zzr/QHVYbSHDgmOiAAAAABJ + RU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAUBJREFUOE+tU6Fu + wzAU7KfkD5pPCIyGwjbWsA0aDgaO1TBjhmE1LJthoGFYDQcNx27vbK1pIm2ZtJ10JPK7u3dP2e3+CusC + Mn3m2cNYj+PrqfmVNofXMNah7Qz2d4dyU4Sua+jBwY0erdLbIoxMuAmQ5PAhQhsLO0ZZKdOc5ZvNPBwv + 1SIV417xAcQIhHcZFIE1uiGifHLYP77NIkbiEmYEtDh1NkCZACPOa6g+C5cPFvv7UxbhvkRM7jG5cw1z + zuVqm+mniFaHNEwWjUEWkH05/OVMd9V76GF5Hb6huPMiLmUtBSQtXf0U5IFwDOhEiODeqg/Jvel8YhKo + bxKUdYs1lZ7Py2JpQPd0FSm+qHVe4Tu0L1ng1vmaQHrbFGieXeqGcWc68Gosvqg2ElTKLRpnaXRNlOGi + 6n5eYfMf+K8Hn1Gm2tY78ARPAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAY9JREFUOE+1k612 + 4zAUhP0IeYQ8gmGhYFkFwyoYFsGyijUsgoaCYRUMFDQUDBQMFCybzpXqNv3ZLdizOmeODDzf3B97GP7H + SdFBFIPD7v5u/GvG8/Fg49FjUfAG9RKaytnDbhX83lKu3YennfoEFGOtEaBqDQiTbfdue5fz7OCshjMj + aiL4tIY1Gt8AYhb5vUGeCbx4pjuU2SBOGmajENwa2Q+wm6+A4JsZTPXOMFGkWfqbmGgJ8LYDzK36XEFY + ANJ3YXq2yGH1oYnPNC5SN+MXwOT60ArvM/vPmgWt4ANbmiKcp/YB1gWYBw9j/Q8AST5zSDPNiQMTAM3v + 54Ud1opyqdBbB23cByR4SaZm1c2nFUoYWrKcEFPXMSEXAmhOc4bSpkNkv9L3Yq7HoQNYNq6S87ki5QK9 + sc2sbjWU4kDl46gzxWQpvRCQJ66LPUvZ1xXIXGLKfT6UGtcEODH3FV1LBiY9L8lpLs0cT13vgMPjTsn+ + 5QszWkGrsZFl2tLzkvbT3Sr405Fpywu/6Z9/5lcMCPZ7KYCY8wAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAURJREFUOE+tkrFx + g0AQRcns7C6zxsldJmV7mRkle5mwk1UJKkElUAIlUAIlUAIlUAId4L/IMBbCBs+YmR0O9v+3n+OSBJd8 + SJCT1Kioz3+++MSXGGPPzJ28y/k3gIh4zvh6p4HxgqpCGnsFIUk+hzgiC02UTDrcyznAa1MhChggIhXK + qpCYLWcy9CilggD7MSUg12+Qko8cOOViMBMVmmR1jwAJqEY/CaZOyx2o2mQe6TDFEEIfb5DWuQ2TJ/Mb + eUxsFDCUQvbUrkYfNoxuZn8IPSG2eXXBOVcpCO/vf9+ciCke4sZ7r7FrrK0xZiisdfc7B81iEiJWUel2 + TjetRYVROELwrlHQIgCNs935XqNjSq6mh8OkCfeuRe8xhXkxubW2B6g2TwuCLxrhTAAwpZuGwBiS50Tj + xcQka4dlrb/ph/2P6BO0v2/wIsEPZwAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAW9JREFUOE+tU6F2 + AjEQ5BP6CXzCSWQkMhIZSVUjkZHIk8hIZCQyEteTlZGVkbjtzB5w4Upr2n1vHu9dMrMzu2Gx+I9KpyqK + dMWxSozAoUjfX7EvEgKwG8QTfpB7bxJzFlyWX6teROwmi9skxXeBff1RgORaqxibpeschBqBCMt0QIvP + 6kYun1U6mxCjiLVxcsC8FPA4mFdLHj4gsE6a/1EAw1IBHLQ1J+ehyNJEcduZACdNAR7c6hk5n4u8rCDg + sth1P0XosaJ8EqwSIg7qvIBp68CQmbbZ+U7mWSvA4aUEASBGrrNKwEbGvReN5uFOO4NsIfoogIeRjhPZ + bjwuNnAe8UJDhoAJUwS+rLYzyXgk0hkjnPxQqrhdQFd2JjnOBGAxHvAOrrYpQLLf9VJA5v596PGNxDj+ + rloHyKe5kXnJgXUGA82KnAfJZ67NKlGBTZiVuhzr7fXdui0HlPSB3IFJc1gKZGbXEXDYCvzlH/0F0FE7 + DNsH26sAAAAASUVORK5CYII= + + + + 371, 17 + + + 70 + + \ No newline at end of file diff --git a/src/Kalman.Studio/CodeBuilder/BatchBuildCustomCode.cs b/src/Kalman.Studio/CodeBuilder/BatchBuildCustomCode.cs new file mode 100644 index 0000000..6c858f0 --- /dev/null +++ b/src/Kalman.Studio/CodeBuilder/BatchBuildCustomCode.cs @@ -0,0 +1,477 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using WeifenLuo.WinFormsUI.Docking; +using System.IO; +using System.Net.Mail; +using System.Net; +using System.Diagnostics; +using System.CodeDom.Compiler; +using Kalman.Extensions; +using Kalman.Data.SchemaObject; +using Kalman.Utilities; +using Kalman.Studio.T4TemplateEngineHost; +using Microsoft.VisualStudio.TextTemplating; + +namespace Kalman.Studio +{ + public partial class BatchBuildCustomCode : Form + { + SODatabase currentDatabase; + string templatePath = Path.Combine(Application.StartupPath, "T4Template"); + + public BatchBuildCustomCode(SODatabase db) + { + InitializeComponent(); + currentDatabase = db; + } + + private void BatchBuildCustomCode_Load(object sender, EventArgs e) + { + cbSchema.SelectedIndex = 0; + List tableList = DbSchemaHelper.Instance.CurrentSchema.GetTableList(currentDatabase); + gbTableSelect.Text = string.Format("当前数据库[{0}]", currentDatabase); + + foreach (SOTable t in tableList) + { + listBox1.Items.Add(t); + } + + folderBrowserDialog1.RootFolder = Environment.SpecialFolder.MyComputer; + openFileDialog1.InitialDirectory = templatePath; + txtOutputPath.Text = Path.Combine(Application.StartupPath, "Output\\CustomCode"); + } + + //选择模板文件 + private void btnSelectTemplate_Click(object sender, EventArgs e) + { + if (openFileDialog1.ShowDialog() == DialogResult.OK) + { + txtTemplateFile.Text = openFileDialog1.FileName; + } + } + + //预览模板 + private void btnPreview_Click(object sender, EventArgs e) + { + string fileName = txtTemplateFile.Text; + + if (File.Exists(fileName)) + { + PreviewFile pf = new PreviewFile(fileName, CodeType.CSHARP); + pf.ShowDialog(); + } + else + { + MessageBox.Show(string.Format("文件[{0}]不存在",fileName)); + } + } + + private void btnReturn_Click(object sender, EventArgs e) + { + this.Close(); + } + + private void btnBrowser_Click(object sender, EventArgs e) + { + DialogResult result = folderBrowserDialog1.ShowDialog(); + if (result == DialogResult.OK) + { + txtOutputPath.Text = folderBrowserDialog1.SelectedPath; + } + } + + //处理窗体关闭事件 + protected override void OnClosing(CancelEventArgs e) + { + if (backgroundWorker1.IsBusy == false) + { + base.OnClosing(e); + } + else + { + e.Cancel = true; + MessageBox.Show("正在生成代码,请不要关闭窗口"); + } + } + + private void btnAddProperty_Click(object sender, EventArgs e) + { + string name = txtPName.Text.Trim(); + string value = txtPValue.Text.Trim().Replace("|", "[<->]"); + + if (name == "" || value == "") return; + + string item = string.Format("{0}|{1}", name, value); + if (listBox3.Items.Contains(item)) return; + listBox3.Items.Add(item); + txtPName.Text = string.Empty; + txtPValue.Text = string.Empty; + } + + private void btnRemoveProperty_Click(object sender, EventArgs e) + { + listBox3.Items.Remove(listBox3.SelectedItem); + } + + private void listBox3_DoubleClick(object sender, EventArgs e) + { + if(listBox3.SelectedItem == null)return; + + string[] ss = listBox3.SelectedItem.ToString().Split('|'); + txtPName.Text = ss[0]; + txtPValue.Text = ss[1].Replace("[<->]", "|"); + listBox3.Items.Remove(listBox3.SelectedItem); + } + + #region 列表选择相关 + private void cbSchema_SelectedIndexChanged(object sender, EventArgs e) + { + listBox1.Items.Clear(); + listBox2.Items.Clear(); + if (cbSchema.SelectedIndex == 0) + { + List list = DbSchemaHelper.Instance.CurrentSchema.GetTableList(currentDatabase); + foreach (SOTable t in list) + { + listBox1.Items.Add(t); + } + } + if (cbSchema.SelectedIndex == 1) + { + List list = DbSchemaHelper.Instance.CurrentSchema.GetViewList(currentDatabase); + foreach (SOView v in list) + { + listBox1.Items.Add(v); + } + } + if (cbSchema.SelectedIndex == 2) + { + List list = DbSchemaHelper.Instance.CurrentSchema.GetCommandList(currentDatabase); + foreach (SOCommand sp in list) + { + listBox1.Items.Add(sp); + } + } + } + + private void listBox1_MouseDoubleClick(object sender, MouseEventArgs e) + { + SelectOne(); + } + + private void listBox2_MouseDoubleClick(object sender, MouseEventArgs e) + { + RemoveOne(); + } + + private void btnSelectAll_Click(object sender, EventArgs e) + { + SelectAll(); + } + private void btnSelectOne_Click(object sender, EventArgs e) + { + SelectOne(); + } + private void btnRemoveOne_Click(object sender, EventArgs e) + { + RemoveOne(); + } + private void btnRemoveAll_Click(object sender, EventArgs e) + { + RemoveAll(); + } + + private void SelectAll() + { + if (backgroundWorker1.IsBusy) return; + if (listBox1.Items.Count > 0) + { + listBox2.Items.AddRange(listBox1.Items); + listBox1.Items.Clear(); + } + } + + private void SelectOne() + { + if (backgroundWorker1.IsBusy) return; + object[] items = new object[listBox1.SelectedItems.Count]; + listBox1.SelectedItems.CopyTo(items, 0); + listBox2.Items.AddRange(items); + + foreach (var item in items) + { + listBox1.Items.Remove(item); + } + } + + private void RemoveOne() + { + if (backgroundWorker1.IsBusy) return; + object[] items = new object[listBox2.SelectedItems.Count]; + listBox2.SelectedItems.CopyTo(items, 0); + listBox1.Items.AddRange(items); + + foreach (var item in items) + { + listBox2.Items.Remove(item); + } + } + + private void RemoveAll() + { + if (backgroundWorker1.IsBusy) return; + if (listBox2.Items.Count > 0) + { + listBox1.Items.AddRange(listBox2.Items); + listBox2.Items.Clear(); + } + } + #endregion + + #region 代码生成相关 + string templateFile = string.Empty; + string outputPath = string.Empty; + + private void btnBuildCode_Click(object sender, EventArgs e) + { + outputPath = txtOutputPath.Text; + + if (listBox2.Items.Count == 0) return; + + templateFile = txtTemplateFile.Text; + if (File.Exists(templateFile) == false) + { + MessageBox.Show("所选的模板文件不存在"); + return; + } + + btnBuildCode.Enabled = false; + cbSchema.Enabled = false; + backgroundWorker1.RunWorkerAsync(cbSchema.SelectedIndex); + } + + private void DoBuild(int selectedIndex) + { + int finish = 0; + int total = listBox2.Items.Count; + + //遍历选中的表,一张表对应生成一个代码文件 + foreach (object item in listBox2.Items) + { + switch (selectedIndex) + { + case 0: + BuildCodeByTableSchema(item); + break; + case 1: + BuildCodeByViewSchema(item); + break; + case 2: + BuildCodeBySPSchema(item); + break; + default: + break; + } + + finish = finish + 1; + int percent = ConvertUtil.ToInt32(finish * 100 / total, 0); + + backgroundWorker1.ReportProgress(percent, item); + }//end build code foreach + } + + private void BuildCodeByTableSchema(object item) + { + SOTable table = item as SOTable; + List columnList = table.ColumnList;//可能传入的是从PDObject对象转换过来的SODatabase对象 + if (columnList == null || columnList.Count == 0) columnList = DbSchemaHelper.Instance.CurrentSchema.GetTableColumnList(table); + + //生成代码文件 + TableHost host = new TableHost(); + host.Table = table; + host.ColumnList = columnList; + host.TemplateFile = templateFile; + + foreach (object obj in listBox3.Items) + { + string[] ss = obj.ToString().Split('|'); + + host.SetValue(ss[0], ss[1].Replace("[<->]", "|")); + } + + Engine engine = new Engine(); + + string fileName = string.Empty; + string separator = txtFileNamePrefix.Text.Trim(); + if (separator != "") + { + fileName = string.Format("{0}{1}", table.Name.RemovePrefix(separator,10), host.FileExtention); + } + else + { + fileName = string.Format("{0}{1}", table.Name, host.FileExtention); + } + + string outputContent = engine.ProcessTemplate(File.ReadAllText(templateFile), host); + string outputFile = Path.Combine(outputPath, fileName); + + StringBuilder sb = new StringBuilder(); + if (host.ErrorCollection.HasErrors) + { + foreach (CompilerError err in host.ErrorCollection) + { + sb.AppendLine(err.ToString()); + } + outputContent = outputContent + Environment.NewLine + sb.ToString(); + outputFile = outputFile + ".error"; + } + + if (Directory.Exists(outputPath) == false) Directory.CreateDirectory(outputPath); + File.WriteAllText(outputFile, outputContent, Encoding.UTF8); + } + + private void BuildCodeByViewSchema(object item) + { + SOView view = item as SOView; + List columnList = DbSchemaHelper.Instance.CurrentSchema.GetViewColumnList(view); + + //生成代码文件 + ViewHost host = new ViewHost(); + host.View = view; + host.ColumnList = columnList; + host.TemplateFile = templateFile; + + foreach (object obj in listBox3.Items) + { + string[] ss = obj.ToString().Split('|'); + + host.SetValue(ss[0], ss[1].Replace("[<->]", "|")); + } + + Engine engine = new Engine(); + + string fileName = string.Empty; + string separator = txtFileNamePrefix.Text.Trim(); + if (separator != "") + { + fileName = string.Format("{0}{1}", view.Name.RemovePrefix(separator, 10), host.FileExtention); + } + else + { + fileName = string.Format("{0}{1}", view.Name, host.FileExtention); + } + + string outputContent = engine.ProcessTemplate(File.ReadAllText(templateFile), host); + string outputFile = Path.Combine(outputPath, fileName); + + StringBuilder sb = new StringBuilder(); + if (host.ErrorCollection.HasErrors) + { + foreach (CompilerError err in host.ErrorCollection) + { + sb.AppendLine(err.ToString()); + } + outputContent = outputContent + Environment.NewLine + sb.ToString(); + outputFile = outputFile + ".error"; + } + + if (Directory.Exists(outputPath) == false) Directory.CreateDirectory(outputPath); + File.WriteAllText(outputFile, outputContent, Encoding.UTF8); + } + + private void BuildCodeBySPSchema(object item) + { + SOCommand sp = item as SOCommand; + //List paramList = DbSchemaHelper.Instance.CurrentSchema.GetCommandParameterList(sp); + + //生成代码文件 + CommandHost host = new CommandHost(); + host.SP = sp; + //host.ParamList = paramList; + host.TemplateFile = templateFile; + + foreach (object obj in listBox3.Items) + { + string[] ss = obj.ToString().Split('|'); + + host.SetValue(ss[0], ss[1].Replace("[<->]", "|")); + } + + Engine engine = new Engine(); + + string fileName = string.Empty; + string separator = txtFileNamePrefix.Text.Trim(); + if (separator != "") + { + fileName = string.Format("{0}{1}", sp.Name.RemovePrefix(separator, 10), host.FileExtention); + } + else + { + fileName = string.Format("{0}{1}", sp.Name, host.FileExtention); + } + + string outputContent = engine.ProcessTemplate(File.ReadAllText(templateFile), host); + string outputFile = Path.Combine(outputPath, fileName); + + StringBuilder sb = new StringBuilder(); + if (host.ErrorCollection.HasErrors) + { + foreach (CompilerError err in host.ErrorCollection) + { + sb.AppendLine(err.ToString()); + } + outputContent = outputContent + Environment.NewLine + sb.ToString(); + outputFile = outputFile + ".error"; + } + + if (Directory.Exists(outputPath) == false) Directory.CreateDirectory(outputPath); + File.WriteAllText(outputFile, outputContent, Encoding.UTF8); + } + + private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) + { + int selectedIndex = ConvertUtil.ToInt32(e.Argument,0); + DoBuild(selectedIndex); + } + + private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) + { + progressBar1.Value = e.ProgressPercentage; + + if (e.ProgressPercentage == 100) + { + lblMsg.Text = "代码已全部生成"; + } + else + { + //SOTable dbTable = e.UserState as SOTable; + lblMsg.Text = string.Format("已完成:{0}%,正在处理:{1}", e.ProgressPercentage, e.UserState.ToString()); + } + } + + private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) + { + DialogResult result = MessageBox.Show("代码生成成功,是否打开输出目录", "代码生成消息提示", MessageBoxButtons.YesNo, MessageBoxIcon.Information); + if (result == DialogResult.Yes) + { + string cmd = "explorer.exe " + outputPath; + Kalman.Command.CmdHelper.Execute(cmd); + } + btnBuildCode.Enabled = true; + cbSchema.Enabled = true; + } + #endregion + + + + + + + } +} diff --git a/src/Kalman.Studio/CodeBuilder/BatchBuildCustomCode.designer.cs b/src/Kalman.Studio/CodeBuilder/BatchBuildCustomCode.designer.cs new file mode 100644 index 0000000..da016b0 --- /dev/null +++ b/src/Kalman.Studio/CodeBuilder/BatchBuildCustomCode.designer.cs @@ -0,0 +1,474 @@ +namespace Kalman.Studio +{ + partial class BatchBuildCustomCode + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.listBox1 = new System.Windows.Forms.ListBox(); + this.gbTableSelect = new System.Windows.Forms.GroupBox(); + this.cbSchema = new System.Windows.Forms.ComboBox(); + this.label1 = new System.Windows.Forms.Label(); + this.btnRemoveOne = new System.Windows.Forms.Button(); + this.btnRemoveAll = new System.Windows.Forms.Button(); + this.btnSelectOne = new System.Windows.Forms.Button(); + this.listBox2 = new System.Windows.Forms.ListBox(); + this.btnSelectAll = new System.Windows.Forms.Button(); + this.btnPreview = new System.Windows.Forms.Button(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.btnSelectTemplate = new System.Windows.Forms.Button(); + this.txtTemplateFile = new System.Windows.Forms.TextBox(); + this.label8 = new System.Windows.Forms.Label(); + this.label7 = new System.Windows.Forms.Label(); + this.txtFileNamePrefix = new System.Windows.Forms.TextBox(); + this.label6 = new System.Windows.Forms.Label(); + this.btnRemoveProperty = new System.Windows.Forms.Button(); + this.btnAddProperty = new System.Windows.Forms.Button(); + this.listBox3 = new System.Windows.Forms.ListBox(); + this.txtPValue = new System.Windows.Forms.TextBox(); + this.txtPName = new System.Windows.Forms.TextBox(); + this.label3 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.lblMsg = new System.Windows.Forms.Label(); + this.progressBar1 = new System.Windows.Forms.ProgressBar(); + this.btnReturn = new System.Windows.Forms.Button(); + this.btnBuildCode = new System.Windows.Forms.Button(); + this.btnBrowser = new System.Windows.Forms.Button(); + this.txtOutputPath = new System.Windows.Forms.TextBox(); + this.label5 = new System.Windows.Forms.Label(); + this.folderBrowserDialog1 = new System.Windows.Forms.FolderBrowserDialog(); + this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker(); + this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog(); + this.gbTableSelect.SuspendLayout(); + this.groupBox1.SuspendLayout(); + this.SuspendLayout(); + // + // listBox1 + // + this.listBox1.FormattingEnabled = true; + this.listBox1.ItemHeight = 12; + this.listBox1.Location = new System.Drawing.Point(11, 41); + this.listBox1.Name = "listBox1"; + this.listBox1.SelectionMode = System.Windows.Forms.SelectionMode.MultiExtended; + this.listBox1.Size = new System.Drawing.Size(240, 172); + this.listBox1.TabIndex = 0; + this.listBox1.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.listBox1_MouseDoubleClick); + // + // gbTableSelect + // + this.gbTableSelect.Controls.Add(this.cbSchema); + this.gbTableSelect.Controls.Add(this.label1); + this.gbTableSelect.Controls.Add(this.btnRemoveOne); + this.gbTableSelect.Controls.Add(this.btnRemoveAll); + this.gbTableSelect.Controls.Add(this.btnSelectOne); + this.gbTableSelect.Controls.Add(this.listBox2); + this.gbTableSelect.Controls.Add(this.btnSelectAll); + this.gbTableSelect.Controls.Add(this.listBox1); + this.gbTableSelect.Dock = System.Windows.Forms.DockStyle.Top; + this.gbTableSelect.Location = new System.Drawing.Point(0, 0); + this.gbTableSelect.Margin = new System.Windows.Forms.Padding(10); + this.gbTableSelect.Name = "gbTableSelect"; + this.gbTableSelect.Padding = new System.Windows.Forms.Padding(10); + this.gbTableSelect.Size = new System.Drawing.Size(592, 221); + this.gbTableSelect.TabIndex = 1; + this.gbTableSelect.TabStop = false; + this.gbTableSelect.Text = "选择架构和模板"; + // + // cbSchema + // + this.cbSchema.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.cbSchema.FormattingEnabled = true; + this.cbSchema.Items.AddRange(new object[] { + "基于表架构代码生成", + "基于视图架构代码生成", + "基于存储过程架构代码生成"}); + this.cbSchema.Location = new System.Drawing.Point(68, 16); + this.cbSchema.Name = "cbSchema"; + this.cbSchema.Size = new System.Drawing.Size(183, 20); + this.cbSchema.TabIndex = 11; + this.cbSchema.SelectedIndexChanged += new System.EventHandler(this.cbSchema_SelectedIndexChanged); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(9, 20); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(53, 12); + this.label1.TabIndex = 10; + this.label1.Text = "选择架构"; + // + // btnRemoveOne + // + this.btnRemoveOne.FlatStyle = System.Windows.Forms.FlatStyle.Popup; + this.btnRemoveOne.Location = new System.Drawing.Point(270, 134); + this.btnRemoveOne.Name = "btnRemoveOne"; + this.btnRemoveOne.Size = new System.Drawing.Size(50, 25); + this.btnRemoveOne.TabIndex = 9; + this.btnRemoveOne.Text = "<"; + this.btnRemoveOne.UseVisualStyleBackColor = true; + this.btnRemoveOne.Click += new System.EventHandler(this.btnRemoveOne_Click); + // + // btnRemoveAll + // + this.btnRemoveAll.FlatStyle = System.Windows.Forms.FlatStyle.Popup; + this.btnRemoveAll.Location = new System.Drawing.Point(270, 176); + this.btnRemoveAll.Name = "btnRemoveAll"; + this.btnRemoveAll.Size = new System.Drawing.Size(50, 25); + this.btnRemoveAll.TabIndex = 8; + this.btnRemoveAll.Text = "<<"; + this.btnRemoveAll.UseVisualStyleBackColor = true; + this.btnRemoveAll.Click += new System.EventHandler(this.btnRemoveAll_Click); + // + // btnSelectOne + // + this.btnSelectOne.FlatStyle = System.Windows.Forms.FlatStyle.Popup; + this.btnSelectOne.Location = new System.Drawing.Point(270, 92); + this.btnSelectOne.Name = "btnSelectOne"; + this.btnSelectOne.Size = new System.Drawing.Size(50, 25); + this.btnSelectOne.TabIndex = 7; + this.btnSelectOne.Text = ">"; + this.btnSelectOne.UseVisualStyleBackColor = true; + this.btnSelectOne.Click += new System.EventHandler(this.btnSelectOne_Click); + // + // listBox2 + // + this.listBox2.FormattingEnabled = true; + this.listBox2.ItemHeight = 12; + this.listBox2.Location = new System.Drawing.Point(339, 41); + this.listBox2.Name = "listBox2"; + this.listBox2.SelectionMode = System.Windows.Forms.SelectionMode.MultiExtended; + this.listBox2.Size = new System.Drawing.Size(240, 172); + this.listBox2.TabIndex = 6; + this.listBox2.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.listBox2_MouseDoubleClick); + // + // btnSelectAll + // + this.btnSelectAll.FlatStyle = System.Windows.Forms.FlatStyle.Popup; + this.btnSelectAll.Location = new System.Drawing.Point(270, 50); + this.btnSelectAll.Name = "btnSelectAll"; + this.btnSelectAll.Size = new System.Drawing.Size(50, 25); + this.btnSelectAll.TabIndex = 2; + this.btnSelectAll.Text = ">>"; + this.btnSelectAll.UseVisualStyleBackColor = true; + this.btnSelectAll.Click += new System.EventHandler(this.btnSelectAll_Click); + // + // btnPreview + // + this.btnPreview.Location = new System.Drawing.Point(519, 16); + this.btnPreview.Name = "btnPreview"; + this.btnPreview.Size = new System.Drawing.Size(62, 23); + this.btnPreview.TabIndex = 22; + this.btnPreview.Text = "预览"; + this.btnPreview.UseVisualStyleBackColor = true; + this.btnPreview.Click += new System.EventHandler(this.btnPreview_Click); + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.btnSelectTemplate); + this.groupBox1.Controls.Add(this.btnPreview); + this.groupBox1.Controls.Add(this.txtTemplateFile); + this.groupBox1.Controls.Add(this.label8); + this.groupBox1.Controls.Add(this.label7); + this.groupBox1.Controls.Add(this.txtFileNamePrefix); + this.groupBox1.Controls.Add(this.label6); + this.groupBox1.Controls.Add(this.btnRemoveProperty); + this.groupBox1.Controls.Add(this.btnAddProperty); + this.groupBox1.Controls.Add(this.listBox3); + this.groupBox1.Controls.Add(this.txtPValue); + this.groupBox1.Controls.Add(this.txtPName); + this.groupBox1.Controls.Add(this.label3); + this.groupBox1.Controls.Add(this.label2); + this.groupBox1.Controls.Add(this.lblMsg); + this.groupBox1.Controls.Add(this.progressBar1); + this.groupBox1.Controls.Add(this.btnReturn); + this.groupBox1.Controls.Add(this.btnBuildCode); + this.groupBox1.Controls.Add(this.btnBrowser); + this.groupBox1.Controls.Add(this.txtOutputPath); + this.groupBox1.Controls.Add(this.label5); + this.groupBox1.Dock = System.Windows.Forms.DockStyle.Fill; + this.groupBox1.Location = new System.Drawing.Point(0, 221); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(592, 316); + this.groupBox1.TabIndex = 10; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "参数设置"; + // + // btnSelectTemplate + // + this.btnSelectTemplate.Location = new System.Drawing.Point(450, 16); + this.btnSelectTemplate.Name = "btnSelectTemplate"; + this.btnSelectTemplate.Size = new System.Drawing.Size(62, 23); + this.btnSelectTemplate.TabIndex = 34; + this.btnSelectTemplate.Text = "浏览..."; + this.btnSelectTemplate.UseVisualStyleBackColor = true; + this.btnSelectTemplate.Click += new System.EventHandler(this.btnSelectTemplate_Click); + // + // txtTemplateFile + // + this.txtTemplateFile.Location = new System.Drawing.Point(92, 17); + this.txtTemplateFile.Name = "txtTemplateFile"; + this.txtTemplateFile.Size = new System.Drawing.Size(352, 21); + this.txtTemplateFile.TabIndex = 33; + // + // label8 + // + this.label8.AutoSize = true; + this.label8.Location = new System.Drawing.Point(9, 21); + this.label8.Name = "label8"; + this.label8.Size = new System.Drawing.Size(53, 12); + this.label8.TabIndex = 32; + this.label8.Text = "选择模板"; + // + // label7 + // + this.label7.AutoSize = true; + this.label7.ForeColor = System.Drawing.Color.Red; + this.label7.Location = new System.Drawing.Point(134, 201); + this.label7.Name = "label7"; + this.label7.Size = new System.Drawing.Size(311, 12); + this.label7.TabIndex = 31; + this.label7.Text = "输入要移除的文件名前缀分隔符,如\"_\",若为空则不处理"; + // + // txtFileNamePrefix + // + this.txtFileNamePrefix.Location = new System.Drawing.Point(92, 197); + this.txtFileNamePrefix.Name = "txtFileNamePrefix"; + this.txtFileNamePrefix.Size = new System.Drawing.Size(36, 21); + this.txtFileNamePrefix.TabIndex = 30; + // + // label6 + // + this.label6.AutoSize = true; + this.label6.Location = new System.Drawing.Point(9, 201); + this.label6.Name = "label6"; + this.label6.Size = new System.Drawing.Size(65, 12); + this.label6.TabIndex = 29; + this.label6.Text = "文件名前缀"; + // + // btnRemoveProperty + // + this.btnRemoveProperty.FlatStyle = System.Windows.Forms.FlatStyle.Popup; + this.btnRemoveProperty.Location = new System.Drawing.Point(270, 126); + this.btnRemoveProperty.Name = "btnRemoveProperty"; + this.btnRemoveProperty.Size = new System.Drawing.Size(50, 25); + this.btnRemoveProperty.TabIndex = 28; + this.btnRemoveProperty.Text = "<"; + this.btnRemoveProperty.UseVisualStyleBackColor = true; + this.btnRemoveProperty.Click += new System.EventHandler(this.btnRemoveProperty_Click); + // + // btnAddProperty + // + this.btnAddProperty.FlatStyle = System.Windows.Forms.FlatStyle.Popup; + this.btnAddProperty.Location = new System.Drawing.Point(270, 70); + this.btnAddProperty.Name = "btnAddProperty"; + this.btnAddProperty.Size = new System.Drawing.Size(50, 25); + this.btnAddProperty.TabIndex = 27; + this.btnAddProperty.Text = ">"; + this.btnAddProperty.UseVisualStyleBackColor = true; + this.btnAddProperty.Click += new System.EventHandler(this.btnAddProperty_Click); + // + // listBox3 + // + this.listBox3.FormattingEnabled = true; + this.listBox3.ItemHeight = 12; + this.listBox3.Location = new System.Drawing.Point(341, 45); + this.listBox3.Name = "listBox3"; + this.listBox3.SelectionMode = System.Windows.Forms.SelectionMode.MultiExtended; + this.listBox3.Size = new System.Drawing.Size(240, 136); + this.listBox3.TabIndex = 26; + this.listBox3.DoubleClick += new System.EventHandler(this.listBox3_DoubleClick); + // + // txtPValue + // + this.txtPValue.Location = new System.Drawing.Point(92, 73); + this.txtPValue.Multiline = true; + this.txtPValue.Name = "txtPValue"; + this.txtPValue.Size = new System.Drawing.Size(159, 114); + this.txtPValue.TabIndex = 25; + // + // txtPName + // + this.txtPName.Location = new System.Drawing.Point(92, 45); + this.txtPName.Name = "txtPName"; + this.txtPName.Size = new System.Drawing.Size(159, 21); + this.txtPName.TabIndex = 24; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(9, 77); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(65, 12); + this.label3.TabIndex = 23; + this.label3.Text = "扩展属性值"; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(9, 49); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(65, 12); + this.label2.TabIndex = 22; + this.label2.Text = "扩展属性名"; + // + // lblMsg + // + this.lblMsg.AutoSize = true; + this.lblMsg.ForeColor = System.Drawing.Color.Red; + this.lblMsg.Location = new System.Drawing.Point(13, 272); + this.lblMsg.Name = "lblMsg"; + this.lblMsg.Size = new System.Drawing.Size(101, 12); + this.lblMsg.TabIndex = 21; + this.lblMsg.Text = "代码生成进度显示"; + // + // progressBar1 + // + this.progressBar1.ForeColor = System.Drawing.Color.ForestGreen; + this.progressBar1.Location = new System.Drawing.Point(11, 292); + this.progressBar1.Name = "progressBar1"; + this.progressBar1.Size = new System.Drawing.Size(570, 18); + this.progressBar1.Step = 2; + this.progressBar1.TabIndex = 20; + // + // btnReturn + // + this.btnReturn.Location = new System.Drawing.Point(506, 261); + this.btnReturn.Name = "btnReturn"; + this.btnReturn.Size = new System.Drawing.Size(75, 23); + this.btnReturn.TabIndex = 19; + this.btnReturn.Text = "返回"; + this.btnReturn.UseVisualStyleBackColor = true; + this.btnReturn.Click += new System.EventHandler(this.btnReturn_Click); + // + // btnBuildCode + // + this.btnBuildCode.Location = new System.Drawing.Point(394, 261); + this.btnBuildCode.Name = "btnBuildCode"; + this.btnBuildCode.Size = new System.Drawing.Size(75, 23); + this.btnBuildCode.TabIndex = 18; + this.btnBuildCode.Text = "生成代码"; + this.btnBuildCode.UseVisualStyleBackColor = true; + this.btnBuildCode.Click += new System.EventHandler(this.btnBuildCode_Click); + // + // btnBrowser + // + this.btnBrowser.Location = new System.Drawing.Point(518, 226); + this.btnBrowser.Name = "btnBrowser"; + this.btnBrowser.Size = new System.Drawing.Size(62, 23); + this.btnBrowser.TabIndex = 12; + this.btnBrowser.Text = "浏览..."; + this.btnBrowser.UseVisualStyleBackColor = true; + this.btnBrowser.Click += new System.EventHandler(this.btnBrowser_Click); + // + // txtOutputPath + // + this.txtOutputPath.Location = new System.Drawing.Point(92, 227); + this.txtOutputPath.Name = "txtOutputPath"; + this.txtOutputPath.Size = new System.Drawing.Size(420, 21); + this.txtOutputPath.TabIndex = 11; + // + // label5 + // + this.label5.AutoSize = true; + this.label5.Location = new System.Drawing.Point(9, 231); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(77, 12); + this.label5.TabIndex = 10; + this.label5.Text = "代码输出目录"; + // + // backgroundWorker1 + // + this.backgroundWorker1.WorkerReportsProgress = true; + this.backgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker1_DoWork); + this.backgroundWorker1.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted); + this.backgroundWorker1.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.backgroundWorker1_ProgressChanged); + // + // openFileDialog1 + // + this.openFileDialog1.Filter = "T4模板|*.tt|所有文件|*.*"; + // + // BatchBuildCustomCode + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(592, 537); + this.Controls.Add(this.groupBox1); + this.Controls.Add(this.gbTableSelect); + this.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.MaximizeBox = false; + this.MaximumSize = new System.Drawing.Size(600, 564); + this.MinimumSize = new System.Drawing.Size(600, 564); + this.Name = "BatchBuildCustomCode"; + this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "批量生成代码"; + this.Load += new System.EventHandler(this.BatchBuildCustomCode_Load); + this.gbTableSelect.ResumeLayout(false); + this.gbTableSelect.PerformLayout(); + this.groupBox1.ResumeLayout(false); + this.groupBox1.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Button btnPreview; + private System.Windows.Forms.Label lblMsg; + private System.Windows.Forms.ProgressBar progressBar1; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.Button btnReturn; + private System.Windows.Forms.Button btnBuildCode; + private System.Windows.Forms.Button btnBrowser; + private System.Windows.Forms.TextBox txtOutputPath; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.FolderBrowserDialog folderBrowserDialog1; + private System.Windows.Forms.Button btnRemoveOne; + private System.Windows.Forms.Button btnRemoveAll; + private System.Windows.Forms.Button btnSelectOne; + private System.Windows.Forms.ListBox listBox2; + private System.Windows.Forms.GroupBox gbTableSelect; + private System.Windows.Forms.Button btnSelectAll; + private System.Windows.Forms.ListBox listBox1; + private System.ComponentModel.BackgroundWorker backgroundWorker1; + private System.Windows.Forms.ComboBox cbSchema; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.TextBox txtPValue; + private System.Windows.Forms.TextBox txtPName; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Button btnAddProperty; + private System.Windows.Forms.ListBox listBox3; + private System.Windows.Forms.Button btnRemoveProperty; + private System.Windows.Forms.Label label7; + private System.Windows.Forms.TextBox txtFileNamePrefix; + private System.Windows.Forms.Label label6; + private System.Windows.Forms.TextBox txtTemplateFile; + private System.Windows.Forms.Label label8; + private System.Windows.Forms.Button btnSelectTemplate; + private System.Windows.Forms.OpenFileDialog openFileDialog1; + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/CodeBuilder/BatchBuildCustomCode.resx b/src/Kalman.Studio/CodeBuilder/BatchBuildCustomCode.resx new file mode 100644 index 0000000..c9884f2 --- /dev/null +++ b/src/Kalman.Studio/CodeBuilder/BatchBuildCustomCode.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + 192, 17 + + + 349, 17 + + \ No newline at end of file diff --git a/src/Kalman.Studio/CodeBuilder/BatchBuildDALCode.cs b/src/Kalman.Studio/CodeBuilder/BatchBuildDALCode.cs new file mode 100644 index 0000000..36c9e96 --- /dev/null +++ b/src/Kalman.Studio/CodeBuilder/BatchBuildDALCode.cs @@ -0,0 +1,276 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using WeifenLuo.WinFormsUI.Docking; +using Microsoft.VisualStudio.TextTemplating; +using Kalman.Studio.T4TemplateEngineHost; +using System.IO; +using System.Net.Mail; +using System.Net; +using System.Diagnostics; +using System.CodeDom.Compiler; +using Kalman.Extensions; +using Kalman.Data.SchemaObject; +using Kalman.Utilities; + +namespace Kalman.Studio +{ + public partial class BatchBuildDALCode : Form + { + SODatabase currentDatabase; + List tableList = new List(); + string templatePath = Path.Combine(Application.StartupPath, "T4Template\\DAL"); + + public BatchBuildDALCode(SODatabase db) + { + InitializeComponent(); + currentDatabase = db; + tableList = db.TableList; + } + + private void BatchBuildDALCode_Load(object sender, EventArgs e) + { + gbTableSelect.Text = string.Format("当前数据库[{0}]", currentDatabase); + + foreach (SOTable t in tableList) + { + listBox1.Items.Add(t); + } + + string[] ss = Directory.GetFiles(templatePath, "*.tt"); + foreach (string s in ss) + { + cbTemplate.Items.Add(Path.GetFileName(s)); + } + if (ss.Length > 0) cbTemplate.SelectedIndex = 0; + + folderBrowserDialog1.RootFolder = Environment.SpecialFolder.MyComputer; + txtOutputPath.Text = Path.Combine(Application.StartupPath, "Output\\DALCode"); + } + + //预览模板 + private void btnPreview_Click(object sender, EventArgs e) + { + if (cbTemplate.SelectedItem == null) return; + string fileName = Path.Combine(templatePath, cbTemplate.SelectedItem.ToString()); + PreviewFile pf = new PreviewFile(fileName, CodeType.CSHARP); + pf.ShowDialog(); + } + + private void btnReturn_Click(object sender, EventArgs e) + { + this.Close(); + } + + private void btnBrowser_Click(object sender, EventArgs e) + { + DialogResult result = folderBrowserDialog1.ShowDialog(); + if (result == DialogResult.OK) + { + txtOutputPath.Text = folderBrowserDialog1.SelectedPath; + } + } + + //处理窗体关闭事件 + protected override void OnClosing(CancelEventArgs e) + { + if (backgroundWorker1.IsBusy == false) + { + base.OnClosing(e); + } + else + { + e.Cancel = true; + MessageBox.Show("正在生成代码,请不要关闭窗口"); + } + } + + #region 列表选择相关 + private void listBox1_MouseDoubleClick(object sender, MouseEventArgs e) + { + SelectOne(); + } + + private void listBox2_MouseDoubleClick(object sender, MouseEventArgs e) + { + RemoveOne(); + } + + private void btnSelectAll_Click(object sender, EventArgs e) + { + SelectAll(); + } + private void btnSelectOne_Click(object sender, EventArgs e) + { + SelectOne(); + } + private void btnRemoveOne_Click(object sender, EventArgs e) + { + RemoveOne(); + } + private void btnRemoveAll_Click(object sender, EventArgs e) + { + RemoveAll(); + } + + private void SelectAll() + { + if (backgroundWorker1.IsBusy) return; + if (listBox1.Items.Count > 0) + { + listBox2.Items.AddRange(listBox1.Items); + listBox1.Items.Clear(); + } + } + + private void SelectOne() + { + if (backgroundWorker1.IsBusy) return; + object[] items = new object[listBox1.SelectedItems.Count]; + listBox1.SelectedItems.CopyTo(items, 0); + listBox2.Items.AddRange(items); + + foreach (var item in items) + { + listBox1.Items.Remove(item); + } + } + + private void RemoveOne() + { + if (backgroundWorker1.IsBusy) return; + object[] items = new object[listBox2.SelectedItems.Count]; + listBox2.SelectedItems.CopyTo(items, 0); + listBox1.Items.AddRange(items); + + foreach (var item in items) + { + listBox2.Items.Remove(item); + } + } + + private void RemoveAll() + { + if (backgroundWorker1.IsBusy) return; + if (listBox2.Items.Count > 0) + { + listBox1.Items.AddRange(listBox2.Items); + listBox2.Items.Clear(); + } + } + #endregion + + #region 代码生成相关 + string nameSpace = "DAL"; + string tablePrefix = string.Empty; + string columnPrefix = string.Empty; + int prefixLevel = 1; + string templateFile = string.Empty; + string outputPath = string.Empty; + + private void btnBuildCode_Click(object sender, EventArgs e) + { + outputPath = txtOutputPath.Text; + if (txtNameSpace.Text.Trim() != "") nameSpace = txtNameSpace.Text.Trim(); + + if (listBox2.Items.Count == 0) return; + if (cbTemplate.SelectedItem == null) return; + templateFile = Path.Combine(templatePath, cbTemplate.SelectedItem.ToString()); + + if (txtTablePrefix.Text.Trim().Length > 0) tablePrefix = txtTablePrefix.Text.Trim(); + if (txtColumnPrefix.Text.Trim().Length > 0) columnPrefix = txtColumnPrefix.Text.Trim(); + prefixLevel = ConvertUtil.ToInt32(txtPrefixLevel.Text, 1); + + btnBuildCode.Enabled = false; + backgroundWorker1.RunWorkerAsync(); + } + + private void DoBuild() + { + int finish = 0; + int total = listBox2.Items.Count; + + //遍历选中的表,一张表对应生成一个代码文件 + foreach (object item in listBox2.Items) + { + SOTable table = item as SOTable; + string className = table.Name.RemovePrefix(tablePrefix, prefixLevel).Replace(" ", ""); + + List columnList = table.ColumnList;//可能传入的是从PDObject对象转换过来的SODatabase对象 + if (columnList == null || columnList.Count == 0) columnList = DbSchemaHelper.Instance.CurrentSchema.GetTableColumnList(table); + + //生成代码文件 + TableHost host = new TableHost(); + host.Table = table; + host.ColumnList = columnList; + host.TemplateFile = templateFile; + host.SetValue("NameSpace", nameSpace); + host.SetValue("ClassName", className); + host.SetValue("TablePrefix", tablePrefix); + host.SetValue("ColumnPrefix", columnPrefix); + host.SetValue("PrefixLevel", prefixLevel); + + Engine engine = new Engine(); + + string outputContent = engine.ProcessTemplate(File.ReadAllText(templateFile), host); + string outputFile = Path.Combine(outputPath, string.Format("{0}{1}", className,host.FileExtention)); + + StringBuilder sb = new StringBuilder(); + if (host.ErrorCollection.HasErrors) + { + foreach (CompilerError err in host.ErrorCollection) + { + sb.AppendLine(err.ToString()); + } + outputContent = outputContent + Environment.NewLine + sb.ToString(); + outputFile = outputFile + ".error"; + } + + if (Directory.Exists(outputPath) == false) Directory.CreateDirectory(outputPath); + File.WriteAllText(outputFile, outputContent, Encoding.UTF8); + + finish = finish + 1; + int percent = ConvertUtil.ToInt32(finish * 100 / total, 0); + + backgroundWorker1.ReportProgress(percent, table); + }//end build code foreach + } + + private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) + { + DoBuild(); + } + + private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) + { + progressBar1.Value = e.ProgressPercentage; + SOTable table = e.UserState as SOTable; + + if (e.ProgressPercentage == 100) + { + lblMsg.Text = "代码已全部生成"; + } + else + { + lblMsg.Text = string.Format("已完成:{0}%,正在处理:{1}", e.ProgressPercentage, table.Name); + } + } + + private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) + { + DialogResult result = MessageBox.Show("代码生成成功,是否打开输出目录", "代码生成消息提示", MessageBoxButtons.YesNo, MessageBoxIcon.Information); + if (result == DialogResult.Yes) + { + string cmd = "explorer.exe " + outputPath; + Kalman.Command.CmdHelper.Execute(cmd); + } + btnBuildCode.Enabled = true; + } + #endregion + } +} diff --git a/src/Kalman.Studio/CodeBuilder/BatchBuildDALCode.designer.cs b/src/Kalman.Studio/CodeBuilder/BatchBuildDALCode.designer.cs new file mode 100644 index 0000000..1877fb6 --- /dev/null +++ b/src/Kalman.Studio/CodeBuilder/BatchBuildDALCode.designer.cs @@ -0,0 +1,431 @@ +namespace Kalman.Studio +{ + partial class BatchBuildDALCode + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.listBox1 = new System.Windows.Forms.ListBox(); + this.gbTableSelect = new System.Windows.Forms.GroupBox(); + this.btnRemoveOne = new System.Windows.Forms.Button(); + this.btnRemoveAll = new System.Windows.Forms.Button(); + this.btnSelectOne = new System.Windows.Forms.Button(); + this.listBox2 = new System.Windows.Forms.ListBox(); + this.btnSelectAll = new System.Windows.Forms.Button(); + this.label1 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.label3 = new System.Windows.Forms.Label(); + this.txtTablePrefix = new System.Windows.Forms.TextBox(); + this.txtColumnPrefix = new System.Windows.Forms.TextBox(); + this.label4 = new System.Windows.Forms.Label(); + this.cbTemplate = new System.Windows.Forms.ComboBox(); + this.txtNameSpace = new System.Windows.Forms.TextBox(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.btnPreview = new System.Windows.Forms.Button(); + this.lblMsg = new System.Windows.Forms.Label(); + this.progressBar1 = new System.Windows.Forms.ProgressBar(); + this.btnReturn = new System.Windows.Forms.Button(); + this.btnBuildCode = new System.Windows.Forms.Button(); + this.label9 = new System.Windows.Forms.Label(); + this.txtPrefixLevel = new System.Windows.Forms.TextBox(); + this.label8 = new System.Windows.Forms.Label(); + this.label7 = new System.Windows.Forms.Label(); + this.label6 = new System.Windows.Forms.Label(); + this.btnBrowser = new System.Windows.Forms.Button(); + this.txtOutputPath = new System.Windows.Forms.TextBox(); + this.label5 = new System.Windows.Forms.Label(); + this.folderBrowserDialog1 = new System.Windows.Forms.FolderBrowserDialog(); + this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker(); + this.gbTableSelect.SuspendLayout(); + this.groupBox1.SuspendLayout(); + this.SuspendLayout(); + // + // listBox1 + // + this.listBox1.FormattingEnabled = true; + this.listBox1.ItemHeight = 12; + this.listBox1.Location = new System.Drawing.Point(12, 20); + this.listBox1.Name = "listBox1"; + this.listBox1.SelectionMode = System.Windows.Forms.SelectionMode.MultiExtended; + this.listBox1.Size = new System.Drawing.Size(240, 172); + this.listBox1.TabIndex = 0; + this.listBox1.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.listBox1_MouseDoubleClick); + // + // gbTableSelect + // + this.gbTableSelect.Controls.Add(this.btnRemoveOne); + this.gbTableSelect.Controls.Add(this.btnRemoveAll); + this.gbTableSelect.Controls.Add(this.btnSelectOne); + this.gbTableSelect.Controls.Add(this.listBox2); + this.gbTableSelect.Controls.Add(this.btnSelectAll); + this.gbTableSelect.Controls.Add(this.listBox1); + this.gbTableSelect.Dock = System.Windows.Forms.DockStyle.Top; + this.gbTableSelect.Location = new System.Drawing.Point(0, 0); + this.gbTableSelect.Margin = new System.Windows.Forms.Padding(10); + this.gbTableSelect.Name = "gbTableSelect"; + this.gbTableSelect.Padding = new System.Windows.Forms.Padding(10); + this.gbTableSelect.Size = new System.Drawing.Size(592, 207); + this.gbTableSelect.TabIndex = 1; + this.gbTableSelect.TabStop = false; + this.gbTableSelect.Text = "groupBox1"; + // + // btnRemoveOne + // + this.btnRemoveOne.FlatStyle = System.Windows.Forms.FlatStyle.Popup; + this.btnRemoveOne.Location = new System.Drawing.Point(271, 114); + this.btnRemoveOne.Name = "btnRemoveOne"; + this.btnRemoveOne.Size = new System.Drawing.Size(50, 25); + this.btnRemoveOne.TabIndex = 9; + this.btnRemoveOne.Text = "<"; + this.btnRemoveOne.UseVisualStyleBackColor = true; + this.btnRemoveOne.Click += new System.EventHandler(this.btnRemoveOne_Click); + // + // btnRemoveAll + // + this.btnRemoveAll.FlatStyle = System.Windows.Forms.FlatStyle.Popup; + this.btnRemoveAll.Location = new System.Drawing.Point(271, 156); + this.btnRemoveAll.Name = "btnRemoveAll"; + this.btnRemoveAll.Size = new System.Drawing.Size(50, 25); + this.btnRemoveAll.TabIndex = 8; + this.btnRemoveAll.Text = "<<"; + this.btnRemoveAll.UseVisualStyleBackColor = true; + this.btnRemoveAll.Click += new System.EventHandler(this.btnRemoveAll_Click); + // + // btnSelectOne + // + this.btnSelectOne.FlatStyle = System.Windows.Forms.FlatStyle.Popup; + this.btnSelectOne.Location = new System.Drawing.Point(271, 72); + this.btnSelectOne.Name = "btnSelectOne"; + this.btnSelectOne.Size = new System.Drawing.Size(50, 25); + this.btnSelectOne.TabIndex = 7; + this.btnSelectOne.Text = ">"; + this.btnSelectOne.UseVisualStyleBackColor = true; + this.btnSelectOne.Click += new System.EventHandler(this.btnSelectOne_Click); + // + // listBox2 + // + this.listBox2.FormattingEnabled = true; + this.listBox2.ItemHeight = 12; + this.listBox2.Location = new System.Drawing.Point(340, 20); + this.listBox2.Name = "listBox2"; + this.listBox2.SelectionMode = System.Windows.Forms.SelectionMode.MultiExtended; + this.listBox2.Size = new System.Drawing.Size(240, 172); + this.listBox2.TabIndex = 6; + this.listBox2.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.listBox2_MouseDoubleClick); + // + // btnSelectAll + // + this.btnSelectAll.FlatStyle = System.Windows.Forms.FlatStyle.Popup; + this.btnSelectAll.Location = new System.Drawing.Point(271, 30); + this.btnSelectAll.Name = "btnSelectAll"; + this.btnSelectAll.Size = new System.Drawing.Size(50, 25); + this.btnSelectAll.TabIndex = 2; + this.btnSelectAll.Text = ">>"; + this.btnSelectAll.UseVisualStyleBackColor = true; + this.btnSelectAll.Click += new System.EventHandler(this.btnSelectAll_Click); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(9, 27); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(77, 12); + this.label1.TabIndex = 2; + this.label1.Text = "设定命名空间"; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(9, 58); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(77, 12); + this.label2.TabIndex = 3; + this.label2.Text = "删除表名前缀"; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(9, 89); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(77, 12); + this.label3.TabIndex = 4; + this.label3.Text = "删除字段前缀"; + // + // txtTablePrefix + // + this.txtTablePrefix.Location = new System.Drawing.Point(92, 54); + this.txtTablePrefix.Name = "txtTablePrefix"; + this.txtTablePrefix.Size = new System.Drawing.Size(47, 21); + this.txtTablePrefix.TabIndex = 5; + // + // txtColumnPrefix + // + this.txtColumnPrefix.Location = new System.Drawing.Point(92, 85); + this.txtColumnPrefix.Name = "txtColumnPrefix"; + this.txtColumnPrefix.Size = new System.Drawing.Size(47, 21); + this.txtColumnPrefix.TabIndex = 6; + // + // label4 + // + this.label4.AutoSize = true; + this.label4.Location = new System.Drawing.Point(292, 27); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(53, 12); + this.label4.TabIndex = 7; + this.label4.Text = "选择模板"; + // + // cbTemplate + // + this.cbTemplate.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.cbTemplate.FormattingEnabled = true; + this.cbTemplate.Location = new System.Drawing.Point(364, 23); + this.cbTemplate.Name = "cbTemplate"; + this.cbTemplate.Size = new System.Drawing.Size(148, 20); + this.cbTemplate.TabIndex = 8; + // + // txtNameSpace + // + this.txtNameSpace.Location = new System.Drawing.Point(92, 23); + this.txtNameSpace.Name = "txtNameSpace"; + this.txtNameSpace.Size = new System.Drawing.Size(194, 21); + this.txtNameSpace.TabIndex = 9; + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.btnPreview); + this.groupBox1.Controls.Add(this.lblMsg); + this.groupBox1.Controls.Add(this.progressBar1); + this.groupBox1.Controls.Add(this.btnReturn); + this.groupBox1.Controls.Add(this.btnBuildCode); + this.groupBox1.Controls.Add(this.label9); + this.groupBox1.Controls.Add(this.txtPrefixLevel); + this.groupBox1.Controls.Add(this.label8); + this.groupBox1.Controls.Add(this.label7); + this.groupBox1.Controls.Add(this.label6); + this.groupBox1.Controls.Add(this.btnBrowser); + this.groupBox1.Controls.Add(this.txtOutputPath); + this.groupBox1.Controls.Add(this.label5); + this.groupBox1.Controls.Add(this.txtTablePrefix); + this.groupBox1.Controls.Add(this.txtNameSpace); + this.groupBox1.Controls.Add(this.label1); + this.groupBox1.Controls.Add(this.cbTemplate); + this.groupBox1.Controls.Add(this.label2); + this.groupBox1.Controls.Add(this.label4); + this.groupBox1.Controls.Add(this.label3); + this.groupBox1.Controls.Add(this.txtColumnPrefix); + this.groupBox1.Dock = System.Windows.Forms.DockStyle.Fill; + this.groupBox1.Location = new System.Drawing.Point(0, 207); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(592, 237); + this.groupBox1.TabIndex = 10; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "参数设置"; + // + // btnPreview + // + this.btnPreview.Location = new System.Drawing.Point(518, 22); + this.btnPreview.Name = "btnPreview"; + this.btnPreview.Size = new System.Drawing.Size(62, 23); + this.btnPreview.TabIndex = 22; + this.btnPreview.Text = "预览"; + this.btnPreview.UseVisualStyleBackColor = true; + this.btnPreview.Click += new System.EventHandler(this.btnPreview_Click); + // + // lblMsg + // + this.lblMsg.AutoSize = true; + this.lblMsg.ForeColor = System.Drawing.Color.Red; + this.lblMsg.Location = new System.Drawing.Point(13, 192); + this.lblMsg.Name = "lblMsg"; + this.lblMsg.Size = new System.Drawing.Size(101, 12); + this.lblMsg.TabIndex = 21; + this.lblMsg.Text = "代码生成进度显示"; + // + // progressBar1 + // + this.progressBar1.ForeColor = System.Drawing.Color.ForestGreen; + this.progressBar1.Location = new System.Drawing.Point(11, 212); + this.progressBar1.Name = "progressBar1"; + this.progressBar1.Size = new System.Drawing.Size(570, 18); + this.progressBar1.Step = 2; + this.progressBar1.TabIndex = 20; + // + // btnReturn + // + this.btnReturn.Location = new System.Drawing.Point(506, 181); + this.btnReturn.Name = "btnReturn"; + this.btnReturn.Size = new System.Drawing.Size(75, 23); + this.btnReturn.TabIndex = 19; + this.btnReturn.Text = "返回"; + this.btnReturn.UseVisualStyleBackColor = true; + this.btnReturn.Click += new System.EventHandler(this.btnReturn_Click); + // + // btnBuildCode + // + this.btnBuildCode.Location = new System.Drawing.Point(394, 181); + this.btnBuildCode.Name = "btnBuildCode"; + this.btnBuildCode.Size = new System.Drawing.Size(75, 23); + this.btnBuildCode.TabIndex = 18; + this.btnBuildCode.Text = "生成代码"; + this.btnBuildCode.UseVisualStyleBackColor = true; + this.btnBuildCode.Click += new System.EventHandler(this.btnBuildCode_Click); + // + // label9 + // + this.label9.AutoSize = true; + this.label9.ForeColor = System.Drawing.Color.Red; + this.label9.Location = new System.Drawing.Point(142, 120); + this.label9.Name = "label9"; + this.label9.Size = new System.Drawing.Size(425, 12); + this.label9.TabIndex = 17; + this.label9.Text = "比如\"sys_right_Role\",若层次为1,结果为right_Role,层次为2,结果为Role"; + // + // txtPrefixLevel + // + this.txtPrefixLevel.Location = new System.Drawing.Point(92, 116); + this.txtPrefixLevel.Name = "txtPrefixLevel"; + this.txtPrefixLevel.Size = new System.Drawing.Size(47, 21); + this.txtPrefixLevel.TabIndex = 16; + this.txtPrefixLevel.Text = "1"; + // + // label8 + // + this.label8.AutoSize = true; + this.label8.Location = new System.Drawing.Point(11, 120); + this.label8.Name = "label8"; + this.label8.Size = new System.Drawing.Size(77, 12); + this.label8.TabIndex = 15; + this.label8.Text = "删除前缀层次"; + // + // label7 + // + this.label7.AutoSize = true; + this.label7.ForeColor = System.Drawing.Color.Red; + this.label7.Location = new System.Drawing.Point(143, 89); + this.label7.Name = "label7"; + this.label7.Size = new System.Drawing.Size(431, 12); + this.label7.TabIndex = 14; + this.label7.Text = "输入字段前缀分隔符,比如\"u_UserID\",那么输入\"_\",保留空白表示不删除前缀"; + // + // label6 + // + this.label6.AutoSize = true; + this.label6.ForeColor = System.Drawing.Color.Red; + this.label6.Location = new System.Drawing.Point(143, 58); + this.label6.Name = "label6"; + this.label6.Size = new System.Drawing.Size(431, 12); + this.label6.TabIndex = 13; + this.label6.Text = "输入表名前缀分隔符,比如\"sys_User\",那么输入\"_\",保留空白表示不删除前缀"; + // + // btnBrowser + // + this.btnBrowser.Location = new System.Drawing.Point(518, 146); + this.btnBrowser.Name = "btnBrowser"; + this.btnBrowser.Size = new System.Drawing.Size(62, 23); + this.btnBrowser.TabIndex = 12; + this.btnBrowser.Text = "浏览..."; + this.btnBrowser.UseVisualStyleBackColor = true; + this.btnBrowser.Click += new System.EventHandler(this.btnBrowser_Click); + // + // txtOutputPath + // + this.txtOutputPath.Location = new System.Drawing.Point(92, 147); + this.txtOutputPath.Name = "txtOutputPath"; + this.txtOutputPath.Size = new System.Drawing.Size(420, 21); + this.txtOutputPath.TabIndex = 11; + // + // label5 + // + this.label5.AutoSize = true; + this.label5.Location = new System.Drawing.Point(9, 151); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(77, 12); + this.label5.TabIndex = 10; + this.label5.Text = "代码输出目录"; + // + // backgroundWorker1 + // + this.backgroundWorker1.WorkerReportsProgress = true; + this.backgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker1_DoWork); + this.backgroundWorker1.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted); + this.backgroundWorker1.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.backgroundWorker1_ProgressChanged); + // + // BatchBuildDALCode + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(592, 444); + this.Controls.Add(this.groupBox1); + this.Controls.Add(this.gbTableSelect); + this.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.MaximizeBox = false; + this.MaximumSize = new System.Drawing.Size(600, 471); + this.Name = "BatchBuildDALCode"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "批量生成数据层代码"; + this.Load += new System.EventHandler(this.BatchBuildDALCode_Load); + this.gbTableSelect.ResumeLayout(false); + this.groupBox1.ResumeLayout(false); + this.groupBox1.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Button btnPreview; + private System.Windows.Forms.Label lblMsg; + private System.Windows.Forms.FolderBrowserDialog folderBrowserDialog1; + private System.Windows.Forms.ProgressBar progressBar1; + private System.Windows.Forms.Button btnReturn; + private System.Windows.Forms.Button btnBuildCode; + private System.Windows.Forms.Label label9; + private System.Windows.Forms.TextBox txtPrefixLevel; + private System.Windows.Forms.Label label8; + private System.Windows.Forms.Label label7; + private System.Windows.Forms.TextBox txtOutputPath; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.Label label6; + private System.Windows.Forms.Button btnBrowser; + private System.Windows.Forms.TextBox txtTablePrefix; + private System.Windows.Forms.TextBox txtNameSpace; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.ComboBox cbTemplate; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.TextBox txtColumnPrefix; + private System.Windows.Forms.Button btnRemoveOne; + private System.Windows.Forms.Button btnRemoveAll; + private System.ComponentModel.BackgroundWorker backgroundWorker1; + private System.Windows.Forms.Button btnSelectOne; + private System.Windows.Forms.ListBox listBox2; + private System.Windows.Forms.Button btnSelectAll; + private System.Windows.Forms.ListBox listBox1; + private System.Windows.Forms.GroupBox gbTableSelect; + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/CodeBuilder/BatchBuildDALCode.resx b/src/Kalman.Studio/CodeBuilder/BatchBuildDALCode.resx new file mode 100644 index 0000000..93ac39c --- /dev/null +++ b/src/Kalman.Studio/CodeBuilder/BatchBuildDALCode.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 28, 18 + + + 184, 19 + + \ No newline at end of file diff --git a/src/Kalman.Studio/CodeBuilder/BatchBuildEntityCode.cs b/src/Kalman.Studio/CodeBuilder/BatchBuildEntityCode.cs new file mode 100644 index 0000000..ef01ce0 --- /dev/null +++ b/src/Kalman.Studio/CodeBuilder/BatchBuildEntityCode.cs @@ -0,0 +1,278 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using WeifenLuo.WinFormsUI.Docking; +using Microsoft.VisualStudio.TextTemplating; +using Kalman.Studio.T4TemplateEngineHost; +using System.IO; +using System.Net.Mail; +using System.Net; +using System.Diagnostics; +using System.CodeDom.Compiler; +using Kalman.Extensions; +using Kalman.Data.SchemaObject; +using Kalman.Utilities; + +namespace Kalman.Studio +{ + public partial class BatchBuildEntityCode : Form + { + SODatabase currentDatabase; + List tableList = new List(); + string templatePath = Path.Combine(Application.StartupPath, "T4Template\\Entity"); + + public BatchBuildEntityCode(SODatabase db) + { + InitializeComponent(); + currentDatabase = db; + tableList = db.TableList; + } + + private void BatchBuildEntityCode_Load(object sender, EventArgs e) + { + gbTableSelect.Text = string.Format("当前数据库[{0}]", currentDatabase); + + foreach (SOTable t in tableList) + { + listBox1.Items.Add(t); + } + + string[] ss = Directory.GetFiles(templatePath, "*.tt"); + foreach (string s in ss) + { + cbTemplate.Items.Add(Path.GetFileName(s)); + } + if (ss.Length > 0) cbTemplate.SelectedIndex = 0; + + folderBrowserDialog1.RootFolder = Environment.SpecialFolder.MyComputer; + txtOutputPath.Text = Path.Combine(Application.StartupPath, "Output\\EntityCode"); + } + + //预览模板 + private void btnPreview_Click(object sender, EventArgs e) + { + if (cbTemplate.SelectedItem == null) return; + string fileName = Path.Combine(templatePath, cbTemplate.SelectedItem.ToString()); + PreviewFile pf = new PreviewFile(fileName, CodeType.CSHARP); + pf.ShowDialog(); + } + + private void btnReturn_Click(object sender, EventArgs e) + { + this.Close(); + } + + private void btnBrowser_Click(object sender, EventArgs e) + { + DialogResult result = folderBrowserDialog1.ShowDialog(); + if (result == DialogResult.OK) + { + txtOutputPath.Text = folderBrowserDialog1.SelectedPath; + } + } + + //处理窗体关闭事件 + protected override void OnClosing(CancelEventArgs e) + { + if (backgroundWorker1.IsBusy == false) + { + base.OnClosing(e); + } + else + { + e.Cancel = true; + MessageBox.Show("正在生成代码,请不要关闭窗口"); + } + } + + #region 列表选择相关 + private void listBox1_MouseDoubleClick(object sender, MouseEventArgs e) + { + SelectOne(); + } + + private void listBox2_MouseDoubleClick(object sender, MouseEventArgs e) + { + RemoveOne(); + } + + private void btnSelectAll_Click(object sender, EventArgs e) + { + SelectAll(); + } + private void btnSelectOne_Click(object sender, EventArgs e) + { + SelectOne(); + } + private void btnRemoveOne_Click(object sender, EventArgs e) + { + RemoveOne(); + } + private void btnRemoveAll_Click(object sender, EventArgs e) + { + RemoveAll(); + } + + private void SelectAll() + { + if (backgroundWorker1.IsBusy) return; + if (listBox1.Items.Count > 0) + { + listBox2.Items.AddRange(listBox1.Items); + listBox1.Items.Clear(); + } + } + + private void SelectOne() + { + if (backgroundWorker1.IsBusy) return; + object[] items = new object[listBox1.SelectedItems.Count]; + listBox1.SelectedItems.CopyTo(items, 0); + listBox2.Items.AddRange(items); + + foreach (var item in items) + { + listBox1.Items.Remove(item); + } + } + + private void RemoveOne() + { + if (backgroundWorker1.IsBusy) return; + object[] items = new object[listBox2.SelectedItems.Count]; + listBox2.SelectedItems.CopyTo(items, 0); + listBox1.Items.AddRange(items); + + foreach (var item in items) + { + listBox2.Items.Remove(item); + } + } + + private void RemoveAll() + { + if (backgroundWorker1.IsBusy) return; + if (listBox2.Items.Count > 0) + { + listBox1.Items.AddRange(listBox2.Items); + listBox2.Items.Clear(); + } + } + #endregion + + #region 代码生成相关 + string nameSpace = "Entity"; + string tablePrefix = string.Empty; + string columnPrefix = string.Empty; + int prefixLevel = 1; + string templateFile = string.Empty; + string outputPath = string.Empty; + + private void btnBuildCode_Click(object sender, EventArgs e) + { + outputPath = txtOutputPath.Text; + if(txtNameSpace.Text.Trim() != "") nameSpace = txtNameSpace.Text.Trim(); + + if (listBox2.Items.Count == 0) return; + if (cbTemplate.SelectedItem == null) return; + templateFile = Path.Combine(templatePath, cbTemplate.SelectedItem.ToString()); + + if (txtTablePrefix.Text.Trim().Length > 0) tablePrefix = txtTablePrefix.Text.Trim(); + if (txtColumnPrefix.Text.Trim().Length > 0) columnPrefix = txtColumnPrefix.Text.Trim(); + prefixLevel = ConvertUtil.ToInt32(txtPrefixLevel.Text, 1); + + btnBuildCode.Enabled = false; + backgroundWorker1.RunWorkerAsync(); + } + + private void DoBuild() + { + int finish = 0; + int total = listBox2.Items.Count; + + //遍历选中的表,一张表对应生成一个代码文件 + foreach (object item in listBox2.Items) + { + SOTable table = item as SOTable; + string className = table.Name.RemovePrefix(tablePrefix, prefixLevel).Replace(" ", ""); + + List columnList = table.ColumnList;//可能传入的是从PDObject对象转换过来的SODatabase对象 + if (columnList == null || columnList.Count == 0) columnList = DbSchemaHelper.Instance.CurrentSchema.GetTableColumnList(table); + + //生成代码文件 + TableHost host = new TableHost(); + host.Table = table; + host.ColumnList = columnList; + host.TemplateFile = templateFile; + host.SetValue("NameSpace", nameSpace); + host.SetValue("ClassName", className); + host.SetValue("TablePrefix", tablePrefix); + host.SetValue("ColumnPrefix", columnPrefix); + host.SetValue("PrefixLevel", prefixLevel); + + Engine engine = new Engine(); + + string outputContent = engine.ProcessTemplate(File.ReadAllText(templateFile), host); + //string outputFile = Path.Combine(outputPath,string.Format("{0}.cs", className)); + string outputFile = Path.Combine(outputPath, string.Format("{0}{1}", className, host.FileExtention)); + + StringBuilder sb = new StringBuilder(); + if (host.ErrorCollection.HasErrors) + { + foreach (CompilerError err in host.ErrorCollection) + { + sb.AppendLine(err.ToString()); + } + outputContent = outputContent + Environment.NewLine + sb.ToString(); + outputFile = outputFile + ".error"; + } + + if (Directory.Exists(outputPath) == false) Directory.CreateDirectory(outputPath); + File.WriteAllText(outputFile, outputContent, Encoding.UTF8); + + finish = finish + 1; + int percent = ConvertUtil.ToInt32(finish * 100 / total, 0); + + backgroundWorker1.ReportProgress(percent, table); + }//end build code foreach + } + + private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) + { + DoBuild(); + } + + private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) + { + progressBar1.Value = e.ProgressPercentage; + SOTable table = e.UserState as SOTable; + + if (e.ProgressPercentage == 100) + { + lblMsg.Text = "代码已全部生成"; + } + else + { + lblMsg.Text = string.Format("已完成:{0}%,正在处理:{1}", e.ProgressPercentage, table.Name); + } + } + + private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) + { + DialogResult result = MessageBox.Show("代码生成成功,是否打开输出目录", "代码生成消息提示", MessageBoxButtons.YesNo, MessageBoxIcon.Information); + if (result == DialogResult.Yes) + { + string cmd = "explorer.exe " + outputPath; + Kalman.Command.CmdHelper.Execute(cmd); + } + btnBuildCode.Enabled = true; + } + #endregion + + } +} diff --git a/src/Kalman.Studio/CodeBuilder/BatchBuildEntityCode.designer.cs b/src/Kalman.Studio/CodeBuilder/BatchBuildEntityCode.designer.cs new file mode 100644 index 0000000..0aa40f8 --- /dev/null +++ b/src/Kalman.Studio/CodeBuilder/BatchBuildEntityCode.designer.cs @@ -0,0 +1,433 @@ +namespace Kalman.Studio +{ + partial class BatchBuildEntityCode + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.listBox1 = new System.Windows.Forms.ListBox(); + this.gbTableSelect = new System.Windows.Forms.GroupBox(); + this.btnRemoveOne = new System.Windows.Forms.Button(); + this.btnRemoveAll = new System.Windows.Forms.Button(); + this.btnSelectOne = new System.Windows.Forms.Button(); + this.listBox2 = new System.Windows.Forms.ListBox(); + this.btnSelectAll = new System.Windows.Forms.Button(); + this.label1 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.label3 = new System.Windows.Forms.Label(); + this.txtTablePrefix = new System.Windows.Forms.TextBox(); + this.txtColumnPrefix = new System.Windows.Forms.TextBox(); + this.label4 = new System.Windows.Forms.Label(); + this.cbTemplate = new System.Windows.Forms.ComboBox(); + this.txtNameSpace = new System.Windows.Forms.TextBox(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.btnPreview = new System.Windows.Forms.Button(); + this.lblMsg = new System.Windows.Forms.Label(); + this.progressBar1 = new System.Windows.Forms.ProgressBar(); + this.btnReturn = new System.Windows.Forms.Button(); + this.btnBuildCode = new System.Windows.Forms.Button(); + this.label9 = new System.Windows.Forms.Label(); + this.txtPrefixLevel = new System.Windows.Forms.TextBox(); + this.label8 = new System.Windows.Forms.Label(); + this.label7 = new System.Windows.Forms.Label(); + this.label6 = new System.Windows.Forms.Label(); + this.btnBrowser = new System.Windows.Forms.Button(); + this.txtOutputPath = new System.Windows.Forms.TextBox(); + this.label5 = new System.Windows.Forms.Label(); + this.folderBrowserDialog1 = new System.Windows.Forms.FolderBrowserDialog(); + this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker(); + this.gbTableSelect.SuspendLayout(); + this.groupBox1.SuspendLayout(); + this.SuspendLayout(); + // + // listBox1 + // + this.listBox1.FormattingEnabled = true; + this.listBox1.ItemHeight = 12; + this.listBox1.Location = new System.Drawing.Point(12, 20); + this.listBox1.Name = "listBox1"; + this.listBox1.SelectionMode = System.Windows.Forms.SelectionMode.MultiExtended; + this.listBox1.Size = new System.Drawing.Size(240, 172); + this.listBox1.TabIndex = 0; + this.listBox1.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.listBox1_MouseDoubleClick); + // + // gbTableSelect + // + this.gbTableSelect.Controls.Add(this.btnRemoveOne); + this.gbTableSelect.Controls.Add(this.btnRemoveAll); + this.gbTableSelect.Controls.Add(this.btnSelectOne); + this.gbTableSelect.Controls.Add(this.listBox2); + this.gbTableSelect.Controls.Add(this.btnSelectAll); + this.gbTableSelect.Controls.Add(this.listBox1); + this.gbTableSelect.Dock = System.Windows.Forms.DockStyle.Top; + this.gbTableSelect.Location = new System.Drawing.Point(0, 0); + this.gbTableSelect.Margin = new System.Windows.Forms.Padding(10); + this.gbTableSelect.Name = "gbTableSelect"; + this.gbTableSelect.Padding = new System.Windows.Forms.Padding(10); + this.gbTableSelect.Size = new System.Drawing.Size(592, 207); + this.gbTableSelect.TabIndex = 1; + this.gbTableSelect.TabStop = false; + this.gbTableSelect.Text = "groupBox1"; + // + // btnRemoveOne + // + this.btnRemoveOne.FlatStyle = System.Windows.Forms.FlatStyle.Popup; + this.btnRemoveOne.Location = new System.Drawing.Point(271, 114); + this.btnRemoveOne.Name = "btnRemoveOne"; + this.btnRemoveOne.Size = new System.Drawing.Size(50, 25); + this.btnRemoveOne.TabIndex = 9; + this.btnRemoveOne.Text = "<"; + this.btnRemoveOne.UseVisualStyleBackColor = true; + this.btnRemoveOne.Click += new System.EventHandler(this.btnRemoveOne_Click); + // + // btnRemoveAll + // + this.btnRemoveAll.FlatStyle = System.Windows.Forms.FlatStyle.Popup; + this.btnRemoveAll.Location = new System.Drawing.Point(271, 156); + this.btnRemoveAll.Name = "btnRemoveAll"; + this.btnRemoveAll.Size = new System.Drawing.Size(50, 25); + this.btnRemoveAll.TabIndex = 8; + this.btnRemoveAll.Text = "<<"; + this.btnRemoveAll.UseVisualStyleBackColor = true; + this.btnRemoveAll.Click += new System.EventHandler(this.btnRemoveAll_Click); + // + // btnSelectOne + // + this.btnSelectOne.FlatStyle = System.Windows.Forms.FlatStyle.Popup; + this.btnSelectOne.Location = new System.Drawing.Point(271, 72); + this.btnSelectOne.Name = "btnSelectOne"; + this.btnSelectOne.Size = new System.Drawing.Size(50, 25); + this.btnSelectOne.TabIndex = 7; + this.btnSelectOne.Text = ">"; + this.btnSelectOne.UseVisualStyleBackColor = true; + this.btnSelectOne.Click += new System.EventHandler(this.btnSelectOne_Click); + // + // listBox2 + // + this.listBox2.FormattingEnabled = true; + this.listBox2.ItemHeight = 12; + this.listBox2.Location = new System.Drawing.Point(340, 20); + this.listBox2.Name = "listBox2"; + this.listBox2.SelectionMode = System.Windows.Forms.SelectionMode.MultiExtended; + this.listBox2.Size = new System.Drawing.Size(240, 172); + this.listBox2.TabIndex = 6; + this.listBox2.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.listBox2_MouseDoubleClick); + // + // btnSelectAll + // + this.btnSelectAll.FlatStyle = System.Windows.Forms.FlatStyle.Popup; + this.btnSelectAll.Location = new System.Drawing.Point(271, 30); + this.btnSelectAll.Name = "btnSelectAll"; + this.btnSelectAll.Size = new System.Drawing.Size(50, 25); + this.btnSelectAll.TabIndex = 2; + this.btnSelectAll.Text = ">>"; + this.btnSelectAll.UseVisualStyleBackColor = true; + this.btnSelectAll.Click += new System.EventHandler(this.btnSelectAll_Click); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(9, 27); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(77, 12); + this.label1.TabIndex = 2; + this.label1.Text = "设定命名空间"; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(9, 58); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(77, 12); + this.label2.TabIndex = 3; + this.label2.Text = "删除表名前缀"; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(9, 89); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(77, 12); + this.label3.TabIndex = 4; + this.label3.Text = "删除字段前缀"; + // + // txtTablePrefix + // + this.txtTablePrefix.Location = new System.Drawing.Point(92, 54); + this.txtTablePrefix.Name = "txtTablePrefix"; + this.txtTablePrefix.Size = new System.Drawing.Size(47, 21); + this.txtTablePrefix.TabIndex = 5; + // + // txtColumnPrefix + // + this.txtColumnPrefix.Location = new System.Drawing.Point(92, 85); + this.txtColumnPrefix.Name = "txtColumnPrefix"; + this.txtColumnPrefix.Size = new System.Drawing.Size(47, 21); + this.txtColumnPrefix.TabIndex = 6; + // + // label4 + // + this.label4.AutoSize = true; + this.label4.Location = new System.Drawing.Point(292, 27); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(53, 12); + this.label4.TabIndex = 7; + this.label4.Text = "选择模板"; + // + // cbTemplate + // + this.cbTemplate.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.cbTemplate.FormattingEnabled = true; + this.cbTemplate.Location = new System.Drawing.Point(364, 23); + this.cbTemplate.Name = "cbTemplate"; + this.cbTemplate.Size = new System.Drawing.Size(148, 20); + this.cbTemplate.TabIndex = 8; + // + // txtNameSpace + // + this.txtNameSpace.Location = new System.Drawing.Point(92, 23); + this.txtNameSpace.Name = "txtNameSpace"; + this.txtNameSpace.Size = new System.Drawing.Size(194, 21); + this.txtNameSpace.TabIndex = 9; + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.btnPreview); + this.groupBox1.Controls.Add(this.lblMsg); + this.groupBox1.Controls.Add(this.progressBar1); + this.groupBox1.Controls.Add(this.btnReturn); + this.groupBox1.Controls.Add(this.btnBuildCode); + this.groupBox1.Controls.Add(this.label9); + this.groupBox1.Controls.Add(this.txtPrefixLevel); + this.groupBox1.Controls.Add(this.label8); + this.groupBox1.Controls.Add(this.label7); + this.groupBox1.Controls.Add(this.label6); + this.groupBox1.Controls.Add(this.btnBrowser); + this.groupBox1.Controls.Add(this.txtOutputPath); + this.groupBox1.Controls.Add(this.label5); + this.groupBox1.Controls.Add(this.txtTablePrefix); + this.groupBox1.Controls.Add(this.txtNameSpace); + this.groupBox1.Controls.Add(this.label1); + this.groupBox1.Controls.Add(this.cbTemplate); + this.groupBox1.Controls.Add(this.label2); + this.groupBox1.Controls.Add(this.label4); + this.groupBox1.Controls.Add(this.label3); + this.groupBox1.Controls.Add(this.txtColumnPrefix); + this.groupBox1.Dock = System.Windows.Forms.DockStyle.Fill; + this.groupBox1.Location = new System.Drawing.Point(0, 207); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(592, 237); + this.groupBox1.TabIndex = 10; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "参数设置"; + // + // btnPreview + // + this.btnPreview.Location = new System.Drawing.Point(518, 22); + this.btnPreview.Name = "btnPreview"; + this.btnPreview.Size = new System.Drawing.Size(62, 23); + this.btnPreview.TabIndex = 22; + this.btnPreview.Text = "预览"; + this.btnPreview.UseVisualStyleBackColor = true; + this.btnPreview.Click += new System.EventHandler(this.btnPreview_Click); + // + // lblMsg + // + this.lblMsg.AutoSize = true; + this.lblMsg.ForeColor = System.Drawing.Color.Red; + this.lblMsg.Location = new System.Drawing.Point(13, 192); + this.lblMsg.Name = "lblMsg"; + this.lblMsg.Size = new System.Drawing.Size(101, 12); + this.lblMsg.TabIndex = 21; + this.lblMsg.Text = "代码生成进度显示"; + // + // progressBar1 + // + this.progressBar1.ForeColor = System.Drawing.Color.ForestGreen; + this.progressBar1.Location = new System.Drawing.Point(11, 212); + this.progressBar1.Name = "progressBar1"; + this.progressBar1.Size = new System.Drawing.Size(570, 18); + this.progressBar1.Step = 2; + this.progressBar1.TabIndex = 20; + // + // btnReturn + // + this.btnReturn.Location = new System.Drawing.Point(506, 181); + this.btnReturn.Name = "btnReturn"; + this.btnReturn.Size = new System.Drawing.Size(75, 23); + this.btnReturn.TabIndex = 19; + this.btnReturn.Text = "返回"; + this.btnReturn.UseVisualStyleBackColor = true; + this.btnReturn.Click += new System.EventHandler(this.btnReturn_Click); + // + // btnBuildCode + // + this.btnBuildCode.Location = new System.Drawing.Point(394, 181); + this.btnBuildCode.Name = "btnBuildCode"; + this.btnBuildCode.Size = new System.Drawing.Size(75, 23); + this.btnBuildCode.TabIndex = 18; + this.btnBuildCode.Text = "生成代码"; + this.btnBuildCode.UseVisualStyleBackColor = true; + this.btnBuildCode.Click += new System.EventHandler(this.btnBuildCode_Click); + // + // label9 + // + this.label9.AutoSize = true; + this.label9.ForeColor = System.Drawing.Color.Red; + this.label9.Location = new System.Drawing.Point(142, 120); + this.label9.Name = "label9"; + this.label9.Size = new System.Drawing.Size(425, 12); + this.label9.TabIndex = 17; + this.label9.Text = "比如\"sys_right_Role\",若层次为1,结果为right_Role,层次为2,结果为Role"; + // + // txtPrefixLevel + // + this.txtPrefixLevel.Location = new System.Drawing.Point(92, 116); + this.txtPrefixLevel.Name = "txtPrefixLevel"; + this.txtPrefixLevel.Size = new System.Drawing.Size(47, 21); + this.txtPrefixLevel.TabIndex = 16; + this.txtPrefixLevel.Text = "1"; + // + // label8 + // + this.label8.AutoSize = true; + this.label8.Location = new System.Drawing.Point(11, 120); + this.label8.Name = "label8"; + this.label8.Size = new System.Drawing.Size(77, 12); + this.label8.TabIndex = 15; + this.label8.Text = "删除前缀层次"; + // + // label7 + // + this.label7.AutoSize = true; + this.label7.ForeColor = System.Drawing.Color.Red; + this.label7.Location = new System.Drawing.Point(143, 89); + this.label7.Name = "label7"; + this.label7.Size = new System.Drawing.Size(431, 12); + this.label7.TabIndex = 14; + this.label7.Text = "输入字段前缀分隔符,比如\"u_UserID\",那么输入\"_\",保留空白表示不删除前缀"; + // + // label6 + // + this.label6.AutoSize = true; + this.label6.ForeColor = System.Drawing.Color.Red; + this.label6.Location = new System.Drawing.Point(143, 58); + this.label6.Name = "label6"; + this.label6.Size = new System.Drawing.Size(431, 12); + this.label6.TabIndex = 13; + this.label6.Text = "输入表名前缀分隔符,比如\"sys_User\",那么输入\"_\",保留空白表示不删除前缀"; + // + // btnBrowser + // + this.btnBrowser.Location = new System.Drawing.Point(518, 146); + this.btnBrowser.Name = "btnBrowser"; + this.btnBrowser.Size = new System.Drawing.Size(62, 23); + this.btnBrowser.TabIndex = 12; + this.btnBrowser.Text = "浏览..."; + this.btnBrowser.UseVisualStyleBackColor = true; + this.btnBrowser.Click += new System.EventHandler(this.btnBrowser_Click); + // + // txtOutputPath + // + this.txtOutputPath.Location = new System.Drawing.Point(92, 147); + this.txtOutputPath.Name = "txtOutputPath"; + this.txtOutputPath.Size = new System.Drawing.Size(420, 21); + this.txtOutputPath.TabIndex = 11; + // + // label5 + // + this.label5.AutoSize = true; + this.label5.Location = new System.Drawing.Point(9, 151); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(77, 12); + this.label5.TabIndex = 10; + this.label5.Text = "代码输出目录"; + // + // backgroundWorker1 + // + this.backgroundWorker1.WorkerReportsProgress = true; + this.backgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker1_DoWork); + this.backgroundWorker1.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted); + this.backgroundWorker1.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.backgroundWorker1_ProgressChanged); + // + // BatchBuildEntityCode + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(592, 444); + this.Controls.Add(this.groupBox1); + this.Controls.Add(this.gbTableSelect); + this.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.MaximizeBox = false; + this.MaximumSize = new System.Drawing.Size(600, 471); + this.Name = "BatchBuildEntityCode"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "批量生成实体层代码"; + this.Load += new System.EventHandler(this.BatchBuildEntityCode_Load); + this.gbTableSelect.ResumeLayout(false); + this.groupBox1.ResumeLayout(false); + this.groupBox1.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.ListBox listBox1; + private System.Windows.Forms.GroupBox gbTableSelect; + private System.Windows.Forms.Button btnSelectAll; + private System.Windows.Forms.ListBox listBox2; + private System.Windows.Forms.Button btnRemoveOne; + private System.Windows.Forms.Button btnRemoveAll; + private System.Windows.Forms.Button btnSelectOne; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.TextBox txtTablePrefix; + private System.Windows.Forms.TextBox txtColumnPrefix; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.ComboBox cbTemplate; + private System.Windows.Forms.TextBox txtNameSpace; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.Button btnBrowser; + private System.Windows.Forms.TextBox txtOutputPath; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.FolderBrowserDialog folderBrowserDialog1; + private System.Windows.Forms.Label label7; + private System.Windows.Forms.Label label6; + private System.Windows.Forms.Label label9; + private System.Windows.Forms.TextBox txtPrefixLevel; + private System.Windows.Forms.Label label8; + private System.Windows.Forms.Button btnReturn; + private System.Windows.Forms.Button btnBuildCode; + private System.Windows.Forms.Label lblMsg; + private System.Windows.Forms.ProgressBar progressBar1; + private System.ComponentModel.BackgroundWorker backgroundWorker1; + private System.Windows.Forms.Button btnPreview; + + + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/CodeBuilder/BatchBuildEntityCode.resx b/src/Kalman.Studio/CodeBuilder/BatchBuildEntityCode.resx new file mode 100644 index 0000000..326ad41 --- /dev/null +++ b/src/Kalman.Studio/CodeBuilder/BatchBuildEntityCode.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + 192, 17 + + \ No newline at end of file diff --git a/src/Kalman.Studio/CodeBuilder/CodeBuilder.cs b/src/Kalman.Studio/CodeBuilder/CodeBuilder.cs new file mode 100644 index 0000000..ee3ed85 --- /dev/null +++ b/src/Kalman.Studio/CodeBuilder/CodeBuilder.cs @@ -0,0 +1,412 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using System.IO; +using ICSharpCode.TextEditor; +using ICSharpCode.TextEditor.Document; +using Microsoft.VisualStudio.TextTemplating; +using Kalman.Studio.T4TemplateEngineHost; +using System.CodeDom.Compiler; +using Kalman.Data.SchemaObject; + +namespace Kalman.Studio +{ + public partial class CodeBuilder : DockableForm + { + public CodeBuilder() + { + InitializeComponent(); + } + + string _CodeType = CodeType.CSHARP; + public SOTable Table { get; set; } + public List ColumnList { get; set; } + + private void CodeBuilder_Load(object sender, EventArgs e) + { + base.MainForm.ShowBuildCodeIcon(); + + SetDocumentCodeType(textEditorControl1, CodeType.CSHARP); + SetDocumentCodeType(textEditorControl2, CodeType.CSHARP); + + LoadTemplateTree(); + LoadColumnList(); + ShowTitle(); + } + + public void LoadColumnList() + { + dataGridView1.AutoGenerateColumns = false; + if (ColumnList != null) + { + this.dataGridView1.DataSource = ColumnList; + foreach (DataGridViewRow row in dataGridView1.Rows) + { + DataGridViewCheckBoxCell cell = row.Cells[0] as DataGridViewCheckBoxCell; + cell.ValueType = typeof(bool); + cell.Value = true; + } + ShowTitle(); + } + } + + private void ShowTitle() + { + if (this.Table != null) + { + if (Table.Database != null) + { + gbObjName.Text = string.Format("当前对象:{0} -> {1}", Table.Database, Table.Name); + } + else + { + gbObjName.Text = string.Format("当前对象:{0}", Table.Name); + } + } + else + { + gbObjName.Text = "没有选择表或视图"; + } + } + + #region 模板树相关代码 + + private void LoadTemplateTree() + { + string templatePath = Path.Combine(Application.StartupPath, "T4Template"); + + TreeNode root = new TreeNode("T4Templates", 0, 0); + root.ContextMenuStrip = cmsTree; + tvTemplate.Nodes.Add(root); + + DirectoryInfo dirInfo = new DirectoryInfo(templatePath); + ExpentTemplateDir(dirInfo, root); + } + + //展开模板文件夹 + private void ExpentTemplateDir(DirectoryInfo rootDirInfo, TreeNode root) + { + DirectoryInfo[] dirs = rootDirInfo.GetDirectories(); + foreach (DirectoryInfo dir in dirs) + { + TreeNode node = new TreeNode(dir.Name, 1, 1); + node.Tag = dir; + node.Name = dir.Name; + if(root.Nodes.ContainsKey(node.Name) == false) root.Nodes.Add(node); + } + + FileInfo[] files = rootDirInfo.GetFiles(); + foreach (FileInfo file in files) + { + TreeNode node = new TreeNode(file.Name, 2, 2); + node.Tag = file; + node.Name = file.Name; + if(root.Nodes.ContainsKey(node.Name) == false) root.Nodes.Add(node); + } + + root.Expand(); + } + + private void tvTemplate_MouseClick(object sender, MouseEventArgs e) + { + if (e.Button == MouseButtons.Right) + { + TreeView tv = sender as TreeView; + TreeNode tn = tv.GetNodeAt(e.X, e.Y); + tv.SelectedNode = tn; + } + } + + private void tvTemplate_MouseDoubleClick(object sender, MouseEventArgs e) + { + TreeView tv = sender as TreeView; + TreeNode tn = tv.GetNodeAt(e.X, e.Y); + + if (tn.Tag is DirectoryInfo) + { + DirectoryInfo dir = (DirectoryInfo)tn.Tag; + if (Directory.Exists(dir.FullName) == false) + { + MessageBox.Show("目标可能被删除、移动、改名,请刷新模板树"); + return; + } + ExpentTemplateDir(dir, tn); + } + if (tn.Tag is FileInfo) + { + FileInfo fi = tn.Tag as FileInfo; + if (File.Exists(fi.FullName) == false) + { + MessageBox.Show("目标可能被删除、移动、改名,请刷新模板树"); + return; + } + textEditorControl1.LoadFile(fi.FullName); + gbTemplateFile.Text = fi.FullName; + } + SetDocumentCodeType(textEditorControl1, CodeType.CSHARP); + } + + //右键菜单项命令:刷新模板树 + private void menuItemRefresh_Click(object sender, EventArgs e) + { + tvTemplate.Nodes.Clear(); + LoadTemplateTree(); + } + + //右键菜单项命令:模板管理 + private void menuItemManage_Click(object sender, EventArgs e) + { + base.MainForm.ShowTemplateExplorer(); + } + + + #endregion + + public void DoBuildCode() + { + textEditorControl1.SaveFile(gbTemplateFile.Text); + + TableHost host = new TableHost(); + host.Table = this.Table; + host.TemplateFile = gbTemplateFile.Text; + + List columnList = new List(); + + foreach (DataGridViewRow row in dataGridView1.Rows) + { + if (row.Cells[0].FormattedValue.ToString().ToLower() == "true") + { + SOColumn c = row.DataBoundItem as SOColumn; + columnList.Add(c); + } + } + + host.ColumnList = columnList; + Engine engine = new Engine(); + string outputContent = engine.ProcessTemplate(File.ReadAllText(host.TemplateFile), host); + + StringBuilder sb = new StringBuilder(); + if (host.ErrorCollection.HasErrors) + { + foreach (CompilerError err in host.ErrorCollection) + { + sb.AppendLine(err.ToString()); + } + outputContent = outputContent + Environment.NewLine + sb.ToString(); + } + + textEditorControl2.Text = outputContent; + tabControl1.SelectedTab = tabPage2; + textEditorControl2.Refresh(); + } + + #region SetDocumentCodeType + void SetDocumentCodeType(TextEditorControl editor, string codeType) + { + IHighlightingStrategy strategy = HighlightingStrategyFactory.CreateHighlightingStrategy(codeType); + editor.Document.HighlightingStrategy = strategy; + _CodeType = codeType; + } + + private void menuItemAspxCode_Click(object sender, EventArgs e) + { + foreach (ToolStripItem item in menuItemConfig.DropDownItems) + { + ((ToolStripMenuItem)item).Checked = false; + } + menuItemAspxCode.Checked = true; + TextEditorControl editor = tabControl1.SelectedTab == tabPage1 ? textEditorControl1 : textEditorControl2; + SetDocumentCodeType(editor, CodeType.ASPX); + } + + private void menuItemCppCode_Click(object sender, EventArgs e) + { + foreach (ToolStripItem item in menuItemConfig.DropDownItems) + { + ((ToolStripMenuItem)item).Checked = false; + } + menuItemCppCode.Checked = true; + TextEditorControl editor = tabControl1.SelectedTab == tabPage1 ? textEditorControl1 : textEditorControl2; + SetDocumentCodeType(editor, CodeType.CPP); + } + + private void menuItemCSharpCode_Click(object sender, EventArgs e) + { + foreach (ToolStripItem item in menuItemConfig.DropDownItems) + { + ((ToolStripMenuItem)item).Checked = false; + } + menuItemCSharpCode.Checked = true; + TextEditorControl editor = tabControl1.SelectedTab == tabPage1 ? textEditorControl1 : textEditorControl2; + SetDocumentCodeType(editor, CodeType.CSHARP); + } + + private void menuItemHtmlCode_Click(object sender, EventArgs e) + { + foreach (ToolStripItem item in menuItemConfig.DropDownItems) + { + ((ToolStripMenuItem)item).Checked = false; + } + menuItemHtmlCode.Checked = true; + TextEditorControl editor = tabControl1.SelectedTab == tabPage1 ? textEditorControl1 : textEditorControl2; + SetDocumentCodeType(editor, CodeType.HTML); + } + + private void menuItemJavaCode_Click(object sender, EventArgs e) + { + foreach (ToolStripItem item in menuItemConfig.DropDownItems) + { + ((ToolStripMenuItem)item).Checked = false; + } + menuItemJavaCode.Checked = true; + TextEditorControl editor = tabControl1.SelectedTab == tabPage1 ? textEditorControl1 : textEditorControl2; + SetDocumentCodeType(editor, CodeType.JAVA); + } + + private void menuItemJsCode_Click(object sender, EventArgs e) + { + foreach (ToolStripItem item in menuItemConfig.DropDownItems) + { + ((ToolStripMenuItem)item).Checked = false; + } + menuItemJsCode.Checked = true; + TextEditorControl editor = tabControl1.SelectedTab == tabPage1 ? textEditorControl1 : textEditorControl2; + SetDocumentCodeType(editor, CodeType.JS); + } + + private void menuItemPhpCode_Click(object sender, EventArgs e) + { + foreach (ToolStripItem item in menuItemConfig.DropDownItems) + { + ((ToolStripMenuItem)item).Checked = false; + } + menuItemPhpCode.Checked = true; + TextEditorControl editor = tabControl1.SelectedTab == tabPage1 ? textEditorControl1 : textEditorControl2; + SetDocumentCodeType(editor, CodeType.PHP); + } + + private void menuItemTSQLCode_Click(object sender, EventArgs e) + { + foreach (ToolStripItem item in menuItemConfig.DropDownItems) + { + ((ToolStripMenuItem)item).Checked = false; + } + menuItemTSQLCode.Checked = true; + TextEditorControl editor = tabControl1.SelectedTab == tabPage1 ? textEditorControl1 : textEditorControl2; + SetDocumentCodeType(editor, CodeType.TSQL); + } + + private void menuItemVBCode_Click(object sender, EventArgs e) + { + foreach (ToolStripItem item in menuItemConfig.DropDownItems) + { + ((ToolStripMenuItem)item).Checked = false; + } + menuItemVBCode.Checked = true; + TextEditorControl editor = tabControl1.SelectedTab == tabPage1 ? textEditorControl1 : textEditorControl2; + SetDocumentCodeType(editor, CodeType.VB); + } + + private void menuItemXmlCode_Click(object sender, EventArgs e) + { + foreach (ToolStripItem item in menuItemConfig.DropDownItems) + { + ((ToolStripMenuItem)item).Checked = false; + } + menuItemXmlCode.Checked = true; + TextEditorControl editor = tabControl1.SelectedTab == tabPage1 ? textEditorControl1 : textEditorControl2; + SetDocumentCodeType(editor, CodeType.XML); + } + #endregion + + #region 处理编辑命令 + private void menuItemUndo_Click(object sender, EventArgs e) { Undo(tabControl1.SelectedTab == tabPage1 ? textEditorControl1 : textEditorControl2); } + private void menuItemRedo_Click(object sender, EventArgs e) { Redo(tabControl1.SelectedTab == tabPage1 ? textEditorControl1 : textEditorControl2); } + private void menuItemCut_Click(object sender, EventArgs e) { Cut(sender, e); } + private void menuItemCopy_Click(object sender, EventArgs e) { Copy(sender, e); } + private void menuItemPaste_Click(object sender, EventArgs e) { Paste(sender, e); } + private void menuItemDelete_Click(object sender, EventArgs e) { Delete(sender, e); } + private void menuItemSelectAll_Click(object sender, EventArgs e) { SelectAll(sender, e); } + + public void Undo(TextEditorControl editor) { editor.Undo(); } + public void Redo(TextEditorControl editor) { editor.Redo(); } + public void Cut(object sender, EventArgs e) { (tabControl1.SelectedTab == tabPage1 ? textEditorControl1 : textEditorControl2).ActiveTextAreaControl.TextArea.ClipboardHandler.Cut(sender, e); } + public void Copy(object sender, EventArgs e) { (tabControl1.SelectedTab == tabPage1 ? textEditorControl1 : textEditorControl2).ActiveTextAreaControl.TextArea.ClipboardHandler.Copy(sender, e); } + public void Paste(object sender, EventArgs e) { (tabControl1.SelectedTab == tabPage1 ? textEditorControl1 : textEditorControl2).ActiveTextAreaControl.TextArea.ClipboardHandler.Paste(sender, e); } + public void Delete(object sender, EventArgs e) { (tabControl1.SelectedTab == tabPage1 ? textEditorControl1 : textEditorControl2).ActiveTextAreaControl.TextArea.ClipboardHandler.Delete(sender, e); } + public void SelectAll(object sender, EventArgs e) { (tabControl1.SelectedTab == tabPage1 ? textEditorControl1 : textEditorControl2).ActiveTextAreaControl.TextArea.ClipboardHandler.SelectAll(sender, e); } + #endregion + + private void menuItemSave_Click(object sender, EventArgs e) + { + if (tabControl1.SelectedTab == tabPage1) + { + textEditorControl1.SaveFile(gbTemplateFile.Text); + } + else + { + SaveFileDialog dialog = new SaveFileDialog(); + dialog.Filter = "所有文件 (*.*)|*.*"; + dialog.FileName = Table.Name + CodeTypeHelper.GetExtention(_CodeType); + if (dialog.ShowDialog() == DialogResult.OK) + { + textEditorControl2.SaveFile(dialog.FileName); + } + } + } + + private void menuItemBuildCode_Click(object sender, EventArgs e) + { + DoBuildCode(); + } + + private void CodeBuilder_FormClosing(object sender, FormClosingEventArgs e) + { + base.MainForm.HideBuildCodeIcon(); + } + + //protected override void CloseDockToolWindow() + //{ + // base.MainForm.HideBuildCodeIcon(); + // //base.CloseDockToolWindow(); + // this.Hide(); + //} + + private void dataGridView1_CellMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e) + { + if (e.RowIndex != -1) + { + bool val = (bool)dataGridView1.Rows[e.RowIndex].Cells[0].Value; + dataGridView1.Rows[e.RowIndex].Cells[0].Value = !val; + } + } + + private void menuItemCheckAll_Click(object sender, EventArgs e) + { + dataGridView1.RefreshEdit(); + foreach (DataGridViewRow row in dataGridView1.Rows) + { + DataGridViewCheckBoxCell cell = row.Cells[0] as DataGridViewCheckBoxCell; + cell.Value = true; + } + } + + private void menuItemUnCheckAll_Click(object sender, EventArgs e) + { + dataGridView1.RefreshEdit(); + foreach (DataGridViewRow row in dataGridView1.Rows) + { + DataGridViewCheckBoxCell cell = row.Cells[0] as DataGridViewCheckBoxCell; + cell.Value = !(bool)cell.Value; + } + } + + + + } +} diff --git a/src/Kalman.Studio/CodeBuilder/CodeBuilder.designer.cs b/src/Kalman.Studio/CodeBuilder/CodeBuilder.designer.cs new file mode 100644 index 0000000..dfdae9a --- /dev/null +++ b/src/Kalman.Studio/CodeBuilder/CodeBuilder.designer.cs @@ -0,0 +1,731 @@ +namespace Kalman.Studio +{ + partial class CodeBuilder + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle2 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle3 = new System.Windows.Forms.DataGridViewCellStyle(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(CodeBuilder)); + this.tabControl1 = new System.Windows.Forms.TabControl(); + this.tabPage1 = new System.Windows.Forms.TabPage(); + this.splitContainer1 = new System.Windows.Forms.SplitContainer(); + this.gbObjName = new System.Windows.Forms.GroupBox(); + this.dataGridView1 = new System.Windows.Forms.DataGridView(); + this.cmsGrid = new System.Windows.Forms.ContextMenuStrip(this.components); + this.menuItemCheckAll = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemUnCheckAll = new System.Windows.Forms.ToolStripMenuItem(); + this.splitContainer2 = new System.Windows.Forms.SplitContainer(); + this.gbTemplateList = new System.Windows.Forms.GroupBox(); + this.tvTemplate = new System.Windows.Forms.TreeView(); + this.imgList = new System.Windows.Forms.ImageList(this.components); + this.gbTemplateFile = new System.Windows.Forms.GroupBox(); + this.textEditorControl1 = new ICSharpCode.TextEditor.TextEditorControl(); + this.cms = new System.Windows.Forms.ContextMenuStrip(this.components); + this.menuItemUndo = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemRedo = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator(); + this.menuItemCut = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemCopy = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemPaste = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemDelete = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); + this.menuItemSelectAll = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); + this.menuItemConfig = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemAspxCode = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemCppCode = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemCSharpCode = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemHtmlCode = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemJavaCode = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemJsCode = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemPhpCode = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemTSQLCode = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemVBCode = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemXmlCode = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemSave = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemBuildCode = new System.Windows.Forms.ToolStripMenuItem(); + this.tabPage2 = new System.Windows.Forms.TabPage(); + this.textEditorControl2 = new ICSharpCode.TextEditor.TextEditorControl(); + this.cmsTree = new System.Windows.Forms.ContextMenuStrip(this.components); + this.menuItemRefresh = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemManage = new System.Windows.Forms.ToolStripMenuItem(); + this.colSelect = new System.Windows.Forms.DataGridViewCheckBoxColumn(); + this.colName = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colPK = new System.Windows.Forms.DataGridViewCheckBoxColumn(); + this.colIdentify = new System.Windows.Forms.DataGridViewCheckBoxColumn(); + this.colAllowDBNull = new System.Windows.Forms.DataGridViewCheckBoxColumn(); + this.colNativeType = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colLength = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colPrecision = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colScale = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colDefaultValue = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colDescription = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.tabControl1.SuspendLayout(); + this.tabPage1.SuspendLayout(); + this.splitContainer1.Panel1.SuspendLayout(); + this.splitContainer1.Panel2.SuspendLayout(); + this.splitContainer1.SuspendLayout(); + this.gbObjName.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit(); + this.cmsGrid.SuspendLayout(); + this.splitContainer2.Panel1.SuspendLayout(); + this.splitContainer2.Panel2.SuspendLayout(); + this.splitContainer2.SuspendLayout(); + this.gbTemplateList.SuspendLayout(); + this.gbTemplateFile.SuspendLayout(); + this.cms.SuspendLayout(); + this.tabPage2.SuspendLayout(); + this.cmsTree.SuspendLayout(); + this.SuspendLayout(); + // + // tabControl1 + // + this.tabControl1.Alignment = System.Windows.Forms.TabAlignment.Bottom; + this.tabControl1.Controls.Add(this.tabPage1); + this.tabControl1.Controls.Add(this.tabPage2); + this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill; + this.tabControl1.Location = new System.Drawing.Point(0, 0); + this.tabControl1.Multiline = true; + this.tabControl1.Name = "tabControl1"; + this.tabControl1.SelectedIndex = 0; + this.tabControl1.Size = new System.Drawing.Size(679, 485); + this.tabControl1.TabIndex = 0; + // + // tabPage1 + // + this.tabPage1.Controls.Add(this.splitContainer1); + this.tabPage1.Location = new System.Drawing.Point(4, 4); + this.tabPage1.Name = "tabPage1"; + this.tabPage1.Padding = new System.Windows.Forms.Padding(3); + this.tabPage1.Size = new System.Drawing.Size(671, 460); + this.tabPage1.TabIndex = 0; + this.tabPage1.Text = "模板"; + this.tabPage1.UseVisualStyleBackColor = true; + // + // splitContainer1 + // + this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill; + this.splitContainer1.Location = new System.Drawing.Point(3, 3); + this.splitContainer1.Name = "splitContainer1"; + this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal; + // + // splitContainer1.Panel1 + // + this.splitContainer1.Panel1.Controls.Add(this.gbObjName); + // + // splitContainer1.Panel2 + // + this.splitContainer1.Panel2.Controls.Add(this.splitContainer2); + this.splitContainer1.Size = new System.Drawing.Size(665, 454); + this.splitContainer1.SplitterDistance = 201; + this.splitContainer1.TabIndex = 0; + // + // gbObjName + // + this.gbObjName.Controls.Add(this.dataGridView1); + this.gbObjName.Dock = System.Windows.Forms.DockStyle.Fill; + this.gbObjName.Location = new System.Drawing.Point(0, 0); + this.gbObjName.Name = "gbObjName"; + this.gbObjName.Size = new System.Drawing.Size(665, 201); + this.gbObjName.TabIndex = 1; + this.gbObjName.TabStop = false; + this.gbObjName.Text = "groupBox1"; + // + // dataGridView1 + // + this.dataGridView1.AllowUserToAddRows = false; + this.dataGridView1.AllowUserToDeleteRows = false; + this.dataGridView1.AllowUserToResizeRows = false; + dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle1.BackColor = System.Drawing.SystemColors.Control; + dataGridViewCellStyle1.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + dataGridViewCellStyle1.ForeColor = System.Drawing.SystemColors.WindowText; + dataGridViewCellStyle1.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle1.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle1.WrapMode = System.Windows.Forms.DataGridViewTriState.True; + this.dataGridView1.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle1; + this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.dataGridView1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { + this.colSelect, + this.colName, + this.colPK, + this.colIdentify, + this.colAllowDBNull, + this.colNativeType, + this.colLength, + this.colPrecision, + this.colScale, + this.colDefaultValue, + this.colDescription}); + this.dataGridView1.ContextMenuStrip = this.cmsGrid; + dataGridViewCellStyle2.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle2.BackColor = System.Drawing.SystemColors.Window; + dataGridViewCellStyle2.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + dataGridViewCellStyle2.ForeColor = System.Drawing.SystemColors.ControlText; + dataGridViewCellStyle2.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle2.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle2.WrapMode = System.Windows.Forms.DataGridViewTriState.False; + this.dataGridView1.DefaultCellStyle = dataGridViewCellStyle2; + this.dataGridView1.Dock = System.Windows.Forms.DockStyle.Fill; + this.dataGridView1.Location = new System.Drawing.Point(3, 17); + this.dataGridView1.MultiSelect = false; + this.dataGridView1.Name = "dataGridView1"; + dataGridViewCellStyle3.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle3.BackColor = System.Drawing.SystemColors.Control; + dataGridViewCellStyle3.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + dataGridViewCellStyle3.ForeColor = System.Drawing.SystemColors.WindowText; + dataGridViewCellStyle3.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle3.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle3.WrapMode = System.Windows.Forms.DataGridViewTriState.True; + this.dataGridView1.RowHeadersDefaultCellStyle = dataGridViewCellStyle3; + this.dataGridView1.RowHeadersVisible = false; + this.dataGridView1.RowTemplate.Height = 23; + this.dataGridView1.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect; + this.dataGridView1.Size = new System.Drawing.Size(659, 181); + this.dataGridView1.TabIndex = 0; + this.dataGridView1.CellMouseDoubleClick += new System.Windows.Forms.DataGridViewCellMouseEventHandler(this.dataGridView1_CellMouseDoubleClick); + // + // cmsGrid + // + this.cmsGrid.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.menuItemCheckAll, + this.menuItemUnCheckAll}); + this.cmsGrid.Name = "cmsGrid"; + this.cmsGrid.Size = new System.Drawing.Size(154, 48); + // + // menuItemCheckAll + // + this.menuItemCheckAll.Name = "menuItemCheckAll"; + this.menuItemCheckAll.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.A))); + this.menuItemCheckAll.Size = new System.Drawing.Size(153, 22); + this.menuItemCheckAll.Text = "全选(&A)"; + this.menuItemCheckAll.Click += new System.EventHandler(this.menuItemCheckAll_Click); + // + // menuItemUnCheckAll + // + this.menuItemUnCheckAll.Name = "menuItemUnCheckAll"; + this.menuItemUnCheckAll.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.U))); + this.menuItemUnCheckAll.Size = new System.Drawing.Size(153, 22); + this.menuItemUnCheckAll.Text = "反选(&U)"; + this.menuItemUnCheckAll.Click += new System.EventHandler(this.menuItemUnCheckAll_Click); + // + // splitContainer2 + // + this.splitContainer2.Dock = System.Windows.Forms.DockStyle.Fill; + this.splitContainer2.FixedPanel = System.Windows.Forms.FixedPanel.Panel1; + this.splitContainer2.Location = new System.Drawing.Point(0, 0); + this.splitContainer2.Name = "splitContainer2"; + // + // splitContainer2.Panel1 + // + this.splitContainer2.Panel1.Controls.Add(this.gbTemplateList); + // + // splitContainer2.Panel2 + // + this.splitContainer2.Panel2.Controls.Add(this.gbTemplateFile); + this.splitContainer2.Size = new System.Drawing.Size(665, 249); + this.splitContainer2.SplitterDistance = 192; + this.splitContainer2.TabIndex = 0; + // + // gbTemplateList + // + this.gbTemplateList.Controls.Add(this.tvTemplate); + this.gbTemplateList.Dock = System.Windows.Forms.DockStyle.Fill; + this.gbTemplateList.Location = new System.Drawing.Point(0, 0); + this.gbTemplateList.Name = "gbTemplateList"; + this.gbTemplateList.Size = new System.Drawing.Size(192, 249); + this.gbTemplateList.TabIndex = 1; + this.gbTemplateList.TabStop = false; + this.gbTemplateList.Text = "代码模板"; + // + // tvTemplate + // + this.tvTemplate.Dock = System.Windows.Forms.DockStyle.Fill; + this.tvTemplate.ImageIndex = 0; + this.tvTemplate.ImageList = this.imgList; + this.tvTemplate.Location = new System.Drawing.Point(3, 17); + this.tvTemplate.Name = "tvTemplate"; + this.tvTemplate.SelectedImageIndex = 0; + this.tvTemplate.Size = new System.Drawing.Size(186, 229); + this.tvTemplate.TabIndex = 0; + this.tvTemplate.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.tvTemplate_MouseDoubleClick); + this.tvTemplate.MouseClick += new System.Windows.Forms.MouseEventHandler(this.tvTemplate_MouseClick); + // + // imgList + // + this.imgList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imgList.ImageStream"))); + this.imgList.TransparentColor = System.Drawing.Color.Transparent; + this.imgList.Images.SetKeyName(0, "templateRoot.png"); + this.imgList.Images.SetKeyName(1, "templateDir.png"); + this.imgList.Images.SetKeyName(2, "templateFile.png"); + // + // gbTemplateFile + // + this.gbTemplateFile.Controls.Add(this.textEditorControl1); + this.gbTemplateFile.Dock = System.Windows.Forms.DockStyle.Fill; + this.gbTemplateFile.Location = new System.Drawing.Point(0, 0); + this.gbTemplateFile.Name = "gbTemplateFile"; + this.gbTemplateFile.Size = new System.Drawing.Size(469, 249); + this.gbTemplateFile.TabIndex = 2; + this.gbTemplateFile.TabStop = false; + this.gbTemplateFile.Text = "模板预览"; + // + // textEditorControl1 + // + this.textEditorControl1.ContextMenuStrip = this.cms; + this.textEditorControl1.Dock = System.Windows.Forms.DockStyle.Fill; + this.textEditorControl1.IsReadOnly = false; + this.textEditorControl1.Location = new System.Drawing.Point(3, 17); + this.textEditorControl1.Name = "textEditorControl1"; + this.textEditorControl1.Size = new System.Drawing.Size(463, 229); + this.textEditorControl1.TabIndex = 1; + // + // cms + // + this.cms.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.menuItemUndo, + this.menuItemRedo, + this.toolStripSeparator5, + this.menuItemCut, + this.menuItemCopy, + this.menuItemPaste, + this.menuItemDelete, + this.toolStripSeparator1, + this.menuItemSelectAll, + this.toolStripSeparator2, + this.menuItemConfig, + this.menuItemSave, + this.menuItemBuildCode}); + this.cms.Name = "cms"; + this.cms.Size = new System.Drawing.Size(154, 242); + // + // menuItemUndo + // + this.menuItemUndo.Image = ((System.Drawing.Image)(resources.GetObject("menuItemUndo.Image"))); + this.menuItemUndo.Name = "menuItemUndo"; + this.menuItemUndo.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Z))); + this.menuItemUndo.Size = new System.Drawing.Size(153, 22); + this.menuItemUndo.Text = "撤销(&Z)"; + this.menuItemUndo.Click += new System.EventHandler(this.menuItemUndo_Click); + // + // menuItemRedo + // + this.menuItemRedo.Image = ((System.Drawing.Image)(resources.GetObject("menuItemRedo.Image"))); + this.menuItemRedo.Name = "menuItemRedo"; + this.menuItemRedo.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Y))); + this.menuItemRedo.Size = new System.Drawing.Size(153, 22); + this.menuItemRedo.Text = "重复(&R)"; + this.menuItemRedo.Click += new System.EventHandler(this.menuItemRedo_Click); + // + // toolStripSeparator5 + // + this.toolStripSeparator5.Name = "toolStripSeparator5"; + this.toolStripSeparator5.Size = new System.Drawing.Size(150, 6); + // + // menuItemCut + // + this.menuItemCut.Image = ((System.Drawing.Image)(resources.GetObject("menuItemCut.Image"))); + this.menuItemCut.Name = "menuItemCut"; + this.menuItemCut.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.X))); + this.menuItemCut.Size = new System.Drawing.Size(153, 22); + this.menuItemCut.Text = "剪切(&X)"; + this.menuItemCut.Click += new System.EventHandler(this.menuItemCut_Click); + // + // menuItemCopy + // + this.menuItemCopy.Image = ((System.Drawing.Image)(resources.GetObject("menuItemCopy.Image"))); + this.menuItemCopy.Name = "menuItemCopy"; + this.menuItemCopy.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.C))); + this.menuItemCopy.Size = new System.Drawing.Size(153, 22); + this.menuItemCopy.Text = "复制(&C)"; + this.menuItemCopy.Click += new System.EventHandler(this.menuItemCopy_Click); + // + // menuItemPaste + // + this.menuItemPaste.Image = ((System.Drawing.Image)(resources.GetObject("menuItemPaste.Image"))); + this.menuItemPaste.Name = "menuItemPaste"; + this.menuItemPaste.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.V))); + this.menuItemPaste.Size = new System.Drawing.Size(153, 22); + this.menuItemPaste.Text = "粘贴(&V)"; + this.menuItemPaste.Click += new System.EventHandler(this.menuItemPaste_Click); + // + // menuItemDelete + // + this.menuItemDelete.Image = ((System.Drawing.Image)(resources.GetObject("menuItemDelete.Image"))); + this.menuItemDelete.Name = "menuItemDelete"; + this.menuItemDelete.ShortcutKeys = System.Windows.Forms.Keys.Delete; + this.menuItemDelete.Size = new System.Drawing.Size(153, 22); + this.menuItemDelete.Text = "删除(&D)"; + this.menuItemDelete.Click += new System.EventHandler(this.menuItemDelete_Click); + // + // toolStripSeparator1 + // + this.toolStripSeparator1.Name = "toolStripSeparator1"; + this.toolStripSeparator1.Size = new System.Drawing.Size(150, 6); + // + // menuItemSelectAll + // + this.menuItemSelectAll.Name = "menuItemSelectAll"; + this.menuItemSelectAll.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.A))); + this.menuItemSelectAll.Size = new System.Drawing.Size(153, 22); + this.menuItemSelectAll.Text = "全选(&A)"; + this.menuItemSelectAll.Click += new System.EventHandler(this.menuItemSelectAll_Click); + // + // toolStripSeparator2 + // + this.toolStripSeparator2.Name = "toolStripSeparator2"; + this.toolStripSeparator2.Size = new System.Drawing.Size(150, 6); + // + // menuItemConfig + // + this.menuItemConfig.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.menuItemAspxCode, + this.menuItemCppCode, + this.menuItemCSharpCode, + this.menuItemHtmlCode, + this.menuItemJavaCode, + this.menuItemJsCode, + this.menuItemPhpCode, + this.menuItemTSQLCode, + this.menuItemVBCode, + this.menuItemXmlCode}); + this.menuItemConfig.Name = "menuItemConfig"; + this.menuItemConfig.Size = new System.Drawing.Size(153, 22); + this.menuItemConfig.Text = "选择配置"; + // + // menuItemAspxCode + // + this.menuItemAspxCode.Name = "menuItemAspxCode"; + this.menuItemAspxCode.Size = new System.Drawing.Size(130, 22); + this.menuItemAspxCode.Text = "Aspx"; + this.menuItemAspxCode.Click += new System.EventHandler(this.menuItemAspxCode_Click); + // + // menuItemCppCode + // + this.menuItemCppCode.Name = "menuItemCppCode"; + this.menuItemCppCode.Size = new System.Drawing.Size(130, 22); + this.menuItemCppCode.Text = "C/C++"; + this.menuItemCppCode.Click += new System.EventHandler(this.menuItemCppCode_Click); + // + // menuItemCSharpCode + // + this.menuItemCSharpCode.Name = "menuItemCSharpCode"; + this.menuItemCSharpCode.Size = new System.Drawing.Size(130, 22); + this.menuItemCSharpCode.Text = "C#"; + this.menuItemCSharpCode.Click += new System.EventHandler(this.menuItemCSharpCode_Click); + // + // menuItemHtmlCode + // + this.menuItemHtmlCode.Name = "menuItemHtmlCode"; + this.menuItemHtmlCode.Size = new System.Drawing.Size(130, 22); + this.menuItemHtmlCode.Text = "Html"; + this.menuItemHtmlCode.Click += new System.EventHandler(this.menuItemHtmlCode_Click); + // + // menuItemJavaCode + // + this.menuItemJavaCode.Name = "menuItemJavaCode"; + this.menuItemJavaCode.Size = new System.Drawing.Size(130, 22); + this.menuItemJavaCode.Text = "Java"; + this.menuItemJavaCode.Click += new System.EventHandler(this.menuItemJavaCode_Click); + // + // menuItemJsCode + // + this.menuItemJsCode.Name = "menuItemJsCode"; + this.menuItemJsCode.Size = new System.Drawing.Size(130, 22); + this.menuItemJsCode.Text = "Javascript"; + this.menuItemJsCode.Click += new System.EventHandler(this.menuItemJsCode_Click); + // + // menuItemPhpCode + // + this.menuItemPhpCode.Name = "menuItemPhpCode"; + this.menuItemPhpCode.Size = new System.Drawing.Size(130, 22); + this.menuItemPhpCode.Text = "PHP"; + this.menuItemPhpCode.Click += new System.EventHandler(this.menuItemPhpCode_Click); + // + // menuItemTSQLCode + // + this.menuItemTSQLCode.Name = "menuItemTSQLCode"; + this.menuItemTSQLCode.Size = new System.Drawing.Size(130, 22); + this.menuItemTSQLCode.Text = "TSQL"; + this.menuItemTSQLCode.Click += new System.EventHandler(this.menuItemTSQLCode_Click); + // + // menuItemVBCode + // + this.menuItemVBCode.Name = "menuItemVBCode"; + this.menuItemVBCode.Size = new System.Drawing.Size(130, 22); + this.menuItemVBCode.Text = "VB.NET"; + this.menuItemVBCode.Click += new System.EventHandler(this.menuItemVBCode_Click); + // + // menuItemXmlCode + // + this.menuItemXmlCode.Name = "menuItemXmlCode"; + this.menuItemXmlCode.Size = new System.Drawing.Size(130, 22); + this.menuItemXmlCode.Text = "XML"; + this.menuItemXmlCode.Click += new System.EventHandler(this.menuItemXmlCode_Click); + // + // menuItemSave + // + this.menuItemSave.Image = ((System.Drawing.Image)(resources.GetObject("menuItemSave.Image"))); + this.menuItemSave.Name = "menuItemSave"; + this.menuItemSave.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.S))); + this.menuItemSave.Size = new System.Drawing.Size(153, 22); + this.menuItemSave.Text = "保存(&S)"; + this.menuItemSave.Click += new System.EventHandler(this.menuItemSave_Click); + // + // menuItemBuildCode + // + this.menuItemBuildCode.Name = "menuItemBuildCode"; + this.menuItemBuildCode.ShortcutKeys = System.Windows.Forms.Keys.F5; + this.menuItemBuildCode.Size = new System.Drawing.Size(153, 22); + this.menuItemBuildCode.Text = "生成代码"; + this.menuItemBuildCode.Click += new System.EventHandler(this.menuItemBuildCode_Click); + // + // tabPage2 + // + this.tabPage2.Controls.Add(this.textEditorControl2); + this.tabPage2.Location = new System.Drawing.Point(4, 4); + this.tabPage2.Name = "tabPage2"; + this.tabPage2.Padding = new System.Windows.Forms.Padding(3); + this.tabPage2.Size = new System.Drawing.Size(671, 460); + this.tabPage2.TabIndex = 1; + this.tabPage2.Text = "代码"; + this.tabPage2.UseVisualStyleBackColor = true; + // + // textEditorControl2 + // + this.textEditorControl2.ContextMenuStrip = this.cms; + this.textEditorControl2.Dock = System.Windows.Forms.DockStyle.Fill; + this.textEditorControl2.IsReadOnly = false; + this.textEditorControl2.Location = new System.Drawing.Point(3, 3); + this.textEditorControl2.Name = "textEditorControl2"; + this.textEditorControl2.Size = new System.Drawing.Size(665, 454); + this.textEditorControl2.TabIndex = 1; + // + // cmsTree + // + this.cmsTree.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.menuItemRefresh, + this.menuItemManage}); + this.cmsTree.Name = "cmsTree"; + this.cmsTree.Size = new System.Drawing.Size(119, 48); + // + // menuItemRefresh + // + this.menuItemRefresh.Name = "menuItemRefresh"; + this.menuItemRefresh.Size = new System.Drawing.Size(118, 22); + this.menuItemRefresh.Text = "刷新"; + this.menuItemRefresh.Click += new System.EventHandler(this.menuItemRefresh_Click); + // + // menuItemManage + // + this.menuItemManage.Name = "menuItemManage"; + this.menuItemManage.Size = new System.Drawing.Size(118, 22); + this.menuItemManage.Text = "模板管理"; + this.menuItemManage.Click += new System.EventHandler(this.menuItemManage_Click); + // + // colSelect + // + this.colSelect.HeaderText = "选择"; + this.colSelect.MinimumWidth = 50; + this.colSelect.Name = "colSelect"; + this.colSelect.Width = 50; + // + // colName + // + this.colName.DataPropertyName = "Name"; + this.colName.HeaderText = "字段名"; + this.colName.Name = "colName"; + this.colName.Width = 160; + // + // colPK + // + this.colPK.DataPropertyName = "PrimaryKey"; + this.colPK.HeaderText = "P"; + this.colPK.Name = "colPK"; + this.colPK.ReadOnly = true; + this.colPK.Resizable = System.Windows.Forms.DataGridViewTriState.True; + this.colPK.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic; + this.colPK.ToolTipText = "是否为主键"; + this.colPK.Width = 25; + // + // colIdentify + // + this.colIdentify.DataPropertyName = "Identify"; + this.colIdentify.HeaderText = "I"; + this.colIdentify.Name = "colIdentify"; + this.colIdentify.ReadOnly = true; + this.colIdentify.Resizable = System.Windows.Forms.DataGridViewTriState.True; + this.colIdentify.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic; + this.colIdentify.ToolTipText = "是否为标识列"; + this.colIdentify.Width = 25; + // + // colAllowDBNull + // + this.colAllowDBNull.DataPropertyName = "Nullable"; + this.colAllowDBNull.HeaderText = "N"; + this.colAllowDBNull.Name = "colAllowDBNull"; + this.colAllowDBNull.ReadOnly = true; + this.colAllowDBNull.Resizable = System.Windows.Forms.DataGridViewTriState.True; + this.colAllowDBNull.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic; + this.colAllowDBNull.ToolTipText = "是否允许为空"; + this.colAllowDBNull.Width = 25; + // + // colNativeType + // + this.colNativeType.DataPropertyName = "NativeType"; + this.colNativeType.HeaderText = "数据类型"; + this.colNativeType.Name = "colNativeType"; + this.colNativeType.ToolTipText = "数据库定义的数据类型"; + this.colNativeType.Width = 120; + // + // colLength + // + this.colLength.DataPropertyName = "Length"; + this.colLength.HeaderText = "长度"; + this.colLength.Name = "colLength"; + this.colLength.Width = 60; + // + // colPrecision + // + this.colPrecision.DataPropertyName = "Precision"; + this.colPrecision.HeaderText = "精度"; + this.colPrecision.Name = "colPrecision"; + this.colPrecision.Width = 60; + // + // colScale + // + this.colScale.DataPropertyName = "Scale"; + this.colScale.HeaderText = "小数"; + this.colScale.Name = "colScale"; + this.colScale.ToolTipText = "小数位数"; + this.colScale.Width = 60; + // + // colDefaultValue + // + this.colDefaultValue.DataPropertyName = "DefaultValue"; + this.colDefaultValue.HeaderText = "默认值"; + this.colDefaultValue.Name = "colDefaultValue"; + this.colDefaultValue.Width = 80; + // + // colDescription + // + this.colDescription.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; + this.colDescription.DataPropertyName = "Comment"; + this.colDescription.HeaderText = "注释"; + this.colDescription.Name = "colDescription"; + // + // CodeBuilder + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(679, 485); + this.Controls.Add(this.tabControl1); + this.Name = "CodeBuilder"; + this.Text = "代码生成器"; + this.Load += new System.EventHandler(this.CodeBuilder_Load); + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.CodeBuilder_FormClosing); + this.tabControl1.ResumeLayout(false); + this.tabPage1.ResumeLayout(false); + this.splitContainer1.Panel1.ResumeLayout(false); + this.splitContainer1.Panel2.ResumeLayout(false); + this.splitContainer1.ResumeLayout(false); + this.gbObjName.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit(); + this.cmsGrid.ResumeLayout(false); + this.splitContainer2.Panel1.ResumeLayout(false); + this.splitContainer2.Panel2.ResumeLayout(false); + this.splitContainer2.ResumeLayout(false); + this.gbTemplateList.ResumeLayout(false); + this.gbTemplateFile.ResumeLayout(false); + this.cms.ResumeLayout(false); + this.tabPage2.ResumeLayout(false); + this.cmsTree.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.TabControl tabControl1; + private System.Windows.Forms.TabPage tabPage1; + private System.Windows.Forms.TabPage tabPage2; + private System.Windows.Forms.SplitContainer splitContainer1; + private System.Windows.Forms.DataGridView dataGridView1; + private System.Windows.Forms.SplitContainer splitContainer2; + private System.Windows.Forms.TreeView tvTemplate; + private ICSharpCode.TextEditor.TextEditorControl textEditorControl1; + private ICSharpCode.TextEditor.TextEditorControl textEditorControl2; + private System.Windows.Forms.GroupBox gbObjName; + private System.Windows.Forms.GroupBox gbTemplateList; + private System.Windows.Forms.GroupBox gbTemplateFile; + private System.Windows.Forms.ImageList imgList; + private System.Windows.Forms.ContextMenuStrip cms; + private System.Windows.Forms.ToolStripMenuItem menuItemUndo; + private System.Windows.Forms.ToolStripMenuItem menuItemRedo; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator5; + private System.Windows.Forms.ToolStripMenuItem menuItemCut; + private System.Windows.Forms.ToolStripMenuItem menuItemCopy; + private System.Windows.Forms.ToolStripMenuItem menuItemPaste; + private System.Windows.Forms.ToolStripMenuItem menuItemDelete; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; + private System.Windows.Forms.ToolStripMenuItem menuItemSelectAll; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator2; + private System.Windows.Forms.ToolStripMenuItem menuItemConfig; + private System.Windows.Forms.ToolStripMenuItem menuItemAspxCode; + private System.Windows.Forms.ToolStripMenuItem menuItemCppCode; + private System.Windows.Forms.ToolStripMenuItem menuItemCSharpCode; + private System.Windows.Forms.ToolStripMenuItem menuItemHtmlCode; + private System.Windows.Forms.ToolStripMenuItem menuItemJavaCode; + private System.Windows.Forms.ToolStripMenuItem menuItemJsCode; + private System.Windows.Forms.ToolStripMenuItem menuItemPhpCode; + private System.Windows.Forms.ToolStripMenuItem menuItemTSQLCode; + private System.Windows.Forms.ToolStripMenuItem menuItemVBCode; + private System.Windows.Forms.ToolStripMenuItem menuItemXmlCode; + private System.Windows.Forms.ToolStripMenuItem menuItemSave; + private System.Windows.Forms.ToolStripMenuItem menuItemBuildCode; + private System.Windows.Forms.ContextMenuStrip cmsGrid; + private System.Windows.Forms.ToolStripMenuItem menuItemCheckAll; + private System.Windows.Forms.ToolStripMenuItem menuItemUnCheckAll; + private System.Windows.Forms.ContextMenuStrip cmsTree; + private System.Windows.Forms.ToolStripMenuItem menuItemRefresh; + private System.Windows.Forms.ToolStripMenuItem menuItemManage; + private System.Windows.Forms.DataGridViewCheckBoxColumn colSelect; + private System.Windows.Forms.DataGridViewTextBoxColumn colName; + private System.Windows.Forms.DataGridViewCheckBoxColumn colPK; + private System.Windows.Forms.DataGridViewCheckBoxColumn colIdentify; + private System.Windows.Forms.DataGridViewCheckBoxColumn colAllowDBNull; + private System.Windows.Forms.DataGridViewTextBoxColumn colNativeType; + private System.Windows.Forms.DataGridViewTextBoxColumn colLength; + private System.Windows.Forms.DataGridViewTextBoxColumn colPrecision; + private System.Windows.Forms.DataGridViewTextBoxColumn colScale; + private System.Windows.Forms.DataGridViewTextBoxColumn colDefaultValue; + private System.Windows.Forms.DataGridViewTextBoxColumn colDescription; + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/CodeBuilder/CodeBuilder.resx b/src/Kalman.Studio/CodeBuilder/CodeBuilder.resx new file mode 100644 index 0000000..4c9cb01 --- /dev/null +++ b/src/Kalman.Studio/CodeBuilder/CodeBuilder.resx @@ -0,0 +1,306 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + 182, 17 + + + 17, 17 + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj0yLjAuMC4w + LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 + ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAACK + CgAAAk1TRnQBSQFMAgEBAwEAAQQBAAEEAQABEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo + AwABQAMAARADAAEBAQABCAYAAQQYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA + AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5 + AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA + AWYDAAGZAwABzAIAATMDAAIzAgABMwFmAgABMwGZAgABMwHMAgABMwH/AgABZgMAAWYBMwIAAmYCAAFm + AZkCAAFmAcwCAAFmAf8CAAGZAwABmQEzAgABmQFmAgACmQIAAZkBzAIAAZkB/wIAAcwDAAHMATMCAAHM + AWYCAAHMAZkCAALMAgABzAH/AgAB/wFmAgAB/wGZAgAB/wHMAQABMwH/AgAB/wEAATMBAAEzAQABZgEA + ATMBAAGZAQABMwEAAcwBAAEzAQAB/wEAAf8BMwIAAzMBAAIzAWYBAAIzAZkBAAIzAcwBAAIzAf8BAAEz + AWYCAAEzAWYBMwEAATMCZgEAATMBZgGZAQABMwFmAcwBAAEzAWYB/wEAATMBmQIAATMBmQEzAQABMwGZ + AWYBAAEzApkBAAEzAZkBzAEAATMBmQH/AQABMwHMAgABMwHMATMBAAEzAcwBZgEAATMBzAGZAQABMwLM + AQABMwHMAf8BAAEzAf8BMwEAATMB/wFmAQABMwH/AZkBAAEzAf8BzAEAATMC/wEAAWYDAAFmAQABMwEA + AWYBAAFmAQABZgEAAZkBAAFmAQABzAEAAWYBAAH/AQABZgEzAgABZgIzAQABZgEzAWYBAAFmATMBmQEA + AWYBMwHMAQABZgEzAf8BAAJmAgACZgEzAQADZgEAAmYBmQEAAmYBzAEAAWYBmQIAAWYBmQEzAQABZgGZ + AWYBAAFmApkBAAFmAZkBzAEAAWYBmQH/AQABZgHMAgABZgHMATMBAAFmAcwBmQEAAWYCzAEAAWYBzAH/ + AQABZgH/AgABZgH/ATMBAAFmAf8BmQEAAWYB/wHMAQABzAEAAf8BAAH/AQABzAEAApkCAAGZATMBmQEA + AZkBAAGZAQABmQEAAcwBAAGZAwABmQIzAQABmQEAAWYBAAGZATMBzAEAAZkBAAH/AQABmQFmAgABmQFm + ATMBAAGZATMBZgEAAZkBZgGZAQABmQFmAcwBAAGZATMB/wEAApkBMwEAApkBZgEAA5kBAAKZAcwBAAKZ + Af8BAAGZAcwCAAGZAcwBMwEAAWYBzAFmAQABmQHMAZkBAAGZAswBAAGZAcwB/wEAAZkB/wIAAZkB/wEz + AQABmQHMAWYBAAGZAf8BmQEAAZkB/wHMAQABmQL/AQABzAMAAZkBAAEzAQABzAEAAWYBAAHMAQABmQEA + AcwBAAHMAQABmQEzAgABzAIzAQABzAEzAWYBAAHMATMBmQEAAcwBMwHMAQABzAEzAf8BAAHMAWYCAAHM + AWYBMwEAAZkCZgEAAcwBZgGZAQABzAFmAcwBAAGZAWYB/wEAAcwBmQIAAcwBmQEzAQABzAGZAWYBAAHM + ApkBAAHMAZkBzAEAAcwBmQH/AQACzAIAAswBMwEAAswBZgEAAswBmQEAA8wBAALMAf8BAAHMAf8CAAHM + Af8BMwEAAZkB/wFmAQABzAH/AZkBAAHMAf8BzAEAAcwC/wEAAcwBAAEzAQAB/wEAAWYBAAH/AQABmQEA + AcwBMwIAAf8CMwEAAf8BMwFmAQAB/wEzAZkBAAH/ATMBzAEAAf8BMwH/AQAB/wFmAgAB/wFmATMBAAHM + AmYBAAH/AWYBmQEAAf8BZgHMAQABzAFmAf8BAAH/AZkCAAH/AZkBMwEAAf8BmQFmAQAB/wKZAQAB/wGZ + AcwBAAH/AZkB/wEAAf8BzAIAAf8BzAEzAQAB/wHMAWYBAAH/AcwBmQEAAf8CzAEAAf8BzAH/AQAC/wEz + AQABzAH/AWYBAAL/AZkBAAL/AcwBAAJmAf8BAAFmAf8BZgEAAWYC/wEAAf8CZgEAAf8BZgH/AQAC/wFm + AQABIQEAAaUBAANfAQADdwEAA4YBAAOWAQADywEAA7IBAAPXAQAD3QEAA+MBAAPqAQAD8QEAA/gBAAHw + AfsB/wEAAaQCoAEAA4ADAAH/AgAB/wMAAv8BAAH/AwAB/wEAAf8BAAL/AgAD/wsAASoBKRkAAioB8QEH + AZIBrgFsARIDZhcAAVEBKQEcATEBMAF0ASkBcxMAAyoBmgF6AyoB8wEJAbsCtQFmEAABBwOuAewB7wG8 + ASkBegEpAnoBKQGgASkB7wcAAbUIZgEAAUsBeQExASoBmgF6ASoBMQF5ASoB8wEZAd0BtQFmEAAB9wH/ + BPMB9AGZASkBegIqAaABKQGZAfEHAAG1Af8F9AEZAWYBAAFLAXkBMQEqAZoBegEqATEBeQEqAfMBBwG7 + AbUBZhAAAfcF/wEwASkBegEpAv8BKgGgATABKQQAAbUCZgG1Af8CtQH/AbUBtAH0AWYCSwGaAXoBUgF6 + AXkBUgJ6AioB8wEZAbUBZhAAAfcF/wExATABegEpAv8BKgF6ATEBMAQAAbUB/wH0AbUE/wP0AWYBSwEx + ASoBmgGgBJoBKgExASoB8AEHAbUBZhAAAfcG/wGZASkBegIpAXoBKQGZAfEBAAG1AmYBtQH/AbUB7wH/ + AbsB7wH/ArUB9AFmAUsEoAJ0AZoDoAEqAfMBGQG7AWYQAAH3Bv8BKQF6ASkCegEpAXoBKQG8AQABtQH/ + AfQBtQL/Ae8H/wFmARwCSwF5AXQCegF0AXkBKgFLAQcB8wEZAQkBZhAAAfcG/wF0ASkBmQEwASkBmQEp + AXQBBwEAAbUB/wG1Ae8B/wK7Af8CBwH/AbsBtQH/AWYBAAFLAnkBoAJ0AaACeQEqAf8C8wEJAWYQAAH3 + Cf8BMQEwAv8BGQH3AQABtQL/Ae8C/wG7B/8BZgEAARwDSwGgAZoDSwGZAf8C8wG8AWYQAAH3DP8B9AEZ + AewBAAHvAf8CuwH/AQcCuwTvA7UCAAHwAf8BBwJLARwC8AL/AfQB8wG8AWYQAAH3Dv8BrgEAAe8C/wG7 + B/8BZgUAAe8B/wTwAfcB6wRtAfABZhAAAQcB9wT/Ca4B9wEAAbsB/wEHArsE7wO1BQAB7wv/ARkBZhEA + AfcE/wH3AQAB9wQJAesDAAG7B/8BZggAAbsB/wVtBf8BGQFmEQABBwT3AQcBAAEHBPcBBwMAArsE7wO1 + CAABuwz/AWYyAAW7BO8EtQH3EAABQgFNAT4HAAE+AwABKAMAAUADAAEQAwABAQEAAQEFAAGAFwAD/wEA + Af8BzwL/AfgDAAH+AQEC/wHABQAB/gEAAYAFAAH+AQABgAUAAfAHAAHwBwABgAcAAYAHAAGAAQABgAUA + AYABAAGABQABgAEAAcAFAAGAAQcBwAUAAYABBwHAAwABgQEDAYABPwHAAwABgQEDAYABPwHAAwAE/wHA + AwAL + + + + 112, 17 + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAURJREFUOE+1kDFy + gzAQRX2E3CDcAG6AuqSD0qlQ6Q51phNlOijpUGc61Dmd1aYyN7BuwN5gs4uTGRg7cVxYMzsqdv/7f3e1 + euSr9qOsLDjzAb514PoD1P1hDP7lycLaAtLvdXcuBlkHcBVSd4Dt5xgxverBsDirAYQaUGwshpmFuPBg + 9gAE8YsURHwqCWAcDHo3liyWtUehHIkdi12cWy+kwfR9mlsCmKYaj6oBVObbWVoUVGHWK+4nug/CtZlS + 6B24izuwY1qy8xkSvlaWxGI+yGl+BaSlx0idIZyEgbodLwCJpgQd2IsEouCd+WAOI4oeranSGn8GKU3A + Pb5B3pymtf58fNj5wPNLJdiEV7ylvdqPN25g90Qfb7vPCVk1BnF+lJO4GOBu92R7EixOiwHDtz69G0AJ + ZLw9lnTExU3uBj1M8AXZCvHw6pRRNAAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAUhJREFUOE/FkTFu + wkAQRTkCN4Ab2Dewu9CtSzpvSWd3cbfpQmeXdN4udN4upGLbVPgG7A3232AzY6TIyEEEKVJG2mrnv/9n + Zjb7q+qOftkd0bQWVh/g6s5L1fr5r/gsNhZgodqPngYIIu9CSOz0O5BUDlFukG5MSAqLvAEKghStzxjS + fvo4LfswAWoCZFuEeK1JaBxBLINiaYJsEPIdHEEk9fXpxgZKfD2aeoNl98VT7YTqluwQ5V0ZrTXiTAfx + CldqhHJHJgSdJBgB7PiTIGm0qg2LOUn2ckk5BexhhAIiSjD+rD983BwuzoO4dCHOmimg2J3Lyw5MWCTq + ez5eGM/MsdmZxcvVDwB25Yhp5QLtIR2nmCzs1k2FOg0pko3t7979JqTqMUCKk8xrP1zjoYpEOxeV68UW + EM/nq1EeAgnlM0ogHxL9W/MXM4DmfcnD838AAAAASUVORK5CYII= + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAW1JREFUOE+lk71O + wzAQx+EJ2jdI3yDeOjpTV3uiozMg6NYMqLAlA2rZ7I1uzgRj/AbJyJa+QbIxxhvj4TMg9SMtRUQ6KTn/ + 73cfOV8CwMW/HgRsW1GUSr8W7ZaPNE1j06U0+1qffN8pdUHUOod0pUd41n1AZkwFYp7GZwFQpNYGHCh3 + 78PmvbNxksFgMPDAfTtwoMC1YZXKoa7rrHrbAI+TvwH0S2mwDfmsqyRTwJiwfdl7Z4BOKXWEgVg6ZqcT + 1jvAowA8cEOzGMxnGTDRP8BegHjsiFh2hmctsEVt+MMG2H1tneX0puQnh+iDZWdZ2lg61TZksqXz0iIk + mlVAhVYnAWzZGP7UOrEBwhU4wE8FI3pbxOg7CcBgl53Q64J8A4a+hbua0CuZkCj5BYB9o1hgtsyL2aLc + RLGrKIohCMKD37mzSG5oX2JXajBm/j5g6eFY2MBZyFIsYSdm58OLp7LFgHByKD57lY9tXZ//E6n3h7WO + zjr9AAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAUBJREFUOE+tU6Fu + wzAU7KfkD5pPCIyGwjbWsA0aDgaO1TBjhmE1LJthoGFYDQcNx27vbK1pIm2ZtJ10JPK7u3dP2e3+CusC + Mn3m2cNYj+PrqfmVNofXMNah7Qz2d4dyU4Sua+jBwY0erdLbIoxMuAmQ5PAhQhsLO0ZZKdOc5ZvNPBwv + 1SIV417xAcQIhHcZFIE1uiGifHLYP77NIkbiEmYEtDh1NkCZACPOa6g+C5cPFvv7UxbhvkRM7jG5cw1z + zuVqm+mniFaHNEwWjUEWkH05/OVMd9V76GF5Hb6huPMiLmUtBSQtXf0U5IFwDOhEiODeqg/Jvel8YhKo + bxKUdYs1lZ7Py2JpQPd0FSm+qHVe4Tu0L1ng1vmaQHrbFGieXeqGcWc68Gosvqg2ElTKLRpnaXRNlOGi + 6n5eYfMf+K8Hn1Gm2tY78ARPAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAY9JREFUOE+1k612 + 4zAUhP0IeYQ8gmGhYFkFwyoYFsGyijUsgoaCYRUMFDQUDBQMFCybzpXqNv3ZLdizOmeODDzf3B97GP7H + SdFBFIPD7v5u/GvG8/Fg49FjUfAG9RKaytnDbhX83lKu3YennfoEFGOtEaBqDQiTbfdue5fz7OCshjMj + aiL4tIY1Gt8AYhb5vUGeCbx4pjuU2SBOGmajENwa2Q+wm6+A4JsZTPXOMFGkWfqbmGgJ8LYDzK36XEFY + ANJ3YXq2yGH1oYnPNC5SN+MXwOT60ArvM/vPmgWt4ANbmiKcp/YB1gWYBw9j/Q8AST5zSDPNiQMTAM3v + 54Ud1opyqdBbB23cByR4SaZm1c2nFUoYWrKcEFPXMSEXAmhOc4bSpkNkv9L3Yq7HoQNYNq6S87ki5QK9 + sc2sbjWU4kDl46gzxWQpvRCQJ66LPUvZ1xXIXGLKfT6UGtcEODH3FV1LBiY9L8lpLs0cT13vgMPjTsn+ + 5QszWkGrsZFl2tLzkvbT3Sr405Fpywu/6Z9/5lcMCPZ7KYCY8wAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAVFJREFUOE+tkjFO + w0AQRS1RQLfbEdHsCiHF3WyHRTPbJdBMjpAj5Ag+go+QMqWPkCO4TYHkI/gGyx9DIuIEbCQsjWLt/P/m + Z7w3GR55k5A/5rv8KW8P74dWz/708ILXMcbEzJ28yuo3s4h4XvLmTAPjGlWHIiYFyULKIcQRWWiiLKXD + 73YI8NpUiAJ6iEiNsiokZstL6XtUUEWA/ZgSkM03yJZfOHDBVW8mqjTJ6H4ACahG/xJMnZbLqZ5kPtJh + iiGEFD8hrXMTJp/Mz+QxsVFAXwqZ07TPi2m92echEWKbBxecc7WCcH7++YbLwBQPceO919h7vFtjTF94 + 1+13DpqrSyRiFW3dzOnSWlQ4Co8QnDUKugpAY2VnPml0TCnVdHGZNOHctehdpjD3prTWJoD25vaK4ItG + uBMAnNKdhsAYsrtM48XMZGOXZaw/etf+T/ABASBzBnL8dsYAAAAASUVORK5CYII= + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAW9JREFUOE+tU6F2 + AjEQ5BP6CXzCSWQkMhIZSVUjkZHIk8hIZCQyEteTlZGVkbjtzB5w4Upr2n1vHu9dMrMzu2Gx+I9KpyqK + dMWxSozAoUjfX7EvEgKwG8QTfpB7bxJzFlyWX6teROwmi9skxXeBff1RgORaqxibpeschBqBCMt0QIvP + 6kYun1U6mxCjiLVxcsC8FPA4mFdLHj4gsE6a/1EAw1IBHLQ1J+ehyNJEcduZACdNAR7c6hk5n4u8rCDg + sth1P0XosaJ8EqwSIg7qvIBp68CQmbbZ+U7mWSvA4aUEASBGrrNKwEbGvReN5uFOO4NsIfoogIeRjhPZ + bjwuNnAe8UJDhoAJUwS+rLYzyXgk0hkjnPxQqrhdQFd2JjnOBGAxHvAOrrYpQLLf9VJA5v596PGNxDj+ + rloHyKe5kXnJgXUGA82KnAfJZ67NKlGBTZiVuhzr7fXdui0HlPSB3IFJc1gKZGbXEXDYCvzlH/0F0FE7 + DNsH26sAAAAASUVORK5CYII= + + + + 277, 17 + + \ No newline at end of file diff --git a/src/Kalman.Studio/CodeBuilder/PreviewFile.cs b/src/Kalman.Studio/CodeBuilder/PreviewFile.cs new file mode 100644 index 0000000..2e21a18 --- /dev/null +++ b/src/Kalman.Studio/CodeBuilder/PreviewFile.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using System.IO; +using ICSharpCode.TextEditor.Document; + +namespace Kalman.Studio +{ + public partial class PreviewFile : Form + { + string _FileName = string.Empty; + string _CodeType = CodeType.CSHARP; + + public PreviewFile(string fileName, string codeType) + { + InitializeComponent(); + + _FileName = fileName; + _CodeType = codeType; + } + + private void PreviewTemplate_Load(object sender, EventArgs e) + { + if (File.Exists(_FileName)) + { + IHighlightingStrategy strategy = HighlightingStrategyFactory.CreateHighlightingStrategy(_CodeType); + textEditorControl1.Document.HighlightingStrategy = strategy; + textEditorControl1.Text = File.ReadAllText(_FileName); + } + this.Text = string.Concat("预览文件 - ", _FileName); + textEditorControl1.TextChanged += new EventHandler(textEditorControl1_TextChanged); + } + + private void Save() + { + File.WriteAllText(_FileName, textEditorControl1.Text, Encoding.UTF8); + this.Text = this.Text.TrimEnd('*'); + } + + protected override void OnClosing(CancelEventArgs e) + { + if (this.Text.EndsWith("*")) + { + if (MessageBox.Show("文件内容已改变,是否保存文件", "信息提示", MessageBoxButtons.YesNo, MessageBoxIcon.Asterisk) == DialogResult.Yes) + { + Save(); + } + } + + base.OnClosing(e); + } + + void textEditorControl1_TextChanged(object sender, EventArgs e) + { + if(this.Text.EndsWith("*")) return; + this.Text = this.Text + "*"; + } + + private void menuItemUndo_Click(object sender, EventArgs e) + { + textEditorControl1.Undo(); + } + + private void menuItemRedo_Click(object sender, EventArgs e) + { + textEditorControl1.Redo(); + } + + private void menuItemReturn_Click(object sender, EventArgs e) + { + this.Close(); + } + + private void menuItemSave_Click(object sender, EventArgs e) + { + this.Save(); + } + } +} diff --git a/src/Kalman.Studio/CodeBuilder/PreviewFile.designer.cs b/src/Kalman.Studio/CodeBuilder/PreviewFile.designer.cs new file mode 100644 index 0000000..c41a06f --- /dev/null +++ b/src/Kalman.Studio/CodeBuilder/PreviewFile.designer.cs @@ -0,0 +1,131 @@ +namespace Kalman.Studio +{ + partial class PreviewFile + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(PreviewFile)); + this.textEditorControl1 = new ICSharpCode.TextEditor.TextEditorControl(); + this.cms = new System.Windows.Forms.ContextMenuStrip(this.components); + this.menuItemUndo = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemRedo = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); + this.menuItemSave = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemReturn = new System.Windows.Forms.ToolStripMenuItem(); + this.cms.SuspendLayout(); + this.SuspendLayout(); + // + // textEditorControl1 + // + this.textEditorControl1.ContextMenuStrip = this.cms; + this.textEditorControl1.Dock = System.Windows.Forms.DockStyle.Fill; + this.textEditorControl1.IsReadOnly = false; + this.textEditorControl1.Location = new System.Drawing.Point(0, 0); + this.textEditorControl1.Name = "textEditorControl1"; + this.textEditorControl1.Size = new System.Drawing.Size(792, 573); + this.textEditorControl1.TabIndex = 0; + // + // cms + // + this.cms.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.menuItemUndo, + this.menuItemRedo, + this.toolStripSeparator1, + this.menuItemSave, + this.menuItemReturn}); + this.cms.Name = "cms"; + this.cms.Size = new System.Drawing.Size(154, 120); + // + // menuItemUndo + // + this.menuItemUndo.Image = ((System.Drawing.Image)(resources.GetObject("menuItemUndo.Image"))); + this.menuItemUndo.Name = "menuItemUndo"; + this.menuItemUndo.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Z))); + this.menuItemUndo.Size = new System.Drawing.Size(153, 22); + this.menuItemUndo.Text = "撤销(&Z)"; + this.menuItemUndo.Click += new System.EventHandler(this.menuItemUndo_Click); + // + // menuItemRedo + // + this.menuItemRedo.Image = ((System.Drawing.Image)(resources.GetObject("menuItemRedo.Image"))); + this.menuItemRedo.Name = "menuItemRedo"; + this.menuItemRedo.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Y))); + this.menuItemRedo.Size = new System.Drawing.Size(153, 22); + this.menuItemRedo.Text = "重复(&R)"; + this.menuItemRedo.Click += new System.EventHandler(this.menuItemRedo_Click); + // + // toolStripSeparator1 + // + this.toolStripSeparator1.Name = "toolStripSeparator1"; + this.toolStripSeparator1.Size = new System.Drawing.Size(150, 6); + // + // menuItemSave + // + this.menuItemSave.Image = ((System.Drawing.Image)(resources.GetObject("menuItemSave.Image"))); + this.menuItemSave.Name = "menuItemSave"; + this.menuItemSave.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.S))); + this.menuItemSave.Size = new System.Drawing.Size(153, 22); + this.menuItemSave.Text = "保存(&S)"; + this.menuItemSave.Click += new System.EventHandler(this.menuItemSave_Click); + // + // menuItemReturn + // + this.menuItemReturn.Image = ((System.Drawing.Image)(resources.GetObject("menuItemReturn.Image"))); + this.menuItemReturn.Name = "menuItemReturn"; + this.menuItemReturn.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Q))); + this.menuItemReturn.Size = new System.Drawing.Size(153, 22); + this.menuItemReturn.Text = "返回(&Q)"; + this.menuItemReturn.Click += new System.EventHandler(this.menuItemReturn_Click); + // + // PreviewFile + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(792, 573); + this.Controls.Add(this.textEditorControl1); + this.Name = "PreviewFile"; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "预览文本文件"; + this.Load += new System.EventHandler(this.PreviewTemplate_Load); + this.cms.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private ICSharpCode.TextEditor.TextEditorControl textEditorControl1; + private System.Windows.Forms.ContextMenuStrip cms; + private System.Windows.Forms.ToolStripMenuItem menuItemSave; + private System.Windows.Forms.ToolStripMenuItem menuItemUndo; + private System.Windows.Forms.ToolStripMenuItem menuItemRedo; + private System.Windows.Forms.ToolStripMenuItem menuItemReturn; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/CodeBuilder/PreviewFile.resx b/src/Kalman.Studio/CodeBuilder/PreviewFile.resx new file mode 100644 index 0000000..6ae4270 --- /dev/null +++ b/src/Kalman.Studio/CodeBuilder/PreviewFile.resx @@ -0,0 +1,177 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAURJREFUOE+1kDFy + gzAQRX2E3CDcAG6AuqSD0qlQ6Q51phNlOijpUGc61Dmd1aYyN7BuwN5gs4uTGRg7cVxYMzsqdv/7f3e1 + euSr9qOsLDjzAb514PoD1P1hDP7lycLaAtLvdXcuBlkHcBVSd4Dt5xgxverBsDirAYQaUGwshpmFuPBg + 9gAE8YsURHwqCWAcDHo3liyWtUehHIkdi12cWy+kwfR9mlsCmKYaj6oBVObbWVoUVGHWK+4nug/CtZlS + 6B24izuwY1qy8xkSvlaWxGI+yGl+BaSlx0idIZyEgbodLwCJpgQd2IsEouCd+WAOI4oeranSGn8GKU3A + Pb5B3pymtf58fNj5wPNLJdiEV7ylvdqPN25g90Qfb7vPCVk1BnF+lJO4GOBu92R7EixOiwHDtz69G0AJ + ZLw9lnTExU3uBj1M8AXZCvHw6pRRNAAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAUhJREFUOE/FkTFu + wkAQRTkCN4Ab2Dewu9CtSzpvSWd3cbfpQmeXdN4udN4upGLbVPgG7A3232AzY6TIyEEEKVJG2mrnv/9n + Zjb7q+qOftkd0bQWVh/g6s5L1fr5r/gsNhZgodqPngYIIu9CSOz0O5BUDlFukG5MSAqLvAEKghStzxjS + fvo4LfswAWoCZFuEeK1JaBxBLINiaYJsEPIdHEEk9fXpxgZKfD2aeoNl98VT7YTqluwQ5V0ZrTXiTAfx + CldqhHJHJgSdJBgB7PiTIGm0qg2LOUn2ckk5BexhhAIiSjD+rD983BwuzoO4dCHOmimg2J3Lyw5MWCTq + ez5eGM/MsdmZxcvVDwB25Yhp5QLtIR2nmCzs1k2FOg0pko3t7979JqTqMUCKk8xrP1zjoYpEOxeV68UW + EM/nq1EeAgnlM0ogHxL9W/MXM4DmfcnD838AAAAASUVORK5CYII= + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAW9JREFUOE+tU6F2 + AjEQ5BP6CXzCSWQkMhIZSVUjkZHIk8hIZCQyEteTlZGVkbjtzB5w4Upr2n1vHu9dMrMzu2Gx+I9KpyqK + dMWxSozAoUjfX7EvEgKwG8QTfpB7bxJzFlyWX6teROwmi9skxXeBff1RgORaqxibpeschBqBCMt0QIvP + 6kYun1U6mxCjiLVxcsC8FPA4mFdLHj4gsE6a/1EAw1IBHLQ1J+ehyNJEcduZACdNAR7c6hk5n4u8rCDg + sth1P0XosaJ8EqwSIg7qvIBp68CQmbbZ+U7mWSvA4aUEASBGrrNKwEbGvReN5uFOO4NsIfoogIeRjhPZ + bjwuNnAe8UJDhoAJUwS+rLYzyXgk0hkjnPxQqrhdQFd2JjnOBGAxHvAOrrYpQLLf9VJA5v596PGNxDj+ + rloHyKe5kXnJgXUGA82KnAfJZ67NKlGBTZiVuhzr7fXdui0HlPSB3IFJc1gKZGbXEXDYCvzlH/0F0FE7 + DNsH26sAAAAASUVORK5CYII= + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAhVJREFUOE91Uk1L + G1EUHakVilpc+bVQYxZ+gDFxYcEqLhLBRusiqK3YukhAqEZF0I0Yv3Fjd7aNi/YXFBcprhRFgq1UmoRp + A0kjMc0YRPzYuT++e6expHkGbmbmvXPPOfe9k6NIfrGNDdxcXSk3lxe8m/vgofLIaFAso+4cGf5ujRrD + 8wtIfvAiNetBfHyCK+p24/vkJLb7+hB6/w5SkujqKk4/fkJqehrHjl6obW2I2Gz8DJkbEX7SDPWZHX7x + vScwGSSs6PXi9M0IEl1dUPtfZKkEhobwq7IKx3W12Dca8XXt7T9McGoKmtOpNwsVciCz+XNxCbGyUsQL + H8NXV69jYuvriM/McGNqcBC/he1wdTXCr15LScjdWX4+jgoLdBekHnW6eLa0Ks2tGgwIOBxSEk3sneTl + YevlABS/+CPW/c7ODHCwqYlJgj09WSQRIUAkn1uf/iUQ9nc7OrKAP0wmHidgtWbs0VmdlZfrBN9cLgbs + WCzymSsqmIRU0yNqdjtOzBb4RC6U4MoKyO6BqYHDIjv9REkxolWVOLdZOWBaezsTHi4u6HhqJhV63hfV + 66IiJIXLdFHI7rDEpAqriZoaTh7d9/9EdMWaOBMqUt9dWs7E7IgghYpLmORPSwsHi/JBdTE2pq+JZsrJ + l+FhuVP/3Dy2xfVERFDIKjVR0Ts1ku0sZdnMex4PfM+7sWk2c9E7rcmwtxVGZzvRCkanAAAAAElFTkSu + QmCC + + + \ No newline at end of file diff --git a/src/Kalman.Studio/CodeLib/readme.txt b/src/Kalman.Studio/CodeLib/readme.txt new file mode 100644 index 0000000..55e2228 --- /dev/null +++ b/src/Kalman.Studio/CodeLib/readme.txt @@ -0,0 +1 @@ +代码文件 \ No newline at end of file diff --git a/src/Kalman.Studio/Constants.cs b/src/Kalman.Studio/Constants.cs new file mode 100644 index 0000000..8f357ac --- /dev/null +++ b/src/Kalman.Studio/Constants.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; + +namespace Kalman.Studio +{ + /// + /// 配置 + /// + public class Constants + { + /// + /// 我的文档 + /// + public static string MyDocumentsPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); + + /// + /// 配置存储路径 + /// + public static string SettingPath + { + get + { + string path = MyDocumentsPath + @"\Loamen\Kalman Studio"; + var di = new DirectoryInfo(path); + if (!di.Exists) + { + di.Create(); + } + return di.FullName; + } + } + + /// + /// 配置数据库路径 + /// + public static string SettingDbFileName = SettingPath + @"\Data\Setting.db"; + + /// + /// 配置数据库字符串 + /// + public static string SettingConnectString = string.Format(@"Data Source={0};Version=3;", SettingDbFileName); + } +} diff --git a/src/Kalman.Studio/DockForm/DockDocument.cs b/src/Kalman.Studio/DockForm/DockDocument.cs new file mode 100644 index 0000000..7f4b290 --- /dev/null +++ b/src/Kalman.Studio/DockForm/DockDocument.cs @@ -0,0 +1,277 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using WeifenLuo.WinFormsUI.Docking; +using ICSharpCode.TextEditor.Document; +using System.IO; +using ICSharpCode.TextEditor; + +namespace Kalman.Studio +{ + public partial class DockDocument : DockFormBase, IDockDocument + { + public DockDocument() + { + InitializeComponent(); + } + + Main main = null; + private void DockDocument_Load(object sender, EventArgs e) + { + main = this.ParentForm as Main; + this.ToolTipText = textEditorControl1.FileName; + + textEditorControl1.Document.FoldingManager.FoldingStrategy = new VariXFolding(); + textEditorControl1.Document.FoldingManager.UpdateFoldings(null, null); + } + + #region Global Methods + public string FileName + { + get { return textEditorControl1.FileName; } + set { textEditorControl1.FileName = value; } + } + + public void LoadTextContent(string content, string codeType) + { + if (content != null) textEditorControl1.Text = content; + if (codeType != null) SetDocumentCodeType(codeType); + } + + /// + /// 加载文件内容 + /// + /// 文件完整路径 + public void LoadFileContent(string fileName) + { + if (File.Exists(fileName)) + { + textEditorControl1.LoadFile(fileName, true, true); + this.Text = Path.GetFileName(textEditorControl1.FileName); + } + } + + public void Save() + { + if (string.IsNullOrEmpty(textEditorControl1.FileName) == false) + { + textEditorControl1.SaveFile(textEditorControl1.FileName); + this.Text = Path.GetFileName(textEditorControl1.FileName); + } + else + { + SaveFileDialog dialog = new SaveFileDialog(); + dialog.Filter = "所有文件 (*.*)|*.*"; + dialog.FileName = this.Text.TrimEnd('*'); + if (dialog.ShowDialog() == DialogResult.OK) + { + textEditorControl1.SaveFile(dialog.FileName); + this.Text = Path.GetFileName(textEditorControl1.FileName); + } + } + } + + public void SaveAs() + { + SaveFileDialog dialog = new SaveFileDialog(); + dialog.Filter = "所有文件 (*.*)|*.*"; + dialog.FileName = this.Text.TrimEnd('*'); + if (dialog.ShowDialog() == DialogResult.OK) + { + textEditorControl1.SaveFile(dialog.FileName); + this.Text = Path.GetFileName(textEditorControl1.FileName); + } + } + + #endregion + + #region SetDocumentCodeType + public void SetDocumentCodeType(string codeType) + { + if (string.IsNullOrEmpty(codeType)) return; + IHighlightingStrategy strategy = HighlightingStrategyFactory.CreateHighlightingStrategy(codeType); + textEditorControl1.Document.HighlightingStrategy = strategy; + //textEditorControl1.Document.FoldingManager.FoldingStrategy = FoldingStrategyFactory + } + + private void menuItemAspxCode_Click(object sender, EventArgs e) + { + foreach (ToolStripItem item in menuItemConfig.DropDownItems) + { + ((ToolStripMenuItem)item).Checked = false; + } + menuItemAspxCode.Checked = true; + SetDocumentCodeType(CodeType.ASPX); + } + + private void menuItemCppCode_Click(object sender, EventArgs e) + { + foreach (ToolStripItem item in menuItemConfig.DropDownItems) + { + ((ToolStripMenuItem)item).Checked = false; + } + menuItemCppCode.Checked = true; + SetDocumentCodeType(CodeType.CPP); + } + + private void menuItemCSharpCode_Click(object sender, EventArgs e) + { + foreach (ToolStripItem item in menuItemConfig.DropDownItems) + { + ((ToolStripMenuItem)item).Checked = false; + } + menuItemCSharpCode.Checked = true; + SetDocumentCodeType(CodeType.CSHARP); + } + + private void menuItemHtmlCode_Click(object sender, EventArgs e) + { + foreach (ToolStripItem item in menuItemConfig.DropDownItems) + { + ((ToolStripMenuItem)item).Checked = false; + } + menuItemHtmlCode.Checked = true; + SetDocumentCodeType(CodeType.HTML); + } + + private void menuItemJavaCode_Click(object sender, EventArgs e) + { + foreach (ToolStripItem item in menuItemConfig.DropDownItems) + { + ((ToolStripMenuItem)item).Checked = false; + } + menuItemJavaCode.Checked = true; + SetDocumentCodeType(CodeType.JAVA); + } + + private void menuItemJsCode_Click(object sender, EventArgs e) + { + foreach (ToolStripItem item in menuItemConfig.DropDownItems) + { + ((ToolStripMenuItem)item).Checked = false; + } + menuItemJsCode.Checked = true; + SetDocumentCodeType(CodeType.JS); + } + + private void menuItemPhpCode_Click(object sender, EventArgs e) + { + foreach (ToolStripItem item in menuItemConfig.DropDownItems) + { + ((ToolStripMenuItem)item).Checked = false; + } + menuItemPhpCode.Checked = true; + SetDocumentCodeType(CodeType.PHP); + } + + private void menuItemTSQLCode_Click(object sender, EventArgs e) + { + foreach (ToolStripItem item in menuItemConfig.DropDownItems) + { + ((ToolStripMenuItem)item).Checked = false; + } + menuItemTSQLCode.Checked = true; + SetDocumentCodeType(CodeType.TSQL); + } + + private void menuItemVBCode_Click(object sender, EventArgs e) + { + foreach (ToolStripItem item in menuItemConfig.DropDownItems) + { + ((ToolStripMenuItem)item).Checked = false; + } + menuItemVBCode.Checked = true; + SetDocumentCodeType(CodeType.VB); + } + + private void menuItemXmlCode_Click(object sender, EventArgs e) + { + foreach (ToolStripItem item in menuItemConfig.DropDownItems) + { + ((ToolStripMenuItem)item).Checked = false; + } + menuItemXmlCode.Checked = true; + SetDocumentCodeType(CodeType.XML); + } + #endregion + + #region 处理文档右键菜单命令 + private void menuItemSave_Click(object sender, EventArgs e) + { + this.Save(); + } + + private void menuItemSaveAs_Click(object sender, EventArgs e) + { + this.SaveAs(); + } + + private void menuItemClose_Click(object sender, EventArgs e) + { + this.Close(); + } + + private void menuItemCloseOther_Click(object sender, EventArgs e) + { + main.CloseOtherDockDocument(); + } + + private void menuItemCloseAll_Click(object sender, EventArgs e) + { + main.CloseAllDockDocument(); + } + + private void menuItemOpenFolder_Click(object sender, EventArgs e) + { + if (File.Exists(textEditorControl1.FileName)) + { + Kalman.Command.CmdHelper.Execute(string.Format("explorer.exe {0}", Path.GetDirectoryName(textEditorControl1.FileName))); + } + } + #endregion + + private void textEditorControl1_TextChanged(object sender, EventArgs e) + { + if (this.Text.EndsWith("*")) return; + this.Text = this.Text + "*"; + } + + protected override void OnClosing(CancelEventArgs e) + { + if (this.Text.EndsWith("*")) + { + if (MessageBox.Show("是否保存文件" + this.Text.TrimEnd('*'), "信息提示", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes) + { + Save(); + } + } + + base.OnClosing(e); + } + + + #region 处理编辑命令 + private void menuItemUndo_Click(object sender, EventArgs e) { Undo(); } + private void menuItemRedo_Click(object sender, EventArgs e) { Redo(); } + private void menuItemCut_Click(object sender, EventArgs e) { Cut(sender, e); } + private void menuItemCopy_Click(object sender, EventArgs e) { Copy(sender, e); } + private void menuItemPaste_Click(object sender, EventArgs e) { Paste(sender, e); } + private void menuItemDelete_Click(object sender, EventArgs e) { Delete(sender, e); } + private void menuItemSelectAll_Click(object sender, EventArgs e) { SelectAll(sender, e); } + + public void Undo() { textEditorControl1.Undo(); } + public void Redo() { textEditorControl1.Redo(); } + public void Cut(object sender, EventArgs e) { textEditorControl1.ActiveTextAreaControl.TextArea.ClipboardHandler.Cut(sender, e); } + public void Copy(object sender, EventArgs e) { textEditorControl1.ActiveTextAreaControl.TextArea.ClipboardHandler.Copy(sender, e); } + public void Paste(object sender, EventArgs e) { textEditorControl1.ActiveTextAreaControl.TextArea.ClipboardHandler.Paste(sender, e); } + public void Delete(object sender, EventArgs e) { textEditorControl1.ActiveTextAreaControl.TextArea.ClipboardHandler.Delete(sender, e); } + public void SelectAll(object sender, EventArgs e) { textEditorControl1.ActiveTextAreaControl.TextArea.ClipboardHandler.SelectAll(sender, e); } + #endregion + + }// +} diff --git a/src/Kalman.Studio/DockForm/DockDocument.designer.cs b/src/Kalman.Studio/DockForm/DockDocument.designer.cs new file mode 100644 index 0000000..2be3723 --- /dev/null +++ b/src/Kalman.Studio/DockForm/DockDocument.designer.cs @@ -0,0 +1,384 @@ +namespace Kalman.Studio +{ + partial class DockDocument + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(DockDocument)); + this.textEditorControl1 = new ICSharpCode.TextEditor.TextEditorControl(); + this.cms = new System.Windows.Forms.ContextMenuStrip(this.components); + this.menuItemUndo = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemRedo = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator(); + this.menuItemCut = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemCopy = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemPaste = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemDelete = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); + this.menuItemSelectAll = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); + this.menuItemConfig = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemAspxCode = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemCppCode = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemCSharpCode = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemHtmlCode = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemJavaCode = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemJsCode = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemPhpCode = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemTSQLCode = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemVBCode = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemXmlCode = new System.Windows.Forms.ToolStripMenuItem(); + this.cmsDock = new System.Windows.Forms.ContextMenuStrip(this.components); + this.menuItemSave = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemSaveAs = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator(); + this.menuItemClose = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemCloseOther = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemCloseAll = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator(); + this.menuItemOpenFolder = new System.Windows.Forms.ToolStripMenuItem(); + this.cms.SuspendLayout(); + this.cmsDock.SuspendLayout(); + this.SuspendLayout(); + // + // textEditorControl1 + // + this.textEditorControl1.AllowDrop = true; + this.textEditorControl1.ContextMenuStrip = this.cms; + this.textEditorControl1.Dock = System.Windows.Forms.DockStyle.Fill; + this.textEditorControl1.IsReadOnly = false; + this.textEditorControl1.Location = new System.Drawing.Point(0, 0); + this.textEditorControl1.Name = "textEditorControl1"; + this.textEditorControl1.Size = new System.Drawing.Size(575, 333); + this.textEditorControl1.TabIndex = 0; + this.textEditorControl1.TextChanged += new System.EventHandler(this.textEditorControl1_TextChanged); + // + // cms + // + this.cms.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.menuItemUndo, + this.menuItemRedo, + this.toolStripSeparator5, + this.menuItemCut, + this.menuItemCopy, + this.menuItemPaste, + this.menuItemDelete, + this.toolStripSeparator1, + this.menuItemSelectAll, + this.toolStripSeparator2, + this.menuItemConfig}); + this.cms.Name = "cms"; + this.cms.Size = new System.Drawing.Size(154, 198); + // + // menuItemUndo + // + this.menuItemUndo.Image = ((System.Drawing.Image)(resources.GetObject("menuItemUndo.Image"))); + this.menuItemUndo.Name = "menuItemUndo"; + this.menuItemUndo.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Z))); + this.menuItemUndo.Size = new System.Drawing.Size(153, 22); + this.menuItemUndo.Text = "撤销(&Z)"; + this.menuItemUndo.Click += new System.EventHandler(this.menuItemUndo_Click); + // + // menuItemRedo + // + this.menuItemRedo.Image = ((System.Drawing.Image)(resources.GetObject("menuItemRedo.Image"))); + this.menuItemRedo.Name = "menuItemRedo"; + this.menuItemRedo.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Y))); + this.menuItemRedo.Size = new System.Drawing.Size(153, 22); + this.menuItemRedo.Text = "重复(&R)"; + this.menuItemRedo.Click += new System.EventHandler(this.menuItemRedo_Click); + // + // toolStripSeparator5 + // + this.toolStripSeparator5.Name = "toolStripSeparator5"; + this.toolStripSeparator5.Size = new System.Drawing.Size(150, 6); + // + // menuItemCut + // + this.menuItemCut.Image = ((System.Drawing.Image)(resources.GetObject("menuItemCut.Image"))); + this.menuItemCut.Name = "menuItemCut"; + this.menuItemCut.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.X))); + this.menuItemCut.Size = new System.Drawing.Size(153, 22); + this.menuItemCut.Text = "剪切(&X)"; + this.menuItemCut.Click += new System.EventHandler(this.menuItemCut_Click); + // + // menuItemCopy + // + this.menuItemCopy.Image = ((System.Drawing.Image)(resources.GetObject("menuItemCopy.Image"))); + this.menuItemCopy.Name = "menuItemCopy"; + this.menuItemCopy.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.C))); + this.menuItemCopy.Size = new System.Drawing.Size(153, 22); + this.menuItemCopy.Text = "复制(&C)"; + this.menuItemCopy.Click += new System.EventHandler(this.menuItemCopy_Click); + // + // menuItemPaste + // + this.menuItemPaste.Image = ((System.Drawing.Image)(resources.GetObject("menuItemPaste.Image"))); + this.menuItemPaste.Name = "menuItemPaste"; + this.menuItemPaste.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.V))); + this.menuItemPaste.Size = new System.Drawing.Size(153, 22); + this.menuItemPaste.Text = "粘贴(&V)"; + this.menuItemPaste.Click += new System.EventHandler(this.menuItemPaste_Click); + // + // menuItemDelete + // + this.menuItemDelete.Image = ((System.Drawing.Image)(resources.GetObject("menuItemDelete.Image"))); + this.menuItemDelete.Name = "menuItemDelete"; + this.menuItemDelete.ShortcutKeys = System.Windows.Forms.Keys.Delete; + this.menuItemDelete.Size = new System.Drawing.Size(153, 22); + this.menuItemDelete.Text = "删除(&D)"; + this.menuItemDelete.Click += new System.EventHandler(this.menuItemDelete_Click); + // + // toolStripSeparator1 + // + this.toolStripSeparator1.Name = "toolStripSeparator1"; + this.toolStripSeparator1.Size = new System.Drawing.Size(150, 6); + // + // menuItemSelectAll + // + this.menuItemSelectAll.Name = "menuItemSelectAll"; + this.menuItemSelectAll.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.A))); + this.menuItemSelectAll.Size = new System.Drawing.Size(153, 22); + this.menuItemSelectAll.Text = "全选(&A)"; + this.menuItemSelectAll.Click += new System.EventHandler(this.menuItemSelectAll_Click); + // + // toolStripSeparator2 + // + this.toolStripSeparator2.Name = "toolStripSeparator2"; + this.toolStripSeparator2.Size = new System.Drawing.Size(150, 6); + // + // menuItemConfig + // + this.menuItemConfig.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.menuItemAspxCode, + this.menuItemCppCode, + this.menuItemCSharpCode, + this.menuItemHtmlCode, + this.menuItemJavaCode, + this.menuItemJsCode, + this.menuItemPhpCode, + this.menuItemTSQLCode, + this.menuItemVBCode, + this.menuItemXmlCode}); + this.menuItemConfig.Name = "menuItemConfig"; + this.menuItemConfig.Size = new System.Drawing.Size(153, 22); + this.menuItemConfig.Text = "选择配置"; + // + // menuItemAspxCode + // + this.menuItemAspxCode.Name = "menuItemAspxCode"; + this.menuItemAspxCode.Size = new System.Drawing.Size(130, 22); + this.menuItemAspxCode.Text = "Aspx"; + this.menuItemAspxCode.Click += new System.EventHandler(this.menuItemAspxCode_Click); + // + // menuItemCppCode + // + this.menuItemCppCode.Name = "menuItemCppCode"; + this.menuItemCppCode.Size = new System.Drawing.Size(130, 22); + this.menuItemCppCode.Text = "C/C++"; + this.menuItemCppCode.Click += new System.EventHandler(this.menuItemCppCode_Click); + // + // menuItemCSharpCode + // + this.menuItemCSharpCode.Name = "menuItemCSharpCode"; + this.menuItemCSharpCode.Size = new System.Drawing.Size(130, 22); + this.menuItemCSharpCode.Text = "C#"; + this.menuItemCSharpCode.Click += new System.EventHandler(this.menuItemCSharpCode_Click); + // + // menuItemHtmlCode + // + this.menuItemHtmlCode.Name = "menuItemHtmlCode"; + this.menuItemHtmlCode.Size = new System.Drawing.Size(130, 22); + this.menuItemHtmlCode.Text = "Html"; + this.menuItemHtmlCode.Click += new System.EventHandler(this.menuItemHtmlCode_Click); + // + // menuItemJavaCode + // + this.menuItemJavaCode.Name = "menuItemJavaCode"; + this.menuItemJavaCode.Size = new System.Drawing.Size(130, 22); + this.menuItemJavaCode.Text = "Java"; + this.menuItemJavaCode.Click += new System.EventHandler(this.menuItemJavaCode_Click); + // + // menuItemJsCode + // + this.menuItemJsCode.Name = "menuItemJsCode"; + this.menuItemJsCode.Size = new System.Drawing.Size(130, 22); + this.menuItemJsCode.Text = "Javascript"; + this.menuItemJsCode.Click += new System.EventHandler(this.menuItemJsCode_Click); + // + // menuItemPhpCode + // + this.menuItemPhpCode.Name = "menuItemPhpCode"; + this.menuItemPhpCode.Size = new System.Drawing.Size(130, 22); + this.menuItemPhpCode.Text = "PHP"; + this.menuItemPhpCode.Click += new System.EventHandler(this.menuItemPhpCode_Click); + // + // menuItemTSQLCode + // + this.menuItemTSQLCode.Name = "menuItemTSQLCode"; + this.menuItemTSQLCode.Size = new System.Drawing.Size(130, 22); + this.menuItemTSQLCode.Text = "TSQL"; + this.menuItemTSQLCode.Click += new System.EventHandler(this.menuItemTSQLCode_Click); + // + // menuItemVBCode + // + this.menuItemVBCode.Name = "menuItemVBCode"; + this.menuItemVBCode.Size = new System.Drawing.Size(130, 22); + this.menuItemVBCode.Text = "VB.NET"; + this.menuItemVBCode.Click += new System.EventHandler(this.menuItemVBCode_Click); + // + // menuItemXmlCode + // + this.menuItemXmlCode.Name = "menuItemXmlCode"; + this.menuItemXmlCode.Size = new System.Drawing.Size(130, 22); + this.menuItemXmlCode.Text = "XML"; + this.menuItemXmlCode.Click += new System.EventHandler(this.menuItemXmlCode_Click); + // + // cmsDock + // + this.cmsDock.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.menuItemSave, + this.menuItemSaveAs, + this.toolStripSeparator3, + this.menuItemClose, + this.menuItemCloseOther, + this.menuItemCloseAll, + this.toolStripSeparator4, + this.menuItemOpenFolder}); + this.cmsDock.Name = "cmsDock"; + this.cmsDock.Size = new System.Drawing.Size(167, 148); + // + // menuItemSave + // + this.menuItemSave.Image = ((System.Drawing.Image)(resources.GetObject("menuItemSave.Image"))); + this.menuItemSave.Name = "menuItemSave"; + this.menuItemSave.Size = new System.Drawing.Size(166, 22); + this.menuItemSave.Text = "保存"; + this.menuItemSave.Click += new System.EventHandler(this.menuItemSave_Click); + // + // menuItemSaveAs + // + this.menuItemSaveAs.Name = "menuItemSaveAs"; + this.menuItemSaveAs.Size = new System.Drawing.Size(166, 22); + this.menuItemSaveAs.Text = "另存为..."; + this.menuItemSaveAs.Click += new System.EventHandler(this.menuItemSaveAs_Click); + // + // toolStripSeparator3 + // + this.toolStripSeparator3.Name = "toolStripSeparator3"; + this.toolStripSeparator3.Size = new System.Drawing.Size(163, 6); + // + // menuItemClose + // + this.menuItemClose.Image = ((System.Drawing.Image)(resources.GetObject("menuItemClose.Image"))); + this.menuItemClose.Name = "menuItemClose"; + this.menuItemClose.Size = new System.Drawing.Size(166, 22); + this.menuItemClose.Text = "关闭"; + this.menuItemClose.Click += new System.EventHandler(this.menuItemClose_Click); + // + // menuItemCloseOther + // + this.menuItemCloseOther.Name = "menuItemCloseOther"; + this.menuItemCloseOther.Size = new System.Drawing.Size(166, 22); + this.menuItemCloseOther.Text = "除此之外全部关闭"; + this.menuItemCloseOther.Click += new System.EventHandler(this.menuItemCloseOther_Click); + // + // menuItemCloseAll + // + this.menuItemCloseAll.Name = "menuItemCloseAll"; + this.menuItemCloseAll.Size = new System.Drawing.Size(166, 22); + this.menuItemCloseAll.Text = "全部关闭"; + this.menuItemCloseAll.Click += new System.EventHandler(this.menuItemCloseAll_Click); + // + // toolStripSeparator4 + // + this.toolStripSeparator4.Name = "toolStripSeparator4"; + this.toolStripSeparator4.Size = new System.Drawing.Size(163, 6); + // + // menuItemOpenFolder + // + this.menuItemOpenFolder.Name = "menuItemOpenFolder"; + this.menuItemOpenFolder.Size = new System.Drawing.Size(166, 22); + this.menuItemOpenFolder.Text = "打开所在文件夹"; + this.menuItemOpenFolder.Click += new System.EventHandler(this.menuItemOpenFolder_Click); + // + // DockDocument + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(575, 333); + this.Controls.Add(this.textEditorControl1); + this.DockAreas = WeifenLuo.WinFormsUI.Docking.DockAreas.Document; + this.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "DockDocument"; + this.TabPageContextMenuStrip = this.cmsDock; + this.Text = "DockDocument"; + this.Load += new System.EventHandler(this.DockDocument_Load); + this.cms.ResumeLayout(false); + this.cmsDock.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private ICSharpCode.TextEditor.TextEditorControl textEditorControl1; + private System.Windows.Forms.ContextMenuStrip cms; + private System.Windows.Forms.ToolStripMenuItem menuItemConfig; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator2; + private System.Windows.Forms.ToolStripMenuItem menuItemCSharpCode; + private System.Windows.Forms.ToolStripMenuItem menuItemTSQLCode; + private System.Windows.Forms.ToolStripMenuItem menuItemHtmlCode; + private System.Windows.Forms.ToolStripMenuItem menuItemJsCode; + private System.Windows.Forms.ToolStripMenuItem menuItemAspxCode; + private System.Windows.Forms.ToolStripMenuItem menuItemCppCode; + private System.Windows.Forms.ToolStripMenuItem menuItemJavaCode; + private System.Windows.Forms.ToolStripMenuItem menuItemPhpCode; + private System.Windows.Forms.ToolStripMenuItem menuItemVBCode; + private System.Windows.Forms.ToolStripMenuItem menuItemXmlCode; + private System.Windows.Forms.ContextMenuStrip cmsDock; + private System.Windows.Forms.ToolStripMenuItem menuItemClose; + private System.Windows.Forms.ToolStripMenuItem menuItemSave; + private System.Windows.Forms.ToolStripMenuItem menuItemCloseOther; + private System.Windows.Forms.ToolStripMenuItem menuItemOpenFolder; + private System.Windows.Forms.ToolStripMenuItem menuItemSaveAs; + private System.Windows.Forms.ToolStripMenuItem menuItemCloseAll; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator3; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator4; + private System.Windows.Forms.ToolStripMenuItem menuItemUndo; + private System.Windows.Forms.ToolStripMenuItem menuItemRedo; + private System.Windows.Forms.ToolStripMenuItem menuItemCut; + private System.Windows.Forms.ToolStripMenuItem menuItemCopy; + private System.Windows.Forms.ToolStripMenuItem menuItemPaste; + private System.Windows.Forms.ToolStripMenuItem menuItemDelete; + private System.Windows.Forms.ToolStripMenuItem menuItemSelectAll; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator5; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/DockForm/DockDocument.resx b/src/Kalman.Studio/DockForm/DockDocument.resx new file mode 100644 index 0000000..43ffa66 --- /dev/null +++ b/src/Kalman.Studio/DockForm/DockDocument.resx @@ -0,0 +1,250 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAURJREFUOE+1kDFy + gzAQRX2E3CDcAG6AuqSD0qlQ6Q51phNlOijpUGc61Dmd1aYyN7BuwN5gs4uTGRg7cVxYMzsqdv/7f3e1 + euSr9qOsLDjzAb514PoD1P1hDP7lycLaAtLvdXcuBlkHcBVSd4Dt5xgxverBsDirAYQaUGwshpmFuPBg + 9gAE8YsURHwqCWAcDHo3liyWtUehHIkdi12cWy+kwfR9mlsCmKYaj6oBVObbWVoUVGHWK+4nug/CtZlS + 6B24izuwY1qy8xkSvlaWxGI+yGl+BaSlx0idIZyEgbodLwCJpgQd2IsEouCd+WAOI4oeranSGn8GKU3A + Pb5B3pymtf58fNj5wPNLJdiEV7ylvdqPN25g90Qfb7vPCVk1BnF+lJO4GOBu92R7EixOiwHDtz69G0AJ + ZLw9lnTExU3uBj1M8AXZCvHw6pRRNAAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAUhJREFUOE/FkTFu + wkAQRTkCN4Ab2Dewu9CtSzpvSWd3cbfpQmeXdN4udN4upGLbVPgG7A3232AzY6TIyEEEKVJG2mrnv/9n + Zjb7q+qOftkd0bQWVh/g6s5L1fr5r/gsNhZgodqPngYIIu9CSOz0O5BUDlFukG5MSAqLvAEKghStzxjS + fvo4LfswAWoCZFuEeK1JaBxBLINiaYJsEPIdHEEk9fXpxgZKfD2aeoNl98VT7YTqluwQ5V0ZrTXiTAfx + CldqhHJHJgSdJBgB7PiTIGm0qg2LOUn2ckk5BexhhAIiSjD+rD983BwuzoO4dCHOmimg2J3Lyw5MWCTq + ez5eGM/MsdmZxcvVDwB25Yhp5QLtIR2nmCzs1k2FOg0pko3t7979JqTqMUCKk8xrP1zjoYpEOxeV68UW + EM/nq1EeAgnlM0ogHxL9W/MXM4DmfcnD838AAAAASUVORK5CYII= + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAW1JREFUOE+lk71O + wzAQx+EJ2jdI3yDeOjpTV3uiozMg6NYMqLAlA2rZ7I1uzgRj/AbJyJa+QbIxxhvj4TMg9SMtRUQ6KTn/ + 73cfOV8CwMW/HgRsW1GUSr8W7ZaPNE1j06U0+1qffN8pdUHUOod0pUd41n1AZkwFYp7GZwFQpNYGHCh3 + 78PmvbNxksFgMPDAfTtwoMC1YZXKoa7rrHrbAI+TvwH0S2mwDfmsqyRTwJiwfdl7Z4BOKXWEgVg6ZqcT + 1jvAowA8cEOzGMxnGTDRP8BegHjsiFh2hmctsEVt+MMG2H1tneX0puQnh+iDZWdZ2lg61TZksqXz0iIk + mlVAhVYnAWzZGP7UOrEBwhU4wE8FI3pbxOg7CcBgl53Q64J8A4a+hbua0CuZkCj5BYB9o1hgtsyL2aLc + RLGrKIohCMKD37mzSG5oX2JXajBm/j5g6eFY2MBZyFIsYSdm58OLp7LFgHByKD57lY9tXZ//E6n3h7WO + zjr9AAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAUBJREFUOE+tU6Fu + wzAU7KfkD5pPCIyGwjbWsA0aDgaO1TBjhmE1LJthoGFYDQcNx27vbK1pIm2ZtJ10JPK7u3dP2e3+CusC + Mn3m2cNYj+PrqfmVNofXMNah7Qz2d4dyU4Sua+jBwY0erdLbIoxMuAmQ5PAhQhsLO0ZZKdOc5ZvNPBwv + 1SIV417xAcQIhHcZFIE1uiGifHLYP77NIkbiEmYEtDh1NkCZACPOa6g+C5cPFvv7UxbhvkRM7jG5cw1z + zuVqm+mniFaHNEwWjUEWkH05/OVMd9V76GF5Hb6huPMiLmUtBSQtXf0U5IFwDOhEiODeqg/Jvel8YhKo + bxKUdYs1lZ7Py2JpQPd0FSm+qHVe4Tu0L1ng1vmaQHrbFGieXeqGcWc68Gosvqg2ElTKLRpnaXRNlOGi + 6n5eYfMf+K8Hn1Gm2tY78ARPAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAY9JREFUOE+1k612 + 4zAUhP0IeYQ8gmGhYFkFwyoYFsGyijUsgoaCYRUMFDQUDBQMFCybzpXqNv3ZLdizOmeODDzf3B97GP7H + SdFBFIPD7v5u/GvG8/Fg49FjUfAG9RKaytnDbhX83lKu3YennfoEFGOtEaBqDQiTbfdue5fz7OCshjMj + aiL4tIY1Gt8AYhb5vUGeCbx4pjuU2SBOGmajENwa2Q+wm6+A4JsZTPXOMFGkWfqbmGgJ8LYDzK36XEFY + ANJ3YXq2yGH1oYnPNC5SN+MXwOT60ArvM/vPmgWt4ANbmiKcp/YB1gWYBw9j/Q8AST5zSDPNiQMTAM3v + 54Ud1opyqdBbB23cByR4SaZm1c2nFUoYWrKcEFPXMSEXAmhOc4bSpkNkv9L3Yq7HoQNYNq6S87ki5QK9 + sc2sbjWU4kDl46gzxWQpvRCQJ66LPUvZ1xXIXGLKfT6UGtcEODH3FV1LBiY9L8lpLs0cT13vgMPjTsn+ + 5QszWkGrsZFl2tLzkvbT3Sr405Fpywu/6Z9/5lcMCPZ7KYCY8wAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAVFJREFUOE+tkjFO + w0AQRS1RQLfbEdHsCiHF3WyHRTPbJdBMjpAj5Ag+go+QMqWPkCO4TYHkI/gGyx9DIuIEbCQsjWLt/P/m + Z7w3GR55k5A/5rv8KW8P74dWz/708ILXMcbEzJ28yuo3s4h4XvLmTAPjGlWHIiYFyULKIcQRWWiiLKXD + 73YI8NpUiAJ6iEiNsiokZstL6XtUUEWA/ZgSkM03yJZfOHDBVW8mqjTJ6H4ACahG/xJMnZbLqZ5kPtJh + iiGEFD8hrXMTJp/Mz+QxsVFAXwqZ07TPi2m92echEWKbBxecc7WCcH7++YbLwBQPceO919h7vFtjTF94 + 1+13DpqrSyRiFW3dzOnSWlQ4Co8QnDUKugpAY2VnPml0TCnVdHGZNOHctehdpjD3prTWJoD25vaK4ItG + uBMAnNKdhsAYsrtM48XMZGOXZaw/etf+T/ABASBzBnL8dsYAAAAASUVORK5CYII= + + + + 123, 22 + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAW9JREFUOE+tU6F2 + AjEQ5BP6CXzCSWQkMhIZSVUjkZHIk8hIZCQyEteTlZGVkbjtzB5w4Upr2n1vHu9dMrMzu2Gx+I9KpyqK + dMWxSozAoUjfX7EvEgKwG8QTfpB7bxJzFlyWX6teROwmi9skxXeBff1RgORaqxibpeschBqBCMt0QIvP + 6kYun1U6mxCjiLVxcsC8FPA4mFdLHj4gsE6a/1EAw1IBHLQ1J+ehyNJEcduZACdNAR7c6hk5n4u8rCDg + sth1P0XosaJ8EqwSIg7qvIBp68CQmbbZ+U7mWSvA4aUEASBGrrNKwEbGvReN5uFOO4NsIfoogIeRjhPZ + bjwuNnAe8UJDhoAJUwS+rLYzyXgk0hkjnPxQqrhdQFd2JjnOBGAxHvAOrrYpQLLf9VJA5v596PGNxDj+ + rloHyKe5kXnJgXUGA82KnAfJZ67NKlGBTZiVuhzr7fXdui0HlPSB3IFJc1gKZGbXEXDYCvzlH/0F0FE7 + DNsH26sAAAAASUVORK5CYII= + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAVJJREFUOE+lkyFy + wzAURN0b+AiChYZl1Q2qI/gGEQyrWcMiGCiWsBgUBBqWxTDQMFA32O63bEdJ3c546pkdz3j+vl19jZ8A + ZP96BLBE2liM6sOXmGV2NL++rcoecP5cFfXBIdVxv9W/gQVAsxneOhNjuNZAqBFEHWHe4bh/r/5qR0gh + kEyG5+T53e9E1Q9tP2L9CYDQsEGq2AhXTzmArXBhodZyrERlxR+Xn0lSNN+OgZAYu8HYlhwzaHfqAcCK + KeAuVcwXpor5izoZNC6HLU3SYADIAmMyJZVnzKHWaDY5SpMCnDRIznxnZroks7qYw6FAXeUwWm553AEB + /TVOCxtrJ+ZTNHc+AvRLcQO4zQhIa8+YBcAF+rVC8axSAIc7z0VZdFxSV3OQw61XaGhonGLqqBzOKiiV + 3wOqtYXl3ZbcrjG6rygpMqjyeU07WPozPc5/A06Irjc9Sw2jAAAAAElFTkSuQmCC + + + + + AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAADAoJD/YEgw/2BIMP9gSDD/YEgw/2BIMP9gSDD/YEgw/2BIMP9gSDD/YEgw/2BI + MP9gSDD/YEgw/wAAAAAAAAAAwKiQ///////g4OD/4NjQ/+DY0P/g0ND/4NDA/+DQwP/gyLD/4Miw/+DI + sP/gwLD/4MCw/2BIMP8AAAAAAAAAAMCooP//+P////jw///48P//+PD///Dw///w4P//8OD//+jg///o + 4P//6OD//+jQ/+DAsP9gSDD/AAAAAAAAAADAqKD//////7CooP+wqKD/sKig///48P+wqKD/sKig///w + 4P//6OD//+jg///o0P/gwLD/YEgw/wAAAAAAAAAAwLCg//////////////jw///48P//+PD///Dw///w + 8P//8OD//+jg///o4P//6OD/4Miw/2BIMP8AAAAAAAAAAMCwoP//////sKig/7CooP+wqKD///jw///4 + 8P//8PD///Dg///w4P//6OD//+jg/+DIsP9gSDD/AAAAAAAAAADQsKD///////////////////j////4 + 8P//+PD///jw///w8P//8OD///Dg///o4P/gyLD/YEgw/wAAAAAAAAAA0Lig//////+wqKD/sKig/7Co + oP+wqKD///jw/7CooP+wqKD///Dw///w4P//8OD/8NjQ/2BIMP8AAAAAAAAAANC4oP////////////// + ///////////////48P//+PD///jw///w8P//8PD///Dg///o0P9gSDD/AAAAAAAAAADwqJD/8KiQ//Co + gP/woID/4Jhw/+CQYP/giFD/4IBQ/+B4QP/gcED/4HBA/+BwQP/gcED/0GAw/wAAAAAAAAAA8KiQ///A + oP//wKD//7iQ//+4kP//sJD//6iA//+ogP/woHD/8KBw//CYcP/wmGD/8Jhg/9BoMP8AAAAAAAAAAPCo + kP/wqJD/8KiQ//CogP/woID/8Jhw/+CYcP/gkGD/4Ihg/+CAUP/geED/4HhA/+B4QP/gcED/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA//+cQf//nEGAAZxBgAGcQYABnEGAAZxBgAGcQYABnEGAAZxBgAGcQYABnEGAAZxBgAGcQYAB + nEH//5xB//+cQQ== + + + \ No newline at end of file diff --git a/src/Kalman.Studio/DockForm/DockExplorer.Designer.cs b/src/Kalman.Studio/DockForm/DockExplorer.Designer.cs new file mode 100644 index 0000000..eb7e540 --- /dev/null +++ b/src/Kalman.Studio/DockForm/DockExplorer.Designer.cs @@ -0,0 +1,38 @@ +namespace Kalman.Studio +{ + partial class DockExplorer + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Text = "DockExplorer"; + } + + #endregion + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/DockForm/DockExplorer.cs b/src/Kalman.Studio/DockForm/DockExplorer.cs new file mode 100644 index 0000000..34c36d9 --- /dev/null +++ b/src/Kalman.Studio/DockForm/DockExplorer.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace Kalman.Studio +{ + /// + /// 停靠在左右侧的窗体基类 + /// + public partial class DockExplorer : DockFormBase + { + public DockExplorer() + { + InitializeComponent(); + } + } +} diff --git a/src/Kalman.Studio/DockForm/DockFormBase.Designer.cs b/src/Kalman.Studio/DockForm/DockFormBase.Designer.cs new file mode 100644 index 0000000..ed61a82 --- /dev/null +++ b/src/Kalman.Studio/DockForm/DockFormBase.Designer.cs @@ -0,0 +1,49 @@ +namespace Kalman.Studio +{ + partial class DockFormBase + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.SuspendLayout(); + // + // DockFromBase + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(292, 273); + this.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.Name = "DockFromBase"; + this.Text = "DockFromBase"; + this.Load += new System.EventHandler(this.DockFromBase_Load); + this.ResumeLayout(false); + + } + + #endregion + + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/DockForm/DockFormBase.cs b/src/Kalman.Studio/DockForm/DockFormBase.cs new file mode 100644 index 0000000..7faed83 --- /dev/null +++ b/src/Kalman.Studio/DockForm/DockFormBase.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using WeifenLuo.WinFormsUI.Docking; + +namespace Kalman.Studio +{ + public partial class DockFormBase : DockContent + { + public DockFormBase() + { + InitializeComponent(); + } + + protected Main MainForm + { + get { return this.ParentForm as Main; } + } + + private void DockFromBase_Load(object sender, EventArgs e) + { + + } + } +} diff --git a/src/Kalman.Studio/DockForm/DockFormBase.resx b/src/Kalman.Studio/DockForm/DockFormBase.resx new file mode 100644 index 0000000..19dc0dd --- /dev/null +++ b/src/Kalman.Studio/DockForm/DockFormBase.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/Kalman.Studio/DockForm/DockableFrom.Designer.cs b/src/Kalman.Studio/DockForm/DockableFrom.Designer.cs new file mode 100644 index 0000000..7b89944 --- /dev/null +++ b/src/Kalman.Studio/DockForm/DockableFrom.Designer.cs @@ -0,0 +1,90 @@ +namespace Kalman.Studio +{ + partial class DockableForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.cmsDock = new System.Windows.Forms.ContextMenuStrip(this.components); + this.menuItemClose = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemCloseOther = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemCloseAll = new System.Windows.Forms.ToolStripMenuItem(); + this.cmsDock.SuspendLayout(); + this.SuspendLayout(); + // + // cmsDock + // + this.cmsDock.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.menuItemClose, + this.menuItemCloseOther, + this.menuItemCloseAll}); + this.cmsDock.Name = "cmsDock"; + this.cmsDock.Size = new System.Drawing.Size(167, 70); + // + // menuItemClose + // + this.menuItemClose.Name = "menuItemClose"; + this.menuItemClose.Size = new System.Drawing.Size(166, 22); + this.menuItemClose.Text = "关闭"; + this.menuItemClose.Click += new System.EventHandler(this.menuItemClose_Click); + // + // menuItemCloseOther + // + this.menuItemCloseOther.Name = "menuItemCloseOther"; + this.menuItemCloseOther.Size = new System.Drawing.Size(166, 22); + this.menuItemCloseOther.Text = "除此之外全部关闭"; + this.menuItemCloseOther.Click += new System.EventHandler(this.menuItemCloseOther_Click); + // + // menuItemCloseAll + // + this.menuItemCloseAll.Name = "menuItemCloseAll"; + this.menuItemCloseAll.Size = new System.Drawing.Size(166, 22); + this.menuItemCloseAll.Text = "全部关闭"; + this.menuItemCloseAll.Click += new System.EventHandler(this.menuItemCloseAll_Click); + // + // DockableFrom + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(292, 273); + this.DockAreas = WeifenLuo.WinFormsUI.Docking.DockAreas.Document; + this.Name = "DockableFrom"; + this.TabPageContextMenuStrip = this.cmsDock; + this.Text = "DockableFrom"; + this.cmsDock.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.ContextMenuStrip cmsDock; + private System.Windows.Forms.ToolStripMenuItem menuItemClose; + private System.Windows.Forms.ToolStripMenuItem menuItemCloseOther; + private System.Windows.Forms.ToolStripMenuItem menuItemCloseAll; + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/DockForm/DockableFrom.cs b/src/Kalman.Studio/DockForm/DockableFrom.cs new file mode 100644 index 0000000..b29cd7f --- /dev/null +++ b/src/Kalman.Studio/DockForm/DockableFrom.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace Kalman.Studio +{ + /// + /// 可停靠在文档区域的窗体基类 + /// + public partial class DockableForm : DockFormBase + { + public DockableForm() + { + InitializeComponent(); + } + + private void menuItemClose_Click(object sender, EventArgs e) + { + this.CloseDockableFrom(); + } + + protected virtual void CloseDockableFrom() + { + this.Hide(); + } + + private void menuItemCloseOther_Click(object sender, EventArgs e) + { + MainForm.CloseOtherDockDocument(); + } + + private void menuItemCloseAll_Click(object sender, EventArgs e) + { + MainForm.CloseAllDockDocument(); + } + } +} diff --git a/src/Kalman.Studio/DockForm/DockableFrom.resx b/src/Kalman.Studio/DockForm/DockableFrom.resx new file mode 100644 index 0000000..32dc42a --- /dev/null +++ b/src/Kalman.Studio/DockForm/DockableFrom.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + \ No newline at end of file diff --git a/src/Kalman.Studio/ErrorInfo.cs b/src/Kalman.Studio/ErrorInfo.cs new file mode 100644 index 0000000..b80e67d --- /dev/null +++ b/src/Kalman.Studio/ErrorInfo.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace Kalman.Studio +{ + public partial class ErrorInfo : Form + { + string errorInfo = ""; + string errorData = ""; + + public ErrorInfo(Exception ex,string data) + { + InitializeComponent(); + errorInfo = ex.ToString(); + errorData = data; + } + + private void ErrorInfo_Load(object sender, EventArgs e) + { + rtbErrorInfo.Text = errorInfo; + rtbErrorData.Text = errorData; + } + } +} diff --git a/src/Kalman.Studio/ErrorInfo.designer.cs b/src/Kalman.Studio/ErrorInfo.designer.cs new file mode 100644 index 0000000..8fabf09 --- /dev/null +++ b/src/Kalman.Studio/ErrorInfo.designer.cs @@ -0,0 +1,116 @@ +namespace Kalman.Studio +{ + partial class ErrorInfo + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.tabControl1 = new System.Windows.Forms.TabControl(); + this.tpErrorInfo = new System.Windows.Forms.TabPage(); + this.tpErrorData = new System.Windows.Forms.TabPage(); + this.rtbErrorInfo = new System.Windows.Forms.RichTextBox(); + this.rtbErrorData = new System.Windows.Forms.RichTextBox(); + this.tabControl1.SuspendLayout(); + this.tpErrorInfo.SuspendLayout(); + this.tpErrorData.SuspendLayout(); + this.SuspendLayout(); + // + // tabControl1 + // + this.tabControl1.Controls.Add(this.tpErrorInfo); + this.tabControl1.Controls.Add(this.tpErrorData); + this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill; + this.tabControl1.Location = new System.Drawing.Point(0, 0); + this.tabControl1.Name = "tabControl1"; + this.tabControl1.SelectedIndex = 0; + this.tabControl1.Size = new System.Drawing.Size(542, 340); + this.tabControl1.TabIndex = 0; + // + // tpErrorInfo + // + this.tpErrorInfo.Controls.Add(this.rtbErrorInfo); + this.tpErrorInfo.Location = new System.Drawing.Point(4, 21); + this.tpErrorInfo.Name = "tpErrorInfo"; + this.tpErrorInfo.Padding = new System.Windows.Forms.Padding(3); + this.tpErrorInfo.Size = new System.Drawing.Size(480, 409); + this.tpErrorInfo.TabIndex = 0; + this.tpErrorInfo.Text = "错误信息"; + this.tpErrorInfo.UseVisualStyleBackColor = true; + // + // tpErrorData + // + this.tpErrorData.Controls.Add(this.rtbErrorData); + this.tpErrorData.Location = new System.Drawing.Point(4, 21); + this.tpErrorData.Name = "tpErrorData"; + this.tpErrorData.Padding = new System.Windows.Forms.Padding(3); + this.tpErrorData.Size = new System.Drawing.Size(534, 315); + this.tpErrorData.TabIndex = 1; + this.tpErrorData.Text = "相关数据"; + this.tpErrorData.UseVisualStyleBackColor = true; + // + // rtbErrorInfo + // + this.rtbErrorInfo.Dock = System.Windows.Forms.DockStyle.Fill; + this.rtbErrorInfo.Location = new System.Drawing.Point(3, 3); + this.rtbErrorInfo.Name = "rtbErrorInfo"; + this.rtbErrorInfo.Size = new System.Drawing.Size(474, 403); + this.rtbErrorInfo.TabIndex = 0; + this.rtbErrorInfo.Text = ""; + // + // rtbErrorData + // + this.rtbErrorData.Dock = System.Windows.Forms.DockStyle.Fill; + this.rtbErrorData.Location = new System.Drawing.Point(3, 3); + this.rtbErrorData.Name = "rtbErrorData"; + this.rtbErrorData.Size = new System.Drawing.Size(528, 309); + this.rtbErrorData.TabIndex = 0; + this.rtbErrorData.Text = ""; + // + // ErrorInfo + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(542, 340); + this.Controls.Add(this.tabControl1); + this.Name = "ErrorInfo"; + this.Text = "错误信息"; + this.Load += new System.EventHandler(this.ErrorInfo_Load); + this.tabControl1.ResumeLayout(false); + this.tpErrorInfo.ResumeLayout(false); + this.tpErrorData.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.TabControl tabControl1; + private System.Windows.Forms.TabPage tpErrorInfo; + private System.Windows.Forms.RichTextBox rtbErrorInfo; + private System.Windows.Forms.TabPage tpErrorData; + private System.Windows.Forms.RichTextBox rtbErrorData; + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/ErrorInfo.resx b/src/Kalman.Studio/ErrorInfo.resx new file mode 100644 index 0000000..19dc0dd --- /dev/null +++ b/src/Kalman.Studio/ErrorInfo.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/Kalman.Studio/ExplorerForm/CodeExplorer.cs b/src/Kalman.Studio/ExplorerForm/CodeExplorer.cs new file mode 100644 index 0000000..c92d968 --- /dev/null +++ b/src/Kalman.Studio/ExplorerForm/CodeExplorer.cs @@ -0,0 +1,400 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using WeifenLuo.WinFormsUI.Docking; +using System.IO; + +namespace Kalman.Studio +{ + public partial class CodeExplorer : DockExplorer + { + public CodeExplorer() + { + InitializeComponent(); + } + + private void CodeExplorer_Load(object sender, EventArgs e) + { + LoadCodeTree(); + } + + private void LoadCodeTree() + { + string codePath = Path.Combine(Application.StartupPath, "CodeLib"); + DirectoryInfo rootDir = new DirectoryInfo(codePath); + + TreeNode root = new TreeNode("代码库", 0, 0); + root.Tag = rootDir; + root.ContextMenuStrip = cmsDir; + tvCode.Nodes.Add(root); + + DirectoryInfo dirInfo = new DirectoryInfo(codePath); + ExpendCodeDir(dirInfo, root); + } + + //展开文件夹 + private void ExpendCodeDir(DirectoryInfo rootDirInfo, TreeNode root) + { + if (root.Nodes.Count > 0) root.Nodes.Clear(); + DirectoryInfo[] dirs = rootDirInfo.GetDirectories(); + foreach (DirectoryInfo dir in dirs) + { + TreeNode node = new TreeNode(dir.Name, 1, 1); + node.Tag = dir; + root.Nodes.Add(node); + node.ContextMenuStrip = cmsDir; + } + + FileInfo[] files = rootDirInfo.GetFiles(); + foreach (FileInfo file in files) + { + int iconIndex = GetFileIconIndex(file); + TreeNode node = new TreeNode(file.Name, iconIndex, iconIndex); + node.Tag = file; + root.Nodes.Add(node); + node.ContextMenuStrip = cmsFile; + } + + root.Expand(); + } + + //获取文件对应的图标索引 + private int GetFileIconIndex(FileInfo fi) + { + FileShellInfo fsi = Win32Shell.GetFileInfo(fi.FullName); + if (imgList.Images.ContainsKey(fsi.szTypeName) == false) + { + imgList.Images.Add(fsi.szTypeName, fsi.Icon); + } + int iconIndex = imgList.Images.IndexOfKey(fsi.szTypeName); + return iconIndex; + } + + private void tvCode_MouseClick(object sender, MouseEventArgs e) + { + if (e.Button == MouseButtons.Right) + { + TreeView tv = sender as TreeView; + TreeNode tn = tv.GetNodeAt(e.X, e.Y); + tv.SelectedNode = tn; + } + } + + private void tvCode_MouseDoubleClick(object sender, MouseEventArgs e) + { + TreeView tv = sender as TreeView; + TreeNode tn = tv.GetNodeAt(e.X, e.Y); + + if (tn.Tag is DirectoryInfo) + { + ExpendCodeDir((DirectoryInfo)tn.Tag, tn); + } + if (tn.Tag is FileInfo) + { + FileInfo fi = tn.Tag as FileInfo; + OpenCodeFile(fi.FullName); + } + } + + void OpenCodeFile(string fileName) + { + foreach (IDockContent content in this.DockPanel.Documents) + { + if (content is DockDocument) + { + DockDocument doc = content as DockDocument; + if (doc.FileName == fileName) + { + doc.DockHandler.Activate(); + return; + } + } + } + + base.MainForm.OpenDockDocument(fileName, CodeType.CSHARP); + } + + #region 右键菜单命令处理 + //新建文件 + private void menuItemNewFile_Click(object sender, EventArgs e) + { + TreeNode dirNode = tvCode.SelectedNode; + DirectoryInfo dir = dirNode.Tag as DirectoryInfo; + string fileName = "NewFile"; + + int n = 1; + while (true) + { + fileName = Path.Combine(dir.FullName,string.Format("NewFile{0}.cs", n)); + n = n + 1; + if (File.Exists(fileName) == false) break; + } + + File.WriteAllText(fileName, "", Encoding.UTF8); + FileInfo fi = new FileInfo(fileName); + + int iconIndex = GetFileIconIndex(fi); + TreeNode fileNode = new TreeNode(Path.GetFileName(fileName), iconIndex, iconIndex); + fileNode.Tag = fi; + fileNode.ContextMenuStrip = cmsFile; + dirNode.Nodes.Add(fileNode); + + tvCode.SelectedNode = fileNode; + fileNode.BeginEdit(); + } + //新建目录 + private void menuItemNewDir_Click(object sender, EventArgs e) + { + TreeNode dirNode = tvCode.SelectedNode; + DirectoryInfo dir = dirNode.Tag as DirectoryInfo; + string dirName = "NewFolder"; + + int n = 1; + while (true) + { + dirName = Path.Combine(dir.FullName, string.Format("NewFolder{0}", n)); + n = n + 1; + if (Directory.Exists(dirName) == false) break; + } + + Directory.CreateDirectory(dirName); + DirectoryInfo newDir = new DirectoryInfo(dirName); + + TreeNode newDirNode = new TreeNode(newDir.Name, 1, 1); + newDirNode.Tag = newDir; + newDirNode.ContextMenuStrip = cmsDir; + dirNode.Nodes.Add(newDirNode); + + tvCode.SelectedNode = newDirNode; + newDirNode.BeginEdit(); + } + //浏览目录 + private void menuItemBrowserDir_Click(object sender, EventArgs e) + { + DirectoryInfo di = tvCode.SelectedNode.Tag as DirectoryInfo; + Kalman.Command.CmdHelper.Execute(string.Format("explorer.exe {0}", di.FullName)); + } + //删除目录 + private void menuItemDeleteDir_Click(object sender, EventArgs e) + { + if (MessageBox.Show("确定删除该目录吗,这将会删除该目录下所有文件", "提示信息", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) == DialogResult.OK) + { + TreeNode dirNode = tvCode.SelectedNode; + tvCode.Nodes.Remove(dirNode); + DirectoryInfo di = dirNode.Tag as DirectoryInfo; + string dirName = di.FullName; + di.Delete(true); + + //删除目录时,同时关闭该目录下已打开的文档 + List deletingDocs = new List(); + foreach (IDockContent content in this.DockPanel.Documents) + { + if (content is DockDocument) + { + DockDocument doc = content as DockDocument; + //判断文档所属目录是否是该删除目录,若是则将其关闭 + if (Path.GetDirectoryName(doc.FileName) == dirName) + { + deletingDocs.Add(doc); + } + } + } + foreach (IDockContent content in deletingDocs) + { + content.DockHandler.Close(); + } + } + } + //重命名目录 + private void menuItemRenameDir_Click(object sender, EventArgs e) + { + tvCode.SelectedNode.BeginEdit(); + } + //刷新目录 + private void menuItemRefresh_Click(object sender, EventArgs e) + { + ExpendCodeDir((DirectoryInfo)tvCode.SelectedNode.Tag, tvCode.SelectedNode); + } + //打开编辑文件 + private void menuItemEditFile_Click(object sender, EventArgs e) + { + FileInfo fi = tvCode.SelectedNode.Tag as FileInfo; + OpenCodeFile(fi.FullName); + } + //删除文件 + private void menuItemDeleteFile_Click(object sender, EventArgs e) + { + if (MessageBox.Show("确定删除该文件吗", "提示信息", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) == DialogResult.OK) + { + TreeNode fileNode = tvCode.SelectedNode; + tvCode.Nodes.Remove(fileNode); + + FileInfo fi = fileNode.Tag as FileInfo; + string oldFileName = fi.FullName; + File.Delete(fi.FullName); + + //若删除的文档已经打开,则将其关闭 + IDockContent deletingDoc = null; + foreach (IDockContent content in this.DockPanel.Documents) + { + if (content is DockDocument) + { + DockDocument doc = content as DockDocument; + if (doc.FileName == oldFileName) + { + deletingDoc = doc; + break; + } + } + } + if (deletingDoc != null) deletingDoc.DockHandler.Close(); + } + } + //重命名文件 + private void menuItemRenameFile_Click(object sender, EventArgs e) + { + tvCode.SelectedNode.BeginEdit(); + } + #endregion + + private void tvCode_AfterLabelEdit(object sender, NodeLabelEditEventArgs e) + { + if(string.IsNullOrEmpty(e.Label))return; + + //节点重命名后,更新对应的Tag对象 + if (e.Label == e.Node.Text) return;//标签文本没有改变 + + if (e.Node.Tag is DirectoryInfo) + { + DirectoryInfo di = e.Node.Tag as DirectoryInfo; + string oldDirName = di.FullName; + string newDirName = Path.Combine(di.Parent.FullName, e.Label); + + di.MoveTo(newDirName); + e.Node.Tag = new DirectoryInfo(newDirName); + + //重命名目录后,需要更新该目录下已打开文档的FileName属性 + foreach (IDockContent content in this.DockPanel.Documents) + { + if (content is DockDocument) + { + DockDocument doc = content as DockDocument; + //判断文档所属目录是否是该删除目录,若是则将其关闭 + if (Path.GetDirectoryName(doc.FileName) == oldDirName) + { + doc.FileName = doc.FileName.Replace(oldDirName, newDirName); + } + } + } + } + if (e.Node.Tag is FileInfo) + { + FileInfo fi = e.Node.Tag as FileInfo; + string oldFileName = fi.FullName; + string newFileName = Path.Combine(fi.DirectoryName, e.Label); + + fi.MoveTo(newFileName); + e.Node.Tag = new FileInfo(newFileName); + e.Node.EndEdit(false); + ExpendCodeDir(new DirectoryInfo(fi.DirectoryName), e.Node.Parent); + + //如果被重命名的文件已经被打开,更新打开的文档实例 + foreach (IDockContent content in this.DockPanel.Documents) + { + if (content is DockDocument) + { + DockDocument doc = content as DockDocument; + if (doc.FileName == oldFileName) + { + doc.Text = Path.GetFileName(newFileName); + doc.FileName = newFileName; + //doc.DockHandler.Activate(); + break; + } + } + } + } + } + + #region 处理拖放操作 + + TreeNode srcNode = null; //拖放起始节点 + private void tvCode_ItemDrag(object sender, ItemDragEventArgs e) + { + TreeNode node = e.Item as TreeNode; + string data = string.Empty; + + if (node.Tag is FileInfo) + { + FileInfo fi = node.Tag as FileInfo; + data = fi.FullName; + } + else if (node.Tag is DirectoryInfo) + { + DirectoryInfo di = node.Tag as DirectoryInfo; + data = di.FullName; + } + else + { + return; + } + + srcNode = e.Item as TreeNode; + DoDragDrop(data, DragDropEffects.Move); + } + + private void tvCode_DragEnter(object sender, DragEventArgs e) + { + if (e.Data.GetDataPresent(DataFormats.Text)) + e.Effect = DragDropEffects.Move; + else + e.Effect = DragDropEffects.None; + } + + private void tvCode_DragDrop(object sender, DragEventArgs e) + { + //string path = (string)e.Data.GetData(DataFormats.Text); //拖放源节点的文件或目录路径 + + Point p = new Point(e.X, e.Y); + p = tvCode.PointToClient(p);//转换坐标 + TreeNode destNode = tvCode.GetNodeAt(p); + if (destNode == null) return; + if (destNode.Tag is FileInfo) return; //如果目标节点是文件节点则不处理拖放动作 + + if (destNode.Tag is DirectoryInfo) + { + DirectoryInfo destDir = destNode.Tag as DirectoryInfo; + + if (srcNode.Tag is FileInfo) + { + FileInfo srcFile = srcNode.Tag as FileInfo; + string srcFileName = srcFile.FullName; + string destFileName = srcFile.FullName.Replace(Path.GetDirectoryName(srcFile.FullName), destDir.FullName); + if (srcFile.DirectoryName == destDir.FullName) return; + + srcFile.MoveTo(destFileName); + tvCode.Nodes.Remove(srcNode); + ExpendCodeDir(destDir, destNode); + } + if (srcNode.Tag is DirectoryInfo) + { + DirectoryInfo srcDir = srcNode.Tag as DirectoryInfo; + string srcDirName = srcDir.FullName; + string destDirName = srcDir.FullName.Replace(srcDir.Parent.FullName, destDir.FullName); + if (srcDir.FullName == destDir.FullName) return; + + srcDir.MoveTo(destDirName); + tvCode.Nodes.Remove(srcNode); + ExpendCodeDir(destDir, destNode); + } + } + } + + #endregion + } +} diff --git a/src/Kalman.Studio/ExplorerForm/CodeExplorer.designer.cs b/src/Kalman.Studio/ExplorerForm/CodeExplorer.designer.cs new file mode 100644 index 0000000..444f570 --- /dev/null +++ b/src/Kalman.Studio/ExplorerForm/CodeExplorer.designer.cs @@ -0,0 +1,205 @@ +namespace Kalman.Studio +{ + partial class CodeExplorer + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(CodeExplorer)); + this.tvCode = new System.Windows.Forms.TreeView(); + this.imgList = new System.Windows.Forms.ImageList(this.components); + this.cmsDir = new System.Windows.Forms.ContextMenuStrip(this.components); + this.menuItemNew = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemNewFile = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemNewDir = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemBrowserDir = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemDeleteDir = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemRenameDir = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemRefresh = new System.Windows.Forms.ToolStripMenuItem(); + this.cmsFile = new System.Windows.Forms.ContextMenuStrip(this.components); + this.menuItemEditFile = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemDeleteFile = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemRenameFile = new System.Windows.Forms.ToolStripMenuItem(); + this.cmsDir.SuspendLayout(); + this.cmsFile.SuspendLayout(); + this.SuspendLayout(); + // + // tvCode + // + this.tvCode.AllowDrop = true; + this.tvCode.Dock = System.Windows.Forms.DockStyle.Fill; + this.tvCode.ImageIndex = 0; + this.tvCode.ImageList = this.imgList; + this.tvCode.LabelEdit = true; + this.tvCode.Location = new System.Drawing.Point(0, 0); + this.tvCode.Margin = new System.Windows.Forms.Padding(5); + this.tvCode.Name = "tvCode"; + this.tvCode.SelectedImageIndex = 0; + this.tvCode.Size = new System.Drawing.Size(253, 531); + this.tvCode.TabIndex = 0; + this.tvCode.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.tvCode_MouseDoubleClick); + this.tvCode.MouseClick += new System.Windows.Forms.MouseEventHandler(this.tvCode_MouseClick); + this.tvCode.AfterLabelEdit += new System.Windows.Forms.NodeLabelEditEventHandler(this.tvCode_AfterLabelEdit); + this.tvCode.DragDrop += new System.Windows.Forms.DragEventHandler(this.tvCode_DragDrop); + this.tvCode.DragEnter += new System.Windows.Forms.DragEventHandler(this.tvCode_DragEnter); + this.tvCode.ItemDrag += new System.Windows.Forms.ItemDragEventHandler(this.tvCode_ItemDrag); + // + // imgList + // + this.imgList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imgList.ImageStream"))); + this.imgList.TransparentColor = System.Drawing.Color.Transparent; + this.imgList.Images.SetKeyName(0, "codeRoot.png"); + this.imgList.Images.SetKeyName(1, "codeFolder.png"); + // + // cmsDir + // + this.cmsDir.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.menuItemNew, + this.menuItemBrowserDir, + this.menuItemDeleteDir, + this.menuItemRenameDir, + this.menuItemRefresh}); + this.cmsDir.Name = "cmsDir"; + this.cmsDir.Size = new System.Drawing.Size(123, 114); + // + // menuItemNew + // + this.menuItemNew.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.menuItemNewFile, + this.menuItemNewDir}); + this.menuItemNew.Name = "menuItemNew"; + this.menuItemNew.Size = new System.Drawing.Size(122, 22); + this.menuItemNew.Text = "新建"; + // + // menuItemNewFile + // + this.menuItemNewFile.Name = "menuItemNewFile"; + this.menuItemNewFile.Size = new System.Drawing.Size(122, 22); + this.menuItemNewFile.Text = "代码文件"; + this.menuItemNewFile.Click += new System.EventHandler(this.menuItemNewFile_Click); + // + // menuItemNewDir + // + this.menuItemNewDir.Name = "menuItemNewDir"; + this.menuItemNewDir.Size = new System.Drawing.Size(122, 22); + this.menuItemNewDir.Text = "代码目录"; + this.menuItemNewDir.Click += new System.EventHandler(this.menuItemNewDir_Click); + // + // menuItemBrowserDir + // + this.menuItemBrowserDir.Name = "menuItemBrowserDir"; + this.menuItemBrowserDir.Size = new System.Drawing.Size(122, 22); + this.menuItemBrowserDir.Text = "浏览目录"; + this.menuItemBrowserDir.Click += new System.EventHandler(this.menuItemBrowserDir_Click); + // + // menuItemDeleteDir + // + this.menuItemDeleteDir.Name = "menuItemDeleteDir"; + this.menuItemDeleteDir.Size = new System.Drawing.Size(122, 22); + this.menuItemDeleteDir.Text = "删除"; + this.menuItemDeleteDir.Click += new System.EventHandler(this.menuItemDeleteDir_Click); + // + // menuItemRenameDir + // + this.menuItemRenameDir.Name = "menuItemRenameDir"; + this.menuItemRenameDir.Size = new System.Drawing.Size(122, 22); + this.menuItemRenameDir.Text = "重命名"; + this.menuItemRenameDir.Click += new System.EventHandler(this.menuItemRenameDir_Click); + // + // menuItemRefresh + // + this.menuItemRefresh.Name = "menuItemRefresh"; + this.menuItemRefresh.Size = new System.Drawing.Size(122, 22); + this.menuItemRefresh.Text = "刷新"; + this.menuItemRefresh.Click += new System.EventHandler(this.menuItemRefresh_Click); + // + // cmsFile + // + this.cmsFile.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.menuItemEditFile, + this.menuItemDeleteFile, + this.menuItemRenameFile}); + this.cmsFile.Name = "cmsFile"; + this.cmsFile.Size = new System.Drawing.Size(111, 70); + // + // menuItemEditFile + // + this.menuItemEditFile.Name = "menuItemEditFile"; + this.menuItemEditFile.Size = new System.Drawing.Size(110, 22); + this.menuItemEditFile.Text = "编辑"; + this.menuItemEditFile.Click += new System.EventHandler(this.menuItemEditFile_Click); + // + // menuItemDeleteFile + // + this.menuItemDeleteFile.Name = "menuItemDeleteFile"; + this.menuItemDeleteFile.Size = new System.Drawing.Size(110, 22); + this.menuItemDeleteFile.Text = "删除"; + this.menuItemDeleteFile.Click += new System.EventHandler(this.menuItemDeleteFile_Click); + // + // menuItemRenameFile + // + this.menuItemRenameFile.Name = "menuItemRenameFile"; + this.menuItemRenameFile.Size = new System.Drawing.Size(110, 22); + this.menuItemRenameFile.Text = "重命名"; + this.menuItemRenameFile.Click += new System.EventHandler(this.menuItemRenameFile_Click); + // + // CodeExplorer + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(253, 531); + this.Controls.Add(this.tvCode); + this.DockAreas = ((WeifenLuo.WinFormsUI.Docking.DockAreas)((WeifenLuo.WinFormsUI.Docking.DockAreas.DockLeft | WeifenLuo.WinFormsUI.Docking.DockAreas.DockRight))); + this.HideOnClose = true; + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "CodeExplorer"; + this.Text = "代码资源管理器"; + this.Load += new System.EventHandler(this.CodeExplorer_Load); + this.cmsDir.ResumeLayout(false); + this.cmsFile.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.TreeView tvCode; + private System.Windows.Forms.ImageList imgList; + private System.Windows.Forms.ContextMenuStrip cmsDir; + private System.Windows.Forms.ToolStripMenuItem menuItemNew; + private System.Windows.Forms.ToolStripMenuItem menuItemNewFile; + private System.Windows.Forms.ToolStripMenuItem menuItemNewDir; + private System.Windows.Forms.ToolStripMenuItem menuItemBrowserDir; + private System.Windows.Forms.ToolStripMenuItem menuItemDeleteDir; + private System.Windows.Forms.ToolStripMenuItem menuItemRenameDir; + private System.Windows.Forms.ToolStripMenuItem menuItemRefresh; + private System.Windows.Forms.ContextMenuStrip cmsFile; + private System.Windows.Forms.ToolStripMenuItem menuItemEditFile; + private System.Windows.Forms.ToolStripMenuItem menuItemDeleteFile; + private System.Windows.Forms.ToolStripMenuItem menuItemRenameFile; + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/ExplorerForm/CodeExplorer.resx b/src/Kalman.Studio/ExplorerForm/CodeExplorer.resx new file mode 100644 index 0000000..b9a94de --- /dev/null +++ b/src/Kalman.Studio/ExplorerForm/CodeExplorer.resx @@ -0,0 +1,203 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj0yLjAuMC4w + LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 + ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAACy + CAAAAk1TRnQBSQFMAgEBAgEAAQQBAAEEAQABEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo + AwABQAMAARADAAEBAQABCAYAAQQYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA + AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5 + AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA + AWYDAAGZAwABzAIAATMDAAIzAgABMwFmAgABMwGZAgABMwHMAgABMwH/AgABZgMAAWYBMwIAAmYCAAFm + AZkCAAFmAcwCAAFmAf8CAAGZAwABmQEzAgABmQFmAgACmQIAAZkBzAIAAZkB/wIAAcwDAAHMATMCAAHM + AWYCAAHMAZkCAALMAgABzAH/AgAB/wFmAgAB/wGZAgAB/wHMAQABMwH/AgAB/wEAATMBAAEzAQABZgEA + ATMBAAGZAQABMwEAAcwBAAEzAQAB/wEAAf8BMwIAAzMBAAIzAWYBAAIzAZkBAAIzAcwBAAIzAf8BAAEz + AWYCAAEzAWYBMwEAATMCZgEAATMBZgGZAQABMwFmAcwBAAEzAWYB/wEAATMBmQIAATMBmQEzAQABMwGZ + AWYBAAEzApkBAAEzAZkBzAEAATMBmQH/AQABMwHMAgABMwHMATMBAAEzAcwBZgEAATMBzAGZAQABMwLM + AQABMwHMAf8BAAEzAf8BMwEAATMB/wFmAQABMwH/AZkBAAEzAf8BzAEAATMC/wEAAWYDAAFmAQABMwEA + AWYBAAFmAQABZgEAAZkBAAFmAQABzAEAAWYBAAH/AQABZgEzAgABZgIzAQABZgEzAWYBAAFmATMBmQEA + AWYBMwHMAQABZgEzAf8BAAJmAgACZgEzAQADZgEAAmYBmQEAAmYBzAEAAWYBmQIAAWYBmQEzAQABZgGZ + AWYBAAFmApkBAAFmAZkBzAEAAWYBmQH/AQABZgHMAgABZgHMATMBAAFmAcwBmQEAAWYCzAEAAWYBzAH/ + AQABZgH/AgABZgH/ATMBAAFmAf8BmQEAAWYB/wHMAQABzAEAAf8BAAH/AQABzAEAApkCAAGZATMBmQEA + AZkBAAGZAQABmQEAAcwBAAGZAwABmQIzAQABmQEAAWYBAAGZATMBzAEAAZkBAAH/AQABmQFmAgABmQFm + ATMBAAGZATMBZgEAAZkBZgGZAQABmQFmAcwBAAGZATMB/wEAApkBMwEAApkBZgEAA5kBAAKZAcwBAAKZ + Af8BAAGZAcwCAAGZAcwBMwEAAWYBzAFmAQABmQHMAZkBAAGZAswBAAGZAcwB/wEAAZkB/wIAAZkB/wEz + AQABmQHMAWYBAAGZAf8BmQEAAZkB/wHMAQABmQL/AQABzAMAAZkBAAEzAQABzAEAAWYBAAHMAQABmQEA + AcwBAAHMAQABmQEzAgABzAIzAQABzAEzAWYBAAHMATMBmQEAAcwBMwHMAQABzAEzAf8BAAHMAWYCAAHM + AWYBMwEAAZkCZgEAAcwBZgGZAQABzAFmAcwBAAGZAWYB/wEAAcwBmQIAAcwBmQEzAQABzAGZAWYBAAHM + ApkBAAHMAZkBzAEAAcwBmQH/AQACzAIAAswBMwEAAswBZgEAAswBmQEAA8wBAALMAf8BAAHMAf8CAAHM + Af8BMwEAAZkB/wFmAQABzAH/AZkBAAHMAf8BzAEAAcwC/wEAAcwBAAEzAQAB/wEAAWYBAAH/AQABmQEA + AcwBMwIAAf8CMwEAAf8BMwFmAQAB/wEzAZkBAAH/ATMBzAEAAf8BMwH/AQAB/wFmAgAB/wFmATMBAAHM + AmYBAAH/AWYBmQEAAf8BZgHMAQABzAFmAf8BAAH/AZkCAAH/AZkBMwEAAf8BmQFmAQAB/wKZAQAB/wGZ + AcwBAAH/AZkB/wEAAf8BzAIAAf8BzAEzAQAB/wHMAWYBAAH/AcwBmQEAAf8CzAEAAf8BzAH/AQAC/wEz + AQABzAH/AWYBAAL/AZkBAAL/AcwBAAJmAf8BAAFmAf8BZgEAAWYC/wEAAf8CZgEAAf8BZgH/AQAC/wFm + AQABIQEAAaUBAANfAQADdwEAA4YBAAOWAQADywEAA7IBAAPXAQAD3QEAA+MBAAPqAQAD8QEAA/gBAAHw + AfsB/wEAAaQCoAEAA4ADAAH/AgAB/wMAAv8BAAH/AwAB/wEAAf8BAAL/AgAD/wsAASoBKTsAAVEBKQEc + ATEBMAF0ASkBczEAAQcDrgHsAe8BvAEpAXoBKQJ6ASkBoAEpAe8BvA6uAQcgAAH3Af8E8wH0AZkBKQF6 + AioBoAEpAZkB8QH3Af8D8wcZA90BriAAAfcF/wEwASkBegEpAv8BKgGgATABKQH3BP8B9ATzBRkBriAA + AfcF/wExATABegEpAv8BKgF6ATEBMAH3Bf8B9ATzBBkBriAAAfcG/wGZASkBegIpAXoBKQGZAfEB9wb/ + AfQE8wMZAa4gAAH3Bv8BKQF6ASkCegEpAXoBKQG8AfcH/wL0A/MCGQGuIAAB9wb/AXQBKQGZATABKQGZ + ASkBdAEHAfcJ/wH0A/MBGQGuIAAB9wn/ATEBMAL/ARkC9wr/AfQC8wEZAa4gAAH3DP8B9AEZAewB9wv/ + AfQB8wEZAa4gAAH3Dv8BrgH3Dv8BriAAAQcB9wT/Ca4B9wG8AfcE/wmuAQchAAH3BP8B9wEAAfcECQHr + AwAB9wT/AfcBAAH3BAkB6yMAAQcE9wEHAQABBwT3AQcDAAG8BPcBvAEAAbwE9wG8YgABQgFNAT4HAAE+ + AwABKAMAAUADAAEQAwABAQEAAQEFAAGAFwAD/wEAAf8BzwL/BAAB/gEBAv9cAAGBAQMBgQEDBAABgQED + AYEBAwQABP8EAAs= + + + + 112, 17 + + + 201, 17 + + + + + AAABAAEAEBAAAAAAAABoBQAAFgAAACgAAAAQAAAAIAAAAAEACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAACAAACAAAAAgIAAgAAAAIAAgACAgAAAgICAAMDcwADwyqYAqj8qAP8/KgAAXyoAVV8qAKpf + KgD/XyoAAH8qAFV/KgCqfyoA/38qAACfKgBVnyoAqp8qAP+fKgAAvyoAVb8qAKq/KgD/vyoAAN8qAFXf + KgCq3yoA/98qAAD/KgBV/yoAqv8qAP//KgAAAFUAVQBVAKoAVQD/AFUAAB9VAFUfVQCqH1UA/x9VAAA/ + VQBVP1UAqj9VAP8/VQAAX1UAVV9VAKpfVQD/X1UAAH9VAFV/VQCqf1UA/39VAACfVQBVn1UAqp9VAP+f + VQAAv1UAVb9VAKq/VQD/v1UAAN9VAFXfVQCq31UA/99VAAD/VQBV/1UAqv9VAP//VQAAAH8AVQB/AKoA + fwD/AH8AAB9/AFUffwCqH38A/x9/AAA/fwBVP38Aqj9/AP8/fwAAX38AVV9/AKpffwD/X38AAH9/AFV/ + fwCqf38A/39/AACffwBVn38Aqp9/AP+ffwAAv38AVb9/AKq/fwD/v38AAN9/AFXffwCq338A/99/AAD/ + fwBV/38Aqv9/AP//fwAAAKoAVQCqAKoAqgD/AKoAAB+qAFUfqgCqH6oA/x+qAAA/qgBVP6oAqj+qAP8/ + qgAAX6oAVV+qAKpfqgD/X6oAAH+qAFV/qgCqf6oA/3+qAACfqgBVn6oAqp+qAP+fqgAAv6oAVb+qAKq/ + qgD/v6oAAN+qAFXfqgCq36oA/9+qAAD/qgBV/6oAqv+qAP//qgAAANQAVQDUAKoA1AD/ANQAAB/UAFUf + 1ACqH9QA/x/UAAA/1ABVP9QAqj/UAP8/1AAAX9QAVV/UAKpf1AD/X9QAAH/UAFV/1ACqf9QA/3/UAACf + 1ABVn9QAqp/UAP+f1AAAv9QAVb/UAKq/1AD/v9QAAN/UAFXf1ACq39QA/9/UAAD/1ABV/9QAqv/UAP// + 1ABVAP8AqgD/AAAf/wBVH/8Aqh//AP8f/wAAP/8AVT//AKo//wD/P/8AAF//AFVf/wCqX/8A/1//AAB/ + /wBVf/8Aqn//AP9//wAAn/8AVZ//AKqf/wD/n/8AAL//AFW//wCqv/8A/7//AADf/wBV3/8Aqt//AP/f + /wBV//8Aqv//AP/MzAD/zP8A//8zAP//ZgD//5kA///MAAB/AABVfwAAqn8AAP9/AAAAnwAAVZ8AAKqf + AAD/nwAAAL8AAFW/AACqvwAA/78AAADfAABV3wAAqt8AAP/fAABV/wAAqv8AAAAAKgBVACoAqgAqAP8A + KgAAHyoAVR8qAKofKgD/HyoAAD8qAFU/KgDw+/8ApKCgAICAgAAAAP8AAP8AAAD//wD/AAAAAAAAAP// + AAD///8A/f0yMv1aMv39/f39/f39/f39MjItMvUt9Q319fX19f0yLTIyMlsyMvXLy8rLy/X9W1pbMvda + MjIy09PT06j1/f1aX/Wuhlcy0NPT09PL9f1bgoNWMTJWMvU2Xq7Tz/X9CYOHg1taM1pWETJe08v1/f39 + g4JaW1YRFRINEdPLDf39/YJb9lo2FDY3FRXTz/X9/f39hvb2imWKOhJi09D1/f39/YL29vYIimEJstPP + 9f39/f0J9vb29vb20/bQ0A39/f39hvb29vb29vaC9fX1/f39/Qn///b29vb2XtT1/f39/f0I0f/29vb2 + 9oL1/f39/f39CQkICQkICYYJ/f39/cn/q4fAAQn/AAEyWwABLvWAAdP2AAHT0wAB09PAAcswwAFff+AB + VgngAVpa4AEyMuABgl7gA15e4AdeWuAPyy0= + + + \ No newline at end of file diff --git a/src/Kalman.Studio/ExplorerForm/DatabaseExplorer.Designer.cs b/src/Kalman.Studio/ExplorerForm/DatabaseExplorer.Designer.cs new file mode 100644 index 0000000..60558f6 --- /dev/null +++ b/src/Kalman.Studio/ExplorerForm/DatabaseExplorer.Designer.cs @@ -0,0 +1,318 @@ +namespace Kalman.Studio +{ + partial class DatabaseExplorer + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(DatabaseExplorer)); + this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); + this.cbConnectionStrings = new System.Windows.Forms.ComboBox(); + this.tvDatabase = new System.Windows.Forms.TreeView(); + this.imgList = new System.Windows.Forms.ImageList(this.components); + this.btnSetConnectString = new System.Windows.Forms.Button(); + this.cmsTable = new System.Windows.Forms.ContextMenuStrip(this.components); + this.menuItemPreviewTableData = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemBuildCodeForTable = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemBuildTestDataForTable = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemBuildInsertSqlForTable = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemSpSql = new System.Windows.Forms.ToolStripMenuItem(); + this.cmsSp = new System.Windows.Forms.ContextMenuStrip(this.components); + this.menuItemViewSql = new System.Windows.Forms.ToolStripMenuItem(); + this.cmsView = new System.Windows.Forms.ContextMenuStrip(this.components); + this.menuItemRefreshDB = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemNewQuery = new System.Windows.Forms.ToolStripMenuItem(); + this.cmsDatabase = new System.Windows.Forms.ContextMenuStrip(this.components); + this.menuItemViewDB = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemBatchBuildCode = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemBuildDBDoc = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStrip1 = new System.Windows.Forms.ToolStrip(); + this.tsbAddDbConnect = new System.Windows.Forms.ToolStripButton(); + this.tableLayoutPanel1.SuspendLayout(); + this.cmsTable.SuspendLayout(); + this.cmsSp.SuspendLayout(); + this.cmsView.SuspendLayout(); + this.cmsDatabase.SuspendLayout(); + this.toolStrip1.SuspendLayout(); + this.SuspendLayout(); + // + // tableLayoutPanel1 + // + this.tableLayoutPanel1.ColumnCount = 2; + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 84F)); + this.tableLayoutPanel1.Controls.Add(this.cbConnectionStrings, 0, 0); + this.tableLayoutPanel1.Controls.Add(this.tvDatabase, 0, 1); + this.tableLayoutPanel1.Controls.Add(this.btnSetConnectString, 1, 0); + this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0); + this.tableLayoutPanel1.Name = "tableLayoutPanel1"; + this.tableLayoutPanel1.RowCount = 2; + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25F)); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.Size = new System.Drawing.Size(290, 429); + this.tableLayoutPanel1.TabIndex = 4; + // + // cbConnectionStrings + // + this.cbConnectionStrings.Dock = System.Windows.Forms.DockStyle.Fill; + this.cbConnectionStrings.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.cbConnectionStrings.FormattingEnabled = true; + this.cbConnectionStrings.Location = new System.Drawing.Point(3, 3); + this.cbConnectionStrings.Name = "cbConnectionStrings"; + this.cbConnectionStrings.Size = new System.Drawing.Size(200, 20); + this.cbConnectionStrings.TabIndex = 0; + this.cbConnectionStrings.SelectedIndexChanged += new System.EventHandler(this.cbConnectionStrings_SelectedIndexChanged); + // + // tvDatabase + // + this.tableLayoutPanel1.SetColumnSpan(this.tvDatabase, 2); + this.tvDatabase.Dock = System.Windows.Forms.DockStyle.Fill; + this.tvDatabase.HotTracking = true; + this.tvDatabase.ImageIndex = 0; + this.tvDatabase.ImageList = this.imgList; + this.tvDatabase.Location = new System.Drawing.Point(5, 30); + this.tvDatabase.Margin = new System.Windows.Forms.Padding(5); + this.tvDatabase.Name = "tvDatabase"; + this.tvDatabase.SelectedImageIndex = 0; + this.tvDatabase.ShowNodeToolTips = true; + this.tvDatabase.Size = new System.Drawing.Size(280, 398); + this.tvDatabase.TabIndex = 1; + this.tvDatabase.MouseClick += new System.Windows.Forms.MouseEventHandler(this.tvDatabase_MouseClick); + this.tvDatabase.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.tvDatabase_MouseDoubleClick); + // + // imgList + // + this.imgList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imgList.ImageStream"))); + this.imgList.TransparentColor = System.Drawing.Color.Transparent; + this.imgList.Images.SetKeyName(0, "cs2.ICO"); + this.imgList.Images.SetKeyName(1, "db.ico"); + this.imgList.Images.SetKeyName(2, "folder.ICO"); + this.imgList.Images.SetKeyName(3, "table.ICO"); + this.imgList.Images.SetKeyName(4, "view.ICO"); + this.imgList.Images.SetKeyName(5, "sp.ICO"); + this.imgList.Images.SetKeyName(6, "key.ICO"); + this.imgList.Images.SetKeyName(7, "column.ICO"); + this.imgList.Images.SetKeyName(8, "index.ICO"); + this.imgList.Images.SetKeyName(9, "trigger.ICO"); + this.imgList.Images.SetKeyName(10, "check.ICO"); + // + // btnSetConnectString + // + this.btnSetConnectString.Location = new System.Drawing.Point(209, 3); + this.btnSetConnectString.Name = "btnSetConnectString"; + this.btnSetConnectString.Size = new System.Drawing.Size(75, 19); + this.btnSetConnectString.TabIndex = 2; + this.btnSetConnectString.Text = "设置服务器"; + this.btnSetConnectString.UseVisualStyleBackColor = true; + this.btnSetConnectString.Click += new System.EventHandler(this.btnSetConnectString_Click); + // + // cmsTable + // + this.cmsTable.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.menuItemPreviewTableData, + this.menuItemBuildCodeForTable, + this.menuItemBuildTestDataForTable, + this.menuItemBuildInsertSqlForTable}); + this.cmsTable.Name = "cmsTable"; + this.cmsTable.Size = new System.Drawing.Size(173, 92); + // + // menuItemPreviewTableData + // + this.menuItemPreviewTableData.Name = "menuItemPreviewTableData"; + this.menuItemPreviewTableData.Size = new System.Drawing.Size(172, 22); + this.menuItemPreviewTableData.Text = "查看前1000行"; + this.menuItemPreviewTableData.Click += new System.EventHandler(this.menuItemPreviewTableData_Click); + // + // menuItemBuildCodeForTable + // + this.menuItemBuildCodeForTable.Name = "menuItemBuildCodeForTable"; + this.menuItemBuildCodeForTable.Size = new System.Drawing.Size(172, 22); + this.menuItemBuildCodeForTable.Text = "代码生成器"; + this.menuItemBuildCodeForTable.Click += new System.EventHandler(this.menuItemBuildCodeForTable_Click); + // + // menuItemBuildTestDataForTable + // + this.menuItemBuildTestDataForTable.Name = "menuItemBuildTestDataForTable"; + this.menuItemBuildTestDataForTable.Size = new System.Drawing.Size(172, 22); + this.menuItemBuildTestDataForTable.Text = "测试数据生成器"; + this.menuItemBuildTestDataForTable.Click += new System.EventHandler(this.menuItemBuildTestDataForTable_Click); + // + // menuItemBuildInsertSqlForTable + // + this.menuItemBuildInsertSqlForTable.Name = "menuItemBuildInsertSqlForTable"; + this.menuItemBuildInsertSqlForTable.Size = new System.Drawing.Size(172, 22); + this.menuItemBuildInsertSqlForTable.Text = "生成数据插入脚本"; + this.menuItemBuildInsertSqlForTable.Click += new System.EventHandler(this.menuItemBuildInsertSqlForTable_Click); + // + // menuItemSpSql + // + this.menuItemSpSql.Name = "menuItemSpSql"; + this.menuItemSpSql.Size = new System.Drawing.Size(172, 22); + this.menuItemSpSql.Text = "查看存储过程定义"; + this.menuItemSpSql.Click += new System.EventHandler(this.menuItemSpSql_Click); + // + // cmsSp + // + this.cmsSp.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.menuItemSpSql}); + this.cmsSp.Name = "cmsSp"; + this.cmsSp.Size = new System.Drawing.Size(173, 26); + // + // menuItemViewSql + // + this.menuItemViewSql.Name = "menuItemViewSql"; + this.menuItemViewSql.Size = new System.Drawing.Size(148, 22); + this.menuItemViewSql.Text = "查看视图定义"; + this.menuItemViewSql.Click += new System.EventHandler(this.menuItemViewSql_Click); + // + // cmsView + // + this.cmsView.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.menuItemViewSql}); + this.cmsView.Name = "cmsView"; + this.cmsView.Size = new System.Drawing.Size(149, 26); + // + // menuItemRefreshDB + // + this.menuItemRefreshDB.Name = "menuItemRefreshDB"; + this.menuItemRefreshDB.Size = new System.Drawing.Size(160, 22); + this.menuItemRefreshDB.Text = "刷新数据库"; + this.menuItemRefreshDB.Click += new System.EventHandler(this.menuItemRefreshDB_Click); + // + // menuItemNewQuery + // + this.menuItemNewQuery.Name = "menuItemNewQuery"; + this.menuItemNewQuery.Size = new System.Drawing.Size(160, 22); + this.menuItemNewQuery.Text = "新建查询"; + this.menuItemNewQuery.Click += new System.EventHandler(this.menuItemNewQuery_Click); + // + // cmsDatabase + // + this.cmsDatabase.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.menuItemNewQuery, + this.menuItemViewDB, + this.menuItemBatchBuildCode, + this.menuItemBuildDBDoc, + this.menuItemRefreshDB}); + this.cmsDatabase.Name = "cmsDatabase"; + this.cmsDatabase.Size = new System.Drawing.Size(161, 114); + // + // menuItemViewDB + // + this.menuItemViewDB.Name = "menuItemViewDB"; + this.menuItemViewDB.Size = new System.Drawing.Size(160, 22); + this.menuItemViewDB.Text = "查看数据库"; + this.menuItemViewDB.Click += new System.EventHandler(this.menuItemViewDB_Click); + // + // menuItemBatchBuildCode + // + this.menuItemBatchBuildCode.Name = "menuItemBatchBuildCode"; + this.menuItemBatchBuildCode.Size = new System.Drawing.Size(160, 22); + this.menuItemBatchBuildCode.Text = "批量生成代码"; + this.menuItemBatchBuildCode.Click += new System.EventHandler(this.menuItemBatchBuildCode_Click); + // + // menuItemBuildDBDoc + // + this.menuItemBuildDBDoc.Name = "menuItemBuildDBDoc"; + this.menuItemBuildDBDoc.Size = new System.Drawing.Size(160, 22); + this.menuItemBuildDBDoc.Text = "生成数据库文档"; + this.menuItemBuildDBDoc.Click += new System.EventHandler(this.menuItemBuildDBDoc_Click); + // + // toolStrip1 + // + this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.tsbAddDbConnect}); + this.toolStrip1.Location = new System.Drawing.Point(0, 0); + this.toolStrip1.Name = "toolStrip1"; + this.toolStrip1.Size = new System.Drawing.Size(290, 25); + this.toolStrip1.TabIndex = 4; + this.toolStrip1.Text = "toolStrip1"; + this.toolStrip1.Visible = false; + // + // tsbAddDbConnect + // + this.tsbAddDbConnect.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.tsbAddDbConnect.Image = ((System.Drawing.Image)(resources.GetObject("tsbAddDbConnect.Image"))); + this.tsbAddDbConnect.ImageTransparentColor = System.Drawing.Color.Magenta; + this.tsbAddDbConnect.Name = "tsbAddDbConnect"; + this.tsbAddDbConnect.Size = new System.Drawing.Size(23, 22); + this.tsbAddDbConnect.Text = "添加数据库连接"; + this.tsbAddDbConnect.Click += new System.EventHandler(this.tsbAddDbConnect_Click); + // + // DatabaseExplorer + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(290, 429); + this.Controls.Add(this.tableLayoutPanel1); + this.Controls.Add(this.toolStrip1); + this.DockAreas = WeifenLuo.WinFormsUI.Docking.DockAreas.DockLeft; + this.HideOnClose = true; + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "DatabaseExplorer"; + this.ShowHint = WeifenLuo.WinFormsUI.Docking.DockState.DockLeft; + this.Text = "数据库对象浏览器"; + this.Load += new System.EventHandler(this.DatabaseExplorer_Load); + this.tableLayoutPanel1.ResumeLayout(false); + this.cmsTable.ResumeLayout(false); + this.cmsSp.ResumeLayout(false); + this.cmsView.ResumeLayout(false); + this.cmsDatabase.ResumeLayout(false); + this.toolStrip1.ResumeLayout(false); + this.toolStrip1.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; + private System.Windows.Forms.ComboBox cbConnectionStrings; + private System.Windows.Forms.TreeView tvDatabase; + private System.Windows.Forms.ImageList imgList; + private System.Windows.Forms.ContextMenuStrip cmsTable; + private System.Windows.Forms.ToolStripMenuItem menuItemPreviewTableData; + private System.Windows.Forms.ToolStripMenuItem menuItemBuildCodeForTable; + private System.Windows.Forms.ToolStripMenuItem menuItemBuildInsertSqlForTable; + private System.Windows.Forms.ToolStripMenuItem menuItemSpSql; + private System.Windows.Forms.ContextMenuStrip cmsSp; + private System.Windows.Forms.ToolStripMenuItem menuItemViewSql; + private System.Windows.Forms.ContextMenuStrip cmsView; + private System.Windows.Forms.ToolStripMenuItem menuItemRefreshDB; + private System.Windows.Forms.ToolStripMenuItem menuItemNewQuery; + private System.Windows.Forms.ContextMenuStrip cmsDatabase; + private System.Windows.Forms.ToolStripMenuItem menuItemViewDB; + private System.Windows.Forms.ToolStripMenuItem menuItemBatchBuildCode; + private System.Windows.Forms.ToolStripMenuItem menuItemBuildDBDoc; + private System.Windows.Forms.ToolStripMenuItem menuItemBuildTestDataForTable; + private System.Windows.Forms.ToolStrip toolStrip1; + private System.Windows.Forms.ToolStripButton tsbAddDbConnect; + private System.Windows.Forms.Button btnSetConnectString; + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/ExplorerForm/DatabaseExplorer.cs b/src/Kalman.Studio/ExplorerForm/DatabaseExplorer.cs new file mode 100644 index 0000000..21af5ee --- /dev/null +++ b/src/Kalman.Studio/ExplorerForm/DatabaseExplorer.cs @@ -0,0 +1,451 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Data.OleDb; +using System.Data.Odbc; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using System.Configuration; +using Kalman.Data; +using Kalman.Data.SchemaObject; +using System.Diagnostics; + +namespace Kalman.Studio +{ + public partial class DatabaseExplorer : DockExplorer + { + public DatabaseExplorer() + { + InitializeComponent(); + } + + private void DatabaseExplorer_Load(object sender, EventArgs e) + { + RefreshDatabase(); + //menuItemBuildSqlForTable.Visible = false; + this.DockPanel.DockLeftPortion = 300; + } + + DbSchema dbSchema; + private void cbConnectionStrings_SelectedIndexChanged(object sender, EventArgs e) + { + tvDatabase.Nodes.Clear(); + + ConnectionStringSettings css = ConfigurationManager.ConnectionStrings[cbConnectionStrings.SelectedItem.ToString()]; + dbSchema = DbSchemaFactory.Create(css.Name); + DbSchemaHelper.Instance.CurrentSchema = dbSchema; + + TreeNode root = new TreeNode(css.Name, 0, 0); + root.ToolTipText = css.ConnectionString; + tvDatabase.Nodes.Add(root); + + Main m = this.ParentForm as Main; + m.ClearDbList(); + + this.Cursor = Cursors.WaitCursor; + IList dbList = dbSchema.GetDatabaseList(); + this.Cursor = Cursors.Default; + + foreach (SODatabase db in dbList) + { + TreeNode dbNode = new TreeNode(db.Name, 1, 1); + dbNode.Tag = db; + dbNode.ToolTipText = string.IsNullOrEmpty(db.Comment) ? db.Name : db.Comment; + dbNode.ContextMenuStrip = cmsDatabase; + root.Nodes.Add(dbNode); + + MainForm.AddDbListItem(db); + } + + root.Expand(); + } + + //加载数据库元数据架构信息 + void LoadDbSchema(TreeNode dbNode) + { + this.Cursor = Cursors.WaitCursor; + dbNode.Nodes.Clear(); + SODatabase db = dbNode.Tag as SODatabase; + TreeNode tableNode = new TreeNode("表", 2, 2); + TreeNode viewNode = new TreeNode("视图", 2, 2); + TreeNode spNode = new TreeNode("存储过程", 2, 2); + + //加载表列表 + IList tableList = dbSchema.GetTableList(db); + foreach (SOTable t in tableList) + { + //TreeNode tn = new TreeNode(t.FullName, 3, 3); + TreeNode tn = new TreeNode(t.Name, 3, 3); + tn.Tag = t; + tn.ToolTipText = string.IsNullOrEmpty(t.Comment) ? t.Name : t.Comment; + tn.ContextMenuStrip = cmsTable; + tableNode.Nodes.Add(tn); + } + + //加载视图列表 + IList viewList = dbSchema.GetViewList(db); + foreach (SOView v in viewList) + { + //TreeNode tn = new TreeNode(v.FullName, 4, 4); + TreeNode tn = new TreeNode(v.Name, 4, 4); + tn.Tag = v; + tn.ToolTipText = string.IsNullOrEmpty(v.Comment) ? v.Name : v.Comment; + tn.ContextMenuStrip = cmsView; + viewNode.Nodes.Add(tn); + } + + //加载存储过程列表 + IList spList = dbSchema.GetCommandList(db); + + if (spList != null && spList.Count > 0) + { + foreach (SOCommand p in spList) + { + //TreeNode tn = new TreeNode(p.FullName, 5, 5); + TreeNode tn = new TreeNode(p.Name, 5, 5); + tn.Tag = p; + tn.ToolTipText = string.IsNullOrEmpty(p.Comment) ? p.Name : p.Comment; + tn.ContextMenuStrip = cmsSp; + spNode.Nodes.Add(tn); + } + } + + dbNode.Nodes.Add(tableNode); + dbNode.Nodes.Add(viewNode); + dbNode.Nodes.Add(spNode); + this.Cursor = Cursors.Default; + } + + + #region 树形菜单事件处理 + + //解决右键点击节点定位的问题 + private void tvDatabase_MouseClick(object sender, MouseEventArgs e) + { + if (e.Button == MouseButtons.Right) + { + TreeView tv = sender as TreeView; + TreeNode tn = tv.GetNodeAt(e.X, e.Y); + tv.SelectedNode = tn; + } + } + + private void tvDatabase_MouseDoubleClick(object sender, MouseEventArgs e) + { + TreeView tv = sender as TreeView; + TreeNode tn = tv.GetNodeAt(e.X, e.Y); + + if (tn != null && tn.Level == 1 && tn.Nodes.Count == 0) + { + LoadDbSchema(tn); + tn.Expand(); + } + if (tn != null && tn.Parent != null && tn.Level == 3) + { + if (tn.Parent.Text == "表") + { + if (this.DockPanel.ActiveDocument is CodeBuilder) + { + SOTable t = tvDatabase.SelectedNode.Tag as SOTable; + if (t == null) return; + + CodeBuilder builder = this.DockPanel.ActiveDocument as CodeBuilder; + builder.Table = t; + builder.ColumnList = dbSchema.GetTableColumnList(t); + builder.LoadColumnList(); + } + } + } + } + + #endregion + + #region 数据库右键菜单事件处理 + + //查看数据库 + private void menuItemViewDB_Click(object sender, EventArgs e) + { + DbObjectViewer ov = new DbObjectViewer(); + ov.CurrentDatabase = tvDatabase.SelectedNode.Tag as SODatabase; + ov.Show(DockPanel); + } + + ////使用实体层模板批量生成代码 + //private void menuItemBatchBuildEnityCode_Click(object sender, EventArgs e) + //{ + // SODatabase db = tvDatabase.SelectedNode.Tag as SODatabase; + + // BatchBuildEntityCode dialog = new BatchBuildEntityCode(db); + // dialog.ShowDialog(); + //} + + ////使用数据层模板批量生成代码 + //private void menuItemBatchBuildDALCode_Click(object sender, EventArgs e) + //{ + // SODatabase db = tvDatabase.SelectedNode.Tag as SODatabase; + + // BatchBuildDALCode dialog = new BatchBuildDALCode(db); + // dialog.ShowDialog(); + //} + + //批量生成代码 + private void menuItemBatchBuildCode_Click(object sender, EventArgs e) + { + SODatabase db = tvDatabase.SelectedNode.Tag as SODatabase; + + BatchBuildCode dialog = new BatchBuildCode(db); + dialog.Show(this.DockPanel); + } + + ////使用自定义模板批量生成代码 + //private void menuItemBatchBuildCustomCode_Click(object sender, EventArgs e) + //{ + // SODatabase db = tvDatabase.SelectedNode.Tag as SODatabase; + + // BatchBuildCustomCode dialog = new BatchBuildCustomCode(db); + // dialog.ShowDialog(); + //} + + //新建查询 + private void menuItemNewQuery_Click(object sender, EventArgs e) + { + SODatabase db = tvDatabase.SelectedNode.Tag as SODatabase; + NewQuery(db, ""); + } + + private void NewQuery(SODatabase db, string sqlText) + { + QueryAnalyzer qa = new QueryAnalyzer(); + qa.CurrentDatabase = db; + base.MainForm.SetCurrentDB(db); + + int count = 1; + string fileName = string.Format("SqlQuery{0}.sql", count.ToString()); + while (base.MainForm.FindDockDocument(fileName) != null) + { + count++; + fileName = string.Format("SqlQuery{0}.sql", count.ToString()); + } + + qa.FileName = fileName; + qa.SqlText = sqlText; + qa.Show(DockPanel); + } + + //生成数据库文档 + private void menuItemBuildDBDoc_Click(object sender, EventArgs e) + { + DbDocBuilder builder = new DbDocBuilder(); + builder.CSName = cbConnectionStrings.SelectedItem.ToString(); + builder.CurrentDatabase = tvDatabase.SelectedNode.Tag as SODatabase; + builder.ShowDialog(); + } + + //刷新数据库 + private void menuItemRefreshDB_Click(object sender, EventArgs e) + { + TreeNode tn = tvDatabase.SelectedNode; + LoadDbSchema(tn); + } + + #endregion + + #region 表右键菜单事件处理 + + private void menuItemPreviewTableData_Click(object sender, EventArgs e) + { + TreeNode tn = tvDatabase.SelectedNode; + SOTable table = tn.Tag as SOTable; + List list = dbSchema.GetTableColumnList(table); + + StringBuilder sb = new StringBuilder(); + sb.AppendLine("SELECT TOP (1000) "); + for (int i = 0; i < list.Count; i++) + { + if (i != list.Count - 1) + sb.AppendLine(string.Format(" {0},", dbSchema.QuoteIdentifier(list[i].Name))); + else + sb.AppendLine(string.Format(" {0}", dbSchema.QuoteIdentifier(list[i].Name))); + } + sb.AppendLine("FROM "); + sb.AppendLine(string.Format(" {1}", sb.ToString().TrimEnd(','), table.FullName)); + + NewQuery(table.Database, sb.ToString()); + } + + //代码生成器 + private void menuItemBuildCodeForTable_Click(object sender, EventArgs e) + { + TreeNode tn = tvDatabase.SelectedNode; + SOTable table = tn.Tag as SOTable; + CodeBuilder builder = null; + + //保证代码生成器使用一个实例 + if (this.DockPanel.ActiveDocument != null && this.DockPanel.ActiveDocument is CodeBuilder) + { + builder = this.DockPanel.ActiveDocument as CodeBuilder; + builder.Table = table; + builder.ColumnList = dbSchema.GetTableColumnList(table); + builder.LoadColumnList(); + } + else + { + builder = new CodeBuilder(); + builder.Table = table; + builder.ColumnList = dbSchema.GetTableColumnList(table); + builder.LoadColumnList();//???:初始化列表CheckBox状态时,数据需要Load两次才能将CheckBox列全部初始化为选中状态 + builder.Show(this.DockPanel); + } + } + + //生成测试数据 + private void menuItemBuildTestDataForTable_Click(object sender, EventArgs e) + { + TreeNode tn = tvDatabase.SelectedNode; + SOTable table = tn.Tag as SOTable; + TestDataGenerator generator = null; + + //保证代码生成器使用一个实例 + if (this.DockPanel.ActiveDocument != null && this.DockPanel.ActiveDocument is TestDataGenerator) + { + generator = this.DockPanel.ActiveDocument as TestDataGenerator; + generator.Table = table; + generator.LoadColumnList(); + } + else + { + generator = new TestDataGenerator(); + generator.Table = table; + generator.LoadColumnList(); + generator.Show(this.DockPanel); + } + } + + //生成数据插入脚本 + private void menuItemBuildInsertSqlForTable_Click(object sender, EventArgs e) + { + TreeNode tn = tvDatabase.SelectedNode; + SOTable table = tn.Tag as SOTable; + List list = dbSchema.GetTableColumnList(table); + string cmdText = string.Format("select * from {0}", table.FullName); + DataTable dt = DbSchemaHelper.Instance.CurrentSchema.ExecuteQuery(table.Database, cmdText).Tables[0]; + + StringBuilder sbDocText = new StringBuilder(); + if (dt != null && dt.Rows.Count > 0) + { + foreach (DataRow dr in dt.Rows) + { + StringBuilder sb = new StringBuilder(); + sb.Append("INSERT INTO "); + sb.Append(table.FullName + " ("); + for (int i = 0; i < list.Count; i++) + { + SOColumn c = list[i]; + if (c.Identify) continue;//忽略标识列 + + if (i != list.Count - 1) + sb.Append(string.Format("{0},", dbSchema.QuoteIdentifier(c.Name))); + else + sb.Append(string.Format("{0}) VALUES (", dbSchema.QuoteIdentifier(c.Name))); + } + for (int i = 0; i < list.Count; i++) + { + SOColumn c = list[i]; + if (c.Identify) continue;//忽略标识列 + + string value = ""; + if (c.DataType == DbType.Boolean) + { + value = string.Format("'{0}'", Utils.DbBooleanValueToStirng(dr[c.Name])); + } + else if (c.DataType == DbType.Byte || c.DataType == DbType.Currency || c.DataType == DbType.Decimal || + c.DataType == DbType.Double || c.DataType == DbType.Int16 || c.DataType == DbType.Int32 || + c.DataType == DbType.Int64 || c.DataType == DbType.SByte || c.DataType == DbType.Single || + c.DataType == DbType.UInt16 || c.DataType == DbType.UInt32 || c.DataType == DbType.UInt64) + { + value = Utils.DbNumericValueToString(dr[c.Name]); + } + else + { + value = string.Format("'{0}'", Utils.DbStringValueToString(dr[c.Name])); + } + + if (i != list.Count - 1) + sb.Append(string.Format("{0},", value)); + else + sb.Append(string.Format("{0});", value)); + } + + sbDocText.AppendLine(sb.ToString()); + } + } + else + { + sbDocText.Append(string.Format("表“{0}”没有任何数据!", table.FullName)); + } + + base.MainForm.NewDockDocument(string.Format("{0}_InsertData", table.Name), CodeType.TSQL, sbDocText.ToString()); + } + + #endregion + + #region 视图右键菜单事件处理 + + //查看视图定义 + private void menuItemViewSql_Click(object sender, EventArgs e) + { + TreeNode tn = tvDatabase.SelectedNode; + SOView v = tn.Tag as SOView; + + base.MainForm.NewDockDocument(v.Name, CodeType.TSQL, v.SqlText); + } + + #endregion + + #region 存储过程右键菜单事件处理 + + //查看存储过程定义 + private void menuItemSpSql_Click(object sender, EventArgs e) + { + TreeNode tn = tvDatabase.SelectedNode; + SOCommand p = tn.Tag as SOCommand; + + base.MainForm.NewDockDocument(p.Name, CodeType.TSQL, p.SqlText); + } + + #endregion + + /// + /// 添加数据库连接 + /// + /// + /// + private void tsbAddDbConnect_Click(object sender, EventArgs e) + { + + } + + private void btnSetConnectString_Click(object sender, EventArgs e) + { + var dbSettingForm = new DatabaseSettingForm(); + if(dbSettingForm.ShowDialog() == DialogResult.Yes) + { + RefreshDatabase(); + } + } + + private void RefreshDatabase() + { + cbConnectionStrings.Items.Clear(); + tvDatabase.Nodes.Clear(); + + foreach (ConnectionStringSettings css in ConfigurationManager.ConnectionStrings) + { + cbConnectionStrings.Items.Add(css.Name); + } + } + } +} diff --git a/src/Kalman.Studio/ExplorerForm/DatabaseExplorer.resx b/src/Kalman.Studio/ExplorerForm/DatabaseExplorer.resx new file mode 100644 index 0000000..4297a84 --- /dev/null +++ b/src/Kalman.Studio/ExplorerForm/DatabaseExplorer.resx @@ -0,0 +1,397 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 127, 17 + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w + LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 + ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAACI + MQAAAk1TRnQBSQFMAgEBCwEAAWwBAAFsAQABEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA + AwABMAMAAQEBAAEgBgABMGIAAxAB/wMQAf88AAG3AaIBkwH/AYABWQFFAf8BgAFZAUUB/wGAAVkBRQH/ + AYABWQFFAf8BgAFZAUUB/wGAAVkBRQH/AYABWQFFAf8BgQFaAUYB/wGBAVoBRgH/mAABGQEmASkB/wEf + ATUBOgH/OAABtwGiAZMC/wH6AfgB/wHpAeEB3QH/AekB3QHYAf8B6QHZAdEB/wHpAdUBywH/AekB0QHF + Af8B6QHOAb8B/wHpAckBuQH/AYEBWgFGAf9MAAHeAYEBRgH/AcIBbQE7Af8BnwFdATQB/wQAAd4BgQFG + Af8BwgFtATsB/wGfAV0BNAH/BAAB3gGBAUYB/wHCAW0BOwH/AZ8BXQE0Af8gAAMQAf8BOQKBAf8BHwE1 + AToB/ywAAS4BiAFKAf8EAAG3AaIBkwL/AfsB+QL/AfoB+AH/AYUCgQH/AYUCgQH/AYUCgQH/AYUCgQL/ + AfcB9AH/AekBxgG1Af8BgQFaAUYB/0wAAf8BlwFyAf8B+AHiAdQB/wHCAW0BOgH/BAAB/wGXAXIB/wH4 + AeIB1AH/AcIBbQE6Af8EAAH/AZcBcgH/AfgB4gHUAf8BwgFtAToB/yQAASYBSAFQAf8BUgGnAb8B/wEf + ATUBOgH/HAAB1AHoAdkB/wEuAYgBSgH/AS4BiAFKAf8BLgGIAUoB/wEuAYgBSgH/AdABwwG5Av8B/AH6 + Av8B+wH5Av8B+wH4Av8B+gH3Av8B+QH2Av8B+QH2Av8B+AH1Af8B6QHLAbwB/wGBAVoBRgH/TAAB/wGw + AYUC/wGgAYEB/wHeAYEBRgH/BAAB/wGwAYUC/wGgAYEB/wHeAYEBRgH/BAAB/wGwAYUC/wGgAYEB/wHe + AYEBRgH/KAABQgGBAZEB/wFYAbQBzgH/AR8BNQE6Af8YAAEuAYgBSgH/AegB8wHrAf8EAAEuAYgBSgH/ + BAABtwGiAZMC/wH9AfwC/wH8AfsB/wGFAoEB/wGFAoEB/wGFAoEB/wGFAoEC/wH5AfYB/wHpAc8BwwH/ + AYEBWgFGAf9QAAGXAoEB/wwAAYEBcQFfAf8MAAGBAVsBRwH/LAABIgE8AUMB/wFdAcIB3gH/AVcBtAHO + Af8BHgE1AToB/xQAAS4BiAFKAf8QAAG3AaIBkwL/Af4B/QL/Af0B/AL/AfwB+wL/AfwB+gL/AfsB+QL/ + AfoB+AL/AfoB9wH/AekB1AHKAf8BgQFaAUYB/1AAAZ0BhwGBAf8MAAKBAWYB/wwAAYEBXwFLAf8UAAMQ + Af8DEAH/AxAB/wMQAf8DEAH/AxAB/wMQAf8BMwFtAYEB/wFeAdYB/gH/AU0BrAHOAf8BGwEzAToB/xAA + AS4BiAFKAf8QAAG3AaIBkwL/AfcB9AL/AfcB9AH/AYUCgQH/AYUCgQH/AYUCgQH/AYUCgQL/AfsB+QH/ + AekB2QHSAf8BgQFaAUYB/1AAAaQBjQGBAf8MAAGHAYEBbAH/DAABgQFkAVEB/xQAAxAB/wFHAZEBqQH/ + AV8B1wH+Af8BXAHVAf4B/wFaAdMB/gH/AVcB0QH+Af8BVQHPAf4B/wFSAc0B/gH/AVABywH+Af8BTQHJ + Af4B/wE/AaEBzgH/ARkBMAE6Af8MAAGAAVkBRQH/AYABWQFFAf8BgAFZAUUB/wGAAVkBRQH/AYABWQFF + Af8BgAFZAUUB/wGAAVkBRQL/AfcB9AL/Av4C/wH+Af0C/wH9AfwC/wH8AfsC/wH8AfoB/wHpAd8B2QH/ + AYEBWgFGAf9QAAGqAZQBhQH/AaMBjAGBAf8BnAGFAYEB/wGVAoEB/wGNAoEB/wGGAYEBbAH/AoEBZAH/ + AYEBcAFdAf8BgQFqAVYB/xgAAxAB/wE8AYkBqQH/AU4BygH+Af8BTAHIAf4B/wFJAcYB/gH/AUcBxAH+ + Af8BRAHCAf4B/wFCAcAB/gH/AT8BvgH+Af8BPQG8Av8BMgGXAc8B/wEWAS4BOwH/CAAB8wHYAcsB/wHD + AbgBsgH/AVoBVQFSAf8BtQGoAaEB/wH2AeIB2AH/AYEBcgFuAf8BgAFZAUUC/wH3AfQB/wGFAoEB/wGF + AoEB/wGFAoEB/wGFAoEC/wH9AfsB/wHpAeMB3wH/AYEBWgFGAf9gAAGUAoEB/ywAAxAB/wExAYEBqQH/ + AT4BvQH+Af8BOwG7Av8BOQG5Av8BNgG3Av8BNAG1Av8BMQGzAv8BLwGxAv8BLAGvAv8BJAGMAc8B/wET + ASwBOwH/BAAB8wHYAcsB/wFaAVYBVAH/AfgB6AHhAf8BWgFVAVIB/wH3AeMB2gH/A4EB/wGAAVkBRQL/ + AfcB9Ar/Av4C/wH+Af0C/wL9Av8B/QH8Af8BgAFZAUUB/2AAAZoBgwGBAf8wAAMQAf8BJgGBAaoB/wEt + AbAC/wEeAW0BiAH/AxAB/wMQAf8DEAH/AxAB/wMQAf8DEAH/AxAB/wQAAfMB2AHLAf8BuwGyAa8B/wFc + AVgBVQH/AaoBnwGaAf8B9wHlAdwB/wG3AasBpQH/AYABWQFFAf8B5gGhAYEB/wHjAZoBgQH/AeEBkwGB + Af8B3QGMAYAB/wHaAYMBaQH/AdcBgQFfAf8B0wGBAVUB/wHPAYEBRgH/XAAB3gGBAUYB/wHCAW0BOwH/ + AZ8BXQE0Af8wAAMQAf8BGwGBAaoB/wEdAaMC/wESATgBUAH/HAAB8wHYAcsB/wG7AbIBrgH/AfkB7AHm + Af8BwwG3AbEB/wFaAVUBUgH/AbUBpwGhAf8BgAFZAUUB/wH9Ab4BnAH/AfwBuAGTAf8B+gGvAYkB/wH4 + AacBgQH/AfYBoAGBAf8B9AGaAYEB/wHzAZUBgQH/Ac4BgQFGAf9cAAH/AZcBcgH/AfgB4gHUAf8BwgFt + AToB/zQAAxAB/wERAYEBqgH/ARABgQG7Af8DEAH/GAAB8wHYAcsB/wGCAoEB/wH6Ae0B6AH/AVoBVgFU + Af8B+AHpAeEB/wFaAVQBUgH/AYABWQFFAf8B5gGgAYEB/wHjAZoBgQH/AeABkwGBAf8B3QGMAYAB/wHa + AYQBaQH/AdcBgQFfAf8B1AGBAVUB/wHPAYEBRwH/XAAB/wGwAYUC/wGgAYEB/wHeAYEBRgH/OAADEAH/ + ARABgQGqAf8BEAFNAYEB/xgAAfMB2AHLAf8DgQH/AfoB8AHqAf8BtgGtAagB/wFaAVYBVAH/AaoBnwGa + Af8BgAFZAUUB/8QAAxAB/wEQAVcBgQH/AxAB/xQAAfMB2AHLAf8B8wHYAcsB/wHzAdgBywH/AfMB2AHL + Af8B8wHYAcsB/wHzAdgBywH/AfMB2AHLAf/IAAMQAf8BEAEeAScB//8AMQABUwGBAY4B/wFTAYEBggH/ + XAABgQFeAUoB/wGBAV4BSgH/AYEBXgFKAf8BgQFeAUoB/wGBAV4BSgH/AYEBXgFKAf8BgQFeAUoB/wGB + AV4BSgH/AYEBXgFKAf8BgQFeAUoB/wGBAV4BSgH/FAABtwGiAZMB/wGAAVkBRQH/AYABWQFFAf8BgAFZ + AUUB/wGAAVkBRQH/AYABWQFFAf8BgAFZAUUB/wGAAVkBRQH/AYABWQFFAf8BgAFZAUUB/wGAAVkBRQH/ + AYABWQFFAf8BgAFZAUUB/wGAAVkBRQH/AYABWQFFAf8BgAFZAUUB/xgAAUcBhgGsAf8BOgGfAc8B/wFE + AYEBjwH/IAABtwGiAZMB/wGAAVkBRQH/AYABWQFFAf8BgAFZAUUB/wGAAVkBRQH/AYABWQFFAf8BgAFZ + AUUB/wGAAVkBRQH/AYABWQFFAf8BgAFZAUUB/wGAAVkBRQH/AYABWQFFAf8MAAGBAV4BSgH/JAABgQFe + AUoB/xQAAbcBogGTAf8B/gH9AfwB/wH4AekB4QH/AfgB5gHfAf8B9wHlAdwB/wH2AeIB2QH/AfYB4QHW + Af8B9QHfAdQB/wH0AdwB0AH/AfQB2wHOAf8B9AHYAcsB/wHzAdcByQH/AfIB1QHGAf8B8gHSAcMB/wHx + AdEBwQH/AYABWQFFAf8YAAFTAYYBpwH/AVMBsQHpAf8BEAGWAdkB/wFeAYEBhgH/HAABtwGiAZMC/wH6 + AfcB/wHpAeEB3QH/AekB3QHYAf8B6QHZAdEB/wHpAdUBywH/AekB0QHFAf8B6QHOAb8B/wHpAckBuQH/ + AekBxgG0Af8B6QHEAbAB/wGAAVkBRQH/DAABgQFeAUoB/wQAAYEBXgFKAf8B3wHYAdMB/wHFAbkBsAH/ + AbIBogGWAf8BxQG5AbAB/wHTAcsBxAH/AYEBXgFKAf8BxQG5AbAB/wGBAV4BSgH/AaEBkgGGAf8BoQGS + AYYB/wGhAZIBhgH/AaEBkgGGAf8BoQGSAYYB/wG3AaIBkwf/Af4B/wHvAYcBZAH/AeIBgQFdAf8B/QH5 + AfgB/wHGAYEBUAH/AbkBgQFKAf8BrgFsAUcB/wGmAWgBQwH/AaYBaAFDAf8BpgFoAUMB/wH4AecB4AH/ + AfcB5gHcAf8B8gHTAcUB/wGAAVkBRQH/GAABVwGIAaoB/wFUAbEB6QH/AV4BgQGGAf8BNwGBAaQB/xwA + AbcBogGTAv8C/QH/AbYBqAGgAf8BtgGoAaAB/wG2AagBoAH/AbYBqAGgAf8BtgGoAaAB/wG2AagBoAH/ + AbYBqAGgAv8B3gHNAf8B6QHGAbUB/wGAAVkBRQH/DAABgQFeAUoB/wQAAeQB1wHOAf8BgQFeAUoB/wH9 + AfoB+AH/Af0B9wH0Af8B/AH0Ae8B/wGBAV4BSgH/AfsB7gHmAf8B+gHrAeIB/wGBAV4BSgH/AekB1gHK + Af8B6QHWAcoB/wHpAdYBygH/AeIB0gHIAf8BoQGSAYYB/wG3AaIBkw3/Af4C/QH/Af4B+wH6Af8B/QH6 + AfcB/wH9AfcB9QH/Af0B9QHxAf8B+wHzAe8B/wH7AfAB6wH/AfkB7QHnAf8B+QHqAeQB/wH4AegB4QH/ + AfMB1wHJAf8BgAFZAUUB/xgAAVkBjAGtAf8BVAGxAekB/wEQAYMBtwH/AVoBgQGOAf8cAAG3AaIBkwb/ + Af4B/QL/AfsB+QL/AfgB9AL/AfQB7wL/AfAB6AL/AesB4QL/AecB2wL/AeIB1AH/AekBywG8Af8BgAFZ + AUUB/wwAAYEBXgFKAf8EAAHkAdcBzgX/AesB3gHWAf8B6QHbAdMB/wHmAdgBzwP/Af4B/wHgAdEBxwH/ + Ad0BzQHDAf8BgQFeAUoB/wH6AeYB2gH/AcQBsgGnAf8BwgGwAaQB/wHiAdIByAH/AaEBkgGGAf8BugGl + AZYK/wGcAYEC/wGVAXAB/wH4AY4BaQH/Af4B/AH7Af8B4AGBAVsB/wHRAYEBVQH/AfwB9QHyAf8B/AHy + Ae4B/wH7AfAB6wH/AfoB7QHoAf8B+QHrAeQB/wH0AdoBzQH/AYABWQFFAf8YAAFdAY8BsQH/AVQBsgHp + Af8BEAGcAd8B/wFUAYEBiwH/HAABtwGiAZMF/wG2AagBoAH/AbYBqAGgAf8BtgGoAaAB/wG2AagBoAH/ + AbYBqAGgAf8BtgGoAaAB/wG2AagBoAH/AbYBqAGgAf8B6QHPAcMB/wGAAVkBRQH/DAABgQFeAUoB/wQA + AeQB1wHOF/8B/gP/AfoB/wGBAV4BSgH/AfoB6QHfAf8B+gHmAdoB/wH6AeQB1wH/AeIB0gHIAf8BoQGS + AYYB/wG+AakBmhb/Af4B/QH/Af4C+wH/Af4B+gH4Af8B/QH4AfYB/wH8AfUB8gH/AfwB8wHvAf8B+wHw + AewB/wH5Ae4B6AH/AfUB3QHSAf8BgAFZAUUB/xgAAV8BkwG0Af8BVAGyAeoB/wFPAW8BgQH/IAABugGl + AZYO/wL+Av8B/QH6Av8B+QH2Av8B9QHwAv8B8QHqAv8B7QHkAf8B6QHUAcoB/wGAAVkBRQH/DAABgQFe + AUoB/wQAAeQB1wHOBf8B7AHgAdcB/wHqAd0B1QH/AegB2gHRBf8B4gHTAcoB/wHfAc8BxQH/AYEBXgFK + Af8B+wHtAeQB/wHFAbQBqQH/AcQBsQGmAf8B4gHSAcgB/wGhAZIBhgH/AcMBrgGeCv8BsQGHAv8BqgGB + Av8BowGBBf8B/gGUAW8B/wH+AfwB+wH/Af4B+gH4Af8B/QH4AfYB/wH8AfUB8gH/AfwB8wHvAf8B+gHw + AewB/wH2AeEB1gH/AYABWQFFAf8QAAFfAaYBywH/AWMBngHBAf8BYwGXAbcB/wFUAbMB7AH/AU8BbwGB + Af8BRwGCAaYB/wE6AYIBrAH/GAABvgGpAZoF/wGFAoEB/wGFAoEB/wGFAoEB/wGFAoEB/wGFAoEB/wGF + AoEB/wGFAoEC/wHyAewB/wHpAdkB0gH/AYABWQFFAf8MAAGBAV4BSgH/BAAB5gHZAdAB/wGBAV4BSg3/ + AYEBXgFKCf8BgQFeAUoB/wH8AfEB6QH/AfsB7QHkAf8B+gHpAd8B/wHjAdUBzQH/AaEBkgGGAf8ByAGy + AaMe/wL+Av8B/AH7Af8B/QH6AfgB/wH9AfkB9gH/Af0B9gHzAf8B/AHzAe8B/wH3AeQB2wH/AYABWQFF + Af8MAAFwAa8B0QH/AYEBpgHCAf8BZQGiAcQB/wGBAdQB+wH/ARIBqAHpAf8BEAGUAc8B/wFPAW8BgQH/ + AUsBgQGdAf8BOQGBAakB/xQAAcMBrgGeGv8C/QL/AfoB+AL/AfcB8wH/AekB3wHZAf8BgAFZAUUB/wwA + AYEBXgFKAf8EAAGBAV4BSgX/Ae0B4QHZAf8B6wHfAdcB/wHoAdwB1AX/AYEBXgFKAf8B4AHRAcgB/wGB + AV4BSgH/Af0B9AHuAf8BxwG2AawB/wHEAbMBqAH/AeMB2gHTAf8BoQGSAYYB/wG+AakBmgr/AcEBoAL/ + AbwBmQL/AbcBkA3/Av4B/QH/Af4C/AH/Af4B+gH5Af8B/QH4AfYB/wH8AfYB8wH/AfgB5wHfAf8BgAFZ + AUUB/wwAAYEBsAHMAf8BcAGtAc4B/wGBAdcC/wEeAa8B7AH/ATcBtQHrAf8BEAGkAeYB/wEQAZQBzwH/ + AU8BbwGBAf8BRAGBAaEB/xQAAcgBsgGjBf8BtgGoAaAB/wG2AagBoAH/AbYBqAGgAf8BtgGoAaAB/wG2 + AagBoAH/AbYBqAGgAf8BtgGoAaAB/wG2AagBoAH/AekB4wHfAf8BgAFZAUUB/wwAAYEBXgFKAf8EAAHr + Ad8B1R3/AYEBXgFKAf8B/QH3AfQB/wH9AfQB7gH/AfwB8QHpAf8B4wHaAdMB/wGhAZIBhgH/AcMBrgGe + Jf8D/gH/Af4B/QH7Af8B/gH7AfkB/wH9AfkB9gH/AfkB6gHkAf8BgAFZAUUB/wwAAYUBrwHFAf8BvwHs + Af0B/wFKAcQB+QH/ATcBtQHrAf8BSgHEAfkB/wFKAcQB+QH/AREBpwHnAf8BEAGTAc0B/wFnAYEBiAH/ + FAABzAG2Aaci/wL+Av8B+wH6Af8BgAFZAUUB/wwAAYEBXgFKAf8BgQFeAUoB/wGBAV4BSgH/AYEBXgFK + Af8BgQFeAUoB/wGBAV4BSgH/AYEBXgFKAf8BgQFeAUoB/wGBAV4BSgH/AYEBXgFKAf8BgQFeAUoB/wH+ + AfoB+AH/AcgBuAGuAf8BxQG1AaoB/wHjAdoB0wH/AaEBkgGGAf8ByAGyAaMq/wL+Af8B/gH9AfwB/wH+ + AfsB+QH/Af0B+QH3Af8BgAFZAUUB/wwAAZUBrAG+Af8BwQHuAv8BgQHXAv8BNQGkAdcB/wGBAZYBrQH/ + AUoBxAH5Af8BEQGnAecB/wEQAZMBzQH/AWcBgQGIAf8UAAHqAaoBiwH/AeoBqgGLAf8B6AGmAYYB/wHm + AaEBgQH/AeMBmgGBAf8B4QGTAYEB/wHdAYwBgAH/AdoBgwFpAf8B1wGBAV8B/wHTAYEBVQH/AdEBgQFN + Af8BzwGBAUYB/xQAAeAB0wHKAf8D/gH/A/4B/wP+Af8D/gH/A/4B/wP+Af8D/gH/A/4B/wH+Af0B+wH/ + Af4B+gH4Af8B/QH3AfQB/wH9AfQB7gH/AaEBkgGGAf8B6gGqAYsB/wHqAaoBiwH/AeoBqgGLAf8B6gGq + AYsB/wHpAaUBhAH/AekBnwGBAf8B5wGXAYEB/wHmAY4BcgH/AeUBhgFmAf8B4wGBAVoB/wHjAYEBUAH/ + AeIBgQFJAf8B4gGBAUkB/wHiAYEBSQH/AeIBgQFJAf8ByAFyAT8B/wwAAY0BswHHAf8B0gH3Av8BgQHX + Af4B/wFGAYEBhgH/AYEBoQG8Af8BgQGfAbQB/wEdAaYB5AH/ARABlQHQAf8BWwGBAZsB/xQAAeoBqgGL + Av8BwgGiAv8BwgGiAf8B/QG+AZwB/wH8AbgBkwH/AfoBrwGJAf8B+AGnAYEB/wH2AaABgQH/AfQBmgGB + Af8B8wGVAYEB/wHzAZUBgQH/Ac4BgQFGAf8UAAHyAcwBuQH/AfIBzAG5Af8B8gHMAbkB/wHyAckBtQH/ + AfIBxQGvAf8B8QHBAagB/wHwAbsBoQH/Ae8BtgGaAf8B7gGxAZIB/wHuAa0BjAH/Ae4BqgGIAf8B7gGq + AYgB/wHuAaoBiAH/Ad4BoQGCAf8B6gGqAYsC/wHCAaIC/wHCAaIB/wH+AcABnwH/Af0BvQGaAf8B/AG5 + AZYB/wH7AbUBkAH/AfoBsAGLAf8B+QGrAYQB/wH4AacBgQH/AfYBogGBAf8B9QGdAYEB/wH1AZkBgQH/ + AfMBlQGBAf8B8wGVAYEB/wHNAYEBQQH/DAABiQG7AdAB/wHSAfcC/wGiAeMB/gH/ATUBpAHXAf8BRgGB + AYYB/wEoAa4B5wH/ATQBpAHXAf8BTAGTAboB/wFPAYoBrQH/FAAB6gGqAYsB/wHqAaoBiwH/AegBpgGG + Af8B5gGgAYEB/wHjAZoBgQH/AeABkwGBAf8B3QGMAYAB/wHaAYQBaQH/AdcBgQFfAf8B1AGBAVUB/wHQ + AYEBTQH/Ac8BgQFHAf8UAAHyAcwBuQL/AdoBxwH/Af4B2QHFAf8B/gHXAcIB/wH9AdUBwAH/Af0B0wG8 + Af8B/AHQAbkB/wH7Ac0BtQH/AfsBygGxAf8B+gHHAa0B/wH5AcQBqgH/AfkBwgGmAf8B+AG/AaMB/wHh + AaMBgwH/AeoBqgGLAf8B6gGqAYsB/wHqAaoBiwH/AeoBqgGLAf8B6gGqAYsB/wHqAaYBhgH/AekBoQGB + Af8B6AGbAYEB/wHnAZQBgQH/AeYBjgFyAf8B5QGHAWgB/wHkAYEBXgH/AeQBgQFWAf8B4wGBAU4B/wHj + AYEBTgH/AeIBgQFJAf8MAAGMAcQB1wH/AYsBuAHMAf8B0gH3Av8B0gH3Av8BogHkAv8BVAG3AfAB/wFb + AZ0BwAH/AWABkgGwAf8BRwGSAbsB/1gAAfIBzAG5Af8B8gHMAbkB/wHyAcwBuQH/AfIBzAG5Af8B8gHK + AbYB/wHyAccBsgH/AfEBwwGtAf8B8QG/AacB/wHwAbsBoQH/Ae8BtwGbAf8B7wGzAZUB/wHvAbABkAH/ + Ae4BrQGLAf8B7gGqAYgB/1AAAYoBxAHXAf8BhwG7AdAB/wGJAbABxAH/AYwBpgG4Af8BgQGeAbUB/wFp + AZ4BvgH/AVQBnQHDAf+EAAEWAYEBngH/+AABFgGBAZ4B/wE1Ab0B7wH/ARQBagGBAf/oAAGYAT8BlQH/ + BAABHAGqAeEB/wGLAeMB9QH/AWQB0AHzAf8BNAG9Ae8B/wEUAWoBgQH/EAADHgErA1QBrgNkAewBZAGD + AZYB/wFRAYEBjQH/ATsBgQGMAf8DXQHwA1YBswMlATcQAAGBAYQBjwH/AoEBhQH/AXACgQH/AWEBbQGB + Af8BUgFcAWQB/wFBAUoBUQH/ATMBOgFAAf8BJgEsATEB/wEeASMBKAH/AR4BIwEoAf8BHgEjASgB/wEe + ASMBKAH/AR4BIwEoAf8BHgEjASgB/wEeASMBKAH/CAABtwGiAZMB/wGAAVkBRQH/AYABWQFFAf8BgAFZ + AUUB/wGAAVkBRQH/AYABWQFFAf8BgAFZAUUB/wGAAVkBRQH/AYABWQFFAf8BgAFZAUUB/wGAAVkBRQH/ + AYABWQFFAf8BgAFZAUUB/wGAAVkBRQH/IAABngE8AZsB/wHeAUYB1wH/AZgBPwGVAf8EAAEcAaoB4QH/ + AYsB4wH1Af8BZAHQAfIB/wE0AbwB7wH/ARQBagGBAf8MAANeAdABWAGwAdEB/wGEAdUB6AH/AaEB6wH2 + Af8BgQHkAv8BKwG+AfMB/wEKAZ8B3gH/ARsBiwG+Af8BWwJeAdkQAAGBAYcBkgH/AaIB3wHwAf8BgQHN + AeoB/wFZAbgB4gH/AUcBrgHbAf8BPQGpAdkB/wE2AaEB0gH/ATEBmAHHAf8BMAGOAbwB/wEuAYMBrgH/ + ASkBgQGrAf8BJQGBAakB/wErAYEBnwH/AS8BgQGWAf8BJgEsATEB/wgAAbcBogGTAf8B2QHLAcIB/wHO + Ab0BsQH/AcsBuQGtAf8ByAG1AakB/wHFAbIBpQH/AcIBrgGhAf8BvwGsAZ4B/wG9AagBmgH/AbsBpgGX + Af8BuQGkAZUB/wG3AaIBkwH/AbcBogGTAf8BgAFZAUUB/wgAAVMBgQGTAf8BRQFtAYMB/wFbAagBxgH/ + AZEB0wHgAf8BggHdAfEB/wG0AUgBsAH/AecBgQHoAf8B5AFgAeEB/wHeAUYB1wH/AYcBOQGEAf8EAAEc + AaoB4QH/AYsB4wH1Af8BHwGYAcgB/xAAAVoBjwGqAf8BVAHXAv8BkAHqAfoB/wGhAesB9gH/AYEB2QH0 + Af8BKwG8AfIB/wEIAacB6AH/AQoBnAHaAf8BMQFqAYQB/xAAAYEBigGVAf8BqgHoAfYB/wGVAeUB/AH/ + AYQB3wH7Af8BgQHWAfoB/wGBAdAB9wH/AW0BxgH0Af8BYAG+AfAB/wFRAbQB7AH/AUUBqgHoAf8BOwGk + AeYB/wEwAZoB3wH/ASYBkAHXAf8BKwGBAZ8B/wEwATcBPQH/CAABtwGiAZMB/wP+Af8D/gH/Af0B+wH6 + Af8BywG5Aa0B/wH8AfIB7QH/AfsB7QHkAf8B+gHnAdwB/wG/AasBnQH/AfcB2wHKAf8B9gHVAcAB/wH1 + Ac8BtwH/AbcBogGTAf8BgAFZAUUB/wgAAVoBhQGgAf8BLwG5Ae4B/wFuAdMB8QH/AaYB7gH3Af8B4QFd + AdwB/wHpAbIB8AH/AecBmAHsAf8B5wGBAegB/wGeATwBmwH/BAABmQE7AQgB/wQAARwBqgHhAf8UAAFb + AZEBrgH/AVMB0gH6Af8BjQHkAfYB/wGhAesB9gH/AYEB1wHzAf8BKwG5Ae8B/wEIAacB6AH/AQoBnAHa + Af8BMwFsAYYB/xAAAYEBjgGYAf8BsAHqAfYB/wGfAekB+wH/AZIB5AH8Af8BgQHdAfsB/wGBAdYB+gH/ + AYEBzgH3Af8BbQHGAfQB/wFdAbwB8AH/AVEBtAHsAf8BRQGqAegB/wE6AaMB5gH/AS0BlgHcAf8BJQGB + AakB/wE9AUQBSwH/CAABtwGiAZMB/wP+Af8D/gH/A/4B/wHOAbwBsAH/Af0B9wHzAf8B/AHyAewB/wH7 + Ae0B5QH/AcIBrgGhAf8B+QHhAdMB/wH3AdsBygH/AfUB1QHAAf8BuQGkAZUB/wGAAVkBRQH/CAABVwGC + AZ0B/wEvAbkB7gH/AW0B0wHyAf8BpgHuAfcB/wGEAeAB9AH/AeIBZQHeAf8B6QGxAfAB/wHBAUcBvAH/ + AQoBlwHWAf8BtQFrAT0B/wHpAagBYQH/AZkBOwEIAf8YAAFeAZUBsAH/AVUB0gH6Af8BjQHkAfQB/wGh + AesB9gH/AYEB1wHyAf8BKwG5Ae4B/wEIAacB6AH/AQoBnAHaAf8BNgFvAYgB/xAAAYEBkQGcAf8BtgHt + AfgB/wGqAewB+wH/AZsB6AH7Af8BjwHjAfwB/wGBAd0B+wH/AYEB1QH5Af8BgQHOAfcB/wFrAcUB9AH/ + AV0BvAHwAf8BTQGyAewB/wFCAakB6AH/ATQBngHiAf8BIAGCAbQB/wFLAVMBWwH/CAABtwGiAZMB/wHg + AdMBygH/AdcBxgG8Af8B1AHDAbgB/wHRAcABtQH/Ac4BvQGxAf8BywG5AawB/wHIAbYBqQH/AcUBsgGl + Af8BwgGvAaEB/wG/AawBnQH/Ab0BqQGaAf8BugGmAZcB/wGAAVkBRQH/CAABXAGIAaMB/wEwAbkB7gH/ + AW0B0wHyAf8BpgHuAfcB/wGEAeAB9AH/AS0BuQHtAf8B4gFlAd4B/wELAaAB3wH/AdgBmwFjAv8BzQGZ + Af8B9gG+AYEB/wHoAakBYQH/AZkBOwEIAf8UAAFgAZkBtQH/AVYB0QH7Af8BjgHkAfUB/wGhAesB9gH/ + AYEB1wHyAf8BKwG5Ae4B/wEIAacB6AH/AQoBnAHaAf8BNwFyAYoB/xAAAYMBlQGfAf8BvgHwAfkB/wGr + AfAB9wH/AaUB7AH7Af8BmAHnAfsB/wGJAeEB/AH/AYEB3QH7Af8BgQHVAfkB/wGBAc0B9wH/AWgBxAHz + Af8BWwG7AfAB/wFNAbIB7AH/ATwBpAHjAf8BHAGKAb8B/wFZAWMBbAH/CAABugGlAZYB/wP+Af8D/gH/ + A/4B/wHVAcQBuQH/A/4B/wH9AfsB+gH/AfwB9wH0Af8ByAG2AakB/wH7Ae4B5AH/AfoB5wHcAf8B+QHi + AdMB/wG9AagBmgH/AYABWQFFAf8IAAFhAY8BqQH/ATABugHtAf8BbgHTAfEB/wGmAe4B9wH/AYQB4AH0 + Af8BLQG5Ae0B/wEJAacB6AH/AQsBoAHfAf8BCgGXAdYB/wHYAZsBYwL/Ac0BmQH/AfYBvgGBAf8B6AGo + AWEB/wGZATsBCAH/EAABYwGbAbcB/wFWAdAB+QH/AY0B4wH1Af8BoQHrAfYB/wGBAdkB8gH/ASsBuQHu + Af8BCAGnAegB/wEKAZwB2gH/ATkBgQGNAf8QAAGGAZkBowH/Ab4B8AH5Af8BtgHtAfgB/wGwAe4B+gH/ + AaQB6wH6Af8BlQHmAfsB/wGJAeEB/AH/AYEB3AH8Af8BgQHVAfkB/wGBAc0B9wH/AWgBxAHzAf8BWQG5 + Ae8B/wFFAakB5wH/ARwBjwHHAf8BZwGAAYEB/wgAAb4BqQGaAf8D/gH/A/4B/wP+Af8B1wHHAbsB/wP+ + Af8D/gH/Af0B+wH6Af8BywG5AawB/wH7AfMB7QH/AfoB7QHlAf8B+gHnAdwB/wG/AasBnQH/AYABWQFF + Af8IAAFmAZYBrgH/ATABuQHtAf8BbQHTAfIB/wGmAe4B9wH/AYQB4AH0Af8BLQG5Ae0B/wEJAacB6AH/ + AQsBoAHfAf8BCgGXAdYB/wQAAdgBmwFjAv8BzQGZAf8B2AGbAWMB/xQAAWUBngG6Af8BVAHQAfkB/wGN + AeMB9AH/AaEB6wH2Af8BgQHXAfIB/wEmAbcB7gH/AQgBpwHoAf8BCgGcAdoB/wE7AYEBjwH/EAABiQGc + AaYB/wG+AfAB+QH/AbYB7QH4Af8BtgHtAfgB/wGrAfAB9wH/AaIB7AH6Af8BlQHmAfsB/wGJAeEB/AH/ + AYEB3AH8Af8BgQHTAfoB/wGAAcwB9wH/AWUBwwHzAf8BWQG5Ae8B/wEpAZkBzwH/AYACgQH/CAABwwGu + AZ4B/wHkAdgB0AH/Ad0BzgHFAf8B3AHMAcEB/wHZAckBvwH/AdcBxwG8Af8B1AHEAbgB/wHRAcABtAH/ + Ac4BvQGxAf8BywG5AawB/wHIAbUBqQH/AcUBsgGlAf8BwgGuAaAB/wGAAVkBRQH/CAABbAGbAbQB/wEw + AbkB7gH/AW0B0wHxAf8BpgHuAfcB/wGFAeAB9AH/AS0BuQHtAf8BCQGmAecB/wELAaAB3wH/AQoBlwHW + Af8IAAHYAZsBYwH/GAABZgGiAbwB/wFOAc4B9wH/AYsB4wH0Af8BoQHrAfYB/wGBAdYB8gH/ASYBtwHu + Af8BCAGnAegB/wEKAZwB2gH/ATgBgQGSAf8QAAGLAaABqAH/Ab4B8AH5Af8BvgHwAfkB/wG+AfAB+QH/ + Ab4B8AH5Af8BtAHyAfgB/wGqAewB+wH/AaAB6QH7Af8BlQHlAfwB/wGKAd8B/AH/AYEB2AH7Af8BgQHS + AfgB/wGBAcoB9AH/AW0BwAHxAf8BgAKBAf8IAAHIAbIBowH/A/4B/wP+Af8D/gH/AdsBzAHBAf8D/gH/ + A/4B/wP+Af8B0QHAAbQB/wH9AfsB+QH/Af0B9wH0Af8B/AHzAe0B/wHFAbIBpQH/AYABWQFFAf8IAAFw + AaEBuQH/AS8BuQHuAf8BbgHTAfEB/wGmAe4B9wH/AYQB4AH0Af8BLQG4Ae0B/wEJAacB5wH/AQsBoAHf + Af8BCgGYAdYB/yQAAXIBqQHAAf8BXQHUAfoB/wGcAewB+gH/AasB7wH6Af8BpgHtAfgB/wGUAecB+AH/ + AYEB2QH2Af8BQwG9AekB/wFKAYEBlwH/EAABjQGhAaoB/wGNAaEBqgH/AY0BoQGqAf8BjQGhAaoB/wGN + AaEBqgH/AYsBnwGoAf8BiQGcAaYB/wGJAZsBpgH/AYcBmgGkAf8BhgGZAaMB/wGEAZYBoAH/AYQBlgGg + Af8BgwGVAaAB/wGDAZUBoAH/AYEBhAGPAf8IAAHMAbYBpwH/A/4B/wP+Af8D/gH/Ad0BzgHFAf8D/gH/ + A/4B/wP+Af8B1AHEAbgB/wP+Af8B/QH7AfoB/wH9AfcB8wH/AcgBtQGoAf8BgQFaAUYB/wgAAYEBpwG9 + Af8BLwG5Ae0B/wFtAdIB8QH/AaYB7gH3Af8BhQHgAfQB/wEsAbgB7QH/AQkBpwHnAf8BCwGgAd8B/wEK + AZgB1gH/JAABgQGzAcUB/wGbAd4B6wH/AcUB+QH9Af8BxQH5Af0B/wHFAfkB/QH/AcUB+QH9Af8BxQH5 + Af0B/wGgAd8B6gH/AW0BkQGiAf8QAAGPAaQBrAH/AbIB5AHsAf8BtgHtAfgB/wG2Ae0B+AH/AakB7AH2 + Af8BkgHhAfMB/wGNAaEBqgH/ATIBWwFsAf8kAAHqAaoBiwH/AeoBqgGLAf8B6gGqAYsB/wHpAaUBhAH/ + AekBnwGBAf8B5wGXAYEB/wHmAY4BcgH/AeUBhgFmAf8B4wGBAVoB/wHjAYEBUAH/AeIBgQFJAf8B4gGB + AUkB/wHiAYEBSQH/AcgBcgE/Af8IAAGBAacBvQH/AT0BvwHvAf8BmwHpAfkB/wHDAfkB/QH/AcYB+gH+ + Af8BqwHvAfsB/wFrAdAB8gH/ARgBpQHhAf8BCgGYAdYB/yQAAzsBYwNgAdYBgQGrAboB/wGBAaMBswH/ + AYABnQGvAf8BcgGbAa4B/wGBAaIBtAH/A14B2QNAAW8QAAGBAYgBkwH/AY8BpAGsAf8BjwGkAawB/wGP + AaQBrAH/AY8BpAGsAf8BjwGkAawB/wEyAVsBbAH/KAAB6gGqAYsC/wHCAaIB/wH+AcABnwH/Af0BvQGa + Af8B/AG5AZYB/wH7AbUBkAH/AfoBsAGLAf8B+QGrAYQB/wH4AacBgQH/AfYBogGBAf8B9QGdAYEB/wH1 + AZkBgQH/AfMBlQGBAf8BzQGBAUEB/wgAAYEBpAG8Af8BxQH5Af0B/wHGAfoB/gH/AcYB+gH+Af8BxgH6 + Af4B/wHGAfoB/gH/AcYB+gH+Af8BxgH6Af4B/wGZAcgB1AH/nAAB6gGqAYsB/wHqAaoBiwH/AeoBqgGL + Af8B6gGqAYsB/wHqAaYBhgH/AekBoQGBAf8B6AGbAYEB/wHnAZQBgQH/AeYBjgFyAf8B5QGHAWgB/wHk + AYEBXgH/AeQBgQFWAf8B4wGBAU4B/wHiAYEBSQH/DAABgQG2Ac0B/wGBAasBwgH/AW4BnAG0Af8BYQGK + AaMB/wFTAYEBkwH/AUUBbgGDAf8BOgFfAYEB/9wAAUIBTQE+BwABPgMAASgDAAFAAwABMAMAAQEBAAEB + BQABgAEBFgAD/wEAAv8B8wH/AfgBAQIAAv8B+QH/AfgBAQIAAcQBRwH4Af8B6AEBAgABxAFHAfwBfwEA + AQECAAHEAUcB/gE/ASgBAQIAAe4B7wH+AR8BeAEBAgAB7gHvAYABDwF4AQECAAHuAe8BgAEHAQABAQIA + AeABDwHAAQMBAAEBAgAB/gH/AeABAQEAAQECAAH+Af8B8AEBAQABAQIAAfwBfwH4AX8BAAEBAgAB/AF/ + AfwBPwEAAQECAAH8AX8B/gE/AQEB/wIAA/8BHwEBAf8CAAP/AZ8C/wIABP8B/gF/Av8BAAEfAgAB/AF/ + AYABBwF/Ad8CAAH8AT8BgAEHAUADAAH8AT8BgAEHAUADAAH8AT8BgAEHAUADAAH8AT8BgAEHAUADAAH8 + AX8BgAEHAUADAAHwAR8BgAEHAUADAAHgAQ8BgAEHAUADAAHgAQ8BgAEHAUADAAHgAQ8BgAEHBAAB4AEP + AYABBwHAAwAB4AEPAYABBwHAAwAB4AEPAYABBwHAAwAB4AEPAv8BwAEAAv8B8AEfA/8B9wf/AeMH/wFB + AeABDwEAAQEBgAEBAf4BIAHgAQ8BAAEBAYABAQGAAREB4AEPAQABAQGAAQEBgAErAeABDwEAAQEBgAEB + AYABBwHgAQ8BAAEBAYABAQGAAQMB4AEPAQABAQGAAQEBgAEBAeABDwEAAQEBgAEBAYABIwHgAQ8BAAEB + AYABAQGAATcB4AEPAQABAQGAAQEBgAE/AeABDwEAAQEBgAEBAYABPwHgAQ8BAAH/AYABAQGAAT8B4AEP + AQEB/wGAAQEBgAE/BP8BgAEBAcABfwb/Cw== + + + + 221, 17 + + + 328, 17 + + + 418, 17 + + + 521, 17 + + + 17, 17 + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIDSURBVDhPpZLrS5NhGMb3j4SWh0oRQVExD4gonkDpg4hG + YKxG6WBogkMZKgPNCEVJFBGdGETEvgwyO9DJE5syZw3PIlPEE9pgBCLZ5XvdMB8Ew8gXbl54nuf63dd9 + 0OGSnwCahxbPRNPAPMw9Xpg6ZmF46kZZ0xSKzJPIrhpDWsVnpBhGkKx3nAX8Pv7z1zg8OoY/cITdn4fw + bf/C0kYAN3Ma/w3gWfZL5kzTKBxjWyK2DftwI9tyMYCZKXbNHaD91bLYJrDXsYbrWfUKwJrPE9M2M1Oc + VzOOpHI7Jr376Hi9ogHqFIANO0/MmmmbmSmm9a8ze+I4MrNWAdjtoJgWcx+PSzg166yZZ8xM8XvXDix9 + c4jIqFYAjoriBV9AhEPv1mH/sonogha0afbZMMZz+yreTGyhpusHwtNNCsA5U1zS4BLxzJIfg299qO32 + Ir7UJtZfftyATqeT+8o2D8JSjQrAJblrncYL7ZJ2+bfaFnC/1S1NjL3diRat7qrO7wLRP3HjWsojBeCo + mDEo5mNjuweFGvjWg2EBhCbpkW78htSHHwRyNdmgAFzPEee2iFkzayy2OLXzT4gr6UdUnlXrullsxxQ+ + kx0g8BTA3aZlButjSTyjODq/WcQcW/B/Je4OQhLvKQDnzN1mp0nnkvAhR8VuMzNrpm1mpjgkoVwB/v8D + TgDQASA1MVpwzwAAAABJRU5ErkJggg== + + + + + AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAM8xm///9/CEzzGb///38IZqhqf8sRlj/Jis5cAAAAAAAAAAAAAAAAAAAAAB1WUT/x7yx/wAA + AAAAAAAAAAAAAP/9/CEAAAAAAAAAAAAAAAB0eYRPMLrs/xtbd/8pKDZnAAAAAAAAAAB1WUT/29HH/7eh + kP/EsKAJAAAAAAAAAAAzzGb/AAAAAAAAAAAAAAAAAAAAAHh4glUwuuz/IWWD/zswNV11WUT/6uHY/7eh + kP8AAAAAAAAAAAAAAAAAAAAA//38IQAAAAAAAAAAAAAAAAAAAAAAAAAAdX+OSTC67P91WUT/+uHR/7eh + kP8AAAAAAAAAAAAAAAByUj4JAAAAADPMZv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB1WUT/+9/O/yFl + g/8AAAAAAAAAAAAAAACLcV7/oIt9PQAAAAD//fwhAAAAAAAAAAAAAAAAAAAAAAAAAAB1WUT/8OLZ/7eh + kP8wuuz/IWWD/4txXv+LcV7/+/r3/4txXv8AAAAAVJu4/0dvivNHb4rzcnuB+YZuXv+Ib13/7Ofi/7eh + kP8AAAAAjISEjKqim//y5+H/08W5/491Yf+sk4A2VJu4/0zJ8f+X4e//bM7q/6SNfP++ubH/w6+g/5N6 + aP8AAAAAAAAAALWahga6o5P//////NDFu/+PdWH/AAAAAFGZt/tRzvT/oez3/3Pa9f+3oZD/AKfs/66v + rv+ji3r/AAAAAINjUBaBZE9Hool4/8i5rv+PdWH/knhkbgAAAABSmbf1Uc70/5/q9v9y2PL/G7Xt/3Wq + u/+3oZD/uaOSvq+XhCqvloP/ooh2/491Yf+PdWH/j3VhZgAAAAAAAAAAU5q49VLO9P+g6vb/ctjz/xu1 + 7f8Ao+f/K3Oa/QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzzGb/AAAAAFOauPVSzvT/oOr2/3PY + 8/8ctez/AKPm/yxzmv0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//38IQAAAABSmrn1Uc30/53p + 9v9s1fL/ELDs/wCf5v8rc5v9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADPMZv8AAAAAVpy59Xri + +/+t8Pj/keT2/1LK8v8quvD/LnWc/QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//fwhAAAAAIq9 + zv+19fr/zP///9P////O////sfP6/3Ojtv8AAAAAM8xm///9/CEzzGb///38ITPMZv///fwhM8xm/wAA + AAAAAAAAir3O/4q9zv+Kvc7/ir3O/4q9zv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAgPMAALhhAAC8BwAAvg4AAL8cAAC+AAAAgEAAAADBAAAAgQAAAAMAAAH9AAAB/QAAAf0AAAH9 + AAABAQAAg/8AAA== + + + \ No newline at end of file diff --git a/src/Kalman.Studio/ExplorerForm/DatabaseSettingForm.Designer.cs b/src/Kalman.Studio/ExplorerForm/DatabaseSettingForm.Designer.cs new file mode 100644 index 0000000..c75e990 --- /dev/null +++ b/src/Kalman.Studio/ExplorerForm/DatabaseSettingForm.Designer.cs @@ -0,0 +1,187 @@ +namespace Kalman.Studio +{ + partial class DatabaseSettingForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(DatabaseSettingForm)); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.btnDelete = new System.Windows.Forms.Button(); + this.txtConnectString = new System.Windows.Forms.TextBox(); + this.label3 = new System.Windows.Forms.Label(); + this.cbProviderName = new System.Windows.Forms.ComboBox(); + this.label2 = new System.Windows.Forms.Label(); + this.cbConnectStringName = new System.Windows.Forms.ComboBox(); + this.label1 = new System.Windows.Forms.Label(); + this.btnSave = new System.Windows.Forms.Button(); + this.groupBox1.SuspendLayout(); + this.SuspendLayout(); + // + // groupBox1 + // + this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.groupBox1.Controls.Add(this.btnDelete); + this.groupBox1.Controls.Add(this.txtConnectString); + this.groupBox1.Controls.Add(this.label3); + this.groupBox1.Controls.Add(this.cbProviderName); + this.groupBox1.Controls.Add(this.label2); + this.groupBox1.Controls.Add(this.cbConnectStringName); + this.groupBox1.Controls.Add(this.label1); + this.groupBox1.Location = new System.Drawing.Point(12, 12); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(364, 226); + this.groupBox1.TabIndex = 0; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "数据库设置"; + // + // btnDelete + // + this.btnDelete.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.btnDelete.Location = new System.Drawing.Point(317, 21); + this.btnDelete.Name = "btnDelete"; + this.btnDelete.Size = new System.Drawing.Size(41, 23); + this.btnDelete.TabIndex = 6; + this.btnDelete.Text = "删除"; + this.btnDelete.UseVisualStyleBackColor = true; + this.btnDelete.Click += new System.EventHandler(this.btnDelete_Click); + // + // txtConnectString + // + this.txtConnectString.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.txtConnectString.Location = new System.Drawing.Point(20, 120); + this.txtConnectString.Multiline = true; + this.txtConnectString.Name = "txtConnectString"; + this.txtConnectString.Size = new System.Drawing.Size(338, 87); + this.txtConnectString.TabIndex = 5; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(20, 93); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(77, 12); + this.label3.TabIndex = 4; + this.label3.Text = "连接字符串:"; + // + // cbProviderName + // + this.cbProviderName.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.cbProviderName.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.cbProviderName.FormattingEnabled = true; + this.cbProviderName.Items.AddRange(new object[] { + "System.Data.SqlClient", + "MySql.Data.MySqlClient", + "System.Data.SQLite", + "System.Data.OleDb", + "Devart.Data.Oracle", + "System.Data.OracleClient", + "Oracle.ManagedDataAccess.Client"}); + this.cbProviderName.Location = new System.Drawing.Point(92, 56); + this.cbProviderName.Name = "cbProviderName"; + this.cbProviderName.Size = new System.Drawing.Size(266, 20); + this.cbProviderName.TabIndex = 3; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(20, 60); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(65, 12); + this.label2.TabIndex = 2; + this.label2.Text = "驱动类型:"; + // + // cbConnectStringName + // + this.cbConnectStringName.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.cbConnectStringName.FormattingEnabled = true; + this.cbConnectStringName.Location = new System.Drawing.Point(92, 23); + this.cbConnectStringName.Name = "cbConnectStringName"; + this.cbConnectStringName.Size = new System.Drawing.Size(219, 20); + this.cbConnectStringName.TabIndex = 1; + this.cbConnectStringName.SelectedIndexChanged += new System.EventHandler(this.cbConnectStringName_SelectedIndexChanged); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(20, 27); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(65, 12); + this.label1.TabIndex = 0; + this.label1.Text = "连接名称:"; + // + // btnSave + // + this.btnSave.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.btnSave.Location = new System.Drawing.Point(160, 243); + this.btnSave.Name = "btnSave"; + this.btnSave.Size = new System.Drawing.Size(75, 23); + this.btnSave.TabIndex = 1; + this.btnSave.Text = "保存"; + this.btnSave.UseVisualStyleBackColor = true; + this.btnSave.Click += new System.EventHandler(this.btnSave_Click); + // + // DatabaseSettingForm + // + this.AcceptButton = this.btnSave; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(388, 278); + this.Controls.Add(this.btnSave); + this.Controls.Add(this.groupBox1); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "DatabaseSettingForm"; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "数据库设置"; + this.Load += new System.EventHandler(this.DatabaseSettingForm_Load); + this.groupBox1.ResumeLayout(false); + this.groupBox1.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.ComboBox cbConnectStringName; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.ComboBox cbProviderName; + private System.Windows.Forms.TextBox txtConnectString; + private System.Windows.Forms.Button btnDelete; + private System.Windows.Forms.Button btnSave; + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/ExplorerForm/DatabaseSettingForm.cs b/src/Kalman.Studio/ExplorerForm/DatabaseSettingForm.cs new file mode 100644 index 0000000..ea40318 --- /dev/null +++ b/src/Kalman.Studio/ExplorerForm/DatabaseSettingForm.cs @@ -0,0 +1,97 @@ +using Kalman.Utilities; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Configuration; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace Kalman.Studio +{ + public partial class DatabaseSettingForm : Form + { + public DatabaseSettingForm() + { + InitializeComponent(); + } + + private void btnSave_Click(object sender, EventArgs e) + { + var connectName = cbConnectStringName.Text.Trim(); + var providerName = cbProviderName.Text.Trim(); + var connectString = txtConnectString.Text.Trim(); + + if (string.IsNullOrEmpty(connectName)) + { + MessageBox.Show("请选择或输入连接名称!"); + return; + } + + if (string.IsNullOrEmpty(providerName)) + { + MessageBox.Show("请选择Provider名称!"); + return; + } + + if (string.IsNullOrEmpty(connectString)) + { + MessageBox.Show("请输入ConnectString内容!"); + return; + } + + try + { + ConnectionStringUtil.UpdateConnectionString(connectName, connectString, providerName); + + this.DialogResult = DialogResult.Yes; + MessageBox.Show("保存成功,程序将重启!"); + System.Windows.Forms.Application.Restart(); + } + catch (Exception ex) + { + MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); + this.DialogResult = DialogResult.No; + } + } + + private void DatabaseSettingForm_Load(object sender, EventArgs e) + { + RefreshDatabase(); + } + + private void cbConnectStringName_SelectedIndexChanged(object sender, EventArgs e) + { + var item = cbConnectStringName.Text; + var connectString = ConnectionStringUtil.GetConnectionString(item.ToString()); + + txtConnectString.Text = connectString; + + var providerName = ConnectionStringUtil.GetProviderName(item.ToString()); + cbProviderName.SelectedItem = providerName; + } + + private void btnDelete_Click(object sender, EventArgs e) + { + var name = cbConnectStringName.Text; + + if (!string.IsNullOrEmpty(name)) + { + ConnectionStringUtil.RemoveConnectionString(name); + RefreshDatabase(); + } + } + + + private void RefreshDatabase() + { + cbConnectStringName.Items.Clear(); + foreach (ConnectionStringSettings css in ConfigurationManager.ConnectionStrings) + { + cbConnectStringName.Items.Add(css.Name); + } + } + } +} diff --git a/src/Kalman.Studio/ExplorerForm/DatabaseSettingForm.resx b/src/Kalman.Studio/ExplorerForm/DatabaseSettingForm.resx new file mode 100644 index 0000000..3034d7d --- /dev/null +++ b/src/Kalman.Studio/ExplorerForm/DatabaseSettingForm.resx @@ -0,0 +1,287 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + AAABAAEAMDAAAAEAIACoJQAAFgAAACgAAAAwAAAAYAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A+/j4APPg4QDoxMQA3KilD92prADjuroA7tDUAOS1pDDPhmBpw2k6iMJo + QHnMfWRK26eiEe7V1gD79fUA/vn5APv19QD79vYA/vn7AP/+/gD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD//v4A+O/vAN+smjLJeFJrvmAylst6X07ZoKQA37CyAM1/ + WWm5Zjvj0odc/cBzR/C1YDPIz4luSuvNzgD05uYA8+DhAO/U1QDw2NkA+OrqAP75+wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD+/PwA47abR8dyQpCzYDXlz4Zb/bth + NrrKeF9OzIJrQcVrQXnKglvw5qeG/+Ked/+7bEHnx3NNbeK0twDowsIA47q6AN6vsQDitLcA7tDUAPjv + 7wD+/PwA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//7+APv4+AD56ekGzX1MkL5t + Qvbkonz/6rmf/9WQbPy3XjO8tV4xwrdjOdfx08L+/vj2//rq4f/JdUrIy3tjStedngDOh3M8xm1HdMh1 + VF/SkYMm4ri6APDd3AD89/cA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A/vn7APbm + 5wDjua4jv2s9qOu2mf/78er//Pf0/+ivkv/flGv/35No/+Kfef/68ez//vz8//749v/SkG73umEzusJk + OYG4Xi+muWY77bZlOtvHdFNf2aGcEOrMzQD58PEA////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A+/X1AO3PzgbdqaQSx2s9mfLSwfr+/Pz///36//fk2//uwqr/8dC8//bg0v/++Pb//vr4//zz + 7//mrIv/5KJ8/8Z7UvfSgFP+4pp0/+Giff+0YDPIzohtS+vNzgD58PEA////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A68i3Msd1RZDBZTiQxm1IbcFoOqv02cv//vr4///9+v/////////////9 + +v/++Pb//vj2//749v/46d//7sau/+Sifv/rvqP/+/Hq/+/Ltv/Ukm76x3JAje7V1gP68vIA//7+AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD//v4A25xza7lrQOXNglf7tmY95rppPO7y0sH//vz8//74 + 9v/++Pb/++/o//PUwfvz08L7++/o//749v///fr//vr4//vy7v///fr///////vy7v/dpYj4yHNDje3O + 0AP26OkA/vn5AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD++vgC0IJSjM6KZvjkoXv/4Jhv/+2/ + pf///fr//vj2//338v/ZlG3b0oZTp9OMWZDUjluQ1o1ap92bctj89vH//vj2//76+P/++Pb//ffy/+Wv + k/DLdEavz4luSeO1uADu0NQA+fDxAP///wD///8A//7+AP///wD///8A//7+APv4+AD58PEA+u/wAPry + 8gD7+PgA/vz8AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD69vEJ0odUkfbh + 0P767ub/9uDS//rx7P/++vj/+Onf/9GAVcnOg2Jf5b6wJvbq6Aj88/EI9eDSI+KvjFzXjmDC9uHT/v74 + 9v/++vj/6r+l/8BjNpnFcEtqyHdZWNaYjx/pxsgA+e7uAPv4+AD68fIA+u/wAPv29gD//v4A/vn5APTm + 5gDtz9AA6cbIAOvP0ADz3d4A+fDxAP78/AD///8A////AP///wD///8A////AP///wD///8A////AP// + /wDz4M8m1Itaqv749v/++vj//vz8//76+P///fr/7cy5/cBiM4vWnJcS5Lu7AO/U1QD05uYA+OrqAPXh + 3wnWlG1q3qF94/749v//////7sSs/8l+VvjGeVLjtGI11MJmOJDoxcQG9ObmAPPg4QDt0dIA6szNAPPd + 3gD58PEA+O/vAOrNyQnerKoI26SmAN2prADlvL4A89/gAPv4+AD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD25Nge1o1co+Wsi+vswaf29tvN/f749v/+/Pz/89C//7ZfMrnMfGRJ2aCkAN+w + sgDlvL4A58PDAOfBwwDUlX8+y3dKv/z28f/+/Pz/9uPX/+Gbdf/flGn/1oti/sFoOpPoxcIL7tLUAOW+ + wgDao54S3amsAOS9vQDv1NUA4a+aOcZvQZHBZTeQwmY+fMt+Z0fcqKUP7tXWAPrx8gD79vYA+vLyAPz3 + 9wD+/PwA////AP///wD///8A////AP///wD///8A7M24OtiZb3PPf1F/yXVIt/z59v/+/Pz/89nK/8uB + Wvi8YDOqyndcUtGOgiLXnZ0F1pmUFM2DbUPCakB8wHRJ6P739f/++Pb//vj2//ru5v/23c//26WG9cl3 + Sn/rzc4A2qCLO8h0SnS+YTSZy3pfTtukpgDfsbMAynpRcrtpQevMgVj8v3RJ9LVgM8fRiXBH6szNAPPg + 4QDw2NkA7c/QAPDc3QD58PEA////AP///wD///8A////AP///wD///8A////AOa6okS8az2xvm5F8fjp + 3////fr/+vHs/+ewj//VkGr9t2M5z7heMae+XzKPvF8ym7VeMbu5Yzjz67uh///////++Pb//vj2///9 + +v/+/Pz/3px44dSQbGbco4RQynlJrcV6UezQimL8vWM0qcp8ZEnMgWhGw2c6gsyGW/nmp4b/4p53/7ps + QOXHc05s4rO1AOW+wgDesbAG3amsAOO6ugDw2twA////AP///wD///8A////AP///wD///8A//7+AdGK + V4u8a0D05KF7//fo3v///fr///36//fi1v/nsI//4Zlw/9+UbP/Lglf60oRb/t6PZP/kon7/+Onf///9 + +v/89vH/6ruj9O3Bqff25Nj+2I1iyOCrkEnOfU2Uz35T/t+TaP/or5L/yXtT+LVcLre2YTTFtWI32+7K + uf/++vj/+urh/898U9DKeFxS1ZWOGMx8Y1HAYzOQy3tjTNignAznwcMA////AP///wD///8A////AP// + /wD///8A/vv5BNKLWI7iro/6/PPv//76+P/++Pb//vj2//78/P/67ub/78iw/+ewj//in3n/56yK/+/L + tv/68ez///36//76+P/jsJD4wmU7gcZtQoDKdkaVy3pKjuCxoyjBbUCs6bWW//rr5P/89/T/6raX/92S + Z//fj2b/4pp0//rr5P/+/Pz//ffy/9ebevbIcUS0wWU6f71oPs/HfFD7umQ2xct7X07fsLIA////AP// + /wD///8A////AP///wD///8A////AOa5m1HclmvP//v5///9+v/rv6z36Lab9P/9+v///fr//vz8//z3 + 9P/68ez//Pf0/////////fr//vj2//rx7P/jpoL/umc818+FZFvnv74M4LGkItminRLBZTiV6bmf8//+ + /v///fr/9+Tb/+7Apv/vy7b/9NfG//v38v/++vj/+/Lu/+esiv/fn3v/yoBZ9tuGVv/konz/1ZBt/L1j + NKXXmYow////AP///wD///8A////AP///wD///8A////APbo3hjdpH9g3ZVu29yfe+y/b0biv2xD0tGA + Vc3z1sr8/vj2//749v///fr//vj2//zz7//89/T//vr4//749v/x0Lz/xn5X9st5TH/Ymn5LwGk8pr9l + NpnBZTiCwGxCy/fl2//++vj///36//78/P///////vz8//749v/++Pb//vj2//rq4f/rvqP/4p53/+7A + pv/78u7/7sau/7xsQ+PQhV9o////AP///wD///8A////AP///wD///8A////AP75+QDdp4pRvWo8xch8 + UfrfkGX/4KF8/71jNKnVjmrj//36//76+P/tx7b957aX/+anhv/ptZb//PPv///9+v/++vj/zYBZ19GK + aVvHbT2LyHtU+diNZ/7HfFD51IRW/vTay//+/Pz//vj2//749v/66uH/7cCp9u/Ls/n77+j//vj2///9 + +v/++Pb/+/Hq///9+v/+/Pz/+/Lu/8x/WOLPh2No////AP///wD///8A////AP///wD//v4A/vn5APTf + 2BXGd0eb14RW/9yLXf/kon7/5aaE/9SPafzrwaz7//////z39P/y1Mn/+Ofd//bf0//z0L//79C9/ue1 + mvPRf1LEw2U3jc2EaU3AZjeg5a+N/+ivkv/in3n/78u2///9+v/++Pb/89jK/deMY8/ShVSi15JkgNSN + Wo3WjVqn3Jdw1fvy7f/++Pb//vr4//749v/02c393Jdx4MhsP6HXmYov////AP///wD///8A////AP// + /wD7+PgA9eXlAN+slzu3Zjm84JVs/+/IsP/68ez/676j/+Wmgv/tv6X/89LB//PZyv/239P//vz8//78 + /P//////57id/sBvRtfBZTiCxGlCdbBZLsTMflX7/PPv//749v/78u7//vr4//749v/34tT+ynFDrNSP + cVLqx7sd+u/wAPv18gPy3M4i4KyKWdeMYcj45dz+/vj2//v38v/HfFPjwGI0h8JoQHnPiHFA////AP// + /wD///8A////AP/+/gD47e0A6svMANKLcknCbkPH+OXc///////+/Pz/+u7n/+asi//fk2j/4Jhv/+Wj + f//34tb///36//76+P/78u7/5qyL/+Sifv/NhVr4umlA7duHWf/kon7//vj2/////////fr//vj2//74 + 9v/irZPyw2k/e9umpwDku7sA7c/QAPDa3ADw3dwA6snDEMx9UnnlrZDw/vr4//76+P/lrIv/zXxR/b1u + Q/DGbER5////AP///wD///8A////AP75+QDjtqE8zHtSdcdzTWzHck1o35134//7+f/++Pb///36//jl + 3P/2283/+uvk//zz7//++Pb//vj2//76+P/68ez/67mc/+Sifv/lo3//35Bl/9yLXf/rtpn/78iw/+m/ + p//ouKH4//36//749v/ktpn9wWM1kcx+aEXZoKQA3qqtAOGzswDhs7MA1ZWDNMVrQH/WlnL1/vz8//78 + /P/z08L/4Zt1/+Cbcv/DZzmK////AP///wD///8A////APfs5wzJekqUvW9G7bhnPuW0YDXOvWo/0fTT + w////fr//vj2///9+v/+/Pz///36//76+P/++Pb//vj2//749v/++vj//PPv//PTwv/mrIv/5aaC//TX + xv///fr/8sy5/9iVb/7WlG7r/vr4//78/P/x0Lz/z45s9MRnOqPHcU5lzH5oRcyCa0HJdlZdwGI0j7Rh + Nubuwaf///////749v/++Pb/+vHs//LUyf/Hbj6J////AP///wD///8A////AOvHsTe9bD+44pp0/+Ka + dP/imnT/3o1i/+/IsP/+/Pz//vj2//749v/++Pb//vj2//749v/++Pb//vj2//749v/++Pb//vr4//78 + /P/68ez//Pf0///////++vj//vz8/+u+o//imnT//PPv///9+v/67ub/5qqI/9eYdPy/b0bgt2E2xbdg + NcK5ZDrYv3JG9N+QZf/249f//vz8//749v/++Pb//vr4//338v/LfEyK////AP///wD///8A////AOGu + jla8bUDS4p95/+GZcP/fk2j/6K+S//76+P/++Pb//vj2//749v/++Pb//vj2//749v/89vH//vj2//74 + 9v/++Pb//vj2//749v/++vj//vj2//749v///fr/9uHT/+29o//x0Lz//vj2//749v/++vj/9+je/+ew + j//hlm3/4Jhv/9+Uaf/fk2j/4pp0//bbzf/++vj//vr4/+Suj+/ThlrL3px24eSrjOzYm29z////AP// + /wD///8A////ANmacXHgpILp9+je//PZyv/wzLn/+urh///9+v/++Pb//vj2//749v/46+L/3Zl14NSI + WsbShVa22pBnzuOriev+9/X//vj2//749v/++Pb//vj2//zz7//qwKb+y3hNyvLVxP7///////36//76 + +P/++Pb//vz8//vx6v/z1cX/78Ot/+2/pf/yzLn/9+je//78/P/++vj/+eje/8Z3TNLMfmBU0IpkZ9eX + a3Pszbc6////AP///wD///8A////ANWPXoTuzLn6//36//78/P////////36//749v/++Pb//vj2//rw + 7P/IdUrJx3NQZs+Ib0fZoY4z2Zh8UNCHXHLYjWTP+u/n//749v/++Pb//vj2//v38v/nq4n/14pk/ue3 + nP7++vj/68Gr+9OLX9Tjqojq+u7m///9+v/+/Pz//vz8//78/P////////36//749v///fr/89PC/9eP + a/7CazuU6cnGDPnw8QD///8A////AP///wD///8A////ANONXIj34tT+/Pb0//76+P/++Pb//vj2//74 + 9v/++Pb//vz8//PQv/+4ZzzexmxHbs6EczXYn6IA3KWnANeXjx3Hb0lz3Jt56/76+P/++Pb//vj2//// + ///vyLD/35Bl/+GWbf/or5L/tWM2zdONb1fVj2ZywXRIz/ru5v/++vj//vj2//vq4//wzLn66LWY8fzy + 7v/++Pb//vj2/+7Bqf/Id0eY8tzWEf75+QD///8A////AP///wD///8A////AOa8nFDWjVqi2Ixeu9aL + Xcvls5jz/vj2//749v/++Pb///36/+3Bqf/hon3/v3FJ57tfMaDBZTp/w2c/er5fMpSxWi/S3p+A/f/9 + +v/++Pb//vj2///9+v/249f/566N/+Wjf//fmW7/tmE0u9ujjjrdp4hXvXFD1Prx7P/++vj/+OHX/sp2 + SKDNfEuO15Zoet2gd93++Pb/+OPX/tuWb9vRiFWP+/X1Bf/+/gD///8A////AP///wD///8A////AP// + /wD04tgd3ayNT8JsPpvGfFXr//36//749v/++Pb//vz8//PVxf/kon7/5aaE/9yWbv/FeE/1v3FI8dOI + Xf3bh1n/6rmf///////++Pb//vj2//749v/++vj//Pf0//zz7//46Nz/yHFDq+C0pifeq4lb0Y5j1/fi + 2/799/L/7cmw+dGIWIL26+sE8dnKKdKOW4zdl27S1I1apuKuil/03c4m////AP///wD///8A////AP// + /wD///8A////AP///wD68eoMyXtKlc58T/3glWz/+u7m///9+v/++Pb//vj2//z39P/uwKb/5KJ+/+Ka + dP/innf/4Jhv/9+Uaf/flGn/9t3P//78/P/++Pb//vj2//749v/++Pb//vj2//76+P/45df+yndGk/DX + 1Qvy3M4i0o5bjNSOW5XXjmC42I5iwdOLWov/+voB////APbl2x3kt5dW9ePXIP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wDw1cIuv3BDsdyLXf/innf/+Onf///9+v/++Pb//vj2//74 + 9v/++Pb/8My5/+Wmgv/in3n/4pp0/+anhv/249f///36//749v/++Pb//vj2//vv6v/vyLL5++zl///7 + +f/swqr30IJSi/vy8gH//v4A/v78Avry7Q7u0ro37MqwQPz49gj///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wDovaBNwXZIy+/IsP/78er///36//74 + 9v/++Pb//vj2//749v/++Pb///36//zz7//45dz/+urh//z39P///fr//vj2//749v/++Pb//vr4/+O1 + mPfCZjmDyG5BoM+BU7zXil636L+kR//+/gD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD04tUi1o1cpvXi + 1P3//fr//vj2//749v/78er//vj2//749v/++Pb//vj2//76+P///fr///36//749v/++Pb//vj2//74 + 9v/++vj/9uDS/+Slgf/Jek/Qz4drUuCumTvryrc1////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A57ydT9aNXK/66uH/++rl/92Yb9jTilmq4aJ94/z27//++vj//vj2//749v/++Pb//vj2//74 + 9v/++Pb//vj2//749v///fr/9NfG/+Wjf//KgVvpzoFacPXl5QD++fsA////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AOa7m1HYjmK8145etuGujFzw1cIw36iBaNCHVrPtxq77/vr4//74 + 9v/++Pb/+/Hq//TZzf3swqz389TB+/749v/++Pb//vz8/+/Ltv/QimLi15ZvaPv19QD//v4A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP7+/ALszbc77tPAM////wD///8A////ANKL + XITjt5z5//36//749v/45dz+znhKrs59TJPVj2GB1o1cqvbf0P3++Pb//vj2//PSwfzShVat7tG9L//+ + /gD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A+vLqENKLWJf88ez//vj2//749v/rv6T20IJWf/Ph3wv++fsA57ydT9iQZL/y2cv93JZt0tKL + WJbnvJ1N////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A/vr4BdSNWo/em3XZ5a6P7vPVxfzgoX3i3aN8Z/75+wD//v4A/vn2Bue9 + oE7UjluW5LeXVvbl2x3///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////APPf0CXisYxe255yddWPXoffqYJn8dbFL/// + /wD///8A////AP///wD68ewP////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD//////////////////8zM//////// + mZn///////9mZv/cD////zMz/wwP////AAD+AA////////wACH///8zM/AAAP///mZn4AAA///9mZvAA + AB///zMz8AAAH///AADgAAA//////+AAAB///8zM4AeAD+f/mZngB8ANwP9mZvAAABDA/zMz+AAAAADf + AADwAAAAAAf///AAAAAAB8zM+AAAAAADmZn4AAAAAANmZvwAAAAAAzMz+AAAAAADAAD4AAAAIAP///gA + AAD4A8zM4AAAAHgDmZnAAAAAAANmZsAAAAAAAzMzwAAAAAADAADAAAAAAAP//8AAAAAAD8zMwAGAAAAP + mZnAAAAAAA9mZuAAAAAAHzMz4AAAAAR/AADgAAACD////+AAAAf//8zM4AAAD///mZnwAAA///9mZvgA + AD///zMz+OAAP///AAD/wCB///8AAP/AYP///wAA/+B7////AAD///////8AAP///////wAA//////// + AAA= + + + \ No newline at end of file diff --git a/src/Kalman.Studio/ExplorerForm/Output.cs b/src/Kalman.Studio/ExplorerForm/Output.cs new file mode 100644 index 0000000..d363520 --- /dev/null +++ b/src/Kalman.Studio/ExplorerForm/Output.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using WeifenLuo.WinFormsUI.Docking; + +namespace Kalman.Studio +{ + public partial class Output : DockExplorer + { + public Output() + { + InitializeComponent(); + } + + /// + /// 向输出窗口追加一行文本 + /// + /// + public void AppendLine(string s) + { + if (string.IsNullOrEmpty(s)) return; + richTextBox1.AppendText(s + Environment.NewLine); + } + + public void AppendText(string s) + { + if (string.IsNullOrEmpty(s)) return; + richTextBox1.AppendText(s); + } + + /// + /// 清除所有输出文本 + /// + public void ClearText() + { + richTextBox1.Clear(); + } + + private void menuItemCopy_Click(object sender, EventArgs e) + { + richTextBox1.Copy(); + } + + private void menuItemClear_Click(object sender, EventArgs e) + { + richTextBox1.Clear(); + } + + private void menuItemSelectAll_Click(object sender, EventArgs e) + { + richTextBox1.SelectAll(); + } + } +} diff --git a/src/Kalman.Studio/ExplorerForm/Output.designer.cs b/src/Kalman.Studio/ExplorerForm/Output.designer.cs new file mode 100644 index 0000000..8dad6c7 --- /dev/null +++ b/src/Kalman.Studio/ExplorerForm/Output.designer.cs @@ -0,0 +1,108 @@ +namespace Kalman.Studio +{ + partial class Output + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Output)); + this.richTextBox1 = new System.Windows.Forms.RichTextBox(); + this.cms = new System.Windows.Forms.ContextMenuStrip(this.components); + this.menuItemCopy = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemSelectAll = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemClear = new System.Windows.Forms.ToolStripMenuItem(); + this.cms.SuspendLayout(); + this.SuspendLayout(); + // + // richTextBox1 + // + this.richTextBox1.ContextMenuStrip = this.cms; + this.richTextBox1.Dock = System.Windows.Forms.DockStyle.Fill; + this.richTextBox1.Location = new System.Drawing.Point(0, 0); + this.richTextBox1.Name = "richTextBox1"; + this.richTextBox1.Size = new System.Drawing.Size(554, 186); + this.richTextBox1.TabIndex = 0; + this.richTextBox1.Text = ""; + // + // cms + // + this.cms.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.menuItemCopy, + this.menuItemSelectAll, + this.menuItemClear}); + this.cms.Name = "cms"; + this.cms.Size = new System.Drawing.Size(154, 70); + // + // menuItemCopy + // + this.menuItemCopy.Name = "menuItemCopy"; + this.menuItemCopy.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.C))); + this.menuItemCopy.Size = new System.Drawing.Size(153, 22); + this.menuItemCopy.Text = "复制(&C)"; + this.menuItemCopy.Click += new System.EventHandler(this.menuItemCopy_Click); + // + // menuItemSelectAll + // + this.menuItemSelectAll.Name = "menuItemSelectAll"; + this.menuItemSelectAll.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.A))); + this.menuItemSelectAll.Size = new System.Drawing.Size(153, 22); + this.menuItemSelectAll.Text = "全选(&A)"; + this.menuItemSelectAll.Click += new System.EventHandler(this.menuItemSelectAll_Click); + // + // menuItemClear + // + this.menuItemClear.Name = "menuItemClear"; + this.menuItemClear.Size = new System.Drawing.Size(153, 22); + this.menuItemClear.Text = "全部清除"; + this.menuItemClear.Click += new System.EventHandler(this.menuItemClear_Click); + // + // Output + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(554, 186); + this.Controls.Add(this.richTextBox1); + this.DockAreas = WeifenLuo.WinFormsUI.Docking.DockAreas.DockBottom; + this.HideOnClose = true; + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "Output"; + this.ShowHint = WeifenLuo.WinFormsUI.Docking.DockState.DockBottomAutoHide; + this.Text = "输出"; + this.cms.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.RichTextBox richTextBox1; + private System.Windows.Forms.ContextMenuStrip cms; + private System.Windows.Forms.ToolStripMenuItem menuItemCopy; + private System.Windows.Forms.ToolStripMenuItem menuItemClear; + private System.Windows.Forms.ToolStripMenuItem menuItemSelectAll; + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/ExplorerForm/Output.resx b/src/Kalman.Studio/ExplorerForm/Output.resx new file mode 100644 index 0000000..e152f8b --- /dev/null +++ b/src/Kalman.Studio/ExplorerForm/Output.resx @@ -0,0 +1,165 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + + + AAABAAIAICAQAAAAAADoAgAAJgAAABAQAAAAAAAAaAUAAA4DAAAoAAAAIAAAAEAAAAABAAQAAAAAAIAC + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAgAAAAICAAIAAAACAAIAAgIAAAMDAwACAgIAAAAD/AAD/ + AAAA//8A/wAAAP8A/wD//wAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //8oAAAAEAAAACAAAAABAAgAAAAAAEABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAgAAAAICAAIAA + AACAAIAAgIAAAMDAwADA3MAA8MqmAAQEBAAICAgADAwMABEREQAWFhYAHBwcACIiIgApKSkAVVVVAE1N + TQBCQkIAOTk5AIB8/wBQUP8AkwDWAP/szADG1u8A1ufnAJCprQAAADMAAABmAAAAmQAAAMwAADMAAAAz + MwAAM2YAADOZAAAzzAAAM/8AAGYAAABmMwAAZmYAAGaZAABmzAAAZv8AAJkAAACZMwAAmWYAAJmZAACZ + zAAAmf8AAMwAAADMMwAAzGYAAMyZAADMzAAAzP8AAP9mAAD/mQAA/8wAMwAAADMAMwAzAGYAMwCZADMA + zAAzAP8AMzMAADMzMwAzM2YAMzOZADMzzAAzM/8AM2YAADNmMwAzZmYAM2aZADNmzAAzZv8AM5kAADOZ + MwAzmWYAM5mZADOZzAAzmf8AM8wAADPMMwAzzGYAM8yZADPMzAAzzP8AM/8zADP/ZgAz/5kAM//MADP/ + /wBmAAAAZgAzAGYAZgBmAJkAZgDMAGYA/wBmMwAAZjMzAGYzZgBmM5kAZjPMAGYz/wBmZgAAZmYzAGZm + ZgBmZpkAZmbMAGaZAABmmTMAZplmAGaZmQBmmcwAZpn/AGbMAABmzDMAZsyZAGbMzABmzP8AZv8AAGb/ + MwBm/5kAZv/MAMwA/wD/AMwAmZkAAJkzmQCZAJkAmQDMAJkAAACZMzMAmQBmAJkzzACZAP8AmWYAAJlm + MwCZM2YAmWaZAJlmzACZM/8AmZkzAJmZZgCZmZkAmZnMAJmZ/wCZzAAAmcwzAGbMZgCZzJkAmczMAJnM + /wCZ/wAAmf8zAJnMZgCZ/5kAmf/MAJn//wDMAAAAmQAzAMwAZgDMAJkAzADMAJkzAADMMzMAzDNmAMwz + mQDMM8wAzDP/AMxmAADMZjMAmWZmAMxmmQDMZswAmWb/AMyZAADMmTMAzJlmAMyZmQDMmcwAzJn/AMzM + AADMzDMAzMxmAMzMmQDMzMwAzMz/AMz/AADM/zMAmf9mAMz/mQDM/8wAzP//AMwAMwD/AGYA/wCZAMwz + AAD/MzMA/zNmAP8zmQD/M8wA/zP/AP9mAAD/ZjMAzGZmAP9mmQD/ZswAzGb/AP+ZAAD/mTMA/5lmAP+Z + mQD/mcwA/5n/AP/MAAD/zDMA/8xmAP/MmQD/zMwA/8z/AP//MwDM/2YA//+ZAP//zABmZv8AZv9mAGb/ + /wD/ZmYA/2b/AP//ZgAhAKUAX19fAHd3dwCGhoYAlpaWAMvLywCysrIA19fXAN3d3QDj4+MA6urqAPHx + 8QD4+PgA8Pv/AKSgoACAgIAAAAD/AAD/AAAA//8A/wAAAP8A/wD//wAA////AAoKCgoKCgoKCgoKCgoK + CgoKCvdmZmZmZmZmZmZmZgoKCgr39fPzGRnd3d0JCWYKCgoK9//v7+/v7+/vGQlmCgoKCvf////19fX0 + 9BndZgoKCgr3/+/v7+/v7+/v3WYKCgoKtf//////9fX19BlmCgoKCrX/+Pj4+Pj4+PUZZgoKCgrv//// + ///////182YKCgoKu//v7+/v7+/v7/NmCgoKCrv/////////////ZgoKCgrW1ta1tLS0tLStra0KCgoK + 1gkJCdzc1tXV1dWtCgoKCtbW1rW0tLS0tK2trQoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK + Cgr//wAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAP// + AAD//wAA + + + \ No newline at end of file diff --git a/src/Kalman.Studio/ExplorerForm/PdmExplorer/PdmColumnsViewer.cs b/src/Kalman.Studio/ExplorerForm/PdmExplorer/PdmColumnsViewer.cs new file mode 100644 index 0000000..26ca09d --- /dev/null +++ b/src/Kalman.Studio/ExplorerForm/PdmExplorer/PdmColumnsViewer.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using Kalman.PdmParser; + +namespace Kalman.Studio +{ + public partial class PdmColumnsViewer : Form + { + IList list = null; + public PdmColumnsViewer(IList columnList) + { + InitializeComponent(); + list = columnList; + } + + private void PdmColumnsViewer_Load(object sender, EventArgs e) + { + dgvColumn.AutoGenerateColumns = false; + dgvColumn.DataSource = list; + } + } +} diff --git a/src/Kalman.Studio/ExplorerForm/PdmExplorer/PdmColumnsViewer.designer.cs b/src/Kalman.Studio/ExplorerForm/PdmExplorer/PdmColumnsViewer.designer.cs new file mode 100644 index 0000000..56d2a3b --- /dev/null +++ b/src/Kalman.Studio/ExplorerForm/PdmExplorer/PdmColumnsViewer.designer.cs @@ -0,0 +1,207 @@ +namespace Kalman.Studio +{ + partial class PdmColumnsViewer + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle2 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle3 = new System.Windows.Forms.DataGridViewCellStyle(); + this.dgvColumn = new System.Windows.Forms.DataGridView(); + this.colID = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colName = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colCode = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colDataType = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colLength = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colPrecision = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colIsPK = new System.Windows.Forms.DataGridViewCheckBoxColumn(); + this.colIsFK = new System.Windows.Forms.DataGridViewCheckBoxColumn(); + this.colMandatory = new System.Windows.Forms.DataGridViewCheckBoxColumn(); + this.colComment = new System.Windows.Forms.DataGridViewTextBoxColumn(); + ((System.ComponentModel.ISupportInitialize)(this.dgvColumn)).BeginInit(); + this.SuspendLayout(); + // + // dgvColumn + // + this.dgvColumn.AllowUserToAddRows = false; + this.dgvColumn.AllowUserToDeleteRows = false; + this.dgvColumn.AllowUserToResizeRows = false; + this.dgvColumn.BackgroundColor = System.Drawing.SystemColors.ActiveCaptionText; + dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle1.BackColor = System.Drawing.SystemColors.Control; + dataGridViewCellStyle1.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + dataGridViewCellStyle1.ForeColor = System.Drawing.SystemColors.WindowText; + dataGridViewCellStyle1.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle1.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle1.WrapMode = System.Windows.Forms.DataGridViewTriState.True; + this.dgvColumn.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle1; + this.dgvColumn.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.dgvColumn.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { + this.colID, + this.colName, + this.colCode, + this.colDataType, + this.colLength, + this.colPrecision, + this.colIsPK, + this.colIsFK, + this.colMandatory, + this.colComment}); + dataGridViewCellStyle2.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle2.BackColor = System.Drawing.SystemColors.Window; + dataGridViewCellStyle2.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + dataGridViewCellStyle2.ForeColor = System.Drawing.SystemColors.ControlText; + dataGridViewCellStyle2.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle2.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle2.WrapMode = System.Windows.Forms.DataGridViewTriState.False; + this.dgvColumn.DefaultCellStyle = dataGridViewCellStyle2; + this.dgvColumn.Dock = System.Windows.Forms.DockStyle.Fill; + this.dgvColumn.Location = new System.Drawing.Point(0, 0); + this.dgvColumn.MultiSelect = false; + this.dgvColumn.Name = "dgvColumn"; + dataGridViewCellStyle3.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle3.BackColor = System.Drawing.SystemColors.Control; + dataGridViewCellStyle3.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + dataGridViewCellStyle3.ForeColor = System.Drawing.SystemColors.WindowText; + dataGridViewCellStyle3.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle3.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle3.WrapMode = System.Windows.Forms.DataGridViewTriState.True; + this.dgvColumn.RowHeadersDefaultCellStyle = dataGridViewCellStyle3; + this.dgvColumn.RowHeadersVisible = false; + this.dgvColumn.RowTemplate.Height = 23; + this.dgvColumn.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.CellSelect; + this.dgvColumn.Size = new System.Drawing.Size(692, 173); + this.dgvColumn.TabIndex = 2; + // + // colID + // + this.colID.DataPropertyName = "ID"; + this.colID.HeaderText = "ID"; + this.colID.Name = "colID"; + this.colID.Width = 42; + // + // colName + // + this.colName.DataPropertyName = "Name"; + this.colName.HeaderText = "Name"; + this.colName.Name = "colName"; + this.colName.Width = 54; + // + // colCode + // + this.colCode.DataPropertyName = "Code"; + this.colCode.HeaderText = "Code"; + this.colCode.Name = "colCode"; + this.colCode.Width = 54; + // + // colDataType + // + this.colDataType.DataPropertyName = "DataType"; + this.colDataType.HeaderText = "DataType"; + this.colDataType.Name = "colDataType"; + this.colDataType.Width = 78; + // + // colLength + // + this.colLength.DataPropertyName = "Length"; + this.colLength.HeaderText = "Length"; + this.colLength.Name = "colLength"; + this.colLength.Width = 66; + // + // colPrecision + // + this.colPrecision.DataPropertyName = "Precision"; + this.colPrecision.HeaderText = "Precision"; + this.colPrecision.Name = "colPrecision"; + this.colPrecision.Width = 84; + // + // colIsPK + // + this.colIsPK.DataPropertyName = "IsPK"; + this.colIsPK.HeaderText = "P"; + this.colIsPK.Name = "colIsPK"; + this.colIsPK.Resizable = System.Windows.Forms.DataGridViewTriState.True; + this.colIsPK.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic; + this.colIsPK.Width = 20; + // + // colIsFK + // + this.colIsFK.DataPropertyName = "IsFK"; + this.colIsFK.HeaderText = "F"; + this.colIsFK.Name = "colIsFK"; + this.colIsFK.Resizable = System.Windows.Forms.DataGridViewTriState.True; + this.colIsFK.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic; + this.colIsFK.Width = 20; + // + // colMandatory + // + this.colMandatory.DataPropertyName = "Mandatory"; + this.colMandatory.HeaderText = "M"; + this.colMandatory.Name = "colMandatory"; + this.colMandatory.Resizable = System.Windows.Forms.DataGridViewTriState.True; + this.colMandatory.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic; + this.colMandatory.Width = 20; + // + // colComment + // + this.colComment.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; + this.colComment.DataPropertyName = "Comment"; + this.colComment.HeaderText = "Comment"; + this.colComment.Name = "colComment"; + // + // PdmColumnsViewer + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(692, 173); + this.Controls.Add(this.dgvColumn); + this.Name = "PdmColumnsViewer"; + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "查看所属字段列表"; + this.Load += new System.EventHandler(this.PdmColumnsViewer_Load); + ((System.ComponentModel.ISupportInitialize)(this.dgvColumn)).EndInit(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.DataGridView dgvColumn; + private System.Windows.Forms.DataGridViewTextBoxColumn colID; + private System.Windows.Forms.DataGridViewTextBoxColumn colName; + private System.Windows.Forms.DataGridViewTextBoxColumn colCode; + private System.Windows.Forms.DataGridViewTextBoxColumn colDataType; + private System.Windows.Forms.DataGridViewTextBoxColumn colLength; + private System.Windows.Forms.DataGridViewTextBoxColumn colPrecision; + private System.Windows.Forms.DataGridViewCheckBoxColumn colIsPK; + private System.Windows.Forms.DataGridViewCheckBoxColumn colIsFK; + private System.Windows.Forms.DataGridViewCheckBoxColumn colMandatory; + private System.Windows.Forms.DataGridViewTextBoxColumn colComment; + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/ExplorerForm/PdmExplorer/PdmColumnsViewer.resx b/src/Kalman.Studio/ExplorerForm/PdmExplorer/PdmColumnsViewer.resx new file mode 100644 index 0000000..0d86845 --- /dev/null +++ b/src/Kalman.Studio/ExplorerForm/PdmExplorer/PdmColumnsViewer.resx @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + \ No newline at end of file diff --git a/src/Kalman.Studio/ExplorerForm/PdmExplorer/PdmExplorer.cs b/src/Kalman.Studio/ExplorerForm/PdmExplorer/PdmExplorer.cs new file mode 100644 index 0000000..d812d60 --- /dev/null +++ b/src/Kalman.Studio/ExplorerForm/PdmExplorer/PdmExplorer.cs @@ -0,0 +1,516 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using Kalman.PdmParser; +using System.IO; +using WeifenLuo.WinFormsUI.Docking; +using Kalman.Command; +using Kalman.Data.SchemaObject; + +namespace Kalman.Studio +{ + public partial class PdmExplorer : DockExplorer + { + List pdmFileList = new List(); //PDM文件列表 + string configFile = Path.Combine(Application.StartupPath, "config\\PDMFileList.config"); + + public PdmExplorer() + { + InitializeComponent(); + } + + private void PdmExplorer_Load(object sender, EventArgs e) + { + TreeNode root = new TreeNode("PDM文件列表", 0, 0); + root.ContextMenuStrip = cms; + tv.Nodes.Add(root); + root.Expand(); + LoadFileNodes(); + } + + #region private method + + void LoadFileNodes() + { + //读配置文件 + if (File.Exists(configFile)) + { + string[] ss = File.ReadAllLines(configFile); + foreach (string s in ss) + { + if (File.Exists(s) && pdmFileList.Contains(s) == false) pdmFileList.Add(s); + } + SaveFile(); + } + //初始化pdm文件节点 + foreach (string fileName in pdmFileList) + { + AddFileNode(fileName); + } + } + + //增加一个文件节点 + void AddFileNode(string fileName) + { + TreeNode root = tv.Nodes[0]; + //先判断要增加的文件节点是否已存在 + foreach (TreeNode node in root.Nodes) + { + if (node.Tag.ToString() == fileName) return; + } + + string name = Path.GetFileName(fileName); + TreeNode tn = new TreeNode(name, 1, 1); + tn.ToolTipText = fileName; + tn.Tag = fileName; + tn.ContextMenuStrip = cmsFile; + + root.Nodes.Add(tn); + root.Expand(); + SaveFile(); + } + //移除一个文件节点 + void RemoveFileNode(TreeNode node) + { + tv.Nodes.Remove(node); + pdmFileList.Remove(node.Tag.ToString()); + SaveFile(); + } + //保存配置文件 + void SaveFile() + { + StringBuilder sb = new StringBuilder(); + foreach (string s in pdmFileList) + { + sb.AppendLine(s); + } + File.WriteAllText(configFile, sb.ToString(), Encoding.UTF8); + } + + #endregion + + #region 模型树事件处理 + + //解决右键点击节点定位的问题 + private void tv_MouseClick(object sender, MouseEventArgs e) + { + if (e.Button == MouseButtons.Right) + { + TreeView tv = sender as TreeView; + TreeNode tn = tv.GetNodeAt(e.X, e.Y); + tv.SelectedNode = tn; + } + } + + private void tv_MouseDoubleClick(object sender, MouseEventArgs e) + { + TreeView tv = sender as TreeView; + TreeNode tn = tv.GetNodeAt(e.X, e.Y); + + if (tn.Level == 1 && tn.Nodes.Count == 0) + { + LoadModel(tn); + tn.Expand(); + } + } + + #endregion + + #region 加载PDM模型对象节点 + + string FormatNodeToolTip(PDObject o) + { + StringBuilder sb = new StringBuilder(); + sb.AppendLine("ID:" + o.ID); + sb.AppendLine("Name:" + o.Name); + sb.AppendLine("Code:" + o.Code); + sb.AppendLine("Comment:" + o.Comment); + return sb.ToString(); + } + + //加载模型节点 + private void LoadModel(TreeNode fileNode) + { + string fileName = fileNode.Tag.ToString(); + PdmReader reader = new PdmReader(fileName); + PDModel m = reader.BuildModel(); + + TreeNode node = new TreeNode(m.Name, 2, 2); + node.ToolTipText = FormatNodeToolTip(m); + node.Tag = m; + node.ContextMenuStrip = cmsModel; + + LoadPackages(m.PackageList, node); + + if (m.TableList.Count > 0) + { + TreeNode tablesNode = new TreeNode("Tables", 4, 4); + tablesNode.Tag = m.TableList; + LoadTables(m.TableList, tablesNode); + node.Nodes.Add(tablesNode); + } + + fileNode.Nodes.Add(node); + node.Expand(); + } + + //加载包节点 + void LoadPackages(IList packageList, TreeNode root) + { + foreach (PDPackage package in packageList) + { + TreeNode node = new TreeNode(package.Name, 3, 3); + node.Tag = package; + node.ToolTipText = FormatNodeToolTip(package); + node.ContextMenuStrip = cmsModel; + + if (package.TableList.Count > 0) + { + TreeNode tablesNode = new TreeNode("Tables", 4, 4); + tablesNode.Tag = package.TableList; + LoadTables(package.TableList, tablesNode); + node.Nodes.Add(tablesNode); + } + + root.Nodes.Add(node); + + LoadPackages(package.ChildrenList, node); + } + } + + //加载表节点 + void LoadTables(IList tableList, TreeNode root) + { + foreach (PDTable table in tableList) + { + TreeNode node = new TreeNode(table.Name,5,5); + node.Tag = table; + node.ToolTipText = FormatNodeToolTip(table); + node.ContextMenuStrip = cmsTable; + + if (table.ColumnList.Count > 0) + { + TreeNode columnsNode = new TreeNode("Columns", 4, 4); + columnsNode.Tag = table.ColumnList; + LoadColumns(table.ColumnList, columnsNode); + node.Nodes.Add(columnsNode); + } + + if (table.KeyList.Count > 0) + { + TreeNode keysNode = new TreeNode("Keys", 4, 4); + keysNode.Tag = table.KeyList; + LoadKeys(table.KeyList, keysNode); + node.Nodes.Add(keysNode); + } + + if (table.IndexList.Count > 0) + { + TreeNode indexesNode = new TreeNode("Indexes", 4, 4); + indexesNode.Tag = table.IndexList; + LoadIndexes(table.IndexList, indexesNode); + node.Nodes.Add(indexesNode); + } + + root.Nodes.Add(node); + } + } + + //加载列节点 + private void LoadColumns(IList columnList, TreeNode root) + { + foreach (PDColumn column in columnList) + { + TreeNode columnNode = new TreeNode(column.Name, 6, 6); + columnNode.Tag = column; + columnNode.ToolTipText = FormatNodeToolTip(column); + + root.Nodes.Add(columnNode); + } + } + + //加载键节点 + private void LoadKeys(IList keyList, TreeNode root) + { + foreach (PDKey key in keyList) + { + TreeNode keyNode = new TreeNode(key.Name, 7, 7); + keyNode.Tag = key; + keyNode.ToolTipText = FormatNodeToolTip(key); + + root.Nodes.Add(keyNode); + } + } + + //加载索引节点 + private void LoadIndexes(IList indexList, TreeNode root) + { + foreach (PDIndex index in indexList) + { + TreeNode indexNode = new TreeNode(index.Name, 8, 8); + indexNode.Tag = index; + indexNode.ToolTipText = FormatNodeToolTip(index); + + root.Nodes.Add(index.Name); + } + } + + #endregion + + #region 模型树右键菜单事件处理 + private void menuItemLoadFile_Click(object sender, EventArgs e) + { + OpenFileDialog dialog = new OpenFileDialog(); + dialog.Filter = "pdm文件(*.pdm)|*.pdm|所有文件 (*.*)|*.*"; + dialog.FilterIndex = 1; + dialog.RestoreDirectory = true; + + if (dialog.ShowDialog() == DialogResult.OK) + { + pdmFileList.Add(dialog.FileName); + AddFileNode(dialog.FileName); + } + } + + + + #endregion + + #region 文件节点右键菜单事件处理 + + private void menuItemRemoveFile_Click(object sender, EventArgs e) + { + TreeNode node = tv.SelectedNode; + RemoveFileNode(node); + } + + private void menuItemReload_Click(object sender, EventArgs e) + { + TreeNode node = tv.SelectedNode; + node.Nodes.Clear(); + LoadModel(node); + } + + #endregion + + #region 模型和包节点右键菜单事件处理 + + private void menuItemBrowserModel_Click(object sender, EventArgs e) + { + PdmModelViewer viewer = null; + foreach (IDockContent content in DockPanel.Documents) + { + if (content is PdmModelViewer) viewer = content as PdmModelViewer; + } + + if (viewer == null) viewer = new PdmModelViewer(); + + TreeNode node = tv.SelectedNode; + + if (node.Tag.GetType().Name == typeof(PDModel).Name) + { + PDModel m = node.Tag as PDModel; + viewer.LoadModel(m); + } + if (node.Tag.GetType().Name == typeof(PDPackage).Name) + { + PDPackage p = node.Tag as PDPackage; + viewer.LoadPackage(p); + } + + viewer.Show(this.DockPanel); + } + + private void menuItemBuildWord_Click(object sender, EventArgs e) + { + IList tableList = new List(); + string title = string.Empty; + TreeNode node = tv.SelectedNode; + + if (node.Tag is PDModel) + { + PDModel m = node.Tag as PDModel; + tableList = m.AllTableList; + title = m.Name; + } + if (node.Tag is PDPackage) + { + PDPackage p = node.Tag as PDPackage; + tableList = p.TableList; + title = p.Name; + } + + saveFileDialog1.FileName = title; + saveFileDialog1.Filter = "rtf文件(*.rtf)|*.rtf|所有文件(*.*)|*.*"; + if (saveFileDialog1.ShowDialog() == DialogResult.OK) + { + string fileName = saveFileDialog1.FileName; + + iTextExporter exporter = new iTextExporter(fileName); + exporter.PDModel2Rtf(tableList,title); + + if (MessageBox.Show("数据库文档生成成功,是否打开文档", "提示信息", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes) + { + CmdHelper.Execute(fileName); + } + } + } + + private void menuItemBuildPdf_Click(object sender, EventArgs e) + { + IList tableList = new List(); + string title = string.Empty; + TreeNode node = tv.SelectedNode; + + if (node.Tag is PDModel) + { + PDModel m = node.Tag as PDModel; + tableList = m.AllTableList; + title = m.Name; + } + if (node.Tag is PDPackage) + { + PDPackage p = node.Tag as PDPackage; + tableList = p.TableList; + title = p.Name; + } + + saveFileDialog1.FileName = title; + saveFileDialog1.Filter = "pdf文件(*.pdf)|*.pdf|所有文件(*.*)|*.*"; + + if (saveFileDialog1.ShowDialog() == DialogResult.OK) + { + string fileName = saveFileDialog1.FileName; + + iTextExporter exporter = new iTextExporter(fileName); + exporter.PDModel2Pdf(tableList, title); + + if (MessageBox.Show("数据库文档生成成功,是否打开文档", "提示信息", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes) + { + CmdHelper.Execute(fileName); + } + } + } + + ////使用实体层模板批量生成代码 + //private void menuItemBatchBuildEnityCode_Click(object sender, EventArgs e) + //{ + // SODatabase db = null; + // TreeNode node = tv.SelectedNode; + + // if (node.Tag is PDModel) + // { + // PDModel m = node.Tag as PDModel; + // db = SOConverter.ToSODatabase(m); + // } + // else + // { + // PDPackage p = node.Tag as PDPackage; + // db = SOConverter.ToSODatabase(p); + // } + + // BatchBuildEntityCode dialog = new BatchBuildEntityCode(db); + // dialog.ShowDialog(); + //} + + ////使用数据层模板批量生成代码 + //private void menuItemBatchBuildDALCode_Click(object sender, EventArgs e) + //{ + // SODatabase db = null; + // TreeNode node = tv.SelectedNode; + + // if (node.Tag is PDModel) + // { + // PDModel m = node.Tag as PDModel; + // db = SOConverter.ToSODatabase(m); + // } + // else + // { + // PDPackage p = node.Tag as PDPackage; + // db = SOConverter.ToSODatabase(p); + // } + + // BatchBuildDALCode dialog = new BatchBuildDALCode(db); + // dialog.ShowDialog(); + //} + + //批量生成代码 + + private void menuItemBatchBuildCode_Click(object sender, EventArgs e) + { + SODatabase db = null; + TreeNode node = tv.SelectedNode; + + if (node.Tag is PDModel) + { + PDModel m = node.Tag as PDModel; + db = SOConverter.ToSODatabase(m); + } + else + { + PDPackage p = node.Tag as PDPackage; + db = SOConverter.ToSODatabase(p); + } + + BatchBuildCode dialog = new BatchBuildCode(db); + dialog.Show(this.DockPanel); + } + + //使用自定义模板批量生成代码 + //private void menuItemBatchBuildCustomCode_Click(object sender, EventArgs e) + //{ + // SODatabase db = null; + // TreeNode node = tv.SelectedNode; + + // if (node.Tag is PDModel) + // { + // PDModel m = node.Tag as PDModel; + // db = SOConverter.ToSODatabase(m); + // } + // else + // { + // PDPackage p = node.Tag as PDPackage; + // db = SOConverter.ToSODatabase(p); + // } + + // BatchBuildCustomCode dialog = new BatchBuildCustomCode(db); + // dialog.ShowDialog(); + //} + + #endregion + + #region 表节点右键菜单事件处理 + + //代码生成器 + private void menuItemBuildCodeForTable_Click(object sender, EventArgs e) + { + TreeNode tn = tv.SelectedNode; + SOTable table = SOConverter.ToSOTable(tn.Tag as PDTable); + CodeBuilder builder = null; + + //保证代码生成器使用一个实例 + if (this.DockPanel.ActiveDocument != null && this.DockPanel.ActiveDocument is CodeBuilder) + { + builder = this.DockPanel.ActiveDocument as CodeBuilder; + builder.Table = table; + builder.ColumnList = table.ColumnList; + builder.LoadColumnList(); + } + else + { + builder = new CodeBuilder(); + builder.Table = table; + builder.ColumnList = table.ColumnList; + builder.LoadColumnList(); + builder.Show(this.DockPanel); + } + } + + #endregion + } +} diff --git a/src/Kalman.Studio/ExplorerForm/PdmExplorer/PdmExplorer.designer.cs b/src/Kalman.Studio/ExplorerForm/PdmExplorer/PdmExplorer.designer.cs new file mode 100644 index 0000000..1e33786 --- /dev/null +++ b/src/Kalman.Studio/ExplorerForm/PdmExplorer/PdmExplorer.designer.cs @@ -0,0 +1,214 @@ +namespace Kalman.Studio +{ + partial class PdmExplorer + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(PdmExplorer)); + this.tv = new System.Windows.Forms.TreeView(); + this.imgList = new System.Windows.Forms.ImageList(this.components); + this.cms = new System.Windows.Forms.ContextMenuStrip(this.components); + this.menuItemLoadFile = new System.Windows.Forms.ToolStripMenuItem(); + this.cmsFile = new System.Windows.Forms.ContextMenuStrip(this.components); + this.menuItemRemoveFile = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemReload = new System.Windows.Forms.ToolStripMenuItem(); + this.cmsModel = new System.Windows.Forms.ContextMenuStrip(this.components); + this.menuItemBrowserModel = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemBuildWord = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemBuildPdf = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemBatchBuildCode = new System.Windows.Forms.ToolStripMenuItem(); + this.saveFileDialog1 = new System.Windows.Forms.SaveFileDialog(); + this.cmsTable = new System.Windows.Forms.ContextMenuStrip(this.components); + this.menuItemBuildCodeForTable = new System.Windows.Forms.ToolStripMenuItem(); + this.cms.SuspendLayout(); + this.cmsFile.SuspendLayout(); + this.cmsModel.SuspendLayout(); + this.cmsTable.SuspendLayout(); + this.SuspendLayout(); + // + // tv + // + this.tv.Dock = System.Windows.Forms.DockStyle.Fill; + this.tv.HotTracking = true; + this.tv.ImageIndex = 8; + this.tv.ImageList = this.imgList; + this.tv.ItemHeight = 18; + this.tv.Location = new System.Drawing.Point(0, 0); + this.tv.Name = "tv"; + this.tv.SelectedImageIndex = 8; + this.tv.ShowNodeToolTips = true; + this.tv.Size = new System.Drawing.Size(239, 489); + this.tv.TabIndex = 4; + this.tv.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.tv_MouseDoubleClick); + this.tv.MouseClick += new System.Windows.Forms.MouseEventHandler(this.tv_MouseClick); + // + // imgList + // + this.imgList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imgList.ImageStream"))); + this.imgList.TransparentColor = System.Drawing.Color.Transparent; + this.imgList.Images.SetKeyName(0, "pd.ico"); + this.imgList.Images.SetKeyName(1, "pdm.ICO"); + this.imgList.Images.SetKeyName(2, "bigdb.ICO"); + this.imgList.Images.SetKeyName(3, "package.ICO"); + this.imgList.Images.SetKeyName(4, "folder.ICO"); + this.imgList.Images.SetKeyName(5, "table.ICO"); + this.imgList.Images.SetKeyName(6, "column.ICO"); + this.imgList.Images.SetKeyName(7, "key.ICO"); + this.imgList.Images.SetKeyName(8, "index.ICO"); + // + // cms + // + this.cms.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.menuItemLoadFile}); + this.cms.Name = "cms"; + this.cms.Size = new System.Drawing.Size(125, 26); + // + // menuItemLoadFile + // + this.menuItemLoadFile.Name = "menuItemLoadFile"; + this.menuItemLoadFile.Size = new System.Drawing.Size(124, 22); + this.menuItemLoadFile.Text = "加载文件"; + this.menuItemLoadFile.Click += new System.EventHandler(this.menuItemLoadFile_Click); + // + // cmsFile + // + this.cmsFile.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.menuItemRemoveFile, + this.menuItemReload}); + this.cmsFile.Name = "cmsFile"; + this.cmsFile.Size = new System.Drawing.Size(125, 48); + // + // menuItemRemoveFile + // + this.menuItemRemoveFile.Name = "menuItemRemoveFile"; + this.menuItemRemoveFile.Size = new System.Drawing.Size(124, 22); + this.menuItemRemoveFile.Text = "移除文件"; + this.menuItemRemoveFile.Click += new System.EventHandler(this.menuItemRemoveFile_Click); + // + // menuItemReload + // + this.menuItemReload.Name = "menuItemReload"; + this.menuItemReload.Size = new System.Drawing.Size(124, 22); + this.menuItemReload.Text = "重新加载"; + this.menuItemReload.Click += new System.EventHandler(this.menuItemReload_Click); + // + // cmsModel + // + this.cmsModel.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.menuItemBrowserModel, + this.menuItemBuildWord, + this.menuItemBuildPdf, + this.menuItemBatchBuildCode}); + this.cmsModel.Name = "cmsModel"; + this.cmsModel.Size = new System.Drawing.Size(158, 114); + // + // menuItemBrowserModel + // + this.menuItemBrowserModel.Name = "menuItemBrowserModel"; + this.menuItemBrowserModel.Size = new System.Drawing.Size(157, 22); + this.menuItemBrowserModel.Text = "浏览模型"; + this.menuItemBrowserModel.Click += new System.EventHandler(this.menuItemBrowserModel_Click); + // + // menuItemBuildWord + // + this.menuItemBuildWord.Name = "menuItemBuildWord"; + this.menuItemBuildWord.Size = new System.Drawing.Size(157, 22); + this.menuItemBuildWord.Text = "生成Word文档"; + this.menuItemBuildWord.Click += new System.EventHandler(this.menuItemBuildWord_Click); + // + // menuItemBuildPdf + // + this.menuItemBuildPdf.Name = "menuItemBuildPdf"; + this.menuItemBuildPdf.Size = new System.Drawing.Size(157, 22); + this.menuItemBuildPdf.Text = "生成Pdf文档"; + this.menuItemBuildPdf.Click += new System.EventHandler(this.menuItemBuildPdf_Click); + // + // menuItemBatchBuildCode + // + this.menuItemBatchBuildCode.Name = "menuItemBatchBuildCode"; + this.menuItemBatchBuildCode.Size = new System.Drawing.Size(157, 22); + this.menuItemBatchBuildCode.Text = "批量生成代码"; + this.menuItemBatchBuildCode.Click += new System.EventHandler(this.menuItemBatchBuildCode_Click); + // + // saveFileDialog1 + // + this.saveFileDialog1.Filter = "pdf文件(*.pdf)|*.pdf|所有文件(*.*)|*.*"; + // + // cmsTable + // + this.cmsTable.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.menuItemBuildCodeForTable}); + this.cmsTable.Name = "cmsTable"; + this.cmsTable.Size = new System.Drawing.Size(137, 26); + // + // menuItemBuildCodeForTable + // + this.menuItemBuildCodeForTable.Name = "menuItemBuildCodeForTable"; + this.menuItemBuildCodeForTable.Size = new System.Drawing.Size(136, 22); + this.menuItemBuildCodeForTable.Text = "代码生成器"; + this.menuItemBuildCodeForTable.Click += new System.EventHandler(this.menuItemBuildCodeForTable_Click); + // + // PdmExplorer + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(239, 489); + this.Controls.Add(this.tv); + this.DockAreas = ((WeifenLuo.WinFormsUI.Docking.DockAreas)((WeifenLuo.WinFormsUI.Docking.DockAreas.DockLeft | WeifenLuo.WinFormsUI.Docking.DockAreas.DockRight))); + this.HideOnClose = true; + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "PdmExplorer"; + this.Text = "PDM模型对象浏览器"; + this.Load += new System.EventHandler(this.PdmExplorer_Load); + this.cms.ResumeLayout(false); + this.cmsFile.ResumeLayout(false); + this.cmsModel.ResumeLayout(false); + this.cmsTable.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.TreeView tv; + private System.Windows.Forms.ContextMenuStrip cms; + private System.Windows.Forms.ToolStripMenuItem menuItemLoadFile; + private System.Windows.Forms.ContextMenuStrip cmsFile; + private System.Windows.Forms.ToolStripMenuItem menuItemRemoveFile; + private System.Windows.Forms.ToolStripMenuItem menuItemReload; + private System.Windows.Forms.ContextMenuStrip cmsModel; + private System.Windows.Forms.ToolStripMenuItem menuItemBrowserModel; + private System.Windows.Forms.ToolStripMenuItem menuItemBuildWord; + private System.Windows.Forms.ToolStripMenuItem menuItemBuildPdf; + private System.Windows.Forms.SaveFileDialog saveFileDialog1; + private System.Windows.Forms.ToolStripMenuItem menuItemBatchBuildCode; + private System.Windows.Forms.ContextMenuStrip cmsTable; + private System.Windows.Forms.ToolStripMenuItem menuItemBuildCodeForTable; + private System.Windows.Forms.ImageList imgList; + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/ExplorerForm/PdmExplorer/PdmExplorer.resx b/src/Kalman.Studio/ExplorerForm/PdmExplorer/PdmExplorer.resx new file mode 100644 index 0000000..139df04 --- /dev/null +++ b/src/Kalman.Studio/ExplorerForm/PdmExplorer/PdmExplorer.resx @@ -0,0 +1,353 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 528, 17 + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj0yLjAuMC4w + LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 + ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAC+ + KgAAAk1TRnQBSQFMAgEBCQEAARQBAAEUAQABEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA + AwABMAMAAQEBAAEgBgABMP8A/wAcAAHeAYEBWAH/AcIBgQFNAf8BnwFvAUYB/wQAAd4BgQFYAf8BwgGB + AU0B/wGfAW8BRgH/BAAB3gGBAVgB/wHCAYEBTQH/AZ8BbwFGAf/UAAH/AZcBgQH/AfgB4gHUAf8BwgGB + AUwB/wQAAf8BlwGBAf8B+AHiAdQB/wHCAYEBTAH/BAAB/wGXAYEB/wH4AeIB1AH/AcIBgQFMAf/UAAH/ + AbABhQL/AaABgQH/Ad4BgQFYAf8EAAH/AbABhQL/AaABgQH/Ad4BgQFYAf8EAAH/AbABhQL/AaABgQH/ + Ad4BgQFYAf/YAAGXAoEB/wwAAoEBcQH/DAABgQFtAVkB/9wAAZ0BhwGBAf8MAAKBAXgB/wwAAYEBcQFd + Af/cAAGkAY0BgQH/DAABhwGBAYAB/wwAAYEBdgFjAf/cAAGqAZQBhQH/AaMBjAGBAf8BnAGFAYEB/wGV + AoEB/wGNAoEB/wGGAYEBgAH/AoEBdgH/AoEBbwH/AYEBfAFoAf/sAAGUAoEB//wAAZoBgwGBAf/4AAHe + AYEBWAH/AcIBgQFNAf8BnwFvAUYB//QAAf8BlwGBAf8B+AHiAdQB/wHCAYEBTAH/9AAB/wGwAYUC/wGg + AYEB/wHeAYEBWAH//wD/AP8AuwABRwF3AY4B/wFHAW4BggH/oAABtwGiAZMB/wGBAWsBVwH/AYEBawFX + Af8BgQFrAVcB/wGBAWsBVwH/AYEBawFXAf8BgQFrAVcB/wGBAWsBVwH/AYEBawFXAf8BgQFrAVcB/wGB + AWsBVwH/AYEBawFXAf8kAAE7AYYBrAH/AS4BnwHPAf8BOAF1AY8B/xwAAYEBhAGPAf8CgQGFAf8DgQH/ + AXMCgQH/AWQBbgF2Af8BUwFcAWMB/wFFAUwBUgH/ATgBPgFDAf8BMAE1AToB/wEwATUBOgH/ATABNQE6 + Af8BMAE1AToB/wEwATUBOgH/ATABNQE6Af8BMAE1AToB/wgAAbcBogGTAf8BgQFrAVcB/wGBAWsBVwH/ + AYEBawFXAf8BgQFrAVcB/wGBAWsBVwH/AYEBawFXAf8BgQFrAVcB/wGBAWsBVwH/AYEBawFXAf8BgQFr + AVcB/wGBAWsBVwH/AYEBawFXAf8BgQFrAVcB/wgAAbcBogGTAv8B+gH3Af8B6QHhAd0B/wHpAd0B2AH/ + AekB2QHRAf8B6QHVAcsB/wHpAdEBxQH/AekBzgG/Af8B6QHJAbkB/wHpAcYBtAH/AekBxAGwAf8BgQFr + AVcB/yQAAUcBhgGnAf8BRwGxAekB/wEEAZYB2QH/AVIBdAGGAf8YAAGBAYcBkgH/AaIB3wHwAf8BgQHN + AeoB/wFrAbgB4gH/AVkBrgHbAf8BTwGpAdkB/wFIAaEB0gH/AUMBmAHHAf8BQgGOAbwB/wFAAYMBrgH/ + ATsBgQGrAf8BNwGBAakB/wE9AYEBnwH/AUEBgQGWAf8BOAE+AUMB/wgAAbcBogGTAf8B2QHLAcIB/wHO + Ab0BsQH/AcsBuQGtAf8ByAG1AakB/wHFAbIBpQH/AcIBrgGhAf8BvwGsAZ4B/wG9AagBmgH/AbsBpgGX + Af8BuQGkAZUB/wG3AaIBkwH/AbcBogGTAf8BgQFrAVcB/wgAAbcBogGTAv8C/QH/AbYBqAGgAf8BtgGo + AaAB/wG2AagBoAH/AbYBqAGgAf8BtgGoAaAB/wG2AagBoAH/AbYBqAGgAv8B3gHNAf8B6QHGAbUB/wGB + AWsBVwH/JAABSwGIAaoB/wFIAbEB6QH/AVIBdAGGAf8BKwGBAaQB/xgAAYEBigGVAf8BqgHoAfYB/wGV + AeUB/AH/AYQB3wH7Af8BgQHWAfoB/wGBAdAB9wH/AYEBxgH0Af8BcgG+AfAB/wFjAbQB7AH/AVcBqgHo + Af8BTQGkAeYB/wFCAZoB3wH/ATgBkAHXAf8BPQGBAZ8B/wFCAUkBTwH/CAABtwGiAZMB/wP+Af8D/gH/ + Af0B+wH6Af8BywG5Aa0B/wH8AfIB7QH/AfsB7QHkAf8B+gHnAdwB/wG/AasBnQH/AfcB2wHKAf8B9gHV + AcAB/wH1Ac8BtwH/AbcBogGTAf8BgQFrAVcB/wgAAbcBogGTBv8B/gH9Av8B+wH5Av8B+AH0Av8B9AHv + Av8B8AHoAv8B6wHhAv8B5wHbAv8B4gHUAf8B6QHLAbwB/wGBAWsBVwH/JAABTQGMAa0B/wFIAbEB6QH/ + AQQBgwG3Af8BTgF5AY4B/xgAAYEBjgGYAf8BsAHqAfYB/wGfAekB+wH/AZIB5AH8Af8BgQHdAfsB/wGB + AdYB+gH/AYEBzgH3Af8BgQHGAfQB/wFvAbwB8AH/AWMBtAHsAf8BVwGqAegB/wFMAaMB5gH/AT8BlgHc + Af8BNwGBAakB/wFPAVYBXQH/CAABtwGiAZMB/wP+Af8D/gH/A/4B/wHOAbwBsAH/Af0B9wHzAf8B/AHy + AewB/wH7Ae0B5QH/AcIBrgGhAf8B+QHhAdMB/wH3AdsBygH/AfUB1QHAAf8BuQGkAZUB/wGBAWsBVwH/ + CAABtwGiAZMF/wG2AagBoAH/AbYBqAGgAf8BtgGoAaAB/wG2AagBoAH/AbYBqAGgAf8BtgGoAaAB/wG2 + AagBoAH/AbYBqAGgAf8B6QHPAcMB/wGBAWsBVwH/JAABUQGPAbEB/wFIAbIB6QH/AQQBnAHfAf8BSAF1 + AYsB/xgAAYEBkQGcAf8BtgHtAfgB/wGqAewB+wH/AZsB6AH7Af8BjwHjAfwB/wGBAd0B+wH/AYEB1QH5 + Af8BgQHOAfcB/wF9AcUB9AH/AW8BvAHwAf8BXwGyAewB/wFUAakB6AH/AUYBngHiAf8BMgGCAbQB/wFd + AWUBbQH/CAABtwGiAZMB/wHgAdMBygH/AdcBxgG8Af8B1AHDAbgB/wHRAcABtQH/Ac4BvQGxAf8BywG5 + AawB/wHIAbYBqQH/AcUBsgGlAf8BwgGvAaEB/wG/AawBnQH/Ab0BqQGaAf8BugGmAZcB/wGBAWsBVwH/ + CAABugGlAZYO/wL+Av8B/QH6Av8B+QH2Av8B9QHwAv8B8QHqAv8B7QHkAf8B6QHUAcoB/wGBAWsBVwH/ + JAABUwGTAbQB/wFIAbIB6gH/AUMBYwF3Af8cAAGDAZUBnwH/Ab4B8AH5Af8BqwHwAfcB/wGlAewB+wH/ + AZgB5wH7Af8BiQHhAfwB/wGBAd0B+wH/AYEB1QH5Af8BgQHNAfcB/wF6AcQB8wH/AW0BuwHwAf8BXwGy + AewB/wFOAaQB4wH/AS4BigG/Af8BawF1AYAB/wgAAboBpQGWAf8D/gH/A/4B/wP+Af8B1QHEAbkB/wP+ + Af8B/QH7AfoB/wH8AfcB9AH/AcgBtgGpAf8B+wHuAeQB/wH6AecB3AH/AfkB4gHTAf8BvQGoAZoB/wGB + AWsBVwH/CAABvgGpAZoF/wGFAoEB/wGFAoEB/wGFAoEB/wGFAoEB/wGFAoEB/wGFAoEB/wGFAoEC/wHy + AewB/wHpAdkB0gH/AYEBawFXAf8cAAFTAaYBywH/AVcBngHBAf8BVwGXAbcB/wFIAbMB7AH/AUMBYwF3 + Af8BOwGCAaYB/wEuAYIBrAH/FAABhgGZAaMB/wG+AfAB+QH/AbYB7QH4Af8BsAHuAfoB/wGkAesB+gH/ + AZUB5gH7Af8BiQHhAfwB/wGBAdwB/AH/AYEB1QH5Af8BgQHNAfcB/wF6AcQB8wH/AWsBuQHvAf8BVwGp + AecB/wEuAY8BxwH/AXkCgQH/CAABvgGpAZoB/wP+Af8D/gH/A/4B/wHXAccBuwH/A/4B/wP+Af8B/QH7 + AfoB/wHLAbkBrAH/AfsB8wHtAf8B+gHtAeUB/wH6AecB3AH/Ab8BqwGdAf8BgQFrAVcB/wgAAcMBrgGe + Gv8C/QL/AfoB+AL/AfcB8wH/AekB3wHZAf8BgQFrAVcB/xgAAWQBrwHRAf8BbQGmAcIB/wFZAaIBxAH/ + AXcB1AH7Af8BBgGoAekB/wEEAZQBzwH/AUMBYwF3Af8BPwGBAZ0B/wEtAYEBqQH/EAABiQGcAaYB/wG+ + AfAB+QH/AbYB7QH4Af8BtgHtAfgB/wGrAfAB9wH/AaIB7AH6Af8BlQHmAfsB/wGJAeEB/AH/AYEB3AH8 + Af8BgQHTAfoB/wGBAcwB9wH/AXcBwwHzAf8BawG5Ae8B/wE7AZkBzwH/A4EB/wgAAcMBrgGeAf8B5AHY + AdAB/wHdAc4BxQH/AdwBzAHBAf8B2QHJAb8B/wHXAccBvAH/AdQBxAG4Af8B0QHAAbQB/wHOAb0BsQH/ + AcsBuQGsAf8ByAG1AakB/wHFAbIBpQH/AcIBrgGgAf8BgQFrAVcB/wgAAcgBsgGjBf8BtgGoAaAB/wG2 + AagBoAH/AbYBqAGgAf8BtgGoAaAB/wG2AagBoAH/AbYBqAGgAf8BtgGoAaAB/wG2AagBoAH/AekB4wHf + Af8BgQFrAVcB/xgAAXYBsAHMAf8BZAGtAc4B/wF3AdcC/wESAa8B7AH/ASsBtQHrAf8BBAGkAeYB/wEE + AZQBzwH/AUMBYwF3Af8BOAGBAaEB/xAAAYsBoAGoAf8BvgHwAfkB/wG+AfAB+QH/Ab4B8AH5Af8BvgHw + AfkB/wG0AfIB+AH/AaoB7AH7Af8BoAHpAfsB/wGVAeUB/AH/AYoB3wH8Af8BgQHYAfsB/wGBAdIB+AH/ + AYEBygH0Af8BgQHAAfEB/wOBAf8IAAHIAbIBowH/A/4B/wP+Af8D/gH/AdsBzAHBAf8D/gH/A/4B/wP+ + Af8B0QHAAbQB/wH9AfsB+QH/Af0B9wH0Af8B/AHzAe0B/wHFAbIBpQH/AYEBawFXAf8IAAHMAbYBpyL/ + Av4C/wH7AfoB/wGBAWsBVwH/GAABhQGvAcUB/wG/AewB/QH/AT4BxAH5Af8BKwG1AesB/wE+AcQB+QH/ + AT4BxAH5Af8BBQGnAecB/wEEAZMBzQH/AVsBeQGIAf8QAAGNAaEBqgH/AY0BoQGqAf8BjQGhAaoB/wGN + AaEBqgH/AY0BoQGqAf8BiwGfAagB/wGJAZwBpgH/AYkBmwGmAf8BhwGaAaQB/wGGAZkBowH/AYQBlgGg + Af8BhAGWAaAB/wGDAZUBoAH/AYMBlQGgAf8BgQGEAY8B/wgAAcwBtgGnAf8D/gH/A/4B/wP+Af8B3QHO + AcUB/wP+Af8D/gH/A/4B/wHUAcQBuAH/A/4B/wH9AfsB+gH/Af0B9wHzAf8ByAG1AagB/wGBAWwBWAH/ + CAAB6gGqAYsB/wHqAaoBiwH/AegBpgGGAf8B5gGhAYEB/wHjAZoBgQH/AeEBkwGBAf8B3QGMAYEB/wHa + AYMBewH/AdcBgQFxAf8B0wGBAWcB/wHRAYEBXwH/Ac8BgQFYAf8YAAGVAawBvgH/AcEB7gL/AXIB1wL/ + ASkBpAHXAf8BcwGWAa0B/wE+AcQB+QH/AQUBpwHnAf8BBAGTAc0B/wFbAXgBiAH/EAABjwGkAawB/wGy + AeQB7AH/AbYB7QH4Af8BtgHtAfgB/wGpAewB9gH/AZIB4QHzAf8BjQGhAaoB/wFEAW0BgAH/JAAB6gGq + AYsB/wHqAaoBiwH/AeoBqgGLAf8B6QGlAYQB/wHpAZ8BgQH/AecBlwGBAf8B5gGOAYEB/wHlAYYBeAH/ + AeMBgQFsAf8B4wGBAWIB/wHiAYEBWwH/AeIBgQFbAf8B4gGBAVsB/wHIAYEBUQH/CAAB6gGqAYsC/wHC + AaIC/wHCAaIB/wH9Ab4BnAH/AfwBuAGTAf8B+gGvAYkB/wH4AacBgQH/AfYBoAGBAf8B9AGaAYEB/wHz + AZUBgQH/AfMBlQGBAf8BzgGBAVgB/xgAAY0BswHHAf8B0gH3Av8BcgHXAf4B/wE6AWsBhgH/AW8BoQG8 + Af8BgQGfAbQB/wERAaYB5AH/AQQBlQHQAf8BTwGBAZsB/xAAAYEBiAGTAf8BjwGkAawB/wGPAaQBrAH/ + AY8BpAGsAf8BjwGkAawB/wGPAaQBrAH/AUQBbQGAAf8oAAHqAaoBiwL/AcIBogH/Af4BwAGfAf8B/QG9 + AZoB/wH8AbkBlgH/AfsBtQGQAf8B+gGwAYsB/wH5AasBhAH/AfgBpwGBAf8B9gGiAYEB/wH1AZ0BgQH/ + AfUBmQGBAf8B8wGVAYEB/wHNAYEBUwH/CAAB6gGqAYsB/wHqAaoBiwH/AegBpgGGAf8B5gGgAYEB/wHj + AZoBgQH/AeABkwGBAf8B3QGMAYEB/wHaAYQBewH/AdcBgQFxAf8B1AGBAWcB/wHQAYEBXwH/Ac8BgQFZ + Af8YAAGJAbsB0AH/AdIB9wL/AaIB4wH+Af8BKQGkAdcB/wE6AWsBhgH/ARwBrgHnAf8BKAGkAdcB/wFA + AZMBugH/AUMBigGtAf9UAAHqAaoBiwH/AeoBqgGLAf8B6gGqAYsB/wHqAaoBiwH/AeoBpgGGAf8B6QGh + AYEB/wHoAZsBgQH/AecBlAGBAf8B5gGOAYEB/wHlAYcBegH/AeQBgQFwAf8B5AGBAWgB/wHjAYEBYAH/ + AeIBgQFbAf9QAAGMAcQB1wH/AYsBuAHMAf8B0gH3Av8B0gH3Av8BogHkAv8BSAG3AfAB/wFPAZ0BwAH/ + AVQBkgGwAf8BOwGSAbsB/+AAAYoBxAHXAf8BhwG7AdAB/wGJAbABxAH/AYwBpgG4Af8BeAGeAbUB/wFd + AZ4BvgH/AUgBnQHDAf90AAGrAToBMAH/AagBNQErAf8BqAE1ASsB/wGoATUBKwH/AagBNQErAf8BqgE6 + AS8B/wGpATcBLQH/EAABTwGaAbsB/wFeAZcBsgH/AWIBjgGlAf8BXQGBAZgB/wFQAXcBigH/AUsBcgGH + Af8BQgF2AY8B/wE2AXkBlwH/AS4BewGfAf8BKQGAAaMB/xgAAU8BmgG7Af8BXgGXAbIB/wFiAY4BpQH/ + AV0BgQGYAf8BUAF3AYoB/wFQAXcBigH/AUsBcgGHAf8BQgF2AY8B/wE2AXkBlwH/AS4BewGfAf8BKQGA + AaMB/2gAAbQBTgFBAf8B+AHwAdAC/wHuAeYC/wHoAd0C/wHjAdQC/wHcAcoB/wGoATUBKwH/DAABTgGV + AbcB/wFXAY0BqQH/AWIBowG/Af8BgAHAAdQB/wGVAdkB5gH/AYEB2wHwAf8BVgHGAewB/wEqAaoB3QH/ + ARwBkgHHAf8BKAGBAawB/wE3AXEBjgH/ASsBdgGYAf8QAAFOAZUBtwH/AVcBjQGpAf8BYgGjAb8B/wGA + AcAB1AH/AZUB2QHmAf8BgQHbAfAB/wGBAdsB8AH/AVYBxgHsAf8BKgGqAd0B/wEcAZIBxwH/ASgBgQGs + Af8BNwFxAY4B/wErAXYBmAH/CAACAwGQAf8CAwGQAf8CAwGQAf8CAwGQAf8CAwGQAf8UAAJTAXQB/wJT + AXQB/wJTAXQB/wJTAXQB/wJTAXQB/yAAAcEBZwFXAf8B+AHwAdAB/wH+AfMB7QH/Af4B7gHmAf8B/QHo + Ad0B/wH9AeIB1AH/AagBNQErAf8MAAFgAYQBmwH/AUoBvQHnAf8BbQHTAfEB/wGMAeMB9AH/AaIB6wH2 + Af8BgwHfAfQB/wFWAcoB8AH/ASQBtgHtAf8BCAGnAegB/wEHAaEB4QH/AQ8BlgHSAf8BQwFkAYEB/xAA + AWABhAGbAf8BSgG9AecB/wFtAdMB8QH/AYwB4wH0Af8BogHrAfYB/wGDAd8B9AH/AYMB3wH0Af8BVgHK + AfAB/wEkAbYB7QH/AQgBpwHoAf8BBwGhAeEB/wEPAZYB0gH/AUMBZAGBAf8EAAIDAZAB/wIDAZAB/wEr + ASoB0QH/ASsBKgHRAf8BKwEqAdEB/wIDAZAB/wIDAZAB/xAAAlMBdAH/AVMByQL/AVMB5AL/AVMBrQL/ + AlMBdAH/DAABswFKAToB/wGzAUkBOQH/AbMBSQE5Af8BswFJATkB/wGyAUgBOAH/Ac4BgQFtAf8B+AHw + AdAB/wH4AfAB0AH/AfgB8AHQAf8B+AHwAdAB/wH4AfAB0AH/AagBNQErAf8MAAFjAYcBngH/AUkBxAHw + Af8BbwHUAfEB/wGMAeMB9AH/AaIB6wH2Af8BgwHfAfQB/wFWAcoB8AH/ASQBtgHtAf8BCAGoAegB/wEH + AaEB4QH/AQkBnAHaAf8BRAFlAYEB/xAAAWMBhwGeAf8BSQHEAfAB/wHPAWoBNAH/AboBYAEuAf8BpQFW + ASsB/wGTAU0BKAH/AYMB3wH0Af8BzwFqATQB/wG6AWABLgH/AaUBVgErAf8BkwFNASgB/wEJAZwB2gH/ + AUQBZQGBAf8EAAIDAZAB/wErASoB0QH/ASsBKgHRAf8CUwL/AlMC/wErASoB0QH/AgMBkAH/EAACUwF0 + Af8BUwHJAv8BUwHkAv8BUwGtAv8CUwF0Af8MAAGzAUkBOQH/AcgBhQGBAf8MAAHSAYEBPgH/AdABgQEq + Af8B0AGBASoB/wHQAYEBKgH/AdABgQEqAf8B0AGBASoB/wHHAXABKgH/DAABZQGJAaAB/wFJAcQB7wH/ + AW4B1AHxAf8BjQHjAfQB/wGiAesB9gH/AYIB3wHzAf8BVwHKAfAB/wEkAbYB7QH/AQgBqAHoAf8BCAGh + AeEB/wEJAZwB2gH/AUYBaAGBAf8QAAFlAYkBoAH/AUkBxAHvAv8BrAGBAf8B8wHYAcwB/wHwAc4BvgH/ + AaUBVQErAf8BggHfAfMC/wGsAYEB/wHzAdgBzAH/AfABzgG+Af8BpQFVASsB/wEJAZwB2gH/AUYBaAGB + Af8EAAIDAZAB/wErASoB0QH/AlMC/wJTAv8CUwL/AlMC/wIDAZAB/xAAAlMBdAH/AVMByQL/AVMB5AL/ + AVMBrQL/AlMBdAH/DAABvgFaAUQB/xAAAfsBtAFcAf8B0AGBASoB/wHQAYEBKgH/AdABgQEqAf8B0AGB + ASoB/wHQAYEBKgH/AfsBtAFcAf8MAAFnAYwBogH/AUsBxgHwAf8BcAHUAfEB/wGMAeMB9AH/AaIB6wH2 + Af8BggHfAfQB/wFXAcoB8AH/ASQBtgHtAf8BCAGoAegB/wEHAaIB4gH/AQoBmwHbAf8BSAFrAYEB/xAA + AWcBjAGiAf8BSwHGAfAC/wG0AYsC/wGoAYEC/wGbAWwB/wH3AY4BXwH/AYIB3wH0Av8BtAGLAv8BqAGB + Av8BmwFsAf8B9wGOAV8B/wEKAZsB2wH/AUgBawGBAf8EAAIDAZAB/wJTAv8CUwL/AlMC/wFtAWwB/QH/ + AW0BbAH9Af8CAwGQAf8CdAFTAf8CdAFTAf8CdAFTAf8CdAFTAf8CUwF0Af8BUwHJAv8BUwHkAv8BUwGt + Av8CUwF0Af8MAAHDAWgBUwH/OAABagGPAaUB/wFMAcYB8AH/AXAB1AHyAf8BjQHjAfQB/wGiAesB9gH/ + AYMB3wH0Af8BVgHKAfAB/wEkAbYB7QH/AQcBpwHoAf8BBwGhAeIB/wEJAZwB2wH/AUoBbgGDAf8QAAFq + AY8BpQH/AUwBxgHwAf8BcAHUAfIB/wGNAeMB9AH/AZcBgQF1Af8BgwHfAfQB/wGDAd8B9AH/AVYBygHw + Af8BcAFVAUEB/wEHAacB6AH/AQcBoQHiAf8BCQGcAdsB/wFKAW4BgwH/BAACAwGQAf8CAwGQAf8BbQFs + Af0B/wFtAWwB/QH/AckBrQL/AgMBkAH/AU0BhAGBAf8BdAGvAWoB/wF0Aa8BagH/AXQBrwFqAf8BdAGd + AWMB/wJTAXQB/wFTAckC/wFTAeQC/wFTAa0C/wJTAXQB/wQAAboBUwE+Af8B2wGaAYoB/wHIAXQBYAH/ + AdsBmgGKAf8BsQFGATcB/wgAA+AB/wOvAf8DpAH/A5gB/wONAf8DgQH/A4EB/wPUAf8IAAFrAZIBqAH/ + AUwBxQHwAf8BcQHUAfIB/wGNAeMB9AH/AaIB6wH2Af8BggHfAfQB/wFWAcoB8AH/ASQBtgHtAf8BBwGn + AegB/wEHAaEB4QH/AQkBnAHbAf8BTAFxAYYB/xAAAWsBkgGoAf8BTAHFAfAB/wFxAdQB8gH/AY0B4wH0 + Af8BpAGOAYEB/wGXAYEBdQH/AYoBeAFmAf8BgQFrAVgB/wF4AV8BTAH/AQcBpwHoAf8BBwGhAeEB/wEJ + AZwB2wH/AUwBcQGGAf8IAAIDAZAB/wIDAZAB/wIDAZAB/wIDAZAB/wFQAYEBcQH/AXQBrwFqAf8BdAHJ + AXQB/wF0AckBdAH/AXQByQF0Af8BdAGvAWoB/wJTAXQB/wFTAckC/wFTAeQC/wFTAa0C/wJTAXQB/wgA + Ab0BVwFCAf8BvQFXAUEB/wGxAUUBNQH/DAADoAH/A8YB/wPZAf8D0gH/A8AB/wOjAf8DhQH/A3QB/wgA + AW4BlQGrAf8BTAHFAfAB/wFxAdQB8gH/AY0B4wH0Af8BogHrAfYB/wGDAd8B9AH/AVcBywHwAf8BJAG1 + Ae0B/wEIAacB6AH/AQcBoQHiAf8BCgGcAdoB/wFPAXQBiAH/EAABbgGVAasB/wFMAcUB8AH/AXEB1AHy + Af8BjQHjAfQB/wGiAesB9gH/AYMB3wH0Af8BlwGBAXUB/wFXAcsB8AH/ASQBtQHtAf8BCAGnAegB/wEH + AaEB4gH/AQoBnAHaAf8BTwF0AYgB/xgAAnQBUwH/AXQBrwFqAf8BdAHJAXQB/wF0AckBdAH/AVMByQGt + Af8BUwH/Aa0B/wJTAXQB/wFTAckC/wFTAeQC/wFTAa0C/wJTAXQB/wwAAbsBVAE/Af8QAAOiAf8DwgH/ + A9EB/wPFAf8DtAH/A5wB/wODAf8DcQH/CAABcAGYAa4B/wFMAcUB8AH/AXEB1AHxAf8BjQHjAfQB/wGi + AesB9gH/AYMB3wH0Af8BVwHKAfAB/wEkAbYB7QH/AQgBqAHpAf8BBwGhAeEB/wEJAZwB2gH/AVEBdgGK + Af8QAAFwAZgBrgH/AUwBxQHwAf8BcQHUAfEB/wGNAeMB9AH/Ad4BdAE8Af8BzwFqATQB/wG6AWABLgH/ + AaUBVgErAf8BkwFNASgB/wEIAagB6QH/AQcBoQHhAf8BCQGcAdoB/wFRAXYBigH/GAACdAFTAf8BXQGb + AWsB/wF0AckBdAH/AVMByQGtAf8BUwH/Aa0B/wFkAY8BZAH/AlMBdAH/AVMB5AL/Aa0D/wFTAeQC/wJT + AXQB/wGrAToBMAH/AagBNQErAf8BqAE1ASsB/wGoATUBKwH/AagBNQErAf8BqgE6AS8B/wGpATcBLQH/ + BAADpAH/A7YB/wO3Af8DqwH/A54B/wOLAf8DgQH/A3IB/wgAAXMBmwGwAf8BSwHGAfAB/wFxAdQB8gH/ + AY0B4wH0Af8BogHrAfYB/wGDAd8B9AH/AVcBygHwAf8BJAG2Ae0B/wEIAagB6AH/AQgBoQHhAf8BCQGc + AdoB/wFUAXoBjgH/EAABcwGbAbAB/wFLAcYB8AH/AXEB1AHyAf8BjQHjAfQC/wGkAXkB/wH3AeMB2wH/ + AfMB2AHMAf8B8AHOAb4B/wGlAVUBKwH/AQgBqAHoAf8BCAGhAeEB/wEJAZwB2gH/AVQBegGOAf8cAAJ0 + AVMB/wF0Aa8BagH/AVMB/wGtAf8BdAP/AnQBUwH/AlMBdAH/AlMBdAH/AlMBdAH/AlMBdAH/AlMBdAH/ + AbQBTgFBAf8B+AHwAdAC/wHuAeYC/wHoAd0C/wHjAdQC/wHcAcoB/wGoATUBKwH/BAADpwH/A8oB/wPe + Af8D0gH/A8AB/wOlAf8DiAH/A3UB/wgAAXYBnwGzAf8BSwHGAfAB/wFvAdQB8QH/AYwB4wH0Af8BogHr + AfYB/wGDAd8B9AH/AVcBygHwAf8BJAG2Ae0B/wEIAacB6AH/AQcBoQHhAf8BCQGbAdoB/wFWAX0BkAH/ + EAABdgGfAbMB/wFLAcYB8AH/AW8B1AHxAf8BjAHjAfQC/wGsAYEB/wH8AfQB8AH/AfkB6gHjAf8B9QHe + AdMB/wG6AV8BLgH/AQgBpwHoAf8BBwGhAeEB/wEJAZsB2gH/AVYBfQGQAf8cAAJ0AVMB/wFdAZsBawH/ + AXQD/wFdAZsBawH/AnQBUwH/FAABwQFnAVcB/wH4AfAB0AH/Af4B8wHtAf8B/gHuAeYB/wH9AegB3QH/ + Af0B4gHUAf8BqAE1ASsB/wQAA6wB/wO6Af8DvQH/A7EB/wOjAf8DkAH/A4EB/wOAAf8IAAF3AaEBtQH/ + AXEB1QH0Af8BmgHoAfcB/wG1AfMB+gH/AcIB+AH8Af8BwwH4Af0B/wHBAfcB/QH/Aa8B8AH7Af8BjwHi + AfcB/wFwAdAB8AH/AUQBuAHlAf8BWQGBAZMB/xAAAXcBoQG1Af8BcQHVAfQB/wGaAegB9wH/AbUB8wH6 + Av8BtAGLAv8BqAGBAv8BmwFsAf8B9wGOAV8B/wHOAWoBNAH/AY8B4gH3Af8BcAHQAfAB/wFEAbgB5QH/ + AVkBgQGTAf8gAAJ0AVMB/wF0A/8CdAFTAf8YAAHOAYEBbQH/AfgB8AHQAf8B+AHwAdAB/wH4AfAB0AH/ + AfgB8AHQAf8B+AHwAdAB/wGoATUBKwH/BAADswH/A9EB/wPYAf8D2AH/A8wB/wO8Af8DsQH/A5UB/wgA + AXoBowG4Af8BxQH5Af0B/wHFAfkB/QH/AcUB+QH9Af8BxQH5Af0B/wHFAfkB/QH/AcUB+QH9Af8BxQH5 + Af0B/wHFAfkB/QH/AcUB+QH9Af8BxQH5Af0B/wFbAYEBlQH/EAABegGjAbgB/wHFAfkB/QH/AcUB+QH9 + Af8BxQH5Af0B/wHFAfkB/QH/AcUB+QH9Af8BxQH5Af0B/wHFAfkB/QH/AcUB+QH9Af8BxQH5Af0B/wHF + AfkB/QH/AcUB+QH9Af8BWwGBAZUB/yAAAnQBUwH/AnQBUwH/AnQBUwH/GAAB0gGBAT4B/wHQAYEBKgH/ + AdABgQEqAf8B0AGBASoB/wHQAYEBKgH/AdABgQEqAf8BxwFwASoB/wQAA7UB/wPiAf8D6AH/A/YB/wP1 + Af8D5QH/A88B/wOhAf8IAAGOAcABzwH/AYwBvQHMAf8BnQHPAdsB/wGtAd8B6AH/AbkB7AHzAf8BwgH1 + AfoB/wHCAfUB+gH/AbgB6wHxAf8BqQHaAeMB/wGUAcQB0QH/AYEBqAG4Af8BgQGlAbcB/xAAAY4BwAHP + Af8BjAG9AcwB/wGdAc8B2wH/Aa0B3wHoAf8BuQHsAfMB/wHCAfUB+gH/AcIB9QH6Af8BwgH1AfoB/wG4 + AesB8QH/AakB2gHjAf8BlAHEAdEB/wGBAagBuAH/AYEBpQG3Af9EAAH7AbQBXAH/AdABgQEqAf8B0AGB + ASoB/wHQAYEBKgH/AdABgQEqAf8B0AGBASoB/wH7AbQBXAH/BAAD2wH/A7MB/wOrAf8DngH/A5QB/wOS + Af8DmwH/A9EB/wgAAZ0B0AHbAf8BlgHIAdUB/wGMAb4BzQH/AYIBswHDAf8BfQGmAbkB/wF0AZsBsAH/ + AXABmAGtAf8BdQGdAbEB/wF9AaQBtwH/AYEBrQG+Af8BhwG1AcQB/wGNAbwBygH/EAABnQHQAdsB/wGW + AcgB1QH/AYwBvgHNAf8BggGzAcMB/wF9AaYBuQH/AXQBmwGwAf8BdAGbAbAB/wFwAZgBrQH/AXUBnQGx + Af8BfQGkAbcB/wGBAa0BvgH/AYcBtQHEAf8BjQG8AcoB/wQAAUIBTQE+BwABPgMAASgDAAFAAwABMAMA + AQEBAAEBBQABgAEBFgAD/wEAAv8GAAL/BgABxAFHBgABxAFHBgABxAFHBgAB7gHvBgAB7gHvBgAB7gHv + BgAB4AEPBgAB/gH/BgAB/gH/BgAB/AF/BgAB/AF/BgAB/AF/BgAC/wYAAv8GAAb/Af4BfwT/AYABBwH8 + AX8BAAEBAYABAQGAAQcB/AE/AQABAQGAAQEBgAEHAfwBPwEAAQEBgAEBAYABBwH8AT8BAAEBAYABAQGA + AQcB/AE/AQABAQGAAQEBgAEHAfwBfwEAAQEBgAEBAYABBwHwAR8BAAEBAYABAQGAAQcB4AEPAQABAQGA + AQEBgAEHAeABDwEAAQEBgAEBAYABBwHgAQ8BAAEBAYABAQGAAQcB4AEPAQAB/wGAAQEBgAEHAeABDwEB + Af8BgAEBAYABBwHgAQ8C/wGAAQEC/wHgAQ8G/wHwAR8D/wEBAeABBwHgAQMD/wEBAcABAwHAAQEBgwHg + Af8BAQHAAQMBwAIBAuABAQHAAQMBwAIBAeAB5wEBAcABAwHAAgEB4AHvAQEBwAEDAcABAQIAAe8B/wHA + AQMBwAEBAgABgwEAAcABAwHAAQEBgAEAAccBAAHAAQMBwAEBAfgBAAHvAQABwAEDAcABAQH4AQABAQEA + AcABAwHAAQEB/AEAAQEBAAHAAQMBwAEBAfwBHwEBAQABwAEDAcABAQH+AT8BAQEAAcABAwHAAQEB/gE/ + AQEBAAHAAQMBwAEBAv8BAQEAAcABAwHAAQEL + + + + 17, 17 + + + 87, 17 + + + 182, 17 + + + 283, 17 + + + 427, 17 + + + + + AAABAAEAEBABAAAAAABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKs0Kv6oLyX/qC8l/6gvJf+oLyX/qjQp/6kx + J/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC0SDv/+PDQ///u5v//6N3//+PU///c + yv+oLyX/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwWFR//jw0P/+8+3//u7m//3o + 3f/94tT/qC8l/wAAAAAAAAAAAAAAAAAAAACzRDT6s0Mz+bNDM/izQzP4skIy+M56Z//48ND/+PDQ//jw + 0P/48ND/+PDQ/6gvJf8AAAAAAAAAAAAAAAAAAAAAs0Mz+ciFfDgAAAAAAAAAAAAAAADSgDj/0Hsk/9B7 + JP/QeyT/0Hsk/9B7JP/HaiT/AAAAAAAAAAAAAAAAAAAAAL5UPvQAAAAAAAAAAAAAAAAAAAAA+7RW/9B7 + JP/QeyT/0Hsk/9B7JP/QeyT/+7RW/wAAAAAAAAAAAAAAAAAAAADDYk38AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALpNOO/bmop7yG5a/tuainuxQDH0AAAAAAAA + AADg4OD/r6+v/6SkpP+YmJj/jY2N/39/f/+AgID/1NTU/wAAAAAAAAAAvVE8971RO/+xPy/vAAAAAAAA + AAAAAAAAoKCg/8bGxv/Z2dn/0tLS/8DAwP+jo6P/hYWF/25ubv8AAAAAAAAAAAAAAAC7Tjn/AAAAAAAA + AAAAAAAAAAAAAKKiov/CwsL/0dHR/8XFxf+0tLT/nJyc/4ODg/9ra2v/qzQq/agvJf+oLyX/qC8l/6gv + Jf+qNCn/qTEn/wAAAACkpKT/tra2/7e3t/+rq6v/np6e/4uLi/98fHz/bGxs/7RIO//48ND//+7m///o + 3f//49T//9zK/6gvJf8AAAAAp6en/8rKyv/e3t7/0tLS/8DAwP+lpaX/iIiI/29vb//BYVH/+PDQ//7z + 7f/+7ub//ejd//3i1P+oLyX/AAAAAKysrP+6urr/vb29/7Gxsf+jo6P/kJCQ/4CAgP94eHj/znpn//jw + 0P/48ND/+PDQ//jw0P/48ND/qC8l/wAAAACzs7P/0dHR/9jY2P/Y2Nj/zMzM/7y8vP+xsbH/lZWV/9KA + OP/QeyT/0Hsk/9B7JP/QeyT/0Hsk/8dqJP8AAAAAtbW1/+Li4v/o6Oj/9vb2//X19f/l5eX/z8/P/6Gh + of/7tFb/0Hsk/9B7JP/QeyT/0Hsk/9B7JP/7tFb/AAAAANvb2/+zs7P/q6ur/56env+UlJT/kpKS/5ub + m//R0dH//wEAAP8BAAD/AQAA4AEAAOcBAADvAQAA7/8AAIMAAADHAAAA7wAAAAEAAAABAAAAAQAAAAEA + AAABAAAAAQAAAA== + + + \ No newline at end of file diff --git a/src/Kalman.Studio/ExplorerForm/PdmExplorer/PdmModelViewer.cs b/src/Kalman.Studio/ExplorerForm/PdmExplorer/PdmModelViewer.cs new file mode 100644 index 0000000..ea5fd91 --- /dev/null +++ b/src/Kalman.Studio/ExplorerForm/PdmExplorer/PdmModelViewer.cs @@ -0,0 +1,88 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using Kalman.PdmParser; + +namespace Kalman.Studio +{ + public partial class PdmModelViewer : DockableForm + { + public PdmModelViewer() + { + InitializeComponent(); + } + + public void LoadModel(PDModel m) + { + this.Text = m.Name; + + dgvTable.AutoGenerateColumns = false; + dgvView.AutoGenerateColumns = false; + dgvSP.AutoGenerateColumns = false; + + dgvTable.DataSource = m.AllTableList; + dgvView.DataSource = m.AllViewList; + dgvSP.DataSource = m.AllProcedureList; + + tpTable.Text = string.Format("表[{0}]", dgvTable.Rows.Count); + tpView.Text = string.Format("视图[{0}]", dgvView.Rows.Count); + tpSP.Text = string.Format("存储过程[{0}]", dgvSP.Rows.Count); + } + + public void LoadPackage(PDPackage p) + { + this.Text = p.Name; + + dgvTable.AutoGenerateColumns = false; + dgvView.AutoGenerateColumns = false; + dgvSP.AutoGenerateColumns = false; + + dgvTable.DataSource = p.TableList; + dgvView.DataSource = p.ViewList; + dgvSP.DataSource = p.ProcedureList; + + tpTable.Text = string.Format("表[{0}]", dgvTable.Rows.Count); + tpView.Text = string.Format("视图[{0}]", dgvView.Rows.Count); + tpSP.Text = string.Format("存储过程[{0}]", dgvSP.Rows.Count); + } + + private void dgvTable_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e) + { + if (e.Button == MouseButtons.Right && e.RowIndex > -1 && e.ColumnIndex > -1) + { + dgvTable.CurrentRow.Selected = false; + dgvTable.Rows[e.RowIndex].Selected = true; + } + } + private void dgvView_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e) + { + if (e.Button == MouseButtons.Right && e.RowIndex > -1 && e.ColumnIndex > -1) + { + dgvView.CurrentRow.Selected = false; + dgvView.Rows[e.RowIndex].Selected = true; + } + } + private void dgvSP_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e) + { + if (e.Button == MouseButtons.Right && e.RowIndex > -1 && e.ColumnIndex > -1) + { + dgvSP.CurrentRow.Selected = false; + dgvSP.Rows[e.RowIndex].Selected = true; + } + } + + private void dgvTable_CellMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e) + { + if (e.RowIndex > -1) + { + PdmTableViewer v = new PdmTableViewer(dgvTable.Rows[e.RowIndex].DataBoundItem as PDTable); + v.ShowDialog(); + } + } + } +} diff --git a/src/Kalman.Studio/ExplorerForm/PdmExplorer/PdmModelViewer.designer.cs b/src/Kalman.Studio/ExplorerForm/PdmExplorer/PdmModelViewer.designer.cs new file mode 100644 index 0000000..0f5a55d --- /dev/null +++ b/src/Kalman.Studio/ExplorerForm/PdmExplorer/PdmModelViewer.designer.cs @@ -0,0 +1,440 @@ +namespace Kalman.Studio +{ + partial class PdmModelViewer + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle2 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle3 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle4 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle5 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle6 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle7 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle8 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle9 = new System.Windows.Forms.DataGridViewCellStyle(); + this.tpSP = new System.Windows.Forms.TabPage(); + this.dgvSP = new System.Windows.Forms.DataGridView(); + this.dataGridViewTextBoxColumn7 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.dataGridViewTextBoxColumn8 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.dataGridViewTextBoxColumn9 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.dataGridViewTextBoxColumn10 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.dataGridViewTextBoxColumn11 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.dataGridViewTextBoxColumn12 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.tpView = new System.Windows.Forms.TabPage(); + this.dgvView = new System.Windows.Forms.DataGridView(); + this.dataGridViewTextBoxColumn1 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.dataGridViewTextBoxColumn2 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.dataGridViewTextBoxColumn3 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.dataGridViewTextBoxColumn4 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.dataGridViewTextBoxColumn5 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.dataGridViewTextBoxColumn6 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.tpTable = new System.Windows.Forms.TabPage(); + this.dgvTable = new System.Windows.Forms.DataGridView(); + this.colID = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colName = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colCode = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colUser = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colPackage = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colComment = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.tabControl1 = new System.Windows.Forms.TabControl(); + this.tpSP.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.dgvSP)).BeginInit(); + this.tpView.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.dgvView)).BeginInit(); + this.tpTable.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.dgvTable)).BeginInit(); + this.tabControl1.SuspendLayout(); + this.SuspendLayout(); + // + // tpSP + // + this.tpSP.Controls.Add(this.dgvSP); + this.tpSP.Location = new System.Drawing.Point(4, 21); + this.tpSP.Name = "tpSP"; + this.tpSP.Padding = new System.Windows.Forms.Padding(3); + this.tpSP.Size = new System.Drawing.Size(611, 414); + this.tpSP.TabIndex = 2; + this.tpSP.Text = "存储过程"; + this.tpSP.UseVisualStyleBackColor = true; + // + // dgvSP + // + this.dgvSP.AllowUserToAddRows = false; + this.dgvSP.AllowUserToDeleteRows = false; + this.dgvSP.AllowUserToResizeRows = false; + dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle1.BackColor = System.Drawing.SystemColors.Control; + dataGridViewCellStyle1.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + dataGridViewCellStyle1.ForeColor = System.Drawing.SystemColors.WindowText; + dataGridViewCellStyle1.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle1.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle1.WrapMode = System.Windows.Forms.DataGridViewTriState.True; + this.dgvSP.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle1; + this.dgvSP.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.dgvSP.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { + this.dataGridViewTextBoxColumn7, + this.dataGridViewTextBoxColumn8, + this.dataGridViewTextBoxColumn9, + this.dataGridViewTextBoxColumn10, + this.dataGridViewTextBoxColumn11, + this.dataGridViewTextBoxColumn12}); + dataGridViewCellStyle2.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle2.BackColor = System.Drawing.SystemColors.Window; + dataGridViewCellStyle2.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + dataGridViewCellStyle2.ForeColor = System.Drawing.SystemColors.ControlText; + dataGridViewCellStyle2.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle2.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle2.WrapMode = System.Windows.Forms.DataGridViewTriState.False; + this.dgvSP.DefaultCellStyle = dataGridViewCellStyle2; + this.dgvSP.Dock = System.Windows.Forms.DockStyle.Fill; + this.dgvSP.Location = new System.Drawing.Point(3, 3); + this.dgvSP.MultiSelect = false; + this.dgvSP.Name = "dgvSP"; + this.dgvSP.ReadOnly = true; + dataGridViewCellStyle3.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle3.BackColor = System.Drawing.SystemColors.Control; + dataGridViewCellStyle3.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + dataGridViewCellStyle3.ForeColor = System.Drawing.SystemColors.WindowText; + dataGridViewCellStyle3.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle3.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle3.WrapMode = System.Windows.Forms.DataGridViewTriState.True; + this.dgvSP.RowHeadersDefaultCellStyle = dataGridViewCellStyle3; + this.dgvSP.RowHeadersVisible = false; + this.dgvSP.RowTemplate.Height = 23; + this.dgvSP.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.CellSelect; + this.dgvSP.Size = new System.Drawing.Size(605, 408); + this.dgvSP.TabIndex = 1; + this.dgvSP.CellMouseDown += new System.Windows.Forms.DataGridViewCellMouseEventHandler(this.dgvSP_CellMouseDown); + // + // dataGridViewTextBoxColumn7 + // + this.dataGridViewTextBoxColumn7.DataPropertyName = "ID"; + this.dataGridViewTextBoxColumn7.HeaderText = "ID"; + this.dataGridViewTextBoxColumn7.Name = "dataGridViewTextBoxColumn7"; + this.dataGridViewTextBoxColumn7.ReadOnly = true; + // + // dataGridViewTextBoxColumn8 + // + this.dataGridViewTextBoxColumn8.DataPropertyName = "Name"; + this.dataGridViewTextBoxColumn8.HeaderText = "Name"; + this.dataGridViewTextBoxColumn8.Name = "dataGridViewTextBoxColumn8"; + this.dataGridViewTextBoxColumn8.ReadOnly = true; + // + // dataGridViewTextBoxColumn9 + // + this.dataGridViewTextBoxColumn9.DataPropertyName = "Code"; + this.dataGridViewTextBoxColumn9.HeaderText = "Code"; + this.dataGridViewTextBoxColumn9.Name = "dataGridViewTextBoxColumn9"; + this.dataGridViewTextBoxColumn9.ReadOnly = true; + // + // dataGridViewTextBoxColumn10 + // + this.dataGridViewTextBoxColumn10.DataPropertyName = "User"; + this.dataGridViewTextBoxColumn10.HeaderText = "User"; + this.dataGridViewTextBoxColumn10.Name = "dataGridViewTextBoxColumn10"; + this.dataGridViewTextBoxColumn10.ReadOnly = true; + // + // dataGridViewTextBoxColumn11 + // + this.dataGridViewTextBoxColumn11.DataPropertyName = "Package"; + this.dataGridViewTextBoxColumn11.HeaderText = "Package"; + this.dataGridViewTextBoxColumn11.Name = "dataGridViewTextBoxColumn11"; + this.dataGridViewTextBoxColumn11.ReadOnly = true; + // + // dataGridViewTextBoxColumn12 + // + this.dataGridViewTextBoxColumn12.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; + this.dataGridViewTextBoxColumn12.DataPropertyName = "Comment"; + this.dataGridViewTextBoxColumn12.HeaderText = "Comment"; + this.dataGridViewTextBoxColumn12.Name = "dataGridViewTextBoxColumn12"; + this.dataGridViewTextBoxColumn12.ReadOnly = true; + // + // tpView + // + this.tpView.Controls.Add(this.dgvView); + this.tpView.Location = new System.Drawing.Point(4, 21); + this.tpView.Name = "tpView"; + this.tpView.Padding = new System.Windows.Forms.Padding(3); + this.tpView.Size = new System.Drawing.Size(611, 414); + this.tpView.TabIndex = 1; + this.tpView.Text = "视图"; + this.tpView.UseVisualStyleBackColor = true; + // + // dgvView + // + this.dgvView.AllowUserToAddRows = false; + this.dgvView.AllowUserToDeleteRows = false; + this.dgvView.AllowUserToResizeRows = false; + dataGridViewCellStyle4.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle4.BackColor = System.Drawing.SystemColors.Control; + dataGridViewCellStyle4.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + dataGridViewCellStyle4.ForeColor = System.Drawing.SystemColors.WindowText; + dataGridViewCellStyle4.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle4.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle4.WrapMode = System.Windows.Forms.DataGridViewTriState.True; + this.dgvView.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle4; + this.dgvView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.dgvView.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { + this.dataGridViewTextBoxColumn1, + this.dataGridViewTextBoxColumn2, + this.dataGridViewTextBoxColumn3, + this.dataGridViewTextBoxColumn4, + this.dataGridViewTextBoxColumn5, + this.dataGridViewTextBoxColumn6}); + dataGridViewCellStyle5.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle5.BackColor = System.Drawing.SystemColors.Window; + dataGridViewCellStyle5.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + dataGridViewCellStyle5.ForeColor = System.Drawing.SystemColors.ControlText; + dataGridViewCellStyle5.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle5.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle5.WrapMode = System.Windows.Forms.DataGridViewTriState.False; + this.dgvView.DefaultCellStyle = dataGridViewCellStyle5; + this.dgvView.Dock = System.Windows.Forms.DockStyle.Fill; + this.dgvView.Location = new System.Drawing.Point(3, 3); + this.dgvView.MultiSelect = false; + this.dgvView.Name = "dgvView"; + this.dgvView.ReadOnly = true; + dataGridViewCellStyle6.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle6.BackColor = System.Drawing.SystemColors.Control; + dataGridViewCellStyle6.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + dataGridViewCellStyle6.ForeColor = System.Drawing.SystemColors.WindowText; + dataGridViewCellStyle6.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle6.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle6.WrapMode = System.Windows.Forms.DataGridViewTriState.True; + this.dgvView.RowHeadersDefaultCellStyle = dataGridViewCellStyle6; + this.dgvView.RowHeadersVisible = false; + this.dgvView.RowTemplate.Height = 23; + this.dgvView.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.CellSelect; + this.dgvView.Size = new System.Drawing.Size(605, 408); + this.dgvView.TabIndex = 1; + this.dgvView.CellMouseDown += new System.Windows.Forms.DataGridViewCellMouseEventHandler(this.dgvView_CellMouseDown); + // + // dataGridViewTextBoxColumn1 + // + this.dataGridViewTextBoxColumn1.DataPropertyName = "ID"; + this.dataGridViewTextBoxColumn1.HeaderText = "ID"; + this.dataGridViewTextBoxColumn1.Name = "dataGridViewTextBoxColumn1"; + this.dataGridViewTextBoxColumn1.ReadOnly = true; + // + // dataGridViewTextBoxColumn2 + // + this.dataGridViewTextBoxColumn2.DataPropertyName = "Name"; + this.dataGridViewTextBoxColumn2.HeaderText = "Name"; + this.dataGridViewTextBoxColumn2.Name = "dataGridViewTextBoxColumn2"; + this.dataGridViewTextBoxColumn2.ReadOnly = true; + // + // dataGridViewTextBoxColumn3 + // + this.dataGridViewTextBoxColumn3.DataPropertyName = "Code"; + this.dataGridViewTextBoxColumn3.HeaderText = "Code"; + this.dataGridViewTextBoxColumn3.Name = "dataGridViewTextBoxColumn3"; + this.dataGridViewTextBoxColumn3.ReadOnly = true; + // + // dataGridViewTextBoxColumn4 + // + this.dataGridViewTextBoxColumn4.DataPropertyName = "User"; + this.dataGridViewTextBoxColumn4.HeaderText = "User"; + this.dataGridViewTextBoxColumn4.Name = "dataGridViewTextBoxColumn4"; + this.dataGridViewTextBoxColumn4.ReadOnly = true; + // + // dataGridViewTextBoxColumn5 + // + this.dataGridViewTextBoxColumn5.DataPropertyName = "Package"; + this.dataGridViewTextBoxColumn5.HeaderText = "Package"; + this.dataGridViewTextBoxColumn5.Name = "dataGridViewTextBoxColumn5"; + this.dataGridViewTextBoxColumn5.ReadOnly = true; + // + // dataGridViewTextBoxColumn6 + // + this.dataGridViewTextBoxColumn6.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; + this.dataGridViewTextBoxColumn6.DataPropertyName = "Comment"; + this.dataGridViewTextBoxColumn6.HeaderText = "Comment"; + this.dataGridViewTextBoxColumn6.Name = "dataGridViewTextBoxColumn6"; + this.dataGridViewTextBoxColumn6.ReadOnly = true; + // + // tpTable + // + this.tpTable.Controls.Add(this.dgvTable); + this.tpTable.Location = new System.Drawing.Point(4, 21); + this.tpTable.Name = "tpTable"; + this.tpTable.Padding = new System.Windows.Forms.Padding(3); + this.tpTable.Size = new System.Drawing.Size(611, 414); + this.tpTable.TabIndex = 0; + this.tpTable.Text = "表"; + this.tpTable.UseVisualStyleBackColor = true; + // + // dgvTable + // + this.dgvTable.AllowUserToAddRows = false; + this.dgvTable.AllowUserToDeleteRows = false; + this.dgvTable.AllowUserToResizeRows = false; + dataGridViewCellStyle7.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle7.BackColor = System.Drawing.SystemColors.Control; + dataGridViewCellStyle7.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + dataGridViewCellStyle7.ForeColor = System.Drawing.SystemColors.WindowText; + dataGridViewCellStyle7.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle7.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle7.WrapMode = System.Windows.Forms.DataGridViewTriState.True; + this.dgvTable.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle7; + this.dgvTable.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.dgvTable.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { + this.colID, + this.colName, + this.colCode, + this.colUser, + this.colPackage, + this.colComment}); + dataGridViewCellStyle8.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle8.BackColor = System.Drawing.SystemColors.Window; + dataGridViewCellStyle8.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + dataGridViewCellStyle8.ForeColor = System.Drawing.SystemColors.ControlText; + dataGridViewCellStyle8.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle8.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle8.WrapMode = System.Windows.Forms.DataGridViewTriState.False; + this.dgvTable.DefaultCellStyle = dataGridViewCellStyle8; + this.dgvTable.Dock = System.Windows.Forms.DockStyle.Fill; + this.dgvTable.Location = new System.Drawing.Point(3, 3); + this.dgvTable.MultiSelect = false; + this.dgvTable.Name = "dgvTable"; + dataGridViewCellStyle9.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle9.BackColor = System.Drawing.SystemColors.Control; + dataGridViewCellStyle9.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + dataGridViewCellStyle9.ForeColor = System.Drawing.SystemColors.WindowText; + dataGridViewCellStyle9.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle9.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle9.WrapMode = System.Windows.Forms.DataGridViewTriState.True; + this.dgvTable.RowHeadersDefaultCellStyle = dataGridViewCellStyle9; + this.dgvTable.RowHeadersVisible = false; + this.dgvTable.RowTemplate.Height = 23; + this.dgvTable.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.CellSelect; + this.dgvTable.Size = new System.Drawing.Size(605, 408); + this.dgvTable.TabIndex = 0; + this.dgvTable.CellMouseDown += new System.Windows.Forms.DataGridViewCellMouseEventHandler(this.dgvTable_CellMouseDown); + this.dgvTable.CellMouseDoubleClick += new System.Windows.Forms.DataGridViewCellMouseEventHandler(this.dgvTable_CellMouseDoubleClick); + // + // colID + // + this.colID.DataPropertyName = "ID"; + this.colID.HeaderText = "ID"; + this.colID.Name = "colID"; + this.colID.Width = 50; + // + // colName + // + this.colName.DataPropertyName = "Name"; + this.colName.HeaderText = "Name"; + this.colName.Name = "colName"; + this.colName.Width = 150; + // + // colCode + // + this.colCode.DataPropertyName = "Code"; + this.colCode.HeaderText = "Code"; + this.colCode.Name = "colCode"; + this.colCode.Width = 150; + // + // colUser + // + this.colUser.DataPropertyName = "User"; + this.colUser.HeaderText = "User"; + this.colUser.Name = "colUser"; + // + // colPackage + // + this.colPackage.DataPropertyName = "Package"; + this.colPackage.HeaderText = "Package"; + this.colPackage.Name = "colPackage"; + this.colPackage.Width = 150; + // + // colComment + // + this.colComment.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; + this.colComment.DataPropertyName = "Comment"; + this.colComment.HeaderText = "Comment"; + this.colComment.Name = "colComment"; + // + // tabControl1 + // + this.tabControl1.Controls.Add(this.tpTable); + this.tabControl1.Controls.Add(this.tpView); + this.tabControl1.Controls.Add(this.tpSP); + this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill; + this.tabControl1.Location = new System.Drawing.Point(0, 0); + this.tabControl1.Name = "tabControl1"; + this.tabControl1.SelectedIndex = 0; + this.tabControl1.Size = new System.Drawing.Size(619, 439); + this.tabControl1.TabIndex = 3; + // + // PdmModelViewer + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(619, 439); + this.Controls.Add(this.tabControl1); + this.Name = "PdmModelViewer"; + this.Text = "PdmModelViewer"; + this.tpSP.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.dgvSP)).EndInit(); + this.tpView.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.dgvView)).EndInit(); + this.tpTable.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.dgvTable)).EndInit(); + this.tabControl1.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.TabPage tpSP; + private System.Windows.Forms.TabPage tpView; + private System.Windows.Forms.TabPage tpTable; + private System.Windows.Forms.DataGridView dgvTable; + private System.Windows.Forms.TabControl tabControl1; + private System.Windows.Forms.DataGridView dgvSP; + private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn7; + private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn8; + private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn9; + private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn10; + private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn11; + private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn12; + private System.Windows.Forms.DataGridView dgvView; + private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn1; + private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn2; + private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn3; + private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn4; + private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn5; + private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn6; + private System.Windows.Forms.DataGridViewTextBoxColumn colID; + private System.Windows.Forms.DataGridViewTextBoxColumn colName; + private System.Windows.Forms.DataGridViewTextBoxColumn colCode; + private System.Windows.Forms.DataGridViewTextBoxColumn colUser; + private System.Windows.Forms.DataGridViewTextBoxColumn colPackage; + private System.Windows.Forms.DataGridViewTextBoxColumn colComment; + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/ExplorerForm/PdmExplorer/PdmModelViewer.resx b/src/Kalman.Studio/ExplorerForm/PdmExplorer/PdmModelViewer.resx new file mode 100644 index 0000000..e6abf6c --- /dev/null +++ b/src/Kalman.Studio/ExplorerForm/PdmExplorer/PdmModelViewer.resx @@ -0,0 +1,174 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + \ No newline at end of file diff --git a/src/Kalman.Studio/ExplorerForm/PdmExplorer/PdmTableViewer.cs b/src/Kalman.Studio/ExplorerForm/PdmExplorer/PdmTableViewer.cs new file mode 100644 index 0000000..562c079 --- /dev/null +++ b/src/Kalman.Studio/ExplorerForm/PdmExplorer/PdmTableViewer.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using Kalman.PdmParser; + +namespace Kalman.Studio +{ + public partial class PdmTableViewer : Form + { + PDTable _Table = null; + + public PdmTableViewer(PDTable table) + { + InitializeComponent(); + _Table = table; + } + + private void PdmTableViewer_Load(object sender, EventArgs e) + { + this.Text = string.Format("查看表[{0}]信息", _Table.Name); + if (_Table.Package != null) this.Text += string.Format(",所属包[{0}]", _Table.Package.Name); + + dgvColumn.AutoGenerateColumns = false; + dgvKey.AutoGenerateColumns = false; + dgvIndex.AutoGenerateColumns = false; + + dgvColumn.DataSource = _Table.ColumnList; + dgvKey.DataSource = _Table.KeyList; + dgvIndex.DataSource = _Table.IndexList; + } + + private void dgvKey_CellMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e) + { + if (e.RowIndex > -1) + { + PDKey key = dgvKey.Rows[e.RowIndex].DataBoundItem as PDKey; + if (key == null) return; + + PdmColumnsViewer v = new PdmColumnsViewer(key.ColumnList); + v.ShowDialog(); + } + } + + private void dgvIndex_CellMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e) + { + if (e.RowIndex > -1) + { + PDIndex index = dgvIndex.Rows[e.RowIndex].DataBoundItem as PDIndex; + if (index == null) return; + + PdmColumnsViewer v = new PdmColumnsViewer(index.ColumnList); + v.ShowDialog(); + } + } + } +} diff --git a/src/Kalman.Studio/ExplorerForm/PdmExplorer/PdmTableViewer.designer.cs b/src/Kalman.Studio/ExplorerForm/PdmExplorer/PdmTableViewer.designer.cs new file mode 100644 index 0000000..10b040d --- /dev/null +++ b/src/Kalman.Studio/ExplorerForm/PdmExplorer/PdmTableViewer.designer.cs @@ -0,0 +1,501 @@ +namespace Kalman.Studio +{ + partial class PdmTableViewer + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle2 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle3 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle4 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle5 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle6 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle7 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle8 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle9 = new System.Windows.Forms.DataGridViewCellStyle(); + this.tpColumn = new System.Windows.Forms.TabPage(); + this.dgvColumn = new System.Windows.Forms.DataGridView(); + this.colID = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colName = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colCode = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colDataType = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colLength = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colPrecision = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colIsPK = new System.Windows.Forms.DataGridViewCheckBoxColumn(); + this.colIsFK = new System.Windows.Forms.DataGridViewCheckBoxColumn(); + this.colMandatory = new System.Windows.Forms.DataGridViewCheckBoxColumn(); + this.colComment = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.tpKey = new System.Windows.Forms.TabPage(); + this.dgvKey = new System.Windows.Forms.DataGridView(); + this.dataGridViewTextBoxColumn1 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.dataGridViewTextBoxColumn2 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.dataGridViewTextBoxColumn3 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colPrimaryKey = new System.Windows.Forms.DataGridViewCheckBoxColumn(); + this.colKeyCluster = new System.Windows.Forms.DataGridViewCheckBoxColumn(); + this.dataGridViewTextBoxColumn5 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.tpIndex = new System.Windows.Forms.TabPage(); + this.dgvIndex = new System.Windows.Forms.DataGridView(); + this.dataGridViewTextBoxColumn4 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.dataGridViewTextBoxColumn6 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.dataGridViewTextBoxColumn7 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colUnique = new System.Windows.Forms.DataGridViewCheckBoxColumn(); + this.colIndexCluster = new System.Windows.Forms.DataGridViewCheckBoxColumn(); + this.dataGridViewTextBoxColumn8 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.tabControl1 = new System.Windows.Forms.TabControl(); + this.tpColumn.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.dgvColumn)).BeginInit(); + this.tpKey.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.dgvKey)).BeginInit(); + this.tpIndex.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.dgvIndex)).BeginInit(); + this.tabControl1.SuspendLayout(); + this.SuspendLayout(); + // + // tpColumn + // + this.tpColumn.Controls.Add(this.dgvColumn); + this.tpColumn.Location = new System.Drawing.Point(4, 21); + this.tpColumn.Name = "tpColumn"; + this.tpColumn.Padding = new System.Windows.Forms.Padding(3); + this.tpColumn.Size = new System.Drawing.Size(784, 348); + this.tpColumn.TabIndex = 0; + this.tpColumn.Text = "字段"; + this.tpColumn.UseVisualStyleBackColor = true; + // + // dgvColumn + // + this.dgvColumn.AllowUserToAddRows = false; + this.dgvColumn.AllowUserToDeleteRows = false; + this.dgvColumn.AllowUserToResizeRows = false; + this.dgvColumn.BackgroundColor = System.Drawing.SystemColors.ActiveCaptionText; + dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle1.BackColor = System.Drawing.SystemColors.Control; + dataGridViewCellStyle1.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + dataGridViewCellStyle1.ForeColor = System.Drawing.SystemColors.WindowText; + dataGridViewCellStyle1.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle1.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle1.WrapMode = System.Windows.Forms.DataGridViewTriState.True; + this.dgvColumn.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle1; + this.dgvColumn.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.dgvColumn.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { + this.colID, + this.colName, + this.colCode, + this.colDataType, + this.colLength, + this.colPrecision, + this.colIsPK, + this.colIsFK, + this.colMandatory, + this.colComment}); + dataGridViewCellStyle2.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle2.BackColor = System.Drawing.SystemColors.Window; + dataGridViewCellStyle2.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + dataGridViewCellStyle2.ForeColor = System.Drawing.SystemColors.ControlText; + dataGridViewCellStyle2.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle2.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle2.WrapMode = System.Windows.Forms.DataGridViewTriState.False; + this.dgvColumn.DefaultCellStyle = dataGridViewCellStyle2; + this.dgvColumn.Dock = System.Windows.Forms.DockStyle.Fill; + this.dgvColumn.Location = new System.Drawing.Point(3, 3); + this.dgvColumn.MultiSelect = false; + this.dgvColumn.Name = "dgvColumn"; + dataGridViewCellStyle3.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle3.BackColor = System.Drawing.SystemColors.Control; + dataGridViewCellStyle3.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + dataGridViewCellStyle3.ForeColor = System.Drawing.SystemColors.WindowText; + dataGridViewCellStyle3.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle3.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle3.WrapMode = System.Windows.Forms.DataGridViewTriState.True; + this.dgvColumn.RowHeadersDefaultCellStyle = dataGridViewCellStyle3; + this.dgvColumn.RowHeadersVisible = false; + this.dgvColumn.RowTemplate.Height = 23; + this.dgvColumn.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.CellSelect; + this.dgvColumn.Size = new System.Drawing.Size(778, 342); + this.dgvColumn.TabIndex = 1; + // + // colID + // + this.colID.DataPropertyName = "ID"; + this.colID.HeaderText = "ID"; + this.colID.Name = "colID"; + this.colID.Width = 40; + // + // colName + // + this.colName.DataPropertyName = "Name"; + this.colName.HeaderText = "Name"; + this.colName.Name = "colName"; + // + // colCode + // + this.colCode.DataPropertyName = "Code"; + this.colCode.HeaderText = "Code"; + this.colCode.Name = "colCode"; + // + // colDataType + // + this.colDataType.DataPropertyName = "DataType"; + this.colDataType.HeaderText = "DataType"; + this.colDataType.Name = "colDataType"; + // + // colLength + // + this.colLength.DataPropertyName = "Length"; + this.colLength.HeaderText = "Length"; + this.colLength.Name = "colLength"; + this.colLength.Width = 50; + // + // colPrecision + // + this.colPrecision.DataPropertyName = "Precision"; + this.colPrecision.HeaderText = "Precision"; + this.colPrecision.Name = "colPrecision"; + this.colPrecision.Width = 60; + // + // colIsPK + // + this.colIsPK.DataPropertyName = "IsPK"; + this.colIsPK.HeaderText = "P"; + this.colIsPK.Name = "colIsPK"; + this.colIsPK.Resizable = System.Windows.Forms.DataGridViewTriState.True; + this.colIsPK.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic; + this.colIsPK.Width = 20; + // + // colIsFK + // + this.colIsFK.DataPropertyName = "IsFK"; + this.colIsFK.HeaderText = "F"; + this.colIsFK.Name = "colIsFK"; + this.colIsFK.Resizable = System.Windows.Forms.DataGridViewTriState.True; + this.colIsFK.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic; + this.colIsFK.Width = 20; + // + // colMandatory + // + this.colMandatory.DataPropertyName = "Mandatory"; + this.colMandatory.HeaderText = "M"; + this.colMandatory.Name = "colMandatory"; + this.colMandatory.Resizable = System.Windows.Forms.DataGridViewTriState.True; + this.colMandatory.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic; + this.colMandatory.Width = 20; + // + // colComment + // + this.colComment.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; + this.colComment.DataPropertyName = "Comment"; + this.colComment.HeaderText = "Comment"; + this.colComment.Name = "colComment"; + // + // tpKey + // + this.tpKey.Controls.Add(this.dgvKey); + this.tpKey.Location = new System.Drawing.Point(4, 21); + this.tpKey.Name = "tpKey"; + this.tpKey.Padding = new System.Windows.Forms.Padding(3); + this.tpKey.Size = new System.Drawing.Size(784, 348); + this.tpKey.TabIndex = 1; + this.tpKey.Text = "键"; + this.tpKey.UseVisualStyleBackColor = true; + // + // dgvKey + // + this.dgvKey.AllowUserToAddRows = false; + this.dgvKey.AllowUserToDeleteRows = false; + this.dgvKey.AllowUserToResizeRows = false; + this.dgvKey.BackgroundColor = System.Drawing.SystemColors.ActiveCaptionText; + dataGridViewCellStyle4.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle4.BackColor = System.Drawing.SystemColors.Control; + dataGridViewCellStyle4.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + dataGridViewCellStyle4.ForeColor = System.Drawing.SystemColors.WindowText; + dataGridViewCellStyle4.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle4.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle4.WrapMode = System.Windows.Forms.DataGridViewTriState.True; + this.dgvKey.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle4; + this.dgvKey.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.dgvKey.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { + this.dataGridViewTextBoxColumn1, + this.dataGridViewTextBoxColumn2, + this.dataGridViewTextBoxColumn3, + this.colPrimaryKey, + this.colKeyCluster, + this.dataGridViewTextBoxColumn5}); + dataGridViewCellStyle5.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle5.BackColor = System.Drawing.SystemColors.Window; + dataGridViewCellStyle5.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + dataGridViewCellStyle5.ForeColor = System.Drawing.SystemColors.ControlText; + dataGridViewCellStyle5.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle5.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle5.WrapMode = System.Windows.Forms.DataGridViewTriState.False; + this.dgvKey.DefaultCellStyle = dataGridViewCellStyle5; + this.dgvKey.Dock = System.Windows.Forms.DockStyle.Fill; + this.dgvKey.Location = new System.Drawing.Point(3, 3); + this.dgvKey.MultiSelect = false; + this.dgvKey.Name = "dgvKey"; + this.dgvKey.ReadOnly = true; + dataGridViewCellStyle6.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle6.BackColor = System.Drawing.SystemColors.Control; + dataGridViewCellStyle6.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + dataGridViewCellStyle6.ForeColor = System.Drawing.SystemColors.WindowText; + dataGridViewCellStyle6.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle6.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle6.WrapMode = System.Windows.Forms.DataGridViewTriState.True; + this.dgvKey.RowHeadersDefaultCellStyle = dataGridViewCellStyle6; + this.dgvKey.RowHeadersVisible = false; + this.dgvKey.RowTemplate.Height = 23; + this.dgvKey.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.CellSelect; + this.dgvKey.Size = new System.Drawing.Size(778, 342); + this.dgvKey.TabIndex = 1; + this.dgvKey.CellMouseDoubleClick += new System.Windows.Forms.DataGridViewCellMouseEventHandler(this.dgvKey_CellMouseDoubleClick); + // + // dataGridViewTextBoxColumn1 + // + this.dataGridViewTextBoxColumn1.DataPropertyName = "ID"; + this.dataGridViewTextBoxColumn1.HeaderText = "ID"; + this.dataGridViewTextBoxColumn1.Name = "dataGridViewTextBoxColumn1"; + this.dataGridViewTextBoxColumn1.ReadOnly = true; + this.dataGridViewTextBoxColumn1.Width = 50; + // + // dataGridViewTextBoxColumn2 + // + this.dataGridViewTextBoxColumn2.DataPropertyName = "Name"; + this.dataGridViewTextBoxColumn2.HeaderText = "Name"; + this.dataGridViewTextBoxColumn2.Name = "dataGridViewTextBoxColumn2"; + this.dataGridViewTextBoxColumn2.ReadOnly = true; + this.dataGridViewTextBoxColumn2.Width = 150; + // + // dataGridViewTextBoxColumn3 + // + this.dataGridViewTextBoxColumn3.DataPropertyName = "Code"; + this.dataGridViewTextBoxColumn3.HeaderText = "Code"; + this.dataGridViewTextBoxColumn3.Name = "dataGridViewTextBoxColumn3"; + this.dataGridViewTextBoxColumn3.ReadOnly = true; + this.dataGridViewTextBoxColumn3.Width = 150; + // + // colPrimaryKey + // + this.colPrimaryKey.DataPropertyName = "PrimaryKey"; + this.colPrimaryKey.HeaderText = "PrimaryKey"; + this.colPrimaryKey.Name = "colPrimaryKey"; + this.colPrimaryKey.ReadOnly = true; + this.colPrimaryKey.Resizable = System.Windows.Forms.DataGridViewTriState.True; + this.colPrimaryKey.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic; + // + // colKeyCluster + // + this.colKeyCluster.DataPropertyName = "Cluster"; + this.colKeyCluster.HeaderText = "Cluster"; + this.colKeyCluster.Name = "colKeyCluster"; + this.colKeyCluster.ReadOnly = true; + this.colKeyCluster.Resizable = System.Windows.Forms.DataGridViewTriState.True; + this.colKeyCluster.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic; + // + // dataGridViewTextBoxColumn5 + // + this.dataGridViewTextBoxColumn5.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; + this.dataGridViewTextBoxColumn5.DataPropertyName = "Comment"; + this.dataGridViewTextBoxColumn5.HeaderText = "Comment"; + this.dataGridViewTextBoxColumn5.Name = "dataGridViewTextBoxColumn5"; + this.dataGridViewTextBoxColumn5.ReadOnly = true; + // + // tpIndex + // + this.tpIndex.Controls.Add(this.dgvIndex); + this.tpIndex.Location = new System.Drawing.Point(4, 21); + this.tpIndex.Name = "tpIndex"; + this.tpIndex.Padding = new System.Windows.Forms.Padding(3); + this.tpIndex.Size = new System.Drawing.Size(784, 348); + this.tpIndex.TabIndex = 2; + this.tpIndex.Text = "索引"; + this.tpIndex.UseVisualStyleBackColor = true; + // + // dgvIndex + // + this.dgvIndex.AllowUserToAddRows = false; + this.dgvIndex.AllowUserToDeleteRows = false; + this.dgvIndex.AllowUserToResizeRows = false; + this.dgvIndex.BackgroundColor = System.Drawing.SystemColors.ActiveCaptionText; + dataGridViewCellStyle7.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle7.BackColor = System.Drawing.SystemColors.Control; + dataGridViewCellStyle7.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + dataGridViewCellStyle7.ForeColor = System.Drawing.SystemColors.WindowText; + dataGridViewCellStyle7.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle7.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle7.WrapMode = System.Windows.Forms.DataGridViewTriState.True; + this.dgvIndex.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle7; + this.dgvIndex.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.dgvIndex.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { + this.dataGridViewTextBoxColumn4, + this.dataGridViewTextBoxColumn6, + this.dataGridViewTextBoxColumn7, + this.colUnique, + this.colIndexCluster, + this.dataGridViewTextBoxColumn8}); + dataGridViewCellStyle8.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle8.BackColor = System.Drawing.SystemColors.Window; + dataGridViewCellStyle8.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + dataGridViewCellStyle8.ForeColor = System.Drawing.SystemColors.ControlText; + dataGridViewCellStyle8.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle8.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle8.WrapMode = System.Windows.Forms.DataGridViewTriState.False; + this.dgvIndex.DefaultCellStyle = dataGridViewCellStyle8; + this.dgvIndex.Dock = System.Windows.Forms.DockStyle.Fill; + this.dgvIndex.Location = new System.Drawing.Point(3, 3); + this.dgvIndex.MultiSelect = false; + this.dgvIndex.Name = "dgvIndex"; + this.dgvIndex.ReadOnly = true; + dataGridViewCellStyle9.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle9.BackColor = System.Drawing.SystemColors.Control; + dataGridViewCellStyle9.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + dataGridViewCellStyle9.ForeColor = System.Drawing.SystemColors.WindowText; + dataGridViewCellStyle9.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle9.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle9.WrapMode = System.Windows.Forms.DataGridViewTriState.True; + this.dgvIndex.RowHeadersDefaultCellStyle = dataGridViewCellStyle9; + this.dgvIndex.RowHeadersVisible = false; + this.dgvIndex.RowTemplate.Height = 23; + this.dgvIndex.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.CellSelect; + this.dgvIndex.Size = new System.Drawing.Size(778, 342); + this.dgvIndex.TabIndex = 1; + this.dgvIndex.CellMouseDoubleClick += new System.Windows.Forms.DataGridViewCellMouseEventHandler(this.dgvIndex_CellMouseDoubleClick); + // + // dataGridViewTextBoxColumn4 + // + this.dataGridViewTextBoxColumn4.DataPropertyName = "ID"; + this.dataGridViewTextBoxColumn4.HeaderText = "ID"; + this.dataGridViewTextBoxColumn4.Name = "dataGridViewTextBoxColumn4"; + this.dataGridViewTextBoxColumn4.ReadOnly = true; + this.dataGridViewTextBoxColumn4.Width = 50; + // + // dataGridViewTextBoxColumn6 + // + this.dataGridViewTextBoxColumn6.DataPropertyName = "Name"; + this.dataGridViewTextBoxColumn6.HeaderText = "Name"; + this.dataGridViewTextBoxColumn6.Name = "dataGridViewTextBoxColumn6"; + this.dataGridViewTextBoxColumn6.ReadOnly = true; + this.dataGridViewTextBoxColumn6.Width = 150; + // + // dataGridViewTextBoxColumn7 + // + this.dataGridViewTextBoxColumn7.DataPropertyName = "Code"; + this.dataGridViewTextBoxColumn7.HeaderText = "Code"; + this.dataGridViewTextBoxColumn7.Name = "dataGridViewTextBoxColumn7"; + this.dataGridViewTextBoxColumn7.ReadOnly = true; + this.dataGridViewTextBoxColumn7.Width = 150; + // + // colUnique + // + this.colUnique.DataPropertyName = "Unique"; + this.colUnique.HeaderText = "Unique"; + this.colUnique.Name = "colUnique"; + this.colUnique.ReadOnly = true; + this.colUnique.Resizable = System.Windows.Forms.DataGridViewTriState.True; + this.colUnique.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic; + // + // colIndexCluster + // + this.colIndexCluster.DataPropertyName = "Cluster"; + this.colIndexCluster.HeaderText = "Cluster"; + this.colIndexCluster.Name = "colIndexCluster"; + this.colIndexCluster.ReadOnly = true; + // + // dataGridViewTextBoxColumn8 + // + this.dataGridViewTextBoxColumn8.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; + this.dataGridViewTextBoxColumn8.DataPropertyName = "Comment"; + this.dataGridViewTextBoxColumn8.HeaderText = "Comment"; + this.dataGridViewTextBoxColumn8.Name = "dataGridViewTextBoxColumn8"; + this.dataGridViewTextBoxColumn8.ReadOnly = true; + // + // tabControl1 + // + this.tabControl1.Controls.Add(this.tpColumn); + this.tabControl1.Controls.Add(this.tpKey); + this.tabControl1.Controls.Add(this.tpIndex); + this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill; + this.tabControl1.Location = new System.Drawing.Point(0, 0); + this.tabControl1.Name = "tabControl1"; + this.tabControl1.SelectedIndex = 0; + this.tabControl1.Size = new System.Drawing.Size(792, 373); + this.tabControl1.TabIndex = 4; + // + // PdmTableViewer + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(792, 373); + this.Controls.Add(this.tabControl1); + this.Name = "PdmTableViewer"; + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "PdmTableViewer"; + this.Load += new System.EventHandler(this.PdmTableViewer_Load); + this.tpColumn.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.dgvColumn)).EndInit(); + this.tpKey.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.dgvKey)).EndInit(); + this.tpIndex.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.dgvIndex)).EndInit(); + this.tabControl1.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.TabPage tpColumn; + private System.Windows.Forms.TabPage tpKey; + private System.Windows.Forms.TabPage tpIndex; + private System.Windows.Forms.TabControl tabControl1; + private System.Windows.Forms.DataGridView dgvColumn; + private System.Windows.Forms.DataGridView dgvKey; + private System.Windows.Forms.DataGridView dgvIndex; + private System.Windows.Forms.DataGridViewTextBoxColumn colID; + private System.Windows.Forms.DataGridViewTextBoxColumn colName; + private System.Windows.Forms.DataGridViewTextBoxColumn colCode; + private System.Windows.Forms.DataGridViewTextBoxColumn colDataType; + private System.Windows.Forms.DataGridViewTextBoxColumn colLength; + private System.Windows.Forms.DataGridViewTextBoxColumn colPrecision; + private System.Windows.Forms.DataGridViewCheckBoxColumn colIsPK; + private System.Windows.Forms.DataGridViewCheckBoxColumn colIsFK; + private System.Windows.Forms.DataGridViewCheckBoxColumn colMandatory; + private System.Windows.Forms.DataGridViewTextBoxColumn colComment; + private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn4; + private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn6; + private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn7; + private System.Windows.Forms.DataGridViewCheckBoxColumn colUnique; + private System.Windows.Forms.DataGridViewCheckBoxColumn colIndexCluster; + private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn8; + private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn1; + private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn2; + private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn3; + private System.Windows.Forms.DataGridViewCheckBoxColumn colPrimaryKey; + private System.Windows.Forms.DataGridViewCheckBoxColumn colKeyCluster; + private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn5; + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/ExplorerForm/PdmExplorer/PdmTableViewer.resx b/src/Kalman.Studio/ExplorerForm/PdmExplorer/PdmTableViewer.resx new file mode 100644 index 0000000..64f2cb6 --- /dev/null +++ b/src/Kalman.Studio/ExplorerForm/PdmExplorer/PdmTableViewer.resx @@ -0,0 +1,186 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + \ No newline at end of file diff --git a/src/Kalman.Studio/ExplorerForm/TemplateExplorer.cs b/src/Kalman.Studio/ExplorerForm/TemplateExplorer.cs new file mode 100644 index 0000000..4c8a1cf --- /dev/null +++ b/src/Kalman.Studio/ExplorerForm/TemplateExplorer.cs @@ -0,0 +1,415 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using WeifenLuo.WinFormsUI.Docking; +using System.IO; + +namespace Kalman.Studio +{ + public partial class TemplateExplorer : DockExplorer + { + Main main = null; + public TemplateExplorer() + { + InitializeComponent(); + } + + private void TemplateExplorer_Load(object sender, EventArgs e) + { + main = this.ParentForm as Main; + LoadTemplateTree(); + } + + private void LoadTemplateTree() + { + string templatePath = Path.Combine(Application.StartupPath, "T4Template"); + DirectoryInfo rootDir = new DirectoryInfo(templatePath); + + TreeNode root = new TreeNode("T4Templates", 0, 0); + root.Tag = rootDir; + root.ContextMenuStrip = cmsDir; + tvTemplate.Nodes.Add(root); + + DirectoryInfo dirInfo = new DirectoryInfo(templatePath); + ExpendTemplateDir(dirInfo, root); + } + + //展开模板文件夹 + private void ExpendTemplateDir(DirectoryInfo rootDirInfo, TreeNode root) + { + if (root.Nodes.Count > 0) root.Nodes.Clear(); + DirectoryInfo[] dirs = rootDirInfo.GetDirectories(); + foreach (DirectoryInfo dir in dirs) + { + TreeNode node = new TreeNode(dir.Name, 1, 1); + node.Tag = dir; + root.Nodes.Add(node); + node.ContextMenuStrip = cmsDir; + } + + FileInfo[] files = rootDirInfo.GetFiles(); + foreach (FileInfo file in files) + { + TreeNode node = new TreeNode(file.Name, 2, 2); + node.Tag = file; + root.Nodes.Add(node); + node.ContextMenuStrip = cmsFile; + } + + root.Expand(); + } + + private void tvTemplate_MouseClick(object sender, MouseEventArgs e) + { + if (e.Button == MouseButtons.Right) + { + TreeView tv = sender as TreeView; + TreeNode tn = tv.GetNodeAt(e.X, e.Y); + tv.SelectedNode = tn; + } + } + + private void tvTemplate_MouseDoubleClick(object sender, MouseEventArgs e) + { + TreeView tv = sender as TreeView; + TreeNode tn = tv.GetNodeAt(e.X, e.Y); + + if (tn.Tag is DirectoryInfo) + { + ExpendTemplateDir((DirectoryInfo)tn.Tag, tn); + } + if (tn.Tag is FileInfo) + { + FileInfo fi = tn.Tag as FileInfo; + OpenTemplateFile(fi.FullName); + } + } + + void OpenTemplateFile(string fileName) + { + foreach (IDockContent content in this.DockPanel.Documents) + { + if (content is DockDocument) + { + DockDocument doc = content as DockDocument; + if (doc.FileName == fileName) + { + doc.DockHandler.Activate(); + return; + } + } + } + + main.OpenDockDocument(fileName, CodeType.CSHARP); + } + + #region 右键菜单命令处理 + //新建模板文件 + private void menuItemNewTemplateFile_Click(object sender, EventArgs e) + { + TreeNode dirNode = tvTemplate.SelectedNode; + DirectoryInfo dir = dirNode.Tag as DirectoryInfo; + string fileName = "NewTemplate"; + + int n = 1; + while (true) + { + fileName = Path.Combine(dir.FullName,string.Format("NewTemplate{0}.tt", n)); + n = n + 1; + if (File.Exists(fileName) == false) break; + } + + File.WriteAllText(fileName, "<#@ template language=\"C#v3.5\" hostSpecific=\"true\" debug=\"true\" #>", Encoding.UTF8); + FileInfo fi = new FileInfo(fileName); + + TreeNode fileNode = new TreeNode(Path.GetFileName(fileName), 2, 2); + fileNode.Tag = fi; + fileNode.ContextMenuStrip = cmsFile; + dirNode.Nodes.Add(fileNode); + + tvTemplate.SelectedNode = fileNode; + fileNode.BeginEdit(); + } + //新建模板目录 + private void menuItemNewTemplateDir_Click(object sender, EventArgs e) + { + TreeNode dirNode = tvTemplate.SelectedNode; + DirectoryInfo dir = dirNode.Tag as DirectoryInfo; + string dirName = "NewFolder"; + + int n = 1; + while (true) + { + dirName = Path.Combine(dir.FullName, string.Format("NewFolder{0}", n)); + n = n + 1; + if (Directory.Exists(dirName) == false) break; + } + + Directory.CreateDirectory(dirName); + DirectoryInfo newDir = new DirectoryInfo(dirName); + + TreeNode newDirNode = new TreeNode(newDir.Name, 1, 1); + newDirNode.Tag = newDir; + newDirNode.ContextMenuStrip = cmsDir; + dirNode.Nodes.Add(newDirNode); + + tvTemplate.SelectedNode = newDirNode; + newDirNode.BeginEdit(); + } + //浏览模板目录 + private void menuItemBrowserDir_Click(object sender, EventArgs e) + { + DirectoryInfo di = tvTemplate.SelectedNode.Tag as DirectoryInfo; + Kalman.Command.CmdHelper.Execute(string.Format("explorer.exe {0}", di.FullName)); + } + //删除模板目录 + private void menuItemDeleteDir_Click(object sender, EventArgs e) + { + if (MessageBox.Show("确定删除该模板目录吗,这将会删除该目录下所有模板文件", "提示信息", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) == DialogResult.OK) + { + TreeNode dirNode = tvTemplate.SelectedNode; + tvTemplate.Nodes.Remove(dirNode); + DirectoryInfo di = dirNode.Tag as DirectoryInfo; + string dirName = di.FullName; + di.Delete(true); + + //删除模板目录时,同时关闭该目录下已打开的模板文档 + List deletingDocs = new List(); + foreach (IDockContent content in this.DockPanel.Documents) + { + if (content is DockDocument) + { + DockDocument doc = content as DockDocument; + //判断模板文档所属目录是否是该删除目录,若是则将其关闭 + if (Path.GetDirectoryName(doc.FileName) == dirName) + { + deletingDocs.Add(doc); + } + } + } + foreach (IDockContent content in deletingDocs) + { + content.DockHandler.Close(); + } + } + } + //重命名模板目录 + private void menuItemRenameDir_Click(object sender, EventArgs e) + { + tvTemplate.SelectedNode.BeginEdit(); + } + //刷新模板目录 + private void menuItemRefresh_Click(object sender, EventArgs e) + { + ExpendTemplateDir((DirectoryInfo)tvTemplate.SelectedNode.Tag, tvTemplate.SelectedNode); + } + //打开编辑模板文件 + private void menuItemEditTemplate_Click(object sender, EventArgs e) + { + FileInfo fi = tvTemplate.SelectedNode.Tag as FileInfo; + OpenTemplateFile(fi.FullName); + } + //删除模板文件 + private void menuItemDeleteTemplate_Click(object sender, EventArgs e) + { + if (MessageBox.Show("确定删除该模板文件吗", "提示信息", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) == DialogResult.OK) + { + TreeNode fileNode = tvTemplate.SelectedNode; + tvTemplate.Nodes.Remove(fileNode); + + FileInfo fi = fileNode.Tag as FileInfo; + string oldFileName = fi.FullName; + File.Delete(fi.FullName); + + //若删除的模板文档已经打开,则将其关闭 + IDockContent deletingDoc = null; + foreach (IDockContent content in this.DockPanel.Documents) + { + if (content is DockDocument) + { + DockDocument doc = content as DockDocument; + if (doc.FileName == oldFileName) + { + deletingDoc = doc; + break; + } + } + } + if (deletingDoc != null) deletingDoc.DockHandler.Close(); + } + } + //重命名模板文件 + private void menuItemRenameTemplate_Click(object sender, EventArgs e) + { + tvTemplate.SelectedNode.BeginEdit(); + } + #endregion + + private void tvTemplate_AfterLabelEdit(object sender, NodeLabelEditEventArgs e) + { + if(string.IsNullOrEmpty(e.Label))return; + + //节点重命名后,更新对应的Tag对象 + if (e.Label == e.Node.Text) return;//标签文本没有改变 + + if (e.Node.Tag is DirectoryInfo) + { + DirectoryInfo di = e.Node.Tag as DirectoryInfo; + string oldDirName = di.FullName; + string newDirName = Path.Combine(di.Parent.FullName, e.Label); + + di.MoveTo(newDirName); + e.Node.Tag = new DirectoryInfo(newDirName); + + //重命名模板目录后,需要更新该目录下已打开模板文档的FileName属性 + foreach (IDockContent content in this.DockPanel.Documents) + { + if (content is DockDocument) + { + DockDocument doc = content as DockDocument; + //判断模板文档所属目录是否是该删除目录,若是则将其关闭 + if (Path.GetDirectoryName(doc.FileName) == oldDirName) + { + doc.FileName = doc.FileName.Replace(oldDirName, newDirName); + } + } + } + } + if (e.Node.Tag is FileInfo) + { + FileInfo fi = e.Node.Tag as FileInfo; + string oldFileName = fi.FullName; + string newFileName = Path.Combine(fi.DirectoryName, e.Label); + + fi.MoveTo(newFileName); + e.Node.Tag = new FileInfo(newFileName); + + //如果被重命名的文件已经被打开,更新打开的文档实例 + foreach (IDockContent content in this.DockPanel.Documents) + { + if (content is DockDocument) + { + DockDocument doc = content as DockDocument; + if (doc.FileName == oldFileName) + { + doc.Text = Path.GetFileName(newFileName); + doc.FileName = newFileName; + //doc.DockHandler.Activate(); + break; + } + } + } + } + } + + #region 处理拖放操作 + + TreeNode srcNode = null; //拖放起始节点 + private void tvTemplate_ItemDrag(object sender, ItemDragEventArgs e) + { + TreeNode node = e.Item as TreeNode; + string data = string.Empty; + + if (node.Tag is FileInfo) + { + FileInfo fi = node.Tag as FileInfo; + data = fi.FullName; + } + else if (node.Tag is DirectoryInfo) + { + DirectoryInfo di = node.Tag as DirectoryInfo; + data = di.FullName; + } + else + { + return; + } + + srcNode = e.Item as TreeNode; + DoDragDrop(data, DragDropEffects.Move); + } + + private void tvTemplate_DragEnter(object sender, DragEventArgs e) + { + if (e.Data.GetDataPresent(DataFormats.Text)) + e.Effect = DragDropEffects.Move; + else + e.Effect = DragDropEffects.None; + } + + private void tvTemplate_DragDrop(object sender, DragEventArgs e) + { + //string path = (string)e.Data.GetData(DataFormats.Text); //拖放源节点的文件或目录路径 + + Point p = new Point(e.X, e.Y); + p = tvTemplate.PointToClient(p);//转换坐标 + TreeNode destNode = tvTemplate.GetNodeAt(p); + if (destNode == null) return; + if (destNode.Tag is FileInfo) return; //如果目标节点是文件节点则不处理拖放动作 + + if (destNode.Tag is DirectoryInfo) + { + DirectoryInfo destDir = destNode.Tag as DirectoryInfo; + + if (srcNode.Tag is FileInfo) + { + FileInfo srcFile = srcNode.Tag as FileInfo; + string srcFileName = srcFile.FullName; + string destFileName = srcFile.FullName.Replace(Path.GetDirectoryName(srcFile.FullName), destDir.FullName); + if (srcFile.DirectoryName == destDir.FullName) return; + + //如果被移动文件已经被打开,更新打开的文档实例 + //foreach (IDockContent content in this.DockPanel.Documents) + //{ + // if (content is DockDocument) + // { + // DockDocument doc = content as DockDocument; + // if (doc.FileName == srcFileName) + // { + // doc.FileName = destFileName; + // break; + // } + // } + //} + + srcFile.MoveTo(destFileName); + tvTemplate.Nodes.Remove(srcNode); + ExpendTemplateDir(destDir, destNode); + } + if (srcNode.Tag is DirectoryInfo) + { + DirectoryInfo srcDir = srcNode.Tag as DirectoryInfo; + string srcDirName = srcDir.FullName; + string destDirName = srcDir.FullName.Replace(srcDir.Parent.FullName, destDir.FullName); + if (srcDir.FullName == destDir.FullName) return; + + //移动模板目录后,需要更新该目录下已打开模板文档的FileName属性 + //foreach (IDockContent content in this.DockPanel.Documents) + //{ + // if (content is DockDocument) + // { + // DockDocument doc = content as DockDocument; + // //判断模板文档所属目录是否是该删除目录,若是则将其关闭 + // if (Path.GetDirectoryName(doc.FileName) == srcDirName) + // { + // doc.FileName = doc.FileName.Replace(srcDir.FullName, destDirName); + // } + // } + //} + + srcDir.MoveTo(destDirName); + tvTemplate.Nodes.Remove(srcNode); + ExpendTemplateDir(destDir, destNode); + } + } + } + + #endregion + + } +} diff --git a/src/Kalman.Studio/ExplorerForm/TemplateExplorer.designer.cs b/src/Kalman.Studio/ExplorerForm/TemplateExplorer.designer.cs new file mode 100644 index 0000000..db568ea --- /dev/null +++ b/src/Kalman.Studio/ExplorerForm/TemplateExplorer.designer.cs @@ -0,0 +1,205 @@ +namespace Kalman.Studio +{ + partial class TemplateExplorer + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(TemplateExplorer)); + this.tvTemplate = new System.Windows.Forms.TreeView(); + this.imgList = new System.Windows.Forms.ImageList(this.components); + this.cmsDir = new System.Windows.Forms.ContextMenuStrip(this.components); + this.menuItemNew = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemNewTemplateFile = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemNewTemplateDir = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemBrowserDir = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemDeleteDir = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemRenameDir = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemRefresh = new System.Windows.Forms.ToolStripMenuItem(); + this.cmsFile = new System.Windows.Forms.ContextMenuStrip(this.components); + this.menuItemEditTemplate = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemDeleteTemplate = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemRenameTemplate = new System.Windows.Forms.ToolStripMenuItem(); + this.cmsDir.SuspendLayout(); + this.cmsFile.SuspendLayout(); + this.SuspendLayout(); + // + // tvTemplate + // + this.tvTemplate.AllowDrop = true; + this.tvTemplate.Dock = System.Windows.Forms.DockStyle.Fill; + this.tvTemplate.ImageIndex = 0; + this.tvTemplate.ImageList = this.imgList; + this.tvTemplate.LabelEdit = true; + this.tvTemplate.Location = new System.Drawing.Point(0, 0); + this.tvTemplate.Name = "tvTemplate"; + this.tvTemplate.SelectedImageIndex = 0; + this.tvTemplate.Size = new System.Drawing.Size(230, 537); + this.tvTemplate.TabIndex = 0; + this.tvTemplate.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.tvTemplate_MouseDoubleClick); + this.tvTemplate.MouseClick += new System.Windows.Forms.MouseEventHandler(this.tvTemplate_MouseClick); + this.tvTemplate.AfterLabelEdit += new System.Windows.Forms.NodeLabelEditEventHandler(this.tvTemplate_AfterLabelEdit); + this.tvTemplate.DragDrop += new System.Windows.Forms.DragEventHandler(this.tvTemplate_DragDrop); + this.tvTemplate.DragEnter += new System.Windows.Forms.DragEventHandler(this.tvTemplate_DragEnter); + this.tvTemplate.ItemDrag += new System.Windows.Forms.ItemDragEventHandler(this.tvTemplate_ItemDrag); + // + // imgList + // + this.imgList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imgList.ImageStream"))); + this.imgList.TransparentColor = System.Drawing.Color.Transparent; + this.imgList.Images.SetKeyName(0, "templateRoot.png"); + this.imgList.Images.SetKeyName(1, "templateDir.png"); + this.imgList.Images.SetKeyName(2, "templateFile.png"); + // + // cmsDir + // + this.cmsDir.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.menuItemNew, + this.menuItemBrowserDir, + this.menuItemDeleteDir, + this.menuItemRenameDir, + this.menuItemRefresh}); + this.cmsDir.Name = "cmsDir"; + this.cmsDir.Size = new System.Drawing.Size(123, 114); + // + // menuItemNew + // + this.menuItemNew.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.menuItemNewTemplateFile, + this.menuItemNewTemplateDir}); + this.menuItemNew.Name = "menuItemNew"; + this.menuItemNew.Size = new System.Drawing.Size(122, 22); + this.menuItemNew.Text = "新建"; + // + // menuItemNewTemplateFile + // + this.menuItemNewTemplateFile.Name = "menuItemNewTemplateFile"; + this.menuItemNewTemplateFile.Size = new System.Drawing.Size(122, 22); + this.menuItemNewTemplateFile.Text = "模板文件"; + this.menuItemNewTemplateFile.Click += new System.EventHandler(this.menuItemNewTemplateFile_Click); + // + // menuItemNewTemplateDir + // + this.menuItemNewTemplateDir.Name = "menuItemNewTemplateDir"; + this.menuItemNewTemplateDir.Size = new System.Drawing.Size(122, 22); + this.menuItemNewTemplateDir.Text = "模板目录"; + this.menuItemNewTemplateDir.Click += new System.EventHandler(this.menuItemNewTemplateDir_Click); + // + // menuItemBrowserDir + // + this.menuItemBrowserDir.Name = "menuItemBrowserDir"; + this.menuItemBrowserDir.Size = new System.Drawing.Size(122, 22); + this.menuItemBrowserDir.Text = "浏览目录"; + this.menuItemBrowserDir.Click += new System.EventHandler(this.menuItemBrowserDir_Click); + // + // menuItemDeleteDir + // + this.menuItemDeleteDir.Name = "menuItemDeleteDir"; + this.menuItemDeleteDir.Size = new System.Drawing.Size(122, 22); + this.menuItemDeleteDir.Text = "删除"; + this.menuItemDeleteDir.Click += new System.EventHandler(this.menuItemDeleteDir_Click); + // + // menuItemRenameDir + // + this.menuItemRenameDir.Name = "menuItemRenameDir"; + this.menuItemRenameDir.Size = new System.Drawing.Size(122, 22); + this.menuItemRenameDir.Text = "重命名"; + this.menuItemRenameDir.Click += new System.EventHandler(this.menuItemRenameDir_Click); + // + // menuItemRefresh + // + this.menuItemRefresh.Name = "menuItemRefresh"; + this.menuItemRefresh.Size = new System.Drawing.Size(122, 22); + this.menuItemRefresh.Text = "刷新"; + this.menuItemRefresh.Click += new System.EventHandler(this.menuItemRefresh_Click); + // + // cmsFile + // + this.cmsFile.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.menuItemEditTemplate, + this.menuItemDeleteTemplate, + this.menuItemRenameTemplate}); + this.cmsFile.Name = "cmsFile"; + this.cmsFile.Size = new System.Drawing.Size(111, 70); + // + // menuItemEditTemplate + // + this.menuItemEditTemplate.Name = "menuItemEditTemplate"; + this.menuItemEditTemplate.Size = new System.Drawing.Size(110, 22); + this.menuItemEditTemplate.Text = "编辑"; + this.menuItemEditTemplate.Click += new System.EventHandler(this.menuItemEditTemplate_Click); + // + // menuItemDeleteTemplate + // + this.menuItemDeleteTemplate.Name = "menuItemDeleteTemplate"; + this.menuItemDeleteTemplate.Size = new System.Drawing.Size(110, 22); + this.menuItemDeleteTemplate.Text = "删除"; + this.menuItemDeleteTemplate.Click += new System.EventHandler(this.menuItemDeleteTemplate_Click); + // + // menuItemRenameTemplate + // + this.menuItemRenameTemplate.Name = "menuItemRenameTemplate"; + this.menuItemRenameTemplate.Size = new System.Drawing.Size(110, 22); + this.menuItemRenameTemplate.Text = "重命名"; + this.menuItemRenameTemplate.Click += new System.EventHandler(this.menuItemRenameTemplate_Click); + // + // TemplateExplorer + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(230, 537); + this.Controls.Add(this.tvTemplate); + this.DockAreas = ((WeifenLuo.WinFormsUI.Docking.DockAreas)((WeifenLuo.WinFormsUI.Docking.DockAreas.DockLeft | WeifenLuo.WinFormsUI.Docking.DockAreas.DockRight))); + this.HideOnClose = true; + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "TemplateExplorer"; + this.Text = "模板资源管理器"; + this.Load += new System.EventHandler(this.TemplateExplorer_Load); + this.cmsDir.ResumeLayout(false); + this.cmsFile.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.TreeView tvTemplate; + private System.Windows.Forms.ImageList imgList; + private System.Windows.Forms.ContextMenuStrip cmsDir; + private System.Windows.Forms.ContextMenuStrip cmsFile; + private System.Windows.Forms.ToolStripMenuItem menuItemNew; + private System.Windows.Forms.ToolStripMenuItem menuItemNewTemplateDir; + private System.Windows.Forms.ToolStripMenuItem menuItemNewTemplateFile; + private System.Windows.Forms.ToolStripMenuItem menuItemBrowserDir; + private System.Windows.Forms.ToolStripMenuItem menuItemDeleteDir; + private System.Windows.Forms.ToolStripMenuItem menuItemRenameDir; + private System.Windows.Forms.ToolStripMenuItem menuItemRefresh; + private System.Windows.Forms.ToolStripMenuItem menuItemEditTemplate; + private System.Windows.Forms.ToolStripMenuItem menuItemDeleteTemplate; + private System.Windows.Forms.ToolStripMenuItem menuItemRenameTemplate; + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/ExplorerForm/TemplateExplorer.resx b/src/Kalman.Studio/ExplorerForm/TemplateExplorer.resx new file mode 100644 index 0000000..c3c35d5 --- /dev/null +++ b/src/Kalman.Studio/ExplorerForm/TemplateExplorer.resx @@ -0,0 +1,356 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj0yLjAuMC4w + LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 + ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAACK + CgAAAk1TRnQBSQFMAgEBAwEAAQQBAAEEAQABEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo + AwABQAMAARADAAEBAQABCAYAAQQYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA + AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5 + AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA + AWYDAAGZAwABzAIAATMDAAIzAgABMwFmAgABMwGZAgABMwHMAgABMwH/AgABZgMAAWYBMwIAAmYCAAFm + AZkCAAFmAcwCAAFmAf8CAAGZAwABmQEzAgABmQFmAgACmQIAAZkBzAIAAZkB/wIAAcwDAAHMATMCAAHM + AWYCAAHMAZkCAALMAgABzAH/AgAB/wFmAgAB/wGZAgAB/wHMAQABMwH/AgAB/wEAATMBAAEzAQABZgEA + ATMBAAGZAQABMwEAAcwBAAEzAQAB/wEAAf8BMwIAAzMBAAIzAWYBAAIzAZkBAAIzAcwBAAIzAf8BAAEz + AWYCAAEzAWYBMwEAATMCZgEAATMBZgGZAQABMwFmAcwBAAEzAWYB/wEAATMBmQIAATMBmQEzAQABMwGZ + AWYBAAEzApkBAAEzAZkBzAEAATMBmQH/AQABMwHMAgABMwHMATMBAAEzAcwBZgEAATMBzAGZAQABMwLM + AQABMwHMAf8BAAEzAf8BMwEAATMB/wFmAQABMwH/AZkBAAEzAf8BzAEAATMC/wEAAWYDAAFmAQABMwEA + AWYBAAFmAQABZgEAAZkBAAFmAQABzAEAAWYBAAH/AQABZgEzAgABZgIzAQABZgEzAWYBAAFmATMBmQEA + AWYBMwHMAQABZgEzAf8BAAJmAgACZgEzAQADZgEAAmYBmQEAAmYBzAEAAWYBmQIAAWYBmQEzAQABZgGZ + AWYBAAFmApkBAAFmAZkBzAEAAWYBmQH/AQABZgHMAgABZgHMATMBAAFmAcwBmQEAAWYCzAEAAWYBzAH/ + AQABZgH/AgABZgH/ATMBAAFmAf8BmQEAAWYB/wHMAQABzAEAAf8BAAH/AQABzAEAApkCAAGZATMBmQEA + AZkBAAGZAQABmQEAAcwBAAGZAwABmQIzAQABmQEAAWYBAAGZATMBzAEAAZkBAAH/AQABmQFmAgABmQFm + ATMBAAGZATMBZgEAAZkBZgGZAQABmQFmAcwBAAGZATMB/wEAApkBMwEAApkBZgEAA5kBAAKZAcwBAAKZ + Af8BAAGZAcwCAAGZAcwBMwEAAWYBzAFmAQABmQHMAZkBAAGZAswBAAGZAcwB/wEAAZkB/wIAAZkB/wEz + AQABmQHMAWYBAAGZAf8BmQEAAZkB/wHMAQABmQL/AQABzAMAAZkBAAEzAQABzAEAAWYBAAHMAQABmQEA + AcwBAAHMAQABmQEzAgABzAIzAQABzAEzAWYBAAHMATMBmQEAAcwBMwHMAQABzAEzAf8BAAHMAWYCAAHM + AWYBMwEAAZkCZgEAAcwBZgGZAQABzAFmAcwBAAGZAWYB/wEAAcwBmQIAAcwBmQEzAQABzAGZAWYBAAHM + ApkBAAHMAZkBzAEAAcwBmQH/AQACzAIAAswBMwEAAswBZgEAAswBmQEAA8wBAALMAf8BAAHMAf8CAAHM + Af8BMwEAAZkB/wFmAQABzAH/AZkBAAHMAf8BzAEAAcwC/wEAAcwBAAEzAQAB/wEAAWYBAAH/AQABmQEA + AcwBMwIAAf8CMwEAAf8BMwFmAQAB/wEzAZkBAAH/ATMBzAEAAf8BMwH/AQAB/wFmAgAB/wFmATMBAAHM + AmYBAAH/AWYBmQEAAf8BZgHMAQABzAFmAf8BAAH/AZkCAAH/AZkBMwEAAf8BmQFmAQAB/wKZAQAB/wGZ + AcwBAAH/AZkB/wEAAf8BzAIAAf8BzAEzAQAB/wHMAWYBAAH/AcwBmQEAAf8CzAEAAf8BzAH/AQAC/wEz + AQABzAH/AWYBAAL/AZkBAAL/AcwBAAJmAf8BAAFmAf8BZgEAAWYC/wEAAf8CZgEAAf8BZgH/AQAC/wFm + AQABIQEAAaUBAANfAQADdwEAA4YBAAOWAQADywEAA7IBAAPXAQAD3QEAA+MBAAPqAQAD8QEAA/gBAAHw + AfsB/wEAAaQCoAEAA4ADAAH/AgAB/wMAAv8BAAH/AwAB/wEAAf8BAAL/AgAD/wsAASoBKRkAAioB8QEH + AZIBrgFsARIDZhcAAVEBKQEcATEBMAF0ASkBcxMAAyoBmgF6AyoB8wEJAbsCtQFmEAABBwOuAewB7wG8 + ASkBegEpAnoBKQGgASkB7wcAAbUIZgEAAUsBeQExASoBmgF6ASoBMQF5ASoB8wEZAd0BtQFmEAAB9wH/ + BPMB9AGZASkBegIqAaABKQGZAfEHAAG1Af8F9AEZAWYBAAFLAXkBMQEqAZoBegEqATEBeQEqAfMBBwG7 + AbUBZhAAAfcF/wEwASkBegEpAv8BKgGgATABKQQAAbUCZgG1Af8CtQH/AbUBtAH0AWYCSwGaAXoBUgF6 + AXkBUgJ6AioB8wEZAbUBZhAAAfcF/wExATABegEpAv8BKgF6ATEBMAQAAbUB/wH0AbUE/wP0AWYBSwEx + ASoBmgGgBJoBKgExASoB8AEHAbUBZhAAAfcG/wGZASkBegIpAXoBKQGZAfEBAAG1AmYBtQH/AbUB7wH/ + AbsB7wH/ArUB9AFmAUsEoAJ0AZoDoAEqAfMBGQG7AWYQAAH3Bv8BKQF6ASkCegEpAXoBKQG8AQABtQH/ + AfQBtQL/Ae8H/wFmARwCSwF5AXQCegF0AXkBKgFLAQcB8wEZAQkBZhAAAfcG/wF0ASkBmQEwASkBmQEp + AXQBBwEAAbUB/wG1Ae8B/wK7Af8CBwH/AbsBtQH/AWYBAAFLAnkBoAJ0AaACeQEqAf8C8wEJAWYQAAH3 + Cf8BMQEwAv8BGQH3AQABtQL/Ae8C/wG7B/8BZgEAARwDSwGgAZoDSwGZAf8C8wG8AWYQAAH3DP8B9AEZ + AewBAAHvAf8CuwH/AQcCuwTvA7UCAAHwAf8BBwJLARwC8AL/AfQB8wG8AWYQAAH3Dv8BrgEAAe8C/wG7 + B/8BZgUAAe8B/wTwAfcB6wRtAfABZhAAAQcB9wT/Ca4B9wEAAbsB/wEHArsE7wO1BQAB7wv/ARkBZhEA + AfcE/wH3AQAB9wQJAesDAAG7B/8BZggAAbsB/wVtBf8BGQFmEQABBwT3AQcBAAEHBPcBBwMAArsE7wO1 + CAABuwz/AWYyAAW7BO8EtQH3EAABQgFNAT4HAAE+AwABKAMAAUADAAEQAwABAQEAAQEFAAGAFwAD/wEA + Af8BzwL/AfgDAAH+AQEC/wHABQAB/gEAAYAFAAH+AQABgAUAAfAHAAHwBwABgAcAAYAHAAGAAQABgAUA + AYABAAGABQABgAEAAcAFAAGAAQcBwAUAAYABBwHAAwABgQEDAYABPwHAAwABgQEDAYABPwHAAwAE/wHA + AwAL + + + + 112, 17 + + + 201, 17 + + + + + AAABAAYAICAQAAEABADoAgAAZgAAABAQEAABAAQAKAEAAE4DAAAgIAAAAQAIAKgIAAB2BAAAEBAAAAEA + CABoBQAAHg0AACAgAAABACAAqBAAAIYSAAAQEAAAAQAgAGgEAAAuIwAAKAAAACAAAABAAAAAAQAEAAAA + AAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAIAAAACAgACAAAAAgACAAICAAACAgIAAwMDAAAAA + /wAA/wAAAP//AP8AAAD/AP8A//8AAP///wAAAAAAAAAAAAAAAAAAAAAAAHR0dHR0dHZWd3d3YAAAAAB4 + iIiIiIh4iIiIj0YAAAAAeP+PiIiI+I+I//hlYAAAAHj/j//4+Pj2xkZGx8cAAAB4+IjojojoiIjnd8hm + wAAAeP//+P+I/46HjI58fHYAAH/4+P+Pj4/3iI6Mjn5WcAB4+IiIiIiIh46IeOfIxwAAf///j4+Ij46I + iIh4fnAAAHj/j//4//j4d3zsjnwAAAB/+Ijojo6IiIiP/3jAAAAAf//////4+Ij4/498AAAAAH////+P + /4//j4+IgAAAAAB/+IiIiIiI6OjoiHAAAAAAf/////j4iPiPiPhgAAAAAH////////+P+Pj4QAAAAAB/ + +Ijojojoh4eM+GAAAAAAf//////4+PiPj/hAAAAAAI////////////j4YAAAAAB/+IiIiIiHjnfniEAA + AAAAj/////j4/4////hgAAAAAH//////////+Pj4UAAAAACP+IiIiI6P////iGAAAAAAf//////////4 + iHdgAAAAAI//////////90ZHQAAAAACP//////////eIhwAAAAAAj//////////3iHAAAAAAAI////// + ////9/cAAAAAAACP////j4+PiPdwAAAAAAAAh4eHh4eHh4d4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + ///AAAB/wAAAP8AAAB/AAAAPwAAAB8AAAAPAAAABwAAAA8AAAAfAAAAPwAAAH8AAAD/AAAB/wAAAf8AA + AH/AAAB/wAAAf8AAAH/AAAB/wAAAf8AAAH/AAAB/wAAAf8AAAH/AAAB/wAAA/8AAAf/AAAP/wAAH/8AA + D///////KAAAABAAAAAgAAAAAQAEAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAIAAAACA + gACAAAAAgACAAICAAACAgIAAwMDAAAAA/wAA/wAAAP//AP8AAAD/AP8A//8AAP///wAAAAAAAABgAACE + dGd4eEcAAH+IiPbHbHAAj///+IyOxwB/iIiMjnjAAI//+P/4fAAAj4jojo+AAAB///+P+IAAAI+IiHeI + cAAAj//4//hAAACPiI5/iGAAAI////dkcAAAj///+ISAAACP///3aAAAAIiIiIiAAAAAAAAAAAAAAP/3 + AADAAwAAwAEAAMAAAADAAQAAwAMAAMAHAADABwAAwAcAAMAHAADABwAAwAcAAMAHAADADwAAwB8AAP// + AAAoAAAAIAAAAEAAAAABAAgAAAAAAAAEAAAAAAAAAAAAAAABAAAAAQAAAAAAAGNJNQBkSjcAZ006AGpR + PgBvV0UAdV9NAHdgTwB6ZFMAfmlZAJJHIwCdTSYAkk4tAJRPLgCdTigAl1AvAJlSMACgUSsApVYvAKhS + KACqWzQAsmA4ALViOQCyYzwAuGM7ALtlPAC9aD8AgWhWAIRrWQCGblsAiXBeALprQwCGcmMAi3NhAI12 + ZACPeGcAjHlrAJJ7aQCVfm0Aj35wAMVrQADJbkEAzXFFAMBxSgDFdk4A2XhIAN16SgDYfE0A4H1MAJiC + cQCbhHMAnYd2AJ+JeQCZiXwAoIl5AKSKeACijHsAoox8AKSOfgDhg1UA6oNQAO2FUgDhi14A8YlVAPeO + WQD6kFsA/JJdANmNZwDbkGoA3ZFrANqabgDbnHEA3J90AOGTagDglG4A/5diAP+ZZQD/nWkA45dxAOWZ + cwDmmnQA6Jx2AN6ieQDepX0A/6BtAOClfgD/onAA/6RyAP+pegD/q30AppGBAKmUhACslocAopSJAK2Z + iQCymYkAsJuNALKdjgC1nY4As5+QALWgkgC3opQAuKOUALmllgC9pZcAuqaYALynmgC8qJoAvqqcAN6n + gADArJ8A1rGeAOGlhADhqIMA46uGAOStiQD/rYAA5rGPAP+yiQD/tY0A5rKQAOm1lQDot5gA6rmaAP+6 + lQD/vJgAwq6gAMWxowDHsaUAybSpANezoQDYs6EA2LWjANi3pQDauqkA27yrANu8rADcva0A6b2hAO29 + oAD/wJ8A3cGxAN3CtQDfxLYA1cW8AN/GugDpwKQA78GmAOvFrAD/wqIA8cWrAP/GqAD/yq4A68ixAOzJ + sgDgx7gA88iwAPXLtQD2zrgA69G/AOzRvQD30LsA5M3DAObSxwDu08EA7NXCAObVywDt2MkA9NvOAPTc + zwDj2tMA6NnRAO/e0QD03dEA9N7UAO3i2wD14NYA9uLZAPbk2wDy5N0A9uXdAPjl3QDv5+MA7+jkAPLn + 4QD35+AA+OfgAPbp4gD26uUA9+zmAPjp4QD46uQA+ezmAPbt6ADz7+0A9e/sAPnu6AD38u8A+vDqAPry + 7QD88u0A+/TwAPz18gD89vQA/fj2AP36+QD+/PoA/v7+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAbAQEBAQEBAQEBAQEDBAUGCAkgJzVdCgAAAAAAAAAAAByojYmJiYWF + hYJvb2+FhYmNjZGipqsKDgAAAAAAAAAAHK3EwMC0tbStra2tqKittLS0tsHFtwsMDgAAAAAAAAAercfA + wMC1tbS0ra2ttLRDCgoKCgoLExUMDgAAAAAAACGwx6Genpyci4uLeouUn0VwST47LyoaKBUPEQAAAAAA + IbTJx8TEwLW6tLC0tLS8SZV2WFRLQDwvKRgPEQAAAAAjtMnJycTEwMC1tLS0vLxOmHx2WFZMQTwvKRgQ + FAAAACW1zKGenZ6Tk4uLeYuZn1CYlX12dFZMQj8wKhgAAAAAJcDMzMnJx8TAwLS5vMC8UJiYnZeVfHZN + Qj8fAAAAAAAlwM7OzMnJx8fAwMC0vLxQUFBJTkVDRXZNKwAAAAAAADLAzqGhnpyck4t6eXqLi5mfn6ir + x7ZFfSwAAAAAAAAAMsTOzs7JzsfHx8fAwLy8wMC8vMDBr1ArAAAAAAAAAAAyx87Ozs7OyczHx8TAwL65 + ubm5ubSjUAAAAAAAAAAAADbHzqGhnpyck4uLeXVzcnJTU1NTtI0kAAAAAAAAAAAANsnOzs7Ozs7MycnH + x8TAvL61tLSwjQcAAAAAAAAAAAA6zM7Ozs7Ozs7OycnJx8TAvr6xtLCJBAAAAAAAAAAAAFrMzqGhoZ6U + k4uLeXlyclVSSEZGtIkBAAAAAAAAAAAAW87Ozs7Ozs7Ozs7JzMnHx8DAwL61iQEAAAAAAAAAAABbzs7O + zs7Ozs7Ozs7OycnHx8TAwLWJAQAAAAAAAAAAAGDOzqGhoZ6UnIuLeXNzclVTSEZGwIkBAAAAAAAAAAAA + YM7Ozs7Ozs7Ozs7Ozs7OycnHx8DAjQEAAAAAAAAAAABjzs7Ozs7Ozs7Ozs7Ozs7OycnHx8CPAQAAAAAA + AAAAAGTOzqGhoZ6UnIuLeXjOzs7MycnHx48BAAAAAAAAAAAAZs7Ozs7Ozs7Ozs7Ozs7Ozs7MgWZgNwEA + AAAAAAAAAABpzs7Ozs7Ozs7Ozs7Ozs7OzjIDAQEBAQAAAAAAAAAAAGvOzs7Ozs7Ozs7Ozs7Ozs7ONpCA + YDcAAAAAAAAAAAAAa87Ozs7Ozs7Ozs7Ozs7Ozs42qpA3AAAAAAAAAAAAAAB+zs7Ozs7Ozs7Ozs7Ozs7O + zlrFMgAAAAAAAAAAAAAAAH7Ozs7Ozs7OzsnJycTEwLy0WlsAAAAAAAAAAAAAAAAAfn5+fm5ra2lmZ2Rj + Y2BgXFtbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////wAAAf8AA + AD/AAAAfwAAAD8AAAAfAAAADwAAAAcAAAAPAAAAHwAAAD8AAAB/AAAA/wAAAf8AAAH/AAAB/wAAAf8AA + AH/AAAB/wAAAf8AAAH/AAAB/wAAAf8AAAH/AAAB/wAAAf8AAAP/AAAH/wAAD/8AAB//AAA///////ygA + AAAQAAAAIAAAAAEACAAAAAAAAAEAAAAAAAAAAAAAAAEAAAABAAAAAAAAY0k1AGRKNgCaSyUAnU4oAKFP + JwCnUigArlgrAKJWMQC/aj8AgWxcAIp3aADGbkEAxXZOAM+DXQDlhFMA8oxZAPyTXgDckGoA25pyAPea + awDlmXMA6Jx2AP2leAChkoYArJiJALeikwC5pJUAsaWbAL6pmgDAq5wAw66eAOGlgQDiqYYA4q2NAOSz + lQDptZcAyLKjAMmzpADMtqcAz7mpANG7qwDUvq4A3r+vAOi8oQDUwrYA2MKyANTFugDxxawA5Mu+AO3N + uQD30LsA5s/DAOvZzwDu39cA8OTeAPHn4QDy6OIA8+rlAPTr5gD07ekA9u/sAPfx7gD59fIA+vf1APz6 + +QD9/PsA/v7+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AAAAAAAAAAAAAAAAAAwAAAAAA + GgEBAQEKGBwcHAUEAAAAABr/KysrNDYOAwUGCQgAAAAa////PT09EhcREA8MBwAAGv8zMCQsMhYSDg4U + BwAAABr/////Pz49OjYVDQAAAAAb/zMwJCEiIzc2FgAAAAAAHf//////Pzo4NRwAAAAAAB//MzAkIBMT + OjELAAAAAAAl////////QDorAQAAAAAAJf8zMCQgE/8rKwEAAAAAACn///////8aAQEBAAAAAAAp//// + ////Gy8BGQAAAAAAK////////x8BGQAAAAAAAC4uLisuKSglLgAAAAAAAAAAAAAAAAAAAAAAAAAAAP/3 + AADAAwAAwAEAAMAAAADAAQAAwAMAAMAHAADABwAAwAcAAMAHAADABwAAwAcAAMAHAADADwAAwB8AAP// + AAAoAAAAIAAAAEAAAAABACAAAAAAAIAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACMRCEBjEoqFYlsXgN8eHYBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIFo + Vv9jSTX/Y0k1/2NJNf9jSTX/Y0k1/2NJNf9jSTX/Y0k1/2NJNf9jSTX/ZEo3/2dNOv9qUT7/b1dF/3Vf + Tf96ZFP/fmlZ/4ZyY/+PfnD/mYl8/6KUif+SRyP/jlY6M4JuYwgAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAhGtZ//Tbzv/ewLH/3L6u/9u8rP/bu6r/2bmo/9i3pf/YtaP/17Oh/9axn//WsZ3/1rGf/9iz + of/Yt6b/3Lyt/93Bsv/dwrX/38a6/+TNw//m1cv/6NnR/5JHI/+dTij/jFM3NX9iVAMAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACGblv/9NzR//ru6f/57Ob/+erj//fn3//45dz/9+Pa//bg1//139T/9N3R//Tc + z//028//9NzQ//Te1P/14tn/9eXd//Lk3f/y5+H/9e3p//fy7//v6OT/nU0m/5JOLf+dTij/jEgnKYxE + IQEAAAAAAAAAAAAAAAAAAAAAAAAAAIlwXv/139P/+vDs//nu6P/56+b/+eni//jn3//45dz/9uPa//Xh + 1v/13tT/9d7T//Xe0//14df/9uXd/9mNZ/+SRyP/kkcj/5JHI/+SRyP/kkcj/51NJv+oUij/smA4/5RP + Lv+dTij/n1c0MIxEIQEAAAAAAAAAAAAAAAAAAAAAi3Nh//bg1v/78u7/99C7//bOuP/1y7X/88iw//HF + q//vwab/7b2g/+u5mv/quZr/6byg/+vFrP/u08H/3ZFr/+GlhP/hk2r/4Yte/+GDVf/YfE3/zHJG/71o + P//Fa0D/tWI5/5VPL/+gUSv/rWZDQK6IdgIAAAAAAAAAAAAAAACNdmT/9uLY//z08v/88+7/+/Dr//rt + 6P/67OX/+Onh//jm3//35Nz/9uLZ//bj2P/349r/9+fg//Tq5v/glG7//8Oj//+yiP//qXr//6Bt//+X + Yv/3jln/6oNQ/9l4SP/IbUH/uGM7/5dQL/+lVi//sHBPOdLNygIAAAAAAAAAAI94Z//35Nv//Pb0//z0 + 8f/78+7/+vDr//ru6P/56+X/+enh//jn3//35Nz/9uTb//fl3f/36eL/9evn/+OXcf//ya3//7uW//+z + iv//q33//6Jw//+ZZP/6kFv/7YVS/916Sv/Lb0L/u2U8/5lSMP+qWzT/2LusAwAAAAAAAAAAkntp//jm + 3v/9+fb/99C7//bOuP/1y7X/88iw//HFq//vwab/7b2g/+u5mv/quZv/6r+j/+zJsv/r0b//5pp0///L + r///waH//7yY//+1jf//rYD//6Ry//+aZv/8kVz/8IhU/+B9TP/PcUT/smM8/+SigS3PzMsBAAAAAAAA + AACVfWz/+Ojh//76+f/9+Pb//Pbz//v08f/78u3/+u/r//ru5//56+X/+Onh//jn4P/36OH/+Ork//Xp + 4//onHb//8uv///Lr///y6///8ao///An///uZT//7OI//+caP/9k17/8opW/7prQ//jpYUw0c3LAQAA + AAAAAAAAAAAAAJZ/b//56uP//vz6//76+P/9+PX//Pbz//v08f/88e3/+vDq//rt5//56uT/+Ori//fq + 4v/36uP/9+vl/+icdv/onHb/5pp0/+OXcf/glG7/3ZFr/9mNZ//bkGr//7OL//+ea//AcUr/46ODLtHM + yQIAAAAAAAAAAAAAAAAAAAAAmIJx//ns5v///f3/99C7//bOuP/1y7X/88iw//HFq//vwab/7b2g/+u5 + mv/pt5j/6LeY/+i6m//pwKT/68ix/+zRvf/s1cL/7djJ/+/e0f/17+z/7+fj/9uQav//vZn/xXZO/+Wf + eyjQzMoBAAAAAAAAAAAAAAAAAAAAAAAAAACbhHP/+u7o///+/v/+/f3//vv6//35+P/9+Pb//fby//v0 + 8P/78u3/+u/q//rt5//56+X/+Orj//fq4v/46eP/9+rj//fq5P/36uT/9+zm//ft6P/t4tv/5Zlz/8V2 + Tv/nm3UmAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJ2Hdv/68ev////////+/v/+/fz//vv6//36 + +P/9+Pb//Pbz//v08P/78u3/+u/q//nt5//46+T/+Ori//fp4f/359//9+ff//fn3v/25t//9uff/+bS + x//lmXP/55pzIwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAn4l5//vy7v//////99C7//bO + uP/1y7X/88iw//HFq//vwab/7b2g/+u5mv/ptZX/5rKQ/+Sui//jq4b/4aiD/9+ngP/epX3/3qV+/96n + gf/249r/38W3/4x5a/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACijHv/+/Tx//// + ///////////////+/v/+/fz//vv6//359//99/X//PXy//vz7//78u3/+u/p//ns5//46uP/+Ojg//jm + 3f/349v/9uLa//bh1//cvq7/d2BP/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKSO + fv/89vP////////////////////////+/v/+/Pz//vv6//359//89/X//PXy//vz7//78ez/+u/p//ns + 5v/46uP/+Ojg//jl3P/249v/9uLY/9u8q/9rUj//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAppGB//349v//////99C7//bOuP/1y7X/88iw//HFq//vwab/7b2g/+u5mv/ptZX/5rGP/+St + if/iqYP/4KV+/96ief/cn3T/25xx/9qab//349r/27ur/2VLN/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACqlIT//vn4//////////////////////////////////79/f/+/fz//vv5//35 + 9//9+PT//PXy//vz7//68ez/+u/o//nt5v/46uL/+Ojg//jl3P/bvKz/Y0k1/wAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAKyWh//++/r////////////////////////////////////////9 + /v/+/Pv//vv6//359v/99/T//PXy//vz7v/78Oz/+e7p//rs5v/56uP/+Off/9y+rv9jSTX/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAArpmK//78/P//////99C7//bOuP/1y7X/88iw//HF + q//vwab/7b2g/+u5mv/ptZX/5rGP/+Stif/iqYP/4KV+/96ief/cn3T/25xx/9qabv/56eL/3cGx/2NJ + Nf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACxnI3///79//////////////////// + //////////////////////////7////+/f/+/fv//fv5//359//89vT//PTx//vy7v/78Ov/+u7o//nr + 5f/fwrP/Y0k1/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALOej/////////////// + //////////////////////////////////////////////7+/f/+/Pv//vv5//359//89/T//PTx//vy + 7v/78Ov/+u7o/9/Etv9jSTX/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtaCS//// + ////////99C7//bOuP/1y7X/88iw//HFq//vwab/7b2g/+u5mv/ptZX/5rGP///+/P/+/Pv//vr4//35 + 9v/89vT//PXx//vz7f/68Ov/4Me4/2NJNf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAC4o5T///////////////////////////////////////////////////////////////////7+///+ + /P/++/v//vr5//349v/JtKn/vaWX/7KZif+kinj/Y0k1/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAALqmmP////////////////////////////////////////////////////////////// + ///////////+//79/P/+/Pv/nod2/2NJNf9jSTX/Y0k1/2NJNf9jSTX/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAvKia//////////////////////////////////////////////////// + ///////////////////////////////9/P+giXn/1cW9/8expf+1nY7/nod2/wAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC+qpz///////////////////////////////////////// + ///////////////////////////////////////////+/6KMfP/j2tP/1cW8/56Hdv8AAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMCtn/////////////////////////////// + ////////////////////////////////////////////////////////pY5+//Pv7f+eh3b/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwq+h//////////////////// + /////fz//vv7//35+P/9+PX//PXy//vz7//78Ov/+u3o//nr5P/46eL/9+fd//fk2/+nkYL/qZSE/wAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADFsaP/w6+h/8Ku + oP/ArJ//v6uc/72pm/+8p5r/u6aX/7iklf+3opT/tqGS/7OfkP+ynY//sJuN/66ai/+tmIj/q5aH/6mU + hP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + /h/AAAAfwAAAD8AAAAfAAAADwAAAAcAAAADAAAAAwAAAAMAAAAHAAAADwAAAB8AAAB/AAAA/wAAAf8AA + AH/AAAB/wAAAf8AAAH/AAAB/wAAAf8AAAH/AAAB/wAAAf8AAAH/AAAB/wAAA/8AAAf/AAAP/wAAH/8AA + D///////KAAAABAAAAAgAAAAAQAgAAAAAABABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJpLJf+WSSQzAAAAAAAAAAAAAAAAAAAAALei + k/9jSTX/Y0k1/2NJNf9jSTX/gWxc/6GShv+xpZv/saWb/7Glm/+hTyf/nU4o/5ZJJDMAAAAAAAAAAAAA + AAC3opP//////96/r//ev6//3r+v/+bPw//u39f/z4Nd/5pLJf+hTyf/p1Io/79qP/+iVjH/lkkkMwAA + AAAAAAAAt6KT/////////////Pr5//fx7v/07en/9e7q/9yQav/9pXj//JNe//KMWf/lhFP/xm5B/65Y + K/8AAAAAAAAAALeik///////99C7//HFrP/ptZf/6Lyh/+3Nuf/onHb/3JBq/8+DXf/Pg13/95pr/65Y + K/+uWCskAAAAAAAAAAC3opP//////////////////fz7//n18//38u7/9u/s//Pq5f/u39f/5Zlz/8V2 + Tv+uWCskAAAAAAAAAAAAAAAAuqWW///////30Lv/8cWs/+m1l//iqYb/4q2N/+Szlf/w5N7/7t/X/+ic + dv/Pg10kAAAAAAAAAAAAAAAAAAAAAL6pmv///////////////////////v38//n18v/06+b/8efh/+vZ + z/+xpZv/AAAAAAAAAAAAAAAAAAAAAAAAAADDrp7///////fQu//xxaz/6bWX/+Glgf/bmnL/25py//Lo + 4v/ky77/indo/wAAAAAAAAAAAAAAAAAAAAAAAAAAyLKj/////////////////////////////v7+//r3 + 9f/17en/3r+v/2NJNf8AAAAAAAAAAAAAAAAAAAAAAAAAAMy2p///////99C7//HFrP/ptZf/4aWB/9ua + cv/9/Pv/3r+v/96/r/9kSjb/AAAAAAAAAAAAAAAAAAAAAAAAAADRu6v///////////////////////// + ////////t6KT/2RKNv9kSjb/ZEo2/wAAAAAAAAAAAAAAAAAAAAAAAAAA1b+v//////////////////// + /////////////7mklf/Uxbr/Y0k1/6KLeuIAAAAAAAAAAAAAAAAAAAAAAAAAANjCsv////////////// + ///////////////////Aq5z/Y0k1/6KLeuEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADYwrL/2MKy/9jC + sv/YwrL/2MKy/9S+rv/Puan/ybOk/8mzpMoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8wAAwAEAAMAA + AADAAAAAwAAAAMABAADAAwAAwAcAAMAHAADABwAAwAcAAMAHAADABwAAwA8AAMAfAAD//wAA + + + \ No newline at end of file diff --git a/src/Kalman.Studio/Interface/IDockDocument.cs b/src/Kalman.Studio/Interface/IDockDocument.cs new file mode 100644 index 0000000..ddba448 --- /dev/null +++ b/src/Kalman.Studio/Interface/IDockDocument.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Kalman.Studio +{ + public interface IDockDocument + { + /// + /// 文件名,不包含路径 + /// + string FileName { get; set; } + + /// + /// 保存文档 + /// + void Save(); + + /// + /// 另存文档 + /// + void SaveAs(); + + void Undo(); + void Redo(); + void Cut(object sender, EventArgs e); + void Copy(object sender, EventArgs e); + void Paste(object sender, EventArgs e); + void Delete(object sender, EventArgs e); + void SelectAll(object sender, EventArgs e); + } +} diff --git a/src/Kalman.Studio/Kalman.Studio.csproj b/src/Kalman.Studio/Kalman.Studio.csproj new file mode 100644 index 0000000..309f463 --- /dev/null +++ b/src/Kalman.Studio/Kalman.Studio.csproj @@ -0,0 +1,888 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {0F3959EA-16FB-4232-827E-E557E0426104} + WinExe + Properties + Kalman.Studio + Kalman.Studio + v4.6 + 512 + App.ICO + + + + + + + + + + + 3.5 + + false + + E:\我的文档\test\KalmanStudio\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 1 + 1.0.0.%2a + false + true + true + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + AllRules.ruleset + x86 + false + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + AllRules.ruleset + false + + + 821BADA723319AB7B38D013A6C9C99A592AD73BF + + + Kalman.Studio_TemporaryKey.pfx + + + true + + + false + + + + ..\packages\Aspose.Cells.18.5.1\lib\net40\Aspose.Cells.dll + + + ..\packages\EmitMapper.1.0.0\lib\EmitMapper.dll + True + + + ..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.dll + + + ..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.SqlServer.dll + + + ..\packages\ManagedEsent.1.9.4\lib\net40\Esent.Interop.dll + + + ..\packages\FirebirdSql.Data.FirebirdClient.5.12.1\lib\net452\FirebirdSql.Data.FirebirdClient.dll + + + ..\packages\Google.Protobuf.3.5.1\lib\net45\Google.Protobuf.dll + + + ..\packages\IBM.Data.DB2.10.0.5.5\lib\net451\IBM.Data.DB2.dll + + + ..\packages\IBM.Data.DB2.10.0.5.5\lib\net451\IBM.Data.DB2.Entity.dll + + + ..\packages\ICSharpCode.TextEditor.3.2.1.6466\lib\Net20\ICSharpCode.TextEditor.dll + + + ..\packages\iTextSharp.5.5.13\lib\itextsharp.dll + + + ..\packages\Microsoft.CodeAnalysis.Common.2.8.2\lib\netstandard1.3\Microsoft.CodeAnalysis.dll + + + ..\packages\Microsoft.CodeAnalysis.CSharp.2.8.2\lib\netstandard1.3\Microsoft.CodeAnalysis.CSharp.dll + + + ..\packages\Microsoft.CodeAnalysis.CSharp.Workspaces.2.8.2\lib\netstandard1.3\Microsoft.CodeAnalysis.CSharp.Workspaces.dll + + + ..\packages\Microsoft.CodeAnalysis.Elfie.0.10.6\lib\net46\Microsoft.CodeAnalysis.Elfie.dll + + + ..\packages\Microsoft.CodeAnalysis.VisualBasic.2.8.2\lib\netstandard1.3\Microsoft.CodeAnalysis.VisualBasic.dll + + + ..\packages\Microsoft.CodeAnalysis.VisualBasic.Workspaces.2.8.2\lib\netstandard1.3\Microsoft.CodeAnalysis.VisualBasic.Workspaces.dll + + + ..\packages\Microsoft.CodeAnalysis.Workspaces.Common.2.8.2\lib\net46\Microsoft.CodeAnalysis.Workspaces.dll + + + ..\packages\Microsoft.CodeAnalysis.Workspaces.Common.2.8.2\lib\net46\Microsoft.CodeAnalysis.Workspaces.Desktop.dll + + + + ..\packages\Microsoft.VisualStudio.TextTemplating.15.0.15.7.27703\lib\net45\Microsoft.VisualStudio.TextTemplating.15.0.dll + True + + + ..\packages\Microsoft.VisualStudio.TextTemplating.Interfaces.10.0.10.0.30320\lib\net40\Microsoft.VisualStudio.TextTemplating.Interfaces.10.0.dll + True + + + ..\packages\Microsoft.VisualStudio.TextTemplating.Interfaces.11.0.11.0.50728\lib\net45\Microsoft.VisualStudio.TextTemplating.Interfaces.11.0.dll + True + + + ..\packages\MySql.Data.8.0.11\lib\net452\MySql.Data.dll + + + ..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll + + + ..\packages\Npgsql.4.0.0\lib\net451\Npgsql.dll + + + ..\packages\Oracle.ManagedDataAccess.12.2.1100\lib\net40\Oracle.ManagedDataAccess.dll + + + + ..\packages\System.AppContext.4.3.0\lib\net46\System.AppContext.dll + True + + + ..\packages\System.Collections.Immutable.1.5.0\lib\netstandard1.3\System.Collections.Immutable.dll + + + + + + ..\packages\System.Composition.AttributedModel.1.2.0\lib\portable-net45+win8+wp8+wpa81\System.Composition.AttributedModel.dll + + + ..\packages\System.Composition.Convention.1.2.0\lib\portable-net45+win8+wp8+wpa81\System.Composition.Convention.dll + + + ..\packages\System.Composition.Hosting.1.2.0\lib\portable-net45+win8+wp8+wpa81\System.Composition.Hosting.dll + + + ..\packages\System.Composition.Runtime.1.2.0\lib\portable-net45+win8+wp8+wpa81\System.Composition.Runtime.dll + + + ..\packages\System.Composition.TypedParts.1.2.0\lib\portable-net45+win8+wp8+wpa81\System.Composition.TypedParts.dll + + + + + ..\packages\System.Console.4.3.1\lib\net46\System.Console.dll + + + + + ..\packages\System.Data.SQLite.Core.1.0.108.0\lib\net46\System.Data.SQLite.dll + + + ..\packages\System.Data.SQLite.EF6.1.0.108.0\lib\net46\System.Data.SQLite.EF6.dll + + + ..\packages\System.Data.SQLite.Linq.1.0.108.0\lib\net46\System.Data.SQLite.Linq.dll + + + + ..\packages\System.Diagnostics.FileVersionInfo.4.3.0\lib\net46\System.Diagnostics.FileVersionInfo.dll + + + ..\packages\System.Diagnostics.StackTrace.4.3.0\lib\net46\System.Diagnostics.StackTrace.dll + + + + ..\packages\System.IO.Compression.4.3.0\lib\net46\System.IO.Compression.dll + True + + + ..\packages\System.IO.FileSystem.4.3.0\lib\net46\System.IO.FileSystem.dll + + + ..\packages\System.IO.FileSystem.Primitives.4.3.0\lib\net46\System.IO.FileSystem.Primitives.dll + + + + + ..\packages\System.Reflection.Metadata.1.6.0\lib\portable-net45+win8\System.Reflection.Metadata.dll + + + ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.0\lib\netstandard1.0\System.Runtime.CompilerServices.Unsafe.dll + + + ..\packages\System.Security.Cryptography.Algorithms.4.3.1\lib\net46\System.Security.Cryptography.Algorithms.dll + True + + + ..\packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll + + + ..\packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll + + + ..\packages\System.Security.Cryptography.X509Certificates.4.3.2\lib\net46\System.Security.Cryptography.X509Certificates.dll + True + + + ..\packages\System.Text.Encoding.CodePages.4.5.0\lib\net46\System.Text.Encoding.CodePages.dll + + + ..\packages\System.Threading.Tasks.Extensions.4.5.0\lib\portable-net45+win8+wp8+wpa81\System.Threading.Tasks.Extensions.dll + + + ..\packages\System.Threading.Thread.4.3.0\lib\net46\System.Threading.Thread.dll + + + + ..\packages\System.ValueTuple.4.5.0\lib\netstandard1.0\System.ValueTuple.dll + + + + + + + + + + + + + ..\packages\System.Xml.ReaderWriter.4.3.1\lib\net46\System.Xml.ReaderWriter.dll + + + ..\packages\System.Xml.XmlDocument.4.3.0\lib\net46\System.Xml.XmlDocument.dll + + + ..\packages\System.Xml.XPath.4.3.0\lib\net46\System.Xml.XPath.dll + + + ..\packages\System.Xml.XPath.XDocument.4.3.0\lib\net46\System.Xml.XPath.XDocument.dll + + + ..\packages\DockPanelSuite.3.0.4\lib\net40\WeifenLuo.WinFormsUI.Docking.dll + + + + + Form + + + About.cs + + + Form + + + DatabaseSettingForm.cs + + + Form + + + String_Random.cs + + + Form + + + String_SymmetricAlgorithm.cs + + + Form + + + String_Guid.cs + + + Form + + + ImportPostParams.cs + + + + + + + Form + + + BatchBuildCustomCode.cs + + + Form + + + BatchBuildDALCode.cs + + + Form + + + BatchBuildEntityCode.cs + + + Form + + + BatchBuildCode.cs + + + Form + + + CodeBuilder.cs + + + Form + + + PreviewFile.cs + + + Form + + + CodeExplorer.cs + + + Form + + + PdmExplorer.cs + + + Form + + + PdmColumnsViewer.cs + + + Form + + + PdmModelViewer.cs + + + Form + + + PdmTableViewer.cs + + + Form + + + TemplateExplorer.cs + + + Form + + + TestDataGenerator.cs + + + Form + + + StringConvertorBase.cs + + + Form + + + String_Replace.cs + + + Form + + + String_Filter.cs + + + Form + + + String_Hash.cs + + + Form + + + String_Convert.cs + + + Code + + + + Form + + + DbObjectViewer.cs + + + Form + + + DatabaseExplorer.cs + + + Form + + + DockableFrom.cs + + + Form + + + DockFormBase.cs + + + Form + + + DockDocument.cs + + + Form + + + DockExplorer.cs + + + Form + + + ErrorInfo.cs + + + + Form + + + Form + + + Main.cs + + + Form + + + Output.cs + + + + + About.cs + + + BatchBuildCustomCode.cs + + + BatchBuildDALCode.cs + + + BatchBuildEntityCode.cs + + + BatchBuildCode.cs + + + CodeBuilder.cs + + + PreviewFile.cs + + + CodeExplorer.cs + + + DatabaseSettingForm.cs + + + PdmExplorer.cs + + + PdmColumnsViewer.cs + + + PdmModelViewer.cs + + + PdmTableViewer.cs + + + TemplateExplorer.cs + + + String_Guid.cs + + + String_Hash.cs + + + String_Random.cs + + + String_Replace.cs + + + String_SymmetricAlgorithm.cs + + + TestDataGenerator.cs + + + StringConvertorBase.cs + + + DbObjectViewer.cs + + + DatabaseExplorer.cs + Designer + + + DockableFrom.cs + + + DockDocument.cs + + + DockFormBase.cs + + + ErrorInfo.cs + + + Main.cs + + + Output.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + DbSPViewer.cs + + + DbTableViewer.cs + + + DbViewViewer.cs + + + QueryAnalyzer.cs + + + IISLogExportToDB.cs + + + IISLogParseCondition.cs + + + IISLogParser.cs + + + StringConnector.cs + + + DbDocBuilder.cs + + + DbSchemaViewer.cs + + + StringConvertor.cs + + + String_Convert.cs + + + ImportPostParams.cs + + + WebSubmitter.cs + + + True + Resources.resx + True + + + Designer + + + PreserveNewest + + + PreserveNewest + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + PreserveNewest + + + PreserveNewest + + + True + Settings.settings + True + + + + + + Form + + + DbSPViewer.cs + + + Form + + + DbTableViewer.cs + + + Form + + + DbViewViewer.cs + + + Form + + + QueryAnalyzer.cs + + + + + + + Form + + + IISLogExportToDB.cs + + + Form + + + IISLogParseCondition.cs + + + Form + + + IISLogParser.cs + + + Form + + + StringConnector.cs + + + PreserveNewest + + + Form + + + DbDocBuilder.cs + + + Form + + + DbSchemaViewer.cs + + + Form + + + StringConvertor.cs + + + Form + + + WebSubmitter.cs + + + + + + PreserveNewest + + + TextTemplatingFileGenerator + Controller.cs + PreserveNewest + + + TextTemplatingFileGenerator + Default.cs + PreserveNewest + + + TextTemplatingFileGenerator + Normal.cs + PreserveNewest + + + TextTemplatingFileGenerator + IService.cs + PreserveNewest + + + TextTemplatingFileGenerator + Service.cs + PreserveNewest + + + TextTemplatingFileGenerator + Create.cs + PreserveNewest + + + TextTemplatingFileGenerator + Delete.cs + PreserveNewest + + + TextTemplatingFileGenerator + Details.cs + PreserveNewest + + + TextTemplatingFileGenerator + Edit.cs + PreserveNewest + + + TextTemplatingFileGenerator + Index.cs + PreserveNewest + + + TextTemplatingFileGenerator + controller.cs + PreserveNewest + + + TextTemplatingFileGenerator + model.cs + PreserveNewest + + + TextTemplatingFileGenerator + index.cs + PreserveNewest + + + PreserveNewest + ASPXCodeBehind + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + {65fed08b-d2b2-4b49-9257-3de1954d1675} + Kalman + + + + + + + + + + + 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 + + + + + \ No newline at end of file diff --git a/src/Kalman.Studio/Library/CodeType.cs b/src/Kalman.Studio/Library/CodeType.cs new file mode 100644 index 0000000..c960180 --- /dev/null +++ b/src/Kalman.Studio/Library/CodeType.cs @@ -0,0 +1,193 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Kalman.Studio +{ + /// + /// 可高亮显示的代码类型 + /// + public struct CodeType + { + /// + /// Mode file="ASPX.xshd" name="ASP/XHTML" extensions=".asp;.aspx;.asax;.asmx" + /// + public const string ASPX = "ASP/XHTML"; + /// + /// Mode file="BAT-Mode.xshd" name="BAT" extensions=".bat" + /// + public const string BAT = "BAT"; + /// + /// Mode file="Boo.xshd" name="Boo" extensions=".boo" + /// + public const string BOO = "Boo"; + /// + /// Mode file="Coco-Mode.xshd" name="Coco" extensions=".atg" + /// + public const string COCO = "Coco"; + /// + /// Mode file="CPP-Mode.xshd" name="C++.NET" extensions=".c;.h;.cc;.C;.cpp;.hpp" + /// + public const string CPP = "C++.NET"; + /// + /// Mode file="CSharp-Mode.xshd" name="C#" extensions=".cs" + /// + public const string CSHARP = "C#"; + /// + /// Mode file="HTML-Mode.xshd" name="HTML" extensions=".htm;.html" + /// + public const string HTML = "HTML"; + /// + /// Mode file="Java-Mode.xshd" name="Java" extensions=".java" + /// + public const string JAVA = "Java"; + /// + /// Mode file="JavaScript-Mode.xshd" name="JavaScript" extensions=".js" + /// + public const string JS = "JavaScript"; + /// + /// Mode file="Patch-Mode.xshd" name="Patch" extensions=".patch;.diff" + /// + public const string PATCH = "Patch"; + /// + /// Mode file="PHP-Mode.xshd" name="PHP" extensions=".php" + /// + public const string PHP = "PHP"; + /// + /// Mode file="Tex-Mode.xshd" name="TeX" extensions=".tex" + /// + public const string TEX = "TeX"; + /// + /// Mode file="VBNET-Mode.xshd" name="VBNET" extensions=".vb" + /// + public const string VB = "VBNET"; + /// + /// Mode file="XML-Mode.xshd" name="XML" extensions=".xml;.xsl;.xslt;.xsd;.manifest;.config;.addin;.xshd;.wxs;.wxi;.wxl;.proj;.csproj;.vbproj;.ilproj;.booproj;.build;.xfrm;.targets;.xaml;.xpt;.xft;.map;.wsdl;.disco" + /// + public const string XML = "XML"; + /// + /// Mode file="TSQL-Mode.xshd" name="TSQL" extensions=".sql" + /// + public const string TSQL = "TSQL"; + } + + public static class CodeTypeHelper + { + /// + /// 根据文件扩展名返回对应的CodeType + /// + /// + /// + public static string GetCodeType(string extention) + { + extention = extention.ToLower(); + switch (extention) + { + case ".asp": + case ".aspx": + case ".asax": + case ".asmx": + return CodeType.ASPX; + case ".bat": + return CodeType.BAT; + case ".boo": + return CodeType.BOO; + case ".atg": + return CodeType.COCO; + case ".c": + case ".h": + case ".cpp": + case ".cc": + case ".hpp": + return CodeType.CPP; + case ".cs": + return CodeType.CSHARP; + case ".htm": + case ".html": + return CodeType.HTML; + case ".java": + return CodeType.JAVA; + case ".js": + return CodeType.JS; + case ".patch": + case ".diff": + return CodeType.PATCH; + case ".php": + return CodeType.PHP; + case ".tex": + return CodeType.TEX; + case ".sql": + return CodeType.TSQL; + case ".vb": + return CodeType.VB; + case ".xml": + case ".xsl": + case ".xslt": + case ".xsd": + case ".manifest": + case ".config": + case ".addin": + case ".xshd": + case ".wxs": + case ".wxi": + case ".wxl": + case ".proj": + case ".csproj": + case ".vbproj": + case ".ilproj": + case ".booproj": + case ".build": + case ".xfrm": + case ".targets": + case ".xaml": + case ".xpt": + case ".xft": + case ".map": + case ".wsdl": + case ".disco": + return CodeType.XML; + default: + return CodeType.CSHARP; + } + } + + /// + /// 根据代码类型返回该类型代码文件的默认扩展名,如代码类型为CodeType.ASPX,那么默认扩展名为".aspx" + /// + /// + /// + public static string GetExtention(string codeType) + { + switch (codeType) + { + case CodeType.ASPX: + return ".aspx"; + case CodeType.BAT: + return ".bat"; + case CodeType.BOO: + return ".boo"; + case CodeType.CPP: + return ".cpp"; + case CodeType.CSHARP: + return ".cs"; + case CodeType.HTML: + return ".html"; + case CodeType.JAVA: + return ".java"; + case CodeType.JS: + return ".js"; + case CodeType.PHP: + return ".php"; + case CodeType.TSQL: + return ".sql"; + case CodeType.VB: + return ".vb"; + case CodeType.XML: + return ".xml"; + default: + return ".txt"; + } + } + } +} diff --git a/src/Kalman.Studio/Library/DbSchemaHelper.cs b/src/Kalman.Studio/Library/DbSchemaHelper.cs new file mode 100644 index 0000000..f86be23 --- /dev/null +++ b/src/Kalman.Studio/Library/DbSchemaHelper.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Kalman.Data; + +namespace Kalman.Studio +{ + public class DbSchemaHelper + { + public static readonly DbSchemaHelper Instance = new DbSchemaHelper(); + private DbSchemaHelper() + { + } + + /// + /// 当前DbSchema + /// + public DbSchema CurrentSchema { get; set; } + } +} diff --git a/src/Kalman.Studio/Library/DockHelper.cs b/src/Kalman.Studio/Library/DockHelper.cs new file mode 100644 index 0000000..febac0b --- /dev/null +++ b/src/Kalman.Studio/Library/DockHelper.cs @@ -0,0 +1,133 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using WeifenLuo.WinFormsUI.Docking; + +namespace Kalman.Studio +{ + internal class DockHelper + { + /// + /// 根据名称查找DockContent + /// + /// + /// + /// + public static DockContent FindDockContent(string name, DockPanel dockPanel) + { + DockContentCollection contents = dockPanel.Contents; + foreach (DockContent item in contents) + { + if (item.Name == name) + { + return item; + } + } + return null; + } + + public static bool IsDockStateAutoHide(DockState dockState) + { + if (dockState == DockState.DockLeftAutoHide || + dockState == DockState.DockRightAutoHide || + dockState == DockState.DockTopAutoHide || + dockState == DockState.DockBottomAutoHide) + return true; + else + return false; + } + + public static bool IsDockStateDocked(DockState dockState) + { + return (dockState == DockState.DockLeft || + dockState == DockState.DockRight || + dockState == DockState.DockTop || + dockState == DockState.DockBottom); + } + + public static bool IsDockBottom(DockState dockState) + { + return (dockState == DockState.DockBottom || dockState == DockState.DockBottomAutoHide) ? true : false; + } + + public static bool IsDockLeft(DockState dockState) + { + return (dockState == DockState.DockLeft || dockState == DockState.DockLeftAutoHide) ? true : false; + } + + public static bool IsDockRight(DockState dockState) + { + return (dockState == DockState.DockRight || dockState == DockState.DockRightAutoHide) ? true : false; + } + + public static bool IsDockTop(DockState dockState) + { + return (dockState == DockState.DockTop || dockState == DockState.DockTopAutoHide) ? true : false; + } + + public static bool IsDockStateValid(DockState dockState, DockAreas dockableAreas) + { + if (((dockableAreas & DockAreas.Float) == 0) && + (dockState == DockState.Float)) + return false; + else if (((dockableAreas & DockAreas.Document) == 0) && + (dockState == DockState.Document)) + return false; + else if (((dockableAreas & DockAreas.DockLeft) == 0) && + (dockState == DockState.DockLeft || dockState == DockState.DockLeftAutoHide)) + return false; + else if (((dockableAreas & DockAreas.DockRight) == 0) && + (dockState == DockState.DockRight || dockState == DockState.DockRightAutoHide)) + return false; + else if (((dockableAreas & DockAreas.DockTop) == 0) && + (dockState == DockState.DockTop || dockState == DockState.DockTopAutoHide)) + return false; + else if (((dockableAreas & DockAreas.DockBottom) == 0) && + (dockState == DockState.DockBottom || dockState == DockState.DockBottomAutoHide)) + return false; + else + return true; + } + + public static bool IsDockWindowState(DockState state) + { + if (state == DockState.DockTop || state == DockState.DockBottom || state == DockState.DockLeft || + state == DockState.DockRight || state == DockState.Document) + return true; + else + return false; + } + + public static bool IsValidRestoreState(DockState state) + { + if (state == DockState.DockLeft || state == DockState.DockRight || state == DockState.DockTop || + state == DockState.DockBottom || state == DockState.Document) + return true; + else + return false; + } + + public static DockState ToggleAutoHideState(DockState state) + { + if (state == DockState.DockLeft) + return DockState.DockLeftAutoHide; + else if (state == DockState.DockRight) + return DockState.DockRightAutoHide; + else if (state == DockState.DockTop) + return DockState.DockTopAutoHide; + else if (state == DockState.DockBottom) + return DockState.DockBottomAutoHide; + else if (state == DockState.DockLeftAutoHide) + return DockState.DockLeft; + else if (state == DockState.DockRightAutoHide) + return DockState.DockRight; + else if (state == DockState.DockTopAutoHide) + return DockState.DockTop; + else if (state == DockState.DockBottomAutoHide) + return DockState.DockBottom; + else + return state; + } + } +} diff --git a/src/Kalman.Studio/Library/Export.cs b/src/Kalman.Studio/Library/Export.cs new file mode 100644 index 0000000..cdde3ac --- /dev/null +++ b/src/Kalman.Studio/Library/Export.cs @@ -0,0 +1,309 @@ +using Aspose.Cells; +using iTextSharp.text; +using iTextSharp.text.pdf; +using Kalman.Data; +using Kalman.Data.SchemaObject; +using Kalman.PdmParser; +using System; +using System.Collections.Generic; +using System.IO; + +/// +/// 由于删除了版权DLL,导致该功能无法使用。可在QQ群:122161138中下载source_lib.zip +/// +namespace Kalman.Studio +{ + public class iTextExporter + { + enum ExportTyep + { + PDF = 0, + RTF = 1 + //HTML = 2 + } + + string fileName = string.Empty; + //Table t = null; + BaseFont baseFont = BaseFont.CreateFont("c:\\windows\\fonts\\STSONG.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); + iTextSharp.text.Font font; + + public iTextExporter(string path) + { + fileName = path; + + //如果不使用CID字体,下面三行不需要 + //BaseFont.AddToResourceSearch("iTextAsian-1.0.dll"); + //BaseFont.AddToResourceSearch("iTextAsianCmaps-1.0.dll"); + //BaseFont baseFont = BaseFont.CreateFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED); + + //BaseFont baseFont = BaseFont.CreateFont("C:\\WINDOWS\\FONTS\\SIMHEI.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); + //BaseFont baseFont = BaseFont.CreateFont("c:\\windows\\fonts\\STSONG.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); + font = new iTextSharp.text.Font(baseFont,12); + } + + public void PDModel2Pdf(IList tableList, string title) + { + Export(tableList,title, ExportTyep.PDF); + } + + public void PDModel2Rtf(IList tableList, string title) + { + Export(tableList,title, ExportTyep.RTF); + } + + //public void PDModel2Html(PDModel m) + //{ + // Export(m, ExportTyep.HTML); + //} + + private void Export(IList tableList,string title, ExportTyep exportType) + { + Document doc = new Document(PageSize.A4.Rotate(), 20, 20, 20, 20); + DocWriter w; + + switch (exportType) + { + case ExportTyep.PDF: + w = PdfWriter.GetInstance(doc, new FileStream(fileName, FileMode.Create, FileAccess.Write)); + break; + case ExportTyep.RTF: + //w = RtfWriter2.GetInstance(doc, new FileStream(fileName, FileMode.Create, FileAccess.Write)); + break; + //case ExportTyep.HTML: + // w = HtmlWriter.GetInstance(doc, new FileStream(fileName, FileMode.Create, FileAccess.Write)); + //break; + default: + break; + } + + doc.Open(); + doc.NewPage(); + + //IList tableList = m.AllTableList; + + //Chapter cpt = new Chapter(m.Name, 1); + Chapter cpt = new Chapter(title, 1); + Section sec; + + //doc.AddTitle(m.Name); + doc.AddTitle(title); + doc.AddAuthor("Kalman"); + doc.AddCreationDate(); + doc.AddCreator("Kalman"); + doc.AddSubject("PDM数据库文档"); + + foreach (PDTable table in tableList) + { + //sec = cpt.AddSection(new Paragraph(string.Format("{0}[{1}]", table.Name, table.Code), font)); + sec = cpt.AddSection(new Paragraph(string.Format("{0}[{1}]", table.Name, table.Code))); + + if (string.IsNullOrEmpty(table.Comment) == false) + { + Chunk chunk = new Chunk(table.Comment, font); + sec.Add(chunk); + } + + //t = new Table(9, table.ColumnList.Count); + + ////t.Border = 15; + ////t.BorderColor = Color.BLACK; + ////t.BorderWidth = 1.0f; + //t.AutoFillEmptyCells = true; + //t.CellsFitPage = true; + //t.TableFitsPage = true; + //t.Cellpadding = 3; + ////if (exportType == ExportTyep.PDF) t.Cellspacing = 2; + //t.DefaultVerticalAlignment = Element.ALIGN_MIDDLE; + + //t.SetWidths(new int[] { 200, 200, 150, 50, 50, 50, 50, 50, 300 }); + + //t.AddCell(BuildHeaderCell("名称")); + //t.AddCell(BuildHeaderCell("代码")); + //t.AddCell(BuildHeaderCell("数据类型")); + //t.AddCell(BuildHeaderCell("长度")); + //t.AddCell(BuildHeaderCell("精度")); + //t.AddCell(BuildHeaderCell("主键")); + //t.AddCell(BuildHeaderCell("外键")); + //t.AddCell(BuildHeaderCell("可空")); + //t.AddCell(BuildHeaderCell("注释")); + + //foreach (PDColumn column in table.ColumnList) + //{ + // t.AddCell(BuildCell(column.Name)); + // t.AddCell(BuildCell(column.Code)); + // t.AddCell(BuildCell(column.DataType)); + // t.AddCell(BuildCell(column.Length == 0 ? "" : column.Length.ToString())); + // t.AddCell(BuildCell(column.Precision == 0 ? "" : column.Precision.ToString())); + // t.AddCell(BuildCell(column.IsPK ? " √" : "")); + // t.AddCell(BuildCell(column.IsFK ? " √" : "")); + // t.AddCell(BuildCell(column.Mandatory ? "" : " √")); + // t.AddCell(BuildCell(column.Comment)); + //} + + //sec.Add(t); + } + + doc.Add(cpt); + doc.Close(); + } + + //private Cell BuildHeaderCell(string title) + //{ + // Phrase phrase = new Phrase(title, font); + // Cell cell = new Cell(phrase); + // cell.Header = true; + // cell.BackgroundColor = Color.LIGHT_GRAY; + // cell.VerticalAlignment = Element.ALIGN_MIDDLE; + // cell.HorizontalAlignment = Element.ALIGN_LEFT; + // //cell.Border = 15; + // //cell.BorderWidth = 0.2f; + // //cell.BorderColor = Color.BLACK; + // return cell; + //} + + //Cell BuildCell(string text) + //{ + // Phrase phrase = new Phrase(text, font); + // Cell cell = new Cell(phrase); + // cell.VerticalAlignment = Element.ALIGN_MIDDLE; + // cell.HorizontalAlignment = Element.ALIGN_LEFT; + // //cell.Border = 15; + // //cell.BorderWidth = 0.2f; + // //cell.BorderColor = Color.BLACK; + + // return cell; + //} + + /// + /// + /// + /// + /// + /// 若该参数为null,则通过DbSchema对象来获取表列表 + public void DbSchema2Pdf(DbSchema schema, SODatabase db, List tableList) + { + tableList = Export(schema, db, tableList, ExportTyep.PDF); + } + + public void DbSchema2Rtf(DbSchema schema, SODatabase db, List tableList) + { + tableList = Export(schema, db, tableList, ExportTyep.RTF); + } + + private List Export(DbSchema schema, SODatabase db, List tableList, ExportTyep exportType) + { + if (schema == null) throw new ArgumentException("参数schema不能为空", "schema"); + if (db == null) throw new ArgumentException("参数dbName不能为空", "dbName"); + + Document doc = new Document(PageSize.A4.Rotate(), 20, 20, 20, 20); + DocWriter w; + + switch (exportType) + { + case ExportTyep.PDF: + w = PdfWriter.GetInstance(doc, new FileStream(fileName, FileMode.Create, FileAccess.Write)); + break; + case ExportTyep.RTF: + //w = RtfWriter2.GetInstance(doc, new FileStream(fileName, FileMode.Create, FileAccess.Write)); + break; + //case ExportTyep.HTML: + // w = HtmlWriter.GetInstance(doc, new FileStream(fileName, FileMode.Create, FileAccess.Write)); + //break; + default: + break; + } + + doc.Open(); + doc.NewPage(); + + if (tableList == null) tableList = schema.GetTableList(db); + + Chapter cpt = new Chapter(db.Name, 1); + Section sec; + + doc.AddTitle(db.Name); + doc.AddAuthor("Kalman"); + doc.AddCreationDate(); + doc.AddCreator("Kalman"); + doc.AddSubject("数据库文档"); + + foreach (SOTable table in tableList) + { + //sec = cpt.AddSection(new Paragraph(table.Name, font)); + sec = cpt.AddSection(new Paragraph(table.Name)); + + if (string.IsNullOrEmpty(table.Comment) == false) + { + Chunk chunk = new Chunk(table.Comment, font); + sec.Add(chunk); + } + + List columnList = schema.GetTableColumnList(table); + + //t = new Table(7, columnList.Count); + + //t.AutoFillEmptyCells = true; + //t.CellsFitPage = true; + //t.TableFitsPage = true; + //t.Cellpadding = 3; + ////if (exportType == ExportTyep.PDF) t.Cellspacing = 2; + //t.DefaultVerticalAlignment = Element.ALIGN_MIDDLE; + + //t.SetWidths(new int[] { 200, 150, 50, 50, 50, 100, 300 }); + + //t.AddCell(BuildHeaderCell("名称")); + //t.AddCell(BuildHeaderCell("数据类型")); + //t.AddCell(BuildHeaderCell("主键")); + //t.AddCell(BuildHeaderCell("标志")); + //t.AddCell(BuildHeaderCell("可空")); + //t.AddCell(BuildHeaderCell("默认值")); + //t.AddCell(BuildHeaderCell("注释")); + + //foreach (SOColumn column in columnList) + //{ + // t.AddCell(BuildCell(column.Name)); + // t.AddCell(BuildCell(GetDbColumnType(column))); + // t.AddCell(BuildCell(column.PrimaryKey ? " √" : "")); + // t.AddCell(BuildCell(column.Identify ? " √" : "")); + // t.AddCell(BuildCell(column.Nullable ? " √" : "")); + // t.AddCell(BuildCell(column.DefaultValue == null ? "" : column.DefaultValue.ToString())); + // t.AddCell(BuildCell(column.Comment)); + //} + + //sec.Add(t); + } + + doc.Add(cpt); + doc.Close(); + return tableList; + } + + string GetDbColumnType(SOColumn c) + { + string s = c.NativeType; + + if (c.Length == -1) return s; + + switch (c.DataType) + { + case System.Data.DbType.AnsiString: + case System.Data.DbType.AnsiStringFixedLength: + case System.Data.DbType.String: + case System.Data.DbType.StringFixedLength: + //s = string.Format("{0}({1})", c.NativeType, c.NativeType.StartsWith("n") ? c.Size / 2 : c.Size); + s = string.Format("{0}({1})", c.NativeType, c.Length); + break; + case System.Data.DbType.Currency: + case System.Data.DbType.Decimal: + case System.Data.DbType.Single: + s = string.Format("{0}({1}, {2})", c.NativeType, c.Precision, c.Scale); + break; + default: + s = c.NativeType; + break; + } + + return s; + } + } +} diff --git a/src/Kalman.Studio/Library/Utils.cs b/src/Kalman.Studio/Library/Utils.cs new file mode 100644 index 0000000..b9c2860 --- /dev/null +++ b/src/Kalman.Studio/Library/Utils.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Kalman.Studio +{ + public static class Utils + { + public static string DbBooleanValueToStirng(object val) + { + if (val == DBNull.Value || val == null) return ""; + return val.ToString(); + } + + public static string DbNumericValueToString(object val) + { + if (val == DBNull.Value || val == null) return ""; + return val.ToString(); + } + + public static string DbStringValueToString(object val) + { + if (val == DBNull.Value || val == null) return ""; + return val.ToString().Replace("'","''"); + } + } +} diff --git a/src/Kalman.Studio/Library/VariXFolding.cs b/src/Kalman.Studio/Library/VariXFolding.cs new file mode 100644 index 0000000..aa7ed02 --- /dev/null +++ b/src/Kalman.Studio/Library/VariXFolding.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using ICSharpCode.TextEditor.Document; + +namespace Kalman.Studio +{ + /// + /// The class to generate the foldings, it implements ICSharpCode.TextEditor.Document.IFoldingStrategy + /// + public class VariXFolding : IFoldingStrategy + { + /// + /// Generates the foldings for our document. + /// + /// The current document. + /// The filename of the document. + /// Extra parse information, not used in this sample. + /// A list of FoldMarkers. + public List GenerateFoldMarkers(IDocument document, string fileName, object parseInformation) + { + List list = new List(); + + int start = 0; + + // Create foldmarkers for the whole document, enumerate through every line. + for (int i = 0; i < document.TotalNumberOfLines; i++) + { + // Get the text of current line. + string text = document.GetText(document.GetLineSegment(i)); + + if (text.StartsWith("def")) // Look for method starts + start = i; + if (text.StartsWith("enddef;")) // Look for method endings + // Add a new FoldMarker to the list. + // document = the current document + // start = the start line for the FoldMarker + // document.GetLineSegment(start).Length = the ending of the current line = the start column of our foldmarker. + // i = The current line = end line of the FoldMarker. + // 7 = The end column + list.Add(new FoldMarker(document, start, document.GetLineSegment(start).Length, i, 7)); + } + + return list; + } + + } + +} diff --git a/src/Kalman.Studio/Library/Win32Shell.cs b/src/Kalman.Studio/Library/Win32Shell.cs new file mode 100644 index 0000000..1bab224 --- /dev/null +++ b/src/Kalman.Studio/Library/Win32Shell.cs @@ -0,0 +1,52 @@ +#region Using directives + +using System; +using System.Collections.Generic; +using System.Text; + +using System.Runtime.InteropServices; +using System.Drawing; + +#endregion + + +namespace Kalman.Studio +{ + [StructLayout(LayoutKind.Sequential)] + public struct FileShellInfo + { + public IntPtr hIcon; + public IntPtr iIcon; + public uint dwAttributes; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] + public string szDisplayName; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)] + public string szTypeName; + public Icon Icon { get { return Icon.FromHandle(hIcon); } } + }; + + /// + /// װWin32 Shellص÷ + /// + public class Win32Shell + { + public const uint SHGFI_ICON = 0x100; // Gets the icon + public const uint SHGFI_DISPLAYNAME = 0x200; // Gets the Display name + public const uint SHGFI_TYPENAME = 0x400; // Gets the type name + public const uint SHGFI_LARGEICON = 0x0; // Large icon + public const uint SHGFI_SMALLICON = 0x1; // Small icon + + [DllImport("shell32.dll")] + public static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref FileShellInfo psfi, uint cbSizeFileInfo, uint uFlags); + + public static FileShellInfo GetFileInfo(string path) + { + FileShellInfo info = new FileShellInfo(); + IntPtr icon; + + icon = SHGetFileInfo(path, 0, ref info, (uint)Marshal.SizeOf(info), SHGFI_ICON | SHGFI_TYPENAME | SHGFI_SMALLICON); + + return info; + } + } +} diff --git a/src/Kalman.Studio/MainForm/Main.Common.cs b/src/Kalman.Studio/MainForm/Main.Common.cs new file mode 100644 index 0000000..7b363f5 --- /dev/null +++ b/src/Kalman.Studio/MainForm/Main.Common.cs @@ -0,0 +1,154 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using WeifenLuo.WinFormsUI.Docking; +using System.Windows.Forms; +using System.IO; + +namespace Kalman.Studio +{ + public partial class Main + { + public DockPanel MainDockPanel + { + get { return this.dockPanel; } + } + + public IDockContent FindDockDocument(string text) + { + if (dockPanel.DocumentStyle == DocumentStyle.SystemMdi) + { + foreach (Form form in MdiChildren) + if (form.Text.TrimEnd('*') == text) + return form as IDockContent; + + return null; + } + else + { + foreach (IDockContent content in dockPanel.Documents) + if (content.DockHandler.TabText.TrimEnd('*') == text) + return content; + + return null; + } + } + + /// + /// 新建文档 + /// + /// 文档所在窗体的标题,如“Class1.cs” + /// 代码类型 + /// 文档文本内容 + public void NewDockDocument(string caption, string codeType, string content) + { + DockDocument doc = new DockDocument(); + + int count = 1; + string ext = CodeTypeHelper.GetExtention(codeType); + string text = string.Format("{0}{1}{2}", caption, count.ToString(), ext); + while (FindDockDocument(text) != null) + { + count++; + if (count > 1) + { + text = string.Format("{0}{1}{2}", caption, count.ToString(), ext); + } + else + { + text = string.Format("{0}{1}", caption, ext); + } + } + doc.Text = text; + doc.LoadTextContent(content, codeType); + + if (dockPanel.DocumentStyle == DocumentStyle.SystemMdi) + { + doc.MdiParent = this; + doc.Show(); + } + else + doc.Show(dockPanel); + } + + public void OpenDockDocument(string fileName, string codeType) + { + //打开文件判断文件大小,不打开过大的文件 + FileInfo fi = new FileInfo(fileName); + if (fi.Length > 2 * 1024 * 1024) + { + MessageBox.Show("大于2M的文件请用其他编辑器打开"); + return; + } + + if (FindDockDocument(fileName) != null) + { + MessageBox.Show(string.Format("文件[{0}]已经打开", fileName)); + return; + } + + DockDocument doc = new DockDocument(); + doc.LoadFileContent(fileName); + doc.SetDocumentCodeType(codeType); + + if (dockPanel.DocumentStyle == DocumentStyle.SystemMdi) + { + doc.MdiParent = this; + doc.Show(); + } + else + doc.Show(dockPanel); + } + + //打开文档 + void OpenDockDocument() + { + OpenFileDialog openFile = new OpenFileDialog(); + + openFile.InitialDirectory = Application.ExecutablePath; + openFile.Filter = "所有文件 (*.*)|*.*"; + openFile.FilterIndex = 1; + openFile.RestoreDirectory = true; + + if (openFile.ShowDialog() == DialogResult.OK) + { + string fileName = openFile.FileName; + OpenDockDocument(fileName, CodeTypeHelper.GetCodeType(Path.GetExtension(fileName))); + } + } + + //除此之外全部关闭 + public void CloseOtherDockDocument() + { + foreach (IDockContent content in dockPanel.DocumentsToArray()) + { + if (content is DockExplorer) continue; + if (!content.DockHandler.IsActivated) + { + //if (content is DockToolWindow) content.DockHandler.Hide(); + //else content.DockHandler.Close(); + + content.DockHandler.Close(); + } + } + } + + //全部关闭 + public void CloseAllDockDocument() + { + for (int i = dockPanel.Contents.Count - 1; i >= 0; i--) + { + if (dockPanel.Contents[i] is IDockContent) + { + IDockContent content = (IDockContent)dockPanel.Contents[i]; + if (content is DockExplorer) continue; + + //if (content is DockToolWindow) content.DockHandler.Hide(); + //else content.DockHandler.Close(); + content.DockHandler.Close(); + } + } + } + } +} diff --git a/src/Kalman.Studio/MainForm/Main.Designer.cs b/src/Kalman.Studio/MainForm/Main.Designer.cs new file mode 100644 index 0000000..e895877 --- /dev/null +++ b/src/Kalman.Studio/MainForm/Main.Designer.cs @@ -0,0 +1,854 @@ +namespace Kalman.Studio +{ + partial class Main + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + WeifenLuo.WinFormsUI.Docking.DockPanelSkin dockPanelSkin1 = new WeifenLuo.WinFormsUI.Docking.DockPanelSkin(); + WeifenLuo.WinFormsUI.Docking.AutoHideStripSkin autoHideStripSkin1 = new WeifenLuo.WinFormsUI.Docking.AutoHideStripSkin(); + WeifenLuo.WinFormsUI.Docking.DockPanelGradient dockPanelGradient1 = new WeifenLuo.WinFormsUI.Docking.DockPanelGradient(); + WeifenLuo.WinFormsUI.Docking.TabGradient tabGradient1 = new WeifenLuo.WinFormsUI.Docking.TabGradient(); + WeifenLuo.WinFormsUI.Docking.DockPaneStripSkin dockPaneStripSkin1 = new WeifenLuo.WinFormsUI.Docking.DockPaneStripSkin(); + WeifenLuo.WinFormsUI.Docking.DockPaneStripGradient dockPaneStripGradient1 = new WeifenLuo.WinFormsUI.Docking.DockPaneStripGradient(); + WeifenLuo.WinFormsUI.Docking.TabGradient tabGradient2 = new WeifenLuo.WinFormsUI.Docking.TabGradient(); + WeifenLuo.WinFormsUI.Docking.DockPanelGradient dockPanelGradient2 = new WeifenLuo.WinFormsUI.Docking.DockPanelGradient(); + WeifenLuo.WinFormsUI.Docking.TabGradient tabGradient3 = new WeifenLuo.WinFormsUI.Docking.TabGradient(); + WeifenLuo.WinFormsUI.Docking.DockPaneStripToolWindowGradient dockPaneStripToolWindowGradient1 = new WeifenLuo.WinFormsUI.Docking.DockPaneStripToolWindowGradient(); + WeifenLuo.WinFormsUI.Docking.TabGradient tabGradient4 = new WeifenLuo.WinFormsUI.Docking.TabGradient(); + WeifenLuo.WinFormsUI.Docking.TabGradient tabGradient5 = new WeifenLuo.WinFormsUI.Docking.TabGradient(); + WeifenLuo.WinFormsUI.Docking.DockPanelGradient dockPanelGradient3 = new WeifenLuo.WinFormsUI.Docking.DockPanelGradient(); + WeifenLuo.WinFormsUI.Docking.TabGradient tabGradient6 = new WeifenLuo.WinFormsUI.Docking.TabGradient(); + WeifenLuo.WinFormsUI.Docking.TabGradient tabGradient7 = new WeifenLuo.WinFormsUI.Docking.TabGradient(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Main)); + this.dockPanel = new WeifenLuo.WinFormsUI.Docking.DockPanel(); + this.toolItemNewFile = new System.Windows.Forms.ToolStripButton(); + this.toolItemOpenFile = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator10 = new System.Windows.Forms.ToolStripSeparator(); + this.toolItemDbExplorer = new System.Windows.Forms.ToolStripButton(); + this.toolItemCodeExplorer = new System.Windows.Forms.ToolStripButton(); + this.toolItemTemplateExplorer = new System.Windows.Forms.ToolStripButton(); + this.toolItemPdmExplorer = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator6 = new System.Windows.Forms.ToolStripSeparator(); + this.toolItemDbSchema = new System.Windows.Forms.ToolStripButton(); + this.toolItemWebSubmitter = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator(); + this.toolItemDbList = new System.Windows.Forms.ToolStripComboBox(); + this.toolStripSeparator9 = new System.Windows.Forms.ToolStripSeparator(); + this.toolItemExecSql = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator(); + this.toolItemBuildCode = new System.Windows.Forms.ToolStripButton(); + this.toolItemBuildCodeSeparator = new System.Windows.Forms.ToolStripSeparator(); + this.toolItemExit = new System.Windows.Forms.ToolStripButton(); + this.toolStrip1 = new System.Windows.Forms.ToolStrip(); + this.menuItemFile = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemNew = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemNewAspx = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemNewCpp = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemNewCSharp = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemNewHtml = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemNewJava = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemNewJavascript = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemNewPHP = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemNewText = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemNewTSQL = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemNewVB = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemNewXML = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemOpen = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); + this.menuItemClose = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemCloseOther = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemCloseAll = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); + this.menuItemSave = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemSaveAs = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator(); + this.menuItemExit = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemEdit = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemUndo = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemRedo = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator7 = new System.Windows.Forms.ToolStripSeparator(); + this.menuItemCut = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemCopy = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemPaste = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemDelete = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator8 = new System.Windows.Forms.ToolStripSeparator(); + this.menuItemSelectAll = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemView = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemDatabaseExplorer = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemCodeExplorer = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemTemplateExplorer = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemPdmExplorer = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemOutput = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemTools = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemDbSchemaViewer = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemDbDocBuilder = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemWebSubmitter = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemIisLogParser = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemStringConnector = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemStringConverter = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemHelp = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemAbout = new System.Windows.Forms.ToolStripMenuItem(); + this.menuStrip1 = new System.Windows.Forms.MenuStrip(); + this.toolStrip1.SuspendLayout(); + this.menuStrip1.SuspendLayout(); + this.SuspendLayout(); + // + // dockPanel + // + this.dockPanel.ActiveAutoHideContent = null; + this.dockPanel.Dock = System.Windows.Forms.DockStyle.Fill; + this.dockPanel.DockBackColor = System.Drawing.SystemColors.AppWorkspace; + this.dockPanel.DockBottomPortion = 150; + this.dockPanel.DockLeftPortion = 200; + this.dockPanel.DockRightPortion = 200; + this.dockPanel.DockTopPortion = 150; + this.dockPanel.Font = new System.Drawing.Font("Tahoma", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.World, ((byte)(0))); + this.dockPanel.Location = new System.Drawing.Point(0, 50); + this.dockPanel.Margin = new System.Windows.Forms.Padding(5); + this.dockPanel.Name = "dockPanel"; + this.dockPanel.RightToLeftLayout = true; + this.dockPanel.Size = new System.Drawing.Size(636, 389); + dockPanelGradient1.EndColor = System.Drawing.SystemColors.ControlLight; + dockPanelGradient1.StartColor = System.Drawing.SystemColors.ControlLight; + autoHideStripSkin1.DockStripGradient = dockPanelGradient1; + tabGradient1.EndColor = System.Drawing.SystemColors.Control; + tabGradient1.StartColor = System.Drawing.SystemColors.Control; + tabGradient1.TextColor = System.Drawing.SystemColors.ControlDarkDark; + autoHideStripSkin1.TabGradient = tabGradient1; + dockPanelSkin1.AutoHideStripSkin = autoHideStripSkin1; + tabGradient2.EndColor = System.Drawing.SystemColors.ControlLightLight; + tabGradient2.StartColor = System.Drawing.SystemColors.ControlLightLight; + tabGradient2.TextColor = System.Drawing.SystemColors.ControlText; + dockPaneStripGradient1.ActiveTabGradient = tabGradient2; + dockPanelGradient2.EndColor = System.Drawing.SystemColors.Control; + dockPanelGradient2.StartColor = System.Drawing.SystemColors.Control; + dockPaneStripGradient1.DockStripGradient = dockPanelGradient2; + tabGradient3.EndColor = System.Drawing.SystemColors.ControlLight; + tabGradient3.StartColor = System.Drawing.SystemColors.ControlLight; + tabGradient3.TextColor = System.Drawing.SystemColors.ControlText; + dockPaneStripGradient1.InactiveTabGradient = tabGradient3; + dockPaneStripSkin1.DocumentGradient = dockPaneStripGradient1; + tabGradient4.EndColor = System.Drawing.SystemColors.ActiveCaption; + tabGradient4.LinearGradientMode = System.Drawing.Drawing2D.LinearGradientMode.Vertical; + tabGradient4.StartColor = System.Drawing.SystemColors.GradientActiveCaption; + tabGradient4.TextColor = System.Drawing.SystemColors.ActiveCaptionText; + dockPaneStripToolWindowGradient1.ActiveCaptionGradient = tabGradient4; + tabGradient5.EndColor = System.Drawing.SystemColors.Control; + tabGradient5.StartColor = System.Drawing.SystemColors.Control; + tabGradient5.TextColor = System.Drawing.SystemColors.ControlText; + dockPaneStripToolWindowGradient1.ActiveTabGradient = tabGradient5; + dockPanelGradient3.EndColor = System.Drawing.SystemColors.ControlLight; + dockPanelGradient3.StartColor = System.Drawing.SystemColors.ControlLight; + dockPaneStripToolWindowGradient1.DockStripGradient = dockPanelGradient3; + tabGradient6.EndColor = System.Drawing.SystemColors.GradientInactiveCaption; + tabGradient6.LinearGradientMode = System.Drawing.Drawing2D.LinearGradientMode.Vertical; + tabGradient6.StartColor = System.Drawing.SystemColors.GradientInactiveCaption; + tabGradient6.TextColor = System.Drawing.SystemColors.ControlText; + dockPaneStripToolWindowGradient1.InactiveCaptionGradient = tabGradient6; + tabGradient7.EndColor = System.Drawing.Color.Transparent; + tabGradient7.StartColor = System.Drawing.Color.Transparent; + tabGradient7.TextColor = System.Drawing.SystemColors.ControlDarkDark; + dockPaneStripToolWindowGradient1.InactiveTabGradient = tabGradient7; + dockPaneStripSkin1.ToolWindowGradient = dockPaneStripToolWindowGradient1; + dockPanelSkin1.DockPaneStripSkin = dockPaneStripSkin1; + //this.dockPanel.Skin = dockPanelSkin1; + this.dockPanel.TabIndex = 8; + // + // toolItemNewFile + // + this.toolItemNewFile.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.toolItemNewFile.Image = ((System.Drawing.Image)(resources.GetObject("toolItemNewFile.Image"))); + this.toolItemNewFile.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolItemNewFile.Name = "toolItemNewFile"; + this.toolItemNewFile.Size = new System.Drawing.Size(23, 22); + this.toolItemNewFile.Text = "新建文档"; + this.toolItemNewFile.Click += new System.EventHandler(this.toolItemNewFile_Click); + // + // toolItemOpenFile + // + this.toolItemOpenFile.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.toolItemOpenFile.Image = ((System.Drawing.Image)(resources.GetObject("toolItemOpenFile.Image"))); + this.toolItemOpenFile.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolItemOpenFile.Name = "toolItemOpenFile"; + this.toolItemOpenFile.Size = new System.Drawing.Size(23, 22); + this.toolItemOpenFile.Text = "打开文档"; + this.toolItemOpenFile.Click += new System.EventHandler(this.toolItemOpenFile_Click); + // + // toolStripSeparator10 + // + this.toolStripSeparator10.Name = "toolStripSeparator10"; + this.toolStripSeparator10.Size = new System.Drawing.Size(6, 25); + // + // toolItemDbExplorer + // + this.toolItemDbExplorer.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.toolItemDbExplorer.Image = ((System.Drawing.Image)(resources.GetObject("toolItemDbExplorer.Image"))); + this.toolItemDbExplorer.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolItemDbExplorer.Name = "toolItemDbExplorer"; + this.toolItemDbExplorer.Size = new System.Drawing.Size(23, 22); + this.toolItemDbExplorer.Text = "数据库对象浏览器"; + this.toolItemDbExplorer.Click += new System.EventHandler(this.toolItemDbExplorer_Click); + // + // toolItemCodeExplorer + // + this.toolItemCodeExplorer.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.toolItemCodeExplorer.Image = ((System.Drawing.Image)(resources.GetObject("toolItemCodeExplorer.Image"))); + this.toolItemCodeExplorer.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolItemCodeExplorer.Name = "toolItemCodeExplorer"; + this.toolItemCodeExplorer.Size = new System.Drawing.Size(23, 22); + this.toolItemCodeExplorer.Text = "代码资源管理器"; + this.toolItemCodeExplorer.Click += new System.EventHandler(this.toolItemCodeExplorer_Click); + // + // toolItemTemplateExplorer + // + this.toolItemTemplateExplorer.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.toolItemTemplateExplorer.Image = ((System.Drawing.Image)(resources.GetObject("toolItemTemplateExplorer.Image"))); + this.toolItemTemplateExplorer.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolItemTemplateExplorer.Name = "toolItemTemplateExplorer"; + this.toolItemTemplateExplorer.Size = new System.Drawing.Size(23, 22); + this.toolItemTemplateExplorer.Text = "模板资源管理器"; + this.toolItemTemplateExplorer.Click += new System.EventHandler(this.toolItemTemplateExplorer_Click); + // + // toolItemPdmExplorer + // + this.toolItemPdmExplorer.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.toolItemPdmExplorer.Image = ((System.Drawing.Image)(resources.GetObject("toolItemPdmExplorer.Image"))); + this.toolItemPdmExplorer.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolItemPdmExplorer.Name = "toolItemPdmExplorer"; + this.toolItemPdmExplorer.Size = new System.Drawing.Size(23, 22); + this.toolItemPdmExplorer.Text = "PDM模型对象浏览器"; + this.toolItemPdmExplorer.Click += new System.EventHandler(this.toolItemPdmExplorer_Click); + // + // toolStripSeparator6 + // + this.toolStripSeparator6.Name = "toolStripSeparator6"; + this.toolStripSeparator6.Size = new System.Drawing.Size(6, 25); + // + // toolItemDbSchema + // + this.toolItemDbSchema.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.toolItemDbSchema.Image = ((System.Drawing.Image)(resources.GetObject("toolItemDbSchema.Image"))); + this.toolItemDbSchema.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolItemDbSchema.Name = "toolItemDbSchema"; + this.toolItemDbSchema.Size = new System.Drawing.Size(23, 22); + this.toolItemDbSchema.Text = "数据库架构查看器"; + this.toolItemDbSchema.Click += new System.EventHandler(this.toolItemDbSchema_Click); + // + // toolItemWebSubmitter + // + this.toolItemWebSubmitter.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.toolItemWebSubmitter.Image = ((System.Drawing.Image)(resources.GetObject("toolItemWebSubmitter.Image"))); + this.toolItemWebSubmitter.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolItemWebSubmitter.Name = "toolItemWebSubmitter"; + this.toolItemWebSubmitter.Size = new System.Drawing.Size(23, 22); + this.toolItemWebSubmitter.Text = "Web客户端模拟器"; + this.toolItemWebSubmitter.Click += new System.EventHandler(this.toolItemWebSubmitter_Click); + // + // toolStripSeparator4 + // + this.toolStripSeparator4.Name = "toolStripSeparator4"; + this.toolStripSeparator4.Size = new System.Drawing.Size(6, 25); + // + // toolItemDbList + // + this.toolItemDbList.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.toolItemDbList.Name = "toolItemDbList"; + this.toolItemDbList.Size = new System.Drawing.Size(150, 25); + this.toolItemDbList.ToolTipText = "数据库列表"; + this.toolItemDbList.SelectedIndexChanged += new System.EventHandler(this.toolItemDbList_SelectedIndexChanged); + // + // toolStripSeparator9 + // + this.toolStripSeparator9.Name = "toolStripSeparator9"; + this.toolStripSeparator9.Size = new System.Drawing.Size(6, 25); + // + // toolItemExecSql + // + this.toolItemExecSql.Image = ((System.Drawing.Image)(resources.GetObject("toolItemExecSql.Image"))); + this.toolItemExecSql.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolItemExecSql.Name = "toolItemExecSql"; + this.toolItemExecSql.Size = new System.Drawing.Size(75, 22); + this.toolItemExecSql.Text = "执行SQL"; + this.toolItemExecSql.ToolTipText = "执行SQL[快捷键F5]"; + this.toolItemExecSql.Click += new System.EventHandler(this.toolItemExecSql_Click); + // + // toolStripSeparator5 + // + this.toolStripSeparator5.Name = "toolStripSeparator5"; + this.toolStripSeparator5.Size = new System.Drawing.Size(6, 25); + // + // toolItemBuildCode + // + this.toolItemBuildCode.Image = ((System.Drawing.Image)(resources.GetObject("toolItemBuildCode.Image"))); + this.toolItemBuildCode.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolItemBuildCode.Name = "toolItemBuildCode"; + this.toolItemBuildCode.Size = new System.Drawing.Size(76, 22); + this.toolItemBuildCode.Text = "生成代码"; + this.toolItemBuildCode.Visible = false; + this.toolItemBuildCode.Click += new System.EventHandler(this.toolItemBuildCode_Click); + // + // toolItemBuildCodeSeparator + // + this.toolItemBuildCodeSeparator.Name = "toolItemBuildCodeSeparator"; + this.toolItemBuildCodeSeparator.Size = new System.Drawing.Size(6, 25); + this.toolItemBuildCodeSeparator.Visible = false; + // + // toolItemExit + // + this.toolItemExit.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.toolItemExit.Image = ((System.Drawing.Image)(resources.GetObject("toolItemExit.Image"))); + this.toolItemExit.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolItemExit.Name = "toolItemExit"; + this.toolItemExit.Size = new System.Drawing.Size(23, 22); + this.toolItemExit.Text = "退出"; + this.toolItemExit.Click += new System.EventHandler(this.toolItemExit_Click); + // + // toolStrip1 + // + this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.toolItemNewFile, + this.toolItemOpenFile, + this.toolStripSeparator10, + this.toolItemDbExplorer, + this.toolItemCodeExplorer, + this.toolItemTemplateExplorer, + this.toolItemPdmExplorer, + this.toolStripSeparator6, + this.toolItemDbSchema, + this.toolItemWebSubmitter, + this.toolStripSeparator4, + this.toolItemDbList, + this.toolStripSeparator9, + this.toolItemExecSql, + this.toolStripSeparator5, + this.toolItemBuildCode, + this.toolItemBuildCodeSeparator, + this.toolItemExit}); + this.toolStrip1.Location = new System.Drawing.Point(0, 25); + this.toolStrip1.Name = "toolStrip1"; + this.toolStrip1.Size = new System.Drawing.Size(636, 25); + this.toolStrip1.TabIndex = 3; + this.toolStrip1.Text = "toolStrip1"; + // + // menuItemFile + // + this.menuItemFile.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.menuItemNew, + this.menuItemOpen, + this.toolStripSeparator1, + this.menuItemClose, + this.menuItemCloseOther, + this.menuItemCloseAll, + this.toolStripSeparator2, + this.menuItemSave, + this.menuItemSaveAs, + this.toolStripSeparator3, + this.menuItemExit}); + this.menuItemFile.Name = "menuItemFile"; + this.menuItemFile.Size = new System.Drawing.Size(58, 21); + this.menuItemFile.Text = "文件(&F)"; + this.menuItemFile.DropDownOpening += new System.EventHandler(this.menuItemFile_DropDownOpening); + // + // menuItemNew + // + this.menuItemNew.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.menuItemNewAspx, + this.menuItemNewCpp, + this.menuItemNewCSharp, + this.menuItemNewHtml, + this.menuItemNewJava, + this.menuItemNewJavascript, + this.menuItemNewPHP, + this.menuItemNewText, + this.menuItemNewTSQL, + this.menuItemNewVB, + this.menuItemNewXML}); + this.menuItemNew.Name = "menuItemNew"; + this.menuItemNew.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.N))); + this.menuItemNew.Size = new System.Drawing.Size(174, 22); + this.menuItemNew.Text = "新建(&N)"; + // + // menuItemNewAspx + // + this.menuItemNewAspx.Name = "menuItemNewAspx"; + this.menuItemNewAspx.Size = new System.Drawing.Size(133, 22); + this.menuItemNewAspx.Text = "Aspx"; + this.menuItemNewAspx.Click += new System.EventHandler(this.menuItemNewAspx_Click); + // + // menuItemNewCpp + // + this.menuItemNewCpp.Name = "menuItemNewCpp"; + this.menuItemNewCpp.Size = new System.Drawing.Size(133, 22); + this.menuItemNewCpp.Text = "C/C++"; + this.menuItemNewCpp.Click += new System.EventHandler(this.menuItemNewCpp_Click); + // + // menuItemNewCSharp + // + this.menuItemNewCSharp.Name = "menuItemNewCSharp"; + this.menuItemNewCSharp.Size = new System.Drawing.Size(133, 22); + this.menuItemNewCSharp.Text = "CSharp"; + this.menuItemNewCSharp.Click += new System.EventHandler(this.menuItemNewCSharp_Click); + // + // menuItemNewHtml + // + this.menuItemNewHtml.Name = "menuItemNewHtml"; + this.menuItemNewHtml.Size = new System.Drawing.Size(133, 22); + this.menuItemNewHtml.Text = "Html"; + this.menuItemNewHtml.Click += new System.EventHandler(this.menuItemNewHtml_Click); + // + // menuItemNewJava + // + this.menuItemNewJava.Name = "menuItemNewJava"; + this.menuItemNewJava.Size = new System.Drawing.Size(133, 22); + this.menuItemNewJava.Text = "Java"; + this.menuItemNewJava.Click += new System.EventHandler(this.menuItemNewJava_Click); + // + // menuItemNewJavascript + // + this.menuItemNewJavascript.Name = "menuItemNewJavascript"; + this.menuItemNewJavascript.Size = new System.Drawing.Size(133, 22); + this.menuItemNewJavascript.Text = "Javascript"; + this.menuItemNewJavascript.Click += new System.EventHandler(this.menuItemNewJavascript_Click); + // + // menuItemNewPHP + // + this.menuItemNewPHP.Name = "menuItemNewPHP"; + this.menuItemNewPHP.Size = new System.Drawing.Size(133, 22); + this.menuItemNewPHP.Text = "PHP"; + this.menuItemNewPHP.Click += new System.EventHandler(this.menuItemNewPHP_Click); + // + // menuItemNewText + // + this.menuItemNewText.Name = "menuItemNewText"; + this.menuItemNewText.Size = new System.Drawing.Size(133, 22); + this.menuItemNewText.Text = "Text"; + this.menuItemNewText.Click += new System.EventHandler(this.menuItemNewText_Click); + // + // menuItemNewTSQL + // + this.menuItemNewTSQL.Name = "menuItemNewTSQL"; + this.menuItemNewTSQL.Size = new System.Drawing.Size(133, 22); + this.menuItemNewTSQL.Text = "TSQL"; + this.menuItemNewTSQL.Click += new System.EventHandler(this.menuItemNewTSQL_Click); + // + // menuItemNewVB + // + this.menuItemNewVB.Name = "menuItemNewVB"; + this.menuItemNewVB.Size = new System.Drawing.Size(133, 22); + this.menuItemNewVB.Text = "VB.NET"; + this.menuItemNewVB.Click += new System.EventHandler(this.menuItemNewVB_Click); + // + // menuItemNewXML + // + this.menuItemNewXML.Name = "menuItemNewXML"; + this.menuItemNewXML.Size = new System.Drawing.Size(133, 22); + this.menuItemNewXML.Text = "XML"; + this.menuItemNewXML.Click += new System.EventHandler(this.menuItemNewXML_Click); + // + // menuItemOpen + // + this.menuItemOpen.Name = "menuItemOpen"; + this.menuItemOpen.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.O))); + this.menuItemOpen.Size = new System.Drawing.Size(174, 22); + this.menuItemOpen.Text = "打开(&O)..."; + this.menuItemOpen.Click += new System.EventHandler(this.menuItemOpen_Click); + // + // toolStripSeparator1 + // + this.toolStripSeparator1.Name = "toolStripSeparator1"; + this.toolStripSeparator1.Size = new System.Drawing.Size(171, 6); + // + // menuItemClose + // + this.menuItemClose.Name = "menuItemClose"; + this.menuItemClose.Size = new System.Drawing.Size(174, 22); + this.menuItemClose.Text = "关闭"; + this.menuItemClose.Click += new System.EventHandler(this.menuItemClose_Click); + // + // menuItemCloseOther + // + this.menuItemCloseOther.Name = "menuItemCloseOther"; + this.menuItemCloseOther.Size = new System.Drawing.Size(174, 22); + this.menuItemCloseOther.Text = "除此之外全部关闭"; + this.menuItemCloseOther.Click += new System.EventHandler(this.menuItemCloseOther_Click); + // + // menuItemCloseAll + // + this.menuItemCloseAll.Name = "menuItemCloseAll"; + this.menuItemCloseAll.Size = new System.Drawing.Size(174, 22); + this.menuItemCloseAll.Text = "全部关闭"; + this.menuItemCloseAll.Click += new System.EventHandler(this.menuItemCloseAll_Click); + // + // toolStripSeparator2 + // + this.toolStripSeparator2.Name = "toolStripSeparator2"; + this.toolStripSeparator2.Size = new System.Drawing.Size(171, 6); + // + // menuItemSave + // + this.menuItemSave.Name = "menuItemSave"; + this.menuItemSave.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.S))); + this.menuItemSave.Size = new System.Drawing.Size(174, 22); + this.menuItemSave.Text = "保存(&S)"; + this.menuItemSave.Click += new System.EventHandler(this.menuItemSave_Click); + // + // menuItemSaveAs + // + this.menuItemSaveAs.Name = "menuItemSaveAs"; + this.menuItemSaveAs.Size = new System.Drawing.Size(174, 22); + this.menuItemSaveAs.Text = "另存为..."; + this.menuItemSaveAs.Click += new System.EventHandler(this.menuItemSaveAs_Click); + // + // toolStripSeparator3 + // + this.toolStripSeparator3.Name = "toolStripSeparator3"; + this.toolStripSeparator3.Size = new System.Drawing.Size(171, 6); + // + // menuItemExit + // + this.menuItemExit.Name = "menuItemExit"; + this.menuItemExit.Size = new System.Drawing.Size(174, 22); + this.menuItemExit.Text = "退出"; + this.menuItemExit.Click += new System.EventHandler(this.menuItemExit_Click); + // + // menuItemEdit + // + this.menuItemEdit.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.menuItemUndo, + this.menuItemRedo, + this.toolStripSeparator7, + this.menuItemCut, + this.menuItemCopy, + this.menuItemPaste, + this.menuItemDelete, + this.toolStripSeparator8, + this.menuItemSelectAll}); + this.menuItemEdit.Name = "menuItemEdit"; + this.menuItemEdit.Size = new System.Drawing.Size(59, 21); + this.menuItemEdit.Text = "编辑(&E)"; + this.menuItemEdit.DropDownOpening += new System.EventHandler(this.menuItemEdit_DropDownOpening); + // + // menuItemUndo + // + this.menuItemUndo.Name = "menuItemUndo"; + this.menuItemUndo.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Z))); + this.menuItemUndo.Size = new System.Drawing.Size(162, 22); + this.menuItemUndo.Text = "撤销(&Z)"; + this.menuItemUndo.Click += new System.EventHandler(this.menuItemUndo_Click); + // + // menuItemRedo + // + this.menuItemRedo.Name = "menuItemRedo"; + this.menuItemRedo.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Y))); + this.menuItemRedo.Size = new System.Drawing.Size(162, 22); + this.menuItemRedo.Text = "重复(&R)"; + this.menuItemRedo.Click += new System.EventHandler(this.menuItemRedo_Click); + // + // toolStripSeparator7 + // + this.toolStripSeparator7.Name = "toolStripSeparator7"; + this.toolStripSeparator7.Size = new System.Drawing.Size(159, 6); + // + // menuItemCut + // + this.menuItemCut.Name = "menuItemCut"; + this.menuItemCut.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.X))); + this.menuItemCut.Size = new System.Drawing.Size(162, 22); + this.menuItemCut.Text = "剪切(&X)"; + this.menuItemCut.Click += new System.EventHandler(this.menuItemCut_Click); + // + // menuItemCopy + // + this.menuItemCopy.Name = "menuItemCopy"; + this.menuItemCopy.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.C))); + this.menuItemCopy.Size = new System.Drawing.Size(162, 22); + this.menuItemCopy.Text = "复制(&C)"; + this.menuItemCopy.Click += new System.EventHandler(this.menuItemCopy_Click); + // + // menuItemPaste + // + this.menuItemPaste.Name = "menuItemPaste"; + this.menuItemPaste.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.V))); + this.menuItemPaste.Size = new System.Drawing.Size(162, 22); + this.menuItemPaste.Text = "粘贴(&V)"; + this.menuItemPaste.Click += new System.EventHandler(this.menuItemPaste_Click); + // + // menuItemDelete + // + this.menuItemDelete.Name = "menuItemDelete"; + this.menuItemDelete.ShortcutKeys = System.Windows.Forms.Keys.Delete; + this.menuItemDelete.Size = new System.Drawing.Size(162, 22); + this.menuItemDelete.Text = "删除(&D)"; + this.menuItemDelete.Click += new System.EventHandler(this.menuItemDelete_Click); + // + // toolStripSeparator8 + // + this.toolStripSeparator8.Name = "toolStripSeparator8"; + this.toolStripSeparator8.Size = new System.Drawing.Size(159, 6); + // + // menuItemSelectAll + // + this.menuItemSelectAll.Name = "menuItemSelectAll"; + this.menuItemSelectAll.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.A))); + this.menuItemSelectAll.Size = new System.Drawing.Size(162, 22); + this.menuItemSelectAll.Text = "全选(&A)"; + this.menuItemSelectAll.Click += new System.EventHandler(this.menuItemSelectAll_Click); + // + // menuItemView + // + this.menuItemView.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.menuItemDatabaseExplorer, + this.menuItemCodeExplorer, + this.menuItemTemplateExplorer, + this.menuItemPdmExplorer, + this.menuItemOutput}); + this.menuItemView.Name = "menuItemView"; + this.menuItemView.Size = new System.Drawing.Size(60, 21); + this.menuItemView.Text = "视图(&V)"; + // + // menuItemDatabaseExplorer + // + this.menuItemDatabaseExplorer.Checked = true; + this.menuItemDatabaseExplorer.CheckState = System.Windows.Forms.CheckState.Checked; + this.menuItemDatabaseExplorer.Name = "menuItemDatabaseExplorer"; + this.menuItemDatabaseExplorer.Size = new System.Drawing.Size(188, 22); + this.menuItemDatabaseExplorer.Text = "数据库对象浏览器"; + this.menuItemDatabaseExplorer.Click += new System.EventHandler(this.menuItemDatabaseExplorer_Click); + // + // menuItemCodeExplorer + // + this.menuItemCodeExplorer.Name = "menuItemCodeExplorer"; + this.menuItemCodeExplorer.Size = new System.Drawing.Size(188, 22); + this.menuItemCodeExplorer.Text = "代码资源管理器"; + this.menuItemCodeExplorer.Click += new System.EventHandler(this.menuItemCodeExplorer_Click); + // + // menuItemTemplateExplorer + // + this.menuItemTemplateExplorer.Name = "menuItemTemplateExplorer"; + this.menuItemTemplateExplorer.Size = new System.Drawing.Size(188, 22); + this.menuItemTemplateExplorer.Text = "模板资源管理器"; + this.menuItemTemplateExplorer.Click += new System.EventHandler(this.menuItemTemplateExplorer_Click); + // + // menuItemPdmExplorer + // + this.menuItemPdmExplorer.Name = "menuItemPdmExplorer"; + this.menuItemPdmExplorer.Size = new System.Drawing.Size(188, 22); + this.menuItemPdmExplorer.Text = "PDM模型对象浏览器"; + this.menuItemPdmExplorer.Click += new System.EventHandler(this.menuItemPdmExplorer_Click); + // + // menuItemOutput + // + this.menuItemOutput.Checked = true; + this.menuItemOutput.CheckState = System.Windows.Forms.CheckState.Checked; + this.menuItemOutput.Name = "menuItemOutput"; + this.menuItemOutput.Size = new System.Drawing.Size(188, 22); + this.menuItemOutput.Text = "输出"; + this.menuItemOutput.Click += new System.EventHandler(this.menuItemOutput_Click); + // + // menuItemTools + // + this.menuItemTools.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.menuItemDbSchemaViewer, + this.menuItemDbDocBuilder, + this.menuItemWebSubmitter, + this.menuItemIisLogParser, + this.menuItemStringConnector, + this.menuItemStringConverter}); + this.menuItemTools.Name = "menuItemTools"; + this.menuItemTools.Size = new System.Drawing.Size(59, 21); + this.menuItemTools.Text = "工具(&T)"; + // + // menuItemDbSchemaViewer + // + this.menuItemDbSchemaViewer.Name = "menuItemDbSchemaViewer"; + this.menuItemDbSchemaViewer.Size = new System.Drawing.Size(175, 22); + this.menuItemDbSchemaViewer.Text = "数据库架构查看器"; + this.menuItemDbSchemaViewer.Click += new System.EventHandler(this.menuItemDbSchemaViewer_Click); + // + // menuItemDbDocBuilder + // + this.menuItemDbDocBuilder.Name = "menuItemDbDocBuilder"; + this.menuItemDbDocBuilder.Size = new System.Drawing.Size(175, 22); + this.menuItemDbDocBuilder.Text = "数据库文档生成器"; + this.menuItemDbDocBuilder.Click += new System.EventHandler(this.menuItemDbDocBuilder_Click); + // + // menuItemWebSubmitter + // + this.menuItemWebSubmitter.Name = "menuItemWebSubmitter"; + this.menuItemWebSubmitter.Size = new System.Drawing.Size(175, 22); + this.menuItemWebSubmitter.Text = "Web客户端模拟器"; + this.menuItemWebSubmitter.Click += new System.EventHandler(this.menuItemWebSubmitter_Click); + // + // menuItemIisLogParser + // + this.menuItemIisLogParser.Name = "menuItemIisLogParser"; + this.menuItemIisLogParser.Size = new System.Drawing.Size(175, 22); + this.menuItemIisLogParser.Text = "IIS日志解析器"; + this.menuItemIisLogParser.Click += new System.EventHandler(this.menuItemIisLogParser_Click); + // + // menuItemStringConnector + // + this.menuItemStringConnector.Name = "menuItemStringConnector"; + this.menuItemStringConnector.Size = new System.Drawing.Size(175, 22); + this.menuItemStringConnector.Text = "字符串拼接工具"; + this.menuItemStringConnector.Click += new System.EventHandler(this.menuItemStringConnector_Click); + // + // menuItemStringConverter + // + this.menuItemStringConverter.Name = "menuItemStringConverter"; + this.menuItemStringConverter.Size = new System.Drawing.Size(175, 22); + this.menuItemStringConverter.Text = "字符串转换工具"; + this.menuItemStringConverter.Click += new System.EventHandler(this.menuItemStringConverter_Click); + // + // menuItemHelp + // + this.menuItemHelp.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.menuItemAbout}); + this.menuItemHelp.Name = "menuItemHelp"; + this.menuItemHelp.Size = new System.Drawing.Size(61, 21); + this.menuItemHelp.Text = "帮助(&H)"; + // + // menuItemAbout + // + this.menuItemAbout.Name = "menuItemAbout"; + this.menuItemAbout.Size = new System.Drawing.Size(188, 22); + this.menuItemAbout.Text = "关于 Kalman Studio"; + this.menuItemAbout.Click += new System.EventHandler(this.menuItemAbout_Click_1); + // + // menuStrip1 + // + this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.menuItemFile, + this.menuItemEdit, + this.menuItemView, + this.menuItemTools, + this.menuItemHelp}); + this.menuStrip1.Location = new System.Drawing.Point(0, 0); + this.menuStrip1.Name = "menuStrip1"; + this.menuStrip1.Size = new System.Drawing.Size(636, 25); + this.menuStrip1.TabIndex = 2; + this.menuStrip1.Text = "menuStrip1"; + // + // Main + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(636, 439); + this.Controls.Add(this.dockPanel); + this.Controls.Add(this.toolStrip1); + this.Controls.Add(this.menuStrip1); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.IsMdiContainer = true; + this.MainMenuStrip = this.menuStrip1; + this.Name = "Main"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "Kalman Studio"; + this.WindowState = System.Windows.Forms.FormWindowState.Maximized; + this.Load += new System.EventHandler(this.Main_Load); + this.toolStrip1.ResumeLayout(false); + this.toolStrip1.PerformLayout(); + this.menuStrip1.ResumeLayout(false); + this.menuStrip1.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private WeifenLuo.WinFormsUI.Docking.DockPanel dockPanel; + private System.Windows.Forms.ToolStripButton toolItemNewFile; + private System.Windows.Forms.ToolStripButton toolItemOpenFile; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator10; + private System.Windows.Forms.ToolStripButton toolItemDbExplorer; + private System.Windows.Forms.ToolStripButton toolItemCodeExplorer; + private System.Windows.Forms.ToolStripButton toolItemTemplateExplorer; + private System.Windows.Forms.ToolStripButton toolItemPdmExplorer; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator6; + private System.Windows.Forms.ToolStripButton toolItemDbSchema; + private System.Windows.Forms.ToolStripButton toolItemWebSubmitter; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator4; + private System.Windows.Forms.ToolStripComboBox toolItemDbList; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator9; + private System.Windows.Forms.ToolStripButton toolItemExecSql; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator5; + private System.Windows.Forms.ToolStripButton toolItemBuildCode; + private System.Windows.Forms.ToolStripSeparator toolItemBuildCodeSeparator; + private System.Windows.Forms.ToolStripButton toolItemExit; + private System.Windows.Forms.ToolStrip toolStrip1; + private System.Windows.Forms.ToolStripMenuItem menuItemFile; + private System.Windows.Forms.ToolStripMenuItem menuItemNew; + private System.Windows.Forms.ToolStripMenuItem menuItemOpen; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; + private System.Windows.Forms.ToolStripMenuItem menuItemClose; + private System.Windows.Forms.ToolStripMenuItem menuItemCloseOther; + private System.Windows.Forms.ToolStripMenuItem menuItemCloseAll; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator2; + private System.Windows.Forms.ToolStripMenuItem menuItemSave; + private System.Windows.Forms.ToolStripMenuItem menuItemSaveAs; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator3; + private System.Windows.Forms.ToolStripMenuItem menuItemExit; + private System.Windows.Forms.ToolStripMenuItem menuItemEdit; + private System.Windows.Forms.ToolStripMenuItem menuItemUndo; + private System.Windows.Forms.ToolStripMenuItem menuItemRedo; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator7; + private System.Windows.Forms.ToolStripMenuItem menuItemCut; + private System.Windows.Forms.ToolStripMenuItem menuItemCopy; + private System.Windows.Forms.ToolStripMenuItem menuItemPaste; + private System.Windows.Forms.ToolStripMenuItem menuItemDelete; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator8; + private System.Windows.Forms.ToolStripMenuItem menuItemSelectAll; + private System.Windows.Forms.ToolStripMenuItem menuItemView; + private System.Windows.Forms.ToolStripMenuItem menuItemDatabaseExplorer; + private System.Windows.Forms.ToolStripMenuItem menuItemCodeExplorer; + private System.Windows.Forms.ToolStripMenuItem menuItemTemplateExplorer; + private System.Windows.Forms.ToolStripMenuItem menuItemPdmExplorer; + private System.Windows.Forms.ToolStripMenuItem menuItemOutput; + private System.Windows.Forms.ToolStripMenuItem menuItemTools; + private System.Windows.Forms.ToolStripMenuItem menuItemDbSchemaViewer; + private System.Windows.Forms.ToolStripMenuItem menuItemDbDocBuilder; + private System.Windows.Forms.ToolStripMenuItem menuItemWebSubmitter; + private System.Windows.Forms.ToolStripMenuItem menuItemIisLogParser; + private System.Windows.Forms.ToolStripMenuItem menuItemHelp; + private System.Windows.Forms.ToolStripMenuItem menuItemAbout; + private System.Windows.Forms.MenuStrip menuStrip1; + private System.Windows.Forms.ToolStripMenuItem menuItemNewAspx; + private System.Windows.Forms.ToolStripMenuItem menuItemNewCpp; + private System.Windows.Forms.ToolStripMenuItem menuItemNewCSharp; + private System.Windows.Forms.ToolStripMenuItem menuItemNewHtml; + private System.Windows.Forms.ToolStripMenuItem menuItemNewJava; + private System.Windows.Forms.ToolStripMenuItem menuItemNewJavascript; + private System.Windows.Forms.ToolStripMenuItem menuItemNewPHP; + private System.Windows.Forms.ToolStripMenuItem menuItemNewText; + private System.Windows.Forms.ToolStripMenuItem menuItemNewTSQL; + private System.Windows.Forms.ToolStripMenuItem menuItemNewVB; + private System.Windows.Forms.ToolStripMenuItem menuItemNewXML; + private System.Windows.Forms.ToolStripMenuItem menuItemStringConnector; + private System.Windows.Forms.ToolStripMenuItem menuItemStringConverter; + + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/MainForm/Main.cs b/src/Kalman.Studio/MainForm/Main.cs new file mode 100644 index 0000000..6eadd72 --- /dev/null +++ b/src/Kalman.Studio/MainForm/Main.cs @@ -0,0 +1,634 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using System.Net; +using WeifenLuo.WinFormsUI.Docking; +using System.IO; +using Kalman.Data.SchemaObject; + +namespace Kalman.Studio +{ + public partial class Main : Form + { + DatabaseExplorer dbExplorer = new DatabaseExplorer(); + Output output = new Output(); + //DbSchemaViewer viewer = new DbSchemaViewer(); + CodeExplorer codeExplorer = new CodeExplorer(); + TemplateExplorer templateExplorer = new TemplateExplorer(); + PdmExplorer pdmExplorer = new PdmExplorer(); + + public Main() + { + InitializeComponent(); + } + + private void Main_Load(object sender, EventArgs e) + { + Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException); + AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); + + output.Show(dockPanel); + dbExplorer.Show(dockPanel); + } + + void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) + { + Exception ex = ((Exception)e.ExceptionObject); + Log(ex); + MessageBox.Show(ex.Message); + } + + void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e) + { + Log(e.Exception); + MessageBox.Show(e.Exception.Message); + } + + void Log(Exception ex) + { + if (output == null) output = new Output(); + + output.ClearText(); + output.AppendText(ex.ToString()); + output.DockState = DockState.DockBottom; + output.Activate(); + + string logFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "log.txt"); + File.AppendAllText(logFile, string.Format("{0}\r\n{1}\r\n", ex.Message, ex.StackTrace)); + } + + #region 文件菜单项事件处理 + + //当文件菜单打开的时候,初始化子菜单项状态 + private void menuItemFile_DropDownOpening(object sender, EventArgs e) + { + //没有激活的文档窗体时,禁用关闭菜单项 + if (dockPanel.DocumentStyle == DocumentStyle.SystemMdi) + { + menuItemClose.Enabled = + menuItemCloseOther.Enabled = + menuItemCloseAll.Enabled = + menuItemSave.Enabled = + menuItemSaveAs.Enabled = (ActiveMdiChild != null); + } + else + { + menuItemClose.Enabled = (dockPanel.ActiveDocument != null); + menuItemCloseOther.Enabled = (dockPanel.ActiveDocument != null); + menuItemCloseAll.Enabled = + menuItemSave.Enabled = + menuItemSaveAs.Enabled = (dockPanel.DocumentsCount > 0); + } + } + + #region 新建文档 + + string GetCodeTemplateText(string ext) + { + string text = ""; + string path = Path.Combine(Application.StartupPath, "Template\\template" + ext); + + if (File.Exists(path)) text = File.ReadAllText(path); + return text; + } + + private void menuItemNewAspx_Click(object sender, EventArgs e) + { + NewDockDocument("WebForm", CodeType.ASPX, GetCodeTemplateText(".aspx")); + } + + private void menuItemNewCpp_Click(object sender, EventArgs e) + { + NewDockDocument("Class", CodeType.CPP, GetCodeTemplateText(".cpp")); + } + + private void menuItemNewCSharp_Click(object sender, EventArgs e) + { + NewDockDocument("Class", CodeType.CSHARP, GetCodeTemplateText(".cs")); + } + + private void menuItemNewHtml_Click(object sender, EventArgs e) + { + NewDockDocument("Page", CodeType.HTML, GetCodeTemplateText(".htm")); + } + + private void menuItemNewJava_Click(object sender, EventArgs e) + { + NewDockDocument("Class", CodeType.JAVA, GetCodeTemplateText(".java")); + } + + private void menuItemNewJavascript_Click(object sender, EventArgs e) + { + NewDockDocument("Script", CodeType.JS, GetCodeTemplateText(".js")); + } + + private void menuItemNewPHP_Click(object sender, EventArgs e) + { + NewDockDocument("Page", CodeType.PHP, GetCodeTemplateText(".php")); + } + + private void menuItemNewText_Click(object sender, EventArgs e) + { + NewDockDocument("TextFile", null, null); + } + + private void menuItemNewTSQL_Click(object sender, EventArgs e) + { + NewDockDocument("Query", CodeType.TSQL, GetCodeTemplateText(".sql")); + } + + private void menuItemNewVB_Click(object sender, EventArgs e) + { + NewDockDocument("Class", CodeType.VB, GetCodeTemplateText(".vb")); + } + + private void menuItemNewXML_Click(object sender, EventArgs e) + { + NewDockDocument("XmlFile", CodeType.XML, GetCodeTemplateText(".xml")); + } + + #endregion + + //打开文档 + private void menuItemOpen_Click(object sender, EventArgs e) + { + OpenDockDocument(); + } + + //关闭当前激活的文档 + private void menuItemClose_Click(object sender, EventArgs e) + { + if (dockPanel.ActiveDocument is DockExplorer) return; + if (dockPanel.ActiveDocument != null) + { + dockPanel.ActiveDocument.DockHandler.Close(); + } + } + + //除此之外全部关闭 + private void menuItemCloseOther_Click(object sender, EventArgs e) + { + CloseOtherDockDocument(); + } + + //全部关闭 + private void menuItemCloseAll_Click(object sender, EventArgs e) + { + CloseAllDockDocument(); + } + + //保存 + private void menuItemSave_Click(object sender, EventArgs e) + { + if (dockPanel.ActiveDocument is IDockDocument) + { + ((IDockDocument)dockPanel.ActiveDocument).Save(); + } + } + + //另存为 + private void menuItemSaveAs_Click(object sender, EventArgs e) + { + if (dockPanel.ActiveDocument is IDockDocument) + { + ((IDockDocument)dockPanel.ActiveDocument).SaveAs(); + } + } + + //退出程序 + private void menuItemExit_Click(object sender, EventArgs e) + { + this.Close(); + Application.Exit(); + } + + #endregion + + #region 编辑菜单项事件处理 + + private void menuItemEdit_DropDownOpening(object sender, EventArgs e) + { + //没有激活的文档窗体时,禁用关闭菜单项 + if (dockPanel.DocumentStyle == DocumentStyle.SystemMdi) + { + menuItemUndo.Enabled = + menuItemRedo.Enabled = + menuItemCut.Enabled = + menuItemPaste.Enabled = + menuItemCopy.Enabled = + menuItemDelete.Enabled = + menuItemSelectAll.Enabled = (ActiveMdiChild != null); + } + else + { + menuItemUndo.Enabled = + menuItemRedo.Enabled = + menuItemCut.Enabled = + menuItemPaste.Enabled = + menuItemCopy.Enabled = + menuItemDelete.Enabled = + menuItemSelectAll.Enabled = (dockPanel.DocumentsCount > 0); + } + } + + private void menuItemUndo_Click(object sender, EventArgs e) + { + if (dockPanel.ActiveContent is IDockDocument) ((IDockDocument)dockPanel.ActiveContent).Undo(); + } + + private void menuItemRedo_Click(object sender, EventArgs e) + { + if (dockPanel.ActiveContent is IDockDocument) ((IDockDocument)dockPanel.ActiveContent).Redo(); + } + + private void menuItemCut_Click(object sender, EventArgs e) + { + if (dockPanel.ActiveContent is IDockDocument) ((IDockDocument)dockPanel.ActiveContent).Cut(sender, e); + } + + private void menuItemCopy_Click(object sender, EventArgs e) + { + if (dockPanel.ActiveContent is IDockDocument) ((IDockDocument)dockPanel.ActiveContent).Copy(sender, e); + } + + private void menuItemPaste_Click(object sender, EventArgs e) + { + if (dockPanel.ActiveContent is IDockDocument) ((IDockDocument)dockPanel.ActiveContent).Paste(sender, e); + } + + private void menuItemDelete_Click(object sender, EventArgs e) + { + if (dockPanel.ActiveContent is IDockDocument) ((IDockDocument)dockPanel.ActiveContent).Delete(sender, e); + } + + private void menuItemSelectAll_Click(object sender, EventArgs e) + { + if (dockPanel.ActiveContent is IDockDocument) ((IDockDocument)dockPanel.ActiveContent).SelectAll(sender, e); + } + #endregion + + #region 视图菜单项事件处理 + // + private void menuItemView_DropDownOpening(object sender, EventArgs e) + { + menuItemDatabaseExplorer.Checked = !dbExplorer.IsHidden; + //menuItemCodeExplorer.Checked = !codeExplorer.IsHidden; + //menuItemTemplateExplorer.Checked = !templateExplorer.IsHidden; + menuItemOutput.Checked = !output.IsHidden; + //menuItemPdmExplorer.Checked = !pdmExplorer.IsHidden; + } + + //数据库连接管理器 + private void menuItemDatabaseExplorer_Click(object sender, EventArgs e) + { + ShowDbExplorer(); + } + + //代码管理器 + private void menuItemCodeExplorer_Click(object sender, EventArgs e) + { + ShowCodeExplorer(); + } + //模板管理器 + private void menuItemTemplateExplorer_Click(object sender, EventArgs e) + { + ShowTemplateExplorer(); + } + //PDM文件管理器 + private void menuItemPdmExplorer_Click(object sender, EventArgs e) + { + ShowPdmExplorer(); + } + //输出 + private void menuItemOutput_Click(object sender, EventArgs e) + { + ShowOutput(); + } + + #region DoShow + public void ShowDbExplorer() + { + if (menuItemDatabaseExplorer.Checked == false) + { + dbExplorer.Show(dockPanel); + menuItemDatabaseExplorer.Checked = true; + } + else + { + dbExplorer.Hide(); + menuItemDatabaseExplorer.Checked = false; + } + } + public void ShowCodeExplorer() + { + if (menuItemCodeExplorer.Checked == false) + { + codeExplorer.Show(dockPanel); + menuItemCodeExplorer.Checked = true; + } + else + { + codeExplorer.Hide(); + menuItemCodeExplorer.Checked = false; + } + } + public void ShowTemplateExplorer() + { + if (menuItemTemplateExplorer.Checked == false) + { + templateExplorer.Show(dockPanel); + menuItemTemplateExplorer.Checked = true; + } + else + { + templateExplorer.Hide(); + menuItemTemplateExplorer.Checked = false; + } + } + public void ShowPdmExplorer() + { + if (menuItemPdmExplorer.Checked == false) + { + pdmExplorer.Show(dockPanel, DockState.DockLeft); + menuItemPdmExplorer.Checked = true; + } + else + { + pdmExplorer.Hide(); + menuItemPdmExplorer.Checked = false; + } + } + public void ShowOutput() + { + if (menuItemOutput.Checked == false) + { + output.Show(dockPanel); + menuItemOutput.Checked = true; + } + else + { + output.Hide(); + menuItemOutput.Checked = false; + } + } + #endregion + + #endregion + + #region 工具菜单项事件处理 + + #region DoShow + + void ShowDbSchemaViewer() + { + foreach (IDockContent dc in dockPanel.Documents) + { + if (dc is DbSchemaViewer) + { + dc.DockHandler.Activate(); + return; + } + } + + DbSchemaViewer viewer = new DbSchemaViewer(); + viewer.Show(dockPanel); + } + + void ShowWebSubmitter() + { + //foreach (IDockContent dc in dockPanel.Documents) + //{ + // if (dc is WebSubmitter) + // { + // dc.DockHandler.Activate(); + // return; + // } + //} + + WebSubmitter ws = new WebSubmitter(); + //ws.Show(dockPanel); + //ws.ShowDialog(); + ws.Show(); + } + + #endregion + + private void menuItemDbSchemaViewer_Click(object sender, EventArgs e) + { + ShowDbSchemaViewer(); + } + + private void menuItemWebSubmitter_Click(object sender, EventArgs e) + { + ShowWebSubmitter(); + } + + private void menuItemDbDocBuilder_Click(object sender, EventArgs e) + { + DbDocBuilder doc = new DbDocBuilder(); + doc.ShowDialog(); + } + + private void menuItemIisLogParser_Click(object sender, EventArgs e) + { + IISLogParseCondition condition = new IISLogParseCondition(this.dockPanel); + condition.Show(); + } + + private void menuItemQueryTools_Click(object sender, EventArgs e) + { + //QueryTools qt = new QueryTools(); + //qt.Show(); + } + + private void menuItemStringConnector_Click(object sender, EventArgs e) + { + //foreach (IDockContent dc in dockPanel.Documents) + //{ + // if (dc is StringConnector) + // { + // dc.DockHandler.Activate(); + // return; + // } + //} + StringConnector connector = new StringConnector(); + connector.ShowDialog(); + } + + private void menuItemStringConverter_Click(object sender, EventArgs e) + { + StringConvertor convertor = new StringConvertor(); + convertor.ShowDialog(); + } + + #endregion + + #region 帮助菜单项事件处理 + + private void menuItemAbout_Click(object sender, EventArgs e) + { + //(new About()).ShowDialog(); + } + + #endregion + + #region 工具栏命令事件处理 + + private void toolItemNewFile_Click(object sender, EventArgs e) + { + NewDockDocument("Document", null, null); + } + + private void toolItemOpenFile_Click(object sender, EventArgs e) + { + OpenDockDocument(); + } + + private void toolItemDbExplorer_Click(object sender, EventArgs e) + { + ShowDbExplorer(); + } + private void toolItemCodeExplorer_Click(object sender, EventArgs e) + { + ShowCodeExplorer(); + } + private void toolItemPdmExplorer_Click(object sender, EventArgs e) + { + ShowPdmExplorer(); + } + private void toolItemTemplateExplorer_Click(object sender, EventArgs e) + { + ShowTemplateExplorer(); + } + private void toolItemDbSchema_Click(object sender, EventArgs e) + { + ShowDbSchemaViewer(); + } + private void toolItemWebSubmitter_Click(object sender, EventArgs e) + { + ShowWebSubmitter(); + } + + //选择数据库改变时,同时改变当前激活的查询分析器的DbName属性 + private void toolItemDbList_SelectedIndexChanged(object sender, EventArgs e) + { + if (this.dockPanel.ActiveDocument != null) + { + if (this.dockPanel.ActiveDocument is QueryAnalyzer) + { + ((QueryAnalyzer)this.dockPanel.ActiveDocument).CurrentDatabase = toolItemDbList.SelectedItem as SODatabase; + } + } + } + //执行SQL语句 + private void toolItemExecSql_Click(object sender, EventArgs e) + { + if (this.dockPanel.ActiveDocument != null) + { + if (this.dockPanel.ActiveDocument is QueryAnalyzer) + { + ((QueryAnalyzer)this.dockPanel.ActiveDocument).ExecuteSql(); + } + } + } + //生成代码 + private void toolItemBuildCode_Click(object sender, EventArgs e) + { + if (this.dockPanel.ActiveDocument != null) + { + if (this.dockPanel.ActiveDocument is CodeBuilder) + { + ((CodeBuilder)this.dockPanel.ActiveDocument).DoBuildCode(); + } + } + } + + + #region 控制生成代码工具栏图标的显示和隐藏 + public void ShowBuildCodeIcon() + { + toolItemBuildCode.Visible = true; + toolItemBuildCodeSeparator.Visible = true; + } + public void HideBuildCodeIcon() + { + toolItemBuildCode.Visible = false; + toolItemBuildCodeSeparator.Visible = false; + } + #endregion + + private void toolItemExit_Click(object sender, EventArgs e) + { + if (MessageBox.Show("是否退出Kalman Studio", "信息提示", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes) + { + this.Close(); + Application.Exit(); + } + } + + #region 工具栏数据库下拉列表相关操作 + public void AddDbListItem(SODatabase db) + { + try + { + toolItemDbList.Items.Add(db); + } + catch { } + } + public void ClearDbList() + { + toolItemDbList.Items.Clear(); + } + public SODatabase GetCurrentDatabase() + { + return toolItemDbList.SelectedItem as SODatabase; + } + public void SetCurrentDB(SODatabase db) + { + foreach (object item in toolItemDbList.Items) + { + if (item.ToString() == db.Name) toolItemDbList.SelectedItem = item; + } + } + #endregion + + + + #endregion + + #region 封装对输出窗体的操作 + + /// + /// 向输出窗体追加一行文本 + /// + /// + public void AppendOutputLine(string s) + { + if (output == null) output = new Output(); + output.AppendLine(s); + output.Activate(); + } + /// + /// 清除所有输出内容 + /// + public void ClearOutputText() + { + if (output == null) return; + output.ClearText(); + } + + #endregion + + private void menuItemAbout_Click_1(object sender, EventArgs e) + { + (new About()).ShowDialog(); + } + + + } +} diff --git a/src/Kalman.Studio/MainForm/Main.resx b/src/Kalman.Studio/MainForm/Main.resx new file mode 100644 index 0000000..d363804 --- /dev/null +++ b/src/Kalman.Studio/MainForm/Main.resx @@ -0,0 +1,436 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAC9SURBVDhPrZMxDsIwDEV7JI7BMThSbkBGNjIyeuyGx44Z + GTOyGf+KQJQ6CUj9UtQu/33n152mvRQoyvawhBuLDyzn6911s2BuyV9IDsdTHxKImwCnAJq5D8GoLTkf + VnM+5lV8BwAwIBlkA7SoltJTJKU0ApDtf5vjYwTQoiwhHeYYBwA0XSuPDgAvI4CWtAGkbzovsd8BGi71 + SdfRkU78D6AojgFQM80/AvL3bj2xTOYe1NtWbl79vtcPvHJerLvyrThQ4osAAAAASUVORK5CYII= + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGMSURBVDhPvZMvT8QwGMb3CWASBXXnYJIEM0VwV4khNweK + zZCcuxqSudVxbjXAuatETiIrkZPIfoOH9+3KcgdcCIYlv6TZ+vx52yxJ/uNZPLS50gaqJpYWi6ZVf8ot + 5hrT66ZgUVm2KZuV963k98n6sZF2pfGV9VOjd6WUd62UNxpMwsLeGXhvA/AGeDewRmP9vPix6qd4MKCN + nkSbYjbAWwVD38xSDWgFzdQVtpoFAxbE5EGsiOJHvhlwSjCIdFaDGc/EKBontohNQps6tuF6vtfBoH+l + zXQm6KnBLmg0Hs+tJMrZ1CSjAZmwuHshg7BpYwRHayeBVwn/kqM3GW6vzjwZZAnX8TTzVrqLBkFIsLDL + g9jbDOpGYHa+N1xzMHBDddfF9A0huiGVhX6VwdUpiguBk8m+CAZ8GK7bmD0mjqlR2BsBp9OQfjw5tONV + 8rXwVTpLB6OTkY7WHaVZNWDmAroSQ/rJkdwy0KqAmhOVRFVIFJc55EWO/DRDlglkQkAcpEjTFIL404/0 + 2+YPSd/lulP9pHQAAAAASUVORK5CYII= + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIJSURBVDhPjZPfS1NhGMfPn9C93nQTlSJCFITQVdhNUK6I + RBREiy5EaadTcxVlG0Od/dCB4pnhtiNIUpu7WPNM7abECjskEqy6iA1xNI40p87Yiq/nfWZvNafsgS8v + vO95Pu/3eZ73CIIR2mwvCsX2SwqWmN0MAVgwtGRIQ3Y9iJeKCAa4unAMv34DxVa6QB25hFzcip+pF8gs + 9yP93oRU5ChGpCoC7BUMmgfIJmx8qEPm+1OkP7VBnzyAlVEBbrFiXwBzRIAp+QI2NBMySQ/WoyL0UDlW + FAGyWFmag/8BZqyGypAgQIkOwsNGCZpRQnIU6WgeMD0h4Yk3jAFFhX0oANtgADe7fWiWHnPx3oSH6wiw + pXux+UWkRH1cgD/gh9WpUBnnW2w419oFS48PfvUtQVotAzs9cF/E2ruz+BEbQlJrw52HYwiqr+AJvMY1 + q4v3wSGH4FIixpiB6bmPBOEupgxIb8cZUtdtM5raHWjs6EY8oZMj9qHd3ge3bwKxRBrq3BIB7rue5yF8 + pgVDP10v4XM8lS8rUg3blYNouu4kbWVztFIKn2mRV8Mg2rccJf97zJLvOj37O3h0T6KbGWQxluXl/AGd + Mpn3dvDAYuG2j1fXECQaS+6CFO2BvfMGJd9qKMOJw0e4dQaZX/xKEM/km78lFf5pz7wyLtdW4mTFoV3P + mUGCM/N8fxvHW7n1e0RLPAAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAE0SURBVDhPfZO5bcQwEEVZj5rYKhirFJYiBYYDNqGNjQ0V + GlALmzug530ey7UoExjw0PxjhpRz3fj8eibi/n3X3K/jFrXv809rgOlIefw8TxGXmKabvyZBoY0BQTCC + xyNdk2BzpFzPqgNcDJ3IwUBZZ6mQHzZbTPOgFBR6AnoSLTlsXg3cISGOCwd9CQJaIrOneQGiSjBoJuoh + 5O4HS/YW0+I0ezufFlO1uHQQF/skkkwUZlQzCHVqZi8CK6n1gNoE3iAwIGBU5zxXIm+EXGMjqO8BAMoC + W5I3JSVrnWulDMA7NzBqopSMgGSSaGYwBxBwZQL1QQm9g1o3gHX9KCVkByL5Q7Bv7kWgJGyWZNm3suoe + JZqWw7X16SU2gkKm2suT1Q3UdTe//Y2VgMN8C/H/X7egfwFrtDnWFWELTAAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAFvSURBVDhPY2CgFth06MZ/GF6//x6YvXr3xf8rd57/v3jT + CTAfr10gTbjAvHWH/5t6Jv/vnLEGtyEg23CBqUt2/t919Ap+Q/AZMHnRdrBmGMbqFZA/QWD3he//1xz9 + +H/61pf/G5c+/F806zZYHORFEAYZgtcAbN74+v3X/6evPuM3ABRQuFwAcgXIgH2nn/zPKO/C7oJZK/dh + DcNPX3+CNT98/vH/+Zuv/89euhG7AaCQRndB28pH/3vXPvo/dfOT//eefPh//f67/2VzXmA3ABTS6ABk + +7uP3/+/ef8N7AqQAcUzn/73KzuKaQjMAORYWLjnxf+dZ9+Cbc2acOd/bPN5MM6e9f2/dsQ6VEPQXQCy + FYZBmiuW/v0fN/nP/8ieT/+DW57+d8w7hmoIzABYfIPow+efgZ0NslXVe9Z/df+F/zWClv+3z9r/3zBs + EaYLkFMbiB2T0/i/bdJCcMjDMNgQv7n4Mxa+XAdyCbI8AFBACsX1pZRiAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHWSURBVDhPhZLNaxpRFMXnj7GUZhNsXRgsTWmy6CYBIXSR + XboJVNGtNIKCCFIRRBQkiviJaRXEzKhgtBiDNojUD2ahmIpYFDeVQlECRU+cV9QOBt6Dw2Peu/f35lwO + 8477C8lZfUPCObNYnU4HLMsiFovB5/PB6XTC4XDA4/Gg0WiAkRubjwIkH74RQCqVQr/fx2g0wnQ6xWQy + wWAwQK1WQyAQAHP68Tvqv+839GT7ggCE14WXWq0WUbVaRS6XQzKZhMvlAqM8uSbNv/7MMRzP8WM0A9+f + YQmIx+PIZrPI5/OkKRQKwW63w2g0QqfTgVG85QhgOMaiGeB/ApU7rADRaBSVSgXdbhfNZhOFQgGRSAQW + iwVarRbMlixGiv/XM9kXPJV+JhbC4TDS6TQymcxqkFarFXq9Hmq1mtSs1s7hlfhgcRMMBlEsFskcSqUS + OI6D1+uFyWSCSqVa179U5qFYaHs3KYL4/X6Uy2W02+2VBWEOZrMZGo3mX638IItP5x0ca27JLn29hvR6 + PSQSCQhW3G43bDYbDAYDGSLP8+I/Pnh/s2FB5JH28ero6waAllQR88UeC735VgShJVUEkO2zECBLPX9z + CVpSaa6oSaUCaEmlAmhJfQBNZvLUUyflPwAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAKfSURBVDhPpVPfS5NRGP4u+ge67TIQuoogFJHIEETRUikj + ZmSlSwVT88eo9WPKEjK1pc0wNTWbbg3nr1ScupmunLPW1szC1TRzlZEKk02XNX16v6Ns7KJueuHhnO/l + fZ73nOc9H8f9b5isszC8+gC98T0GxqbwVPcGHVoz1L2TaO024pHmOR6qR1Hbpoe8ZQj50joE9RydnEEg + tmj7i+AluAkuwjK2sEjrAmEOF2/UBAsMGqZ3+JuMXNEHiJ8AGQ0AL85j+MVb9I1YoBmYgKJzDHVKLe42 + dqP0ngpcj85CRB9hg7AGiYb6enxw/thg5H+FuKwJXHv/S6r5ycjAKgpbgY9OL8wzbgyPb5/u+/w4zHoZ + tOoi6DTFWF7cFs4tpuvwRgGenfuuICx3DvuFVuxLGfILWHUl8K00YXO9E655GXqUtwMCze0Gv1lgZjmZ + WXkltezefJjbk7HpOI/1pRYsqHejo17E8kJRBbg61Qi5vESf3wifIZG1MvK5gnIyzcQKJxQJ+G1LZAJT + 1RxUNdsCgmwpOH62wFdGBhyMDNhI1AxF1ygrNDTH+QXsDzgUpBxg+aS0q+AqG/pp+ylofAKZlwSMfoGu + qmi/gEW+C4+rigICt2q7qdjOxsc7P2JxISSxjXLP2Lz5mLX2QFF1BvWVWZCe3YMvDivLx6QUgpNWExPT + fudDktqwN0ZOuUF6LF2s8G8ReTwH3PU79OzwmmCirgaCnvZaWntRKldCXNaIPMl9pIsqybSbSEy7Rp2L + EHkiB+HHMsFdKaeXgwmsOcvhmZfC4xDDY78E97tMuG2pcFtOYnUyHi5jFFYNEQiNvxD8L/ACcamXEXta + hGhBIaJO5eNIch4O0/EOJWUjIiEL4UczERafgdA4IQ7GpgcJ/AHendgcGUlabAAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAG7SURBVDhPfZMhc+MwFIRNeldm/4MrOVzDg4KFgoGCBwWP + VbBQMOwEwyLUCRQ0O8FAwTILhm33OUnHrpvTzJtxbO2n3aeXppmtmAo+aihIl4op831GOGT8ff3n55rF + s4j/t0JMUNrchtwEnIDKEkAaMvonQvZfOBGbq3URXwFKW7qwE2Rhn8JuDihvdTot7BJ8iIiHhJzL5fc5 + yqoXV0B548YjRZXi6mAOHmYb4VgC9YSuHez3XWSXQct+4OaTRjwFBJ6qdxV9IuSPhydEXC0AuGv78XsT + I60KwO4KzKBhsoXdgoCCh0HBWLqxfgJIHz4ijE3jCfCRHwTgQoUJ3JTYMGbXPqIPGtoQ8NutI9Smwdj+ + 6EI8RwjbDOMBFR36qKAcITZCbyzcS7gB+PnYyz2jVtSNhnMRygfoFw9l6WbDHjCC7PF0t+gBI9jxW5Oi + 86jHgnrfoWqNQLFkFtty8jRIbKpc67KJbfswtq0pjDJV1yETkn8pFArysbL43+DzlwDpJp6fu0By5T3n + +wb5SSFvwzQ8c/FNgEDkekrhKTw5Mr9YPk/ieRrntRokAciEyYhq1nXmr3Mvgs8lmnca9T/wS0FnYAAA + AABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADVSURBVDhPtZIhDsJAEEVH4qgjEJJW4lhZQ1oHCnoD6sCx + ErkOgmElrpW4coP2BvQIe4S9wadDwgFmE0bPe/9Pdon+Me3tpNxVoz+X6I8F3ocsEeUw7J8WqA28KVGv + 5k4k4GQ8DFAqoIjQpSMvEwy1YfUX9nmEekEyQXfYdu48SDYsIOwnZEQN2uNOOz0IBrhXhN2MlEjAy12e + wKcEK63/S7qnsWbBfkpanP4DXkWOYJjBKovD09+Xk+EP1WRxEdSCYX5Gu4jCzmjWsWG4Wo7DzwiqLoU+ + zvdlgW6ts3EAAAAASUVORK5CYII= + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACDSURBVDhPY2AYpqCFwYAyn3Uw/GeYQokhIANmAHE/uYY0 + MPxveNDwn2EC0BCyvFPB8N/ghgPEEJBrSkh1CdAAhQsK/xVOKPwveFDwnwHIJy1QQS7YYfDfYIPBf4YC + clwA1ATWnAHUnE+q80FuBdkKwinkaAYZQLbNsJAi22bSgpo6qgEVFTNJc4FFjQAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAM1SURBVDhPZdN9TNNHHMfxU2txlEy0FBcJ0ylqRUxmxjLm + /phUjSaEB5ViEaU2ImXoEFmAJi6IDnAPdAVxU9QqRbA/H6kKSEGNwLKB4MYE5gTGNFOCmkhUtsVJ8t4P + lk2bXfJNLpe7Vz753p0QLw19lovUT93YKtsokdopPn6NIrlsFdewHmvFWt7CVyd/ZN+pLswF9fjNWMTL + 50XKngYut92jua2fwqPNOGp6kBp6OX+1T17/je9uDFBY4uC0q5qT8rqXOtgTSLM2Y7XXY94Yz7pV4SyL + SSYl7xyf2FspreqiurmfUF08euM2zlzuQTklyBMolb5lg/59rl8xwXMnTlsYBoOB8gudlFX/zKXWO+ii + k0hMsSDV3kDx6kxP4JCjjvTkBTy9PxX+UHOnURCzcjEdnX0MPhqhs/chS6I2kWgeBTr+D5h21ROdmEl+ + nhJ3g8BomkJaRg73Bod4NgJDT4ZZsWYzCcnZlLtaGK+a7pkgcbeb1MwClr73Fto3V/BhRoHcsDp6bz+g + +ptfudDYw5r1W0jYnE3Z6SbEpGmeQOq2rbiOWvjzYQtlJWbOHklnf04kS5dHErYqh71ldcRu3M56OYFd + akBMVL8AAgLmEh+9kMeDx4AWbneXcvP7Iop2LGa6fwC6OAv7HedZa/poLMHBilrEhMkeCVj+rh/PnuTD + SDH5aa8zK1BDbLyZrI/zqW3s4qdf7hNl+ADDJgvFh88gxnn/B6AYLyjeNRuGExi6u1q+RiO1zkVkZmfR + fuspt+4OM/DgMRF68xhgO3BCPuyF8FIK4iIUNFW9JkcPpco+De0MFV/mauCv+bidKozGdbTffETfwDC6 + qCQMSRY+31f5D+DrI2hye8HvKnIzBMHzQ1i5oZAYYx6HvvClplIwd7YPEXHbWbJ2J35zlmHaupPP/gXk + z8C8IEHIPCGL3uTZJOyu6+xxdBBpSCcgMIiQsGhCw/W8o4vl7fA4dhR8jfWAJO9XvujBKKScHMiW3ErO + XunjeE0nFTXdHHH9gHSxG2fdaHUhubs519iPKcPKOIWP5zvw9X8DlWYWk9RaXvHT4q3RovIPHpt7lCYY + lXomExQT+RssnhRIzLKxxwAAAABJRU5ErkJggg== + + + + 22, 19 + + + 132, 18 + + + + AAABAAEAMDAAAAEAIACoJQAAFgAAACgAAAAwAAAAYAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A+/j4APPg4QDoxMQA3KilD92prADjuroA7tDUAOS1pDDPhmBpw2k6iMJo + QHnMfWRK26eiEe7V1gD79fUA/vn5APv19QD79vYA/vn7AP/+/gD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD//v4A+O/vAN+smjLJeFJrvmAylst6X07ZoKQA37CyAM1/ + WWm5Zjvj0odc/cBzR/C1YDPIz4luSuvNzgD05uYA8+DhAO/U1QDw2NkA+OrqAP75+wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD+/PwA47abR8dyQpCzYDXlz4Zb/bth + NrrKeF9OzIJrQcVrQXnKglvw5qeG/+Ked/+7bEHnx3NNbeK0twDowsIA47q6AN6vsQDitLcA7tDUAPjv + 7wD+/PwA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//7+APv4+AD56ekGzX1MkL5t + Qvbkonz/6rmf/9WQbPy3XjO8tV4xwrdjOdfx08L+/vj2//rq4f/JdUrIy3tjStedngDOh3M8xm1HdMh1 + VF/SkYMm4ri6APDd3AD89/cA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A/vn7APbm + 5wDjua4jv2s9qOu2mf/78er//Pf0/+ivkv/flGv/35No/+Kfef/68ez//vz8//749v/SkG73umEzusJk + OYG4Xi+muWY77bZlOtvHdFNf2aGcEOrMzQD58PEA////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A+/X1AO3PzgbdqaQSx2s9mfLSwfr+/Pz///36//fk2//uwqr/8dC8//bg0v/++Pb//vr4//zz + 7//mrIv/5KJ8/8Z7UvfSgFP+4pp0/+Giff+0YDPIzohtS+vNzgD58PEA////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A68i3Msd1RZDBZTiQxm1IbcFoOqv02cv//vr4///9+v/////////////9 + +v/++Pb//vj2//749v/46d//7sau/+Sifv/rvqP/+/Hq/+/Ltv/Ukm76x3JAje7V1gP68vIA//7+AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD//v4A25xza7lrQOXNglf7tmY95rppPO7y0sH//vz8//74 + 9v/++Pb/++/o//PUwfvz08L7++/o//749v///fr//vr4//vy7v///fr///////vy7v/dpYj4yHNDje3O + 0AP26OkA/vn5AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD++vgC0IJSjM6KZvjkoXv/4Jhv/+2/ + pf///fr//vj2//338v/ZlG3b0oZTp9OMWZDUjluQ1o1ap92bctj89vH//vj2//76+P/++Pb//ffy/+Wv + k/DLdEavz4luSeO1uADu0NQA+fDxAP///wD///8A//7+AP///wD///8A//7+APv4+AD58PEA+u/wAPry + 8gD7+PgA/vz8AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD69vEJ0odUkfbh + 0P767ub/9uDS//rx7P/++vj/+Onf/9GAVcnOg2Jf5b6wJvbq6Aj88/EI9eDSI+KvjFzXjmDC9uHT/v74 + 9v/++vj/6r+l/8BjNpnFcEtqyHdZWNaYjx/pxsgA+e7uAPv4+AD68fIA+u/wAPv29gD//v4A/vn5APTm + 5gDtz9AA6cbIAOvP0ADz3d4A+fDxAP78/AD///8A////AP///wD///8A////AP///wD///8A////AP// + /wDz4M8m1Itaqv749v/++vj//vz8//76+P///fr/7cy5/cBiM4vWnJcS5Lu7AO/U1QD05uYA+OrqAPXh + 3wnWlG1q3qF94/749v//////7sSs/8l+VvjGeVLjtGI11MJmOJDoxcQG9ObmAPPg4QDt0dIA6szNAPPd + 3gD58PEA+O/vAOrNyQnerKoI26SmAN2prADlvL4A89/gAPv4+AD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD25Nge1o1co+Wsi+vswaf29tvN/f749v/+/Pz/89C//7ZfMrnMfGRJ2aCkAN+w + sgDlvL4A58PDAOfBwwDUlX8+y3dKv/z28f/+/Pz/9uPX/+Gbdf/flGn/1oti/sFoOpPoxcIL7tLUAOW+ + wgDao54S3amsAOS9vQDv1NUA4a+aOcZvQZHBZTeQwmY+fMt+Z0fcqKUP7tXWAPrx8gD79vYA+vLyAPz3 + 9wD+/PwA////AP///wD///8A////AP///wD///8A7M24OtiZb3PPf1F/yXVIt/z59v/+/Pz/89nK/8uB + Wvi8YDOqyndcUtGOgiLXnZ0F1pmUFM2DbUPCakB8wHRJ6P739f/++Pb//vj2//ru5v/23c//26WG9cl3 + Sn/rzc4A2qCLO8h0SnS+YTSZy3pfTtukpgDfsbMAynpRcrtpQevMgVj8v3RJ9LVgM8fRiXBH6szNAPPg + 4QDw2NkA7c/QAPDc3QD58PEA////AP///wD///8A////AP///wD///8A////AOa6okS8az2xvm5F8fjp + 3////fr/+vHs/+ewj//VkGr9t2M5z7heMae+XzKPvF8ym7VeMbu5Yzjz67uh///////++Pb//vj2///9 + +v/+/Pz/3px44dSQbGbco4RQynlJrcV6UezQimL8vWM0qcp8ZEnMgWhGw2c6gsyGW/nmp4b/4p53/7ps + QOXHc05s4rO1AOW+wgDesbAG3amsAOO6ugDw2twA////AP///wD///8A////AP///wD///8A//7+AdGK + V4u8a0D05KF7//fo3v///fr///36//fi1v/nsI//4Zlw/9+UbP/Lglf60oRb/t6PZP/kon7/+Onf///9 + +v/89vH/6ruj9O3Bqff25Nj+2I1iyOCrkEnOfU2Uz35T/t+TaP/or5L/yXtT+LVcLre2YTTFtWI32+7K + uf/++vj/+urh/898U9DKeFxS1ZWOGMx8Y1HAYzOQy3tjTNignAznwcMA////AP///wD///8A////AP// + /wD///8A/vv5BNKLWI7iro/6/PPv//76+P/++Pb//vj2//78/P/67ub/78iw/+ewj//in3n/56yK/+/L + tv/68ez///36//76+P/jsJD4wmU7gcZtQoDKdkaVy3pKjuCxoyjBbUCs6bWW//rr5P/89/T/6raX/92S + Z//fj2b/4pp0//rr5P/+/Pz//ffy/9ebevbIcUS0wWU6f71oPs/HfFD7umQ2xct7X07fsLIA////AP// + /wD///8A////AP///wD///8A////AOa5m1HclmvP//v5///9+v/rv6z36Lab9P/9+v///fr//vz8//z3 + 9P/68ez//Pf0/////////fr//vj2//rx7P/jpoL/umc818+FZFvnv74M4LGkItminRLBZTiV6bmf8//+ + /v///fr/9+Tb/+7Apv/vy7b/9NfG//v38v/++vj/+/Lu/+esiv/fn3v/yoBZ9tuGVv/konz/1ZBt/L1j + NKXXmYow////AP///wD///8A////AP///wD///8A////APbo3hjdpH9g3ZVu29yfe+y/b0biv2xD0tGA + Vc3z1sr8/vj2//749v///fr//vj2//zz7//89/T//vr4//749v/x0Lz/xn5X9st5TH/Ymn5LwGk8pr9l + NpnBZTiCwGxCy/fl2//++vj///36//78/P///////vz8//749v/++Pb//vj2//rq4f/rvqP/4p53/+7A + pv/78u7/7sau/7xsQ+PQhV9o////AP///wD///8A////AP///wD///8A////AP75+QDdp4pRvWo8xch8 + UfrfkGX/4KF8/71jNKnVjmrj//36//76+P/tx7b957aX/+anhv/ptZb//PPv///9+v/++vj/zYBZ19GK + aVvHbT2LyHtU+diNZ/7HfFD51IRW/vTay//+/Pz//vj2//749v/66uH/7cCp9u/Ls/n77+j//vj2///9 + +v/++Pb/+/Hq///9+v/+/Pz/+/Lu/8x/WOLPh2No////AP///wD///8A////AP///wD//v4A/vn5APTf + 2BXGd0eb14RW/9yLXf/kon7/5aaE/9SPafzrwaz7//////z39P/y1Mn/+Ofd//bf0//z0L//79C9/ue1 + mvPRf1LEw2U3jc2EaU3AZjeg5a+N/+ivkv/in3n/78u2///9+v/++Pb/89jK/deMY8/ShVSi15JkgNSN + Wo3WjVqn3Jdw1fvy7f/++Pb//vr4//749v/02c393Jdx4MhsP6HXmYov////AP///wD///8A////AP// + /wD7+PgA9eXlAN+slzu3Zjm84JVs/+/IsP/68ez/676j/+Wmgv/tv6X/89LB//PZyv/239P//vz8//78 + /P//////57id/sBvRtfBZTiCxGlCdbBZLsTMflX7/PPv//749v/78u7//vr4//749v/34tT+ynFDrNSP + cVLqx7sd+u/wAPv18gPy3M4i4KyKWdeMYcj45dz+/vj2//v38v/HfFPjwGI0h8JoQHnPiHFA////AP// + /wD///8A////AP/+/gD47e0A6svMANKLcknCbkPH+OXc///////+/Pz/+u7n/+asi//fk2j/4Jhv/+Wj + f//34tb///36//76+P/78u7/5qyL/+Sifv/NhVr4umlA7duHWf/kon7//vj2/////////fr//vj2//74 + 9v/irZPyw2k/e9umpwDku7sA7c/QAPDa3ADw3dwA6snDEMx9UnnlrZDw/vr4//76+P/lrIv/zXxR/b1u + Q/DGbER5////AP///wD///8A////AP75+QDjtqE8zHtSdcdzTWzHck1o35134//7+f/++Pb///36//jl + 3P/2283/+uvk//zz7//++Pb//vj2//76+P/68ez/67mc/+Sifv/lo3//35Bl/9yLXf/rtpn/78iw/+m/ + p//ouKH4//36//749v/ktpn9wWM1kcx+aEXZoKQA3qqtAOGzswDhs7MA1ZWDNMVrQH/WlnL1/vz8//78 + /P/z08L/4Zt1/+Cbcv/DZzmK////AP///wD///8A////APfs5wzJekqUvW9G7bhnPuW0YDXOvWo/0fTT + w////fr//vj2///9+v/+/Pz///36//76+P/++Pb//vj2//749v/++vj//PPv//PTwv/mrIv/5aaC//TX + xv///fr/8sy5/9iVb/7WlG7r/vr4//78/P/x0Lz/z45s9MRnOqPHcU5lzH5oRcyCa0HJdlZdwGI0j7Rh + Nubuwaf///////749v/++Pb/+vHs//LUyf/Hbj6J////AP///wD///8A////AOvHsTe9bD+44pp0/+Ka + dP/imnT/3o1i/+/IsP/+/Pz//vj2//749v/++Pb//vj2//749v/++Pb//vj2//749v/++Pb//vr4//78 + /P/68ez//Pf0///////++vj//vz8/+u+o//imnT//PPv///9+v/67ub/5qqI/9eYdPy/b0bgt2E2xbdg + NcK5ZDrYv3JG9N+QZf/249f//vz8//749v/++Pb//vr4//338v/LfEyK////AP///wD///8A////AOGu + jla8bUDS4p95/+GZcP/fk2j/6K+S//76+P/++Pb//vj2//749v/++Pb//vj2//749v/89vH//vj2//74 + 9v/++Pb//vj2//749v/++vj//vj2//749v///fr/9uHT/+29o//x0Lz//vj2//749v/++vj/9+je/+ew + j//hlm3/4Jhv/9+Uaf/fk2j/4pp0//bbzf/++vj//vr4/+Suj+/ThlrL3px24eSrjOzYm29z////AP// + /wD///8A////ANmacXHgpILp9+je//PZyv/wzLn/+urh///9+v/++Pb//vj2//749v/46+L/3Zl14NSI + WsbShVa22pBnzuOriev+9/X//vj2//749v/++Pb//vj2//zz7//qwKb+y3hNyvLVxP7///////36//76 + +P/++Pb//vz8//vx6v/z1cX/78Ot/+2/pf/yzLn/9+je//78/P/++vj/+eje/8Z3TNLMfmBU0IpkZ9eX + a3Pszbc6////AP///wD///8A////ANWPXoTuzLn6//36//78/P////////36//749v/++Pb//vj2//rw + 7P/IdUrJx3NQZs+Ib0fZoY4z2Zh8UNCHXHLYjWTP+u/n//749v/++Pb//vj2//v38v/nq4n/14pk/ue3 + nP7++vj/68Gr+9OLX9Tjqojq+u7m///9+v/+/Pz//vz8//78/P////////36//749v///fr/89PC/9eP + a/7CazuU6cnGDPnw8QD///8A////AP///wD///8A////ANONXIj34tT+/Pb0//76+P/++Pb//vj2//74 + 9v/++Pb//vz8//PQv/+4ZzzexmxHbs6EczXYn6IA3KWnANeXjx3Hb0lz3Jt56/76+P/++Pb//vj2//// + ///vyLD/35Bl/+GWbf/or5L/tWM2zdONb1fVj2ZywXRIz/ru5v/++vj//vj2//vq4//wzLn66LWY8fzy + 7v/++Pb//vj2/+7Bqf/Id0eY8tzWEf75+QD///8A////AP///wD///8A////AOa8nFDWjVqi2Ixeu9aL + Xcvls5jz/vj2//749v/++Pb///36/+3Bqf/hon3/v3FJ57tfMaDBZTp/w2c/er5fMpSxWi/S3p+A/f/9 + +v/++Pb//vj2///9+v/249f/566N/+Wjf//fmW7/tmE0u9ujjjrdp4hXvXFD1Prx7P/++vj/+OHX/sp2 + SKDNfEuO15Zoet2gd93++Pb/+OPX/tuWb9vRiFWP+/X1Bf/+/gD///8A////AP///wD///8A////AP// + /wD04tgd3ayNT8JsPpvGfFXr//36//749v/++Pb//vz8//PVxf/kon7/5aaE/9yWbv/FeE/1v3FI8dOI + Xf3bh1n/6rmf///////++Pb//vj2//749v/++vj//Pf0//zz7//46Nz/yHFDq+C0pifeq4lb0Y5j1/fi + 2/799/L/7cmw+dGIWIL26+sE8dnKKdKOW4zdl27S1I1apuKuil/03c4m////AP///wD///8A////AP// + /wD///8A////AP///wD68eoMyXtKlc58T/3glWz/+u7m///9+v/++Pb//vj2//z39P/uwKb/5KJ+/+Ka + dP/innf/4Jhv/9+Uaf/flGn/9t3P//78/P/++Pb//vj2//749v/++Pb//vj2//76+P/45df+yndGk/DX + 1Qvy3M4i0o5bjNSOW5XXjmC42I5iwdOLWov/+voB////APbl2x3kt5dW9ePXIP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wDw1cIuv3BDsdyLXf/innf/+Onf///9+v/++Pb//vj2//74 + 9v/++Pb/8My5/+Wmgv/in3n/4pp0/+anhv/249f///36//749v/++Pb//vj2//vv6v/vyLL5++zl///7 + +f/swqr30IJSi/vy8gH//v4A/v78Avry7Q7u0ro37MqwQPz49gj///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wDovaBNwXZIy+/IsP/78er///36//74 + 9v/++Pb//vj2//749v/++Pb///36//zz7//45dz/+urh//z39P///fr//vj2//749v/++Pb//vr4/+O1 + mPfCZjmDyG5BoM+BU7zXil636L+kR//+/gD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD04tUi1o1cpvXi + 1P3//fr//vj2//749v/78er//vj2//749v/++Pb//vj2//76+P///fr///36//749v/++Pb//vj2//74 + 9v/++vj/9uDS/+Slgf/Jek/Qz4drUuCumTvryrc1////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A57ydT9aNXK/66uH/++rl/92Yb9jTilmq4aJ94/z27//++vj//vj2//749v/++Pb//vj2//74 + 9v/++Pb//vj2//749v///fr/9NfG/+Wjf//KgVvpzoFacPXl5QD++fsA////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AOa7m1HYjmK8145etuGujFzw1cIw36iBaNCHVrPtxq77/vr4//74 + 9v/++Pb/+/Hq//TZzf3swqz389TB+/749v/++Pb//vz8/+/Ltv/QimLi15ZvaPv19QD//v4A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP7+/ALszbc77tPAM////wD///8A////ANKL + XITjt5z5//36//749v/45dz+znhKrs59TJPVj2GB1o1cqvbf0P3++Pb//vj2//PSwfzShVat7tG9L//+ + /gD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A+vLqENKLWJf88ez//vj2//749v/rv6T20IJWf/Ph3wv++fsA57ydT9iQZL/y2cv93JZt0tKL + WJbnvJ1N////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A/vr4BdSNWo/em3XZ5a6P7vPVxfzgoX3i3aN8Z/75+wD//v4A/vn2Bue9 + oE7UjluW5LeXVvbl2x3///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////APPf0CXisYxe255yddWPXoffqYJn8dbFL/// + /wD///8A////AP///wD68ewP////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD//////////////////8zM//////// + mZn///////9mZv/cD////zMz/wwP////AAD+AA////////wACH///8zM/AAAP///mZn4AAA///9mZvAA + AB///zMz8AAAH///AADgAAA//////+AAAB///8zM4AeAD+f/mZngB8ANwP9mZvAAABDA/zMz+AAAAADf + AADwAAAAAAf///AAAAAAB8zM+AAAAAADmZn4AAAAAANmZvwAAAAAAzMz+AAAAAADAAD4AAAAIAP///gA + AAD4A8zM4AAAAHgDmZnAAAAAAANmZsAAAAAAAzMzwAAAAAADAADAAAAAAAP//8AAAAAAD8zMwAGAAAAP + mZnAAAAAAA9mZuAAAAAAHzMz4AAAAAR/AADgAAACD////+AAAAf//8zM4AAAD///mZnwAAA///9mZvgA + AD///zMz+OAAP///AAD/wCB///8AAP/AYP///wAA/+B7////AAD///////8AAP///////wAA//////// + AAA= + + + \ No newline at end of file diff --git a/src/Kalman.Studio/Program.cs b/src/Kalman.Studio/Program.cs new file mode 100644 index 0000000..f6366e8 --- /dev/null +++ b/src/Kalman.Studio/Program.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Windows.Forms; + +namespace Kalman.Studio +{ + static class Program + { + /// + /// 应用程序的主入口点。 + /// + [STAThread] + static void Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new Main()); + } + } +} diff --git a/src/Kalman.Studio/Properties/AssemblyInfo.cs b/src/Kalman.Studio/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..af86c2a --- /dev/null +++ b/src/Kalman.Studio/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 有关程序集的常规信息通过下列属性集 +// 控制。更改这些属性值可修改 +// 与程序集关联的信息。 +[assembly: AssemblyTitle("Kalman.Studio")] +[assembly: AssemblyDescription(".Net平台开发辅助工具")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Kalman")] +[assembly: AssemblyProduct("Kalman.Studio")] +[assembly: AssemblyCopyright("Copyright © 2013")] +[assembly: AssemblyTrademark("Kalman")] +[assembly: AssemblyCulture("")] + +// 将 ComVisible 设置为 false 使此程序集中的类型 +// 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型, +// 则将该类型上的 ComVisible 属性设置为 true。 +[assembly: ComVisible(false)] + +// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID +[assembly: Guid("a55bd079-4636-4e63-a01b-e8539d45de44")] + +// 程序集的版本信息由下面四个值组成: +// +// 主版本 +// 次版本 +// 内部版本号 +// 修订号 +// +// 可以指定所有这些值,也可以使用“内部版本号”和“修订号”的默认值, +// 方法是按如下所示使用“*”: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("2.2.*")] +[assembly: AssemblyFileVersion("2.2.0")] diff --git a/src/Kalman.Studio/Properties/Resources.Designer.cs b/src/Kalman.Studio/Properties/Resources.Designer.cs new file mode 100644 index 0000000..e6978a3 --- /dev/null +++ b/src/Kalman.Studio/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// 此代码由工具生成。 +// 运行时版本:4.0.30319.42000 +// +// 对此文件的更改可能会导致不正确的行为,并且如果 +// 重新生成代码,这些更改将会丢失。 +// +//------------------------------------------------------------------------------ + +namespace Kalman.Studio.Properties { + using System; + + + /// + /// 一个强类型的资源类,用于查找本地化的字符串等。 + /// + // 此类是由 StronglyTypedResourceBuilder + // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 + // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen + // (以 /str 作为命令选项),或重新生成 VS 项目。 + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.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() { + } + + /// + /// 返回此类使用的缓存的 ResourceManager 实例。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Kalman.Studio.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// 使用此强类型资源类,为所有资源查找 + /// 重写当前线程的 CurrentUICulture 属性。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/src/Kalman.Studio/Properties/Resources.resx b/src/Kalman.Studio/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/src/Kalman.Studio/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/Kalman.Studio/Properties/Settings.Designer.cs b/src/Kalman.Studio/Properties/Settings.Designer.cs new file mode 100644 index 0000000..40be113 --- /dev/null +++ b/src/Kalman.Studio/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// 此代码由工具生成。 +// 运行时版本:4.0.30319.42000 +// +// 对此文件的更改可能会导致不正确的行为,并且如果 +// 重新生成代码,这些更改将会丢失。 +// +//------------------------------------------------------------------------------ + +namespace Kalman.Studio.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.3.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; + } + } + } +} diff --git a/src/Kalman.Studio/Properties/Settings.settings b/src/Kalman.Studio/Properties/Settings.settings new file mode 100644 index 0000000..3964565 --- /dev/null +++ b/src/Kalman.Studio/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/Kalman.Studio/SQL/IISLogData.sql b/src/Kalman.Studio/SQL/IISLogData.sql new file mode 100644 index 0000000..1e51325 --- /dev/null +++ b/src/Kalman.Studio/SQL/IISLogData.sql @@ -0,0 +1,20 @@ +create table IISLogData ( + LogID int identity, + LogTime datetime null, + Method varchar(8) null, + ClientIP varchar(20) null, + ClientIPLocation varchar(100) null, + Status varchar(10) null, + SubStatus varchar(10) null, + Win32Status varchar(10) null, + ReceiveBytes varchar(10) null, + SendBytes varchar(10) null, + UriStem varchar(1024) null, + Referer varchar(1024) null, + UriStemAlias varchar(100) null, + RefererAlias varchar(100) null, + UserAgentAlias varchar(100) null, + UserAgent varchar(1024) null, + constraint PK_IISLOGDATA primary key (LogID) +) +go \ No newline at end of file diff --git a/src/Kalman.Studio/T4Template/Asp.Net/Controller/Controller.tt b/src/Kalman.Studio/T4Template/Asp.Net/Controller/Controller.tt new file mode 100644 index 0000000..915e96d --- /dev/null +++ b/src/Kalman.Studio/T4Template/Asp.Net/Controller/Controller.tt @@ -0,0 +1,198 @@ +<#@ template language="C#" hostSpecific="true" debug="false" #> +<#@ output extension=".cs" #> +<# + TableHost host = (TableHost)(Host); + SOTable table = host.Table; + List list = host.ColumnList; + string nameSpace = host.GetString("NameSpace"); + string className = host.GetString("ClassName"); + if(string.IsNullOrEmpty(nameSpace))nameSpace = "Entity"; + if(string.IsNullOrEmpty(className))className = table.Name; + string tableName = table.Name.EndsWith("s") ?table.Name.TrimEnd('s') : table.Name.Trim(); + + int length = tableName.Length; + string controllerName = tableName + "Controller"; + string lowerTableName = tableName.Substring(0, 1).ToLower() + tableName.Substring(1, length - 1); + string serviceName = "_" + lowerTableName + "Service"; +#> +using Ebboy.Core; +using Ebboy.Core.Domain; +using Ebboy.Core.PagedList; +using Ebboy.Services.Servers; +using Ebboy.Services.Users; +using Ebboy.Web.Framework.Controllers; +using System; +using System.Linq; +using System.Web.Mvc; +using Loamen.Web.Controllers; + +namespace <#= nameSpace #> +{ + /// + /// <#= table.Comment == "" ? table.Name : table.Comment.Replace("\r\n"," ") #> + /// + public class <#= controllerName #>: UserBaseController + { + #region Fileds + private readonly IMemberService _userService; + private readonly IWorkContext _workContext; + private readonly I<#=tableName#>Service <#=serviceName#>; + #endregion + + #region Ctor + public <#= controllerName #>( + IMemberService userService, + IWorkContext workContext, + I<#=tableName#>Service <#=lowerTableName#>Service) + { + _userService = userService; + _workContext = workContext; + <#=serviceName#> = <#=lowerTableName#>Service; + } + #endregion + + #region Action + /// + /// 首页列表 + /// + /// + /// + public ActionResult Index(int page = 1) + { + var pageOption = new PageOption() { PageIndex = page < 1 ? 1 : page }; + + var list = <#=serviceName#>.GetAllList(); + + var pageList = new PagedList<<#=tableName#>>(list, pageOption); + + return View(pageList); + } + + /// + /// 详细 + /// + /// + /// + public ActionResult Details(int id) + { + var model = <#=serviceName#>.GetById(id); + return View(model); + } + + /// + /// 添加 + /// + /// + public ActionResult Create() + { + return View(); + } + + /// + /// 提交添加 + /// + /// + /// + [HttpPost] + public ActionResult Create(<#=tableName#> model) + { + try + { + if (!ModelState.IsValid) + { + ModelState.AddModelError("", "实体参数错误!"); + return View(model); + } + + <#=serviceName#>.Insert(model); + this.Tips("添加成功!"); + return RedirectToAction("Index"); + } + catch (Exception ex) + { + ModelState.AddModelError("", ex.Message); + return View(model); + } + } + + /// + /// 修改 + /// + /// + /// + public ActionResult Edit(int id) + { + var model = <#=serviceName#>.GetById(id); + return View(model); + } + + /// + /// 修改 + /// + /// + /// + [HttpPost] + public ActionResult Edit(<#=tableName#> model) + { + try + { + if (!ModelState.IsValid) + { + ModelState.AddModelError("", "实体参数错误!"); + return View(model); + } + var entity = <#=serviceName#>.GetById(model.Id); + <# foreach (SOColumn c in list) + { #> + entity.<#= c.Name #> = model.<#= c.Name #>; + <# } #> + <#=serviceName#>.Update(entity); + + this.Tips("修改成功!"); + return RedirectToAction("Index"); + } + catch (Exception ex) + { + ModelState.AddModelError("", ex.Message); + return View(model); + } + } + + /// + /// 删除 + /// + /// + /// + public ActionResult Delete(int id) + { + var model = <#=serviceName#>.GetById(id); + return View(model); + } + + /// + /// 提交删除 + /// + /// + /// + /// + [HttpPost] + public ActionResult Delete(int id,<#=tableName#> model) + { + try + { + <#=serviceName#>.Delete(id); + this.Tips("删除成功!"); + return RedirectToAction("Index"); + } + catch (Exception ex) + { + this.Tips(ex.Message); + return RedirectToAction("Index"); + } + } + #endregion + + #region Utilities + #endregion + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/T4Template/Asp.Net/Entity/Default.tt b/src/Kalman.Studio/T4Template/Asp.Net/Entity/Default.tt new file mode 100644 index 0000000..a8d067a --- /dev/null +++ b/src/Kalman.Studio/T4Template/Asp.Net/Entity/Default.tt @@ -0,0 +1,34 @@ +<#@ template language="C#" hostSpecific="true" debug="false" #> +<#@ output extension=".cs" #> +<# + TableHost host = (TableHost)(Host); + SOTable table = host.Table; + List list = host.ColumnList; + string nameSpace = host.GetString("NameSpace"); + string className = host.GetString("ClassName"); + if(string.IsNullOrEmpty(nameSpace))nameSpace = "Entity"; + if(string.IsNullOrEmpty(className))className = table.Name; +#> +using System; +using System.Collections.Generic; +using System.Text; +using System.Data; + +namespace <#= nameSpace #> +{ + /// + /// <#= table.Comment == "" ? table.Name : table.Comment.Replace("\r\n"," ") #> + /// + [Serializable] + public partial class <#= className #> + { + <# foreach (SOColumn c in list) + { #>/// + /// <#= c.Comment == "" ? c.Name : c.Comment.Replace("\r\n"," ") #> + /// + public <#= TypeUtil.DbType2TypeString(c.DataType) #> <#= c.Name #> { get; set; } + + <# } #> + + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/T4Template/Asp.Net/Entity/Normal.tt b/src/Kalman.Studio/T4Template/Asp.Net/Entity/Normal.tt new file mode 100644 index 0000000..88467e5 --- /dev/null +++ b/src/Kalman.Studio/T4Template/Asp.Net/Entity/Normal.tt @@ -0,0 +1,36 @@ +<#@ template language="C#" hostSpecific="true" debug="false" #> +<#@ output extension=".cs" #> +<# + TableHost host = (TableHost)(Host); + SOTable table = host.Table; + List list = host.ColumnList; + string nameSpace = host.GetString("NameSpace"); + string className = host.GetString("ClassName"); + if(string.IsNullOrEmpty(nameSpace))nameSpace = "Entity"; + if(string.IsNullOrEmpty(className))className = table.Name; +#> +using System; +using System.Collections.Generic; +using System.Text; +using System.Data; + +namespace <#= nameSpace #> +{ + /// + /// <#= table.Comment == "" ? table.Name : table.Comment.Replace("\r\n"," ") #> + /// + [Serializable] + public class <#= className #> + { + <# foreach (SOColumn c in list) + { + string cname = c.Name; + #> + /// + /// <#= c.Comment == "" ? c.Name : c.Comment.Replace("\r\n"," ") #> + /// + public <#= TypeUtil.DbType2TypeString(c.DataType) #> <#= cname #> { get;set;} + + <# } #> + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/T4Template/Asp.Net/Service/IService.tt b/src/Kalman.Studio/T4Template/Asp.Net/Service/IService.tt new file mode 100644 index 0000000..82a59a2 --- /dev/null +++ b/src/Kalman.Studio/T4Template/Asp.Net/Service/IService.tt @@ -0,0 +1,52 @@ +<#@ template language="C#" hostSpecific="true" debug="false" #> +<#@ output extension=".cs" #> +<# + TableHost host = (TableHost)(Host); + SOTable table = host.Table; + List list = host.ColumnList; + string nameSpace = host.GetString("NameSpace"); + string className = host.GetString("ClassName"); + if(string.IsNullOrEmpty(nameSpace))nameSpace = "Entity"; + if(string.IsNullOrEmpty(className))className = table.Name; + string tableName = table.Name.EndsWith("s") ?table.Name.TrimEnd('s') : table.Name.Trim(); +#> +using Ebboy.Core.Domain; +using System.Linq; + +namespace <#= nameSpace #> +{ + /// + /// <#= table.Comment == "" ? table.Name : table.Comment.Replace("\r\n"," ") #> + /// + public partial interface I<#= tableName #>Service + { + #region Interface + /// + /// 添加 + /// + /// + void Insert(<#=tableName#> model); + /// + /// 修改 + /// + /// + void Update(<#=tableName#> model); + /// + /// 删除 + /// + /// + void Delete(int id); + /// + /// 获取实体 + /// + /// + /// + <#= tableName #> GetById(int id); + /// + /// 获取所有列表 + /// + /// + IQueryable<<#=tableName#>> GetAllList(); + #endregion + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/T4Template/Asp.Net/Service/Service.tt b/src/Kalman.Studio/T4Template/Asp.Net/Service/Service.tt new file mode 100644 index 0000000..f209227 --- /dev/null +++ b/src/Kalman.Studio/T4Template/Asp.Net/Service/Service.tt @@ -0,0 +1,83 @@ +<#@ template language="C#" hostSpecific="true" debug="false" #> +<#@ output extension=".cs" #> +<# + TableHost host = (TableHost)(Host); + SOTable table = host.Table; + List list = host.ColumnList; + string nameSpace = host.GetString("NameSpace"); + string className = host.GetString("ClassName"); + if(string.IsNullOrEmpty(nameSpace))nameSpace = "Entity"; + if(string.IsNullOrEmpty(className))className = table.Name; + string tableName = table.Name.EndsWith("s") ?table.Name.TrimEnd('s') : table.Name.Trim(); +#> +using Ebboy.Core.Data; +using Ebboy.Core.Domain; +using System.Linq; + +namespace <#= nameSpace #> +{ + /// + /// <#= table.Comment == "" ? table.Name : table.Comment.Replace("\r\n"," ") #> + /// + public partial class <#= tableName #>Service: I<#= tableName #>Service + { + #region Fields + private readonly IRepository<<#=tableName#>> _repository; + #endregion + + #region Ctor + public <#= tableName #>Service(IRepository<<#=tableName#>> repository) + { + _repository = repository; + } + #endregion + + #region Methods + /// + /// 添加 + /// + /// + public virtual void Insert(<#=tableName#> model) + { + _repository.Insert(model); + } + + /// + /// 修改 + /// + /// + public virtual void Update(<#=tableName#> model) + { + _repository.Update(model); + } + + /// + /// 删除 + /// + /// + public virtual void Delete(int id) + { + _repository.Delete(GetById(id)); + } + + /// + /// 获取实体 + /// + /// + /// + public virtual <#=tableName#> GetById(int id) + { + return _repository.GetById(id); + } + + /// + /// 获取所有信息 + /// + /// + public virtual IQueryable<<#=tableName#>> GetAllList() + { + return _repository.Table; + } + #endregion + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/T4Template/Asp.Net/View/Create.tt b/src/Kalman.Studio/T4Template/Asp.Net/View/Create.tt new file mode 100644 index 0000000..47adeee --- /dev/null +++ b/src/Kalman.Studio/T4Template/Asp.Net/View/Create.tt @@ -0,0 +1,118 @@ +<#@ template language="C#" hostSpecific="true" debug="false" #> +<#@ output extension=".cshtml" #> +<# + TableHost host = (TableHost)(Host); + SOTable table = host.Table; + List list = host.ColumnList; + string nameSpace = host.GetString("NameSpace"); + string className = host.GetString("ClassName"); + if(string.IsNullOrEmpty(nameSpace))nameSpace = "Entity"; + if(string.IsNullOrEmpty(className))className = table.Name; + string tableName = table.Name.EndsWith("s") ?table.Name.TrimEnd('s') : table.Name.Trim(); + + int length = tableName.Length; + string controllerName = tableName + "Controller"; + string lowerTableName = tableName.Substring(0, 1).ToLower() + tableName.Substring(1, length - 1); + string serviceName = "_" + lowerTableName + "Service"; +#> +@model Ebboy.Core.Domain.<#=tableName#> +@{ + ViewBag.Title = "Create"; + Layout = "~/Views/Shared/_Layout.cshtml"; +} +
+ +
+ +
+

+ + + 首页 + + > + @ViewBag.Title + +

+
+
+ + +
+ +
+
+ +
+
+ +

+
+ +
+ +
+ +
+ + +
+ @using (Html.BeginForm("Create", "<#=tableName#>", FormMethod.Post, new { @class = "form-horizontal" })) + { + @Html.AntiForgeryToken() +
+ @ViewBag.Title + <# foreach (SOColumn c in list) + { #> +
+ +
+ @Html.TextBoxFor(model => model.<#= c.Name #>, new { @class = "form-control", @placeholder = "<#= c.Name #>" }) +

@Html.ValidationMessageFor(model => model.<#= c.Name #>)

+
+
+ <# } #> +
+
+
+
+
+ @Html.ValidationSummary(true) +
+
+
+
+
+
+
+ @Html.ActionLink("返回", "Index", "<#=tableName#>", null, new { @class = "btn btn-default" }) + +
+
+
+ } +
+ +
+ +
+ +
+
+ + +
+ +
+ +
+
+ +
+ +
\ No newline at end of file diff --git a/src/Kalman.Studio/T4Template/Asp.Net/View/Delete.tt b/src/Kalman.Studio/T4Template/Asp.Net/View/Delete.tt new file mode 100644 index 0000000..2b0db29 --- /dev/null +++ b/src/Kalman.Studio/T4Template/Asp.Net/View/Delete.tt @@ -0,0 +1,121 @@ +<#@ template language="C#" hostSpecific="true" debug="false" #> +<#@ output extension=".cshtml" #> +<# + TableHost host = (TableHost)(Host); + SOTable table = host.Table; + List list = host.ColumnList; + string nameSpace = host.GetString("NameSpace"); + string className = host.GetString("ClassName"); + if(string.IsNullOrEmpty(nameSpace))nameSpace = "Entity"; + if(string.IsNullOrEmpty(className))className = table.Name; + string tableName = table.Name.EndsWith("s") ?table.Name.TrimEnd('s') : table.Name.Trim(); + + int length = tableName.Length; + string controllerName = tableName + "Controller"; + string lowerTableName = tableName.Substring(0, 1).ToLower() + tableName.Substring(1, length - 1); + string serviceName = "_" + lowerTableName + "Service"; +#> +@model Ebboy.Core.Domain.<#=tableName#> +@{ + ViewBag.Title = "Delete"; + Layout = "~/Views/Shared/_Layout.cshtml"; +} +
+ +
+ +
+

+ + + 首页 + + > + @ViewBag.Title + +

+
+
+ + +
+ +
+
+ +
+
+ +

+
+ +
+ +
+ +
+ + +
+ @using (Html.BeginForm("Delete", "<#=tableName#>", FormMethod.Post, new { @class = "form-horizontal" })) + { + @Html.AntiForgeryToken() +
+ 详细信息如下: + + <# foreach (SOColumn c in list) + { #> + + + + + <# } #> +
+ @Html.DisplayNameFor(model => model.<#= c.Name #>): + + @Html.DisplayFor(model => model.<#= c.Name #>) +
+
+
+
+
+
+ @Html.ValidationSummary(true) +
+
+
+
+
+
+
+ @Html.ActionLink("返回", "Index", "<#=tableName#>", null, new { @class = "btn btn-default" }) + +
+
+
+ } +
+ +
+ +
+ +
+
+ + +
+ +
+ +
+
+ +
+ +
\ No newline at end of file diff --git a/src/Kalman.Studio/T4Template/Asp.Net/View/Details.tt b/src/Kalman.Studio/T4Template/Asp.Net/View/Details.tt new file mode 100644 index 0000000..38dcc45 --- /dev/null +++ b/src/Kalman.Studio/T4Template/Asp.Net/View/Details.tt @@ -0,0 +1,120 @@ +<#@ template language="C#" hostSpecific="true" debug="false" #> +<#@ output extension=".cshtml" #> +<# + TableHost host = (TableHost)(Host); + SOTable table = host.Table; + List list = host.ColumnList; + string nameSpace = host.GetString("NameSpace"); + string className = host.GetString("ClassName"); + if(string.IsNullOrEmpty(nameSpace))nameSpace = "Entity"; + if(string.IsNullOrEmpty(className))className = table.Name; + string tableName = table.Name.EndsWith("s") ?table.Name.TrimEnd('s') : table.Name.Trim(); + + int length = tableName.Length; + string controllerName = tableName + "Controller"; + string lowerTableName = tableName.Substring(0, 1).ToLower() + tableName.Substring(1, length - 1); + string serviceName = "_" + lowerTableName + "Service"; +#> +@model Ebboy.Core.Domain.<#=tableName#> +@{ + ViewBag.Title = "Index"; + Layout = "~/Views/Shared/_Layout.cshtml"; +} +
+ +
+ +
+

+ + + 首页 + + > + @ViewBag.Title + +

+
+
+ + +
+ +
+
+ +
+
+ +

+
+ +
+ +
+ +
+ + +
+ @using (Html.BeginForm("Details", "<#=tableName#>", FormMethod.Post, new { @class = "form-horizontal" })) + { + @Html.AntiForgeryToken() +
+ 详细信息如下: + + <# foreach (SOColumn c in list) + { #> + + + + + <# } #> +
+ @Html.DisplayNameFor(model => model.<#= c.Name #>): + + @Html.DisplayFor(model => model.<#= c.Name #>) +
+
+
+
+
+
+ @Html.ValidationSummary(true) +
+
+
+
+
+
+
+ @Html.ActionLink("返回", "Index", "<#=tableName#>", null, new { @class = "btn btn-default" }) +
+
+
+ } +
+ +
+ +
+ +
+
+ + +
+ +
+ +
+
+ +
+ +
\ No newline at end of file diff --git a/src/Kalman.Studio/T4Template/Asp.Net/View/Edit.tt b/src/Kalman.Studio/T4Template/Asp.Net/View/Edit.tt new file mode 100644 index 0000000..4592f7e --- /dev/null +++ b/src/Kalman.Studio/T4Template/Asp.Net/View/Edit.tt @@ -0,0 +1,118 @@ +<#@ template language="C#" hostSpecific="true" debug="false" #> +<#@ output extension=".cshtml" #> +<# + TableHost host = (TableHost)(Host); + SOTable table = host.Table; + List list = host.ColumnList; + string nameSpace = host.GetString("NameSpace"); + string className = host.GetString("ClassName"); + if(string.IsNullOrEmpty(nameSpace))nameSpace = "Entity"; + if(string.IsNullOrEmpty(className))className = table.Name; + string tableName = table.Name.EndsWith("s") ?table.Name.TrimEnd('s') : table.Name.Trim(); + + int length = tableName.Length; + string controllerName = tableName + "Controller"; + string lowerTableName = tableName.Substring(0, 1).ToLower() + tableName.Substring(1, length - 1); + string serviceName = "_" + lowerTableName + "Service"; +#> +@model Ebboy.Core.Domain.<#=tableName#> +@{ + ViewBag.Title = "Edit"; + Layout = "~/Views/Shared/_Layout.cshtml"; +} +
+ +
+ +
+

+ + + 首页 + + > + @ViewBag.Title + +

+
+
+ + +
+ +
+
+ +
+
+ +

+
+ +
+ +
+ +
+ + +
+ @using (Html.BeginForm("Edit","<#=tableName#>", FormMethod.Post, new { @class = "form-horizontal" })) + { + @Html.AntiForgeryToken() +
+ @ViewBag.Title + <# foreach (SOColumn c in list) + { #> +
+ +
+ @Html.TextBoxFor(model => model.<#= c.Name #>, new { @class = "form-control", @placeholder = "<#= c.Name #>" }) +

@Html.ValidationMessageFor(model => model.<#= c.Name #>)

+
+
+ <# } #> +
+
+
+
+
+ @Html.ValidationSummary(true) +
+
+
+
+
+
+
+ @Html.ActionLink("返回", "Index", "<#=tableName#>", null, new { @class = "btn btn-default" }) + +
+
+
+ } +
+ +
+ +
+ +
+
+ + +
+ +
+ +
+
+ +
+ +
\ No newline at end of file diff --git a/src/Kalman.Studio/T4Template/Asp.Net/View/Index.tt b/src/Kalman.Studio/T4Template/Asp.Net/View/Index.tt new file mode 100644 index 0000000..be3166a --- /dev/null +++ b/src/Kalman.Studio/T4Template/Asp.Net/View/Index.tt @@ -0,0 +1,127 @@ +<#@ template language="C#" hostSpecific="true" debug="false" #> +<#@ output extension=".cshtml" #> +<# + TableHost host = (TableHost)(Host); + SOTable table = host.Table; + List list = host.ColumnList; + string nameSpace = host.GetString("NameSpace"); + string className = host.GetString("ClassName"); + if(string.IsNullOrEmpty(nameSpace))nameSpace = "Entity"; + if(string.IsNullOrEmpty(className))className = table.Name; + string tableName = table.Name.EndsWith("s") ?table.Name.TrimEnd('s') : table.Name.Trim(); + + int length = tableName.Length; + string controllerName = tableName + "Controller"; + string lowerTableName = tableName.Substring(0, 1).ToLower() + tableName.Substring(1, length - 1); + string serviceName = "_" + lowerTableName + "Service"; +#> +@model IPagedList> +@{ + ViewBag.Title = "Index"; + Layout = "~/Views/Shared/_Layout.cshtml"; +} +
+ +
+ +
+

+ + + 首页 + + > + @ViewBag.Title + +

+
+
+ + +
+ +
+ +
+ +
+
+ +

@ViewBag.Title

+
+ +
+ @Html.ActionLink("添加", "Create", "<#=tableName#>", null, new {@class="btn btn-success" }) +
+
+
+ +
+ +
+ + +
+ + +
+ + + + <# foreach (SOColumn c in list) + { #> + + <# } #> + + + + + @foreach (var item in Model) + { + + <# foreach (SOColumn c in list) + { #> + + <# } #> + + + } + +
+ @Html.DisplayNameFor(model => model.<#= c.Name #>) +
+ @Html.DisplayFor(modelItem => item.<#= c.Name #>) + + @Html.ActionLink("修改", "Edit", new { id = item.Id }, new { @class = "btn btn-primary btn-xs" }) + @Html.ActionLink("详细", "Details", new { id = item.Id }, new { @class = "btn btn-info btn-xs" }) + @Html.ActionLink("删除", "Delete", new { id = item.Id }, new { @class = "btn btn-danger btn-xs" }) +
+
+ +
+ +
+ +
+ +
+ + +
+ +
+ +
+
+ +
+ +
+@section endscripts{ + @Scripts.Render("~/scripts/filter-datatables") +} \ No newline at end of file diff --git a/src/Kalman.Studio/T4Template/PHP/Yii/ADPlatform/View/index.tt b/src/Kalman.Studio/T4Template/PHP/Yii/ADPlatform/View/index.tt new file mode 100644 index 0000000..c7c5319 --- /dev/null +++ b/src/Kalman.Studio/T4Template/PHP/Yii/ADPlatform/View/index.tt @@ -0,0 +1,243 @@ +<#@ template language="C#v3.5" hostSpecific="true" debug="true" #> +<#@ output extension=".php" #> + +<# + TableHost host = (TableHost)(Host); + SOTable table = host.Table; + List list = host.ColumnList; + + string _TableName = table.Name.RemovePrefix("_", 1).InitialToUpperMulti();//camel naming + string _tableName = _TableName.InitialToLower();//pascal naming +#> +
+ beginWidget('CActiveForm', array( + 'id'=>'searchForm', + 'action'=>$this->createUrl('<#= _tableName #>/index'), + 'method'=>'get', + )); ?> + +
    +
  • + <# foreach (SOColumn c in list) + { if(c.PrimaryKey)continue;#> + + + <# } #> + + +
  • +
+ endWidget(); ?> +
+
+添加 +
+

结果列表

+
+ + + + <# foreach (SOColumn c in list){ #> + + <# } #> + + + + + + + <# foreach (SOColumn c in list){ #> + + <# } #> + + + + + + + + + +
getAttributeLabel('<#= c.Name #>')?>操作
<#= c.Name #>; ?> + 查看 | + 修改 | + 删除 +
+ widget('CEventPager',array('pages'=>$pages, 'onclick'=>'javascript:changePage(this);')); ?> +
+
+ + + + + + +<#+ + public string GetPK() + { + TableHost host = (TableHost)(Host); + foreach (SOColumn c in host.ColumnList) + { + if(c.PrimaryKey)return c.Name; + } + return host.Table.Name.RemovePrefix("_", 1)+"_id"; + } +#> \ No newline at end of file diff --git a/src/Kalman.Studio/T4Template/PHP/Yii/ADPlatform/controller.tt b/src/Kalman.Studio/T4Template/PHP/Yii/ADPlatform/controller.tt new file mode 100644 index 0000000..c44edcf --- /dev/null +++ b/src/Kalman.Studio/T4Template/PHP/Yii/ADPlatform/controller.tt @@ -0,0 +1,160 @@ +<#@ template language="C#v3.5" hostSpecific="true" debug="true" #> +<#@ output extension=".php" #> + +<# + TableHost host = (TableHost)(Host); + SOTable table = host.Table; + List list = host.ColumnList; + + string _TableName = table.Name.RemovePrefix("_", 1).InitialToUpperMulti();//camel naming + string _tableName = _TableName.InitialToLower();//pascal naming +#> + +Controller <#= _TableName #>控制器,负责<#= _TableName #>相关页面的列表展现和增删改操作 + * @author <#= Environment.MachineName #> + * @package application.controllers + * @version <#= DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") #> + * @since 1.0 + */ +class <#= _TableName #>Controller extends Controller +{ + /** + * 获取一个指定的<#= _TableName #>对象 + * @return string 返回json格式化的对象 + */ + public function actionGet() + { + $model = $this->_loadModel(); + echo $this->modeltoJson($model); + } + + /** + * 新增<#= _TableName #> + * @return string 返回json格式的成功或错误提示信息 + */ + public function actionCreate() + { + $model = new <#= _TableName #>(); + if (isset($_REQUEST['<#= _TableName #>'])) + { + $model->attributes = $_REQUEST['<#= _TableName #>']; + if ($model->save()) + { + $this->successJson(); + } + else + { + $this->errorJson($model); + } + } + } + + /** + * 更新一个指定的<#= _TableName #>对象 + * @param string 返回json格式的成功或错误提示信息 + */ + public function actionUpdate() + { + $model = $this->_loadModel(); + if (isset($_REQUEST['<#= _TableName #>'])) + { + $model->attributes = $_REQUEST['<#= _TableName #>']; + if ($model->save()) + { + $this->successJson(); + } + else + { + $this->errorJson($model); + } + } + } + + /** + * 删除一个指定的<#= _TableName #>对象 + * @param string 返回json格式的成功或错误提示信息 + */ + public function actionDelete() + { + if ($this->_loadModel()->delete()) + { + $this->successJson(); + } + else + { + $this->errorJson('删除失败!'); + } + } + + /** + * 根据查询条件得到查询<#= _TableName #>结果列表 + * @return view 显示查询<#= _TableName #>列表页面 + */ + public function actionIndex() + { + $pageSize = (isset($_REQUEST['pageSize']) ? (int)$_REQUEST['pageSize'] : 10); + $currentPage = (isset($_REQUEST['page']) ? (int)$_REQUEST['page'] - 1 : 0); + + $criteria = $this->_getCriteria(); + $count = <#= _TableName #>::model()->count($criteria); + + $pages = new CPagination($count); + $pages->pageSize = $pageSize; + $pages->currentPage = $currentPage; + $pages->applyLimit($criteria); + $result = <#= _TableName #>::model()->findAll($criteria); + $this->render('index',array( + 'list' => $result, + 'pages' => $pages, + 'model' => new <#= _TableName #>(), + 'req' => $_REQUEST, + )); + } + + /** + * 组织查询条件 + * @return CDbCriteria 查询条件 + */ + private function _getCriteria() + { + $criteria = new CDbCriteria(); + + <# foreach (SOColumn c in list){ if(c.PrimaryKey)continue;#> + if (isset($_REQUEST['<#= c.Name #>'])) + { + $criteria->compare('<#= c.Name #>', $_REQUEST['<#= c.Name #>'], true);//非模糊查询请去掉参数true或者另写条件 + } + <#}#> + + return $criteria; + } + + /** + * 根据请求中的参数构造一个<#= _TableName #>对象 + * @return <#= _TableName #> 返回一个<#= _TableName #>对象 + */ + private function _loadModel() + { + if (isset($_REQUEST['ID'])) + { + return <#= _TableName #>::model()->findByPk($_REQUEST['ID']); + } + if (isset($_REQUEST['<#= _TableName #>']['<#= GetPK() #>'])) + { + return <#= _TableName #>::model()->findByPk($_REQUEST['<#= _TableName #>']['<#= GetPK() #>']); + } + } +} +<#+ + public string GetPK() + { + TableHost host = (TableHost)(Host); + foreach (SOColumn c in host.ColumnList) + { + if(c.PrimaryKey)return c.Name; + } + return host.Table.Name.RemovePrefix("_", 1)+"_id"; + } +#> \ No newline at end of file diff --git a/src/Kalman.Studio/T4Template/PHP/Yii/ADPlatform/model.tt b/src/Kalman.Studio/T4Template/PHP/Yii/ADPlatform/model.tt new file mode 100644 index 0000000..9344f1b --- /dev/null +++ b/src/Kalman.Studio/T4Template/PHP/Yii/ADPlatform/model.tt @@ -0,0 +1,83 @@ +<#@ template language="C#v3.5" hostSpecific="true" debug="true" #> +<#@ output extension=".cs" #> +<# + TableHost host = (TableHost)(Host); + SOTable table = host.Table; + List list = host.ColumnList; + string columnPrefix = host.GetString("ColumnPrefix"); + int prefixLevel = host.GetInt32("PrefixLevel"); + string nameSpace = host.GetString("NameSpace"); + string className = host.GetString("ClassName"); + if(string.IsNullOrEmpty(nameSpace))nameSpace = "Entity"; + if(string.IsNullOrEmpty(className))className = table.Name; +#> +64), + array('account', 'length', 'max'=>32), + array('password', 'length', 'max'=>128), + array('level', 'length', 'max'=>8), + array('memo', 'length', 'max'=>1024), + ); + } + + /** + * @return array 与其他Active Record实体的关联关系 + */ + public function relations() + { + return array( + ); + } + + /** + * @return array 字段自定义标签('字段名'=>'标签名称') + */ + public function attributeLabels() + { + return array( + 'partner_id' => '编号', + 'partner_name' => '合作商', + 'account' => '帐号', + 'password' => '密码', + 'level' => '阶级', + 'memo' => '备注', + ); + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/T4TemplateEngineHost/CommandHost.cs b/src/Kalman.Studio/T4TemplateEngineHost/CommandHost.cs new file mode 100644 index 0000000..79a16f8 --- /dev/null +++ b/src/Kalman.Studio/T4TemplateEngineHost/CommandHost.cs @@ -0,0 +1,293 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Microsoft.VisualStudio.TextTemplating; +using System.IO; +using System.CodeDom.Compiler; +using Kalman.Data.SchemaObject; +using Kalman.Utilities; + +namespace Kalman.Studio.T4TemplateEngineHost +{ + /// + /// T4模板处理引擎,提供数据库存储过程的架构数据 + /// + [Serializable] + public class CommandHost : HostBase, ITextTemplatingEngineHost + { + /// + /// 存储过程信息 + /// + public SOCommand SP { get; set; } + + #region ITextTemplatingEngineHost + + CompilerErrorCollection _ErrorCollection; + /// + /// 模板引擎主机处理模板时错误信息集合 + /// + public CompilerErrorCollection ErrorCollection + { + get { return _ErrorCollection; } + } + + string _FileExtention = ".cs"; + /// + /// 文件扩展名 + /// + public string FileExtention { get { return _FileExtention; } } + + Encoding _FileEncoding = Encoding.UTF8; + /// + /// 文件编码 + /// + public Encoding FileEncoding { get { return _FileEncoding; } } + + #endregion + + #region ITextTemplatingEngineHost 成员 + + /// + /// 通过不同的optionName获取相应的Host数据(可以不实现该方法) + /// + /// + /// + public object GetHostOption(string optionName) + { + object returnObject = null; + //根据选项名称来获取数据 + switch (optionName) + { + case "CacheAssemblies": + returnObject = true; + break; + default: + break; + } + return returnObject; + } + + /// + /// 加载文件中包含的文本(可以不实现该方法) + /// The engine calls this method based on the optional include directive if the user has specified it in the text template.This method can be called 0, 1, or more times. + /// 该引擎调用可选include指令,如果用户指定了在文本template.This方法,它可以被调用0次,1次或更多次此方法。 + /// If the host searches the registry for the location of include files or if the host searches multiple locations by default, the host can return the final path of the include file in the location parameter. + /// 如果主机搜索的位置的注册表包含文件或主机搜查多个地点,默认情况下,主机可以返回包含文件中的位置参数的最终路径。 + /// + /// 请求的文件名(包含路径) + /// 文本内容 + /// 位置? + /// 文件加载成功则返回true + public bool LoadIncludeText(string requestFileName, out string content, out string location) + { + content = System.String.Empty; + location = System.String.Empty; + + if (File.Exists(requestFileName)) + { + content = File.ReadAllText(requestFileName); + return true; + } + else + { + return false; + } + } + + /// + /// 记录错误信息 + /// The engine calls this method when it is done processing a text template to pass any errors that occurred to the host. The host can decide how to display them. + /// 该引擎调用完成时,处理文本模板通过任何错误发生的主机此方法。主机可以决定如何显示它们。 + /// + /// + public void LogErrors(System.CodeDom.Compiler.CompilerErrorCollection errors) + { + _ErrorCollection = errors; + } + + /// + /// 提供处理模板的应用程序域 + /// This is the application domain that is used to compile and run the generated transformation class to create the generated text output. + /// 该应用程序域用于编译和运行生成的类来创建转换生成的文本输出。 + /// + /// + /// + public AppDomain ProvideTemplatingAppDomain(string content) + { + //This host will provide a new application domain each time the engine processes a text template. + //该主机将提供一个新的应用程序域每次引擎处理文本模板。 + return AppDomain.CreateDomain("Generation App Domain"); + + //This could be changed to return the current appdomain, but new + //assemblies are loaded into this AppDomain on a regular basis. + //If the AppDomain lasts too long, it will grow indefintely, + //which might be regarded as a leak. + + //This could be customized to cache the application domain for + //a certain number of text template generations (for example, 10). + + //This could be customized based on the contents of the text + //template, which are provided as a parameter for that purpose. + } + + /// + /// 解析程序集引用 + /// The engine calls this method to resolve assembly references used in the generated transformation class project and for the optional assembly directive if the user has specified it in the text template. This method can be called 0, 1, or more times. + /// 该引擎调用此方法来解决在生成的改造类项目所使用的程序集引用和可选的指令集,如果用户在文本中指定它的模板。这种方法可调用0,1次或多次。 + /// + /// 程序集引用路径 + /// + public string ResolveAssemblyReference(string assemblyReference) + { + //完全路径 + if (File.Exists(assemblyReference)) + { + return assemblyReference; + } + + //和模板文件在同一目录 + string candidate = Path.Combine(Path.GetDirectoryName(this.TemplateFile), assemblyReference); + if (File.Exists(candidate)) + { + return candidate; + } + + //不属于前两种情况的话,返回空字符串 + return string.Empty; + } + + /// + /// 模板引擎在用户指定文本模板指令的基础上调用该方法,该方法可以调用0,1次或多次 + /// + /// + /// + public Type ResolveDirectiveProcessor(string processorName) + { + //This host will not resolve any specific processors. + + //Check the processor name, and if it is the name of a processor the + //host wants to support, return the type of the processor. + //--------------------------------------------------------------------- + if (string.Compare(processorName, "XYZ", StringComparison.OrdinalIgnoreCase) == 0) + { + //return typeof(); + } + + //This can be customized to search specific paths for the file + //or to search the GAC + + //If the directive processor cannot be found, throw an error. + throw new Exception("没有找到指令处理器"); + } + + /// + /// If a call to a directive in a text template does not provide a value for a required parameter, the directive processor can try to get it from the host by calling this method. + /// + /// + /// + /// + /// + public string ResolveParameterValue(string directiveId, string processorName, string parameterName) + { + if (directiveId == null) + { + throw new ArgumentNullException("the directiveId cannot be null"); + } + if (processorName == null) + { + throw new ArgumentNullException("the processorName cannot be null"); + } + if (parameterName == null) + { + throw new ArgumentNullException("the parameterName cannot be null"); + } + + //Code to provide "hard-coded" parameter values goes here. + //This code depends on the directive processors this host will interact with. + + //If we cannot do better, return the empty string. + return String.Empty; + } + + /// + /// A directive processor can call this method if a file name does not have a path. + /// The host can attempt to provide path information by searching specific paths for the file and returning the file and path if found. + /// + /// + /// + public string ResolvePath(string path) + { + if (path == null) throw new ArgumentNullException("the path cannot be null"); + + //正确的完整路径 + if (File.Exists(path)) return path; + + //跟模板文件在同一目录 + string candidate = Path.Combine(Path.GetDirectoryName(this.TemplateFile), path); + if (File.Exists(candidate)) + { + return candidate; + } + + //todo: 这里还可以执行更多的解析文件路径操作 + + //若前面的解析操作无效,则返回原始路径 + return path; + } + + /// + /// The engine calls this method to change the extension of the generated text output file based on the optional output directive if the user specifies it in the text template. + /// + /// 扩展名,比如".txt" + public void SetFileExtension(string extension) + { + _FileExtention = extension; + } + + /// + /// The engine calls this method to change the encoding of the generated text output file based on the optional output directive if the user specifies it in the text template. + /// + /// + /// + public void SetOutputEncoding(Encoding encoding, bool fromOutputDirective) + { + _FileEncoding = encoding; + } + + /// + /// 这个是你的代码中要引入的包包,这个例子中引入了 System.dll 和 本项目的 dll,如果你不想引用,那么就得在 你的 tt 文件中引入 + /// The host can provide standard assembly references. The engine will use these references when compiling and executing the generated transformation class. + /// + public IList StandardAssemblyReferences + { + get + { + return base.AssemblyLocationList; + } + } + + /// + /// 这个是你的代码中要using 的命名空间,这个例子中引入了 System 和 本项目的,如果你不想引用,那么就得在 你的 tt 文件中写 + /// The host can provide standard imports or using statements. The engine will add these statements to the generated transformation class. + /// + public IList StandardImports + { + get + { + return base.NamespaceList; + } + } + + /// + /// 模板文件 + /// + public string TemplateFile + { + get; + set; + } + + #endregion + } +} diff --git a/src/Kalman.Studio/T4TemplateEngineHost/DatabaseHost.cs b/src/Kalman.Studio/T4TemplateEngineHost/DatabaseHost.cs new file mode 100644 index 0000000..7751904 --- /dev/null +++ b/src/Kalman.Studio/T4TemplateEngineHost/DatabaseHost.cs @@ -0,0 +1,289 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Microsoft.VisualStudio.TextTemplating; +using System.IO; +using System.CodeDom.Compiler; +using Kalman.Data.SchemaObject; + +namespace Kalman.Studio.T4TemplateEngineHost +{ + /// + /// T4模板处理引擎,提供数据库的架构数据 + /// + [Serializable] + public class DatabaseHost : HostBase, ITextTemplatingEngineHost + { + public SODatabase Database { get; set; } + + #region ITextTemplatingEngineHost + + CompilerErrorCollection _ErrorCollection; + /// + /// 模板引擎主机处理模板时错误信息集合 + /// + public CompilerErrorCollection ErrorCollection + { + get { return _ErrorCollection; } + } + + string _FileExtention = ".cs"; + /// + /// 文件扩展名 + /// + public string FileExtention { get { return _FileExtention; } } + + Encoding _FileEncoding = Encoding.UTF8; + /// + /// 文件编码 + /// + public Encoding FileEncoding { get { return _FileEncoding; } } + + #endregion + + #region ITextTemplatingEngineHost 成员 + + /// + /// 通过不同的optionName获取相应的Host数据(可以不实现该方法) + /// + /// + /// + public object GetHostOption(string optionName) + { + object returnObject = null; + //根据选项名称来获取数据 + switch (optionName) + { + case "CacheAssemblies": + returnObject = true; + break; + default: + break; + } + return returnObject; + } + + /// + /// 加载文件中包含的文本(可以不实现该方法) + /// The engine calls this method based on the optional include directive if the user has specified it in the text template.This method can be called 0, 1, or more times. + /// 该引擎调用可选include指令,如果用户指定了在文本template.This方法,它可以被调用0次,1次或更多次此方法。 + /// If the host searches the registry for the location of include files or if the host searches multiple locations by default, the host can return the final path of the include file in the location parameter. + /// 如果主机搜索的位置的注册表包含文件或主机搜查多个地点,默认情况下,主机可以返回包含文件中的位置参数的最终路径。 + /// + /// 请求的文件名(包含路径) + /// 文本内容 + /// 位置? + /// 文件加载成功则返回true + public bool LoadIncludeText(string requestFileName, out string content, out string location) + { + content = System.String.Empty; + location = System.String.Empty; + + if (File.Exists(requestFileName)) + { + content = File.ReadAllText(requestFileName); + return true; + } + else + { + return false; + } + } + + /// + /// 记录错误信息 + /// The engine calls this method when it is done processing a text template to pass any errors that occurred to the host. The host can decide how to display them. + /// 该引擎调用完成时,处理文本模板通过任何错误发生的主机此方法。主机可以决定如何显示它们。 + /// + /// + public void LogErrors(System.CodeDom.Compiler.CompilerErrorCollection errors) + { + _ErrorCollection = errors; + } + + /// + /// 提供处理模板的应用程序域 + /// This is the application domain that is used to compile and run the generated transformation class to create the generated text output. + /// 该应用程序域用于编译和运行生成的类来创建转换生成的文本输出。 + /// + /// + /// + public AppDomain ProvideTemplatingAppDomain(string content) + { + //This host will provide a new application domain each time the engine processes a text template. + //该主机将提供一个新的应用程序域每次引擎处理文本模板。 + return AppDomain.CreateDomain("Generation App Domain"); + + //This could be changed to return the current appdomain, but new + //assemblies are loaded into this AppDomain on a regular basis. + //If the AppDomain lasts too long, it will grow indefintely, + //which might be regarded as a leak. + + //This could be customized to cache the application domain for + //a certain number of text template generations (for example, 10). + + //This could be customized based on the contents of the text + //template, which are provided as a parameter for that purpose. + } + + /// + /// 解析程序集引用 + /// The engine calls this method to resolve assembly references used in the generated transformation class project and for the optional assembly directive if the user has specified it in the text template. This method can be called 0, 1, or more times. + /// 该引擎调用此方法来解决在生成的改造类项目所使用的程序集引用和可选的指令集,如果用户在文本中指定它的模板。这种方法可调用0,1次或多次。 + /// + /// 程序集引用路径 + /// + public string ResolveAssemblyReference(string assemblyReference) + { + //完全路径 + if (File.Exists(assemblyReference)) + { + return assemblyReference; + } + + //和模板文件在同一目录 + string candidate = Path.Combine(Path.GetDirectoryName(this.TemplateFile), assemblyReference); + if (File.Exists(candidate)) + { + return candidate; + } + + //不属于前两种情况的话,返回空字符串 + return string.Empty; + } + + /// + /// 模板引擎在用户指定文本模板指令的基础上调用该方法,该方法可以调用0,1次或多次 + /// + /// + /// + public Type ResolveDirectiveProcessor(string processorName) + { + //This host will not resolve any specific processors. + + //Check the processor name, and if it is the name of a processor the + //host wants to support, return the type of the processor. + //--------------------------------------------------------------------- + if (string.Compare(processorName, "XYZ", StringComparison.OrdinalIgnoreCase) == 0) + { + //return typeof(); + } + + //This can be customized to search specific paths for the file + //or to search the GAC + + //If the directive processor cannot be found, throw an error. + throw new Exception("没有找到指令处理器"); + } + + /// + /// If a call to a directive in a text template does not provide a value for a required parameter, the directive processor can try to get it from the host by calling this method. + /// + /// + /// + /// + /// + public string ResolveParameterValue(string directiveId, string processorName, string parameterName) + { + if (directiveId == null) + { + throw new ArgumentNullException("the directiveId cannot be null"); + } + if (processorName == null) + { + throw new ArgumentNullException("the processorName cannot be null"); + } + if (parameterName == null) + { + throw new ArgumentNullException("the parameterName cannot be null"); + } + + //Code to provide "hard-coded" parameter values goes here. + //This code depends on the directive processors this host will interact with. + + //If we cannot do better, return the empty string. + return String.Empty; + } + + /// + /// A directive processor can call this method if a file name does not have a path. + /// The host can attempt to provide path information by searching specific paths for the file and returning the file and path if found. + /// + /// + /// + public string ResolvePath(string path) + { + if (path == null) throw new ArgumentNullException("the path cannot be null"); + + //正确的完整路径 + if (File.Exists(path)) return path; + + //跟模板文件在同一目录 + string candidate = Path.Combine(Path.GetDirectoryName(this.TemplateFile), path); + if (File.Exists(candidate)) + { + return candidate; + } + + //todo: 这里还可以执行更多的解析文件路径操作 + + //若前面的解析操作无效,则返回原始路径 + return path; + } + + /// + /// The engine calls this method to change the extension of the generated text output file based on the optional output directive if the user specifies it in the text template. + /// + /// 扩展名,比如".txt" + public void SetFileExtension(string extension) + { + _FileExtention = extension; + } + + /// + /// The engine calls this method to change the encoding of the generated text output file based on the optional output directive if the user specifies it in the text template. + /// + /// + /// + public void SetOutputEncoding(Encoding encoding, bool fromOutputDirective) + { + _FileEncoding = encoding; + } + + /// + /// 这个是你的代码中要引入的包包,这个例子中引入了 System.dll 和 本项目的 dll,如果你不想引用,那么就得在 你的 tt 文件中引入 + /// The host can provide standard assembly references. The engine will use these references when compiling and executing the generated transformation class. + /// + public IList StandardAssemblyReferences + { + get + { + return base.AssemblyLocationList; + } + } + + /// + /// 这个是你的代码中要using 的命名空间,这个例子中引入了 System 和 本项目的,如果你不想引用,那么就得在 你的 tt 文件中写 + /// The host can provide standard imports or using statements. The engine will add these statements to the generated transformation class. + /// + public IList StandardImports + { + get + { + return base.NamespaceList; + } + } + + /// + /// 模板文件 + /// + public string TemplateFile + { + get; + set; + } + + #endregion + } +} diff --git a/src/Kalman.Studio/T4TemplateEngineHost/DefaultHost.cs b/src/Kalman.Studio/T4TemplateEngineHost/DefaultHost.cs new file mode 100644 index 0000000..464c028 --- /dev/null +++ b/src/Kalman.Studio/T4TemplateEngineHost/DefaultHost.cs @@ -0,0 +1,308 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Microsoft.VisualStudio.TextTemplating; +using System.IO; +using System.CodeDom.Compiler; +using Kalman.Data.SchemaObject; + +namespace Kalman.Studio.T4TemplateEngineHost +{ + /// + /// T4模板处理引擎 + /// + [Serializable] + public class DefaultHost : HostBase, ITextTemplatingEngineHost + { + #region ITextTemplatingEngineHost + + CompilerErrorCollection _ErrorCollection; + /// + /// 模板引擎主机处理模板时错误信息集合 + /// + public CompilerErrorCollection ErrorCollection + { + get { return _ErrorCollection; } + } + + string _FileExtention = ".cs"; + /// + /// 文件扩展名 + /// + public string FileExtention { get { return _FileExtention; } } + + Encoding _FileEncoding = Encoding.UTF8; + /// + /// 文件编码 + /// + public Encoding FileEncoding { get { return _FileEncoding; } } + + #endregion + + #region ITextTemplatingEngineHost 成员 + + /// + /// 通过不同的optionName获取相应的Host数据(可以不实现该方法) + /// + /// + /// + public object GetHostOption(string optionName) + { + object returnObject = null; + //根据选项名称来获取数据 + switch (optionName) + { + case "CacheAssemblies": + returnObject = true; + break; + default: + break; + } + return returnObject; + } + + /// + /// 加载文件中包含的文本(可以不实现该方法) + /// The engine calls this method based on the optional include directive if the user has specified it in the text template.This method can be called 0, 1, or more times. + /// 该引擎调用可选include指令,如果用户指定了在文本template.This方法,它可以被调用0次,1次或更多次此方法。 + /// If the host searches the registry for the location of include files or if the host searches multiple locations by default, the host can return the final path of the include file in the location parameter. + /// 如果主机搜索的位置的注册表包含文件或主机搜查多个地点,默认情况下,主机可以返回包含文件中的位置参数的最终路径。 + /// + /// 请求的文件名(包含路径) + /// 文本内容 + /// 位置? + /// 文件加载成功则返回true + public bool LoadIncludeText(string requestFileName, out string content, out string location) + { + content = System.String.Empty; + location = System.String.Empty; + + if (File.Exists(requestFileName)) + { + content = File.ReadAllText(requestFileName); + return true; + } + else + { + return false; + } + } + + /// + /// 记录错误信息 + /// The engine calls this method when it is done processing a text template to pass any errors that occurred to the host. The host can decide how to display them. + /// 该引擎调用完成时,处理文本模板通过任何错误发生的主机此方法。主机可以决定如何显示它们。 + /// + /// + public void LogErrors(System.CodeDom.Compiler.CompilerErrorCollection errors) + { + _ErrorCollection = errors; + } + + /// + /// 提供处理模板的应用程序域 + /// This is the application domain that is used to compile and run the generated transformation class to create the generated text output. + /// 该应用程序域用于编译和运行生成的类来创建转换生成的文本输出。 + /// + /// + /// + public AppDomain ProvideTemplatingAppDomain(string content) + { + //This host will provide a new application domain each time the engine processes a text template. + //该主机将提供一个新的应用程序域每次引擎处理文本模板。 + return AppDomain.CreateDomain("Generation App Domain"); + + //This could be changed to return the current appdomain, but new + //assemblies are loaded into this AppDomain on a regular basis. + //If the AppDomain lasts too long, it will grow indefintely, + //which might be regarded as a leak. + + //This could be customized to cache the application domain for + //a certain number of text template generations (for example, 10). + + //This could be customized based on the contents of the text + //template, which are provided as a parameter for that purpose. + } + + /// + /// 解析程序集引用 + /// The engine calls this method to resolve assembly references used in the generated transformation class project and for the optional assembly directive if the user has specified it in the text template. This method can be called 0, 1, or more times. + /// 该引擎调用此方法来解决在生成的改造类项目所使用的程序集引用和可选的指令集,如果用户在文本中指定它的模板。这种方法可调用0,1次或多次。 + /// + /// 程序集引用路径 + /// + public string ResolveAssemblyReference(string assemblyReference) + { + //完全路径 + if (File.Exists(assemblyReference)) + { + return assemblyReference; + } + + //和模板文件在同一目录 + string candidate = Path.Combine(Path.GetDirectoryName(this.TemplateFile), assemblyReference); + if (File.Exists(candidate)) + { + return candidate; + } + + //不属于前两种情况的话,返回空字符串 + return string.Empty; + } + + /// + /// 模板引擎在用户指定文本模板指令的基础上调用该方法,该方法可以调用0,1次或多次 + /// + /// + /// + public Type ResolveDirectiveProcessor(string processorName) + { + //This host will not resolve any specific processors. + + //Check the processor name, and if it is the name of a processor the + //host wants to support, return the type of the processor. + //--------------------------------------------------------------------- + if (string.Compare(processorName, "XYZ", StringComparison.OrdinalIgnoreCase) == 0) + { + //return typeof(); + } + + //This can be customized to search specific paths for the file + //or to search the GAC + + //If the directive processor cannot be found, throw an error. + throw new Exception("没有找到指令处理器"); + } + + /// + /// If a call to a directive in a text template does not provide a value for a required parameter, the directive processor can try to get it from the host by calling this method. + /// + /// + /// + /// + /// + public string ResolveParameterValue(string directiveId, string processorName, string parameterName) + { + if (directiveId == null) + { + throw new ArgumentNullException("the directiveId cannot be null"); + } + if (processorName == null) + { + throw new ArgumentNullException("the processorName cannot be null"); + } + if (parameterName == null) + { + throw new ArgumentNullException("the parameterName cannot be null"); + } + + //Code to provide "hard-coded" parameter values goes here. + //This code depends on the directive processors this host will interact with. + + //If we cannot do better, return the empty string. + return String.Empty; + } + + /// + /// A directive processor can call this method if a file name does not have a path. + /// The host can attempt to provide path information by searching specific paths for the file and returning the file and path if found. + /// + /// + /// + public string ResolvePath(string path) + { + if (path == null) throw new ArgumentNullException("the path cannot be null"); + + //正确的完整路径 + if (File.Exists(path)) return path; + + //跟模板文件在同一目录 + string candidate = Path.Combine(Path.GetDirectoryName(this.TemplateFile), path); + if (File.Exists(candidate)) + { + return candidate; + } + + //todo: 这里还可以执行更多的解析文件路径操作 + + //若前面的解析操作无效,则返回原始路径 + return path; + } + + /// + /// The engine calls this method to change the extension of the generated text output file based on the optional output directive if the user specifies it in the text template. + /// + /// 扩展名,比如".txt" + public void SetFileExtension(string extension) + { + _FileExtention = extension; + } + + /// + /// The engine calls this method to change the encoding of the generated text output file based on the optional output directive if the user specifies it in the text template. + /// + /// + /// + public void SetOutputEncoding(Encoding encoding, bool fromOutputDirective) + { + _FileEncoding = encoding; + } + + /// + /// 这个是你的代码中要引入的包包,这个例子中引入了 System.dll 和 本项目的 dll,如果你不想引用,那么就得在 你的 tt 文件中引入 + /// The host can provide standard assembly references. The engine will use these references when compiling and executing the generated transformation class. + /// + public IList StandardAssemblyReferences + { + get + { + return new string[] + { + typeof(System.Uri).Assembly.Location, + typeof(System.Data.DbType).Assembly.Location, + typeof(DefaultHost).Assembly.Location, + typeof(Kalman.Data.DbSchema).Assembly.Location, + }; + } + } + + /// + /// 这个是你的代码中要using 的命名空间,这个例子中引入了 System 和 本项目的,如果你不想引用,那么就得在 你的 tt 文件中写 + /// The host can provide standard imports or using statements. The engine will add these statements to the generated transformation class. + /// + public IList StandardImports + { + get + { + return new string[] + { + "System", + "System.Linq", + "System.Text", + "System.Data", + "System.Collections.Generic", + "Kalman", + "Kalman.Extensions", + "Kalman.Data", + "Kalman.Data.SchemaObject", + "Kalman.Data.DbSchemaProvider", + "Kalman.Data.DbProvider", + "Kalman.Utilities", + "Kalman.Studio.T4TemplateEngineHost" + }; + } + } + + /// + /// 模板文件 + /// + public string TemplateFile + { + get; + set; + } + + #endregion + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/T4TemplateEngineHost/HostBase.cs b/src/Kalman.Studio/T4TemplateEngineHost/HostBase.cs new file mode 100644 index 0000000..0ad3c5f --- /dev/null +++ b/src/Kalman.Studio/T4TemplateEngineHost/HostBase.cs @@ -0,0 +1,170 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Kalman.Utilities; + +namespace Kalman.Studio.T4TemplateEngineHost +{ + /// + /// T4模板引擎基类 + /// + [Serializable] + public abstract class HostBase + { + IList assemblyLocationList = new List(); //程序集的引用路径列表 + IList namespaceList = new List(); //命名空间列表 + + public HostBase() + { + AddAssemblyLocation(typeof(Kalman.Data.DbSchema).Assembly.Location); //Kalman.dll + AddAssemblyLocation(typeof(HostBase).Assembly.Location); //Kalman.Studio.exe + + AddAssemblyLocation(typeof(System.AppDomain).Assembly.Location); //mscorlib.dll + AddAssemblyLocation(typeof(System.Uri).Assembly.Location); //System.dll + AddAssemblyLocation(typeof(System.Data.DbType).Assembly.Location); //System.Data.dll + AddAssemblyLocation(typeof(System.Linq.Queryable).Assembly.Location); //System.Core.dll + + AddNamespace("Kalman"); + AddNamespace("Kalman.Extensions"); + AddNamespace("Kalman.Data"); + AddNamespace("Kalman.Data.SchemaObject"); + AddNamespace("Kalman.Data.DbSchemaProvider"); + AddNamespace("Kalman.Data.DbProvider"); + AddNamespace("Kalman.Utilities"); + + AddNamespace("Kalman.Studio.T4TemplateEngineHost"); + + AddNamespace("System"); + AddNamespace("System.IO"); + AddNamespace("System.Xml"); + AddNamespace("System.Linq"); + AddNamespace("System.Text"); + AddNamespace("System.Data"); + AddNamespace("System.Data.Common"); + AddNamespace("System.Collections"); + AddNamespace("System.Collections.Generic"); + AddNamespace("System.Collections.Specialized"); + } + + /// + /// 获取程序集的引用路径列表 + /// + public IList AssemblyLocationList + { + get { return assemblyLocationList;} + } + + /// + /// 添加一个程序集的引用路径,也可以在tt模板中通过assembly指令声明,如:<#@ assembly name="System.dll" #> + /// + /// + public void AddAssemblyLocation(string assemblyLocation) + { + if (assemblyLocationList.Contains(assemblyLocation)) return; + assemblyLocationList.Add(assemblyLocation); + } + + /// + /// 获取导入的命名空间列表 + /// + public IList NamespaceList + { + get { return namespaceList; } + } + + /// + /// 添加一个导入的命名空间名称,也可以在tt模板中通过namespace指令声明,如<#@ import namespace="System" #> + /// + /// + public void AddNamespace(string namespaceName) + { + if (namespaceList.Contains(namespaceName)) return; + namespaceList.Add(namespaceName); + } + + #region ExtendProperties + + Dictionary _ExtendProperties = new Dictionary(); + + /// + /// 设置扩展属性值 + /// + /// + /// + public void SetValue(string key, object value) + { + if (_ExtendProperties.ContainsKey(key)) + { + _ExtendProperties[key] = value; + } + else + { + _ExtendProperties.Add(key, value); + } + } + + /// + /// 获取扩展属性值 + /// + /// + /// + public object GetValue(string key) + { + if (_ExtendProperties.ContainsKey(key)) + { + return _ExtendProperties[key]; + } + else + { + return null; + } + } + + /// + /// 获取扩展属性值 + /// + /// + /// + public string GetString(string key) + { + object obj = GetValue(key); + if (obj == null) return string.Empty; + else return obj.ToString(); + } + + /// + /// 获取扩展属性值 + /// + public int GetInt32(string key) + { + return ConvertUtil.ToInt32(GetValue(key), 0); + } + + /// + /// 获取扩展属性值 + /// + public bool GetBoolean(string key) + { + return ConvertUtil.ToBoolean(GetValue(key), false); + } + + /// + /// 获取扩展属性值 + /// + public DateTime GetDateTime(string key) + { + return ConvertUtil.ToDateTime(GetValue(key), DateTime.MinValue); + } + + /// + /// 获取扩展属性值 + /// + public decimal GetDecimal(string key) + { + return ConvertUtil.ToDecimal(GetValue(key), decimal.Zero); + } + + #endregion + } +} diff --git a/src/Kalman.Studio/T4TemplateEngineHost/TableHost.cs b/src/Kalman.Studio/T4TemplateEngineHost/TableHost.cs new file mode 100644 index 0000000..3c1b1f2 --- /dev/null +++ b/src/Kalman.Studio/T4TemplateEngineHost/TableHost.cs @@ -0,0 +1,304 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Microsoft.VisualStudio.TextTemplating; +using System.IO; +using System.CodeDom.Compiler; +using Kalman.Data.SchemaObject; +using Kalman.Utilities; + +namespace Kalman.Studio.T4TemplateEngineHost +{ + /// + /// T4模板处理引擎,提供数据库表的架构数据 + /// + [Serializable] + public class TableHost : HostBase, ITextTemplatingEngineHost + { + /// + /// 表信息 + /// + public SOTable Table { get; set; } + + List _ColumnList; + public List ColumnList + { + get + { + if (_ColumnList == null) return Table.ColumnList; + return _ColumnList; + } + set { _ColumnList = value; } + } + + #region ITextTemplatingEngineHost + + CompilerErrorCollection _ErrorCollection; + /// + /// 模板引擎主机处理模板时错误信息集合 + /// + public CompilerErrorCollection ErrorCollection + { + get { return _ErrorCollection; } + } + + string _FileExtention = ".cs"; + /// + /// 文件扩展名 + /// + public string FileExtention { get { return _FileExtention; } set { _FileExtention = value; } } + + Encoding _FileEncoding = Encoding.UTF8; + /// + /// 文件编码 + /// + public Encoding FileEncoding { get { return _FileEncoding; } } + + #endregion + + #region ITextTemplatingEngineHost 成员 + + /// + /// 通过不同的optionName获取相应的Host数据(可以不实现该方法) + /// + /// + /// + public object GetHostOption(string optionName) + { + object returnObject = null; + //根据选项名称来获取数据 + switch (optionName) + { + case "CacheAssemblies": + returnObject = true; + break; + default: + break; + } + return returnObject; + } + + /// + /// 加载文件中包含的文本(可以不实现该方法) + /// The engine calls this method based on the optional include directive if the user has specified it in the text template.This method can be called 0, 1, or more times. + /// 该引擎调用可选include指令,如果用户指定了在文本template.This方法,它可以被调用0次,1次或更多次此方法。 + /// If the host searches the registry for the location of include files or if the host searches multiple locations by default, the host can return the final path of the include file in the location parameter. + /// 如果主机搜索的位置的注册表包含文件或主机搜查多个地点,默认情况下,主机可以返回包含文件中的位置参数的最终路径。 + /// + /// 请求的文件名(包含路径) + /// 文本内容 + /// 位置? + /// 文件加载成功则返回true + public bool LoadIncludeText(string requestFileName, out string content, out string location) + { + content = System.String.Empty; + location = System.String.Empty; + + if (File.Exists(requestFileName)) + { + content = File.ReadAllText(requestFileName); + return true; + } + else + { + return false; + } + } + + /// + /// 记录错误信息 + /// The engine calls this method when it is done processing a text template to pass any errors that occurred to the host. The host can decide how to display them. + /// 该引擎调用完成时,处理文本模板通过任何错误发生的主机此方法。主机可以决定如何显示它们。 + /// + /// + public void LogErrors(System.CodeDom.Compiler.CompilerErrorCollection errors) + { + _ErrorCollection = errors; + } + + /// + /// 提供处理模板的应用程序域 + /// This is the application domain that is used to compile and run the generated transformation class to create the generated text output. + /// 该应用程序域用于编译和运行生成的类来创建转换生成的文本输出。 + /// + /// + /// + public AppDomain ProvideTemplatingAppDomain(string content) + { + //This host will provide a new application domain each time the engine processes a text template. + //该主机将提供一个新的应用程序域每次引擎处理文本模板。 + return AppDomain.CreateDomain("Generation App Domain"); + + //This could be changed to return the current appdomain, but new + //assemblies are loaded into this AppDomain on a regular basis. + //If the AppDomain lasts too long, it will grow indefintely, + //which might be regarded as a leak. + + //This could be customized to cache the application domain for + //a certain number of text template generations (for example, 10). + + //This could be customized based on the contents of the text + //template, which are provided as a parameter for that purpose. + } + + /// + /// 解析程序集引用 + /// The engine calls this method to resolve assembly references used in the generated transformation class project and for the optional assembly directive if the user has specified it in the text template. This method can be called 0, 1, or more times. + /// 该引擎调用此方法来解决在生成的改造类项目所使用的程序集引用和可选的指令集,如果用户在文本中指定它的模板。这种方法可调用0,1次或多次。 + /// + /// 程序集引用路径 + /// + public string ResolveAssemblyReference(string assemblyReference) + { + //完全路径 + if (File.Exists(assemblyReference)) + { + return assemblyReference; + } + + //和模板文件在同一目录 + string candidate = Path.Combine(Path.GetDirectoryName(this.TemplateFile), assemblyReference); + if (File.Exists(candidate)) + { + return candidate; + } + + //不属于前两种情况的话,返回空字符串 + return string.Empty; + } + + /// + /// 模板引擎在用户指定文本模板指令的基础上调用该方法,该方法可以调用0,1次或多次 + /// + /// + /// + public Type ResolveDirectiveProcessor(string processorName) + { + //This host will not resolve any specific processors. + + //Check the processor name, and if it is the name of a processor the + //host wants to support, return the type of the processor. + //--------------------------------------------------------------------- + if (string.Compare(processorName, "XYZ", StringComparison.OrdinalIgnoreCase) == 0) + { + //return typeof(); + } + + //This can be customized to search specific paths for the file + //or to search the GAC + + //If the directive processor cannot be found, throw an error. + throw new Exception("没有找到指令处理器"); + } + + /// + /// If a call to a directive in a text template does not provide a value for a required parameter, the directive processor can try to get it from the host by calling this method. + /// + /// + /// + /// + /// + public string ResolveParameterValue(string directiveId, string processorName, string parameterName) + { + if (directiveId == null) + { + throw new ArgumentNullException("the directiveId cannot be null"); + } + if (processorName == null) + { + throw new ArgumentNullException("the processorName cannot be null"); + } + if (parameterName == null) + { + throw new ArgumentNullException("the parameterName cannot be null"); + } + + //Code to provide "hard-coded" parameter values goes here. + //This code depends on the directive processors this host will interact with. + + //If we cannot do better, return the empty string. + return String.Empty; + } + + /// + /// A directive processor can call this method if a file name does not have a path. + /// The host can attempt to provide path information by searching specific paths for the file and returning the file and path if found. + /// + /// + /// + public string ResolvePath(string path) + { + if (path == null) throw new ArgumentNullException("the path cannot be null"); + + //正确的完整路径 + if (File.Exists(path)) return path; + + //跟模板文件在同一目录 + string candidate = Path.Combine(Path.GetDirectoryName(this.TemplateFile), path); + if (File.Exists(candidate)) + { + return candidate; + } + + //todo: 这里还可以执行更多的解析文件路径操作 + + //若前面的解析操作无效,则返回原始路径 + return path; + } + + /// + /// The engine calls this method to change the extension of the generated text output file based on the optional output directive if the user specifies it in the text template. + /// + /// 扩展名,比如".txt" + public void SetFileExtension(string extension) + { + _FileExtention = extension; + } + + /// + /// The engine calls this method to change the encoding of the generated text output file based on the optional output directive if the user specifies it in the text template. + /// + /// + /// + public void SetOutputEncoding(Encoding encoding, bool fromOutputDirective) + { + _FileEncoding = encoding; + } + + /// + /// 这个是你的代码中要引入的包包,这个例子中引入了 System.dll 和 本项目的 dll,如果你不想引用,那么就得在 你的 tt 文件中引入 + /// The host can provide standard assembly references. The engine will use these references when compiling and executing the generated transformation class. + /// + public IList StandardAssemblyReferences + { + get + { + return base.AssemblyLocationList; + } + } + + /// + /// 这个是你的代码中要using 的命名空间,这个例子中引入了 System 和 本项目的,如果你不想引用,那么就得在 你的 tt 文件中写 + /// The host can provide standard imports or using statements. The engine will add these statements to the generated transformation class. + /// + public IList StandardImports + { + get + { + return base.NamespaceList; + } + } + + /// + /// 模板文件 + /// + public string TemplateFile + { + get; + set; + } + + #endregion + } +} diff --git a/src/Kalman.Studio/T4TemplateEngineHost/ViewHost.cs b/src/Kalman.Studio/T4TemplateEngineHost/ViewHost.cs new file mode 100644 index 0000000..d158a44 --- /dev/null +++ b/src/Kalman.Studio/T4TemplateEngineHost/ViewHost.cs @@ -0,0 +1,304 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Microsoft.VisualStudio.TextTemplating; +using System.IO; +using System.CodeDom.Compiler; +using Kalman.Utilities; +using Kalman.Data.SchemaObject; + +namespace Kalman.Studio.T4TemplateEngineHost +{ + /// + /// T4模板处理引擎,提供数据库视图的架构数据 + /// + [Serializable] + public class ViewHost : HostBase, ITextTemplatingEngineHost + { + /// + /// 视图信息 + /// + public SOView View { get; set; } + + List _ColumnList; + public List ColumnList + { + get + { + if (_ColumnList == null) return View.ColumnList; + return _ColumnList; + } + set { _ColumnList = value; } + } + + #region ITextTemplatingEngineHost + + CompilerErrorCollection _ErrorCollection; + /// + /// 模板引擎主机处理模板时错误信息集合 + /// + public CompilerErrorCollection ErrorCollection + { + get { return _ErrorCollection; } + } + + string _FileExtention = ".cs"; + /// + /// 文件扩展名 + /// + public string FileExtention { get { return _FileExtention; } } + + Encoding _FileEncoding = Encoding.UTF8; + /// + /// 文件编码 + /// + public Encoding FileEncoding { get { return _FileEncoding; } } + + #endregion + + #region ITextTemplatingEngineHost 成员 + + /// + /// 通过不同的optionName获取相应的Host数据(可以不实现该方法) + /// + /// + /// + public object GetHostOption(string optionName) + { + object returnObject = null; + //根据选项名称来获取数据 + switch (optionName) + { + case "CacheAssemblies": + returnObject = true; + break; + default: + break; + } + return returnObject; + } + + /// + /// 加载文件中包含的文本(可以不实现该方法) + /// The engine calls this method based on the optional include directive if the user has specified it in the text template.This method can be called 0, 1, or more times. + /// 该引擎调用可选include指令,如果用户指定了在文本template.This方法,它可以被调用0次,1次或更多次此方法。 + /// If the host searches the registry for the location of include files or if the host searches multiple locations by default, the host can return the final path of the include file in the location parameter. + /// 如果主机搜索的位置的注册表包含文件或主机搜查多个地点,默认情况下,主机可以返回包含文件中的位置参数的最终路径。 + /// + /// 请求的文件名(包含路径) + /// 文本内容 + /// 位置? + /// 文件加载成功则返回true + public bool LoadIncludeText(string requestFileName, out string content, out string location) + { + content = System.String.Empty; + location = System.String.Empty; + + if (File.Exists(requestFileName)) + { + content = File.ReadAllText(requestFileName); + return true; + } + else + { + return false; + } + } + + /// + /// 记录错误信息 + /// The engine calls this method when it is done processing a text template to pass any errors that occurred to the host. The host can decide how to display them. + /// 该引擎调用完成时,处理文本模板通过任何错误发生的主机此方法。主机可以决定如何显示它们。 + /// + /// + public void LogErrors(System.CodeDom.Compiler.CompilerErrorCollection errors) + { + _ErrorCollection = errors; + } + + /// + /// 提供处理模板的应用程序域 + /// This is the application domain that is used to compile and run the generated transformation class to create the generated text output. + /// 该应用程序域用于编译和运行生成的类来创建转换生成的文本输出。 + /// + /// + /// + public AppDomain ProvideTemplatingAppDomain(string content) + { + //This host will provide a new application domain each time the engine processes a text template. + //该主机将提供一个新的应用程序域每次引擎处理文本模板。 + return AppDomain.CreateDomain("Generation App Domain"); + + //This could be changed to return the current appdomain, but new + //assemblies are loaded into this AppDomain on a regular basis. + //If the AppDomain lasts too long, it will grow indefintely, + //which might be regarded as a leak. + + //This could be customized to cache the application domain for + //a certain number of text template generations (for example, 10). + + //This could be customized based on the contents of the text + //template, which are provided as a parameter for that purpose. + } + + /// + /// 解析程序集引用 + /// The engine calls this method to resolve assembly references used in the generated transformation class project and for the optional assembly directive if the user has specified it in the text template. This method can be called 0, 1, or more times. + /// 该引擎调用此方法来解决在生成的改造类项目所使用的程序集引用和可选的指令集,如果用户在文本中指定它的模板。这种方法可调用0,1次或多次。 + /// + /// 程序集引用路径 + /// + public string ResolveAssemblyReference(string assemblyReference) + { + //完全路径 + if (File.Exists(assemblyReference)) + { + return assemblyReference; + } + + //和模板文件在同一目录 + string candidate = Path.Combine(Path.GetDirectoryName(this.TemplateFile), assemblyReference); + if (File.Exists(candidate)) + { + return candidate; + } + + //不属于前两种情况的话,返回空字符串 + return string.Empty; + } + + /// + /// 模板引擎在用户指定文本模板指令的基础上调用该方法,该方法可以调用0,1次或多次 + /// + /// + /// + public Type ResolveDirectiveProcessor(string processorName) + { + //This host will not resolve any specific processors. + + //Check the processor name, and if it is the name of a processor the + //host wants to support, return the type of the processor. + //--------------------------------------------------------------------- + if (string.Compare(processorName, "XYZ", StringComparison.OrdinalIgnoreCase) == 0) + { + //return typeof(); + } + + //This can be customized to search specific paths for the file + //or to search the GAC + + //If the directive processor cannot be found, throw an error. + throw new Exception("没有找到指令处理器"); + } + + /// + /// If a call to a directive in a text template does not provide a value for a required parameter, the directive processor can try to get it from the host by calling this method. + /// + /// + /// + /// + /// + public string ResolveParameterValue(string directiveId, string processorName, string parameterName) + { + if (directiveId == null) + { + throw new ArgumentNullException("the directiveId cannot be null"); + } + if (processorName == null) + { + throw new ArgumentNullException("the processorName cannot be null"); + } + if (parameterName == null) + { + throw new ArgumentNullException("the parameterName cannot be null"); + } + + //Code to provide "hard-coded" parameter values goes here. + //This code depends on the directive processors this host will interact with. + + //If we cannot do better, return the empty string. + return String.Empty; + } + + /// + /// A directive processor can call this method if a file name does not have a path. + /// The host can attempt to provide path information by searching specific paths for the file and returning the file and path if found. + /// + /// + /// + public string ResolvePath(string path) + { + if (path == null) throw new ArgumentNullException("the path cannot be null"); + + //正确的完整路径 + if (File.Exists(path)) return path; + + //跟模板文件在同一目录 + string candidate = Path.Combine(Path.GetDirectoryName(this.TemplateFile), path); + if (File.Exists(candidate)) + { + return candidate; + } + + //todo: 这里还可以执行更多的解析文件路径操作 + + //若前面的解析操作无效,则返回原始路径 + return path; + } + + /// + /// The engine calls this method to change the extension of the generated text output file based on the optional output directive if the user specifies it in the text template. + /// + /// 扩展名,比如".txt" + public void SetFileExtension(string extension) + { + _FileExtention = extension; + } + + /// + /// The engine calls this method to change the encoding of the generated text output file based on the optional output directive if the user specifies it in the text template. + /// + /// + /// + public void SetOutputEncoding(Encoding encoding, bool fromOutputDirective) + { + _FileEncoding = encoding; + } + + /// + /// 这个是你的代码中要引入的包包,这个例子中引入了 System.dll 和 本项目的 dll,如果你不想引用,那么就得在 你的 tt 文件中引入 + /// The host can provide standard assembly references. The engine will use these references when compiling and executing the generated transformation class. + /// + public IList StandardAssemblyReferences + { + get + { + return base.AssemblyLocationList; + } + } + + /// + /// 这个是你的代码中要using 的命名空间,这个例子中引入了 System 和 本项目的,如果你不想引用,那么就得在 你的 tt 文件中写 + /// The host can provide standard imports or using statements. The engine will add these statements to the generated transformation class. + /// + public IList StandardImports + { + get + { + return base.NamespaceList; + } + } + + /// + /// 模板文件 + /// + public string TemplateFile + { + get; + set; + } + + #endregion + } +} diff --git a/src/Kalman.Studio/Template/template.aspx b/src/Kalman.Studio/Template/template.aspx new file mode 100644 index 0000000..669e522 --- /dev/null +++ b/src/Kalman.Studio/Template/template.aspx @@ -0,0 +1,20 @@ +<%@ Page Language="C#" %> + + + + + + + + + + +
+
+ +
+
+ + diff --git a/src/Kalman.Studio/Template/template.cpp b/src/Kalman.Studio/Template/template.cpp new file mode 100644 index 0000000..e9fc9eb --- /dev/null +++ b/src/Kalman.Studio/Template/template.cpp @@ -0,0 +1,8 @@ +#include + +int main( int argc, char *argv[] ) +{ + printf( "Hello World!\n" ); + + return 0; +} diff --git a/src/Kalman.Studio/Template/template.cs b/src/Kalman.Studio/Template/template.cs new file mode 100644 index 0000000..f9fcbfc --- /dev/null +++ b/src/Kalman.Studio/Template/template.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Kalman +{ + class Class1 + { + } +} diff --git a/src/Kalman.Studio/Template/template.htm b/src/Kalman.Studio/Template/template.htm new file mode 100644 index 0000000..db7c701 --- /dev/null +++ b/src/Kalman.Studio/Template/template.htm @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/Kalman.Studio/Template/template.java b/src/Kalman.Studio/Template/template.java new file mode 100644 index 0000000..9ea143e --- /dev/null +++ b/src/Kalman.Studio/Template/template.java @@ -0,0 +1,7 @@ + +class Hello { + public static void main(String args[]) + { + System.out.println("Hello, world!"); + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/Template/template.js b/src/Kalman.Studio/Template/template.js new file mode 100644 index 0000000..5f28270 --- /dev/null +++ b/src/Kalman.Studio/Template/template.js @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/Kalman.Studio/Template/template.php b/src/Kalman.Studio/Template/template.php new file mode 100644 index 0000000..14938ff --- /dev/null +++ b/src/Kalman.Studio/Template/template.php @@ -0,0 +1,17 @@ + + + + + Untitled + + + + + + + + diff --git a/src/Kalman.Studio/Template/template.sql b/src/Kalman.Studio/Template/template.sql new file mode 100644 index 0000000..5f28270 --- /dev/null +++ b/src/Kalman.Studio/Template/template.sql @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/Kalman.Studio/Template/template.vb b/src/Kalman.Studio/Template/template.vb new file mode 100644 index 0000000..5f28270 --- /dev/null +++ b/src/Kalman.Studio/Template/template.vb @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/Kalman.Studio/Template/template.xml b/src/Kalman.Studio/Template/template.xml new file mode 100644 index 0000000..7dde50e --- /dev/null +++ b/src/Kalman.Studio/Template/template.xml @@ -0,0 +1 @@ + diff --git a/src/Kalman.Studio/ToolForm/DbDocBuilder.cs b/src/Kalman.Studio/ToolForm/DbDocBuilder.cs new file mode 100644 index 0000000..6221793 --- /dev/null +++ b/src/Kalman.Studio/ToolForm/DbDocBuilder.cs @@ -0,0 +1,239 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using System.Configuration; +using Kalman.Command; +using Kalman.Data; +using Kalman.Data.SchemaObject; + +namespace Kalman.Studio +{ + public partial class DbDocBuilder : DockableForm + { + public DbDocBuilder() + { + InitializeComponent(); + } + + /// + /// 连接字符串名称 + /// + public string CSName { get; set; } + /// + /// 数据库名称 + /// + public SODatabase CurrentDatabase { get; set; } + + DbSchema currentSchema; + + private void DbDocBuilder_Load(object sender, EventArgs e) + { + foreach (ConnectionStringSettings css in ConfigurationManager.ConnectionStrings) + { + cbConnectionStrings.Items.Add(css.Name); + } + + if (string.IsNullOrEmpty(CSName) == false) + { + ChangeConnection(CSName); + } + if (CurrentDatabase != null) + { + ChangeDatabase(CurrentDatabase); + } + } + //改变连接 + void ChangeConnection(string csName) + { + ConnectionStringSettings css = ConfigurationManager.ConnectionStrings[csName]; + currentSchema = DbSchemaFactory.Create(css.Name); + + List dbList = currentSchema.GetDatabaseList(); + cbDatabase.Items.Clear(); + foreach (SODatabase db in dbList) + { + if (db.IsSystemDatabase) continue; + cbDatabase.Items.Add(db); + } + + //if (cbDatabase.Items.Count > 0) + //{ + // DbName = cbDatabase.Items[0].ToString(); + // cbDatabase.SelectedIndex = 0; + //} + //else + //{ + // DbName = string.Empty; + //} + + foreach (object item in cbConnectionStrings.Items) + { + if (item.ToString() == CSName) + { + cbConnectionStrings.SelectedItem = item; + break; + } + } + } + //改变数据库 + void ChangeDatabase(SODatabase db) + { + listBox1.Items.Clear(); + listBox2.Items.Clear(); + + CurrentDatabase = db; + List list = currentSchema.GetTableList(db); + foreach (SOTable table in list) + { + listBox1.Items.Add(table); + } + + foreach (object item in cbDatabase.Items) + { + if (item.ToString() == CurrentDatabase.Name) + { + cbDatabase.SelectedItem = item; + break; + } + } + } + + private void cbConnectionStrings_SelectedIndexChanged(object sender, EventArgs e) + { + ChangeConnection(cbConnectionStrings.SelectedItem.ToString()); + } + + private void cbDatabase_SelectedIndexChanged(object sender, EventArgs e) + { + ChangeDatabase(cbDatabase.SelectedItem as SODatabase); + } + + #region 列表选择相关 + private void listBox1_MouseDoubleClick(object sender, MouseEventArgs e) + { + SelectOne(); + } + + private void listBox2_MouseDoubleClick(object sender, MouseEventArgs e) + { + RemoveOne(); + } + + private void btnSelectAll_Click(object sender, EventArgs e) + { + SelectAll(); + } + private void btnSelectOne_Click(object sender, EventArgs e) + { + SelectOne(); + } + private void btnRemoveOne_Click(object sender, EventArgs e) + { + RemoveOne(); + } + private void btnRemoveAll_Click(object sender, EventArgs e) + { + RemoveAll(); + } + + private void SelectAll() + { + if (listBox1.Items.Count > 0) + { + listBox2.Items.AddRange(listBox1.Items); + listBox1.Items.Clear(); + } + } + + private void SelectOne() + { + object[] items = new object[listBox1.SelectedItems.Count]; + listBox1.SelectedItems.CopyTo(items, 0); + listBox2.Items.AddRange(items); + + foreach (var item in items) + { + listBox1.Items.Remove(item); + } + } + + private void RemoveOne() + { + object[] items = new object[listBox2.SelectedItems.Count]; + listBox2.SelectedItems.CopyTo(items, 0); + listBox1.Items.AddRange(items); + + foreach (var item in items) + { + listBox2.Items.Remove(item); + } + } + + private void RemoveAll() + { + if (listBox2.Items.Count > 0) + { + listBox1.Items.AddRange(listBox2.Items); + listBox2.Items.Clear(); + } + } + #endregion + + private void btnOK_Click(object sender, EventArgs e) + { + List list = new List(); + foreach (object item in listBox2.Items) + { + list.Add(item as SOTable); + } + if (list.Count == 0) return; + + if (rbtnPdf.Checked) + { + saveFileDialog1.Filter = "pdf文件(*.pdf)|*.pdf|所有文件(*.*)|*.*"; + saveFileDialog1.FileName = CurrentDatabase.Name; + if (saveFileDialog1.ShowDialog() == DialogResult.OK) + { + string fileName = saveFileDialog1.FileName; + + iTextExporter exporter = new iTextExporter(fileName); + exporter.DbSchema2Pdf(currentSchema, CurrentDatabase, list); + + if (MessageBox.Show("数据库文档生成成功,是否打开文档", "提示信息", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes) + { + CmdHelper.Execute(fileName); + } + } + } + + if (rbtnWord.Checked) + { + saveFileDialog1.Filter = "rtf文件(*.rtf)|*.rtf|所有文件(*.*)|*.*"; + saveFileDialog1.FileName = CurrentDatabase.Name; + if (saveFileDialog1.ShowDialog() == DialogResult.OK) + { + string fileName = saveFileDialog1.FileName; + + iTextExporter exporter = new iTextExporter(fileName); + exporter.DbSchema2Rtf(currentSchema, CurrentDatabase, list); + + if (MessageBox.Show("数据库文档生成成功,是否打开文档", "提示信息", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes) + { + CmdHelper.Execute(fileName); + } + } + } + } + + private void btnExit_Click(object sender, EventArgs e) + { + this.Close(); + } + + } +} diff --git a/src/Kalman.Studio/ToolForm/DbDocBuilder.designer.cs b/src/Kalman.Studio/ToolForm/DbDocBuilder.designer.cs new file mode 100644 index 0000000..3151400 --- /dev/null +++ b/src/Kalman.Studio/ToolForm/DbDocBuilder.designer.cs @@ -0,0 +1,298 @@ +namespace Kalman.Studio +{ + partial class DbDocBuilder + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.cbDatabase = new System.Windows.Forms.ComboBox(); + this.label2 = new System.Windows.Forms.Label(); + this.label1 = new System.Windows.Forms.Label(); + this.cbConnectionStrings = new System.Windows.Forms.ComboBox(); + this.groupBox2 = new System.Windows.Forms.GroupBox(); + this.btnExit = new System.Windows.Forms.Button(); + this.btnOK = new System.Windows.Forms.Button(); + this.rbtnPdf = new System.Windows.Forms.RadioButton(); + this.rbtnWord = new System.Windows.Forms.RadioButton(); + this.btnRemoveAll = new System.Windows.Forms.Button(); + this.btnSelectOne = new System.Windows.Forms.Button(); + this.btnRemoveOne = new System.Windows.Forms.Button(); + this.gbTableSelect = new System.Windows.Forms.GroupBox(); + this.listBox2 = new System.Windows.Forms.ListBox(); + this.btnSelectAll = new System.Windows.Forms.Button(); + this.listBox1 = new System.Windows.Forms.ListBox(); + this.saveFileDialog1 = new System.Windows.Forms.SaveFileDialog(); + this.groupBox1.SuspendLayout(); + this.groupBox2.SuspendLayout(); + this.gbTableSelect.SuspendLayout(); + this.SuspendLayout(); + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.cbDatabase); + this.groupBox1.Controls.Add(this.label2); + this.groupBox1.Controls.Add(this.label1); + this.groupBox1.Controls.Add(this.cbConnectionStrings); + this.groupBox1.Dock = System.Windows.Forms.DockStyle.Top; + this.groupBox1.Location = new System.Drawing.Point(5, 5); + this.groupBox1.Margin = new System.Windows.Forms.Padding(5); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(574, 44); + this.groupBox1.TabIndex = 0; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "选择数据库"; + // + // cbDatabase + // + this.cbDatabase.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.cbDatabase.FormattingEnabled = true; + this.cbDatabase.Location = new System.Drawing.Point(410, 16); + this.cbDatabase.Name = "cbDatabase"; + this.cbDatabase.Size = new System.Drawing.Size(158, 20); + this.cbDatabase.TabIndex = 4; + this.cbDatabase.SelectedIndexChanged += new System.EventHandler(this.cbDatabase_SelectedIndexChanged); + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(327, 20); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(65, 12); + this.label2.TabIndex = 3; + this.label2.Text = "选择数据库"; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(8, 20); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(125, 12); + this.label1.TabIndex = 2; + this.label1.Text = "选择数据库连接字符串"; + // + // cbConnectionStrings + // + this.cbConnectionStrings.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.cbConnectionStrings.FormattingEnabled = true; + this.cbConnectionStrings.Location = new System.Drawing.Point(143, 16); + this.cbConnectionStrings.Name = "cbConnectionStrings"; + this.cbConnectionStrings.Size = new System.Drawing.Size(168, 20); + this.cbConnectionStrings.TabIndex = 1; + this.cbConnectionStrings.SelectedIndexChanged += new System.EventHandler(this.cbConnectionStrings_SelectedIndexChanged); + // + // groupBox2 + // + this.groupBox2.Controls.Add(this.btnExit); + this.groupBox2.Controls.Add(this.btnOK); + this.groupBox2.Controls.Add(this.rbtnPdf); + this.groupBox2.Controls.Add(this.rbtnWord); + this.groupBox2.Dock = System.Windows.Forms.DockStyle.Bottom; + this.groupBox2.Location = new System.Drawing.Point(5, 319); + this.groupBox2.Name = "groupBox2"; + this.groupBox2.Size = new System.Drawing.Size(574, 57); + this.groupBox2.TabIndex = 1; + this.groupBox2.TabStop = false; + this.groupBox2.Text = "选择文档输出格式"; + // + // btnExit + // + this.btnExit.Location = new System.Drawing.Point(491, 20); + this.btnExit.Name = "btnExit"; + this.btnExit.Size = new System.Drawing.Size(75, 23); + this.btnExit.TabIndex = 5; + this.btnExit.Text = "退出"; + this.btnExit.UseVisualStyleBackColor = true; + this.btnExit.Click += new System.EventHandler(this.btnExit_Click); + // + // btnOK + // + this.btnOK.Location = new System.Drawing.Point(410, 20); + this.btnOK.Name = "btnOK"; + this.btnOK.Size = new System.Drawing.Size(75, 23); + this.btnOK.TabIndex = 4; + this.btnOK.Text = "确定"; + this.btnOK.UseVisualStyleBackColor = true; + this.btnOK.Click += new System.EventHandler(this.btnOK_Click); + // + // rbtnPdf + // + this.rbtnPdf.AutoSize = true; + this.rbtnPdf.Checked = true; + this.rbtnPdf.Location = new System.Drawing.Point(17, 23); + this.rbtnPdf.Name = "rbtnPdf"; + this.rbtnPdf.Size = new System.Drawing.Size(65, 16); + this.rbtnPdf.TabIndex = 1; + this.rbtnPdf.TabStop = true; + this.rbtnPdf.Text = "Pdf格式"; + this.rbtnPdf.UseVisualStyleBackColor = true; + // + // rbtnWord + // + this.rbtnWord.AutoSize = true; + this.rbtnWord.Location = new System.Drawing.Point(104, 23); + this.rbtnWord.Name = "rbtnWord"; + this.rbtnWord.Size = new System.Drawing.Size(71, 16); + this.rbtnWord.TabIndex = 0; + this.rbtnWord.TabStop = true; + this.rbtnWord.Text = "Word格式"; + this.rbtnWord.UseVisualStyleBackColor = true; + // + // btnRemoveAll + // + this.btnRemoveAll.FlatStyle = System.Windows.Forms.FlatStyle.Popup; + this.btnRemoveAll.Location = new System.Drawing.Point(271, 189); + this.btnRemoveAll.Name = "btnRemoveAll"; + this.btnRemoveAll.Size = new System.Drawing.Size(50, 25); + this.btnRemoveAll.TabIndex = 8; + this.btnRemoveAll.Text = "<<"; + this.btnRemoveAll.UseVisualStyleBackColor = true; + this.btnRemoveAll.Click += new System.EventHandler(this.btnRemoveAll_Click); + // + // btnSelectOne + // + this.btnSelectOne.FlatStyle = System.Windows.Forms.FlatStyle.Popup; + this.btnSelectOne.Location = new System.Drawing.Point(271, 105); + this.btnSelectOne.Name = "btnSelectOne"; + this.btnSelectOne.Size = new System.Drawing.Size(50, 25); + this.btnSelectOne.TabIndex = 7; + this.btnSelectOne.Text = ">"; + this.btnSelectOne.UseVisualStyleBackColor = true; + this.btnSelectOne.Click += new System.EventHandler(this.btnSelectOne_Click); + // + // btnRemoveOne + // + this.btnRemoveOne.FlatStyle = System.Windows.Forms.FlatStyle.Popup; + this.btnRemoveOne.Location = new System.Drawing.Point(271, 147); + this.btnRemoveOne.Name = "btnRemoveOne"; + this.btnRemoveOne.Size = new System.Drawing.Size(50, 25); + this.btnRemoveOne.TabIndex = 9; + this.btnRemoveOne.Text = "<"; + this.btnRemoveOne.UseVisualStyleBackColor = true; + this.btnRemoveOne.Click += new System.EventHandler(this.btnRemoveOne_Click); + // + // gbTableSelect + // + this.gbTableSelect.Controls.Add(this.btnRemoveOne); + this.gbTableSelect.Controls.Add(this.btnRemoveAll); + this.gbTableSelect.Controls.Add(this.btnSelectOne); + this.gbTableSelect.Controls.Add(this.listBox2); + this.gbTableSelect.Controls.Add(this.btnSelectAll); + this.gbTableSelect.Controls.Add(this.listBox1); + this.gbTableSelect.Dock = System.Windows.Forms.DockStyle.Fill; + this.gbTableSelect.Location = new System.Drawing.Point(5, 49); + this.gbTableSelect.Margin = new System.Windows.Forms.Padding(10); + this.gbTableSelect.Name = "gbTableSelect"; + this.gbTableSelect.Padding = new System.Windows.Forms.Padding(10); + this.gbTableSelect.Size = new System.Drawing.Size(574, 270); + this.gbTableSelect.TabIndex = 2; + this.gbTableSelect.TabStop = false; + this.gbTableSelect.Text = "选择表"; + // + // listBox2 + // + this.listBox2.FormattingEnabled = true; + this.listBox2.ItemHeight = 12; + this.listBox2.Location = new System.Drawing.Point(340, 20); + this.listBox2.Name = "listBox2"; + this.listBox2.SelectionMode = System.Windows.Forms.SelectionMode.MultiExtended; + this.listBox2.Size = new System.Drawing.Size(231, 244); + this.listBox2.TabIndex = 6; + this.listBox2.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.listBox2_MouseDoubleClick); + // + // btnSelectAll + // + this.btnSelectAll.FlatStyle = System.Windows.Forms.FlatStyle.Popup; + this.btnSelectAll.Location = new System.Drawing.Point(271, 63); + this.btnSelectAll.Name = "btnSelectAll"; + this.btnSelectAll.Size = new System.Drawing.Size(50, 25); + this.btnSelectAll.TabIndex = 2; + this.btnSelectAll.Text = ">>"; + this.btnSelectAll.UseVisualStyleBackColor = true; + this.btnSelectAll.Click += new System.EventHandler(this.btnSelectAll_Click); + // + // listBox1 + // + this.listBox1.FormattingEnabled = true; + this.listBox1.ItemHeight = 12; + this.listBox1.Location = new System.Drawing.Point(12, 20); + this.listBox1.Name = "listBox1"; + this.listBox1.SelectionMode = System.Windows.Forms.SelectionMode.MultiExtended; + this.listBox1.Size = new System.Drawing.Size(240, 244); + this.listBox1.TabIndex = 0; + this.listBox1.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.listBox1_MouseDoubleClick); + // + // saveFileDialog1 + // + this.saveFileDialog1.Filter = "pdf文件(*.pdf)|*.pdf|所有文件(*.*)|*.*"; + // + // DbDocBuilder + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(584, 381); + this.Controls.Add(this.gbTableSelect); + this.Controls.Add(this.groupBox2); + this.Controls.Add(this.groupBox1); + this.MaximumSize = new System.Drawing.Size(600, 420); + this.MinimumSize = new System.Drawing.Size(600, 420); + this.Name = "DbDocBuilder"; + this.Padding = new System.Windows.Forms.Padding(5); + this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "数据库文档生成器"; + this.Load += new System.EventHandler(this.DbDocBuilder_Load); + this.groupBox1.ResumeLayout(false); + this.groupBox1.PerformLayout(); + this.groupBox2.ResumeLayout(false); + this.groupBox2.PerformLayout(); + this.gbTableSelect.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.GroupBox groupBox2; + private System.Windows.Forms.Button btnRemoveAll; + private System.Windows.Forms.Button btnSelectOne; + private System.Windows.Forms.Button btnRemoveOne; + private System.Windows.Forms.GroupBox gbTableSelect; + private System.Windows.Forms.ListBox listBox2; + private System.Windows.Forms.Button btnSelectAll; + private System.Windows.Forms.ListBox listBox1; + private System.Windows.Forms.ComboBox cbDatabase; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.ComboBox cbConnectionStrings; + private System.Windows.Forms.RadioButton rbtnWord; + private System.Windows.Forms.Button btnOK; + private System.Windows.Forms.RadioButton rbtnPdf; + private System.Windows.Forms.Button btnExit; + private System.Windows.Forms.SaveFileDialog saveFileDialog1; + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/ToolForm/DbDocBuilder.resx b/src/Kalman.Studio/ToolForm/DbDocBuilder.resx new file mode 100644 index 0000000..081d426 --- /dev/null +++ b/src/Kalman.Studio/ToolForm/DbDocBuilder.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + \ No newline at end of file diff --git a/src/Kalman.Studio/ToolForm/DbObjectViewer/DbObjectViewer.cs b/src/Kalman.Studio/ToolForm/DbObjectViewer/DbObjectViewer.cs new file mode 100644 index 0000000..42891cf --- /dev/null +++ b/src/Kalman.Studio/ToolForm/DbObjectViewer/DbObjectViewer.cs @@ -0,0 +1,116 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using WeifenLuo.WinFormsUI.Docking; +using Kalman.Data.SchemaObject; + +namespace Kalman.Studio +{ + public partial class DbObjectViewer : DockableForm + { + public DbObjectViewer() + { + InitializeComponent(); + } + + public SODatabase CurrentDatabase { get; set; } + + private void DbObjectViewer_Load(object sender, EventArgs e) + { + dgvTable.AutoGenerateColumns = false; + dgvView.AutoGenerateColumns = false; + dgvSP.AutoGenerateColumns = false; + cbDatabase.DataSource = DbSchemaHelper.Instance.CurrentSchema.GetDatabaseList(); + + if (CurrentDatabase != null) + { + for (int i = 0; i < cbDatabase.Items.Count; i++) + { + if (cbDatabase.Items[i].ToString() == CurrentDatabase.Name) + { + cbDatabase.SelectedItem = cbDatabase.Items[i]; + break; + } + } + } + BindData(); + cbDatabase.SelectedIndexChanged += new EventHandler(cbDatabase_SelectedIndexChanged); + } + + private void cbDatabase_SelectedIndexChanged(object sender, EventArgs e) + { + CurrentDatabase = cbDatabase.SelectedItem as SODatabase; + BindData(); + } + + void BindData() + { + if (CurrentDatabase == null) return; + dgvTable.DataSource = DbSchemaHelper.Instance.CurrentSchema.GetTableList(CurrentDatabase); + dgvView.DataSource = DbSchemaHelper.Instance.CurrentSchema.GetViewList(CurrentDatabase); + dgvSP.DataSource = DbSchemaHelper.Instance.CurrentSchema.GetCommandList(CurrentDatabase); + tpTable.Text = string.Format("表[{0}]", dgvTable.Rows.Count); + tpView.Text = string.Format("视图[{0}]", dgvView.Rows.Count); + tpSP.Text = string.Format("存储过程[{0}]", dgvSP.Rows.Count); + } + + + + private void dgvTable_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e) + { + if (e.Button == MouseButtons.Right && e.RowIndex > -1 && e.ColumnIndex > -1) + { + dgvTable.CurrentRow.Selected = false; + dgvTable.Rows[e.RowIndex].Selected = true; + } + } + private void dgvView_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e) + { + if (e.Button == MouseButtons.Right && e.RowIndex > -1 && e.ColumnIndex > -1) + { + dgvView.CurrentRow.Selected = false; + dgvView.Rows[e.RowIndex].Selected = true; + } + } + private void dgvSP_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e) + { + if (e.Button == MouseButtons.Right && e.RowIndex > -1 && e.ColumnIndex > -1) + { + dgvSP.CurrentRow.Selected = false; + dgvSP.Rows[e.RowIndex].Selected = true; + } + } + + private void dgvTable_CellMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e) + { + if (e.RowIndex > -1) + { + DbTableViewer v = new DbTableViewer(dgvTable.Rows[e.RowIndex].DataBoundItem as SOTable); + v.ShowDialog(); + } + } + + private void dgvView_CellMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e) + { + if (e.RowIndex > -1) + { + DbViewViewer v = new DbViewViewer(dgvView.Rows[e.RowIndex].DataBoundItem as SOView); + v.ShowDialog(); + } + } + + private void dgvSP_CellMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e) + { + if (e.RowIndex > -1) + { + DbSPViewer v = new DbSPViewer(dgvSP.Rows[e.RowIndex].DataBoundItem as SOCommand); + v.ShowDialog(); + } + } + } +} diff --git a/src/Kalman.Studio/ToolForm/DbObjectViewer/DbObjectViewer.designer.cs b/src/Kalman.Studio/ToolForm/DbObjectViewer/DbObjectViewer.designer.cs new file mode 100644 index 0000000..e877e1e --- /dev/null +++ b/src/Kalman.Studio/ToolForm/DbObjectViewer/DbObjectViewer.designer.cs @@ -0,0 +1,409 @@ +namespace Kalman.Studio +{ + partial class DbObjectViewer + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle2 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle3 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle4 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle5 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle6 = new System.Windows.Forms.DataGridViewCellStyle(); + this.panel1 = new System.Windows.Forms.Panel(); + this.cbDatabase = new System.Windows.Forms.ComboBox(); + this.lblDbName = new System.Windows.Forms.Label(); + this.tabControl1 = new System.Windows.Forms.TabControl(); + this.tpTable = new System.Windows.Forms.TabPage(); + this.dgvTable = new System.Windows.Forms.DataGridView(); + this.tpView = new System.Windows.Forms.TabPage(); + this.dgvView = new System.Windows.Forms.DataGridView(); + this.tpSP = new System.Windows.Forms.TabPage(); + this.dgvSP = new System.Windows.Forms.DataGridView(); + this.colSPOwner = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colSPName = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colSPFullName = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colSPComment = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colViewOwner = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colViewName = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colViewFullName = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colViewComment = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colTableOwner = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colTableName = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colFullName = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colTableComment = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.panel1.SuspendLayout(); + this.tabControl1.SuspendLayout(); + this.tpTable.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.dgvTable)).BeginInit(); + this.tpView.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.dgvView)).BeginInit(); + this.tpSP.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.dgvSP)).BeginInit(); + this.SuspendLayout(); + // + // panel1 + // + this.panel1.Controls.Add(this.cbDatabase); + this.panel1.Controls.Add(this.lblDbName); + this.panel1.Dock = System.Windows.Forms.DockStyle.Top; + this.panel1.Location = new System.Drawing.Point(0, 0); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(739, 33); + this.panel1.TabIndex = 0; + // + // cbDatabase + // + this.cbDatabase.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.cbDatabase.FormattingEnabled = true; + this.cbDatabase.Location = new System.Drawing.Point(74, 8); + this.cbDatabase.Name = "cbDatabase"; + this.cbDatabase.Size = new System.Drawing.Size(178, 20); + this.cbDatabase.TabIndex = 1; + // + // lblDbName + // + this.lblDbName.AutoSize = true; + this.lblDbName.Location = new System.Drawing.Point(3, 12); + this.lblDbName.Name = "lblDbName"; + this.lblDbName.Size = new System.Drawing.Size(65, 12); + this.lblDbName.TabIndex = 0; + this.lblDbName.Text = "当前数据库"; + // + // tabControl1 + // + this.tabControl1.Controls.Add(this.tpTable); + this.tabControl1.Controls.Add(this.tpView); + this.tabControl1.Controls.Add(this.tpSP); + this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill; + this.tabControl1.Location = new System.Drawing.Point(0, 33); + this.tabControl1.Name = "tabControl1"; + this.tabControl1.SelectedIndex = 0; + this.tabControl1.Size = new System.Drawing.Size(739, 420); + this.tabControl1.TabIndex = 1; + // + // tpTable + // + this.tpTable.Controls.Add(this.dgvTable); + this.tpTable.Location = new System.Drawing.Point(4, 21); + this.tpTable.Name = "tpTable"; + this.tpTable.Padding = new System.Windows.Forms.Padding(3); + this.tpTable.Size = new System.Drawing.Size(731, 395); + this.tpTable.TabIndex = 0; + this.tpTable.Text = "表"; + this.tpTable.UseVisualStyleBackColor = true; + // + // dgvTable + // + this.dgvTable.AllowUserToAddRows = false; + this.dgvTable.AllowUserToDeleteRows = false; + this.dgvTable.AllowUserToResizeRows = false; + dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle1.BackColor = System.Drawing.SystemColors.Control; + dataGridViewCellStyle1.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + dataGridViewCellStyle1.ForeColor = System.Drawing.SystemColors.WindowText; + dataGridViewCellStyle1.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle1.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle1.WrapMode = System.Windows.Forms.DataGridViewTriState.True; + this.dgvTable.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle1; + this.dgvTable.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.dgvTable.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { + this.colTableOwner, + this.colTableName, + this.colFullName, + this.colTableComment}); + dataGridViewCellStyle2.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle2.BackColor = System.Drawing.SystemColors.Window; + dataGridViewCellStyle2.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + dataGridViewCellStyle2.ForeColor = System.Drawing.SystemColors.ControlText; + dataGridViewCellStyle2.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle2.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle2.WrapMode = System.Windows.Forms.DataGridViewTriState.False; + this.dgvTable.DefaultCellStyle = dataGridViewCellStyle2; + this.dgvTable.Dock = System.Windows.Forms.DockStyle.Fill; + this.dgvTable.Location = new System.Drawing.Point(3, 3); + this.dgvTable.MultiSelect = false; + this.dgvTable.Name = "dgvTable"; + this.dgvTable.RowHeadersVisible = false; + this.dgvTable.RowTemplate.Height = 23; + this.dgvTable.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.CellSelect; + this.dgvTable.Size = new System.Drawing.Size(725, 389); + this.dgvTable.TabIndex = 0; + this.dgvTable.CellMouseDown += new System.Windows.Forms.DataGridViewCellMouseEventHandler(this.dgvTable_CellMouseDown); + this.dgvTable.CellMouseDoubleClick += new System.Windows.Forms.DataGridViewCellMouseEventHandler(this.dgvTable_CellMouseDoubleClick); + // + // tpView + // + this.tpView.Controls.Add(this.dgvView); + this.tpView.Location = new System.Drawing.Point(4, 21); + this.tpView.Name = "tpView"; + this.tpView.Padding = new System.Windows.Forms.Padding(3); + this.tpView.Size = new System.Drawing.Size(731, 395); + this.tpView.TabIndex = 1; + this.tpView.Text = "视图"; + this.tpView.UseVisualStyleBackColor = true; + // + // dgvView + // + this.dgvView.AllowUserToAddRows = false; + this.dgvView.AllowUserToDeleteRows = false; + this.dgvView.AllowUserToResizeRows = false; + dataGridViewCellStyle3.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle3.BackColor = System.Drawing.SystemColors.Control; + dataGridViewCellStyle3.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + dataGridViewCellStyle3.ForeColor = System.Drawing.SystemColors.WindowText; + dataGridViewCellStyle3.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle3.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle3.WrapMode = System.Windows.Forms.DataGridViewTriState.True; + this.dgvView.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle3; + this.dgvView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.dgvView.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { + this.colViewOwner, + this.colViewName, + this.colViewFullName, + this.colViewComment}); + dataGridViewCellStyle4.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle4.BackColor = System.Drawing.SystemColors.Window; + dataGridViewCellStyle4.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + dataGridViewCellStyle4.ForeColor = System.Drawing.SystemColors.ControlText; + dataGridViewCellStyle4.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle4.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle4.WrapMode = System.Windows.Forms.DataGridViewTriState.False; + this.dgvView.DefaultCellStyle = dataGridViewCellStyle4; + this.dgvView.Dock = System.Windows.Forms.DockStyle.Fill; + this.dgvView.Location = new System.Drawing.Point(3, 3); + this.dgvView.MultiSelect = false; + this.dgvView.Name = "dgvView"; + this.dgvView.ReadOnly = true; + this.dgvView.RowHeadersVisible = false; + this.dgvView.RowTemplate.Height = 23; + this.dgvView.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect; + this.dgvView.Size = new System.Drawing.Size(725, 389); + this.dgvView.TabIndex = 1; + this.dgvView.CellMouseDoubleClick += new System.Windows.Forms.DataGridViewCellMouseEventHandler(this.dgvView_CellMouseDoubleClick); + // + // tpSP + // + this.tpSP.Controls.Add(this.dgvSP); + this.tpSP.Location = new System.Drawing.Point(4, 21); + this.tpSP.Name = "tpSP"; + this.tpSP.Padding = new System.Windows.Forms.Padding(3); + this.tpSP.Size = new System.Drawing.Size(731, 395); + this.tpSP.TabIndex = 2; + this.tpSP.Text = "存储过程"; + this.tpSP.UseVisualStyleBackColor = true; + // + // dgvSP + // + this.dgvSP.AllowUserToAddRows = false; + this.dgvSP.AllowUserToDeleteRows = false; + this.dgvSP.AllowUserToResizeRows = false; + dataGridViewCellStyle5.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle5.BackColor = System.Drawing.SystemColors.Control; + dataGridViewCellStyle5.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + dataGridViewCellStyle5.ForeColor = System.Drawing.SystemColors.WindowText; + dataGridViewCellStyle5.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle5.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle5.WrapMode = System.Windows.Forms.DataGridViewTriState.True; + this.dgvSP.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle5; + this.dgvSP.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.dgvSP.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { + this.colSPOwner, + this.colSPName, + this.colSPFullName, + this.colSPComment}); + dataGridViewCellStyle6.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle6.BackColor = System.Drawing.SystemColors.Window; + dataGridViewCellStyle6.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + dataGridViewCellStyle6.ForeColor = System.Drawing.SystemColors.ControlText; + dataGridViewCellStyle6.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle6.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle6.WrapMode = System.Windows.Forms.DataGridViewTriState.False; + this.dgvSP.DefaultCellStyle = dataGridViewCellStyle6; + this.dgvSP.Dock = System.Windows.Forms.DockStyle.Fill; + this.dgvSP.Location = new System.Drawing.Point(3, 3); + this.dgvSP.MultiSelect = false; + this.dgvSP.Name = "dgvSP"; + this.dgvSP.ReadOnly = true; + this.dgvSP.RowHeadersVisible = false; + this.dgvSP.RowTemplate.Height = 23; + this.dgvSP.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect; + this.dgvSP.Size = new System.Drawing.Size(725, 389); + this.dgvSP.TabIndex = 1; + this.dgvSP.CellMouseDoubleClick += new System.Windows.Forms.DataGridViewCellMouseEventHandler(this.dgvSP_CellMouseDoubleClick); + // + // colSPOwner + // + this.colSPOwner.DataPropertyName = "Owner"; + this.colSPOwner.FillWeight = 60F; + this.colSPOwner.HeaderText = "所有者"; + this.colSPOwner.Name = "colSPOwner"; + this.colSPOwner.ReadOnly = true; + this.colSPOwner.Width = 120; + // + // colSPName + // + this.colSPName.DataPropertyName = "Name"; + this.colSPName.FillWeight = 60F; + this.colSPName.HeaderText = "存储过程名"; + this.colSPName.Name = "colSPName"; + this.colSPName.ReadOnly = true; + this.colSPName.Width = 150; + // + // colSPFullName + // + this.colSPFullName.DataPropertyName = "FullName"; + this.colSPFullName.HeaderText = "全名"; + this.colSPFullName.Name = "colSPFullName"; + this.colSPFullName.ReadOnly = true; + this.colSPFullName.Width = 280; + // + // colSPComment + // + this.colSPComment.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; + this.colSPComment.DataPropertyName = "Comment"; + this.colSPComment.FillWeight = 200F; + this.colSPComment.HeaderText = "说明"; + this.colSPComment.Name = "colSPComment"; + this.colSPComment.ReadOnly = true; + // + // colViewOwner + // + this.colViewOwner.DataPropertyName = "Owner"; + this.colViewOwner.FillWeight = 60F; + this.colViewOwner.HeaderText = "所有者"; + this.colViewOwner.Name = "colViewOwner"; + this.colViewOwner.ReadOnly = true; + this.colViewOwner.Width = 120; + // + // colViewName + // + this.colViewName.DataPropertyName = "Name"; + this.colViewName.FillWeight = 60F; + this.colViewName.HeaderText = "视图名"; + this.colViewName.Name = "colViewName"; + this.colViewName.ReadOnly = true; + this.colViewName.Width = 150; + // + // colViewFullName + // + this.colViewFullName.DataPropertyName = "FullName"; + this.colViewFullName.HeaderText = "全名"; + this.colViewFullName.Name = "colViewFullName"; + this.colViewFullName.ReadOnly = true; + this.colViewFullName.Width = 280; + // + // colViewComment + // + this.colViewComment.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; + this.colViewComment.DataPropertyName = "Comment"; + this.colViewComment.FillWeight = 200F; + this.colViewComment.HeaderText = "说明"; + this.colViewComment.Name = "colViewComment"; + this.colViewComment.ReadOnly = true; + // + // colTableOwner + // + this.colTableOwner.DataPropertyName = "Owner"; + this.colTableOwner.FillWeight = 60F; + this.colTableOwner.HeaderText = "所有者"; + this.colTableOwner.Name = "colTableOwner"; + this.colTableOwner.Width = 120; + // + // colTableName + // + this.colTableName.DataPropertyName = "Name"; + this.colTableName.FillWeight = 60F; + this.colTableName.HeaderText = "表名"; + this.colTableName.Name = "colTableName"; + this.colTableName.Width = 150; + // + // colFullName + // + this.colFullName.DataPropertyName = "FullName"; + this.colFullName.HeaderText = "全名"; + this.colFullName.Name = "colFullName"; + this.colFullName.Width = 280; + // + // colTableComment + // + this.colTableComment.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; + this.colTableComment.DataPropertyName = "Comment"; + this.colTableComment.FillWeight = 200F; + this.colTableComment.HeaderText = "说明"; + this.colTableComment.Name = "colTableComment"; + // + // DbObjectViewer + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(739, 453); + this.Controls.Add(this.tabControl1); + this.Controls.Add(this.panel1); + this.Name = "DbObjectViewer"; + this.Text = "数据库对象查看器"; + this.Load += new System.EventHandler(this.DbObjectViewer_Load); + this.panel1.ResumeLayout(false); + this.panel1.PerformLayout(); + this.tabControl1.ResumeLayout(false); + this.tpTable.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.dgvTable)).EndInit(); + this.tpView.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.dgvView)).EndInit(); + this.tpSP.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.dgvSP)).EndInit(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Panel panel1; + private System.Windows.Forms.Label lblDbName; + private System.Windows.Forms.TabControl tabControl1; + private System.Windows.Forms.TabPage tpTable; + private System.Windows.Forms.TabPage tpView; + private System.Windows.Forms.TabPage tpSP; + private System.Windows.Forms.ComboBox cbDatabase; + private System.Windows.Forms.DataGridView dgvTable; + private System.Windows.Forms.DataGridView dgvView; + private System.Windows.Forms.DataGridView dgvSP; + private System.Windows.Forms.DataGridViewTextBoxColumn colTableFullName; + private System.Windows.Forms.DataGridViewTextBoxColumn colTableOwner; + private System.Windows.Forms.DataGridViewTextBoxColumn colTableName; + private System.Windows.Forms.DataGridViewTextBoxColumn colFullName; + private System.Windows.Forms.DataGridViewTextBoxColumn colTableComment; + private System.Windows.Forms.DataGridViewTextBoxColumn colViewOwner; + private System.Windows.Forms.DataGridViewTextBoxColumn colViewName; + private System.Windows.Forms.DataGridViewTextBoxColumn colViewFullName; + private System.Windows.Forms.DataGridViewTextBoxColumn colViewComment; + private System.Windows.Forms.DataGridViewTextBoxColumn colSPOwner; + private System.Windows.Forms.DataGridViewTextBoxColumn colSPName; + private System.Windows.Forms.DataGridViewTextBoxColumn colSPFullName; + private System.Windows.Forms.DataGridViewTextBoxColumn colSPComment; + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/ToolForm/DbObjectViewer/DbObjectViewer.resx b/src/Kalman.Studio/ToolForm/DbObjectViewer/DbObjectViewer.resx new file mode 100644 index 0000000..db051ab --- /dev/null +++ b/src/Kalman.Studio/ToolForm/DbObjectViewer/DbObjectViewer.resx @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + \ No newline at end of file diff --git a/src/Kalman.Studio/ToolForm/DbObjectViewer/DbSPViewer.cs b/src/Kalman.Studio/ToolForm/DbObjectViewer/DbSPViewer.cs new file mode 100644 index 0000000..f802be9 --- /dev/null +++ b/src/Kalman.Studio/ToolForm/DbObjectViewer/DbSPViewer.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using ICSharpCode.TextEditor.Document; +using Kalman.Data.SchemaObject; + +namespace Kalman.Studio +{ + public partial class DbSPViewer : Form + { + SOCommand currentSP; + + public DbSPViewer(SOCommand sp) + { + InitializeComponent(); + currentSP = sp; + } + + private void DbSPViewer_Load(object sender, EventArgs e) + { + this.Text = string.Format("查看存储过程信息[{0}->{1}]", currentSP.Database.Name, currentSP.Name); + dgv.DataSource = DbSchemaHelper.Instance.CurrentSchema.GetCommandParameterList(currentSP); + + IHighlightingStrategy strategy = HighlightingStrategyFactory.CreateHighlightingStrategy(CodeType.TSQL); + textEditorControl1.Document.HighlightingStrategy = strategy; + textEditorControl1.Text = currentSP.SqlText; + } + } +} diff --git a/src/Kalman.Studio/ToolForm/DbObjectViewer/DbSPViewer.designer.cs b/src/Kalman.Studio/ToolForm/DbObjectViewer/DbSPViewer.designer.cs new file mode 100644 index 0000000..09c4000 --- /dev/null +++ b/src/Kalman.Studio/ToolForm/DbObjectViewer/DbSPViewer.designer.cs @@ -0,0 +1,84 @@ +namespace Kalman.Studio +{ + partial class DbSPViewer + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.dgv = new System.Windows.Forms.DataGridView(); + this.textEditorControl1 = new ICSharpCode.TextEditor.TextEditorControl(); + ((System.ComponentModel.ISupportInitialize)(this.dgv)).BeginInit(); + this.SuspendLayout(); + // + // dgv + // + this.dgv.AllowUserToAddRows = false; + this.dgv.AllowUserToDeleteRows = false; + this.dgv.AllowUserToResizeRows = false; + this.dgv.BackgroundColor = System.Drawing.SystemColors.Window; + this.dgv.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.dgv.Dock = System.Windows.Forms.DockStyle.Bottom; + this.dgv.Location = new System.Drawing.Point(0, 322); + this.dgv.MultiSelect = false; + this.dgv.Name = "dgv"; + this.dgv.ReadOnly = true; + this.dgv.RowHeadersVisible = false; + this.dgv.RowTemplate.Height = 23; + this.dgv.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.CellSelect; + this.dgv.Size = new System.Drawing.Size(792, 251); + this.dgv.TabIndex = 4; + // + // textEditorControl1 + // + this.textEditorControl1.Dock = System.Windows.Forms.DockStyle.Fill; + this.textEditorControl1.IsReadOnly = false; + this.textEditorControl1.Location = new System.Drawing.Point(0, 0); + this.textEditorControl1.Name = "textEditorControl1"; + this.textEditorControl1.Size = new System.Drawing.Size(792, 322); + this.textEditorControl1.TabIndex = 5; + // + // DbSPViewer + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(792, 573); + this.Controls.Add(this.textEditorControl1); + this.Controls.Add(this.dgv); + this.Name = "DbSPViewer"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "DbSPViewer"; + this.Load += new System.EventHandler(this.DbSPViewer_Load); + ((System.ComponentModel.ISupportInitialize)(this.dgv)).EndInit(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.DataGridView dgv; + private ICSharpCode.TextEditor.TextEditorControl textEditorControl1; + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/ToolForm/DbObjectViewer/DbSPViewer.resx b/src/Kalman.Studio/ToolForm/DbObjectViewer/DbSPViewer.resx new file mode 100644 index 0000000..19dc0dd --- /dev/null +++ b/src/Kalman.Studio/ToolForm/DbObjectViewer/DbSPViewer.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/Kalman.Studio/ToolForm/DbObjectViewer/DbTableViewer.cs b/src/Kalman.Studio/ToolForm/DbObjectViewer/DbTableViewer.cs new file mode 100644 index 0000000..8152331 --- /dev/null +++ b/src/Kalman.Studio/ToolForm/DbObjectViewer/DbTableViewer.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using Kalman.Data.SchemaObject; + +namespace Kalman.Studio +{ + public partial class DbTableViewer : Form + { + SOTable currentTable; + public DbTableViewer(SOTable table) + { + InitializeComponent(); + currentTable = table; + } + + private void DbTableViewer_Load(object sender, EventArgs e) + { + dgv.AutoGenerateColumns = false; + this.Text = string.Format("查看表信息[{0}->{1}]", currentTable.Database.Name, currentTable.Name); + dgv.DataSource = DbSchemaHelper.Instance.CurrentSchema.GetTableColumnList(currentTable); + } + } +} diff --git a/src/Kalman.Studio/ToolForm/DbObjectViewer/DbTableViewer.designer.cs b/src/Kalman.Studio/ToolForm/DbObjectViewer/DbTableViewer.designer.cs new file mode 100644 index 0000000..4b9dc1c --- /dev/null +++ b/src/Kalman.Studio/ToolForm/DbObjectViewer/DbTableViewer.designer.cs @@ -0,0 +1,229 @@ +namespace Kalman.Studio +{ + partial class DbTableViewer + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.dgv = new System.Windows.Forms.DataGridView(); + this.Comment = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.DataType = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.DefaultValue = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.Scale = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.Precision = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.Length = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.NativeType = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.FieldName = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.Nullable = new System.Windows.Forms.DataGridViewCheckBoxColumn(); + this.Identify = new System.Windows.Forms.DataGridViewCheckBoxColumn(); + this.ForeignKey = new System.Windows.Forms.DataGridViewCheckBoxColumn(); + this.PrimaryKey = new System.Windows.Forms.DataGridViewCheckBoxColumn(); + ((System.ComponentModel.ISupportInitialize)(this.dgv)).BeginInit(); + this.SuspendLayout(); + // + // dgv + // + this.dgv.AllowUserToAddRows = false; + this.dgv.AllowUserToDeleteRows = false; + this.dgv.AllowUserToResizeRows = false; + this.dgv.BackgroundColor = System.Drawing.SystemColors.Window; + this.dgv.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.dgv.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { + this.PrimaryKey, + this.ForeignKey, + this.Identify, + this.Nullable, + this.FieldName, + this.NativeType, + this.Length, + this.Precision, + this.Scale, + this.DefaultValue, + this.DataType, + this.Comment}); + this.dgv.Dock = System.Windows.Forms.DockStyle.Fill; + this.dgv.Location = new System.Drawing.Point(0, 0); + this.dgv.MultiSelect = false; + this.dgv.Name = "dgv"; + this.dgv.RowHeadersVisible = false; + this.dgv.RowTemplate.Height = 23; + this.dgv.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.CellSelect; + this.dgv.Size = new System.Drawing.Size(792, 473); + this.dgv.TabIndex = 1; + // + // Comment + // + this.Comment.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; + this.Comment.DataPropertyName = "Comment"; + this.Comment.HeaderText = "注释"; + this.Comment.Name = "Comment"; + // + // DataType + // + this.DataType.DataPropertyName = "DataType"; + this.DataType.HeaderText = "转换类型"; + this.DataType.MinimumWidth = 80; + this.DataType.Name = "DataType"; + this.DataType.ToolTipText = "特定数据库中定义的数据类型对应的.Net Framework类型"; + this.DataType.Width = 80; + // + // DefaultValue + // + this.DefaultValue.DataPropertyName = "DefaultValue"; + this.DefaultValue.HeaderText = "默认值"; + this.DefaultValue.MinimumWidth = 80; + this.DefaultValue.Name = "DefaultValue"; + this.DefaultValue.Width = 80; + // + // Scale + // + this.Scale.DataPropertyName = "Scale"; + this.Scale.Frozen = true; + this.Scale.HeaderText = "小数"; + this.Scale.MinimumWidth = 40; + this.Scale.Name = "Scale"; + this.Scale.ToolTipText = "小数位数"; + this.Scale.Width = 40; + // + // Precision + // + this.Precision.DataPropertyName = "Precision"; + this.Precision.Frozen = true; + this.Precision.HeaderText = "精度"; + this.Precision.MinimumWidth = 40; + this.Precision.Name = "Precision"; + this.Precision.Width = 40; + // + // Length + // + this.Length.DataPropertyName = "Length"; + this.Length.Frozen = true; + this.Length.HeaderText = "长度"; + this.Length.MinimumWidth = 40; + this.Length.Name = "Length"; + this.Length.Width = 40; + // + // NativeType + // + this.NativeType.DataPropertyName = "NativeType"; + this.NativeType.Frozen = true; + this.NativeType.HeaderText = "原生类型"; + this.NativeType.MaxInputLength = 200; + this.NativeType.Name = "NativeType"; + this.NativeType.ToolTipText = "对应数据库定义的原生类型"; + this.NativeType.Width = 120; + // + // FieldName + // + this.FieldName.DataPropertyName = "Name"; + this.FieldName.Frozen = true; + this.FieldName.HeaderText = "字段名"; + this.FieldName.MaxInputLength = 100; + this.FieldName.Name = "FieldName"; + this.FieldName.Width = 120; + // + // Nullable + // + this.Nullable.DataPropertyName = "Nullable"; + this.Nullable.FalseValue = ""; + this.Nullable.Frozen = true; + this.Nullable.HeaderText = "N"; + this.Nullable.MinimumWidth = 20; + this.Nullable.Name = "Nullable"; + this.Nullable.ReadOnly = true; + this.Nullable.Resizable = System.Windows.Forms.DataGridViewTriState.False; + this.Nullable.ToolTipText = "允许为空"; + this.Nullable.TrueValue = ""; + this.Nullable.Width = 20; + // + // Identify + // + this.Identify.DataPropertyName = "Identify"; + this.Identify.Frozen = true; + this.Identify.HeaderText = "I"; + this.Identify.MinimumWidth = 20; + this.Identify.Name = "Identify"; + this.Identify.ReadOnly = true; + this.Identify.Resizable = System.Windows.Forms.DataGridViewTriState.False; + this.Identify.ToolTipText = "是否为标志列"; + this.Identify.Width = 20; + // + // ForeignKey + // + this.ForeignKey.DataPropertyName = "ForeignKey"; + this.ForeignKey.Frozen = true; + this.ForeignKey.HeaderText = "F"; + this.ForeignKey.MinimumWidth = 20; + this.ForeignKey.Name = "ForeignKey"; + this.ForeignKey.ReadOnly = true; + this.ForeignKey.Resizable = System.Windows.Forms.DataGridViewTriState.False; + this.ForeignKey.ToolTipText = "是否为外键"; + this.ForeignKey.Width = 20; + // + // PrimaryKey + // + this.PrimaryKey.DataPropertyName = "PrimaryKey"; + this.PrimaryKey.Frozen = true; + this.PrimaryKey.HeaderText = "P"; + this.PrimaryKey.MinimumWidth = 20; + this.PrimaryKey.Name = "PrimaryKey"; + this.PrimaryKey.ReadOnly = true; + this.PrimaryKey.Resizable = System.Windows.Forms.DataGridViewTriState.False; + this.PrimaryKey.ToolTipText = "是否为主键"; + this.PrimaryKey.Width = 20; + // + // DbTableViewer + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(792, 473); + this.Controls.Add(this.dgv); + this.Name = "DbTableViewer"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "DbTableViewer"; + this.Load += new System.EventHandler(this.DbTableViewer_Load); + ((System.ComponentModel.ISupportInitialize)(this.dgv)).EndInit(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.DataGridView dgv; + private System.Windows.Forms.DataGridViewCheckBoxColumn PrimaryKey; + private System.Windows.Forms.DataGridViewCheckBoxColumn ForeignKey; + private System.Windows.Forms.DataGridViewCheckBoxColumn Identify; + private System.Windows.Forms.DataGridViewCheckBoxColumn Nullable; + private System.Windows.Forms.DataGridViewTextBoxColumn FieldName; + private System.Windows.Forms.DataGridViewTextBoxColumn NativeType; + private System.Windows.Forms.DataGridViewTextBoxColumn Length; + private System.Windows.Forms.DataGridViewTextBoxColumn Precision; + private System.Windows.Forms.DataGridViewTextBoxColumn Scale; + private System.Windows.Forms.DataGridViewTextBoxColumn DefaultValue; + private System.Windows.Forms.DataGridViewTextBoxColumn DataType; + private System.Windows.Forms.DataGridViewTextBoxColumn Comment; + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/ToolForm/DbObjectViewer/DbTableViewer.resx b/src/Kalman.Studio/ToolForm/DbObjectViewer/DbTableViewer.resx new file mode 100644 index 0000000..bebb0e6 --- /dev/null +++ b/src/Kalman.Studio/ToolForm/DbObjectViewer/DbTableViewer.resx @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + \ No newline at end of file diff --git a/src/Kalman.Studio/ToolForm/DbObjectViewer/DbViewViewer.cs b/src/Kalman.Studio/ToolForm/DbObjectViewer/DbViewViewer.cs new file mode 100644 index 0000000..e121193 --- /dev/null +++ b/src/Kalman.Studio/ToolForm/DbObjectViewer/DbViewViewer.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using ICSharpCode.TextEditor.Document; +using Kalman.Data.SchemaObject; + +namespace Kalman.Studio +{ + public partial class DbViewViewer : Form + { + SOView currentView; + + public DbViewViewer(SOView view) + { + InitializeComponent(); + currentView = view; + } + + private void DbViewViewer_Load(object sender, EventArgs e) + { + dgv.AutoGenerateColumns = false; + this.Text = string.Format("查看视图信息[{0}->{1}]", currentView.Database.Name, currentView.Name); + dgv.DataSource = DbSchemaHelper.Instance.CurrentSchema.GetViewColumnList(currentView); + + IHighlightingStrategy strategy = HighlightingStrategyFactory.CreateHighlightingStrategy(CodeType.TSQL); + textEditorControl1.Document.HighlightingStrategy = strategy; + textEditorControl1.Text = currentView.SqlText; + } + } +} diff --git a/src/Kalman.Studio/ToolForm/DbObjectViewer/DbViewViewer.designer.cs b/src/Kalman.Studio/ToolForm/DbObjectViewer/DbViewViewer.designer.cs new file mode 100644 index 0000000..78105f5 --- /dev/null +++ b/src/Kalman.Studio/ToolForm/DbObjectViewer/DbViewViewer.designer.cs @@ -0,0 +1,168 @@ +namespace Kalman.Studio +{ + partial class DbViewViewer + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.textEditorControl1 = new ICSharpCode.TextEditor.TextEditorControl(); + this.dgv = new System.Windows.Forms.DataGridView(); + this.FieldName = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.NativeType = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.Length = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.Precision = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.Scale = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.DataType = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.Comment = new System.Windows.Forms.DataGridViewTextBoxColumn(); + ((System.ComponentModel.ISupportInitialize)(this.dgv)).BeginInit(); + this.SuspendLayout(); + // + // textEditorControl1 + // + this.textEditorControl1.Dock = System.Windows.Forms.DockStyle.Top; + this.textEditorControl1.IsReadOnly = false; + this.textEditorControl1.Location = new System.Drawing.Point(0, 0); + this.textEditorControl1.Name = "textEditorControl1"; + this.textEditorControl1.Size = new System.Drawing.Size(792, 357); + this.textEditorControl1.TabIndex = 3; + this.textEditorControl1.Text = "textEditorControl1"; + // + // dgv + // + this.dgv.AllowUserToAddRows = false; + this.dgv.AllowUserToDeleteRows = false; + this.dgv.AllowUserToResizeRows = false; + this.dgv.BackgroundColor = System.Drawing.SystemColors.Window; + this.dgv.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.dgv.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { + this.FieldName, + this.NativeType, + this.Length, + this.Precision, + this.Scale, + this.DataType, + this.Comment}); + this.dgv.Dock = System.Windows.Forms.DockStyle.Fill; + this.dgv.Location = new System.Drawing.Point(0, 357); + this.dgv.MultiSelect = false; + this.dgv.Name = "dgv"; + this.dgv.RowHeadersVisible = false; + this.dgv.RowTemplate.Height = 23; + this.dgv.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.CellSelect; + this.dgv.Size = new System.Drawing.Size(792, 216); + this.dgv.TabIndex = 4; + // + // FieldName + // + this.FieldName.DataPropertyName = "Name"; + this.FieldName.Frozen = true; + this.FieldName.HeaderText = "字段名"; + this.FieldName.MaxInputLength = 100; + this.FieldName.Name = "FieldName"; + this.FieldName.Width = 150; + // + // NativeType + // + this.NativeType.DataPropertyName = "NativeType"; + this.NativeType.Frozen = true; + this.NativeType.HeaderText = "原生类型"; + this.NativeType.MaxInputLength = 200; + this.NativeType.Name = "NativeType"; + this.NativeType.ToolTipText = "对应数据库定义的原生类型"; + this.NativeType.Width = 150; + // + // Length + // + this.Length.DataPropertyName = "Length"; + this.Length.Frozen = true; + this.Length.HeaderText = "长度"; + this.Length.MinimumWidth = 40; + this.Length.Name = "Length"; + this.Length.Width = 40; + // + // Precision + // + this.Precision.DataPropertyName = "Precision"; + this.Precision.Frozen = true; + this.Precision.HeaderText = "精度"; + this.Precision.MinimumWidth = 40; + this.Precision.Name = "Precision"; + this.Precision.Width = 40; + // + // Scale + // + this.Scale.DataPropertyName = "Scale"; + this.Scale.Frozen = true; + this.Scale.HeaderText = "小数"; + this.Scale.MinimumWidth = 40; + this.Scale.Name = "Scale"; + this.Scale.ToolTipText = "小数位数"; + this.Scale.Width = 40; + // + // DataType + // + this.DataType.DataPropertyName = "DataType"; + this.DataType.HeaderText = "转换类型"; + this.DataType.MinimumWidth = 100; + this.DataType.Name = "DataType"; + this.DataType.ToolTipText = "特定数据库中定义的数据类型对应的.Net Framework类型"; + // + // Comment + // + this.Comment.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; + this.Comment.DataPropertyName = "Comment"; + this.Comment.HeaderText = "注释"; + this.Comment.Name = "Comment"; + // + // DbViewViewer + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(792, 573); + this.Controls.Add(this.dgv); + this.Controls.Add(this.textEditorControl1); + this.Name = "DbViewViewer"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "DbViewViewer"; + this.Load += new System.EventHandler(this.DbViewViewer_Load); + ((System.ComponentModel.ISupportInitialize)(this.dgv)).EndInit(); + this.ResumeLayout(false); + + } + + #endregion + + private ICSharpCode.TextEditor.TextEditorControl textEditorControl1; + private System.Windows.Forms.DataGridView dgv; + private System.Windows.Forms.DataGridViewTextBoxColumn FieldName; + private System.Windows.Forms.DataGridViewTextBoxColumn NativeType; + private System.Windows.Forms.DataGridViewTextBoxColumn Length; + private System.Windows.Forms.DataGridViewTextBoxColumn Precision; + private System.Windows.Forms.DataGridViewTextBoxColumn Scale; + private System.Windows.Forms.DataGridViewTextBoxColumn DataType; + private System.Windows.Forms.DataGridViewTextBoxColumn Comment; + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/ToolForm/DbObjectViewer/DbViewViewer.resx b/src/Kalman.Studio/ToolForm/DbObjectViewer/DbViewViewer.resx new file mode 100644 index 0000000..59f8f9d --- /dev/null +++ b/src/Kalman.Studio/ToolForm/DbObjectViewer/DbViewViewer.resx @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + \ No newline at end of file diff --git a/src/Kalman.Studio/ToolForm/DbSchemaViewer.cs b/src/Kalman.Studio/ToolForm/DbSchemaViewer.cs new file mode 100644 index 0000000..3bdd9ee --- /dev/null +++ b/src/Kalman.Studio/ToolForm/DbSchemaViewer.cs @@ -0,0 +1,77 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using System.Configuration; +using System.Data.Common; +using System.Data.SqlClient; +using WeifenLuo.WinFormsUI.Docking; +using Kalman.Data; + +namespace Kalman.Studio +{ + public partial class DbSchemaViewer : DockableForm + { + public DbSchemaViewer() + { + InitializeComponent(); + } + + private void DbSchemaViewer_Load(object sender, EventArgs e) + { + foreach (ConnectionStringSettings css in ConfigurationManager.ConnectionStrings) + { + cbConnectionStrings.Items.Add(css.Name); + } + + cbSchemaName.DataSource = new string[]{ + "MetaDataCollections", + "Databases", + "Catalogs", + "Users", + "Tables", + "Columns", + "Views", + "ViewColumns", + "Procedures", + "ProcedureParameters", + "Indexes", + "IndexColumns", + "ForeignKeys", + "UserDefinedTypes", + "StructuredTypeMembers", + "DataSourceInformation", + "DataTypes", + "Restrictions", + "ReservedWords" + }; + } + + private void btnQuery_Click(object sender, EventArgs e) + { + if (cbConnectionStrings.SelectedItem == null) return; + string cnName = cbConnectionStrings.SelectedItem.ToString(); + + DbSchema schema = DbSchemaFactory.Create(cnName); + string schemaName = cbSchemaName.SelectedItem == null ? cbSchemaName.Text : cbSchemaName.SelectedItem.ToString(); + string s = txtRestrictions.Text; + + DataTable dt; + if (s == string.Empty) + { + dt = schema.GetSchema(schemaName); + } + else + { + string[] restrictions = s.Split(','); + dt = schema.GetSchema(schemaName,restrictions); + } + + gridView.DataSource = dt; + } + } +} diff --git a/src/Kalman.Studio/ToolForm/DbSchemaViewer.designer.cs b/src/Kalman.Studio/ToolForm/DbSchemaViewer.designer.cs new file mode 100644 index 0000000..02138e2 --- /dev/null +++ b/src/Kalman.Studio/ToolForm/DbSchemaViewer.designer.cs @@ -0,0 +1,184 @@ +namespace Kalman.Studio +{ + partial class DbSchemaViewer + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.label1 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.label3 = new System.Windows.Forms.Label(); + this.txtRestrictions = new System.Windows.Forms.TextBox(); + this.cbConnectionStrings = new System.Windows.Forms.ComboBox(); + this.gridView = new System.Windows.Forms.DataGridView(); + this.cbSchemaName = new System.Windows.Forms.ComboBox(); + this.btnQuery = new System.Windows.Forms.Button(); + this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); + this.panel1 = new System.Windows.Forms.Panel(); + ((System.ComponentModel.ISupportInitialize)(this.gridView)).BeginInit(); + this.tableLayoutPanel1.SuspendLayout(); + this.panel1.SuspendLayout(); + this.SuspendLayout(); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(3, 13); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(89, 12); + this.label1.TabIndex = 0; + this.label1.Text = "数据库连接名称"; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(312, 13); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(89, 12); + this.label2.TabIndex = 1; + this.label2.Text = "数据库架构名称"; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(3, 38); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(101, 12); + this.label3.TabIndex = 2; + this.label3.Text = "限制值[逗号分隔]"; + // + // txtRestrictions + // + this.txtRestrictions.Location = new System.Drawing.Point(106, 34); + this.txtRestrictions.Name = "txtRestrictions"; + this.txtRestrictions.Size = new System.Drawing.Size(419, 21); + this.txtRestrictions.TabIndex = 3; + // + // cbConnectionStrings + // + this.cbConnectionStrings.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.cbConnectionStrings.FormattingEnabled = true; + this.cbConnectionStrings.Location = new System.Drawing.Point(106, 9); + this.cbConnectionStrings.Name = "cbConnectionStrings"; + this.cbConnectionStrings.Size = new System.Drawing.Size(200, 20); + this.cbConnectionStrings.TabIndex = 4; + // + // gridView + // + this.gridView.AllowUserToAddRows = false; + this.gridView.AllowUserToDeleteRows = false; + this.gridView.AllowUserToResizeRows = false; + this.gridView.BackgroundColor = System.Drawing.SystemColors.Window; + this.gridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.gridView.Dock = System.Windows.Forms.DockStyle.Fill; + this.gridView.Location = new System.Drawing.Point(3, 73); + this.gridView.Name = "gridView"; + this.gridView.RowTemplate.Height = 23; + this.gridView.Size = new System.Drawing.Size(633, 370); + this.gridView.TabIndex = 5; + // + // cbSchemaName + // + this.cbSchemaName.FormattingEnabled = true; + this.cbSchemaName.Location = new System.Drawing.Point(407, 9); + this.cbSchemaName.Name = "cbSchemaName"; + this.cbSchemaName.Size = new System.Drawing.Size(200, 20); + this.cbSchemaName.TabIndex = 6; + // + // btnQuery + // + this.btnQuery.Location = new System.Drawing.Point(532, 33); + this.btnQuery.Name = "btnQuery"; + this.btnQuery.Size = new System.Drawing.Size(75, 23); + this.btnQuery.TabIndex = 7; + this.btnQuery.Text = "查询"; + this.btnQuery.UseVisualStyleBackColor = true; + this.btnQuery.Click += new System.EventHandler(this.btnQuery_Click); + // + // tableLayoutPanel1 + // + this.tableLayoutPanel1.ColumnCount = 1; + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel1.Controls.Add(this.gridView, 0, 1); + this.tableLayoutPanel1.Controls.Add(this.panel1, 0, 0); + this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanel1.Location = new System.Drawing.Point(5, 5); + this.tableLayoutPanel1.Name = "tableLayoutPanel1"; + this.tableLayoutPanel1.RowCount = 2; + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 70F)); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.Size = new System.Drawing.Size(639, 443); + this.tableLayoutPanel1.TabIndex = 8; + // + // panel1 + // + this.panel1.Controls.Add(this.label3); + this.panel1.Controls.Add(this.btnQuery); + this.panel1.Controls.Add(this.label1); + this.panel1.Controls.Add(this.cbSchemaName); + this.panel1.Controls.Add(this.label2); + this.panel1.Controls.Add(this.cbConnectionStrings); + this.panel1.Controls.Add(this.txtRestrictions); + this.panel1.Location = new System.Drawing.Point(3, 3); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(633, 64); + this.panel1.TabIndex = 9; + // + // DbSchemaViewer + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(649, 453); + this.Controls.Add(this.tableLayoutPanel1); + this.HideOnClose = true; + this.Name = "DbSchemaViewer"; + this.Padding = new System.Windows.Forms.Padding(5); + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "数据库架构信息查看器"; + this.Load += new System.EventHandler(this.DbSchemaViewer_Load); + ((System.ComponentModel.ISupportInitialize)(this.gridView)).EndInit(); + this.tableLayoutPanel1.ResumeLayout(false); + this.panel1.ResumeLayout(false); + this.panel1.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.TextBox txtRestrictions; + private System.Windows.Forms.ComboBox cbConnectionStrings; + private System.Windows.Forms.DataGridView gridView; + private System.Windows.Forms.ComboBox cbSchemaName; + private System.Windows.Forms.Button btnQuery; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; + private System.Windows.Forms.Panel panel1; + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/ToolForm/DbSchemaViewer.resx b/src/Kalman.Studio/ToolForm/DbSchemaViewer.resx new file mode 100644 index 0000000..19dc0dd --- /dev/null +++ b/src/Kalman.Studio/ToolForm/DbSchemaViewer.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/Kalman.Studio/ToolForm/IISLogParser/IISLogExportToDB.cs b/src/Kalman.Studio/ToolForm/IISLogParser/IISLogExportToDB.cs new file mode 100644 index 0000000..2c7c896 --- /dev/null +++ b/src/Kalman.Studio/ToolForm/IISLogParser/IISLogExportToDB.cs @@ -0,0 +1,134 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using System.Data.SqlClient; +using Kalman.IISLogParser; +using System.Threading; +using System.Configuration; + +namespace Kalman.Studio +{ + public partial class IISLogExportToDB : Form + { + IList logList; + int total = 0; + int batch = 10; + + public IISLogExportToDB(IList list) + { + InitializeComponent(); + logList = list; + total = list.Count; + } + + private void IISLogExportToDB_Load(object sender, EventArgs e) + { + try + { + txtConnectionString.Text = ConfigurationManager.ConnectionStrings["IISLog"].ConnectionString; + } + catch { } + } + + public void Export() + { + backgroundWorker1.RunWorkerAsync(); + } + + private void DoExport() + { + string sql = string.Empty; + try + { + using (SqlConnection cn = new SqlConnection(txtConnectionString.Text.Trim())) + { + cn.Open(); + + int n = 0; + int remainder = total % batch; + if (remainder != 0) n = total / batch + 1; + else n = total / batch; + + for (int i = 0; i < n; i++) + { + IList temp = new List(); + int begin = i * batch; + int end = (i + 1) * batch; + if (i == n - 1) end = total; + + for (; begin < end; begin++) + { + temp.Add(logList[begin]); + } + + sql = GetBatchInsertSql(temp); + //ExcuteBatchInsertSql(sql); + + int p = (i + 1) * 100 / n; + backgroundWorker1.ReportProgress(p); + + + SqlCommand cmd = new SqlCommand(sql, cn); + cmd.ExecuteNonQuery(); + + Thread.Sleep(1); + } + } + } + catch (Exception ex) + { + //MessageBox.Show(ex.ToString()); + ErrorInfo ei = new ErrorInfo(ex, sql); + ei.Show(); + } + + } + + string GetBatchInsertSql(IList list) + { + StringBuilder sb = new StringBuilder(); + string tableName = txtTableName.Text.Trim(); + foreach (LogRecord lr in list) + { + string s = string.Format(@"INSERT INTO {0} ([LogTime],[Method],[ClientIP],[ClientIPLocation],[Status],[SubStatus],[Win32Status],[ReceiveBytes],[SendBytes],[UriStem],[Referer],[UriStemAlias],[RefererAlias],[UserAgentAlias],[UserAgent]) VALUES ('{1}','{2}','{3}','{4}','{5}','{6}','{7}','{8}','{9}','{10}','{11}','{12}','{13}','{14}','{15}');", + tableName, lr.LogTime, lr.Method, lr.ClientIP, lr.ClientIPLocation, lr.Status, lr.SubStatus, lr.Win32Status, lr.ReceiveBytes, lr.SendBytes, lr.UriStem, lr.Referer, lr.UriStemAlias, lr.RefererAlias, lr.UserAgentAlias, lr.UserAgent); + sb.AppendLine(s); + } + return sb.ToString(); + } + + private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) + { + DoExport(); + } + + private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) + { + progressBar1.Value = e.ProgressPercentage; + lblMsg.Text = string.Format("正在导出数据,已完成:{0}%", e.ProgressPercentage); + } + + private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) + { + MessageBox.Show("数据导入完成"); + this.Close(); + } + + private void btnExport_Click(object sender, EventArgs e) + { + Export(); + } + + private void btnReturn_Click(object sender, EventArgs e) + { + this.Close(); + } + + + } +} diff --git a/src/Kalman.Studio/ToolForm/IISLogParser/IISLogExportToDB.designer.cs b/src/Kalman.Studio/ToolForm/IISLogParser/IISLogExportToDB.designer.cs new file mode 100644 index 0000000..e70f281 --- /dev/null +++ b/src/Kalman.Studio/ToolForm/IISLogParser/IISLogExportToDB.designer.cs @@ -0,0 +1,159 @@ +namespace Kalman.Studio +{ + partial class IISLogExportToDB + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.label1 = new System.Windows.Forms.Label(); + this.txtConnectionString = new System.Windows.Forms.TextBox(); + this.progressBar1 = new System.Windows.Forms.ProgressBar(); + this.lblMsg = new System.Windows.Forms.Label(); + this.btnExport = new System.Windows.Forms.Button(); + this.btnReturn = new System.Windows.Forms.Button(); + this.label3 = new System.Windows.Forms.Label(); + this.txtTableName = new System.Windows.Forms.TextBox(); + this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker(); + this.SuspendLayout(); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(5, 13); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(101, 12); + this.label1.TabIndex = 0; + this.label1.Text = "数据库连接字符串"; + // + // txtConnectionString + // + this.txtConnectionString.Location = new System.Drawing.Point(4, 33); + this.txtConnectionString.Name = "txtConnectionString"; + this.txtConnectionString.Size = new System.Drawing.Size(412, 21); + this.txtConnectionString.TabIndex = 1; + this.txtConnectionString.Text = "Data Source=.;Initial Catalog=Test;Integrated Security=True"; + // + // progressBar1 + // + this.progressBar1.Location = new System.Drawing.Point(6, 82); + this.progressBar1.Name = "progressBar1"; + this.progressBar1.Size = new System.Drawing.Size(410, 23); + this.progressBar1.TabIndex = 2; + // + // lblMsg + // + this.lblMsg.AutoSize = true; + this.lblMsg.Location = new System.Drawing.Point(5, 62); + this.lblMsg.Name = "lblMsg"; + this.lblMsg.Size = new System.Drawing.Size(77, 12); + this.lblMsg.TabIndex = 3; + this.lblMsg.Text = "数据导出进度"; + // + // btnExport + // + this.btnExport.Location = new System.Drawing.Point(248, 114); + this.btnExport.Name = "btnExport"; + this.btnExport.Size = new System.Drawing.Size(75, 23); + this.btnExport.TabIndex = 4; + this.btnExport.Text = "导出"; + this.btnExport.UseVisualStyleBackColor = true; + this.btnExport.Click += new System.EventHandler(this.btnExport_Click); + // + // btnReturn + // + this.btnReturn.Location = new System.Drawing.Point(341, 114); + this.btnReturn.Name = "btnReturn"; + this.btnReturn.Size = new System.Drawing.Size(75, 23); + this.btnReturn.TabIndex = 5; + this.btnReturn.Text = "返回"; + this.btnReturn.UseVisualStyleBackColor = true; + this.btnReturn.Click += new System.EventHandler(this.btnReturn_Click); + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(5, 119); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(53, 12); + this.label3.TabIndex = 6; + this.label3.Text = "目标表名"; + // + // txtTableName + // + this.txtTableName.Location = new System.Drawing.Point(67, 115); + this.txtTableName.Name = "txtTableName"; + this.txtTableName.Size = new System.Drawing.Size(137, 21); + this.txtTableName.TabIndex = 7; + this.txtTableName.Text = "dbo.IISLogData"; + // + // backgroundWorker1 + // + this.backgroundWorker1.WorkerReportsProgress = true; + this.backgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker1_DoWork); + this.backgroundWorker1.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted); + this.backgroundWorker1.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.backgroundWorker1_ProgressChanged); + // + // IISLogExportToDB + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(425, 145); + this.Controls.Add(this.txtTableName); + this.Controls.Add(this.label3); + this.Controls.Add(this.btnReturn); + this.Controls.Add(this.btnExport); + this.Controls.Add(this.lblMsg); + this.Controls.Add(this.progressBar1); + this.Controls.Add(this.txtConnectionString); + this.Controls.Add(this.label1); + this.MaximizeBox = false; + this.MaximumSize = new System.Drawing.Size(433, 172); + this.MinimumSize = new System.Drawing.Size(433, 172); + this.Name = "IISLogExportToDB"; + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "日志数据导出到数据库(仅支持SQLServer)"; + this.Load += new System.EventHandler(this.IISLogExportToDB_Load); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label label1; + private System.Windows.Forms.TextBox txtConnectionString; + private System.Windows.Forms.ProgressBar progressBar1; + private System.Windows.Forms.Label lblMsg; + private System.Windows.Forms.Button btnExport; + private System.Windows.Forms.Button btnReturn; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.TextBox txtTableName; + private System.ComponentModel.BackgroundWorker backgroundWorker1; + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/ToolForm/IISLogParser/IISLogExportToDB.resx b/src/Kalman.Studio/ToolForm/IISLogParser/IISLogExportToDB.resx new file mode 100644 index 0000000..c5b00c8 --- /dev/null +++ b/src/Kalman.Studio/ToolForm/IISLogParser/IISLogExportToDB.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + \ No newline at end of file diff --git a/src/Kalman.Studio/ToolForm/IISLogParser/IISLogParseCondition.cs b/src/Kalman.Studio/ToolForm/IISLogParser/IISLogParseCondition.cs new file mode 100644 index 0000000..dc25d4b --- /dev/null +++ b/src/Kalman.Studio/ToolForm/IISLogParser/IISLogParseCondition.cs @@ -0,0 +1,205 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using Kalman.IISLogParser; +using System.IO; +using WeifenLuo.WinFormsUI.Docking; + +namespace Kalman.Studio +{ + public partial class IISLogParseCondition : Form + { + LogParseFilter filter = new LogParseFilter(); + DockPanel dockPanel; + IISLogParser parser = null; + + public IISLogParseCondition(DockPanel panel) + { + InitializeComponent(); + dockPanel = panel; + } + + private void IISLogParseCondition_Load(object sender, EventArgs e) + { + } + + void BindFileList() + { + listBoxLogFiles.Items.Clear(); + foreach (string item in filter.FileList) + { + listBoxLogFiles.Items.Add(item); + } + } + + private void btnAddFile_Click(object sender, EventArgs e) + { + if (openFileDialog1.ShowDialog() == DialogResult.OK) + { + foreach (string item in openFileDialog1.FileNames) + { + filter.AddFile(item); + } + BindFileList(); + } + } + + private void btnAddFolder_Click(object sender, EventArgs e) + { + if (folderBrowserDialog1.ShowDialog() == DialogResult.OK) + { + string[] files = Directory.GetFiles(folderBrowserDialog1.SelectedPath); + filter.AddFiles(files); + BindFileList(); + } + } + + private void btnRemoveFile_Click(object sender, EventArgs e) + { + if (listBoxLogFiles.SelectedIndex == -1) return; + listBoxLogFiles.Items.Remove(listBoxLogFiles.SelectedItem); + filter.FileList.Remove(listBoxLogFiles.SelectedItem.ToString()); + } + + private void btnRemoveAll_Click(object sender, EventArgs e) + { + listBoxLogFiles.Items.Clear(); + filter.FileList.Clear(); + } + + private void btnOK_Click(object sender, EventArgs e) + { + if (rbtnAll.Checked) filter.Method = 0; + if (rbtnGet.Checked) filter.Method = 1; + if (rbtnPost.Checked) filter.Method = 2; + + if (cbAllowQueryByIP.Checked) + { + filter.IPList.Clear(); + filter.AllowQueryByIP = true; + string[] ss = txtIPList.Text.Trim().Split(','); + foreach (string s in ss) + { + filter.AddIP(s.Trim()); + } + } + else + { + filter.AllowQueryByIP = false; + } + + if (cbAllowQueryByIPLocation.Checked) + { + filter.IPLocationList.Clear(); + filter.AllowQueryByIPLocation = true; + string[] ss = txtIPLocationList.Text.Trim().Split(','); + foreach (string s in ss) + { + filter.AddIPLocation(s.Trim()); + } + } + else + { + filter.AllowQueryByIPLocation = false; + } + + if (cbAllowQueryByReferer.Checked) + { + filter.RefererList.Clear(); + filter.AllowQueryByReferer = true; + string[] ss = txtRefererList.Text.Trim().ToLower().Split(','); + foreach (string s in ss) + { + filter.AddReferer(s.Trim()); + } + } + else + { + filter.AllowQueryByReferer = false; + } + + if (cbAllowQueryByStatus.Checked) + { + filter.StatusList.Clear(); + filter.AllowQueryByStatus = true; + string[] ss = txtStatusList.Text.Trim().Split(','); + foreach (string s in ss) + { + filter.AddStatus(s.Trim()); + } + } + else + { + filter.AllowQueryByStatus = false; + } + + if (cbAllowQueryByUri.Checked) + { + filter.UriList.Clear(); + filter.AllowQueryByUri = true; + string[] ss = txtUriList.Text.Trim().ToLower().Split(','); + foreach (string s in ss) + { + filter.AddUri(s.Trim()); + } + } + else + { + filter.AllowQueryByUri = false; + } + + if (cbAllowQueryByUserAgent.Checked) + { + filter.UserAgentList.Clear(); + filter.AllowQueryByUserAgent = true; + string[] ss = txtUserAgentList.Text.Trim().Split(','); + foreach (string s in ss) + { + filter.AddUserAgent(s.Trim()); + } + } + else + { + filter.AllowQueryByUserAgent = false; + } + + if (cbAllowQueryByTime.Checked) + { + filter.AllowQueryByTime = true; + filter.BeginTime = dtpBeginTime.Value; + filter.EndTime = dtpEndTime.Value; + } + else + { + filter.AllowQueryByTime = false; + } + + if (parser == null) + { + parser = new IISLogParser(); + parser.Show(dockPanel); + } + parser.Activate(); + parser.ParseLog(filter); + } + + private void btnExit_Click(object sender, EventArgs e) + { + this.Close(); + } + + protected override void OnClosing(CancelEventArgs e) + { + if (parser != null) + { + parser.Close(); + } + base.OnClosing(e); + } + } +} diff --git a/src/Kalman.Studio/ToolForm/IISLogParser/IISLogParseCondition.designer.cs b/src/Kalman.Studio/ToolForm/IISLogParser/IISLogParseCondition.designer.cs new file mode 100644 index 0000000..b410cdf --- /dev/null +++ b/src/Kalman.Studio/ToolForm/IISLogParser/IISLogParseCondition.designer.cs @@ -0,0 +1,534 @@ +namespace Kalman.Studio +{ + partial class IISLogParseCondition + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.btnRemoveAll = new System.Windows.Forms.Button(); + this.btnRemoveFile = new System.Windows.Forms.Button(); + this.btnAddFolder = new System.Windows.Forms.Button(); + this.btnAddFile = new System.Windows.Forms.Button(); + this.listBoxLogFiles = new System.Windows.Forms.ListBox(); + this.groupBox2 = new System.Windows.Forms.GroupBox(); + this.cbAllowQueryByTime = new System.Windows.Forms.CheckBox(); + this.label2 = new System.Windows.Forms.Label(); + this.label1 = new System.Windows.Forms.Label(); + this.dtpEndTime = new System.Windows.Forms.DateTimePicker(); + this.dtpBeginTime = new System.Windows.Forms.DateTimePicker(); + this.groupBox3 = new System.Windows.Forms.GroupBox(); + this.cbAllowQueryByIP = new System.Windows.Forms.CheckBox(); + this.txtIPList = new System.Windows.Forms.TextBox(); + this.groupBox4 = new System.Windows.Forms.GroupBox(); + this.cbAllowQueryByIPLocation = new System.Windows.Forms.CheckBox(); + this.txtIPLocationList = new System.Windows.Forms.TextBox(); + this.cbAllowQueryByUserAgent = new System.Windows.Forms.CheckBox(); + this.txtUserAgentList = new System.Windows.Forms.TextBox(); + this.groupBox5 = new System.Windows.Forms.GroupBox(); + this.cbAllowQueryByUri = new System.Windows.Forms.CheckBox(); + this.txtUriList = new System.Windows.Forms.TextBox(); + this.groupBox6 = new System.Windows.Forms.GroupBox(); + this.groupBox7 = new System.Windows.Forms.GroupBox(); + this.cbAllowQueryByReferer = new System.Windows.Forms.CheckBox(); + this.txtRefererList = new System.Windows.Forms.TextBox(); + this.btnExit = new System.Windows.Forms.Button(); + this.folderBrowserDialog1 = new System.Windows.Forms.FolderBrowserDialog(); + this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog(); + this.groupBox8 = new System.Windows.Forms.GroupBox(); + this.cbAllowQueryByStatus = new System.Windows.Forms.CheckBox(); + this.txtStatusList = new System.Windows.Forms.TextBox(); + this.btnOK = new System.Windows.Forms.Button(); + this.label3 = new System.Windows.Forms.Label(); + this.rbtnAll = new System.Windows.Forms.RadioButton(); + this.rbtnGet = new System.Windows.Forms.RadioButton(); + this.rbtnPost = new System.Windows.Forms.RadioButton(); + this.groupBox1.SuspendLayout(); + this.groupBox2.SuspendLayout(); + this.groupBox3.SuspendLayout(); + this.groupBox4.SuspendLayout(); + this.groupBox5.SuspendLayout(); + this.groupBox6.SuspendLayout(); + this.groupBox7.SuspendLayout(); + this.groupBox8.SuspendLayout(); + this.SuspendLayout(); + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.btnRemoveAll); + this.groupBox1.Controls.Add(this.btnRemoveFile); + this.groupBox1.Controls.Add(this.btnAddFolder); + this.groupBox1.Controls.Add(this.btnAddFile); + this.groupBox1.Controls.Add(this.listBoxLogFiles); + this.groupBox1.Location = new System.Drawing.Point(5, 5); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(781, 132); + this.groupBox1.TabIndex = 1; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "选择日志文件"; + // + // btnRemoveAll + // + this.btnRemoveAll.Location = new System.Drawing.Point(700, 100); + this.btnRemoveAll.Name = "btnRemoveAll"; + this.btnRemoveAll.Size = new System.Drawing.Size(75, 23); + this.btnRemoveAll.TabIndex = 4; + this.btnRemoveAll.Text = "全部移除"; + this.btnRemoveAll.UseVisualStyleBackColor = true; + this.btnRemoveAll.Click += new System.EventHandler(this.btnRemoveAll_Click); + // + // btnRemoveFile + // + this.btnRemoveFile.Location = new System.Drawing.Point(700, 71); + this.btnRemoveFile.Name = "btnRemoveFile"; + this.btnRemoveFile.Size = new System.Drawing.Size(75, 23); + this.btnRemoveFile.TabIndex = 3; + this.btnRemoveFile.Text = "移除文件"; + this.btnRemoveFile.UseVisualStyleBackColor = true; + this.btnRemoveFile.Click += new System.EventHandler(this.btnRemoveFile_Click); + // + // btnAddFolder + // + this.btnAddFolder.Location = new System.Drawing.Point(700, 42); + this.btnAddFolder.Name = "btnAddFolder"; + this.btnAddFolder.Size = new System.Drawing.Size(75, 23); + this.btnAddFolder.TabIndex = 2; + this.btnAddFolder.Text = "添加目录"; + this.btnAddFolder.UseVisualStyleBackColor = true; + this.btnAddFolder.Click += new System.EventHandler(this.btnAddFolder_Click); + // + // btnAddFile + // + this.btnAddFile.Location = new System.Drawing.Point(700, 13); + this.btnAddFile.Name = "btnAddFile"; + this.btnAddFile.Size = new System.Drawing.Size(75, 23); + this.btnAddFile.TabIndex = 1; + this.btnAddFile.Text = "添加文件"; + this.btnAddFile.UseVisualStyleBackColor = true; + this.btnAddFile.Click += new System.EventHandler(this.btnAddFile_Click); + // + // listBoxLogFiles + // + this.listBoxLogFiles.FormattingEnabled = true; + this.listBoxLogFiles.ItemHeight = 12; + this.listBoxLogFiles.Location = new System.Drawing.Point(6, 13); + this.listBoxLogFiles.Name = "listBoxLogFiles"; + this.listBoxLogFiles.Size = new System.Drawing.Size(688, 112); + this.listBoxLogFiles.TabIndex = 0; + // + // groupBox2 + // + this.groupBox2.Controls.Add(this.cbAllowQueryByTime); + this.groupBox2.Controls.Add(this.label2); + this.groupBox2.Controls.Add(this.label1); + this.groupBox2.Controls.Add(this.dtpEndTime); + this.groupBox2.Controls.Add(this.dtpBeginTime); + this.groupBox2.Location = new System.Drawing.Point(5, 143); + this.groupBox2.Name = "groupBox2"; + this.groupBox2.Size = new System.Drawing.Size(781, 52); + this.groupBox2.TabIndex = 2; + this.groupBox2.TabStop = false; + this.groupBox2.Text = "选择时间范围"; + // + // cbAllowQueryByTime + // + this.cbAllowQueryByTime.AutoSize = true; + this.cbAllowQueryByTime.Location = new System.Drawing.Point(691, 23); + this.cbAllowQueryByTime.Name = "cbAllowQueryByTime"; + this.cbAllowQueryByTime.Size = new System.Drawing.Size(84, 16); + this.cbAllowQueryByTime.TabIndex = 4; + this.cbAllowQueryByTime.Text = "启用该条件"; + this.cbAllowQueryByTime.UseVisualStyleBackColor = true; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(297, 25); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(53, 12); + this.label2.TabIndex = 3; + this.label2.Text = "结束时间"; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(7, 25); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(53, 12); + this.label1.TabIndex = 2; + this.label1.Text = "开始时间"; + // + // dtpEndTime + // + this.dtpEndTime.CustomFormat = "yyyy-MM-dd HH:mm:ss"; + this.dtpEndTime.Format = System.Windows.Forms.DateTimePickerFormat.Custom; + this.dtpEndTime.Location = new System.Drawing.Point(391, 21); + this.dtpEndTime.Name = "dtpEndTime"; + this.dtpEndTime.Size = new System.Drawing.Size(155, 21); + this.dtpEndTime.TabIndex = 1; + // + // dtpBeginTime + // + this.dtpBeginTime.CustomFormat = "yyyy-MM-dd HH:mm:ss"; + this.dtpBeginTime.Format = System.Windows.Forms.DateTimePickerFormat.Custom; + this.dtpBeginTime.Location = new System.Drawing.Point(101, 21); + this.dtpBeginTime.Name = "dtpBeginTime"; + this.dtpBeginTime.Size = new System.Drawing.Size(155, 21); + this.dtpBeginTime.TabIndex = 0; + // + // groupBox3 + // + this.groupBox3.Controls.Add(this.cbAllowQueryByIP); + this.groupBox3.Controls.Add(this.txtIPList); + this.groupBox3.Location = new System.Drawing.Point(5, 201); + this.groupBox3.Name = "groupBox3"; + this.groupBox3.Size = new System.Drawing.Size(781, 45); + this.groupBox3.TabIndex = 3; + this.groupBox3.TabStop = false; + this.groupBox3.Text = "客户端IP[多个IP之间用\",\"隔开]"; + // + // cbAllowQueryByIP + // + this.cbAllowQueryByIP.AutoSize = true; + this.cbAllowQueryByIP.Location = new System.Drawing.Point(691, 20); + this.cbAllowQueryByIP.Name = "cbAllowQueryByIP"; + this.cbAllowQueryByIP.Size = new System.Drawing.Size(84, 16); + this.cbAllowQueryByIP.TabIndex = 4; + this.cbAllowQueryByIP.Text = "启用该条件"; + this.cbAllowQueryByIP.UseVisualStyleBackColor = true; + // + // txtIPList + // + this.txtIPList.Location = new System.Drawing.Point(8, 17); + this.txtIPList.Multiline = true; + this.txtIPList.Name = "txtIPList"; + this.txtIPList.Size = new System.Drawing.Size(672, 23); + this.txtIPList.TabIndex = 0; + // + // groupBox4 + // + this.groupBox4.Controls.Add(this.cbAllowQueryByIPLocation); + this.groupBox4.Controls.Add(this.txtIPLocationList); + this.groupBox4.Location = new System.Drawing.Point(5, 252); + this.groupBox4.Name = "groupBox4"; + this.groupBox4.Size = new System.Drawing.Size(781, 45); + this.groupBox4.TabIndex = 4; + this.groupBox4.TabStop = false; + this.groupBox4.Text = "客户端IP归属地[多个地址之间用\",\"隔开],部分匹配"; + // + // cbAllowQueryByIPLocation + // + this.cbAllowQueryByIPLocation.AutoSize = true; + this.cbAllowQueryByIPLocation.Location = new System.Drawing.Point(691, 20); + this.cbAllowQueryByIPLocation.Name = "cbAllowQueryByIPLocation"; + this.cbAllowQueryByIPLocation.Size = new System.Drawing.Size(84, 16); + this.cbAllowQueryByIPLocation.TabIndex = 4; + this.cbAllowQueryByIPLocation.Text = "启用该条件"; + this.cbAllowQueryByIPLocation.UseVisualStyleBackColor = true; + // + // txtIPLocationList + // + this.txtIPLocationList.Location = new System.Drawing.Point(8, 17); + this.txtIPLocationList.Multiline = true; + this.txtIPLocationList.Name = "txtIPLocationList"; + this.txtIPLocationList.Size = new System.Drawing.Size(672, 23); + this.txtIPLocationList.TabIndex = 0; + // + // cbAllowQueryByUserAgent + // + this.cbAllowQueryByUserAgent.AutoSize = true; + this.cbAllowQueryByUserAgent.Location = new System.Drawing.Point(691, 20); + this.cbAllowQueryByUserAgent.Name = "cbAllowQueryByUserAgent"; + this.cbAllowQueryByUserAgent.Size = new System.Drawing.Size(84, 16); + this.cbAllowQueryByUserAgent.TabIndex = 4; + this.cbAllowQueryByUserAgent.Text = "启用该条件"; + this.cbAllowQueryByUserAgent.UseVisualStyleBackColor = true; + // + // txtUserAgentList + // + this.txtUserAgentList.Location = new System.Drawing.Point(8, 17); + this.txtUserAgentList.Multiline = true; + this.txtUserAgentList.Name = "txtUserAgentList"; + this.txtUserAgentList.Size = new System.Drawing.Size(672, 23); + this.txtUserAgentList.TabIndex = 0; + // + // groupBox5 + // + this.groupBox5.Controls.Add(this.cbAllowQueryByUserAgent); + this.groupBox5.Controls.Add(this.txtUserAgentList); + this.groupBox5.Location = new System.Drawing.Point(5, 303); + this.groupBox5.Name = "groupBox5"; + this.groupBox5.Size = new System.Drawing.Size(781, 45); + this.groupBox5.TabIndex = 5; + this.groupBox5.TabStop = false; + this.groupBox5.Text = "用户代理[多条记录之间用\",\"隔开],部分匹配"; + // + // cbAllowQueryByUri + // + this.cbAllowQueryByUri.AutoSize = true; + this.cbAllowQueryByUri.Location = new System.Drawing.Point(691, 20); + this.cbAllowQueryByUri.Name = "cbAllowQueryByUri"; + this.cbAllowQueryByUri.Size = new System.Drawing.Size(84, 16); + this.cbAllowQueryByUri.TabIndex = 4; + this.cbAllowQueryByUri.Text = "启用该条件"; + this.cbAllowQueryByUri.UseVisualStyleBackColor = true; + // + // txtUriList + // + this.txtUriList.Location = new System.Drawing.Point(8, 17); + this.txtUriList.Multiline = true; + this.txtUriList.Name = "txtUriList"; + this.txtUriList.Size = new System.Drawing.Size(672, 23); + this.txtUriList.TabIndex = 0; + // + // groupBox6 + // + this.groupBox6.Controls.Add(this.cbAllowQueryByUri); + this.groupBox6.Controls.Add(this.txtUriList); + this.groupBox6.Location = new System.Drawing.Point(5, 354); + this.groupBox6.Name = "groupBox6"; + this.groupBox6.Size = new System.Drawing.Size(781, 45); + this.groupBox6.TabIndex = 6; + this.groupBox6.TabStop = false; + this.groupBox6.Text = "请求地址[多个地址之间用\",\"隔开,不区分大小写],模糊查询"; + // + // groupBox7 + // + this.groupBox7.Controls.Add(this.cbAllowQueryByReferer); + this.groupBox7.Controls.Add(this.txtRefererList); + this.groupBox7.Location = new System.Drawing.Point(5, 405); + this.groupBox7.Name = "groupBox7"; + this.groupBox7.Size = new System.Drawing.Size(781, 45); + this.groupBox7.TabIndex = 7; + this.groupBox7.TabStop = false; + this.groupBox7.Text = "引用地址[多个地址之间用\",\"隔开,不区分大小写],部分匹配"; + // + // cbAllowQueryByReferer + // + this.cbAllowQueryByReferer.AutoSize = true; + this.cbAllowQueryByReferer.Location = new System.Drawing.Point(691, 20); + this.cbAllowQueryByReferer.Name = "cbAllowQueryByReferer"; + this.cbAllowQueryByReferer.Size = new System.Drawing.Size(84, 16); + this.cbAllowQueryByReferer.TabIndex = 4; + this.cbAllowQueryByReferer.Text = "启用该条件"; + this.cbAllowQueryByReferer.UseVisualStyleBackColor = true; + // + // txtRefererList + // + this.txtRefererList.Location = new System.Drawing.Point(8, 17); + this.txtRefererList.Multiline = true; + this.txtRefererList.Name = "txtRefererList"; + this.txtRefererList.Size = new System.Drawing.Size(672, 23); + this.txtRefererList.TabIndex = 0; + // + // btnExit + // + this.btnExit.Location = new System.Drawing.Point(711, 507); + this.btnExit.Name = "btnExit"; + this.btnExit.Size = new System.Drawing.Size(75, 23); + this.btnExit.TabIndex = 9; + this.btnExit.Text = "退出"; + this.btnExit.UseVisualStyleBackColor = true; + this.btnExit.Click += new System.EventHandler(this.btnExit_Click); + // + // folderBrowserDialog1 + // + this.folderBrowserDialog1.RootFolder = System.Environment.SpecialFolder.MyComputer; + // + // openFileDialog1 + // + this.openFileDialog1.Filter = "IIS日志文件(*.log)|*.log|所有文件(*.*)|*.*"; + this.openFileDialog1.InitialDirectory = "C:\\WINDOWS\\system32\\LogFiles"; + this.openFileDialog1.Multiselect = true; + // + // groupBox8 + // + this.groupBox8.Controls.Add(this.cbAllowQueryByStatus); + this.groupBox8.Controls.Add(this.txtStatusList); + this.groupBox8.Location = new System.Drawing.Point(5, 456); + this.groupBox8.Name = "groupBox8"; + this.groupBox8.Size = new System.Drawing.Size(781, 45); + this.groupBox8.TabIndex = 10; + this.groupBox8.TabStop = false; + this.groupBox8.Text = "协议状态[多个状态之间用\",\"隔开]"; + // + // cbAllowQueryByStatus + // + this.cbAllowQueryByStatus.AutoSize = true; + this.cbAllowQueryByStatus.Location = new System.Drawing.Point(691, 20); + this.cbAllowQueryByStatus.Name = "cbAllowQueryByStatus"; + this.cbAllowQueryByStatus.Size = new System.Drawing.Size(84, 16); + this.cbAllowQueryByStatus.TabIndex = 4; + this.cbAllowQueryByStatus.Text = "启用该条件"; + this.cbAllowQueryByStatus.UseVisualStyleBackColor = true; + // + // txtStatusList + // + this.txtStatusList.Location = new System.Drawing.Point(8, 17); + this.txtStatusList.Multiline = true; + this.txtStatusList.Name = "txtStatusList"; + this.txtStatusList.Size = new System.Drawing.Size(672, 23); + this.txtStatusList.TabIndex = 0; + // + // btnOK + // + this.btnOK.Location = new System.Drawing.Point(624, 507); + this.btnOK.Name = "btnOK"; + this.btnOK.Size = new System.Drawing.Size(75, 23); + this.btnOK.TabIndex = 11; + this.btnOK.Text = "确定"; + this.btnOK.UseVisualStyleBackColor = true; + this.btnOK.Click += new System.EventHandler(this.btnOK_Click); + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(12, 512); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(29, 12); + this.label3.TabIndex = 12; + this.label3.Text = "方法"; + // + // rbtnAll + // + this.rbtnAll.AutoSize = true; + this.rbtnAll.Checked = true; + this.rbtnAll.Location = new System.Drawing.Point(65, 510); + this.rbtnAll.Name = "rbtnAll"; + this.rbtnAll.Size = new System.Drawing.Size(41, 16); + this.rbtnAll.TabIndex = 13; + this.rbtnAll.TabStop = true; + this.rbtnAll.Text = "All"; + this.rbtnAll.UseVisualStyleBackColor = true; + // + // rbtnGet + // + this.rbtnGet.AutoSize = true; + this.rbtnGet.Location = new System.Drawing.Point(128, 510); + this.rbtnGet.Name = "rbtnGet"; + this.rbtnGet.Size = new System.Drawing.Size(41, 16); + this.rbtnGet.TabIndex = 14; + this.rbtnGet.Text = "Get"; + this.rbtnGet.UseVisualStyleBackColor = true; + // + // rbtnPost + // + this.rbtnPost.AutoSize = true; + this.rbtnPost.Location = new System.Drawing.Point(191, 510); + this.rbtnPost.Name = "rbtnPost"; + this.rbtnPost.Size = new System.Drawing.Size(47, 16); + this.rbtnPost.TabIndex = 15; + this.rbtnPost.Text = "Post"; + this.rbtnPost.UseVisualStyleBackColor = true; + // + // IISLogParseCondition + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(792, 533); + this.Controls.Add(this.rbtnPost); + this.Controls.Add(this.rbtnGet); + this.Controls.Add(this.rbtnAll); + this.Controls.Add(this.label3); + this.Controls.Add(this.btnOK); + this.Controls.Add(this.groupBox8); + this.Controls.Add(this.btnExit); + this.Controls.Add(this.groupBox7); + this.Controls.Add(this.groupBox6); + this.Controls.Add(this.groupBox5); + this.Controls.Add(this.groupBox4); + this.Controls.Add(this.groupBox3); + this.Controls.Add(this.groupBox2); + this.Controls.Add(this.groupBox1); + this.MaximizeBox = false; + this.Name = "IISLogParseCondition"; + this.Padding = new System.Windows.Forms.Padding(3); + this.ShowIcon = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "选择日志解析条件"; + this.Load += new System.EventHandler(this.IISLogParseCondition_Load); + this.groupBox1.ResumeLayout(false); + this.groupBox2.ResumeLayout(false); + this.groupBox2.PerformLayout(); + this.groupBox3.ResumeLayout(false); + this.groupBox3.PerformLayout(); + this.groupBox4.ResumeLayout(false); + this.groupBox4.PerformLayout(); + this.groupBox5.ResumeLayout(false); + this.groupBox5.PerformLayout(); + this.groupBox6.ResumeLayout(false); + this.groupBox6.PerformLayout(); + this.groupBox7.ResumeLayout(false); + this.groupBox7.PerformLayout(); + this.groupBox8.ResumeLayout(false); + this.groupBox8.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.Button btnRemoveAll; + private System.Windows.Forms.Button btnRemoveFile; + private System.Windows.Forms.Button btnAddFolder; + private System.Windows.Forms.Button btnAddFile; + private System.Windows.Forms.ListBox listBoxLogFiles; + private System.Windows.Forms.GroupBox groupBox2; + private System.Windows.Forms.DateTimePicker dtpBeginTime; + private System.Windows.Forms.DateTimePicker dtpEndTime; + private System.Windows.Forms.CheckBox cbAllowQueryByTime; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.GroupBox groupBox3; + private System.Windows.Forms.TextBox txtIPList; + private System.Windows.Forms.CheckBox cbAllowQueryByIP; + private System.Windows.Forms.GroupBox groupBox4; + private System.Windows.Forms.CheckBox cbAllowQueryByIPLocation; + private System.Windows.Forms.TextBox txtIPLocationList; + private System.Windows.Forms.CheckBox cbAllowQueryByUserAgent; + private System.Windows.Forms.TextBox txtUserAgentList; + private System.Windows.Forms.GroupBox groupBox5; + private System.Windows.Forms.CheckBox cbAllowQueryByUri; + private System.Windows.Forms.TextBox txtUriList; + private System.Windows.Forms.GroupBox groupBox6; + private System.Windows.Forms.GroupBox groupBox7; + private System.Windows.Forms.CheckBox cbAllowQueryByReferer; + private System.Windows.Forms.TextBox txtRefererList; + private System.Windows.Forms.Button btnExit; + private System.Windows.Forms.FolderBrowserDialog folderBrowserDialog1; + private System.Windows.Forms.OpenFileDialog openFileDialog1; + private System.Windows.Forms.GroupBox groupBox8; + private System.Windows.Forms.CheckBox cbAllowQueryByStatus; + private System.Windows.Forms.TextBox txtStatusList; + private System.Windows.Forms.Button btnOK; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.RadioButton rbtnAll; + private System.Windows.Forms.RadioButton rbtnGet; + private System.Windows.Forms.RadioButton rbtnPost; + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/ToolForm/IISLogParser/IISLogParseCondition.resx b/src/Kalman.Studio/ToolForm/IISLogParser/IISLogParseCondition.resx new file mode 100644 index 0000000..62bf1d8 --- /dev/null +++ b/src/Kalman.Studio/ToolForm/IISLogParser/IISLogParseCondition.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + 192, 17 + + \ No newline at end of file diff --git a/src/Kalman.Studio/ToolForm/IISLogParser/IISLogParser.cs b/src/Kalman.Studio/ToolForm/IISLogParser/IISLogParser.cs new file mode 100644 index 0000000..68dca10 --- /dev/null +++ b/src/Kalman.Studio/ToolForm/IISLogParser/IISLogParser.cs @@ -0,0 +1,567 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using Kalman.IISLogParser; +using System.IO; +using System.Threading; +using System.Diagnostics; +using System.Globalization; +using Aspose.Cells; + +namespace Kalman.Studio +{ + public partial class IISLogParser : DockableForm + { + Main main = null; + LogParser parser = null; + LogParseFilter filter = null; + + public IISLogParser() + { + InitializeComponent(); + } + + private void IISLogParser_Load(object sender, EventArgs e) + { + main = this.ParentForm as Main; + cbCategory.SelectedIndex = 0; + dataGridView1.AutoGenerateColumns = false; + dataGridView1.DataError += new DataGridViewDataErrorEventHandler(dataGridView1_DataError); + } + + void dataGridView1_DataError(object sender, DataGridViewDataErrorEventArgs e) + { + main.AppendOutputLine(e.Exception.ToString()); + } + + public void ParseLog(LogParseFilter logParseFilter) + { + filter = logParseFilter; + cbCategory.SelectedIndex = 0; + listBox1.Items.Clear(); + + dataGridView1.DataSource = null; + gbGrid.Text = "日志数据"; + + Thread t1 = new Thread(DoParse); + t1.Start(); + + Thread t2 = new Thread(CheckParseProgress); + t2.Start(); + } + + protected override void OnClosing(CancelEventArgs e) + { + if (parser != null) parser.Clear(); + this.Dispose(); + base.OnClosing(e); + } + + //开始解析日志文件 + void DoParse() + { + parser = new LogParser(filter); + parser.LoadIPData(Path.Combine(Application.StartupPath, "data\\qqwry.dat")); + parser.DoParser(); + } + + delegate void ParsingEventHandler(int num); + delegate void ParsedEventHandler(); + + //检查解析进度 + void CheckParseProgress() + { + while (true) + { + Thread.Sleep(100); + if (parser != null) + { + if (parser.IsParseFinish) + { + this.Invoke(new ParsedEventHandler(ShowParsedStatus)); + return; + } + else + { + this.Invoke(new ParsingEventHandler(ShowParsingStatus), parser.LogRecordNum); + } + } + } + } + + void ShowParsingStatus(int num) + { + gbGrid.Text = string.Format("正在分析日志,已处理[{0}]条记录", num); + } + + void ShowParsedStatus() + { + //btnDoParse.Enabled = true; + bindingSource1.DataSource = parser.RecordList; + dataGridView1.DataSource = bindingSource1.DataSource; + gbGrid.Text = string.Format("日志数据解析完成,记录总数[{0}]", dataGridView1.Rows.Count); + } + + #region + + private void ShowUserAgentList() + { + if (parser == null) return; + listBox1.Items.Clear(); + foreach (KeyValuePair kvp in parser.UserAgentStat) + { + listBox1.Items.Add(kvp); + } + if (listBox1.Items.Count > 0) + { + dataGridView1.DataSource = StatByUserAgent(((KeyValuePair)listBox1.Items[0]).Key); + } + } + + private void ShowUserAgentAliasList() + { + if (parser == null) return; + listBox1.Items.Clear(); + foreach (KeyValuePair kvp in parser.UserAgentAliasStat) + { + listBox1.Items.Add(kvp); + } + if (listBox1.Items.Count > 0) + { + dataGridView1.DataSource = StatByUserAgentAlias(((KeyValuePair)listBox1.Items[0]).Key); + } + } + + private void ShowUriStemAliasList() + { + if (parser == null) return; + listBox1.Items.Clear(); + foreach (KeyValuePair kvp in parser.UriStemAliasStat) + { + listBox1.Items.Add(kvp); + } + if (listBox1.Items.Count > 0) + { + dataGridView1.DataSource = StatByUriStemAlias(((KeyValuePair)listBox1.Items[0]).Key); + } + } + + private void ShowClientIPList() + { + if (parser == null) return; + listBox1.Items.Clear(); + foreach (KeyValuePair kvp in parser.ClientIPStat) + { + listBox1.Items.Add(kvp); + } + if (listBox1.Items.Count > 0) + { + dataGridView1.DataSource = StatByClientIP(((KeyValuePair)listBox1.Items[0]).Key); + } + } + + private void ShowClientIPLocationList() + { + if (parser == null) return; + listBox1.Items.Clear(); + foreach (KeyValuePair kvp in parser.ClientIPLocationStat) + { + listBox1.Items.Add(kvp); + } + if (listBox1.Items.Count > 0) + { + dataGridView1.DataSource = StatByClientIPLocation(((KeyValuePair)listBox1.Items[0]).Key); + } + } + + private void ShowTimeList() + { + if (parser == null) return; + listBox1.Items.Clear(); + foreach (KeyValuePair kvp in parser.TimeStat) + { + listBox1.Items.Add(kvp); + } + if (listBox1.Items.Count > 0) + { + dataGridView1.DataSource = StatByTime(((KeyValuePair)listBox1.Items[0]).Key); + } + } + + void ShowRefererList() + { + if (parser == null) return; + listBox1.Items.Clear(); + foreach (KeyValuePair kvp in parser.RefererStat) + { + listBox1.Items.Add(kvp); + } + if (listBox1.Items.Count > 0) + { + dataGridView1.DataSource = StatByReferer(((KeyValuePair)listBox1.Items[0]).Key); + } + } + + void ShowRefererAliasList() + { + if (parser == null) return; + listBox1.Items.Clear(); + foreach (KeyValuePair kvp in parser.RefererAliasStat) + { + listBox1.Items.Add(kvp); + } + if (listBox1.Items.Count > 0) + { + dataGridView1.DataSource = StatByRefererAlias(((KeyValuePair)listBox1.Items[0]).Key); + } + } + + private IList StatByUserAgent(string userAgent) + { + IList list = parser.RecordList; + IList result = new List(); + + foreach (LogRecord item in list) + { + if (item.UserAgent == userAgent) result.Add(item); + } + + return result; + } + + private IList StatByUserAgentAlias(string userAgentAlias) + { + IList list = parser.RecordList; + IList result = new List(); + + foreach (LogRecord item in list) + { + if (item.UserAgentAliasList.Contains(userAgentAlias)) result.Add(item); + } + + return result; + } + + private IList StatByUriStemAlias(string uriStemAlias) + { + IList list = parser.RecordList; + IList result = new List(); + + foreach (LogRecord item in list) + { + if (item.UriStemAlias == uriStemAlias) result.Add(item); + } + + return result; + } + + private IList StatByClientIP(string ip) + { + IList list = parser.RecordList; + IList result = new List(); + + foreach (LogRecord item in list) + { + if (item.ClientIP == ip) result.Add(item); + } + + return result; + } + + private IList StatByClientIPLocation(string ipLocation) + { + IList list = parser.RecordList; + IList result = new List(); + + foreach (LogRecord item in list) + { + if (item.ClientIPLocation == ipLocation) result.Add(item); + } + + return result; + } + + private IList StatByTime(string time) + { + IList list = parser.RecordList; + IList result = new List(); + + foreach (LogRecord item in list) + { + if (item.LogTime.ToString("yyyy-MM-dd HH") == time) result.Add(item); + } + + return result; + } + + private IList StatByReferer(string referer) + { + IList list = parser.RecordList; + IList result = new List(); + + foreach (LogRecord item in list) + { + if (item.Referer == referer) result.Add(item); + } + + return result; + } + + private IList StatByRefererAlias(string refererAlias) + { + IList list = parser.RecordList; + IList result = new List(); + + foreach (LogRecord item in list) + { + if (item.RefererAlias == refererAlias) result.Add(item); + } + + return result; + } + + private void cbCategory_SelectedIndexChanged(object sender, EventArgs e) + { + string s = cbCategory.SelectedItem.ToString(); + switch (s) + { + case "显示全部数据": + if (parser != null) + { + listBox1.Items.Clear(); + dataGridView1.DataSource = parser.RecordList; + gbGrid.Text = string.Format("显示全部日志数据,记录总数[{0}]", dataGridView1.Rows.Count); + } + break; + case "按用户代理汇总": + ShowUserAgentList(); + break; + case "按用户代理别名汇总": + ShowUserAgentAliasList(); + break; + case "按请求地址别名汇总": + ShowUriStemAliasList(); + break; + case "按客户端IP汇总": + ShowClientIPList(); + break; + case "按时间汇总": + ShowTimeList(); + break; + case "按引用地址汇总": + ShowRefererList(); + break; + case "按引用地址别名汇总": + ShowRefererAliasList(); + break; + case "按客户端IP归属地汇总": + ShowClientIPLocationList(); + break; + default: + break; + } + if (listBox1.Items.Count > 0) + { + listBox1.SelectedIndex = 0; + gbGrid.Text = listBox1.SelectedItem.ToString(); + } + } + + private void listBox1_MouseDoubleClick(object sender, MouseEventArgs e) + { + if (parser == null) return; + if (listBox1.SelectedItem == null) return; + + string s = cbCategory.SelectedItem.ToString(); + + switch (s) + { + case "按用户代理汇总": + dataGridView1.DataSource = StatByUserAgent(((KeyValuePair)listBox1.SelectedItem).Key); + break; + case "按用户代理别名汇总": + dataGridView1.DataSource = StatByUserAgentAlias(((KeyValuePair)listBox1.SelectedItem).Key); + break; + case "按请求地址别名汇总": + dataGridView1.DataSource = StatByUriStemAlias(((KeyValuePair)listBox1.SelectedItem).Key); + break; + case "按客户端IP汇总": + dataGridView1.DataSource = StatByClientIP(((KeyValuePair)listBox1.SelectedItem).Key); + break; + case "按时间汇总": + dataGridView1.DataSource = StatByTime(((KeyValuePair)listBox1.SelectedItem).Key); + break; + case "按引用地址汇总": + dataGridView1.DataSource = StatByReferer(((KeyValuePair)listBox1.SelectedItem).Key); + break; + case "按引用地址别名汇总": + dataGridView1.DataSource = StatByRefererAlias(((KeyValuePair)listBox1.SelectedItem).Key); + break; + case "按客户端IP归属地汇总": + dataGridView1.DataSource = StatByClientIPLocation(((KeyValuePair)listBox1.SelectedItem).Key); + break; + default: + break; + } + if (listBox1.Items.Count > 0) + { + gbGrid.Text = listBox1.SelectedItem.ToString(); + } + } + + #endregion + + private void menuItemCopy_Click(object sender, EventArgs e) + { + Clipboard.SetText(dataGridView1.GetClipboardContent().GetText(), TextDataFormat.UnicodeText); + } + + private void menuItemExport_Click(object sender, EventArgs e) + { + //Export.DataGridViewToExcel(dataGridView1); + int colCount = dataGridView1.Columns.Count; + int rowCount = dataGridView1.Rows.Count; + int recordCount = 50000; //限制每个Worksheet做多能写的记录数 + int remainder = rowCount % recordCount; + int sheetCount = 1; //需要将数据写入多少个Worksheet + + if (remainder != 0) sheetCount = rowCount / recordCount + 1; + else sheetCount = rowCount / recordCount; + + Workbook wb = new Workbook(); + + for (int sheetIndex = 0; sheetIndex < sheetCount; sheetIndex++) + { + if (sheetIndex > 0) wb.Worksheets.Add(); + Worksheet ws = wb.Worksheets[sheetIndex]; + + //for (int ci = 0; ci < colCount; ci++) + //{ + // int width = dataGridView1.Columns[ci].Width; + // ws.Cells.SetColumnWidth(ci, width / 7); + // ws.Cells[0, ci].PutValue(dataGridView1.Columns[ci].HeaderText); + + // for (int ri = 0; ri < rowCount; ri++) + // { + // ws.Cells[ri + 1, ci].PutValue(dataGridView1.Rows[ri].Cells[ci].Value); + // } + //} + + //写列标题文本及设置列宽度 + for (int ci = 0; ci < colCount; ci++) + { + int width = dataGridView1.Columns[ci].Width; + ws.Cells.SetColumnWidth(ci, width / 7); + ws.Cells[0, ci].PutValue(dataGridView1.Columns[ci].HeaderText); + } + + int beginRowIndex = sheetIndex * recordCount; + int endRowIndex = (sheetIndex + 1) * recordCount; + if (sheetIndex == sheetCount - 1) endRowIndex = rowCount; + + for (; beginRowIndex < endRowIndex; beginRowIndex++) + { + for (int ci = 0; ci < colCount; ci++) + { + int ri = beginRowIndex + 1 - sheetIndex * recordCount; + ws.Cells[ri, ci].PutValue(dataGridView1.Rows[beginRowIndex].Cells[ci].Value); + } + } + } + + string dicName = Path.Combine(Application.StartupPath, "IISLogExport"); + if(Directory.Exists(dicName) == false)Directory.CreateDirectory(dicName); + + string fileName = Path.Combine(dicName, string.Format("{0}.xls", Guid.NewGuid().ToString())); + wb.Save(fileName, SaveFormat.Excel97To2003); + RunExcel(fileName); + } + + private void RunExcel1(string filename) + { + try + { + System.Diagnostics.Process.Start("Excel", string.Concat("\"", filename, "\"")); + } + catch// (Exception ex) + { + RunExcel(filename); + } + } + + private void RunExcel(string filename) + { + ProcessStartInfo startInfo = new ProcessStartInfo(filename); + startInfo.UseShellExecute = true; + Process.Start(startInfo); + } + + + private void menuItemSelectAll_Click(object sender, EventArgs e) + { + dataGridView1.SelectAll(); + } + + private void dataGridView1_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e) + { + SolidBrush b = new SolidBrush(dataGridView1.RowHeadersDefaultCellStyle.ForeColor); + e.Graphics.DrawString((e.RowIndex + 1).ToString(), dataGridView1.DefaultCellStyle.Font, b, e.RowBounds.Location.X + 15, e.RowBounds.Location.Y + 5); + } + + private void menuItemExportToDB_Click(object sender, EventArgs e) + { + IList list = dataGridView1.DataSource as IList; + if (list == null || list.Count == 0) return; + + //DataTable dt = new DataTable("IISLogData"); + //dt.Columns.Add("LogTime", typeof(string)); + //dt.Columns.Add("Method", typeof(string)); + //dt.Columns.Add("ClientIP", typeof(string)); + //dt.Columns.Add("ClientIPLocation", typeof(string)); + //dt.Columns.Add("Status", typeof(string)); + //dt.Columns.Add("SubStatus", typeof(string)); + //dt.Columns.Add("Win32Status", typeof(string)); + //dt.Columns.Add("ReceiveBytes", typeof(string)); + //dt.Columns.Add("SendBytes", typeof(string)); + //dt.Columns.Add("UriStem", typeof(string)); + //dt.Columns.Add("Referer", typeof(string)); + //dt.Columns.Add("UriStemAlias", typeof(string)); + //dt.Columns.Add("RefererAlias", typeof(string)); + //dt.Columns.Add("UserAgentAlias", typeof(string)); + //dt.Columns.Add("UserAgent", typeof(string)); + + //foreach (LogRecord lr in list) + //{ + // DataRow row = dt.NewRow(); + + // row["LogTime"] = lr.LogTime.ToString(); + // row["Method"] = lr.Method; + // row["ClientIP"] = lr.ClientIP; + // row["ClientIPLocation"] = lr.ClientIPLocation; + // row["Status"] = lr.Status; + // row["SubStatus"] = lr.SubStatus; + // row["Win32Status"] = lr.Win32Status; + // row["ReceiveBytes"] = lr.ReceiveBytes; + // row["SendBytes"] = lr.SendBytes; + // row["UriStem"] = lr.UriStem; + // row["Referer"] = lr.Referer; + // row["UriStemAlias"] = lr.UriStemAlias; + // row["RefererAlias"] = lr.RefererAlias; + // row["UserAgentAlias"] = lr.UserAgentAlias; + // row["UserAgent"] = lr.UserAgent; + + // dt.Rows.Add(row); + //} + + //IISLogExportToDB exporter = new IISLogExportToDB(dt); + IISLogExportToDB exporter = new IISLogExportToDB(list); + exporter.ShowDialog(); + } + + } +} diff --git a/src/Kalman.Studio/ToolForm/IISLogParser/IISLogParser.designer.cs b/src/Kalman.Studio/ToolForm/IISLogParser/IISLogParser.designer.cs new file mode 100644 index 0000000..eabe8e4 --- /dev/null +++ b/src/Kalman.Studio/ToolForm/IISLogParser/IISLogParser.designer.cs @@ -0,0 +1,413 @@ +namespace Kalman.Studio +{ + partial class IISLogParser + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle2 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle3 = new System.Windows.Forms.DataGridViewCellStyle(); + this.splitContainer1 = new System.Windows.Forms.SplitContainer(); + this.groupBox2 = new System.Windows.Forms.GroupBox(); + this.listBox1 = new System.Windows.Forms.ListBox(); + this.cbCategory = new System.Windows.Forms.ComboBox(); + this.gbGrid = new System.Windows.Forms.GroupBox(); + this.dataGridView1 = new System.Windows.Forms.DataGridView(); + this.colDate = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colTime = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colMethod = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colClientIP = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colClientIPLocation = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colStatus = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colSubStatus = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colWin32Status = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colSendBytes = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colReceiveBytes = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colUri = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colReferer = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colUriStemAlias = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colRefererAlias = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colUserAgentAlias = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colUserAgent = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.cms = new System.Windows.Forms.ContextMenuStrip(this.components); + this.menuItemSelectAll = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemCopy = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemExportToExcel = new System.Windows.Forms.ToolStripMenuItem(); + this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog(); + this.bindingSource1 = new System.Windows.Forms.BindingSource(this.components); + this.menuItemExportToDB = new System.Windows.Forms.ToolStripMenuItem(); + this.splitContainer1.Panel1.SuspendLayout(); + this.splitContainer1.Panel2.SuspendLayout(); + this.splitContainer1.SuspendLayout(); + this.groupBox2.SuspendLayout(); + this.gbGrid.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit(); + this.cms.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.bindingSource1)).BeginInit(); + this.SuspendLayout(); + // + // splitContainer1 + // + this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill; + this.splitContainer1.Location = new System.Drawing.Point(5, 5); + this.splitContainer1.Name = "splitContainer1"; + // + // splitContainer1.Panel1 + // + this.splitContainer1.Panel1.Controls.Add(this.groupBox2); + // + // splitContainer1.Panel2 + // + this.splitContainer1.Panel2.Controls.Add(this.gbGrid); + this.splitContainer1.Size = new System.Drawing.Size(823, 483); + this.splitContainer1.SplitterDistance = 193; + this.splitContainer1.TabIndex = 0; + // + // groupBox2 + // + this.groupBox2.Controls.Add(this.listBox1); + this.groupBox2.Controls.Add(this.cbCategory); + this.groupBox2.Dock = System.Windows.Forms.DockStyle.Fill; + this.groupBox2.Location = new System.Drawing.Point(0, 0); + this.groupBox2.Name = "groupBox2"; + this.groupBox2.Size = new System.Drawing.Size(193, 483); + this.groupBox2.TabIndex = 0; + this.groupBox2.TabStop = false; + this.groupBox2.Text = "分类统计"; + // + // listBox1 + // + this.listBox1.Dock = System.Windows.Forms.DockStyle.Fill; + this.listBox1.FormattingEnabled = true; + this.listBox1.ItemHeight = 12; + this.listBox1.Location = new System.Drawing.Point(3, 37); + this.listBox1.Name = "listBox1"; + this.listBox1.Size = new System.Drawing.Size(187, 436); + this.listBox1.TabIndex = 3; + this.listBox1.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.listBox1_MouseDoubleClick); + // + // cbCategory + // + this.cbCategory.Dock = System.Windows.Forms.DockStyle.Top; + this.cbCategory.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.cbCategory.FormattingEnabled = true; + this.cbCategory.Items.AddRange(new object[] { + "显示全部数据", + "按用户代理汇总", + "按用户代理别名汇总", + "按时间汇总", + "按客户端IP汇总", + "按引用地址汇总", + "按引用地址别名汇总", + "按请求地址别名汇总", + "按客户端IP归属地汇总"}); + this.cbCategory.Location = new System.Drawing.Point(3, 17); + this.cbCategory.MaxDropDownItems = 15; + this.cbCategory.Name = "cbCategory"; + this.cbCategory.Size = new System.Drawing.Size(187, 20); + this.cbCategory.TabIndex = 2; + this.cbCategory.SelectedIndexChanged += new System.EventHandler(this.cbCategory_SelectedIndexChanged); + // + // gbGrid + // + this.gbGrid.Controls.Add(this.dataGridView1); + this.gbGrid.Dock = System.Windows.Forms.DockStyle.Fill; + this.gbGrid.Location = new System.Drawing.Point(0, 0); + this.gbGrid.Name = "gbGrid"; + this.gbGrid.Size = new System.Drawing.Size(626, 483); + this.gbGrid.TabIndex = 1; + this.gbGrid.TabStop = false; + this.gbGrid.Text = "日志数据"; + // + // dataGridView1 + // + this.dataGridView1.AllowUserToAddRows = false; + this.dataGridView1.AllowUserToDeleteRows = false; + this.dataGridView1.AllowUserToOrderColumns = true; + this.dataGridView1.AllowUserToResizeRows = false; + dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle1.BackColor = System.Drawing.SystemColors.Control; + dataGridViewCellStyle1.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + dataGridViewCellStyle1.ForeColor = System.Drawing.SystemColors.WindowText; + dataGridViewCellStyle1.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle1.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle1.WrapMode = System.Windows.Forms.DataGridViewTriState.True; + this.dataGridView1.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle1; + this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.dataGridView1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { + this.colDate, + this.colTime, + this.colMethod, + this.colClientIP, + this.colClientIPLocation, + this.colStatus, + this.colSubStatus, + this.colWin32Status, + this.colSendBytes, + this.colReceiveBytes, + this.colUri, + this.colReferer, + this.colUriStemAlias, + this.colRefererAlias, + this.colUserAgentAlias, + this.colUserAgent}); + this.dataGridView1.ContextMenuStrip = this.cms; + dataGridViewCellStyle2.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle2.BackColor = System.Drawing.SystemColors.Window; + dataGridViewCellStyle2.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + dataGridViewCellStyle2.ForeColor = System.Drawing.SystemColors.ControlText; + dataGridViewCellStyle2.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle2.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle2.WrapMode = System.Windows.Forms.DataGridViewTriState.False; + this.dataGridView1.DefaultCellStyle = dataGridViewCellStyle2; + this.dataGridView1.Dock = System.Windows.Forms.DockStyle.Fill; + this.dataGridView1.Location = new System.Drawing.Point(3, 17); + this.dataGridView1.Name = "dataGridView1"; + dataGridViewCellStyle3.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle3.BackColor = System.Drawing.SystemColors.Control; + dataGridViewCellStyle3.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + dataGridViewCellStyle3.ForeColor = System.Drawing.SystemColors.WindowText; + dataGridViewCellStyle3.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle3.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle3.WrapMode = System.Windows.Forms.DataGridViewTriState.True; + this.dataGridView1.RowHeadersDefaultCellStyle = dataGridViewCellStyle3; + this.dataGridView1.RowTemplate.Height = 23; + this.dataGridView1.Size = new System.Drawing.Size(620, 463); + this.dataGridView1.TabIndex = 2; + this.dataGridView1.RowPostPaint += new System.Windows.Forms.DataGridViewRowPostPaintEventHandler(this.dataGridView1_RowPostPaint); + // + // colDate + // + this.colDate.DataPropertyName = "Date"; + this.colDate.HeaderText = "日期"; + this.colDate.Name = "colDate"; + this.colDate.Width = 80; + // + // colTime + // + this.colTime.DataPropertyName = "Time"; + this.colTime.HeaderText = "时间"; + this.colTime.Name = "colTime"; + this.colTime.Width = 80; + // + // colMethod + // + this.colMethod.DataPropertyName = "Method"; + this.colMethod.HeaderText = "方法"; + this.colMethod.Name = "colMethod"; + this.colMethod.Width = 55; + // + // colClientIP + // + this.colClientIP.DataPropertyName = "ClientIP"; + this.colClientIP.HeaderText = "客户端IP"; + this.colClientIP.Name = "colClientIP"; + // + // colClientIPLocation + // + this.colClientIPLocation.DataPropertyName = "ClientIPLocation"; + this.colClientIPLocation.HeaderText = "客户端IP归属地"; + this.colClientIPLocation.Name = "colClientIPLocation"; + this.colClientIPLocation.Width = 120; + // + // colStatus + // + this.colStatus.DataPropertyName = "Status"; + this.colStatus.HeaderText = "协议状态"; + this.colStatus.Name = "colStatus"; + this.colStatus.Width = 80; + // + // colSubStatus + // + this.colSubStatus.DataPropertyName = "SubStatus"; + this.colSubStatus.HeaderText = "协议子状态"; + this.colSubStatus.Name = "colSubStatus"; + this.colSubStatus.Width = 90; + // + // colWin32Status + // + this.colWin32Status.DataPropertyName = "Win32Status"; + this.colWin32Status.HeaderText = "Win32状态"; + this.colWin32Status.Name = "colWin32Status"; + this.colWin32Status.Width = 85; + // + // colSendBytes + // + this.colSendBytes.DataPropertyName = "SendBytes"; + this.colSendBytes.HeaderText = "发送字节数"; + this.colSendBytes.Name = "colSendBytes"; + // + // colReceiveBytes + // + this.colReceiveBytes.DataPropertyName = "ReceiveBytes"; + this.colReceiveBytes.HeaderText = "接收字节数"; + this.colReceiveBytes.Name = "colReceiveBytes"; + // + // colUri + // + this.colUri.DataPropertyName = "UriStem"; + this.colUri.HeaderText = "请求地址"; + this.colUri.Name = "colUri"; + this.colUri.Width = 200; + // + // colReferer + // + this.colReferer.DataPropertyName = "Referer"; + this.colReferer.HeaderText = "引用地址"; + this.colReferer.Name = "colReferer"; + this.colReferer.Width = 200; + // + // colUriStemAlias + // + this.colUriStemAlias.DataPropertyName = "UriStemAlias"; + this.colUriStemAlias.HeaderText = "请求地址别名"; + this.colUriStemAlias.Name = "colUriStemAlias"; + this.colUriStemAlias.Width = 120; + // + // colRefererAlias + // + this.colRefererAlias.DataPropertyName = "RefererAlias"; + this.colRefererAlias.HeaderText = "引用地址别名"; + this.colRefererAlias.Name = "colRefererAlias"; + this.colRefererAlias.Width = 120; + // + // colUserAgentAlias + // + this.colUserAgentAlias.DataPropertyName = "UserAgentAlias"; + this.colUserAgentAlias.HeaderText = "用户代理别名"; + this.colUserAgentAlias.Name = "colUserAgentAlias"; + this.colUserAgentAlias.Resizable = System.Windows.Forms.DataGridViewTriState.True; + this.colUserAgentAlias.Width = 250; + // + // colUserAgent + // + this.colUserAgent.DataPropertyName = "UserAgent"; + this.colUserAgent.HeaderText = "用户代理"; + this.colUserAgent.Name = "colUserAgent"; + this.colUserAgent.Width = 700; + // + // cms + // + this.cms.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.menuItemSelectAll, + this.menuItemCopy, + this.menuItemExportToExcel, + this.menuItemExportToDB}); + this.cms.Name = "cms"; + this.cms.Size = new System.Drawing.Size(161, 114); + // + // menuItemSelectAll + // + this.menuItemSelectAll.Name = "menuItemSelectAll"; + this.menuItemSelectAll.Size = new System.Drawing.Size(160, 22); + this.menuItemSelectAll.Text = "全选"; + this.menuItemSelectAll.Click += new System.EventHandler(this.menuItemSelectAll_Click); + // + // menuItemCopy + // + this.menuItemCopy.Name = "menuItemCopy"; + this.menuItemCopy.Size = new System.Drawing.Size(160, 22); + this.menuItemCopy.Text = "复制"; + this.menuItemCopy.Click += new System.EventHandler(this.menuItemCopy_Click); + // + // menuItemExportToExcel + // + this.menuItemExportToExcel.Name = "menuItemExportToExcel"; + this.menuItemExportToExcel.Size = new System.Drawing.Size(160, 22); + this.menuItemExportToExcel.Text = "导出Excel"; + this.menuItemExportToExcel.Click += new System.EventHandler(this.menuItemExport_Click); + // + // openFileDialog1 + // + this.openFileDialog1.Filter = "IIS日志文件(*.log)|*.log|所有文件(*.*)|*.*"; + this.openFileDialog1.InitialDirectory = "C:\\WINDOWS\\system32\\LogFiles"; + // + // menuItemExportToDB + // + this.menuItemExportToDB.Name = "menuItemExportToDB"; + this.menuItemExportToDB.Size = new System.Drawing.Size(160, 22); + this.menuItemExportToDB.Text = "导出到SqlServer"; + this.menuItemExportToDB.Click += new System.EventHandler(this.menuItemExportToDB_Click); + // + // IISLogParser + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(833, 493); + this.Controls.Add(this.splitContainer1); + this.Name = "IISLogParser"; + this.Padding = new System.Windows.Forms.Padding(5); + this.Text = "IIS日志解析器"; + this.Load += new System.EventHandler(this.IISLogParser_Load); + this.splitContainer1.Panel1.ResumeLayout(false); + this.splitContainer1.Panel2.ResumeLayout(false); + this.splitContainer1.ResumeLayout(false); + this.groupBox2.ResumeLayout(false); + this.gbGrid.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit(); + this.cms.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.bindingSource1)).EndInit(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.SplitContainer splitContainer1; + private System.Windows.Forms.GroupBox groupBox2; + private System.Windows.Forms.ListBox listBox1; + private System.Windows.Forms.ComboBox cbCategory; + private System.Windows.Forms.GroupBox gbGrid; + private System.Windows.Forms.DataGridView dataGridView1; + private System.Windows.Forms.OpenFileDialog openFileDialog1; + private System.Windows.Forms.ContextMenuStrip cms; + private System.Windows.Forms.ToolStripMenuItem menuItemCopy; + private System.Windows.Forms.ToolStripMenuItem menuItemExportToExcel; + private System.Windows.Forms.ToolStripMenuItem menuItemSelectAll; + private System.Windows.Forms.BindingSource bindingSource1; + private System.Windows.Forms.DataGridViewTextBoxColumn colDate; + private System.Windows.Forms.DataGridViewTextBoxColumn colTime; + private System.Windows.Forms.DataGridViewTextBoxColumn colMethod; + private System.Windows.Forms.DataGridViewTextBoxColumn colClientIP; + private System.Windows.Forms.DataGridViewTextBoxColumn colClientIPLocation; + private System.Windows.Forms.DataGridViewTextBoxColumn colStatus; + private System.Windows.Forms.DataGridViewTextBoxColumn colSubStatus; + private System.Windows.Forms.DataGridViewTextBoxColumn colWin32Status; + private System.Windows.Forms.DataGridViewTextBoxColumn colSendBytes; + private System.Windows.Forms.DataGridViewTextBoxColumn colReceiveBytes; + private System.Windows.Forms.DataGridViewTextBoxColumn colUri; + private System.Windows.Forms.DataGridViewTextBoxColumn colReferer; + private System.Windows.Forms.DataGridViewTextBoxColumn colUriStemAlias; + private System.Windows.Forms.DataGridViewTextBoxColumn colRefererAlias; + private System.Windows.Forms.DataGridViewTextBoxColumn colUserAgentAlias; + private System.Windows.Forms.DataGridViewTextBoxColumn colUserAgent; + private System.Windows.Forms.ToolStripMenuItem menuItemExportToDB; + + + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/ToolForm/IISLogParser/IISLogParser.resx b/src/Kalman.Studio/ToolForm/IISLogParser/IISLogParser.resx new file mode 100644 index 0000000..8f9c4a1 --- /dev/null +++ b/src/Kalman.Studio/ToolForm/IISLogParser/IISLogParser.resx @@ -0,0 +1,177 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + 161, 17 + + + 17, 17 + + + 231, 17 + + \ No newline at end of file diff --git a/src/Kalman.Studio/ToolForm/QueryAnalyzer.cs b/src/Kalman.Studio/ToolForm/QueryAnalyzer.cs new file mode 100644 index 0000000..9514d3e --- /dev/null +++ b/src/Kalman.Studio/ToolForm/QueryAnalyzer.cs @@ -0,0 +1,184 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using WeifenLuo.WinFormsUI.Docking; +using ICSharpCode.TextEditor.Document; +using System.IO; +using Kalman.Command; +using Kalman.Data.SchemaObject; + +namespace Kalman.Studio +{ + public partial class QueryAnalyzer : DockableForm, IDockDocument + { + public QueryAnalyzer() + { + InitializeComponent(); + } + + public string FileName { get; set; } + + /// + /// 当前数据库 + /// + public SODatabase CurrentDatabase { get; set; } + + /// + /// Sql查询文本 + /// + public string SqlText { get; set; } + + private void QueryAnalyzer_Load(object sender, EventArgs e) + { + this.Text = FileName; + + IHighlightingStrategy strategy = HighlightingStrategyFactory.CreateHighlightingStrategy(CodeType.TSQL); + textEditorControl1.Document.HighlightingStrategy = strategy; + + if (DbSchemaHelper.Instance.CurrentSchema == null || string.IsNullOrEmpty(SqlText)) return; + + textEditorControl1.Text = SqlText; + ExecuteSql(); + } + + private void QueryAnalyzer_Activated(object sender, EventArgs e) + { + base.MainForm.SetCurrentDB(this.CurrentDatabase); + } + + public void ExecuteSql() + { + try + { + SODatabase db = base.MainForm.GetCurrentDatabase(); + string cmdText = textEditorControl1.Text; + + if (this.CurrentDatabase != db) this.CurrentDatabase = db; + + DataSet ds = DbSchemaHelper.Instance.CurrentSchema.ExecuteQuery(CurrentDatabase, cmdText); + + if (ds != null && ds.Tables.Count > 0) + { + dataGridView1.DataSource = ds.Tables[0].DefaultView; + richTextBox1.Text = string.Format("({0} 行受影响)", ds.Tables[0].Rows.Count); + tabControl1.SelectedTab = tabPage1; + } + else + { + richTextBox1.Text = "已成功执行查询"; + dataGridView1.DataSource = null; + tabControl1.SelectedTab = tabPage2; + } + } + catch (Exception ex) + { + tabControl1.SelectedTab = tabPage2; + richTextBox1.Text = ex.ToString(); + } + } + + protected override bool ProcessCmdKey(ref Message msg, Keys keyData) + { + if (keyData.ToString() == "F5") + { + ExecuteSql(); + } + + return base.ProcessCmdKey(ref msg, keyData); + } + + public void Save() + { + if (string.IsNullOrEmpty(textEditorControl1.FileName) == false) + { + textEditorControl1.SaveFile(textEditorControl1.FileName); + this.Text = Path.GetFileName(textEditorControl1.FileName); + } + else + { + SaveFileDialog dialog = new SaveFileDialog(); + dialog.Filter = "所有文件 (*.*)|*.*"; + dialog.FileName = this.Text.TrimEnd('*'); + if (dialog.ShowDialog() == DialogResult.OK) + { + textEditorControl1.SaveFile(dialog.FileName); + this.Text = Path.GetFileName(textEditorControl1.FileName); + } + } + } + + public void SaveAs() + { + SaveFileDialog dialog = new SaveFileDialog(); + dialog.Filter = "所有文件 (*.*)|*.*"; + dialog.FileName = this.Text.TrimEnd('*'); + if (dialog.ShowDialog() == DialogResult.OK) + { + textEditorControl1.SaveFile(dialog.FileName); + this.Text = Path.GetFileName(textEditorControl1.FileName); + } + } + + private void menuItemSave_Click(object sender, EventArgs e) + { + this.Save(); + } + + private void menuItemSaveAs_Click(object sender, EventArgs e) + { + this.SaveAs(); + } + + private void menuItemClose_Click(object sender, EventArgs e) + { + this.Close(); + } + + private void menuItemCloseOther_Click(object sender, EventArgs e) + { + base.MainForm.CloseOtherDockDocument(); + } + + private void menuItemCloseAll_Click(object sender, EventArgs e) + { + base.MainForm.CloseAllDockDocument(); + } + + private void textEditorControl1_TextChanged(object sender, EventArgs e) + { + if (this.Text.EndsWith("*") == false) this.Text = this.Text + "*"; + } + + private void menuItemOpenFolder_Click(object sender, EventArgs e) + { + if (File.Exists(textEditorControl1.FileName)) + { + CmdHelper.Execute(string.Format("explorer.exe {0}", Path.GetDirectoryName(textEditorControl1.FileName))); + } + } + + #region 处理编辑命令 + private void menuItemUndo_Click(object sender, EventArgs e) { Undo(); } + private void menuItemRedo_Click(object sender, EventArgs e) { Redo(); } + private void menuItemCut_Click(object sender, EventArgs e) { Cut(sender, e); } + private void menuItemCopy_Click(object sender, EventArgs e) { Copy(sender, e); } + private void menuItemPaste_Click(object sender, EventArgs e) { Paste(sender, e); } + private void menuItemDelete_Click(object sender, EventArgs e) { Delete(sender, e); } + private void menuItemSelectAll_Click(object sender, EventArgs e) { SelectAll(sender, e); } + + public void Undo() { textEditorControl1.Undo(); } + public void Redo() { textEditorControl1.Redo(); } + public void Cut(object sender, EventArgs e) { textEditorControl1.ActiveTextAreaControl.TextArea.ClipboardHandler.Cut(sender, e); } + public void Copy(object sender, EventArgs e) { textEditorControl1.ActiveTextAreaControl.TextArea.ClipboardHandler.Copy(sender, e); } + public void Paste(object sender, EventArgs e) { textEditorControl1.ActiveTextAreaControl.TextArea.ClipboardHandler.Paste(sender, e); } + public void Delete(object sender, EventArgs e) { textEditorControl1.ActiveTextAreaControl.TextArea.ClipboardHandler.Delete(sender, e); } + public void SelectAll(object sender, EventArgs e) { textEditorControl1.ActiveTextAreaControl.TextArea.ClipboardHandler.SelectAll(sender, e); } + #endregion + + } +} diff --git a/src/Kalman.Studio/ToolForm/QueryAnalyzer.designer.cs b/src/Kalman.Studio/ToolForm/QueryAnalyzer.designer.cs new file mode 100644 index 0000000..7faea70 --- /dev/null +++ b/src/Kalman.Studio/ToolForm/QueryAnalyzer.designer.cs @@ -0,0 +1,374 @@ +namespace Kalman.Studio +{ + partial class QueryAnalyzer + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(QueryAnalyzer)); + this.splitContainer1 = new System.Windows.Forms.SplitContainer(); + this.textEditorControl1 = new ICSharpCode.TextEditor.TextEditorControl(); + this.cms = new System.Windows.Forms.ContextMenuStrip(this.components); + this.menuItemUndo = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemRedo = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator(); + this.menuItemCut = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemCopy = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemPaste = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemDelete = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); + this.menuItemSelectAll = new System.Windows.Forms.ToolStripMenuItem(); + this.tabControl1 = new System.Windows.Forms.TabControl(); + this.tabPage1 = new System.Windows.Forms.TabPage(); + this.dataGridView1 = new System.Windows.Forms.DataGridView(); + this.tabPage2 = new System.Windows.Forms.TabPage(); + this.richTextBox1 = new System.Windows.Forms.RichTextBox(); + this.imageList1 = new System.Windows.Forms.ImageList(this.components); + this.cmsDock = new System.Windows.Forms.ContextMenuStrip(this.components); + this.menuItemSave = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemSaveAs = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator(); + this.menuItemClose = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemCloseOther = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemCloseAll = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator(); + this.menuItemOpenFolder = new System.Windows.Forms.ToolStripMenuItem(); + this.splitContainer1.Panel1.SuspendLayout(); + this.splitContainer1.Panel2.SuspendLayout(); + this.splitContainer1.SuspendLayout(); + this.cms.SuspendLayout(); + this.tabControl1.SuspendLayout(); + this.tabPage1.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit(); + this.tabPage2.SuspendLayout(); + this.cmsDock.SuspendLayout(); + this.SuspendLayout(); + // + // splitContainer1 + // + this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill; + this.splitContainer1.Location = new System.Drawing.Point(0, 0); + this.splitContainer1.Name = "splitContainer1"; + this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal; + // + // splitContainer1.Panel1 + // + this.splitContainer1.Panel1.Controls.Add(this.textEditorControl1); + // + // splitContainer1.Panel2 + // + this.splitContainer1.Panel2.Controls.Add(this.tabControl1); + this.splitContainer1.Size = new System.Drawing.Size(674, 519); + this.splitContainer1.SplitterDistance = 259; + this.splitContainer1.TabIndex = 1; + // + // textEditorControl1 + // + this.textEditorControl1.ContextMenuStrip = this.cms; + this.textEditorControl1.Dock = System.Windows.Forms.DockStyle.Fill; + this.textEditorControl1.IsReadOnly = false; + this.textEditorControl1.Location = new System.Drawing.Point(0, 0); + this.textEditorControl1.Name = "textEditorControl1"; + this.textEditorControl1.Size = new System.Drawing.Size(674, 259); + this.textEditorControl1.TabIndex = 1; + this.textEditorControl1.TextChanged += new System.EventHandler(this.textEditorControl1_TextChanged); + // + // cms + // + this.cms.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.menuItemUndo, + this.menuItemRedo, + this.toolStripSeparator5, + this.menuItemCut, + this.menuItemCopy, + this.menuItemPaste, + this.menuItemDelete, + this.toolStripSeparator1, + this.menuItemSelectAll}); + this.cms.Name = "cms"; + this.cms.Size = new System.Drawing.Size(154, 170); + // + // menuItemUndo + // + this.menuItemUndo.Image = ((System.Drawing.Image)(resources.GetObject("menuItemUndo.Image"))); + this.menuItemUndo.Name = "menuItemUndo"; + this.menuItemUndo.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Z))); + this.menuItemUndo.Size = new System.Drawing.Size(153, 22); + this.menuItemUndo.Text = "撤销(&Z)"; + this.menuItemUndo.Click += new System.EventHandler(this.menuItemUndo_Click); + // + // menuItemRedo + // + this.menuItemRedo.Image = ((System.Drawing.Image)(resources.GetObject("menuItemRedo.Image"))); + this.menuItemRedo.Name = "menuItemRedo"; + this.menuItemRedo.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Y))); + this.menuItemRedo.Size = new System.Drawing.Size(153, 22); + this.menuItemRedo.Text = "重复(&R)"; + this.menuItemRedo.Click += new System.EventHandler(this.menuItemRedo_Click); + // + // toolStripSeparator5 + // + this.toolStripSeparator5.Name = "toolStripSeparator5"; + this.toolStripSeparator5.Size = new System.Drawing.Size(150, 6); + // + // menuItemCut + // + this.menuItemCut.Image = ((System.Drawing.Image)(resources.GetObject("menuItemCut.Image"))); + this.menuItemCut.Name = "menuItemCut"; + this.menuItemCut.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.X))); + this.menuItemCut.Size = new System.Drawing.Size(153, 22); + this.menuItemCut.Text = "剪切(&X)"; + this.menuItemCut.Click += new System.EventHandler(this.menuItemCut_Click); + // + // menuItemCopy + // + this.menuItemCopy.Image = ((System.Drawing.Image)(resources.GetObject("menuItemCopy.Image"))); + this.menuItemCopy.Name = "menuItemCopy"; + this.menuItemCopy.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.C))); + this.menuItemCopy.Size = new System.Drawing.Size(153, 22); + this.menuItemCopy.Text = "复制(&C)"; + this.menuItemCopy.Click += new System.EventHandler(this.menuItemCopy_Click); + // + // menuItemPaste + // + this.menuItemPaste.Image = ((System.Drawing.Image)(resources.GetObject("menuItemPaste.Image"))); + this.menuItemPaste.Name = "menuItemPaste"; + this.menuItemPaste.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.V))); + this.menuItemPaste.Size = new System.Drawing.Size(153, 22); + this.menuItemPaste.Text = "粘贴(&V)"; + this.menuItemPaste.Click += new System.EventHandler(this.menuItemPaste_Click); + // + // menuItemDelete + // + this.menuItemDelete.Image = ((System.Drawing.Image)(resources.GetObject("menuItemDelete.Image"))); + this.menuItemDelete.Name = "menuItemDelete"; + this.menuItemDelete.ShortcutKeys = System.Windows.Forms.Keys.Delete; + this.menuItemDelete.Size = new System.Drawing.Size(153, 22); + this.menuItemDelete.Text = "删除(&D)"; + this.menuItemDelete.Click += new System.EventHandler(this.menuItemDelete_Click); + // + // toolStripSeparator1 + // + this.toolStripSeparator1.Name = "toolStripSeparator1"; + this.toolStripSeparator1.Size = new System.Drawing.Size(150, 6); + // + // menuItemSelectAll + // + this.menuItemSelectAll.Name = "menuItemSelectAll"; + this.menuItemSelectAll.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.A))); + this.menuItemSelectAll.Size = new System.Drawing.Size(153, 22); + this.menuItemSelectAll.Text = "全选(&A)"; + this.menuItemSelectAll.Click += new System.EventHandler(this.menuItemSelectAll_Click); + // + // tabControl1 + // + this.tabControl1.Controls.Add(this.tabPage1); + this.tabControl1.Controls.Add(this.tabPage2); + this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill; + this.tabControl1.ImageList = this.imageList1; + this.tabControl1.Location = new System.Drawing.Point(0, 0); + this.tabControl1.Name = "tabControl1"; + this.tabControl1.SelectedIndex = 0; + this.tabControl1.Size = new System.Drawing.Size(674, 256); + this.tabControl1.TabIndex = 0; + // + // tabPage1 + // + this.tabPage1.Controls.Add(this.dataGridView1); + this.tabPage1.ImageIndex = 0; + this.tabPage1.Location = new System.Drawing.Point(4, 23); + this.tabPage1.Name = "tabPage1"; + this.tabPage1.Padding = new System.Windows.Forms.Padding(3); + this.tabPage1.Size = new System.Drawing.Size(666, 229); + this.tabPage1.TabIndex = 0; + this.tabPage1.Text = "结果"; + this.tabPage1.UseVisualStyleBackColor = true; + // + // dataGridView1 + // + this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.dataGridView1.Dock = System.Windows.Forms.DockStyle.Fill; + this.dataGridView1.Location = new System.Drawing.Point(3, 3); + this.dataGridView1.Name = "dataGridView1"; + this.dataGridView1.RowTemplate.Height = 23; + this.dataGridView1.Size = new System.Drawing.Size(660, 223); + this.dataGridView1.TabIndex = 0; + // + // tabPage2 + // + this.tabPage2.Controls.Add(this.richTextBox1); + this.tabPage2.ImageIndex = 1; + this.tabPage2.Location = new System.Drawing.Point(4, 23); + this.tabPage2.Name = "tabPage2"; + this.tabPage2.Padding = new System.Windows.Forms.Padding(3); + this.tabPage2.Size = new System.Drawing.Size(666, 229); + this.tabPage2.TabIndex = 1; + this.tabPage2.Text = "消息"; + this.tabPage2.UseVisualStyleBackColor = true; + // + // richTextBox1 + // + this.richTextBox1.Dock = System.Windows.Forms.DockStyle.Fill; + this.richTextBox1.Location = new System.Drawing.Point(3, 3); + this.richTextBox1.Name = "richTextBox1"; + this.richTextBox1.Size = new System.Drawing.Size(660, 223); + this.richTextBox1.TabIndex = 0; + this.richTextBox1.Text = ""; + // + // imageList1 + // + this.imageList1.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageList1.ImageStream"))); + this.imageList1.TransparentColor = System.Drawing.Color.Transparent; + this.imageList1.Images.SetKeyName(0, "grid.png"); + this.imageList1.Images.SetKeyName(1, "dbmsg.png"); + // + // cmsDock + // + this.cmsDock.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.menuItemSave, + this.menuItemSaveAs, + this.toolStripSeparator3, + this.menuItemClose, + this.menuItemCloseOther, + this.menuItemCloseAll, + this.toolStripSeparator4, + this.menuItemOpenFolder}); + this.cmsDock.Name = "cmsDock"; + this.cmsDock.Size = new System.Drawing.Size(167, 148); + // + // menuItemSave + // + this.menuItemSave.Image = ((System.Drawing.Image)(resources.GetObject("menuItemSave.Image"))); + this.menuItemSave.Name = "menuItemSave"; + this.menuItemSave.Size = new System.Drawing.Size(166, 22); + this.menuItemSave.Text = "保存"; + this.menuItemSave.Click += new System.EventHandler(this.menuItemSave_Click); + // + // menuItemSaveAs + // + this.menuItemSaveAs.Name = "menuItemSaveAs"; + this.menuItemSaveAs.Size = new System.Drawing.Size(166, 22); + this.menuItemSaveAs.Text = "另存为..."; + this.menuItemSaveAs.Click += new System.EventHandler(this.menuItemSaveAs_Click); + // + // toolStripSeparator3 + // + this.toolStripSeparator3.Name = "toolStripSeparator3"; + this.toolStripSeparator3.Size = new System.Drawing.Size(163, 6); + // + // menuItemClose + // + this.menuItemClose.Image = ((System.Drawing.Image)(resources.GetObject("menuItemClose.Image"))); + this.menuItemClose.Name = "menuItemClose"; + this.menuItemClose.Size = new System.Drawing.Size(166, 22); + this.menuItemClose.Text = "关闭"; + this.menuItemClose.Click += new System.EventHandler(this.menuItemClose_Click); + // + // menuItemCloseOther + // + this.menuItemCloseOther.Name = "menuItemCloseOther"; + this.menuItemCloseOther.Size = new System.Drawing.Size(166, 22); + this.menuItemCloseOther.Text = "除此之外全部关闭"; + this.menuItemCloseOther.Click += new System.EventHandler(this.menuItemCloseOther_Click); + // + // menuItemCloseAll + // + this.menuItemCloseAll.Name = "menuItemCloseAll"; + this.menuItemCloseAll.Size = new System.Drawing.Size(166, 22); + this.menuItemCloseAll.Text = "全部关闭"; + this.menuItemCloseAll.Click += new System.EventHandler(this.menuItemCloseAll_Click); + // + // toolStripSeparator4 + // + this.toolStripSeparator4.Name = "toolStripSeparator4"; + this.toolStripSeparator4.Size = new System.Drawing.Size(163, 6); + // + // menuItemOpenFolder + // + this.menuItemOpenFolder.Name = "menuItemOpenFolder"; + this.menuItemOpenFolder.Size = new System.Drawing.Size(166, 22); + this.menuItemOpenFolder.Text = "打开所在文件夹"; + this.menuItemOpenFolder.Click += new System.EventHandler(this.menuItemOpenFolder_Click); + // + // QueryAnalyzer + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(674, 519); + this.Controls.Add(this.splitContainer1); + this.DockAreas = WeifenLuo.WinFormsUI.Docking.DockAreas.Document; + this.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "QueryAnalyzer"; + this.TabPageContextMenuStrip = this.cmsDock; + this.Text = "查询分析器"; + this.Load += new System.EventHandler(this.QueryAnalyzer_Load); + this.Activated += new System.EventHandler(this.QueryAnalyzer_Activated); + this.splitContainer1.Panel1.ResumeLayout(false); + this.splitContainer1.Panel2.ResumeLayout(false); + this.splitContainer1.ResumeLayout(false); + this.cms.ResumeLayout(false); + this.tabControl1.ResumeLayout(false); + this.tabPage1.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit(); + this.tabPage2.ResumeLayout(false); + this.cmsDock.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.SplitContainer splitContainer1; + private System.Windows.Forms.TabControl tabControl1; + private System.Windows.Forms.TabPage tabPage1; + private System.Windows.Forms.TabPage tabPage2; + private System.Windows.Forms.DataGridView dataGridView1; + private System.Windows.Forms.RichTextBox richTextBox1; + private ICSharpCode.TextEditor.TextEditorControl textEditorControl1; + private System.Windows.Forms.ContextMenuStrip cmsDock; + private System.Windows.Forms.ToolStripMenuItem menuItemSave; + private System.Windows.Forms.ToolStripMenuItem menuItemSaveAs; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator3; + private System.Windows.Forms.ToolStripMenuItem menuItemClose; + private System.Windows.Forms.ToolStripMenuItem menuItemCloseOther; + private System.Windows.Forms.ToolStripMenuItem menuItemCloseAll; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator4; + private System.Windows.Forms.ToolStripMenuItem menuItemOpenFolder; + private System.Windows.Forms.ContextMenuStrip cms; + private System.Windows.Forms.ToolStripMenuItem menuItemUndo; + private System.Windows.Forms.ToolStripMenuItem menuItemRedo; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator5; + private System.Windows.Forms.ToolStripMenuItem menuItemCut; + private System.Windows.Forms.ToolStripMenuItem menuItemCopy; + private System.Windows.Forms.ToolStripMenuItem menuItemPaste; + private System.Windows.Forms.ToolStripMenuItem menuItemDelete; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; + private System.Windows.Forms.ToolStripMenuItem menuItemSelectAll; + private System.Windows.Forms.ImageList imageList1; + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/ToolForm/QueryAnalyzer.resx b/src/Kalman.Studio/ToolForm/QueryAnalyzer.resx new file mode 100644 index 0000000..827c027 --- /dev/null +++ b/src/Kalman.Studio/ToolForm/QueryAnalyzer.resx @@ -0,0 +1,304 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 112, 17 + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAURJREFUOE+1kDFy + gzAQRX2E3CDcAG6AuqSD0qlQ6Q51phNlOijpUGc61Dmd1aYyN7BuwN5gs4uTGRg7cVxYMzsqdv/7f3e1 + euSr9qOsLDjzAb514PoD1P1hDP7lycLaAtLvdXcuBlkHcBVSd4Dt5xgxverBsDirAYQaUGwshpmFuPBg + 9gAE8YsURHwqCWAcDHo3liyWtUehHIkdi12cWy+kwfR9mlsCmKYaj6oBVObbWVoUVGHWK+4nug/CtZlS + 6B24izuwY1qy8xkSvlaWxGI+yGl+BaSlx0idIZyEgbodLwCJpgQd2IsEouCd+WAOI4oeranSGn8GKU3A + Pb5B3pymtf58fNj5wPNLJdiEV7ylvdqPN25g90Qfb7vPCVk1BnF+lJO4GOBu92R7EixOiwHDtz69G0AJ + ZLw9lnTExU3uBj1M8AXZCvHw6pRRNAAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAUhJREFUOE/FkTFu + wkAQRTkCN4Ab2Dewu9CtSzpvSWd3cbfpQmeXdN4udN4upGLbVPgG7A3232AzY6TIyEEEKVJG2mrnv/9n + Zjb7q+qOftkd0bQWVh/g6s5L1fr5r/gsNhZgodqPngYIIu9CSOz0O5BUDlFukG5MSAqLvAEKghStzxjS + fvo4LfswAWoCZFuEeK1JaBxBLINiaYJsEPIdHEEk9fXpxgZKfD2aeoNl98VT7YTqluwQ5V0ZrTXiTAfx + CldqhHJHJgSdJBgB7PiTIGm0qg2LOUn2ckk5BexhhAIiSjD+rD983BwuzoO4dCHOmimg2J3Lyw5MWCTq + ez5eGM/MsdmZxcvVDwB25Yhp5QLtIR2nmCzs1k2FOg0pko3t7979JqTqMUCKk8xrP1zjoYpEOxeV68UW + EM/nq1EeAgnlM0ogHxL9W/MXM4DmfcnD838AAAAASUVORK5CYII= + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAW1JREFUOE+lk71O + wzAQx+EJ2jdI3yDeOjpTV3uiozMg6NYMqLAlA2rZ7I1uzgRj/AbJyJa+QbIxxhvj4TMg9SMtRUQ6KTn/ + 73cfOV8CwMW/HgRsW1GUSr8W7ZaPNE1j06U0+1qffN8pdUHUOod0pUd41n1AZkwFYp7GZwFQpNYGHCh3 + 78PmvbNxksFgMPDAfTtwoMC1YZXKoa7rrHrbAI+TvwH0S2mwDfmsqyRTwJiwfdl7Z4BOKXWEgVg6ZqcT + 1jvAowA8cEOzGMxnGTDRP8BegHjsiFh2hmctsEVt+MMG2H1tneX0puQnh+iDZWdZ2lg61TZksqXz0iIk + mlVAhVYnAWzZGP7UOrEBwhU4wE8FI3pbxOg7CcBgl53Q64J8A4a+hbua0CuZkCj5BYB9o1hgtsyL2aLc + RLGrKIohCMKD37mzSG5oX2JXajBm/j5g6eFY2MBZyFIsYSdm58OLp7LFgHByKD57lY9tXZ//E6n3h7WO + zjr9AAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAUBJREFUOE+tU6Fu + wzAU7KfkD5pPCIyGwjbWsA0aDgaO1TBjhmE1LJthoGFYDQcNx27vbK1pIm2ZtJ10JPK7u3dP2e3+CusC + Mn3m2cNYj+PrqfmVNofXMNah7Qz2d4dyU4Sua+jBwY0erdLbIoxMuAmQ5PAhQhsLO0ZZKdOc5ZvNPBwv + 1SIV417xAcQIhHcZFIE1uiGifHLYP77NIkbiEmYEtDh1NkCZACPOa6g+C5cPFvv7UxbhvkRM7jG5cw1z + zuVqm+mniFaHNEwWjUEWkH05/OVMd9V76GF5Hb6huPMiLmUtBSQtXf0U5IFwDOhEiODeqg/Jvel8YhKo + bxKUdYs1lZ7Py2JpQPd0FSm+qHVe4Tu0L1ng1vmaQHrbFGieXeqGcWc68Gosvqg2ElTKLRpnaXRNlOGi + 6n5eYfMf+K8Hn1Gm2tY78ARPAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAY9JREFUOE+1k612 + 4zAUhP0IeYQ8gmGhYFkFwyoYFsGyijUsgoaCYRUMFDQUDBQMFCybzpXqNv3ZLdizOmeODDzf3B97GP7H + SdFBFIPD7v5u/GvG8/Fg49FjUfAG9RKaytnDbhX83lKu3YennfoEFGOtEaBqDQiTbfdue5fz7OCshjMj + aiL4tIY1Gt8AYhb5vUGeCbx4pjuU2SBOGmajENwa2Q+wm6+A4JsZTPXOMFGkWfqbmGgJ8LYDzK36XEFY + ANJ3YXq2yGH1oYnPNC5SN+MXwOT60ArvM/vPmgWt4ANbmiKcp/YB1gWYBw9j/Q8AST5zSDPNiQMTAM3v + 54Ud1opyqdBbB23cByR4SaZm1c2nFUoYWrKcEFPXMSEXAmhOc4bSpkNkv9L3Yq7HoQNYNq6S87ki5QK9 + sc2sbjWU4kDl46gzxWQpvRCQJ66LPUvZ1xXIXGLKfT6UGtcEODH3FV1LBiY9L8lpLs0cT13vgMPjTsn+ + 5QszWkGrsZFl2tLzkvbT3Sr405Fpywu/6Z9/5lcMCPZ7KYCY8wAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAVFJREFUOE+tkjFO + w0AQRS1RQLfbEdHsCiHF3WyHRTPbJdBMjpAj5Ag+go+QMqWPkCO4TYHkI/gGyx9DIuIEbCQsjWLt/P/m + Z7w3GR55k5A/5rv8KW8P74dWz/708ILXMcbEzJ28yuo3s4h4XvLmTAPjGlWHIiYFyULKIcQRWWiiLKXD + 73YI8NpUiAJ6iEiNsiokZstL6XtUUEWA/ZgSkM03yJZfOHDBVW8mqjTJ6H4ACahG/xJMnZbLqZ5kPtJh + iiGEFD8hrXMTJp/Mz+QxsVFAXwqZ07TPi2m92echEWKbBxecc7WCcH7++YbLwBQPceO919h7vFtjTF94 + 1+13DpqrSyRiFW3dzOnSWlQ4Co8QnDUKugpAY2VnPml0TCnVdHGZNOHctehdpjD3prTWJoD25vaK4ItG + uBMAnNKdhsAYsrtM48XMZGOXZaw/etf+T/ABASBzBnL8dsYAAAAASUVORK5CYII= + + + + 182, 17 + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj0yLjAuMC4w + LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 + ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAA6 + CQAAAk1TRnQBSQFMAgEBAgEAAQQBAAEEAQABEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo + AwABQAMAARADAAEBAQABCAYAAQQYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA + AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5 + AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA + AWYDAAGZAwABzAIAATMDAAIzAgABMwFmAgABMwGZAgABMwHMAgABMwH/AgABZgMAAWYBMwIAAmYCAAFm + AZkCAAFmAcwCAAFmAf8CAAGZAwABmQEzAgABmQFmAgACmQIAAZkBzAIAAZkB/wIAAcwDAAHMATMCAAHM + AWYCAAHMAZkCAALMAgABzAH/AgAB/wFmAgAB/wGZAgAB/wHMAQABMwH/AgAB/wEAATMBAAEzAQABZgEA + ATMBAAGZAQABMwEAAcwBAAEzAQAB/wEAAf8BMwIAAzMBAAIzAWYBAAIzAZkBAAIzAcwBAAIzAf8BAAEz + AWYCAAEzAWYBMwEAATMCZgEAATMBZgGZAQABMwFmAcwBAAEzAWYB/wEAATMBmQIAATMBmQEzAQABMwGZ + AWYBAAEzApkBAAEzAZkBzAEAATMBmQH/AQABMwHMAgABMwHMATMBAAEzAcwBZgEAATMBzAGZAQABMwLM + AQABMwHMAf8BAAEzAf8BMwEAATMB/wFmAQABMwH/AZkBAAEzAf8BzAEAATMC/wEAAWYDAAFmAQABMwEA + AWYBAAFmAQABZgEAAZkBAAFmAQABzAEAAWYBAAH/AQABZgEzAgABZgIzAQABZgEzAWYBAAFmATMBmQEA + AWYBMwHMAQABZgEzAf8BAAJmAgACZgEzAQADZgEAAmYBmQEAAmYBzAEAAWYBmQIAAWYBmQEzAQABZgGZ + AWYBAAFmApkBAAFmAZkBzAEAAWYBmQH/AQABZgHMAgABZgHMATMBAAFmAcwBmQEAAWYCzAEAAWYBzAH/ + AQABZgH/AgABZgH/ATMBAAFmAf8BmQEAAWYB/wHMAQABzAEAAf8BAAH/AQABzAEAApkCAAGZATMBmQEA + AZkBAAGZAQABmQEAAcwBAAGZAwABmQIzAQABmQEAAWYBAAGZATMBzAEAAZkBAAH/AQABmQFmAgABmQFm + ATMBAAGZATMBZgEAAZkBZgGZAQABmQFmAcwBAAGZATMB/wEAApkBMwEAApkBZgEAA5kBAAKZAcwBAAKZ + Af8BAAGZAcwCAAGZAcwBMwEAAWYBzAFmAQABmQHMAZkBAAGZAswBAAGZAcwB/wEAAZkB/wIAAZkB/wEz + AQABmQHMAWYBAAGZAf8BmQEAAZkB/wHMAQABmQL/AQABzAMAAZkBAAEzAQABzAEAAWYBAAHMAQABmQEA + AcwBAAHMAQABmQEzAgABzAIzAQABzAEzAWYBAAHMATMBmQEAAcwBMwHMAQABzAEzAf8BAAHMAWYCAAHM + AWYBMwEAAZkCZgEAAcwBZgGZAQABzAFmAcwBAAGZAWYB/wEAAcwBmQIAAcwBmQEzAQABzAGZAWYBAAHM + ApkBAAHMAZkBzAEAAcwBmQH/AQACzAIAAswBMwEAAswBZgEAAswBmQEAA8wBAALMAf8BAAHMAf8CAAHM + Af8BMwEAAZkB/wFmAQABzAH/AZkBAAHMAf8BzAEAAcwC/wEAAcwBAAEzAQAB/wEAAWYBAAH/AQABmQEA + AcwBMwIAAf8CMwEAAf8BMwFmAQAB/wEzAZkBAAH/ATMBzAEAAf8BMwH/AQAB/wFmAgAB/wFmATMBAAHM + AmYBAAH/AWYBmQEAAf8BZgHMAQABzAFmAf8BAAH/AZkCAAH/AZkBMwEAAf8BmQFmAQAB/wKZAQAB/wGZ + AcwBAAH/AZkB/wEAAf8BzAIAAf8BzAEzAQAB/wHMAWYBAAH/AcwBmQEAAf8CzAEAAf8BzAH/AQAC/wEz + AQABzAH/AWYBAAL/AZkBAAL/AcwBAAJmAf8BAAFmAf8BZgEAAWYC/wEAAf8CZgEAAf8BZgH/AQAC/wFm + AQABIQEAAaUBAANfAQADdwEAA4YBAAOWAQADywEAA7IBAAPXAQAD3QEAA+MBAAPqAQAD8QEAA/gBAAHw + AfsB/wEAAaQCoAEAA4ADAAH/AgAB/wMAAv8BAAH/AwAB/wEAAf8BAAL/AgAD/xoAAbwBHAFzAUsCcwG8 + MgAB9wRmAWwB7QEcAXQBeQGaAXkBdAFzIQAB9w1mAwAB9wH/AvACvAHyAXQDmgF6AXkBSyEAAfcBvAMH + A+8DtQL3AWYDAAH3A/8B9AHzAfQBdAEaA5oBeQFLIQAB9wP/AQcB/wL0AbUCGQEJAfcBZgMAAfcB/wS1 + AfABdAHDARoCmgF5AUshAAH3A/8BBwL/AfQB7wMZAbUBZgMAAfcG/wEcAcMBGgOaAUshAAH3AfACvAQH + A+8CtQFmAwABtQH/A7UBuwHwAXMBHAR0AXMhAAG1A/8BvAP/AQcC9AEZAbUBZgMAAbUG/wFzAZkBGgKa + AXkBcyEAAbUD/wG8A/8BBwH/AvQBtQFmAwAB7wH/ArsB7wG7AbwBGwGZAhwBdAEcAZkhAAHvAfEC8AO8 + BAcC7wFmAwABuwj/AfMB7yQAAbsD/wHwA/8BBwP/Ae8BZgMAAbsB/wEHA7sC/wHyAfEBriQAAbsD/wHw + A/8BvAP/AQcBZgMAAQcG/wG1AxIkAAXWBLQFrQMAAQcB/wQHAf8BtQG8AWYBByQAAdYDCQPcAtYE1QGt + AwABCQb/AbUBZgEHJQAG1gHVBLQDrQMABQkCBwG7AQdlAAFCAU0BPgcAAT4DAAEoAwABQAMAARADAAEB + AQABAQUAAYAXAAP/AQAD/wGABAAC/wHABQABgAEBAcAFAAGAAQEBwAUAAYABAQHABQABgAEBAcAFAAGA + AQEBwAUAAYABAQHABQABgAEBAcAFAAGAAQEBwAEHBAABgAEBAcABBwQAAYABAQHAAQcEAAGAAQEBwAEH + BAABgAEBAcABDwQAAYABAQHAAR8EAAT/BAAL + + + + 17, 17 + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAW9JREFUOE+tU6F2 + AjEQ5BP6CXzCSWQkMhIZSVUjkZHIk8hIZCQyEteTlZGVkbjtzB5w4Upr2n1vHu9dMrMzu2Gx+I9KpyqK + dMWxSozAoUjfX7EvEgKwG8QTfpB7bxJzFlyWX6teROwmi9skxXeBff1RgORaqxibpeschBqBCMt0QIvP + 6kYun1U6mxCjiLVxcsC8FPA4mFdLHj4gsE6a/1EAw1IBHLQ1J+ehyNJEcduZACdNAR7c6hk5n4u8rCDg + sth1P0XosaJ8EqwSIg7qvIBp68CQmbbZ+U7mWSvA4aUEASBGrrNKwEbGvReN5uFOO4NsIfoogIeRjhPZ + bjwuNnAe8UJDhoAJUwS+rLYzyXgk0hkjnPxQqrhdQFd2JjnOBGAxHvAOrrYpQLLf9VJA5v596PGNxDj+ + rloHyKe5kXnJgXUGA82KnAfJZ67NKlGBTZiVuhzr7fXdui0HlPSB3IFJc1gKZGbXEXDYCvzlH/0F0FE7 + DNsH26sAAAAASUVORK5CYII= + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAVJJREFUOE+lkyFy + wzAURN0b+AiChYZl1Q2qI/gGEQyrWcMiGCiWsBgUBBqWxTDQMFA32O63bEdJ3c546pkdz3j+vl19jZ8A + ZP96BLBE2liM6sOXmGV2NL++rcoecP5cFfXBIdVxv9W/gQVAsxneOhNjuNZAqBFEHWHe4bh/r/5qR0gh + kEyG5+T53e9E1Q9tP2L9CYDQsEGq2AhXTzmArXBhodZyrERlxR+Xn0lSNN+OgZAYu8HYlhwzaHfqAcCK + KeAuVcwXpor5izoZNC6HLU3SYADIAmMyJZVnzKHWaDY5SpMCnDRIznxnZroks7qYw6FAXeUwWm553AEB + /TVOCxtrJ+ZTNHc+AvRLcQO4zQhIa8+YBcAF+rVC8axSAIc7z0VZdFxSV3OQw61XaGhonGLqqBzOKiiV + 3wOqtYXl3ZbcrjG6rygpMqjyeU07WPozPc5/A06Irjc9Sw2jAAAAAElFTkSuQmCC + + + + + AAABAAEAEBAAAAAAAABoBQAAFgAAACgAAAAQAAAAIAAAAAEACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA/fr5APru6QDny74A9+XdAPnq4wD67+oA/PPvAN6/rwDz2MsA9dzQAPbh1wD46uMA+/PvAP33 + 9AD89vMA/vr4AP/9/ADHs6gAyLasAPfm3QD56+MA4NPMAPrv6QD88+4AkXhoAK6YiwC5pJcA+/PuAIdt + WwCWf28ApI1+AKWOfwChi3wArJeJALOfkgC6ppgAwKyeAL+rnQDFsaQAvq2hAMOypgDw6uYA/fr4AGNJ + NQBsUT0AcVdEAJeAbwCdhnUAnIV0AKONfQCok4MAq5aGAKyXiAC0n5AAs56PALKdjgCzn5AAx7erAJR9 + awCrl4cAuaaXALimmACzopQAvqyeAMKypQC4qJoA/v38AMz//wDO//8A0///ALX1+gCt8PgAsfP6AKHs + 9wCd6fYAn+r2AKDq9gCR5PYAl+HvAHri+wBs1fIAbM7qAHPa9QBy2PMActjyAHPY8wBMyfEAUc30AFHO + 9ABSzvQAELDsABq38AAbte0AHLXsACq68ABSyvIAir3OAACn7AAAo+cAAKTnAACj5gAgptoAVJu4AFOa + twBVmbUAWZ25AFyfugBzo7YAAJ/mAAiY1QBVmbYAWJu4AC10nAAtc5sALXSbAC1zmgAudJsAMHadADV0 + mABPdY8AUHaQAP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAZ3l5eHkAAAAuLCwsLCwsZ1dPUmZudwAAHQMICAgICGhZSlNcYnQAABkXFRQL + CglwWUxVXWRyAAAeHDY1IDA7aVpNVF1jcwAAMQ8NBgwEC2paTVZeZXUAACEQJDk8HzFvWEtRW21xAAAz + QysPGBcFa1BITmBfdgAAGnolPTc0MmFHREZFSWwAACN6ekMrDg0CYWFhYWEAAAA+eicmGzgWBxcILQAA + AAAAQHp6enpDAS8tLS0AAAAAAEF6enp6ehEvKi8AAAAAAAA6enp6enp6Ly8AAAAAAAAAEhMpKEI/Ii8A + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+DohSAAW9wgAFlkYABh4SAAejPgAGxuoAB2NaAAQAAgAF6MoAD + OB2AD1EWgA8KE4Af6c+AP7G6gH/Z1///AAA= + + + \ No newline at end of file diff --git a/src/Kalman.Studio/ToolForm/StringConnector.Designer.cs b/src/Kalman.Studio/ToolForm/StringConnector.Designer.cs new file mode 100644 index 0000000..0c9d979 --- /dev/null +++ b/src/Kalman.Studio/ToolForm/StringConnector.Designer.cs @@ -0,0 +1,237 @@ +namespace Kalman.Studio +{ + partial class StringConnector + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(StringConnector)); + this.splitContainer1 = new System.Windows.Forms.SplitContainer(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.rtb2 = new System.Windows.Forms.RichTextBox(); + this.groupBox2 = new System.Windows.Forms.GroupBox(); + this.rtb1 = new System.Windows.Forms.RichTextBox(); + this.btnReturn = new System.Windows.Forms.Button(); + this.txtChars = new System.Windows.Forms.TextBox(); + this.label4 = new System.Windows.Forms.Label(); + this.label3 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.btnBuild = new System.Windows.Forms.Button(); + this.rtb = new System.Windows.Forms.RichTextBox(); + this.label1 = new System.Windows.Forms.Label(); + this.splitContainer1.Panel1.SuspendLayout(); + this.splitContainer1.Panel2.SuspendLayout(); + this.splitContainer1.SuspendLayout(); + this.groupBox1.SuspendLayout(); + this.groupBox2.SuspendLayout(); + this.SuspendLayout(); + // + // splitContainer1 + // + this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill; + this.splitContainer1.FixedPanel = System.Windows.Forms.FixedPanel.Panel2; + this.splitContainer1.Location = new System.Drawing.Point(3, 3); + this.splitContainer1.Margin = new System.Windows.Forms.Padding(10); + this.splitContainer1.Name = "splitContainer1"; + // + // splitContainer1.Panel1 + // + this.splitContainer1.Panel1.Controls.Add(this.groupBox1); + this.splitContainer1.Panel1.Controls.Add(this.groupBox2); + // + // splitContainer1.Panel2 + // + this.splitContainer1.Panel2.Controls.Add(this.btnReturn); + this.splitContainer1.Panel2.Controls.Add(this.txtChars); + this.splitContainer1.Panel2.Controls.Add(this.label4); + this.splitContainer1.Panel2.Controls.Add(this.label3); + this.splitContainer1.Panel2.Controls.Add(this.label2); + this.splitContainer1.Panel2.Controls.Add(this.btnBuild); + this.splitContainer1.Panel2.Controls.Add(this.rtb); + this.splitContainer1.Panel2.Controls.Add(this.label1); + this.splitContainer1.Size = new System.Drawing.Size(886, 567); + this.splitContainer1.SplitterDistance = 539; + this.splitContainer1.TabIndex = 0; + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.rtb2); + this.groupBox1.Dock = System.Windows.Forms.DockStyle.Fill; + this.groupBox1.Location = new System.Drawing.Point(0, 269); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(539, 298); + this.groupBox1.TabIndex = 3; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "输出代码"; + // + // rtb2 + // + this.rtb2.Dock = System.Windows.Forms.DockStyle.Fill; + this.rtb2.Location = new System.Drawing.Point(3, 17); + this.rtb2.Name = "rtb2"; + this.rtb2.Size = new System.Drawing.Size(533, 278); + this.rtb2.TabIndex = 0; + this.rtb2.Text = ""; + // + // groupBox2 + // + this.groupBox2.Controls.Add(this.rtb1); + this.groupBox2.Dock = System.Windows.Forms.DockStyle.Top; + this.groupBox2.Location = new System.Drawing.Point(0, 0); + this.groupBox2.Margin = new System.Windows.Forms.Padding(5); + this.groupBox2.Name = "groupBox2"; + this.groupBox2.Size = new System.Drawing.Size(539, 269); + this.groupBox2.TabIndex = 1; + this.groupBox2.TabStop = false; + this.groupBox2.Text = "原始文本"; + // + // rtb1 + // + this.rtb1.Dock = System.Windows.Forms.DockStyle.Fill; + this.rtb1.Location = new System.Drawing.Point(3, 17); + this.rtb1.Name = "rtb1"; + this.rtb1.Size = new System.Drawing.Size(533, 249); + this.rtb1.TabIndex = 0; + this.rtb1.Text = ""; + // + // btnReturn + // + this.btnReturn.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.btnReturn.Location = new System.Drawing.Point(263, 443); + this.btnReturn.Name = "btnReturn"; + this.btnReturn.Size = new System.Drawing.Size(75, 23); + this.btnReturn.TabIndex = 8; + this.btnReturn.Text = "退出"; + this.btnReturn.UseVisualStyleBackColor = true; + this.btnReturn.Click += new System.EventHandler(this.btnReturn_Click); + // + // txtChars + // + this.txtChars.Location = new System.Drawing.Point(6, 416); + this.txtChars.Name = "txtChars"; + this.txtChars.Size = new System.Drawing.Size(332, 21); + this.txtChars.TabIndex = 7; + this.txtChars.Text = "\\,\\\\|\",\\\""; + // + // label4 + // + this.label4.AutoSize = true; + this.label4.Location = new System.Drawing.Point(6, 398); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(263, 12); + this.label4.TabIndex = 6; + this.label4.Text = "替换特殊字符,请把转义字符前缀\"\\\"放在最前面"; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.ForeColor = System.Drawing.Color.Red; + this.label3.Location = new System.Drawing.Point(8, 503); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(269, 12); + this.label3.TabIndex = 5; + this.label3.Text = "模板中含有该参数的行将会根据原始文本逐行遍历"; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.ForeColor = System.Drawing.Color.Red; + this.label2.Location = new System.Drawing.Point(8, 481); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(125, 12); + this.label2.TabIndex = 4; + this.label2.Text = "参数格式:$(RowText)"; + // + // btnBuild + // + this.btnBuild.Location = new System.Drawing.Point(165, 443); + this.btnBuild.Name = "btnBuild"; + this.btnBuild.Size = new System.Drawing.Size(75, 23); + this.btnBuild.TabIndex = 3; + this.btnBuild.Text = "生成"; + this.btnBuild.UseVisualStyleBackColor = true; + this.btnBuild.Click += new System.EventHandler(this.btnBuild_Click); + // + // rtb + // + this.rtb.Location = new System.Drawing.Point(6, 19); + this.rtb.Name = "rtb"; + this.rtb.Size = new System.Drawing.Size(332, 373); + this.rtb.TabIndex = 2; + this.rtb.Text = ""; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(8, 4); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(53, 12); + this.label1.TabIndex = 0; + this.label1.Text = "编辑模板"; + // + // StringConnector + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.btnReturn; + this.ClientSize = new System.Drawing.Size(892, 573); + this.Controls.Add(this.splitContainer1); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "StringConnector"; + this.Padding = new System.Windows.Forms.Padding(3); + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "字符串拼接工具"; + this.Load += new System.EventHandler(this.StringConnector_Load); + this.splitContainer1.Panel1.ResumeLayout(false); + this.splitContainer1.Panel2.ResumeLayout(false); + this.splitContainer1.Panel2.PerformLayout(); + this.splitContainer1.ResumeLayout(false); + this.groupBox1.ResumeLayout(false); + this.groupBox2.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.SplitContainer splitContainer1; + private System.Windows.Forms.GroupBox groupBox2; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.RichTextBox rtb2; + private System.Windows.Forms.RichTextBox rtb1; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Button btnBuild; + private System.Windows.Forms.RichTextBox rtb; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.TextBox txtChars; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.Button btnReturn; + + + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/ToolForm/StringConnector.cs b/src/Kalman.Studio/ToolForm/StringConnector.cs new file mode 100644 index 0000000..78ddabd --- /dev/null +++ b/src/Kalman.Studio/ToolForm/StringConnector.cs @@ -0,0 +1,91 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace Kalman.Studio +{ + public partial class StringConnector : DockableForm + { + static readonly string paramFormat = "$(RowText)"; + + public StringConnector() + { + InitializeComponent(); + } + + private void StringConnector_Load(object sender, EventArgs e) + { + rtb.AppendText("StringBuilder sb = new StringBuilder();\r\n"); + rtb.AppendText(string.Format("sb.AppendLine(\"{0}\");", paramFormat)); + + rtb1.AppendText("这是一个字符串拼接工具" + Environment.NewLine); + rtb1.AppendText("请在左边文本框编辑模板" + Environment.NewLine); + rtb1.AppendText("模板文本中参数\"$(RowText)\"将会被原始文本中的每行文本所替换" + Environment.NewLine); + rtb1.AppendText("请在右下方文本框中输入要替换的字符" + Environment.NewLine); + rtb1.AppendText("格式:字符1,替换字符1|字符2,替换字符2|..." + Environment.NewLine); + rtb1.AppendText("如果要替换转义符号,请将转义符号放在最前面" + Environment.NewLine); + rtb1.AppendText("如:右下方文本框中的示例中就把\"\\,\\\\\"放在最前面" + Environment.NewLine); + rtb1.AppendText("点击生成按钮,左下方文本框中会输出根据模板格式化后的代码"); + //rtb.AppendText("" + Environment.NewLine); + //rtb.AppendText("" + Environment.NewLine); + } + + private void btnBuild_Click(object sender, EventArgs e) + { + rtb2.Clear(); + if (rtb.Text.Trim().Length == 0) return; + + Dictionary dic = new Dictionary(); + if (txtChars.Text.Contains(","))//保证至少有一个替换项 + { + string[] chars = txtChars.Text.Split('|'); + foreach (string s in chars) + { + dic.Add(s.Split(',')[0], s.Split(',')[1]); + } + } + + string[] ss1 = rtb1.Lines; //原始文本 + string[] ss = rtb.Lines; //模板 + + foreach (string s in ss) + { + if (s.Contains(paramFormat)) + { + foreach (string s1 in ss1) + { + string str = s1; + foreach (KeyValuePair kvp in dic) + { + str = str.Replace(kvp.Key, kvp.Value); + } + + str = s.Replace(paramFormat, str); + + rtb2.AppendText(str); + rtb2.AppendText(Environment.NewLine); + } + } + else + { + rtb2.AppendText(s); + rtb2.AppendText(Environment.NewLine); + } + } + + + + } + + private void btnReturn_Click(object sender, EventArgs e) + { + this.Close(); + } + + } +} diff --git a/src/Kalman.Studio/ToolForm/StringConnector.resx b/src/Kalman.Studio/ToolForm/StringConnector.resx new file mode 100644 index 0000000..5d1a811 --- /dev/null +++ b/src/Kalman.Studio/ToolForm/StringConnector.resx @@ -0,0 +1,145 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAQAAAAQAAAAKAAAACAAAAAIAAAACAAAAEQAAADQAAABRAAAATQAAADIAAAAhAAAAGwAA + AA4AAAADAAAAAgAAAA0AAAAjAAAANwAAADUAAAAjAAAAFg98HWIgpzbKNLNS2QwuE5MAAABwBQ4IaAAA + AFsAAAA7AAAAFgAAAAsACjM3K0KemTM9ZZcFBgp7AAAAYxFWHmQcwTH2JclB/zTVVf8ywFDtHKMx4lHd + e+4scUSuAAAAbgAAADgAK9dNACzq0zlg//95lP39cYrq8UdRiLofXTWZJs89/xzCNP8lyED/J8tE/zfY + Wf9M6Xb/WfCI+zKBTasAAABFBDX5ngk6//8hTf//ZIP//2+M//9whO30IU5BrTXZU/kbwDL/GL4v/x7D + N/8pzEb/P99k/0necfZKxnHQAAAAORA/90MWRf/+HUn//01x//9igf//aob//0RbxehEzHr4MNdL/wy1 + Hf8hxjv/J8tD/zHTT/891mH4Dy0YiAAAADgYQuYKIEz83yZR//87Yv//VHb//1x+//9QZPf/RZW0/1D0 + dv8dwjT/ELgj/zTWVf8sz0r/MtJR/hVQIqAAAABHAAAAACpT93sxWv//OGD//0Rq//9Ncf//VHP//0Ba + 5f9UyaX/WP1+/x7DNv8cwjT/J8pE/yXJQf8bfC64AAAATAAAAAA1XPUzPGP++0Jo//86Yf//PmT//0lu + //8xV///J07o/1bFrP9f/on/MNhJ/xa8K/8awDL/HKUyxAAAADQAAAAAAAAAAEZq+tBPcv//P2X//y5Y + //88Y///FkL5/ytP+/9CXe//SY3M/1nNqPhP5XfdRN5r3iWqPWoAAAAQAAAAAAAAAABNb/d8Wnr//1B0 + //8kUP//K1b//yhQ+P81W/r/Rmv//0Zh//8uRZKpAAAALDWUUA8AAAABAAAAAQAAAAAAAAAAWXj1NGKA + /vtohv//JlL//xpH//8nUv//Llj//zVd//88YPL0EBc7ZAAAABkAAAABAAAAAAAAAAAAAAAAAAAAAAAA + AABqh/rPeJP//0Rp//8GOP//F0X//yBN//8nUv//JUbGywAAADcAAAAKAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAcoz3foCZ//91kf//GEb//wU3//8HOP//GEb//xAmfXQAAAAaAAAAAgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAH+Y+CeGnv7qkKf//4qi//9vjP//VXf//hY+3K8DCykfAAAABgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAiqD5KI6j9WmZq/Whp7f1uoeX1VwAAAANAAAAAwAAAAAAAAAAAAAAAAAA + AAAAAAAAgAAo/wAAYf8AAFj/AABF/wAARf8AAE73AAAAU4AAAAKAAAAAwAAAAMAA/9fAA///4Af//+AH + ///gD///8B///w== + + + \ No newline at end of file diff --git a/src/Kalman.Studio/ToolForm/StringConvertor/StringConvertor.Designer.cs b/src/Kalman.Studio/ToolForm/StringConvertor/StringConvertor.Designer.cs new file mode 100644 index 0000000..c8e966c --- /dev/null +++ b/src/Kalman.Studio/ToolForm/StringConvertor/StringConvertor.Designer.cs @@ -0,0 +1,407 @@ +namespace Kalman.Studio +{ + partial class StringConvertor + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.splitContainer1 = new System.Windows.Forms.SplitContainer(); + this.gb23 = new System.Windows.Forms.GroupBox(); + this.gb2 = new System.Windows.Forms.GroupBox(); + this.rtb2 = new System.Windows.Forms.RichTextBox(); + this.groupBox6 = new System.Windows.Forms.GroupBox(); + this.btnReplace = new System.Windows.Forms.Button(); + this.btnToLower = new System.Windows.Forms.Button(); + this.btnToUpper = new System.Windows.Forms.Button(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.gb1 = new System.Windows.Forms.GroupBox(); + this.rtb1 = new System.Windows.Forms.RichTextBox(); + this.groupBox4 = new System.Windows.Forms.GroupBox(); + this.rbtnGB2312Encoding = new System.Windows.Forms.RadioButton(); + this.txtEncoding = new System.Windows.Forms.TextBox(); + this.rbtnOtherEncoding = new System.Windows.Forms.RadioButton(); + this.rbtnUTF8Encoding = new System.Windows.Forms.RadioButton(); + this.rbtnUnicodeEncoding = new System.Windows.Forms.RadioButton(); + this.rbtnDefaultEncoding = new System.Windows.Forms.RadioButton(); + this.groupBox3 = new System.Windows.Forms.GroupBox(); + this.button1 = new System.Windows.Forms.Button(); + this.btnRandomString = new System.Windows.Forms.Button(); + this.btnSecure = new System.Windows.Forms.Button(); + this.btnConvert = new System.Windows.Forms.Button(); + this.btnToHash = new System.Windows.Forms.Button(); + this.button4 = new System.Windows.Forms.Button(); + this.splitContainer1.Panel1.SuspendLayout(); + this.splitContainer1.Panel2.SuspendLayout(); + this.splitContainer1.SuspendLayout(); + this.gb23.SuspendLayout(); + this.gb2.SuspendLayout(); + this.groupBox6.SuspendLayout(); + this.groupBox1.SuspendLayout(); + this.gb1.SuspendLayout(); + this.groupBox4.SuspendLayout(); + this.groupBox3.SuspendLayout(); + this.SuspendLayout(); + // + // splitContainer1 + // + this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill; + this.splitContainer1.FixedPanel = System.Windows.Forms.FixedPanel.Panel2; + this.splitContainer1.Location = new System.Drawing.Point(0, 0); + this.splitContainer1.Name = "splitContainer1"; + // + // splitContainer1.Panel1 + // + this.splitContainer1.Panel1.Controls.Add(this.gb23); + this.splitContainer1.Panel1.Controls.Add(this.groupBox1); + // + // splitContainer1.Panel2 + // + this.splitContainer1.Panel2.Controls.Add(this.groupBox3); + this.splitContainer1.Size = new System.Drawing.Size(792, 573); + this.splitContainer1.SplitterDistance = 628; + this.splitContainer1.TabIndex = 0; + // + // gb23 + // + this.gb23.Controls.Add(this.gb2); + this.gb23.Controls.Add(this.groupBox6); + this.gb23.Dock = System.Windows.Forms.DockStyle.Fill; + this.gb23.Location = new System.Drawing.Point(0, 273); + this.gb23.Name = "gb23"; + this.gb23.Size = new System.Drawing.Size(628, 300); + this.gb23.TabIndex = 1; + this.gb23.TabStop = false; + this.gb23.Text = "输出结果"; + // + // gb2 + // + this.gb2.Controls.Add(this.rtb2); + this.gb2.Dock = System.Windows.Forms.DockStyle.Fill; + this.gb2.Location = new System.Drawing.Point(3, 17); + this.gb2.Name = "gb2"; + this.gb2.Size = new System.Drawing.Size(502, 280); + this.gb2.TabIndex = 2; + this.gb2.TabStop = false; + this.gb2.Text = "内容"; + // + // rtb2 + // + this.rtb2.Dock = System.Windows.Forms.DockStyle.Fill; + this.rtb2.Location = new System.Drawing.Point(3, 17); + this.rtb2.Name = "rtb2"; + this.rtb2.Size = new System.Drawing.Size(496, 260); + this.rtb2.TabIndex = 0; + this.rtb2.Text = ""; + this.rtb2.TextChanged += new System.EventHandler(this.rtb2_TextChanged); + // + // groupBox6 + // + this.groupBox6.Controls.Add(this.btnReplace); + this.groupBox6.Controls.Add(this.btnToLower); + this.groupBox6.Controls.Add(this.btnToUpper); + this.groupBox6.Dock = System.Windows.Forms.DockStyle.Right; + this.groupBox6.Location = new System.Drawing.Point(505, 17); + this.groupBox6.Name = "groupBox6"; + this.groupBox6.Size = new System.Drawing.Size(120, 280); + this.groupBox6.TabIndex = 1; + this.groupBox6.TabStop = false; + this.groupBox6.Text = "转换"; + // + // btnReplace + // + this.btnReplace.Location = new System.Drawing.Point(16, 128); + this.btnReplace.Name = "btnReplace"; + this.btnReplace.Size = new System.Drawing.Size(75, 23); + this.btnReplace.TabIndex = 3; + this.btnReplace.Text = "替换"; + this.btnReplace.UseVisualStyleBackColor = true; + this.btnReplace.Click += new System.EventHandler(this.btnReplace_Click); + // + // btnToLower + // + this.btnToLower.Location = new System.Drawing.Point(16, 78); + this.btnToLower.Name = "btnToLower"; + this.btnToLower.Size = new System.Drawing.Size(75, 23); + this.btnToLower.TabIndex = 1; + this.btnToLower.Text = "转小写"; + this.btnToLower.UseVisualStyleBackColor = true; + this.btnToLower.Click += new System.EventHandler(this.btnToLower_Click); + // + // btnToUpper + // + this.btnToUpper.Location = new System.Drawing.Point(16, 31); + this.btnToUpper.Name = "btnToUpper"; + this.btnToUpper.Size = new System.Drawing.Size(75, 23); + this.btnToUpper.TabIndex = 0; + this.btnToUpper.Text = "转大写"; + this.btnToUpper.UseVisualStyleBackColor = true; + this.btnToUpper.Click += new System.EventHandler(this.btnToUpper_Click); + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.gb1); + this.groupBox1.Controls.Add(this.groupBox4); + this.groupBox1.Dock = System.Windows.Forms.DockStyle.Top; + this.groupBox1.Location = new System.Drawing.Point(0, 0); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(628, 273); + this.groupBox1.TabIndex = 0; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "原始字符串"; + // + // gb1 + // + this.gb1.Controls.Add(this.rtb1); + this.gb1.Dock = System.Windows.Forms.DockStyle.Fill; + this.gb1.Location = new System.Drawing.Point(3, 17); + this.gb1.Name = "gb1"; + this.gb1.Size = new System.Drawing.Size(502, 253); + this.gb1.TabIndex = 2; + this.gb1.TabStop = false; + this.gb1.Text = "内容"; + // + // rtb1 + // + this.rtb1.Dock = System.Windows.Forms.DockStyle.Fill; + this.rtb1.Location = new System.Drawing.Point(3, 17); + this.rtb1.Name = "rtb1"; + this.rtb1.Size = new System.Drawing.Size(496, 233); + this.rtb1.TabIndex = 0; + this.rtb1.Text = ""; + this.rtb1.TextChanged += new System.EventHandler(this.rtb1_TextChanged); + // + // groupBox4 + // + this.groupBox4.Controls.Add(this.rbtnGB2312Encoding); + this.groupBox4.Controls.Add(this.txtEncoding); + this.groupBox4.Controls.Add(this.rbtnOtherEncoding); + this.groupBox4.Controls.Add(this.rbtnUTF8Encoding); + this.groupBox4.Controls.Add(this.rbtnUnicodeEncoding); + this.groupBox4.Controls.Add(this.rbtnDefaultEncoding); + this.groupBox4.Dock = System.Windows.Forms.DockStyle.Right; + this.groupBox4.Location = new System.Drawing.Point(505, 17); + this.groupBox4.Name = "groupBox4"; + this.groupBox4.Size = new System.Drawing.Size(120, 253); + this.groupBox4.TabIndex = 1; + this.groupBox4.TabStop = false; + this.groupBox4.Text = "编码"; + // + // rbtnGB2312Encoding + // + this.rbtnGB2312Encoding.AutoSize = true; + this.rbtnGB2312Encoding.Location = new System.Drawing.Point(16, 108); + this.rbtnGB2312Encoding.Name = "rbtnGB2312Encoding"; + this.rbtnGB2312Encoding.Size = new System.Drawing.Size(59, 16); + this.rbtnGB2312Encoding.TabIndex = 6; + this.rbtnGB2312Encoding.TabStop = true; + this.rbtnGB2312Encoding.Text = "GB2312"; + this.rbtnGB2312Encoding.UseVisualStyleBackColor = true; + // + // txtEncoding + // + this.txtEncoding.Location = new System.Drawing.Point(16, 164); + this.txtEncoding.Name = "txtEncoding"; + this.txtEncoding.Size = new System.Drawing.Size(80, 21); + this.txtEncoding.TabIndex = 5; + this.txtEncoding.Text = "gb2312"; + // + // rbtnOtherEncoding + // + this.rbtnOtherEncoding.AutoSize = true; + this.rbtnOtherEncoding.Location = new System.Drawing.Point(16, 136); + this.rbtnOtherEncoding.Name = "rbtnOtherEncoding"; + this.rbtnOtherEncoding.Size = new System.Drawing.Size(71, 16); + this.rbtnOtherEncoding.TabIndex = 4; + this.rbtnOtherEncoding.TabStop = true; + this.rbtnOtherEncoding.Text = "指定编码"; + this.rbtnOtherEncoding.UseVisualStyleBackColor = true; + // + // rbtnUTF8Encoding + // + this.rbtnUTF8Encoding.AutoSize = true; + this.rbtnUTF8Encoding.Location = new System.Drawing.Point(16, 80); + this.rbtnUTF8Encoding.Name = "rbtnUTF8Encoding"; + this.rbtnUTF8Encoding.Size = new System.Drawing.Size(53, 16); + this.rbtnUTF8Encoding.TabIndex = 3; + this.rbtnUTF8Encoding.TabStop = true; + this.rbtnUTF8Encoding.Text = "UTF-8"; + this.rbtnUTF8Encoding.UseVisualStyleBackColor = true; + // + // rbtnUnicodeEncoding + // + this.rbtnUnicodeEncoding.AutoSize = true; + this.rbtnUnicodeEncoding.Location = new System.Drawing.Point(16, 52); + this.rbtnUnicodeEncoding.Name = "rbtnUnicodeEncoding"; + this.rbtnUnicodeEncoding.Size = new System.Drawing.Size(65, 16); + this.rbtnUnicodeEncoding.TabIndex = 2; + this.rbtnUnicodeEncoding.TabStop = true; + this.rbtnUnicodeEncoding.Text = "Unicode"; + this.rbtnUnicodeEncoding.UseVisualStyleBackColor = true; + // + // rbtnDefaultEncoding + // + this.rbtnDefaultEncoding.AutoSize = true; + this.rbtnDefaultEncoding.Checked = true; + this.rbtnDefaultEncoding.Location = new System.Drawing.Point(16, 24); + this.rbtnDefaultEncoding.Name = "rbtnDefaultEncoding"; + this.rbtnDefaultEncoding.Size = new System.Drawing.Size(71, 16); + this.rbtnDefaultEncoding.TabIndex = 1; + this.rbtnDefaultEncoding.TabStop = true; + this.rbtnDefaultEncoding.Text = "系统默认"; + this.rbtnDefaultEncoding.UseVisualStyleBackColor = true; + // + // groupBox3 + // + this.groupBox3.Controls.Add(this.button1); + this.groupBox3.Controls.Add(this.btnRandomString); + this.groupBox3.Controls.Add(this.btnSecure); + this.groupBox3.Controls.Add(this.btnConvert); + this.groupBox3.Controls.Add(this.btnToHash); + this.groupBox3.Controls.Add(this.button4); + this.groupBox3.Dock = System.Windows.Forms.DockStyle.Fill; + this.groupBox3.Location = new System.Drawing.Point(0, 0); + this.groupBox3.Name = "groupBox3"; + this.groupBox3.Size = new System.Drawing.Size(160, 573); + this.groupBox3.TabIndex = 1; + this.groupBox3.TabStop = false; + this.groupBox3.Text = "字符串操作"; + // + // button1 + // + this.button1.Location = new System.Drawing.Point(19, 202); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(120, 23); + this.button1.TabIndex = 16; + this.button1.Text = "button1"; + this.button1.UseVisualStyleBackColor = true; + this.button1.Visible = false; + // + // btnRandomString + // + this.btnRandomString.Location = new System.Drawing.Point(19, 149); + this.btnRandomString.Name = "btnRandomString"; + this.btnRandomString.Size = new System.Drawing.Size(120, 23); + this.btnRandomString.TabIndex = 15; + this.btnRandomString.Text = "随机字符串"; + this.btnRandomString.UseVisualStyleBackColor = true; + this.btnRandomString.Click += new System.EventHandler(this.btnRandomString_Click); + // + // btnSecure + // + this.btnSecure.Location = new System.Drawing.Point(19, 105); + this.btnSecure.Name = "btnSecure"; + this.btnSecure.Size = new System.Drawing.Size(120, 23); + this.btnSecure.TabIndex = 13; + this.btnSecure.Text = "加密解密"; + this.btnSecure.UseVisualStyleBackColor = true; + this.btnSecure.Click += new System.EventHandler(this.btnSecure_Click); + // + // btnConvert + // + this.btnConvert.Location = new System.Drawing.Point(19, 61); + this.btnConvert.Name = "btnConvert"; + this.btnConvert.Size = new System.Drawing.Size(120, 23); + this.btnConvert.TabIndex = 11; + this.btnConvert.Text = "常用转换"; + this.btnConvert.UseVisualStyleBackColor = true; + this.btnConvert.Click += new System.EventHandler(this.btnConvert_Click); + // + // btnToHash + // + this.btnToHash.Location = new System.Drawing.Point(19, 17); + this.btnToHash.Name = "btnToHash"; + this.btnToHash.Size = new System.Drawing.Size(120, 23); + this.btnToHash.TabIndex = 5; + this.btnToHash.Text = "计算哈希值"; + this.btnToHash.UseVisualStyleBackColor = true; + this.btnToHash.Click += new System.EventHandler(this.btnToHash_Click); + // + // button4 + // + this.button4.Location = new System.Drawing.Point(19, 523); + this.button4.Name = "button4"; + this.button4.Size = new System.Drawing.Size(120, 23); + this.button4.TabIndex = 2; + this.button4.Text = "button4"; + this.button4.UseVisualStyleBackColor = true; + this.button4.Visible = false; + // + // StringConvertor + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(792, 573); + this.Controls.Add(this.splitContainer1); + this.MaximizeBox = false; + this.MinimumSize = new System.Drawing.Size(800, 600); + this.Name = "StringConvertor"; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "字符串转换工具"; + this.splitContainer1.Panel1.ResumeLayout(false); + this.splitContainer1.Panel2.ResumeLayout(false); + this.splitContainer1.ResumeLayout(false); + this.gb23.ResumeLayout(false); + this.gb2.ResumeLayout(false); + this.groupBox6.ResumeLayout(false); + this.groupBox1.ResumeLayout(false); + this.gb1.ResumeLayout(false); + this.groupBox4.ResumeLayout(false); + this.groupBox4.PerformLayout(); + this.groupBox3.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.SplitContainer splitContainer1; + private System.Windows.Forms.GroupBox gb23; + private System.Windows.Forms.RichTextBox rtb2; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.RichTextBox rtb1; + private System.Windows.Forms.GroupBox groupBox3; + private System.Windows.Forms.Button btnToHash; + private System.Windows.Forms.Button button4; + private System.Windows.Forms.Button btnRandomString; + private System.Windows.Forms.Button btnSecure; + private System.Windows.Forms.Button btnConvert; + private System.Windows.Forms.GroupBox groupBox4; + private System.Windows.Forms.GroupBox gb1; + private System.Windows.Forms.GroupBox gb2; + private System.Windows.Forms.GroupBox groupBox6; + private System.Windows.Forms.RadioButton rbtnDefaultEncoding; + private System.Windows.Forms.RadioButton rbtnUnicodeEncoding; + private System.Windows.Forms.RadioButton rbtnUTF8Encoding; + private System.Windows.Forms.RadioButton rbtnOtherEncoding; + private System.Windows.Forms.TextBox txtEncoding; + private System.Windows.Forms.Button btnToLower; + private System.Windows.Forms.Button btnToUpper; + private System.Windows.Forms.RadioButton rbtnGB2312Encoding; + private System.Windows.Forms.Button btnReplace; + private System.Windows.Forms.Button button1; + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/ToolForm/StringConvertor/StringConvertor.cs b/src/Kalman.Studio/ToolForm/StringConvertor/StringConvertor.cs new file mode 100644 index 0000000..302f052 --- /dev/null +++ b/src/Kalman.Studio/ToolForm/StringConvertor/StringConvertor.cs @@ -0,0 +1,111 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using Kalman.Utilities; +using Kalman.Security; +using System.IO; + +namespace Kalman.Studio +{ + public partial class StringConvertor : DockableForm + { + public StringConvertor() + { + InitializeComponent(); + } + + #region 共享成员 + + /// + /// 原始字符串 + /// + public string S1 { get { return rtb1.Text.Trim(); } } + /// + /// 转换后的字符串 + /// + public string S2 { get { return rtb2.Text.Trim(); } set { rtb2.Text = value; } } + + /// + /// 获取指定原始字符串的编码 + /// + /// + public Encoding GetEncoding() + { + if (rbtnDefaultEncoding.Checked) return Encoding.Default; + if (rbtnUnicodeEncoding.Checked) return Encoding.Unicode; + if (rbtnUTF8Encoding.Checked) return Encoding.UTF8; + if (rbtnGB2312Encoding.Checked) return Encoding.GetEncoding("gb2312"); + if (rbtnOtherEncoding.Checked) + { + try + { + return Encoding.GetEncoding(txtEncoding.Text.Trim()); + } + catch + { + return Encoding.Default; + } + } + return Encoding.Default; + } + + #endregion + + private void btnToHash_Click(object sender, EventArgs e) + { + String_Hash convert = new String_Hash(); + convert.ShowDialog(this); + } + + private void btnConvert_Click(object sender, EventArgs e) + { + String_Convert convert = new String_Convert(); + convert.ShowDialog(this); + //MessageBox.Show(convert.Visible.ToString()); + } + + private void btnToUpper_Click(object sender, EventArgs e) + { + this.S2 = this.S2.ToUpper(); + } + + private void btnToLower_Click(object sender, EventArgs e) + { + this.S2 = this.S2.ToLower(); + } + + private void btnReplace_Click(object sender, EventArgs e) + { + String_Replace replace = new String_Replace(); + replace.ShowDialog(this); + } + + private void rtb1_TextChanged(object sender, EventArgs e) + { + gb1.Text = string.Format("内容[字数:{0}]",S1.Length); + } + + private void rtb2_TextChanged(object sender, EventArgs e) + { + gb2.Text = string.Format("内容[字数:{0}]", S2.Length); + } + + private void btnSecure_Click(object sender, EventArgs e) + { + String_SymmetricAlgorithm srcure = new String_SymmetricAlgorithm(); + srcure.ShowDialog(this); + } + + private void btnRandomString_Click(object sender, EventArgs e) + { + String_Random random = new String_Random(); + random.ShowDialog(this); + } + + } +} diff --git a/src/Kalman.Studio/ToolForm/StringConvertor/StringConvertor.resx b/src/Kalman.Studio/ToolForm/StringConvertor/StringConvertor.resx new file mode 100644 index 0000000..19dc0dd --- /dev/null +++ b/src/Kalman.Studio/ToolForm/StringConvertor/StringConvertor.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/Kalman.Studio/ToolForm/StringConvertor/StringConvertorBase.Designer.cs b/src/Kalman.Studio/ToolForm/StringConvertor/StringConvertorBase.Designer.cs new file mode 100644 index 0000000..a06c0b2 --- /dev/null +++ b/src/Kalman.Studio/ToolForm/StringConvertor/StringConvertorBase.Designer.cs @@ -0,0 +1,52 @@ +namespace Kalman.Studio +{ + partial class StringConvertorBase + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.SuspendLayout(); + // + // StringConvertorBase + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(292, 273); + this.MaximizeBox = false; + this.Name = "StringConvertorBase"; + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "StringConverterBase"; + this.Load += new System.EventHandler(this.StringConverterBase_Load); + this.ResumeLayout(false); + + } + + #endregion + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/ToolForm/StringConvertor/StringConvertorBase.cs b/src/Kalman.Studio/ToolForm/StringConvertor/StringConvertorBase.cs new file mode 100644 index 0000000..1525a6a --- /dev/null +++ b/src/Kalman.Studio/ToolForm/StringConvertor/StringConvertorBase.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace Kalman.Studio +{ + public partial class StringConvertorBase : Form + { + public StringConvertorBase() + { + InitializeComponent(); + } + + public StringConvertor SC { get; set; } + private void StringConverterBase_Load(object sender, EventArgs e) + { + SC = this.Owner as StringConvertor; + } + } +} diff --git a/src/Kalman.Studio/ToolForm/StringConvertor/StringConvertorBase.resx b/src/Kalman.Studio/ToolForm/StringConvertor/StringConvertorBase.resx new file mode 100644 index 0000000..19dc0dd --- /dev/null +++ b/src/Kalman.Studio/ToolForm/StringConvertor/StringConvertorBase.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/Kalman.Studio/ToolForm/StringConvertor/String_Convert.Designer.cs b/src/Kalman.Studio/ToolForm/StringConvertor/String_Convert.Designer.cs new file mode 100644 index 0000000..467eca9 --- /dev/null +++ b/src/Kalman.Studio/ToolForm/StringConvertor/String_Convert.Designer.cs @@ -0,0 +1,190 @@ +namespace Kalman.Studio +{ + partial class String_Convert + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.btnToDBC = new System.Windows.Forms.Button(); + this.btnToSBC = new System.Windows.Forms.Button(); + this.btnToBase64 = new System.Windows.Forms.Button(); + this.btnUrlEncode = new System.Windows.Forms.Button(); + this.btnUrlDecode = new System.Windows.Forms.Button(); + this.btnHtmlDecode = new System.Windows.Forms.Button(); + this.btnHtmlEncode = new System.Windows.Forms.Button(); + this.btnGuid = new System.Windows.Forms.Button(); + this.btnToHex = new System.Windows.Forms.Button(); + this.btnFromHex = new System.Windows.Forms.Button(); + this.btnFromBase64 = new System.Windows.Forms.Button(); + this.SuspendLayout(); + // + // btnToDBC + // + this.btnToDBC.Location = new System.Drawing.Point(302, 128); + this.btnToDBC.Name = "btnToDBC"; + this.btnToDBC.Size = new System.Drawing.Size(100, 23); + this.btnToDBC.TabIndex = 5; + this.btnToDBC.Text = "转半角"; + this.btnToDBC.UseVisualStyleBackColor = true; + this.btnToDBC.Click += new System.EventHandler(this.btnToDBC_Click); + // + // btnToSBC + // + this.btnToSBC.Location = new System.Drawing.Point(163, 128); + this.btnToSBC.Name = "btnToSBC"; + this.btnToSBC.Size = new System.Drawing.Size(100, 23); + this.btnToSBC.TabIndex = 4; + this.btnToSBC.Text = "转全角"; + this.btnToSBC.UseVisualStyleBackColor = true; + this.btnToSBC.Click += new System.EventHandler(this.btnToSBC_Click); + // + // btnToBase64 + // + this.btnToBase64.Location = new System.Drawing.Point(163, 99); + this.btnToBase64.Name = "btnToBase64"; + this.btnToBase64.Size = new System.Drawing.Size(100, 23); + this.btnToBase64.TabIndex = 6; + this.btnToBase64.Text = "Base64 Encode"; + this.btnToBase64.UseVisualStyleBackColor = true; + this.btnToBase64.Click += new System.EventHandler(this.btnToBase64_Click); + // + // btnUrlEncode + // + this.btnUrlEncode.Location = new System.Drawing.Point(163, 12); + this.btnUrlEncode.Name = "btnUrlEncode"; + this.btnUrlEncode.Size = new System.Drawing.Size(100, 23); + this.btnUrlEncode.TabIndex = 7; + this.btnUrlEncode.Text = "URL Encode"; + this.btnUrlEncode.UseVisualStyleBackColor = true; + this.btnUrlEncode.Click += new System.EventHandler(this.btnUrlEncode_Click); + // + // btnUrlDecode + // + this.btnUrlDecode.Location = new System.Drawing.Point(302, 12); + this.btnUrlDecode.Name = "btnUrlDecode"; + this.btnUrlDecode.Size = new System.Drawing.Size(100, 23); + this.btnUrlDecode.TabIndex = 8; + this.btnUrlDecode.Text = "URL Decode"; + this.btnUrlDecode.UseVisualStyleBackColor = true; + this.btnUrlDecode.Click += new System.EventHandler(this.btnUrlDecode_Click); + // + // btnHtmlDecode + // + this.btnHtmlDecode.Location = new System.Drawing.Point(302, 41); + this.btnHtmlDecode.Name = "btnHtmlDecode"; + this.btnHtmlDecode.Size = new System.Drawing.Size(100, 23); + this.btnHtmlDecode.TabIndex = 9; + this.btnHtmlDecode.Text = "Html Decode"; + this.btnHtmlDecode.UseVisualStyleBackColor = true; + this.btnHtmlDecode.Click += new System.EventHandler(this.btnHtmlDecode_Click); + // + // btnHtmlEncode + // + this.btnHtmlEncode.Location = new System.Drawing.Point(163, 41); + this.btnHtmlEncode.Name = "btnHtmlEncode"; + this.btnHtmlEncode.Size = new System.Drawing.Size(100, 23); + this.btnHtmlEncode.TabIndex = 10; + this.btnHtmlEncode.Text = "Html Encode"; + this.btnHtmlEncode.UseVisualStyleBackColor = true; + this.btnHtmlEncode.Click += new System.EventHandler(this.btnHtmlEncode_Click); + // + // btnGuid + // + this.btnGuid.Location = new System.Drawing.Point(12, 12); + this.btnGuid.Name = "btnGuid"; + this.btnGuid.Size = new System.Drawing.Size(100, 23); + this.btnGuid.TabIndex = 11; + this.btnGuid.Text = "生成Guid"; + this.btnGuid.UseVisualStyleBackColor = true; + this.btnGuid.Click += new System.EventHandler(this.btnGuid_Click); + // + // btnToHex + // + this.btnToHex.Location = new System.Drawing.Point(163, 70); + this.btnToHex.Name = "btnToHex"; + this.btnToHex.Size = new System.Drawing.Size(100, 23); + this.btnToHex.TabIndex = 12; + this.btnToHex.Text = "To Hex"; + this.btnToHex.UseVisualStyleBackColor = true; + this.btnToHex.Click += new System.EventHandler(this.btnToHex_Click); + // + // btnFromHex + // + this.btnFromHex.Location = new System.Drawing.Point(302, 70); + this.btnFromHex.Name = "btnFromHex"; + this.btnFromHex.Size = new System.Drawing.Size(100, 23); + this.btnFromHex.TabIndex = 13; + this.btnFromHex.Text = "From Hex"; + this.btnFromHex.UseVisualStyleBackColor = true; + this.btnFromHex.Click += new System.EventHandler(this.btnFromHex_Click); + // + // btnFromBase64 + // + this.btnFromBase64.Location = new System.Drawing.Point(302, 99); + this.btnFromBase64.Name = "btnFromBase64"; + this.btnFromBase64.Size = new System.Drawing.Size(100, 23); + this.btnFromBase64.TabIndex = 14; + this.btnFromBase64.Text = "Base64 Decode"; + this.btnFromBase64.UseVisualStyleBackColor = true; + this.btnFromBase64.Click += new System.EventHandler(this.btnFromBase64_Click); + // + // String_Convert + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(414, 194); + this.Controls.Add(this.btnFromBase64); + this.Controls.Add(this.btnFromHex); + this.Controls.Add(this.btnToHex); + this.Controls.Add(this.btnGuid); + this.Controls.Add(this.btnHtmlEncode); + this.Controls.Add(this.btnHtmlDecode); + this.Controls.Add(this.btnUrlDecode); + this.Controls.Add(this.btnUrlEncode); + this.Controls.Add(this.btnToBase64); + this.Controls.Add(this.btnToDBC); + this.Controls.Add(this.btnToSBC); + this.Name = "String_Convert"; + this.Text = "常用转换"; + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Button btnToDBC; + private System.Windows.Forms.Button btnToSBC; + private System.Windows.Forms.Button btnToBase64; + private System.Windows.Forms.Button btnUrlEncode; + private System.Windows.Forms.Button btnUrlDecode; + private System.Windows.Forms.Button btnHtmlDecode; + private System.Windows.Forms.Button btnHtmlEncode; + private System.Windows.Forms.Button btnGuid; + private System.Windows.Forms.Button btnToHex; + private System.Windows.Forms.Button btnFromHex; + private System.Windows.Forms.Button btnFromBase64; + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/ToolForm/StringConvertor/String_Convert.cs b/src/Kalman.Studio/ToolForm/StringConvertor/String_Convert.cs new file mode 100644 index 0000000..2982b92 --- /dev/null +++ b/src/Kalman.Studio/ToolForm/StringConvertor/String_Convert.cs @@ -0,0 +1,94 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using Kalman.Utilities; + +namespace Kalman.Studio +{ + public partial class String_Convert : StringConvertorBase + { + public String_Convert() + { + InitializeComponent(); + } + + private void btnToSBC_Click(object sender, EventArgs e) + { + if (SC != null && SC.S1.Length > 0) + { + SC.S2 = StringUtil.ToSBC(SC.S1); + this.Close(); + } + } + + private void btnToDBC_Click(object sender, EventArgs e) + { + if (SC != null && SC.S1.Length > 0) + { + SC.S2 = StringUtil.ToDBC(SC.S1); + this.Close(); + } + } + + private void btnToBase64_Click(object sender, EventArgs e) + { + SC.S2 = StringUtil.Base64Encode(SC.S1, SC.GetEncoding()); + this.Close(); + } + + private void btnFromBase64_Click(object sender, EventArgs e) + { + SC.S2 = StringUtil.Base64Decode(SC.S1, SC.GetEncoding()); + this.Close(); + } + + private void btnUrlEncode_Click(object sender, EventArgs e) + { + SC.S2 = System.Web.HttpUtility.UrlEncode(SC.S1, SC.GetEncoding()); + this.Close(); + } + + private void btnUrlDecode_Click(object sender, EventArgs e) + { + SC.S2 = System.Web.HttpUtility.UrlDecode(SC.S1, SC.GetEncoding()); + this.Close(); + } + + private void btnHtmlEncode_Click(object sender, EventArgs e) + { + SC.S2 = System.Web.HttpUtility.HtmlEncode(SC.S1); + this.Close(); + } + + private void btnHtmlDecode_Click(object sender, EventArgs e) + { + SC.S2 = System.Web.HttpUtility.HtmlDecode(SC.S1); + this.Close(); + } + + private void btnGuid_Click(object sender, EventArgs e) + { + SC.S2 = Guid.NewGuid().ToString(); + this.Close(); + } + + private void btnToHex_Click(object sender, EventArgs e) + { + SC.S2 = StringUtil.ToHexString(SC.S1, SC.GetEncoding()); + this.Close(); + } + + private void btnFromHex_Click(object sender, EventArgs e) + { + SC.S2 = StringUtil.FromHexString(SC.S1, SC.GetEncoding()); + this.Close(); + } + + + } +} diff --git a/src/Kalman.Studio/ToolForm/StringConvertor/String_Convert.resx b/src/Kalman.Studio/ToolForm/StringConvertor/String_Convert.resx new file mode 100644 index 0000000..19dc0dd --- /dev/null +++ b/src/Kalman.Studio/ToolForm/StringConvertor/String_Convert.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/Kalman.Studio/ToolForm/StringConvertor/String_Filter.Designer.cs b/src/Kalman.Studio/ToolForm/StringConvertor/String_Filter.Designer.cs new file mode 100644 index 0000000..aef2a44 --- /dev/null +++ b/src/Kalman.Studio/ToolForm/StringConvertor/String_Filter.Designer.cs @@ -0,0 +1,38 @@ +namespace Kalman.Studio +{ + partial class String_Filter + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Text = "String_Filter"; + } + + #endregion + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/ToolForm/StringConvertor/String_Filter.cs b/src/Kalman.Studio/ToolForm/StringConvertor/String_Filter.cs new file mode 100644 index 0000000..353905b --- /dev/null +++ b/src/Kalman.Studio/ToolForm/StringConvertor/String_Filter.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace Kalman.Studio +{ + public partial class String_Filter : Form + { + public String_Filter() + { + InitializeComponent(); + } + } +} diff --git a/src/Kalman.Studio/ToolForm/StringConvertor/String_Guid.Designer.cs b/src/Kalman.Studio/ToolForm/StringConvertor/String_Guid.Designer.cs new file mode 100644 index 0000000..28146e6 --- /dev/null +++ b/src/Kalman.Studio/ToolForm/StringConvertor/String_Guid.Designer.cs @@ -0,0 +1,102 @@ +namespace Kalman.Studio +{ + partial class String_Guid + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.rbtnToLower = new System.Windows.Forms.RadioButton(); + this.rbtnToUpper = new System.Windows.Forms.RadioButton(); + this.cbRemove = new System.Windows.Forms.CheckBox(); + this.btnOK = new System.Windows.Forms.Button(); + this.SuspendLayout(); + // + // rbtnToLower + // + this.rbtnToLower.AutoSize = true; + this.rbtnToLower.Location = new System.Drawing.Point(100, 35); + this.rbtnToLower.Name = "rbtnToLower"; + this.rbtnToLower.Size = new System.Drawing.Size(59, 16); + this.rbtnToLower.TabIndex = 12; + this.rbtnToLower.TabStop = true; + this.rbtnToLower.Text = "转小写"; + this.rbtnToLower.UseVisualStyleBackColor = true; + // + // rbtnToUpper + // + this.rbtnToUpper.AutoSize = true; + this.rbtnToUpper.Location = new System.Drawing.Point(24, 35); + this.rbtnToUpper.Name = "rbtnToUpper"; + this.rbtnToUpper.Size = new System.Drawing.Size(59, 16); + this.rbtnToUpper.TabIndex = 11; + this.rbtnToUpper.TabStop = true; + this.rbtnToUpper.Text = "转大写"; + this.rbtnToUpper.UseVisualStyleBackColor = true; + // + // cbRemove + // + this.cbRemove.AutoSize = true; + this.cbRemove.Location = new System.Drawing.Point(183, 36); + this.cbRemove.Name = "cbRemove"; + this.cbRemove.Size = new System.Drawing.Size(114, 16); + this.cbRemove.TabIndex = 13; + this.cbRemove.Text = "移除连接字符[-]"; + this.cbRemove.UseVisualStyleBackColor = true; + // + // btnOK + // + this.btnOK.Location = new System.Drawing.Point(260, 98); + this.btnOK.Name = "btnOK"; + this.btnOK.Size = new System.Drawing.Size(75, 23); + this.btnOK.TabIndex = 14; + this.btnOK.Text = "确定"; + this.btnOK.UseVisualStyleBackColor = true; + this.btnOK.Click += new System.EventHandler(this.btnOK_Click); + // + // String_Guid + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(370, 151); + this.Controls.Add(this.btnOK); + this.Controls.Add(this.cbRemove); + this.Controls.Add(this.rbtnToLower); + this.Controls.Add(this.rbtnToUpper); + this.Name = "String_Guid"; + this.Text = "GUID生成器"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.RadioButton rbtnToLower; + private System.Windows.Forms.RadioButton rbtnToUpper; + private System.Windows.Forms.CheckBox cbRemove; + private System.Windows.Forms.Button btnOK; + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/ToolForm/StringConvertor/String_Guid.cs b/src/Kalman.Studio/ToolForm/StringConvertor/String_Guid.cs new file mode 100644 index 0000000..2dac18b --- /dev/null +++ b/src/Kalman.Studio/ToolForm/StringConvertor/String_Guid.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace Kalman.Studio +{ + public partial class String_Guid : StringConvertorBase + { + public String_Guid() + { + InitializeComponent(); + } + + private void btnOK_Click(object sender, EventArgs e) + { + string guid = Guid.NewGuid().ToString(); + + if (rbtnToLower.Checked) guid = guid.ToLower(); + if (rbtnToUpper.Checked) guid = guid.ToUpper(); + if (cbRemove.Checked) guid = guid.Replace("-", ""); + + base.SC.S2 = guid; + + } + } +} diff --git a/src/Kalman.Studio/ToolForm/StringConvertor/String_Guid.resx b/src/Kalman.Studio/ToolForm/StringConvertor/String_Guid.resx new file mode 100644 index 0000000..19dc0dd --- /dev/null +++ b/src/Kalman.Studio/ToolForm/StringConvertor/String_Guid.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/Kalman.Studio/ToolForm/StringConvertor/String_Hash.Designer.cs b/src/Kalman.Studio/ToolForm/StringConvertor/String_Hash.Designer.cs new file mode 100644 index 0000000..12427cb --- /dev/null +++ b/src/Kalman.Studio/ToolForm/StringConvertor/String_Hash.Designer.cs @@ -0,0 +1,199 @@ +namespace Kalman.Studio +{ + partial class String_Hash + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.rbMD5 = new System.Windows.Forms.RadioButton(); + this.rbSHA1 = new System.Windows.Forms.RadioButton(); + this.rbSHA256 = new System.Windows.Forms.RadioButton(); + this.rbSHA384 = new System.Windows.Forms.RadioButton(); + this.rbSHA512 = new System.Windows.Forms.RadioButton(); + this.btnOK = new System.Windows.Forms.Button(); + this.cbBase64 = new System.Windows.Forms.CheckBox(); + this.btnReturn = new System.Windows.Forms.Button(); + this.cbFileHash = new System.Windows.Forms.CheckBox(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.groupBox2 = new System.Windows.Forms.GroupBox(); + this.groupBox1.SuspendLayout(); + this.groupBox2.SuspendLayout(); + this.SuspendLayout(); + // + // rbMD5 + // + this.rbMD5.AutoSize = true; + this.rbMD5.Checked = true; + this.rbMD5.Location = new System.Drawing.Point(20, 20); + this.rbMD5.Name = "rbMD5"; + this.rbMD5.Size = new System.Drawing.Size(41, 16); + this.rbMD5.TabIndex = 0; + this.rbMD5.TabStop = true; + this.rbMD5.Text = "MD5"; + this.rbMD5.UseVisualStyleBackColor = true; + // + // rbSHA1 + // + this.rbSHA1.AutoSize = true; + this.rbSHA1.Location = new System.Drawing.Point(20, 42); + this.rbSHA1.Name = "rbSHA1"; + this.rbSHA1.Size = new System.Drawing.Size(47, 16); + this.rbSHA1.TabIndex = 1; + this.rbSHA1.Text = "SHA1"; + this.rbSHA1.UseVisualStyleBackColor = true; + // + // rbSHA256 + // + this.rbSHA256.AutoSize = true; + this.rbSHA256.Location = new System.Drawing.Point(20, 64); + this.rbSHA256.Name = "rbSHA256"; + this.rbSHA256.Size = new System.Drawing.Size(59, 16); + this.rbSHA256.TabIndex = 2; + this.rbSHA256.Text = "SHA256"; + this.rbSHA256.UseVisualStyleBackColor = true; + // + // rbSHA384 + // + this.rbSHA384.AutoSize = true; + this.rbSHA384.Location = new System.Drawing.Point(20, 86); + this.rbSHA384.Name = "rbSHA384"; + this.rbSHA384.Size = new System.Drawing.Size(59, 16); + this.rbSHA384.TabIndex = 3; + this.rbSHA384.Text = "SHA384"; + this.rbSHA384.UseVisualStyleBackColor = true; + // + // rbSHA512 + // + this.rbSHA512.AutoSize = true; + this.rbSHA512.Location = new System.Drawing.Point(20, 108); + this.rbSHA512.Name = "rbSHA512"; + this.rbSHA512.Size = new System.Drawing.Size(59, 16); + this.rbSHA512.TabIndex = 4; + this.rbSHA512.Text = "SHA512"; + this.rbSHA512.UseVisualStyleBackColor = true; + // + // btnOK + // + this.btnOK.Location = new System.Drawing.Point(220, 179); + this.btnOK.Name = "btnOK"; + this.btnOK.Size = new System.Drawing.Size(75, 23); + this.btnOK.TabIndex = 5; + this.btnOK.Text = "确定"; + this.btnOK.UseVisualStyleBackColor = true; + this.btnOK.Click += new System.EventHandler(this.btnOK_Click); + // + // cbBase64 + // + this.cbBase64.AutoSize = true; + this.cbBase64.Location = new System.Drawing.Point(16, 20); + this.cbBase64.Name = "cbBase64"; + this.cbBase64.Size = new System.Drawing.Size(180, 16); + this.cbBase64.TabIndex = 6; + this.cbBase64.Text = "是否将结果转换为Base64编码"; + this.cbBase64.UseVisualStyleBackColor = true; + // + // btnReturn + // + this.btnReturn.Location = new System.Drawing.Point(325, 179); + this.btnReturn.Name = "btnReturn"; + this.btnReturn.Size = new System.Drawing.Size(75, 23); + this.btnReturn.TabIndex = 7; + this.btnReturn.Text = "返回"; + this.btnReturn.UseVisualStyleBackColor = true; + this.btnReturn.Click += new System.EventHandler(this.btnReturn_Click); + // + // cbFileHash + // + this.cbFileHash.AutoSize = true; + this.cbFileHash.Location = new System.Drawing.Point(16, 43); + this.cbFileHash.Name = "cbFileHash"; + this.cbFileHash.Size = new System.Drawing.Size(216, 16); + this.cbFileHash.TabIndex = 8; + this.cbFileHash.Text = "输入的是文件路径,计算文件哈希值"; + this.cbFileHash.UseVisualStyleBackColor = true; + this.cbFileHash.CheckedChanged += new System.EventHandler(this.cbFileHash_CheckedChanged); + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.rbMD5); + this.groupBox1.Controls.Add(this.rbSHA1); + this.groupBox1.Controls.Add(this.rbSHA256); + this.groupBox1.Controls.Add(this.rbSHA384); + this.groupBox1.Controls.Add(this.rbSHA512); + this.groupBox1.Location = new System.Drawing.Point(12, 12); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(133, 148); + this.groupBox1.TabIndex = 11; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "选择哈希算法"; + // + // groupBox2 + // + this.groupBox2.Controls.Add(this.cbBase64); + this.groupBox2.Controls.Add(this.cbFileHash); + this.groupBox2.Location = new System.Drawing.Point(151, 12); + this.groupBox2.Name = "groupBox2"; + this.groupBox2.Size = new System.Drawing.Size(250, 148); + this.groupBox2.TabIndex = 12; + this.groupBox2.TabStop = false; + this.groupBox2.Text = "选项"; + // + // String_Hash + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(412, 223); + this.Controls.Add(this.groupBox2); + this.Controls.Add(this.groupBox1); + this.Controls.Add(this.btnReturn); + this.Controls.Add(this.btnOK); + this.MaximumSize = new System.Drawing.Size(420, 250); + this.MinimumSize = new System.Drawing.Size(420, 250); + this.Name = "String_Hash"; + this.Text = "选择哈希算法"; + this.groupBox1.ResumeLayout(false); + this.groupBox1.PerformLayout(); + this.groupBox2.ResumeLayout(false); + this.groupBox2.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.RadioButton rbMD5; + private System.Windows.Forms.RadioButton rbSHA1; + private System.Windows.Forms.RadioButton rbSHA256; + private System.Windows.Forms.RadioButton rbSHA384; + private System.Windows.Forms.RadioButton rbSHA512; + private System.Windows.Forms.Button btnOK; + private System.Windows.Forms.CheckBox cbBase64; + private System.Windows.Forms.Button btnReturn; + private System.Windows.Forms.CheckBox cbFileHash; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.GroupBox groupBox2; + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/ToolForm/StringConvertor/String_Hash.cs b/src/Kalman.Studio/ToolForm/StringConvertor/String_Hash.cs new file mode 100644 index 0000000..58e767a --- /dev/null +++ b/src/Kalman.Studio/ToolForm/StringConvertor/String_Hash.cs @@ -0,0 +1,79 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using Kalman.Security; +using System.IO; + +namespace Kalman.Studio +{ + public partial class String_Hash : StringConvertorBase + { + public String_Hash() + { + InitializeComponent(); + } + + private void btnOK_Click(object sender, EventArgs e) + { + HashAlgorithmType hashAlgorithmType = HashAlgorithmType.MD5; + + if (rbMD5.Checked) hashAlgorithmType = HashAlgorithmType.MD5; + if (rbSHA1.Checked) hashAlgorithmType = HashAlgorithmType.SHA1; + if (rbSHA256.Checked) hashAlgorithmType = HashAlgorithmType.SHA256; + if (rbSHA384.Checked) hashAlgorithmType = HashAlgorithmType.SHA384; + if (rbSHA512.Checked) hashAlgorithmType = HashAlgorithmType.SHA512; + + if (SC != null && SC.S1.Length > 0) + { + if (cbFileHash.Checked) + { + if (File.Exists(SC.S1)) + { + this.Cursor = Cursors.WaitCursor; + FileStream fs = new FileStream(SC.S1, FileMode.Open, FileAccess.Read, FileShare.Read, 1024 * 1024); + SC.S2 = HashCryto.GetHash2String(fs, hashAlgorithmType); + this.Cursor = Cursors.Default; + } + else + { + MessageBox.Show(string.Format("文件{0}不存在", SC.S1)); + } + return; + } + + if (cbBase64.Checked) + { + SC.S2 = HashCryto.GetHash2Base64(SC.S1, hashAlgorithmType, SC.GetEncoding()); + } + else + { + SC.S2 = HashCryto.GetHash2String(SC.S1, hashAlgorithmType, SC.GetEncoding()); + } + } + this.Close(); + } + + private void btnReturn_Click(object sender, EventArgs e) + { + this.Close(); + } + + private void cbFileHash_CheckedChanged(object sender, EventArgs e) + { + if (cbFileHash.Checked) + { + cbBase64.Checked = false; + cbBase64.Enabled = false; + } + else + { + cbBase64.Enabled = true; + } + } + } +} diff --git a/src/Kalman.Studio/ToolForm/StringConvertor/String_Hash.resx b/src/Kalman.Studio/ToolForm/StringConvertor/String_Hash.resx new file mode 100644 index 0000000..19dc0dd --- /dev/null +++ b/src/Kalman.Studio/ToolForm/StringConvertor/String_Hash.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/Kalman.Studio/ToolForm/StringConvertor/String_Random.Designer.cs b/src/Kalman.Studio/ToolForm/StringConvertor/String_Random.Designer.cs new file mode 100644 index 0000000..12039cb --- /dev/null +++ b/src/Kalman.Studio/ToolForm/StringConvertor/String_Random.Designer.cs @@ -0,0 +1,287 @@ +namespace Kalman.Studio +{ + partial class String_Random + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.label1 = new System.Windows.Forms.Label(); + this.numLength = new System.Windows.Forms.NumericUpDown(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.cbSymbol = new System.Windows.Forms.CheckBox(); + this.cbCapital = new System.Windows.Forms.CheckBox(); + this.cbLower = new System.Windows.Forms.CheckBox(); + this.cbDigital = new System.Windows.Forms.CheckBox(); + this.groupBox2 = new System.Windows.Forms.GroupBox(); + this.txtCharList = new System.Windows.Forms.TextBox(); + this.cbCustomBuild = new System.Windows.Forms.CheckBox(); + this.btnOK = new System.Windows.Forms.Button(); + this.numCount = new System.Windows.Forms.NumericUpDown(); + this.label2 = new System.Windows.Forms.Label(); + this.label3 = new System.Windows.Forms.Label(); + this.txtSplit = new System.Windows.Forms.TextBox(); + this.cbSaveToFile = new System.Windows.Forms.CheckBox(); + this.saveFileDialog1 = new System.Windows.Forms.SaveFileDialog(); + ((System.ComponentModel.ISupportInitialize)(this.numLength)).BeginInit(); + this.groupBox1.SuspendLayout(); + this.groupBox2.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.numCount)).BeginInit(); + this.SuspendLayout(); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(8, 173); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(29, 12); + this.label1.TabIndex = 0; + this.label1.Text = "长度"; + // + // numLength + // + this.numLength.Location = new System.Drawing.Point(51, 169); + this.numLength.Maximum = new decimal(new int[] { + 10000, + 0, + 0, + 0}); + this.numLength.Minimum = new decimal(new int[] { + 1, + 0, + 0, + 0}); + this.numLength.Name = "numLength"; + this.numLength.Size = new System.Drawing.Size(60, 21); + this.numLength.TabIndex = 1; + this.numLength.Value = new decimal(new int[] { + 10, + 0, + 0, + 0}); + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.cbSymbol); + this.groupBox1.Controls.Add(this.cbCapital); + this.groupBox1.Controls.Add(this.cbLower); + this.groupBox1.Controls.Add(this.cbDigital); + this.groupBox1.Location = new System.Drawing.Point(6, 10); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(424, 49); + this.groupBox1.TabIndex = 2; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "生成选项"; + // + // cbSymbol + // + this.cbSymbol.AutoSize = true; + this.cbSymbol.Location = new System.Drawing.Point(338, 20); + this.cbSymbol.Name = "cbSymbol"; + this.cbSymbol.Size = new System.Drawing.Size(72, 16); + this.cbSymbol.TabIndex = 3; + this.cbSymbol.Text = "标点符号"; + this.cbSymbol.UseVisualStyleBackColor = true; + // + // cbCapital + // + this.cbCapital.AutoSize = true; + this.cbCapital.Location = new System.Drawing.Point(223, 20); + this.cbCapital.Name = "cbCapital"; + this.cbCapital.Size = new System.Drawing.Size(102, 16); + this.cbCapital.TabIndex = 2; + this.cbCapital.Text = "大写字母[A-Z]"; + this.cbCapital.UseVisualStyleBackColor = true; + // + // cbLower + // + this.cbLower.AutoSize = true; + this.cbLower.Location = new System.Drawing.Point(108, 20); + this.cbLower.Name = "cbLower"; + this.cbLower.Size = new System.Drawing.Size(102, 16); + this.cbLower.TabIndex = 1; + this.cbLower.Text = "小写字母[a-z]"; + this.cbLower.UseVisualStyleBackColor = true; + // + // cbDigital + // + this.cbDigital.AutoSize = true; + this.cbDigital.Checked = true; + this.cbDigital.CheckState = System.Windows.Forms.CheckState.Checked; + this.cbDigital.Location = new System.Drawing.Point(17, 20); + this.cbDigital.Name = "cbDigital"; + this.cbDigital.Size = new System.Drawing.Size(78, 16); + this.cbDigital.TabIndex = 0; + this.cbDigital.Text = "数字[0-9]"; + this.cbDigital.UseVisualStyleBackColor = true; + // + // groupBox2 + // + this.groupBox2.Controls.Add(this.txtCharList); + this.groupBox2.Location = new System.Drawing.Point(6, 65); + this.groupBox2.Name = "groupBox2"; + this.groupBox2.Size = new System.Drawing.Size(424, 97); + this.groupBox2.TabIndex = 3; + this.groupBox2.TabStop = false; + this.groupBox2.Text = "自定义生成"; + // + // txtCharList + // + this.txtCharList.Dock = System.Windows.Forms.DockStyle.Fill; + this.txtCharList.Location = new System.Drawing.Point(3, 17); + this.txtCharList.Multiline = true; + this.txtCharList.Name = "txtCharList"; + this.txtCharList.Size = new System.Drawing.Size(418, 77); + this.txtCharList.TabIndex = 0; + // + // cbCustomBuild + // + this.cbCustomBuild.AutoSize = true; + this.cbCustomBuild.Location = new System.Drawing.Point(237, 204); + this.cbCustomBuild.Name = "cbCustomBuild"; + this.cbCustomBuild.Size = new System.Drawing.Size(108, 16); + this.cbCustomBuild.TabIndex = 4; + this.cbCustomBuild.Text = "使用自定义生成"; + this.cbCustomBuild.UseVisualStyleBackColor = true; + // + // btnOK + // + this.btnOK.Location = new System.Drawing.Point(355, 168); + this.btnOK.Name = "btnOK"; + this.btnOK.Size = new System.Drawing.Size(75, 54); + this.btnOK.TabIndex = 5; + this.btnOK.Text = "确定"; + this.btnOK.UseVisualStyleBackColor = true; + this.btnOK.Click += new System.EventHandler(this.btnOK_Click); + // + // numCount + // + this.numCount.Location = new System.Drawing.Point(168, 169); + this.numCount.Maximum = new decimal(new int[] { + 100000, + 0, + 0, + 0}); + this.numCount.Minimum = new decimal(new int[] { + 1, + 0, + 0, + 0}); + this.numCount.Name = "numCount"; + this.numCount.Size = new System.Drawing.Size(60, 21); + this.numCount.TabIndex = 7; + this.numCount.Value = new decimal(new int[] { + 1, + 0, + 0, + 0}); + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(125, 173); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(29, 12); + this.label2.TabIndex = 6; + this.label2.Text = "数量"; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(242, 173); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(41, 12); + this.label3.TabIndex = 8; + this.label3.Text = "分隔符"; + // + // txtSplit + // + this.txtSplit.Location = new System.Drawing.Point(297, 169); + this.txtSplit.Name = "txtSplit"; + this.txtSplit.Size = new System.Drawing.Size(48, 21); + this.txtSplit.TabIndex = 9; + this.txtSplit.Text = "\\r\\n"; + // + // cbSaveToFile + // + this.cbSaveToFile.AutoSize = true; + this.cbSaveToFile.Location = new System.Drawing.Point(144, 204); + this.cbSaveToFile.Name = "cbSaveToFile"; + this.cbSaveToFile.Size = new System.Drawing.Size(84, 16); + this.cbSaveToFile.TabIndex = 10; + this.cbSaveToFile.Text = "保存到文件"; + this.cbSaveToFile.UseVisualStyleBackColor = true; + // + // String_Random + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(436, 229); + this.Controls.Add(this.cbSaveToFile); + this.Controls.Add(this.txtSplit); + this.Controls.Add(this.label3); + this.Controls.Add(this.numCount); + this.Controls.Add(this.label2); + this.Controls.Add(this.btnOK); + this.Controls.Add(this.cbCustomBuild); + this.Controls.Add(this.groupBox2); + this.Controls.Add(this.groupBox1); + this.Controls.Add(this.numLength); + this.Controls.Add(this.label1); + this.Name = "String_Random"; + this.Text = "随机字符串生成"; + this.Load += new System.EventHandler(this.String_Random_Load); + ((System.ComponentModel.ISupportInitialize)(this.numLength)).EndInit(); + this.groupBox1.ResumeLayout(false); + this.groupBox1.PerformLayout(); + this.groupBox2.ResumeLayout(false); + this.groupBox2.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.numCount)).EndInit(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label label1; + private System.Windows.Forms.NumericUpDown numLength; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.GroupBox groupBox2; + private System.Windows.Forms.CheckBox cbSymbol; + private System.Windows.Forms.CheckBox cbCapital; + private System.Windows.Forms.CheckBox cbLower; + private System.Windows.Forms.CheckBox cbDigital; + private System.Windows.Forms.CheckBox cbCustomBuild; + private System.Windows.Forms.TextBox txtCharList; + private System.Windows.Forms.Button btnOK; + private System.Windows.Forms.NumericUpDown numCount; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.TextBox txtSplit; + private System.Windows.Forms.CheckBox cbSaveToFile; + private System.Windows.Forms.SaveFileDialog saveFileDialog1; + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/ToolForm/StringConvertor/String_Random.cs b/src/Kalman.Studio/ToolForm/StringConvertor/String_Random.cs new file mode 100644 index 0000000..a4166a6 --- /dev/null +++ b/src/Kalman.Studio/ToolForm/StringConvertor/String_Random.cs @@ -0,0 +1,103 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using Kalman.Utilities; +using System.Collections.Specialized; +using System.IO; + +namespace Kalman.Studio +{ + public partial class String_Random : StringConvertorBase + { + public String_Random() + { + InitializeComponent(); + } + + private void String_Random_Load(object sender, EventArgs e) + { + StringBuilder sb = new StringBuilder(); + + for (int i = 33; i < 127; i++) + { + string s = ((char)i).ToString(); + sb.Append(s); + } + + txtCharList.Text = sb.ToString(); + } + + private void btnOK_Click(object sender, EventArgs e) + { + int len = (int)numLength.Value; + string dic = "0123456789"; + + if (cbCustomBuild.Checked) + { + dic = txtCharList.Text.Trim(); + if (dic.Length == 0) + { + MessageBox.Show("使用自定义生成时,字典内容不能为空"); + return; + } + } + else + { + if (cbLower.Checked) dic = string.Concat(dic, "abcdefghijklmnopqrstuvwxyz"); + if (cbCapital.Checked) dic = string.Concat(dic, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"); + if (cbSymbol.Checked) dic = string.Concat(dic, "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"); + } + + int count = (int)numCount.Value; + string split = txtSplit.Text.Trim(); + int capacity = (int)(count * (numLength.Value + split.Length)); + StringCollection sc = new StringCollection(); + StringBuilder sb = new StringBuilder(); + + for (int i = 0; i < count; i++) + { + string s = RandomUtil.BuildRandomString(len, dic); + + if (sc.Contains(s)) + { + continue; + } + sc.Add(s); + + } + + foreach (var item in sc) + { + sb.Append(item); + sb.Append(split); + } + + if (cbSaveToFile.Checked) + { + if (saveFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + string fileName = saveFileDialog1.FileName; + File.AppendAllText(fileName, sb.ToString()); + SC.S2 = "数据已保存到文件:" + fileName; + } + else + { + return; + } + } + else + { + SC.S2 = sb.ToString(); + } + this.Close(); + } + + + + } +} diff --git a/src/Kalman.Studio/ToolForm/StringConvertor/String_Random.resx b/src/Kalman.Studio/ToolForm/StringConvertor/String_Random.resx new file mode 100644 index 0000000..f6392f7 --- /dev/null +++ b/src/Kalman.Studio/ToolForm/StringConvertor/String_Random.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + \ No newline at end of file diff --git a/src/Kalman.Studio/ToolForm/StringConvertor/String_Replace.Designer.cs b/src/Kalman.Studio/ToolForm/StringConvertor/String_Replace.Designer.cs new file mode 100644 index 0000000..35e3d4b --- /dev/null +++ b/src/Kalman.Studio/ToolForm/StringConvertor/String_Replace.Designer.cs @@ -0,0 +1,105 @@ +namespace Kalman.Studio +{ + partial class String_Replace + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.label1 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.txt1 = new System.Windows.Forms.TextBox(); + this.txt2 = new System.Windows.Forms.TextBox(); + this.btnOK = new System.Windows.Forms.Button(); + this.SuspendLayout(); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(12, 12); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(53, 12); + this.label1.TabIndex = 0; + this.label1.Text = "查找内容"; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(12, 45); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(41, 12); + this.label2.TabIndex = 1; + this.label2.Text = "替换为"; + // + // txt1 + // + this.txt1.Location = new System.Drawing.Point(77, 8); + this.txt1.Name = "txt1"; + this.txt1.Size = new System.Drawing.Size(162, 21); + this.txt1.TabIndex = 2; + // + // txt2 + // + this.txt2.Location = new System.Drawing.Point(77, 41); + this.txt2.Name = "txt2"; + this.txt2.Size = new System.Drawing.Size(162, 21); + this.txt2.TabIndex = 3; + // + // btnOK + // + this.btnOK.Location = new System.Drawing.Point(164, 84); + this.btnOK.Name = "btnOK"; + this.btnOK.Size = new System.Drawing.Size(75, 23); + this.btnOK.TabIndex = 4; + this.btnOK.Text = "确定"; + this.btnOK.UseVisualStyleBackColor = true; + this.btnOK.Click += new System.EventHandler(this.btnOK_Click); + // + // String_Replace + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(259, 119); + this.Controls.Add(this.btnOK); + this.Controls.Add(this.txt2); + this.Controls.Add(this.txt1); + this.Controls.Add(this.label2); + this.Controls.Add(this.label1); + this.Name = "String_Replace"; + this.Text = "字符串替换"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.TextBox txt1; + private System.Windows.Forms.TextBox txt2; + private System.Windows.Forms.Button btnOK; + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/ToolForm/StringConvertor/String_Replace.cs b/src/Kalman.Studio/ToolForm/StringConvertor/String_Replace.cs new file mode 100644 index 0000000..5f3cd3f --- /dev/null +++ b/src/Kalman.Studio/ToolForm/StringConvertor/String_Replace.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace Kalman.Studio +{ + public partial class String_Replace : StringConvertorBase + { + public String_Replace() + { + InitializeComponent(); + } + + private void btnOK_Click(object sender, EventArgs e) + { + string s1 = txt1.Text; + string s2 = txt2.Text; + + if (!string.IsNullOrEmpty(s1)) + { + SC.S2 = SC.S2.Replace(s1, s2); + } + this.Close(); + } + } +} diff --git a/src/Kalman.Studio/ToolForm/StringConvertor/String_Replace.resx b/src/Kalman.Studio/ToolForm/StringConvertor/String_Replace.resx new file mode 100644 index 0000000..19dc0dd --- /dev/null +++ b/src/Kalman.Studio/ToolForm/StringConvertor/String_Replace.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/Kalman.Studio/ToolForm/StringConvertor/String_SymmetricAlgorithm.Designer.cs b/src/Kalman.Studio/ToolForm/StringConvertor/String_SymmetricAlgorithm.Designer.cs new file mode 100644 index 0000000..8242df4 --- /dev/null +++ b/src/Kalman.Studio/ToolForm/StringConvertor/String_SymmetricAlgorithm.Designer.cs @@ -0,0 +1,307 @@ +namespace Kalman.Studio +{ + partial class String_SymmetricAlgorithm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.btnReturn = new System.Windows.Forms.Button(); + this.rbtnDES = new System.Windows.Forms.RadioButton(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.rbtnRijndael_256 = new System.Windows.Forms.RadioButton(); + this.rbtnTripleDES_192 = new System.Windows.Forms.RadioButton(); + this.rbtnRijndael_192 = new System.Windows.Forms.RadioButton(); + this.rbtnRC2_128 = new System.Windows.Forms.RadioButton(); + this.rbtnTripleDES_128 = new System.Windows.Forms.RadioButton(); + this.rbtnRijndael_128 = new System.Windows.Forms.RadioButton(); + this.rbtnRC2_40 = new System.Windows.Forms.RadioButton(); + this.rbtnRC2_64 = new System.Windows.Forms.RadioButton(); + this.rbtnRC2_96 = new System.Windows.Forms.RadioButton(); + this.btnOK = new System.Windows.Forms.Button(); + this.label1 = new System.Windows.Forms.Label(); + this.txtKey = new System.Windows.Forms.TextBox(); + this.txtIV = new System.Windows.Forms.TextBox(); + this.label2 = new System.Windows.Forms.Label(); + this.groupBox2 = new System.Windows.Forms.GroupBox(); + this.rbtnDE = new System.Windows.Forms.RadioButton(); + this.rbtnEN = new System.Windows.Forms.RadioButton(); + this.groupBox1.SuspendLayout(); + this.groupBox2.SuspendLayout(); + this.SuspendLayout(); + // + // btnReturn + // + this.btnReturn.Location = new System.Drawing.Point(353, 241); + this.btnReturn.Name = "btnReturn"; + this.btnReturn.Size = new System.Drawing.Size(75, 23); + this.btnReturn.TabIndex = 14; + this.btnReturn.Text = "返回"; + this.btnReturn.UseVisualStyleBackColor = true; + this.btnReturn.Click += new System.EventHandler(this.btnReturn_Click); + // + // rbtnDES + // + this.rbtnDES.AutoSize = true; + this.rbtnDES.Checked = true; + this.rbtnDES.Location = new System.Drawing.Point(15, 20); + this.rbtnDES.Name = "rbtnDES"; + this.rbtnDES.Size = new System.Drawing.Size(41, 16); + this.rbtnDES.TabIndex = 0; + this.rbtnDES.TabStop = true; + this.rbtnDES.Text = "DES"; + this.rbtnDES.UseVisualStyleBackColor = true; + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.rbtnRijndael_256); + this.groupBox1.Controls.Add(this.rbtnTripleDES_192); + this.groupBox1.Controls.Add(this.rbtnRijndael_192); + this.groupBox1.Controls.Add(this.rbtnRC2_128); + this.groupBox1.Controls.Add(this.rbtnTripleDES_128); + this.groupBox1.Controls.Add(this.rbtnRijndael_128); + this.groupBox1.Controls.Add(this.rbtnDES); + this.groupBox1.Controls.Add(this.rbtnRC2_40); + this.groupBox1.Controls.Add(this.rbtnRC2_64); + this.groupBox1.Controls.Add(this.rbtnRC2_96); + this.groupBox1.Location = new System.Drawing.Point(8, 8); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(420, 135); + this.groupBox1.TabIndex = 15; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "选择对称加密算法"; + // + // rbtnRijndael_256 + // + this.rbtnRijndael_256.AutoSize = true; + this.rbtnRijndael_256.Location = new System.Drawing.Point(165, 78); + this.rbtnRijndael_256.Name = "rbtnRijndael_256"; + this.rbtnRijndael_256.Size = new System.Drawing.Size(95, 16); + this.rbtnRijndael_256.TabIndex = 10; + this.rbtnRijndael_256.Text = "Rijndael_256"; + this.rbtnRijndael_256.UseVisualStyleBackColor = true; + // + // rbtnTripleDES_192 + // + this.rbtnTripleDES_192.AutoSize = true; + this.rbtnTripleDES_192.Location = new System.Drawing.Point(285, 49); + this.rbtnTripleDES_192.Name = "rbtnTripleDES_192"; + this.rbtnTripleDES_192.Size = new System.Drawing.Size(101, 16); + this.rbtnTripleDES_192.TabIndex = 9; + this.rbtnTripleDES_192.Text = "TripleDES_192"; + this.rbtnTripleDES_192.UseVisualStyleBackColor = true; + // + // rbtnRijndael_192 + // + this.rbtnRijndael_192.AutoSize = true; + this.rbtnRijndael_192.Location = new System.Drawing.Point(165, 49); + this.rbtnRijndael_192.Name = "rbtnRijndael_192"; + this.rbtnRijndael_192.Size = new System.Drawing.Size(95, 16); + this.rbtnRijndael_192.TabIndex = 8; + this.rbtnRijndael_192.Text = "Rijndael_192"; + this.rbtnRijndael_192.UseVisualStyleBackColor = true; + // + // rbtnRC2_128 + // + this.rbtnRC2_128.AutoSize = true; + this.rbtnRC2_128.Location = new System.Drawing.Point(81, 107); + this.rbtnRC2_128.Name = "rbtnRC2_128"; + this.rbtnRC2_128.Size = new System.Drawing.Size(65, 16); + this.rbtnRC2_128.TabIndex = 3; + this.rbtnRC2_128.Text = "RC2_128"; + this.rbtnRC2_128.UseVisualStyleBackColor = true; + // + // rbtnTripleDES_128 + // + this.rbtnTripleDES_128.AutoSize = true; + this.rbtnTripleDES_128.Location = new System.Drawing.Point(285, 20); + this.rbtnTripleDES_128.Name = "rbtnTripleDES_128"; + this.rbtnTripleDES_128.Size = new System.Drawing.Size(101, 16); + this.rbtnTripleDES_128.TabIndex = 6; + this.rbtnTripleDES_128.Text = "TripleDES_128"; + this.rbtnTripleDES_128.UseVisualStyleBackColor = true; + // + // rbtnRijndael_128 + // + this.rbtnRijndael_128.AutoSize = true; + this.rbtnRijndael_128.Location = new System.Drawing.Point(165, 20); + this.rbtnRijndael_128.Name = "rbtnRijndael_128"; + this.rbtnRijndael_128.Size = new System.Drawing.Size(95, 16); + this.rbtnRijndael_128.TabIndex = 5; + this.rbtnRijndael_128.Text = "Rijndael_128"; + this.rbtnRijndael_128.UseVisualStyleBackColor = true; + // + // rbtnRC2_40 + // + this.rbtnRC2_40.AutoSize = true; + this.rbtnRC2_40.Location = new System.Drawing.Point(81, 49); + this.rbtnRC2_40.Name = "rbtnRC2_40"; + this.rbtnRC2_40.Size = new System.Drawing.Size(59, 16); + this.rbtnRC2_40.TabIndex = 1; + this.rbtnRC2_40.Text = "RC2_40"; + this.rbtnRC2_40.UseVisualStyleBackColor = true; + // + // rbtnRC2_64 + // + this.rbtnRC2_64.AutoSize = true; + this.rbtnRC2_64.Location = new System.Drawing.Point(81, 20); + this.rbtnRC2_64.Name = "rbtnRC2_64"; + this.rbtnRC2_64.Size = new System.Drawing.Size(59, 16); + this.rbtnRC2_64.TabIndex = 2; + this.rbtnRC2_64.Text = "RC2_64"; + this.rbtnRC2_64.UseVisualStyleBackColor = true; + // + // rbtnRC2_96 + // + this.rbtnRC2_96.AutoSize = true; + this.rbtnRC2_96.Location = new System.Drawing.Point(81, 78); + this.rbtnRC2_96.Name = "rbtnRC2_96"; + this.rbtnRC2_96.Size = new System.Drawing.Size(59, 16); + this.rbtnRC2_96.TabIndex = 4; + this.rbtnRC2_96.Text = "RC2_96"; + this.rbtnRC2_96.UseVisualStyleBackColor = true; + // + // btnOK + // + this.btnOK.Location = new System.Drawing.Point(255, 241); + this.btnOK.Name = "btnOK"; + this.btnOK.Size = new System.Drawing.Size(75, 23); + this.btnOK.TabIndex = 13; + this.btnOK.Text = "确定"; + this.btnOK.UseVisualStyleBackColor = true; + this.btnOK.Click += new System.EventHandler(this.btnOK_Click); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(15, 22); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(53, 12); + this.label1.TabIndex = 16; + this.label1.Text = "加密密钥"; + // + // txtKey + // + this.txtKey.Location = new System.Drawing.Point(95, 18); + this.txtKey.Name = "txtKey"; + this.txtKey.Size = new System.Drawing.Size(237, 21); + this.txtKey.TabIndex = 17; + // + // txtIV + // + this.txtIV.Location = new System.Drawing.Point(95, 50); + this.txtIV.Name = "txtIV"; + this.txtIV.Size = new System.Drawing.Size(237, 21); + this.txtIV.TabIndex = 18; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(15, 54); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(65, 12); + this.label2.TabIndex = 19; + this.label2.Text = "初始化向量"; + // + // groupBox2 + // + this.groupBox2.Controls.Add(this.rbtnDE); + this.groupBox2.Controls.Add(this.rbtnEN); + this.groupBox2.Controls.Add(this.label2); + this.groupBox2.Controls.Add(this.label1); + this.groupBox2.Controls.Add(this.txtIV); + this.groupBox2.Controls.Add(this.txtKey); + this.groupBox2.Location = new System.Drawing.Point(8, 149); + this.groupBox2.Name = "groupBox2"; + this.groupBox2.Size = new System.Drawing.Size(420, 86); + this.groupBox2.TabIndex = 20; + this.groupBox2.TabStop = false; + this.groupBox2.Text = "选项"; + // + // rbtnDE + // + this.rbtnDE.AutoSize = true; + this.rbtnDE.Location = new System.Drawing.Point(356, 52); + this.rbtnDE.Name = "rbtnDE"; + this.rbtnDE.Size = new System.Drawing.Size(47, 16); + this.rbtnDE.TabIndex = 21; + this.rbtnDE.Text = "解密"; + this.rbtnDE.UseVisualStyleBackColor = true; + // + // rbtnEN + // + this.rbtnEN.AutoSize = true; + this.rbtnEN.Checked = true; + this.rbtnEN.Location = new System.Drawing.Point(356, 20); + this.rbtnEN.Name = "rbtnEN"; + this.rbtnEN.Size = new System.Drawing.Size(47, 16); + this.rbtnEN.TabIndex = 20; + this.rbtnEN.TabStop = true; + this.rbtnEN.Text = "加密"; + this.rbtnEN.UseVisualStyleBackColor = true; + // + // String_SymmetricAlgorithm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(435, 271); + this.Controls.Add(this.groupBox2); + this.Controls.Add(this.btnReturn); + this.Controls.Add(this.groupBox1); + this.Controls.Add(this.btnOK); + this.Name = "String_SymmetricAlgorithm"; + this.Text = "加密与解密"; + this.groupBox1.ResumeLayout(false); + this.groupBox1.PerformLayout(); + this.groupBox2.ResumeLayout(false); + this.groupBox2.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Button btnReturn; + private System.Windows.Forms.RadioButton rbtnDES; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.RadioButton rbtnRC2_40; + private System.Windows.Forms.RadioButton rbtnRC2_64; + private System.Windows.Forms.RadioButton rbtnRC2_128; + private System.Windows.Forms.RadioButton rbtnRC2_96; + private System.Windows.Forms.Button btnOK; + private System.Windows.Forms.RadioButton rbtnRijndael_256; + private System.Windows.Forms.RadioButton rbtnTripleDES_192; + private System.Windows.Forms.RadioButton rbtnRijndael_192; + private System.Windows.Forms.RadioButton rbtnTripleDES_128; + private System.Windows.Forms.RadioButton rbtnRijndael_128; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.TextBox txtKey; + private System.Windows.Forms.TextBox txtIV; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.GroupBox groupBox2; + private System.Windows.Forms.RadioButton rbtnDE; + private System.Windows.Forms.RadioButton rbtnEN; + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/ToolForm/StringConvertor/String_SymmetricAlgorithm.cs b/src/Kalman.Studio/ToolForm/StringConvertor/String_SymmetricAlgorithm.cs new file mode 100644 index 0000000..4c6ce2f --- /dev/null +++ b/src/Kalman.Studio/ToolForm/StringConvertor/String_SymmetricAlgorithm.cs @@ -0,0 +1,80 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using Kalman.Security; + +namespace Kalman.Studio +{ + public partial class String_SymmetricAlgorithm : StringConvertorBase + { + public String_SymmetricAlgorithm() + { + InitializeComponent(); + } + + private void btnOK_Click(object sender, EventArgs e) + { + SymmetricAlgorithmType algorithmType = SymmetricAlgorithmType.DES; + if (rbtnDES.Checked) algorithmType = SymmetricAlgorithmType.DES; + + if (rbtnRC2_128.Checked) algorithmType = SymmetricAlgorithmType.RC2_128; + if (rbtnRC2_40.Checked) algorithmType = SymmetricAlgorithmType.RC2_40; + if (rbtnRC2_64.Checked) algorithmType = SymmetricAlgorithmType.RC2_64; + if (rbtnRC2_96.Checked) algorithmType = SymmetricAlgorithmType.RC2_96; + + if (rbtnRijndael_128.Checked) algorithmType = SymmetricAlgorithmType.Rijndael_128; + if (rbtnRijndael_192.Checked) algorithmType = SymmetricAlgorithmType.Rijndael_192; + if (rbtnRijndael_256.Checked) algorithmType = SymmetricAlgorithmType.Rijndael_256; + + if (rbtnTripleDES_128.Checked) algorithmType = SymmetricAlgorithmType.TripleDES_128; + if (rbtnTripleDES_192.Checked) algorithmType = SymmetricAlgorithmType.TripleDES_192; + + string key = txtKey.Text; + string iv = txtIV.Text; + + SymmetricCryto sc = null; + if (string.IsNullOrEmpty(key)) + { + sc = new SymmetricCryto(algorithmType); + } + else + { + if (string.IsNullOrEmpty(iv)) + { + sc = new SymmetricCryto(key, algorithmType); + } + else + { + sc = new SymmetricCryto(key, iv, algorithmType); + } + } + + try + { + if (rbtnEN.Checked) + { + SC.S2 = sc.EncryptString(SC.S1); + } + else + { + SC.S2 = sc.DecryptString(SC.S1); + } + this.Close(); + } + catch (Exception ex) + { + MessageBox.Show(ex.Message); + } + } + + private void btnReturn_Click(object sender, EventArgs e) + { + this.Close(); + } + } +} diff --git a/src/Kalman.Studio/ToolForm/StringConvertor/String_SymmetricAlgorithm.resx b/src/Kalman.Studio/ToolForm/StringConvertor/String_SymmetricAlgorithm.resx new file mode 100644 index 0000000..19dc0dd --- /dev/null +++ b/src/Kalman.Studio/ToolForm/StringConvertor/String_SymmetricAlgorithm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/Kalman.Studio/ToolForm/TestDataGenerator/TestDataGenerator.Designer.cs b/src/Kalman.Studio/ToolForm/TestDataGenerator/TestDataGenerator.Designer.cs new file mode 100644 index 0000000..57157d0 --- /dev/null +++ b/src/Kalman.Studio/ToolForm/TestDataGenerator/TestDataGenerator.Designer.cs @@ -0,0 +1,657 @@ +namespace Kalman.Studio +{ + partial class TestDataGenerator + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle4 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle5 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle6 = new System.Windows.Forms.DataGridViewCellStyle(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(TestDataGenerator)); + this.tabControl1 = new System.Windows.Forms.TabControl(); + this.tabPage1 = new System.Windows.Forms.TabPage(); + this.splitContainer1 = new System.Windows.Forms.SplitContainer(); + this.gbObjName = new System.Windows.Forms.GroupBox(); + this.dataGridView1 = new System.Windows.Forms.DataGridView(); + this.colSelect = new System.Windows.Forms.DataGridViewCheckBoxColumn(); + this.colName = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colPK = new System.Windows.Forms.DataGridViewCheckBoxColumn(); + this.colIdentify = new System.Windows.Forms.DataGridViewCheckBoxColumn(); + this.colAllowDBNull = new System.Windows.Forms.DataGridViewCheckBoxColumn(); + this.colNativeType = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colLength = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colPercision = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colScale = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colDefaultValue = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colDescription = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.cmsGrid = new System.Windows.Forms.ContextMenuStrip(this.components); + this.menuItemCheckAll = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemUnCheckAll = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemImport = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemExport = new System.Windows.Forms.ToolStripMenuItem(); + this.label2 = new System.Windows.Forms.Label(); + this.btnGenerator = new System.Windows.Forms.Button(); + this.btnPreview = new System.Windows.Forms.Button(); + this.label1 = new System.Windows.Forms.Label(); + this.tabPage2 = new System.Windows.Forms.TabPage(); + this.textEditorControl2 = new ICSharpCode.TextEditor.TextEditorControl(); + this.cms = new System.Windows.Forms.ContextMenuStrip(this.components); + this.menuItemUndo = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemRedo = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator(); + this.menuItemCut = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemCopy = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemPaste = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemDelete = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); + this.menuItemSelectAll = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); + this.menuItemConfig = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemAspxCode = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemCppCode = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemCSharpCode = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemHtmlCode = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemJavaCode = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemJsCode = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemPhpCode = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemTSQLCode = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemVBCode = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemXmlCode = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemSave = new System.Windows.Forms.ToolStripMenuItem(); + this.menuItemBuildCode = new System.Windows.Forms.ToolStripMenuItem(); + this.tabControl1.SuspendLayout(); + this.tabPage1.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); + this.splitContainer1.Panel1.SuspendLayout(); + this.splitContainer1.Panel2.SuspendLayout(); + this.splitContainer1.SuspendLayout(); + this.gbObjName.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit(); + this.cmsGrid.SuspendLayout(); + this.tabPage2.SuspendLayout(); + this.cms.SuspendLayout(); + this.SuspendLayout(); + // + // tabControl1 + // + this.tabControl1.Alignment = System.Windows.Forms.TabAlignment.Bottom; + this.tabControl1.Controls.Add(this.tabPage1); + this.tabControl1.Controls.Add(this.tabPage2); + this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill; + this.tabControl1.Location = new System.Drawing.Point(0, 0); + this.tabControl1.Multiline = true; + this.tabControl1.Name = "tabControl1"; + this.tabControl1.SelectedIndex = 0; + this.tabControl1.Size = new System.Drawing.Size(808, 528); + this.tabControl1.TabIndex = 3; + // + // tabPage1 + // + this.tabPage1.Controls.Add(this.splitContainer1); + this.tabPage1.Location = new System.Drawing.Point(4, 4); + this.tabPage1.Name = "tabPage1"; + this.tabPage1.Padding = new System.Windows.Forms.Padding(3); + this.tabPage1.Size = new System.Drawing.Size(800, 502); + this.tabPage1.TabIndex = 0; + this.tabPage1.Text = "生成选项"; + this.tabPage1.UseVisualStyleBackColor = true; + // + // splitContainer1 + // + this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill; + this.splitContainer1.Location = new System.Drawing.Point(3, 3); + this.splitContainer1.Name = "splitContainer1"; + this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal; + // + // splitContainer1.Panel1 + // + this.splitContainer1.Panel1.Controls.Add(this.gbObjName); + // + // splitContainer1.Panel2 + // + this.splitContainer1.Panel2.Controls.Add(this.label2); + this.splitContainer1.Panel2.Controls.Add(this.btnGenerator); + this.splitContainer1.Panel2.Controls.Add(this.btnPreview); + this.splitContainer1.Panel2.Controls.Add(this.label1); + this.splitContainer1.Size = new System.Drawing.Size(794, 496); + this.splitContainer1.SplitterDistance = 263; + this.splitContainer1.TabIndex = 0; + // + // gbObjName + // + this.gbObjName.Controls.Add(this.dataGridView1); + this.gbObjName.Dock = System.Windows.Forms.DockStyle.Fill; + this.gbObjName.Location = new System.Drawing.Point(0, 0); + this.gbObjName.Name = "gbObjName"; + this.gbObjName.Size = new System.Drawing.Size(794, 263); + this.gbObjName.TabIndex = 2; + this.gbObjName.TabStop = false; + this.gbObjName.Text = "groupBox1"; + // + // dataGridView1 + // + this.dataGridView1.AllowUserToAddRows = false; + this.dataGridView1.AllowUserToDeleteRows = false; + this.dataGridView1.AllowUserToResizeRows = false; + dataGridViewCellStyle4.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle4.BackColor = System.Drawing.SystemColors.Control; + dataGridViewCellStyle4.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + dataGridViewCellStyle4.ForeColor = System.Drawing.SystemColors.WindowText; + dataGridViewCellStyle4.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle4.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle4.WrapMode = System.Windows.Forms.DataGridViewTriState.True; + this.dataGridView1.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle4; + this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.dataGridView1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { + this.colSelect, + this.colName, + this.colPK, + this.colIdentify, + this.colAllowDBNull, + this.colNativeType, + this.colLength, + this.colPercision, + this.colScale, + this.colDefaultValue, + this.colDescription}); + this.dataGridView1.ContextMenuStrip = this.cmsGrid; + dataGridViewCellStyle5.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle5.BackColor = System.Drawing.SystemColors.Window; + dataGridViewCellStyle5.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + dataGridViewCellStyle5.ForeColor = System.Drawing.SystemColors.ControlText; + dataGridViewCellStyle5.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle5.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle5.WrapMode = System.Windows.Forms.DataGridViewTriState.False; + this.dataGridView1.DefaultCellStyle = dataGridViewCellStyle5; + this.dataGridView1.Dock = System.Windows.Forms.DockStyle.Fill; + this.dataGridView1.Location = new System.Drawing.Point(3, 17); + this.dataGridView1.MultiSelect = false; + this.dataGridView1.Name = "dataGridView1"; + dataGridViewCellStyle6.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle6.BackColor = System.Drawing.SystemColors.Control; + dataGridViewCellStyle6.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + dataGridViewCellStyle6.ForeColor = System.Drawing.SystemColors.WindowText; + dataGridViewCellStyle6.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle6.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle6.WrapMode = System.Windows.Forms.DataGridViewTriState.True; + this.dataGridView1.RowHeadersDefaultCellStyle = dataGridViewCellStyle6; + this.dataGridView1.RowHeadersVisible = false; + this.dataGridView1.RowTemplate.Height = 23; + this.dataGridView1.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect; + this.dataGridView1.Size = new System.Drawing.Size(788, 243); + this.dataGridView1.TabIndex = 0; + // + // colSelect + // + this.colSelect.HeaderText = "选择"; + this.colSelect.MinimumWidth = 50; + this.colSelect.Name = "colSelect"; + this.colSelect.Width = 50; + // + // colName + // + this.colName.DataPropertyName = "Name"; + this.colName.HeaderText = "字段名"; + this.colName.Name = "colName"; + this.colName.Width = 160; + // + // colPK + // + this.colPK.DataPropertyName = "PrimaryKey"; + this.colPK.HeaderText = "P"; + this.colPK.Name = "colPK"; + this.colPK.ReadOnly = true; + this.colPK.Resizable = System.Windows.Forms.DataGridViewTriState.True; + this.colPK.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic; + this.colPK.ToolTipText = "是否为主键"; + this.colPK.Width = 25; + // + // colIdentify + // + this.colIdentify.DataPropertyName = "Identify"; + this.colIdentify.HeaderText = "I"; + this.colIdentify.Name = "colIdentify"; + this.colIdentify.ReadOnly = true; + this.colIdentify.Resizable = System.Windows.Forms.DataGridViewTriState.True; + this.colIdentify.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic; + this.colIdentify.ToolTipText = "是否为标识列"; + this.colIdentify.Width = 25; + // + // colAllowDBNull + // + this.colAllowDBNull.DataPropertyName = "Nullable"; + this.colAllowDBNull.HeaderText = "N"; + this.colAllowDBNull.Name = "colAllowDBNull"; + this.colAllowDBNull.ReadOnly = true; + this.colAllowDBNull.Resizable = System.Windows.Forms.DataGridViewTriState.True; + this.colAllowDBNull.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic; + this.colAllowDBNull.ToolTipText = "是否允许为空"; + this.colAllowDBNull.Width = 25; + // + // colNativeType + // + this.colNativeType.DataPropertyName = "NativeType"; + this.colNativeType.HeaderText = "数据类型"; + this.colNativeType.Name = "colNativeType"; + this.colNativeType.ToolTipText = "数据库定义的数据类型"; + this.colNativeType.Width = 120; + // + // colLength + // + this.colLength.DataPropertyName = "Length"; + this.colLength.HeaderText = "长度"; + this.colLength.Name = "colLength"; + this.colLength.Width = 60; + // + // colPercision + // + this.colPercision.DataPropertyName = "Percision"; + this.colPercision.HeaderText = "精度"; + this.colPercision.Name = "colPercision"; + this.colPercision.Width = 60; + // + // colScale + // + this.colScale.DataPropertyName = "Scale"; + this.colScale.HeaderText = "小数"; + this.colScale.Name = "colScale"; + this.colScale.ToolTipText = "小数位数"; + this.colScale.Width = 60; + // + // colDefaultValue + // + this.colDefaultValue.DataPropertyName = "DefaultValue"; + this.colDefaultValue.HeaderText = "默认值"; + this.colDefaultValue.Name = "colDefaultValue"; + this.colDefaultValue.Width = 80; + // + // colDescription + // + this.colDescription.DataPropertyName = "Comment"; + this.colDescription.HeaderText = "注释"; + this.colDescription.Name = "colDescription"; + this.colDescription.Width = 120; + // + // cmsGrid + // + this.cmsGrid.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.menuItemCheckAll, + this.menuItemUnCheckAll, + this.menuItemImport, + this.menuItemExport}); + this.cmsGrid.Name = "cmsGrid"; + this.cmsGrid.Size = new System.Drawing.Size(171, 92); + // + // menuItemCheckAll + // + this.menuItemCheckAll.Name = "menuItemCheckAll"; + this.menuItemCheckAll.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.A))); + this.menuItemCheckAll.Size = new System.Drawing.Size(170, 22); + this.menuItemCheckAll.Text = "全选(&A)"; + // + // menuItemUnCheckAll + // + this.menuItemUnCheckAll.Name = "menuItemUnCheckAll"; + this.menuItemUnCheckAll.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.U))); + this.menuItemUnCheckAll.Size = new System.Drawing.Size(170, 22); + this.menuItemUnCheckAll.Text = "反选(&U)"; + // + // menuItemImport + // + this.menuItemImport.Name = "menuItemImport"; + this.menuItemImport.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.I))); + this.menuItemImport.Size = new System.Drawing.Size(170, 22); + this.menuItemImport.Text = "导入(&I)..."; + // + // menuItemExport + // + this.menuItemExport.Name = "menuItemExport"; + this.menuItemExport.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.U))); + this.menuItemExport.Size = new System.Drawing.Size(170, 22); + this.menuItemExport.Text = "导出(&E)..."; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(61, 20); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(101, 12); + this.label2.TabIndex = 3; + this.label2.Text = "生成测试数据行数"; + // + // btnGenerator + // + this.btnGenerator.Location = new System.Drawing.Point(668, 59); + this.btnGenerator.Name = "btnGenerator"; + this.btnGenerator.Size = new System.Drawing.Size(75, 23); + this.btnGenerator.TabIndex = 2; + this.btnGenerator.Text = "生成"; + this.btnGenerator.UseVisualStyleBackColor = true; + this.btnGenerator.Click += new System.EventHandler(this.btnGenerator_Click); + // + // btnPreview + // + this.btnPreview.Location = new System.Drawing.Point(668, 15); + this.btnPreview.Name = "btnPreview"; + this.btnPreview.Size = new System.Drawing.Size(75, 23); + this.btnPreview.TabIndex = 1; + this.btnPreview.Text = "预览"; + this.btnPreview.UseVisualStyleBackColor = true; + this.btnPreview.Click += new System.EventHandler(this.btnPreview_Click); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(80, 172); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(101, 12); + this.label1.TabIndex = 0; + this.label1.Text = "生成测试数据行数"; + // + // tabPage2 + // + this.tabPage2.Controls.Add(this.textEditorControl2); + this.tabPage2.Location = new System.Drawing.Point(4, 4); + this.tabPage2.Name = "tabPage2"; + this.tabPage2.Padding = new System.Windows.Forms.Padding(3); + this.tabPage2.Size = new System.Drawing.Size(800, 502); + this.tabPage2.TabIndex = 1; + this.tabPage2.Text = "输出脚本"; + this.tabPage2.UseVisualStyleBackColor = true; + // + // textEditorControl2 + // + this.textEditorControl2.ContextMenuStrip = this.cms; + this.textEditorControl2.Dock = System.Windows.Forms.DockStyle.Fill; + this.textEditorControl2.IsReadOnly = false; + this.textEditorControl2.Location = new System.Drawing.Point(3, 3); + this.textEditorControl2.Name = "textEditorControl2"; + this.textEditorControl2.Size = new System.Drawing.Size(794, 496); + this.textEditorControl2.TabIndex = 1; + // + // cms + // + this.cms.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.menuItemUndo, + this.menuItemRedo, + this.toolStripSeparator5, + this.menuItemCut, + this.menuItemCopy, + this.menuItemPaste, + this.menuItemDelete, + this.toolStripSeparator1, + this.menuItemSelectAll, + this.toolStripSeparator2, + this.menuItemConfig, + this.menuItemSave, + this.menuItemBuildCode}); + this.cms.Name = "cms"; + this.cms.Size = new System.Drawing.Size(163, 242); + // + // menuItemUndo + // + this.menuItemUndo.Image = ((System.Drawing.Image)(resources.GetObject("menuItemUndo.Image"))); + this.menuItemUndo.Name = "menuItemUndo"; + this.menuItemUndo.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Z))); + this.menuItemUndo.Size = new System.Drawing.Size(162, 22); + this.menuItemUndo.Text = "撤销(&Z)"; + // + // menuItemRedo + // + this.menuItemRedo.Image = ((System.Drawing.Image)(resources.GetObject("menuItemRedo.Image"))); + this.menuItemRedo.Name = "menuItemRedo"; + this.menuItemRedo.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Y))); + this.menuItemRedo.Size = new System.Drawing.Size(162, 22); + this.menuItemRedo.Text = "重复(&R)"; + // + // toolStripSeparator5 + // + this.toolStripSeparator5.Name = "toolStripSeparator5"; + this.toolStripSeparator5.Size = new System.Drawing.Size(159, 6); + // + // menuItemCut + // + this.menuItemCut.Image = ((System.Drawing.Image)(resources.GetObject("menuItemCut.Image"))); + this.menuItemCut.Name = "menuItemCut"; + this.menuItemCut.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.X))); + this.menuItemCut.Size = new System.Drawing.Size(162, 22); + this.menuItemCut.Text = "剪切(&X)"; + // + // menuItemCopy + // + this.menuItemCopy.Image = ((System.Drawing.Image)(resources.GetObject("menuItemCopy.Image"))); + this.menuItemCopy.Name = "menuItemCopy"; + this.menuItemCopy.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.C))); + this.menuItemCopy.Size = new System.Drawing.Size(162, 22); + this.menuItemCopy.Text = "复制(&C)"; + // + // menuItemPaste + // + this.menuItemPaste.Image = ((System.Drawing.Image)(resources.GetObject("menuItemPaste.Image"))); + this.menuItemPaste.Name = "menuItemPaste"; + this.menuItemPaste.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.V))); + this.menuItemPaste.Size = new System.Drawing.Size(162, 22); + this.menuItemPaste.Text = "粘贴(&V)"; + // + // menuItemDelete + // + this.menuItemDelete.Image = ((System.Drawing.Image)(resources.GetObject("menuItemDelete.Image"))); + this.menuItemDelete.Name = "menuItemDelete"; + this.menuItemDelete.ShortcutKeys = System.Windows.Forms.Keys.Delete; + this.menuItemDelete.Size = new System.Drawing.Size(162, 22); + this.menuItemDelete.Text = "删除(&D)"; + // + // toolStripSeparator1 + // + this.toolStripSeparator1.Name = "toolStripSeparator1"; + this.toolStripSeparator1.Size = new System.Drawing.Size(159, 6); + // + // menuItemSelectAll + // + this.menuItemSelectAll.Name = "menuItemSelectAll"; + this.menuItemSelectAll.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.A))); + this.menuItemSelectAll.Size = new System.Drawing.Size(162, 22); + this.menuItemSelectAll.Text = "全选(&A)"; + // + // toolStripSeparator2 + // + this.toolStripSeparator2.Name = "toolStripSeparator2"; + this.toolStripSeparator2.Size = new System.Drawing.Size(159, 6); + // + // menuItemConfig + // + this.menuItemConfig.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.menuItemAspxCode, + this.menuItemCppCode, + this.menuItemCSharpCode, + this.menuItemHtmlCode, + this.menuItemJavaCode, + this.menuItemJsCode, + this.menuItemPhpCode, + this.menuItemTSQLCode, + this.menuItemVBCode, + this.menuItemXmlCode}); + this.menuItemConfig.Name = "menuItemConfig"; + this.menuItemConfig.Size = new System.Drawing.Size(162, 22); + this.menuItemConfig.Text = "选择配置"; + // + // menuItemAspxCode + // + this.menuItemAspxCode.Name = "menuItemAspxCode"; + this.menuItemAspxCode.Size = new System.Drawing.Size(133, 22); + this.menuItemAspxCode.Text = "Aspx"; + // + // menuItemCppCode + // + this.menuItemCppCode.Name = "menuItemCppCode"; + this.menuItemCppCode.Size = new System.Drawing.Size(133, 22); + this.menuItemCppCode.Text = "C/C++"; + // + // menuItemCSharpCode + // + this.menuItemCSharpCode.Name = "menuItemCSharpCode"; + this.menuItemCSharpCode.Size = new System.Drawing.Size(133, 22); + this.menuItemCSharpCode.Text = "C#"; + // + // menuItemHtmlCode + // + this.menuItemHtmlCode.Name = "menuItemHtmlCode"; + this.menuItemHtmlCode.Size = new System.Drawing.Size(133, 22); + this.menuItemHtmlCode.Text = "Html"; + // + // menuItemJavaCode + // + this.menuItemJavaCode.Name = "menuItemJavaCode"; + this.menuItemJavaCode.Size = new System.Drawing.Size(133, 22); + this.menuItemJavaCode.Text = "Java"; + // + // menuItemJsCode + // + this.menuItemJsCode.Name = "menuItemJsCode"; + this.menuItemJsCode.Size = new System.Drawing.Size(133, 22); + this.menuItemJsCode.Text = "Javascript"; + // + // menuItemPhpCode + // + this.menuItemPhpCode.Name = "menuItemPhpCode"; + this.menuItemPhpCode.Size = new System.Drawing.Size(133, 22); + this.menuItemPhpCode.Text = "PHP"; + // + // menuItemTSQLCode + // + this.menuItemTSQLCode.Name = "menuItemTSQLCode"; + this.menuItemTSQLCode.Size = new System.Drawing.Size(133, 22); + this.menuItemTSQLCode.Text = "TSQL"; + // + // menuItemVBCode + // + this.menuItemVBCode.Name = "menuItemVBCode"; + this.menuItemVBCode.Size = new System.Drawing.Size(133, 22); + this.menuItemVBCode.Text = "VB.NET"; + // + // menuItemXmlCode + // + this.menuItemXmlCode.Name = "menuItemXmlCode"; + this.menuItemXmlCode.Size = new System.Drawing.Size(133, 22); + this.menuItemXmlCode.Text = "XML"; + // + // menuItemSave + // + this.menuItemSave.Image = ((System.Drawing.Image)(resources.GetObject("menuItemSave.Image"))); + this.menuItemSave.Name = "menuItemSave"; + this.menuItemSave.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.S))); + this.menuItemSave.Size = new System.Drawing.Size(162, 22); + this.menuItemSave.Text = "保存(&S)"; + // + // menuItemBuildCode + // + this.menuItemBuildCode.Name = "menuItemBuildCode"; + this.menuItemBuildCode.ShortcutKeys = System.Windows.Forms.Keys.F5; + this.menuItemBuildCode.Size = new System.Drawing.Size(162, 22); + this.menuItemBuildCode.Text = "生成代码"; + // + // TestDataGenerator + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(808, 528); + this.Controls.Add(this.tabControl1); + this.Name = "TestDataGenerator"; + this.Text = "测试数据生成器"; + this.Load += new System.EventHandler(this.TestDataGenerator_Load); + this.tabControl1.ResumeLayout(false); + this.tabPage1.ResumeLayout(false); + this.splitContainer1.Panel1.ResumeLayout(false); + this.splitContainer1.Panel2.ResumeLayout(false); + this.splitContainer1.Panel2.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit(); + this.splitContainer1.ResumeLayout(false); + this.gbObjName.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit(); + this.cmsGrid.ResumeLayout(false); + this.tabPage2.ResumeLayout(false); + this.cms.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.TabControl tabControl1; + private System.Windows.Forms.TabPage tabPage1; + private System.Windows.Forms.ContextMenuStrip cmsGrid; + private System.Windows.Forms.ToolStripMenuItem menuItemCheckAll; + private System.Windows.Forms.ToolStripMenuItem menuItemUnCheckAll; + private System.Windows.Forms.ContextMenuStrip cms; + private System.Windows.Forms.ToolStripMenuItem menuItemUndo; + private System.Windows.Forms.ToolStripMenuItem menuItemRedo; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator5; + private System.Windows.Forms.ToolStripMenuItem menuItemCut; + private System.Windows.Forms.ToolStripMenuItem menuItemCopy; + private System.Windows.Forms.ToolStripMenuItem menuItemPaste; + private System.Windows.Forms.ToolStripMenuItem menuItemDelete; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; + private System.Windows.Forms.ToolStripMenuItem menuItemSelectAll; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator2; + private System.Windows.Forms.ToolStripMenuItem menuItemConfig; + private System.Windows.Forms.ToolStripMenuItem menuItemAspxCode; + private System.Windows.Forms.ToolStripMenuItem menuItemCppCode; + private System.Windows.Forms.ToolStripMenuItem menuItemCSharpCode; + private System.Windows.Forms.ToolStripMenuItem menuItemHtmlCode; + private System.Windows.Forms.ToolStripMenuItem menuItemJavaCode; + private System.Windows.Forms.ToolStripMenuItem menuItemJsCode; + private System.Windows.Forms.ToolStripMenuItem menuItemPhpCode; + private System.Windows.Forms.ToolStripMenuItem menuItemTSQLCode; + private System.Windows.Forms.ToolStripMenuItem menuItemVBCode; + private System.Windows.Forms.ToolStripMenuItem menuItemXmlCode; + private System.Windows.Forms.ToolStripMenuItem menuItemSave; + private System.Windows.Forms.ToolStripMenuItem menuItemBuildCode; + private System.Windows.Forms.TabPage tabPage2; + private ICSharpCode.TextEditor.TextEditorControl textEditorControl2; + private System.Windows.Forms.SplitContainer splitContainer1; + private System.Windows.Forms.GroupBox gbObjName; + private System.Windows.Forms.DataGridView dataGridView1; + private System.Windows.Forms.Button btnGenerator; + private System.Windows.Forms.Button btnPreview; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.ToolStripMenuItem menuItemImport; + private System.Windows.Forms.ToolStripMenuItem menuItemExport; + private System.Windows.Forms.DataGridViewCheckBoxColumn colSelect; + private System.Windows.Forms.DataGridViewTextBoxColumn colName; + private System.Windows.Forms.DataGridViewCheckBoxColumn colPK; + private System.Windows.Forms.DataGridViewCheckBoxColumn colIdentify; + private System.Windows.Forms.DataGridViewCheckBoxColumn colAllowDBNull; + private System.Windows.Forms.DataGridViewTextBoxColumn colNativeType; + private System.Windows.Forms.DataGridViewTextBoxColumn colLength; + private System.Windows.Forms.DataGridViewTextBoxColumn colPercision; + private System.Windows.Forms.DataGridViewTextBoxColumn colScale; + private System.Windows.Forms.DataGridViewTextBoxColumn colDefaultValue; + private System.Windows.Forms.DataGridViewTextBoxColumn colDescription; + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/ToolForm/TestDataGenerator/TestDataGenerator.cs b/src/Kalman.Studio/ToolForm/TestDataGenerator/TestDataGenerator.cs new file mode 100644 index 0000000..101a447 --- /dev/null +++ b/src/Kalman.Studio/ToolForm/TestDataGenerator/TestDataGenerator.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using Kalman.Data.SchemaObject; + +namespace Kalman.Studio +{ + public partial class TestDataGenerator : DockableForm + { + public TestDataGenerator() + { + InitializeComponent(); + } + + public SOTable Table { get; set; } + + private void TestDataGenerator_Load(object sender, EventArgs e) + { + LoadColumnList(); + ShowTitle(); + } + + public void LoadColumnList() + { + dataGridView1.AutoGenerateColumns = false; + if (Table.ColumnList != null) + { + this.dataGridView1.DataSource = Table.ColumnList; + foreach (DataGridViewRow row in dataGridView1.Rows) + { + DataGridViewCheckBoxCell cell = row.Cells[0] as DataGridViewCheckBoxCell; + cell.ValueType = typeof(bool); + cell.Value = true; + } + ShowTitle(); + } + } + + private void ShowTitle() + { + if (this.Table != null) + { + if (Table.Database != null) + { + gbObjName.Text = string.Format("当前对象:{0} -> {1}", Table.Database, Table.Name); + } + else + { + gbObjName.Text = string.Format("当前对象:{0}", Table.Name); + } + } + else + { + gbObjName.Text = "没有选择表"; + } + } + + private void btnPreview_Click(object sender, EventArgs e) + { + + } + + private void btnGenerator_Click(object sender, EventArgs e) + { + + } + } +} diff --git a/src/Kalman.Studio/ToolForm/TestDataGenerator/TestDataGenerator.resx b/src/Kalman.Studio/ToolForm/TestDataGenerator/TestDataGenerator.resx new file mode 100644 index 0000000..f2dc86b --- /dev/null +++ b/src/Kalman.Studio/ToolForm/TestDataGenerator/TestDataGenerator.resx @@ -0,0 +1,246 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + 372, 17 + + + 562, 17 + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6 + JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAABSUlEQVQ4T82QPXKDMBCFOUJuEG4AN0Bd + 0kHpVFC6Q53pRJkOSjrUmQ51Tme1qeAG1g3YG2y0QpnYk8Rxiszkm9lBs8t7+xP8Kc1hKRoFWr6A6TXo + 8QjteFxCX74OCVsFaL9GDGuQkdIAX5q0A2D/usT0bkaQJM5bAMZnZFuFUa4gqQzIA4A1MU70jnW8q62B + 1DCL/VKTuGgNMq6tWJNYJ6UyrJCYPbv/Lg0I3hnkHSCXvnOhkCLKR071VIxhtJFuCrEH7UTnUMesps6r + SfTYKCtmvuygab41yGqDMV9NaBIyFP3yySAV1mAA5VMfsIp2poNpjO3o8cZG1qIvB3aakGp0g7I7ubWu + Qof1T8f9Q8OoCa3oU78j2eqZuqdi+rn7OXmzhEk5FU5czeDTt5PuTozEWTVj9DRmPn07doIi2U21PeLF + Tf4LQfAG2Qrx8PcCm/4AAAAASUVORK5CYII= + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6 + JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAABUElEQVQ4T82SIXLDMBBFc4TcoLmBfQOb + NUyGYTYMs1nNVNYwG4ZZrGUWa4oiWhTfILqB/g3UXcXTOpOmncwU9M2IrPT//l179mf0e7fo92g7A6N2 + sE3vCtm5+Xj9MyzWBmChfJkcBZBJMT67DomtegWS2iLKNdK19klpkLdASSZl5zJ+1727OK0GH0RTFBlk + G/h4pUioLZkYNooL7YsWPt/CkklB74Z0bTwlPh9NPsNw97v7xgrZL7gW5X0VrRTiTHnxBFsp+GpLTcg0 + iKZMDMxYCpBJGi0bzWJOkj2eUo7XX9DCtJBARAnGUqB5c3G7O3UO4sr6OGsvDcrtsTrtQPu7RH7Oxwvj + mTk2d2bxYvmNAcMR09p6GiMdS4GLhV1DyENIkazNMJZuR9QDgkl5KPLGha9xE5Ho5qK2g9gA4uF4NspN + COkySvD7L/wPmM0+ADOA5n3xyUK3AAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6 + JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAABbklEQVQ4T6WTr1LDQBDG+wbtG6RvkHOV + F1V7USAvgoG6RjAFlwim4O4cdRcFMvcGicSlb5A4ZM4hl93wZ5Imw8AgfjPZb779dm87nQHAvxgJeV5o + 85w3PY3Vde2SvbI97ZuRoEzO9CGD5N4sqW7fILW2BLlNolMvMRIIfbCAQRl+L+rX1kVxCvP5vAs8ZSQQ + +AyndQZVVaXlyxHCKP5bgHkqLD1DPZoyTjUIId2Uj5gUlTIBNdLqNJ2vxeQBiUmRwKM5ag43KQg5fUBi + JMi7lsl9a8O0AbGrbHh7BHFTOSTjl0V46h8UXbNqnUhqx8+N84Vq+LZwFBJsSuDS6L6fGBRiX9vwoUGz + BRZqwICvDZb8Ko9I6/uJQUHNOJ3xi5x9Biy6gOuK8TMVsyBG208B9G4yS5qWooRb7YpjEOFGQQSe549+ + zkGBR/sw43RvJbr/A63ur6TzEF8ktMKgZ1B05nPVUIO/HpunmBR/D8zeAdVhtIeECSVyAAAAAElFTkSu + QmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6 + JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAABPklEQVQ4T72RoXLDMBBE/Sn+g/gTDD1F + Zi2LWQsNCwXLIugywbAImlXQUNCsgoWCZdu7kxPH7iQGnenOLNHcvb07ZX+WdQHJPrn3MNbj8H6qp5L7 + 4ua1jHVolMHuYV9MZbfFqWvpo4MbPJpWb0N4ZJYbAZocPkRoY2GHSCslm57ebPL+8FlOrUk87kXfQIxA + +KJGAqyljhHFi8Pu+WOGGBqXZQYanZKUDWhNgKHktdougYsni93jKUF4X1aU9CjpvIbp03G1TfZjRKOD + NLPz2iABaF9uPieLO0+HXP4O1zDceYLTsZYAmpZT/RiogDwEKAKxeO+2C5JeKy8WQHUFKKrml1s9f+85 + gNPlV+jweaUT4JaatwS4Tr5MQHfbBNSvTvbmcWc7aebD5+UGoGzd4uJiShVTc16q+4B/Upb9AFGm2tYv + vAfhAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6 + JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAABkElEQVQ4T7WSIW/DMBCF8xP6E/oTAgcN + x2ZYNsOyGo7NbGU1DDQsm2GhYaBhoWGh4djbuzjZuqnTpEk76clSkve9u3O6f6kUHUQxOOweH/r58e16 + PR5sPHosCt6gXsKkcvawWwW/t5SbzsPLTs3WVmKqNQJUrQFhsNO52z7kPDo4q+FMj5oIPq1hjcZsbSUA + MYv83iCPBF480x3KaBAHDbNRCG6N7DvYzXdAWAAB3hkmijRbn8VES4C3DWDu1VdAWAAyd2F6tshh9amB + onGRuuu/AQbXllZ4njl/1uSt4ANHGiKcp/YB1gWYJw9j/Q2AJJ+5pJHmxIUJgOaPemOTtaJcKvTWQRv3 + CQlekqlRNfNphRK6KVkqxNR0TMiFAJrTmKG0aRC5X5l7Mddj1wBs+zo5nytSLtAbO5nVvYZSXKj8HHWk + xMzWCwF54HVxZjFfdyB7iSm3/VCqXxPgxNyu6FqysOvkNJbJHE9NH4DD807J/ct9G62gVT+9kG3LzEva + LU2An0q2LR/8pvnzv1bXvQMMCPZ7n6JfIwAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6 + JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAABR0lEQVQ4T7VSsXHDMAxkl3RkF18asLM7 + sIsvDdjZSQOP4BE8gkfwCB5BI2gEjaARtIHyoGldnDiJXeTv/iTh8Q9IlDPouyZdaQvmUrgXspJtznkU + kUHfdFPLV6GqUdayq48nwLgFm7TMowVhk32VJhBzQE/WtQ64Hmv5BBSiiRZiASVEtQGD6SwSZK1F4yUf + GGHFeA0I2X0KOcqrJFnKoZiZD7ZJbf0ZCElgZ68E02CkBTc3mc+AKaeUxnwK6YnuMb9wxMTOAgotZM59 + lX8HphVzXKSRsbZ/pkREjQWhfnl8X4EpEc1djNHWbnEfvPeFuLevPxB6avslmMWajjQj+2g9mKrkziGo + dRZUy5eAsAmzONrqmLI3Q5Um2HSaUw/t+xb+ye9DCCOCWv9wpaGC8U8gYNpuAozJPTpbLzvv/jqy24/0 + n+HcB7S/b/AP6IsnAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6 + JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAABa0lEQVQ4T62SoXLDMBBE8wn9hHyCYaBg + oKChYIoqGCgYaBgoGCgYKFhWw0LBQsGw6+7ZSRQ3U9Dpzex4xvI+3e159S+VzlVUadapSozQscgwzDoU + CQHaj+IpP8psBwCmnAUfyq9VLyK2z+L6pJrtDeBQ509/Fs21VjE2S9c5gBpARMsEsMVndTWXryqdTRij + iLWxAWBeAjwOltWax08AtknnfwQgLAXgoK2lOY9F1iaK2y0ATJkAHlzrmTm/F3nZAOCy2O3QALCifBas + EhAHOj9A2hoYZmbbvPlm5lkLYHgpAQDFyHVWCdjItPeio3l0dzVbQB8B+DHS6W62vX+U8xgvNGbIhDuA + f1Z7M014LZ0xOv9Yqrh9mIxqjgsAWoxH/Adz2wTQ7PeDFJgZpA8D3tEYp+emBWA+vR3mNQPrDALNqpxH + pM+1WTWqEKbZaJdTvb1+WLdjQEn3exOCYlgqtMxbJ6HDFvD3Wq2+AdBROwy2G7LMAAAAAElFTkSuQmCC + + + \ No newline at end of file diff --git a/src/Kalman.Studio/ToolForm/WebSubmitter/ImportPostParams.Designer.cs b/src/Kalman.Studio/ToolForm/WebSubmitter/ImportPostParams.Designer.cs new file mode 100644 index 0000000..059c3b8 --- /dev/null +++ b/src/Kalman.Studio/ToolForm/WebSubmitter/ImportPostParams.Designer.cs @@ -0,0 +1,195 @@ +namespace Kalman.Studio +{ + partial class ImportPostParams + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.groupBox2 = new System.Windows.Forms.GroupBox(); + this.richTextBox1 = new System.Windows.Forms.RichTextBox(); + this.label1 = new System.Windows.Forms.Label(); + this.txtSeparator1 = new System.Windows.Forms.TextBox(); + this.label2 = new System.Windows.Forms.Label(); + this.txtSeparator2 = new System.Windows.Forms.TextBox(); + this.btnOK = new System.Windows.Forms.Button(); + this.cbTrim = new System.Windows.Forms.CheckBox(); + this.cbUrlDecode = new System.Windows.Forms.CheckBox(); + this.cbMutilRow = new System.Windows.Forms.CheckBox(); + this.groupBox1.SuspendLayout(); + this.groupBox2.SuspendLayout(); + this.SuspendLayout(); + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.cbMutilRow); + this.groupBox1.Controls.Add(this.cbUrlDecode); + this.groupBox1.Controls.Add(this.cbTrim); + this.groupBox1.Controls.Add(this.btnOK); + this.groupBox1.Controls.Add(this.txtSeparator2); + this.groupBox1.Controls.Add(this.label2); + this.groupBox1.Controls.Add(this.txtSeparator1); + this.groupBox1.Controls.Add(this.label1); + this.groupBox1.Dock = System.Windows.Forms.DockStyle.Bottom; + this.groupBox1.Location = new System.Drawing.Point(0, 296); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(592, 77); + this.groupBox1.TabIndex = 0; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "解析选项"; + // + // groupBox2 + // + this.groupBox2.Controls.Add(this.richTextBox1); + this.groupBox2.Dock = System.Windows.Forms.DockStyle.Fill; + this.groupBox2.Location = new System.Drawing.Point(0, 0); + this.groupBox2.Name = "groupBox2"; + this.groupBox2.Size = new System.Drawing.Size(592, 296); + this.groupBox2.TabIndex = 1; + this.groupBox2.TabStop = false; + this.groupBox2.Text = "原始字符串"; + // + // richTextBox1 + // + this.richTextBox1.Dock = System.Windows.Forms.DockStyle.Fill; + this.richTextBox1.Location = new System.Drawing.Point(3, 17); + this.richTextBox1.Name = "richTextBox1"; + this.richTextBox1.Size = new System.Drawing.Size(586, 276); + this.richTextBox1.TabIndex = 0; + this.richTextBox1.Text = ""; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(6, 20); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(65, 12); + this.label1.TabIndex = 0; + this.label1.Text = "参数分隔符"; + // + // txtSeparator1 + // + this.txtSeparator1.Location = new System.Drawing.Point(82, 16); + this.txtSeparator1.Name = "txtSeparator1"; + this.txtSeparator1.Size = new System.Drawing.Size(100, 21); + this.txtSeparator1.TabIndex = 1; + this.txtSeparator1.Text = "&"; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(193, 20); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(65, 12); + this.label2.TabIndex = 2; + this.label2.Text = "键值分隔符"; + // + // txtSeparator2 + // + this.txtSeparator2.Location = new System.Drawing.Point(269, 16); + this.txtSeparator2.Name = "txtSeparator2"; + this.txtSeparator2.Size = new System.Drawing.Size(100, 21); + this.txtSeparator2.TabIndex = 3; + this.txtSeparator2.Text = "="; + // + // btnOK + // + this.btnOK.Location = new System.Drawing.Point(505, 20); + this.btnOK.Name = "btnOK"; + this.btnOK.Size = new System.Drawing.Size(75, 45); + this.btnOK.TabIndex = 4; + this.btnOK.Text = "确定"; + this.btnOK.UseVisualStyleBackColor = true; + this.btnOK.Click += new System.EventHandler(this.btnOK_Click); + // + // cbTrim + // + this.cbTrim.AutoSize = true; + this.cbTrim.Checked = true; + this.cbTrim.CheckState = System.Windows.Forms.CheckState.Checked; + this.cbTrim.Location = new System.Drawing.Point(6, 48); + this.cbTrim.Name = "cbTrim"; + this.cbTrim.Size = new System.Drawing.Size(96, 16); + this.cbTrim.TabIndex = 5; + this.cbTrim.Text = "移除首尾空格"; + this.cbTrim.UseVisualStyleBackColor = true; + // + // cbUrlDecode + // + this.cbUrlDecode.AutoSize = true; + this.cbUrlDecode.Location = new System.Drawing.Point(115, 48); + this.cbUrlDecode.Name = "cbUrlDecode"; + this.cbUrlDecode.Size = new System.Drawing.Size(66, 16); + this.cbUrlDecode.TabIndex = 6; + this.cbUrlDecode.Text = "Url解码"; + this.cbUrlDecode.UseVisualStyleBackColor = true; + // + // cbMutilRow + // + this.cbMutilRow.AutoSize = true; + this.cbMutilRow.Location = new System.Drawing.Point(195, 48); + this.cbMutilRow.Name = "cbMutilRow"; + this.cbMutilRow.Size = new System.Drawing.Size(240, 16); + this.cbMutilRow.TabIndex = 7; + this.cbMutilRow.Text = "一行一个参数,相当于参数分隔符为回车"; + this.cbMutilRow.UseVisualStyleBackColor = true; + // + // ImportPostParams + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(592, 373); + this.Controls.Add(this.groupBox2); + this.Controls.Add(this.groupBox1); + this.MaximizeBox = false; + this.MaximumSize = new System.Drawing.Size(600, 400); + this.MinimumSize = new System.Drawing.Size(600, 400); + this.Name = "ImportPostParams"; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "导入Post参数"; + this.groupBox1.ResumeLayout(false); + this.groupBox1.PerformLayout(); + this.groupBox2.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.TextBox txtSeparator1; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.GroupBox groupBox2; + private System.Windows.Forms.RichTextBox richTextBox1; + private System.Windows.Forms.CheckBox cbTrim; + private System.Windows.Forms.Button btnOK; + private System.Windows.Forms.TextBox txtSeparator2; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.CheckBox cbUrlDecode; + private System.Windows.Forms.CheckBox cbMutilRow; + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/ToolForm/WebSubmitter/ImportPostParams.cs b/src/Kalman.Studio/ToolForm/WebSubmitter/ImportPostParams.cs new file mode 100644 index 0000000..5f5d053 --- /dev/null +++ b/src/Kalman.Studio/ToolForm/WebSubmitter/ImportPostParams.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using Kalman.Utilities; +using System.Web; + +namespace Kalman.Studio +{ + public partial class ImportPostParams : Form + { + public ImportPostParams() + { + InitializeComponent(); + } + + private void btnOK_Click(object sender, EventArgs e) + { + WebSubmitter owner = this.Owner as WebSubmitter; + + string s = richTextBox1.Text; + + if (s.IndexOf("?") != -1) + { + string[] arr = s.Split('?'); + owner.SetUrl(arr[0]); + s = arr[1]; + } + + string separator1 = txtSeparator1.Text; //参数分隔符号 + string separator2 = txtSeparator2.Text; //键值分隔符号 + bool isTrim = cbTrim.Checked; //是否移除参数及其值的首尾空格 + bool isUrlDecode = cbUrlDecode.Checked; //是否对原始字符串进行Url解码 + bool mutilRow = cbMutilRow.Checked; + + if (isUrlDecode) s = HttpUtility.UrlDecode(s); + + //如果分隔符有转义符的时候,需要处理一下 + separator1 = separator1.Replace("\\\\", "\\"); + separator2 = separator2.Replace("\\\\", "\\"); + + string[] paramItems = s.Split(new string[]{separator1}, StringSplitOptions.None); + if (mutilRow) paramItems = richTextBox1.Lines; + + foreach (string item in paramItems) + { + string[] ss = item.Split(separator2.ToCharArray()); + string name = ss[0]; + string value = ss.Length > 1 ? ss[1] : string.Empty; + + if (isTrim) + { + name = name.Trim(); + value = value.Trim(); + } + + owner.AddParam(name, value); + } + + owner.BindParams(); + this.Close(); + } + } +} diff --git a/src/Kalman.Studio/ToolForm/WebSubmitter/ImportPostParams.resx b/src/Kalman.Studio/ToolForm/WebSubmitter/ImportPostParams.resx new file mode 100644 index 0000000..19dc0dd --- /dev/null +++ b/src/Kalman.Studio/ToolForm/WebSubmitter/ImportPostParams.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/Kalman.Studio/ToolForm/WebSubmitter/WebSubmitter.Designer.cs b/src/Kalman.Studio/ToolForm/WebSubmitter/WebSubmitter.Designer.cs new file mode 100644 index 0000000..d8ac0c1 --- /dev/null +++ b/src/Kalman.Studio/ToolForm/WebSubmitter/WebSubmitter.Designer.cs @@ -0,0 +1,436 @@ +namespace Kalman.Studio +{ + partial class WebSubmitter + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.label1 = new System.Windows.Forms.Label(); + this.txtUrl = new System.Windows.Forms.TextBox(); + this.label2 = new System.Windows.Forms.Label(); + this.lbParams = new System.Windows.Forms.ListBox(); + this.txtPName = new System.Windows.Forms.TextBox(); + this.label3 = new System.Windows.Forms.Label(); + this.txtPValue = new System.Windows.Forms.TextBox(); + this.groupBox2 = new System.Windows.Forms.GroupBox(); + this.txtEncode = new System.Windows.Forms.TextBox(); + this.rbtnOther = new System.Windows.Forms.RadioButton(); + this.rbtnUnicode = new System.Windows.Forms.RadioButton(); + this.rbtnDefault = new System.Windows.Forms.RadioButton(); + this.rbtnGB2312 = new System.Windows.Forms.RadioButton(); + this.rbtnUTF8 = new System.Windows.Forms.RadioButton(); + this.label4 = new System.Windows.Forms.Label(); + this.btnImport = new System.Windows.Forms.Button(); + this.btnClear = new System.Windows.Forms.Button(); + this.btnSubmit = new System.Windows.Forms.Button(); + this.btnRemove = new System.Windows.Forms.Button(); + this.btnAdd = new System.Windows.Forms.Button(); + this.cbIsPost = new System.Windows.Forms.CheckBox(); + this.tabControl1 = new System.Windows.Forms.TabControl(); + this.tabPage1 = new System.Windows.Forms.TabPage(); + this.rtbResponse = new System.Windows.Forms.RichTextBox(); + this.tabPage3 = new System.Windows.Forms.TabPage(); + this.webBrowser1 = new System.Windows.Forms.WebBrowser(); + this.tabPage2 = new System.Windows.Forms.TabPage(); + this.lbHistory = new System.Windows.Forms.ListBox(); + this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components); + this.menuItemRemoveHistory = new System.Windows.Forms.ToolStripMenuItem(); + this.groupBox2.SuspendLayout(); + this.tabControl1.SuspendLayout(); + this.tabPage1.SuspendLayout(); + this.tabPage3.SuspendLayout(); + this.tabPage2.SuspendLayout(); + this.contextMenuStrip1.SuspendLayout(); + this.SuspendLayout(); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(8, 18); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(53, 12); + this.label1.TabIndex = 0; + this.label1.Text = "请求地址"; + // + // txtUrl + // + this.txtUrl.Location = new System.Drawing.Point(67, 14); + this.txtUrl.Multiline = true; + this.txtUrl.Name = "txtUrl"; + this.txtUrl.Size = new System.Drawing.Size(559, 61); + this.txtUrl.TabIndex = 1; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(8, 107); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(53, 12); + this.label2.TabIndex = 2; + this.label2.Text = "参数名称"; + // + // lbParams + // + this.lbParams.FormattingEnabled = true; + this.lbParams.ItemHeight = 12; + this.lbParams.Location = new System.Drawing.Point(361, 107); + this.lbParams.Name = "lbParams"; + this.lbParams.Size = new System.Drawing.Size(391, 184); + this.lbParams.TabIndex = 3; + this.lbParams.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.lbParams_MouseDoubleClick); + // + // txtPName + // + this.txtPName.Location = new System.Drawing.Point(68, 107); + this.txtPName.Name = "txtPName"; + this.txtPName.Size = new System.Drawing.Size(223, 21); + this.txtPName.TabIndex = 4; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(8, 134); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(41, 12); + this.label3.TabIndex = 5; + this.label3.Text = "参数值"; + // + // txtPValue + // + this.txtPValue.Location = new System.Drawing.Point(67, 134); + this.txtPValue.Multiline = true; + this.txtPValue.Name = "txtPValue"; + this.txtPValue.Size = new System.Drawing.Size(223, 159); + this.txtPValue.TabIndex = 6; + // + // groupBox2 + // + this.groupBox2.Controls.Add(this.txtEncode); + this.groupBox2.Controls.Add(this.rbtnOther); + this.groupBox2.Controls.Add(this.rbtnUnicode); + this.groupBox2.Controls.Add(this.rbtnDefault); + this.groupBox2.Controls.Add(this.rbtnGB2312); + this.groupBox2.Controls.Add(this.rbtnUTF8); + this.groupBox2.Controls.Add(this.label4); + this.groupBox2.Controls.Add(this.btnImport); + this.groupBox2.Controls.Add(this.btnClear); + this.groupBox2.Controls.Add(this.btnSubmit); + this.groupBox2.Controls.Add(this.btnRemove); + this.groupBox2.Controls.Add(this.btnAdd); + this.groupBox2.Controls.Add(this.cbIsPost); + this.groupBox2.Controls.Add(this.lbParams); + this.groupBox2.Controls.Add(this.label1); + this.groupBox2.Controls.Add(this.txtPValue); + this.groupBox2.Controls.Add(this.txtUrl); + this.groupBox2.Controls.Add(this.label3); + this.groupBox2.Controls.Add(this.label2); + this.groupBox2.Controls.Add(this.txtPName); + this.groupBox2.Dock = System.Windows.Forms.DockStyle.Top; + this.groupBox2.Location = new System.Drawing.Point(5, 5); + this.groupBox2.Name = "groupBox2"; + this.groupBox2.Size = new System.Drawing.Size(760, 300); + this.groupBox2.TabIndex = 9; + this.groupBox2.TabStop = false; + this.groupBox2.Text = "请求设置"; + // + // txtEncode + // + this.txtEncode.Location = new System.Drawing.Point(527, 81); + this.txtEncode.Name = "txtEncode"; + this.txtEncode.Size = new System.Drawing.Size(101, 21); + this.txtEncode.TabIndex = 20; + // + // rbtnOther + // + this.rbtnOther.AutoSize = true; + this.rbtnOther.Location = new System.Drawing.Point(438, 83); + this.rbtnOther.Name = "rbtnOther"; + this.rbtnOther.Size = new System.Drawing.Size(83, 16); + this.rbtnOther.TabIndex = 19; + this.rbtnOther.Text = "其他编码:"; + this.rbtnOther.UseVisualStyleBackColor = true; + // + // rbtnUnicode + // + this.rbtnUnicode.AutoSize = true; + this.rbtnUnicode.Location = new System.Drawing.Point(254, 83); + this.rbtnUnicode.Name = "rbtnUnicode"; + this.rbtnUnicode.Size = new System.Drawing.Size(65, 16); + this.rbtnUnicode.TabIndex = 18; + this.rbtnUnicode.Text = "Unicode"; + this.rbtnUnicode.UseVisualStyleBackColor = true; + // + // rbtnDefault + // + this.rbtnDefault.AutoSize = true; + this.rbtnDefault.Checked = true; + this.rbtnDefault.Location = new System.Drawing.Point(70, 83); + this.rbtnDefault.Name = "rbtnDefault"; + this.rbtnDefault.Size = new System.Drawing.Size(71, 16); + this.rbtnDefault.TabIndex = 17; + this.rbtnDefault.TabStop = true; + this.rbtnDefault.Text = "系统默认"; + this.rbtnDefault.UseVisualStyleBackColor = true; + // + // rbtnGB2312 + // + this.rbtnGB2312.AutoSize = true; + this.rbtnGB2312.Location = new System.Drawing.Point(349, 83); + this.rbtnGB2312.Name = "rbtnGB2312"; + this.rbtnGB2312.Size = new System.Drawing.Size(59, 16); + this.rbtnGB2312.TabIndex = 16; + this.rbtnGB2312.Text = "GB2312"; + this.rbtnGB2312.UseVisualStyleBackColor = true; + // + // rbtnUTF8 + // + this.rbtnUTF8.AutoSize = true; + this.rbtnUTF8.Location = new System.Drawing.Point(171, 83); + this.rbtnUTF8.Name = "rbtnUTF8"; + this.rbtnUTF8.Size = new System.Drawing.Size(53, 16); + this.rbtnUTF8.TabIndex = 15; + this.rbtnUTF8.Text = "UTF-8"; + this.rbtnUTF8.UseVisualStyleBackColor = true; + // + // label4 + // + this.label4.AutoSize = true; + this.label4.Location = new System.Drawing.Point(8, 85); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(53, 12); + this.label4.TabIndex = 14; + this.label4.Text = "请求编码"; + // + // btnImport + // + this.btnImport.Location = new System.Drawing.Point(301, 106); + this.btnImport.Name = "btnImport"; + this.btnImport.Size = new System.Drawing.Size(50, 23); + this.btnImport.TabIndex = 13; + this.btnImport.Text = "导入"; + this.btnImport.UseVisualStyleBackColor = true; + this.btnImport.Click += new System.EventHandler(this.btnImport_Click); + // + // btnClear + // + this.btnClear.Location = new System.Drawing.Point(301, 250); + this.btnClear.Name = "btnClear"; + this.btnClear.Size = new System.Drawing.Size(50, 23); + this.btnClear.TabIndex = 12; + this.btnClear.Text = "重置"; + this.btnClear.UseVisualStyleBackColor = true; + this.btnClear.Click += new System.EventHandler(this.btnClear_Click); + // + // btnSubmit + // + this.btnSubmit.Location = new System.Drawing.Point(633, 38); + this.btnSubmit.Name = "btnSubmit"; + this.btnSubmit.Size = new System.Drawing.Size(120, 63); + this.btnSubmit.TabIndex = 11; + this.btnSubmit.Text = "提交请求"; + this.btnSubmit.UseVisualStyleBackColor = true; + this.btnSubmit.Click += new System.EventHandler(this.btnSubmit_Click); + // + // btnRemove + // + this.btnRemove.Location = new System.Drawing.Point(301, 200); + this.btnRemove.Name = "btnRemove"; + this.btnRemove.Size = new System.Drawing.Size(50, 23); + this.btnRemove.TabIndex = 10; + this.btnRemove.Text = "删除"; + this.btnRemove.UseVisualStyleBackColor = true; + this.btnRemove.Click += new System.EventHandler(this.btnRemove_Click); + // + // btnAdd + // + this.btnAdd.Location = new System.Drawing.Point(301, 150); + this.btnAdd.Name = "btnAdd"; + this.btnAdd.Size = new System.Drawing.Size(50, 23); + this.btnAdd.TabIndex = 9; + this.btnAdd.Text = "添加"; + this.btnAdd.UseVisualStyleBackColor = true; + this.btnAdd.Click += new System.EventHandler(this.btnAdd_Click); + // + // cbIsPost + // + this.cbIsPost.AutoSize = true; + this.cbIsPost.Location = new System.Drawing.Point(632, 16); + this.cbIsPost.Name = "cbIsPost"; + this.cbIsPost.Size = new System.Drawing.Size(120, 16); + this.cbIsPost.TabIndex = 8; + this.cbIsPost.Text = "是否POST方式提交"; + this.cbIsPost.UseVisualStyleBackColor = true; + // + // tabControl1 + // + this.tabControl1.Controls.Add(this.tabPage1); + this.tabControl1.Controls.Add(this.tabPage3); + this.tabControl1.Controls.Add(this.tabPage2); + this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill; + this.tabControl1.Location = new System.Drawing.Point(5, 305); + this.tabControl1.Name = "tabControl1"; + this.tabControl1.SelectedIndex = 0; + this.tabControl1.Size = new System.Drawing.Size(760, 268); + this.tabControl1.TabIndex = 10; + // + // tabPage1 + // + this.tabPage1.Controls.Add(this.rtbResponse); + this.tabPage1.Location = new System.Drawing.Point(4, 21); + this.tabPage1.Name = "tabPage1"; + this.tabPage1.Padding = new System.Windows.Forms.Padding(3); + this.tabPage1.Size = new System.Drawing.Size(752, 243); + this.tabPage1.TabIndex = 0; + this.tabPage1.Text = "响应输出"; + this.tabPage1.UseVisualStyleBackColor = true; + // + // rtbResponse + // + this.rtbResponse.Dock = System.Windows.Forms.DockStyle.Fill; + this.rtbResponse.Location = new System.Drawing.Point(3, 3); + this.rtbResponse.Name = "rtbResponse"; + this.rtbResponse.Size = new System.Drawing.Size(746, 237); + this.rtbResponse.TabIndex = 1; + this.rtbResponse.Text = ""; + // + // tabPage3 + // + this.tabPage3.Controls.Add(this.webBrowser1); + this.tabPage3.Location = new System.Drawing.Point(4, 21); + this.tabPage3.Name = "tabPage3"; + this.tabPage3.Padding = new System.Windows.Forms.Padding(3); + this.tabPage3.Size = new System.Drawing.Size(752, 243); + this.tabPage3.TabIndex = 2; + this.tabPage3.Text = "HTML预览"; + this.tabPage3.UseVisualStyleBackColor = true; + // + // webBrowser1 + // + this.webBrowser1.Dock = System.Windows.Forms.DockStyle.Fill; + this.webBrowser1.Location = new System.Drawing.Point(3, 3); + this.webBrowser1.MinimumSize = new System.Drawing.Size(20, 20); + this.webBrowser1.Name = "webBrowser1"; + this.webBrowser1.Size = new System.Drawing.Size(746, 237); + this.webBrowser1.TabIndex = 0; + // + // tabPage2 + // + this.tabPage2.Controls.Add(this.lbHistory); + this.tabPage2.Location = new System.Drawing.Point(4, 21); + this.tabPage2.Name = "tabPage2"; + this.tabPage2.Padding = new System.Windows.Forms.Padding(3); + this.tabPage2.Size = new System.Drawing.Size(752, 243); + this.tabPage2.TabIndex = 1; + this.tabPage2.Text = "历史记录"; + this.tabPage2.UseVisualStyleBackColor = true; + // + // lbHistory + // + this.lbHistory.ContextMenuStrip = this.contextMenuStrip1; + this.lbHistory.Dock = System.Windows.Forms.DockStyle.Fill; + this.lbHistory.FormattingEnabled = true; + this.lbHistory.ItemHeight = 12; + this.lbHistory.Location = new System.Drawing.Point(3, 3); + this.lbHistory.Name = "lbHistory"; + this.lbHistory.ScrollAlwaysVisible = true; + this.lbHistory.Size = new System.Drawing.Size(746, 232); + this.lbHistory.TabIndex = 4; + this.lbHistory.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.lbHistory_MouseDoubleClick); + this.lbHistory.MouseDown += new System.Windows.Forms.MouseEventHandler(this.lbHistory_MouseDown); + // + // contextMenuStrip1 + // + this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.menuItemRemoveHistory}); + this.contextMenuStrip1.Name = "contextMenuStrip1"; + this.contextMenuStrip1.Size = new System.Drawing.Size(135, 26); + // + // menuItemRemoveHistory + // + this.menuItemRemoveHistory.Name = "menuItemRemoveHistory"; + this.menuItemRemoveHistory.Size = new System.Drawing.Size(134, 22); + this.menuItemRemoveHistory.Text = "移除该记录"; + this.menuItemRemoveHistory.Click += new System.EventHandler(this.menuItemRemoveHistory_Click); + // + // WebSubmitter + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(770, 578); + this.Controls.Add(this.tabControl1); + this.Controls.Add(this.groupBox2); + this.Name = "WebSubmitter"; + this.Padding = new System.Windows.Forms.Padding(5); + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Web客户端模拟器"; + this.Load += new System.EventHandler(this.WebSubmitter_Load); + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.WebSubmitter_FormClosing); + this.groupBox2.ResumeLayout(false); + this.groupBox2.PerformLayout(); + this.tabControl1.ResumeLayout(false); + this.tabPage1.ResumeLayout(false); + this.tabPage3.ResumeLayout(false); + this.tabPage2.ResumeLayout(false); + this.contextMenuStrip1.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Label label1; + private System.Windows.Forms.TextBox txtUrl; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.ListBox lbParams; + private System.Windows.Forms.TextBox txtPName; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.TextBox txtPValue; + private System.Windows.Forms.GroupBox groupBox2; + private System.Windows.Forms.CheckBox cbIsPost; + private System.Windows.Forms.Button btnAdd; + private System.Windows.Forms.Button btnRemove; + private System.Windows.Forms.Button btnSubmit; + private System.Windows.Forms.Button btnClear; + private System.Windows.Forms.TabControl tabControl1; + private System.Windows.Forms.TabPage tabPage1; + private System.Windows.Forms.TabPage tabPage2; + private System.Windows.Forms.RichTextBox rtbResponse; + private System.Windows.Forms.ListBox lbHistory; + private System.Windows.Forms.TabPage tabPage3; + private System.Windows.Forms.WebBrowser webBrowser1; + private System.Windows.Forms.ContextMenuStrip contextMenuStrip1; + private System.Windows.Forms.ToolStripMenuItem menuItemRemoveHistory; + private System.Windows.Forms.Button btnImport; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.RadioButton rbtnGB2312; + private System.Windows.Forms.RadioButton rbtnUTF8; + private System.Windows.Forms.RadioButton rbtnDefault; + private System.Windows.Forms.RadioButton rbtnUnicode; + private System.Windows.Forms.TextBox txtEncode; + private System.Windows.Forms.RadioButton rbtnOther; + } +} \ No newline at end of file diff --git a/src/Kalman.Studio/ToolForm/WebSubmitter/WebSubmitter.cs b/src/Kalman.Studio/ToolForm/WebSubmitter/WebSubmitter.cs new file mode 100644 index 0000000..241f0cb --- /dev/null +++ b/src/Kalman.Studio/ToolForm/WebSubmitter/WebSubmitter.cs @@ -0,0 +1,316 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using WeifenLuo.WinFormsUI.Docking; +using System.Web; +using System.Net; +using System.IO; +using Newtonsoft.Json; +using Kalman.Net; + +namespace Kalman.Studio +{ + public partial class WebSubmitter : DockableForm + { + static Dictionary dicParams = new Dictionary(); //用于保存请求参数 + static Dictionary dic = new Dictionary(); + + public WebSubmitter() + { + InitializeComponent(); + } + + private void btnAdd_Click(object sender, EventArgs e) + { + string paramName = txtPName.Text.Trim(); + string paramValue = txtPValue.Text.Trim(); + + AddParam(paramName, paramValue); + BindParams(); + } + + public void SetUrl(string url) + { + txtUrl.Text = url; + } + + public void AddParam(string paramName, string paramValue) + { + if (paramName == string.Empty) return; + + if (dicParams.ContainsKey(paramName)) dicParams[paramName] = paramValue; + else dicParams.Add(paramName, paramValue); + } + + public void BindParams() + { + lbParams.Items.Clear(); + + foreach (KeyValuePair kvp in dicParams) + { + lbParams.Items.Add(string.Format("{0}|{1}", kvp.Key, kvp.Value)); + } + + txtPName.Text = string.Empty; + txtPValue.Text = string.Empty; + } + + private void btnRemove_Click(object sender, EventArgs e) + { + RemoveParam(); + } + + private void RemoveParam() + { + object obj = lbParams.SelectedItem; + if (obj == null) return; + + string paramName = obj.ToString().Split('|')[0]; + + dicParams.Remove(paramName); + BindParams(); + } + + private void btnSubmit_Click(object sender, EventArgs e) + { + if (txtUrl.Text.Trim() == string.Empty) + { + MessageBox.Show("请求地址不能为空"); + return; + } + + DialogResult result = MessageBox.Show("是否提交当前请求", "确认提交请求", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); + if (result != DialogResult.Yes) return; + + DoSubmit(); + } + + void DoSubmit() + { + RequestInfo ri = new RequestInfo(); + ri.Url = txtUrl.Text.Trim(); + ri.IsPost = cbIsPost.Checked; + ri.Params = new Dictionary(); + ri.RequestTime = DateTime.Now; + + foreach (KeyValuePair kvp in dicParams) + { + ri.Params.Add(kvp.Key, kvp.Value); + } + + rtbResponse.Text = string.Format("正在向{0}提交请求...",ri.FullUrl); + + HttpClient hc; + string responseText = string.Empty; + + if (ri.IsPost) + { + //ServicePointManager.Expect100Continue = false; + hc = new HttpClient(ri.Url); + hc.Verb = HttpVerb.POST; + hc.RequestEncoding = GetRequestEncoding(); + + foreach (KeyValuePair kvp in ri.Params) + { + hc.PostingData.Add(kvp.Key, kvp.Value); + } + + responseText = hc.GetString(); + } + else + { + hc = new HttpClient(ri.FullUrl); + hc.RequestEncoding = GetRequestEncoding(); + responseText = hc.GetString(); + } + + rtbResponse.Text = responseText; + lbHistory.Items.Add(ri.ToString()); + dic.Add(ri.ToString(), ri); + webBrowser1.DocumentText = responseText; + this.Clear(); + } + + void Clear() + { + txtUrl.Text = string.Empty; + txtPName.Text = string.Empty; + txtPValue.Text = string.Empty; + cbIsPost.Checked = false; + dicParams.Clear(); + lbParams.Items.Clear(); + } + + Encoding GetRequestEncoding() + { + if (rbtnDefault.Checked) return Encoding.Default; + if (rbtnGB2312.Checked) return Encoding.GetEncoding("gb2312"); + if (rbtnUTF8.Checked) return Encoding.UTF8; + if (rbtnUnicode.Checked) return Encoding.Unicode; + if (rbtnOther.Checked && txtEncode.Text.Trim().Length > 0) return Encoding.GetEncoding(txtEncode.Text); + + return Encoding.UTF8; + } + + private void lbParams_MouseDoubleClick(object sender, MouseEventArgs e) + { + //DialogResult result = MessageBox.Show("是否删除所选参数", "确认参数删除", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); + //if (result == DialogResult.Yes) + //RemoveParam(); + + object obj = lbParams.SelectedItem; + if (obj == null) return; + + txtPName.Text = obj.ToString().Split('|')[0]; + txtPValue.Text = obj.ToString().Split('|')[1]; + } + + private void lbHistory_MouseDoubleClick(object sender, MouseEventArgs e) + { + RequestInfo ri = dic[lbHistory.SelectedItem.ToString()]; + if (ri == null) return; + + this.txtUrl.Text = ri.Url; + cbIsPost.Checked = ri.IsPost; + //dicParams = ri.Params; + + dicParams.Clear(); + foreach (KeyValuePair kvp in ri.Params) + { + dicParams.Add(kvp.Key, kvp.Value); + } + BindParams(); + } + + private void btnClear_Click(object sender, EventArgs e) + { + this.Clear(); + } + + #region RequestInfo + /// + /// 请求信息 + /// + class RequestInfo + { + /// + /// 请求地址 + /// + public string Url { get; set; } + + /// + /// 是否已Post方式提交 + /// + public bool IsPost { get; set; } + + public DateTime RequestTime { get; set; } + + /// + /// 参数集合 + /// + public Dictionary Params { get; set; } + + public string QueryString + { + get + { + if (this.Params == null || this.Params.Count == 0) return string.Empty; + else + { + StringBuilder sb = new StringBuilder(); + foreach (KeyValuePair kvp in this.Params) + { + sb.Append(string.Format("{0}={1}&", kvp.Key, HttpUtility.UrlEncode(kvp.Value))); + } + + return sb.ToString().Trim('&'); + } + } + } + + public string FullUrl + { + get + { + if (this.IsPost == true || this.Params == null || this.Params.Count == 0) return this.Url; + else + { + if (this.Url.IndexOf("?") == -1) + { + return string.Format("{0}?{1}", this.Url, this.QueryString); + } + else + { + return string.Format("{0}&{1}", this.Url, this.QueryString); + } + } + } + } + + public override string ToString() + { + if (IsPost == false) + { + return string.Format("{0}->{1}", this.RequestTime.ToString("yyyy-MM-dd HH:mm:ss:fff"), this.FullUrl); + } + else + + return string.Format("{0}->{1}[PostData:{2}]", this.RequestTime.ToString("yyyy-MM-dd HH:mm:ss:fff"), this.Url,this.QueryString); + } + } + #endregion + + string path = Path.Combine(Application.StartupPath, "config\\RequestHistory.json"); + private void WebSubmitter_Load(object sender, EventArgs e) + { + if (File.Exists(path)) + { + dic = JsonConvert.DeserializeObject>(File.ReadAllText(path)); + + foreach (KeyValuePair kvp in dic) + { + lbHistory.Items.Add(kvp.Key); + } + } + } + + private void WebSubmitter_FormClosing(object sender, FormClosingEventArgs e) + { + string s = JsonConvert.SerializeObject(dic); + File.WriteAllText(path, s, Encoding.UTF8); + } + + private void lbHistory_MouseDown(object sender, MouseEventArgs e) + { + if (e.Button == MouseButtons.Right) + { + //lbHistory.se + } + } + + private void menuItemRemoveHistory_Click(object sender, EventArgs e) + { + if (lbHistory.SelectedItem != null) + { + string s = lbHistory.SelectedItem.ToString(); + dic.Remove(s); + + lbHistory.Items.Remove(s); + } + } + + private void btnImport_Click(object sender, EventArgs e) + { + ImportPostParams import = new ImportPostParams(); + import.ShowDialog(this); + } + + + + } +} diff --git a/src/Kalman.Studio/ToolForm/WebSubmitter/WebSubmitter.resx b/src/Kalman.Studio/ToolForm/WebSubmitter/WebSubmitter.resx new file mode 100644 index 0000000..6fab886 --- /dev/null +++ b/src/Kalman.Studio/ToolForm/WebSubmitter/WebSubmitter.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + \ No newline at end of file diff --git a/src/Kalman.Studio/config/iislog/UserAgentAlias.config b/src/Kalman.Studio/config/iislog/UserAgentAlias.config new file mode 100644 index 0000000..b83fdd4 --- /dev/null +++ b/src/Kalman.Studio/config/iislog/UserAgentAlias.config @@ -0,0 +1,27 @@ +Mozilla/4.0 Mozilla4.0 + +#IE浏览器 +compatible;+MSIE IE浏览器 +compatible;+MSIE+5.0 IE浏览器5.0 +compatible;+MSIE+5.5 IE浏览器5.5 +compatible;+MSIE+6.0 IE浏览器6.0 +compatible;+MSIE+7.0 IE浏览器7.0 +compatible;+MSIE+8.0 IE浏览器8.0 + +MAXTHON+2.0 遨游浏览器2.0[IE6] +TheWorld 世界之窗浏览器 +360SE 360浏览器 +TencentTraveler 腾讯浏览器 + +Firefox/3.0 Firefox浏览器3.0 +Firefox/3.5 Firefox浏览器3.5 + +Chrome/4.0 谷歌浏览器4.0 + +#搜索引擎机器人 +Googlebot Google机器人 +Baiduspider 百度蜘蛛 +Sosospider 搜搜蜘蛛 +msnbot MSN机器人 +VoilaBot Voila机器人 +Yahoo!+Slurp+China 雅虎蜘蛛 diff --git a/src/Kalman.Studio/data/QQWry.dat b/src/Kalman.Studio/data/QQWry.dat new file mode 100644 index 0000000..f382405 Binary files /dev/null and b/src/Kalman.Studio/data/QQWry.dat differ diff --git a/src/Kalman.Studio/packages.config b/src/Kalman.Studio/packages.config new file mode 100644 index 0000000..8f7f8f4 --- /dev/null +++ b/src/Kalman.Studio/packages.config @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Kalman/App.config b/src/Kalman/App.config new file mode 100644 index 0000000..a6a2b7f --- /dev/null +++ b/src/Kalman/App.config @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/src/Kalman/BindableEntity.cs b/src/Kalman/BindableEntity.cs new file mode 100644 index 0000000..bf6ca03 --- /dev/null +++ b/src/Kalman/BindableEntity.cs @@ -0,0 +1,163 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Reflection; +using System.Data; +using System.Collections.Specialized; +using System.Collections; +using Kalman.Resources; +using Kalman.Data; + +namespace Kalman +{ + /// + /// 获取实体类成员属性值的方法委托 + /// + /// 成员属性名称 + /// 返回成员属性对应的值 + public delegate object GetHandler(string propertyName); + + /// + /// 可绑定数据的实体 + /// + [Serializable] + public abstract class BindableEntity + { + /// + /// 获取指定成员属性的值 + /// + /// 成员属性名称 + /// 返回成员属性对应的值 + public object GetValue(string propertyName) + { + PropertyInfo p = this.GetType().GetProperty(propertyName, + BindingFlags.Public | + BindingFlags.Instance | + BindingFlags.IgnoreCase); + + if (p != null) + return p.GetValue(this, null); + else + return null; + } + + /// + /// 设置指定成员属性的值 + /// + /// 成员属性名称 + /// 成员属性值 + public void SetValue(string propertyName, object value) + { + PropertyInfo p = this.GetType().GetProperty(propertyName, + BindingFlags.Public | + BindingFlags.Instance | + BindingFlags.IgnoreCase); + + if (p != null) p.SetValue(this, value, null); + } + + /// + /// 类型转换 + /// + /// 目标类型 + /// 待转换对象 + protected T Cast(object obj) + { + if (obj != null && obj != DBNull.Value) + { + try + { + if (Type.Equals(typeof(T), obj.GetType())) + return (T)obj; + else + return (T)Convert.ChangeType(obj, typeof(T)); + } + catch + { + //string msg = string.Format("[{0},类型<{1}>]转换为类型<{2}>失败", obj, obj.GetType().Name, typeof(T).Name); + string msg = string.Format(Common.TypeConvertFailed, obj.GetType().Name, typeof(T).Name); + throw new InvalidCastException(msg); + } + } + else + return default(T); + } + + /// + /// 需要在派生类中定义具体的绑定方法 + /// + /// + public abstract void Bind(GetHandler get); + + /// + /// 将DataReader对象绑定到实体类 + /// + /// + /// 绑定操作完成后是否关闭DataReader对象 + /// + public virtual bool Bind(IDataReader dataReader, bool isClose) + { + DataReaderWrapper wrapper = DataReaderWrapper.New(dataReader); + if (isClose) + { + using (wrapper) + { + if (wrapper.Read()) + { + Bind(delegate(string name) + { + return wrapper[name]; + }); + return true; + } + else + return false; + } + } + else + { + Bind(delegate(string name) + { + return wrapper[name]; + }); + return true; + } + } + + public virtual void Bind(IDataReader dataReader) + { + DataReaderWrapper wrapper = DataReaderWrapper.New(dataReader); + Bind(delegate(string name) + { + return wrapper[name]; + }); + } + + /// + /// 将DataRow对象绑定到实体类 + /// + /// + public virtual void Bind(DataRow dataRow) + { + Bind(delegate(string name) + { + int colIndex = dataRow.Table.Columns.IndexOf(name); + + if (colIndex >= 0) + return dataRow[colIndex]; + else + return null; + }); + } + + public virtual void Bind(BindableEntity entity) + { + Bind(delegate(string name) { return entity.GetValue(name); }); + } + + public virtual void Bind(NameValueCollection nvc) + { + Bind(delegate(string name) { return nvc[name]; }); + } + } +} diff --git a/src/Kalman/Caching/Cache.cs b/src/Kalman/Caching/Cache.cs new file mode 100644 index 0000000..7b752b4 --- /dev/null +++ b/src/Kalman/Caching/Cache.cs @@ -0,0 +1,153 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Threading; +using System.IO; +using System.Security.Permissions; + +namespace Kalman.Caching +{ + public class Cache + { + private Hashtable inMemoryCache = Hashtable.Synchronized(new Hashtable()); + + public int Count + { + get { return inMemoryCache.Count; } + } + + public void Add(string key, object value) + { + Add(key, value, null); + } + + public void Add(string key, object value, params ICacheItemExpiration[] expirations) + { + if (string.IsNullOrEmpty(key)) + { + throw new ArgumentException("[key]Ϊջַ"); + } + + CacheItem cacheItemBeforeLock = null; + + lock (inMemoryCache.SyncRoot) + { + if (!inMemoryCache.Contains(key)) + { + cacheItemBeforeLock = new CacheItem(key, value, expirations); + inMemoryCache[key] = cacheItemBeforeLock; + } + else + { + cacheItemBeforeLock = (CacheItem)inMemoryCache[key]; + try + { + cacheItemBeforeLock.Replace(value, expirations); + inMemoryCache[key] = cacheItemBeforeLock; + } + catch + { + inMemoryCache.Remove(key); + throw; + } + } + } + } + + public void Remove(string key) + { + if (string.IsNullOrEmpty(key)) + { + throw new ArgumentException("[key]Ϊջַ"); + } + + lock (inMemoryCache.SyncRoot) + { + if (inMemoryCache.ContainsKey(key)) + { + inMemoryCache.Remove(key); + } + } + } + + public void RemoveByKeyPrefix(string keyPrefix) + { + List toRemoveKeys = new List(); + foreach (string key in inMemoryCache.Keys) + { + if (key.StartsWith(keyPrefix)) + { + toRemoveKeys.Add(key); + } + } + + lock (inMemoryCache) + { + foreach (string key in toRemoveKeys) + { + inMemoryCache.Remove(key); + } + } + } + + public object Get(string key) + { + if (string.IsNullOrEmpty(key)) + { + throw new ArgumentException("[key]Ϊջַ"); + } + + CacheItem cacheItem = (CacheItem)inMemoryCache[key]; + + if (cacheItem == null) + { + return null; + } + + lock (inMemoryCache.SyncRoot) + { + if (cacheItem.HasExpired()) + { + cacheItem.TouchedByUserAction(true); + + inMemoryCache.Remove(key); + + return null; + } + } + + cacheItem.TouchedByUserAction(false); + return cacheItem.Value; + } + + public void Clear() + { + RestartFlushAlgorithm: + lock (inMemoryCache.SyncRoot) + { + foreach (string key in inMemoryCache.Keys) + { + bool lockWasSuccessful = false; + CacheItem itemToRemove = (CacheItem)inMemoryCache[key]; + try + { + if (lockWasSuccessful = Monitor.TryEnter(itemToRemove)) + { + itemToRemove.TouchedByUserAction(true); + } + else + { + goto RestartFlushAlgorithm; + } + } + finally + { + if (lockWasSuccessful) Monitor.Exit(itemToRemove); + } + } + + inMemoryCache.Clear(); + } + } + } +} \ No newline at end of file diff --git a/src/Kalman/Caching/CacheItem.cs b/src/Kalman/Caching/CacheItem.cs new file mode 100644 index 0000000..5133769 --- /dev/null +++ b/src/Kalman/Caching/CacheItem.cs @@ -0,0 +1,144 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Kalman.Caching +{ + /// + /// This class contains all data important to define an item stored in the cache. It holds both the DEFAULT_KEY and + /// value specified by the user, as well as housekeeping information used internally by this block. It is public, + /// rather than internal, to allow block extenders access to it inside their own implementations of IBackingStore. + /// + public class CacheItem + { + // User-provided data + private string key; + private object data; + + private ICacheItemExpiration[] expirations; + private bool willBeExpired; + + /// + /// Initializes a new instance of the class. + /// + /// The key. + /// The value. + /// The expirations. + public CacheItem(string key, object value, params ICacheItemExpiration[] expirations) + { + Initialize(key, value, expirations); + + TouchedByUserAction(false); + } + + /// + /// Replaces the internals of the current cache item with the given new values. This is strictly used in the Cache + /// class when adding a new item into the cache. By replacing the item's contents, rather than replacing the item + /// itself, it allows us to keep a single reference in the cache, simplifying locking. + /// + /// Value to be stored. May be null. + /// Param array of ICacheItemExpiration objects. May provide 0 or more of these. + internal void Replace(object cacheItemData, params ICacheItemExpiration[] cacheItemExpirations) + { + Initialize(this.key, cacheItemData, cacheItemExpirations); + TouchedByUserAction(false); + } + + /// + /// Intended to be used internally only. The value should be true when an item is eligible to be expired. + /// + public bool WillBeExpired + { + get { return willBeExpired; } + set { willBeExpired = value; } + } + + /// + /// Returns the cached value of this CacheItem + /// + public object Value + { + get { return data; } + } + + /// + /// Returns the DEFAULT_KEY associated with this CacheItem + /// + public string Key + { + get { return key; } + } + + /// + /// Returns array of objects for this instance. + /// + /// + /// An array of objects. + /// + public ICacheItemExpiration[] GetExpirations() + { + return (ICacheItemExpiration[])expirations.Clone(); + } + + /// + /// Evaluates all cacheItemExpirations associated with this cache item to determine if it + /// should be considered expired. Evaluation stops as soon as any expiration returns true. + /// + /// True if item should be considered expired, according to policies + /// defined in this item's cacheItemExpirations. + public bool HasExpired() + { + foreach (ICacheItemExpiration expiration in expirations) + { + if (expiration.HasExpired()) + { + return true; + } + } + + return false; + } + + /// + /// Intended to be used internally only. This method is called whenever a CacheItem is touched through the action of a user. It + /// prevents this CacheItem from being expired or scavenged during an in-progress expiration or scavenging process. It has no effect + /// on subsequent expiration or scavenging processes. + /// + public void TouchedByUserAction(bool objectRemovedFromCache) + { + TouchedByUserAction(objectRemovedFromCache, DateTime.Now); + } + + /// + /// Intended to be used internally only. This method is called whenever a CacheItem is touched through the action of a user. It + /// prevents this CacheItem from being expired or scavenged during an in-progress expiration or scavenging process. It has no effect + /// on subsequent expiration or scavenging processes. + /// + internal void TouchedByUserAction(bool objectRemovedFromCache, DateTime timestamp) + { + willBeExpired = objectRemovedFromCache ? false : HasExpired(); + } + + private void InitializeExpirations() + { + foreach (ICacheItemExpiration expiration in expirations) + { + expiration.Initialize(this); + } + } + + private void Initialize(string cacheItemKey, object cacheItemData, ICacheItemExpiration[] cacheItemExpirations) + { + key = cacheItemKey; + data = cacheItemData; + if (cacheItemExpirations == null) + { + expirations = new ICacheItemExpiration[1] { new NeverExpired() }; + } + else + { + expirations = cacheItemExpirations; + } + } + } +} diff --git a/src/Kalman/Caching/CacheItemExpiration/AbsoluteTime.cs b/src/Kalman/Caching/CacheItemExpiration/AbsoluteTime.cs new file mode 100644 index 0000000..9143af1 --- /dev/null +++ b/src/Kalman/Caching/CacheItemExpiration/AbsoluteTime.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Kalman.Caching +{ + /// + /// 使用绝对时间[UTC]来判断一个缓存项是否过期 + /// + [Serializable] + public class AbsoluteTime : ICacheItemExpiration + { + private DateTime absoluteExpirationTime; + + /// + /// 创建一个实例并将输入的时间转换为UTC时间,转换后的时间值将用来判断该缓存项是否过期 + /// + public AbsoluteTime(DateTime absoluteTime) + { + if (absoluteTime > DateTime.Now) + { + this.absoluteExpirationTime = absoluteTime.ToUniversalTime(); + } + else + { + throw new ArgumentOutOfRangeException("时间超出范围,应该指定一个将来的时间"); + } + } + + /// + /// 获取过期时间 + /// + public DateTime AbsoluteExpirationTime + { + get { return absoluteExpirationTime; } + } + + /// + /// 创建一个实例并指定从现在开始的时间间隔,在这个时间间隔后缓存项将过期 + /// + public AbsoluteTime(TimeSpan timeFromNow) + : this(DateTime.Now + timeFromNow) + { + } + + public bool HasExpired() + { + DateTime nowDateTime = DateTime.Now.ToUniversalTime(); + return nowDateTime.Ticks >= this.absoluteExpirationTime.Ticks; + } + + public void Initialize(CacheItem owningCacheItem) + { + } + } +} diff --git a/src/Kalman/Caching/CacheItemExpiration/FileDependency.cs b/src/Kalman/Caching/CacheItemExpiration/FileDependency.cs new file mode 100644 index 0000000..9b7fb58 --- /dev/null +++ b/src/Kalman/Caching/CacheItemExpiration/FileDependency.cs @@ -0,0 +1,91 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; +using System.Security.Permissions; + +namespace Kalman.Caching +{ + /// + /// 基于文件依赖的缓存项过期对象 + /// + [Serializable] + [System.Runtime.InteropServices.ComVisible(false)] + public class FileDependency : ICacheItemExpiration + { + private readonly string dependencyFileName; + + private DateTime lastModifiedTime; + + public FileDependency(string fullFileName) + { + if (string.IsNullOrEmpty(fullFileName)) + { + throw new ArgumentException("文件名不能为空"); + } + + dependencyFileName = Path.GetFullPath(fullFileName); + EnsureTargetFileAccessible(); + + if (!File.Exists(dependencyFileName)) + { + throw new ArgumentException("指定的文件不存在"); + } + + this.lastModifiedTime = File.GetLastWriteTime(fullFileName); + } + + /// + /// 获取缓存项依赖的文件名 + /// + public string FileName + { + get { return dependencyFileName; } + } + + /// + /// 获取缓存项依赖文件的最后修改时间 + /// + public DateTime LastModifiedTime + { + get { return lastModifiedTime; } + } + + /// + /// 判断缓存项是否过期 + /// + public bool HasExpired() + { + EnsureTargetFileAccessible(); + + if (File.Exists(this.dependencyFileName) == false) + { + return true; + } + + DateTime currentModifiedTime = File.GetLastWriteTime(dependencyFileName); + if (DateTime.Compare(lastModifiedTime, currentModifiedTime) != 0) + { + return true; + } + else + { + return false; + } + } + + public void Initialize(CacheItem owningCacheItem) + { + } + + /// + /// 确认目标文件可被访问 + /// + private void EnsureTargetFileAccessible() + { + string file = dependencyFileName; + FileIOPermission permission = new FileIOPermission(FileIOPermissionAccess.Read, file); + permission.Demand(); + } + } +} diff --git a/src/Kalman/Caching/CacheItemExpiration/ICacheItemExpiration.cs b/src/Kalman/Caching/CacheItemExpiration/ICacheItemExpiration.cs new file mode 100644 index 0000000..c59c861 --- /dev/null +++ b/src/Kalman/Caching/CacheItemExpiration/ICacheItemExpiration.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Kalman.Caching +{ + /// + /// 缓存项过期接口,可以基于该接口实现需要的缓存项过期对象 + /// + public interface ICacheItemExpiration + { + /// + /// 判断缓存项是否过期 + /// + bool HasExpired(); + + /// + /// 初始化 + /// + void Initialize(CacheItem owningCacheItem); + } +} diff --git a/src/Kalman/Caching/CacheItemExpiration/NeverExpired.cs b/src/Kalman/Caching/CacheItemExpiration/NeverExpired.cs new file mode 100644 index 0000000..ba1701e --- /dev/null +++ b/src/Kalman/Caching/CacheItemExpiration/NeverExpired.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Kalman.Caching +{ + /// + /// 从不过期 + /// + [Serializable] + public class NeverExpired : ICacheItemExpiration + { + public bool HasExpired() + { + return false; + } + + public void Initialize(CacheItem owningCacheItem) + { + } + } +} diff --git a/src/Kalman/Caching/CacheItemExpiration/SlidingTime.cs b/src/Kalman/Caching/CacheItemExpiration/SlidingTime.cs new file mode 100644 index 0000000..bc314d7 --- /dev/null +++ b/src/Kalman/Caching/CacheItemExpiration/SlidingTime.cs @@ -0,0 +1,88 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Kalman.Caching +{ + /// + /// 使用时间片来判断一个缓存项是否过期 + /// + [Serializable] + public class SlidingTime : ICacheItemExpiration + { + private DateTime timeLastUsed; + private TimeSpan itemSlidingExpiration; + + public SlidingTime(TimeSpan slidingExpiration) + { + if (!(slidingExpiration.TotalSeconds >= 1)) + { + throw new ArgumentOutOfRangeException("参数值超出范围"); + } + + this.itemSlidingExpiration = slidingExpiration; + } + + internal SlidingTime(TimeSpan slidingExpiration, DateTime originalTimeStamp) + : this(slidingExpiration) + { + timeLastUsed = originalTimeStamp; + } + + public TimeSpan ItemSlidingExpiration + { + get { return itemSlidingExpiration; } + } + + /// + /// 获取缓存项最近使用时间 + /// + public DateTime TimeLastUsed + { + get { return timeLastUsed; } + } + + /// + /// 判断缓存项是否过期 + /// + public bool HasExpired() + { + bool expired = CheckSlidingExpiration(DateTime.Now, + this.timeLastUsed, + this.itemSlidingExpiration); + return expired; + } + + /// + /// 通知该缓存项最近被使用过 + /// + public void Notify() + { + this.timeLastUsed = DateTime.Now; + } + + public void Initialize(CacheItem owningCacheItem) + { + } + + /// + /// 检查是否过期 + /// + /// 当前时间 + /// 缓存项最后使用时间 + /// 过期时间片 + private static bool CheckSlidingExpiration(DateTime nowDateTime, + DateTime lastUsed, + TimeSpan slidingExpiration) + { + DateTime tmpNowDateTime = nowDateTime.ToUniversalTime(); + DateTime tmpLastUsed = lastUsed.ToUniversalTime(); + + long expirationTicks = tmpLastUsed.Ticks + slidingExpiration.Ticks; + + bool expired = (tmpNowDateTime.Ticks >= expirationTicks) ? true : false; + + return expired; + } + } +} diff --git a/src/Kalman/Collections/KeyedList.cs b/src/Kalman/Collections/KeyedList.cs new file mode 100644 index 0000000..19c3d07 --- /dev/null +++ b/src/Kalman/Collections/KeyedList.cs @@ -0,0 +1,357 @@ +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Kalman.Collections +{ + [Serializable] + public class KeyedList : IDictionary, IList> + { + private readonly Dictionary objectTable = new Dictionary(); + private readonly List> objectList = new List>(); + + /// + /// Returns false. + /// + public bool IsReadOnly + { + get { return false; } + } + + /// + /// Returns the number of entries in the KeyedList. + /// + public int Count + { + get { return objectList.Count; } + } + + /// + /// Get/Set the value at the specified index. + /// + /// The index. + /// The value. + public KeyValuePair this[int index] + { + get + { + if (index < 0 || index >= Count) + throw new ArgumentOutOfRangeException("index"); + + return objectList[index]; + } + set + { + if (index < 0 || index >= Count) + throw new ArgumentOutOfRangeException("index"); + + objectList[index] = value; + objectTable[value.Key] = value.Value; + } + } + + /// + /// Get/Set the value associated with the specified key. + /// + /// The key. + /// The associated value. + public virtual V this[K key] + { + get { return objectTable[key]; } + set + { + if (objectTable.ContainsKey(key)) + { + objectTable[key] = value; + objectList[IndexOf(key)] = new KeyValuePair(key, value); + } + else + { + Add(key, value); + } + } + } + + /// + /// Get an unordered list of keys. + /// This collection refers back to the keys in the original Dictionary. + /// + public ICollection Keys + { + get { return objectTable.Keys; } + } + + /// + /// Get an unordered list of values. + /// This collection refers back to the values in the original Dictionary. + /// + public ICollection Values + { + get { return objectTable.Values; } + } + + /// + /// Get the ordered list of keys. + /// This is a copy of the keys in the original Dictionary. + /// + public List OrderedKeys + { + get + { + List retList = new List(); + + foreach (KeyValuePair kvp in objectList) + { + retList.Add(kvp.Key); + } + + return retList; + } + } + + /// + /// Get the ordered list of values. + /// This is a copy of the values in the original Dictionary. + /// + public List OrderedValues + { + get + { + List retList = new List(); + + foreach (KeyValuePair kvp in objectList) + { + retList.Add(kvp.Value); + } + + return retList; + } + } + + /// + /// Returns the key at the specified index. + /// + /// The index. + /// The key at the index. + public K GetKey(int index) + { + if (index < 0 || index >= Count) + throw new ArgumentOutOfRangeException("index"); + + return objectList[index].Key; + } + + /// + /// Returns the value at the specified index. + /// + /// The index. + /// The value at the index. + public V GetValue(int index) + { + if (index < 0 || index >= Count) + throw new ArgumentOutOfRangeException("index"); + + return objectList[index].Value; + } + + /// + /// Get the index of a particular key. + /// + /// The key to find the index of. + /// The index of the key, or -1 if not found. + public int IndexOf(K key) + { + int ret = -1; + + for (int i = 0; i < objectList.Count; i++) + { + if (objectList[i].Key.Equals(key)) + { + ret = i; + break; + } + } + + return ret; + } + + /// + /// Given the key-value pair, find the index. + /// + /// The key-value pair. + /// The index, or -1 if not found. + public int IndexOf(KeyValuePair kvp) + { + return objectList.IndexOf(kvp); + } + + /// + /// Gets the Dictionary class backing the KeyedList. + /// + public Dictionary ObjectTable + { + get { return objectTable; } + } + + /// + /// Clears all entries in the KeyedList. + /// + public void Clear() + { + objectTable.Clear(); + objectList.Clear(); + } + + /// + /// Test if the KeyedList contains the key. + /// + /// The key. + /// True if the key is found. + public bool ContainsKey(K key) + { + return objectTable.ContainsKey(key); + } + + /// + /// Test if the KeyedList contains the key in the key-value pair. + /// + /// The key-value pair. + /// True if the key is found. + public bool Contains(KeyValuePair kvp) + { + return objectList.Contains(kvp); + } + + /// + /// Adds a key-value pair to the KeyedList. + /// + /// The key. + /// The associated value. + public void Add(K key, V value) + { + objectTable.Add(key, value); + objectList.Add(new KeyValuePair(key, value)); + } + + /// + /// Adds a key-value pair to the KeyedList. + /// + /// The KeyValuePair instance. + public void Add(KeyValuePair kvp) + { + Add(kvp.Key, kvp.Value); + } + + /// + /// Copy the entire key-value pairs to the KeyValuePair array, starting + /// at the specified index of the target array. The array is populated + /// as an ordered list. + /// + /// The KeyValuePair array. + /// The position to start the copy. + public void CopyTo(KeyValuePair[] kvpa, int idx) + { + objectList.CopyTo(kvpa, idx); + } + + /// + /// Insert the key-value at the specified index. + /// + /// The zero-based insert point. + /// The key. + /// The value. + public void Insert(int index, K key, V value) + { + if (index < 0 || index > Count) + throw new ArgumentOutOfRangeException("index"); + + objectTable.Add(key, value); + objectList.Insert(index, new KeyValuePair(key, value)); + } + + /// + /// Insert the key-value pair at the specified index location. + /// + /// The key. + /// The value. + public void Insert(int index, KeyValuePair kvp) + { + if (index < 0 || index > Count) + throw new ArgumentOutOfRangeException("index"); + + objectTable.Add(kvp.Key, kvp.Value); + objectList.Insert(index, kvp); + } + + /// + /// Remove the entry. + /// + /// The key identifying the key-value pair. + /// True if removed. + public bool Remove(K key) + { + bool found = objectTable.Remove(key); + + if (found) + objectList.RemoveAt(IndexOf(key)); + + return found; + } + + /// + /// Remove the key in the specified KeyValuePair instance. The Value + /// property is ignored. + /// + /// The key-value identifying the entry. + /// True if removed. + public bool Remove(KeyValuePair kvp) + { + bool found = objectList.Remove(kvp); + + if (found) + objectTable.Remove(kvp.Key); + + return found; + } + + /// + /// Remove the entry at the specified index. + /// + /// The index to the entry to be removed. + public void RemoveAt(int index) + { + if (index < 0 || index >= Count) + throw new ArgumentOutOfRangeException("index"); + + objectTable.Remove(objectList[index].Key); + objectList.RemoveAt(index); + } + + /// + /// Attempt to get the value, given the key, without throwing an exception if not found. + /// + /// The key indentifying the entry. + /// The value, if found. + /// True if found. + public bool TryGetValue(K key, out V val) + { + return objectTable.TryGetValue(key, out val); + } + + /// + /// Returns an ordered System.Collections KeyValuePair objects. + /// + IEnumerator IEnumerable.GetEnumerator() + { + return objectList.GetEnumerator(); + } + + /// + /// Returns an ordered KeyValuePair enumerator. + /// + IEnumerator> IEnumerable>.GetEnumerator() + { + return objectList.GetEnumerator(); + } + } +} \ No newline at end of file diff --git a/src/Kalman/Collections/SynchronizedDictionary.cs b/src/Kalman/Collections/SynchronizedDictionary.cs new file mode 100644 index 0000000..174f631 --- /dev/null +++ b/src/Kalman/Collections/SynchronizedDictionary.cs @@ -0,0 +1,682 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Runtime.Serialization; +using System.Threading; + +namespace Kalman.Collections +{ + /// + /// Represents a syncrhonized collection of keys and values. + /// + /// The type of the keys in the dictionary. + /// The type of the values in the dictionary. + public class SynchronizedDictionary : IDictionary, ICollection>, IEnumerable>, IDictionary, ICollection, IEnumerable, ISerializable, IDeserializationCallback + { + private ReaderWriterLock rwLock; + private Dictionary dictionary; + + #region Public Constructors + /// + /// Initializes a new instance of the Dictionary class that is empty, has the default initial capacity, and uses the default equality comparer for the key type. + /// + public SynchronizedDictionary() + { + rwLock = new ReaderWriterLock(); + dictionary = new Dictionary(); + } + + /// + /// Initializes a new instance of the Dictionary class that contains elements copied from the specified IDictionary and uses the default equality comparer for the key type. + /// + /// The IDictionary whose elements are copied to the new Dictionary. + public SynchronizedDictionary(IDictionary dictionary) + { + rwLock = new ReaderWriterLock(); + this.dictionary = new Dictionary(dictionary); + } + + /// + /// Initializes a new instance of the Dictionary class that is empty, has the default initial capacity, and uses the specified IEqualityComparer. + /// + /// The IEqualityComparer implementation to use when comparing keys, or a null reference (Nothing in Visual Basic) to use the default EqualityComparer for the type of the key. + public SynchronizedDictionary(IEqualityComparer comparer) + { + rwLock = new ReaderWriterLock(); + dictionary = new Dictionary(comparer); + } + + /// + /// Initializes a new instance of the Dictionary class that is empty, has the specified initial capacity, and uses the default equality comparer for the key type. + /// + /// The initial number of elements that the Dictionary can contain. + public SynchronizedDictionary(int capacity) + { + rwLock = new ReaderWriterLock(); + dictionary = new Dictionary(capacity); + } + + /// + /// Initializes a new instance of the Dictionary class that contains elements copied from the specified IDictionary and uses the specified IEqualityComparer. + /// + /// The IDictionary whose elements are copied to the new Dictionary. + /// The IEqualityComparer implementation to use when comparing keys, or a null reference (Nothing in Visual Basic) to use the default EqualityComparer for the type of the key. + public SynchronizedDictionary(IDictionary dictionary, IEqualityComparer comparer) + { + rwLock = new ReaderWriterLock(); + this.dictionary = new Dictionary(dictionary, comparer); + } + + /// + /// Initializes a new instance of the Dictionary class that is empty, has the specified initial capacity, and uses the specified IEqualityComparer. + /// + /// The initial number of elements that the Dictionary can contain. + /// The IEqualityComparer implementation to use when comparing keys, or a null reference (Nothing in Visual Basic) to use the default EqualityComparer for the type of the key. + public SynchronizedDictionary(int capacity, IEqualityComparer comparer) + { + rwLock = new ReaderWriterLock(); + dictionary = new Dictionary(capacity, comparer); + } + #endregion + + #region Public Properties + /// + /// Gets the IEqualityComparer that is used to determine equality of keys for the dictionary. + /// + public IEqualityComparer Comparer + { + get { return dictionary.Comparer; } + } + + /// + /// Gets the number of key/value pairs contained in the Dictionary. + /// + public int Count + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return dictionary.Count; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + } + + /// + /// Gets or sets the value associated with the specified key. + /// + /// The key of the value to get or set. + /// The value associated with the specified key. If the specified key is not found, a get operation throws a KeyNotFoundException, and a set operation creates a new element with the specified key. + public TValue this[TKey key] + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return dictionary[key]; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + set + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + dictionary[key] = value; + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + } + + /// + /// Gets a collection containing the keys in the Dictionary. + /// + public ICollection Keys + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + Dictionary newDictionary = new Dictionary(dictionary); + return newDictionary.Keys; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + } + + /// + /// Gets a collection containing the values in the Dictionary. + /// + public ICollection Values + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + Dictionary newDictionary = new Dictionary(dictionary); + return newDictionary.Values; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + } + #endregion + + #region Public Members + /// + /// Adds the specified key and value to the dictionary. + /// + /// The key of the element to add. + /// The value of the element to add. The value can be a null reference (Nothing in Visual Basic) for reference types. + public void Add(TKey key, TValue value) + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + dictionary.Add(key, value); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Removes all keys and values from the Dictionary. + /// + public void Clear() + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + dictionary.Clear(); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Determines whether the Dictionary contains the specified key. + /// + /// The key to locate in the Dictionary. + /// true if the Dictionary contains an element with the specified key; otherwise, false. + public bool ContainsKey(TKey key) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return dictionary.ContainsKey(key); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Determines whether the Dictionary contains the specified value. + /// + /// The value to locate in the Dictionary. + /// true if the Dictionary contains an element with the specified value; otherwise, false. + public bool ContainsValue(TValue value) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return dictionary.ContainsValue(value); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Returns an enumerator that iterates through the collection. + /// + /// An IEnumerator that can be used to iterate through the collection. + public IEnumerator GetEnumerator() + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + Dictionary newDictionary = new Dictionary(dictionary); + return newDictionary.GetEnumerator(); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Implements the System.Runtime.Serialization.ISerializable interface and returns the data needed to serialize the Dictionary instance. + /// + /// A System.Runtime.Serialization.SerializationInfo object that contains the information required to serialize the Dictionary instance. + /// A System.Runtime.Serialization.StreamingContext structure that contains the source and destination of the serialized stream associated with the Dictionary instance. + public void GetObjectData(SerializationInfo info, StreamingContext context) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + ((ISerializable) dictionary).GetObjectData(info, context); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Implements the System.Runtime.Serialization.ISerializable interface and raises the deserialization event when the deserialization is complete. + /// + /// The source of the deserialization event. + public void OnDeserialization(object sender) + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + ((IDeserializationCallback) dictionary).OnDeserialization(sender); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Removes the value with the specified key from the Dictionary. + /// + /// The key of the element to remove. + /// true if the element is successfully found and removed; otherwise, false. This method returns false if key is not found in the Dictionary. + public bool Remove(TKey key) + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + return dictionary.Remove(key); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Gets the value associated with the specified key. + /// + /// The key of the value to get. + /// When this method returns, contains the value associated with the specified key, if the key is found; otherwise, the default value for the type of the value parameter. This parameter is passed uninitialized. + /// true if the Dictionary contains an element with the specified key; otherwise, false. + public bool TryGetValue(TKey key, out TValue value) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return dictionary.TryGetValue(key, out value); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + #endregion + + #region Explicit Interface Implementations + /// + /// Adds the specified value to the ICollection with the specified key. + /// + /// The KeyValuePair structure representing the key and value to add to the Dictionary. + void ICollection>.Add(KeyValuePair item) + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + ((ICollection>) dictionary).Add(item); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Determines whether the ICollection contains a specific key and value. + /// + /// The KeyValuePair structure to locate in the ICollection. + /// true if keyValuePair is found in the ICollection; otherwise, false. + bool ICollection>.Contains(KeyValuePair item) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return ((ICollection>) dictionary).Contains(item); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Copies the elements of the ICollection to an array of type KeyValuePair, starting at the specified array index. + /// + /// The one-dimensional array of type KeyValuePair that is the destination of the KeyValuePair elements copied from the ICollection. The array must have zero-based indexing. + /// The zero-based index in array at which copying begins. + void ICollection>.CopyTo(KeyValuePair[] array, int arrayIndex) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + ((ICollection>) dictionary).CopyTo(array, arrayIndex); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Gets a value indicating whether the dictionary is read-only. + /// + bool ICollection>.IsReadOnly + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return ((ICollection>) dictionary).IsReadOnly; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + } + + /// + /// Removes a key and value from the dictionary. + /// + /// The KeyValuePair structure representing the key and value to remove from the Dictionary. + /// true if the key and value represented by keyValuePair is successfully found and removed; otherwise, false. This method returns false if keyValuePair is not found in the ICollection. + bool ICollection>.Remove(KeyValuePair item) + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + return ((ICollection>) dictionary).Remove(item); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Returns an enumerator that iterates through the collection. + /// + /// An IEnumerator that can be used to iterate through the collection. + IEnumerator> IEnumerable>.GetEnumerator() + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + Dictionary newDictionary = new Dictionary(dictionary); + return newDictionary.GetEnumerator(); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Adds the specified key and value to the dictionary. + /// + /// The object to use as the key. + /// The object to use as the value. + void IDictionary.Add(object key, object value) + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + ((IDictionary) dictionary).Add(key, value); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Determines whether the IDictionary contains an element with the specified key. + /// + /// The key to locate in the IDictionary. + /// true if the IDictionary contains an element with the specified key; otherwise, false. + bool IDictionary.Contains(object key) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return ((IDictionary) dictionary).Contains(key); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Returns an IDictionaryEnumerator for the IDictionary. + /// + /// An IDictionaryEnumerator for the IDictionary. + IDictionaryEnumerator IDictionary.GetEnumerator() + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return ((IDictionary) dictionary).GetEnumerator(); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Gets a value indicating whether the IDictionary has a fixed size. + /// + bool IDictionary.IsFixedSize + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return ((IDictionary) dictionary).IsFixedSize; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + } + + /// + /// Gets a value indicating whether the IDictionary is read-only. + /// + bool IDictionary.IsReadOnly + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return ((IDictionary) dictionary).IsReadOnly; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + } + + /// + /// Gets an ICollection containing the keys of the IDictionary. + /// + ICollection IDictionary.Keys + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + IDictionary newDictionary = new Dictionary(dictionary); + return ((IDictionary) newDictionary).Keys; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + } + + /// + /// Removes the element with the specified key from the IDictionary. + /// + /// The key of the element to remove. + void IDictionary.Remove(object key) + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + ((IDictionary) dictionary).Remove(key); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Gets an ICollection containing the values in the IDictionary. + /// + ICollection IDictionary.Values + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + IDictionary newDictionary = new Dictionary(dictionary); + return ((IDictionary) newDictionary).Values; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + } + + /// + /// Gets or sets the value with the specified key. + /// + /// The key of the value to get. + /// The value associated with the specified key, or a null reference (Nothing in Visual Basic) if key is not in the dictionary or key is of a type that is not assignable to the key type TKey of the Dictionary. + object IDictionary.this[object key] + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return ((IDictionary) dictionary)[key]; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + set + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + ((IDictionary) dictionary)[key] = value; + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + } + + /// + /// Copies the elements of the ICollection to an array, starting at the specified array index. + /// + /// The one-dimensional array that is the destination of the elements copied from ICollection. The array must have zero-based indexing. + /// The zero-based index in array at which copying begins. + void ICollection.CopyTo(Array array, int index) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + ((ICollection) dictionary).CopyTo(array, index); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Gets a value indicating whether access to the ICollection is synchronized (thread safe). + /// + bool ICollection.IsSynchronized + { + get { return true; } + } + + /// + /// Gets an object that can be used to synchronize access to the ICollection. + /// + object ICollection.SyncRoot + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return ((ICollection) dictionary).SyncRoot; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + } + #endregion + } +} diff --git a/src/Kalman/Collections/SynchronizedLinkedList.cs b/src/Kalman/Collections/SynchronizedLinkedList.cs new file mode 100644 index 0000000..a8bf79b --- /dev/null +++ b/src/Kalman/Collections/SynchronizedLinkedList.cs @@ -0,0 +1,549 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Runtime.Serialization; +using System.Threading; + +namespace Kalman.Collections +{ + /// + /// Represents a sychronized doubly linked list. + /// + /// Specifies the element type of the linked list. + public class SynchronizedLinkedList : ICollection, IEnumerable, ICollection, IEnumerable, ISerializable, IDeserializationCallback + { + private ReaderWriterLock rwLock; + private LinkedList linkedList; + + #region Constructors + /// + /// Initializes a new instance of the LinkedList class that is empty. + /// + public SynchronizedLinkedList() + { + rwLock = new ReaderWriterLock(); + linkedList = new LinkedList(); + } + + /// + /// Initializes a new instance of the LinkedList class that contains elements copied from the specified IEnumerable and has sufficient capacity to accommodate the number of elements copied. + /// + /// The IEnumerable whose elements are copied to the new LinkedList. + public SynchronizedLinkedList(IEnumerable collection) + { + rwLock = new ReaderWriterLock(); + linkedList = new LinkedList(collection); + } + #endregion + + #region Public Properties + /// + /// Gets the number of nodes actually contained in the LinkedList. + /// + public int Count + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return linkedList.Count; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + } + + /// + /// Gets the first node of the LinkedList. + /// + public LinkedListNode First + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return linkedList.First; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + } + + /// + /// Gets the last node of the LinkedList. + /// + public LinkedListNode Last + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return linkedList.Last; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + } + #endregion + + #region Public Members + /// + /// Adds the specified new node after the specified existing node in the LinkedList. + /// + /// The LinkedListNode after which to insert newNode. + /// The new LinkedListNode to add to the LinkedList. + public void AddAfter(LinkedListNode node, LinkedListNode newNode) + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + linkedList.AddAfter(node, newNode); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Adds a new node containing the specified value after the specified existing node in the LinkedList. + /// + /// The LinkedListNode after which to insert a new LinkedListNode containing value. + /// The value to add to the LinkedList. + public void AddAfter(LinkedListNode node, T value) + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + linkedList.AddAfter(node, value); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Adds the specified new node before the specified existing node in the LinkedList. + /// + /// The LinkedListNode before which to insert newNode. + /// new LinkedListNode to add to the LinkedList. + public void AddBefore(LinkedListNode node, LinkedListNode newNode) + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + linkedList.AddBefore(node, newNode); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Adds a new node containing the specified value before the specified existing node in the LinkedList. + /// + /// The LinkedListNode before which to insert a new LinkedListNode containing value. + /// The value to add to the LinkedList. + public void AddBefore(LinkedListNode node, T value) + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + linkedList.AddBefore(node, value); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Adds the specified new node at the start of the LinkedList. + /// + /// new LinkedListNode to add at the start of the LinkedList. + public void AddFirst(LinkedListNode node) + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + linkedList.AddFirst(node); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Adds a new node containing the specified value at the start of the LinkedList. + /// + /// The value to add at the start of the LinkedList. + public void AddFirst(T value) + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + linkedList.AddFirst(value); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Adds the specified new node at the end of the LinkedList. + /// + /// The new LinkedListNode to add at the end of the LinkedList. + public void AddLast(LinkedListNode node) + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + linkedList.AddLast(node); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Adds a new node containing the specified value at the end of the LinkedList. + /// + /// The value to add at the end of the LinkedList. + public void AddLast(T value) + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + linkedList.AddLast(value); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Removes all nodes from the LinkedList. + /// + public void Clear() + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + linkedList.Clear(); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Determines whether a value is in the LinkedList. + /// + /// The value to locate in the LinkedList. The value can be a null reference (Nothing in Visual Basic) for reference types. + /// true if value is found in the LinkedList; otherwise, false. + public bool Contains(T item) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return linkedList.Contains(item); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Copies the entire LinkedList to a compatible one-dimensional Array, starting at the specified index of the target array. + /// + /// The one-dimensional Array that is the destination of the elements copied from LinkedList. The Array must have zero-based indexing. + /// The zero-based index in array at which copying begins. + public void CopyTo(T[] array, int arrayIndex) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + linkedList.CopyTo(array, arrayIndex); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Finds the first node that contains the specified value. + /// + /// The value to locate in the LinkedLis. + /// The first LinkedListNode that contains the specified value, if found; otherwise, a null reference (Nothing in Visual Basic). + public LinkedListNode Find(T value) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return linkedList.Find(value); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Finds the last node that contains the specified value. + /// + /// The value to locate in the LinkedList. + /// The last LinkedListNode that contains the specified value, if found; otherwise, a null reference (Nothing in Visual Basic). + public LinkedListNode FindLast(T value) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return linkedList.FindLast(value); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Returns an enumerator that iterates through the collection. + /// + /// An IEnumerator that can be used to iterate through the collection. + public IEnumerator GetEnumerator() + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + LinkedList newLinkedList = new LinkedList(linkedList); + return newLinkedList.GetEnumerator(); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Implements the System.Runtime.Serialization.ISerializable interface and returns the data needed to serialize the Dictionary instance. + /// + /// A System.Runtime.Serialization.SerializationInfo object that contains the information required to serialize the Dictionary instance. + /// A System.Runtime.Serialization.StreamingContext structure that contains the source and destination of the serialized stream associated with the Dictionary instance. + public void GetObjectData(SerializationInfo info, StreamingContext context) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + ((ISerializable) linkedList).GetObjectData(info, context); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Implements the System.Runtime.Serialization.ISerializable interface and raises the deserialization event when the deserialization is complete. + /// + /// The source of the deserialization event. + public void OnDeserialization(object sender) + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + ((IDeserializationCallback) linkedList).OnDeserialization(sender); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Removes the specified node from the LinkedList. + /// + /// The LinkedListNode to remove from the LinkedList. + public void Remove(LinkedListNode node) + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + linkedList.Remove(node); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Removes the first occurrence of the specified value from the LinkedList. + /// + /// The value to remove from the LinkedList. + /// true if the element containing value is successfully removed; otherwise, false. This method also returns false if value was not found in the original LinkedList. + public bool Remove(T item) + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + return linkedList.Remove(item); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Removes the node at the start of the LinkedList. + /// + public void RemoveFirst() + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + linkedList.RemoveFirst(); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Removes the node at the end of the LinkedList. + /// + public void RemoveLast() + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + linkedList.RemoveLast(); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + #endregion + + #region Explicit Interface Implementations + /// + /// Adds an item at the end of the ICollection. + /// + /// The value to add at the end of the ICollection. + void ICollection.Add(T item) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + linkedList.AddLast(item); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Returns an enumerator that iterates through a collection. + /// + /// An IEnumerator that can be used to iterate through the collection. + IEnumerator IEnumerable.GetEnumerator() + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + LinkedList newLinkedList = new LinkedList(linkedList); + return newLinkedList.GetEnumerator(); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Gets a value indicating whether the ICollection is read-only. + /// + bool ICollection.IsReadOnly + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return ((ICollection) linkedList).IsReadOnly; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + } + + /// + /// Copies the elements of the ICollection to an array, starting at the specified array index. + /// + /// The one-dimensional array that is the destination of the elements copied from ICollection. The array must have zero-based indexing. + /// The zero-based index in array at which copying begins. + void ICollection.CopyTo(Array array, int index) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + ((ICollection) linkedList).CopyTo(array, index); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Gets a value indicating whether access to the ICollection is synchronized (thread safe). + /// + bool ICollection.IsSynchronized + { + get { return true; } + } + + /// + /// Gets an object that can be used to synchronize access to the ICollection. + /// + object ICollection.SyncRoot + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return ((ICollection) linkedList).SyncRoot; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + } + #endregion + } +} diff --git a/src/Kalman/Collections/SynchronizedList.cs b/src/Kalman/Collections/SynchronizedList.cs new file mode 100644 index 0000000..646887c --- /dev/null +++ b/src/Kalman/Collections/SynchronizedList.cs @@ -0,0 +1,1194 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Runtime.Serialization; +using System.Threading; + +namespace Kalman.Collections +{ + /// + /// Represents a strongly typed list of objects that can be accessed by index. Provides methods to search, sort, and manipulate lists. + /// + /// The type of elements in the list. + public class SynchronizedList : IList, ICollection, IEnumerable, IList, ICollection, IEnumerable + { + private ReaderWriterLock rwLock; + private List list; + + #region Constructors + /// + /// Initializes a new instance of the List class that is empty and has the default initial capacity. + /// + public SynchronizedList() + { + rwLock = new ReaderWriterLock(); + list = new List(); + } + + /// + /// Initializes a new instance of the List class that contains elements copied from the specified collection and has sufficient capacity to accommodate the number of elements copied. + /// + /// The collection whose elements are copied to the new list. + public SynchronizedList(IEnumerable collection) + { + rwLock = new ReaderWriterLock(); + list = new List(collection); + } + + /// + /// Initializes a new instance of the List class that is empty and has the specified initial capacity. + /// + /// The number of elements that the new list can initially store. + public SynchronizedList(int capacity) + { + rwLock = new ReaderWriterLock(); + list = new List(capacity); + } + #endregion + + #region Public Properties + /// + /// Gets or sets the total number of elements the internal data structure can hold without resizing. + /// + public int Capacity + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return list.Capacity; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + set + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + list.Capacity = value; + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + } + + /// + /// Gets the number of elements actually contained in the List. + /// + public int Count + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return list.Count; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + } + + /// + /// Gets or sets the element at the specified index. + /// + /// The zero-based index of the element to get or set. + /// The element at the specified index. + public T this[int index] + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return list[index]; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + set + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + list[index] = value; + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + } + #endregion + + #region Public Methods + /// + /// Adds an object to the end of the List. + /// + /// object to be added to the end of the List. The value can be a null reference (Nothing in Visual Basic) for reference types. + public void Add(T item) + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + list.Add(item); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Adds the elements of the specified collection to the end of the List. + /// + /// The collection whose elements should be added to the end of the List. The collection itself cannot be a null reference (Nothing in Visual Basic), but it can contain elements that are a null reference (Nothing in Visual Basic), if type T is a reference type. + public void AddRange(IEnumerable collection) + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + list.AddRange(collection); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Returns a read-only IList wrapper for the current collection. + /// + /// A ReadOnlyCollection that acts as a read-only wrapper around the current List. + public ReadOnlyCollection AsReadOnly() + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return list.AsReadOnly(); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Searches the entire sorted List for an element using the default comparer and returns the zero-based index of the element. + /// + /// The object to locate. The value can be a null reference (Nothing in Visual Basic) for reference types. + /// The zero-based index of item in the sorted List, if item is found; otherwise, a negative number that is the bitwise complement of the index of the next element that is larger than item or, if there is no larger element, the bitwise complement of Count. + public int BinarySearch(T item) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return list.BinarySearch(item); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Searches the entire sorted List for an element using the specified comparer and returns the zero-based index of the element. + /// + /// The object to locate. The value can be a null reference (Nothing in Visual Basic) for reference types. + /// The IComparer implementation to use when comparing elements, or a null reference (Nothing in Visual Basic) to use the default comparer Comparer. + /// The zero-based index of item in the sorted List, if item is found; otherwise, a negative number that is the bitwise complement of the index of the next element that is larger than item or, if there is no larger element, the bitwise complement of Count. + public int BinarySearch(T item, IComparer comparer) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return list.BinarySearch(item, comparer); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Searches a range of elements in the sorted List for an element using the specified comparer and returns the zero-based index of the element. + /// + /// The zero-based starting index of the range to search. + /// The length of the range to search. + /// The object to locate. The value can be a null reference (Nothing in Visual Basic) for reference types. + /// The IComparer implementation to use when comparing elements, or a null reference (Nothing in Visual Basic) to use the default comparer Comparer. + /// The zero-based index of item in the sorted List, if item is found; otherwise, a negative number that is the bitwise complement of the index of the next element that is larger than item or, if there is no larger element, the bitwise complement of Count. + public int BinarySearch(int index, int count, T item, IComparer comparer) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return list.BinarySearch(index, count, item, comparer); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Removes all elements from the List. + /// + public void Clear() + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + list.Clear(); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Determines whether an element is in the List. + /// + /// The object to locate in the List. The value can be a null reference (Nothing in Visual Basic) for reference types. + /// true if item is found in the List; otherwise, false. + public bool Contains(T item) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return list.Contains(item); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Converts the elements in the current List to another type, and returns a list containing the converted elements. + /// + /// The type each element in the list should be converted to. + /// A Converter delegate that converts each element from one type to another type. + /// A List of the target type containing the converted elements from the current List. + public List ConvertAll(Converter converter) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return list.ConvertAll(converter); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Copies the entire List to a compatible one-dimensional array, starting at the beginning of the target array. + /// + /// The one-dimensional Array that is the destination of the elements copied from List. The Array must have zero-based indexing. + public void CopyTo(T[] array) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + list.CopyTo(array); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Copies the entire List to a compatible one-dimensional array, starting at the specified index of the target array. + /// + /// The one-dimensional Array that is the destination of the elements copied from List. The Array must have zero-based indexing. + /// The zero-based index in array at which copying begins. + public void CopyTo(T[] array, int arrayIndex) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + list.CopyTo(array, arrayIndex); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Copies a range of elements from the List to a compatible one-dimensional array, starting at the specified index of the target array. + /// + /// The zero-based index in the source List at which copying begins. + /// The one-dimensional Array that is the destination of the elements copied from List. The Array must have zero-based indexing + /// The zero-based index in array at which copying begins. + /// The number of elements to copy. + public void CopyTo(int index, T[] array, int arrayIndex, int count) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + list.CopyTo(index, array, arrayIndex, count); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Determines whether the List contains elements that match the conditions defined by the specified predicate. + /// + /// The Predicate delegate that defines the conditions of the elements to search for. + /// true if the List contains one or more elements that match the conditions defined by the specified predicate; otherwise, false. + public bool Exists(Predicate match) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return list.Exists(match); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Searches for an element that matches the conditions defined by the specified predicate, and returns the first occurrence within the entire List. + /// + /// The Predicate delegate that defines the conditions of the element to search for. + /// first element that matches the conditions defined by the specified predicate, if found; otherwise, the default value for type T. + public T Find(Predicate match) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return list.Find(match); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Retrieves all the elements that match the conditions defined by the specified predicate. + /// + /// The Predicate delegate that defines the conditions of the elements to search for. + /// A List containing all the elements that match the conditions defined by the specified predicate, if found; otherwise, an empty List. + public List FindAll(Predicate match) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return list.FindAll(match); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Searches for an element that matches the conditions defined by the specified predicate, and returns the zero-based index of the first occurrence within the entire List. + /// + /// The Predicate delegate that defines the conditions of the element to search for. + /// The zero-based index of the first occurrence of an element that matches the conditions defined by match, if found; otherwise, ?. + public int FindIndex(Predicate match) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return list.FindIndex(match); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Searches for an element that matches the conditions defined by the specified predicate, and returns the zero-based index of the first occurrence within the range of elements in the List that extends from the specified index to the last element. + /// + /// The zero-based starting index of the search. + /// The Predicate delegate that defines the conditions of the element to search for. + /// The zero-based index of the first occurrence of an element that matches the conditions defined by match, if found; otherwise, ?. + public int FindIndex(int startIndex, Predicate match) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return list.FindIndex(startIndex, match); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Searches for an element that matches the conditions defined by the specified predicate, and returns the last occurrence within the entire List. + /// + /// The Predicate delegate that defines the conditions of the element to search for. + /// The last element that matches the conditions defined by the specified predicate, if found; otherwise, the default value for type T. + public T FindLast(Predicate match) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return list.FindLast(match); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Searches for an element that matches the conditions defined by the specified predicate, and returns the zero-based index of the last occurrence within the entire List. + /// + /// The Predicate delegate that defines the conditions of the element to search for. + /// The zero-based index of the last occurrence of an element that matches the conditions defined by match, if found; otherwise, ?. + public int FindLastIndex(Predicate match) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return list.FindLastIndex(match); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Searches for an element that matches the conditions defined by the specified predicate, and returns the zero-based index of the last occurrence within the range of elements in the List that extends from the first element to the specified index. + /// + /// The zero-based starting index of the backward search. + /// The Predicate delegate that defines the conditions of the element to search for. + /// The zero-based index of the last occurrence of an element that matches the conditions defined by match, if found; otherwise, ?. + public int FindLastIndex(int startIndex, Predicate match) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return list.FindLastIndex(startIndex, match); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Searches for an element that matches the conditions defined by the specified predicate, and returns the zero-based index of the last occurrence within the range of elements in the List that contains the specified number of elements and ends at the specified index. + /// + /// The zero-based starting index of the backward search. + /// The number of elements in the section to search. + /// The Predicate delegate that defines the conditions of the element to search for. + /// The zero-based index of the last occurrence of an element that matches the conditions defined by match, if found; otherwise, ?. + public int FindLastIndex(int startIndex, int count, Predicate match) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return list.FindLastIndex(startIndex, count, match); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Performs the specified action on each element of the List. + /// + /// The Action delegate to perform on each element of the List. + public void ForEach(Action action) + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + list.ForEach(action); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Returns an enumerator that iterates through the List. + /// + /// A List.Enumerator for the List. + public IEnumerator GetEnumerator() + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + List newList = new List(list); + return newList.GetEnumerator(); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Creates a shallow copy of a range of elements in the source List. + /// + /// The zero-based List index at which the range starts. + /// The number of elements in the range. + /// A shallow copy of a range of elements in the source List. + public List GetRange(int index, int count) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return list.GetRange(index, count); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Searches for the specified object and returns the zero-based index of the first occurrence within the entire List. + /// + /// The object to locate in the List. The value can be a null reference (Nothing in Visual Basic) for reference types. + /// The zero-based index of the first occurrence of item within the entire List, if found; otherwise, ?. + public int IndexOf(T item) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return list.IndexOf(item); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Searches for the specified object and returns the zero-based index of the first occurrence within the range of elements in the List that extends from the specified index to the last element. + /// + /// The object to locate in the List. The value can be a null reference (Nothing in Visual Basic) for reference types. + /// The zero-based starting index of the search. + /// zero-based index of the first occurrence of item within the range of elements in the List that extends from index to the last element, if found; otherwise, ?. + public int IndexOf(T item, int index) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return list.IndexOf(item, index); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Searches for the specified object and returns the zero-based index of the first occurrence within the range of elements in the List that starts at the specified index and contains the specified number of elements. + /// + /// The object to locate in the List. The value can be a null reference (Nothing in Visual Basic) for reference types. + /// The zero-based starting index of the search. + /// The number of elements in the section to search. + /// The zero-based index of the first occurrence of item within the range of elements in the List that starts at index and contains count number of elements, if found; otherwise, ?. + public int IndexOf(T item, int index, int count) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return list.IndexOf(item, index, count); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Inserts an element into the List at the specified index. + /// + /// The zero-based index at which item should be inserted. + /// The object to insert. The value can be a null reference (Nothing in Visual Basic) for reference types. + public void Insert(int index, T item) + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + list.Insert(index, item); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Inserts the elements of a collection into the List at the specified index. + /// + /// The zero-based index at which the new elements should be inserted. + /// The collection whose elements should be inserted into the List. The collection itself cannot be a null reference (Nothing in Visual Basic), but it can contain elements that are a null reference (Nothing in Visual Basic), if type T is a reference type. + public void InsertRange(int index, IEnumerable collection) + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + list.InsertRange(index, collection); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Searches for the specified object and returns the zero-based index of the last occurrence within the entire List. + /// + /// The object to locate in the List. The value can be a null reference (Nothing in Visual Basic) for reference types. + /// The zero-based index of the last occurrence of item within the entire the List, if found; otherwise, ?. + public int LastIndexOf(T item) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return list.LastIndexOf(item); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Searches for the specified object and returns the zero-based index of the last occurrence within the range of elements in the List that extends from the first element to the specified index. + /// + /// object to locate in the List. The value can be a null reference (Nothing in Visual Basic) for reference types. + /// The zero-based starting index of the backward search. + /// The zero-based index of the last occurrence of item within the range of elements in the List that extends from the first element to index, if found; otherwise, ?. + public int LastIndexOf(T item, int index) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return list.LastIndexOf(item, index); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Searches for the specified object and returns the zero-based index of the last occurrence within the range of elements in the List that contains the specified number of elements and ends at the specified index. + /// + /// The object to locate in the List. The value can be a null reference (Nothing in Visual Basic) for reference types. + /// The zero-based starting index of the backward search. + /// The number of elements in the section to search. + /// The zero-based index of the last occurrence of item within the range of elements in the List that contains count number of elements and ends at index, if found; otherwise, ?. + public int LastIndexOf(T item, int index, int count) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return list.LastIndexOf(item, index, count); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Removes the first occurrence of a specific object from the List. + /// + /// The object to remove from the List. The value can be a null reference (Nothing in Visual Basic) for reference types. + /// true if item is successfully removed; otherwise, false. This method also returns false if item was not found in the List. + public bool Remove(T item) + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + return list.Remove(item); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Removes the all the elements that match the conditions defined by the specified predicate. + /// + /// The Predicate delegate that defines the conditions of the elements to remove. + /// The number of elements removed from the List. + public int RemoveAll(Predicate match) + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + return list.RemoveAll(match); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Removes the element at the specified index of the List. + /// + /// The zero-based index of the element to remove. + public void RemoveAt(int index) + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + list.RemoveAt(index); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Removes a range of elements from the List. + /// + /// The zero-based starting index of the range of elements to remove. + /// The number of elements to remove. + public void RemoveRange(int index, int count) + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + list.RemoveRange(index, count); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Reverses the order of the elements in the entire List. + /// + public void Reverse() + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + list.Reverse(); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Reverses the order of the elements in the specified range. + /// + /// The zero-based starting index of the range to reverse. + /// The number of elements in the range to reverse. + public void Reverse(int index, int count) + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + list.Reverse(index, count); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Sorts the elements in the entire List using the default comparer. + /// + public void Sort() + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + list.Sort(); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Sorts the elements in the entire List using the specified System.Comparison. + /// + /// The System.Comparison to use when comparing elements. + public void Sort(Comparison comparison) + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + list.Sort(comparison); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Sorts the elements in the entire List using the specified comparer. + /// + /// The IComparer implementation to use when comparing elements, or a null reference (Nothing in Visual Basic) to use the default comparer. + public void Sort(IComparer comparer) + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + list.Sort(comparer); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Sorts the elements in a range of elements in List using the specified comparer. + /// + /// The zero-based starting index of the range to sort. + /// The length of the range to sort. + /// The IComparer implementation to use when comparing elements, or a null reference (Nothing in Visual Basic) to use the default comparer. + public void Sort(int index, int count, IComparer comparer) + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + list.Sort(); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Copies the elements of the List to a new array. + /// + /// An array containing copies of the elements of the List. + public T[] ToArrary() + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return list.ToArray(); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Sets the capacity to the actual number of elements in the List, if that number is less than a threshold value. + /// + public void TrimExcess() + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + list.TrimExcess(); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Determines whether every element in the List matches the conditions defined by the specified predicate. + /// + /// The Predicate delegate that defines the conditions to check against the elements. + /// true if every element in the List matches the conditions defined by the specified predicate; otherwise, false. If the list has no elements, the return value is true. + public bool TrueForAll(Predicate match) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return list.TrueForAll(match); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + #endregion + + #region Explicit Interface Implementations + /// + /// Returns an enumerator that iterates through a collection. + /// + /// An IEnumerator that can be used to iterate through the collection. + IEnumerator IEnumerable.GetEnumerator() + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + List newList = new List(list); + return newList.GetEnumerator(); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Copies the elements of the ICollection to an Array, starting at a particular Array index. + /// + /// The one-dimensional Array that is the destination of the elements copied from ICollection. The Array must have zero-based indexing. + /// The zero-based index in array at which copying begins. + void ICollection.CopyTo(Array array, int index) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + ((ICollection) list).CopyTo(array, index); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Adds an item to the IList. + /// + /// The Object to add to the IList. + /// The position into which the new element was inserted. + int IList.Add(object value) + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + return ((IList) list).Add(value); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Determines whether the IList contains a specific value. + /// + /// The Object to locate in the IList. + /// true if item is found in the IList; otherwise, false. + bool IList.Contains(object value) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return ((IList) list).Contains(value); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Determines the index of a specific item in the IList. + /// + /// The object to locate in the IList. + /// The index of item if found in the list; otherwise, ?. + int IList.IndexOf(object value) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return ((IList) list).IndexOf(value); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Inserts an item to the IList at the specified index. + /// + /// The zero-based index at which item should be inserted. + /// The object to insert into the IList. + void IList.Insert(int index, object value) + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + ((IList) list).Insert(index, value); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Removes the first occurrence of a specific object from the IList. + /// + /// The object to remove from the IList. + void IList.Remove(object value) + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + ((IList) list).Remove(value); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Gets a value indicating whether the ICollection is read-only. + /// + bool ICollection.IsReadOnly + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return ((ICollection) list).IsReadOnly; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + } + + /// + /// Gets a value indicating whether access to the ICollection is synchronized (thread safe). + /// + bool ICollection.IsSynchronized + { + get { return true; } + } + + /// + /// Gets an object that can be used to synchronize access to the ICollection. + /// + object ICollection.SyncRoot + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return ((ICollection) list).SyncRoot; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + } + + /// + /// Gets a value indicating whether the IList has a fixed size. + /// + bool IList.IsFixedSize + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return ((IList) list).IsFixedSize; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + } + + /// + /// Gets a value indicating whether the IList is read-only. + /// + bool IList.IsReadOnly + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return ((IList) list).IsReadOnly; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + } + + /// + /// Gets or sets the element at the specified index. + /// + /// The zero-based index of the element to get or set. + /// The element at the specified index. + object IList.this[int index] + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return ((IList) list)[index]; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + set + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + } + #endregion + } +} diff --git a/src/Kalman/Collections/SynchronizedQueue.cs b/src/Kalman/Collections/SynchronizedQueue.cs new file mode 100644 index 0000000..baf911f --- /dev/null +++ b/src/Kalman/Collections/SynchronizedQueue.cs @@ -0,0 +1,291 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Runtime.Serialization; +using System.Threading; + +namespace Kalman.Collections +{ + /// + /// Represents a first-in, first-out synchronized collection of objects. + /// + /// Specifies the type of elements in the queue. + public class SynchronizedQueue : IEnumerable, ICollection, IEnumerable + { + private ReaderWriterLock rwLock; + private Queue queue; + + #region Constructors + /// + /// Initializes a new instance of the Queue class that is empty and has the default initial capacity. + /// + public SynchronizedQueue() + { + rwLock = new ReaderWriterLock(); + queue = new Queue(); + } + + /// + /// Initializes a new instance of the Queue class that contains elements copied from the specified collection and has sufficient capacity to accommodate the number of elements copied. + /// + /// The collection whose elements are copied to the new Queue. + public SynchronizedQueue(ICollection collection) + { + rwLock = new ReaderWriterLock(); + queue = new Queue(collection); + } + + /// + /// Initializes a new instance of the Queue class that is empty and has the specified initial capacity. + /// + /// The initial number of elements that the Queue can contain. + public SynchronizedQueue(int capacity) + { + rwLock = new ReaderWriterLock(); + queue = new Queue(capacity); + } + #endregion + + #region Public Properties + /// + /// Gets the number of elements contained in the Queue. + /// + public int Count + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return queue.Count; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + } + #endregion + + #region Public Methods + /// + /// Removes all objects from the Queue. + /// + public void Clear() + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + queue.Clear(); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Determines whether an element is in the Queue. + /// + /// The object to locate in the Queue. The value can be a null reference (Nothing in Visual Basic) for reference types. + /// true if item is found in the Queue; otherwise, false. + public bool Contains(T item) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return queue.Contains(item); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Copies the Queue elements to an existing one-dimensional Array, starting at the specified array index. + /// + /// The one-dimensional Array that is the destination of the elements copied from Queue. The Array must have zero-based indexing. + /// The zero-based index in array at which copying begins. + public void CopyTo(T[] array, int arrayIndex) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + queue.CopyTo(array, arrayIndex); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Removes and returns the object at the beginning of the Queue. + /// + /// The object that is removed from the beginning of the Queue. + public T Dequeue() + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + return queue.Dequeue(); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Adds an object to the end of the Queue. + /// + /// The object to add to the Queue. The value can be a null reference (Nothing in Visual Basic) for reference types. + public void Enqueue(T item) + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + queue.Enqueue(item); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Returns an enumerator that iterates through the Queue. + /// + /// An Queue.Enumerator for the Queue. + public IEnumerator GetEnumerator() + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + Queue newQueue = new Queue(queue); + return newQueue.GetEnumerator(); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Returns the object at the beginning of the Queue without removing it. + /// + /// The object at the beginning of the Queue. + public T Peek() + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return queue.Peek(); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Copies the Queue elements to a new array. + /// + /// A new array containing elements copied from the Queue. + public T[] ToArray() + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return queue.ToArray(); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Sets the capacity to the actual number of elements in the Queue, if that number is less than 90 percent of current capacity. + /// + public void TrimExcess() + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + queue.TrimExcess(); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + #endregion + + #region Explicit Interface Implementations + /// + /// Returns an enumerator that iterates through a collection. + /// + /// An IEnumerator that can be used to iterate through the collection. + IEnumerator IEnumerable.GetEnumerator() + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + Queue newQueue = new Queue(queue); + return newQueue.GetEnumerator(); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// the elements of the ICollection to an Array, starting at a particular Array index. + /// + /// The one-dimensional Array that is the destination of the elements copied from ICollection. The Array must have zero-based indexing. + /// The zero-based index in array at which copying begin. + void ICollection.CopyTo(Array array, int index) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + ((ICollection) queue).CopyTo(array, index); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Gets a value indicating whether access to the ICollection is synchronized (thread safe). + /// + bool ICollection.IsSynchronized + { + get { return true; } + } + + /// + /// Gets an object that can be used to synchronize access to the ICollection. + /// + object ICollection.SyncRoot + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return ((ICollection) queue).SyncRoot; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + } + #endregion + } +} diff --git a/src/Kalman/Collections/SynchronizedSortedDictionary.cs b/src/Kalman/Collections/SynchronizedSortedDictionary.cs new file mode 100644 index 0000000..fbf8df2 --- /dev/null +++ b/src/Kalman/Collections/SynchronizedSortedDictionary.cs @@ -0,0 +1,680 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Runtime.Serialization; +using System.Threading; + +namespace Kalman.Collections +{ + /// + /// Represents a collection of key/value pairs that are sorted on the key. + /// + /// The type of the keys in the dictionary. + /// The type of the values in the dictionary. + public class SynchronizedSortedDictionary : IDictionary, ICollection>, IEnumerable>, IDictionary, ICollection, IEnumerable + { + private ReaderWriterLock rwLock; + private SortedDictionary sortedDictionary; + + #region Constructors + /// + /// Initializes a new instance of the SortedDictionary class that is empty and uses the default IComparer implementation for the key type. + /// + public SynchronizedSortedDictionary() + { + rwLock = new ReaderWriterLock(); + sortedDictionary = new SortedDictionary(); + } + + /// + /// Initializes a new instance of the SortedDictionary class that is empty and uses the specified IComparer implementation to compare keys. + /// + /// The IComparer implementation to use when comparing keys, or a null reference (Nothing in Visual Basic) to use the default Comparer for the type of the key. + public SynchronizedSortedDictionary(IComparer comparer) + { + rwLock = new ReaderWriterLock(); + sortedDictionary = new SortedDictionary(comparer); + } + + /// + /// Initializes a new instance of the SortedDictionary class that contains elements copied from the specified IDictionary and uses the default IComparer implementation for the key type. + /// + /// The IDictionary whose elements are copied to the new SortedDictionary. + public SynchronizedSortedDictionary(IDictionary dictionary) + { + rwLock = new ReaderWriterLock(); + this.sortedDictionary = new SortedDictionary(dictionary); + } + + /// + /// Initializes a new instance of the SortedDictionary class that contains elements copied from the specified IDictionary and uses the specified IComparer implementation to compare keys. + /// + /// The IDictionary whose elements are copied to the new SortedDictionary. + /// The IComparer implementation to use when comparing keys, or a null reference (Nothing in Visual Basic) to use the default Comparer for the type of the key. + public SynchronizedSortedDictionary(IDictionary dictionary, IComparer comparer) + { + rwLock = new ReaderWriterLock(); + this.sortedDictionary = new SortedDictionary(dictionary, comparer); + } + #endregion + + #region Public Properties + /// + /// Gets the IComparer used to order the elements of the SortedDictionary. + /// + public IComparer Comparer + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return sortedDictionary.Comparer; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + } + + /// + /// Gets the number of key/value pairs contained in the SortedDictionary. + /// + public int Count + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return sortedDictionary.Count; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + } + + /// + /// Gets or sets the value associated with the specified key. + /// + /// The key of the value to get or set. + /// The value associated with the specified key. If the specified key is not found, a get operation throws a KeyNotFoundException, and a set operation creates a new element with the specified key. + public TValue this[TKey key] + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return sortedDictionary[key]; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + set + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + sortedDictionary[key] = value; + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + } + + /// + /// Gets a collection containing the keys in the SortedDictionary. + /// + public ICollection Keys + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + Dictionary newDictionary = new Dictionary(sortedDictionary); + return newDictionary.Keys; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + } + + /// + /// Gets a collection containing the values in the SortedDictionary. + /// + public ICollection Values + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + Dictionary newDictionary = new Dictionary(sortedDictionary); + return newDictionary.Values; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + } + #endregion + + #region Public Methods + /// + /// Adds an element with the specified key and value into the SortedDictionary. + /// + /// The key of the element to add. + /// The value of the element to add. The value can be a null reference (Nothing in Visual Basic) for reference types. + public void Add(TKey key, TValue value) + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + sortedDictionary.Add(key, value); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Removes all elements from the SortedDictionary. + /// + public void Clear() + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + sortedDictionary.Clear(); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Determines whether the SortedDictionary contains an element with the specified key. + /// + /// The key to locate in the SortedDictionary. + /// true if the SortedDictionary contains an element with the specified key; otherwise, false. + public bool ContainsKey(TKey key) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return sortedDictionary.ContainsKey(key); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Determines whether the SortedDictionary contains an element with the specified value. + /// + /// The value to locate in the SortedDictionary. The value can be a null reference (Nothing in Visual Basic) for reference types. + /// true if the SortedDictionary contains an element with the specified value; otherwise, false. + public bool ContainsValue(TValue value) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return sortedDictionary.ContainsValue(value); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Copies the elements of the SortedDictionary to the specified array of KeyValuePair structures, starting at the specified index. + /// + /// The one-dimensional array of KeyValuePair structures that is the destination of the elements copied from the current SortedDictionary The array must have zero-based indexing. + /// The zero-based index in array at which copying begins. + public void CopyTo(KeyValuePair[] array, int arrayIndex) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + ((ICollection>) sortedDictionary).CopyTo(array, arrayIndex); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Returns an enumerator that iterates through the SortedDictionary. + /// + /// A SortedDictionary.Enumerator for the SortedDictionary. + public IEnumerator GetEnumerator() + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + SortedDictionary newSortedDictionary = new SortedDictionary(sortedDictionary); + return newSortedDictionary.GetEnumerator(); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Removes the element with the specified key from the SortedDictionary. + /// + /// The key of the element to remove. + /// true if the element is successfully removed; otherwise, false. This method also returns false if key is not found in the SortedDictionary. + public bool Remove(TKey key) + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + return sortedDictionary.Remove(key); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Gets the value associated with the specified key. + /// + /// The key of the value to get. + /// When this method returns, the value associated with the specified key, if the key is found; otherwise, the default value for the type of the value parameter. + /// + public bool TryGetValue(TKey key, out TValue value) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return sortedDictionary.TryGetValue(key, out value); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + #endregion + + #region Explicit Interface Implementations + /// + /// Adds an item to the ICollection. + /// + /// The KeyValuePair structure to add to the ICollection. + void ICollection>.Add(KeyValuePair item) + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + ((ICollection>) sortedDictionary).Add(item); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Determines whether the ICollection contains a specific key and value. + /// + /// The KeyValuePair structure to locate in the ICollection. + /// true if keyValuePair is found in the ICollection; otherwise, false. + bool ICollection>.Contains(KeyValuePair item) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return ((ICollection>) sortedDictionary).Contains(item); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Removes the first occurrence of the specified element from the ICollection. + /// + /// The KeyValuePair structure to remove from the ICollection. + /// true if keyValuePair was successfully removed from the ICollection; otherwise, false. This method also returns false if keyValuePair was not found in the ICollection. + bool ICollection>.Remove(KeyValuePair item) + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + return ((ICollection>) sortedDictionary).Remove(item); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Returns an enumerator that iterates through the collection. + /// + /// An IEnumerator that can be used to iterate through the collection. + IEnumerator> IEnumerable>.GetEnumerator() + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + Dictionary newDictionary = new Dictionary(sortedDictionary); + return newDictionary.GetEnumerator(); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Copies the elements of the ICollection to an array, starting at the specified array index. + /// + /// The one-dimensional array that is the destination of the elements copied from the ICollection. The array must have zero-based indexing. + /// The zero-based index in array at which copying begins. + void ICollection.CopyTo(Array array, int index) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + ((ICollection) sortedDictionary).CopyTo(array, index); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Adds an element with the provided key and value to the IDictionary. + /// + /// The object to use as the key of the element to add. + /// The object to use as the value of the element to add. + void IDictionary.Add(object key, object value) + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + ((IDictionary) sortedDictionary).Add(key, value); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Determines whether the IDictionary contains an element with the specified key. + /// + /// The key to locate in the IDictionary. + /// true if the IDictionary contains an element with the key; otherwise, false. + bool IDictionary.Contains(object key) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return ((IDictionary) sortedDictionary).Contains(key); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Returns an IDictionaryEnumerator for the IDictionary. + /// + /// An IDictionaryEnumerator for the IDictionary. + IDictionaryEnumerator IDictionary.GetEnumerator() + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + SortedDictionary newSortedDictionary = new SortedDictionary(sortedDictionary); + return ((IDictionary) newSortedDictionary).GetEnumerator(); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Removes the element with the specified key from the IDictionary. + /// + /// The key of the element to remove. + void IDictionary.Remove(object key) + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + ((IDictionary) sortedDictionary).Remove(key); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Gets a value indicating whether the ICollection is read-only. + /// + bool ICollection>.IsReadOnly + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return ((ICollection>) sortedDictionary).IsReadOnly; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + } + + /// + /// Gets an ICollection containing the keys of the IDictionary. + /// + ICollection IDictionary.Keys + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + SortedDictionary newSortedDictionary = new SortedDictionary(sortedDictionary); + return ((IDictionary) newSortedDictionary).Keys; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + } + + /// + /// Gets an ICollection containing the values of the IDictionary. + /// + ICollection IDictionary.Values + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + SortedDictionary newSortedDictionary = new SortedDictionary(sortedDictionary); + return ((IDictionary) newSortedDictionary).Values; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + } + + /// + /// Gets a value indicating whether access to the ICollection is synchronized (thread safe). + /// + bool ICollection.IsSynchronized + { + get { return true; } + } + + /// + /// Gets an object that can be used to synchronize access to the ICollection. + /// + object ICollection.SyncRoot + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return ((ICollection) sortedDictionary).SyncRoot; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + } + + /// + /// Gets a value indicating whether the IDictionary has a fixed size. + /// + bool IDictionary.IsFixedSize + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return ((IDictionary) sortedDictionary).IsFixedSize; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + } + + /// + /// Gets a value indicating whether the IDictionary is read-only. + /// + bool IDictionary.IsReadOnly + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return ((IDictionary) sortedDictionary).IsReadOnly; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + } + + /// + /// Gets or sets the element with the specified key. + /// + /// The key of the element to get. + /// The element with the specified key, or a null reference (Nothing in Visual Basic) if key is not in the dictionary or key is of a type that is not assignable to the key type TKey of the SortedDictionary. + object IDictionary.this[object key] + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return ((IDictionary) sortedDictionary)[key]; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + set + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + ((IDictionary) sortedDictionary)[key] = value; + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + } + + /// + /// Gets an ICollection containing the keys of the IDictionary. + /// + ICollection IDictionary.Keys + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + SortedDictionary newSortedDictionary = new SortedDictionary(sortedDictionary); + return ((IDictionary) newSortedDictionary).Keys; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + } + + /// + /// Gets an ICollection containing the values in the IDictionary. + /// + ICollection IDictionary.Values + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + SortedDictionary newSortedDictionary = new SortedDictionary(sortedDictionary); + return ((IDictionary) newSortedDictionary).Values; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + } + #endregion + } +} diff --git a/src/Kalman/Collections/SynchronizedSortedList.cs b/src/Kalman/Collections/SynchronizedSortedList.cs new file mode 100644 index 0000000..5779d22 --- /dev/null +++ b/src/Kalman/Collections/SynchronizedSortedList.cs @@ -0,0 +1,790 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Runtime.Serialization; +using System.Threading; + +namespace Kalman.Collections +{ + /// + /// Represents a synchronized collection of key/value pairs that are sorted by key based on the associated IComparer implementation. + /// + /// The type of keys in the collection. + /// The type of values in the collection. + public class SynchronizedSortedList : IDictionary, ICollection>, IEnumerable>, IDictionary, ICollection, IEnumerable + { + private ReaderWriterLock rwLock; + private SortedList sortedList; + + #region Constructors + /// + /// Initializes a new instance of the SortedList class that is empty, has the default initial capacity, and uses the default IComparer. + /// + public SynchronizedSortedList() + { + rwLock = new ReaderWriterLock(); + sortedList = new SortedList(); + } + + /// + /// Initializes a new instance of the SortedList class that is empty, has the default initial capacity, and uses the specified IComparer. + /// + /// The IComparer implementation to use when comparing keys, or aa null reference (Nothing in Visual Basic) to use the default Comparer for the type of the key. + public SynchronizedSortedList(IComparer comparer) + { + rwLock = new ReaderWriterLock(); + sortedList = new SortedList(comparer); + } + + /// + /// Initializes a new instance of the SortedList class that contains elements copied from the specified IDictionary, has sufficient capacity to accommodate the number of elements copied, and uses the default IComparer. + /// + /// The IDictionary whose elements are copied to the new SortedList. + public SynchronizedSortedList(IDictionary dictionary) + { + rwLock = new ReaderWriterLock(); + sortedList = new SortedList(dictionary); + } + + /// + /// Initializes a new instance of the SortedList class that is empty, has the specified initial capacity, and uses the default IComparer. + /// + /// The initial number of elements that the SortedList can contain. + public SynchronizedSortedList(int capacity) + { + rwLock = new ReaderWriterLock(); + sortedList = new SortedList(capacity); + } + + /// + /// Initializes a new instance of the SortedList class that contains elements copied from the specified IDictionary, has sufficient capacity to accommodate the number of elements copied, and uses the specified IComparer. + /// + /// The IDictionary whose elements are copied to the new SortedList. + /// The IComparer implementation to use when comparing keys, or aa null reference (Nothing in Visual Basic) to use the default Comparer for the type of the key. + public SynchronizedSortedList(IDictionary dictionary, IComparer comparer) + { + rwLock = new ReaderWriterLock(); + sortedList = new SortedList(dictionary, comparer); + } + + /// + /// Initializes a new instance of the SortedList class that is empty, has the specified initial capacity, and uses the specified IComparer. + /// + /// The initial number of elements that the SortedList can contain. + /// The IComparer implementation to use when comparing keys, or aa null reference (Nothing in Visual Basic) to use the default Comparer for the type of the key. + public SynchronizedSortedList(int capacity, IComparer comparer) + { + rwLock = new ReaderWriterLock(); + sortedList = new SortedList(capacity, comparer); + } + #endregion + + #region Public Properties + /// + /// Gets or sets the number of elements that the SortedList can contain. + /// + public int Capacity + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return sortedList.Capacity; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + } + + /// + /// Gets the IComparer for the sorted list. + /// + public IComparer Comparer + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return sortedList.Comparer; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + } + + /// + /// Gets the number of key/value pairs contained in the SortedList. + /// + public int Count + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return sortedList.Count; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + } + + /// + /// Gets or sets the value associated with the specified key. + /// + /// The key whose value to get or set. + /// The value associated with the specified key. If the specified key is not found, a get operation throws a KeyNotFoundException and a set operation creates a new element using the specified key. + public TValue this[TKey key] + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return sortedList[key]; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + set + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + sortedList[key] = value; + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + } + + /// + /// Gets a collection containing the keys in the SortedList. + /// + public ICollection Keys + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + SortedList newSortedList = new SortedList(sortedList); + return newSortedList.Keys; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + } + + /// + /// Gets a collection containing the values in the SortedList. + /// + public ICollection Values + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + SortedList newSortedList = new SortedList(sortedList); + return newSortedList.Values; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + } + #endregion + + #region Public Methods + /// + /// Adds an element with the specified key and value into the SortedList. + /// + /// The key of the element to add. + /// The value of the element to add. The value can be a null reference (Nothing in Visual Basic) for reference types. + public void Add(TKey key, TValue value) + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + sortedList.Add(key, value); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Removes all elements from the SortedList. + /// + public void Clear() + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + sortedList.Clear(); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Determines whether the SortedList contains a specific key. + /// + /// The key to locate in the SortedList. + /// true if the SortedList contains an element with the specified key; otherwise, false. + public bool ContainsKey(TKey key) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return sortedList.ContainsKey(key); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Determines whether the SortedList contains a specific value. + /// + /// The value to locate in the SortedList. + /// true if the SortedList contains an element with the specified value; otherwise, false. + public bool ContainsValue(TValue value) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return sortedList.ContainsValue(value); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Returns an enumerator that iterates through the SortedList. + /// + /// An IEnumerator of type KeyValuePair for the SortedList. + public IEnumerator> GetEnumerator() + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return ((IEnumerable>) sortedList).GetEnumerator(); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Searches for the specified key and returns the zero-based index within the entire SortedList. + /// + /// The key to locate in the SortedList. + /// The zero-based index of key within the entire SortedList, if found; otherwise, -1. + public int IndexOfKey(TKey key) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return sortedList.IndexOfKey(key); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Searches for the specified value and returns the zero-based index within the entire SortedList. + /// + /// The value to locate in the SortedList. + /// The zero-based index of value within the entire SortedList, if found; otherwise, -1. + public int IndexOfValue(TValue value) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return sortedList.IndexOfValue(value); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Removes the element with the specified key from the SortedList. + /// + /// The key of the element to remove. + /// true if the element is successfully removed; otherwise, false. This method also returns false if key was not found in the original SortedList. + public bool Remove(TKey key) + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + return sortedList.Remove(key); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Removes the element at the specified index of the SortedList. + /// + /// The zero-based index of the element to remove. + public void RemoveAt(int index) + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + sortedList.RemoveAt(index); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Sets the capacity to the actual number of elements in the SortedList, if that number is less than 90 percent of current capacity. + /// + public void TrimExcess() + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + sortedList.TrimExcess(); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Gets the value associated with the specified key. + /// + /// The key whose value to get. + /// When this method returns, the value associated with the specified key, if the key is found; otherwise, the default value for the type of the value parameter. This parameter is passed uninitialized. + /// + public bool TryGetValue(TKey key, out TValue value) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return sortedList.TryGetValue(key, out value); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + #endregion + + #region Explicit Interface Implementations + /// + /// Adds a key/value pair to the ICollection. + /// + /// The KeyValuePair to add to the ICollection. + void ICollection>.Add(KeyValuePair item) + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + ((ICollection>) sortedList).Add(item); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Determines whether the ICollection contains a specific element. + /// + /// The KeyValuePair to locate in the ICollection. + /// true if keyValuePair is found in the ICollection; otherwise, false. + bool ICollection>.Contains(KeyValuePair item) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return ((ICollection>) sortedList).Contains(item); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Copies the elements of the ICollection to an Array, starting at a particular Array index. + /// + /// The one-dimensional Array that is the destination of the elements copied from ICollection. The Array must have zero-based indexing. + /// The zero-based index in array at which copying begins. + void ICollection>.CopyTo(KeyValuePair[] array, int arrayIndex) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + ((ICollection>) sortedList).CopyTo(array, arrayIndex); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Removes the first occurrence of a specific key/value pair from the ICollection. + /// + /// The KeyValuePair to remove from the ICollection. + /// true if keyValuePair was successfully removed from the ICollection; otherwise, false. This method also returns false if keyValuePair was not found in the original ICollection. + bool ICollection>.Remove(KeyValuePair item) + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + return ((ICollection>) sortedList).Remove(item); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Copies the elements of the ICollection to an Array, starting at a particular Array index. + /// + /// The one-dimensional Array that is the destination of the elements copied from ICollection. The Array must have zero-based indexing. + /// The zero-based index in array at which copying begins. + void ICollection.CopyTo(Array array, int index) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + ((ICollection) sortedList).CopyTo(array, index); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Adds an element with the provided key and value to the IDictionary. + /// + /// The Object to use as the key of the element to add. + /// The Object to use as the value of the element to add. + void IDictionary.Add(object key, object value) + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + ((IDictionary) sortedList).Add(key, value); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Determines whether the IDictionary contains an element with the specified key. + /// + /// The key to locate in the IDictionary. + /// true if the IDictionary contains an element with the key; otherwise, false. + bool IDictionary.Contains(object key) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return ((IDictionary) sortedList).Contains(key); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Returns an IDictionaryEnumerator for the IDictionary. + /// + /// An IDictionaryEnumerator for the IDictionary. + IDictionaryEnumerator IDictionary.GetEnumerator() + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + SortedList newSortedList = new SortedList(sortedList); + return ((IDictionary) newSortedList).GetEnumerator(); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Removes the element with the specified key from the IDictionary. + /// + /// The key of the element to remove. + void IDictionary.Remove(object key) + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + ((IDictionary) sortedList).Remove(key); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Returns an enumerator that iterates through a collection. + /// + /// An IEnumerator that can be used to iterate through the collection. + IEnumerator IEnumerable.GetEnumerator() + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + SortedList newSortedList = new SortedList(sortedList); + return ((IEnumerable) newSortedList).GetEnumerator(); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Gets a value indicating whether the ICollection is read-only. + /// + bool ICollection>.IsReadOnly + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return ((ICollection>) sortedList).IsReadOnly; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + } + + /// + /// Gets an ICollection containing the keys of the IDictionary. + /// + ICollection IDictionary.Keys + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + SortedList newSortedList = new SortedList(sortedList); + return ((IDictionary) newSortedList).Keys; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + } + + /// + /// Gets an ICollection containing the values of the IDictionary. + /// + ICollection IDictionary.Values + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + SortedList newSortedList = new SortedList(sortedList); + return ((IDictionary) newSortedList).Values; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + } + + /// + /// Gets a value indicating whether access to the ICollection is synchronized (thread safe). + /// + bool ICollection.IsSynchronized + { + get { return true; } + } + + /// + /// Gets an object that can be used to synchronize access to the ICollection. + /// + object ICollection.SyncRoot + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return ((ICollection) sortedList).SyncRoot; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + } + + /// + /// Gets a value indicating whether the IDictionary has a fixed size. + /// + bool IDictionary.IsFixedSize + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return ((IDictionary) sortedList).IsFixedSize; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + } + + /// + /// Gets a value indicating whether the IDictionary is read-only. + /// + bool IDictionary.IsReadOnly + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return ((IDictionary) sortedList).IsReadOnly; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + } + + /// + /// Gets or sets the element with the specified key. + /// + /// The key of the element to get or set. + /// The element with the specified key, or a null reference (Nothing in Visual Basic) if key is not in the dictionary or key is of a type that is not assignable to the key type TKey of the SortedList. + object IDictionary.this[object key] + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + SortedList newSortedList = new SortedList(sortedList); + return ((IDictionary) newSortedList)[key]; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + set + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + SortedList newSortedList = new SortedList(sortedList); + ((IDictionary) newSortedList)[key] = value; + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + } + + /// + /// Gets an ICollection containing the keys of the IDictionary. + /// + ICollection IDictionary.Keys + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + SortedList newSortedList = new SortedList(sortedList); + return ((IDictionary) newSortedList).Keys; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + } + + /// + /// Gets an ICollection containing the values in the IDictionary. + /// + ICollection IDictionary.Values + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + SortedList newSortedList = new SortedList(sortedList); + return ((IDictionary) newSortedList).Values; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + } + #endregion + } +} diff --git a/src/Kalman/Collections/SynchronizedStack.cs b/src/Kalman/Collections/SynchronizedStack.cs new file mode 100644 index 0000000..6b7fc33 --- /dev/null +++ b/src/Kalman/Collections/SynchronizedStack.cs @@ -0,0 +1,291 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Runtime.Serialization; +using System.Threading; + +namespace Kalman.Collections +{ + /// + /// Represents a variable size last-in-first-out (LIFO) collection of instances of the same arbitrary type. + /// + /// Specifies the type of elements in the stack. + public class SynchronizedStack : IEnumerable, ICollection, IEnumerable + { + private ReaderWriterLock rwLock; + private Stack stack; + + #region Constructors + /// + /// Initializes a new instance of the Stack class that is empty and has the default initial capacity. + /// + public SynchronizedStack() + { + rwLock = new ReaderWriterLock(); + stack = new Stack(); + } + + /// + /// Initializes a new instance of the Stack class that contains elements copied from the specified collection and has sufficient capacity to accommodate the number of elements copied. + /// + /// The collection to copy elements from. + public SynchronizedStack(IEnumerable collection) + { + rwLock = new ReaderWriterLock(); + stack = new Stack(collection); + } + + /// + /// Initializes a new instance of the Stack class that is empty and has the specified initial capacity or the default initial capacity, whichever is greater. + /// + /// The initial number of elements that the Stack can contain. + public SynchronizedStack(int capacity) + { + rwLock = new ReaderWriterLock(); + stack = new Stack(capacity); + } + #endregion + + #region Public Properties + /// + /// Gets the number of elements contained in the Stack. + /// + public int Count + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return stack.Count; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + } + #endregion + + #region Public Methods + /// + /// Removes all objects from the Stack. + /// + public void Clear() + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + stack.Clear(); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Determines whether an element is in the Stack. + /// + /// The object to locate in the Stack. The value can be a null reference (Nothing in Visual Basic) for reference types. + /// true if item is found in the Stack; otherwise, false. + public bool Contains(T item) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return stack.Contains(item); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Copies the Stack to an existing one-dimensional Array, starting at the specified array index. + /// + /// The one-dimensional Array that is the destination of the elements copied from Stack. The Array must have zero-based indexing. + /// The zero-based index in array at which copying begins. + public void CopyTo(T[] array, int arrayIndex) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + stack.CopyTo(array, arrayIndex); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Returns an enumerator for the Stack. + /// + /// An Stack.Enumerator for the Stack. + public IEnumerator GetEnumerator() + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + Stack newStack = new Stack(stack); + return newStack.GetEnumerator(); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Returns the object at the top of the Stack without removing it. + /// + /// The object at the top of the Stack. + public T Peek() + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return stack.Peek(); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Removes and returns the object at the top of the Stack. + /// + /// The object removed from the top of the Stack. + public T Pop() + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + return stack.Pop(); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Inserts an object at the top of the Stack. + /// + /// The object to push onto the Stack. The value can be a null reference (Nothing in Visual Basic) for reference types. + public void Push(T item) + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + stack.Push(item); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + + /// + /// Copies the Stack to a new array. + /// + /// A new array containing copies of the elements of the Stack. + public T[] ToArray() + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return stack.ToArray(); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Sets the capacity to the actual number of elements in the Stack, if that number is less than 90 percent of current capacity. + /// + public void TrimExcess() + { + try + { + rwLock.AcquireWriterLock(Timeout.Infinite); + stack.TrimExcess(); + } + finally + { + rwLock.ReleaseWriterLock(); + } + } + #endregion + + #region Explicit Interface Implementations + /// + /// Returns an enumerator that iterates through the collection. + /// + /// An IEnumerator that can be used to iterate through the collection. + IEnumerator IEnumerable.GetEnumerator() + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + Stack newStack = new Stack(stack); + return newStack.GetEnumerator(); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Copies the elements of the ICollection to an Array, starting at a particular Array index. + /// + /// The one-dimensional Array that is the destination of the elements copied from ICollection. The Array must have zero-based indexing. + /// The zero-based index in array at which copying begins. + void ICollection.CopyTo(Array array, int index) + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + ((ICollection) stack).CopyTo(array, index); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + + /// + /// Gets a value indicating whether access to the ICollection is synchronized (thread safe). + /// + bool ICollection.IsSynchronized + { + get { return true; } + } + + /// + /// Gets an object that can be used to synchronize access to the ICollection. + /// + object ICollection.SyncRoot + { + get + { + try + { + rwLock.AcquireReaderLock(Timeout.Infinite); + return ((ICollection) stack).SyncRoot; + } + finally + { + rwLock.ReleaseReaderLock(); + } + } + } + #endregion + } +} diff --git a/src/Kalman/Command/CmdHelper.cs b/src/Kalman/Command/CmdHelper.cs new file mode 100644 index 0000000..7751915 --- /dev/null +++ b/src/Kalman/Command/CmdHelper.cs @@ -0,0 +1,121 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Diagnostics; + +namespace Kalman.Command +{ + /// + /// а + /// + public class CmdHelper + { + /// + /// cmd.exeִһ + /// + /// + /// + public static string Execute(string cmdText) + { + return Execute(new string[] { cmdText }); + } + + /// + /// cmd.exeִж + /// + /// + /// + public static string Execute(string[] cmdTexts) + { + Process p = new Process(); + p.StartInfo.FileName = "cmd.exe"; + p.StartInfo.UseShellExecute = false; + p.StartInfo.RedirectStandardInput = true; + p.StartInfo.RedirectStandardOutput = true; + p.StartInfo.RedirectStandardError = true; + p.StartInfo.CreateNoWindow = true; + string output = null; + try + { + p.Start(); + + foreach (string item in cmdTexts) + { + p.StandardInput.WriteLine(item); + } + + p.StandardInput.WriteLine("exit"); + output = p.StandardOutput.ReadToEnd(); + //strOutput = Encoding.UTF8.GetString(Encoding.Default.GetBytes(strOutput)); + p.WaitForExit(); + p.Close(); + } + catch (Exception e) + { + output = e.Message; + } + + return output; + } + + /// + /// ⲿWindowsӦóس + /// + /// Ӧó + /// + public static bool RunApp(string appName) + { + return RunApp(appName, ProcessWindowStyle.Hidden); + } + + /// + /// ⲿӦó + /// + /// Ӧó + /// Ӧóʱʾʽ + /// + public static bool RunApp(string appName, ProcessWindowStyle style) + { + return RunApp(appName, null, style); + } + + /// + /// ⲿӦóس + /// + /// Ӧó + /// + /// + public static bool RunApp(string appName, string args) + { + return RunApp(appName, args, ProcessWindowStyle.Hidden); + } + + /// + /// ⲿӦó + /// + /// Ӧó + /// + /// Ӧóʱʾʽ + /// + public static bool RunApp(string appName, string args, ProcessWindowStyle style) + { + bool flag = false; + + Process p = new Process(); + p.StartInfo.FileName = appName;//exe,bat and so on + p.StartInfo.WindowStyle = style; + p.StartInfo.Arguments = args; + try + { + p.Start(); + p.WaitForExit(); + p.Close(); + flag = true; + } + catch + { + } + return flag; + } + } +} diff --git a/src/Kalman/Command/WinrarHelper.cs b/src/Kalman/Command/WinrarHelper.cs new file mode 100644 index 0000000..f42b074 --- /dev/null +++ b/src/Kalman/Command/WinrarHelper.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace Kalman.Command +{ + /// + /// WinrarDosйrar.exeѹѹİ + /// + public class WinrarHelper + { + string _RarExePath = string.Empty; + + /// + /// + /// + /// + public WinrarHelper(string rarExePath) + { + _RarExePath = rarExePath; + } + + /// + /// rar.exeѹļ + /// + /// Դ·ļļ· + /// Ŀ·ѹѹļ· + public void Zip(string srcPath, string targetPath) + { + string cmdLine = string.Format("a \"{0}\" \"{1}\" -ep1", targetPath, srcPath); + Rar(cmdLine); + } + + /// + /// ѹļ + /// + /// ļ· + /// + public void Zip(string[] srcFiles, string targetPath) + { + string tmpLstFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tmp.lst"); + StringBuilder sb = new StringBuilder(); + foreach (string s in srcFiles) + { + sb.Append(s); + sb.Append("\r\n"); + } + File.AppendAllText(tmpLstFile, sb.ToString()); + + string cmdLine = string.Format("a \"{0}\" \"@{1}\"", targetPath, tmpLstFile); + Rar(cmdLine); + + File.Delete(tmpLstFile); + } + + /// + /// rar.exeѹļĿļ + /// + /// Ҫѹѹļ· + /// ѹĿļ· + public void Unzip(string srcPath, string targetPath) + { + string cmdLine = string.Format("x \"{0}\" \"{1}\" -o+", srcPath, targetPath); + Rar(cmdLine); + } + + /// + /// rar.exeѹѹִԶѹѹ + /// + /// Уrar.exe· + public void Rar(string cmdLine) + { + cmdLine = string.Format("\"{0}\" {1}", _RarExePath, cmdLine); + CmdHelper.Execute(cmdLine); + } + } +} diff --git a/src/Kalman/Config/ConfigBase.cs b/src/Kalman/Config/ConfigBase.cs new file mode 100644 index 0000000..14f9934 --- /dev/null +++ b/src/Kalman/Config/ConfigBase.cs @@ -0,0 +1,198 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Xml; +using System.Configuration; +using System.Collections.Specialized; + +namespace Kalman +{ + /// + /// û + /// + public abstract class ConfigBase + { + /// + /// ȡԣstringͣ + /// + public string GetStringAttribute(XmlNode node, string key, string defaultValue) + { + XmlAttributeCollection attributes = node.Attributes; + if (attributes[key] != null && !string.IsNullOrEmpty(attributes[key].Value)) + return attributes[key].Value; + return defaultValue; + } + + /// + /// ȡԣstringͣĬֵstring.Empty + /// + public string GetStringAttribute(XmlNode node, string key) + { + return GetStringAttribute(node,key,string.Empty); + } + + /// + /// ȡԣintͣ + /// + public int GetIntAttribute(XmlNode node, string key, int defaultValue) + { + int val = defaultValue; + XmlAttributeCollection attributes = node.Attributes; + + if (attributes[key] != null && !string.IsNullOrEmpty(attributes[key].Value)) + { + int.TryParse(attributes[key].Value, out val); + } + return val; + } + + /// + /// ȡԣboolͣ + /// + public bool GetBoolAttribute(XmlNode node, string key, bool defaultValue) + { + bool val = defaultValue; + XmlAttributeCollection attributes = node.Attributes; + + if (attributes[key] != null && !string.IsNullOrEmpty(attributes[key].Value)) + { + bool.TryParse(attributes[key].Value, out val); + } + return val; + } + + /// + /// ýڵȡֵ + /// + /// ǷΪǿ + /// + public string GetAttribute(XmlNode node, string key, bool isMandatory) + { + string errMsg = string.Format("ýڵ[{0}][{1}]", node.Name, key); + + if (node.Attributes == null) + throw new ConfigurationErrorsException(errMsg); + + XmlAttribute attribute = node.Attributes[key]; + if (attribute == null && isMandatory) + throw new ConfigurationErrorsException(errMsg); + + return attribute == null ? null : attribute.InnerText; + } + + /// + /// ýڵȡֵ + /// + /// + /// + /// ýڵֵΪkeyûã򷵻һĬֵ + /// ýڵֵΪkeyֵ + public string GetAttribute(XmlNode node, string key, string defaultValue) + { + if (node.Attributes.Count == 0)return defaultValue; + + XmlAttribute attribute = node.Attributes[key]; + if (attribute == null)return defaultValue; + + return attribute.InnerText; + } + + /// + /// + /// + protected Dictionary LoadModules(XmlNode node) + { + Dictionary modules = new Dictionary(); + + if (node != null) + { + foreach (XmlNode n in node.ChildNodes) + { + if (n.NodeType != XmlNodeType.Comment) + { + switch (n.Name) + { + case "clear": + modules.Clear(); + break; + case "remove": + XmlAttribute removeNameAtt = n.Attributes["name"]; + string removeName = removeNameAtt == null ? null : removeNameAtt.Value; + + if (!string.IsNullOrEmpty(removeName) && modules.ContainsKey(removeName)) + { + modules.Remove(removeName); + } + + break; + case "add": + + XmlAttribute en = n.Attributes["enabled"]; + if (en != null && en.Value == "false") + continue; + + XmlAttribute nameAtt = n.Attributes["name"]; + XmlAttribute typeAtt = n.Attributes["type"]; + string name = nameAtt == null ? null : nameAtt.Value; + string itype = typeAtt == null ? null : typeAtt.Value; + + if (string.IsNullOrEmpty(name)) + { + continue; + } + + if (string.IsNullOrEmpty(itype)) + { + continue; + } + + Type type = Type.GetType(itype); + + if (type == null) + { + continue; + } + + T mod = default(T); + + try + { + mod = (T)Activator.CreateInstance(type); + } + catch { + //todo: log + } + + if (mod == null) + { + continue; + } + + modules.Add(name, mod); + break; + + } + } + } + } + return modules; + } + + /// + /// ýڵתNameValueCollection + /// + /// ýڵ + /// + protected NameValueCollection XmlNode2NameValueCollection(XmlNode node) + { + NameValueCollection nvc = new NameValueCollection(); + + foreach (XmlNode item in node) + { + nvc.Add(item.Name, item.InnerXml); + } + + return nvc; + } + } +} diff --git a/src/Kalman/Config/ConfigHandler.cs b/src/Kalman/Config/ConfigHandler.cs new file mode 100644 index 0000000..2013fc6 --- /dev/null +++ b/src/Kalman/Config/ConfigHandler.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Configuration; + +namespace Kalman +{ + /// + /// Kalman框架组件通用配置处理类,返回配置节XML字符串给具体的组件配置类解析 + /// + public class ConfigHandler : IConfigurationSectionHandler + { + #region IConfigurationSectionHandler 成员 + + public object Create(object parent, object configContext, System.Xml.XmlNode section) + { + return section; + } + + #endregion + } +} diff --git a/src/Kalman/Data/CachingMechanism.cs b/src/Kalman/Data/CachingMechanism.cs new file mode 100644 index 0000000..b0c929e --- /dev/null +++ b/src/Kalman/Data/CachingMechanism.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections; +using System.Data; + +namespace Kalman.Data +{ + /// + /// CachingMechanism provides caching support for stored procedure + /// parameter discovery and caching + /// + internal class CachingMechanism + { + private Hashtable paramCache = Hashtable.Synchronized(new Hashtable()); + + /// + /// Create and return a copy of the IDataParameter array. + /// + public static IDataParameter[] CloneParameters(IDataParameter[] originalParameters) + { + IDataParameter[] clonedParameters = new IDataParameter[originalParameters.Length]; + + for (int i = 0, j = originalParameters.Length; i < j; i++) + { + clonedParameters[i] = (IDataParameter)((ICloneable)originalParameters[i]).Clone(); + } + + return clonedParameters; + } + + /// + /// Empties all items from the cache + /// + public void Clear() + { + this.paramCache.Clear(); + } + + /// + /// Add a parameter array to the cache for the command. + /// + public void AddParameterSetToCache(string connectionString, IDbCommand command, IDataParameter[] parameters) + { + string storedProcedure = command.CommandText; + string key = CreateHashKey(connectionString, storedProcedure); + this.paramCache[key] = parameters; + } + + /// + /// Gets a parameter array from the cache for the command. Returns null if no parameters are found. + /// + public IDataParameter[] GetCachedParameterSet(string connectionString, IDbCommand command) + { + string storedProcedure = command.CommandText; + string key = CreateHashKey(connectionString, storedProcedure); + IDataParameter[] cachedParameters = (IDataParameter[])(this.paramCache[key]); + return CloneParameters(cachedParameters); + } + + /// + /// Gets if a given stored procedure on a specific connection string has a cached parameter set + /// + public bool IsParameterSetCached(string connectionString, IDbCommand command) + { + string hashKey = CreateHashKey( + connectionString, + command.CommandText); + return this.paramCache[hashKey] != null; + } + + private static string CreateHashKey(string connectionString, string storedProcedure) + { + return connectionString + ":" + storedProcedure; + } + } +} diff --git a/src/Kalman/Data/Common/DataReaderWrapper.cs b/src/Kalman/Data/Common/DataReaderWrapper.cs new file mode 100644 index 0000000..ef747fd --- /dev/null +++ b/src/Kalman/Data/Common/DataReaderWrapper.cs @@ -0,0 +1,125 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Data; +using System.Data.Common; +using System.Globalization; + +namespace Kalman.Data +{ + /// + /// DataReader包装器,解决BindableEntity绑定DataReader时,实体属性名称在DataReader中不存在时引发的索引超出范围异常问题 + /// + public class DataReaderWrapper : IDisposable + { + public static DataReaderWrapper New(IDataReader iReader) + { + return new DataReaderWrapper(iReader); + } + + private IDataReader _InnerReader; + public IDataReader InnerReader + { + get { return _InnerReader; } + } + + private DataReaderWrapper(IDataReader reader) + { + _InnerReader = reader; + + _InnerReadMetaData(); + } + + #region IDataReader 成员 + + private int _FieldCount = 0; + public int FieldCount + { + get { return _FieldCount; } + } + + public void Close() + { + InnerReader.Close(); + } + + public bool Read() + { + return InnerReader.Read(); + } + + /// + /// 如果不存在,则返回Null + /// + public object this[string name] + { + get + { + int i = IndexOf(name); + + if (i < 0) + return null; + else + return InnerReader[i]; + } + } + + public object this[int i] + { + get { return InnerReader[i]; } + } + + #endregion + + #region IDataReader Ex 成员 + + private string[] _MetaData; + internal string[] MetaData + { + get + { + return _MetaData; + } + } + + private void _InnerReadMetaData() + { + int count = InnerReader.FieldCount; + _MetaData = new string[count]; + _FieldCount = InnerReader.FieldCount; + + for (int i = 0; i < count; i++) + _MetaData[i] = InnerReader.GetName(i); + } + + private static CompareInfo compare = CultureInfo.InvariantCulture.CompareInfo; + public int IndexOf(string name) + { + for (int i = 0; i < FieldCount; i++) + { + if (compare.Compare(MetaData[i], name, CompareOptions.OrdinalIgnoreCase) == 0) + return i; + } + + return -1; + } + + public string GetName(int index) + { + return InnerReader.GetName(index); + } + + #endregion + + + #region IDisposable 成员 + + public void Dispose() + { + InnerReader.Dispose(); + _MetaData = null; + } + + #endregion + } +} diff --git a/src/Kalman/Data/DataType.cs b/src/Kalman/Data/DataType.cs new file mode 100644 index 0000000..222a21a --- /dev/null +++ b/src/Kalman/Data/DataType.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Kalman.Data +{ + /// + /// 数据类型(将数据类型分文本、数字、日期时间、布尔四类) + /// + public enum DataType + { + /// + /// 文本 + /// + Text = 1, + /// + /// 数字 + /// + NUM = 2, + /// + /// 日期时间 + /// + Time = 3, + /// + /// 布尔 + /// + Bool = 4 + } +} diff --git a/src/Kalman/Data/Database.cs b/src/Kalman/Data/Database.cs new file mode 100644 index 0000000..eb8868a --- /dev/null +++ b/src/Kalman/Data/Database.cs @@ -0,0 +1,1141 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Data.Common; +using System.Data; +using System.Data.SqlClient; +using System.Data.OleDb; +using System.Globalization; +using System.Transactions; +using Kalman.Utilities; +using Kalman.Data.DbSchemaProvider; +using Kalman.Data.SchemaObject; +using Kalman.Mapping; +using Kalman.Extensions; + +namespace Kalman.Data +{ + /// + /// 抽象数据库类 + /// + public abstract class Database + { + #region Property&Field + //参数缓存 + static readonly ParameterCache parameterCache = new ParameterCache(); + + /// + /// 数据库架构 + /// + //public abstract SODatabase Schema { get; } + + DbProviderFactory _DbProviderFactory; + /// + /// 获取数据提供程序工厂实例 + /// + public DbProviderFactory DbProviderFactory + { + get { return _DbProviderFactory; } + } + + /// + /// 获取数据库类型 + /// + public abstract DatabaseType DatabaseType { get; } + + string _ConnectionString; + /// + /// 连接字符串 + /// + public string ConnectionString + { + get { return _ConnectionString; } + } + + /// + /// 获取或设置已切换的当前数据库名称 + /// + public string CurrentDatabaseName { get; set; } + #endregion + + #region constructor + /// + /// 构造函数,默认使用Sql Server数据提供程序 + /// + /// + public Database(string connectionString) + : this(connectionString, SqlClientFactory.Instance) + { + } + + /// + /// 构造函数,指定数据提供程序工厂实例 + /// + /// + /// + public Database(string connectionString, DbProviderFactory dbProviderFactory) + { + CheckUtil.ArgumentNotNullOrEmpty(connectionString, "connectionString"); + CheckUtil.ArgumentNotNull(dbProviderFactory, "dbProviderFactory"); + + this._ConnectionString = connectionString; + this._DbProviderFactory = dbProviderFactory; + } + + /// + /// 构造函数,指定数据提供程序固定名称,用于创建数据提供程序工厂实例 + /// + /// 数据提供程序固定名称,用来标志和调用数据提供程序 + /// + public Database(string providerInvariantName, string connectionString) + { + this._DbProviderFactory = DbProviderFactories.GetFactory(providerInvariantName); + this._ConnectionString = connectionString; + } + + /// + /// + /// + /// 数据提供程序名称 + /// 数据提供程序说明 + /// 数据提供程序固定名称,用来标志和调用数据提供程序 + /// 数据提供程序所属程序集的限定名,如 + /// 数据库连接字符串 + public Database(string name, string description, string invariantName, string assemblyQualifiedName, string connectionString) + { + DataRow providerRow; + DataTable dt = DbProviderFactories.GetFactoryClasses(); //获取已安装数据提供程序列表 + providerRow = dt.Rows.Find(invariantName); + + //若指定的数据提供程序没有安装,则向已安装数据提供程序列表增加一条该数据提供程序的安装信息 + if (providerRow == null) + { + providerRow = dt.NewRow(); + providerRow[0] = name; + providerRow[1] = description; + providerRow[2] = invariantName; + providerRow[3] = assemblyQualifiedName; + + dt.Rows.Add(providerRow); + } + + this._DbProviderFactory = DbProviderFactories.GetFactory(invariantName); + this._ConnectionString = connectionString; + } + #endregion + + #region Add Parameter Method + public void AddInParameter(DbCommand command, string name, DbType dbType) + { + AddParameter(command, name, dbType, ParameterDirection.Input, String.Empty, DataRowVersion.Default, null); + } + public void AddInParameter(DbCommand command, string name, DbType dbType, object value) + { + AddParameter(command, name, dbType, ParameterDirection.Input, String.Empty, DataRowVersion.Default, value); + } + public void AddInParameter(DbCommand command, string name, DbType dbType, string sourceColumn, DataRowVersion sourceVersion) + { + AddParameter(command, name, dbType, 0, ParameterDirection.Input, true, 0, 0, sourceColumn, sourceVersion, null); + } + public void AddOutParameter(DbCommand command, string name, DbType dbType, int size) + { + AddParameter(command, name, dbType, size, ParameterDirection.Output, true, 0, 0, String.Empty, DataRowVersion.Default, DBNull.Value); + } + public virtual void AddParameter(DbCommand command, string name, DbType dbType, int size, ParameterDirection direction, bool nullable, byte precision, byte scale, string sourceColumn, DataRowVersion sourceVersion, object value) + { + //每个子类需要重写该方法,提供不同数据库提供程序所定义的DbType,比如Sql Server的SqlDbType,否则可能出现性能上的问题 + DbParameter parameter = CreateParameter(name, dbType, size, direction, nullable, precision, scale, sourceColumn, sourceVersion, value); + command.Parameters.Add(parameter); + } + public void AddParameter(DbCommand command, string name, DbType dbType, ParameterDirection direction, string sourceColumn, DataRowVersion sourceVersion, object value) + { + AddParameter(command, name, dbType, 0, direction, false, 0, 0, sourceColumn, sourceVersion, value); + } + #endregion + + void AssignParameterValues(DbCommand command, object[] values) + { + int parameterIndexShift = UserParametersStartIndex(); // DONE magic number, depends on the database + for (int i = 0; i < values.Length; i++) + { + IDataParameter parameter = command.Parameters[i + parameterIndexShift]; + SetParameterValue(command, parameter.ParameterName, values[i]); + } + } + + static DbTransaction BeginTransaction(DbConnection connection) + { + DbTransaction tran = connection.BeginTransaction(); + return tran; + } + + /// + /// 为当前数据库生成一个带前缀的参数名 + /// + /// 不带前缀的参数名 + public virtual string BuildParameterName(string name) + { + //子类需要重写该方法,每个数据库的参数前缀可能不同 + return name; + } + + public static void ClearParameterCache() + { + parameterCache.Clear(); + } + + static void CommitTransaction(IDbTransaction tran) + { + tran.Commit(); + } + + protected virtual void ConfigureParameter(DbParameter param, + string name, + DbType dbType, + int size, + ParameterDirection direction, + bool nullable, + byte precision, + byte scale, + string sourceColumn, + DataRowVersion sourceVersion, + object value) + { + param.DbType = dbType; + param.Size = size; + param.Value = value ?? DBNull.Value; + param.Direction = direction; + param.IsNullable = nullable; + param.SourceColumn = sourceColumn; + param.SourceVersion = sourceVersion; + } + + DbCommand CreateCommandByCommandType(CommandType commandType, string commandText) + { + DbCommand command = _DbProviderFactory.CreateCommand(); + command.CommandType = commandType; + command.CommandText = commandText; + + return command; + } + + public virtual DbConnection CreateConnection() + { + DbConnection newConnection = _DbProviderFactory.CreateConnection(); + newConnection.ConnectionString = ConnectionString; + + return newConnection; + } + + protected DbParameter CreateParameter(string name, + DbType dbType, + int size, + ParameterDirection direction, + bool nullable, + byte precision, + byte scale, + string sourceColumn, + DataRowVersion sourceVersion, + object value) + { + DbParameter param = CreateParameter(name); + ConfigureParameter(param, name, dbType, size, direction, nullable, precision, scale, sourceColumn, sourceVersion, value); + return param; + } + + protected DbParameter CreateParameter(string name) + { + DbParameter param = _DbProviderFactory.CreateParameter(); + param.ParameterName = BuildParameterName(name); + + return param; + } + + protected abstract void DeriveParameters(DbCommand discoveryCommand); + + public void DiscoverParameters(DbCommand command) + { + using (ConnectionWrapper wrapper = GetOpenConnection()) + { + using (DbCommand discoveryCommand = CreateCommandByCommandType(command.CommandType, command.CommandText)) + { + discoveryCommand.Connection = wrapper.Connection; + DeriveParameters(discoveryCommand); + + foreach (IDataParameter parameter in discoveryCommand.Parameters) + { + IDataParameter cloneParameter = (IDataParameter)((ICloneable)parameter).Clone(); + command.Parameters.Add(cloneParameter); + } + } + } + } + + protected int DoExecuteNonQuery(DbCommand command) + { + try + { + //DateTime startTime = DateTime.Now; + int rowsAffected = command.ExecuteNonQuery(); + //instrumentationProvider.FireCommandExecutedEvent(startTime); + return rowsAffected; + } + catch (Exception) + { + //instrumentationProvider.FireCommandFailedEvent(command.CommandText, ConnectionStringNoCredentials, e); + throw; + } + } + + IDataReader DoExecuteReader(DbCommand command, CommandBehavior cmdBehavior) + { + try + { + //DateTime startTime = DateTime.Now; + IDataReader reader = command.ExecuteReader(cmdBehavior); + //instrumentationProvider.FireCommandExecutedEvent(startTime); + return reader; + } + catch (Exception) + { + //instrumentationProvider.FireCommandFailedEvent(command.CommandText, ConnectionStringNoCredentials, e); + throw; + } + } + + object DoExecuteScalar(IDbCommand command) + { + try + { + //DateTime startTime = DateTime.Now; + object returnValue = command.ExecuteScalar(); + //instrumentationProvider.FireCommandExecutedEvent(startTime); + return returnValue; + } + catch (Exception) + { + //instrumentationProvider.FireCommandFailedEvent(command.CommandText, ConnectionStringNoCredentials, e); + throw; + } + } + + void DoLoadDataSet(IDbCommand command, DataSet dataSet, string[] tableNames) + { + CheckUtil.ArgumentNotNullOrEmptyForCollection(tableNames, "tableNames"); + + for (int i = 0; i < tableNames.Length; i++) + { + CheckUtil.ArgumentNotNullOrEmpty(tableNames[i], string.Concat("tableNames[", i, "]")); + //if (string.IsNullOrEmpty(tableNames[i])) throw new ArgumentException("值不能为空或者空字符串", string.Concat("tableNames[", i, "]")); + } + + try + { + using (DbDataAdapter adapter = GetDataAdapter(UpdateBehavior.Standard)) + { + ((IDbDataAdapter)adapter).SelectCommand = command; + + //DateTime startTime = DateTime.Now; + string systemCreatedTableNameRoot = "Table"; + for (int i = 0; i < tableNames.Length; i++) + { + string systemCreatedTableName = (i == 0) ? systemCreatedTableNameRoot : systemCreatedTableNameRoot + i; + + adapter.TableMappings.Add(systemCreatedTableName, tableNames[i]); + } + + adapter.Fill(dataSet); + //instrumentationProvider.FireCommandExecutedEvent(startTime); + } + } + catch (Exception) + { + throw; + //instrumentationProvider.FireCommandFailedEvent(command.CommandText, ConnectionStringNoCredentials, e); + } + } + + int DoUpdateDataSet(UpdateBehavior behavior, DataSet dataSet, string tableName, IDbCommand insertCommand, IDbCommand updateCommand, IDbCommand deleteCommand, int? updateBatchSize) + { + CheckUtil.ArgumentNotNullOrEmpty(tableName, "tableName"); + CheckUtil.ArgumentNotNull(dataSet, "dataSet"); + + if (insertCommand == null && updateCommand == null && deleteCommand == null) + { + throw new ArgumentException(Resources.Data.MustInitAtLeastOneCommand); + } + + using (DbDataAdapter adapter = GetDataAdapter(behavior)) + { + IDbDataAdapter explicitAdapter = adapter; + if (insertCommand != null) + { + explicitAdapter.InsertCommand = insertCommand; + } + if (updateCommand != null) + { + explicitAdapter.UpdateCommand = updateCommand; + } + if (deleteCommand != null) + { + explicitAdapter.DeleteCommand = deleteCommand; + } + + if (updateBatchSize != null) + { + adapter.UpdateBatchSize = (int)updateBatchSize; + if (insertCommand != null) + adapter.InsertCommand.UpdatedRowSource = UpdateRowSource.None; + if (updateCommand != null) + adapter.UpdateCommand.UpdatedRowSource = UpdateRowSource.None; + if (deleteCommand != null) + adapter.DeleteCommand.UpdatedRowSource = UpdateRowSource.None; + } + + try + { + //DateTime startTime = DateTime.Now; + int rows = adapter.Update(dataSet.Tables[tableName]); + //instrumentationProvider.FireCommandExecutedEvent(startTime); + return rows; + } + catch (Exception) + { + //instrumentationProvider.FireCommandFailedEvent("DbDataAdapter.Update() " + tableName, ConnectionStringNoCredentials, e); + throw; + } + } + } + + #region ExecuteDataSet + public virtual DataSet ExecuteDataSet(DbCommand command) + { + DataSet dataSet = new DataSet(); + dataSet.Locale = CultureInfo.InvariantCulture; + LoadDataSet(command, dataSet, "Table"); + return dataSet; + } + + public virtual DataSet ExecuteDataSet(DbCommand command, DbTransaction transaction) + { + DataSet dataSet = new DataSet(); + dataSet.Locale = CultureInfo.InvariantCulture; + LoadDataSet(command, dataSet, "Table", transaction); + return dataSet; + } + + public virtual DataSet ExecuteDataSet(string storedProcedureName, params object[] parameterValues) + { + using (DbCommand command = GetStoredProcCommand(storedProcedureName, parameterValues)) + { + return ExecuteDataSet(command); + } + } + + public virtual DataSet ExecuteDataSet(DbTransaction transaction, string storedProcedureName, params object[] parameterValues) + { + using (DbCommand command = GetStoredProcCommand(storedProcedureName, parameterValues)) + { + return ExecuteDataSet(command, transaction); + } + } + + public virtual DataSet ExecuteDataSet(CommandType commandType, string commandText) + { + using (DbCommand command = CreateCommandByCommandType(commandType, commandText)) + { + return ExecuteDataSet(command); + } + } + + public virtual DataSet ExecuteDataSet(DbTransaction transaction, CommandType commandType, string commandText) + { + using (DbCommand command = CreateCommandByCommandType(commandType, commandText)) + { + return ExecuteDataSet(command, transaction); + } + } + #endregion + + #region ExecuteNonQuery + public virtual int ExecuteNonQuery(DbCommand command) + { + using (ConnectionWrapper wrapper = GetOpenConnection()) + { + PrepareCommand(command, wrapper.Connection); + return DoExecuteNonQuery(command); + } + } + + public virtual int ExecuteNonQuery(DbCommand command, DbTransaction transaction) + { + PrepareCommand(command, transaction); + return DoExecuteNonQuery(command); + } + + public virtual int ExecuteNonQuery(string storedProcedureName, params object[] parameterValues) + { + using (DbCommand command = GetStoredProcCommand(storedProcedureName, parameterValues)) + { + return ExecuteNonQuery(command); + } + } + + public virtual int ExecuteNonQuery(DbTransaction transaction, string storedProcedureName, params object[] parameterValues) + { + using (DbCommand command = GetStoredProcCommand(storedProcedureName, parameterValues)) + { + return ExecuteNonQuery(command, transaction); + } + } + + public virtual int ExecuteNonQuery(CommandType commandType, string commandText) + { + using (DbCommand command = CreateCommandByCommandType(commandType, commandText)) + { + return ExecuteNonQuery(command); + } + } + + public virtual int ExecuteNonQuery(DbTransaction transaction, CommandType commandType, string commandText) + { + using (DbCommand command = CreateCommandByCommandType(commandType, commandText)) + { + return ExecuteNonQuery(command, transaction); + } + } + #endregion + + #region ExecuteReader + public virtual IDataReader ExecuteReader(DbCommand command) + { + ConnectionWrapper wrapper = GetOpenConnection(false); + + try + { + // + // JS-L: I moved the PrepareCommand inside the try because it can fail. + // + PrepareCommand(command, wrapper.Connection); + + // + // If there is a current transaction, we'll be using a shared connection, so we don't + // want to close the connection when we're done with the reader. + // + if (Transaction.Current != null) + return DoExecuteReader(command, CommandBehavior.Default); + else + return DoExecuteReader(command, CommandBehavior.CloseConnection); + } + catch + { + wrapper.Connection.Close(); + throw; + } + } + + public virtual IDataReader ExecuteReader(DbCommand command, DbTransaction transaction) + { + PrepareCommand(command, transaction); + return DoExecuteReader(command, CommandBehavior.Default); + } + + public IDataReader ExecuteReader(string storedProcedureName, params object[] parameterValues) + { + using (DbCommand command = GetStoredProcCommand(storedProcedureName, parameterValues)) + { + return ExecuteReader(command); + } + } + + public IDataReader ExecuteReader(DbTransaction transaction, string storedProcedureName, params object[] parameterValues) + { + using (DbCommand command = GetStoredProcCommand(storedProcedureName, parameterValues)) + { + return ExecuteReader(command, transaction); + } + } + + public IDataReader ExecuteReader(CommandType commandType, string commandText) + { + using (DbCommand command = CreateCommandByCommandType(commandType, commandText)) + { + return ExecuteReader(command); + } + } + + public IDataReader ExecuteReader(DbTransaction transaction, CommandType commandType, string commandText) + { + using (DbCommand command = CreateCommandByCommandType(commandType, commandText)) + { + return ExecuteReader(command, transaction); + } + } + #endregion + + #region ExecuteScalar + public virtual object ExecuteScalar(DbCommand command) + { + if (command == null) throw new ArgumentNullException("command"); + + using (ConnectionWrapper wrapper = GetOpenConnection()) + { + PrepareCommand(command, wrapper.Connection); + return DoExecuteScalar(command); + } + } + + public virtual object ExecuteScalar(DbCommand command, DbTransaction transaction) + { + PrepareCommand(command, transaction); + return DoExecuteScalar(command); + } + + public virtual object ExecuteScalar(string storedProcedureName, params object[] parameterValues) + { + using (DbCommand command = GetStoredProcCommand(storedProcedureName, parameterValues)) + { + return ExecuteScalar(command); + } + } + + public virtual object ExecuteScalar(DbTransaction transaction, string storedProcedureName, params object[] parameterValues) + { + using (DbCommand command = GetStoredProcCommand(storedProcedureName, parameterValues)) + { + return ExecuteScalar(command, transaction); + } + } + + public virtual object ExecuteScalar(CommandType commandType, string commandText) + { + using (DbCommand command = CreateCommandByCommandType(commandType, commandText)) + { + return ExecuteScalar(command); + } + } + + public virtual object ExecuteScalar(DbTransaction transaction, CommandType commandType, string commandText) + { + using (DbCommand command = CreateCommandByCommandType(commandType, commandText)) + { + return ExecuteScalar(command, transaction); + } + } + #endregion + + #region ExecuteScalar + public virtual T ExecuteScalar(DbCommand command) + { + object result = ExecuteScalar(command); + return result.ConvertType(); + } + + public virtual T ExecuteScalar(DbCommand command, DbTransaction transaction) + { + object result = ExecuteScalar(command, transaction); + return result.ConvertType(); + } + + public virtual T ExecuteScalar(string storedProcedureName, params object[] parameterValues) + { + object result = ExecuteScalar(storedProcedureName, parameterValues); + return result.ConvertType(); + } + + public virtual T ExecuteScalar(DbTransaction transaction, string storedProcedureName, params object[] parameterValues) + { + object result = ExecuteScalar(transaction, storedProcedureName, parameterValues); + return result.ConvertType(); + } + + public virtual T ExecuteScalar(CommandType commandType, string commandText) + { + object result = ExecuteScalar(commandType, commandText); + return result.ConvertType(); + } + + public virtual T ExecuteScalar(DbTransaction transaction, CommandType commandType, string commandText) + { + object result = ExecuteScalar(transaction, commandType, commandText); + return result.ConvertType(); + } + #endregion + + #region ExecuteList + public virtual List ExecuteList(DbCommand command) + { + using (DbDataReader reader = ExecuteReader(command) as DbDataReader) + { + return reader.ToObjects().ToList(); + } + } + + public virtual List ExecuteList(DbCommand command, DbTransaction transaction) + { + using (DbDataReader reader = ExecuteReader(command, transaction) as DbDataReader) + { + return reader.ToObjects().ToList(); + } + } + + public List ExecuteList(string storedProcedureName, params object[] parameterValues) + { + using (DbDataReader reader = ExecuteReader(storedProcedureName, parameterValues) as DbDataReader) + { + return reader.ToObjects().ToList(); + } + } + + public List ExecuteList(DbTransaction transaction, string storedProcedureName, params object[] parameterValues) + { + using (DbDataReader reader = ExecuteReader(transaction, storedProcedureName, parameterValues) as DbDataReader) + { + return reader.ToObjects().ToList(); + } + } + + public List ExecuteList(CommandType commandType, string commandText) + { + using (DbDataReader reader = ExecuteReader(commandType, commandText) as DbDataReader) + { + return reader.ToObjects().ToList(); + } + } + + public List ExecuteList(DbTransaction transaction, CommandType commandType, string commandText) + { + using (DbDataReader reader = ExecuteReader(transaction, commandType, commandText) as DbDataReader) + { + return reader.ToObjects().ToList(); + } + } + #endregion + + #region ExecuteObject + public virtual T ExecuteObject(DbCommand command) + { + using (DbDataReader reader = ExecuteReader(command) as DbDataReader) + { + return reader.Read() ? reader.ToObject() : default(T); + } + } + + public virtual T ExecuteObject(DbCommand command, DbTransaction transaction) + { + using (DbDataReader reader = ExecuteReader(command, transaction) as DbDataReader) + { + return reader.Read() ? reader.ToObject() : default(T); + } + } + + public T ExecuteObject(string storedProcedureName, params object[] parameterValues) + { + using (DbDataReader reader = ExecuteReader(storedProcedureName, parameterValues) as DbDataReader) + { + //return reader.ToObject(); + return reader.Read() ? reader.ToObject() : default(T); + } + } + + public T ExecuteObject(DbTransaction transaction, string storedProcedureName, params object[] parameterValues) + { + using (DbDataReader reader = ExecuteReader(transaction, storedProcedureName, parameterValues) as DbDataReader) + { + //return reader.ToObject(); + return reader.Read() ? reader.ToObject() : default(T); + } + } + + public T ExecuteObject(CommandType commandType, string commandText) + { + using (DbDataReader reader = ExecuteReader(commandType, commandText) as DbDataReader) + { + //return reader.ToObject(); + return reader.Read() ? reader.ToObject() : default(T); + } + } + + public T ExecuteObject(DbTransaction transaction, CommandType commandType, string commandText) + { + using (DbDataReader reader = ExecuteReader(transaction, commandType, commandText) as DbDataReader) + { + //return reader.ToObject(); + return reader.Read() ? reader.ToObject() : default(T); + } + } + #endregion + + /// + /// Get a DbDataAdapter with Standard update behavior. + /// + public DbDataAdapter GetDataAdapter() + { + return GetDataAdapter(UpdateBehavior.Standard); + } + + protected DbDataAdapter GetDataAdapter(UpdateBehavior updateBehavior) + { + DbDataAdapter adapter = _DbProviderFactory.CreateDataAdapter(); + + if (updateBehavior == UpdateBehavior.Continue) + { + SetUpRowUpdatedEvent(adapter); + } + return adapter; + } + + //public object GetInstrumentationEventProvider() + //{ + // return instrumentationProvider; + //} + + //所有打开新连接的操作都在这里进行 + internal DbConnection GetNewOpenConnection() + { + DbConnection connection = null; + try + { + try + { + connection = CreateConnection(); + connection.Open(); + + if (string.IsNullOrEmpty(CurrentDatabaseName) == false && !connection.GetType().Name.ToLower().Contains("oracle")) + { + connection.ChangeDatabase(this.CurrentDatabaseName); + } + } + catch (Exception) + { + //instrumentationProvider.FireConnectionFailedEvent(ConnectionStringNoCredentials, ex); + throw; + } + + //instrumentationProvider.FireConnectionOpenedEvent(); + } + catch + { + if (connection != null) + connection.Close(); + + throw; + } + + return connection; + } + + protected ConnectionWrapper GetOpenConnection() + { + return GetOpenConnection(true); + } + + protected ConnectionWrapper GetOpenConnection(bool disposeInnerConnection) + { + DbConnection connection = TransactionScopeConnections.GetConnection(this); + if (connection != null) + return new ConnectionWrapper(connection, false); + else + return new ConnectionWrapper(GetNewOpenConnection(), disposeInnerConnection); + } + + /// + /// 获取参数值 + /// + /// 包含参数的DbCommand对象 + /// 参数名称 + /// 返回当前参数的值 + public virtual object GetParameterValue(DbCommand command, string name) + { + return command.Parameters[BuildParameterName(name)].Value; + } + + #region DbCommand Getter + /// + /// 为SQL查询创建一个DbCommand对象实例 + /// + public DbCommand GetSqlStringCommand(string query) + { + CheckUtil.ArgumentNotNullOrEmpty(query, "query"); + return CreateCommandByCommandType(CommandType.Text, query); + } + + /// + /// 为指定的存储过程创建一个DbCommand对象实例 + /// + public virtual DbCommand GetStoredProcCommand(string storedProcedureName) + { + CheckUtil.ArgumentNotNullOrEmpty(storedProcedureName, "storedProcedureName"); + return CreateCommandByCommandType(CommandType.StoredProcedure, storedProcedureName); + } + + /// + /// 为指定的存储过程创建一个DbCommand对象实例 + /// + public virtual DbCommand GetStoredProcCommand(string storedProcedureName, params object[] parameterValues) + { + CheckUtil.ArgumentNotNullOrEmpty(storedProcedureName, "storedProcedureName"); + + DbCommand command = CreateCommandByCommandType(CommandType.StoredProcedure, storedProcedureName); + + parameterCache.SetParameters(command, this); + + if (SameNumberOfParametersAndValues(command, parameterValues) == false) + { + throw new InvalidOperationException(Resources.Data.ParameterMatchFailure); + } + + AssignParameterValues(command, parameterValues); + return command; + } + + public DbCommand GetStoredProcCommandWithSourceColumns(string storedProcedureName, params string[] sourceColumns) + { + CheckUtil.ArgumentNotNullOrEmpty(storedProcedureName, "storedProcedureName"); + if (sourceColumns == null) throw new ArgumentNullException("sourceColumns"); + + DbCommand dbCommand = GetStoredProcCommand(storedProcedureName); + + using (DbConnection connection = CreateConnection()) + { + dbCommand.Connection = connection; + DiscoverParameters(dbCommand); + } + + int iSourceIndex = 0; + foreach (IDataParameter dbParam in dbCommand.Parameters) + { + if ((dbParam.Direction == ParameterDirection.Input) | (dbParam.Direction == ParameterDirection.InputOutput)) + { + dbParam.SourceColumn = sourceColumns[iSourceIndex]; + iSourceIndex++; + } + } + + return dbCommand; + } + #endregion + + #region LoadDataSet + public virtual void LoadDataSet(DbCommand command, DataSet dataSet, string tableName) + { + LoadDataSet(command, dataSet, new string[] { tableName }); + } + + public virtual void LoadDataSet(DbCommand command, DataSet dataSet, string tableName, DbTransaction transaction) + { + LoadDataSet(command, dataSet, new string[] { tableName }, transaction); + } + + public virtual void LoadDataSet(DbCommand command, DataSet dataSet, string[] tableNames) + { + using (ConnectionWrapper wrapper = GetOpenConnection()) + { + PrepareCommand(command, wrapper.Connection); + DoLoadDataSet(command, dataSet, tableNames); + } + } + + public virtual void LoadDataSet(DbCommand command, DataSet dataSet, string[] tableNames, DbTransaction transaction) + { + PrepareCommand(command, transaction); + DoLoadDataSet(command, dataSet, tableNames); + } + + public virtual void LoadDataSet(string storedProcedureName, DataSet dataSet, string[] tableNames, params object[] parameterValues) + { + using (DbCommand command = GetStoredProcCommand(storedProcedureName, parameterValues)) + { + LoadDataSet(command, dataSet, tableNames); + } + } + + public virtual void LoadDataSet(DbTransaction transaction, string storedProcedureName, DataSet dataSet, string[] tableNames, params object[] parameterValues) + { + using (DbCommand command = GetStoredProcCommand(storedProcedureName, parameterValues)) + { + LoadDataSet(command, dataSet, tableNames, transaction); + } + } + + public virtual void LoadDataSet(CommandType commandType, string commandText, DataSet dataSet, string[] tableNames) + { + using (DbCommand command = CreateCommandByCommandType(commandType, commandText)) + { + LoadDataSet(command, dataSet, tableNames); + } + } + + public void LoadDataSet(DbTransaction transaction, CommandType commandType, string commandText, DataSet dataSet, string[] tableNames) + { + using (DbCommand command = CreateCommandByCommandType(commandType, commandText)) + { + LoadDataSet(command, dataSet, tableNames, transaction); + } + } + #endregion + + ///// + ///// Opens a connection. + ///// + ///// The opened connection. + //[Obsolete("Use GetOpenConnection instead.")] + //protected DbConnection OpenConnection() + //{ + // return GetNewOpenConnection(); + //} + + #region PrepareCommand + protected static void PrepareCommand(DbCommand command, DbConnection connection) + { + if (command == null) throw new ArgumentNullException("command"); + if (connection == null) throw new ArgumentNullException("connection"); + + command.Connection = connection; + } + + protected static void PrepareCommand(DbCommand command, DbTransaction transaction) + { + if (command == null) throw new ArgumentNullException("command"); + if (transaction == null) throw new ArgumentNullException("transaction"); + + PrepareCommand(command, transaction.Connection); + command.Transaction = transaction; + } + #endregion + + static void RollbackTransaction(IDbTransaction tran) + { + tran.Rollback(); + } + + /// + /// 判断DbCommand的参数个数是否与值数组的长度一致 + /// + protected virtual bool SameNumberOfParametersAndValues(DbCommand command, object[] values) + { + int numberOfParametersToStoredProcedure = command.Parameters.Count; + int numberOfValuesProvidedForStoredProcedure = values.Length; + return numberOfParametersToStoredProcedure == numberOfValuesProvidedForStoredProcedure; + } + + public virtual void SetParameterValue(DbCommand command, string parameterName, object value) + { + command.Parameters[BuildParameterName(parameterName)].Value = value ?? DBNull.Value; + } + + /// + /// Sets the RowUpdated event for the data adapter. + /// + /// The to set the event. + protected virtual void SetUpRowUpdatedEvent(DbDataAdapter adapter) { } + + #region UpdateDataSet + public int UpdateDataSet(DataSet dataSet, string tableName, DbCommand insertCommand, DbCommand updateCommand, DbCommand deleteCommand, UpdateBehavior updateBehavior, int? updateBatchSize) + { + using (ConnectionWrapper wrapper = GetOpenConnection()) + { + if (updateBehavior == UpdateBehavior.Transactional && Transaction.Current == null) + { + using (DbTransaction trans = BeginTransaction(wrapper.Connection)) + { + try + { + int rowsAffected = UpdateDataSet(dataSet, tableName, insertCommand, updateCommand, deleteCommand, trans, updateBatchSize); + CommitTransaction(trans); + return rowsAffected; + } + catch + { + RollbackTransaction(trans); + throw; + } + } + } + else + { + if (insertCommand != null) + { + PrepareCommand(insertCommand, wrapper.Connection); + } + if (updateCommand != null) + { + PrepareCommand(updateCommand, wrapper.Connection); + } + if (deleteCommand != null) + { + PrepareCommand(deleteCommand, wrapper.Connection); + } + + return DoUpdateDataSet(updateBehavior, dataSet, tableName, + insertCommand, updateCommand, deleteCommand, updateBatchSize); + } + } + } + + public int UpdateDataSet(DataSet dataSet, string tableName, DbCommand insertCommand, DbCommand updateCommand, DbCommand deleteCommand, UpdateBehavior updateBehavior) + { + return UpdateDataSet(dataSet, tableName, insertCommand, updateCommand, deleteCommand, updateBehavior, null); + } + + public int UpdateDataSet(DataSet dataSet, string tableName, DbCommand insertCommand, DbCommand updateCommand, DbCommand deleteCommand, DbTransaction transaction, int? updateBatchSize) + { + if (insertCommand != null) + { + PrepareCommand(insertCommand, transaction); + } + if (updateCommand != null) + { + PrepareCommand(updateCommand, transaction); + } + if (deleteCommand != null) + { + PrepareCommand(deleteCommand, transaction); + } + + return DoUpdateDataSet(UpdateBehavior.Transactional, dataSet, tableName, insertCommand, updateCommand, deleteCommand, updateBatchSize); + } + + public int UpdateDataSet(DataSet dataSet, string tableName, DbCommand insertCommand, DbCommand updateCommand, DbCommand deleteCommand, DbTransaction transaction) + { + return UpdateDataSet(dataSet, tableName, insertCommand, updateCommand, deleteCommand, transaction, null); + } + #endregion + + /// + /// 返回参数的开始索引,默认0 + /// + protected virtual int UserParametersStartIndex() + { + return 0; + } + + /// + /// 包装DbConnection对象的类 + /// + protected class ConnectionWrapper : IDisposable + { + readonly DbConnection connection; + readonly bool disposeConnection; + + public ConnectionWrapper(DbConnection connection, bool disposeConnection) + { + this.connection = connection; + this.disposeConnection = disposeConnection; + } + + public DbConnection Connection + { + get { return connection; } + } + + public void Dispose() + { + if (disposeConnection) + connection.Dispose(); + } + } + + } +} diff --git a/src/Kalman/Data/DatabaseFactory.cs b/src/Kalman/Data/DatabaseFactory.cs new file mode 100644 index 0000000..e9c8b57 --- /dev/null +++ b/src/Kalman/Data/DatabaseFactory.cs @@ -0,0 +1,108 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Configuration; +using Kalman.Data.DbProvider; +using Kalman.Utilities; +using System.Data.Common; +using System.Data; +using System.Data.OleDb; +using System.Reflection; + +namespace Kalman.Data +{ + /// + /// 数据库工厂 + /// + public static class DatabaseFactory + { + /// + /// 创建一个数据提供程序实例 + /// + /// + /// + public static Database Create(string connectionStringName) + { + CheckUtil.ArgumentNotNullOrEmpty(connectionStringName, "connectionStringName"); + + ConnectionStringSettings css = ConfigurationManager.ConnectionStrings[connectionStringName]; + if (css == null) throw new Exception(string.Format(Resources.Data.ConnectionStringNameNotFound, connectionStringName)); + + string connectionString = css.ConnectionString; + string providerName = css.ProviderName; + Database db = new SqlServerDatabase(connectionString); + DbProviderFactory providerFactory = null; + + if(string.IsNullOrEmpty(providerName))return db; + + //if (css.ProviderName == "System.Data.OleDb") + //{ + // providerFactory = OleDbFactory.Instance; + //} + //else + //{ + // providerFactory = DbProviderFactories.GetFactory(css.ProviderName); + //} + //if (providerFactory == null) throw new Exception(string.Format(Resources.Data.DataProviderNotFound, css.ProviderName)); + + switch (providerName) + { + //case "System.Data.SqlClient": + // break; + case "System.Data.Odbc": + db = new OdbcDatabase(connectionString); + break; + case "System.Data.OleDb": + db = new OleDbDatabase(connectionString); + break; + case "System.Data.OracleClient": + db = new OracleDatabase(connectionString); + break; + case "Oracle.ManagedDataAccess.Client": + db = new OracleDatabase(connectionString); + break; + case "Devart.Data.Oracle": //http://evget.com/zh-CN/product/954/feature.aspx http://www.devart.com/ + case "DDTek.Oracle": //http://www.datadirect.com/index.html 由于删除了版权DLL,导致该功能可能无法使用。可在QQ群:122161138中下载source_lib.zip + providerFactory = DbProviderFactories.GetFactory(providerName); + db = new OracleDatabase(connectionString, providerFactory); + break; + case "System.Data.SQLite": + providerFactory = DbProviderFactories.GetFactory(providerName); + db = new SQLiteDatabase(connectionString, providerFactory); + break; + case "MySql.Data.MySqlClient": + providerFactory = DbProviderFactories.GetFactory(providerName); + db = new MySqlDatabase(connectionString, providerFactory); + break; + case "IBM.Data.DB2": + providerFactory = DbProviderFactories.GetFactory(providerName); + db = new DB2Database(connectionString, providerFactory); + break; + case "FirebirdSql.Data.FirebirdClient": + providerFactory = DbProviderFactories.GetFactory(providerName); + db = new FirebirdDatabase(connectionString, providerFactory); + break; + default: + break; + } + + return db; + } + + public static Database Create() + { + string connectionStringName = string.Empty; + int count = ConfigurationManager.ConnectionStrings.Count; + + //machine.config默认有个名为LocalSqlServer的连接字符串 + for (int i = 0; i < count; i++) + { + connectionStringName = ConfigurationManager.ConnectionStrings[i].Name; + } + + if(connectionStringName == string.Empty) throw new Exception(Resources.Data.ConnectionStringNotConfig); + return Create(connectionStringName); + } + }//end class +} diff --git a/src/Kalman/Data/DatabaseType.cs b/src/Kalman/Data/DatabaseType.cs new file mode 100644 index 0000000..efd49fd --- /dev/null +++ b/src/Kalman/Data/DatabaseType.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Kalman.Data +{ + /// + /// 所支持的数据库类型 + /// + public enum DatabaseType + { + Odbc, + OleDb, + SqlServer, + Oracle, + MySql, + DB2, + SQLite, + Firebird, + PostgreSql + } +} diff --git a/src/Kalman/Data/DbProvider/DB2/DB2Database.cs b/src/Kalman/Data/DbProvider/DB2/DB2Database.cs new file mode 100644 index 0000000..d53d989 --- /dev/null +++ b/src/Kalman/Data/DbProvider/DB2/DB2Database.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Data.Common; +using Kalman.Data.SchemaObject; + +namespace Kalman.Data.DbProvider +{ + public class DB2Database : Database + { + #region 构造函数 + + /// + /// 构造函数,指定数据提供程序工厂实例 + /// + /// + /// + public DB2Database(string connectionString, DbProviderFactory dbProviderFactory) + : base(connectionString,dbProviderFactory) + { + } + + /// + /// 构造函数,指定数据提供程序固定名称,用于创建数据提供程序工厂实例 + /// + /// + public DB2Database(string connectionString) + : base("IBM.Data.DB2", connectionString) + { + } + + #endregion + + //public override SODatabase Schema + //{ + // get { throw new NotImplementedException(); } + //} + + public override DatabaseType DatabaseType + { + get { return DatabaseType.DB2; } + } + + protected override void DeriveParameters(System.Data.Common.DbCommand discoveryCommand) + { + throw new NotImplementedException(); + } + } +} diff --git a/src/Kalman/Data/DbProvider/Firebird/FirebirdDatabase.cs b/src/Kalman/Data/DbProvider/Firebird/FirebirdDatabase.cs new file mode 100644 index 0000000..e8678ac --- /dev/null +++ b/src/Kalman/Data/DbProvider/Firebird/FirebirdDatabase.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Data.Common; +using Kalman.Data.SchemaObject; + +namespace Kalman.Data.DbProvider +{ + public class FirebirdDatabase : Database + { + #region 构造函数 + + /// + /// 构造函数,指定数据提供程序工厂实例 + /// + /// + /// + public FirebirdDatabase(string connectionString, DbProviderFactory dbProviderFactory) + : base(connectionString,dbProviderFactory) + { + } + + /// + /// 构造函数,指定数据提供程序固定名称,用于创建数据提供程序工厂实例 + /// + /// + public FirebirdDatabase(string connectionString) + : base("FirebirdSql.Data.FirebirdClient", connectionString) + { + } + + #endregion + + //public override SODatabase Schema + //{ + // get { throw new NotImplementedException(); } + //} + + public override DatabaseType DatabaseType + { + get { return DatabaseType.Firebird; } + } + + protected override void DeriveParameters(System.Data.Common.DbCommand discoveryCommand) + { + throw new NotImplementedException(); + } + } +} diff --git a/src/Kalman/Data/DbProvider/MySql/MySqlDatabase.cs b/src/Kalman/Data/DbProvider/MySql/MySqlDatabase.cs new file mode 100644 index 0000000..8d12925 --- /dev/null +++ b/src/Kalman/Data/DbProvider/MySql/MySqlDatabase.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Data.Common; +using Kalman.Data.SchemaObject; +using System.Data.SqlClient; + +namespace Kalman.Data.DbProvider +{ + public class MySqlDatabase : Database + { + #region 构造函数 + + /// + /// 构造函数,指定数据提供程序工厂实例 + /// + /// + /// + public MySqlDatabase(string connectionString, DbProviderFactory dbProviderFactory) + : base(connectionString,dbProviderFactory) + { + } + + /// + /// 构造函数,指定数据提供程序固定名称,用于创建数据提供程序工厂实例 + /// + /// + public MySqlDatabase(string connectionString) + : base("MySql.Data.MySqlClient", connectionString) + { + } + + #endregion + + //public override SODatabase Schema + //{ + // get { throw new NotImplementedException(); } + //} + + public override DatabaseType DatabaseType + { + get { return DatabaseType.MySql; } + } + + protected override void DeriveParameters(System.Data.Common.DbCommand discoveryCommand) + { + throw new NotImplementedException(); + } + } +} diff --git a/src/Kalman/Data/DbProvider/Odbc/OdbcDatabase.cs b/src/Kalman/Data/DbProvider/Odbc/OdbcDatabase.cs new file mode 100644 index 0000000..e148b02 --- /dev/null +++ b/src/Kalman/Data/DbProvider/Odbc/OdbcDatabase.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Data.Common; +using System.Data.Odbc; +using Kalman.Data.SchemaObject; + +namespace Kalman.Data.DbProvider +{ + public class OdbcDatabase : Database + { + #region 构造函数 + + /// + /// 构造函数,指定数据提供程序工厂实例 + /// + /// + /// + public OdbcDatabase(string connectionString, DbProviderFactory dbProviderFactory) : base(connectionString,dbProviderFactory) + { + } + + /// + /// 构造函数,指定数据提供程序固定名称,用于创建数据提供程序工厂实例 + /// + /// + public OdbcDatabase(string connectionString) : base(connectionString, OdbcFactory.Instance) + { + } + + #endregion + + //public override SODatabase Schema + //{ + // get { throw new NotImplementedException(); } + //} + + public override DatabaseType DatabaseType + { + get { return DatabaseType.Odbc; } + } + + protected override void DeriveParameters(System.Data.Common.DbCommand discoveryCommand) + { + throw new NotImplementedException(); + } + } +} diff --git a/src/Kalman/Data/DbProvider/OleDb/OleDbDatabase.cs b/src/Kalman/Data/DbProvider/OleDb/OleDbDatabase.cs new file mode 100644 index 0000000..9bf7e2e --- /dev/null +++ b/src/Kalman/Data/DbProvider/OleDb/OleDbDatabase.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Data.Common; +using System.Data.OleDb; +using Kalman.Data.SchemaObject; + +namespace Kalman.Data.DbProvider +{ + public class OleDbDatabase : Database + { + #region 构造函数 + + /// + /// 构造函数,指定数据提供程序工厂实例 + /// + /// + /// + public OleDbDatabase(string connectionString, DbProviderFactory dbProviderFactory) : base(connectionString,dbProviderFactory) + { + } + + /// + /// 构造函数,指定数据提供程序固定名称,用于创建数据提供程序工厂实例 + /// + /// + public OleDbDatabase(string connectionString) : base(connectionString, OleDbFactory.Instance) + { + } + + #endregion + + //public override SODatabase Schema + //{ + // get { throw new NotImplementedException(); } + //} + + public override DatabaseType DatabaseType + { + get { return DatabaseType.OleDb; } + } + + protected override void DeriveParameters(System.Data.Common.DbCommand discoveryCommand) + { + throw new NotImplementedException(); + } + } +} diff --git a/src/Kalman/Data/DbProvider/Oracle/IOraclePackage.cs b/src/Kalman/Data/DbProvider/Oracle/IOraclePackage.cs new file mode 100644 index 0000000..428ebce --- /dev/null +++ b/src/Kalman/Data/DbProvider/Oracle/IOraclePackage.cs @@ -0,0 +1,30 @@ +namespace Kalman.Data.DbProvider +{ + /// + /// Represents the description of an oracle package mapping. + /// + /// + /// is used to specify how to transform store procedure names + /// into package qualified Oracle stored procedure names. + /// + public interface IOraclePackage + { + /// + /// When implemented by a class, gets the name of the package. + /// + /// + /// The name of the package. + /// + string Name + { get; } + + /// + /// When implemented by a class, gets the prefix for the package. + /// + /// + /// The prefix for the package. + /// + string Prefix + { get; } + } +} diff --git a/src/Kalman/Data/DbProvider/Oracle/OracleDataReaderWrapper.cs b/src/Kalman/Data/DbProvider/Oracle/OracleDataReaderWrapper.cs new file mode 100644 index 0000000..c1e4043 --- /dev/null +++ b/src/Kalman/Data/DbProvider/Oracle/OracleDataReaderWrapper.cs @@ -0,0 +1,276 @@ +using Oracle.ManagedDataAccess.Client; +using System; +using System.Collections; +using System.Data; +using System.Globalization; + +namespace Kalman.Data.DbProvider +{ + /// + /// 对OracleDataReader对象的包装 + /// + public class OracleDataReaderWrapper : MarshalByRefObject, IDataReader, IEnumerable + { + private readonly OracleDataReader innerReader; + + internal OracleDataReaderWrapper(OracleDataReader reader) + { + this.innerReader = reader; + } + + /// + /// 获取指定索引所在列的值 + /// + /// 从零开始的索引 + public object this[int index] + { + get { return InnerReader[index]; } + } + + public object this[string name] + { + get { return InnerReader[name]; } + } + + IEnumerator IEnumerable.GetEnumerator() + { + return ((IEnumerable)InnerReader).GetEnumerator(); + } + + /// + /// 释放OracleDataReader对象实例所使用的所有资源 + /// + void IDisposable.Dispose() + { + InnerReader.Dispose(); + } + + /// + /// 关闭OracleDataReader对象 + /// + public void Close() + { + InnerReader.Close(); + } + + /// + /// 返回元数据描述 + /// + public DataTable GetSchemaTable() + { + return InnerReader.GetSchemaTable(); + } + + /// + /// 使OracleDataReader前进到下一个结果 + /// + public bool NextResult() + { + return InnerReader.NextResult(); + } + + /// + /// 使OracleDataReader前进到下一条记录 + /// + /// if there are more rows; otherwise, . + public bool Read() + { + return InnerReader.Read(); + } + + /// + /// 获取一个值,该值指示当前行的嵌套深度 + /// + public int Depth + { + get { return InnerReader.Depth; } + } + + /// + /// 获取OracleDataReader对象是否关闭 + /// + public bool IsClosed + { + get { return InnerReader.IsClosed; } + } + + /// + /// 获取通过执行SQL语句插入、更新、删除的行数 + /// + public int RecordsAffected + { + get { return InnerReader.RecordsAffected; } + } + + /// + /// 返回当前行中的列数 + /// + public int FieldCount + { + get { return InnerReader.FieldCount; } + } + + public bool GetBoolean(int index) + { + return Convert.ToBoolean(InnerReader[index], CultureInfo.InvariantCulture); + } + + public byte GetByte(int index) + { + return Convert.ToByte(InnerReader[index], CultureInfo.InvariantCulture); + } + + /// + /// 从指定的列偏移量将字节流作为数组从给定的缓冲区偏移量开始读入缓冲区 + /// + /// 从零开始的列序号 + /// 行中读取操作开始位置的索引 + /// 要向其中复制数据的缓冲区 + /// 开始写操作位置的索引. + /// 要读取的字符数 + /// 读取的实际字符数 + public long GetBytes(int ordinal, long dataIndex, byte[] buffer, int bufferIndex, int length) + { + return InnerReader.GetBytes(ordinal, dataIndex, buffer, bufferIndex, length); + } + + /// + /// 获取指定列字符形式的值 + /// + public Char GetChar(int index) + { + return InnerReader.GetChar(index); + } + + /// + /// 从指定的列偏移量将字符流作为数组从给定的缓冲区偏移量开始读入缓冲区 + /// + /// 从零开始的列序号 + /// 行中读取操作开始位置的索引 + /// 要向其中复制数据的缓冲区 + /// 开始写操作位置的索引. + /// 要读取的字符数 + /// 读取的实际字符数 + public long GetChars(int index, long dataIndex, char[] buffer, int bufferIndex, int length) + { + return InnerReader.GetChars(index, dataIndex, buffer, bufferIndex, length); + } + + /// + /// 返回被请求的列序号的 System.Data.Common.DbDataReader 对象 + /// + public IDataReader GetData(int index) + { + return InnerReader.GetData(index); + } + + /// + /// 获取源数据类型的名称 + /// + public string GetDataTypeName(int index) + { + return InnerReader.GetDataTypeName(index); + } + + public DateTime GetDateTime(int ordinal_) + { + return InnerReader.GetDateTime(ordinal_); + } + + public decimal GetDecimal(int index) + { + return InnerReader.GetDecimal(index); + } + + public double GetDouble(int index) + { + return InnerReader.GetDouble(index); + } + + /// + /// 获取是对象的数据类型的 System.Type + /// + public Type GetFieldType(int index) + { + return InnerReader.GetFieldType(index); + } + + public float GetFloat(int index) + { + return InnerReader.GetFloat(index); + } + + public Guid GetGuid(int index) + { + byte[] guidBuffer = (byte[])InnerReader[index]; + return new Guid(guidBuffer); + } + + public short GetInt16(int index) + { + return Convert.ToInt16(InnerReader[index], CultureInfo.InvariantCulture); + } + + public int GetInt32(int index) + { + return InnerReader.GetInt32(index); + } + + public long GetInt64(int index) + { + return InnerReader.GetInt64(index); + } + + /// + /// 获取指定列的名称 + /// + public string GetName(int index) + { + return InnerReader.GetName(index); + } + + /// + /// 在给定列名称的情况下获取列序号 + /// + public int GetOrdinal(string index) + { + return InnerReader.GetOrdinal(index); + } + + /// + /// 获取指定列字符串形式的值 + /// + /// + /// + public string GetString(int index) + { + return InnerReader.GetString(index); + } + + public object GetValue(int index) + { + return InnerReader.GetValue(index); + } + + /// + /// 获取当前记录所有集合中的属性字段 + /// + public int GetValues(object[] values) + { + return InnerReader.GetValues(values); + } + + public bool IsDBNull(int index) + { + return InnerReader.IsDBNull(index); + } + + /// + /// 获取OracleDataReader的包装实例 + /// + public OracleDataReader InnerReader + { + get { return this.innerReader; } + } + } +} diff --git a/src/Kalman/Data/DbProvider/Oracle/OracleDatabase.cs b/src/Kalman/Data/DbProvider/Oracle/OracleDatabase.cs new file mode 100644 index 0000000..28fd6b1 --- /dev/null +++ b/src/Kalman/Data/DbProvider/Oracle/OracleDatabase.cs @@ -0,0 +1,375 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Globalization; +using Kalman.Data.DbSchemaProvider; +using Kalman.Data.SchemaObject; +using Oracle.ManagedDataAccess.Client; + +namespace Kalman.Data.DbProvider +{ + public class OracleDatabase : Database + { + private const string RefCursorName = "cur_OUT"; + private readonly IList packages; + private static readonly IList emptyPackages = new List(0); + private readonly IDictionary registeredParameterTypes + = new Dictionary(); + + public OracleDatabase(string connectionString) + : this(connectionString, emptyPackages) + { + } + + /// + /// 数据库类型 + /// + public override DatabaseType DatabaseType + { + get { return DatabaseType.Oracle; } + } + + /// + /// 数据库架构对象 + /// + //public override SODatabase Schema + //{ + // get + // { + // SODatabase schema = new SODatabase(new OracleSchema(this)); + // schema.Name = this.CreateConnection().Database; + // schema.Comment = schema.Name; + // return schema; + // } + //} + + public OracleDatabase(string connectionString,DbProviderFactory dbProviderFactory) + : base(connectionString, dbProviderFactory) + { + } + + public OracleDatabase(string connectionString, IList packages) + : base(connectionString, OracleClientFactory.Instance) + { + if (packages == null) throw new ArgumentNullException("packages"); + this.packages = packages; + } + + public override void AddParameter(DbCommand command, string name, DbType dbType, int size, + ParameterDirection direction, bool nullable, byte precision, byte scale, string sourceColumn, + DataRowVersion sourceVersion, object value) + { + if (DbType.Guid.Equals(dbType)) + { + object convertedValue = ConvertGuidToByteArray(value); + + AddParameter((OracleCommand)command, name, OracleDbType.Raw, 16, direction, nullable, precision, + scale, sourceColumn, sourceVersion, convertedValue); + + RegisterParameterType(command, name, dbType); + } + else + { + base.AddParameter(command, name, dbType, size, direction, nullable, precision, scale, + sourceColumn, sourceVersion, value); + } + } + + public void AddParameter(OracleCommand command, string name, OracleDbType oracleType, int size, + ParameterDirection direction, bool nullable, byte precision, byte scale, string sourceColumn, + DataRowVersion sourceVersion, object value) + { + OracleParameter param = CreateParameter(name, DbType.AnsiString, size, direction, nullable, precision, scale, sourceColumn, sourceVersion, value) as OracleParameter; + param.OracleDbType = oracleType; + command.Parameters.Add(param); + } + + public override IDataReader ExecuteReader(DbCommand command) + { + PrepareCWRefCursor(command); + return new OracleDataReaderWrapper((OracleDataReader)base.ExecuteReader(command)); + } + + public override IDataReader ExecuteReader(DbCommand command, DbTransaction transaction) + { + PrepareCWRefCursor(command); + return new OracleDataReaderWrapper((OracleDataReader)base.ExecuteReader(command, transaction)); + } + + public override DataSet ExecuteDataSet(DbCommand command) + { + PrepareCWRefCursor(command); + return base.ExecuteDataSet(command); + } + + public override DataSet ExecuteDataSet(DbCommand command, DbTransaction transaction) + { + PrepareCWRefCursor(command); + return base.ExecuteDataSet(command, transaction); + } + + public override void LoadDataSet(DbCommand command, DataSet dataSet, string[] tableNames) + { + PrepareCWRefCursor(command); + base.LoadDataSet(command, dataSet, tableNames); + } + + public override void LoadDataSet(DbCommand command, DataSet dataSet, string[] tableNames, DbTransaction transaction) + { + PrepareCWRefCursor(command); + base.LoadDataSet(command, dataSet, tableNames, transaction); + } + + public override object GetParameterValue(DbCommand command, string parameterName) + { + object convertedValue = base.GetParameterValue(command, parameterName); + + ParameterTypeRegistry registry = GetParameterTypeRegistry(command.CommandText); + if (registry != null) + { + if (registry.HasRegisteredParameterType(parameterName)) + { + DbType dbType = registry.GetRegisteredParameterType(parameterName); + + if (DbType.Guid == dbType) + { + convertedValue = ConvertByteArrayToGuid(convertedValue); + } + else if (DbType.Boolean == dbType) + { + convertedValue = Convert.ToBoolean(convertedValue, CultureInfo.InvariantCulture); + } + } + } + + return convertedValue; + } + + /// + /// 设置参数值 + /// + /// + /// 参数名称 + /// 参数值 + public override void SetParameterValue(DbCommand command, string parameterName, object value) + { + object convertedValue = value; + + ParameterTypeRegistry registry = GetParameterTypeRegistry(command.CommandText); + if (registry != null) + { + if (registry.HasRegisteredParameterType(parameterName)) + { + DbType dbType = registry.GetRegisteredParameterType(parameterName); + + if (DbType.Guid == dbType) + { + convertedValue = ConvertGuidToByteArray(value); + } + } + } + + base.SetParameterValue(command, parameterName, convertedValue); + } + + /// + /// This is a private method that will build the Oracle package name if your stored procedure + /// has proper prefix and postfix. + /// This functionality is include for + /// the portability of the architecture between SQL and Oracle datbase. + /// This method also adds the reference cursor to the command writer if not already added. This + /// is required for Oracle .NET managed data provider. + /// + private void PrepareCWRefCursor(DbCommand command) + { + if (command == null) throw new ArgumentNullException("command"); + + if (CommandType.StoredProcedure == command.CommandType) + { + // Check for ref. cursor in the command writer, if it does not exist, add a know reference cursor out + // of "cur_OUT" + if (QueryProcedureNeedsCursorParameter(command)) + { + AddParameter(command as OracleCommand, RefCursorName, OracleDbType.RefCursor, 0, ParameterDirection.Output, true, 0, 0, String.Empty, DataRowVersion.Default, Convert.DBNull); + } + } + } + + private ParameterTypeRegistry GetParameterTypeRegistry(string commandText) + { + ParameterTypeRegistry registry; + registeredParameterTypes.TryGetValue(commandText, out registry); + return registry; + } + + + private void RegisterParameterType(DbCommand command, string parameterName, DbType dbType) + { + ParameterTypeRegistry registry = GetParameterTypeRegistry(command.CommandText); + if (registry == null) + { + registry = new ParameterTypeRegistry(command.CommandText); + registeredParameterTypes.Add(command.CommandText, registry); + } + + registry.RegisterParameterType(parameterName, dbType); + } + + private static object ConvertGuidToByteArray(object value) + { + return ((value is DBNull) || (value == null)) ? Convert.DBNull : ((Guid)value).ToByteArray(); + } + + private static object ConvertByteArrayToGuid(object value) + { + byte[] buffer = (byte[])value; + if (buffer.Length == 0) + { + return DBNull.Value; + } + else + { + return new Guid(buffer); + } + } + + private static bool QueryProcedureNeedsCursorParameter(DbCommand command) + { + foreach (OracleParameter parameter in command.Parameters) + { + if (parameter.OracleDbType == OracleDbType.RefCursor) + { + return false; + } + } + return true; + } + + //为一个支持UpdateBehavior.Continue的DataAdapter对象监听RowUpdate事件 + private void OnOracleRowUpdated(object sender, OracleRowUpdatedEventArgs args) + { + if (args.RecordsAffected == 0) + { + if (args.Errors != null) + { + args.Row.RowError = Resources.Data.RowUpdateFailed; + args.Status = UpdateStatus.SkipCurrentRow; + } + } + } + + /// + /// Retrieves parameter information from the stored procedure specified in the and populates the Parameters collection of the specified object. + /// + /// The to do the discovery. + /// + /// The must be an instance of a object. + /// + protected override void DeriveParameters(DbCommand discoveryCommand) + { + OracleCommandBuilder.DeriveParameters((OracleCommand)discoveryCommand); + } + + /// + /// Creates a for a stored procedure. + /// + /// The name of the stored procedure. + /// The list of parameters for the procedure. + /// The for the stored procedure. + /// + /// The parameters for the stored procedure will be discovered and the values are assigned in positional order. + /// + public override DbCommand GetStoredProcCommand(string storedProcedureName, params object[] parameterValues) + { + // need to do this before of eventual parameter discovery + string updatedStoredProcedureName = TranslatePackageSchema(storedProcedureName); + DbCommand command = base.GetStoredProcCommand(updatedStoredProcedureName, parameterValues); + return command; + } + + /// + /// Creates a for a stored procedure. + /// + /// The name of the stored procedure. + /// The for the stored procedure. + /// + /// The parameters for the stored procedure will be discovered and the values are assigned in positional order. + /// + public override DbCommand GetStoredProcCommand(string storedProcedureName) + { + // need to do this before of eventual parameter discovery + string updatedStoredProcedureName = TranslatePackageSchema(storedProcedureName); + DbCommand command = base.GetStoredProcCommand(updatedStoredProcedureName); + return command; + } + + /// + /// Looks into configuration and gets the information on how the command wrapper should be updated if calling a package on this + /// connection. + /// + private string TranslatePackageSchema(string storedProcedureName) + { + const string allPrefix = "*"; + string packageName = String.Empty; + string updatedStoredProcedureName = storedProcedureName; + + if (packages != null && !string.IsNullOrEmpty(storedProcedureName)) + { + foreach (IOraclePackage oraPackage in packages) + { + if ((oraPackage.Prefix == allPrefix) || (storedProcedureName.StartsWith(oraPackage.Prefix))) + { + //use the package name for the matching prefix + packageName = oraPackage.Name; + //prefix = oraPackage.Prefix; + break; + } + } + } + if (0 != packageName.Length) + { + updatedStoredProcedureName = String.Format(CultureInfo.InvariantCulture, "{0}.{1}", packageName, storedProcedureName); + } + + return updatedStoredProcedureName; + } + + /// + /// Sets the RowUpdated event for the data adapter. + /// + /// The to set the event. + /// The must be an . + protected override void SetUpRowUpdatedEvent(DbDataAdapter adapter) + { + ((OracleDataAdapter)adapter).RowUpdated += OnOracleRowUpdated; + } + } + + internal sealed class ParameterTypeRegistry + { + private string commandText; + private IDictionary parameterTypes; + + internal ParameterTypeRegistry(string commandText) + { + this.commandText = commandText; + this.parameterTypes = new Dictionary(); + } + + internal void RegisterParameterType(string parameterName, DbType parameterType) + { + this.parameterTypes[parameterName] = parameterType; + } + + internal bool HasRegisteredParameterType(string parameterName) + { + return this.parameterTypes.ContainsKey(parameterName); + } + + internal DbType GetRegisteredParameterType(string parameterName) + { + return this.parameterTypes[parameterName]; + } + } +} diff --git a/src/Kalman/Data/DbProvider/SQLite/SQLiteDatabase.cs b/src/Kalman/Data/DbProvider/SQLite/SQLiteDatabase.cs new file mode 100644 index 0000000..9cddb2b --- /dev/null +++ b/src/Kalman/Data/DbProvider/SQLite/SQLiteDatabase.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Data.Common; +using Kalman.Data.SchemaObject; + +namespace Kalman.Data.DbProvider +{ + public class SQLiteDatabase : Database + { + #region 构造函数 + + /// + /// 构造函数,指定数据提供程序工厂实例 + /// + /// + /// + public SQLiteDatabase(string connectionString, DbProviderFactory dbProviderFactory) : base(connectionString,dbProviderFactory) + { + } + + /// + /// 构造函数,指定数据提供程序固定名称,用于创建数据提供程序工厂实例 + /// + /// + public SQLiteDatabase(string connectionString) + : base("System.Data.SQLite", connectionString) + { + } + + #endregion + + //public override SODatabase Schema + //{ + // get { throw new NotImplementedException(); } + //} + + public override DatabaseType DatabaseType + { + get { return DatabaseType.SQLite; } + } + + protected override void DeriveParameters(System.Data.Common.DbCommand discoveryCommand) + { + throw new NotImplementedException(); + } + } +} diff --git a/src/Kalman/Data/DbProvider/Sql/SqlServerDatabase.cs b/src/Kalman/Data/DbProvider/Sql/SqlServerDatabase.cs new file mode 100644 index 0000000..83a5c2a --- /dev/null +++ b/src/Kalman/Data/DbProvider/Sql/SqlServerDatabase.cs @@ -0,0 +1,197 @@ +using System; +using System.Data; +using System.Data.Common; +using System.Data.SqlClient; +using System.Security.Permissions; +using System.Transactions; +using System.Xml; +using Kalman.Data.DbSchemaProvider; +using Kalman.Data.SchemaObject; + +namespace Kalman.Data.DbProvider +{ + public class SqlServerDatabase : Database + { + public SqlServerDatabase(string connectionString) + : base(connectionString, SqlClientFactory.Instance) + { + } + + protected char ParameterToken + { + get { return '@'; } + } + + /// + /// 数据库类型 + /// + public override DatabaseType DatabaseType + { + get { return DatabaseType.SqlServer; } + } + + /// + /// 数据库架构对象 + /// + //public override SODatabase Schema + //{ + // get + // { + // SODatabase schema = new SODatabase(new SqlServerSchema(this)); + // schema.Name = this.CreateConnection().Database; + // schema.Comment = schema.Name; + // return schema; + // } + //} + + public XmlReader ExecuteXmlReader(DbCommand command) + { + SqlCommand sqlCommand = CheckIfSqlCommand(command); + + ConnectionWrapper wrapper = GetOpenConnection(false); + PrepareCommand(command, wrapper.Connection); + return DoExecuteXmlReader(sqlCommand); + } + + public XmlReader ExecuteXmlReader(DbCommand command, DbTransaction transaction) + { + SqlCommand sqlCommand = CheckIfSqlCommand(command); + + PrepareCommand(sqlCommand, transaction); + return DoExecuteXmlReader(sqlCommand); + } + + private XmlReader DoExecuteXmlReader(SqlCommand sqlCommand) + { + try + { + XmlReader reader = sqlCommand.ExecuteXmlReader(); + return reader; + } + catch (Exception e) + { + throw e; + } + } + + private static SqlCommand CheckIfSqlCommand(DbCommand command) + { + SqlCommand sqlCommand = command as SqlCommand; + if (sqlCommand == null) throw new ArgumentException(Resources.Data.CommandNotSqlCommand, "command"); + return sqlCommand; + } + + //为一个支持UpdateBehavior.Continue的DataAdapter对象监听RowUpdate事件 + private void OnSqlRowUpdated(object sender, SqlRowUpdatedEventArgs rowThatCouldNotBeWritten) + { + if (rowThatCouldNotBeWritten.RecordsAffected == 0) + { + if (rowThatCouldNotBeWritten.Errors != null) + { + rowThatCouldNotBeWritten.Row.RowError = Resources.Data.RowUpdateFailed; + rowThatCouldNotBeWritten.Status = UpdateStatus.SkipCurrentRow; + } + } + } + + /// + /// 检索从DbCommand指定存储过程的参数信息,并填充指定DbCommand对象的Parameters集合。 + /// + protected override void DeriveParameters(DbCommand discoveryCommand) + { + SqlCommandBuilder.DeriveParameters((SqlCommand)discoveryCommand); + } + + /// + /// Returns the starting index for parameters in a command. + /// + /// The starting index for parameters in a command. + protected override int UserParametersStartIndex() + { + return 1; + } + + /// + /// 生成一个带前缀的参数名 + /// + public override string BuildParameterName(string name) + { + if (name[0] != this.ParameterToken) + { + return name.Insert(0, new string(this.ParameterToken, 1)); + } + return name; + } + + /// + /// Sets the RowUpdated event for the data adapter. + /// + protected override void SetUpRowUpdatedEvent(DbDataAdapter adapter) + { + ((SqlDataAdapter)adapter).RowUpdated += OnSqlRowUpdated; + } + + /// + /// Determines if the number of parameters in the command matches the array of parameter values. + /// + /// The containing the parameters. + /// The array of parameter values. + /// if the number of parameters and values match; otherwise, . + protected override bool SameNumberOfParametersAndValues(DbCommand command, object[] values) + { + int returnParameterCount = 1; + int numberOfParametersToStoredProcedure = command.Parameters.Count - returnParameterCount; + int numberOfValuesProvidedForStoredProcedure = values.Length; + return numberOfParametersToStoredProcedure == numberOfValuesProvidedForStoredProcedure; + } + + public virtual void AddParameter(DbCommand command, string name, SqlDbType dbType, int size, ParameterDirection direction, bool nullable, byte precision, byte scale, string sourceColumn, DataRowVersion sourceVersion, object value) + { + DbParameter parameter = CreateParameter(name, dbType, size, direction, nullable, precision, scale, sourceColumn, sourceVersion, value); + command.Parameters.Add(parameter); + } + + public void AddParameter(DbCommand command, string name, SqlDbType dbType, ParameterDirection direction, string sourceColumn, DataRowVersion sourceVersion, object value) + { + AddParameter(command, name, dbType, 0, direction, false, 0, 0, sourceColumn, sourceVersion, value); + } + + public void AddOutParameter(DbCommand command, string name, SqlDbType dbType, int size) + { + AddParameter(command, name, dbType, size, ParameterDirection.Output, true, 0, 0, String.Empty, DataRowVersion.Default, DBNull.Value); + } + + public void AddInParameter(DbCommand command, string name, SqlDbType dbType) + { + AddParameter(command, name, dbType, ParameterDirection.Input, String.Empty, DataRowVersion.Default, null); + } + + public void AddInParameter(DbCommand command, string name, SqlDbType dbType, object value) + { + AddParameter(command, name, dbType, ParameterDirection.Input, String.Empty, DataRowVersion.Default, value); + } + + public void AddInParameter(DbCommand command, string name, SqlDbType dbType, string sourceColumn, DataRowVersion sourceVersion) + { + AddParameter(command, name, dbType, 0, ParameterDirection.Input, true, 0, 0, sourceColumn, sourceVersion, null); + } + + protected DbParameter CreateParameter(string name, SqlDbType dbType, int size, ParameterDirection direction, bool nullable, byte precision, byte scale, string sourceColumn, DataRowVersion sourceVersion, object value) + { + SqlParameter param = CreateParameter(name) as SqlParameter; + ConfigureParameter(param, name, dbType, size, direction, nullable, precision, scale, sourceColumn, sourceVersion, value); + return param; + } + + protected virtual void ConfigureParameter(SqlParameter param, string name, SqlDbType dbType, int size, ParameterDirection direction, bool nullable, byte precision, byte scale, string sourceColumn, DataRowVersion sourceVersion, object value) + { + param.SqlDbType = dbType; + param.Size = size; + param.Value = (value == null) ? DBNull.Value : value; + param.Direction = direction; + param.IsNullable = nullable; + param.SourceColumn = sourceColumn; + param.SourceVersion = sourceVersion; + } + } +} diff --git a/src/Kalman/Data/DbSchema.cs b/src/Kalman/Data/DbSchema.cs new file mode 100644 index 0000000..ea07f2d --- /dev/null +++ b/src/Kalman/Data/DbSchema.cs @@ -0,0 +1,471 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Kalman.Data.SchemaObject; +using System.Data; +using System.Data.Common; +using Kalman.Utilities; + +namespace Kalman.Data +{ + public abstract class DbSchema : IDbSchema + { + #region 元数据集合名称定义,不同的数据提供程序对元数据集合名称的定义都可能不同,可以通过重写属性来解决 + + /// + /// [数据库] + /// + public virtual string MetaDataCollectionName_Databases { get { return "Databases"; } } + /// + /// 元数据集合名称[表] + /// + public virtual string MetaDataCollectionName_Tables { get { return "Tables"; } } + /// + /// 元数据集合名称[列] + /// + public virtual string MetaDataCollectionName_Columns { get { return "Columns"; } } + /// + /// 元数据集合名称[视图] + /// + public virtual string MetaDataCollectionName_Views { get { return "Views"; } } + /// + /// 元数据集合名称[视图列] + /// + public virtual string MetaDataCollectionName_ViewColumns { get { return "ViewColumns"; } } + /// + /// 元数据集合名称[索引] + /// + public virtual string MetaDataCollectionName_Indexes { get { return "Indexes"; } } + /// + /// 元数据集合名称[索引列] + /// + public virtual string MetaDataCollectionName_IndexColumns { get { return "IndexColumns"; } } + /// + /// 元数据集合名称[存储过程] + /// + public virtual string MetaDataCollectionName_Procedures { get { return "Procedures"; } } + /// + /// 元数据集合名称[存储过程参数] + /// + public virtual string MetaDataCollectionName_Parameters { get { return "Parameters"; } } + + #endregion + + DbCommandBuilder cmdBuilder; + /// + /// 以正确的目录大小写给定一个不带引号的标识符,返回该标识符的带引号的正确形式,包括正确转义该标识符中嵌入的任何引号。 + /// + /// + /// + public virtual string QuoteIdentifier(string name) + { + if(cmdBuilder == null) cmdBuilder = this.DbProvider.DbProviderFactory.CreateCommandBuilder(); + string s = string.Concat(cmdBuilder.QuotePrefix, name, cmdBuilder.QuoteSuffix); + return s; + } + + /// + /// 在指定数据库上执行一个查询,返回一个结果集 + /// + /// + /// + /// + public virtual DataSet ExecuteQuery(SODatabase db, string cmdText) + { + this.DbProvider.CurrentDatabaseName = db.Name; + DataSet ds = this.DbProvider.ExecuteDataSet(CommandType.Text, cmdText); + return ds; + } + + #region IDbSchema 成员 + + /// + /// 获取或设置数据提供者实例 + /// + public virtual Database DbProvider { get; set; } + + /// + /// 获取数据库列表 + /// + /// + public virtual List GetDatabaseList() + { + List list = new List(); + DataTable dt = GetSchema(MetaDataCollectionName_Databases); + + foreach (DataRow dr in dt.Rows) + { + SODatabase db = new SODatabase(); + db.Name = dr["database_name"].ToString(); + db.Comment = db.Name; + db.Parent = this; + + list.Add(db); + } + + return list; + } + + public virtual SODatabase GetDatabase(string dbName) + { + var db = GetDatabaseList().Find(p=>p.Name == dbName); + return db; + } + + /// + /// 获取表列表 + /// + /// + /// + public virtual List GetTableList(SODatabase db) + { + List list = new List(); + + string[] restrictions = new string[4]; + restrictions[0] = db.Name; + DataTable dt = GetSchema(MetaDataCollectionName_Tables, restrictions); + + foreach (DataRow dr in dt.Rows) + { + SOTable table = new SOTable(); + table.Name = dr["table_name"].ToString(); + table.Comment = table.Name; + table.Parent = db; + + list.Add(table); + } + + return list; + } + + /// + /// + /// + /// + /// + public virtual List GetTableList(string dbName) + { + SODatabase db = GetDatabase(dbName); + return GetTableList(db); + } + + /// + /// + /// + /// + /// + /// + public virtual SOTable GetTable(string dbName, string tableName) + { + var table = GetTableList(dbName).Find(p => p.Name == tableName); + return table; + } + + /// + /// + /// + /// + /// + /// + public virtual SOTable GetTable(SODatabase db, string tableName) + { + var table = GetTableList(db).Find(p => p.Name == tableName); + return table; + } + + /// + /// 获取表所拥有的列列表 + /// + /// + /// + public virtual List GetTableColumnList(SOTable table) + { + List list = new List(); + + string[] restrictions = new string[4]; + restrictions[0] = table.Database.Name; + restrictions[2] = table.Name; + DataTable dt = GetSchema(MetaDataCollectionName_Columns, restrictions); + + foreach (DataRow dr in dt.Rows) + { + SOColumn c = new SOColumn(); + c.Name = dr["column_name"].ToString(); + c.Comment = c.Name; + c.Parent = table; + c.DefaultValue = ConvertUtil.ToString(dr["column_default"]); + c.Nullable = dr["is_nullable"].ToString() == "YES" ? true : false; + c.NativeType = dr["data_type"].ToString(); + c.Length = ConvertUtil.ToInt32(dr["character_maximum_length"], -1); + c.Precision = ConvertUtil.ToInt32(dr["numeric_precision"], -1); + c.Scale = ConvertUtil.ToInt32(dr["numeric_scale"], -1); + + c.DataType = this.GetDbType(c.NativeType); + + list.Add(c); + } + + return list; + } + + /// + /// 获取表所拥有的索引列表 + /// + /// + /// + public virtual List GetTableIndexList(SOTable table) + { + List list = new List(); + + string[] restrictions = new string[4]; + restrictions[0] = table.Database.Name; + //restrictions[4] = table.Name; + DataTable dt = GetSchema(MetaDataCollectionName_Indexes, restrictions); + + foreach (DataRow dr in dt.Rows) + { + if (dr["TABLE_NAME"].ToString() != table.Name) continue; + + SOIndex index = new SOIndex(); + index.Name = dr["INDEX_NAME"].ToString(); + index.IndexColumnName = dr["COLUMN_NAME"].ToString(); + index.IsPrimaryKey = dr["PRIMARY_KEY"].ToString().ToLower() == "true" ? true : false; + index.IsUnique = dr["UNIQUE"].ToString().ToLower() == "true" ? true : false; + index.IsCluster = dr["CLUSTERED"].ToString().ToLower() == "true" ? true : false; + index.IsIdentity = dr["NULLS"].ToString() == "1" ? true : false; //这里判断自增列默认情况下是没问题的 + index.Comment = index.Name; + index.Parent = table; + + list.Add(index); + } + + return list; + } + + /// + /// 获取视图列表 + /// + /// + /// + public virtual List GetViewList(SODatabase db) + { + List list = new List(); + + string[] restrictions = new string[3]; + restrictions[0] = db.Name; + DataTable dt = GetSchema(MetaDataCollectionName_Views, restrictions); + + foreach (DataRow dr in dt.Rows) + { + SOView view = new SOView(); + view.Name = dr["table_name"].ToString(); + view.Comment = view.Name; + view.Parent = db; + + list.Add(view); + } + + return list; + } + + public virtual List GetViewList(string dbName) + { + SODatabase db = GetDatabase(dbName); + return GetViewList(db); + } + + public virtual SOView GetView(SODatabase db, string viewName) + { + var view = GetViewList(db).Find(p => p.Name == viewName); + return view; + } + + public virtual SOView GetView(string dbName, string viewName) + { + var view = GetViewList(dbName).Find(p => p.Name == viewName); + return view; + } + + /// + /// 获取视图所拥有的列列表 + /// + /// + /// + public virtual List GetViewColumnList(SOView view) + { + throw new NotImplementedException(); + } + + /// + /// 获取视图所拥有的索引列表 + /// + /// + /// + public virtual List GetViewIndexList(SOView view) + { + throw new NotImplementedException(); + } + + /// + /// 获取存储过程列表 + /// + /// + /// + public virtual List GetCommandList(SODatabase db) + { + List list = new List(); + + string[] restrictions = new string[4]; + restrictions[0] = db.Name; + DataTable dt = GetSchema(MetaDataCollectionName_Procedures, restrictions); + + foreach (DataRow dr in dt.Rows) + { + SOCommand cmd = new SOCommand(); + cmd.Name = dr["routine_name"].ToString(); + cmd.Comment = cmd.Name; + cmd.Parent = db; + + list.Add(cmd); + } + + return list; + } + + public virtual List GetCommandList(string dbName) + { + SODatabase db = GetDatabase(dbName); + return GetCommandList(db); + } + + public virtual SOCommand GetCommand(SODatabase db, string spName) + { + var sp = GetCommandList(db).Find(p => p.Name == spName); + return sp; + } + + public virtual SOCommand GetCommand(string dbName, string spName) + { + var sp = GetCommandList(dbName).Find(p => p.Name == spName); + return sp; + } + + /// + /// 获取存储过程参数列表 + /// + /// + /// + public virtual List GetCommandParameterList(SOCommand command) + { + List list = new List(); + + string[] restrictions = new string[4]; + restrictions[0] = command.Database.Name; + restrictions[2] = command.Name; + DataTable dt = GetSchema(MetaDataCollectionName_Parameters, restrictions); + + //todo:转换数据 + + return list; + } + + /// + /// 获取表的Sql脚本 + /// + /// + /// + public virtual string GetTableSqlText(SOTable table) + { + return "该方法目前还没有实现"; + } + + /// + /// 获取视图的Sql脚本 + /// + /// + /// + public virtual string GetViewSqlText(SOView view) + { + return "该方法目前还没有实现"; + } + + /// + /// 获取存储过程的Sql脚本 + /// + /// + /// + public virtual string GetCommandSqlText(SOCommand command) + { + return "该方法目前还没有实现"; + } + + /// + /// 基于DbConnection对象的元数据对象获取方法 + /// + /// 元数据集合名 + /// + public virtual DataTable GetSchema(string metaDataCollectionName) + { + return GetSchema(metaDataCollectionName, null); + } + + /// + /// 基于DbConnection对象的元数据对象获取方法 + /// + /// 元数据集合名 + /// 过滤条件 + /// + public virtual DataTable GetSchema(string metaDataCollectionName, string[] restrictions) + { + DataTable dt; + + using (DbConnection cn = DbProvider.CreateConnection()) + { + cn.ConnectionString = DbProvider.ConnectionString; + cn.Open(); + + if (string.IsNullOrEmpty(metaDataCollectionName)) + { + dt = cn.GetSchema(); + } + else + { + if (restrictions == null || restrictions.All(s => s == null)) + dt = cn.GetSchema(metaDataCollectionName); + else + dt = cn.GetSchema(metaDataCollectionName, restrictions); + } + } + + return dt; + } + + ///// + ///// 获取数据库原生类型,这里可能存在一对多的关系,只取一个默认原生类型 + ///// + ///// + ///// + //public abstract string GetNativeType(System.Data.DbType dbType); + + /// + /// 获取.Net Framework数据类型 + /// + /// + /// + public abstract DbType GetDbType(string nativeType); + + /// + /// 获取System.Type类型 + /// + /// + /// + public virtual Type GetType(string nativeType) + { + DbType dbType = GetDbType(nativeType); + return TypeUtil.DbType2Type(dbType); + } + + #endregion + } +} diff --git a/src/Kalman/Data/DbSchemaFactory.cs b/src/Kalman/Data/DbSchemaFactory.cs new file mode 100644 index 0000000..7271395 --- /dev/null +++ b/src/Kalman/Data/DbSchemaFactory.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Kalman.Data.DbSchemaProvider; + +namespace Kalman.Data +{ + /// + /// 数据库架构工厂类 + /// + public static class DbSchemaFactory + { + /// + /// 创建一个数据库架构实例 + /// + /// 连接字符串名称 + /// + public static DbSchema Create(string connectionStringName) + { + Database db = DatabaseFactory.Create(connectionStringName); + return Create(db); + } + + /// + /// 创建一个数据库架构实例 + /// + /// 数据提供程序实例 + /// + public static DbSchema Create(Database db) + { + DbSchema schema = null; + + switch (db.DatabaseType) + { + case DatabaseType.SqlServer: + schema = new SqlServerSchema(db); + break; + case DatabaseType.Oracle: + schema = new OracleSchema(db); + break; + case DatabaseType.MySql: + schema = new MySqlSchema(db); + break; + case DatabaseType.DB2: + schema = new DB2Schema(db); + break; + case DatabaseType.SQLite: + schema = new SQLiteSchema(db); + break; + case DatabaseType.OleDb: + schema = new OleDbSchema(db); + break; + default: + break; + } + + return schema; + } + } +} diff --git a/src/Kalman/Data/DbSchemaProvider/DB2Schema.cs b/src/Kalman/Data/DbSchemaProvider/DB2Schema.cs new file mode 100644 index 0000000..fe8b2ef --- /dev/null +++ b/src/Kalman/Data/DbSchemaProvider/DB2Schema.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Data; +using Kalman.Data.SchemaObject; +using Kalman.Utilities; + +namespace Kalman.Data.DbSchemaProvider +{ + public class DB2Schema : DbSchema + { + public DB2Schema() + { + + } + + public DB2Schema(Database db) + { + base.DbProvider = db; + } + + /// + /// 获取表的Sql脚本 + /// + /// + /// + public override string GetTableSqlText(SOTable table) + { + throw new NotImplementedException(); + } + + /// + /// 获取视图的Sql脚本 + /// + /// + /// + public override string GetViewSqlText(SOView view) + { + throw new NotImplementedException(); + } + + /// + /// 获取存储过程的Sql脚本 + /// + /// + /// + public override string GetCommandSqlText(SOCommand command) + { + throw new NotImplementedException(); + } + + /// + /// 获取.Net Framework数据类型 + /// + /// + /// + public override DbType GetDbType(string nativeType) + { + return TypeUtil.DB2DataType2DbType(nativeType); + } + } +} diff --git a/src/Kalman/Data/DbSchemaProvider/MySqlSchema.cs b/src/Kalman/Data/DbSchemaProvider/MySqlSchema.cs new file mode 100644 index 0000000..c6f1688 --- /dev/null +++ b/src/Kalman/Data/DbSchemaProvider/MySqlSchema.cs @@ -0,0 +1,341 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Kalman.Data.SchemaObject; +using System.Data.Common; +using System.Data; +using Kalman.Utilities; + +/* MySql元数据信息架构参考:http://dev.mysql.com/doc/refman/5.1/zh/information-schema.html */ + +namespace Kalman.Data.DbSchemaProvider +{ + public class MySqlSchema : DbSchema + { + public MySqlSchema(Database db) + { + base.DbProvider = db; + } + + /// + /// 获取数据库列表 + /// + /// + public override List GetDatabaseList() + { + string cmdText = "SELECT SCHEMA_NAME AS `Database` FROM INFORMATION_SCHEMA.SCHEMATA;"; + //string cmdText = "SHOW DATABASES;"; + + List dbList = new List(); + DataTable dt = this.DbProvider.ExecuteDataSet(System.Data.CommandType.Text, cmdText).Tables[0]; + + foreach (DataRow row in dt.Rows) + { + SODatabase db = new SODatabase { Parent = this, Name = row[0].ToString() }; + db.Comment = db.Name; + if (db.Name.ToLower() == "information_schema" || db.Name.ToLower() == "mysql") continue; + + dbList.Add(db); + } + + return dbList; + } + + /// + /// 获取表列表 + /// + /// + /// + public override List GetTableList(SODatabase db) + { + string cmdText = string.Format("SELECT table_name,table_type,table_comment FROM INFORMATION_SCHEMA.`TABLES` WHERE table_schema='{0}' AND table_type='BASE TABLE';", db.Name); + List tableList = new List(); + DataTable dt = this.DbProvider.ExecuteDataSet(System.Data.CommandType.Text, cmdText).Tables[0]; + + foreach (DataRow row in dt.Rows) + { + SOTable table = new SOTable { Parent = db, Name = row["table_name"].ToString(),Comment = row["table_comment"].ToString() }; + tableList.Add(table); + } + + return tableList; + } + + /// + /// 获取表所拥有的列列表 + /// + /// + /// + public override List GetTableColumnList(SOTable table) + { + string cmdText = string.Format(@"SELECT * + FROM INFORMATION_SCHEMA.`COLUMNS` + WHERE table_schema='{0}' AND table_name='{1}' + ORDER BY ordinal_position;", table.Database.Name,table.Name); + + List columnList = new List(); + DataTable dt = this.DbProvider.ExecuteDataSet(System.Data.CommandType.Text, cmdText).Tables[0]; + + foreach (DataRow row in dt.Rows) + { + SOColumn column = new SOColumn + { + Parent = table, + Name = row["column_name"].ToString(), + DefaultValue = row["column_default"].ToString(), + Nullable = row["is_nullable"].ToString().ToUpper() == "YES", + NativeType = row["data_type"].ToString(), + Identify = row["extra"].ToString().IndexOf("auto_increment") != -1, + //ForeignKey + Length = ConvertUtil.ToInt32(row["character_maximum_length"], -1), + Precision = ConvertUtil.ToInt32(row["numeric_precision"], -1), + PrimaryKey = row["column_key"].ToString() == "PRI", + Scale = ConvertUtil.ToInt32(row["numeric_scale"], -1), + Comment = row["column_comment"].ToString() + }; + + column.DataType = this.GetDbType(column.NativeType); + columnList.Add(column); + } + + return columnList; + } + + /// + /// 获取表所拥有的索引列表 + /// + /// + /// + public override List GetTableIndexList(SOTable table) + { + string cmdText = string.Format(@"SELECT * + FROM INFORMATION_SCHEMA.`constraints` + WHERE table_schema='{0}' AND table_name='{1}';", table.Database.Name, table.Name); + + List indexList = new List(); + List columnList = GetTableColumnList(table); + DataTable dt = this.DbProvider.ExecuteDataSet(System.Data.CommandType.Text, cmdText).Tables[0]; + + foreach (DataRow row in dt.Rows) + { + SOIndex index = new SOIndex + { + Parent = table, + Name = row["constraint_name"].ToString(), + Comment = row["constraint_name"].ToString(), + IsCluster = false, + IsFullText = row["constraint_type"].ToString() == "Full Text", + IsPrimaryKey = row["constraint_type"].ToString() == "PRIMARY KEY", + IsUnique = row["constraint_type"].ToString() == "UNIQUE" + }; + indexList.Add(index); + + string cmdText2 = string.Format(@"SELECT column_name + FROM INFORMATION_SCHEMA.`statistics` + WHERE table_schema='{0}' AND table_name='{1}';", table.Database.Name, table.Name); + + DataTable dt2 = this.DbProvider.ExecuteDataSet(CommandType.Text, cmdText2).Tables[0]; + index.Columns = new List(); + foreach (DataRow row2 in dt2.Rows) + { + foreach (SOColumn column in columnList) + { + if (row2[0].ToString() == column.Name) index.Columns.Add(column); + } + } + } + + return indexList; + } + + /// + /// 获取视图列表 + /// + /// + /// + public override List GetViewList(SODatabase db) + { + string cmdText = string.Format("SELECT table_name,table_type,table_comment FROM INFORMATION_SCHEMA.`TABLES` WHERE table_schema='{0}' AND table_type='VIEW';", db.Name); + List viewList = new List(); + DataTable dt = this.DbProvider.ExecuteDataSet(System.Data.CommandType.Text, cmdText).Tables[0]; + + foreach (DataRow row in dt.Rows) + { + SOView view = new SOView { Parent = db, Name = row["table_name"].ToString(), Comment = row["table_comment"].ToString() }; + viewList.Add(view); + } + + return viewList; + } + + /// + /// 获取视图所拥有的列列表 + /// + /// + /// + public override List GetViewColumnList(SOView view) + { + string cmdText = string.Format(@"SELECT * + FROM INFORMATION_SCHEMA.`COLUMNS` + WHERE table_schema='{0}' AND table_name='{1}' + ORDER BY ordinal_position;", view.Database.Name, view.Name); + + List columnList = new List(); + DataTable dt = this.DbProvider.ExecuteDataSet(System.Data.CommandType.Text, cmdText).Tables[0]; + + foreach (DataRow row in dt.Rows) + { + SOColumn column = new SOColumn + { + Parent = view, + Name = row["column_name"].ToString(), + DefaultValue = row["column_default"].ToString(), + Nullable = row["is_nullable"].ToString().ToUpper() == "YES", + NativeType = row["data_type"].ToString(), + Identify = row["extra"].ToString().IndexOf("auto_increment") != -1, + //ForeignKey + Length = ConvertUtil.ToInt32(row["character_maximum_length"], -1), + Precision = ConvertUtil.ToInt32(row["numeric_precision"], -1), + PrimaryKey = row["column_key"].ToString() == "PRI", + Scale = ConvertUtil.ToInt32(row["numeric_scale"], -1), + Comment = row["column_comment"].ToString() + }; + + column.DataType = this.GetDbType(column.NativeType); + columnList.Add(column); + } + + return columnList; + } + + /// + /// 获取视图所拥有的索引列表 + /// + /// + /// + public override List GetViewIndexList(SOView view) + { + string cmdText = string.Format(@"SELECT * + FROM INFORMATION_SCHEMA.`constraints` + WHERE table_schema='{0}' AND table_name='{1}';", view.Database.Name, view.Name); + + List indexList = new List(); + List columnList = GetViewColumnList(view); + DataTable dt = this.DbProvider.ExecuteDataSet(System.Data.CommandType.Text, cmdText).Tables[0]; + + foreach (DataRow row in dt.Rows) + { + SOIndex index = new SOIndex + { + Parent = view, + Name = row["constraint_name"].ToString(), + Comment = row["constraint_name"].ToString(), + IsCluster = false, + IsFullText = row["constraint_type"].ToString() == "Full Text", + IsPrimaryKey = row["constraint_type"].ToString() == "PRIMARY KEY", + IsUnique = row["constraint_type"].ToString() == "UNIQUE" + }; + indexList.Add(index); + + string cmdText2 = string.Format(@"SELECT column_name + FROM INFORMATION_SCHEMA.`statistics` + WHERE table_schema='{0}' AND table_name='{1}';", view.Database.Name, view.Name); + + DataTable dt2 = this.DbProvider.ExecuteDataSet(CommandType.Text, cmdText2).Tables[0]; + index.Columns = new List(); + foreach (DataRow row2 in dt2.Rows) + { + foreach (SOColumn column in columnList) + { + if (row2[0].ToString() == column.Name) index.Columns.Add(column); + } + } + } + + return indexList; + } + + /// + /// 获取存储过程列表 + /// + /// + /// + public override List GetCommandList(SODatabase db) + { + string cmdText = string.Format(@"SELECT routine_name,routine_comment + FROM INFORMATION_SCHEMA.`ROUTINES` + WHERE routine_schema='{0}' AND routine_type='PROCEDURE';", db.Name); + + List commandList = new List(); + DataTable dt = this.DbProvider.ExecuteDataSet(System.Data.CommandType.Text, cmdText).Tables[0]; + + foreach (DataRow row in dt.Rows) + { + SOCommand command = new SOCommand { Parent = db, Name = row["routine_name"].ToString(), Comment = row["routine_comment"].ToString() }; + commandList.Add(command); + } + + return commandList; + } + + /// + /// 获取存储过程参数列表 + /// + /// + /// + public override List GetCommandParameterList(SOCommand command) + { + //在information_schema数据库中没有找到存储存储过程参数的表,可以考虑从存储过程DDL脚本解析出来 + throw new NotImplementedException(); + } + + /// + /// 获取表的Sql脚本 + /// + /// + /// + public override string GetTableSqlText(SOTable table) + { + throw new NotImplementedException(); + } + + /// + /// 获取视图的Sql脚本 + /// + /// + /// + public override string GetViewSqlText(SOView view) + { + string cmdText = string.Format("SELECT VIEW_DEFINITION FROM INFORMATION_SCHEMA.`VIEWS` WHERE table_schema='{0}' AND table_name='{1}';", view.Database.Name, view.Name); + string text = this.DbProvider.ExecuteScalar(System.Data.CommandType.Text, cmdText).ToString(); + return text; + } + + /// + /// 获取存储过程的Sql脚本 + /// + /// + /// + public override string GetCommandSqlText(SOCommand command) + { + string cmdText = string.Format(@"SELECT routine_definition + FROM INFORMATION_SCHEMA.`ROUTINES` + WHERE routine_schema='{0}' AND routine_type='PROCEDURE' AND routine_name='{1}';", command.Database.Name, command.Name); + + string text = this.DbProvider.ExecuteScalar(System.Data.CommandType.Text, cmdText).ToString(); + return text; + } + + /// + /// 获取.Net Framework数据类型 + /// + /// + /// + public override DbType GetDbType(string nativeType) + { + return TypeUtil.MySqlDataType2DbType(nativeType); + } + } +} + diff --git a/src/Kalman/Data/DbSchemaProvider/OleDbSchema.cs b/src/Kalman/Data/DbSchemaProvider/OleDbSchema.cs new file mode 100644 index 0000000..012a70d --- /dev/null +++ b/src/Kalman/Data/DbSchemaProvider/OleDbSchema.cs @@ -0,0 +1,207 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Data; +using System.Data.OleDb; +using System.Data.Common; +using Kalman.Data.SchemaObject; +using Kalman.Utilities; + +namespace Kalman.Data.DbSchemaProvider +{ + public class OleDbSchema : DbSchema + { + public OleDbSchema() + { + } + + public OleDbSchema(Database db) + { + base.DbProvider = db; + } + + public override string MetaDataCollectionName_Databases + { + get { return "Catalogs"; } + } + + public override DataSet ExecuteQuery(SODatabase db, string cmdText) + { + DataSet ds = new DataSet(); + using (DbConnection cn = base.DbProvider.DbProviderFactory.CreateConnection()) + { + cn.ConnectionString = base.DbProvider.ConnectionString; + cn.Open(); + + DbCommand cmd = base.DbProvider.DbProviderFactory.CreateCommand(); + cmd.Connection = cn; + cmd.CommandType = CommandType.Text; + cmd.CommandText = cmdText; + + DbDataAdapter adapter = base.DbProvider.DbProviderFactory.CreateDataAdapter(); + adapter.SelectCommand = cmd; + adapter.Fill(ds, 0, 100000, "temp"); + } + + return ds; + } + + public override List GetDatabaseList() + { + return new List + { + new SODatabase + { + //Name = "Main", + Parent = this, + //Comment = "Main" + } + }; + } + + /// + /// 获取表列表 + /// + /// + /// + public override List GetTableList(SODatabase db) + { + List list = new List(); + + string[] restrictions = new string[4]; + restrictions[0] = db.Name; + DataTable dt = GetSchema(MetaDataCollectionName_Tables, restrictions); + + foreach (DataRow dr in dt.Rows) + { + if (dr["TABLE_TYPE"].ToString() != "TABLE") continue; //排除系统表 + + SOTable table = new SOTable(); + table.Name = dr["table_name"].ToString(); + table.Comment = table.Name; + table.Parent = db; + + list.Add(table); + } + + return list; + } + + /// + /// 获取表所拥有的列列表 + /// + /// + /// + public override List GetTableColumnList(SOTable table) + { + List list = new List(); + + string[] restrictions = new string[4]; + restrictions[0] = table.Database.Name; + restrictions[2] = table.Name; + DataTable dt = GetSchema(MetaDataCollectionName_Columns, restrictions); + + List indexList = this.GetTableIndexList(table); + + foreach (DataRow dr in dt.Rows) + { + SOColumn c = new SOColumn(); + c.Name = dr["column_name"].ToString(); + c.Comment = dr["DESCRIPTION"].ToString(); + c.Parent = table; + + if (dr["COLUMN_HASDEFAULT"].ToString().ToLower() != "false") + { + c.DefaultValue = ConvertUtil.ToString(dr["COLUMN_DEFAULT"]); + } + + c.Nullable = dr["IS_NULLABLE"].ToString().ToLower() == "true" ? true : false; + c.NativeType = dr["DATA_TYPE"].ToString(); + c.Length = ConvertUtil.ToInt32(dr["CHARACTER_MAXIMUM_LENGTH"], -1); + c.Precision = ConvertUtil.ToInt32(dr["NUMERIC_PRECISION"], -1); + c.Scale = ConvertUtil.ToInt32(dr["NUMERIC_SCALE"], -1); + + c.DataType = this.GetDbType(c.NativeType); + c.PrimaryKey = IndexColumnIsPrimary(indexList, c.Name); + c.Identify = IndexColumnIsIdentity(indexList, c.Name); + + list.Add(c); + } + + return list; + } + + //判断是否主键,从索引列里面判断 + bool IndexColumnIsPrimary(List list, string columnName) + { + foreach (var item in list) + { + if (item.IndexColumnName == columnName && item.IsPrimaryKey) return true; + } + + return false; + } + + //判断是否标识列,从索引列里面判断 + bool IndexColumnIsIdentity(List list, string columnName) + { + foreach (var item in list) + { + if (item.IndexColumnName == columnName && item.IsIdentity) return true; + } + + return false; + } + + public override List GetCommandList(SODatabase db) + { + return new List(); + } + + public override List GetCommandParameterList(SOCommand command) + { + return new List(); + } + + /// + /// 获取表的Sql脚本 + /// + /// + /// + public override string GetTableSqlText(SOTable table) + { + throw new NotImplementedException(); + } + + /// + /// 获取视图的Sql脚本 + /// + /// + /// + public override string GetViewSqlText(SOView view) + { + throw new NotImplementedException(); + } + + /// + /// 获取存储过程的Sql脚本 + /// + /// + /// + public override string GetCommandSqlText(SOCommand command) + { + throw new NotImplementedException(); + } + + /// + /// 获取.Net Framework数据类型 + /// + /// + /// + public override DbType GetDbType(string nativeType) + { + return TypeUtil.OleDbADataType2DbType(nativeType); + } + } +} diff --git a/src/Kalman/Data/DbSchemaProvider/OracleSchema.cs b/src/Kalman/Data/DbSchemaProvider/OracleSchema.cs new file mode 100644 index 0000000..e0f9379 --- /dev/null +++ b/src/Kalman/Data/DbSchemaProvider/OracleSchema.cs @@ -0,0 +1,318 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Kalman.Data.SchemaObject; +using System.Data; +using Kalman.Utilities; +using System.Collections.Specialized; + +namespace Kalman.Data.DbSchemaProvider +{ + public class OracleSchema : DbSchema + { + public bool IsDBA + { + get; set; + } + public OracleSchema() + { + init(); + } + + public OracleSchema(Database db) + { + base.DbProvider = db; + init(); + } + + public void init() + { + string result = this.DbProvider.ExecuteScalar(CommandType.Text, "select userenv('ISDBA') from dual"); + IsDBA = (result != "FALSE"); + } + + public override List GetDatabaseList() + { + List list = new List(); + + string cmdText = "select * from dba_users"; + if (!IsDBA) + { + cmdText = "select * from user_users"; + } + try + { + DataTable dt = this.DbProvider.ExecuteDataSet(System.Data.CommandType.Text, cmdText).Tables[0]; + foreach (DataRow row in dt.Rows) + { + SODatabase db = new SODatabase(); + db.Name = row["USERNAME"].ToString(); + db.Comment = db.Name; + db.Parent = this; + + list.Add(db); + } + } + catch (Exception) + { + } + return list; + } + + /// + /// 获取表列表 + /// + /// + /// + public override List GetTableList(SODatabase db) + { + SortedDictionary dic = new SortedDictionary(); + string cmdText = string.Format(@"select t.OWNER,t.TABLE_NAME,t.NUM_ROWS,c.TABLE_TYPE,c.COMMENTS from dba_tables t left join dba_tab_comments c on t.TABLE_NAME = c.TABLE_NAME where t.owner='{0}'", db.Name); + if (!IsDBA) + { + cmdText = string.Format(@"select t.TABLE_NAME,t.NUM_ROWS,c.TABLE_TYPE,c.COMMENTS from user_tables t left join user_tab_comments c on t.TABLE_NAME = c.TABLE_NAME"); + // cmdText = @"select a.TABLE_NAME,b.COMMENTS,a.NUM_ROWS,b.table_type from user_tables a,user_tab_comments b WHERE a.TABLE_NAME=b.TABLE_NAME order by TABLE_NAME"; + } + DataTable dt = this.DbProvider.ExecuteDataSet(System.Data.CommandType.Text, cmdText).Tables[0]; + + foreach (DataRow row in dt.Rows) + { + //if (row["TABLE_TYPE"].ToString() != "TABLE") continue; + if (row["TABLE_NAME"].ToString().StartsWith("BIN$")) continue; + + SOTable table = new SOTable { Parent = db, Name = row["TABLE_NAME"].ToString(), Owner = IsDBA ? row["OWNER"].ToString() : db.Name, Comment = row["COMMENTS"].ToString() }; + table.SchemaName = table.Owner; + if (!dic.ContainsKey(table.Name)) dic.Add(table.Name, table); + } + + return dic.Values.ToList(); + } + + //获取表的主键列 + List GetPrimaryKeys(SOTable table) + { + string cmdText = string.Format(@"select c.owner,c.constraint_name,c.table_name,cc.column_name,cc.position + from dba_constraints c inner join dba_cons_columns cc on c.constraint_name = cc.constraint_name + where c.owner='{0}' and c.constraint_type='P' and c.table_name='{1}'", table.Database.Name, table.Name); + + if (!IsDBA) + { + cmdText = string.Format(@"select c.owner,c.constraint_name,c.table_name,cc.column_name,cc.position + from user_constraints c inner join user_cons_columns cc on c.constraint_name = cc.constraint_name + where c.owner='{0}' and c.constraint_type='P' and c.table_name='{1}'", table.Database.Name, table.Name); + } + + List list = new List(); + DataTable dt = this.DbProvider.ExecuteDataSet(System.Data.CommandType.Text, cmdText).Tables[0]; + + foreach (DataRow row in dt.Rows) + { + list.Add(row["column_name"].ToString()); + } + + return list; + } + + /// + /// 获取表所拥有的列列表 + /// + /// + /// + public override List GetTableColumnList(SOTable table) + { + string cmdText = string.Format(@"select c.COLUMN_ID,c.COLUMN_NAME,c.DATA_TYPE,c.DATA_LENGTH,c.DATA_PRECISION,c.DATA_SCALE,c.NULLABLE,c.DATA_DEFAULT,c.CHAR_COL_DECL_LENGTH,c.CHAR_LENGTH,cc.COMMENTS + from dba_tab_columns c left join dba_col_comments cc on c.table_name=cc.table_name and c.column_name=cc.column_name + where c.owner='{0}' and cc.owner='{0}' and c.table_name='{1}' order by c.column_id", table.Database.Name, table.Name); + if (!IsDBA) + { + cmdText = string.Format(@"select c.COLUMN_ID,c.COLUMN_NAME,c.DATA_TYPE,c.DATA_LENGTH,c.DATA_PRECISION,c.DATA_SCALE,c.NULLABLE,c.DATA_DEFAULT,c.CHAR_COL_DECL_LENGTH,c.CHAR_LENGTH,cc.COMMENTS + from user_tab_columns c left join user_col_comments cc on c.table_name = cc.table_name and c.column_name = cc.column_name + where c.table_name='{0}' order by c.column_id", table.Name); + } + List columnList = new List(); + List pkList = GetPrimaryKeys(table); + DataTable dt = this.DbProvider.ExecuteDataSet(System.Data.CommandType.Text, cmdText).Tables[0]; + + StringCollection sc = new StringCollection(); + foreach (DataRow row in dt.Rows) + { + SOColumn column = new SOColumn + { + Parent = table, + Name = row["COLUMN_NAME"].ToString(), + DefaultValue = row["DATA_LENGTH"].ToString(), + Nullable = row["NULLABLE"].ToString().ToUpper() == "Y", + NativeType = row["DATA_TYPE"].ToString().Replace(" identity", ""), + //Identify = row["type_name"].ToString().IndexOf("identity") != -1, + Identify = false, + //ForeignKey + Length = ConvertUtil.ToInt32(row["CHAR_LENGTH"], 0), + Precision = ConvertUtil.ToInt32(row["DATA_PRECISION"], 0), + Scale = ConvertUtil.ToInt32(row["DATA_SCALE"], 0), + Comment = row["COMMENTS"].ToString() + }; + + column.PrimaryKey = pkList.Contains(column.Name); + column.DataType = this.GetDbType(column.NativeType, column.Precision, column.Scale); + + if (!sc.Contains(column.Name)) + { + columnList.Add(column); + } + + sc.Add(column.Name); + } + + return columnList; + } + + + /// + /// 获取表的Sql脚本 + /// + /// + /// + public override string GetTableSqlText(SOTable table) + { + throw new NotImplementedException(); + } + + /// + /// 获取视图列表 + /// + /// + /// + public override List GetViewList(SODatabase db) + { + string cmdText = string.Format("select VIEW_NAME,TEXT from dba_views where owner='{0}'", db.Name); + if (!IsDBA) + { + cmdText = string.Format("select VIEW_NAME,TEXT from user_views"); + } + SortedDictionary dic = new SortedDictionary(); + DataTable dt = this.DbProvider.ExecuteDataSet(System.Data.CommandType.Text, cmdText).Tables[0]; + + foreach (DataRow row in dt.Rows) + { + SOView view = new SOView { Parent = db, Name = row["VIEW_NAME"].ToString(), SqlText = row["TEXT"].ToString(), Owner = db.Name }; + view.SchemaName = view.Owner; + dic.Add(view.Name, view); + } + + return dic.Values.ToList(); + } + + /// + /// 获取视图的Sql脚本 + /// + /// + /// + public override string GetViewSqlText(SOView view) + { + return view.SqlText; + } + + /// + /// 获取存储过程列表 + /// + /// + /// + public override List GetCommandList(SODatabase db) + { + string cmdText = string.Format(@"select PROCEDURE_NAME from dba_procedures where owner='{0}'", db.Name); + if (!IsDBA) + { + cmdText = string.Format(@"select PROCEDURE_NAME from user_procedures"); + } + List commandList = new List(); + DataTable dt = this.DbProvider.ExecuteDataSet(System.Data.CommandType.Text, cmdText).Tables[0]; + + foreach (DataRow row in dt.Rows) + { + SOCommand command = new SOCommand { Parent = db, Name = row["PROCEDURE_NAME"].ToString(), Comment = row["PROCEDURE_NAME"].ToString() }; + commandList.Add(command); + } + + return commandList; + } + + /// + /// 获取存储过程参数列表 + /// + /// + /// + public override List GetCommandParameterList(SOCommand command) + { + string cmdText = string.Format(@"select * from all_arguments where owner='{0}' and package_name={1} order by position", command.Database.Name, command.Name); + if (!IsDBA) + { + cmdText = string.Format(@"select * from all_arguments where owner='{0}' and package_name={1} order by position", command.Database.Name, command.Name); + } + List columnList = new List(); + DataTable dt = this.DbProvider.ExecuteDataSet(System.Data.CommandType.Text, cmdText).Tables[0]; + + foreach (DataRow row in dt.Rows) + { + ParameterDirection direction = ParameterDirection.ReturnValue; + string pmode = row["IN_OUT"].ToString(); + if (pmode == "IN") direction = ParameterDirection.Input; + if (pmode == "OUT") direction = ParameterDirection.Output; + if (pmode == "IN/OUT") direction = ParameterDirection.InputOutput; + + SOCommandParameter param = new SOCommandParameter + { + Parent = command, + Name = row["ARGUMENT_NAME"].ToString(), + Direction = direction, + NativeType = row["DATA_TYPE"].ToString(), + Length = ConvertUtil.ToInt32(row["CHAR_LENGTH"], 0), + Precision = ConvertUtil.ToInt32(row["DATA_PRECISION"], 0), + Scale = ConvertUtil.ToInt32(row["DATA_SCALE"], 0), + }; + + param.DataType = this.GetDbType(param.NativeType); + columnList.Add(param); + } + + return columnList; + } + + /// + /// 获取存储过程的Sql脚本 + /// + /// + /// + public override string GetCommandSqlText(SOCommand command) + { + string cmdText = string.Format(@"select TEXT from dba_source where type='PROCEDURE' and owner='{0}' and name='{1}' order by line", command.Database.Name, command.Name); + if (!IsDBA) + { + cmdText = string.Format(@"select TEXT from user_source where type='PROCEDURE' and owner='{0}' and name='{1}' order by line", command.Database.Name, command.Name); + } + DataTable dt = this.DbProvider.ExecuteDataSet(System.Data.CommandType.Text, cmdText).Tables[0]; + StringBuilder sb = new StringBuilder(); + foreach (DataRow row in dt.Rows) + { + sb.AppendLine(row["TEXT"].ToString()); + } + + return sb.ToString(); + } + + /// + /// 获取.Net Framework数据类型 + /// + /// + /// + public override DbType GetDbType(string nativeType) + { + return TypeUtil.OracleDataType2DbType(nativeType); + } + + public DbType GetDbType(string nativeType, int precision = 0, int scale = 0) + { + return TypeUtil.OracleDataType2DbType(nativeType, precision, scale); + } + } +} diff --git a/src/Kalman/Data/DbSchemaProvider/SQLiteSchema.cs b/src/Kalman/Data/DbSchemaProvider/SQLiteSchema.cs new file mode 100644 index 0000000..6d90b65 --- /dev/null +++ b/src/Kalman/Data/DbSchemaProvider/SQLiteSchema.cs @@ -0,0 +1,115 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Kalman.Data.SchemaObject; +using System.Data; +using System.Data.Common; +using Kalman.Utilities; + +namespace Kalman.Data.DbSchemaProvider +{ + public class SQLiteSchema : DbSchema + { + public SQLiteSchema() + { + + } + + public SQLiteSchema(Database db) + { + base.DbProvider = db; + } + + public override string MetaDataCollectionName_Databases + { + get { return "Catalogs"; } + } + + public override DataSet ExecuteQuery(SODatabase db, string cmdText) + { + DataSet ds = new DataSet(); + using (DbConnection cn = base.DbProvider.DbProviderFactory.CreateConnection()) + { + cn.ConnectionString = base.DbProvider.ConnectionString; + cn.Open(); + + DbCommand cmd = base.DbProvider.DbProviderFactory.CreateCommand(); + cmd.Connection = cn; + cmd.CommandType = CommandType.Text; + cmd.CommandText = cmdText; + + DbDataAdapter adapter = base.DbProvider.DbProviderFactory.CreateDataAdapter(); + adapter.SelectCommand = cmd; + adapter.Fill(ds, 0, 100000, "temp"); + } + + return ds; + } + + public override List GetDatabaseList() + { + return new List + { + new SODatabase + { + Name = "Main", + Parent = this, + Comment = "Main" + } + }; + } + + public override List GetCommandList(SODatabase db) + { + return new List(); + } + + public override List GetCommandParameterList(SOCommand command) + { + return new List(); + } + + /// + /// 获取表的Sql脚本 + /// + /// + /// + public override string GetTableSqlText(SOTable table) + { + throw new NotImplementedException(); + } + + /// + /// 获取视图的Sql脚本 + /// + /// + /// + public override string GetViewSqlText(SOView view) + { + throw new NotImplementedException(); + } + + /// + /// 获取存储过程的Sql脚本 + /// + /// + /// + public override string GetCommandSqlText(SOCommand command) + { + throw new NotImplementedException(); + } + + /// + /// 获取.Net Framework数据类型 + /// + /// + /// + public override DbType GetDbType(string nativeType) + { + return TypeUtil.SQLiteDataType2DbType(nativeType); + } + + }//end class +} + diff --git a/src/Kalman/Data/DbSchemaProvider/SqlServerSchema.cs b/src/Kalman/Data/DbSchemaProvider/SqlServerSchema.cs new file mode 100644 index 0000000..7e96c5b --- /dev/null +++ b/src/Kalman/Data/DbSchemaProvider/SqlServerSchema.cs @@ -0,0 +1,438 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Kalman.Utilities; +using Kalman.Data.SchemaObject; +using System.Data; +using System.Collections; + +namespace Kalman.Data.DbSchemaProvider +{ + /// + /// SqlServerSchema + /// + public class SqlServerSchema : DbSchema + { + /// + /// + /// + /// + public SqlServerSchema(Database db) + { + base.DbProvider = db; + } + + Dictionary dic = new Dictionary(); + static object syncObject = new object(); + + string GetDBComment(SODatabase db) + { + string cmdText = string.Format(@"use [{0}]; + SELECT value as 'comment' + FROM fn_listextendedproperty(default, default, default, default, default, default, default); ",db.Name); + + return this.DbProvider.ExecuteScalar(CommandType.Text, cmdText); + } + + string GetTableComment(SOTable table) + { + string key = string.Format("{0}_{1}_{2}", table.Database.Name, table.Owner, table.Name); + + lock (syncObject) + { + if (dic.ContainsKey(key)) return dic[key]; + else + { + string cmdText = string.Format(@"use [{0}]; + SELECT objname as 'table_name', value as 'comment' + FROM fn_listextendedproperty (NULL, 'schema', '{1}', 'table', default, NULL, NULL); ", table.Database.Name, table.Owner); + DataTable dt = this.DbProvider.ExecuteDataSet(CommandType.Text, cmdText).Tables[0]; + foreach (DataRow row in dt.Rows) + { + string tempKey = string.Format("{0}_{1}_{2}", table.Database.Name, table.Owner, row["table_name"].ToString()); + if (dic.ContainsKey(tempKey)) continue; + dic.Add(tempKey, row["comment"].ToString()); + } + } + + if (dic.ContainsKey(key)) return dic[key]; + else return table.Name; + } + } + + string GetColumnComment(SOColumn column) + { + string key = string.Format("{0}_{1}_{2}", column.Database.Name, column.Parent.Name, column.Name); + + lock (syncObject) + { + if (dic.ContainsKey(key)) return dic[key]; + else + { + string cmdText = string.Format(@"use [{0}]; + SELECT major_id, minor_id, t.name AS 'table_name', c.name AS 'column_name', value AS 'comment' + FROM sys.extended_properties AS ep + INNER JOIN sys.tables AS t ON ep.major_id = t.object_id + INNER JOIN sys.columns AS c ON ep.major_id = c.object_id AND ep.minor_id = c.column_id + WHERE class = 1;", column.Database.Name); + DataTable dt = this.DbProvider.ExecuteDataSet(CommandType.Text, cmdText).Tables[0]; + foreach (DataRow row in dt.Rows) + { + string tempKey = string.Format("{0}_{1}_{2}", column.Database.Name, row["table_name"].ToString(), row["column_name"].ToString()); + if (dic.ContainsKey(tempKey)) continue; + dic.Add(tempKey, row["comment"].ToString()); + } + } + + if (dic.ContainsKey(key)) return dic[key]; + else return column.Name; + } + } + + //获取表的主键列 + List GetPrimaryKeys(SOTable table) + { + string cmdText = string.Format(@"use [{2}];exec sp_pkeys '{0}','{1}','{2}';", table.Name, table.Owner, table.Database.Name); + List list = new List(); + DataTable dt = this.DbProvider.ExecuteDataSet(System.Data.CommandType.Text, cmdText).Tables[0]; + + foreach (DataRow row in dt.Rows) + { + list.Add(row["column_name"].ToString()); + } + + return list; + } + + public override List GetDatabaseList() + { + List list = base.GetDatabaseList(); + SortedDictionary dic = new SortedDictionary(); + foreach (var item in list) + { + if (item.Name == "master" || item.Name == "model" || item.Name == "msdb" || item.Name == "tempdb") continue; + dic.Add(item.Name,item); + } + return dic.Values.ToList(); + } + + /// + /// 获取表列表 + /// + /// + /// + public override List GetTableList(SODatabase db) + { + string cmdText = string.Format("use [{0}];exec sp_tables;",db.Name); + SortedDictionary dic = new SortedDictionary(); + DataTable dt = this.DbProvider.ExecuteDataSet(System.Data.CommandType.Text, cmdText).Tables[0]; + + foreach (DataRow row in dt.Rows) + { + if (row["TABLE_TYPE"].ToString() != "TABLE") continue; + if (row["TABLE_OWNER"].ToString() == "sys") continue; + SOTable table = new SOTable { Parent = db, Name = row["TABLE_NAME"].ToString(), Owner = row["TABLE_OWNER"].ToString() }; + table.SchemaName = table.Owner; + table.Comment = GetTableComment(table); + dic.Add(table.Name,table); + } + + return dic.Values.ToList(); + } + + /// + /// 获取表所拥有的列列表 + /// + /// + /// + public override List GetTableColumnList(SOTable table) + { + string cmdText = string.Format(@"use [{2}];exec sp_columns '{0}','{1}','{2}';", table.Name, table.Owner, table.Database.Name); + + List columnList = new List(); + List pkList = GetPrimaryKeys(table); + DataTable dt = this.DbProvider.ExecuteDataSet(System.Data.CommandType.Text, cmdText).Tables[0]; + + foreach (DataRow row in dt.Rows) + { + SOColumn column = new SOColumn + { + Parent = table, + Name = row["column_name"].ToString(), + DefaultValue = row["column_def"].ToString(), + Nullable = row["is_nullable"].ToString().ToUpper() == "YES", + NativeType = row["type_name"].ToString().Replace(" identity",""), + Identify = row["type_name"].ToString().IndexOf("identity") != -1, + //ForeignKey + Length = ConvertUtil.ToInt32(row["length"], -1), + Precision = ConvertUtil.ToInt32(row["precision"], -1), + Scale = ConvertUtil.ToInt32(row["scale"], -1), + }; + + column.PrimaryKey = pkList.Contains(column.Name); + column.DataType = this.GetDbType(column.NativeType); + column.Comment = GetColumnComment(column); + columnList.Add(column); + } + + return columnList; + } + +// /// +// /// 获取表所拥有的索引列表 +// /// +// /// +// /// +// public override List GetTableIndexList(SOTable table) +// { +// string cmdText = string.Format(@"SELECT * +// FROM INFORMATION_SCHEMA.`constraints` +// WHERE table_schema='{0}' AND table_name='{1}';", table.Database.Name, table.Name); + +// List indexList = new List(); +// List columnList = GetTableColumnList(table); +// DataTable dt = this.DbProvider.ExecuteDataSet(System.Data.CommandType.Text, cmdText).Tables[0]; + +// foreach (DataRow row in dt.Rows) +// { +// SOIndex index = new SOIndex +// { +// Parent = table, +// Name = row["constraint_name"].ToString(), +// Comment = row["constraint_name"].ToString(), +// IsCluster = false, +// IsFullText = row["constraint_type"].ToString() == "Full Text", +// IsPrimaryKey = row["constraint_type"].ToString() == "PRIMARY KEY", +// IsUnique = row["constraint_type"].ToString() == "UNIQUE" +// }; +// indexList.Add(index); + +// string cmdText2 = string.Format(@"SELECT column_name +// FROM INFORMATION_SCHEMA.`statistics` +// WHERE table_schema='{0}' AND table_name='{1}';", table.Database.Name, table.Name); + +// DataTable dt2 = this.DbProvider.ExecuteDataSet(CommandType.Text, cmdText2).Tables[0]; +// index.Columns = new List(); +// foreach (DataRow row2 in dt2.Rows) +// { +// foreach (SOColumn column in columnList) +// { +// if (row2[0].ToString() == column.Name) index.Columns.Add(column); +// } +// } +// } + +// return indexList; +// } + + /// + /// 获取视图列表 + /// + /// + /// + public override List GetViewList(SODatabase db) + { + string cmdText = string.Format("use [{0}];exec sp_tables;", db.Name); + SortedDictionary dic = new SortedDictionary(); + DataTable dt = this.DbProvider.ExecuteDataSet(System.Data.CommandType.Text, cmdText).Tables[0]; + + foreach (DataRow row in dt.Rows) + { + if (row["TABLE_TYPE"].ToString() != "VIEW") continue; + if (row["TABLE_OWNER"].ToString() == "sys" || row["TABLE_OWNER"].ToString() == "INFORMATION_SCHEMA") continue; + SOView view = new SOView { Parent = db, Name = row["TABLE_NAME"].ToString(), Owner = row["TABLE_OWNER"].ToString() }; + view.SchemaName = view.Owner; + dic.Add(view.Name, view); + } + + return dic.Values.ToList(); + } + + /// + /// 获取视图所拥有的列列表 + /// + /// + /// + public override List GetViewColumnList(SOView view) + { + string cmdText = string.Format(@"use [{2}];exec sp_columns '{0}','{1}','{2}';", view.Name, view.Owner, view.Database.Name); + + List columnList = new List(); + DataTable dt = this.DbProvider.ExecuteDataSet(System.Data.CommandType.Text, cmdText).Tables[0]; + + foreach (DataRow row in dt.Rows) + { + SOColumn column = new SOColumn + { + Parent = view, + Name = row["column_name"].ToString(), + DefaultValue = row["column_def"].ToString(), + Nullable = row["is_nullable"].ToString().ToUpper() == "YES", + NativeType = row["type_name"].ToString().Replace(" identity", ""), + Identify = row["type_name"].ToString().IndexOf("identity") != -1, + //ForeignKey + Length = ConvertUtil.ToInt32(row["length"], -1), + Precision = ConvertUtil.ToInt32(row["precision"], -1), + Scale = ConvertUtil.ToInt32(row["scale"], -1), + }; + + column.DataType = this.GetDbType(column.NativeType); + column.Comment = GetColumnComment(column); + columnList.Add(column); + } + + return columnList; + } + +// /// +// /// 获取视图所拥有的索引列表 +// /// +// /// +// /// +// public override List GetViewIndexList(SOView view) +// { +// string cmdText = string.Format(@"SELECT * +// FROM INFORMATION_SCHEMA.`constraints` +// WHERE table_schema='{0}' AND table_name='{1}';", view.Database.Name, view.Name); + +// List indexList = new List(); +// List columnList = GetViewColumnList(view); +// DataTable dt = this.DbProvider.ExecuteDataSet(System.Data.CommandType.Text, cmdText).Tables[0]; + +// foreach (DataRow row in dt.Rows) +// { +// SOIndex index = new SOIndex +// { +// Parent = view, +// Name = row["constraint_name"].ToString(), +// Comment = row["constraint_name"].ToString(), +// IsCluster = false, +// IsFullText = row["constraint_type"].ToString() == "Full Text", +// IsPrimaryKey = row["constraint_type"].ToString() == "PRIMARY KEY", +// IsUnique = row["constraint_type"].ToString() == "UNIQUE" +// }; +// indexList.Add(index); + +// string cmdText2 = string.Format(@"SELECT column_name +// FROM INFORMATION_SCHEMA.`statistics` +// WHERE table_schema='{0}' AND table_name='{1}';", view.Database.Name, view.Name); + +// DataTable dt2 = this.DbProvider.ExecuteDataSet(CommandType.Text, cmdText2).Tables[0]; +// index.Columns = new List(); +// foreach (DataRow row2 in dt2.Rows) +// { +// foreach (SOColumn column in columnList) +// { +// if (row2[0].ToString() == column.Name) index.Columns.Add(column); +// } +// } +// } + +// return indexList; +// } + + /// + /// 获取存储过程列表 + /// + /// + /// + public override List GetCommandList(SODatabase db) + { + string cmdText = string.Format(@"use [{0}];SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE routine_catalog='{0}' AND routine_type='PROCEDURE';", db.Name); + + List commandList = new List(); + DataTable dt = this.DbProvider.ExecuteDataSet(System.Data.CommandType.Text, cmdText).Tables[0]; + + foreach (DataRow row in dt.Rows) + { + SOCommand command = new SOCommand { Parent = db, Name = row["routine_name"].ToString(), Comment = row["routine_name"].ToString() }; + commandList.Add(command); + } + + return commandList; + } + + /// + /// 获取存储过程参数列表 + /// + /// + /// + public override List GetCommandParameterList(SOCommand command) + { + string cmdText = string.Format(@"USE [{1}];SELECT routine_definition FROM INFORMATION_SCHEMA.PARAMETERS + WHERE SPECIFIC_schema='{0}' AND SPECIFIC_type='PROCEDURE' AND SPECIFIC_catalog='{1}' AND SPECIFIC_name='{2}';", + command.Owner ?? "dbo", command.Database.Name, command.Name); + + List columnList = new List(); + DataTable dt = this.DbProvider.ExecuteDataSet(System.Data.CommandType.Text, cmdText).Tables[0]; + + foreach (DataRow row in dt.Rows) + { + ParameterDirection direction = ParameterDirection.ReturnValue; + string pmode = row["PARAMETER_MODE"].ToString(); + if (pmode == "IN") direction = ParameterDirection.Input; + if (pmode == "OUT") direction = ParameterDirection.Output; + if (pmode == "INOUT") direction = ParameterDirection.InputOutput; + + SOCommandParameter param = new SOCommandParameter + { + Parent = command, + Name = row["PARAMETER_NAME"].ToString(), + Direction = direction, + NativeType = row["DATA_TYPE"].ToString().Replace(" identity", ""), + Length = ConvertUtil.ToInt32(row["CHARACTER_OCTET_LENGTH"], -1), + Precision = ConvertUtil.ToInt32(row["NUMERIC_PRECISION"], -1), + Scale = ConvertUtil.ToInt32(row["NUMERIC_SCALE"], -1), + }; + + param.DataType = this.GetDbType(param.NativeType); + columnList.Add(param); + } + + return columnList; + } + + ///// + ///// 获取表的Sql脚本 + ///// + ///// + ///// + //public override string GetTableSqlText(SOTable table) + //{ + // throw new NotImplementedException(); + //} + + /// + /// 获取视图的Sql脚本 + /// + /// + /// + public override string GetViewSqlText(SOView view) + { + string cmdText = string.Format("use [{0}];SELECT VIEW_DEFINITION FROM INFORMATION_SCHEMA.VIEWS WHERE table_schema='{1}' AND table_name='{2}';", view.Database.Name, view.Owner, view.Name); + string text = this.DbProvider.ExecuteScalar(System.Data.CommandType.Text, cmdText).ToString(); + return text; + } + + /// + /// 获取存储过程的Sql脚本 + /// + /// + /// + public override string GetCommandSqlText(SOCommand command) + { + string cmdText = string.Format(@"USE [{1}];SELECT routine_definition FROM INFORMATION_SCHEMA.ROUTINES + WHERE routine_schema='{0}' AND routine_type='PROCEDURE' AND routine_catalog='{1}' AND routine_name='{2}';", + command.Owner ?? "dbo", command.Database.Name, command.Name); + + string text = this.DbProvider.ExecuteScalar(System.Data.CommandType.Text, cmdText).ToString(); + return text; + } + + public override System.Data.DbType GetDbType(string nativeType) + { + return TypeUtil.SqlServerDataType2DbType(nativeType); + } + } +} diff --git a/src/Kalman/Data/IDbSchema.cs b/src/Kalman/Data/IDbSchema.cs new file mode 100644 index 0000000..dff530a --- /dev/null +++ b/src/Kalman/Data/IDbSchema.cs @@ -0,0 +1,140 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Kalman.Data.SchemaObject; +using System.Data; + +namespace Kalman.Data +{ + /// + /// + /// + public interface IDbSchema + { + /// + /// 获取或设置数据提供者实例 + /// + Database DbProvider { get; set; } + + /// + /// 获取数据库列表 + /// + /// + List GetDatabaseList(); + + /// + /// 获取表列表 + /// + /// + /// + List GetTableList(SODatabase db); + + /// + /// 获取表所拥有的列列表 + /// + /// + /// + List GetTableColumnList(SOTable table); + + /// + /// 获取表所拥有的索引列表 + /// + /// + /// + List GetTableIndexList(SOTable table); + + /// + /// 获取视图列表 + /// + /// + /// + List GetViewList(SODatabase db); + + /// + /// 获取视图所拥有的列列表 + /// + /// + /// + List GetViewColumnList(SOView view); + + /// + /// 获取视图所拥有的索引列表 + /// + /// + /// + List GetViewIndexList(SOView view); + + /// + /// 获取存储过程列表 + /// + /// + /// + List GetCommandList(SODatabase db); + + /// + /// 获取存储过程参数列表 + /// + /// + /// + List GetCommandParameterList(SOCommand command); + + /// + /// 获取表的Sql脚本 + /// + /// + /// + string GetTableSqlText(SOTable table); + + /// + /// 获取视图的Sql脚本 + /// + /// + /// + string GetViewSqlText(SOView view); + + /// + /// 获取存储过程的Sql脚本 + /// + /// + /// + string GetCommandSqlText(SOCommand command); + + /// + /// 基于DbConnection对象的元数据对象获取方法 + /// + /// 元数据集合名 + /// + DataTable GetSchema(string metaDataCollectionName); + + /// + /// 基于DbConnection对象的元数据对象获取方法 + /// + /// 元数据集合名 + /// 过滤条件 + /// + DataTable GetSchema(string metaDataCollectionName, string[] restrictions); + + /// + /// 获取.Net Framework数据类型 + /// + /// + /// + DbType GetDbType(string nativeType); + + /// + /// 以正确的目录大小写给定一个不带引号的标识符,返回该标识符的带引号的正确形式,包括正确转义该标识符中嵌入的任何引号。 + /// + /// + /// + string QuoteIdentifier(string name); + + /// + /// 在指定数据库上执行一个查询,返回一个结果集 + /// + /// + /// + /// + DataSet ExecuteQuery(SODatabase db, string cmdText); + } +} diff --git a/src/Kalman/Data/ParameterCache.cs b/src/Kalman/Data/ParameterCache.cs new file mode 100644 index 0000000..35af978 --- /dev/null +++ b/src/Kalman/Data/ParameterCache.cs @@ -0,0 +1,96 @@ +using System.Data; +using System.Data.Common; +using System; + +namespace Kalman.Data +{ + /// + /// + /// Provides parameter caching services for dynamic parameter discovery of stored procedures. + /// Eliminates the round-trip to the database to derive the parameters and types when a command + /// is executed more than once. + /// + /// + public class ParameterCache + { + private CachingMechanism cache = new CachingMechanism(); + + /// + /// + /// Populates the parameter collection for a command wrapper from the cache + /// or performs a round-trip to the database to query the parameters. + /// + /// + /// + /// The command to add the parameters. + /// + /// + /// The database to use to set the parameters. + /// + public void SetParameters(DbCommand command, Database database) + { + if (command == null) throw new ArgumentNullException("command"); + if (database == null) throw new ArgumentNullException("database"); + + + if (AlreadyCached(command, database)) + { + AddParametersFromCache(command, database); + } + else + { + database.DiscoverParameters(command); + IDataParameter[] copyOfParameters = CreateParameterCopy(command); + + this.cache.AddParameterSetToCache(database.ConnectionString, command, copyOfParameters); + } + } + + /// + /// Empties the parameter cache. + /// + protected internal void Clear() + { + this.cache.Clear(); + } + + /// + /// Adds parameters to a command using the cache. + /// + /// + /// The command to add the parameters. + /// + /// The database to use. + protected virtual void AddParametersFromCache(DbCommand command, Database database) + { + IDataParameter[] parameters = this.cache.GetCachedParameterSet(database.ConnectionString, command); + + foreach (IDataParameter p in parameters) + { + command.Parameters.Add(p); + } + } + + /// + /// Checks to see if a cache entry exists for a specific command on a specific connection + /// + /// + /// The command to check. + /// + /// The database to check. + /// True if the parameters are already cached for the provided command, false otherwise + private bool AlreadyCached(IDbCommand command, Database database) + { + return this.cache.IsParameterSetCached(database.ConnectionString, command); + } + + private static IDataParameter[] CreateParameterCopy(DbCommand command) + { + IDataParameterCollection parameters = command.Parameters; + IDataParameter[] parameterArray = new IDataParameter[parameters.Count]; + parameters.CopyTo(parameterArray, 0); + + return CachingMechanism.CloneParameters(parameterArray); + } + } +} diff --git a/src/Kalman/Data/SchemaObject/SOBase.cs b/src/Kalman/Data/SchemaObject/SOBase.cs new file mode 100644 index 0000000..83067c4 --- /dev/null +++ b/src/Kalman/Data/SchemaObject/SOBase.cs @@ -0,0 +1,92 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Kalman.Collections; +using System.Runtime.Serialization; +using Kalman.Utilities; + +namespace Kalman.Data.SchemaObject +{ + /// + /// 架构对象基类 + /// + [Serializable] + public abstract class SOBase + { + /// + /// 获取所属数据库对象 + /// + public abstract SODatabase Database { get; } + + /// + /// 用来标识对象的名称 + /// + public virtual string Name { get; set; } + + /// + /// 完整名称,比如"[dbo].[user]" + /// + public virtual string FullName { get { return this.Name; } } + + /// + /// 获取数据库对象的映射名称(代码中的类名或属性名) + /// + /// 前缀层次,默认1 + /// 分隔符,默认下划线 + /// + public string GetMappingName(int prefixLevel = 1, string separator = "_") + { + string mappingName = StringUtil.ToPascalName(StringUtil.RemovePrefix(this.Name, prefixLevel), separator); + return mappingName; + } + + /// + /// 对象的注释信息 + /// + public virtual string Comment { get; set; } + + [NonSerialized]//避免生成代码出现序列化错误 + SynchronizedDictionary extendProperties = new SynchronizedDictionary(); + + /// + /// 设置扩展属性 + /// 若指定属性不存在,则添加该属性,若指定属性已存在,则修改该属性 + /// + /// + /// + public virtual void SetValue(string name, object value) + { + if (extendProperties.ContainsKey(name)) + { + extendProperties[name] = value; + } + else + { + extendProperties.Add(name, value); + } + } + + /// + /// 获取扩展属性 + /// + /// + /// + public virtual object GetValue(string name) + { + if (extendProperties.ContainsKey(name)) + { + return extendProperties[name]; + } + else + { + return null; + } + } + + public override string ToString() + { + return this.Name; + } + } +} diff --git a/src/Kalman/Data/SchemaObject/SOColumn.cs b/src/Kalman/Data/SchemaObject/SOColumn.cs new file mode 100644 index 0000000..9774a4c --- /dev/null +++ b/src/Kalman/Data/SchemaObject/SOColumn.cs @@ -0,0 +1,198 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Data; + +namespace Kalman.Data.SchemaObject +{ + /// + /// 列架构对象 + /// + [Serializable] + public class SOColumn : SOBase + { + /// + /// 父对象,所属表或视图 + /// + public SOTableViewBase Parent { get; set; } + + /// + /// 是否主键 + /// + public bool PrimaryKey { get; set; } + + /// + /// 是否外键 + /// + public bool ForeignKey { get; set; } + + /// + /// 是否标志字段 + /// + public bool Identify { get; set; } + + /// + /// 原生类型,数据库定义的类型 + /// + public string NativeType { get; set; } + + /// + /// 数据类型,原生类型所对应的.Net Framework所定义的数据类型 + /// + public DbType DataType { get; set; } + + /// + /// 是否允许空值 + /// + public bool Nullable { get; set; } + + /// + /// 默认值 + /// + public string DefaultValue { get; set; } + + /// + /// 精度[字段长度] + /// + public int Precision { get; set; } + + /// + /// 小数位数 + /// + public int Scale { get; set; } + + /// + /// 长度,nchar(10),char(10)长度都是10,但nchar(10)的Size为20 + /// + public int Length { get; set; } + + /// + /// .net framework 类型 + /// + public Type Type + { + get + { + return Kalman.Utilities.TypeUtil.DbType2Type(DataType); + } + } + + /// + /// .net framework 类型的字符串表示,如"int"、"long" + /// + public string TypeString + { + get + { + return Kalman.Utilities.TypeUtil.DbType2TypeString(DataType); + } + } + + /// + /// 获取所属数据库对象 + /// + public override SODatabase Database + { + get { return Parent.Parent; } + } + + /// + /// 判断当前列是否数字类型 + /// + /// + public bool IsNumeric() + { + if ( + this.DataType == DbType.Int16 || + this.DataType == DbType.Int32 || + this.DataType == DbType.Int64 || + this.DataType == DbType.UInt16 || + this.DataType == DbType.UInt32 || + this.DataType == DbType.UInt64 || + this.DataType == DbType.Decimal || + this.DataType == DbType.Double || + this.DataType == DbType.SByte || + this.DataType == DbType.Byte || + this.DataType == DbType.Currency || + this.DataType == DbType.Single + ) + return true; + + return false; + } + + /// + /// 判断当前列是否整数类型 + /// + /// + public bool IsInt() + { + if ( + this.DataType == DbType.Int16 || + this.DataType == DbType.Int32 || + this.DataType == DbType.Int64 || + this.DataType == DbType.UInt16 || + this.DataType == DbType.UInt32 || + this.DataType == DbType.UInt64 || + this.DataType == DbType.SByte || + this.DataType == DbType.Byte + ) + return true; + + return false; + } + + /// + /// 判断当前列是否小数类型 + /// + /// + public bool IsDecimal() + { + if ( + this.DataType == DbType.Decimal || + this.DataType == DbType.Double || + this.DataType == DbType.Currency || + this.DataType == DbType.Single + ) + return true; + + return false; + } + + /// + /// 判断当前列是否日期类型 + /// + /// + public bool IsDateTime() + { + if ( + this.DataType == DbType.Date || + this.DataType == DbType.DateTime || + this.DataType == DbType.DateTime2 || + this.DataType == DbType.DateTimeOffset || + this.DataType == DbType.Time + ) + return true; + + return false; + } + + /// + /// 判断当前列是否字符串类型 + /// + /// + public bool IsString() + { + if ( + this.DataType == DbType.AnsiString || + this.DataType == DbType.AnsiStringFixedLength || + this.DataType == DbType.String || + this.DataType == DbType.StringFixedLength + ) + return true; + + return false; + } + } +} diff --git a/src/Kalman/Data/SchemaObject/SOCommand.cs b/src/Kalman/Data/SchemaObject/SOCommand.cs new file mode 100644 index 0000000..c5f167d --- /dev/null +++ b/src/Kalman/Data/SchemaObject/SOCommand.cs @@ -0,0 +1,103 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Data.Common; + +namespace Kalman.Data.SchemaObject +{ + /// + /// 存储过程架构对象 + /// + [Serializable] + public class SOCommand : SOBase + { + /// + /// 获取或设置父对象 + /// + public SODatabase Parent { get; set; } + + /// + /// 获取完整名称 + /// + public override string FullName + { + get + { + DbCommandBuilder cmdBuilder = Parent.Parent.DbProvider.DbProviderFactory.CreateCommandBuilder(); + string prifix = Owner; + if (string.IsNullOrEmpty(SchemaName) == false) prifix = SchemaName; + + string quotePrifix = string.Concat(cmdBuilder.QuotePrefix, prifix, cmdBuilder.QuoteSuffix); + string quoteName = string.Concat(cmdBuilder.QuotePrefix, this.Name, cmdBuilder.QuoteSuffix); + + if (string.IsNullOrEmpty(prifix)) + { + return quoteName; + } + else + { + return string.Format("{0}.{1}", quotePrifix, quoteName); + } + } + } + + /// + /// 获取或设置对象所有者 + /// + public string Owner { get; set; } + + /// + /// 所属架构名称,SqlServer2005+特有属性 + /// + public string SchemaName { get; set; } + + List _ParameterList; + /// + /// 获取或设置参数列表 + /// + public List ParameterList + { + get + { + if (_ParameterList == null && Parent != null && Parent.Parent != null) + { + return Parent.Parent.GetCommandParameterList(this); + } + else + { + return _ParameterList; + } + } + set { _ParameterList = value; } + } + + /// + /// 获取所属数据库对象 + /// + public override SODatabase Database + { + get { return Parent; } + } + + string _SqlText = string.Empty; + /// + /// 获取或设置存储过程Sql脚本 + /// + public string SqlText + { + get + { + if (string.IsNullOrEmpty(_SqlText) && Parent != null && Parent.Parent != null) + { + return Parent.Parent.GetCommandSqlText(this); + } + else + { + return _SqlText; + } + } + set { _SqlText = value; } + } + } +} diff --git a/src/Kalman/Data/SchemaObject/SOCommandParameter.cs b/src/Kalman/Data/SchemaObject/SOCommandParameter.cs new file mode 100644 index 0000000..8c0a99a --- /dev/null +++ b/src/Kalman/Data/SchemaObject/SOCommandParameter.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Data; + +namespace Kalman.Data.SchemaObject +{ + /// + /// 存储过程参数 + /// + [Serializable] + public class SOCommandParameter : SOBase + { + /// + /// 父对象,所属存储过程 + /// + public SOCommand Parent { get; set; } + + /// + /// 原生类型,数据库定义的类型 + /// + public string NativeType { get; set; } + + /// + /// 数据类型,原生类型所对应的.Net Framework所定义的数据类型 + /// + public DbType DataType { get; set; } + + /// + /// 参数方向 + /// + public ParameterDirection Direction { get; set; } + + /// + /// 默认值 + /// + public string DefaultValue { get; set; } + + /// + /// 精度[字段长度] + /// + public int Precision { get; set; } + + /// + /// 小数位数 + /// + public int Scale { get; set; } + + /// + /// 长度,nchar(10),char(10)长度都是10,但nchar(10)的Size为20 + /// + public int Length { get; set; } + + /// + /// 获取所属数据库对象 + /// + public override SODatabase Database + { + get { return Parent.Parent; } + } + } +} diff --git a/src/Kalman/Data/SchemaObject/SODatabase.cs b/src/Kalman/Data/SchemaObject/SODatabase.cs new file mode 100644 index 0000000..1ee4c7a --- /dev/null +++ b/src/Kalman/Data/SchemaObject/SODatabase.cs @@ -0,0 +1,156 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Kalman.Data.SchemaObject +{ + /// + /// 数据库架构对象 + /// + [Serializable] + public class SODatabase : SOBase + { + [NonSerialized]//避免生成代码出现序列化错误 + IDbSchema _Parent; + + /// + /// 获取或设置父对象 + /// + public IDbSchema Parent + { + get { return _Parent; } + set { _Parent = value; } + } + + bool _IsSystemDatabase = false; + /// + /// 是否是系统数据库 + /// + public bool IsSystemDatabase + { + get { return _IsSystemDatabase; } + set { _IsSystemDatabase = value; } + } + + /// + /// 获取所属数据库对象 + /// + public override SODatabase Database { get { return this; } } + + List _TableList; + /// + /// 获取或设置表列表 + /// + //public List TableList { get { return Parent == null ? null : Parent.GetTableList(this); } } + public List TableList + { + get + { + if (_TableList == null && Parent != null) + { + _TableList = Parent == null ? null : Parent.GetTableList(this); + } + return _TableList; + } + set + { + _TableList = value; + } + } + + List _ViewList; + /// + /// 获取或设置视图列表 + /// + //public List ViewList { get { return Parent == null ? null : Parent.GetViewList(this); } } + public List ViewList + { + get + { + if (_ViewList == null && Parent != null) + { + _ViewList = Parent == null ? null : Parent.GetViewList(this); + } + return _ViewList; + } + set + { + _ViewList = value; + } + } + + List _CommandList; + /// + /// 获取或设置存储过程列表 + /// + //public List CommandList { get { return Parent == null ? null : Parent.GetCommandList(this); } } + public List CommandList + { + get + { + if (_CommandList == null && Parent != null) + { + _CommandList = Parent == null ? null : Parent.GetCommandList(this); + } + return _CommandList; + } + set + { + _CommandList = value; + } + } + + public SOTable GetTable(string tableName) + { + List list = this.TableList; + SOTable table = null; + + foreach (SOTable item in list) + { + if (item.Name == tableName) + { + table = item; + break; + } + } + + return table; + } + + public SOView GetView(string viewName) + { + List list = this.ViewList; + SOView view = null; + + foreach (SOView item in list) + { + if (item.Name == viewName) + { + view = item; + break; + } + } + + return view; + } + + public SOCommand GetSP(string spName) + { + List list = this.CommandList; + SOCommand sp = null; + + foreach (SOCommand item in list) + { + if (item.Name == spName) + { + sp = item; + break; + } + } + + return sp; + } + + } +} diff --git a/src/Kalman/Data/SchemaObject/SOIndex.cs b/src/Kalman/Data/SchemaObject/SOIndex.cs new file mode 100644 index 0000000..dbb3710 --- /dev/null +++ b/src/Kalman/Data/SchemaObject/SOIndex.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Kalman.Data.SchemaObject +{ + /// + /// + /// + [Serializable] + public class SOIndex : SOBase + { + /// + /// 父对象,所属表或视图 + /// + public SOTableViewBase Parent { get; set; } + + /// + /// 是否聚簇索引 + /// + public bool IsCluster { get; set; } + + /// + /// 是否主键 + /// + public bool IsPrimaryKey { get; set; } + + /// + /// 是否唯一键 + /// + public bool IsUnique { get; set; } + + /// + /// 该索引列是否标识列(目前只有Access(OleDb)用到) + /// + public bool IsIdentity { get; set; } + + /// + /// 索引列表(目前只有Access(OleDb)用到) + /// + public string IndexColumnName { get; set; } + + /// + /// 是否全文索引(MySQL专用) + /// + public bool IsFullText { get; set; } + + /// + /// 索引成员列集合 + /// + public List Columns { get; set; } + + /// + /// 获取所属数据库对象 + /// + public override SODatabase Database + { + get { return Parent.Parent; } + } + } +} diff --git a/src/Kalman/Data/SchemaObject/SOSchemaBase.cs b/src/Kalman/Data/SchemaObject/SOSchemaBase.cs new file mode 100644 index 0000000..b9ad947 --- /dev/null +++ b/src/Kalman/Data/SchemaObject/SOSchemaBase.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Kalman.Data.SchemaObject +{ + /// + /// 具有Schema特性的对象基类,Schema对象用来标志数据库对象[如:SchemaName.ObjectName],如Table、View、StoreProcedure等,每个对象只能属于一个Schema + /// Schema概念的引入就是为了解决数据库对象太多不好管理的缺点,也就是将对象进行分类,目前只有SqlServer2005以上的版本支持 + /// + [Obsolete] + public abstract class SOSchemaBase : SOBase + { + public string SchemaName { get; set; } + } +} diff --git a/src/Kalman/Data/SchemaObject/SOTable.cs b/src/Kalman/Data/SchemaObject/SOTable.cs new file mode 100644 index 0000000..166cf06 --- /dev/null +++ b/src/Kalman/Data/SchemaObject/SOTable.cs @@ -0,0 +1,215 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Data.Common; +using System.Data; +using Kalman.Extensions; + +namespace Kalman.Data.SchemaObject +{ + /// + /// 表架构对象 + /// + [Serializable] + public class SOTable : SOTableViewBase + { + public SOTable() + { + + } + + /// + /// 以视图对象为原型创建一个表对象实例 + /// + /// + public SOTable(SOView view) + { + this.ColumnList = view.ColumnList; + this.Comment = view.Comment ?? string.Empty; + this.Name = view.Name; + this.Owner = view.Owner; + this.Parent = view.Parent; + this.SchemaName = view.SchemaName; + this.SqlText = view.SqlText; + } + + /// + /// 获取完整名称 + /// + public override string FullName + { + get + { + DbCommandBuilder cmdBuilder = Parent.Parent.DbProvider.DbProviderFactory.CreateCommandBuilder(); + string prifix = Owner; + if (string.IsNullOrEmpty(SchemaName) == false) prifix = SchemaName; + + string quotePrifix = string.Concat(cmdBuilder.QuotePrefix, prifix, cmdBuilder.QuoteSuffix); + string quoteName = string.Concat(cmdBuilder.QuotePrefix, this.Name, cmdBuilder.QuoteSuffix); + + if (string.IsNullOrEmpty(prifix)) + { + return quoteName; + } + else + { + return string.Format("{0}.{1}", quotePrifix, quoteName); + } + } + } + + /// + /// 获取或设置所属架构名称,SqlServer2005+特有属性 + /// + public string SchemaName { get; set; } + + List _ColumnList; + /// + /// 获取或设置列列表 + /// + public override List ColumnList + { + get + { + if (_ColumnList == null && Parent != null && Parent.Parent != null) + { + _ColumnList = Parent.Parent.GetTableColumnList(this); + } + return _ColumnList; + } + set { _ColumnList = value; } + } + + List _IndexList; + /// + /// 获取或设置视图列表 + /// + public override List IndexList + { + get + { + if (_IndexList == null && Parent != null && Parent.Parent != null) + { + _IndexList = Parent.Parent.GetTableIndexList(this); + } + return _IndexList; + } + set { _IndexList = value; } + } + + string _SqlText = string.Empty; + /// + /// 获取或设置表Sql脚本 + /// + public override string SqlText + { + get + { + if (string.IsNullOrEmpty(_SqlText) && Parent != null && Parent.Parent != null) + { + _SqlText = Parent.Parent.GetTableSqlText(this); + } + return _SqlText; + } + set { _SqlText = value; } + } + + List _PrimaryKeys = new List(); + + /// + /// 获取或设置表的主键列 + /// + public List PrimaryKeys + { + get + { + if (_PrimaryKeys.Count ==0) + { + List list = this.ColumnList; + foreach (var item in list) + { + if (item.PrimaryKey && !_PrimaryKeys.Contains(item)) + { + _PrimaryKeys.Add(item); + } + } + } + + return _PrimaryKeys; + } + set + { + _PrimaryKeys = value; + } + } + + public SOColumn PrimaryKey + { + get + { + if (PrimaryKeys == null || PrimaryKeys.Count == 0) return null; + return PrimaryKeys[0]; + } + } + + /// + /// 索引器 + /// + /// 列名 + /// + public SOColumn this[string columnName] + { + get + { + var col = ColumnList.Find(p => p.Name == columnName); + return col; + } + } + + /// + /// 是否存在列 + /// + /// 列名 + /// 存在返回true,否则返回false + public bool IsExistColumn(string columnName) + { + var col = this.ColumnList.Find(p => p.Name == columnName); + return col != null; + } + + /// + /// 主键字段是否是自增列(主键字段为一个的情况下),暂时不支持oracle + /// + /// + public bool IsAutoID() + { + if (PrimaryKeys.Count != 1) return false; + + return PrimaryKeys[0].Identify; + } + + public DataTable Query(List columnList, string where = "") + { + string cmdText = string.Empty; + IDbSchema dbSchema = this.Database.Parent; + StringBuilder sb = new StringBuilder(); + + columnList.ForEach(s => sb.AppendFormat("{0},", dbSchema.QuoteIdentifier(s))); + + if (!string.IsNullOrEmpty(where)) + { + cmdText = string.Format("SELECT {0} FROM {0} WHERE {2}", sb.ToString().TrimEnd(','), this.Name, where); + } + else + { + cmdText = string.Format("SELECT {0} FROM {0}", sb.ToString().TrimEnd(','), this.Name); + } + + DataTable dt = dbSchema.ExecuteQuery(this.Database, cmdText).Tables[0]; + return dt; + } + + + } +} diff --git a/src/Kalman/Data/SchemaObject/SOTableViewBase.cs b/src/Kalman/Data/SchemaObject/SOTableViewBase.cs new file mode 100644 index 0000000..8560b47 --- /dev/null +++ b/src/Kalman/Data/SchemaObject/SOTableViewBase.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Kalman.Data.SchemaObject +{ + [Serializable] + public abstract class SOTableViewBase : SOBase + { + /// + /// 获取所属数据库对象 + /// + public override SODatabase Database + { + get + { + return this.Parent; + } + } + + /// + /// 获取或设置父对象 + /// + public SODatabase Parent { get; set; } + + /// + /// 获取或设置对象所有者 + /// + public string Owner { get; set; } + + /// + /// 获取列列表 + /// + public abstract List ColumnList { get; set; } + + /// + /// 获取索引列表 + /// + public abstract List IndexList { get; set; } + + /// + /// 获取Sql脚本 + /// + public abstract string SqlText { get; set; } + } +} diff --git a/src/Kalman/Data/SchemaObject/SOView.cs b/src/Kalman/Data/SchemaObject/SOView.cs new file mode 100644 index 0000000..d0eebb6 --- /dev/null +++ b/src/Kalman/Data/SchemaObject/SOView.cs @@ -0,0 +1,105 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Data.Common; + +namespace Kalman.Data.SchemaObject +{ + /// + /// 视图架构对象 + /// + [Serializable] + public class SOView : SOTableViewBase + { + /// + /// 获取完整名称 + /// + public override string FullName + { + get + { + DbCommandBuilder cmdBuilder = Parent.Parent.DbProvider.DbProviderFactory.CreateCommandBuilder(); + string prifix = Owner; + if (string.IsNullOrEmpty(SchemaName) == false) prifix = SchemaName; + + string quotePrifix = string.Concat(cmdBuilder.QuotePrefix, prifix, cmdBuilder.QuoteSuffix); + string quoteName = string.Concat(cmdBuilder.QuotePrefix, this.Name, cmdBuilder.QuoteSuffix); + + if (string.IsNullOrEmpty(prifix)) + { + return quoteName; + } + else + { + return string.Format("{0}.{1}", quotePrifix, quoteName); + } + } + } + + /// + /// 获取或设置所属架构名称,SqlServer2005+特有属性 + /// + public string SchemaName { get; set; } + + List _ColumnList; + /// + /// 获取或设置列列表 + /// + public override List ColumnList + { + get + { + if (_ColumnList == null && Parent != null && Parent.Parent != null) + { + return Parent.Parent.GetViewColumnList(this); + } + else + { + return _ColumnList; + } + } + set { _ColumnList = value; } + } + + List _IndexList; + /// + /// 获取或设置视图列表 + /// + public override List IndexList + { + get + { + if (_IndexList == null && Parent != null && Parent.Parent != null) + { + return Parent.Parent.GetViewIndexList(this); + } + else + { + return _IndexList; + } + } + set { _IndexList = value; } + } + + string _SqlText = string.Empty; + /// + /// 获取或设置表Sql脚本 + /// + public override string SqlText + { + get + { + if (string.IsNullOrEmpty(_SqlText) && Parent != null && Parent.Parent != null) + { + return Parent.Parent.GetViewSqlText(this); + } + else + { + return _SqlText; + } + } + set { _SqlText = value; } + } + } +} diff --git a/src/Kalman/Data/TransactionScopeConnections.cs b/src/Kalman/Data/TransactionScopeConnections.cs new file mode 100644 index 0000000..5de9fb9 --- /dev/null +++ b/src/Kalman/Data/TransactionScopeConnections.cs @@ -0,0 +1,104 @@ +using System; +using System.Collections.Generic; +using System.Data.Common; +using System.Transactions; + +namespace Kalman.Data +{ + /// + /// This class manages the connections that will be used when transactions are active + /// as a result of instantiating a . When a transaction + /// is active, all database access must be through this single connection unless you want + /// to use a distributed transaction, which is an expensive operation. + /// + public static class TransactionScopeConnections + { + // There's a reason why this field is not thread-static: notifications for completed oracle transactions + // may happen in a different thread + static readonly Dictionary> transactionConnections = + new Dictionary>(); + + /// + /// Returns a connection for the current transaction. This will be an existing + /// instance or a new one if there is a active. Otherwise this method + /// returns null. + /// + /// + /// Either a instance or null. + public static DbConnection GetConnection(Database db) + { + Transaction currentTransaction = Transaction.Current; + + if (currentTransaction == null) + return null; + + Dictionary connectionList; + DbConnection connection; + + lock (transactionConnections) + { + if (!transactionConnections.TryGetValue(currentTransaction, out connectionList)) + { + // We don't have a list for this transaction, so create a new one + connectionList = new Dictionary(); + transactionConnections.Add(currentTransaction, connectionList); + + // We need to know when this previously unknown transaction is completed too + currentTransaction.TransactionCompleted += OnTransactionCompleted; + } + } + + lock (connectionList) + { + // Next we'll see if there is already a connection. If not, we'll create a new connection and add it + // to the transaction's list of connections. + // This collection should only be modified by the thread where the transaction scope was created + // while the transaction scope is active. + // However there's no documentation to confirm this, so we err on the safe side and lock. + if (!connectionList.TryGetValue(db.ConnectionString, out connection)) + { + // we're betting the cost of acquiring a new finer-grained lock is less than + // that of opening a new connection, and besides this allows threads to work in parallel + connection = db.GetNewOpenConnection(); + connectionList.Add(db.ConnectionString, connection); + } + } + + return connection; + } + + /// + /// This event handler is called whenever a transaction is about to be disposed, which allows + /// us to remove the transaction from our list and dispose the connection instance we created. + /// + /// + /// + static void OnTransactionCompleted(object sender, TransactionEventArgs e) + { + Dictionary connectionList; + + lock (transactionConnections) + { + if (!transactionConnections.TryGetValue(e.Transaction, out connectionList)) + { + // we don't know about this transaction. odd. + return; + } + + // we know about this transaction - remove it from the mappings + transactionConnections.Remove(e.Transaction); + } + + lock (connectionList) + { + // acquiring this lock should not be necessary unless there's a possibility for this event to be fired + // while the transaction involved in the event is still set as the current transaction for a + // different thread. + foreach (DbConnection connection in connectionList.Values) + { + connection.Dispose(); + } + } + } + } +} diff --git a/src/Kalman/Data/UpdateBehavior.cs b/src/Kalman/Data/UpdateBehavior.cs new file mode 100644 index 0000000..77a275b --- /dev/null +++ b/src/Kalman/Data/UpdateBehavior.cs @@ -0,0 +1,21 @@ +namespace Kalman.Data +{ + /// + /// 使用Database.UpdateDataSet方法当DataAdapter的更新命令遇到错误时,选择采用哪种更新行为 + /// + public enum UpdateBehavior + { + /// + /// 标准行为,更新数据时遇到错误后终止,剩下的数据行不再更新 + /// + Standard, + /// + /// 更新数据时遇到错误后继续更新后面的数据行 + /// + Continue, + /// + /// 使用实物,所有更新过的数据行自动回滚 + /// + Transactional + } +} diff --git a/src/Kalman/Data/config.xml b/src/Kalman/Data/config.xml new file mode 100644 index 0000000..a3da1b3 --- /dev/null +++ b/src/Kalman/Data/config.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Kalman/DynamicBuilder.cs b/src/Kalman/DynamicBuilder.cs new file mode 100644 index 0000000..2dc60af --- /dev/null +++ b/src/Kalman/DynamicBuilder.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Reflection.Emit; +using System.Reflection; +using System.Data; + +namespace Kalman +{ + [Obsolete("请使用ConvertUtil类中的ToObject和ToList方法来映射实体")] + public class DynamicBuilder + { + private static readonly MethodInfo getValueMethod = + typeof(IDataRecord).GetMethod("get_Item", new Type[] { typeof(int) }); + private static readonly MethodInfo isDBNullMethod = + typeof(IDataRecord).GetMethod("IsDBNull", new Type[] { typeof(int) }); + private delegate T Load(IDataRecord dataRecord); + private Load handler; + + private DynamicBuilder() { } + + public T Build(IDataRecord dataRecord) + { + return handler(dataRecord); + } + + public static DynamicBuilder CreateBuilder(IDataRecord dataRecord) + { + DynamicBuilder dynamicBuilder = new DynamicBuilder(); + + DynamicMethod method = new DynamicMethod("DynamicCreate", typeof(T), + new Type[] { typeof(IDataRecord) }, typeof(T), true); + ILGenerator generator = method.GetILGenerator(); + + LocalBuilder result = generator.DeclareLocal(typeof(T)); + generator.Emit(OpCodes.Newobj, typeof(T).GetConstructor(Type.EmptyTypes)); + generator.Emit(OpCodes.Stloc, result); + + for (int i = 0; i < dataRecord.FieldCount; i++) + { + PropertyInfo propertyInfo = typeof(T).GetProperty(dataRecord.GetName(i)); + Label endIfLabel = generator.DefineLabel(); + + if (propertyInfo != null && propertyInfo.GetSetMethod() != null) + { + generator.Emit(OpCodes.Ldarg_0); + generator.Emit(OpCodes.Ldc_I4, i); + generator.Emit(OpCodes.Callvirt, isDBNullMethod); + generator.Emit(OpCodes.Brtrue, endIfLabel); + + generator.Emit(OpCodes.Ldloc, result); + generator.Emit(OpCodes.Ldarg_0); + generator.Emit(OpCodes.Ldc_I4, i); + generator.Emit(OpCodes.Callvirt, getValueMethod); + generator.Emit(OpCodes.Unbox_Any, dataRecord.GetFieldType(i)); + generator.Emit(OpCodes.Callvirt, propertyInfo.GetSetMethod()); + + generator.MarkLabel(endIfLabel); + } + } + + generator.Emit(OpCodes.Ldloc, result); + generator.Emit(OpCodes.Ret); + + dynamicBuilder.handler = (Load)method.CreateDelegate(typeof(Load)); + return dynamicBuilder; + } + } +} diff --git a/src/Kalman/Extensions/ByteExt.cs b/src/Kalman/Extensions/ByteExt.cs new file mode 100644 index 0000000..26182ec --- /dev/null +++ b/src/Kalman/Extensions/ByteExt.cs @@ -0,0 +1,118 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.IO; +using System.Security.Cryptography; +using Kalman.Security; +using Kalman.Utilities; + +namespace Kalman.Extensions +{ + public static class ByteExt + { + /// + /// 转十六进制 + /// + /// + /// + public static string ToHex(this byte b) + { + return ByteUtil.ToHex(b); + } + + /// + /// 转十六进制 + /// + /// + /// + public static string ToHex(this IEnumerable bytes) + { + return ByteUtil.ToHex(bytes); + } + + /// + /// 将 8 位无符号整数数组转换为它的等效 System.String 表示形式(使用 Base 64 数字编码) + /// + /// + /// + public static string ToBase64String(this byte[] data) + { + return ByteUtil.ToBase64String(data); + } + + /// + /// 返回由字节数组中指定位置的八个字节转换来的 32 位有符号整数 + /// + /// + /// + /// + public static int ToInt(this byte[] data, int startIndex) + { + return ByteUtil.ToInt(data, startIndex); + } + + /// + /// 返回由字节数组中指定位置的八个字节转换来的 64 位有符号整数 + /// + /// + /// + /// + public static long ToInt64(this byte[] data, int startIndex) + { + return ByteUtil.ToInt64(data, startIndex); + } + + /// + /// 转换为指定编码字符串 + /// + /// + /// + /// + public static string Decode(this byte[] data, Encoding encoding) + { + return ByteUtil.Decode(data, encoding); + } + + /// + /// 保存到文件 + /// + /// + /// + public static void Save(this byte[] data, string path) + { + ByteUtil.Save(data, path); + } + + /// + /// 保存到内存流 + /// + /// + /// + public static MemoryStream ToMemoryStream(this byte[] data) + { + return ByteUtil.ToMemoryStream(data); + } + + /// + /// 使用指定哈希算法计算哈希值 + /// + /// + /// + /// + public static byte[] ComputeHash(this byte[] data, HashAlgorithmType hashAlgorithmType) + { + return ByteUtil.ComputeHash(data, hashAlgorithmType); + } + + /// + /// 使用默认Hash算法SHA1计算哈希值 + /// + /// + /// + public static byte[] ComputeHash(this byte[] data) + { + return ByteUtil.ComputeHash(data); + } + } +} diff --git a/src/Kalman/Extensions/CollectionExt.cs b/src/Kalman/Extensions/CollectionExt.cs new file mode 100644 index 0000000..f91f4f2 --- /dev/null +++ b/src/Kalman/Extensions/CollectionExt.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Kalman.Utilities; +using System.Collections; +using System.Collections.Specialized; + +namespace Kalman.Extensions +{ + public static class CollectionExt + { + /// + /// 将集合对象转换为指定字符分隔的字符串 + /// + /// 集合对象 + /// 分隔字符 + /// + public static string Implode(this ICollection collection, string separator) + { + return CollectionUtil.Implode(collection, separator); + } + + /// + /// 将NameValueCollection集合转换成字符串 + /// + /// NameValueCollection集合对象 + /// + public static string FormatToString(this NameValueCollection nvc) + { + return CollectionUtil.FormatToString(nvc); + } + + /// + /// 将NameValueCollection集合转换成字符串 + /// + /// 集合对象 + /// 转换格式,如:"{0}={1}",{0}表示Name,{1}表示Value + /// 分隔符,如:& + /// + public static string FormatToString(this NameValueCollection nvc, string format, string separator) + { + return CollectionUtil.FormatToString(nvc, format, separator); + } + + /// + /// 将IDictionary集合转换成字符串 + /// + /// 集合对象 + /// 转换格式,如:"{0}={1}",{0}表示Key,{1}表示Value + /// 分隔符,如:& + /// + public static string FormatToString(this IDictionary dic, string format, string separator) + { + return CollectionUtil.FormatToString(dic, format, separator); + } + + /// + /// 将IDictionary泛型集合转换成字符串 + /// + /// 泛型集合对象 + /// 转换格式,如:"{0}={1}",{0}表示Key,{1}表示Value + /// 分隔符,如:& + /// + public static string FormatToString(this IDictionary dic, string format, string separator) + { + return CollectionUtil.FormatToString(dic, format, separator); + } + } +} diff --git a/src/Kalman/Extensions/DataExt.cs b/src/Kalman/Extensions/DataExt.cs new file mode 100644 index 0000000..8abdda2 --- /dev/null +++ b/src/Kalman/Extensions/DataExt.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Data; +using Kalman.Utilities; + +namespace Kalman.Extensions +{ + public static class DataExt + { + ///// + ///// 将IDataReader转换成对象实体列表 + ///// + ///// + ///// 目标对象类型 + ///// + //public static List ToList(this IDataReader reader) where T : class, new() + //{ + // return ConvertUtil.ToList(reader); + //} + + ///// + ///// 将IDataReader转换成对象实体 + ///// + ///// 目标对象类型 + ///// + ///// + //public static T ToObject(this IDataReader reader) where T : class, new() + //{ + // return ConvertUtil.ToObject(reader); + //} + } +} diff --git a/src/Kalman/Extensions/ObjectExt.cs b/src/Kalman/Extensions/ObjectExt.cs new file mode 100644 index 0000000..cb93920 --- /dev/null +++ b/src/Kalman/Extensions/ObjectExt.cs @@ -0,0 +1,119 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Reflection; +using System.ComponentModel; +using System.Runtime.Serialization.Formatters.Binary; +using System.IO; + +namespace Kalman.Extensions +{ + public static class ObjectExt + { + public static string ToString(this object obj, string defaultValue) + { + if (obj == null) return defaultValue; + else return obj.ToString(); + } + + /// + /// 将对象属性数据保存到字典 + /// + /// + /// + public static Dictionary ToDictionary(this object value) + { + Dictionary result = new Dictionary(); + PropertyInfo[] props = value.GetType().GetProperties(); + foreach (PropertyInfo pi in props) + { + try + { + result.Add(pi.Name, pi.GetValue(value, null)); + } + catch { } + } + return result; + } + + /// + /// 从字典中还原对象属性数据 + /// + /// + /// + /// + /// + public static T FromDictionary(this Dictionary settings, T item) where T : class + { + PropertyInfo[] props = item.GetType().GetProperties(); + FieldInfo[] fields = item.GetType().GetFields(); + foreach (PropertyInfo pi in props) + { + if (settings.ContainsKey(pi.Name)) + { + if (pi.CanWrite) + pi.SetValue(item, settings[pi.Name], null); + } + } + return item; + } + + /// + /// 将对象属性数据拷贝到另一个同类型对象 + /// + /// + /// + /// + /// + public static T CopyTo(this object From, T to) where T : class + { + Type t = From.GetType(); + var settings = From.ToDictionary(); + + to = settings.FromDictionary(to); + return to; + } + + /// + /// 类型转换 + /// + /// 目标类型 + /// + /// + public static T ConvertType(this object obj) + { + if (typeof(T) == typeof(Guid)) + { + if (obj == null) + { + return (T)((object)Guid.Empty); + } + return (T)((object)new Guid(obj.ToString())); + } + if (obj is DBNull || obj == null) + { + return default(T); + } + return (T)Convert.ChangeType(obj, typeof(T)); + } + + /// + /// 实现对象的深拷贝 + /// + /// + /// + /// + public static T DeepClone(this T obj) + { + using (var ms = new MemoryStream()) + { + BinaryFormatter bf = new BinaryFormatter(); + bf.Serialize(ms, obj); + + ms.Position = 0; + return (T)bf.Deserialize(ms); + } + } + } +} diff --git a/src/Kalman/Extensions/StringExtension/StringExt.CodeBuilder.cs b/src/Kalman/Extensions/StringExtension/StringExt.CodeBuilder.cs new file mode 100644 index 0000000..5caeed4 --- /dev/null +++ b/src/Kalman/Extensions/StringExtension/StringExt.CodeBuilder.cs @@ -0,0 +1,79 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Kalman.Utilities; + +namespace Kalman.Extensions +{ + public static partial class StringExt + { + #region 代码生成器常用的一些字符串处理扩展方法,比如表名前缀的处理 + + /// + /// 将字符串的首字母转换成大写,比如将user转换成User + /// + /// + /// + public static string InitialToUpper(this string s) + { + return StringUtil.InitialToUpper(s); + } + + /// + /// 将字符串的首字母转换成小写,比如将User转换成user + /// + /// + /// + public static string InitialToLower(this string s) + { + return StringUtil.InitialToLower(s); + } + + /// + /// 专用方法,将类似aaa_bbb_ccc_ddd的字符串转换为AaaBbbCccDdd + /// + /// + /// + public static string InitialToUpperMulti(this string s) + { + return StringUtil.InitialToUpperMulti(s); + } + + /// + /// 移除字符串的前缀,示例:"aa_bb_cc_xxx".RemovePrefix("aa_bb_");结果为"cc_xxx"; + /// + /// + /// + /// + public static string RemovePrefix(this string s, string prefix) + { + return StringUtil.RemovePrefix(s,prefix); + } + + /// + /// 移除字符串的前缀,默认前缀分隔符是下划线"_",示例:"aa_bb_cc_xxx".RemovePrefix(2);结果为"cc_xxx"; + /// + /// + /// + /// + public static string RemovePrefix(this string s, int level) + { + return StringUtil.RemovePrefix(s, level); + } + + /// + /// 移除字符串的前缀,示例:"aa_bb_cc_xxx".RemovePrefix("_",2);结果为"cc_xxx"; + /// + /// + /// 前缀分隔符,一般为下划线"_" + /// 前缀层次 + /// + public static string RemovePrefix(this string s, string separator, int level) + { + return StringUtil.RemovePrefix(s, separator, level); + } + + #endregion + } +} diff --git a/src/Kalman/Extensions/StringExtension/StringExt.Format.cs b/src/Kalman/Extensions/StringExtension/StringExt.Format.cs new file mode 100644 index 0000000..8bf1f31 --- /dev/null +++ b/src/Kalman/Extensions/StringExtension/StringExt.Format.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Web.UI; + +namespace Kalman.Extensions +{ + /// + /// 字符串格式化相关的扩展方法 + /// + public static partial class StringExt + { + public static string FormatWith(this string format, params object[] args) + { + return format.FormatWith(null, args); + } + + public static string FormatWith(this string format, IFormatProvider provider, params object[] args) + { + if (format == null) + throw new ArgumentNullException("format"); + + return string.Format(provider, format, args); + } + + public static string FormatWith(this string format, object source) + { + return FormatWith(format, null, source); + } + + public static string FormatWith(this string format, IFormatProvider provider, object source) + { + if (format == null) + throw new ArgumentNullException("format"); + + Regex r = new Regex(@"(?\{)+(?[\w\.\[\]]+)(?:[^}]+)?(?\})+", + RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase); + + List values = new List(); + string rewrittenFormat = r.Replace(format, delegate(Match m) + { + Group startGroup = m.Groups["start"]; + Group propertyGroup = m.Groups["property"]; + Group formatGroup = m.Groups["format"]; + Group endGroup = m.Groups["end"]; + + values.Add((propertyGroup.Value == "0") + ? source + : DataBinder.Eval(source, propertyGroup.Value)); + + return new string('{', startGroup.Captures.Count) + (values.Count - 1) + formatGroup.Value + + new string('}', endGroup.Captures.Count); + }); + + return string.Format(provider, rewrittenFormat, values.ToArray()); + } + } +} diff --git a/src/Kalman/Extensions/StringExtension/StringExt.Html.cs b/src/Kalman/Extensions/StringExtension/StringExt.Html.cs new file mode 100644 index 0000000..40ccc40 --- /dev/null +++ b/src/Kalman/Extensions/StringExtension/StringExt.Html.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using Kalman.Utilities; + +namespace Kalman.Extensions +{ + /// + /// Html相关的字符串处理方法 + /// + public static partial class StringExt + { + /// + /// 对Html文本字符串进行编码 + /// + /// + /// + public static string HtmlEncode(this string s) + { + return StringUtil.HtmlEncode(s); + } + + /// + /// 对Html文本字符串进行解码 + /// + public static string HtmlDecode(this string s) + { + return StringUtil.HtmlDecode(s); + } + + /// + /// 移除字符串中所有的HTML标签 + /// + public static string RemoveHtml(this string s) + { + return StringUtil.RemoveHtml(s); + } + + /// + /// 移除字符串中在指定集合中所包含的HTML标签,标签名称不区分大小写 + /// + /// + /// + /// + public static string RemoveHtml(this string s, IList removeTags) + { + return StringUtil.RemoveHtml(s, removeTags); + } + + /// + /// 移除字符串不安全的HTML代码,例如"script,iframe"等 + /// + public static string RemoveUnsafeHtml(this string s) + { + return StringUtil.RemoveUnsafeHtml(s); + } + } +} diff --git a/src/Kalman/Extensions/StringExtension/StringExt.cs b/src/Kalman/Extensions/StringExtension/StringExt.cs new file mode 100644 index 0000000..a6e61d0 --- /dev/null +++ b/src/Kalman/Extensions/StringExtension/StringExt.cs @@ -0,0 +1,209 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Security.Cryptography; +using Kalman.Utilities; +using Kalman.Security; + +namespace Kalman.Extensions +{ + /// + /// Stirng类型扩展方法 + /// 注:这里所有方法的实现都封装在StringUtil类中 + /// + public static partial class StringExt + { + /// + /// 将字符串首字母转成大写 + /// + //public static string InitialToUpper(this string s) + //{ + // return StringUtil.InitialToUpper(s); + //} + + /// + /// 转全角(SBC case) + /// + /// 任意字符串 + /// 全角字符串 + public static string ToSBC(this string s) + { + return StringUtil.ToSBC(s); + } + + /// + /// 转半角(DBC case) + /// + public static string ToDBC(this string s) + { + return StringUtil.ToDBC(s); + } + + /// + /// 裁剪字符串,对Substring方法的改良,参数超出范围不抛出异常 + /// 若裁剪起始位置startIndex超出字符串长度,则返回空字符串,若裁剪长度length超出范围,则返回从startIndex开始的全部字符 + /// + /// + /// + /// + /// + public static string CutString(this string s, int startIndex, int length) + { + return StringUtil.CutString(s, startIndex, length); + } + + /// + /// 返回指定加密哈希算法的字符串的副本 + /// + /// + /// 哈希算法 + /// + public static string ToHash(this string s, HashAlgorithmType hashAlgorithm) + { + return StringUtil.ToHash(s, hashAlgorithm); + } + + /// + /// 判断字符串是否都是有空白字符组成,空字符串将返回false + /// + /// 如果该字符串都是空白字符,返回true ,否则返回false + public static bool IsWhiteSpace(this string s) + { + return StringUtil.IsWhiteSpace(s); + } + + /// + /// 判断字符串是否含有空白字符 + /// + /// 如果该字符串含有空白字符,返回true ,否则返回false + public static bool HasWhiteSpace(this string s) + { + return StringUtil.HasWhiteSpace(s); + } + + /// + /// 向字符串结尾附加换行符 + /// + /// + /// + public static string AppendNewLine(this string s) + { + return StringUtil.AppendNewLine(s); + } + + /// + /// 反转字符串,如:字符串“ABC”,反转后为“CBA” + /// + /// + public static string Reverse(this string s) + { + return StringUtil.Reverse(s); + } + + /// + /// 将字符串编码成16进制字符串,比如12345->3132333435;张三->D5C5C8FD,使用当前系统默认编码 + /// + /// + /// + /// + public static string ToHexString(this string s, Encoding encoding) + { + return StringUtil.ToHexString(s, encoding); + } + + /// + /// 将字符串编码成16进制字符串,比如12345->3132333435;张三->D5C5C8FD,使用当前系统默认编码 + /// + /// + /// + public static string ToHexString(this string s) + { + return StringUtil.ToHexString(s); + } + + /// + /// 将16进制编码字符串还原成编码前的字符串,比如:D5C5C8FD->张三,3132333435->12345,使用当前系统默认编码 + /// + /// + /// + /// + public static string FromHexString(this string s, Encoding encoding) + { + return StringUtil.FromHexString(s, encoding); + } + + /// + /// 将16进制编码字符串还原成编码前的字符串,比如:D5C5C8FD->张三,3132333435->12345,使用当前系统默认编码 + /// + /// + /// + public static string FromHexString(this string s) + { + return StringUtil.FromHexString(s); + } + + /// + /// 获取字符串长度,字节长度,一个中文字符长度为2 + /// + /// + /// 字符串编码 + /// + public static int GetByteLength(this string s, Encoding encoding) + { + return StringUtil.GetByteLength(s, encoding); + } + + /// + /// 获取字符串长度,字节长度,一个中文字符长度为2 + /// + /// + /// + public static int GetByteLength(this string s) + { + return StringUtil.GetByteLength(s); + } + + /// + /// Base64加密 + /// + /// + /// + public static string Base64Encode(this string s) + { + return StringUtil.Base64Encode(s); + } + + /// + /// Base64加密 + /// + /// + /// + /// + public static string Base64Encode(this string s, Encoding encoding) + { + return StringUtil.Base64Encode(s, encoding); + } + + /// + /// Base64解密 + /// + /// + /// + public static string Base64Decode(this string s) + { + return StringUtil.Base64Decode(s); + } + + /// + /// Base64解密 + /// + /// + /// + /// + public static string Base64Decode(this string s, Encoding encoding) + { + return StringUtil.Base64Decode(s, encoding); + } + } +} diff --git a/src/Kalman/Extensions/TypeExt.cs b/src/Kalman/Extensions/TypeExt.cs new file mode 100644 index 0000000..0cd869d --- /dev/null +++ b/src/Kalman/Extensions/TypeExt.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Data; +using System.ComponentModel; +using System.Reflection; +using Kalman.Utilities; + +namespace Kalman.Extensions +{ + /// + /// 数据库相关扩展方法 + /// + public static class TypeExt + { + /// + /// 获取对应的SqlServer特定数据类型 + /// + /// + /// + public static SqlDbType ToSqlDbType(this DbType dbType) + { + return TypeUtil.DbType2SqlDbType(dbType); + } + + /// + /// 获取对应的数据类型 + /// + /// type由数据库元数据中定义的DataType转换而来 + /// + public static DbType ToDbType(this Type dataType) + { + return TypeUtil.Type2DbType(dataType); + } + + /// + /// 将System.Data.DbType类型转换为对应System.Type类型字符串 + /// + /// + /// + public static string ToTypeString(this DbType dbType) + { + return TypeUtil.DbType2TypeString(dbType); + } + + /// + /// 将System.Data.DbType类型转换为对应System.Type类型 + /// + /// + /// + public static Type ToType(this DbType dbType) + { + return TypeUtil.DbType2Type(dbType); + } + + } +} diff --git a/src/Kalman/IDBuilder.cs b/src/Kalman/IDBuilder.cs new file mode 100644 index 0000000..08118db --- /dev/null +++ b/src/Kalman/IDBuilder.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Kalman +{ + /// + /// 用来生成主键ID + /// + public static class IDBuilder + { + /// + /// 根据当前时间来生成 + /// + /// 日期格式,如:yyyyMMddHHmmssfff + /// 后面附加的随机字符串长度 + /// 前缀 + /// + public static string BuildByDateTime(string format, int randomStringLength = 0, string prefix = "") + { + StringBuilder sb = new StringBuilder(prefix); + + sb.Append(DateTime.Now.ToString(format)); + + if (randomStringLength > 0) + { + sb.Append(Utilities.RandomUtil.BuildRandomString(randomStringLength, "0123456789")); + } + + return sb.ToString(); + } + + } +} diff --git a/src/Kalman/IISLogParser/LogParseFilter.cs b/src/Kalman/IISLogParser/LogParseFilter.cs new file mode 100644 index 0000000..3fa757d --- /dev/null +++ b/src/Kalman/IISLogParser/LogParseFilter.cs @@ -0,0 +1,102 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Kalman.IISLogParser +{ + public class LogParseFilter + { + int _Method = 0; + /// + /// 方法[0:All,1:Get,2:Post] + /// + public int Method + { + get { return _Method; } + set { _Method = value; } + } + + List _FileList = new List(); + public List FileList + { + get + { + return _FileList; + } + } + + public void AddFile(string fileName) + { + if (_FileList.Contains(fileName)) return; + _FileList.Add(fileName); + } + + public void AddFiles(string[] fileNames) + { + foreach (string item in fileNames) + { + AddFile(item); + } + } + + public bool AllowQueryByTime = false; + public bool AllowQueryByIP = false; + public bool AllowQueryByIPLocation = false; + public bool AllowQueryByUserAgent = false; + public bool AllowQueryByUri = false; + public bool AllowQueryByReferer = false; + public bool AllowQueryByStatus = false; + + public DateTime BeginTime = DateTime.Now; + public DateTime EndTime = DateTime.Now; + + IList _IPList = new List(); + public IList IPList { get { return _IPList; } } + public void AddIP(string ip) + { + if (_IPList.Contains(ip)) return; + _IPList.Add(ip); + } + + IList _IPLocationList = new List(); + public IList IPLocationList { get { return _IPLocationList; } } + public void AddIPLocation(string location) + { + if (_IPLocationList.Contains(location)) return; + _IPLocationList.Add(location); + } + + IList _UserAgentList = new List(); + public IList UserAgentList { get { return _UserAgentList; } } + public void AddUserAgent(string userAgent) + { + if (_UserAgentList.Contains(userAgent)) return; + _UserAgentList.Add(userAgent); + } + + IList _UriList = new List(); + public IList UriList { get { return _UriList; } } + public void AddUri(string uri) + { + if (_UriList.Contains(uri)) return; + _UriList.Add(uri); + } + + IList _RefererList = new List(); + public IList RefererList { get { return _RefererList; } } + public void AddReferer(string referer) + { + if (_RefererList.Contains(referer)) return; + _RefererList.Add(referer); + } + + IList _StatusList = new List(); + public IList StatusList { get { return _StatusList; } } + public void AddStatus(string status) + { + if (_StatusList.Contains(status)) return; + _StatusList.Add(status); + } + } +} diff --git a/src/Kalman/IISLogParser/LogParser.cs b/src/Kalman/IISLogParser/LogParser.cs new file mode 100644 index 0000000..0b780f3 --- /dev/null +++ b/src/Kalman/IISLogParser/LogParser.cs @@ -0,0 +1,589 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.IO; +using System.Threading; +using System.Diagnostics; +using Kalman.Utilities; + +namespace Kalman.IISLogParser +{ + public class LogParser : IDisposable + { + List fileList = new List(); + IList recordList = new List(); + Dictionary dicUserAgent = new Dictionary(); + Dictionary dicClientIP = new Dictionary(); + Dictionary dicClientIPLocation = new Dictionary(); + Dictionary dicReferer = new Dictionary(); + Dictionary dicTime = new Dictionary(); + + //别名 + static Dictionary dicUserAgentAlias = new Dictionary(); + static Dictionary dicRefererAlias = new Dictionary(); + static Dictionary dicUriStemAlias = new Dictionary(); + + //别名映射字典 + Dictionary dicUserAgentAliasMapping = new Dictionary(); + Dictionary dicRefererAliasMapping = new Dictionary(); + Dictionary dicUriStemAliasMapping = new Dictionary(); + + QQWryLocator qqWry = null; + LogParseFilter filter = null; + + public LogParser(LogParseFilter logParseFilter) + { + filter = logParseFilter; + LoadMappingData(); + } + + void LoadMappingData() + { + string uriSteamAliasPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "config\\iislog\\UriStemAlias.config"); + string refererAliasPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "config\\iislog\\RefererAlias.config"); + string userAgentAliasPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "config\\iislog\\UserAgentAlias.config"); + + if (File.Exists(uriSteamAliasPath)) + { + string[] ss = File.ReadAllLines(uriSteamAliasPath); + foreach (string s in ss) + { + if (s.Trim().Length == 0) continue; + if (s.StartsWith("#")) continue;//注释以#号开头 + + string[] arr = s.Split(' '); + if (arr.Length == 2) + { + if (dicUriStemAliasMapping.ContainsKey(arr[0])) continue; + dicUriStemAliasMapping.Add(arr[0].Trim(), arr[1].Trim()); + } + } + } + + if (File.Exists(refererAliasPath)) + { + string[] ss = File.ReadAllLines(refererAliasPath); + foreach (string s in ss) + { + if (s.Trim().Length == 0) continue; + if (s.StartsWith("#")) continue;//注释以#号开头 + + string[] arr = s.Split(' '); + if (arr.Length == 2) + { + if (dicRefererAliasMapping.ContainsKey(arr[0])) continue; + dicRefererAliasMapping.Add(arr[0].Trim(), arr[1].Trim()); + } + } + } + + if (File.Exists(userAgentAliasPath)) + { + string[] ss = File.ReadAllLines(userAgentAliasPath); + foreach (string s in ss) + { + if (s.Trim().Length == 0) continue; + if (s.StartsWith("#")) continue;//注释以#号开头 + + string[] arr = s.Split(' '); + if (arr.Length == 2) + { + if (dicUserAgentAliasMapping.ContainsKey(arr[0])) continue; + dicUserAgentAliasMapping.Add(arr[0].Trim(), arr[1].Trim()); + } + } + } + } + + public void LoadIPData(string fileName) + { + if (File.Exists(fileName) == false) return; + try + { + qqWry = new QQWryLocator(fileName); + } + catch + { + qqWry = null; + } + } + + /// + /// 日志记录数 + /// + public int LogRecordNum + { + get { return recordList.Count; } + } + + public Dictionary UserAgentStat + { + get { return dicUserAgent; } + } + + public Dictionary ClientIPStat + { + get { return dicClientIP; } + } + + public Dictionary ClientIPLocationStat + { + get { return dicClientIPLocation; } + } + + public Dictionary RefererStat + { + get { return dicReferer; } + } + + public Dictionary TimeStat + { + get { return dicTime; } + } + + public Dictionary UserAgentAliasStat + { + get { return dicUserAgentAlias; } + } + + public Dictionary RefererAliasStat + { + get { return dicRefererAlias; } + } + + public Dictionary UriStemAliasStat + { + get { return dicUriStemAlias; } + } + + /// + /// 获取日志解析结果集 + /// + /// + public IList RecordList + { + get { return recordList; } + } + + /// + /// 清除解析结果 + /// + public void Clear() + { + recordList.Clear(); + dicClientIP.Clear(); + dicClientIPLocation.Clear(); + dicReferer.Clear(); + dicUserAgent.Clear(); + dicTime.Clear(); + + dicRefererAlias.Clear(); + dicUriStemAlias.Clear(); + dicUserAgentAlias.Clear(); + } + + public string[] Fields { get; set; } + bool _isParseFinish = false; + public bool IsParseFinish + { + get { return _isParseFinish; } + } + + public void DoParser() + { + Clear(); + _isParseFinish = false; + fileList = filter.FileList; + foreach (string fileName in fileList) + { + if (File.Exists(fileName) == false) continue; + + FileInfo fi = new FileInfo(fileName); + using (StreamReader reader = fi.OpenText()) + { + while (!reader.EndOfStream) + { + string s = reader.ReadLine(); + + if (s.StartsWith("#Software")) + { + } + else if (s.StartsWith("#Version")) + { + } + else if (s.StartsWith("#Date")) + { + } + else if (s.StartsWith("#Fields")) + { + this.Fields = s.Split(':')[1].Trim().Split(' '); + } + else + { + try + { + LogRecord record = ParserLogLine(s); + if (DoFilter(record)) + { + recordList.Add(record); + } + } + catch { } + } + } + } + } + + if (recordList.Count > 0) + { + DoStat(); + } + _isParseFinish = true; + } + + bool DoFilter(LogRecord record) + { + if (filter.Method == 1) + { + if (record.Method != "GET") return false; + } + if (filter.Method == 2) + { + if (record.Method != "POST") return false; + } + + if (filter.AllowQueryByTime) + { + if (record.LogTime < filter.BeginTime) return false; + if (record.LogTime > filter.EndTime) return false; + } + + if (filter.AllowQueryByIP) + { + if (filter.IPList.Contains(record.ClientIP) == false) return false; + } + + if (filter.AllowQueryByStatus) + { + if (filter.StatusList.Contains(record.Status) == false) return false; + } + + if (filter.AllowQueryByIPLocation) + { + bool flag = false; + foreach (string s in filter.IPLocationList) + { + if (record.ClientIPLocation.StartsWith(s) == true) + { + flag = true; + break; + } + } + if (flag == false) return false; + } + + if (filter.AllowQueryByReferer) + { + bool flag = false; + foreach (string s in filter.RefererList) + { + if (record.Referer.ToLower().StartsWith(s) == true) + { + flag = true; + break; + } + } + if (flag == false) return false; + } + + if (filter.AllowQueryByUri) + { + bool flag = false; + foreach (string s in filter.UriList) + { + //if (r.UriStem.StartsWith(s) == true) + if(record.UriStem.ToLower().Contains(s) == true) + { + flag = true; + break; + } + } + if (flag == false) return false; + } + + if (filter.AllowQueryByUserAgent) + { + bool flag = false; + foreach (string s in filter.UserAgentList) + { + if (record.UserAgent.StartsWith(s) == true) + { + flag = true; + break; + } + } + if (flag == false) return false; + } + + return true; + } + + void DoStat() + { + foreach (LogRecord record in recordList) + { + if (record.ClientIP != null) + { + //if (record.ClientIP == "127.0.0.1") record.ClientIPLocation = "本地机器"; + if (record.ClientIPLocation == null) record.ClientIPLocation = "未知地区"; + + if (dicClientIP.ContainsKey(record.ClientIP)) + { + int val = dicClientIP[record.ClientIP]; + dicClientIP[record.ClientIP] = val + 1; + } + else + { + dicClientIP.Add(record.ClientIP, 1); + } + + if (dicClientIPLocation.ContainsKey(record.ClientIPLocation)) + { + int val = dicClientIPLocation[record.ClientIPLocation]; + dicClientIPLocation[record.ClientIPLocation] = val + 1; + } + else + { + dicClientIPLocation.Add(record.ClientIPLocation, 1); + } + } + + if (record.UserAgent != null) + { + if (dicUserAgent.ContainsKey(record.UserAgent)) + { + int val = dicUserAgent[record.UserAgent]; + dicUserAgent[record.UserAgent] = val + 1; + } + else + { + dicUserAgent.Add(record.UserAgent, 1); + } + } + //这里不统计用户代理别名字段 + //if (record.UserAgentAlias != null) + //{ + // if (dicUserAgentAlias.ContainsKey(record.UserAgentAlias)) + // { + // int val = dicUserAgentAlias[record.UserAgentAlias]; + // dicUserAgentAlias[record.UserAgentAlias] = val + 1; + // } + // else + // { + // dicUserAgentAlias.Add(record.UserAgentAlias, 1); + // } + //} + + if (record.Referer != null) + { + if (dicReferer.ContainsKey(record.Referer)) + { + int val = dicReferer[record.Referer]; + dicReferer[record.Referer] = val + 1; + } + else + { + dicReferer.Add(record.Referer, 1); + } + } + + if (record.RefererAlias != null) + { + if (dicRefererAlias.ContainsKey(record.RefererAlias)) + { + int val = dicRefererAlias[record.RefererAlias]; + dicRefererAlias[record.RefererAlias] = val + 1; + } + else + { + dicRefererAlias.Add(record.RefererAlias, 1); + } + } + + if (record.UriStemAlias != null) + { + if (dicUriStemAlias.ContainsKey(record.UriStemAlias)) + { + int val = dicUriStemAlias[record.UriStemAlias]; + dicUriStemAlias[record.UriStemAlias] = val + 1; + } + else + { + dicUriStemAlias.Add(record.UriStemAlias, 1); + } + } + + if (record.Date != null) + { + string timeKey = record.LogTime.ToString("yyyy-MM-dd HH"); + if (dicTime.ContainsKey(timeKey)) + { + int val = dicTime[timeKey]; + dicTime[timeKey] = val + 1; + } + else + { + dicTime.Add(timeKey, 1); + } + } + } + } + + //解析扩展字段 + private void ParseExtendField(LogRecord record) + { + if (qqWry != null) + { + string ipLocation = qqWry.Query(record.ClientIP).Country; + record.ClientIPLocation = ipLocation; + } + + record.UriStemAlias = ""; + foreach (KeyValuePair kvp in dicUriStemAliasMapping) + { + if (record.UriStem.Trim().ToLower() == kvp.Key.Trim().ToLower()) + { + record.UriStemAlias = kvp.Value; + break; + } + } + record.RefererAlias = ""; + foreach (KeyValuePair kvp in dicRefererAliasMapping) + { + if (record.Referer.ToLower().StartsWith(kvp.Key.ToLower())) + { + record.RefererAlias = kvp.Value; + break; + } + } + record.UserAgentAliasList = new List(); + foreach (KeyValuePair kvp in dicUserAgentAliasMapping) + { + //多次匹配统计,一条日志记录的用户代理字段可以匹配多个别名 + if (record.UserAgent.ToLower().Contains(kvp.Key.ToLower())) + { + record.UserAgentAliasList.Add(kvp.Value); + + if (dicUserAgentAlias.ContainsKey(kvp.Value)) + { + int val = dicUserAgentAlias[kvp.Value]; + dicUserAgentAlias[kvp.Value] = val + 1; + } + else + { + dicUserAgentAlias.Add(kvp.Value, 1); + } + } + } + } + + LogRecord ParserLogLine(string s) + { + string[] ss = s.Split(' '); + int len = ss.Length; + LogRecord record = new LogRecord(); + record.ReceiveBytes = 0; + record.SendBytes = 0; + record.Referer = ""; + + for (int i = 0; i < len; i++) + { + switch (this.Fields[i]) + { + case "c-ip": + record.ClientIP = ss[i]; + break; + case "date": + record.Date = ss[i]; + break; + case "cs-method": + record.Method = ss[i]; + break; + case "s-port": + record.Port = ss[i]; + break; + case "cs-bytes": + record.ReceiveBytes = ConvertUtil.ToInt32(ss[i], 0); + break; + case "cs(Referer)": + record.Referer = ss[i]; + break; + case "sc-bytes": + record.SendBytes = ConvertUtil.ToInt32(ss[i], 0); + break; + case "s-ip": + record.ServerIP = ss[i]; + break; + case "s-sitename": + record.SiteName = ss[i]; + break; + case "sc-status": + record.Status = ss[i]; + break; + case "sc-substatus": + record.SubStatus = ss[i]; + break; + case "time": + record.Time = ss[i]; + break; + case "cs-uri-query": + record.UriQuery = ss[i]; + break; + case "cs-uri-stem": + record.UriStem = ss[i]; + break; + case "cs(User-Agent)": + record.UserAgent = ss[i]; + break; + case "cs-username": + record.UserName = ss[i]; + break; + case "sc-win32-status": + record.Win32Status = ss[i]; + break; + + case "cs-host": + break; + case "time-taken": + break; + case "cs-version": + break; + case "s-computername": + break; + case "cs(Cookie)": + break; + default: + break; + } + } + + ParseExtendField(record); + return record; + } + + #region IDisposable 成员 + + public void Dispose() + { + this.Clear(); + } + + #endregion + + ~LogParser() + { + this.Dispose(); + } + } +} diff --git a/src/Kalman/IISLogParser/LogRecord.cs b/src/Kalman/IISLogParser/LogRecord.cs new file mode 100644 index 0000000..d66c8dc --- /dev/null +++ b/src/Kalman/IISLogParser/LogRecord.cs @@ -0,0 +1,191 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Kalman.Utilities; + +namespace Kalman.IISLogParser +{ + /// + /// IIS日志记录对象,对应一条IIS日志记录 + /// + [Serializable] + public class LogRecord + { + /// + /// 客户端IP地址[c-ip] + /// + public string ClientIP { get; set; } + + /// + /// IP归属地 + /// + public string ClientIPLocation { get; set; } + + /// + /// 方法[cs-method] + /// + public string Method { get; set; } + + /// + /// URI查询[cs-uri-query] + /// + public string UriQuery { get; set; } + + /// + /// URI资源[cs-uri-stem] + /// + public string UriStem { get; set; } + + /// + /// URI资源别名,需要配置与URI资源的对照表 + /// + public string UriStemAlias { get; set; } + + /// + /// 完整的请求Url,包括参数部分 + /// + public string Url + { + get + { + if (string.IsNullOrEmpty(UriStem)) return string.Empty; + string url = UriStem; + if (string.IsNullOrEmpty(UriQuery)) + { + return url; + } + else + { + return string.Format("{0}?{1}", url, UriQuery); + } + } + } + + /// + /// 用户代理,客户端所用浏览器[cs(User-Agent)] + /// + public string UserAgent { get; set; } + + /// + /// 用户代理别名,需要配置与用户代理的对照表 + /// + public List UserAgentAliasList { get; set; } + + public string UserAgentAlias + { + get + { + if (UserAgentAliasList == null || UserAgentAliasList.Count == 0) return ""; + StringBuilder sb = new StringBuilder(); + foreach (string s in UserAgentAliasList) + { + sb.AppendFormat("{0},", s); + } + return sb.ToString().TrimEnd(','); + } + } + + /// + /// 用户名[cs-username] + /// + public string UserName { get; set; } + + /// + /// 记录日期[date] + /// + public string Date { get; set; } + + /// + /// 记录时间[time] + /// + public string Time { get; set; } + + /// + /// 日志记录时间 + /// + public DateTime LogTime + { + get + { + return ConvertUtil.ToDateTime(string.Format("{0} {1}", Date, Time), DateTime.MinValue); + } + } + + /// + /// 服务器IP地址[s-ip] + /// + public string ServerIP { get; set; } + + /// + /// 服务器端口[s-port] + /// + public string Port { get; set; } + + /// + /// 服务名[s-sitename] + /// + public string SiteName { get; set; } + + /// + /// 引用站点,统计访问来源[cs(Referer)] + /// + public string Referer { get; set; } + + /// + /// 引用站点别名,需要配置与引用站点的对照表,比如:"http://www.baidu.com"别名为"百度" + /// + public string RefererAlias { get; set; } + + /// + /// 协议状态[sc-status] + /// + public string Status { get; set; } + + /// + /// 协议子状态[sc-substatus] + /// + public string SubStatus { get; set; } + + /// + /// Win32状态[sc-win32-status] + /// + public string Win32Status { get; set; } + + /// + /// 接收的字节数[cs-bytes] + /// + public int ReceiveBytes { get; set; } + + /// + /// 发送的字节数[sc-bytes] + /// + public int SendBytes { get; set; } + + ///// + ///// Cookie[cs(Cookie)] + ///// + //public string Cookie { get; set; } + + ///// + ///// 服务器名[s-computername] + ///// + //public string ComputerName { get; set; } + + ///// + ///// 协议版本[cs-version] + ///// + //public string Version { get; set; } + + ///// + ///// 主机[cs-host] + ///// + //public string Host { get; set; } + + ///// + ///// 所用时间[time-taken],分析耗时访问动作 + ///// + //public string TimeTaken { get; set; } + + } +} diff --git a/src/Kalman/IISLogParser/help.txt b/src/Kalman/IISLogParser/help.txt new file mode 100644 index 0000000..b66b017 --- /dev/null +++ b/src/Kalman/IISLogParser/help.txt @@ -0,0 +1,12 @@ +IIS日志文件解析组件 + +配置别名对照关系(一行对应一条对照关系,中间用空格隔开) + +UriStemAlias.config 用户请求资源地址别名对照关系 +配置示例:Index.aspx 主页 + +RefererAlias.config 引用地址别名对照关系 +配置示例:http://www.baidu.com 百度 + +UserAgentAlias.config 用户代理别名对照关系 +配置示例:Baiduspider+(+http://www.baidu.com/search/spider.htm) 百度蜘蛛 diff --git a/src/Kalman/ILogable.cs b/src/Kalman/ILogable.cs new file mode 100644 index 0000000..1b0241c --- /dev/null +++ b/src/Kalman/ILogable.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Kalman +{ + /// + /// ־ί + /// + /// ־Ϣ + public delegate void LogHandler(string msg); + + /// + /// Ҫ¼־̳иýӿ + /// + public interface ILogable + { + /// + /// ־¼ + /// + event LogHandler OnLog; + } +} diff --git a/src/Kalman/IocContainer/IIoc.cs b/src/Kalman/IocContainer/IIoc.cs new file mode 100644 index 0000000..fb542c9 --- /dev/null +++ b/src/Kalman/IocContainer/IIoc.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Collections; + + +namespace Kalman.IocContainer +{ + /// + /// Service locator interface used for getting any service instance. + /// + public interface IIoc + { + /// + /// Get a named service associated with the type. + /// + /// + /// + /// + T GetObject(string objectName); + + + /// + /// Get object using just the type. + /// + /// + /// + /// + T GetObject(); + + + /// + /// Determine if the container contains the specified type. + /// + /// + /// + /// + bool Contains(); + + + /// + /// Add a named service. + /// + /// + /// + /// + void AddObject(string objectName, object obj); + } +} diff --git a/src/Kalman/IocContainer/Ioc.cs b/src/Kalman/IocContainer/Ioc.cs new file mode 100644 index 0000000..1cb4782 --- /dev/null +++ b/src/Kalman/IocContainer/Ioc.cs @@ -0,0 +1,77 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Collections; + + +namespace Kalman.IocContainer +{ + + /// + /// Helper class to get a service object out of the + /// service locator. + /// + public class Ioc + { + private static IIoc _container; + private static object _syncRoot = new object(); + + + /// + /// Sets the object container. + /// + /// The container. + public static void Init(IIoc container) + { + lock (_syncRoot) + { + _container = container; + } + } + + + /// + /// Adds the object to the container. + /// + /// Name of the obj. + /// The obj. + public static void AddObject(string objName, object obj) + { + _container.AddObject(objName, obj); + } + + + /// + /// Get the service and automatically converts to the appropriate type. + /// + /// + /// + public static T GetObject(string objName) + { + return _container.GetObject(objName); + } + + + /// + /// Get the object using just the type. + /// + /// + /// + public static T GetObject() + { + return _container.GetObject(); + } + + + /// + /// Determine if the container contains the specified type. + /// + /// + /// + /// + public static bool Contains() + { + return _container.Contains(); + } + } +} diff --git a/src/Kalman/IocContainer/IocMemory.cs b/src/Kalman/IocContainer/IocMemory.cs new file mode 100644 index 0000000..7e72a7f --- /dev/null +++ b/src/Kalman/IocContainer/IocMemory.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Collections; + +namespace Kalman.IocContainer +{ + /// + /// Simple in Memory container to use for Unit Testing. + /// + public class IocContainerInMemory : IIoc + { + private Hashtable _objects; + + /// + /// The instance name given to the service + /// added as a default service. + /// + public const string DefaultServiceName = "default"; + + /// + /// Make this class a singleton. + /// + public IocContainerInMemory() + { + _objects = new Hashtable(); + } + + #region IIocContainer Members + /// + /// Adds a service to the service to the locator. + /// Supports multiple ( instances ) of a specific type. + /// This is to support different implementations of specific interface + /// for example. + /// + /// + /// + /// + public void AddObject(string key, object obj) + { + _objects.Add(key, obj); + } + + /// + /// Gets a specific service with name provided. + /// + /// + /// + /// + public T GetObject(string serviceName) + { + if (!_objects.ContainsKey(serviceName)) + { + throw new ArgumentException("object : " + serviceName + " does not exist."); + } + object obj = _objects[serviceName]; + return (T)obj; + } + + /// + /// Get object using just the type. + /// + /// + /// + /// + public T GetObject() + { + return GetObject(typeof(T).FullName); + } + + /// + /// Determine if the container contains the specified type. + /// + /// + /// + /// + public bool Contains() + { + return _objects.ContainsKey(typeof(T).FullName); + } + #endregion + } +} diff --git a/src/Kalman/Kalman.csproj b/src/Kalman/Kalman.csproj new file mode 100644 index 0000000..c4e5f42 --- /dev/null +++ b/src/Kalman/Kalman.csproj @@ -0,0 +1,391 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {65FED08B-D2B2-4B49-9257-3DE1954D1675} + Library + Properties + Kalman + Kalman + v4.6 + 512 + + + + + + + + + + + 3.5 + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + ..\ + true + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + bin\Debug\Kalman.XML + AllRules.ruleset + false + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + bin\Release\Kalman.XML + AllRules.ruleset + false + + + + ..\packages\EmitMapper.1.0.0\lib\EmitMapper.dll + True + + + ..\packages\Oracle.ManagedDataAccess.12.2.1100\lib\net40\Oracle.ManagedDataAccess.dll + + + + + False + + + + + + + + + + + + + + + + + + + + + + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + True + True + Common.resx + + + True + True + Data.resx + + + + + + + + + + + + + + + + + + + + + + + + + ResXFileCodeGenerator + Common.Designer.cs + Designer + + + ResXFileCodeGenerator + Data.Designer.cs + Designer + + + + + + + + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + + + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + \ No newline at end of file diff --git a/src/Kalman/Logging/Config/FormatterConfig.cs b/src/Kalman/Logging/Config/FormatterConfig.cs new file mode 100644 index 0000000..57dd672 --- /dev/null +++ b/src/Kalman/Logging/Config/FormatterConfig.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Xml; + +namespace Kalman.Logging +{ + /// + /// 格式化器配置 + /// + public class FormatterConfig + { + /// + /// 获取或设置格式化器名称 + /// + public string Name { get; set; } + + /// + /// 获取或设置格式化字符串 + /// + public string Format { get; set; } + + /// + /// 获取或设置格式化器类型 + /// + public Type Type { get; set; } + + /// + /// 获取或设置格式化器子配置 + /// + public XmlNodeList ChildConfig { get; set; } + } +} diff --git a/src/Kalman/Logging/Config/LoggerConfig.cs b/src/Kalman/Logging/Config/LoggerConfig.cs new file mode 100644 index 0000000..897ef9a --- /dev/null +++ b/src/Kalman/Logging/Config/LoggerConfig.cs @@ -0,0 +1,77 @@ +using System.Collections.Generic; +using System.Xml; + +namespace Kalman.Logging +{ + /// + /// 日志记录器配置类 + /// + public class LoggerConfig + { + private string _namespace; + + /// + /// + /// + public LoggerConfig() + { + TargetNames = new List(); + } + + /// + /// 获取或设置日志记录器所作用的命名空间,只支持唯一的通配符(*) + /// + public string Namespace + { + get { return _namespace; } + set + { + if (value == "*") + { + IsWildCard = true; + _namespace = string.Empty; + } + else if (value.EndsWith(".*")) + { + IsWildCard = true; + _namespace = value.Remove(value.Length - 2); + } + else + _namespace = value; + } + } + + /// + /// 获取或设置指定命名空间是否包含通配符[*] + /// + public bool IsWildCard { get; private set; } + + /// + /// 获取或设置日志记录器的名称 + /// + public string Name { get; set; } + + /// + /// 获取Target名称集合,配置中用逗号隔开 + /// + public ICollection TargetNames { get; private set; } + + /// + /// 子配置 + /// + public XmlNodeList ChildConfig { get; internal set; } + + /// + /// 获取可以被记录日志的最小级别 + /// + public LogLevel MinLevel { get; set; } + + /// + /// 日志记录器Target列表 + /// + public IList Targets + { + get; internal set; + } + } +} diff --git a/src/Kalman/Logging/Config/LoggingConfig.cs b/src/Kalman/Logging/Config/LoggingConfig.cs new file mode 100644 index 0000000..c1d5009 --- /dev/null +++ b/src/Kalman/Logging/Config/LoggingConfig.cs @@ -0,0 +1,165 @@ +using System; +using System.Collections.Generic; +using System.Xml; +using System.Configuration; + +namespace Kalman.Logging +{ + /// + /// 日志组件配置 + /// + public class LoggingConfig : ConfigBase + { + public static readonly LoggingConfig Instance = new LoggingConfig(); + + List _Formatters = new List(); + List _Loggers = new List(); + List _Targets = new List(); + + public LoggingConfig() + { + LoadConfig(); + } + + private void LoadConfig() + { + XmlNode root = (XmlNode)ConfigurationManager.GetSection("kalman/logging"); + if (root == null) + { + return; + } + + foreach (XmlNode node in root.ChildNodes) + { + switch (node.Name) + { + case "targets": + ParseTargets(node.ChildNodes); + break; + case "loggers": + ParseLoggers(node.ChildNodes); + break; + case "formatters": + ParseFormatters(node.ChildNodes); + break; + } + } + } + + #region Properties + + /// + /// 获取或设置Target列表 + /// + public List Targets + { + get { return _Targets; } + } + + /// + /// 获取或设置日志记录器列表 + /// + public List Loggers + { + get { return _Loggers; } + } + + /// + /// 获取或设置格式化器列表 + /// + public List Formatters + { + get { return _Formatters; } + } + + #endregion + + //解析formatters节点 + private void ParseFormatters(XmlNodeList nodes) + { + foreach (XmlNode node in nodes) + { + if (node is XmlComment) continue; + + var config = new FormatterConfig + { + Name = GetAttribute(node, "name", true), + Format = GetAttribute(node,"format", false) + }; + + string typeName = GetAttribute(node, "type", true); + if (!typeName.Contains(".")) + typeName = "Kalman.Logging." + typeName; + + config.Type = Type.GetType(typeName, false); + if (config.Type == null) + throw new ConfigurationErrorsException(string.Format("找不到类型名称为{0}的格式化器",typeName)); + + config.ChildConfig = node.ChildNodes; + _Formatters.Add(config); + } + } + + //解析loggers节点 + private void ParseLoggers(XmlNodeList nodes) + { + foreach (XmlNode node in nodes) + { + if (node is XmlComment) continue; + + var config = new LoggerConfig + { + ChildConfig = node.ChildNodes, + Namespace = GetAttribute(node, "namespace","*"),//若namespace属性没配置,则默认为“*”,表示该Logger可以在任意地方写日志 + Name = GetAttribute(node, "name", true) + }; + + string[] names = GetAttribute(node, "targets", true).Split(','); + foreach (string name in names) + config.TargetNames.Add(name.Trim()); + + try + { + string minLevel = GetAttribute(node, "minLevel", false); + if (!string.IsNullOrEmpty(minLevel)) + config.MinLevel = (LogLevel)Enum.Parse(typeof(LogLevel), minLevel); + else + config.MinLevel = LogLevel.Trace; + } + catch (Exception ex) + { + throw new ConfigurationErrorsException(string.Format("解析minLevel属性时出错,错误信息:{0}", ex.Message)); + } + + _Loggers.Add(config); + } + } + + //解析Targets节点 + private void ParseTargets(XmlNodeList nodes) + { + foreach (XmlNode node in nodes) + { + if (node is XmlComment) continue; + + var config = new TargetConfig(); + config.Name = GetAttribute(node, "name", true); + config.ChildConfig = node.ChildNodes; + + config.FormatterName = GetAttribute(node, "formatter", false); + if (string.IsNullOrEmpty(config.FormatterName)) + config.FormatterName = "DefaultFormatter"; + + string typeName = GetAttribute(node, "type", true); + if (!typeName.Contains(".")) + typeName = "Kalman.Logging.Targets." + typeName; + + config.TargetType = Type.GetType(typeName, false); + if (config.TargetType == null) + throw new ConfigurationErrorsException(string.Format("找不到类型名称为{0}的Target",typeName)); + + _Targets.Add(config); + } + } + } +} \ No newline at end of file diff --git a/src/Kalman/Logging/Config/TargetConfig.cs b/src/Kalman/Logging/Config/TargetConfig.cs new file mode 100644 index 0000000..046143e --- /dev/null +++ b/src/Kalman/Logging/Config/TargetConfig.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Xml; + +namespace Kalman.Logging +{ + /// + /// Target Configuration + /// + public class TargetConfig + { + /// + /// 获取或设置Target类型 + /// + public Type TargetType { get; set; } + + /// + /// 获取或设置Target名称 + /// + public string Name { get; set; } + + /// + /// 获取或设置格式化器名称 + /// + public string FormatterName { get; set; } + + /// + /// 获取或设置Target子配置 + /// + public XmlNodeList ChildConfig { get; set; } + } +} diff --git a/src/Kalman/Logging/DefaultFormatter.cs b/src/Kalman/Logging/DefaultFormatter.cs new file mode 100644 index 0000000..dbf7eb4 --- /dev/null +++ b/src/Kalman/Logging/DefaultFormatter.cs @@ -0,0 +1,186 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using Kalman.Logging.Formatters; +using System.Text; + +namespace Kalman.Logging +{ + /// + /// 默认格式化器 + /// + public class DefaultFormatter : IFormatter + { + private readonly DateTimeFormatter _dateTimeFormatter = new DateTimeFormatter(); + private string _formatString; + private List _lineFormatters = new List(); + + public DefaultFormatter() + { + Name = "Default"; + _dateTimeFormatter.FormatString = "yyyy-MM-dd HH:mm:ss.fff"; + + _lineFormatters.Add(_dateTimeFormatter); + _lineFormatters.Add(new TextFormatter(" ")); + _lineFormatters.Add(new ThreadIdFormatter()); + _lineFormatters.Add(new TextFormatter(" ")); + _lineFormatters.Add(new LogLevelFormatter()); + _lineFormatters.Add(new TextFormatter(" ")); + _lineFormatters.Add(new MessageFormatter()); + _lineFormatters.Add(new TextFormatter(" ")); + _lineFormatters.Add(new StackTraceFormatter()); + _lineFormatters.Add(new TextFormatter(" ")); + } + + #region IFormatter Members + + /// + /// 加载配置 + /// + /// + /// 配置已经被加载 + /// 参数config 不能为空 + public void LoadConfig(FormatterConfig config) + { + if (config == null) + throw new ArgumentNullException("config"); + Name = config.Name; + FormatString = config.Format; + } + + + /// + /// 获取或设置格式化器名称 + /// + public string Name { get; private set; } + + /// + /// 获取或设置格式化字符串 + /// + public string FormatString + { + get { return _formatString; } + set + { + if (!string.IsNullOrEmpty(value)) + _lineFormatters = ParseFormat(value); + _formatString = value; + } + } + + /// + /// 格式化日志实体 + /// + public string Format(LogEntry entry) + { + if (entry == null) + return "NullEntry"; + + StringBuilder sb = new StringBuilder(); + + foreach (IPartFormatter formatter in _lineFormatters) + { + sb.Append(formatter.Format(entry)); + } + + if (entry.Exception != null) + { + sb.Append(Environment.NewLine); + sb.Append(entry.Exception); + } + + return sb.ToString(); + } + + /// + /// 格式化日期和时间 + /// + public string FormatDateTime(DateTime dateTime) + { + return _dateTimeFormatter.Format(dateTime); + } + + /// + /// 格式化日期 + /// + public string FormatDate(DateTime dateTime) + { + return dateTime.ToString("yyyy-MM-dd"); + } + + #endregion + + /// + /// 解析格式化字符串 + /// + /// + /// + public static List ParseFormat(string format) + { + int start = -1; + int tag = 0; + var parts = new List(); + int len = format.Length; + int idx = format.IndexOf('{'); + + parts.Add(format.Substring(0, idx)); + for (int i = idx; i < len; ++i) + { + switch (format[i]) + { + case '{': + if (start != -1) + parts.Add(format.Substring(start, i - start)); + start = i; + break; + case '}': + parts.Add(format.Substring(start, i - start)); + start = i + 1; + tag = start;//标记最后面的填充字符的开始位置 + break; + } + } + parts.Add(format.Substring(tag, len - tag)); + + // {Date:yyyy-MM-dd HH:mm:ss.ffff} {ThreadId} {StackTrace:3,40} {Message} + var formatters = new List(); + foreach (string part in parts) + { + if (part.StartsWith("{DateTime")) + { + if (part.Length > 9 && part[9] == ':') + formatters.Add(new DateTimeFormatter { FormatString = part.Substring(10) }); + else + formatters.Add(new DateTimeFormatter()); + } + else if (part.StartsWith("{ThreadId")) + formatters.Add(new ThreadIdFormatter()); + else if (part.StartsWith("{StackTrace")) + { + if (!part.StartsWith("{StackTrace:")) + { + formatters.Add(new StackTraceFormatter()); + continue; + } + + string[] subparts = part.Substring(12).Split(','); + var formatter = new StackTraceFormatter(); + if (subparts.Length > 0) + formatter.Count = int.Parse(subparts[0]); + if (subparts.Length > 1) + formatter.PadLength = int.Parse(subparts[1]); + if (subparts.Length > 2) + formatter.SkipCount = int.Parse(subparts[2]); + formatters.Add(formatter); + } + else if (part.StartsWith("{Message")) + formatters.Add(new MessageFormatter()); + else if (part.StartsWith("{LogLevel")) + formatters.Add(new LogLevelFormatter()); + else + formatters.Add(new TextFormatter {Text = part}); + } + return formatters; + } + } +} \ No newline at end of file diff --git a/src/Kalman/Logging/ExceptionEventArgs.cs b/src/Kalman/Logging/ExceptionEventArgs.cs new file mode 100644 index 0000000..d83375b --- /dev/null +++ b/src/Kalman/Logging/ExceptionEventArgs.cs @@ -0,0 +1,15 @@ +using System; + +namespace Kalman.Logging +{ + /// + /// 日志组件抛出异常的时候使用 + /// + public class ExceptionEventArgs : EventArgs + { + /// + /// 获取或设置抛出的异常 + /// + public Exception Exception { get; set; } + } +} diff --git a/src/Kalman/Logging/Formatters/DateTimeFormatter.cs b/src/Kalman/Logging/Formatters/DateTimeFormatter.cs new file mode 100644 index 0000000..dfa2c09 --- /dev/null +++ b/src/Kalman/Logging/Formatters/DateTimeFormatter.cs @@ -0,0 +1,30 @@ +using System; + +namespace Kalman.Logging.Formatters +{ + /// + /// 日期和时间格式化器 + /// + public class DateTimeFormatter : IPartFormatter + { + /// + /// 获取或设置日期时间格式化字符串 + /// + public string FormatString { get; set; } + + /// + /// 格式化日期和时间属性 + /// + /// + /// + public string Format(LogEntry entry) + { + return entry.CreatedAt.ToString(FormatString); + } + + public string Format(DateTime dateTime) + { + return dateTime.ToString(FormatString); + } + } +} diff --git a/src/Kalman/Logging/Formatters/ExceptionFormatter.cs b/src/Kalman/Logging/Formatters/ExceptionFormatter.cs new file mode 100644 index 0000000..9bf040a --- /dev/null +++ b/src/Kalman/Logging/Formatters/ExceptionFormatter.cs @@ -0,0 +1,13 @@ +namespace Kalman.Logging.Formatters +{ + /// + /// 异常信息格式化器 + /// + public class ExceptionFormatter : IPartFormatter + { + public string Format(LogEntry entry) + { + return entry.Exception.ToString(); + } + } +} diff --git a/src/Kalman/Logging/Formatters/IPartFormatter.cs b/src/Kalman/Logging/Formatters/IPartFormatter.cs new file mode 100644 index 0000000..9e0e220 --- /dev/null +++ b/src/Kalman/Logging/Formatters/IPartFormatter.cs @@ -0,0 +1,10 @@ +namespace Kalman.Logging.Formatters +{ + /// + /// 用于格式化日志实体的部分属性 + /// + public interface IPartFormatter + { + string Format(LogEntry entry); + } +} diff --git a/src/Kalman/Logging/Formatters/LogLevelFormatter.cs b/src/Kalman/Logging/Formatters/LogLevelFormatter.cs new file mode 100644 index 0000000..599a9c8 --- /dev/null +++ b/src/Kalman/Logging/Formatters/LogLevelFormatter.cs @@ -0,0 +1,14 @@ +namespace Kalman.Logging.Formatters +{ + /// + /// LogLevelFormatter + /// + public class LogLevelFormatter : IPartFormatter + { + public string Format(LogEntry entry) + { + //将LogLevel字符串长度控制为7个字符,不足的左边用空格填充 + return entry.Level.ToString().PadLeft(7, ' '); + } + } +} diff --git a/src/Kalman/Logging/Formatters/MessageFormatter.cs b/src/Kalman/Logging/Formatters/MessageFormatter.cs new file mode 100644 index 0000000..7d907b1 --- /dev/null +++ b/src/Kalman/Logging/Formatters/MessageFormatter.cs @@ -0,0 +1,13 @@ +namespace Kalman.Logging.Formatters +{ + /// + /// MessageFormatter + /// + public class MessageFormatter : IPartFormatter + { + public string Format(LogEntry entry) + { + return entry.Message; + } + } +} diff --git a/src/Kalman/Logging/Formatters/StackTraceFormatter.cs b/src/Kalman/Logging/Formatters/StackTraceFormatter.cs new file mode 100644 index 0000000..086ac04 --- /dev/null +++ b/src/Kalman/Logging/Formatters/StackTraceFormatter.cs @@ -0,0 +1,68 @@ +using System; +using System.Diagnostics; +using System.Reflection; +using System.Text; + +namespace Kalman.Logging.Formatters +{ + /// + /// 格式化堆栈帧 + /// + public class StackTraceFormatter : IPartFormatter + { + public StackTraceFormatter() + { + SkipCount = 0; + Count = 3; + PadLength = 0; + } + + /// + /// 获取或设置跳过的帧数 + /// + public int SkipCount { get; set; } + + /// + /// 获取或设置包含的帧数 + /// + public int Count { get; set; } + + /// + /// 获取或设置填充字符的长度 + /// + public int PadLength { get; set; } + + public string Format(LogEntry entry) + { + StringBuilder sb = new StringBuilder(); + int stop = Math.Min(entry.StackFrames.Length, Count); + + for (int i = SkipCount; i < stop; ++i) + { + StackFrame frame = entry.StackFrames[i]; + if (frame == null) + { + sb.Append("UnknownFrame <--"); + continue; + } + + MethodBase method = frame.GetMethod(); + if (method == null) + { + sb.Append("UnknownFrame <--"); + continue; + } + + string typeName = method.ReflectedType == null ? "UnknownType" : method.ReflectedType.Name ?? "UnknownTypeName"; + string methodName = method.Name ?? "UnknownMethodName"; + sb.Append(string.Format("{0}.{1}<--", typeName, methodName)); + } + + string temp = sb.ToString(); + if (temp.Length > 3) + temp = temp.Remove(temp.Length - 3); + + return PadLength == 0 ? temp : temp.PadRight(PadLength); + } + } +} diff --git a/src/Kalman/Logging/Formatters/TextFormatter.cs b/src/Kalman/Logging/Formatters/TextFormatter.cs new file mode 100644 index 0000000..ac39235 --- /dev/null +++ b/src/Kalman/Logging/Formatters/TextFormatter.cs @@ -0,0 +1,26 @@ +namespace Kalman.Logging.Formatters +{ + /// + /// 当不包含任何格式化器的时候直接输出文本 + /// + public class TextFormatter : IPartFormatter + { + public TextFormatter(string text) + { + Text = text; + } + public TextFormatter() + { + } + + /// + /// 获取或设置要输出的文本 + /// + public string Text { get; set; } + + public string Format(LogEntry entry) + { + return Text; + } + } +} diff --git a/src/Kalman/Logging/Formatters/ThreadIdFormatter.cs b/src/Kalman/Logging/Formatters/ThreadIdFormatter.cs new file mode 100644 index 0000000..6839293 --- /dev/null +++ b/src/Kalman/Logging/Formatters/ThreadIdFormatter.cs @@ -0,0 +1,11 @@ +namespace Kalman.Logging.Formatters +{ + public class ThreadIdFormatter : IPartFormatter + { + public string Format(LogEntry entry) + { + //限定线程ID的位数,不足左边用0填充 + return entry.ThreadID.ToString("000"); + } + } +} diff --git a/src/Kalman/Logging/IFormatter.cs b/src/Kalman/Logging/IFormatter.cs new file mode 100644 index 0000000..dedabed --- /dev/null +++ b/src/Kalman/Logging/IFormatter.cs @@ -0,0 +1,44 @@ +using System; + +namespace Kalman.Logging +{ + /// + /// 日志实体格式化器接口 + /// + public interface IFormatter + { + /// + /// 加载配置 + /// + /// + /// 配置已经被加载 + /// 参数config 不能为空 + void LoadConfig(FormatterConfig config); + + /// + /// 获取或设置格式化器名称 + /// + string Name { get; } + + /// + /// 获取或设置格式化字符串 + /// + string FormatString { get; } + + /// + /// 格式化日志实体 + /// + string Format(LogEntry entry); + + /// + /// 格式化日期和时间 + /// + string FormatDateTime(DateTime dateTime); + + /// + /// 格式化日期 + /// + string FormatDate(DateTime dateTime); + + } +} diff --git a/src/Kalman/Logging/ILogProvider.cs b/src/Kalman/Logging/ILogProvider.cs new file mode 100644 index 0000000..b90821f --- /dev/null +++ b/src/Kalman/Logging/ILogProvider.cs @@ -0,0 +1,18 @@ +namespace Kalman.Logging +{ + /// + /// Provides loggers. + /// + public interface ILogProvider + { + /// + /// 获取日志记录器(根据指定名称) + /// + ILogger GetLogger(string name); + + /// + /// 获取日志记录器(为当前类找出匹配的日志记录器) + /// + ILogger GetCurrentClassLogger(); + } +} \ No newline at end of file diff --git a/src/Kalman/Logging/ILogger.cs b/src/Kalman/Logging/ILogger.cs new file mode 100644 index 0000000..337da97 --- /dev/null +++ b/src/Kalman/Logging/ILogger.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; + +namespace Kalman.Logging +{ + /// + /// 日志记录器接口 + /// + public interface ILogger + { + /// + /// 获取可以被记录日志的最小级别 + /// + LogLevel MinLevel { get; } + + /// + /// 获取或设置日志记录器的名称 + /// + string Name { get; set; } + + /// + /// 获取或设置日志记录器所作用的命名空间 + /// + string NameSpace { get; set; } + + /// + /// Targets + /// + IEnumerable Targets { get; } + + void Trace(string message); + void Trace(string message, Exception exception); + void Debug(string message); + void Debug(string message, Exception exception); + void Info(string message); + void Info(string message, Exception exception); + void Warning(string message); + void Warning(string message, Exception exception); + void Error(string message); + void Error(string message, Exception exception); + void Fatal(string message); + void Fatal(string message, Exception exception); + + /// + /// 加载配置 + /// + /// + /// + /// 只能在启动时调用 + /// + /// 配置已经被指定 + void LoadConfig(LoggerConfig config); + + /// + /// 限制日志记录器只能在指定的命名空间记录日志,根据命名空间来判断日志记录器是否能记录日志 + /// + /// 要检测的命名空间 + bool CanLog(string value); + } +} \ No newline at end of file diff --git a/src/Kalman/Logging/ITarget.cs b/src/Kalman/Logging/ITarget.cs new file mode 100644 index 0000000..20f5906 --- /dev/null +++ b/src/Kalman/Logging/ITarget.cs @@ -0,0 +1,36 @@ +using System; +using System.Configuration; + +namespace Kalman.Logging +{ + /// + /// Logger target. + /// + public interface ITarget + { + /// + /// 加载配置 + /// + /// + /// 配置已经被加载 + /// 参数config 不能为空 + /// 配置无法正确加载 + void LoadConfig(TargetConfig config); + + /// + /// 获取或设置Target名称 + /// + string Name { get; } + + /// + /// 获取或设置格式化器 + /// + IFormatter Formatter { get; } + + + /// + /// 写日志实体 + /// + void Write(LogEntry logEntry); + } +} \ No newline at end of file diff --git a/src/Kalman/Logging/LogEntry.cs b/src/Kalman/Logging/LogEntry.cs new file mode 100644 index 0000000..dae5829 --- /dev/null +++ b/src/Kalman/Logging/LogEntry.cs @@ -0,0 +1,69 @@ +using System; +using System.Diagnostics; + +namespace Kalman.Logging +{ + /// + /// 日志实体类 + /// + [Serializable] + public class LogEntry : ICloneable + { + /// + /// 获取或设置日志级别 + /// + public LogLevel Level { get; set; } + + /// + /// 获取或设计日志消息 + /// + public string Message { get; set; } + + /// + /// 获取或设置日志创建时间 + /// + public DateTime CreatedAt { get; set; } + + /// + /// 获取或设置写日志的线程ID + /// + public int ThreadID { get; set; } + + /// + /// 获取或设置堆栈帧数组 + /// + public StackFrame[] StackFrames { get; set; } + + /// + /// 获取或设置应用程序抛出的异常 + /// + public Exception Exception { get; set; } + + /// + /// 获取或设置日志实体所属的日志记录器 + /// + public ILogger Logger { get; set; } + + #region ICloneable 成员 + + /// + /// 克隆一个日志实体 + /// + /// + public object Clone() + { + return new LogEntry() + { + Level = this.Level, + Message = this.Message, + CreatedAt = this.CreatedAt, + ThreadID = this.ThreadID, + StackFrames = this.StackFrames, + Exception = this.Exception, + Logger = this.Logger + }; + } + + #endregion + } +} \ No newline at end of file diff --git a/src/Kalman/Logging/LogLevel.cs b/src/Kalman/Logging/LogLevel.cs new file mode 100644 index 0000000..6bfe04a --- /dev/null +++ b/src/Kalman/Logging/LogLevel.cs @@ -0,0 +1,42 @@ +using System; +using System.Diagnostics; + +namespace Kalman.Logging +{ + /// + /// 日志记录级别 + /// + [Serializable] + public enum LogLevel + { + /// + /// 记录用来跟踪程序的执行情况的信息 + /// + Trace, + + /// + /// 记录用来帮助程序调式的信息 + /// + Debug, + + /// + /// 记录正常信息 + /// + Info, + + /// + /// 记录警告信息,可能发生了错误,但是不影响程序执行 + /// + Warning, + + /// + /// 记录错误信息,程序发生了异常,但是没有必要终止程序 + /// + Error, + + /// + /// 记录致命错误信息,程序发生了致命异常,必须重新启动程序 + /// + Fatal + } +} diff --git a/src/Kalman/Logging/LogManager.cs b/src/Kalman/Logging/LogManager.cs new file mode 100644 index 0000000..7f72a9a --- /dev/null +++ b/src/Kalman/Logging/LogManager.cs @@ -0,0 +1,67 @@ +using System; +using System.Configuration; +using System.Diagnostics; + +namespace Kalman.Logging +{ + /// + /// 日志管理类 + /// + public class LogManager + { + private static ILogProvider _provider; + private static Type _providerAssigner; + + public static readonly NullLogger NullLogger = new NullLogger(); + + static LogManager() + { + } + + /// + /// 获取指定名称的日志记录器 + /// + public static ILogger GetLogger(string name) + { + if (_provider == null) SetProvider(new LogProvider()); + return _provider.GetLogger(name); + } + + /// + /// 获取日志记录器(为当前类找出匹配的日志记录器) + /// + public static ILogger GetCurrentClassLogger() + { + if (_provider == null) SetProvider(new LogProvider()); + return _provider.GetCurrentClassLogger(); + } + + /// + /// 设置一个日志记录器提供者 + /// + /// 日志记录器提供者已经被指定 + internal static void SetProvider(ILogProvider provider) + { + if (_provider != null) + throw new InvalidOperationException("日志记录器提供者已经被指定给" + _providerAssigner.FullName); + + _providerAssigner = new StackFrame(1).GetMethod().ReflectedType; + _provider = provider; + } + + /// + /// 用于触发异常抛出事件 + /// + /// + /// + internal static void TriggerEvent(object source, Exception ex) + { + ExceptionThrown(source, new ExceptionEventArgs {Exception = ex}); + } + + /// + /// 日志组件异常抛出事件 + /// + public static event EventHandler ExceptionThrown = delegate{}; + } +} diff --git a/src/Kalman/Logging/LogProvider.cs b/src/Kalman/Logging/LogProvider.cs new file mode 100644 index 0000000..0fd132a --- /dev/null +++ b/src/Kalman/Logging/LogProvider.cs @@ -0,0 +1,157 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Diagnostics; + +namespace Kalman.Logging +{ + /// + /// 默认的日志记录器提供者 + /// + public class LogProvider : ILogProvider + { + private readonly List _formatters = new List(); + private readonly List _loggers = new List(); + private readonly List _targets = new List(); + + public LogProvider() + { + LoadConfig(); + } + + #region ILogProvider Members + + /// + /// 获取日志记录器(根据指定名称) + /// + public ILogger GetLogger(string name) + { + foreach (ILogger logger in _loggers) + { + if (string.Compare(logger.Name, name, true) == 0) + return logger; + } + + return LogManager.NullLogger; + } + + /// + /// 获取日志记录器(为当前类找出匹配的日志记录器) + /// + public ILogger GetCurrentClassLogger() + { + var frame = new StackFrame(2); //调用日志记录器的类所在的堆栈帧 + Type classType = frame.GetMethod().ReflectedType; + + // 查找配置中所有匹配的日志记录器 + IList loggers = FindLoggers(classType); + if (loggers.Count == 0) + { + return LogManager.NullLogger; + } + if (loggers.Count == 1) + return loggers[0]; + + MultiLogger logger = new MultiLogger(loggers); + LogLevel minLevel = LogLevel.Fatal; + foreach (var logger1 in loggers) + { + if (logger1.MinLevel < minLevel) + minLevel = logger1.MinLevel; + } + + logger.LoadConfig(new LoggerConfig{MinLevel = minLevel, Name = "MultiLogger"}); + return logger; + } + + #endregion + + /// + /// 加载配置 + /// + void LoadConfig() + { + var config = LoggingConfig.Instance; + LoadFormatters(config.Formatters); + LoadTargets(config.Targets); + LoadLoggers(config.Loggers); + } + + private void LoadFormatters(IEnumerable formatterConfigurations) + { + foreach (FormatterConfig formatter in formatterConfigurations) + { + var instance = (IFormatter) Activator.CreateInstance(formatter.Type); + instance.LoadConfig(formatter); + _formatters.Add(instance); + } + } + + private void LoadTargets(IEnumerable targetConfigurations) + { + foreach (TargetConfig targetConfig in targetConfigurations) + { + IFormatter formatter = GetFormatter(targetConfig.FormatterName); + if (formatter == null) + throw new InvalidOperationException(string.Format("不能找到格式化器[{0}]", targetConfig.FormatterName)); + + var target = (ITarget)Activator.CreateInstance(targetConfig.TargetType, new object[] { formatter }); + target.LoadConfig(targetConfig); + _targets.Add(target); + } + } + + protected void LoadLoggers(IEnumerable loggerConfigurations) + { + foreach (LoggerConfig loggerConfig in loggerConfigurations) + { + IList targets = new List(); + foreach (string targetName in loggerConfig.TargetNames) + { + ITarget target = GetTarget(targetName); + if (target == null) + throw new ConfigurationErrorsException(string.Format("不能找到Target[{0}]",targetName)); + targets.Add(target); + } + loggerConfig.Targets = targets; + + ILogger logger = new Logger(); + logger.LoadConfig(loggerConfig); + _loggers.Add(logger); + } + } + + private ITarget GetTarget(string name) + { + foreach (ITarget target in _targets) + { + if (target.Name == name) + return target; + } + + return null; + } + + protected virtual IFormatter GetFormatter(string name) + { + foreach (IFormatter formatter in _formatters) + { + if (formatter.Name == name) + return formatter; + } + + return null; + } + + private IList FindLoggers(Type classType) + { + var loggers = new List(); + foreach (ILogger logger in _loggers) + { + if (logger.CanLog(classType.Namespace)) + loggers.Add(logger); + } + return loggers; + } + } +} \ No newline at end of file diff --git a/src/Kalman/Logging/Logger.cs b/src/Kalman/Logging/Logger.cs new file mode 100644 index 0000000..ccb8361 --- /dev/null +++ b/src/Kalman/Logging/Logger.cs @@ -0,0 +1,284 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Threading; + +namespace Kalman.Logging +{ + /// + /// 日志记录器 + /// + public class Logger : ILogger + { + private readonly ICollection _targets; + private LoggerConfig _config; + + /// + /// + /// + /// 参数targets 不能为空 + public Logger(ICollection targets) + { + if (targets == null) + throw new ArgumentNullException("targets"); + _targets = targets; + } + + /// + /// + /// + public Logger() + { + _targets = new List(); + } + + #region ILogger Members + + /// + /// 用来跟踪程序的执行情况 + /// + public void Trace(string msg) + { + WriteEntry(LogLevel.Trace, msg); + } + + /// + /// 用来跟踪程序的执行情况 + /// + public void Trace(string msg, Exception ex) + { + WriteEntry(LogLevel.Trace, msg, ex); + } + + /// + /// 记录调试信息 + /// + public void Debug(string msg) + { + WriteEntry(LogLevel.Debug, msg); + } + + /// + /// 记录调试信息 + /// + public void Debug(string msg, Exception ex) + { + WriteEntry(LogLevel.Debug, msg, ex); + } + + /// + /// + /// + public void Info(string msg) + { + WriteEntry(LogLevel.Info, msg); + } + + /// + /// + /// + public void Info(string msg, Exception ex) + { + WriteEntry(LogLevel.Info, msg, ex); + } + + /// + /// 记录警告信息 + /// + public void Warning(string msg) + { + WriteEntry(LogLevel.Warning, msg); + } + + /// + /// + /// + public void Warning(string msg, Exception ex) + { + WriteEntry(LogLevel.Warning, msg, ex); + } + + /// + /// + /// + public void Error(string msg) + { + WriteEntry(LogLevel.Error, msg); + } + + /// + /// + /// + public void Error(string msg, Exception ex) + { + WriteEntry(LogLevel.Error, msg, ex); + } + + /// + /// + /// + public void Fatal(string msg) + { + WriteEntry(LogLevel.Fatal, msg); + } + + /// + /// + /// + public void Fatal(string msg, Exception ex) + { + WriteEntry(LogLevel.Fatal, msg, ex); + } + + /// + /// 加载配置 + /// + /// + /// + /// 只能在启动时调用 + /// + /// 配置已经被指定 + public void LoadConfig(LoggerConfig config) + { + if (_config != null) + throw new InvalidOperationException("配置已经被指定."); + + _config = config; + Name = _config.Name; + NameSpace = _config.Namespace; + + if (_targets.Count != 0) + return; + + foreach (var target in _config.Targets) + _targets.Add(target); + } + + /// + /// 获取可以被记录日志的最小级别 + /// + public LogLevel MinLevel + { + get { return _config.MinLevel; } + } + + /// + /// 获取或设置日志记录器的名称 + /// + public string Name { get; set; } + + /// + /// 获取或设置日志记录器所作用的命名空间 + /// + public string NameSpace { get; set; } + + /// + /// 限制日志记录器只能在指定的命名空间记录日志,根据命名空间来判断日志记录器是否能记录日志 + /// + /// 要检测的命名空间 + public bool CanLog(string value) + { + if (_config.IsWildCard) + { + if (_config.Namespace == string.Empty)//没有限制命名空间 + return true; + + if (value.Length < _config.Namespace.Length)//指定命名空间长度只能大于或等于配置的命名空间长度 + return false; + + string ns = value == _config.Namespace + ? value + : value.Substring(0, _config.Namespace.Length); + if (ns == _config.Namespace) + return true; + } + + return value == _config.Namespace; + } + + /// + /// Targets + /// + public IEnumerable Targets + { + get { return _targets; } + } + + #endregion + + internal void AddTarget(ITarget target) + { + _targets.Add(target); + } + + internal bool ContainsTarget(ITarget target) + { + return _targets.Contains(target); + } + + protected virtual void WriteEntry(LogLevel level, string msg) + { + if (level < _config.MinLevel) + return; + + LogEntry entry = CreateEntry(level, msg); + WriteToTargets(entry, _targets); + } + + protected virtual void WriteEntry(LogLevel level, string msg, Exception ex) + { + if (level < _config.MinLevel) + return; + + LogEntry entry = CreateEntry(level, msg, ex); + WriteToTargets(entry, _targets); + } + + protected virtual void WriteToTargets(LogEntry entry, IEnumerable targets) + { + foreach (ITarget target in _targets) + target.Write(entry); + } + + /// + /// 创建一个日志实体对象 + /// + protected virtual LogEntry CreateEntry(LogLevel level, string msg) + { + return new LogEntry + { + CreatedAt = DateTime.Now, + Level = level, + Message = msg, + StackFrames = new StackTrace(SkipCount).GetFrames(), + ThreadID = Thread.CurrentThread.ManagedThreadId, + Logger = this + }; + } + + /// + /// 创建一个日志实体对象 + /// + protected virtual LogEntry CreateEntry(LogLevel level, string msg, Exception ex) + { + return new LogEntry + { + CreatedAt = DateTime.Now, + Exception = ex, + Level = level, + Message = msg, + StackFrames = new StackTrace(SkipCount).GetFrames(), + ThreadID = Thread.CurrentThread.ManagedThreadId, + Logger = this + }; + } + + /// + /// 获取跳过的堆栈帧数 + /// + protected virtual int SkipCount + { + get { return 3; } + } + } +} \ No newline at end of file diff --git a/src/Kalman/Logging/MultiLogger.cs b/src/Kalman/Logging/MultiLogger.cs new file mode 100644 index 0000000..454dd81 --- /dev/null +++ b/src/Kalman/Logging/MultiLogger.cs @@ -0,0 +1,54 @@ +using System.Collections.Generic; + +namespace Kalman.Logging +{ + /// + /// 多日志记录器 + /// + /// + /// 当配置中的命名空间匹配多个日志记录器的时候使用 + /// + class MultiLogger : Logger + { + private readonly Dictionary _loggerMapping = new Dictionary(); + + /// + /// 初始化,合并多个日志记录器的Target + /// + /// 所有匹配的日志记录器 + public MultiLogger(IEnumerable loggers) + { + foreach (var logger in loggers) + { + foreach (var target in logger.Targets) + { + if (ContainsTarget(target)) continue; + _loggerMapping.Add(target, logger); + AddTarget(target); + } + } + } + + /// + /// 将日志实体写入到所有Target + /// + /// + /// + protected override void WriteToTargets(LogEntry entry, IEnumerable targets) + { + foreach (var target in targets) + { + entry.Logger = _loggerMapping[target]; + target.Write(entry.Clone() as LogEntry); + } + } + + /// + /// 获取跳过的堆栈帧数 + /// + protected override int SkipCount + { + get { return 3; } + } + } +} diff --git a/src/Kalman/Logging/NullLogger.cs b/src/Kalman/Logging/NullLogger.cs new file mode 100644 index 0000000..e94e2b0 --- /dev/null +++ b/src/Kalman/Logging/NullLogger.cs @@ -0,0 +1,148 @@ +using System; +using System.Collections.Generic; + +namespace Kalman.Logging +{ + /// + /// 空日志记录器,不记录任何日志 + /// + public class NullLogger : ILogger + { + private string _Name = "NullLogger"; + private string _NameSpace = string.Empty; + private readonly IEnumerable _Targets = new List(); + + /// + /// 获取可以被记录日志的最小级别 + /// + public LogLevel MinLevel + { + get { return LogLevel.Fatal; } + } + + /// + /// 获取或设置日志记录器的名称 + /// + public string Name + { + get { return _Name; } + set { _Name = value; } + } + + /// + /// 获取或设置日志记录器所作用的命名空间 + /// + public string NameSpace + { + get { return _NameSpace; } + set { _NameSpace = value; } + } + + /// + /// 获取日志记录器写入目标集合 + /// + public IEnumerable Targets + { + get { return _Targets; } + } + + /// + /// 用来跟踪程序的执行情况 + /// + public void Trace(string msg) + { + } + + /// + /// 用来跟踪程序的执行情况 + /// + public void Trace(string msg, Exception ex) + { + } + + /// + /// + /// + public void Debug(string msg) + { + } + + /// + /// + /// + public void Debug(string msg, Exception ex) + { + } + + /// + /// + /// + public void Info(string msg) + { + } + + /// + /// + /// + public void Info(string msg, Exception ex) + { + } + + /// + /// + /// + public void Warning(string msg) + { + } + + /// + /// + /// + public void Warning(string msg, Exception ex) + { + } + + /// + /// + /// + public void Error(string msg) + { + } + + /// + /// + /// + public void Error(string msg, Exception ex) + { + } + + /// + /// + /// + public void Fatal(string msg) + { + } + + /// + /// + /// + public void Fatal(string msg, Exception ex) + { + } + + /// + /// 加载配置 + /// + public void LoadConfig(LoggerConfig config) + { + } + + /// + /// 限制日志记录器只能在指定的命名空间记录日志,根据命名空间来判断日志记录器是否能记录日志 + /// + public bool CanLog(string value) + { + return false; + } + } +} diff --git a/src/Kalman/Logging/Targets/ConsoleTarget.cs b/src/Kalman/Logging/Targets/ConsoleTarget.cs new file mode 100644 index 0000000..0251956 --- /dev/null +++ b/src/Kalman/Logging/Targets/ConsoleTarget.cs @@ -0,0 +1,140 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Xml; +using Kalman.Utilities; + +namespace Kalman.Logging.Targets +{ + /// + /// 将日志输出到控制台 + /// + public class ConsoleTarget : ITarget + { + private readonly Queue _queue = new Queue(); + private bool _isWriting; + + public ConsoleTarget(IFormatter formatter) + { + if (formatter == null) + throw new ArgumentNullException("formatter"); + + Formatter = formatter; + } + + /// + /// 加载配置 + /// + /// + /// 配置已经被加载 + /// 参数config 不能为空 + /// 配置无法正确加载 + public void LoadConfig(TargetConfig config) + { + if (config == null) + throw new ArgumentNullException("config"); + + Name = config.Name; + foreach (XmlNode node in config.ChildConfig) + { + try + { + if (node.ChildNodes.Count != 1) + throw new ConfigurationErrorsException("ConsoleTarget子元素 " + node.Name + "只能为单值元素"); + + object value = Enum.Parse(typeof(ConsoleColor), node.FirstChild.Value, true); + string fc = node.Name.Substring(0, 1).ToUpper(); + GetType().GetProperty(StringUtil.InitialToUpper(node.Name)).SetValue(this, value, null); + } + catch (Exception ex) + { + throw new ConfigurationErrorsException("解析ConsoleTarget子元素值 '" + node.FirstChild.Value + "'失败", ex); + } + } + } + + /// + /// 获取或设置Target名称 + /// + public string Name { get; private set; } + + /// + /// 获取或设置格式化器 + /// + public IFormatter Formatter { get; private set; } + + /// + /// 写日志实体 + /// + public void Write(LogEntry logEntry) + { + lock (_queue) + { + _queue.Enqueue(logEntry); + if (_isWriting) return; + + System.Threading.ThreadPool.QueueUserWorkItem(DoWrite); + _isWriting = true; + } + } + + //写日志线程方法,递归 + private void DoWrite(object state) + { + LogEntry entry; + lock (_queue) + entry = _queue.Dequeue(); + + string msg = Formatter.Format(entry); + ConsoleColor color = Console.ForegroundColor; + Console.ForegroundColor = GetColor(entry.Level); + Console.WriteLine(msg); + Console.ForegroundColor = color; + + lock (_queue) + { + if (_queue.Count == 0) + { + _isWriting = false; + return; + } + } + + DoWrite(null); + } + + private ConsoleColor GetColor(LogLevel level) + { + switch (level) + { + case LogLevel.Trace: + return TraceColor; + case LogLevel.Debug: + return DebugColor; + case LogLevel.Info: + return InfoColor; + case LogLevel.Warning: + return WarningColor; + case LogLevel.Error: + return ErrorColor; + case LogLevel.Fatal: + return FatalColor; + default: + return ConsoleColor.Gray; + } + } + + public ConsoleColor WarningColor { get; set; } + + public ConsoleColor ErrorColor { get; set; } + + public ConsoleColor DebugColor { get; set; } + + public ConsoleColor TraceColor { get; set; } + + public ConsoleColor InfoColor { get; set; } + + public ConsoleColor FatalColor { get; set; } + + } +} \ No newline at end of file diff --git a/src/Kalman/Logging/Targets/DbTarget.cs b/src/Kalman/Logging/Targets/DbTarget.cs new file mode 100644 index 0000000..465937d --- /dev/null +++ b/src/Kalman/Logging/Targets/DbTarget.cs @@ -0,0 +1,187 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Xml; +using System.Configuration; +using System.Data.Common; +using System.Data.SqlClient; +using Kalman.Logging.Formatters; +using Kalman.Extensions; +using Kalman.Utilities; + +namespace Kalman.Logging.Targets +{ + public class DbTarget : ITarget + { + public DbTarget(IFormatter formatter) + { + CheckUtil.ArgumentNotNull(formatter, "formatter"); + + Formatter = formatter; + } + + #region ITarget 成员 + + public void LoadConfig(TargetConfig config) + { + CheckUtil.ArgumentNotNull(config, "config"); + + Name = config.Name; + foreach (XmlNode node in config.ChildConfig) + { + try + { + if (node.ChildNodes.Count != 1) + throw new ConfigurationErrorsException("DbTarget子元素 " + node.Name + "只能为单值元素"); + + switch (node.Name) + { + case "connectionStringName": + ConnectionStringName = node.FirstChild.Value; + break; + case "commandText": + CommandText = node.FirstChild.Value; + break; + } + } + catch (FormatException ex) + { + throw new ConfigurationErrorsException("解析DbTarget子元素值 '" + node.FirstChild.Value + "'失败", ex); + } + } + } + + public string Name { get; private set; } + + public IFormatter Formatter { get; set; } + + /// + /// 连接字符串名称,必须配置connectionStrings节 + /// + public string ConnectionStringName { get; set; } + + /// + /// 将日志写入数据库的Sql语句 + /// + public string CommandText { get; set; } + + public void Write(LogEntry logEntry) + { + ConnectionStringSettings css = ConfigurationManager.ConnectionStrings[ConnectionStringName]; + DbProviderFactory factory = SqlClientFactory.Instance; + if (css.ProviderName != string.Empty) factory = DbProviderFactories.GetFactory(css.ProviderName); + + using (DbConnection cn = factory.CreateConnection()) + { + cn.ConnectionString = css.ConnectionString; + cn.Open(); + DbCommand cmd = cn.CreateCommand(); + cmd.CommandType = System.Data.CommandType.Text; + cmd.CommandText = this.CommandText; + + //@Level 日志级别 + if (this.CommandText.Contains("@Level")) + { + DbParameter p1 = factory.CreateParameter(); + p1.ParameterName = "Level"; + p1.DbType = System.Data.DbType.String; + p1.Size = 10; + p1.Value = logEntry.Level.ToString(); + + cmd.Parameters.Add(p1); + } + + //@Message 日志消息 + if (this.CommandText.Contains("@Message")) + { + DbParameter p2 = factory.CreateParameter(); + p2.ParameterName = "Message"; + p2.DbType = System.Data.DbType.String; + p2.Size = 1000; + p2.Value = logEntry.Message.CutString(0, 1000); + + cmd.Parameters.Add(p2); + } + + //@CreatedAt 创建时间 + if (this.CommandText.Contains("@CreatedAt")) + { + DbParameter p3 = factory.CreateParameter(); + p3.ParameterName = "CreatedAt"; + p3.DbType = System.Data.DbType.DateTime; + p3.Value = logEntry.CreatedAt; + + cmd.Parameters.Add(p3); + } + + //@ThreadID 线程ID + if (this.CommandText.Contains("@ThreadID")) + { + DbParameter p4 = factory.CreateParameter(); + p4.ParameterName = "ThreadID"; + p4.DbType = System.Data.DbType.Int32; + p4.Value = logEntry.ThreadID; + + cmd.Parameters.Add(p4); + } + + //@StackFrames 堆栈帧集合(描述方法的调用关系) + if (this.CommandText.Contains("@StackFrames")) + { + DbParameter p5 = factory.CreateParameter(); + p5.ParameterName = "StackFrames"; + p5.DbType = System.Data.DbType.String; + p5.Size = 200; + p5.Value = new StackTraceFormatter().Format(logEntry).CutString(0, 200); + + cmd.Parameters.Add(p5); + } + + //@Exception 异常信息,暂时只记录堆栈跟踪信息 + if (this.CommandText.Contains("@Exception")) + { + DbParameter p6 = factory.CreateParameter(); + p6.ParameterName = "Exception"; + p6.DbType = System.Data.DbType.String; + p6.Size = 2000; + p6.Value = logEntry.Exception.StackTrace.CutString(0, 2000); + + cmd.Parameters.Add(p6); + } + + //@LogText 使用格式化器格式化后的日志文本 + if (this.CommandText.Contains("@LogText")) + { + DbParameter p7 = factory.CreateParameter(); + p7.ParameterName = "LogText"; + p7.DbType = System.Data.DbType.String; + p7.Size = 2000; + + if (this.Formatter != null) + p7.Value = Formatter.Format(logEntry).CutString(0, 2000); + else + p7.Value = logEntry.Message; + + cmd.Parameters.Add(p7); + } + + //@Logger 日志记录器名称 + if (this.CommandText.Contains("@Logger")) + { + DbParameter p8 = factory.CreateParameter(); + p8.ParameterName = "Logger"; + p8.DbType = System.Data.DbType.String; + p8.Size = 50; + p8.Value = logEntry.Logger.Name.CutString(0, 50); + + cmd.Parameters.Add(p8); + } + + cmd.ExecuteNonQuery(); + } + } + + #endregion + } +} diff --git a/src/Kalman/Logging/Targets/EventLogTarget.cs b/src/Kalman/Logging/Targets/EventLogTarget.cs new file mode 100644 index 0000000..06d1461 --- /dev/null +++ b/src/Kalman/Logging/Targets/EventLogTarget.cs @@ -0,0 +1,121 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Diagnostics; +using System.Xml; +using System.Configuration; +using Kalman.Utilities; + +namespace Kalman.Logging.Targets +{ + /// + /// Windows事件日志 + /// + public class EventLogTarget : ITarget + { + public EventLogTarget(IFormatter formatter) + { + if (formatter == null) + throw new ArgumentNullException("formatter"); + + Formatter = formatter; + } + + #region ITarget 成员 + + public void LoadConfig(TargetConfig config) + { + if (config == null) + throw new ArgumentNullException("config"); + + Name = config.Name; + foreach (XmlNode node in config.ChildConfig) + { + try + { + if (node.ChildNodes.Count != 1) + throw new ConfigurationErrorsException("EventLogTarget子元素 " + node.Name + "只能为单值元素"); + + switch (node.Name) + { + case "maxSize": + MaxSize = ConvertUtil.ToInt64(node.FirstChild.Value, 1024); + break; + case "eventLogName": + EventLogName = node.FirstChild.Value; + break; + } + } + catch (FormatException ex) + { + throw new ConfigurationErrorsException("解析EventLogTarget子元素值 '" + node.FirstChild.Value + "'失败", ex); + } + } + } + + public string Name { get; private set; } + + public IFormatter Formatter { get; set; } + + public void Write(LogEntry logEntry) + { + EventLog eventLog = new EventLog(); + + if (string.IsNullOrEmpty(this.EventLogName)) + { + eventLog.Log = "Kalman.Logging"; + } + else + { + eventLog.Log = this.EventLogName; + } + + if (!EventLog.SourceExists(logEntry.Logger.Name)) + { + EventLog.CreateEventSource(logEntry.Logger.Name, EventLogName); + } + + string logMsg = this.Formatter.Format(logEntry); + + eventLog.MaximumKilobytes = this.MaxSize; + eventLog.Source = logEntry.Logger.Name; + eventLog.WriteEntry(logMsg, GetEventLogEntryType(logEntry.Level)); + } + + #endregion + + /// + /// 事件日志名称 + /// + public string EventLogName { get; set; } + + /// + /// 事件日志显示名称 + /// + public string EventLogDisplayName { get; set; } + + /// + /// 日志文件最大尺寸[kb] + /// + public long MaxSize { get; set; } + + EventLogEntryType GetEventLogEntryType(LogLevel level) + { + switch (level) + { + case LogLevel.Trace: + case LogLevel.Debug: + case LogLevel.Info: + return EventLogEntryType.Information; + case LogLevel.Warning: + return EventLogEntryType.Warning; + case LogLevel.Error: + case LogLevel.Fatal: + return EventLogEntryType.Error; + default: + return EventLogEntryType.Information; + } + } + } +} diff --git a/src/Kalman/Logging/Targets/FileTarget.cs b/src/Kalman/Logging/Targets/FileTarget.cs new file mode 100644 index 0000000..eb7ebe6 --- /dev/null +++ b/src/Kalman/Logging/Targets/FileTarget.cs @@ -0,0 +1,331 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.IO; +using System.Xml; +using Kalman.Utilities; + +namespace Kalman.Logging.Targets +{ + /// + /// 将日志输出到文件 + /// + public class FileTarget : ITarget + { + private TargetConfig _Config; + private readonly Queue _Queue = new Queue(); + private bool _IsWriting; + + public FileTarget(IFormatter formatter) + { + CheckUtil.ArgumentNotNull(formatter, "formatter"); + + Formatter = formatter; + DaysToKeepLogs = 0; + + //路径规则相关 + YearInPath = false; + MonthInPath = true; + DayInPath = false; + LoggerNameInPath = false; + LogLevelInPath = false; + + //文件名规则相关,优先级Hour>Day>Month>Year,其他附加在日期时间后面 + WritePerYear = false; + WritePerMonth = false; + WritePerDay = true; + WritePerHour = false; + LoggerNameInFilename = false; + LogLevelInFilename = false; + } + + /// + /// 获取或设置Target名称 + /// + public string Name { get; set; } + + /// + /// 获取或设置格式化器 + /// + public IFormatter Formatter { get; set; } + + + #region 可配置属性 + /// + /// 获取或设置日志文件名,如果配置了这个参数,则文件名规则失效 + /// + public string FileName { get; set; } + + /// + /// 获取或设置日志保留天数(0表示永久保留) + /// + public int DaysToKeepLogs { get; set; } + + /// + /// 年份作为写日志路径的一部分(yyyy) + /// + public bool YearInPath { get; set; } + + /// + /// 月份作为写日志路径的一部分(yyyyMM),默认true + /// + public bool MonthInPath { get; set; } + + /// + /// 日期作为写日志路径的一部分(yyyyMMdd) + /// + public bool DayInPath { get; set; } + + /// + /// 是否将日志记录器名称作为写日志路径的一部分 + /// + public bool LoggerNameInPath { get; set; } + + /// + /// 是否将日志级别作为写日志路径的一部分 + /// + public bool LogLevelInPath { get; set; } + + /// + /// 获取或设置是否直接写日志,不通过队列和线程池 + /// + public bool WriteDirectly { get; set; } + + /// + /// 每年写一个日志文件,文件名包含年份(yyyy) + /// + public bool WritePerYear { get; set; } + + /// + /// 每月写一个日志文件,文件名包含月份(yyyyMM) + /// + public bool WritePerMonth { get; set; } + + /// + /// 每天写一个日志文件,文件名包含日期(yyyyMMdd),默认true + /// + public bool WritePerDay { get; set; } + + /// + /// 每小时写一个日志文件,文件名包含小时(yyyyMMdd_HH) + /// + public bool WritePerHour { get; set; } + + /// + /// 是否将日志记录器名称作为日志文件名的一部分,文件名包含日志记录器名称 + /// + public bool LoggerNameInFilename { get; set; } + + /// + /// 是否将日志级别作为日志文件名的一部分,文件名包含日志级别 + /// + public bool LogLevelInFilename { get; set; } + + private string _BaseDirectory = string.Empty; + /// + /// 获取写日志的基础目录 + /// + public string BaseDirectory + { + get + { + if (_BaseDirectory == string.Empty || Directory.Exists(_BaseDirectory) == false) + { + string dir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "log"); + if (Directory.Exists(dir) == false) Directory.CreateDirectory(dir); + return dir; + } + else + { + return _BaseDirectory; + } + } + } + + #endregion + + #region 加载配置 + /// + /// 加载配置 + /// + /// + /// 配置已经被加载 + /// 参数config 不能为空 + /// 配置无法正确加载 + public void LoadConfig(TargetConfig config) + { + CheckUtil.ArgumentNotNull(config,"config"); + + _Config = config; + Name = _Config.Name; + foreach (XmlNode node in config.ChildConfig) + { + try + { + if (node.ChildNodes.Count != 1) + throw new ConfigurationErrorsException("FileTarget子元素 " + node.Name + "只能为单值元素"); + + switch (node.Name) + { + case "daysToKeepLogs": + DaysToKeepLogs = int.Parse(node.FirstChild.Value); + break; + case "writeDirectly": + WriteDirectly = node.FirstChild.Value.ToLower() == "true"; + break; + case "baseDirectory": + _BaseDirectory = node.FirstChild.Value; + break; + case "yearInPath": + YearInPath = node.FirstChild.Value.ToLower() == "true"; + break; + case "monthInPath": + MonthInPath = node.FirstChild.Value.ToLower() == "true"; + break; + case "dayInPath": + DayInPath = node.FirstChild.Value.ToLower() == "true"; + break; + case "loggerNameInPath": + LoggerNameInPath = node.FirstChild.Value.ToLower() == "true"; + break; + case "logLevelInPath": + LogLevelInPath = node.FirstChild.Value.ToLower() == "true"; + break; + case "fileName": + FileName = node.FirstChild.Value; + break; + case "writePerYear": + WritePerYear = node.FirstChild.Value.ToLower() == "true"; + break; + case "writePerMonth": + WritePerMonth = node.FirstChild.Value.ToLower() == "true"; + break; + case "writePerDay": + WritePerDay = node.FirstChild.Value.ToLower() == "true"; + break; + case "writePerHour": + WritePerHour = node.FirstChild.Value.ToLower() == "true"; + break; + case "loggerNameInFilename": + LoggerNameInFilename = node.FirstChild.Value.ToLower() == "true"; + break; + case "logLevelInFilename": + LogLevelInFilename = node.FirstChild.Value.ToLower() == "true"; + break; + default: break; + } + } + catch (FormatException ex) + { + throw new ConfigurationErrorsException("解析FileTarget子元素值 '" + node.FirstChild.Value + "'失败", ex); + } + } + + try + { + if (string.IsNullOrEmpty(_BaseDirectory) == false && Directory.Exists(_BaseDirectory) == false) + { + Directory.CreateDirectory(_BaseDirectory); + } + } + catch (Exception ex) + { + LogManager.TriggerEvent(this, ex); + } + } + #endregion + + #region 写文件日志 + /// + /// 写日志实体 + /// + public void Write(LogEntry logEntry) + { + if (WriteDirectly) + { + lock (_Queue) + WriteLog(logEntry); + return; + } + + lock (_Queue) + { + _Queue.Enqueue(logEntry); + if (_IsWriting) return; + + System.Threading.ThreadPool.QueueUserWorkItem(DoWrite); + _IsWriting = true; + } + } + + private void DoWrite(object state) + { + LogEntry entry; + lock (_Queue) + entry = _Queue.Dequeue(); + + WriteLog(entry); + + lock (_Queue) + { + if (_Queue.Count == 0) + { + _IsWriting = false; + return; + } + } + + DoWrite(null); + } + + private void WriteLog(LogEntry entry) + { + try + { + string path = this.BaseDirectory; + string msg = Formatter.Format(entry); + + if(YearInPath) path = Path.Combine(path, DateTime.Now.ToString("yyyy")); + if (MonthInPath) path = Path.Combine(path, DateTime.Now.ToString("yyyyMM")); + if (DayInPath) path = Path.Combine(path, DateTime.Now.ToString("yyyyMMdd")); + if (LoggerNameInPath) path = Path.Combine(path, entry.Logger.Name); + if (LogLevelInPath) path = Path.Combine(path, entry.Level.ToString()); + + if (Directory.Exists(path) == false) Directory.CreateDirectory(path); + + string filename = GenerateFilename(entry); + path = Path.Combine(path, filename); + File.AppendAllText(path, msg + Environment.NewLine); + } + catch (Exception ex) + { + LogManager.TriggerEvent(this, ex); + } + } + + /// + /// 按规则生成日志文件名,不包含路径 + /// + /// + private string GenerateFilename(LogEntry entry) + { + string filename = FileName; + + if (string.IsNullOrEmpty(filename)) + { + if (WritePerYear) filename = DateTime.Now.ToString("yyyy"); + if (WritePerMonth) filename = DateTime.Now.ToString("yyyyMM"); + if (WritePerDay) filename = DateTime.Now.ToString("yyyyMMdd"); + if (WritePerHour) filename = DateTime.Now.ToString("yyyyMMdd_HH"); + + if (LoggerNameInFilename) filename = string.Format("{0}_{1}", filename, entry.Logger.Name); + if(LogLevelInFilename) filename = string.Format("{0}_{1}", filename, entry.Level.ToString()); + + filename = filename + ".log"; + } + + return filename; + } + #endregion + } +} diff --git a/src/Kalman/Logging/Targets/RemotingTarget.cs b/src/Kalman/Logging/Targets/RemotingTarget.cs new file mode 100644 index 0000000..610f27b --- /dev/null +++ b/src/Kalman/Logging/Targets/RemotingTarget.cs @@ -0,0 +1,123 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Kalman.Utilities; +using System.Xml; +using Kalman.Remoting; +using System.Configuration; +using System.IO; + +namespace Kalman.Logging.Targets +{ + public class RemotingTarget : ITarget + { + public RemotingTarget(IFormatter formatter) + { + CheckUtil.ArgumentNotNull(formatter, "formatter"); + this.Formatter = formatter; + this.ClientName = string.Empty; + } + + #region ITarget 成员 + + /// + /// 加载配置 + /// + /// + /// 配置已经被加载 + /// 参数config 不能为空 + /// 配置无法正确加载 + public void LoadConfig(TargetConfig config) + { + CheckUtil.ArgumentNotNull(config, "config"); + + this.Name = config.Name; + foreach (XmlNode node in config.ChildConfig) + { + try + { + if (node.ChildNodes.Count != 1) + throw new ConfigurationErrorsException("RemotingTarget子元素 " + node.Name + "只能为单值元素"); + + switch (node.Name) + { + case "clientName": + ClientName = node.FirstChild.Value; + break; + case "appName": + AppName = node.FirstChild.Value; + break; + default: break; + } + } + catch (FormatException ex) + { + throw new ConfigurationErrorsException("解析RemotingTarget子元素值 '" + node.FirstChild.Value + "'失败", ex); + } + } + } + + /// + /// 获取或设置Target名称 + /// + public string Name { get; set; } + + /// + /// 获取或设置格式化器 + /// + public IFormatter Formatter { get; set; } + + /// + /// 写日志实体 + /// + public void Write(LogEntry logEntry) + { + string msg = Formatter.Format(logEntry); + + try + { + LoggingService logger; + + if (string.IsNullOrEmpty(ClientName)) + { + logger = RemotingClientProxy.Instance.GetObject(); + } + else + { + logger = RemotingClientProxy.Instance.GetObjectByClient(ClientName); + } + + logger.WriteLog(AppName, msg); + + } + catch (Exception ex) + { + //写Remoting日志失败时改写本地文件 + string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "log"); + if (Directory.Exists(path) == false) Directory.CreateDirectory(path); + string logPath = Path.Combine(path, DateTime.Now.ToString("yyyy-MM-dd") + ".log"); + string errPath = Path.Combine(path, "logging_error.log"); + + string time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); + string log = string.Format("{0} {1}\r\n", time, msg); + File.AppendAllText(logPath, log, Encoding.UTF8); + + string err = string.Format("{0} 写Remoting日志失败,错误信息:{1}\r\n", time, ex.ToString()); + File.AppendAllText(errPath, err, Encoding.UTF8); + } + } + + #endregion + + /// + /// Remoting ClientName + /// + public string ClientName { get; set; } + + /// + /// 应用程序名称(用来区分不同应用程序的写日志路径) + /// + public string AppName { get; set; } + } +} diff --git a/src/Kalman/Logging/help.txt b/src/Kalman/Logging/help.txt new file mode 100644 index 0000000..0036004 --- /dev/null +++ b/src/Kalman/Logging/help.txt @@ -0,0 +1,144 @@ +配置示例 + + + + + +
+ + + + + + + + + + + + + + + d:\log + + + red + + + Northwind_Local + + INSERT INTO Log (Logger,LogLevel,ThreadID,CreateDate,LogText) VALUES (@Logger, @Level, @ThreadID, @CreatedAt, @LogText) + + + + Kalman.Logging + 1024 + + + + HR.Recurit + + + + + + + + + + +若日志组件没有配置,则默认调用NullLogger,不会写任何日志 + +Formatter + +name 格式化器的名称 +type 格式化器类型名称,可以指定自定义的格式化器 +format 组件提供默认格式化器DefaultFormatter,可以自定义format字符串来限制日志消息的输出格式,如: + format="{DateTime:yyyy-MM-dd HH:mm:ss.ffff} {ThreadId} {StackTrace:3,40} {Message} + 格式说明 + 日志实体成员定义用一对大括号限定,格式为{日志实体成员名称:格式字符串或值列表} + {DateTime:yyyy-MM-dd HH:mm:ss.ffff} 冒号后面跟的是日期的格式化字符串 + {StackTrace:3,40} 冒号后面格式为[帧数,填充字符的长度,跳过的帧数] + {LogLevel} 日志级别 + {Message} 日志消息内容 + {ThreadID} 线程ID + + +Target + +name Target名称 +type Target类型名称,可以指定自定义的Target +formatter 指定Target所使用的格式化器名称 + + Target下面可以声明一系列子元素,用来设置其成员变量的值 + ConsoleTarget + 可以指定Console显示不同级别日志消息的颜色,如:Red + Console颜色枚举请参考ConsoleColor + + FileTarget + 7 + true + d:\log + + false + true + false + false + false + + app.log + + false + false + true + false + false + false + + 写日志路径格式 + BaseDirectory + Date[format:yyyyMM]+[LoggerName],例如:D:\...\log\201007\[LoggerName]\[LogLevel] + 日志文件名格式 + yyyy-MM-dd.log yyyy-MM-dd[HH].log + + DbTarget + Northwind_Local 连接字符串名称 + + INSERT INTO Log (Logger,LogLevel,ThreadID,CreateDate,LogText) VALUES (@Logger, @Level, @ThreadID, @CreatedAt, @LogText) + + 每个日志表的字符对应一个日志属性参数[创建日志表时可选几个必须参数作为字段],可用参数列表说明如下: + @Level 数据类型[varchar(10)] 日志级别 + @Message 数据类型[varchar(1000)] 日志消息 + @CreatedAt 数据类型[datetime] 创建时间 + @ThreadID 数据类型[int] 线程ID + @StackFrames 数据类型[varchar(200)] 堆栈帧集合(描述方法的调用关系) + @Exception 数据类型[varchar(2000)] 异常信息,暂时只记录堆栈跟踪信息 + @LogText 数据类型[varchar(2000)] 使用格式化器格式化后的日志文本 + @Logger 数据类型[varchar(50)] 日志记录器名称 + + EventLogTarget + Kalman.Logging 事件日志名称 + 1024 事件日志文件最大尺寸[kb],默认1024 + +Logger + +name 日志记录器的名称 +namespace 日志记录器的所作用的命名空间,可以在指定的命名空间内使用这个日志记录器,可以使用通配符*,比如 + Kalman.* 表示在命名空间Kalman下的所有类都可以使用这个日志记录器 + Kalman.Remoting 表示只能在命名空间Kalman.Remoting下使用这个日志记录器 + 若namespace属性没配置,则默认为“*”,表示该Logger可以在任意地方写日志 +targets Target名称字符串,多个Target用逗号隔开,表示日志记录器可以将日志输出到多个Target +minLevel 记录日志的最小级别,低于这个级别不予记录,日志级别从低到高如下:Trace,Debug,Info,Warning,Error,Fatal + +日志调用方法 + +1、使用当前类的Logger实例写日志,通过配置限制指定命名空间下的类的写日志行为 +ILogger logger = LogManager.GetCurrentClassLogger(); +logger.Info("log message"); +logger.Error("log message",ex); + +2、使用指定名称的Logger实例写日志,不受配置的命名空间限制 +ILogger logger = LogManager.GetLogger("DbLogger"); +logger.Info("test data"); +logger.Error("test data",ex); + + \ No newline at end of file diff --git a/src/Kalman/Mapping/DataReaderToObjectMapper.cs b/src/Kalman/Mapping/DataReaderToObjectMapper.cs new file mode 100644 index 0000000..500fc5d --- /dev/null +++ b/src/Kalman/Mapping/DataReaderToObjectMapper.cs @@ -0,0 +1,348 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using EmitMapper; +using EmitMapper.Mappers; +using System.Data.Common; +using System.Reflection; +using EmitMapper.Utils; +using EmitMapper.MappingConfiguration.MappingOperations; +using EmitMapper.MappingConfiguration; +using System.Text; + +namespace Kalman.Mapping +{ + /// + /// + /// + /// + public class DataReaderToObjectMapper : ObjectsMapper + { + class DbReaderMappingConfig : IMappingConfigurator + { + class ReaderValuesExtrator + { + public Func valueExtractor; + public int fieldNum; + public string fieldName; + + public ReaderValuesExtrator(string fieldName, Func valueExtractor) + { + fieldNum = -1; + this.fieldName = fieldName; + this.valueExtractor = valueExtractor; + } + + public Delegate ExtrationDelegate + { + get + { + return (ValueGetter) + ( + (value, state) => + { + return ValueToWrite.ReturnValue(GetValue((DbDataReader)state)); + } + ); + } + } + + private T GetValue(DbDataReader reader) + { + if (fieldNum == -1) + { + fieldNum = reader.GetOrdinal(fieldName); + } + return reader.IsDBNull(fieldNum) ? default(T) : valueExtractor(fieldNum, reader); + } + } + + IEnumerable _skipFields; + string _mappingKey; + + public DbReaderMappingConfig(IEnumerable skipFields, string mappingKey) + { + _skipFields = skipFields == null ? new List() : skipFields; + _mappingKey = mappingKey; + } + + public IRootMappingOperation GetRootMappingOperation(Type from, Type to) + { + return null; + } + + private Delegate GetValuesGetter(int ind, MemberInfo m) + { + var memberType = ReflectionUtils.GetMemberType(m); + + //需要判断非数据库字段,否则会抛异常 + if (_mappingKey != null && _mappingKey.IndexOf(string.Concat(m.Name, "$").ToLower()) != -1) + { + if (memberType == typeof(string)) + { + return new ReaderValuesExtrator(m.Name, (idx, reader) => reader.IsDBNull(idx) ? null : reader.GetString(idx)).ExtrationDelegate; + } + else if (memberType == typeof(bool)) + { + return new ReaderValuesExtrator(m.Name, (idx, reader) => reader.GetBoolean(idx)).ExtrationDelegate; + } + else if (memberType == typeof(bool?)) + { + return new ReaderValuesExtrator(m.Name, (idx, reader) => reader.GetBoolean(idx)).ExtrationDelegate; + } + else if (memberType == typeof(Int16)) + { + return new ReaderValuesExtrator(m.Name, (idx, reader) => reader.GetInt16(idx)).ExtrationDelegate; + } + else if (memberType == typeof(Int16?)) + { + return new ReaderValuesExtrator(m.Name, (idx, reader) => reader.GetInt16(idx)).ExtrationDelegate; + } + else if (memberType == typeof(Int32)) + { + return new ReaderValuesExtrator(m.Name, (idx, reader) => reader.GetInt32(idx)).ExtrationDelegate; + } + else if (memberType == typeof(Int32?)) + { + return new ReaderValuesExtrator(m.Name, (idx, reader) => reader.GetInt32(idx)).ExtrationDelegate; + } + else if (memberType == typeof(Int64)) + { + return new ReaderValuesExtrator(m.Name, (idx, reader) => reader.GetInt64(idx)).ExtrationDelegate; + } + else if (memberType == typeof(Int64?)) + { + return new ReaderValuesExtrator(m.Name, (idx, reader) => reader.GetInt64(idx)).ExtrationDelegate; + } + else if (memberType == typeof(byte)) + { + return new ReaderValuesExtrator(m.Name, (idx, reader) => reader.GetByte(idx)).ExtrationDelegate; + } + else if (memberType == typeof(byte?)) + { + return new ReaderValuesExtrator(m.Name, (idx, reader) => reader.GetByte(idx)).ExtrationDelegate; + } + else if (memberType == typeof(char)) + { + return new ReaderValuesExtrator(m.Name, (idx, reader) => reader.GetChar(idx)).ExtrationDelegate; + } + else if (memberType == typeof(char?)) + { + return new ReaderValuesExtrator(m.Name, (idx, reader) => reader.GetChar(idx)).ExtrationDelegate; + } + else if (memberType == typeof(DateTime)) + { + return new ReaderValuesExtrator(m.Name, (idx, reader) => reader.GetDateTime(idx)).ExtrationDelegate; + } + else if (memberType == typeof(DateTime?)) + { + return new ReaderValuesExtrator(m.Name, (idx, reader) => reader.GetDateTime(idx)).ExtrationDelegate; + } + else if (memberType == typeof(decimal)) + { + return new ReaderValuesExtrator(m.Name, (idx, reader) => reader.GetDecimal(idx)).ExtrationDelegate; + } + else if (memberType == typeof(decimal?)) + { + return new ReaderValuesExtrator(m.Name, (idx, reader) => reader.GetDecimal(idx)).ExtrationDelegate; + } + else if (memberType == typeof(double)) + { + return new ReaderValuesExtrator(m.Name, (idx, reader) => reader.GetDouble(idx)).ExtrationDelegate; + } + else if (memberType == typeof(double?)) + { + return new ReaderValuesExtrator(m.Name, (idx, reader) => reader.GetDouble(idx)).ExtrationDelegate; + } + else if (memberType == typeof(float)) + { + return new ReaderValuesExtrator(m.Name, (idx, reader) => reader.GetFloat(idx)).ExtrationDelegate; + } + else if (memberType == typeof(float?)) + { + return new ReaderValuesExtrator(m.Name, (idx, reader) => reader.GetFloat(idx)).ExtrationDelegate; + } + else if (memberType == typeof(Guid)) + { + return new ReaderValuesExtrator(m.Name, (idx, reader) => reader.GetGuid(idx)).ExtrationDelegate; + } + else if (memberType == typeof(Guid?)) + { + return new ReaderValuesExtrator(m.Name, (idx, reader) => reader.GetGuid(idx)).ExtrationDelegate; + } + } + + Func converter = StaticConvertersManager.DefaultInstance.GetStaticConverterFunc(typeof(object), memberType); + if (converter == null) + { + throw new EmitMapperException("Could not convert an object to " + memberType.ToString()); + } + int fieldNum = -1; + string fieldName = m.Name; + Type fieldType = m.GetType(); + return + (ValueGetter) + ( + (value, state) => + { + var reader = ((DbDataReader)state); + object result = null; + + //需要判断非数据库字段,否则会抛异常 + if (_mappingKey != null && _mappingKey.IndexOf(string.Concat(fieldName, "$").ToLower()) == -1) + { + PropertyInfo p = (PropertyInfo)m; + + if (p.PropertyType.IsValueType) + { + var blank = Activator.CreateInstance(p.PropertyType); + return ValueToWrite.ReturnValue(blank); + } + else + { + return ValueToWrite.ReturnValue(null); + } + } + + if (_mappingKey != null) + { + if (fieldNum == -1) + { + fieldNum = reader.GetOrdinal(fieldName); + } + result = reader[fieldNum]; + } + else + { + result = reader[fieldName]; + } + + if (result is DBNull) + { + return ValueToWrite.ReturnValue(null); + } + return ValueToWrite.ReturnValue(converter(result)); + } + ) + ; + } + + public IMappingOperation[] GetMappingOperations(Type from, Type to) + { + return ReflectionUtils + .GetPublicFieldsAndProperties(to) + .Where( + m => m.MemberType == MemberTypes.Field || + m.MemberType == MemberTypes.Property && ((PropertyInfo)m).GetSetMethod() != null + ) + .Where(m => !_skipFields.Select(sf => sf.ToUpper()).Contains(m.Name.ToUpper())) + .Select( + (m, ind) => + new DestWriteOperation() + { + Destination = new MemberDescriptor(new[] { m }), + Getter = GetValuesGetter(ind, m) + } + ) + .ToArray(); + } + + public string GetConfigurationName() + { + if (_mappingKey != null) + { + return "dbreader_" + _mappingKey; + } + else + { + return "dbreader_"; + } + } + + public StaticConvertersManager GetStaticConvertersManager() + { + return null; + } + } + + public DataReaderToObjectMapper( + string mappingKey, + ObjectMapperManager mapperManager, + IEnumerable skipFields) + : base(GetMapperImpl(mappingKey, mapperManager, skipFields)) + { + } + + public DataReaderToObjectMapper(ObjectMapperManager mapperManager) + : this(null, mapperManager, null) + { + } + + public DataReaderToObjectMapper() + : this(null, null, null) + { + } + + public DataReaderToObjectMapper(IEnumerable skipFields) + : this(null, null, skipFields) + { + } + + public T ReadSingle(DbDataReader reader) + { + return ReadSingle(reader, null); + } + + public T ReadSingle(DbDataReader reader, ObjectsChangeTracker changeTracker) + { + T result = reader.Read() ? MapUsingState(reader, reader) : default(T); + if (changeTracker != null) + { + changeTracker.RegisterObject(result); + } + return result; + } + + public IEnumerable ReadCollection(DbDataReader reader) + { + return ReadCollection(reader, null); + } + + public IEnumerable ReadCollection(DbDataReader reader, ObjectsChangeTracker changeTracker) + { + while (reader.Read()) + { + T result = MapUsingState(reader, reader); + if (changeTracker != null) + { + changeTracker.RegisterObject(result); + } + yield return result; + } + reader.Close(); + } + + private static ObjectsMapperBaseImpl GetMapperImpl( + string mappingKey, + ObjectMapperManager mapperManager, + IEnumerable skipFields) + { + IMappingConfigurator config = new DbReaderMappingConfig(skipFields, mappingKey); + + if (mapperManager != null) + { + return mapperManager.GetMapperImpl( + typeof(DbDataReader), + typeof(T), + config); + } + else + { + return ObjectMapperManager.DefaultInstance.GetMapperImpl( + typeof(DbDataReader), + typeof(T), + config); + } + } + } +} diff --git a/src/Kalman/Mapping/MapExt.cs b/src/Kalman/Mapping/MapExt.cs new file mode 100644 index 0000000..983b015 --- /dev/null +++ b/src/Kalman/Mapping/MapExt.cs @@ -0,0 +1,102 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Data.Common; +using System.Data; + +namespace Kalman.Mapping +{ + /// + /// EmitMapper扩展类 + /// + public static class MapExt + { + public static string ToCSV(this IEnumerable collection, string delim) + { + if (collection == null) + { + return ""; + } + + StringBuilder result = new StringBuilder(); + foreach (T value in collection) + { + result.Append(value); + result.Append(delim); + } + if (result.Length > 0) + { + result.Length -= delim.Length; + } + return result.ToString(); + } + + public static T ToObject(this DbDataReader reader) + { + return reader.ToObject(null, null, null); + } + + public static T ToObject(this DbDataReader reader, string readerName) + { + return reader.ToObject(readerName, null, null); + } + + public static T ToObject(this DbDataReader reader, string[] excludeFields) + { + return reader.ToObject(null, excludeFields, null); + } + + public static T ToObject(this DbDataReader reader, string readerName, string[] excludeFields, ObjectsChangeTracker changeTracker) + { + ///这里将数据库表对应的字段串在一起赋值给readerName变量,方便后面判断非数据库字段 + if (string.IsNullOrEmpty(readerName)) + { + var mappingKeyBuilder = new StringBuilder(); + for (int i = 0; i < reader.FieldCount; ++i) + { + mappingKeyBuilder.Append(reader.GetName(i)); + mappingKeyBuilder.Append('$'); + } + readerName = mappingKeyBuilder.ToString().ToLower(); + } + + T result = new DataReaderToObjectMapper(readerName, null, excludeFields).MapUsingState(reader, reader); + if (changeTracker != null) + { + changeTracker.RegisterObject(result); + } + return result; + } + + public static IEnumerable ToObjects(this DbDataReader reader) + { + return reader.ToObjects(null, null, null); + } + + public static IEnumerable ToObjects(this DbDataReader reader, string readerName) + { + return reader.ToObjects(readerName, null, null); + } + + public static IEnumerable ToObjects(this DbDataReader reader, string[] excludeFields) + { + return reader.ToObjects(null, excludeFields, null); + } + + public static IEnumerable ToObjects(this DbDataReader reader, string readerName, string[] excludeFields, ObjectsChangeTracker changeTracker) + { + if (string.IsNullOrEmpty(readerName)) + { + var mappingKeyBuilder = new StringBuilder(); + for (int i = 0; i < reader.FieldCount; ++i) + { + mappingKeyBuilder.Append(reader.GetName(i)); + mappingKeyBuilder.Append('$'); + } + readerName = mappingKeyBuilder.ToString().ToLower(); + } + return new DataReaderToObjectMapper(readerName, null, excludeFields).ReadCollection(reader, changeTracker); + } + + } +} diff --git a/src/Kalman/Mapping/ObjectsChangeTracker.cs b/src/Kalman/Mapping/ObjectsChangeTracker.cs new file mode 100644 index 0000000..6016a6c --- /dev/null +++ b/src/Kalman/Mapping/ObjectsChangeTracker.cs @@ -0,0 +1,115 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using EmitMapper; +using EmitMapper.MappingConfiguration; +using EmitMapper.Utils; +using EmitMapper.MappingConfiguration.MappingOperations; + +namespace Kalman.Mapping +{ + public class ObjectsChangeTracker + { + class MappingConfiguration : IMappingConfigurator + { + public IMappingOperation[] GetMappingOperations(Type from, Type to) + { + return ReflectionUtils + .GetPublicFieldsAndProperties(from) + .Select(m => + new SrcReadOperation + { + Source = new MemberDescriptor(m), + Setter = + (obj, value, state) => + (state as TrackingMembersList).TrackingMembers.Add( + new TrackingMember { name = m.Name, value = value } + ) + } + ) + .ToArray(); + } + + public IRootMappingOperation GetRootMappingOperation(Type from, Type to) + { + return null; + } + + public string GetConfigurationName() + { + return "ObjectsTracker"; + } + + public StaticConvertersManager GetStaticConvertersManager() + { + return null; + } + } + + internal class TrackingMembersList + { + public List TrackingMembers = new List(); + } + + public struct TrackingMember + { + public string name; + public object value; + } + + Dictionary> _trackingObjects = new Dictionary>(); + ObjectMapperManager _mapManager; + + public ObjectsChangeTracker() + { + _mapManager = ObjectMapperManager.DefaultInstance; + } + + public ObjectsChangeTracker(ObjectMapperManager MapManager) + { + _mapManager = MapManager; + } + + public void RegisterObject(object Obj) + { + var type = Obj.GetType(); + _trackingObjects[Obj] = GetObjectMembers(Obj); + } + + public TrackingMember[] GetChanges(object Obj) + { + List originalValues; + if (!_trackingObjects.TryGetValue(Obj, out originalValues)) + { + return null; + } + var currentValues = GetObjectMembers(Obj); + return currentValues + .Where( + (current, idx) => + { + var original = originalValues[idx]; + return + ((original.value == null) != (current.value == null)) + || + (original.value != null && !original.value.Equals(current.value)); + } + ) + .ToArray(); + } + + private List GetObjectMembers(object Obj) + { + var type = Obj.GetType(); + var fields = new TrackingMembersList(); + _mapManager.GetMapperImpl( + type, + null, + new MappingConfiguration() + ).Map(Obj, null, fields); + + return fields.TrackingMembers; + } + } +} diff --git a/src/Kalman/Net/FtpClient.cs b/src/Kalman/Net/FtpClient.cs new file mode 100644 index 0000000..854a45c --- /dev/null +++ b/src/Kalman/Net/FtpClient.cs @@ -0,0 +1,1411 @@ +using System; +using System.IO; +using System.Net; +using System.Net.Sockets; +using System.Text; +using System.Text.RegularExpressions; +using System.Collections; + +//Ftp配置 +namespace Kalman.Net +{ + /* 示例代码 + FTP ftp = new FTP("127.0.0.1", "abc", "123456"); + + //建立文件夹 + ftp.MakeDir("com"); + ftp.ChangeDir("com"); + ftp.MakeDir("mzwu"); + ftp.ChangeDir("mzwu"); + + //文件夹列表 + ArrayList list = ftp.ListDirectories(); + for (int i = 0; i < list.Count; i++) + { + Response.Write(list[i].ToString() + "
"); + } + + //删除文件夹(不能直接删除非空文件夹) + ftp.RemoveDir("com\\mzwu"); + + //上传文件 + ftp.Connect(); + ftp.OpenUpload(@"F:\mzwucom.jpg", Path.GetFileName(@"F:\mzwucom.jpg")); + while (ftp.DoUpload() > 0) + { + int perc = (int)(((ftp.BytesTotal) * 100) / ftp.FileSize); + Response.Write(perc.ToString() + "%
"); + Response.Flush(); + } + ftp.Disconnect(); + + //下载文件 + ftp.Connect(); + ftp.OpenDownload("mzwucom.jpg", @"E:\mzwucom.jpg"); + while (ftp.DoDownload() > 0) + { + int perc = (int)(((ftp.BytesTotal) * 100) / ftp.FileSize); + Response.Write(perc.ToString() + "%
"); + Response.Flush(); + } + ftp.Disconnect(); + + //文件列表 + ArrayList list = ftp.ListFiles(); + for (int i = 0; i < list.Count; i++) + { + Response.Write(list[i].ToString() + "
"); + } + + //文件重命名 + ftp.RenameFile("mzwucom.jpg", "test.jpg"); + + //删除文件 + ftp.RemoveFile("test.jpg"); + + //显示错误信息 + Response.Write(ftp.errormessage); + */ + + /// + /// FTP客户端组件(该组件来自Discuz.Net,已修改命令行中有中文时会出现乱码的问题) + /// + public class FtpClient + { + #region 变量声明 + + /// + /// 服务器连接地址 + /// + public string server; + + /// + /// 登陆帐号 + /// + public string user; + + /// + /// 登陆口令 + /// + public string pass; + + /// + /// 端口号 + /// + public int port; + + /// + /// 无响应时间(FTP在指定时间内无响应) + /// + public int timeout; + + /// + /// 服务器错误状态信息 + /// + public string errormessage; + + + /// + /// 服务器状态返回信息 + /// + private string messages; + + /// + /// 服务器的响应信息 + /// + private string responseStr; + + /// + /// 链接模式(主动或被动,默认为被动) + /// + private bool passive_mode; + + /// + /// 上传或下载信息字节数 + /// + private long bytes_total; + + /// + /// 上传或下载的文件大小 + /// + private long file_size; + + /// + /// 主套接字 + /// + private Socket main_sock; + + /// + /// 要链接的网络地址终结点 + /// + private IPEndPoint main_ipEndPoint; + + /// + /// 侦听套接字 + /// + private Socket listening_sock; + + /// + /// 数据套接字 + /// + private Socket data_sock; + + /// + /// 要链接的网络数据地址终结点 + /// + private IPEndPoint data_ipEndPoint; + + /// + /// 用于上传或下载的文件流对象 + /// + private FileStream file; + + /// + /// 与FTP服务器交互的状态值 + /// + private int response; + + /// + /// 读取并保存当前命令执行后从FTP服务器端返回的数据信息 + /// + private string bucket; + + #endregion + + #region 构造函数 + + /// + /// 构造函数 + /// + public FtpClient() + { + server = null; + user = null; + pass = null; + port = 21; + passive_mode = true; + main_sock = null; + main_ipEndPoint = null; + listening_sock = null; + data_sock = null; + data_ipEndPoint = null; + file = null; + bucket = ""; + bytes_total = 0; + timeout = 10000; //无响应时间为10秒 + messages = ""; + errormessage = ""; + } + + /// + /// 构造函数 + /// + /// 服务器IP或名称 + /// 登陆帐号 + /// 登陆口令 + public FtpClient(string server, string user, string pass) + { + this.server = server; + this.user = user; + this.pass = pass; + port = 21; + passive_mode = true; + main_sock = null; + main_ipEndPoint = null; + listening_sock = null; + data_sock = null; + data_ipEndPoint = null; + file = null; + bucket = ""; + bytes_total = 0; + timeout = 10000; //无响应时间为10秒 + messages = ""; + errormessage = ""; + } + + /// + /// 构造函数 + /// + /// 服务器IP或名称 + /// 端口号 + /// 登陆帐号 + /// 登陆口令 + public FtpClient(string server, int port, string user, string pass) + { + this.server = server; + this.user = user; + this.pass = pass; + this.port = port; + passive_mode = true; + main_sock = null; + main_ipEndPoint = null; + listening_sock = null; + data_sock = null; + data_ipEndPoint = null; + file = null; + bucket = ""; + bytes_total = 0; + timeout = 10000; //无响应时间为10秒 + messages = ""; + errormessage = ""; + } + + + /// + /// 构造函数 + /// + /// 服务器IP或名称 + /// 端口号 + /// 登陆帐号 + /// 登陆口令 + /// 链接方式 + public FtpClient(string server, int port, string user, string pass, int mode) + { + this.server = server; + this.user = user; + this.pass = pass; + this.port = port; + passive_mode = mode <= 1 ? true : false; + main_sock = null; + main_ipEndPoint = null; + listening_sock = null; + data_sock = null; + data_ipEndPoint = null; + file = null; + bucket = ""; + bytes_total = 0; + this.timeout = 10000; //无响应时间为10秒 + messages = ""; + errormessage = ""; + } + + /// + /// 构造函数 + /// + /// 服务器IP或名称 + /// 端口号 + /// 登陆帐号 + /// 登陆口令 + /// 链接方式 + /// 无响应时间(限时),单位:秒 (小于或等于0为不受时间限制) + public FtpClient(string server, int port, string user, string pass, int mode, int timeout_sec) + { + this.server = server; + this.user = user; + this.pass = pass; + this.port = port; + passive_mode = mode <= 1 ? true : false; + main_sock = null; + main_ipEndPoint = null; + listening_sock = null; + data_sock = null; + data_ipEndPoint = null; + file = null; + bucket = ""; + bytes_total = 0; + this.timeout = (timeout_sec <= 0) ? int.MaxValue : (timeout_sec * 1000); //无响应时间 + messages = ""; + errormessage = ""; + } + + #endregion + + #region 属性 + /// + /// 当前是否已连接 + /// + public bool IsConnected + { + get + { + if (main_sock != null) + return main_sock.Connected; + return false; + } + } + + /// + /// 当message缓冲区有数据则返回 + /// + public bool MessagesAvailable + { + get + { + if (messages.Length > 0) + return true; + return false; + } + } + + /// + /// 获取服务器状态返回信息, 并清空messages变量 + /// + public string Messages + { + get + { + string tmp = messages; + messages = ""; + return tmp; + } + } + /// + /// 最新指令发出后服务器的响应 + /// + public string ResponseString + { + get + { + return responseStr; + } + } + + + /// + ///在一次传输中,发送或接收的字节数 + /// + public long BytesTotal + { + get + { + return bytes_total; + } + } + + /// + ///被下载或上传的文件大小,当文件大小无效时为0 + /// + public long FileSize + { + get + { + return file_size; + } + } + + /// + /// 链接模式: + /// true 被动模式 [默认] + /// false: 主动模式 + /// + public bool PassiveMode + { + get + { + return passive_mode; + } + set + { + passive_mode = value; + } + } + + #endregion + + #region 操作 + + /// + /// 操作失败 + /// + private void Fail() + { + Disconnect(); + errormessage += responseStr; + //throw new Exception(responseStr); + } + + + private void SetBinaryMode(bool mode) + { + if (mode) + SendCommand("TYPE I"); + else + SendCommand("TYPE A"); + + ReadResponse(); + if (response != 200) + Fail(); + } + + + private void SendCommand(string command) + { + //Byte[] cmd = Encoding.ASCII.GetBytes((command + "\r\n").ToCharArray()); + Byte[] cmd = Encoding.UTF8.GetBytes((command + "\r\n").ToCharArray()); + //Byte[] cmd = Encoding.BigEndianUnicode.GetBytes((command + "\r\n").ToCharArray()); + + if (command.Length > 3 && command.Substring(0, 4) == "PASS") + { + messages = "\rPASS xxx"; + } + else + { + messages = "\r" + command; + } + + try + { + main_sock.Send(cmd, cmd.Length, 0); + } + catch (Exception ex) + { + try + { + Disconnect(); + errormessage += ex.Message; + return; + } + catch + { + main_sock.Close(); + file.Close(); + main_sock = null; + main_ipEndPoint = null; + file = null; + } + } + } + + + private void FillBucket() + { + Byte[] bytes = new Byte[512]; + long bytesgot; + int msecs_passed = 0; + + while (main_sock.Available < 1) + { + System.Threading.Thread.Sleep(50); + msecs_passed += 50; + //当等待时间到,则断开链接 + if (msecs_passed > timeout) + { + Disconnect(); + errormessage += "Timed out waiting on server to respond."; + return; + } + } + + while (main_sock.Available > 0) + { + bytesgot = main_sock.Receive(bytes, 512, 0); + bucket += Encoding.ASCII.GetString(bytes, 0, (int)bytesgot); + System.Threading.Thread.Sleep(50); + } + } + + + private string GetLineFromBucket() + { + int i; + string buf = ""; + + if ((i = bucket.IndexOf('\n')) < 0) + { + while (i < 0) + { + FillBucket(); + i = bucket.IndexOf('\n'); + } + } + + buf = bucket.Substring(0, i); + bucket = bucket.Substring(i + 1); + + return buf; + } + + + /// + /// 返回服务器端返回信息 + /// + private void ReadResponse() + { + string buf; + messages = ""; + + while (true) + { + buf = GetLineFromBucket(); + + if (Regex.Match(buf, "^[0-9]+ ").Success) + { + responseStr = buf; + response = int.Parse(buf.Substring(0, 3)); + break; + } + else + messages += Regex.Replace(buf, "^[0-9]+-", "") + "\n"; + } + } + + + /// + /// 打开数据套接字 + /// + private void OpenDataSocket() + { + if (passive_mode) + { + string[] pasv; + string server; + int port; + + Connect(); + SendCommand("PASV"); + ReadResponse(); + if (response != 227) + Fail(); + + try + { + int i1, i2; + + i1 = responseStr.IndexOf('(') + 1; + i2 = responseStr.IndexOf(')') - i1; + pasv = responseStr.Substring(i1, i2).Split(','); + } + catch (Exception) + { + Disconnect(); + errormessage += "Malformed PASV response: " + responseStr; + return; + } + + if (pasv.Length < 6) + { + Disconnect(); + errormessage += "Malformed PASV response: " + responseStr; + return; + } + + server = String.Format("{0}.{1}.{2}.{3}", pasv[0], pasv[1], pasv[2], pasv[3]); + port = (int.Parse(pasv[4]) << 8) + int.Parse(pasv[5]); + + try + { + CloseDataSocket(); + + data_sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + +#if NET1 + data_ipEndPoint = new IPEndPoint(Dns.GetHostByName(server).AddressList[0], port); +#else + data_ipEndPoint = new IPEndPoint(System.Net.Dns.GetHostEntry(server).AddressList[0], port); +#endif + + data_sock.Connect(data_ipEndPoint); + + } + catch (Exception ex) + { + errormessage += "Failed to connect for data transfer: " + ex.Message; + return; + } + } + else + { + Connect(); + + try + { + CloseDataSocket(); + + listening_sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + + // 对于端口,则发送IP地址.下面则提取相应信息 + string sLocAddr = main_sock.LocalEndPoint.ToString(); + int ix = sLocAddr.IndexOf(':'); + if (ix < 0) + { + errormessage += "Failed to parse the local address: " + sLocAddr; + return; + } + string sIPAddr = sLocAddr.Substring(0, ix); + // 系统自动绑定一个端口号(设置 port = 0) + System.Net.IPEndPoint localEP = new IPEndPoint(IPAddress.Parse(sIPAddr), 0); + + listening_sock.Bind(localEP); + sLocAddr = listening_sock.LocalEndPoint.ToString(); + ix = sLocAddr.IndexOf(':'); + if (ix < 0) + { + errormessage += "Failed to parse the local address: " + sLocAddr; + + } + int nPort = int.Parse(sLocAddr.Substring(ix + 1)); + + // 开始侦听链接请求 + listening_sock.Listen(1); + string sPortCmd = string.Format("PORT {0},{1},{2}", + sIPAddr.Replace('.', ','), + nPort / 256, nPort % 256); + SendCommand(sPortCmd); + ReadResponse(); + if (response != 200) + Fail(); + } + catch (Exception ex) + { + errormessage += "Failed to connect for data transfer: " + ex.Message; + return; + } + } + } + + + private void ConnectDataSocket() + { + if (data_sock != null) // 已链接 + return; + + try + { + data_sock = listening_sock.Accept(); // Accept is blocking + listening_sock.Close(); + listening_sock = null; + + if (data_sock == null) + { + throw new Exception("Winsock error: " + + Convert.ToString(System.Runtime.InteropServices.Marshal.GetLastWin32Error())); + } + } + catch (Exception ex) + { + errormessage += "Failed to connect for data transfer: " + ex.Message; + } + } + + + private void CloseDataSocket() + { + if (data_sock != null) + { + if (data_sock.Connected) + { + data_sock.Close(); + } + data_sock = null; + } + + data_ipEndPoint = null; + } + + /// + /// 关闭所有链接 + /// + public void Disconnect() + { + CloseDataSocket(); + + if (main_sock != null) + { + if (main_sock.Connected) + { + SendCommand("QUIT"); + main_sock.Close(); + } + main_sock = null; + } + + if (file != null) + file.Close(); + + main_ipEndPoint = null; + file = null; + } + + /// + /// 链接到FTP服务器 + /// + /// 要链接的IP地址或主机名 + /// 端口号 + /// 登陆帐号 + /// 登陆口令 + public void Connect(string server, int port, string user, string pass) + { + this.server = server; + this.user = user; + this.pass = pass; + this.port = port; + + Connect(); + } + + /// + /// 链接到FTP服务器 + /// + /// 要链接的IP地址或主机名 + /// 登陆帐号 + /// 登陆口令 + public void Connect(string server, string user, string pass) + { + this.server = server; + this.user = user; + this.pass = pass; + + Connect(); + } + + /// + /// 链接到FTP服务器 + /// + public bool Connect() + { + if (server == null) + { + errormessage += "No server has been set.\r\n"; + } + if (user == null) + { + errormessage += "No server has been set.\r\n"; + } + + if (main_sock != null) + if (main_sock.Connected) + return true; + + try + { + main_sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); +#if NET1 + main_ipEndPoint = new IPEndPoint(Dns.GetHostByName(server).AddressList[0], port); +#else + main_ipEndPoint = new IPEndPoint(System.Net.Dns.GetHostEntry(server).AddressList[0], port); +#endif + + main_sock.Connect(main_ipEndPoint); + } + catch (Exception ex) + { + errormessage += ex.Message; + return false; + } + + ReadResponse(); + if (response != 220) + Fail(); + + SendCommand("USER " + user); + ReadResponse(); + + switch (response) + { + case 331: + if (pass == null) + { + Disconnect(); + errormessage += "No password has been set."; + return false; + } + SendCommand("PASS " + pass); + ReadResponse(); + if (response != 230) + { + Fail(); + return false; + } + break; + case 230: + break; + } + + return true; + } + + /// + /// 获取FTP当前(工作)目录下的文件列表 + /// + /// 返回文件列表数组 + public ArrayList List() + { + Byte[] bytes = new Byte[512]; + string file_list = ""; + long bytesgot = 0; + int msecs_passed = 0; + ArrayList list = new ArrayList(); + + Connect(); + OpenDataSocket(); + SendCommand("LIST"); + ReadResponse(); + + switch (response) + { + case 125: + case 150: + break; + default: + CloseDataSocket(); + throw new Exception(responseStr); + } + ConnectDataSocket(); + + while (data_sock.Available < 1) + { + System.Threading.Thread.Sleep(50); + msecs_passed += 50; + + if (msecs_passed > (timeout / 10)) + { + break; + } + } + + while (data_sock.Available > 0) + { + bytesgot = data_sock.Receive(bytes, bytes.Length, 0); + file_list += Encoding.ASCII.GetString(bytes, 0, (int)bytesgot); + System.Threading.Thread.Sleep(50); + } + + CloseDataSocket(); + + ReadResponse(); + if (response != 226) + throw new Exception(responseStr); + + foreach (string f in file_list.Split('\n')) + { + if (f.Length > 0 && !Regex.Match(f, "^total").Success) + list.Add(f.Substring(0, f.Length - 1)); + } + + return list; + } + + /// + /// 获取到文件名列表 + /// + /// 返回文件名列表 + public ArrayList ListFiles() + { + ArrayList list = new ArrayList(); + + foreach (string f in List()) + { + if ((f.Length > 0)) + { + if ((f[0] != 'd') && (f.ToUpper().IndexOf("") < 0)) + list.Add(f); + } + } + + return list; + } + + /// + /// 获取路径列表 + /// + /// 返回路径列表 + public ArrayList ListDirectories() + { + ArrayList list = new ArrayList(); + + foreach (string f in List()) + { + if (f.Length > 0) + { + if ((f[0] == 'd') || (f.ToUpper().IndexOf("") >= 0)) + list.Add(f); + } + } + + return list; + } + + /// + /// 获取原始数据信息. + /// + /// 远程文件名 + /// 返回原始数据信息. + public string GetFileDateRaw(string fileName) + { + Connect(); + + SendCommand("MDTM " + fileName); + ReadResponse(); + if (response != 213) + { + errormessage += responseStr; + return ""; + } + + return (this.responseStr.Substring(4)); + } + + /// + /// 得到文件日期. + /// + /// 远程文件名 + /// 返回远程文件日期 + public DateTime GetFileDate(string fileName) + { + return ConvertFTPDateToDateTime(GetFileDateRaw(fileName)); + } + + private DateTime ConvertFTPDateToDateTime(string input) + { + if (input.Length < 14) + throw new ArgumentException("Input Value for ConvertFTPDateToDateTime method was too short."); + + //YYYYMMDDhhmmss": + int year = Convert.ToInt16(input.Substring(0, 4)); + int month = Convert.ToInt16(input.Substring(4, 2)); + int day = Convert.ToInt16(input.Substring(6, 2)); + int hour = Convert.ToInt16(input.Substring(8, 2)); + int min = Convert.ToInt16(input.Substring(10, 2)); + int sec = Convert.ToInt16(input.Substring(12, 2)); + + return new DateTime(year, month, day, hour, min, sec); + } + + /// + /// 获取FTP上的当前(工作)路径 + /// + /// 返回FTP上的当前(工作)路径 + public string GetWorkingDirectory() + { + //PWD - 显示工作路径 + Connect(); + SendCommand("PWD"); + ReadResponse(); + + if (response != 257) + { + errormessage += responseStr; + } + + string pwd; + try + { + pwd = responseStr.Substring(responseStr.IndexOf("\"", 0) + 1);//5); + pwd = pwd.Substring(0, pwd.LastIndexOf("\"")); + pwd = pwd.Replace("\"\"", "\""); // 替换带引号的路径信息符号 + } + catch (Exception ex) + { + errormessage += ex.Message; + return null; + } + + return pwd; + } + + + /// + /// 跳转服务器上的当前(工作)路径 + /// + /// 要跳转的路径 + public bool ChangeDir(string path) + { + Connect(); + SendCommand("CWD " + path); + ReadResponse(); + if (response != 250) + { + errormessage += responseStr; + return false; + } + return true; + } + + /// + /// 创建指定的目录 + /// + /// 要创建的目录 + public void MakeDir(string dir) + { + Connect(); + SendCommand("MKD " + dir); + ReadResponse(); + + switch (response) + { + case 257: + case 250: + break; + default: + { + errormessage += responseStr; + break; + } + } + } + + /// + /// 移除FTP上的指定目录 + /// + /// 要移除的目录 + public void RemoveDir(string dir) + { + Connect(); + SendCommand("RMD " + dir); + ReadResponse(); + if (response != 250) + { + errormessage += responseStr; + return; ; + } + } + + /// + /// 移除FTP上的指定文件 + /// + /// 要移除的文件名称 + public void RemoveFile(string filename) + { + Connect(); + SendCommand("DELE " + filename); + ReadResponse(); + if (response != 250) + { + errormessage += responseStr; + } + } + + /// + /// 重命名FTP上的文件 + /// + /// 原文件名 + /// 新文件名 + public void RenameFile(string oldfilename, string newfilename) + { + Connect(); + SendCommand("RNFR " + oldfilename); + ReadResponse(); + if (response != 350) + { + errormessage += responseStr; + } + else + { + SendCommand("RNTO " + newfilename); + ReadResponse(); + if (response != 250) + { + errormessage += responseStr; + } + } + } + + /// + /// 获得指定文件的大小(如果FTP支持) + /// + /// 指定的文件 + /// 返回指定文件的大小 + public long GetFileSize(string filename) + { + Connect(); + SendCommand("SIZE " + filename); + ReadResponse(); + if (response != 213) + { + errormessage += responseStr; + } + + return Int64.Parse(responseStr.Substring(4)); + } + + /// + /// 上传指定的文件 + /// + /// 要上传的文件 + public bool OpenUpload(string filename) + { + return OpenUpload(filename, filename, false); + } + + /// + /// 上传指定的文件 + /// + /// 本地文件名 + /// 远程要覆盖的文件名 + public bool OpenUpload(string filename, string remotefilename) + { + return OpenUpload(filename, remotefilename, false); + } + + /// + /// 上传指定的文件 + /// + /// 本地文件名 + /// 如果存在,则尝试恢复 + public bool OpenUpload(string filename, bool resume) + { + return OpenUpload(filename, filename, resume); + } + + /// + /// 上传指定的文件 + /// + /// 本地文件名 + /// 远程要覆盖的文件名 + /// 如果存在,则尝试恢复 + public bool OpenUpload(string filename, string remote_filename, bool resume) + { + Connect(); + SetBinaryMode(true); + OpenDataSocket(); + + bytes_total = 0; + + try + { + file = new FileStream(filename, FileMode.Open); + } + catch (Exception ex) + { + file = null; + errormessage += ex.Message; + return false; + } + + file_size = file.Length; + + if (resume) + { + long size = GetFileSize(remote_filename); + SendCommand("REST " + size); + ReadResponse(); + if (response == 350) + file.Seek(size, SeekOrigin.Begin); + } + + SendCommand("STOR " + remote_filename); + ReadResponse(); + + switch (response) + { + case 125: + case 150: + break; + default: + file.Close(); + file = null; + errormessage += responseStr; + return false; + } + ConnectDataSocket(); + + return true; + } + + /// + /// 下载指定文件 + /// + /// 远程文件名称 + public void OpenDownload(string filename) + { + OpenDownload(filename, filename, false); + } + + /// + /// 下载并恢复指定文件 + /// + /// 远程文件名称 + /// 如文件存在,则尝试恢复 + public void OpenDownload(string filename, bool resume) + { + OpenDownload(filename, filename, resume); + } + + /// + /// 下载指定文件 + /// + /// 远程文件名称 + /// 本地文件名 + public void OpenDownload(string remote_filename, string localfilename) + { + OpenDownload(remote_filename, localfilename, false); + } + + /// + /// 打开并下载文件 + /// + /// 远程文件名称 + /// 本地文件名 + /// 如果文件存在则恢复 + public void OpenDownload(string remote_filename, string local_filename, bool resume) + { + Connect(); + SetBinaryMode(true); + + bytes_total = 0; + + try + { + file_size = GetFileSize(remote_filename); + } + catch + { + file_size = 0; + } + + if (resume && File.Exists(local_filename)) + { + try + { + file = new FileStream(local_filename, FileMode.Open); + } + catch (Exception ex) + { + file = null; + throw new Exception(ex.Message); + } + + SendCommand("REST " + file.Length); + ReadResponse(); + if (response != 350) + throw new Exception(responseStr); + file.Seek(file.Length, SeekOrigin.Begin); + bytes_total = file.Length; + } + else + { + try + { + file = new FileStream(local_filename, FileMode.Create); + } + catch (Exception ex) + { + file = null; + throw new Exception(ex.Message); + } + } + + OpenDataSocket(); + SendCommand("RETR " + remote_filename); + ReadResponse(); + + switch (response) + { + case 125: + case 150: + break; + default: + file.Close(); + file = null; + errormessage += responseStr; + return; + } + ConnectDataSocket(); + + return; + } + + /// + /// 上传文件(循环调用直到上传完毕) + /// + /// 发送的字节数 + public long DoUpload() + { + Byte[] bytes = new Byte[512]; + long bytes_got; + + try + { + bytes_got = file.Read(bytes, 0, bytes.Length); + bytes_total += bytes_got; + data_sock.Send(bytes, (int)bytes_got, 0); + + if (bytes_got <= 0) + { + //上传完毕或有错误发生 + file.Close(); + file = null; + + CloseDataSocket(); + ReadResponse(); + switch (response) + { + case 226: + case 250: + break; + default: //当上传中断时 + { + errormessage += responseStr; + return -1; + } + } + + SetBinaryMode(false); + } + } + catch (Exception ex) + { + file.Close(); + file = null; + CloseDataSocket(); + ReadResponse(); + SetBinaryMode(false); + //throw ex; + //当上传中断时 + errormessage += ex.Message; + return -1; + } + + return bytes_got; + } + + /// + /// 下载文件(循环调用直到下载完毕) + /// + /// 接收到的字节点 + public long DoDownload() + { + Byte[] bytes = new Byte[512]; + long bytes_got; + + try + { + bytes_got = data_sock.Receive(bytes, bytes.Length, 0); + + if (bytes_got <= 0) + { + //下载完毕或有错误发生 + CloseDataSocket(); + file.Close(); + file = null; + + ReadResponse(); + switch (response) + { + case 226: + case 250: + break; + default: + { + errormessage += responseStr; + return -1; + } + } + + SetBinaryMode(false); + + return bytes_got; + } + + file.Write(bytes, 0, (int)bytes_got); + bytes_total += bytes_got; + } + catch (Exception ex) + { + CloseDataSocket(); + file.Close(); + file = null; + ReadResponse(); + SetBinaryMode(false); + //throw ex; + //当下载中断时 + errormessage += ex.Message; + return -1; + } + + return bytes_got; + } + + #endregion + } +} \ No newline at end of file diff --git a/src/Kalman/Net/HttpClient.cs b/src/Kalman/Net/HttpClient.cs new file mode 100644 index 0000000..e307cdd --- /dev/null +++ b/src/Kalman/Net/HttpClient.cs @@ -0,0 +1,667 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Net; +using System.Web; + +namespace Kalman.Net +{ + /// + /// HTTP通信客户端组件修正版(解决了.NET HTTP模块与非IIS服务器通信时,使用POST方式提交数据可能出现471异常的问题; + /// .NET HTTP模块向服务器POST数据时先验证URL是否有效,然后才提交数据,而非IIS服务器可能被认为是异常) + /// + public class HttpClient + { + #region fields + private bool keepContext; + private string defaultLanguage = "zh-CN"; + private Encoding defaultEncoding = Encoding.UTF8; + private Encoding requestEncoding = Encoding.UTF8; + private string accept = "*/*"; + private string userAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)"; + private HttpVerb verb = HttpVerb.GET; + private HttpClientContext context; + private readonly List files = new List(); + private readonly Dictionary postingData = new Dictionary(); + private string url; + private WebHeaderCollection responseHeaders; + private int startPoint; + private int endPoint; + #endregion + + #region events + public event EventHandler StatusUpdate; + + private void OnStatusUpdate(StatusUpdateEventArgs e) + { + EventHandler temp = StatusUpdate; + + if (temp != null) + temp(this, e); + } + #endregion + + #region properties + /// + /// 是否自动在不同的请求间保留Cookie, Referer + /// + public bool KeepContext + { + get { return keepContext; } + set { keepContext = value; } + } + + /// + /// 期望的回应的语言 + /// + public string DefaultLanguage + { + get { return defaultLanguage; } + set { defaultLanguage = value; } + } + + /// + /// GetString()如果不能从HTTP头或Meta标签中获取编码信息,则使用此编码来获取字符串 + /// + public Encoding DefaultEncoding + { + get { return defaultEncoding; } + set { defaultEncoding = value; } + } + + /// + /// 发出请求的数据编码 + /// + public Encoding RequestEncoding + { + get { return requestEncoding; } + set { requestEncoding = value; } + } + + /// + /// 指示发出Get请求还是Post请求 + /// + public HttpVerb Verb + { + get { return verb; } + set { verb = value; } + } + + /// + /// 要上传的文件.如果不为空则自动转为Post请求 + /// + public List Files + { + get { return files; } + } + + /// + /// 要发送的Form表单信息 + /// + public Dictionary PostingData + { + get { return postingData; } + } + + /// + /// 获取或设置请求资源的地址 + /// + public string Url + { + get { return url; } + set { url = value; } + } + + /// + /// 用于在获取回应后,暂时记录回应的HTTP头 + /// + public WebHeaderCollection ResponseHeaders + { + get { return responseHeaders; } + } + + /// + /// 获取或设置期望的资源类型 + /// + public string Accept + { + get { return accept; } + set { accept = value; } + } + + /// + /// 获取或设置请求中的Http头User-Agent的值 + /// + public string UserAgent + { + get { return userAgent; } + set { userAgent = value; } + } + + /// + /// 获取或设置Cookie及Referer + /// + public HttpClientContext Context + { + get { return context; } + set { context = value; } + } + + /// + /// 获取或设置获取内容的起始点,用于断点续传,多线程下载等 + /// + public int StartPoint + { + get { return startPoint; } + set { startPoint = value; } + } + + /// + /// 获取或设置获取内容的结束点,用于断点续传,多下程下载等. + /// 如果为0,表示获取资源从StartPoint开始的剩余内容 + /// + public int EndPoint + { + get { return endPoint; } + set { endPoint = value; } + } + + /// + /// 请求超时前等待的毫秒数。默认值为 100,000 毫秒(100 秒) + /// + public int Timeout { get; set; } + + #endregion + + #region constructors + /// + /// 构造新的HttpClient实例 + /// + public HttpClient() + : this(null) + { + } + + /// + /// 构造新的HttpClient实例 + /// + /// 要获取的资源的地址 + public HttpClient(string url) + : this(url, false) + { + } + + /// + /// 构造新的HttpClient实例 + /// + /// 要获取的资源的地址 + /// 是否使用100-continue行为(默认为false,对于非IIS服务器向其POST数据时可能会出现471错误,将该参数设置为false可以避免这个问题) + public HttpClient(string url, bool expect100Continue) + : this(url, expect100Continue, null) + { + } + + /// + /// 构造新的HttpClient实例 + /// + /// 要获取的资源的地址 + /// 是否使用100-continue行为(默认为false,对于非IIS服务器向其POST数据时可能会出现471错误,将该参数设置为false可以避免这个问题) + /// Cookie及Referer + public HttpClient(string url, bool expect100Continue, HttpClientContext context) + : this(url, expect100Continue, context, false) + { + } + + /// + /// 构造新的HttpClient实例 + /// + /// 要获取的资源的地址 + /// 是否使用100-continue行为(默认为false,对于非IIS服务器向其POST数据时可能会出现471错误,将该参数设置为false可以避免这个问题) + /// Cookie及Referer + /// 是否自动在不同的请求间保留Cookie, Referer + public HttpClient(string url, bool expect100Continue, HttpClientContext context, bool keepContext) + { + ServicePointManager.Expect100Continue = expect100Continue; + this.url = url; + this.context = context; + this.keepContext = keepContext; + if (this.context == null) + this.context = new HttpClientContext(); + } + #endregion + + #region AttachFile + /// + /// 在请求中添加要上传的文件 + /// + /// 要上传的文件路径 + /// 文件字段的名称(相当于<input type=file name=fieldName>)里的fieldName) + public void AttachFile(string fileName, string fieldName) + { + HttpUploadingFile file = new HttpUploadingFile(fileName, fieldName); + files.Add(file); + } + + /// + /// 在请求中添加要上传的文件 + /// + /// 要上传的文件内容 + /// 文件名 + /// 文件字段的名称(相当于<input type=file name=fieldName>)里的fieldName) + public void AttachFile(byte[] data, string fileName, string fieldName) + { + HttpUploadingFile file = new HttpUploadingFile(data, fileName, fieldName); + files.Add(file); + } + #endregion + + /// + /// 清空PostingData, Files, StartPoint, EndPoint, ResponseHeaders, 并把Verb设置为Get. + /// 在发出一个包含上述信息的请求后,必须调用此方法或手工设置相应属性以使下一次请求不会受到影响. + /// + public void Reset() + { + verb = HttpVerb.GET; + files.Clear(); + postingData.Clear(); + responseHeaders = null; + startPoint = 0; + endPoint = 0; + } + + private HttpWebRequest CreateRequest() + { + HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url); + req.AllowAutoRedirect = false; + req.CookieContainer = new CookieContainer(); + req.Headers.Add("Accept-Language", defaultLanguage); + req.Accept = accept; + req.UserAgent = userAgent; + req.KeepAlive = false; + + if (Timeout > 0) + { + req.Timeout = Timeout; + } + + if (context.Cookies != null) + req.CookieContainer.Add(context.Cookies); + if (!string.IsNullOrEmpty(context.Referer)) + req.Referer = context.Referer; + + if (verb == HttpVerb.HEAD) + { + req.Method = "HEAD"; + return req; + } + + if (postingData.Count > 0 || files.Count > 0) + verb = HttpVerb.POST; + + if (verb == HttpVerb.POST) + { + req.Method = "POST"; + + MemoryStream memoryStream = new MemoryStream(); + StreamWriter writer = new StreamWriter(memoryStream); + + if (files.Count > 0) + { + string newLine = "\r\n"; + string boundary = Guid.NewGuid().ToString().Replace("-", ""); + req.ContentType = "multipart/form-data; boundary=" + boundary; + + foreach (string key in postingData.Keys) + { + writer.Write("--" + boundary + newLine); + writer.Write("Content-Disposition: form-data; name=\"{0}\"{1}{1}", key, newLine); + writer.Write(postingData[key] + newLine); + } + + foreach (HttpUploadingFile file in files) + { + writer.Write("--" + boundary + newLine); + writer.Write( + "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"{2}", + file.FieldName, + file.FileName, + newLine + ); + writer.Write("Content-Type: application/octet-stream" + newLine + newLine); + writer.Flush(); + memoryStream.Write(file.Data, 0, file.Data.Length); + writer.Write(newLine); + writer.Write("--" + boundary + newLine); + } + } + else + { + req.ContentType = "application/x-www-form-urlencoded"; + StringBuilder sb = new StringBuilder(); + foreach (string key in postingData.Keys) + { + sb.AppendFormat("{0}={1}&", HttpUtility.UrlEncode(key, requestEncoding), HttpUtility.UrlEncode(postingData[key], requestEncoding)); + } + if (sb.Length > 0) + sb.Length--; + writer.Write(sb.ToString()); + } + + writer.Flush(); + + using (Stream stream = req.GetRequestStream()) + { + memoryStream.WriteTo(stream); + } + } + + if (startPoint != 0 && endPoint != 0) + req.AddRange(startPoint, endPoint); + else if (startPoint != 0 && endPoint == 0) + req.AddRange(startPoint); + + return req; + } + + /// + /// 发出一次新的请求,并返回获得的回应 + /// 调用此方法永远不会触发StatusUpdate事件. + /// + /// 相应的HttpWebResponse + public HttpWebResponse GetResponse() + { + HttpWebRequest req = CreateRequest(); + HttpWebResponse res = (HttpWebResponse)req.GetResponse(); + responseHeaders = res.Headers; + if (keepContext) + { + context.Cookies = res.Cookies; + context.Referer = url; + } + return res; + } + + /// + /// 发出一次新的请求,并返回回应内容的流 + /// 调用此方法永远不会触发StatusUpdate事件. + /// + /// 包含回应主体内容的流 + public Stream GetStream() + { + return GetResponse().GetResponseStream(); + } + + /// + /// 发出一次新的请求,并以字节数组形式返回回应的内容 + /// 调用此方法会触发StatusUpdate事件 + /// + /// 包含回应主体内容的字节数组 + public byte[] GetBytes() + { + HttpWebResponse res = GetResponse(); + int length = (int)res.ContentLength; + + MemoryStream memoryStream = new MemoryStream(); + byte[] buffer = new byte[0x100]; + Stream rs = res.GetResponseStream(); + for (int i = rs.Read(buffer, 0, buffer.Length); i > 0; i = rs.Read(buffer, 0, buffer.Length)) + { + memoryStream.Write(buffer, 0, i); + OnStatusUpdate(new StatusUpdateEventArgs((int)memoryStream.Length, length)); + } + rs.Close(); + + return memoryStream.ToArray(); + } + + /// + /// 发出一次新的请求,以Http头,或Html Meta标签,或DefaultEncoding指示的编码信息对回应主体解码 + /// 调用此方法会触发StatusUpdate事件 + /// + /// 解码后的字符串 + public string GetString() + { + byte[] data = GetBytes(); + string encodingName = GetEncodingFromHeaders(); + + if (encodingName == null) + encodingName = GetEncodingFromBody(data); + + Encoding encoding; + if (encodingName == null) + encoding = defaultEncoding; + else + { + try + { + encoding = Encoding.GetEncoding(encodingName); + } + catch (ArgumentException) + { + encoding = defaultEncoding; + } + } + return encoding.GetString(data); + } + + /// + /// 发出一次新的请求,对回应的主体内容以指定的编码进行解码 + /// 调用此方法会触发StatusUpdate事件 + /// + /// 指定的编码 + /// 解码后的字符串 + public string GetString(Encoding encoding) + { + byte[] data = GetBytes(); + return encoding.GetString(data); + } + + private string GetEncodingFromHeaders() + { + string encoding = null; + string contentType = responseHeaders["Content-Type"]; + if (contentType != null) + { + int i = contentType.IndexOf("charset="); + if (i != -1) + { + encoding = contentType.Substring(i + 8); + } + } + return encoding; + } + + private string GetEncodingFromBody(byte[] data) + { + string encodingName = null; + string dataAsAscii = Encoding.ASCII.GetString(data); + if (dataAsAscii != null) + { + int i = dataAsAscii.IndexOf("charset="); + if (i != -1) + { + int j = dataAsAscii.IndexOf("\"", i); + if (j != -1) + { + int k = i + 8; + encodingName = dataAsAscii.Substring(k, (j - k) + 1); + char[] chArray = new char[2] { '>', '"' }; + encodingName = encodingName.TrimEnd(chArray); + } + } + } + return encodingName; + } + + /// + /// 发出一次新的Head请求,获取资源的长度 + /// 此请求会忽略PostingData, Files, StartPoint, EndPoint, Verb + /// + /// 返回的资源长度 + public int HeadContentLength() + { + Reset(); + HttpVerb lastVerb = verb; + verb = HttpVerb.HEAD; + using (HttpWebResponse res = GetResponse()) + { + verb = lastVerb; + return (int)res.ContentLength; + } + } + + /// + /// 发出一次新的请求,把回应的主体内容保存到文件 + /// 调用此方法会触发StatusUpdate事件 + /// 如果指定的文件存在,它会被覆盖 + /// + /// 要保存的文件路径 + public void SaveToFile(string fileName) + { + SaveToFile(fileName, FileExistsAction.Overwrite); + } + + /// + /// 发出一次新的请求,把回应的主体内容保存到文件 + /// 调用此方法会触发StatusUpdate事件 + /// + /// 要保存的文件路径 + /// 指定的文件存在时的选项 + /// 是否向目标文件写入了数据 + public bool SaveToFile(string fileName, FileExistsAction existsAction) + { + byte[] data = GetBytes(); + switch (existsAction) + { + case FileExistsAction.Overwrite: + using (BinaryWriter writer = new BinaryWriter(new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.Write))) + writer.Write(data); + return true; + + case FileExistsAction.Append: + using (BinaryWriter writer = new BinaryWriter(new FileStream(fileName, FileMode.Append, FileAccess.Write))) + writer.Write(data); + return true; + + default: + if (!File.Exists(fileName)) + { + using ( + BinaryWriter writer = + new BinaryWriter(new FileStream(fileName, FileMode.Create, FileAccess.Write))) + writer.Write(data); + return true; + } + else + { + return false; + } + } + } + } + + public class HttpClientContext + { + private CookieCollection cookies; + private string referer; + + public CookieCollection Cookies + { + get { return cookies; } + set { cookies = value; } + } + + public string Referer + { + get { return referer; } + set { referer = value; } + } + } + + public enum HttpVerb + { + GET, + POST, + HEAD, + } + + public enum FileExistsAction + { + Overwrite, + Append, + Cancel, + } + + public class HttpUploadingFile + { + private string fileName; + private string fieldName; + private byte[] data; + + public string FileName + { + get { return fileName; } + set { fileName = value; } + } + + public string FieldName + { + get { return fieldName; } + set { fieldName = value; } + } + + public byte[] Data + { + get { return data; } + set { data = value; } + } + + public HttpUploadingFile(string fileName, string fieldName) + { + this.fileName = fileName; + this.fieldName = fieldName; + using (FileStream stream = new FileStream(fileName, FileMode.Open)) + { + byte[] inBytes = new byte[stream.Length]; + stream.Read(inBytes, 0, inBytes.Length); + data = inBytes; + } + } + + public HttpUploadingFile(byte[] data, string fileName, string fieldName) + { + this.data = data; + this.fileName = fileName; + this.fieldName = fieldName; + } + } + + public class StatusUpdateEventArgs : EventArgs + { + private readonly int bytesGot; + private readonly int bytesTotal; + + public StatusUpdateEventArgs(int got, int total) + { + bytesGot = got; + bytesTotal = total; + } + + /// + /// 已经下载的字节数 + /// + public int BytesGot + { + get { return bytesGot; } + } + + /// + /// 资源的总字节数 + /// + public int BytesTotal + { + get { return bytesTotal; } + } + } +} diff --git a/src/Kalman/Net/MXLookUp.cs b/src/Kalman/Net/MXLookUp.cs new file mode 100644 index 0000000..9b7630c --- /dev/null +++ b/src/Kalman/Net/MXLookUp.cs @@ -0,0 +1,107 @@ +using System; +using System.Runtime.InteropServices; +using System.Collections; +using System.ComponentModel; + +namespace Kalman.Net +{ + public class MXLookUp + { + [DllImport("dnsapi", EntryPoint="DnsQuery_W", CharSet=CharSet.Unicode, SetLastError=true, ExactSpelling=true)] + private static extern int DnsQuery([MarshalAs(UnmanagedType.VBByRefStr)]ref string pszName, QueryTypes wType, QueryOptions options, int aipServers, ref IntPtr ppQueryResults, int pReserved); + + [DllImport("dnsapi", CharSet=CharSet.Auto, SetLastError=true)] + private static extern void DnsRecordListFree(IntPtr pRecordList, int FreeType); + + /// + /// ȡMX¼磺mx0.qq.com,mx1.qq.com + /// + /// ʼַxxx@qq.com,qq.com + /// MX¼ + public static string[] GetMXRecords(string mailAddress) + { + IntPtr ResultsPointer = IntPtr.Zero; + IntPtr MXPointer = IntPtr.Zero; + MXStruct RecordStruct; + ArrayList QueryResults = new ArrayList(); + int QueryCode; + string MXRecord; + string Domain; + + Domain = mailAddress.Substring(mailAddress.IndexOf('@') + 1); + + try + { + QueryCode = MXLookUp.DnsQuery(ref Domain, QueryTypes.DNS_TYPE_MX, QueryOptions.DNS_QUERY_BYPASS_CACHE, 0, ref ResultsPointer, 0); + + if (QueryCode != 0) + { + if(QueryCode==9003) + { + QueryResults.Add("MX Record Not Found"); + } + else + { + throw new Win32Exception(QueryCode); + } + } + + for (MXPointer = ResultsPointer; !MXPointer.Equals(IntPtr.Zero); MXPointer = RecordStruct.pNext) + { + RecordStruct = (MXStruct) Marshal.PtrToStructure(MXPointer, typeof(MXStruct)); + + if (RecordStruct.wType == 15) + { + MXRecord = Marshal.PtrToStringAuto(RecordStruct.pNameExchange); + QueryResults.Add(MXRecord); + } + } + } + finally + { + MXLookUp.DnsRecordListFree(ResultsPointer, 0); + } + + return (string[]) QueryResults.ToArray(typeof(string)); + } + + private enum QueryOptions + { + DNS_QUERY_ACCEPT_TRUNCATED_RESPONSE = 1, + DNS_QUERY_BYPASS_CACHE = 8, + DNS_QUERY_DONT_RESET_TTL_VALUES = 0x100000, + DNS_QUERY_NO_HOSTS_FILE = 0x40, + DNS_QUERY_NO_LOCAL_NAME = 0x20, + DNS_QUERY_NO_NETBT = 0x80, + DNS_QUERY_NO_RECURSION = 4, + DNS_QUERY_NO_WIRE_QUERY = 0x10, + DNS_QUERY_RESERVED = -16777216, + DNS_QUERY_RETURN_MESSAGE = 0x200, + DNS_QUERY_STANDARD = 0, + DNS_QUERY_TREAT_AS_FQDN = 0x1000, + DNS_QUERY_USE_TCP_ONLY = 2, + DNS_QUERY_WIRE_ONLY = 0x100 + } + + private enum QueryTypes + { + DNS_TYPE_MX = 15 + } + + [StructLayout(LayoutKind.Sequential)] + private struct MXStruct + { + public IntPtr pNext; + public string pName; + public short wType; + public short wDataLength; + public int flags; + public int dwTtl; + public int dwReserved; + public IntPtr pNameExchange; + public short wPreference; + public short Pad; + } + } +} + diff --git a/src/Kalman/PdmParser/PDColumn.cs b/src/Kalman/PdmParser/PDColumn.cs new file mode 100644 index 0000000..f496424 --- /dev/null +++ b/src/Kalman/PdmParser/PDColumn.cs @@ -0,0 +1,77 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Kalman.PdmParser +{ + [Serializable] + public class PDColumn : PDObject + { + /// + /// 所属包对象 + /// + public PDPackage Package { get; set; } + + /// + /// 所属表对象 + /// + public PDTable Table { get; set; } + + /// + /// 列的数据类型,如"varchar(50)" + /// + public string DataType { get; set; } + /// + /// 列长度 + /// + public int Length { get; set; } + /// + /// 精度 + /// + public int Precision { get; set; } + /// + /// 是否强制不能为空 + /// + public bool Mandatory { get; set; } + /// + /// 默认值 + /// + public string DefaultValue { get; set; } + public bool Identity { get; set; } + /// + /// 是否主键 + /// + public bool IsPK + { + get + { + //判断该列是否属于一个Key + foreach (PDKey key in this.Table.KeyList) + { + //判断该Key是表的主键Key,并且该列是主键Key的列 + if (key.Table.PrimaryKeyID == key.ID&& key.ColumnIDList != null && key.ColumnIDList.Contains(this.ID)) return true; + } + return false; + } + } + /// + /// 是否外键 + /// + public bool IsFK + { + get + { + foreach (PDReference reference in base.Model.ReferenceList) + { + if (reference.JoinList == null) continue; + foreach (ReferenceJoin join in reference.JoinList) + { + if (join.ChildColumnID == this.ID) return true; + } + } + return false; + } + } + } +} diff --git a/src/Kalman/PdmParser/PDDbms.cs b/src/Kalman/PdmParser/PDDbms.cs new file mode 100644 index 0000000..db8c535 --- /dev/null +++ b/src/Kalman/PdmParser/PDDbms.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Kalman.PdmParser +{ + /// + /// 数据库管理系统对象 + /// + [Serializable] + public class PDDbms : PDObject + { + } +} diff --git a/src/Kalman/PdmParser/PDIndex.cs b/src/Kalman/PdmParser/PDIndex.cs new file mode 100644 index 0000000..b6a4aa2 --- /dev/null +++ b/src/Kalman/PdmParser/PDIndex.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Kalman.PdmParser +{ + public class PDIndex : PDObject + { + /// + /// 所属包对象 + /// + public PDPackage Package { get; set; } + + /// + /// 所属表对象 + /// + public PDTable Table { get; set; } + + /// + /// 唯一性索引,一般主键列默认会创建唯一性索引 + /// + public bool Unique { get; set; } + + /// + /// 聚集对象 + /// + public bool Cluster + { + get + { + return Table.ClusterObjectID == this.ID; + } + } + + /// + /// 索引所拥有的列的ID列表 + /// + public IList ColumnIDList { get; set; } + + public IList ColumnList + { + get + { + IList list = new List(); + foreach (string columnID in ColumnIDList) + { + PDColumn column = base.Model.GetColumn(columnID); + if (column != null) list.Add(column); + } + return list; + } + } + } +} diff --git a/src/Kalman/PdmParser/PDKey.cs b/src/Kalman/PdmParser/PDKey.cs new file mode 100644 index 0000000..31826bb --- /dev/null +++ b/src/Kalman/PdmParser/PDKey.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Kalman.PdmParser +{ + [Serializable] + public class PDKey : PDObject + { + /// + /// 所属包对象 + /// + public PDPackage Package { get; set; } + + /// + /// 所属表对象 + /// + public PDTable Table { get; set; } + + /// + /// 主键Key + /// + public bool PrimaryKey + { + get + { + return Table.PrimaryKeyID == this.ID; + } + } + + /// + /// 聚集对象 + /// + public bool Cluster + { + get + { + return Table.ClusterObjectID == this.ID; + } + } + + /// + /// 键所拥有的列的ID列表 + /// + public IList ColumnIDList { get; set; } + + public IList ColumnList + { + get + { + IList list = new List(); + foreach (string columnID in ColumnIDList) + { + PDColumn column = base.Model.GetColumn(columnID); + if (column != null) list.Add(column); + } + return list; + } + } + } +} diff --git a/src/Kalman/PdmParser/PDModel.cs b/src/Kalman/PdmParser/PDModel.cs new file mode 100644 index 0000000..e174ca7 --- /dev/null +++ b/src/Kalman/PdmParser/PDModel.cs @@ -0,0 +1,253 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Xml; + +namespace Kalman.PdmParser +{ + /// + /// PowerDesigner物理模型对象 + /// + [Serializable] + public class PDModel : PDObject + { + public PDDbms DBMS { get; set; } + + IList _UserList = new List(); + public IList UserList { get { return _UserList; } set { _UserList = value; } } + public void AddUser(PDUser user) { _UserList.Add(user); } + + public PDUser GetUser(string userID) + { + foreach (PDUser user in _UserList) + { + if (user.ID == userID) return user; + } + return null; + } + + IList _PackageList = new List(); + public IList PackageList { get { return _PackageList; } set { _PackageList = value; } } + public void AddPackage(PDPackage package) { _PackageList.Add(package); } + + IList _TableList = new List(); + public IList TableList { get { return _TableList; } set { _TableList = value; } } + public void AddTable(PDTable table) { _TableList.Add(table); } + + IList _ViewList = new List(); + public IList ViewList { get { return _ViewList; } set { _ViewList = value; } } + public void AddView(PDView view) { _ViewList.Add(view); } + + IList _ProcedureList = new List(); + public IList ProcedureList { get { return _ProcedureList; } set { _ProcedureList = value; } } + public void AddProcedure(PDProcedure procedure) { _ProcedureList.Add(procedure); } + + IList _ReferenceList = new List(); + public IList ReferenceList { get { return _ReferenceList; } set { _ReferenceList = value; } } + public void AddReference(PDReference Reference) { _ReferenceList.Add(Reference); } + + /// + /// 获取该模型所有的包对象 + /// + public IList AllPackageList + { + get + { + IList list = new List(); + + foreach (PDPackage package in _PackageList) + { + list.Add(package); + ParseChildPackageList(list, package); + } + + return list; + } + } + + void ParseChildPackageList(IList list , PDPackage package) + { + if (list == null) return; + foreach (PDPackage item in package.ChildrenList) + { + list.Add(item); + ParseChildPackageList(list, item); + } + } + + /// + /// 获取该模型所有的表对象 + /// + public IList AllTableList + { + get + { + IList list = new List(); + + foreach (PDTable table in _TableList) + { + list.Add(table); + } + + foreach (PDPackage package in this.AllPackageList) + { + foreach (PDTable table in package.TableList) + { + list.Add(table); + } + } + + return list; + } + } + + public PDTable GetTable(string tableID) + { + foreach (PDTable table in this.AllTableList) + { + if (table.ID == tableID) return table; + } + return null; + } + + public IList AllColumnList + { + get + { + IList list = new List(); + foreach (PDTable table in AllTableList) + { + foreach (PDColumn column in table.ColumnList) + { + list.Add(column); + } + } + return list; + } + } + + public PDColumn GetColumn(string columnID) + { + foreach (PDColumn column in AllColumnList) + { + if (column.ID == columnID) return column; + } + return null; + } + + public IList AllKeyList + { + get + { + IList list = new List(); + foreach (PDTable table in AllTableList) + { + foreach (PDKey key in table.KeyList) + { + list.Add(key); + } + } + return list; + } + } + + public PDKey GetKey(string keyID) + { + foreach (PDKey key in AllKeyList) + { + if (key.ID == keyID) return key; + } + return null; + } + + public IList AllIndexList + { + get + { + IList list = new List(); + foreach (PDTable table in AllTableList) + { + foreach (PDIndex index in table.IndexList) + { + list.Add(index); + } + } + return list; + } + } + + public PDIndex GetIndex(string indexID) + { + foreach (PDIndex index in AllIndexList) + { + if (index.ID == indexID) return index; + } + return null; + } + + public IList AllViewList + { + get + { + IList list = new List(); + + foreach (PDView view in _ViewList) + { + list.Add(view); + } + + foreach (PDPackage package in this.AllPackageList) + { + foreach (PDView view in package.ViewList) + { + list.Add(view); + } + } + + return list; + } + } + + public PDView GetView(string viewID) + { + foreach (PDView view in this.AllViewList) + { + if (view.ID == viewID) return view; + } + return null; + } + + public IList AllProcedureList + { + get + { + IList list = new List(); + + foreach (PDProcedure procedure in _ProcedureList) + { + list.Add(procedure); + } + + foreach (PDPackage package in this.AllPackageList) + { + foreach (PDProcedure procedure in package.ProcedureList) + { + list.Add(procedure); + } + } + + return list; + } + } + + public PDProcedure GetProcedure(string procedureID) + { + foreach (PDProcedure procedure in this.AllProcedureList) + { + if (procedure.ID == procedureID) return procedure; + } + return null; + } + } +} diff --git a/src/Kalman/PdmParser/PDObject.cs b/src/Kalman/PdmParser/PDObject.cs new file mode 100644 index 0000000..cc79042 --- /dev/null +++ b/src/Kalman/PdmParser/PDObject.cs @@ -0,0 +1,67 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Xml; + +namespace Kalman.PdmParser +{ + /// + /// PowerDesinger物理模型对象基类 + /// + [Serializable] + public class PDObject + { + /// + /// 所属模型对象 + /// + public PDModel Model { get; set; } + + public string ID { get; set; } + public string Name { get; set; } + public string Code { get; set; } + public string Comment { get; set; } + + //未解析节点列表 + [NonSerialized] + Dictionary _UnparsedNodeList = new Dictionary(); + + /// + /// 添加未解析节点 + /// + /// + public void AddUnparsedNode(XmlNode node) + { + _UnparsedNodeList.Add(node.Name, node); + } + + /// + /// 获取未解析节点 + /// + /// + /// + public XmlNode GetUnparsedNode(string nodeName) + { + return _UnparsedNodeList[nodeName]; + } + + /// + /// 获取未解析节点列表 + /// + /// + public IList GetUnparsedNodeList() + { + IList list = new List(); + foreach (KeyValuePair item in _UnparsedNodeList) + { + list.Add(item.Value); + } + return list; + } + + public override string ToString() + { + return this.Name; + } + } +} diff --git a/src/Kalman/PdmParser/PDPackage.cs b/src/Kalman/PdmParser/PDPackage.cs new file mode 100644 index 0000000..a78cda8 --- /dev/null +++ b/src/Kalman/PdmParser/PDPackage.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Kalman.PdmParser +{ + [Serializable] + public class PDPackage : PDObject + { + /// + /// 父包对象 + /// + public PDPackage Parent { get; set; } + + IList _ChildrenList = new List(); + /// + /// 子包列表 + /// + public IList ChildrenList { get { return _ChildrenList; } set { _ChildrenList = value; } } + public void AddPackage(PDPackage package) { _ChildrenList.Add(package); } + + IList _TableList = new List(); + public IList TableList { get { return _TableList; } set { _TableList = value; } } + public void AddTable(PDTable table) { _TableList.Add(table); } + + IList _ViewList = new List(); + public IList ViewList { get { return _ViewList; } set { _ViewList = value; } } + public void AddView(PDView view) { _ViewList.Add(view); } + + IList _ProcedureList = new List(); + public IList ProcedureList { get { return _ProcedureList; } set { _ProcedureList = value; } } + public void AddProcedure(PDProcedure procedure) { _ProcedureList.Add(procedure); } + + IList _ReferenceList = new List(); + public IList ReferenceList { get { return _ReferenceList; } set { _ReferenceList = value; } } + public void AddReference(PDReference Reference) { _ReferenceList.Add(Reference); } + } +} diff --git a/src/Kalman/PdmParser/PDProcedure.cs b/src/Kalman/PdmParser/PDProcedure.cs new file mode 100644 index 0000000..c8fbddf --- /dev/null +++ b/src/Kalman/PdmParser/PDProcedure.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Kalman.PdmParser +{ + [Serializable] + public class PDProcedure : PDObject + { + /// + /// 所属包对象 + /// + public PDPackage Package { get; set; } + } +} diff --git a/src/Kalman/PdmParser/PDReference.cs b/src/Kalman/PdmParser/PDReference.cs new file mode 100644 index 0000000..74c161d --- /dev/null +++ b/src/Kalman/PdmParser/PDReference.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Kalman.PdmParser +{ + /// + /// 对象之间的关系实体 + /// + [Serializable] + public class PDReference : PDObject + { + /// + /// 获取或设置所属包对象 + /// + public PDPackage Package { get; set; } + + /// + /// 获取或设置基数(如0..n,1..n) + /// + public string Cardinality { get; set; } + + /// + /// 获取或设置是否强制更新标志 + /// + public bool UpdateConstraint { get; set; } + + /// + /// 获取或设置是否强制删除标志 + /// + public bool DeleteConstraint { get; set; } + + /// + /// 获取或设置父表ID + /// + public string ParentTableID { get; set; } + + /// + /// 获取父表对象 + /// + public PDTable ParentTable + { + get + { + return base.Model.GetTable(ParentTableID); + } + } + + /// + /// 获取或设置子表ID + /// + public string ChildTableID { get; set; } + + /// + /// 获取子表对象 + /// + public PDTable ChildTable + { + get + { + return base.Model.GetTable(ChildTableID); + } + } + + /// + /// 获取或设置父表的键ID + /// + public string ParentKeyID { get; set; } + + /// + /// 获取父表的键对象 + /// + public PDKey ParentKey + { + get + { + return base.Model.GetKey(ParentKeyID); + } + } + + /// + /// 用来查找外键字段,ReferenceJoin对象的ChildColumnID为外键列ID + /// + public IList JoinList { get; set; } + } +} diff --git a/src/Kalman/PdmParser/PDTable.cs b/src/Kalman/PdmParser/PDTable.cs new file mode 100644 index 0000000..364b327 --- /dev/null +++ b/src/Kalman/PdmParser/PDTable.cs @@ -0,0 +1,140 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Kalman.PdmParser +{ + [Serializable] + public class PDTable : PDObject + { + /// + /// 所属包对象 + /// + public PDPackage Package { get; set; } + + IList _ColumnList = new List(); + public IList ColumnList { get { return _ColumnList; } set { _ColumnList = value; } } + public void AddColumn(PDColumn column) { _ColumnList.Add(column); } + + public PDColumn GetColumn(string columnID) + { + foreach (PDColumn column in _ColumnList) + { + if (column.ID == columnID) return column; + } + return null; + } + + IList _KeyList = new List(); + public IList KeyList { get { return _KeyList; } set { _KeyList = value; } } + public void AddKey(PDKey key) { _KeyList.Add(key); } + + public PDKey GetKey(string keyID) + { + foreach (PDKey key in _KeyList) + { + if (key.ID == keyID) return key; + } + return null; + } + + IList _IndexList = new List(); + public IList IndexList { get { return _IndexList; } set { _IndexList = value; } } + public void AddIndex(PDIndex index) { _IndexList.Add(index); } + + public PDIndex GetIndex(string indexID) + { + foreach (PDIndex index in _IndexList) + { + if (index.ID == indexID) return index; + } + return null; + } + + /// + /// 表所属的用户ID + /// + public string UserID { get; set; } + + /// + /// 表所属的用户对象 + /// + public PDUser User + { + get + { + IList userList = base.Model.UserList; + foreach (PDUser user in userList) + { + if (user.ID == this.UserID) return user; + } + return null; + } + } + + /// + /// 主键所属的KeyID + /// + public string PrimaryKeyID { get; set; } + + /// + /// 获取主键列列表 + /// + public IList PKColumnList + { + get + { + IList list = new List(); + PDKey key = GetKey(PrimaryKeyID); + + foreach (string columnID in key.ColumnIDList) + { + PDColumn column = GetColumn(columnID); + if (column != null) list.Add(column); + } + + return list; + } + } + + /// + /// 聚集对象ID(可以是Key和Index对象),一个表只能有一个聚集对象,注意:有些数据库不支持聚集对象 + /// + public string ClusterObjectID { get; set; } + + /// + /// 获取聚集对象列列表 + /// + public IList ClusterObjectColumnList + { + get + { + IList list = new List(); + if (string.IsNullOrEmpty(ClusterObjectID)) return list; + + PDKey key = GetKey(ClusterObjectID); + PDIndex index = GetIndex(ClusterObjectID); + + if (key != null) + { + foreach (string columnID in key.ColumnIDList) + { + PDColumn column = GetColumn(columnID); + if (column != null) list.Add(column); + } + } + else if(index != null) + { + foreach (string columnID in index.ColumnIDList) + { + PDColumn column = GetColumn(columnID); + if (column != null) list.Add(column); + } + } + + return list; + } + } + } +} diff --git a/src/Kalman/PdmParser/PDUser.cs b/src/Kalman/PdmParser/PDUser.cs new file mode 100644 index 0000000..6bd15e6 --- /dev/null +++ b/src/Kalman/PdmParser/PDUser.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Kalman.PdmParser +{ + [Serializable] + public class PDUser : PDObject + { + } +} diff --git a/src/Kalman/PdmParser/PDView.cs b/src/Kalman/PdmParser/PDView.cs new file mode 100644 index 0000000..9dda87f --- /dev/null +++ b/src/Kalman/PdmParser/PDView.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Kalman.PdmParser +{ + [Serializable] + public class PDView : PDObject + { + /// + /// 所属包对象 + /// + public PDPackage Package { get; set; } + } +} diff --git a/src/Kalman/PdmParser/PdmReader.cs b/src/Kalman/PdmParser/PdmReader.cs new file mode 100644 index 0000000..a8a4491 --- /dev/null +++ b/src/Kalman/PdmParser/PdmReader.cs @@ -0,0 +1,591 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Xml; +using Kalman.Utilities; +using System.IO; + +namespace Kalman.PdmParser +{ + /// + /// PDM文件读取类 + /// + public class PdmReader + { + XmlDocument doc = new XmlDocument(); + string tempFileName = string.Empty; + + public PdmReader(string fileName) + { + try + { + doc.Load(fileName); + } + catch (IOException ex) + { + string dic = Path.GetDirectoryName(fileName); + string tempFileName = Path.Combine(dic, Path.GetFileNameWithoutExtension(fileName) + ".tmp"); + File.Copy(fileName, tempFileName, true); + doc.Load(tempFileName); + } + } + + /// + /// 解析并生成模型实例 + /// + /// + public PDModel BuildModel() + { + PDModel m = new PDModel(); + + XmlElement docElement = doc.DocumentElement; + XmlNode root = docElement.FirstChild.FirstChild.FirstChild; + if (root == null) return null; + + m.ID = root.Attributes["Id"].Value; + foreach (XmlNode node in root.ChildNodes) + { + switch (node.Name) + { + case "a:Name": + m.Name = node.InnerText; + break; + case "a:Code": + m.Code = node.InnerText; + break; + case "a:Comment": + m.Comment = node.InnerText; + break; + case "c:DBMS": + ParseDbms(m, node); + break; + case "c:Packages": + ParsePackages(m, null, node); + break; + case "c:Users": + ParseUsers(m, node); + break; + case "c:Domains": + break; + case "c:Tables": + ParseTables(m, null, node); + break; + case "c:Views": + ParseViews(m, null, node); + break; + case "c:Procedures": + ParseProcedures(m, null, node); + break; + case "c:References": + ParseReferences(m, null, node); + break; + default: + m.AddUnparsedNode(node); + break; + } + } + + return m; + } + + #region ParseDbms + void ParseDbms(PDModel m, XmlNode root) + { + PDDbms dbms = new PDDbms(); + XmlNode shortcutNode = root.FirstChild; + + dbms.Model = m; + dbms.ID = shortcutNode.Attributes["Id"].Value; + + foreach (XmlNode node in shortcutNode.ChildNodes) + { + switch (node.Name) + { + case "a:Name": + dbms.Name = node.InnerText; + break; + case "a:Code": + dbms.Code = node.InnerText; + break; + case "a:Comment": + dbms.Comment = node.InnerText; + break; + default: + dbms.AddUnparsedNode(node); + break; + } + } + + m.DBMS = dbms; + } + #endregion + + #region ParsePackages + void ParsePackages(PDModel m,PDPackage parent, XmlNode root) + { + foreach (XmlNode packageNode in root.ChildNodes) + { + PDPackage package = new PDPackage(); + package.Model = m; + package.Parent = parent; + package.ID = packageNode.Attributes["Id"].Value; + + foreach (XmlNode node in packageNode.ChildNodes) + { + switch (node.Name) + { + case "a:Name": + package.Name = node.InnerText; + break; + case "a:Code": + package.Code = node.InnerText; + break; + case "a:Comment": + package.Comment = node.InnerText; + break; + case "c:Packages": + ParsePackages(m, package, node); + break; + case "c:Tables": + ParseTables(m, package, node); + break; + case "c:Views": + ParseViews(m, package, node); + break; + case "c:Procedures": + ParseProcedures(m, package, node); + break; + case "c:References": + ParseReferences(m, package, node); + break; + default: + package.AddUnparsedNode(node); + break; + } + }//end parse package + + if (parent == null) + { + m.AddPackage(package); + } + else + { + parent.AddPackage(package); + } + }//end parse packages + } + #endregion + + #region ParseUsers + void ParseUsers(PDModel m, XmlNode root) + { + foreach (XmlNode userNode in root.ChildNodes) + { + PDUser user = new PDUser(); + user.Model = m; + user.ID = userNode.Attributes["Id"].Value; + + foreach (XmlNode node in userNode.ChildNodes) + { + switch (node.Name) + { + case "a:Name": + user.Name = node.InnerText; + break; + case "a:Code": + user.Code = node.InnerText; + break; + case "a:Comment": + user.Comment = node.InnerText; + break; + default: + user.AddUnparsedNode(node); + break; + } + }//end parse user + + m.AddUser(user); + }//end parse users + } + #endregion + + #region ParseTables + void ParseTables(PDModel m, PDPackage package, XmlNode root) + { + foreach (XmlNode tableNode in root.ChildNodes) + { + PDTable table = new PDTable(); + table.Model = m; + table.Package = package; + table.ID = tableNode.Attributes["Id"].Value; + + foreach (XmlNode node in tableNode.ChildNodes) + { + switch (node.Name) + { + case "a:Name": + table.Name = node.InnerText; + break; + case "a:Code": + table.Code = node.InnerText; + break; + case "a:Comment": + table.Comment = node.InnerText; + break; + case "c:Owner": + table.UserID = node["o:User"].Attributes["Ref"].Value; + break; + case "c:PrimaryKey": + table.PrimaryKeyID = node["o:Key"].Attributes["Ref"].Value; + break; + case "c:ClusterObject": + table.ClusterObjectID = node.FirstChild.Attributes["Ref"].Value; + break; + case "c:Columns": + ParseColumns(m, package, table, node); + break; + case "c:Keys": + ParseKeys(m, package, table, node); + break; + case "c:Indexes": + ParseIndexes(m, package, table, node); + break; + default: + table.AddUnparsedNode(node); + break; + } + }//end parse table + + if (package == null) + { + m.AddTable(table); + } + else + { + package.AddTable(table); + } + }//end parse tables + } + + void ParseColumns(PDModel m, PDPackage package,PDTable table,XmlNode root) + { + foreach (XmlNode columnNode in root.ChildNodes) + { + PDColumn column = new PDColumn(); + column.Model = m; + column.Package = package; + column.Table = table; + column.ID = columnNode.Attributes["Id"].Value; + + foreach (XmlNode node in columnNode.ChildNodes) + { + switch (node.Name) + { + case "a:Name": + column.Name = node.InnerText; + break; + case "a:Code": + column.Code = node.InnerText; + break; + case "a:Comment": + column.Comment = node.InnerText; + break; + case "a:DataType": + column.DataType = node.InnerText; + break; + case "a:Length": + column.Length = ConvertUtil.ToInt32(node.InnerText, 0); + break; + case "a:Precision": + column.Precision = ConvertUtil.ToInt32(node.InnerText, 0); + break; + case "a:Mandatory": + column.Mandatory = node.InnerText == "1" ? true : false; + break; + case "a:DefaultValue": + column.DefaultValue = node.InnerText; + break; + case "a:Identity": + column.Identity = node.InnerText == "1"; + break; + default: + column.AddUnparsedNode(node); + break; + } + }//end parse column + + table.AddColumn(column); + }//end parse columns + } + + void ParseKeys(PDModel m, PDPackage package, PDTable table, XmlNode root) + { + foreach (XmlNode keyNode in root.ChildNodes) + { + PDKey key = new PDKey(); + key.Model = m; + key.Package = package; + key.Table = table; + key.ID = keyNode.Attributes["Id"].Value; + + foreach (XmlNode node in keyNode.ChildNodes) + { + switch (node.Name) + { + case "a:Name": + key.Name = node.InnerText; + break; + case "a:Code": + key.Code = node.InnerText; + break; + case "a:Comment": + key.Comment = node.InnerText; + break; + case "c:Key.Columns": + key.ColumnIDList = ParseKeyColumnIDs(node.ChildNodes); + break; + default: + break; + } + }//end parse key + + table.AddKey(key); + }//end parse keys + } + //解析键所包含列的ID列表 + IList ParseKeyColumnIDs(XmlNodeList nodeList) + { + IList list = new List(); + foreach (XmlNode node in nodeList) + { + string id = node.Attributes["Ref"].Value; + list.Add(id); + } + return list; + } + + void ParseIndexes(PDModel m, PDPackage package, PDTable table, XmlNode root) + { + foreach (XmlNode indexNode in root.ChildNodes) + { + PDIndex index = new PDIndex(); + index.Model = m; + index.Package = package; + index.Table = table; + index.ID = indexNode.Attributes["Id"].Value; + + foreach (XmlNode node in indexNode.ChildNodes) + { + switch (node.Name) + { + case "a:Name": + index.Name = node.InnerText; + break; + case "a:Code": + index.Code = node.InnerText; + break; + case "a:Comment": + index.Comment = node.InnerText; + break; + case "a:Unique": + index.Unique = node.InnerText == "1" ? true : false; + break; + case "c:IndexColumns": + index.ColumnIDList = ParseIndexColumnIDs(node.ChildNodes); + break; + default: + break; + } + }//end parse index + + table.AddIndex(index); + }//end parse indexes + } + //解析索引所包含列的ID列表 + IList ParseIndexColumnIDs(XmlNodeList nodeList) + { + IList list = new List(); + foreach (XmlNode node in nodeList) + { + foreach (XmlNode n1 in node.ChildNodes) + { + if (n1.Name == "c:Column") + { + list.Add(n1.FirstChild.Attributes["Ref"].Value); + } + } + } + return list; + } + #endregion + + #region ParseViews + void ParseViews(PDModel m, PDPackage package, XmlNode root) + { + foreach (XmlNode viewNode in root.ChildNodes) + { + PDView view = new PDView(); + view.Model = m; + view.Package = package; + view.ID = viewNode.Attributes["Id"].Value; + + foreach (XmlNode node in viewNode.ChildNodes) + { + switch (node.Name) + { + case "a:Name": + view.Name = node.InnerText; + break; + case "a:Code": + view.Code = node.InnerText; + break; + case "a:Comment": + view.Comment = node.InnerText; + break; + default: + break; + } + }//end parse view + + if (package == null) + { + m.AddView(view); + } + else + { + package.AddView(view); + } + }//end parse views + } + #endregion + + #region ParseProcedures + void ParseProcedures(PDModel m, PDPackage package, XmlNode root) + { + foreach (XmlNode procedureNode in root.ChildNodes) + { + PDProcedure procedure = new PDProcedure(); + procedure.Model = m; + procedure.Package = package; + procedure.ID = procedureNode.Attributes["Id"].Value; + + foreach (XmlNode node in procedureNode.ChildNodes) + { + switch (node.Name) + { + case "a:Name": + procedure.Name = node.InnerText; + break; + case "a:Code": + procedure.Code = node.InnerText; + break; + case "a:Comment": + procedure.Comment = node.InnerText; + break; + default: + break; + } + }//end parse procedure + + if (package == null) + { + m.AddProcedure(procedure); + } + else + { + package.AddProcedure(procedure); + } + }//end parse procedures + } + #endregion + + #region ParseReferences + void ParseReferences(PDModel m, PDPackage package, XmlNode root) + { + foreach (XmlNode referenceNode in root.ChildNodes) + { + PDReference reference = new PDReference(); + reference.Model = m; + reference.Package = package; + reference.ID = referenceNode.Attributes["Id"].Value; + + foreach (XmlNode node in referenceNode.ChildNodes) + { + switch (node.Name) + { + case "a:Name": + reference.Name = node.InnerText; + break; + case "a:Code": + reference.Code = node.InnerText; + break; + case "a:Comment": + reference.Comment = node.InnerText; + break; + case "a:Cardinality": + reference.Cardinality = node.InnerText; + break; + case "a:UpdateConstraint": + reference.UpdateConstraint = node.InnerText == "1" ? true : false; + break; + case "a:DeleteConstraint": + reference.DeleteConstraint = node.InnerText == "1" ? true : false; + break; + case "c:ParentTable": + reference.ParentTableID = node.FirstChild.Attributes["Ref"].Value; + break; + case "c:ChildTable": + reference.ChildTableID = node.FirstChild.Attributes["Ref"].Value; + break; + case "c:ParentKey": + reference.ParentKeyID = node.FirstChild.Attributes["Ref"].Value; + break; + case "c:Joins": + reference.JoinList = ParseJoins(node.ChildNodes); + break; + default: + break; + } + }//end parse reference + + if (package == null) + { + m.AddReference(reference); + } + else + { + package.AddReference(reference); + } + }//end parse references + } + + IList ParseJoins(XmlNodeList nodeList) + { + IList list = new List(); + + foreach (XmlNode node in nodeList) + { + ReferenceJoin join = new ReferenceJoin(); + join.ID = node.Attributes["Id"].Value; + + foreach (XmlNode n1 in node.ChildNodes) + { + if (n1.Name == "c:Object1") + { + join.ParentColumnID = n1.FirstChild.Attributes["Ref"].Value; + } + if (n1.Name == "c:Object2") + { + join.ChildColumnID = n1.FirstChild.Attributes["Ref"].Value; + } + } + + list.Add(join); + } + + return list; + } + #endregion + } +} diff --git a/src/Kalman/PdmParser/ReferenceJoin.cs b/src/Kalman/PdmParser/ReferenceJoin.cs new file mode 100644 index 0000000..07adcf8 --- /dev/null +++ b/src/Kalman/PdmParser/ReferenceJoin.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Kalman.PdmParser +{ + [Serializable] + public class ReferenceJoin + { + public string ID { get; set; } + + /// + /// 父表列ID + /// + public string ParentColumnID { get; set; } + + /// + /// 子表列ID,该列为外键列 + /// + public string ChildColumnID { get; set; } + } +} diff --git a/src/Kalman/PdmParser/SchemaObjectConverter.cs b/src/Kalman/PdmParser/SchemaObjectConverter.cs new file mode 100644 index 0000000..e445406 --- /dev/null +++ b/src/Kalman/PdmParser/SchemaObjectConverter.cs @@ -0,0 +1,139 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Kalman.Data.SchemaObject; +using System.Data; +using Kalman.Utilities; + +namespace Kalman.PdmParser +{ + /// + /// 将PDObject对象转换成SchemaObject对象,方便重用基于SchemaObject代码生成引擎 + /// PDM模型的代码生成主要是针对表对象,其他对象暂时不予支持 + /// + public sealed class SOConverter + { + public static SODatabase ToSODatabase(PDPackage package) + { + if (package == null) return null; + + SODatabase db = new SODatabase(); + + db.Name = package.Code; + db.Comment = string.IsNullOrEmpty(package.Comment) ? package.Name : package.Comment; + db.TableList = new List(); + foreach (PDTable item in package.TableList) + { + db.TableList.Add(ToSOTable(item)); + } + db.ViewList = new List(); + //foreach (PDView item in package.ViewList) + //{ + // db.ViewList.Add(ToSOView(item)); + //} + db.CommandList = new List(); + //foreach (PDProcedure item in package.ProcedureList) + //{ + // db.CommandList.Add(ToSOCommand(item)); + //} + + return db; + } + + public static SODatabase ToSODatabase(PDModel model) + { + if (model == null) return null; + + SODatabase db = new SODatabase(); + + db.Name = model.Code; + db.Comment = string.IsNullOrEmpty(model.Comment) ? model.Name : model.Comment; + db.TableList = new List(); + foreach (PDTable item in model.AllTableList) + { + db.TableList.Add(ToSOTable(item)); + } + db.ViewList = new List(); + //foreach (PDView item in model.AllViewList) + //{ + // db.ViewList.Add(ToSOView(item)); + //} + db.CommandList = new List(); + //foreach (PDProcedure item in model.AllProcedureList) + //{ + // db.CommandList.Add(ToSOCommand(item)); + //} + + return db; + } + + public static SOTable ToSOTable(PDTable table) + { + SOTable t = new SOTable(); + + t.Name = table.Code; + t.Comment = string.IsNullOrEmpty(table.Comment) ? table.Name : table.Comment; + t.ColumnList = new List(); + foreach (PDColumn item in table.ColumnList) + { + t.ColumnList.Add(ToSOColumn(item)); + } + t.IndexList = new List(); + + return t; + } + + [Obsolete("暂时不实现该对象的转换")] + public static SOView ToSOView(PDView view) + { + SOView v = new SOView(); + return v; + } + + [Obsolete("暂时不实现该对象的转换")] + public static SOCommand ToSOCommand(PDProcedure sp) + { + SOCommand cmd = new SOCommand(); + return cmd; + } + + public static SOColumn ToSOColumn(PDColumn column) + { + SOColumn c = new SOColumn(); + + c.Name = column.Code; + c.Comment = string.IsNullOrEmpty(column.Comment) ? column.Name : column.Comment; + c.PrimaryKey = column.IsPK; + c.ForeignKey = column.IsFK; + c.Identify = column.Identity; + c.Length = column.Length; + c.NativeType = column.DataType.Split('(')[0]; + c.Nullable = !column.Mandatory; + c.DefaultValue = column.DefaultValue; + c.Precision = column.Length; + c.Scale = column.Precision; //pdm的精度对应数据库的小数位数 + c.DataType = PDMDataTypeToDbType(column); + + return c; + } + + /// + /// + /// + /// + /// + public static DbType PDMDataTypeToDbType(PDColumn column) + { + PDDbms dbms = column.Model.DBMS; + string dataType = column.DataType; + + ///todo:将PDM模型中不同关系数据库的数据类型转换成System.Data.DbType + if (dbms.Code.StartsWith("MSSQLSRV")) return TypeUtil.SqlServerDataType2DbType(column.DataType); + if (dbms.Code.StartsWith("MYSQL")) return TypeUtil.MySqlDataType2DbType(column.DataType); + + + return DbType.String; + } + } +} diff --git a/src/Kalman/PdmParser/help.txt b/src/Kalman/PdmParser/help.txt new file mode 100644 index 0000000..267081c --- /dev/null +++ b/src/Kalman/PdmParser/help.txt @@ -0,0 +1,5 @@ +PowerDesigner 物理模型文件解析组件 + +使用示例 +PdmReader reader = new PdmReader(fileName); +PDModel m = reader.BuildModel(); \ No newline at end of file diff --git a/src/Kalman/Properties/AssemblyInfo.cs b/src/Kalman/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..d5a361e --- /dev/null +++ b/src/Kalman/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 有关程序集的常规信息通过下列属性集 +// 控制。更改这些属性值可修改 +// 与程序集关联的信息。 +[assembly: AssemblyTitle("Kalman")] +[assembly: AssemblyDescription("Kalman开发框架")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Kalman")] +[assembly: AssemblyProduct("Kalman开发框架")] +[assembly: AssemblyCopyright("Copyright © 2010")] +[assembly: AssemblyTrademark("Kalman")] +[assembly: AssemblyCulture("")] + +// 将 ComVisible 设置为 false 使此程序集中的类型 +// 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型, +// 则将该类型上的 ComVisible 属性设置为 true。 +[assembly: ComVisible(false)] + +// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID +[assembly: Guid("ecc54f1f-919c-44a7-9ed8-1ef8c3fbef31")] + +// 程序集的版本信息由下面四个值组成: +// +// 主版本 +// 次版本 +// 内部版本号 +// 修订号 +// +// 可以指定所有这些值,也可以使用“内部版本号”和“修订号”的默认值, +// 方法是按如下所示使用“*”: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/src/Kalman/QQWryLocator.cs b/src/Kalman/QQWryLocator.cs new file mode 100644 index 0000000..cad4cec --- /dev/null +++ b/src/Kalman/QQWryLocator.cs @@ -0,0 +1,272 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; +using System.Text.RegularExpressions; + +namespace Kalman +{ + /* 该查询组件来自网络,请及时更新IP地址库(data\qqwry.dat),以保证查询结果准确 + * + * 调用示例 + * + string path = Path.Combine(Application.StartupPath, "data\\qqwry.dat"); + QQWry.NET.QQWryLocator qqWry = new QQWry.NET.QQWryLocator(path);//初始化数据库文件,并获得IP记录数,通过Count可以获得 + + QQWry.NET.IPLocation ip = qqWry.Query("120.67.217.7"); //查询一个IP地址 + Console.WriteLine("{0} {1} {2}", ip.IP, ip.Country, ip.Local); + + List ips = new List { "218.5.3.128", "120.67.217.7", "125.78.67.175", "220.250.64.23", "218.5.3.128", "120.67.217.7", "125.78.67.175", "220.250.64.23" }; + for (int i = 0; i < 100; i++) + { + foreach (string item in ips) + { + ip = qqWry.Query(item);//这种方式最快 + } + } + + for (int i = 0; i < 100; i++) + { + foreach (string item in ips) + { + string s = IPLocation.IPLocation.IPLocate("qqwry.dat", item); + } + } + */ + + public class IPLocation + { + public string IP { get; set; } + public string Country { get; set; } + public string Local { get; set; } + } + public class QQWryLocator + { + private byte[] data; + Regex regex = new Regex(@"(((\d{1,2})|(1\d{2})|(2[0-4]\d)|(25[0-5]))\.){3}((\d{1,2})|(1\d{2})|(2[0-4]\d)|(25[0-5]))"); + long firstStartIpOffset; + long lastStartIpOffset; + long ipCount; + public long Count { get { return ipCount; } } + public QQWryLocator(string dataPath) + { + using (FileStream fs = new FileStream(dataPath, FileMode.Open, FileAccess.Read, FileShare.Read)) + { + data = new byte[fs.Length]; + fs.Read(data, 0, data.Length); + } + byte[] buffer = new byte[8]; + Array.Copy(data, 0, buffer, 0, 8); + firstStartIpOffset = ((buffer[0] + (buffer[1] * 0x100)) + ((buffer[2] * 0x100) * 0x100)) + (((buffer[3] * 0x100) * 0x100) * 0x100); + lastStartIpOffset = ((buffer[4] + (buffer[5] * 0x100)) + ((buffer[6] * 0x100) * 0x100)) + (((buffer[7] * 0x100) * 0x100) * 0x100); + ipCount = Convert.ToInt64((double)(((double)(lastStartIpOffset - firstStartIpOffset)) / 7.0)); + + if (ipCount <= 1L) + { + throw new ArgumentException("ip FileDataError"); + } + } + private static long IpToInt(string ip) + { + char[] separator = new char[] { '.' }; + if (ip.Split(separator).Length == 3) + { + ip = ip + ".0"; + } + string[] strArray = ip.Split(separator); + long num2 = ((long.Parse(strArray[0]) * 0x100L) * 0x100L) * 0x100L; + long num3 = (long.Parse(strArray[1]) * 0x100L) * 0x100L; + long num4 = long.Parse(strArray[2]) * 0x100L; + long num5 = long.Parse(strArray[3]); + return (((num2 + num3) + num4) + num5); + } + private static string IntToIP(long ip_Int) + { + long num = (long)((ip_Int & 0xff000000L) >> 0x18); + if (num < 0L) + { + num += 0x100L; + } + long num2 = (ip_Int & 0xff0000L) >> 0x10; + if (num2 < 0L) + { + num2 += 0x100L; + } + long num3 = (ip_Int & 0xff00L) >> 8; + if (num3 < 0L) + { + num3 += 0x100L; + } + long num4 = ip_Int & 0xffL; + if (num4 < 0L) + { + num4 += 0x100L; + } + return (num.ToString() + "." + num2.ToString() + "." + num3.ToString() + "." + num4.ToString()); + } + public IPLocation Query(string ip) + { + if (!regex.Match(ip).Success) + { + throw new ArgumentException("IP格式错误"); + } + IPLocation ipLocation = new IPLocation() { IP = ip }; + long intIP = IpToInt(ip); + if ((intIP >= IpToInt("127.0.0.1") && (intIP <= IpToInt("127.255.255.255")))) + { + ipLocation.Country = "本机内部环回地址"; + ipLocation.Local = ""; + } + else + { + if ((((intIP >= IpToInt("0.0.0.0")) && (intIP <= IpToInt("2.255.255.255"))) || ((intIP >= IpToInt("64.0.0.0")) && (intIP <= IpToInt("126.255.255.255")))) || + ((intIP >= IpToInt("58.0.0.0")) && (intIP <= IpToInt("60.255.255.255")))) + { + ipLocation.Country = "网络保留地址"; + ipLocation.Local = ""; + } + } + long right = ipCount; + long left = 0L; + long middle = 0L; + long startIp = 0L; + long endIpOff = 0L; + long endIp = 0L; + int countryFlag = 0; + while (left < (right - 1L)) + { + middle = (right + left) / 2L; + startIp = GetStartIp(middle, out endIpOff); + if (intIP == startIp) + { + left = middle; + break; + } + if (intIP > startIp) + { + left = middle; + } + else + { + right = middle; + } + } + startIp = GetStartIp(left, out endIpOff); + endIp = GetEndIp(endIpOff, out countryFlag); + if ((startIp <= intIP) && (endIp >= intIP)) + { + string local; + ipLocation.Country = GetCountry(endIpOff, countryFlag, out local); + ipLocation.Local = local; + } + else + { + ipLocation.Country = "未知"; + ipLocation.Local = ""; + } + return ipLocation; + } + private long GetStartIp(long left, out long endIpOff) + { + long leftOffset = firstStartIpOffset + (left * 7L); + byte[] buffer = new byte[7]; + Array.Copy(data, leftOffset, buffer, 0, 7); + endIpOff = (Convert.ToInt64(buffer[4].ToString()) + (Convert.ToInt64(buffer[5].ToString()) * 0x100L)) + ((Convert.ToInt64(buffer[6].ToString()) * 0x100L) * 0x100L); + return ((Convert.ToInt64(buffer[0].ToString()) + (Convert.ToInt64(buffer[1].ToString()) * 0x100L)) + ((Convert.ToInt64(buffer[2].ToString()) * 0x100L) * 0x100L)) + (((Convert.ToInt64(buffer[3].ToString()) * 0x100L) * 0x100L) * 0x100L); + } + private long GetEndIp(long endIpOff, out int countryFlag) + { + byte[] buffer = new byte[5]; + Array.Copy(data, endIpOff, buffer, 0, 5); + countryFlag = buffer[4]; + return ((Convert.ToInt64(buffer[0].ToString()) + (Convert.ToInt64(buffer[1].ToString()) * 0x100L)) + ((Convert.ToInt64(buffer[2].ToString()) * 0x100L) * 0x100L)) + (((Convert.ToInt64(buffer[3].ToString()) * 0x100L) * 0x100L) * 0x100L); + } + /// + /// Gets the country. + /// + /// The end ip off. + /// The country flag. + /// The local. + /// country + private string GetCountry(long endIpOff, int countryFlag, out string local) + { + string country = ""; + long offset = endIpOff + 4L; + switch (countryFlag) + { + case 1: + case 2: + country = GetFlagStr(ref offset, ref countryFlag, ref endIpOff); + offset = endIpOff + 8L; + local = (1 == countryFlag) ? "" : GetFlagStr(ref offset, ref countryFlag, ref endIpOff); + break; + default: + country = GetFlagStr(ref offset, ref countryFlag, ref endIpOff); + local = GetFlagStr(ref offset, ref countryFlag, ref endIpOff); + break; + } + return country; + } + private string GetFlagStr(ref long offset, ref int countryFlag, ref long endIpOff) + { + int flag = 0; + byte[] buffer = new byte[3]; + + while (true) + { + //用于向前累加偏移量 + long forwardOffset = offset; + flag = data[forwardOffset++]; + //没有重定向 + if (flag != 1 && flag != 2) + { + break; + } + Array.Copy(data, forwardOffset, buffer, 0, 3); + forwardOffset += 3; + if (flag == 2) + { + countryFlag = 2; + endIpOff = offset - 4L; + } + offset = (Convert.ToInt64(buffer[0].ToString()) + (Convert.ToInt64(buffer[1].ToString()) * 0x100L)) + ((Convert.ToInt64(buffer[2].ToString()) * 0x100L) * 0x100L); + } + if (offset < 12L) + { + return ""; + } + return GetStr(ref offset); + } + private string GetStr(ref long offset) + { + byte lowByte = 0; + byte highByte = 0; + StringBuilder stringBuilder = new StringBuilder(); + byte[] bytes = new byte[2]; + Encoding encoding = Encoding.GetEncoding("GB2312"); + while (true) + { + lowByte = data[offset++]; + if (lowByte == 0) + { + return stringBuilder.ToString(); + } + if (lowByte > 0x7f) + { + highByte = data[offset++]; + bytes[0] = lowByte; + bytes[1] = highByte; + if (highByte == 0) + { + return stringBuilder.ToString(); + } + stringBuilder.Append(encoding.GetString(bytes)); + } + else + { + stringBuilder.Append((char)lowByte); + } + } + } + } +} diff --git a/src/Kalman/RegexConst.cs b/src/Kalman/RegexConst.cs new file mode 100644 index 0000000..b9d9750 --- /dev/null +++ b/src/Kalman/RegexConst.cs @@ -0,0 +1,127 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Kalman +{ + /// + /// ʽ + /// + public struct RegexConst + { + /// + /// Ǹ + /// + public const string UnMinusInteger = "\\d+$"; + + /// + /// + /// + public const string PlusInteger = "^[0-9]*[1-9][0-9]*$"; + + /// + /// + 0 + /// + public const string UnPlusInteger = "^((-\\d+)|(0+))$"; + + /// + /// + /// + public const string MinusInteger = "^-[0-9]*[1-9][0-9]*$"; + + /// + /// + /// + public const string Integer = "^-?\\d+$"; + + /// + /// Ǹ + 0 + /// + public const string UnMinusFloat = "^\\d+(\\.\\d+)?$"; + + /// + /// + /// + public const string PlusFloat = "^(([0-9]+\\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\\.[0-9]+)|([0-9]*[1-9][0-9]*))$"; + + /// + /// + 0 + /// + public const string UnPlusFloat = "^((-\\d+(\\.\\d+)?)|(0+(\\.0+)?))$"; + + /// + /// + /// + public const string MinusFloat = "^(-(([0-9]+\\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\\.[0-9]+)|([0-9]*[1-9][0-9]*)))$"; + + /// + /// + /// + public const string Float = "^(-?\\d+)(\\.\\d+)?$"; + + /// + /// 26Ӣĸɵַ + /// + public const string Letter = "^[A-Za-z]+$"; + + /// + /// 26ӢĸĴдɵַ + /// + public const string UpperLetter = "^[A-Z]+$"; + + /// + /// 26ӢĸСдɵַ + /// + public const string LowerLetter = "^[a-z]+$"; + + /// + /// ֺ26Ӣĸɵַ + /// + public const string NumericOrLetter = "^[A-Za-z0-9]+$"; + + /// + /// ֡26Ӣĸ»ɵַ + /// + public const string NumericOrLetterOrUnderline = "^\\w+$"; + + /// + /// emailַ + /// + //public const string Email = "^[\\w-]+(\\.[\\w-]+)*@[\\w-]+(\\.[\\w-]+)+$"; + public const string Email = @"^([a-zA-Z0-9_'+*$%\^&!\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9:]{2,4})+$"; + + /// + /// URL + /// + public const string Url = "^[a-zA-z]+://(\\w+(-\\w+)*)(\\.(\\w+(-\\w+)*))*(\\?\\S*)?$"; + + /// + /// 绰 + /// + public const string Telephone = @"(\d+-)?(\d{4}-?\d{7}|\d{3}-?\d{8}|^\d{7,8})(-\d+)?"; + + /// + /// ͼļչ + /// + public const string ImageFormat = @"\.(?i:gif|jpg|bmp)$"; + + /// + /// IPַ + /// + public const string IP = @"^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$"; + + /// + /// ڣYYYY-MM-DD + /// + public const string Date = @"^((((1[6-9]|[2-9]\d)\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\d|3[01]))|(((1[6-9]|[2-9]\d)\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\d|30))|(((1[6-9]|[2-9]\d)\d{2})-0?2-(0?[1-9]|1\d|2[0-8]))|(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29-))$"; + + /// + /// ںʱ䣨YYYY-MM-DD HH:MM:SS + /// + public const string DateTime = @"^((((1[6-9]|[2-9]\d)\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\d|3[01]))|(((1[6-9]|[2-9]\d)\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\d|30))|(((1[6-9]|[2-9]\d)\d{2})-0?2-(0?[1-9]|1\d|2[0-8]))|(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29-)) (20|21|22|23|[0-1]?\d):[0-5]?\d:[0-5]?\d$"; + + //ֻ룺^(13[0-9]|15[0-9]|18[0-9])\d{8}$ + + + } +} diff --git a/src/Kalman/RegexValidate.cs b/src/Kalman/RegexValidate.cs new file mode 100644 index 0000000..3e75441 --- /dev/null +++ b/src/Kalman/RegexValidate.cs @@ -0,0 +1,243 @@ +using System; +using System.Collections.Generic; +using System.Text.RegularExpressions; + +namespace Kalman +{ + /// + /// ʽ֤ + /// + public class RegexValidate + { + /// + /// жַǷָʽƥ + /// + /// Ҫַ֤ + /// ʽ + /// ֤ͨtrue + public static bool IsMatch(string input, string regularExp) + { + return Regex.IsMatch(input, regularExp); + } + + /// + /// ֤Ǹ + 0 + /// + /// Ҫַ֤ + /// ֤ͨtrue + public static bool IsUnMinusInt(string input) + { + return Regex.IsMatch(input, RegexConst.UnMinusInteger); + } + + /// + /// ֤ + /// + /// Ҫַ֤ + /// ֤ͨtrue + public static bool IsPlusInt(string input) + { + return Regex.IsMatch(input, RegexConst.PlusInteger); + } + + /// + /// ֤ + 0 + /// + /// Ҫַ֤ + /// ֤ͨtrue + public static bool IsUnPlusInt(string input) + { + return Regex.IsMatch(input, RegexConst.UnPlusInteger); + } + + /// + /// ֤ + /// + /// Ҫַ֤ + /// ֤ͨtrue + public static bool IsMinusInt(string input) + { + return Regex.IsMatch(input, RegexConst.MinusInteger); + } + + /// + /// ֤ + /// + /// Ҫַ֤ + /// ֤ͨtrue + public static bool IsInt(string input) + { + return Regex.IsMatch(input, RegexConst.Integer); + } + + /// + /// ֤Ǹ + 0 + /// + /// Ҫַ֤ + /// ֤ͨtrue + public static bool IsUnMinusFloat(string input) + { + return Regex.IsMatch(input, RegexConst.UnMinusFloat); + } + + /// + /// ֤ + /// + /// Ҫַ֤ + /// ֤ͨtrue + public static bool IsPlusFloat(string input) + { + return Regex.IsMatch(input, RegexConst.PlusFloat); + } + + /// + /// ֤ + 0 + /// + /// Ҫַ֤ + /// ֤ͨtrue + public static bool IsUnPlusFloat(string input) + { + return Regex.IsMatch(input, RegexConst.UnPlusFloat); + } + + /// + /// ֤ + /// + /// Ҫַ֤ + /// ֤ͨtrue + public static bool IsMinusFloat(string input) + { + return Regex.IsMatch(input, RegexConst.MinusFloat); + } + + /// + /// ֤ + /// + /// Ҫַ֤ + /// ֤ͨtrue + public static bool IsFloat(string input) + { + return Regex.IsMatch(input, RegexConst.Float); + } + + /// + /// ֤26Ӣĸɵַ + /// + /// Ҫַ֤ + /// ֤ͨtrue + public static bool IsLetter(string input) + { + return Regex.IsMatch(input, RegexConst.Letter); + } + + /// + /// ֤26ӢĸĴдɵַ + /// + /// Ҫַ֤ + /// ֤ͨtrue + public static bool IsUpperLetter(string input) + { + return Regex.IsMatch(input, RegexConst.UpperLetter); + } + + /// + /// ֤26ӢĸСдɵַ + /// + /// Ҫַ֤ + /// ֤ͨtrue + public static bool IsLowerLetter(string input) + { + return Regex.IsMatch(input, RegexConst.LowerLetter); + } + + /// + /// ֺ֤26Ӣĸɵַ + /// + /// Ҫַ֤ + /// ֤ͨtrue + public static bool IsNumericOrLetter(string input) + { + return Regex.IsMatch(input, RegexConst.NumericOrLetter); + } + + /// + /// ֤֡26Ӣĸ»ɵַ + /// + /// Ҫַ֤ + /// ֤ͨtrue + public static bool IsNumericOrLetterOrUnderline(string input) + { + return Regex.IsMatch(input, RegexConst.NumericOrLetterOrUnderline); + } + + /// + /// ֤emailַ + /// + /// Ҫַ֤ + /// ֤ͨtrue + public static bool IsEmail(string input) + { + return Regex.IsMatch(input, RegexConst.Email); + } + + /// + /// ֤URL + /// + /// Ҫַ֤ + /// ֤ͨtrue + public static bool IsUrl(string input) + { + return Regex.IsMatch(input, RegexConst.Url); + } + + /// + /// ֤绰 + /// + /// + /// + public static bool IsTelephone(string input) + { + return Regex.IsMatch(input, RegexConst.Telephone); + } + + /// + /// ͨļչ֤ͼʽ + /// + /// + /// + public static bool IsImageFormat(string input) + { + return Regex.IsMatch(input, RegexConst.ImageFormat); + } + + /// + /// ֤IP + /// + /// + /// + public static bool IsIP(string input) + { + return Regex.IsMatch(input, RegexConst.IP); + } + + /// + /// ֤ڣYYYY-MM-DD + /// + /// + /// + public static bool IsDate(string input) + { + return Regex.IsMatch(input, RegexConst.Date); + } + + /// + /// ֤ںʱ䣨YYYY-MM-DD HH:MM:SS + /// + /// + /// + public static bool IsDateTime(string input) + { + return Regex.IsMatch(input, RegexConst.DateTime); + } + } +} diff --git a/src/Kalman/Remoting/ChannelType.cs b/src/Kalman/Remoting/ChannelType.cs new file mode 100644 index 0000000..ce2f748 --- /dev/null +++ b/src/Kalman/Remoting/ChannelType.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Kalman.Remoting +{ + /// + /// 通道类型枚举 + /// + [Serializable] + public enum ChannelType + { + /// + /// Tcp Channel + /// + TCP, + /// + /// Http Channel + /// + HTTP, + /// + /// Ipc Channel + /// + IPC + } +} diff --git a/src/Kalman/Remoting/Client/Host.cs b/src/Kalman/Remoting/Client/Host.cs new file mode 100644 index 0000000..240d530 --- /dev/null +++ b/src/Kalman/Remoting/Client/Host.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Kalman.Remoting +{ + /// + /// Remoting宿主实体类 + /// + [Serializable] + public class Host + { + /// + /// Remoting宿主名称 + /// + public string Name { get; set; } + + /// + /// Remoting宿主地址 + /// + public string Url { get; set; } + + /// + /// Remoting宿主是否可用 + /// + //public bool IsUsable { get; set; } + } +} diff --git a/src/Kalman/Remoting/Client/HostManager.cs b/src/Kalman/Remoting/Client/HostManager.cs new file mode 100644 index 0000000..441a8b5 --- /dev/null +++ b/src/Kalman/Remoting/Client/HostManager.cs @@ -0,0 +1,221 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Collections.Specialized; +using System.Collections; +using System.Threading; +using System.Diagnostics; +using System.Runtime.Remoting; + +namespace Kalman.Remoting +{ + /// + /// Remoting宿主管理类 + /// 宿主监控(监控宿主的状态,并标志不可用的宿主) + /// 负载均衡(将客户端的远程调用请求均匀的分配到各个宿主) + /// + public class HostManager : IDisposable + { + public static readonly HostManager Instance = new HostManager(); + RemotingConfig cfg = RemotingConfig.Instance; + StringDictionary hostStateInfo = new StringDictionary(); //主机状态信息 + Hashtable ht = Hashtable.Synchronized(new Hashtable()); //用来保存每个Client的可用Host列表 + List threads = new List(); + + private HostManager() + { + } + + /// + /// 轮询Remoting宿主,检测其是否可用 + /// + public void PollingHost() + { + foreach (ClientConfig ci in cfg.ClientInfoCollection.Values) + { + if (ci.LBEnabled) + { + Thread t = new Thread(new ParameterizedThreadStart(DoCheck)); + t.IsBackground = true; + threads.Add(t); + t.Start(ci); + } + } + } + + void DoCheck(object obj) + { + ClientConfig ci = obj as ClientConfig; + Host[] hosts = new Host[ci.HostCollection.Count]; + ci.HostCollection.Values.CopyTo(hosts, 0); + int interval = ci.PollingInterval * 1000; + + while (true) + { + StringBuilder sb = new StringBuilder(); + foreach (Host host in hosts) + { + #region Remoting调用方式检测Host + try + { + //若服务不可用,耗时比较长,需改用其他方式检测 + string objectUri = "Kalman.Remoting.HostMonitorService"; + HostMonitorService srv = RCHelper.Instance.GetWellKnownObject(host.Url, objectUri); + //Trace.WriteLine(srv.GetCurrentDate()); + + //HostMonitorService srv = (HostMonitorService)RemotingServices.Connect(typeof(HostMonitorService), string.Format("{0}/{1}", host.Url, objectUri)); + //srv.GetCurrentDate(); + sb.Append(host.Url); + sb.Append("|"); + } + catch (Exception ex) + { + string key = string.Format("{0}|{1}", ci.Name, host.Name); + lock (hostStateInfo.SyncRoot) + { + if (hostStateInfo.ContainsKey(key)) + hostStateInfo[key] = ex.Message; + else + hostStateInfo.Add(key, ex.Message); + } + //Trace.WriteLine(key+"."+ex.Message); + } + #endregion + + #region + //string[] ss = host.Url.TrimStart("tcp://".ToCharArray()).Split(':'); + //string ip = ss[0]; + //int port = int.Parse(ss[1]); + //string errMsg = string.Empty; + //bool flag = NetUtil.TestIpAndPort(ip, port, out errMsg); + + //if (flag) + //{ + // sb.Append(host.Url); + // sb.Append("|"); + //} + //else + //{ + // string key = string.Format("{0}|{1}", ci.Name, host.Name); + // lock (hostStateInfo.SyncRoot) + // { + // if (hostStateInfo.ContainsKey(key)) + // hostStateInfo[key] = errMsg; + // else + // hostStateInfo.Add(key, errMsg); + // } + //} + #endregion + }//foreach + + string s = sb.ToString().TrimEnd('|'); + + //更新可用Host列表 + lock (ht.SyncRoot) + { + if (ht.ContainsKey(ci.Name)) + { + ht[ci.Name] = s; + } + else + { + ht.Add(ci.Name, s); + } + } + Thread.Sleep(interval); + } + } + + /// + /// 获取当前Host地址 + /// + /// + public string GetCurrentHostAddress() + { + //取配置的第一个clientName + string clientName = string.Empty; + foreach (ClientConfig cc in RemotingConfig.Instance.ClientInfoCollection.Values) + { + clientName = cc.Name; + break; + } + return GetCurrentHostAddress(clientName); + } + + /// + /// 获取当前Host地址 + /// + /// + /// + public string GetCurrentHostAddress(string clientName) + { + if (string.IsNullOrEmpty(clientName)) return string.Empty; + + ClientConfig ci = cfg.ClientInfoCollection[clientName]; + + if (ci.LBEnabled == false) + return ci.DefaultHost.Url; + else + return GetUsableHostAddress(clientName); + } + + /// + /// 从Client可用Host列表中随机获取一个可用的Host + /// + /// + string GetUsableHostAddress(string clientName) + { + //改进负载均衡算法,可以根据各Host的调用计数和Host的权重(给性能好的机器更多的调用请求)来设计 + if (!ht.ContainsKey(clientName)) return null; + + string s = ht[clientName].ToString().Trim(); + if (s == string.Empty) return null; + + string[] ss = s.Split('|'); + int len = ss.Length; + int second = DateTime.Now.Second; + int idx = second % len; + + return ss[idx]; + } + + /// + /// 返回Host状态信息,只记录异常信息 + /// + /// + /// + /// + public string GetHostStateInfo(string clientName,string hostName) + { + string key = string.Format("{0}|{1}", clientName, hostName); + + if (hostStateInfo.ContainsKey(key)) return hostStateInfo[key]; + else return string.Empty; + } + + #region IDisposable 成员 + + public void Dispose() + { + foreach (Thread t in threads) + { + if (t.ThreadState != System.Threading.ThreadState.Stopped) + { + try + { + t.Abort(); + } + catch { } + } + } + } + + #endregion + + ~HostManager() + { + this.Dispose(); + } + } +} diff --git a/src/Kalman/Remoting/Client/RemotingClientHelper.cs b/src/Kalman/Remoting/Client/RemotingClientHelper.cs new file mode 100644 index 0000000..796fa5f --- /dev/null +++ b/src/Kalman/Remoting/Client/RemotingClientHelper.cs @@ -0,0 +1,106 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Runtime.Remoting; +using System.Reflection; +using System.Diagnostics; +using System.Runtime.Remoting.Channels; +using System.Collections; +using System.Runtime.Remoting.Channels.Tcp; +using System.Runtime.Serialization.Formatters; + +namespace Kalman.Remoting +{ + /// + /// Remoting客户端代理类,客户端通过该对象来访问远程对象的代理实例 + /// + [Obsolete("RCHelper已过时,请使用RemtingClientProxy")] + public class RCHelper + { + public static readonly RCHelper Instance = new RCHelper(); + private RCHelper() + { + HostManager.Instance.PollingHost(); + + //注册通道信息 + //BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider(); + //BinaryClientFormatterSinkProvider clientProvider = new BinaryClientFormatterSinkProvider(); + //serverProvider.TypeFilterLevel = TypeFilterLevel.Full; + //IDictionary props = new Hashtable(); + //props["port"] = 0; + //props["name"] = AppDomain.CurrentDomain.FriendlyName; + //props["secure"] = false; + //TcpChannel channel = new TcpChannel(props, clientProvider, serverProvider); + + //ChannelServices.RegisterChannel(channel, false); + } + + /// + /// 获取远程对象实例 + /// + /// + /// + /// + /// + public T GetWellKnownObject(string hostUrl,string objectUri) + { + string url = string.Format("{0}/{1}", hostUrl.TrimEnd('/'), objectUri); + return (T)Activator.GetObject(typeof(T), url); + } + + /// + /// 获取远程对象实例 + /// + /// + /// + public T GetWellKnownObject() + { + string clientName = string.Empty; + foreach (ClientConfig cc in RemotingConfig.Instance.ClientInfoCollection.Values) + { + clientName = cc.Name; + break; + } + return GetWellKnownObject(clientName); + } + + /// + /// 获取指定客户端名称的远程对象实例 + /// + /// + /// + /// + public T GetWellKnownObject(string clientName) + { + ClientConfig ci = RemotingConfig.Instance.ClientInfoCollection[clientName]; + string hostUrl = HostManager.Instance.GetCurrentHostAddress(clientName); + + if (string.IsNullOrEmpty(hostUrl)) + hostUrl = RemotingConfig.Instance.ClientInfoCollection[clientName].DefaultHost.Url; + + foreach (WellKnownClientTypeEntry entry in RemotingConfiguration.GetRegisteredWellKnownClientTypes()) + { + if (entry.TypeName == typeof(T).FullName) + { + return GetWellKnownObject(hostUrl, entry.ObjectUrl); + } + } + + //若没有在配置中映射类型的远程对象地址,那么用类型的全名称代替 + return GetWellKnownObject(hostUrl, typeof(T).FullName); + } + + /// + /// 获取默认客户端的远程对象实例 + /// + /// + /// + /// + public T GetRemoteObject(string objectUri) + { + string hostUrl = HostManager.Instance.GetCurrentHostAddress(); + return GetWellKnownObject(hostUrl, objectUri); + } + } +} diff --git a/src/Kalman/Remoting/Client/RemotingClientProxy.cs b/src/Kalman/Remoting/Client/RemotingClientProxy.cs new file mode 100644 index 0000000..0675066 --- /dev/null +++ b/src/Kalman/Remoting/Client/RemotingClientProxy.cs @@ -0,0 +1,117 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Runtime.Remoting; + +namespace Kalman.Remoting +{ + /// + /// 客户端访问Remoting对象的代理类 + /// + public class RemotingClientProxy + { + public static readonly RemotingClientProxy Instance = new RemotingClientProxy(); + private RemotingClientProxy() + { + HostManager.Instance.PollingHost(); + + //注册通道信息 + //BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider(); + //BinaryClientFormatterSinkProvider clientProvider = new BinaryClientFormatterSinkProvider(); + //serverProvider.TypeFilterLevel = TypeFilterLevel.Full; + //IDictionary props = new Hashtable(); + //props["port"] = 0; + //props["name"] = AppDomain.CurrentDomain.FriendlyName; + //props["secure"] = false; + //TcpChannel channel = new TcpChannel(props, clientProvider, serverProvider); + + //ChannelServices.RegisterChannel(channel, false); + } + + /// + /// 获取远程对象实例 + /// + /// + /// + /// + public T GetObject(string objectUri) + { + string hostUrl = HostManager.Instance.GetCurrentHostAddress(); + return GetObject(hostUrl, objectUri); + } + + /// + /// 获取远程对象实例 + /// + /// + /// + /// + /// + public T GetObject(string hostUrl,string objectUri) + { + string url = string.Format("{0}/{1}", hostUrl.TrimEnd('/'), objectUri); + return (T)Activator.GetObject(typeof(T), url); + } + + /// + /// 获取远程对象实例 + /// + /// + /// + public T GetObject() + { + string clientName = string.Empty; + foreach (ClientConfig cc in RemotingConfig.Instance.ClientInfoCollection.Values) + { + clientName = cc.Name; + break; + } + return GetObjectByClient(clientName); + } + + /// + /// 获取指定客户端名称的远程对象实例 + /// + /// + /// + /// + public T GetObjectByClient(string clientName) + { + ClientConfig ci = RemotingConfig.Instance.ClientInfoCollection[clientName]; + string hostUrl = HostManager.Instance.GetCurrentHostAddress(clientName); + + if (string.IsNullOrEmpty(hostUrl)) + hostUrl = RemotingConfig.Instance.ClientInfoCollection[clientName].DefaultHost.Url; + + foreach (WellKnownClientTypeEntry entry in RemotingConfiguration.GetRegisteredWellKnownClientTypes()) + { + if (entry.TypeName == typeof(T).FullName) + { + return GetObject(hostUrl, entry.ObjectUrl); + } + } + + //若没有在配置中映射类型的远程对象地址,那么用类型的全名称代替 + return GetObject(hostUrl, typeof(T).FullName); + } + + /// + /// 获取指定客户端名称的远程对象实例 + /// + /// + /// + /// + /// + public T GetObjectByClient(string clientName, string objectUri) + { + ClientConfig ci = RemotingConfig.Instance.ClientInfoCollection[clientName]; + string hostUrl = HostManager.Instance.GetCurrentHostAddress(clientName); + + if (string.IsNullOrEmpty(hostUrl)) + hostUrl = RemotingConfig.Instance.ClientInfoCollection[clientName].DefaultHost.Url; + + return GetObject(hostUrl, objectUri); + } + } +} diff --git a/src/Kalman/Remoting/Config/ClientConfig.cs b/src/Kalman/Remoting/Config/ClientConfig.cs new file mode 100644 index 0000000..f93aac3 --- /dev/null +++ b/src/Kalman/Remoting/Config/ClientConfig.cs @@ -0,0 +1,93 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Runtime.Remoting; + +namespace Kalman.Remoting +{ + /// + /// 客户端配置,每个Client对应一个目标Host + /// + [Serializable] + public class ClientConfig + { + /// + /// 名称 + /// + public string Name { get; set; } + + Host _DefaultHost; + /// + /// 默认Remoting宿主 + /// + public Host DefaultHost + { + get { return _DefaultHost; } + set { _DefaultHost = value; } + } + + bool _LBEnabled = false; + /// + /// 获取或设置是否启用负载均衡 + /// + public bool LBEnabled + { + get { return _LBEnabled; } + set { _LBEnabled = value; } + } + + int _PollingInterval = 1; + /// + /// 获取或设置Remoting宿主轮询时间间隔 + /// + public int PollingInterval + { + get { return _PollingInterval; } + set { _PollingInterval = value; } + } + + Dictionary _HostCollection = new Dictionary(); + //Dictionary _WellKnownObjectCollection = new Dictionary(); + + /// + /// Remoting宿主集合 + /// + public Dictionary HostCollection + { + get { return _HostCollection; } + } + + /// + /// 加入一个Remoting宿主 + /// + /// + public void AddHost(Host host) + { + if (_HostCollection.ContainsKey(host.Name) == false) + { + _HostCollection.Add(host.Name, host); + } + } + + ///// + ///// WellKnown对象集合 + ///// + //public Dictionary WellKnownObjectCollection + //{ + // get { return _WellKnownObjectCollection; } + //} + + ///// + ///// 加入一个WellKnown对象 + ///// + ///// + //public void AddWellKnownObject(WellKnownClientObject entry) + //{ + // if (_WellKnownObjectCollection.ContainsKey(entry.ObjectUri) == false) + // { + // _WellKnownObjectCollection.Add(entry.ObjectUri, entry); + // } + //} + } +} diff --git a/src/Kalman/Remoting/Config/RemotingConfig.cs b/src/Kalman/Remoting/Config/RemotingConfig.cs new file mode 100644 index 0000000..a127ac7 --- /dev/null +++ b/src/Kalman/Remoting/Config/RemotingConfig.cs @@ -0,0 +1,264 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Xml; +using System.Configuration; +using System.Runtime.Remoting; +using System.Reflection; +using Kalman.Utilities; + +namespace Kalman.Remoting +{ + /// + /// Remoting Config + /// + public class RemotingConfig : ConfigBase + { + public static readonly RemotingConfig Instance = new RemotingConfig(); + + private RemotingConfig() + { + XmlNode root = (XmlNode)ConfigurationManager.GetSection("kalman/remoting"); + if (root == null) return; + + foreach (XmlNode node in root.ChildNodes) + { + if (node.NodeType == XmlNodeType.Comment) continue; + switch (node.Name) + { + case "client": + ParseClientSection(node); + break; + case "server": + ParseServerSection(node); + break; + default: + break; + } + } + } + + Dictionary _ClientInfoCollection = new Dictionary(); + Dictionary _ServerInfoCollection = new Dictionary(); + + public Dictionary ClientInfoCollection + { + get { return _ClientInfoCollection; } + } + + #region Client Config Parse + + ClientConfig ci; + + //解析客户端配置节 + void ParseClientSection(XmlNode root) + { + ci = new ClientConfig(); + + ci.Name = base.GetStringAttribute(root, "name", "default"); + ci.LBEnabled = base.GetBoolAttribute(root, "lbEnabled", false); + ci.PollingInterval = base.GetIntAttribute(root, "pollingInterval", 1); + + foreach (XmlNode node in root.ChildNodes) + { + if (node.NodeType == XmlNodeType.Comment) continue; + switch (node.Name) + { + case "host": + ParseHostSection(node); + break; + case "wellknown": + ParseWellKnownClientObjectSection(node); + break; + //case "activated": + // ParseActivatedClientObjectSection(node); + // break; + default: + break; + } + } + + if (!_ClientInfoCollection.ContainsKey(ci.Name)) + _ClientInfoCollection.Add(ci.Name, ci); + } + + //解析Remoting宿主 + void ParseHostSection(XmlNode root) + { + string defaultHostName = base.GetStringAttribute(root, "default"); + + Host firstHost = null; + + foreach (XmlNode node in root.ChildNodes) + { + if (node.NodeType == XmlNodeType.Comment) continue; + if (node.Name != "add") continue; + + if (node.Attributes["name"] == null || + node.Attributes["url"] == null || + string.IsNullOrEmpty(node.Attributes["name"].Value) || + string.IsNullOrEmpty(node.Attributes["url"].Value)) continue; + + Host host = new Host(); + host.Name = node.Attributes["name"].Value; + host.Url = node.Attributes["url"].Value; + + ci.AddHost(host); + + if (firstHost == null) firstHost = host; + } + + if (ci.HostCollection.Count == 0) + { + throw new Exception("没有配置Remoting宿主"); + } + else + { + if (ci.HostCollection.ContainsKey(defaultHostName)) + { + ci.DefaultHost = ci.HostCollection[defaultHostName]; + } + else + { + ci.DefaultHost = firstHost; + } + } + } + + //解析并注册WellKnown对象 + void ParseWellKnownClientObjectSection(XmlNode root) + { + foreach (XmlNode node in root.ChildNodes) + { + if (node.NodeType == XmlNodeType.Comment) continue; + if (node.Name != "add") continue; + + string objectUri = base.GetStringAttribute(node, "objectUri"); + if (string.IsNullOrEmpty(objectUri)) continue; + + string fullTypeName = base.GetStringAttribute(node, "type"); + if (string.IsNullOrEmpty(fullTypeName)) continue; + + string typeName = fullTypeName.Split(',')[0]; + string assemblyName = string.Empty; + + if (fullTypeName.IndexOf(',') != -1) + { + assemblyName = fullTypeName.Split(',')[1]; + } + else + { + Assembly assembly = ReflectUtil.FindAssemblyFromAppDirectory(typeName); + if (assembly != null) + assemblyName = assembly.FullName; + } + + WellKnownClientTypeEntry wce = new WellKnownClientTypeEntry(typeName, assemblyName, objectUri); + RemotingConfiguration.RegisterWellKnownClientType(wce); + } + } + + //解析并注册Activated对象 + //void ParseActivatedClientObjectSection(XmlNode root) + //{ + // // + //} + + #endregion + + #region Server Config Parse + + ServerConfig si = new ServerConfig(); + + /// + /// 服务端配置信息 + /// + public ServerConfig ServerConfig + { + get { return si; } + } + + //解析服务端配置节 + void ParseServerSection(XmlNode root) + { + si.Address = base.GetStringAttribute(root, "address"); + string channelType = base.GetStringAttribute(root, "channelType").ToUpper(); + switch (channelType) + { + case "TCP": + si.ChannelType = ChannelType.TCP; + break; + case "HTTP": + si.ChannelType = ChannelType.HTTP; + break; + case "IPC": + si.ChannelType = ChannelType.IPC; + break; + default: + si.ChannelType = ChannelType.TCP; + break; + } + + si.Port = base.GetIntAttribute(root, "port", 9999); + + foreach (XmlNode node in root.ChildNodes) + { + if (node.NodeType == XmlNodeType.Comment) continue; + switch (node.Name) + { + case "wellknown": + ParseWellKnownServerObjectSection(node); + break; + //case "activated": + // ParseActivatedServerObjectSection(node); + // break; + default: + break; + } + } + } + + //解析WellKnown对象 + void ParseWellKnownServerObjectSection(XmlNode root) + { + foreach (XmlNode node in root.ChildNodes) + { + if (node.NodeType == XmlNodeType.Comment) continue; + if (node.Name != "add") continue; + + string objectUri = base.GetStringAttribute(node, "objectUri"); + if (string.IsNullOrEmpty(objectUri)) continue; + + string fullTypeName = base.GetStringAttribute(node, "type"); + if (string.IsNullOrEmpty(fullTypeName)) continue; + + string mode = base.GetStringAttribute(node, "mode").ToLower(); + + + string typeName = fullTypeName.Split(',')[0]; + string assemblyName = string.Empty; + + if (fullTypeName.IndexOf(',') != -1) + { + assemblyName = fullTypeName.Split(',')[1]; + } + else + { + Assembly assembly = ReflectUtil.FindAssemblyFromAppDirectory(typeName); + if (assembly != null) + assemblyName = assembly.FullName; + } + + WellKnownObjectMode objectMode = WellKnownObjectMode.Singleton; + if (mode == "singlecall") + objectMode = WellKnownObjectMode.SingleCall; + + WellKnownServiceTypeEntry wse = new WellKnownServiceTypeEntry(typeName, assemblyName, objectUri, objectMode); + si.AddWellKnownObject(wse); + } + } + + #endregion + } +} diff --git a/src/Kalman/Remoting/Config/ServerConfig.cs b/src/Kalman/Remoting/Config/ServerConfig.cs new file mode 100644 index 0000000..df8fbee --- /dev/null +++ b/src/Kalman/Remoting/Config/ServerConfig.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Runtime.Remoting; + +namespace Kalman.Remoting +{ + /// + /// 服务端配置,每个Remoting宿主目前只允许配置一项 + /// + [Serializable] + public class ServerConfig + { + ChannelType _ChannelType = ChannelType.TCP; + + /// + /// 通道类型,默认为TCP通道 + /// + public ChannelType ChannelType + { + get { return _ChannelType; } + set { _ChannelType = value; } + } + + /// + /// 服务器地址(IP、机器名或域名) + /// + public string Address { get; set; } + + /// + /// 服务端口 + /// + public int Port { get; set; } + + Dictionary _WellKnownObjectCollection = new Dictionary(); + + public Dictionary WellKnownObjectCollection + { + get { return _WellKnownObjectCollection; } + } + + /// + /// 加入一个WellKnown对象实体 + /// + /// + public void AddWellKnownObject(WellKnownServiceTypeEntry entry) + { + if (_WellKnownObjectCollection.ContainsKey(entry.ObjectUri)) return; + _WellKnownObjectCollection.Add(entry.ObjectUri, entry); + } + } +} diff --git a/src/Kalman/Remoting/IAuthentication.cs b/src/Kalman/Remoting/IAuthentication.cs new file mode 100644 index 0000000..e119c00 --- /dev/null +++ b/src/Kalman/Remoting/IAuthentication.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Kalman.Remoting +{ + /// + /// 认证接口,对于需要进行认证才能调用的远程对象必须实现该接口 + /// + public interface IAuthentication + { + bool IsValidate { get; } + bool Validate(); + } +} diff --git a/src/Kalman/Remoting/RemoteObject.cs b/src/Kalman/Remoting/RemoteObject.cs new file mode 100644 index 0000000..8544815 --- /dev/null +++ b/src/Kalman/Remoting/RemoteObject.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Kalman.Remoting +{ + /// + /// 远程对象基类 + /// + public class RemoteObject : MarshalByRefObject + { + } +} diff --git a/src/Kalman/Remoting/Server/RemotingServerHelper.cs b/src/Kalman/Remoting/Server/RemotingServerHelper.cs new file mode 100644 index 0000000..129bcb0 --- /dev/null +++ b/src/Kalman/Remoting/Server/RemotingServerHelper.cs @@ -0,0 +1,105 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Runtime.Remoting; +using System.Runtime.Remoting.Channels; +using System.Runtime.Serialization.Formatters; +using System.Collections; +using System.Runtime.Remoting.Channels.Tcp; +using System.Runtime.Remoting.Channels.Http; +using System.Runtime.Remoting.Channels.Ipc; + +namespace Kalman.Remoting +{ + /// + /// Remoting服务端帮助类 + /// + [Obsolete("暂停使用该对象发布Remoting业务组件,改用配置文件")] + public class RSHelper : ILogable + { + IChannel serviceChannel; + ServerConfig sc; + + public RSHelper(ServerConfig cfg) + { + sc = cfg; + + if (string.IsNullOrEmpty(sc.Address)) + { + //取本机IP + } + + //使用二进制格式化 + BinaryServerFormatterSinkProvider serverProvider = new + BinaryServerFormatterSinkProvider(); + BinaryClientFormatterSinkProvider clientProvider = new + BinaryClientFormatterSinkProvider(); + + //设置反序列化级别为Full,支持远程处理在所有情况下支持的所有类型 + serverProvider.TypeFilterLevel = TypeFilterLevel.Full; + + IDictionary props = new Hashtable(); + props["name"] = AppDomain.CurrentDomain.FriendlyName; + props["port"] = sc.Port; + + switch (sc.ChannelType) + { + case ChannelType.TCP: + serviceChannel = new TcpChannel(props, clientProvider, serverProvider); + break; + case ChannelType.HTTP: + serviceChannel = new HttpChannel(props, clientProvider, serverProvider); + break; + case ChannelType.IPC: + serviceChannel = new IpcChannel(props, clientProvider, serverProvider); + break; + default: + break; + } + + ChannelServices.RegisterChannel(serviceChannel, false); + } + + public void RegisterWellKnownObject() + { + Log("开始注册Remoting对象"); + foreach (WellKnownServiceTypeEntry entry in sc.WellKnownObjectCollection.Values) + { + RemotingConfiguration.RegisterWellKnownServiceType(entry); + Log(string.Format("已注册[{0}],对象地址[{1}],激活类型[{2}]", entry.TypeName, entry.ObjectUri, entry.Mode)); + } + + RemotingConfiguration.CustomErrorsMode = CustomErrorsModes.Off; + RemotingConfiguration.CustomErrorsEnabled(false); + + //注册Remoting宿主监控服务模块 + Log("已注册Remoting宿主监控服务模块,对象地址[HostMonitorService],激活类型[Singleton]"); + RemotingConfiguration.RegisterWellKnownServiceType(typeof(HostMonitorService), "Kalman.Remoting.HostMonitorService", WellKnownObjectMode.Singleton); + + Log("Remoting对象已全部注册完成"); + } + + /// + /// 对象销毁时注销已注册的Remoting信道 + /// + ~RSHelper() + { + ChannelServices.UnregisterChannel(serviceChannel); + } + + #region ILogable 成员 + + public event LogHandler OnLog; + + #endregion + + void Log(string msg) + { + if (OnLog != null) + { + OnLog(msg); + } + } + } +} diff --git a/src/Kalman/Remoting/Service/HostMonitorService.cs b/src/Kalman/Remoting/Service/HostMonitorService.cs new file mode 100644 index 0000000..0a6d33c --- /dev/null +++ b/src/Kalman/Remoting/Service/HostMonitorService.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Kalman.Remoting +{ + /// + /// Remoting宿主监控服务类,提供Remoting宿主服务器的一些基本信息和操作,比如:获取当前时间、CPU、内存信息及对本机服务控制等 + /// 该对象在Remoting服务端默认发布,客户端可以通过该服务类来获取Remoting宿主服务器的一些基本信息 + /// + public class HostMonitorService : MarshalByRefObject + { + /// + /// 获取Remoting宿主服务器当前时间 + /// + /// + public DateTime GetCurrentDate() + { + return DateTime.Now; + } + } +} diff --git a/src/Kalman/Remoting/Service/LoggingService.cs b/src/Kalman/Remoting/Service/LoggingService.cs new file mode 100644 index 0000000..26144ed --- /dev/null +++ b/src/Kalman/Remoting/Service/LoggingService.cs @@ -0,0 +1,76 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Kalman.Logging; +using System.IO; + +namespace Kalman.Remoting +{ + /// + /// Remoting Logging Service + /// + public class LoggingService : MarshalByRefObject + { + #region Write Log + + /// + /// 写日志 + /// + /// 应用程序名称(唯一) + /// 日志消息 + public void WriteLog(string appName, string msg) + { + string path = GetLogPath(appName); + msg = FormatLogMessage(msg,null); + File.AppendAllText(path, msg, Encoding.UTF8); + } + + ///// + ///// 写日志 + ///// + ///// 应用程序名称(唯一) + ///// 日志消息 + ///// 需要记录的异常 + //public void WriteLog(string appName, string msg, Exception ex) + //{ + // string path = GetLogPath(appName); + // msg = FormatLogMessage(msg, ex); + // File.AppendAllText(path, msg, Encoding.UTF8); + //} + + /// + /// 获取指定名称的应用程序日志写入路径 + /// + /// 应用程序名称 + /// + private string GetLogPath(string appName) + { + string path = string.Format("log\\{0}\\{1}", appName, DateTime.Now.ToString("yyyyMM")); + path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, path); + + if (Directory.Exists(path) == false) + { + Directory.CreateDirectory(path); + } + + path = Path.Combine(path, DateTime.Now.ToString("yyyy-MM-dd") + ".log"); + return path; + } + + private string FormatLogMessage(string msg, Exception ex) + { + if (ex != null) + { + msg = msg + "\r\n" + ex.ToString(); + } + return string.Format("{0} {1}\r\n", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), msg); + } + #endregion + + #region Log File Manage + ///todo:Log File Manage + + #endregion + } +} diff --git a/src/Kalman/Remoting/help.txt b/src/Kalman/Remoting/help.txt new file mode 100644 index 0000000..b1b10c0 --- /dev/null +++ b/src/Kalman/Remoting/help.txt @@ -0,0 +1,33 @@ +完整配置示例 + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Kalman/Resources/Common.Designer.cs b/src/Kalman/Resources/Common.Designer.cs new file mode 100644 index 0000000..1a99f2e --- /dev/null +++ b/src/Kalman/Resources/Common.Designer.cs @@ -0,0 +1,99 @@ +//------------------------------------------------------------------------------ +// +// 此代码由工具生成。 +// 运行时版本:4.0.30319.42000 +// +// 对此文件的更改可能会导致不正确的行为,并且如果 +// 重新生成代码,这些更改将会丢失。 +// +//------------------------------------------------------------------------------ + +namespace Kalman.Resources { + using System; + + + /// + /// 一个强类型的资源类,用于查找本地化的字符串等。 + /// + // 此类是由 StronglyTypedResourceBuilder + // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 + // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen + // (以 /str 作为命令选项),或重新生成 VS 项目。 + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Common { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Common() { + } + + /// + /// 返回此类使用的缓存的 ResourceManager 实例。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Kalman.Resources.Common", typeof(Common).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// 使用此强类型资源类,为所有资源查找 + /// 重写当前线程的 CurrentUICulture 属性。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// 查找类似 参数[{0}]不能为空 的本地化字符串。 + /// + internal static string ArgumentNotEmpty { + get { + return ResourceManager.GetString("ArgumentNotEmpty", resourceCulture); + } + } + + /// + /// 查找类似 参数[{0}]不能为Null 的本地化字符串。 + /// + internal static string ArgumentNotNull { + get { + return ResourceManager.GetString("ArgumentNotNull", resourceCulture); + } + } + + /// + /// 查找类似 参数[{0}]不能为空白字符 的本地化字符串。 + /// + internal static string ArgumentNotWhitespace { + get { + return ResourceManager.GetString("ArgumentNotWhitespace", resourceCulture); + } + } + + /// + /// 查找类似 类型转换失败,原始类型[{0}] -> 目标类型[{1}] 的本地化字符串。 + /// + internal static string TypeConvertFailed { + get { + return ResourceManager.GetString("TypeConvertFailed", resourceCulture); + } + } + } +} diff --git a/src/Kalman/Resources/Common.resx b/src/Kalman/Resources/Common.resx new file mode 100644 index 0000000..e817281 --- /dev/null +++ b/src/Kalman/Resources/Common.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 参数[{0}]不能为空 + + + 参数[{0}]不能为Null + + + 参数[{0}]不能为空白字符 + + + 类型转换失败,原始类型[{0}] -> 目标类型[{1}] + + \ No newline at end of file diff --git a/src/Kalman/Resources/Data.Designer.cs b/src/Kalman/Resources/Data.Designer.cs new file mode 100644 index 0000000..5e2e81a --- /dev/null +++ b/src/Kalman/Resources/Data.Designer.cs @@ -0,0 +1,126 @@ +//------------------------------------------------------------------------------ +// +// 此代码由工具生成。 +// 运行时版本:4.0.30319.42000 +// +// 对此文件的更改可能会导致不正确的行为,并且如果 +// 重新生成代码,这些更改将会丢失。 +// +//------------------------------------------------------------------------------ + +namespace Kalman.Resources { + using System; + + + /// + /// 一个强类型的资源类,用于查找本地化的字符串等。 + /// + // 此类是由 StronglyTypedResourceBuilder + // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 + // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen + // (以 /str 作为命令选项),或重新生成 VS 项目。 + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Data { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Data() { + } + + /// + /// 返回此类使用的缓存的 ResourceManager 实例。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Kalman.Resources.Data", typeof(Data).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// 使用此强类型资源类,为所有资源查找 + /// 重写当前线程的 CurrentUICulture 属性。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// 查找类似 该Command对象必须是SqlCommand类型 的本地化字符串。 + /// + internal static string CommandNotSqlCommand { + get { + return ResourceManager.GetString("CommandNotSqlCommand", resourceCulture); + } + } + + /// + /// 查找类似 不能找到名称为[{0}]的连接字符串 的本地化字符串。 + /// + internal static string ConnectionStringNameNotFound { + get { + return ResourceManager.GetString("ConnectionStringNameNotFound", resourceCulture); + } + } + + /// + /// 查找类似 连接字符串没有配置 的本地化字符串。 + /// + internal static string ConnectionStringNotConfig { + get { + return ResourceManager.GetString("ConnectionStringNotConfig", resourceCulture); + } + } + + /// + /// 查找类似 找不到名称为[{0}]数据提供程序,请检查配置节system.data->DbProviderFactories 的本地化字符串。 + /// + internal static string DataProviderNotFound { + get { + return ResourceManager.GetString("DataProviderNotFound", resourceCulture); + } + } + + /// + /// 查找类似 必须初始化至少一个Command 的本地化字符串。 + /// + internal static string MustInitAtLeastOneCommand { + get { + return ResourceManager.GetString("MustInitAtLeastOneCommand", resourceCulture); + } + } + + /// + /// 查找类似 参数值的个数与当前存储过程的参数个数不匹配 的本地化字符串。 + /// + internal static string ParameterMatchFailure { + get { + return ResourceManager.GetString("ParameterMatchFailure", resourceCulture); + } + } + + /// + /// 查找类似 无法更新行 的本地化字符串。 + /// + internal static string RowUpdateFailed { + get { + return ResourceManager.GetString("RowUpdateFailed", resourceCulture); + } + } + } +} diff --git a/src/Kalman/Resources/Data.resx b/src/Kalman/Resources/Data.resx new file mode 100644 index 0000000..85a50ff --- /dev/null +++ b/src/Kalman/Resources/Data.resx @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 该Command对象必须是SqlCommand类型 + + + 不能找到名称为[{0}]的连接字符串 + + + 连接字符串没有配置 + + + 找不到名称为[{0}]数据提供程序,请检查配置节system.data->DbProviderFactories + + + 必须初始化至少一个Command + + + 参数值的个数与当前存储过程的参数个数不匹配 + + + 无法更新行 + + \ No newline at end of file diff --git a/src/Kalman/Security/Enums/AsymmetricAlgorithmType.cs b/src/Kalman/Security/Enums/AsymmetricAlgorithmType.cs new file mode 100644 index 0000000..65e3378 --- /dev/null +++ b/src/Kalman/Security/Enums/AsymmetricAlgorithmType.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Kalman.Security +{ + /// + /// 不对称加密算法类型枚举 + /// + public enum AsymmetricAlgorithmType + { + DSA, + RSA + } +} diff --git a/src/Kalman/Security/Enums/HashAlgorithmType.cs b/src/Kalman/Security/Enums/HashAlgorithmType.cs new file mode 100644 index 0000000..096036f --- /dev/null +++ b/src/Kalman/Security/Enums/HashAlgorithmType.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Kalman.Security +{ + /// + /// 哈希算法类型 + /// + public enum HashAlgorithmType + { + /// MD5 Hash + MD5, + /// SHA1 - A 160 bit Secure Algorithm Hash + SHA1, + /// SHA2 - A 256 bit Secure Algorithm Hash + SHA256, + /// SHA3 - A 384 bit Secure Algorithm Hash + SHA384, + /// SHA5 - A 512 bit Secure Algorithm Hash + SHA512 + } +} diff --git a/src/Kalman/Security/Enums/SymmetricAlgorithmType.cs b/src/Kalman/Security/Enums/SymmetricAlgorithmType.cs new file mode 100644 index 0000000..ebfa272 --- /dev/null +++ b/src/Kalman/Security/Enums/SymmetricAlgorithmType.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Kalman.Security +{ + /// + /// 对称加密算法类型枚举 + /// + public enum SymmetricAlgorithmType + { + /// + /// 数据加密标准,速度较快,适用于加密大量数据的场合,密钥长度固定为64 + /// + DES, + /// + /// RC2加密算法,密钥长度40,用变长密钥对大量数据进行加密,比 DES 快 + /// + RC2_40, + /// + /// RC2加密算法,密钥长度64,用变长密钥对大量数据进行加密,比 DES 快 + /// + RC2_64, + /// + /// RC2加密算法,密钥长度96,用变长密钥对大量数据进行加密,比 DES 快 + /// + RC2_96, + /// + /// RC2加密算法,密钥长度128,用变长密钥对大量数据进行加密,比 DES 快 + /// + RC2_128, + /// + /// Rijndael加密算法,密钥长度128 + /// AES(Advanced Encryption Standard):高级加密标准,是下一代的加密算法标准,速度快,安全级别高,目前 AES 标准的一个实现是 Rijndael 算法; + /// + Rijndael_128, + /// + /// Rijndael加密算法,密钥长度192 + /// AES(Advanced Encryption Standard):高级加密标准,是下一代的加密算法标准,速度快,安全级别高,目前 AES 标准的一个实现是 Rijndael 算法; + /// + Rijndael_192, + /// + /// Rijndael加密算法,密钥长度256 + /// AES(Advanced Encryption Standard):高级加密标准,是下一代的加密算法标准,速度快,安全级别高,目前 AES 标准的一个实现是 Rijndael 算法; + /// + Rijndael_256, + /// + /// 3DES加密算法,密钥长度128 + /// 3DES(Triple DES):是基于DES,对一块数据用三个不同的密钥进行三次加密,强度更高; + /// + TripleDES_128, + /// + /// 3DES加密算法,密钥长度192 + /// 3DES(Triple DES):是基于DES,对一块数据用三个不同的密钥进行三次加密,强度更高; + /// + TripleDES_192 + } +} diff --git a/src/Kalman/Security/HashCryto.cs b/src/Kalman/Security/HashCryto.cs new file mode 100644 index 0000000..c52f018 --- /dev/null +++ b/src/Kalman/Security/HashCryto.cs @@ -0,0 +1,259 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Security.Cryptography; +using System.Globalization; +using System.IO; +using Kalman.Utilities; + +// Kalman Create by 2010-03-08 +namespace Kalman.Security +{ + /// + /// 哈希加密算法 + /// + public static class HashCryto + { + #region 计算文件流的哈希值 + + /// + /// 计算文件流的哈希值 + /// + /// + /// + /// + public static byte[] GetHash(FileStream fileStream, HashAlgorithmType hashAlgorithmType) + { + CheckUtil.ArgumentNotNull(fileStream, "fileStream"); + + HashAlgorithm hashAlgorithm = CreateHashAlgorithmProvider(hashAlgorithmType); + byte[] result = hashAlgorithm.ComputeHash(fileStream); + hashAlgorithm.Clear(); + fileStream.Close(); + + return result; + } + + /// + /// 计算文件流的哈希值并将其转换为字符串 + /// + /// + /// + /// + public static string GetHash2String(FileStream fileStream, HashAlgorithmType hashAlgorithmType) + { + CheckUtil.ArgumentNotNull(fileStream, "fileStream"); + + string result = string.Empty; + byte[] bytes = GetHash(fileStream, hashAlgorithmType); + + foreach (byte b in bytes) + { + result += Convert.ToString(b, 16).ToUpper(CultureInfo.InvariantCulture).PadLeft(2, '0'); + } + + return result; + } + + /// + /// 计算文件流的哈希值并将其转换为使用Base64编码的字符串 + /// + /// + /// + /// + public static string GetHash2Base64(FileStream fileStream, HashAlgorithmType hashAlgorithmType) + { + CheckUtil.ArgumentNotNull(fileStream, "fileStream"); + + byte[] bytes = GetHash(fileStream, hashAlgorithmType); + string result = Convert.ToBase64String(bytes); + + return result; + } + + #endregion + + #region 计算字节数组的哈希值 + + /// + /// 计算字节数组的哈希值 + /// + /// + /// + /// + public static byte[] GetHash(byte[] data, HashAlgorithmType hashAlgorithmType) + { + CheckUtil.ArgumentNotNull(data, "data"); + + HashAlgorithm hashAlgorithm = CreateHashAlgorithmProvider(hashAlgorithmType); + byte[] result = hashAlgorithm.ComputeHash(data); + hashAlgorithm.Clear(); + + return result; + } + + /// + /// 计算字节数组的哈希值并将其转换为字符串 + /// + /// + /// + /// + public static string GetHash2String(byte[] data, HashAlgorithmType hashAlgorithmType) + { + CheckUtil.ArgumentNotNull(data, "data"); + + string result = string.Empty; + byte[] bytes = GetHash(data, hashAlgorithmType); + + foreach (byte b in bytes) + { + result += Convert.ToString(b, 16).ToUpper(CultureInfo.InvariantCulture).PadLeft(2, '0'); + } + + return result; + } + + /// + /// 计算字节数组的哈希值并将其转换为使用Base64编码的字符串 + /// + /// + /// + /// + public static string GetHash2Base64(byte[] data, HashAlgorithmType hashAlgorithmType) + { + CheckUtil.ArgumentNotNull(data, "data"); + + byte[] bytes = GetHash(data, hashAlgorithmType); + string result = Convert.ToBase64String(bytes); + + return result; + } + + #endregion + + #region 计算字符串的哈希值 + + /// + /// 计算字符串的哈希值 + /// + /// + /// + /// + public static byte[] GetHash(string s, HashAlgorithmType hashAlgorithmType) + { + return GetHash(s, hashAlgorithmType, Encoding.Default); + } + + /// + /// 计算字符串的哈希值 + /// + /// + /// + /// 指定字符串的编码 + /// + public static byte[] GetHash(string s, HashAlgorithmType hashAlgorithmType, Encoding encoding) + { + CheckUtil.ArgumentNotNullOrEmpty(s, "s"); + + byte[] data = encoding.GetBytes(s); + return GetHash(data, hashAlgorithmType); + } + + /// + /// 计算字符串的哈希值并将其转换为字符串 + /// + /// + /// + /// + public static string GetHash2String(string s, HashAlgorithmType hashAlgorithmType) + { + return GetHash2String(s, hashAlgorithmType, Encoding.Default); + } + + /// + /// 计算字符串的哈希值并将其转换为字符串 + /// + /// + /// + /// 指定字符串的编码 + /// + public static string GetHash2String(string s, HashAlgorithmType hashAlgorithmType, Encoding encoding) + { + CheckUtil.ArgumentNotNullOrEmpty(s, "s"); + + string result = string.Empty; + byte[] bytes = GetHash(s, hashAlgorithmType, encoding); + + foreach (byte b in bytes) + { + result += Convert.ToString(b, 16).ToUpper(CultureInfo.InvariantCulture).PadLeft(2, '0'); + } + + return result; + } + + /// + /// 计算字符串的哈希值并将其转换为使用Base64编码的字符串 + /// + /// + /// + /// + public static string GetHash2Base64(string s, HashAlgorithmType hashAlgorithmType) + { + return GetHash2Base64(s, hashAlgorithmType, Encoding.Default); + } + + /// + /// 计算字符串的哈希值并将其转换为使用Base64编码的字符串 + /// + /// + /// + /// + public static string GetHash2Base64(string s, HashAlgorithmType hashAlgorithmType, Encoding encoding) + { + CheckUtil.ArgumentNotNullOrEmpty(s, "s"); + + byte[] data = GetHash(s, hashAlgorithmType, encoding); + string result = Convert.ToBase64String(data); + + return result; + } + + #endregion + + /// + /// 创建一个哈希算法提供者实例 + /// + /// + /// + public static HashAlgorithm CreateHashAlgorithmProvider(HashAlgorithmType hashAlgorithmType) + { + HashAlgorithm hashAlgorithm = null; + + switch (hashAlgorithmType) + { + case HashAlgorithmType.MD5: + hashAlgorithm = new MD5CryptoServiceProvider(); + break; + case HashAlgorithmType.SHA1: + hashAlgorithm = new SHA1Managed(); + break; + case HashAlgorithmType.SHA256: + hashAlgorithm = new SHA256Managed(); + break; + case HashAlgorithmType.SHA384: + hashAlgorithm = new SHA384Managed(); + break; + case HashAlgorithmType.SHA512: + hashAlgorithm = new SHA512Managed(); + break; + default: + hashAlgorithm = new MD5CryptoServiceProvider(); + break; + } + + return hashAlgorithm; + } + } +} diff --git a/src/Kalman/Security/SymmetricCryto.cs b/src/Kalman/Security/SymmetricCryto.cs new file mode 100644 index 0000000..f0093d3 --- /dev/null +++ b/src/Kalman/Security/SymmetricCryto.cs @@ -0,0 +1,369 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Security.Cryptography; +using System.IO; +using Kalman.Utilities; + +// Kalman Create by 2010-03-09 +namespace Kalman.Security +{ + /// + /// 对称加密算法 + /// + public class SymmetricCryto + { + // 随机字符串,长度为32,由于密钥最大长度为256,若用户输入的密钥长度不够,用该字符串来补足 + const string _RandomKey = "#a,7.~_*j8'/m[%}?@d2!9ge)^; + /// 创建一个对称加密算法提供者实例 + /// + /// + /// + SymmetricAlgorithm CreateSymmetricAlgorithmProvider(SymmetricAlgorithmType symmetricAlgorithmType) + { + SymmetricAlgorithm symmetricAlgorithm = null; + switch (symmetricAlgorithmType) + { + case SymmetricAlgorithmType.DES: + //,key[64,64],block[64,64] ; IV[8byte],KEY[8byte] + symmetricAlgorithm = new DESCryptoServiceProvider(); + multiKey = 8; + multiIV = 8; + break; + case SymmetricAlgorithmType.RC2_40: + //,key[40,128],block[64,64] ; IV[8byte],KEY[16byte] + symmetricAlgorithm = new RC2CryptoServiceProvider(); + multiKey = 5; + multiIV = 8; + break; + case SymmetricAlgorithmType.RC2_64: + //,key[40,128],block[64,64] ; IV[8byte],KEY[16byte] + symmetricAlgorithm = new RC2CryptoServiceProvider(); + multiKey = 8; + multiIV = 8; + break; + case SymmetricAlgorithmType.RC2_96: + //,key[40,128],block[64,64] ; IV[8byte],KEY[16byte] + symmetricAlgorithm = new RC2CryptoServiceProvider(); + multiKey = 12; + multiIV = 8; + break; + case SymmetricAlgorithmType.RC2_128: + //,key[40,128],block[64,64] ; IV[8byte],KEY[16byte] + symmetricAlgorithm = new RC2CryptoServiceProvider(); + multiKey = 16; + multiIV = 8; + break; + case SymmetricAlgorithmType.Rijndael_128: + //,key[128,256],block[128,256] ; IV[16byte],KEY[32byte] + symmetricAlgorithm = new RijndaelManaged(); + multiKey = 16; + multiIV = 16; + break; + case SymmetricAlgorithmType.Rijndael_192: + //,key[128,256],block[128,256] ; IV[16byte],KEY[32byte] + symmetricAlgorithm = new RijndaelManaged(); + multiKey = 24; + multiIV = 16; + break; + case SymmetricAlgorithmType.Rijndael_256: + //,key[128,256],block[128,256] ; IV[16byte],KEY[32byte] + symmetricAlgorithm = new RijndaelManaged(); + multiKey = 32; + multiIV = 16; + break; + case SymmetricAlgorithmType.TripleDES_128: + //,key[128,192],block[64,64] ; IV[8byte],KEY[24byte] + symmetricAlgorithm = new TripleDESCryptoServiceProvider(); + multiKey = 16; + multiIV = 8; + break; + case SymmetricAlgorithmType.TripleDES_192: + //,key[128,192],block[64,64] ; IV[8byte],KEY[24byte] + symmetricAlgorithm = new TripleDESCryptoServiceProvider(); + multiKey = 24; + multiIV = 8; + break; + default: + break; + } + + symmetricAlgorithm.KeySize = factorKey * multiKey; + symmetricAlgorithm.BlockSize = factorIV * multiIV; + + return symmetricAlgorithm; + } + + /// + /// 生成合法的密钥 + /// + byte[] GetLegalKey() + { + string tmp = this._Key; + + if (tmp.Length < multiKey) + { + tmp += _RandomKey.Substring(0, multiKey - tmp.Length); + } + else if (tmp.Length > multiKey) + { + tmp = tmp.Substring(0, multiKey); + } + + return ASCIIEncoding.ASCII.GetBytes(tmp); + } + + /// + /// 生成合法的初始化向量 + /// + byte[] GetLegalIV() + { + string tmp = this._IV; + + if (tmp.Length < multiIV) + { + tmp += _RandomIV.Substring(0, multiIV - tmp.Length); + } + else if (tmp.Length > multiIV) + { + tmp = tmp.Substring(0, multiIV); + } + + return ASCIIEncoding.ASCII.GetBytes(tmp); + } + + #endregion + + #region 加密方法 + /// + /// 加密为字符串 + /// + /// + /// + public string EncryptString(string s) + { + CheckUtil.ArgumentNotNullOrEmpty(s, "s"); + + byte[] inputData = Encoding.UTF8.GetBytes(s); + byte[] outputData = null; + + using (MemoryStream ms = new System.IO.MemoryStream()) + { + symmetricAlgorithmProvider.Key = GetLegalKey(); + symmetricAlgorithmProvider.IV = GetLegalIV(); + + ICryptoTransform cryptoTransform = symmetricAlgorithmProvider.CreateEncryptor(); + + using (CryptoStream cs = new CryptoStream(ms, cryptoTransform, CryptoStreamMode.Write)) + { + cs.Write(inputData, 0, inputData.Length); + cs.FlushFinalBlock(); + + outputData = ms.ToArray(); + } + } + + return Convert.ToBase64String(outputData, 0, outputData.Length); + } + + /// + /// 加密为数据 + /// + /// + /// + public byte[] EncryptData(string s) + { + CheckUtil.ArgumentNotNullOrEmpty(s, "s"); + + byte[] inputData = Encoding.UTF8.GetBytes(s); + byte[] outputData = null; + + using (MemoryStream ms = new System.IO.MemoryStream()) + { + symmetricAlgorithmProvider.Key = GetLegalKey(); + symmetricAlgorithmProvider.IV = GetLegalIV(); + + ICryptoTransform cryptoTransform = symmetricAlgorithmProvider.CreateEncryptor(); + + using (CryptoStream cs = new CryptoStream(ms, cryptoTransform, CryptoStreamMode.Write)) + { + cs.Write(inputData, 0, inputData.Length); + cs.FlushFinalBlock(); + + outputData = ms.ToArray(); + } + } + + return outputData; + } + + /// + /// 加密为数据 + /// + /// + /// + public byte[] EncryptData(byte[] inputData) + { + CheckUtil.ArgumentNotNull(inputData, "inputData"); + + byte[] outputData = null; + + using (MemoryStream ms = new System.IO.MemoryStream()) + { + symmetricAlgorithmProvider.Key = GetLegalKey(); + symmetricAlgorithmProvider.IV = GetLegalIV(); + + ICryptoTransform cryptoTransform = symmetricAlgorithmProvider.CreateEncryptor(); + + using (CryptoStream cs = new CryptoStream(ms, cryptoTransform, CryptoStreamMode.Write)) + { + cs.Write(inputData, 0, inputData.Length); + cs.FlushFinalBlock(); + + outputData = ms.ToArray(); + } + } + + return outputData; + } + + /// + /// 加密为字符串 + /// + /// + /// + public string EncryptString(byte[] inputData) + { + CheckUtil.ArgumentNotNull(inputData, "inputData"); + + byte[] outputData = null; + + using (MemoryStream ms = new System.IO.MemoryStream()) + { + symmetricAlgorithmProvider.Key = GetLegalKey(); + symmetricAlgorithmProvider.IV = GetLegalIV(); + + ICryptoTransform cryptoTransform = symmetricAlgorithmProvider.CreateEncryptor(); + + using (CryptoStream cs = new CryptoStream(ms, cryptoTransform, CryptoStreamMode.Write)) + { + cs.Write(inputData, 0, inputData.Length); + cs.FlushFinalBlock(); + + outputData = ms.ToArray(); + } + } + + return Convert.ToBase64String(outputData, 0, outputData.Length); + } + + #endregion + + #region 解密方法 + + /// + /// 解密为字符串 + /// + /// + /// + public string DecryptString(string s) + { + CheckUtil.ArgumentNotNullOrEmpty(s, "s"); + + byte[] inputData = Convert.FromBase64String(s); + string result = string.Empty; + + using (MemoryStream ms = new System.IO.MemoryStream(inputData)) + { + symmetricAlgorithmProvider.Key = GetLegalKey(); + symmetricAlgorithmProvider.IV = GetLegalIV(); + + ICryptoTransform encrypto = symmetricAlgorithmProvider.CreateDecryptor(); + + CryptoStream cs = new CryptoStream(ms, encrypto, CryptoStreamMode.Read); + StreamReader sr = new StreamReader(cs); + result = sr.ReadLine(); + + //CryptoStream cs = new CryptoStream(ms, encrypto, CryptoStreamMode.Read); + //byte[] outputData = new byte[inputData.Length]; + //cs.Read(outputData, 0, outputData.Length); + + //result = Encoding.UTF8.GetString(outputData).TrimEnd(new char[] { '\0' }); + + cs.Clear(); + cs.Close(); + } + + return result; + } + + /// + /// 解密为数据 + /// + /// + /// + public byte[] DecryptData(string s) + { + CheckUtil.ArgumentNotNullOrEmpty(s, "s"); + + byte[] inputData = Convert.FromBase64String(s); + byte[] outputData = null; + + using (MemoryStream ms = new System.IO.MemoryStream(inputData)) + { + symmetricAlgorithmProvider.Key = GetLegalKey(); + symmetricAlgorithmProvider.IV = GetLegalIV(); + + ICryptoTransform encrypto = symmetricAlgorithmProvider.CreateDecryptor(); + + CryptoStream cs = new CryptoStream(ms, encrypto, CryptoStreamMode.Read); + outputData = new byte[inputData.Length]; + cs.Read(outputData, 0, outputData.Length); + + cs.Clear(); + cs.Close(); + } + + return outputData; + } + + #endregion + } +} diff --git a/src/Kalman/ServiceModel/ErrorInfo.cs b/src/Kalman/ServiceModel/ErrorInfo.cs new file mode 100644 index 0000000..f519901 --- /dev/null +++ b/src/Kalman/ServiceModel/ErrorInfo.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Runtime.Serialization; + +namespace Kalman.ServiceModel +{ + /// + /// 错误信息 + /// + [Serializable] + public class ErrorInfo + { + /// + /// 错误代码 + /// + [DataMember] + public int Code { get; set; } + + /// + /// 错误原因 + /// + [DataMember] + public string Reason { get; set; } + + /// + /// 发生异常的类型名称,如FC.xxxService + /// + [DataMember] + public string TypeName { get; set; } + + /// + /// 发生异常的方法名称 + /// + [DataMember] + public string MethodName { get; set; } + } +} diff --git a/src/Kalman/ServiceModel/IWcfServiceBase.cs b/src/Kalman/ServiceModel/IWcfServiceBase.cs new file mode 100644 index 0000000..114e5e6 --- /dev/null +++ b/src/Kalman/ServiceModel/IWcfServiceBase.cs @@ -0,0 +1,19 @@ +using System; +using System.ServiceModel; + +namespace Kalman.ServiceModel +{ + /// + /// WCF服务基础接口 + /// + [ServiceContract] + public interface IWcfServiceBase + { + /// + /// 校验服务器是否在线 + /// + [Obsolete("改用专门的监控服务来检查服务状态")] + [OperationContract] + void CheckIsOnline(); + } +} diff --git a/src/Kalman/ServiceModel/ServiceHostManager.cs b/src/Kalman/ServiceModel/ServiceHostManager.cs new file mode 100644 index 0000000..05d68b8 --- /dev/null +++ b/src/Kalman/ServiceModel/ServiceHostManager.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.ServiceModel; +using System.Xml.Serialization; + +namespace Kalman.ServiceModel +{ + /// + /// WCF服务宿主管理类 + /// + public sealed class ServiceHostManager + { + public static readonly ServiceHostManager Instance = new ServiceHostManager(); + + List _HostList; + + private ServiceHostManager() + { + _HostList = new List(); + } + + /// + /// 发布WCF服务组件 + /// + /// + public void Open(Type type) + { + ServiceHost host = new ServiceHost(type); + host.Open(); + _HostList.Add(host); + } + + public void Dispose() + { + foreach (ServiceHost host in _HostList) + { + try + { + if (host.State == CommunicationState.Opened) + host.Close(); + } + catch + { + host.Abort(); + } + } + } + } +} diff --git a/src/Kalman/ServiceModel/ServiceUriManage/ServiceUri.cs b/src/Kalman/ServiceModel/ServiceUriManage/ServiceUri.cs new file mode 100644 index 0000000..1c10476 --- /dev/null +++ b/src/Kalman/ServiceModel/ServiceUriManage/ServiceUri.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Kalman.ServiceModel +{ + class ServiceUri + { + } +} diff --git a/src/Kalman/ServiceModel/ServiceUriManage/ServiceUriManager.cs b/src/Kalman/ServiceModel/ServiceUriManage/ServiceUriManager.cs new file mode 100644 index 0000000..5fc24cd --- /dev/null +++ b/src/Kalman/ServiceModel/ServiceUriManage/ServiceUriManager.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; + +namespace Kalman.ServiceModel +{ + public sealed class ServiceUriManager + { + public static readonly ServiceUriManager Instance = new ServiceUriManager(); + private ServiceUriManager() + { + } + + Dictionary dic = new Dictionary(); + object syncLock = new object(); + + /// + /// 获取服务URL + /// + /// 客户端名称,每种WCF数据服务都需要在调用方配置对应的客户端(命名规范:服务顶层命名空间加Client后缀,如:xxx.Client) + /// + /// + public string GetServiceUrl(string clientName, string serviceName) + { + ///todo:容灾及负载均衡的具体实现 + return "net.tcp://127.0.0.1:6666/" + serviceName; + } + + + public void AddUriMapping(string serviceName, string uri) + { + lock (syncLock) + { + dic.Add(serviceName, uri); + } + } + + public void AddUriMapping(string[] serviceNames, string uri) + { + foreach (string serviceName in serviceNames) + { + AddUriMapping(serviceName, uri); + } + } + } +} diff --git a/src/Kalman/ServiceModel/WcfClientProxy.cs b/src/Kalman/ServiceModel/WcfClientProxy.cs new file mode 100644 index 0000000..3d40a44 --- /dev/null +++ b/src/Kalman/ServiceModel/WcfClientProxy.cs @@ -0,0 +1,134 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.ServiceModel; +using System.Threading; +using System.ServiceModel.Channels; + +namespace Kalman.ServiceModel +{ + /// + /// WCF客户端代理类 + /// + public static class WcfClientProxy + { + /// + /// 创建一个客户端代理,不需要配置,默认使用NetTcpBinding + /// + /// 服务契约接口类型 + /// 服务地址 + /// + public static I Create(string uri) + { + NetTcpBinding binding = new NetTcpBinding(); + EndpointAddress ea = new EndpointAddress(new Uri(uri)); + return new ChannelFactory(binding, ea).CreateChannel(); + } + + /// + /// 创建一个客户端代理,不需要配置,默认使用NetTcpBinding + /// + /// 服务契约接口类型 + /// 端点地址 + /// + public static I Create(EndpointAddress ea) + { + NetTcpBinding binding = new NetTcpBinding(); + return new ChannelFactory(binding, ea).CreateChannel(); + } + + /// + /// 创建一个客户端代理,不需要配置 + /// + /// 服务契约接口类型 + /// 服务地址 + /// 通道绑定类型(BasicHttpBinding|NetTcpBinding|CustomBinding|NetNamedPipeBinding|NetPeerTcpBinding|WebHttpBinding|WSDualHttpBinding) + /// + public static I Create(Binding binding, string uri) + { + EndpointAddress ea = new EndpointAddress(new Uri(uri)); + return new ChannelFactory(binding, ea).CreateChannel(); + } + + /// + /// 创建一个客户端代理,不需要配置 + /// + /// 服务契约接口类型 + /// 通道绑定类型(BasicHttpBinding|NetTcpBinding|CustomBinding|NetNamedPipeBinding|NetPeerTcpBinding|WebHttpBinding|WSDualHttpBinding) + /// 端点地址 + /// + public static I Create(Binding binding, EndpointAddress ea) + { + return new ChannelFactory(binding, ea).CreateChannel(); + } + + /// + /// 创建一个客户端代理,需配置端点并指定名称 + /// + /// 服务契约接口类型 + /// 端点名称 + /// + public static I CreateByConfig(string endPointConfigurationName) + { + return new ChannelFactory(endPointConfigurationName).CreateChannel(); + } + + /// + /// 创建一个客户端代理,需配置端点并指定名称 + /// + /// 服务契约接口类型 + /// 服务地址 + /// 端点名称 + /// + public static I CreateByConfig(string uri, string endPointConfigurationName) + { + EndpointAddress ea = new EndpointAddress(new Uri(uri)); + return new ChannelFactory(endPointConfigurationName, ea).CreateChannel(); + } + + /// + /// 创建一个自托管实例,主要用于测试 + /// + /// 服务契约接口类型 + /// 服务契约的实现类型 + /// 返回客户端代理实例 + public static I CreateSelfHost() + { + WcfSelfHost host = new WcfSelfHost(); + return host.Client; + } + + /// + /// 关闭通道连接并释放资源 + /// + /// WcfClientProxy.CloseAndDispose((IClientChannel)_IService); + /// 代理实例 + public static void CloseAndDispose(IClientChannel serviceProxy) + { + if (serviceProxy == null) return; + + try + { + if (serviceProxy.State == CommunicationState.Opened) + { + serviceProxy.Close(); + } + serviceProxy.Dispose(); + } + catch (CommunicationException) { serviceProxy.Abort(); } + catch (TimeoutException) { serviceProxy.Abort(); } + catch (Exception) + { + serviceProxy.Abort(); + //throw; + ///todo:未知异常,暂不抛出,考虑记录日志 + } + finally + { + serviceProxy = null; + } + } + + } +} diff --git a/src/Kalman/ServiceModel/WcfErrorHandler.cs b/src/Kalman/ServiceModel/WcfErrorHandler.cs new file mode 100644 index 0000000..78d47c4 --- /dev/null +++ b/src/Kalman/ServiceModel/WcfErrorHandler.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.ServiceModel.Dispatcher; +using System.ServiceModel; +using System.ServiceModel.Channels; + +namespace Kalman.ServiceModel +{ + /// + /// 自定义错误处理器 + /// + public class WcfErrorHandler : IErrorHandler + { + #region IErrorHandler 成员 + + /// + /// 启用错误相关处理并返回一个值,该值指示调度程序在某些情况下是否中止会话和实例上下文 + /// + /// 处理过程中引发的异常 + /// + /// 如果WCF不应中止会话(如果有一个)和实例上下文(如果实例上下文不是 System.ServiceModel.InstanceContextMode.Single),则为true;否则为 false。默认值为 false。 + /// + public bool HandleError(Exception error) + { + ///todo: if(error is FaultException) + //在异常返回给客户端之后被调用,在这里记录异常日志 + // System.IO.File.AppendAllText(@"C:\WCF_Log.txt",error.ToString() + "\r\n"); + Console.WriteLine(error.ToString()); + + //异常已处理,不终止会话或实例上下文 + return true; + } + + /// + /// 启用创建从服务方法过程中的异常返回的自定义 System.ServiceModel.FaultException。 + /// + /// 服务操作过程中引发的 System.Exception 对象。 + /// 消息的 SOAP 版本 + /// 双工情况下,返回到客户端或服务的 System.ServiceModel.Channels.Message 对象。 + public void ProvideFault(Exception error, MessageVersion version, ref Message fault) + { + //在异常发生后,异常信息返回前被调用,这里一般不做处理 + //将托管异常System.Exception转换为System.ServiceModel.FaultException + //FaultException ex = new FaultException("这条消息将返回至调用方"); + //MessageFault mf = ex.CreateMessageFault(); + //fault = System.ServiceModel.Channels.Message.CreateMessage(version, mf, ex.Action); + + //WCF服务层统一抛出FaultException类型的异常,对于未处理异常则将其包装成FaultException类型的异常,以免造成信道异常 + if (error is FaultException) return; + FaultException ex = new FaultException(error.Message); + MessageFault mf = ex.CreateMessageFault(); + fault = System.ServiceModel.Channels.Message.CreateMessage(version, mf, ex.Action); + } + + #endregion + } +} diff --git a/src/Kalman/ServiceModel/WcfSelfHost.cs b/src/Kalman/ServiceModel/WcfSelfHost.cs new file mode 100644 index 0000000..6a8bd4e --- /dev/null +++ b/src/Kalman/ServiceModel/WcfSelfHost.cs @@ -0,0 +1,163 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.ServiceModel; +using System.ServiceModel.Description; +using System.Threading; +namespace Kalman.ServiceModel +{ + /// + /// 一个简单的WCF自托管组件,可以方便的在单元测试和控制台程序中使用,不需要配置也不需要代理类 + /// + /// 契约对应的实现类型 + /// 契约接口类型 + public class WcfSelfHost : IDisposable + { + /// + /// {protocol}//{host}:{port} + /// + private const string _ENDPOINTURL = "{protocol}//{host}:{port}"; + ReaderWriterLockSlim _portLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion); + private const ushort _BASEPORT = 30000; + /// + /// string == address + /// + private static Dictionary _portMap = new Dictionary(); + ServiceEndpoint _ep; + ServiceHost _host = null; + + /// + /// + /// + public WcfSelfHost() + { + EndpointAddress ea = buildEndPoint(); + + _host = new ServiceHost(typeof(T), new Uri[] { ea.Uri }); + _ep = _host.AddServiceEndpoint(typeof(I), new NetTcpBinding(), ea.Uri); + CommunicationState state = _host.State; + _host.Open(); + } + + + private EndpointAddress buildEndPoint() + { + string subAddress = typeof(T).Name; + string addressKey = typeof(T).FullName; + ushort hostPort = 0; + try + { + _portLock.EnterUpgradeableReadLock(); + + if (_portMap.ContainsKey(addressKey) == true) + { + hostPort = (ushort)((ushort)_portMap[addressKey] + (ushort)_BASEPORT); + } + else + { + try + { + _portLock.EnterWriteLock(); + _portMap[addressKey] = (ushort)(_BASEPORT + _portMap.Count); + hostPort = _portMap[addressKey]; + } + finally + { + _portLock.ExitWriteLock(); + } + } + } + finally + { + _portLock.ExitUpgradeableReadLock(); + } + + string endPoint = _ENDPOINTURL; + string protocol = "net.tcp:"; + string host = "localhost/"+subAddress; + string port = hostPort.ToString(); + + endPoint = endPoint.Replace("{protocol}", protocol).Replace("{host}", host).Replace("{port}", port); + return new EndpointAddress(endPoint); + + } + + #region IDisposable Members + + /// + /// 释放服务宿主资源 + /// + /// 如果为True则调用Dispose + public void Dispose(bool isDisposing) + { + if (isDisposing == true) + { + if (_host != null) + { + try + { + switch (_host.State) + { + case CommunicationState.Created: + break; + case CommunicationState.Opening: + _host.Close(new TimeSpan(0, 0, 0, 0, 500)); + break; + case CommunicationState.Opened: + _host.Close(new TimeSpan(0,0,0,0,500)); + break; + case CommunicationState.Faulted: + break; + + } + } + catch + { + _host.Abort(); + } + + _host = null; + } + } + GC.SuppressFinalize(this); + } + + /// + /// + public void Dispose() + { + Dispose(true); + } + + /// + /// Destructor + /// + ~WcfSelfHost() + { + Dispose(false); + } + private I _client; + private bool _isClientSet = false; + + /// + /// 获取服务的客户端代理实例 + /// + public I Client + { + get + { + if (_isClientSet == false) + { + ChannelFactory factory = new ChannelFactory(_ep.Binding, _ep.Address); + _client = factory.CreateChannel(); + _isClientSet = true; + } + + return _client; + } + } + + #endregion + } +} diff --git a/src/Kalman/ServiceModel/WcfServiceBase.cs b/src/Kalman/ServiceModel/WcfServiceBase.cs new file mode 100644 index 0000000..9ed1a9a --- /dev/null +++ b/src/Kalman/ServiceModel/WcfServiceBase.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.ServiceModel.Description; +using System.ServiceModel; +using System.Collections.ObjectModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Dispatcher; + +namespace Kalman.ServiceModel +{ + /// + /// WCF服务对象基类 + /// + public abstract class WcfServiceBase : IServiceBehavior, IWcfServiceBase + { + /// + /// 校验服务器是否在线 + /// + public virtual void CheckIsOnline() + { } + + #region IServiceBehavior 成员 + + /// + /// 用于向绑定元素传递自定义数据,以支持协定实现。 + /// + /// 服务的服务说明 + /// 服务的宿主 + /// 服务终结点 + /// 绑定元素可访问的自定义对象 + public virtual void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection endpoints, BindingParameterCollection bindingParameters) + { + } + + /// + /// 用于更改运行时属性值或插入自定义扩展对象(例如错误处理程序、消息或参数拦截器、安全扩展以及其他自定义扩展对象)。 + /// + /// 服务说明 + /// 当前正在生成的宿主 + public virtual void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) + { + IErrorHandler handler = new WcfErrorHandler(); + + foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers) + { + // 增加错误处理器 + dispatcher.ErrorHandlers.Add(handler); + } + } + + /// + /// 用于检查服务宿主和服务说明,从而确定服务是否可成功运行。 + /// + /// 服务说明 + /// 当前正在构建的服务宿主 + public virtual void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) + { + } + + #endregion + } +} diff --git a/src/Kalman/ServiceModel/help.txt b/src/Kalman/ServiceModel/help.txt new file mode 100644 index 0000000..142d36d --- /dev/null +++ b/src/Kalman/ServiceModel/help.txt @@ -0,0 +1,25 @@ +完整配置示例 + + + + +
+ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Kalman/TimeConst.cs b/src/Kalman/TimeConst.cs new file mode 100644 index 0000000..e893fe4 --- /dev/null +++ b/src/Kalman/TimeConst.cs @@ -0,0 +1,183 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Kalman +{ + /// + /// 时间常量(基础单位:毫秒),可以作为线程等待时间 + /// + public static class TimeConst + { + /// + /// 1毫秒 + /// + public static readonly int MS1 = 1; + + /// + /// 10毫秒 + /// + public static readonly int MS10 = 10; + + /// + /// 100毫秒 + /// + public static readonly int MS100 = 100; + + /// + /// 200毫秒 + /// + public static readonly int MS200 = 200; + + /// + /// 300毫秒 + /// + public static readonly int MS300 = 300; + + /// + /// 500毫秒 + /// + public static readonly int MS500 = 500; + + /// + /// 1秒(=1000毫秒) + /// + public static readonly int S1 = 1000; + + /// + /// 2秒(=2000毫秒) + /// + public static readonly int S2 = 2000; + + /// + /// 3秒(=3000毫秒) + /// + public static readonly int S3 = 3000; + + /// + /// 5秒(=5000毫秒) + /// + public static readonly int S5 = 5000; + + /// + /// 10秒(=10000毫秒) + /// + public static readonly int S10 = 10000; + + /// + /// 20秒(=20000毫秒) + /// + public static readonly int S20 = 20000; + + /// + /// 30秒(=30000毫秒) + /// + public static readonly int S30 = 30000; + + /// + /// 1分钟(=60000毫秒) + /// + public static readonly int M1 = 60000; + + /// + /// 2分钟(=120000毫秒) + /// + public static readonly int M2 = 120000; + + /// + /// 3分钟(=180000毫秒) + /// + public static readonly int M3 = 180000; + + /// + /// 5分钟(=300000毫秒) + /// + public static readonly int M5 = 300000; + + /// + /// 10分钟(=600000毫秒) + /// + public static readonly int M10 = 600000; + + /// + /// 20分钟(=1200000毫秒) + /// + public static readonly int M20 = 1200000; + + /// + /// 30分钟(=1800000毫秒) + /// + public static readonly int M30 = 1800000; + + /// + /// 1小时(=3600000毫秒) + /// + public static readonly int H1 = 3600000; + + /// + /// 2小时(=7200000毫秒) + /// + public static readonly int H2 = 7200000; + + /// + /// 3小时(=10800000毫秒) + /// + public static readonly int H3 = 10800000; + + /// + /// 5小时(=18000000毫秒) + /// + public static readonly int H5 = 18000000; + + /// + /// 10小时(=36000000毫秒) + /// + public static readonly int H10 = 36000000; + + /// + /// 1天(=86400000毫秒) + /// + public static readonly int D1 = 86400000; + + /// + /// 计算指定秒数对应的毫秒数 + /// + /// + /// + public static int Second2MS(int s) + { + return s * S1; + } + + /// + /// 计算指定分钟数对应的毫秒数 + /// + /// + /// + public static int Minute2MS(int m) + { + return m * M1; + } + + /// + /// 计算指定小时数对应的毫秒数 + /// + /// + /// + public static int Hour2MS(int h) + { + return h * H1; + } + + /// + /// 计算指定天数对应的毫秒数 + /// + /// + /// + public static int Day2MS(int d) + { + return d * D1; + } + } +} diff --git a/src/Kalman/Utilities/ByteUtil.cs b/src/Kalman/Utilities/ByteUtil.cs new file mode 100644 index 0000000..f3591be --- /dev/null +++ b/src/Kalman/Utilities/ByteUtil.cs @@ -0,0 +1,117 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.IO; +using System.Security.Cryptography; +using Kalman.Security; + +namespace Kalman.Utilities +{ + public static class ByteUtil + { + /// + /// 转十六进制 + /// + /// + /// + public static string ToHex(byte b) + { + return b.ToString("X2"); + } + + /// + /// 转十六进制 + /// + public static string ToHex(IEnumerable bytes) + { + var sb = new StringBuilder(); + foreach (byte b in bytes) + sb.Append(b.ToString("X2")); + return sb.ToString(); + } + + /// + /// 将 8 位无符号整数数组转换为它的等效 System.String 表示形式(使用 Base 64 数字编码) + /// + public static string ToBase64String(byte[] data) + { + return Convert.ToBase64String(data); + } + + /// + /// 返回由字节数组中指定位置的八个字节转换来的 32 位有符号整数 + /// + /// + /// + /// + public static int ToInt(byte[] data, int startIndex) + { + return BitConverter.ToInt32(data, startIndex); + } + + /// + /// 返回由字节数组中指定位置的八个字节转换来的 64 位有符号整数 + /// + /// + /// + /// + public static long ToInt64(byte[] data, int startIndex) + { + return BitConverter.ToInt64(data, startIndex); + } + + /// + /// 转换为指定编码字符串 + /// + /// + /// + /// + public static string Decode(byte[] data, Encoding encoding) + { + return encoding.GetString(data); + } + + /// + /// 保存到文件 + /// + /// + /// + public static void Save(byte[] data, string path) + { + File.WriteAllBytes(path, data); + } + + /// + /// 保存到内存流 + /// + /// + /// + public static MemoryStream ToMemoryStream(byte[] data) + { + return new MemoryStream(data); + } + + /// + /// 使用指定哈希算法计算哈希值 + /// + /// + /// + /// + public static byte[] ComputeHash(byte[] data, HashAlgorithmType hashAlgorithmType) + { + HashAlgorithm algorithm = HashAlgorithm.Create(hashAlgorithmType.ToString()); + return algorithm.ComputeHash(data); + } + + /// + /// 使用默认Hash算法SHA1计算哈希值 + /// + /// + /// + public static byte[] ComputeHash(byte[] data) + { + return ComputeHash(data, HashAlgorithmType.SHA1); + } + } +} diff --git a/src/Kalman/Utilities/CheckUtil.cs b/src/Kalman/Utilities/CheckUtil.cs new file mode 100644 index 0000000..9575530 --- /dev/null +++ b/src/Kalman/Utilities/CheckUtil.cs @@ -0,0 +1,131 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Text; +using System.Collections; + +using Kalman.Extensions; + +namespace Kalman.Utilities +{ + /// + /// 方法参数检查工具类 + /// + public static class CheckUtil + { + #region 检查对象类型参数 + + /// + /// 检查参数不为空 + /// + /// 待检查的参数值 + /// 参数名称 + public static void ArgumentNotNull(object value, string parameterName) + { + if (value == null) + throw new ArgumentNullException(parameterName); + } + + #endregion + + #region 检查字符串类型参数 + + /// + /// 检查一个参数不为Null或者空 + /// + /// 待检查的参数值 + /// 参数名称 + public static void ArgumentNotNullOrEmpty(string value, string parameterName) + { + if (value == null) + throw new ArgumentNullException(parameterName); + + if (value.Length == 0) + throw new ArgumentException(string.Format(Resources.Common.ArgumentNotEmpty, parameterName), parameterName); + } + + /// + /// 检查一个参数不为null或空或空白 + /// + /// 待检查的参数值 + /// 参数名称 + public static void ArgumentNotNullOrEmptyOrWhitespace(string value, string parameterName) + { + ArgumentNotNullOrEmpty(value, parameterName); + + if (value.IsWhiteSpace()) + throw new ArgumentException(string.Format(Resources.Common.ArgumentNotWhitespace, parameterName), parameterName); + } + + #endregion + + #region 检查集合类型参数 + + /// + /// 检查集合参数不为null或空 + /// + /// + /// 待检查的集合 + /// 参数名称 + public static void ArgumentNotNullOrEmptyForGenericCollection(ICollection collection, string parameterName) + { + ArgumentNotNullOrEmptyForGenericCollection(collection, parameterName, string.Format(Resources.Common.ArgumentNotEmpty, parameterName)); + } + + /// + /// 检查集合参数不为null或空 + /// + /// + /// 待检查的集合 + /// 参数名称 + /// 指定的错误消息 + public static void ArgumentNotNullOrEmptyForGenericCollection(ICollection collection, string parameterName, string errorMessage) + { + if (collection == null) + throw new ArgumentNullException(parameterName); + + if (collection.Count == 0) + throw new ArgumentException(errorMessage, parameterName); + } + + /// + /// 检查集合参数不为null或空 + /// + /// 待检查的集合 + /// 参数名称 + public static void ArgumentNotNullOrEmptyForCollection(ICollection collection, string parameterName) + { + ArgumentNotNullOrEmptyForCollection(collection, parameterName, string.Format(Resources.Common.ArgumentNotEmpty, parameterName)); + } + + /// + /// 检查集合参数不为null或空 + /// + /// 待检查的集合 + /// 参数名称 + /// 指定的错误消息 + public static void ArgumentNotNullOrEmptyForCollection(ICollection collection, string parameterName, string errorMessage) + { + if (collection == null) + throw new ArgumentNullException(parameterName); + + if (collection.Count == 0) + throw new ArgumentException(errorMessage, parameterName); + } + + #endregion + + /// + /// 检查指定类型的参数是一个枚举类型 + /// + /// The type argument. + /// Name of the parameter. + public static void ArgumentTypeIsEnum(Type type, string parameterName) + { + ArgumentNotNull(type, "type"); + + if (!type.IsEnum) + throw new ArgumentException(string.Format("Type {0} is not an Enum.", type), parameterName); + } + } +} diff --git a/src/Kalman/Utilities/CollectionUtil.cs b/src/Kalman/Utilities/CollectionUtil.cs new file mode 100644 index 0000000..1026f99 --- /dev/null +++ b/src/Kalman/Utilities/CollectionUtil.cs @@ -0,0 +1,109 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Collections; +using System.Collections.Specialized; + +namespace Kalman.Utilities +{ + /// + /// 集合工具类 + /// + public static class CollectionUtil + { + /// + /// 将集合对象转换为指定字符分隔的字符串 + /// + /// 集合对象 + /// 分隔字符 + /// + public static string Implode(ICollection collection, string separator) + { + if (collection == null || collection.Count == 0) return string.Empty; + if (separator == null) separator = string.Empty; + + StringBuilder sb = new StringBuilder(); + foreach (object item in collection) + { + sb.Append(item.ToString() + separator); + } + + string result = sb.ToString().TrimEnd(separator.ToCharArray()); + return result; + } + + /// + /// 将NameValueCollection集合转换成字符串 + /// + /// NameValueCollection集合对象 + /// + public static string FormatToString(NameValueCollection nvc) + { + return FormatToString(nvc, "{0}={1}", "&"); + } + + /// + /// 将NameValueCollection集合转换成字符串 + /// + /// 集合对象 + /// 转换格式,如:"{0}={1}",{0}表示Name,{1}表示Value + /// 分隔符,如:& + /// + public static string FormatToString(NameValueCollection nvc, string format, string separator) + { + StringBuilder sb = new StringBuilder(); + + foreach (string key in nvc.Keys) + { + sb.AppendFormat(format, key, nvc[key]); + sb.Append(separator); + } + + string s = sb.ToString().TrimEnd(separator.ToCharArray()); + return s; + } + + /// + /// 将IDictionary集合转换成字符串 + /// + /// 集合对象 + /// 转换格式,如:"{0}={1}",{0}表示Key,{1}表示Value + /// 分隔符,如:& + /// + public static string FormatToString(IDictionary dic, string format, string separator) + { + StringBuilder sb = new StringBuilder(); + + foreach (DictionaryEntry item in dic) + { + sb.AppendFormat(format, item.Key, item.Value); + sb.Append(separator); + } + + string s = sb.ToString().TrimEnd(separator.ToCharArray()); + return s; + } + + /// + /// 将IDictionary泛型集合转换成字符串 + /// + /// 泛型集合对象 + /// 转换格式,如:"{0}={1}",{0}表示Key,{1}表示Value + /// 分隔符,如:& + /// + public static string FormatToString(IDictionary dic, string format, string separator) + { + StringBuilder sb = new StringBuilder(); + + foreach (KeyValuePair item in dic) + { + sb.AppendFormat(format, item.Key, item.Value); + sb.Append(separator); + } + + string s = sb.ToString().TrimEnd(separator.ToCharArray()); + return s; + } + } +} diff --git a/src/Kalman/Utilities/ConnectionStringUtil.cs b/src/Kalman/Utilities/ConnectionStringUtil.cs new file mode 100644 index 0000000..e76d913 --- /dev/null +++ b/src/Kalman/Utilities/ConnectionStringUtil.cs @@ -0,0 +1,136 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Linq; +using System.Text; + +namespace Kalman.Utilities +{ + /// + /// 连接字符串管理 + /// + public class ConnectionStringUtil + { + /// + /// Sql Server Provider + /// + public const string MSSQL_PROVIDER_NAME = "System.Data.SqlClient"; + /// + /// My Sql Provider + /// + public const string MYSQL_PROVIDER_NAME = "MySql.Data.MySqlClient"; + /// + /// Sqlite Provider + /// + public const string SQLITE_PROVIDER_NAME = "System.Data.SQLite"; + /// + /// Access Oledb Provider + /// + public const string OLEDB_PROVIDER_NAME = "System.Data.OleDb"; + /// + /// Oracle Provider + /// + public const string ORACLE_PROVIDER_NAME = "Devart.Data.Oracle"; + /// + /// Oracle MS Provider + /// + public const string ORACLE_MS_PROVIDER_NAME = "System.Data.OracleClient"; + + + /// + /// 获取ConnectionStrings + /// + /// + /// + public static string GetConnectionString(string connectionName) + { + try + { + string connectionString = ConfigurationManager.ConnectionStrings[connectionName].ConnectionString; + return connectionString; + } + catch + { + return ""; + } + } + + /// + /// 驱动名称 + /// + /// + /// + public static string GetProviderName(string connectionName) + { + try + { + string providerName = ConfigurationManager.ConnectionStrings[connectionName].ProviderName; + return providerName; + } + catch + { + return ""; + } + } + + /// + /// 更新连接字符串 + /// + /// + /// + /// + public static void UpdateConnectionString(string newName, string newConString, string newProviderName) + { + bool isModified = false; //记录该连接串是否已经存在 + if (ConfigurationManager.ConnectionStrings[newName] != null) + { + isModified = true; + } + //新建一个连接字符串实例 + ConnectionStringSettings mySettings = new ConnectionStringSettings(newName, newConString, newProviderName); + + // 打开可执行的配置文件*.exe.config + Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); + + // 如果连接串已存在,首先删除它 + if (isModified) + { + config.ConnectionStrings.ConnectionStrings.Remove(newName); + // 将新的连接串添加到配置文件中. + config.ConnectionStrings.ConnectionStrings.Add(mySettings); + // 保存对配置文件所作的更改 + config.Save(ConfigurationSaveMode.Modified); + // 强制重新载入配置文件的ConnectionStrings配置节 + ConfigurationManager.RefreshSection("ConnectionStrings"); + } + else + { + config.ConnectionStrings.ConnectionStrings.Add(mySettings); + config.Save(ConfigurationSaveMode.Modified); + ConfigurationManager.RefreshSection("ConnectionStrings"); + } + } + + /// + /// 删除ConnectString + /// + /// + public static void RemoveConnectionString(string name) + { + if (ConfigurationManager.ConnectionStrings[name] == null) + { + return; + } + + // 打开可执行的配置文件*.exe.config + Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); + + // 如果连接串已存在,首先删除它 + config.ConnectionStrings.ConnectionStrings.Remove(name); + // 保存对配置文件所作的更改 + config.Save(ConfigurationSaveMode.Modified); + // 强制重新载入配置文件的ConnectionStrings配置节 + ConfigurationManager.RefreshSection("ConnectionStrings"); + } + } +} diff --git a/src/Kalman/Utilities/ConvertUtil.cs b/src/Kalman/Utilities/ConvertUtil.cs new file mode 100644 index 0000000..6c61557 --- /dev/null +++ b/src/Kalman/Utilities/ConvertUtil.cs @@ -0,0 +1,814 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Data; +using System.Reflection; + +namespace Kalman.Utilities +{ + /// + /// 类型转换工具类 + /// + public sealed class ConvertUtil + { + #region ToByte + /// + /// + /// + /// + /// + /// + public static byte ToByte(object obj, byte defaultValue) + { + if (obj == null) return defaultValue; + return ToByte(obj.ToString(), defaultValue); + } + /// + /// + /// + /// + /// + /// + public static byte ToByte(string s, byte defaultValue) + { + byte b = 0; + if (byte.TryParse(s, out b)) + return b; + else + return defaultValue; + } + #endregion + + #region ToNullableByte + public static byte? ToNullableByte(object obj) + { + if (obj == null) return null; + return ToNullableByte(obj.ToString()); + } + + public static byte? ToNullableByte(string s) + { + byte n = 0; + if (byte.TryParse(s, out n)) + return n; + else + return null; + } + #endregion + + #region ToSByte + /// + /// + /// + /// + /// + /// + public static sbyte ToByte(object obj, sbyte defaultValue) + { + if (obj == null) return defaultValue; + return ToByte(obj.ToString(), defaultValue); + } + /// + /// + /// + /// + /// + /// + public static sbyte ToByte(string s, sbyte defaultValue) + { + sbyte b = 0; + if (sbyte.TryParse(s, out b)) + return b; + else + return defaultValue; + } + #endregion + + #region ToNullableSByte + public static sbyte? ToNullableSByte(object obj) + { + if (obj == null) return null; + return ToNullableSByte(obj.ToString()); + } + + public static sbyte? ToNullableSByte(string s) + { + sbyte n = 0; + if (sbyte.TryParse(s, out n)) + return n; + else + return null; + } + #endregion + + #region ToChar + /// + /// + /// + /// + /// + /// + public static char ToByte(object obj, char defaultValue) + { + if (obj == null) return defaultValue; + return ToByte(obj.ToString(), defaultValue); + } + /// + /// + /// + /// + /// + /// + public static char ToByte(string s, char defaultValue) + { + if (string.IsNullOrEmpty(s)) return defaultValue; + + char c = ' '; + if (char.TryParse(s.Substring(0, 1), out c)) + return c; + else + return defaultValue; + } + #endregion + + #region ToString + /// + /// + /// + /// + /// + /// + public static string ToString(object obj, string defaultValue) + { + if (obj == null) return defaultValue; + return obj.ToString(); + } + + /// + /// + /// + /// + /// + public static string ToString(object obj) + { + return ToString(obj, string.Empty); + } + #endregion + + #region ToInt32 + /// + /// + /// + /// + /// + /// + public static int ToInt32(object obj, int defaultValue) + { + if (obj == null) return defaultValue; + + return ToInt32(obj.ToString(), defaultValue); + } + + /// + /// + /// + /// + /// + /// + public static int ToInt32(string s, int defaultValue) + { + if (string.IsNullOrEmpty(s)) return defaultValue; + if (s.ToLower().Trim() == "true") return 1; + if (s.ToLower().Trim() == "false") return 0; + + int n = 0; + if (int.TryParse(s, out n)) + return n; + else + return defaultValue; + } + #endregion + + #region ToNullableInt32 + public static int? ToNullableInt32(object obj) + { + if(obj == null)return null; + return ToNullableInt32(obj.ToString()); + } + + public static int? ToNullableInt32(string s) + { + if (string.IsNullOrEmpty(s)) return null; + if (s.ToLower().Trim() == "true") return 1; + if (s.ToLower().Trim() == "false") return 0; + + int n = 0; + if (int.TryParse(s, out n)) + return n; + else + return null; + } + #endregion + + #region ToInt16 + /// + /// + /// + /// + /// + /// + public static Int16 ToInt16(object obj, Int16 defaultValue) + { + if (obj == null) return defaultValue; + + return ToInt16(obj.ToString(), defaultValue); + } + + /// + /// + /// + /// + /// + /// + public static Int16 ToInt16(string s, Int16 defaultValue) + { + if (string.IsNullOrEmpty(s)) return defaultValue; + if (s.ToLower().Trim() == "true") return 1; + if (s.ToLower().Trim() == "false") return 0; + + Int16 n = 0; + if (Int16.TryParse(s, out n)) + return n; + else + return defaultValue; + } + #endregion + + #region ToNullableInt16 + public static Int16? ToNullableInt16(object obj) + { + if (obj == null) return null; + return ToNullableInt16(obj.ToString()); + } + + public static Int16? ToNullableInt16(string s) + { + if (string.IsNullOrEmpty(s)) return null; + if (s.ToLower().Trim() == "true") return 1; + if (s.ToLower().Trim() == "false") return 0; + + Int16 n = 0; + if (Int16.TryParse(s, out n)) + return n; + else + return null; + } + #endregion + + #region ToInt64 + /// + /// + /// + /// + /// + /// + public static Int64 ToInt64(object obj, Int64 defaultValue) + { + if (obj == null) return defaultValue; + + return ToInt64(obj.ToString(), defaultValue); + } + + /// + /// + /// + /// + /// + /// + public static Int64 ToInt64(string s, Int64 defaultValue) + { + if (string.IsNullOrEmpty(s)) return defaultValue; + if (s.ToLower().Trim() == "true") return 1; + if (s.ToLower().Trim() == "false") return 0; + + Int64 n = 0; + if (Int64.TryParse(s, out n)) + return n; + else + return defaultValue; + } + #endregion + + #region ToNullableInt64 + public static Int64? ToNullableInt64(object obj) + { + if (obj == null) return null; + return ToNullableInt64(obj.ToString()); + } + + public static Int64? ToNullableInt64(string s) + { + if (string.IsNullOrEmpty(s)) return null; + if (s.ToLower().Trim() == "true") return 1; + if (s.ToLower().Trim() == "false") return 0; + + Int64 n = 0; + if (Int64.TryParse(s, out n)) + return n; + else + return null; + } + #endregion + + #region ToUInt32 + /// + /// + /// + /// + /// + /// + public static UInt32 ToUInt32(object obj, UInt32 defaultValue) + { + if (obj == null) return defaultValue; + + return ToUInt32(obj.ToString(), defaultValue); + } + + /// + /// + /// + /// + /// + /// + public static UInt32 ToUInt32(string s, UInt32 defaultValue) + { + if (string.IsNullOrEmpty(s)) return defaultValue; + if (s.ToLower().Trim() == "true") return 1; + if (s.ToLower().Trim() == "false") return 0; + + UInt32 n = 0; + if (UInt32.TryParse(s, out n)) + return n; + else + return defaultValue; + } + #endregion + + #region ToNullableUInt32 + public static UInt32? ToNullableUInt32(object obj) + { + if (obj == null) return null; + return ToNullableUInt32(obj.ToString()); + } + + public static UInt32? ToNullableUInt32(string s) + { + if (string.IsNullOrEmpty(s)) return null; + if (s.ToLower().Trim() == "true") return 1; + if (s.ToLower().Trim() == "false") return 0; + + UInt32 n = 0; + if (UInt32.TryParse(s, out n)) + return n; + else + return null; + } + #endregion + + #region ToUInt16 + /// + /// + /// + /// + /// + /// + public static UInt16 ToUInt16(object obj, UInt16 defaultValue) + { + if (obj == null) return defaultValue; + + return ToUInt16(obj.ToString(), defaultValue); + } + + /// + /// + /// + /// + /// + /// + public static UInt16 ToUInt16(string s, UInt16 defaultValue) + { + if (string.IsNullOrEmpty(s)) return defaultValue; + if (s.ToLower().Trim() == "true") return 1; + if (s.ToLower().Trim() == "false") return 0; + + UInt16 n = 0; + if (UInt16.TryParse(s, out n)) + return n; + else + return defaultValue; + } + #endregion + + #region ToNullableUInt16 + public static UInt16? ToNullableUInt16(object obj) + { + if (obj == null) return null; + return ToNullableUInt16(obj.ToString()); + } + + public static UInt16? ToNullableUInt16(string s) + { + if (string.IsNullOrEmpty(s)) return null; + if (s.ToLower().Trim() == "true") return 1; + if (s.ToLower().Trim() == "false") return 0; + + UInt16 n = 0; + if (UInt16.TryParse(s, out n)) + return n; + else + return null; + } + #endregion + + #region ToUInt64 + /// + /// + /// + /// + /// + /// + public static UInt64 ToUInt64(object obj, UInt64 defaultValue) + { + if (obj == null) return defaultValue; + + return ToUInt64(obj.ToString(), defaultValue); + } + + /// + /// + /// + /// + /// + /// + public static UInt64 ToUInt64(string s, UInt64 defaultValue) + { + if (string.IsNullOrEmpty(s)) return defaultValue; + if (s.ToLower().Trim() == "true") return 1; + if (s.ToLower().Trim() == "false") return 0; + + UInt64 n = 0; + if (UInt64.TryParse(s, out n)) + return n; + else + return defaultValue; + } + #endregion + + #region ToNullableUInt64 + public static UInt64? ToNullableUInt64(object obj) + { + if (obj == null) return null; + return ToNullableUInt64(obj.ToString()); + } + + public static UInt64? ToNullableUInt64(string s) + { + if (string.IsNullOrEmpty(s)) return null; + if (s.ToLower().Trim() == "true") return 1; + if (s.ToLower().Trim() == "false") return 0; + + UInt64 n = 0; + if (UInt64.TryParse(s, out n)) + return n; + else + return null; + } + #endregion + + #region ToDecimal + /// + /// + /// + /// + /// + /// + public static Decimal ToDecimal(object obj, Decimal defaultValue) + { + if (obj == null) return defaultValue; + return ToDecimal(obj.ToString(), defaultValue); + } + + /// + /// + /// + /// + /// + /// + public static Decimal ToDecimal(string s, Decimal defaultValue) + { + Decimal n = 0; + if (Decimal.TryParse(s, out n)) + return n; + else + return defaultValue; + } + #endregion + + #region ToNullableDecimal + public static Decimal? ToNullableDecimal(object obj) + { + if (obj == null) return null; + return ToNullableDecimal(obj.ToString()); + } + + public static Decimal? ToNullableDecimal(string s) + { + Decimal n = 0; + if (Decimal.TryParse(s, out n)) + return n; + else + return null; + } + #endregion + + #region ToDouble + /// + /// + /// + /// + /// + /// + public static Double ToDouble(object obj, Double defaultValue) + { + if (obj == null) return defaultValue; + + return ToDouble(obj.ToString(), defaultValue); + } + + /// + /// + /// + /// + /// + /// + public static Double ToDouble(string s, Double defaultValue) + { + Double n = 0; + if (Double.TryParse(s, out n)) + return n; + else + return defaultValue; + } + #endregion + + #region ToNullableDouble + public static Double? ToNullableDouble(object obj) + { + if (obj == null) return null; + return ToNullableDouble(obj.ToString()); + } + + public static Double? ToNullableDouble(string s) + { + Double n = 0; + if (Double.TryParse(s, out n)) + return n; + else + return null; + } + #endregion + + #region ToSingle + /// + /// + /// + /// + /// + /// + public static Single ToSingle(object obj, Single defaultValue) + { + if (obj == null) return defaultValue; + + return ToSingle(obj.ToString(), defaultValue); + } + + /// + /// + /// + /// + /// + /// + public static Single ToSingle(string s, Single defaultValue) + { + Single n = 0; + if (Single.TryParse(s, out n)) + return n; + else + return defaultValue; + } + #endregion + + #region ToNullableSingle + public static Single? ToNullableSingle(object obj) + { + if (obj == null) return null; + return ToNullableSingle(obj.ToString()); + } + + public static Single? ToNullableSingle(string s) + { + Single n = 0; + if (Single.TryParse(s, out n)) + return n; + else + return null; + } + #endregion + + #region ToDateTime + /// + /// + /// + /// + /// + /// + public static DateTime ToDateTime(string s, DateTime defaultValue) + { + DateTime dt = DateTime.MinValue; + if (DateTime.TryParse(s, out dt)) + return dt; + else + return defaultValue; + } + + /// + /// + /// + /// + /// + /// + public static DateTime ToDateTime(object obj, DateTime defaultValue) + { + if (obj == null) return defaultValue; + return ToDateTime(obj.ToString(), defaultValue); + } + #endregion + + #region ToNullableDateTime + public static DateTime? ToNullableDateTime(object obj) + { + if (obj == null) return null; + return ToNullableDateTime(obj.ToString()); + } + + public static DateTime? ToNullableDateTime(string s) + { + DateTime dt = DateTime.MinValue; + if (DateTime.TryParse(s, out dt)) + return dt; + else + return null; + } + #endregion + + #region ToBoolean + /// + /// + /// + /// + /// + /// + public static bool ToBoolean(string s, bool defaultValue) + { + if (string.IsNullOrEmpty(s)) return false; + if (s == "0") return false; + if (s == "1") return true; + if (s.ToLower() == "false") return false; + if (s.ToLower() == "true") return true; + + bool b = false; + if (bool.TryParse(s, out b)) + return b; + else + return defaultValue; + } + + /// + /// + /// + /// + /// + /// + public static bool ToBoolean(object obj, bool defaultValue) + { + if (obj == null) return defaultValue; + return ToBoolean(obj.ToString(), defaultValue); + } + #endregion + + #region ToNullableBoolean + public static bool? ToNullableBoolean(object obj) + { + if (obj == null) return null; + return ToNullableBoolean(obj.ToString()); + } + + public static bool? ToNullableBoolean(string s) + { + if (string.IsNullOrEmpty(s)) return false; + if (s == "0") return false; + if (s == "1") return true; + if (s.ToLower() == "false") return false; + if (s.ToLower() == "true") return true; + + bool b = false; + if (bool.TryParse(s, out b)) + return b; + else + return null; + } + #endregion + + #region ToObject + + /// + /// 将IDataReader转换成对象实体 + /// + /// 目标对象类型 + /// + /// + [Obsolete("负载测试下性能比较差,改用EmitMapper")] + public static T ToObject(IDataReader reader) where T : class, new() + { + Type entityType = typeof(T); + Dictionary dic = new Dictionary(); + foreach (PropertyInfo info in entityType.GetProperties()) + { + dic.Add(info.Name, info); + } + + string columnName = string.Empty; + T t = new T(); + foreach (KeyValuePair attribute in dic) + { + columnName = attribute.Key; + int filedIndex = 0; + while (filedIndex < reader.FieldCount) + { + if (reader.GetName(filedIndex) == columnName) + { + attribute.Value.SetValue(t, reader[filedIndex], null); + break; + } + filedIndex++; + } + } + return t; + } + + #endregion + + #region ToList + + /// + /// 将IDataReader转换成对象实体列表 + /// + /// 目标对象类型 + /// + [Obsolete("负载测试下性能比较差,改用EmitMapper")] + public static List ToList(IDataReader reader) where T : class, new() + { + List list = new List(); + Type entityType = typeof(T); + Dictionary dic = new Dictionary(); + foreach (PropertyInfo info in entityType.GetProperties()) + { + dic.Add(info.Name, info); + } + + string columnName = string.Empty; + while (reader.Read()) + { + T t = new T(); + foreach (KeyValuePair attribute in dic) + { + columnName = attribute.Key; + int filedIndex = 0; + while (filedIndex < reader.FieldCount) + { + if (reader.GetName(filedIndex) == columnName) + { + attribute.Value.SetValue(t, reader[filedIndex], null); + break; + } + filedIndex++; + } + } + list.Add(t); + } + return list; + } + + #endregion + } +} \ No newline at end of file diff --git a/src/Kalman/Utilities/CurrencyUtil.cs b/src/Kalman/Utilities/CurrencyUtil.cs new file mode 100644 index 0000000..8791cc4 --- /dev/null +++ b/src/Kalman/Utilities/CurrencyUtil.cs @@ -0,0 +1,274 @@ +using System; + +namespace Kalman.Utilities +{ + /// + /// ṹ + /// + /// + /// ȷдƱݺͽƾ֤Ļ涨 + ///

+ /// Сλ͸дĸƱݺͽƾ֤ǰֽ֧ոҪݣ + /// ֱӹϵ֧׼ȷʱͰȫƱݺͽƾ֤Сλ͸ƾԼ + /// Ļƾ֤Ǽؾҵȷεһ֤ˣдƱݺͽƾ + /// ֤׼淶ҪҪȫȷּ©ʲݣֹ + /// Ϳġ + ///

+ /// һĴдӦдҼҼ + /// 飨飩½½⡢ơʰۡǪ򣩡ڡԪǡ֡㡢 + /// һġ塢ߡˡšʮë0 + /// д֡дʹ÷֣Eꑡ|fAģҲ + /// Ӧ + ///

+ /// ĴдֵԪΪֹģڡԪ֮Ӧд֣ + /// ڡǡ֮Բд֡дС֡ģ֡治 + /// д֡ + ///

+ /// ĴдǰӦҡдӦӡҡ + /// дпհסдǰδӡҡģӦҡ֡ + /// Ʊݺͽƾ֤дڲԤӡ̶ġǪۡʰǪʰԪǡ + /// ֡ + ///

+ /// ġСдС0ʱĴдӦպԹɡֹ + /// ɺͷֹͿĵҪд£ + ///

+ /// һмСOʱĴдҪд㡱֡磤140950 + /// ӦдҼǪԪǡ + ///

+ /// мм0ʱĴдмֻдһ㡱 + /// ֡磤600714Ӧд½ǪԪҼ֡ + ///

+ /// λԪλǡ0мм0λ + /// ԪλҲǡ0ǧλλǡ0ʱĴдпֻдһ֣Ҳ + /// Բд㡱֡磤168032ӦдҼǪ½۰ʰԪǷ֣д + /// ҼǪ½۰ʰԪǷ֣磤10700053ӦдҼʰǪԪ + /// ֣дҼʰǪԪ֡ + ///

+ /// ģֽλǡ0λǡ0ʱĴдԪ + /// Ӧд㡱֡磤16409.02ӦдҼ½ǪԪ㷡֣ + /// 32504Ӧд۷ʰԪ֡ + ///

+ /// 塢Сдǰ棬Ӧдҷšд + /// СдҪддֱ治塣 + ///

+ /// ƱݵijƱڱʹĴдΪֹƱݵijڣд¡ + /// ʱΪҼҼʰģΪҼҼʰʰ̧ģӦǰӡ㡱 + /// Ϊ̧ҼʰģӦǰӡҼ115գӦдҼҼʰա + /// 1020գӦдҼʰ㷡ʰա + ///

+ /// ߡƱݳƱʹСддģвдδҪ淶дģ + /// пɴʧģɳƱге + ///

+ /// 㷨ȷдƱݺͽƾ֤Ļ涨̣ܶԲд㡱ĵطһɲд㡱 + ///

+ /// ǵпܡҡӡֽϣķؽн + ///
+ public class CurrencyUtil + { + /// + /// ýֵṹ + /// + /// ҽֵ + public CurrencyUtil(double currency) + { + _Value = currency; + } + + private double _Value; + + /// + /// ȡǰṹĽֵ + /// + public double Value + { + get + { + return _Value; + } + } + + /// + /// ȡдַ + /// + /// شдҽַ + public override string ToString() + { + return _Value.ToString ("C"); + } + + private static char[] ChineseNumber = new char[] {'', 'Ҽ', '', '', '', '', '½', '', '', ''}; + private static char[] ChinesePower = new char[] {'ʰ', '', 'Ǫ'}; + + /// + /// ȡĴд + /// + /// ؽд + public string ToChineseCurrencyString() + { + double value = _Value; + if (value < 0) + { + value = - value; + } + int[] x = new int[5]; + string[] s = new string[5]; + bool[] b = new bool[5]; + bool bl; + double v = Math.Floor(value); + x[4] = (int) Math.Round((value - v) * 100); + int i = 3; + double v1; + while (v > 0 && i >= 0) + { + v1 = Math.Floor(v / 10000) * 10000; + x[i] = (int) Math.Round(v - v1); + i --; + v = v1 / 10000; + } + // ȼÿڵĴ + for (i = 0; i < 4; i++) + { + s[i] = ""; + if (x[i] > 0) + { + b[i] = false; + int p = 1000; + bool bk = false; // ǰλΪ + bl = false; // δ¼ + for (int j = 0; j < 4; j ++) + { + int n = x[i] / p; // ǰλ + x[i] -= n * p; // ʣλ + p /= 10; // + if (n == 0) // ǰλΪ + { + if (j == 0) + { + b[i] = true; // λ + } + else + { + if (bl) // δ¼ + { + bk = true; + } + } + } + else + { + if (bk) + { + s[i] += ""; + } + bl = true; + s[i] += ChineseNumber[n]; + if (j < 3) + { + s[i] += ChinesePower[2 - j]; + } + bk = false; + } + } + } + } + // С + bl = false; + if (x[4] % 10 > 0) + { + s[4] = ChineseNumber[x[4] % 10] + ""; + } + else + { + bl = true; + s[4] = ""; + } + x[4] /= 10; + if (x[4] > 0) + { + s[4] = ChineseNumber[x[4] % 10] + "" + s[4]; + b[4] = false; + } + else + { + b[4] = !bl; + } + // ϲ + string sv = ""; + bl = false; + for (i = 0; i < 4; i++) + { + if (s[i].Length > 0) + { + if (bl && b[i]) + { + sv += ""; + } + sv += s[i]; + switch (i) + { + case 0: + case 2: + sv += ""; + break; + case 1: + sv += ""; + break; + case 3: + sv += "Ԫ"; + break; + } + bl = true; + } + else + { + if (bl) + { + switch (i) + { + case 1: + sv += ""; + break; + case 3: + sv += "Ԫ"; + break; + } + } + } + } + // ϲС + if (s[4].Length == 0) + { + if (!bl) + { + sv = "Ԫ"; + } + sv += ""; + } + else + { + if (b[4] && bl) + { + sv += ""; + } + sv += s[4]; + } + return sv; + } + + /// + /// ȡֵָĴд + /// + ///  + /// ؽд + public static string ToChineseCurrencyString(double value) + { + CurrencyUtil currency = new CurrencyUtil(value); + return currency.ToChineseCurrencyString(); + } + + public static string ToChineseCurrencyString(string value) + { + return ToChineseCurrencyString((double.Parse(value))); + } + } +} diff --git a/src/Kalman/Utilities/DatetimeUtil.cs b/src/Kalman/Utilities/DatetimeUtil.cs new file mode 100644 index 0000000..dc085ce --- /dev/null +++ b/src/Kalman/Utilities/DatetimeUtil.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Kalman.Utilities +{ + public sealed class DatetimeUtil + { + /// + /// 当前系统时间转换为Unix时间戳 + /// + /// Unix时间戳 + public static Int64 GetCurrentUnixTime() + { + return GetUnixTime(DateTime.Now); + } + + /// + /// 系统时间转换为Unix时间戳 + /// + /// 时间 + /// Unix时间戳 + public static Int64 GetUnixTime(DateTime dt) + { + DateTime unixStartTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1)); + TimeSpan timeSpan = dt.Subtract(unixStartTime); + string timeStamp = timeSpan.Ticks.ToString(); + return Int64.Parse(timeStamp.Substring(0, timeStamp.Length - 7)); + } + + /// + /// Unix时间戳转换为系统时间 + /// + /// Unix时间戳 + /// + public static DateTime GetFromUnixTime(Int64 unixTime) + { + DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1)); + long lTime = long.Parse(unixTime + "0000000"); + TimeSpan toNow = new TimeSpan(lTime); + return dtStart.Add(toNow); + } + + /// + /// 获取指定日期对应的星期中文名,如:星期一 + /// + /// + /// + public static string GetWeekCNName(DateTime dt) + { + DayOfWeek week = dt.DayOfWeek; + switch (week) + { + case DayOfWeek.Friday: + return "星期五"; + case DayOfWeek.Monday: + return "星期一"; + case DayOfWeek.Saturday: + return "星期六"; + case DayOfWeek.Sunday: + return "星期日"; + case DayOfWeek.Thursday: + return "星期四"; + case DayOfWeek.Tuesday: + return "星期二"; + case DayOfWeek.Wednesday: + return "星期三"; + } + + return string.Empty; + } + + } +} diff --git a/src/Kalman/Utilities/LunarDateUtil.cs b/src/Kalman/Utilities/LunarDateUtil.cs new file mode 100644 index 0000000..13a0471 --- /dev/null +++ b/src/Kalman/Utilities/LunarDateUtil.cs @@ -0,0 +1,1038 @@ +using System; +using System.Collections.Generic; + +namespace Kalman.Utilities +{ + /// + /// ũڽṹ + /// + /// + /// ṹôʵ䷨ʵ֣Ч䣺19011121001231ա + /// + public struct LunarDateUtil + { + #region Ƕ + + /// + /// ķת + /// + sealed class IndependentReversingDays + { + private List _Days; + + private IndependentReversingDays() + { + _Days = new List(); + } + + public void Add(int day) + { + int index = _Days.BinarySearch(day); + index = ~index; + _Days.Insert(index, day); + } + + public int[] GetDays(int first, int last) + { + int index0 = _Days.BinarySearch(first); + if (index0 < 0) + { + index0 = ~index0; + } + int index1 = _Days.BinarySearch(last); + if (index1 < 0) + { + index1 = ~index1; + } + else + { + index1++; + } + index1 -= index0; + if (index1 > 0) + { + int[] days = new int[index1]; + _Days.CopyTo(index0, days, 0, index1); + _Days.RemoveRange(index0, index1); + return days; + } + return new int[0]; + } + + private static IndependentReversingDays _Current = new IndependentReversingDays(); + + public static IndependentReversingDays Current + { + get + { + return _Current; + } + } + } + + /// + /// + /// + /// + /// 鱣ڣͨŻ㷨 + /// ټڵţԼÿŶӦ + /// + abstract class DayArray + { + protected int _First, _Last; + private int _Index; + private byte[] _Days; + + protected DayArray(int year) + { + _Last = year * 365 + year / 4 - year / 100 + year / 400; + _First = year - 1; + _First = _First * 365 + _First / 4 - _First / 100 + _First / 400; + _Last -= _First; + int[] days = CreateDays(year); + _Index = Array.BinarySearch(days, 256); + if (_Index < 0) + { + _Index = ~_Index; + } + _Days = new byte[days.Length]; + for (int i = 0; i < days.Length; i++) + { + if (days[i] < 256) + { + _Days[i] = (byte)days[i]; + } + else + { + _Days[i] = (byte)(days[i] - 256); + } + } + } + + protected abstract int[] CreateDays(int year); + + public int IndexOf(DateTime day) + { + int days = GetDays(day) - _First; + if (days >= 0 & days < _Last) + { + int low = 0; + int high = _Days.Length - 1; + while (low <= high) + { + int index = (low + high) >> 1; + int v = _Days[index]; + if (index >= _Index) + { + v += 256; + } + if (v == days) + { + return index; + } + if (v < days) + { + low = index + 1; + } + else + { + high = index - 1; + } + } + return ~low; + } + throw new ArgumentOutOfRangeException("day"); + } + + public int Length + { + get + { + return _Days.Length; + } + } + + public DateTime this[int index] + { + get + { + if (index >= 0 && index < Length) + { + int days = _Days[index]; + if (index >= _Index) + { + days += 256; + } + return GetDateTime(_First + days); + } + throw new ArgumentOutOfRangeException("index"); + } + } + + protected static DateTime GetDateTime(int days) + { + long ticks = days; + ticks *= TicksPerDay; + return new DateTime(ticks); + } + + protected static int GetDays(DateTime date) + { + return GetDays(date.Date.Ticks); + } + + protected static int GetDays(long ticks) + { + return (int)(ticks / TicksPerDay); + } + + const long TicksPerDay = 0xc92a69c000L; + } + + /// + /// + /// + sealed class SolarTeamDayArray : DayArray + { + public SolarTeamDayArray(int year) : base(year) + { + } + + protected override int[] CreateDays(int year) + { + int[] days = new int[24]; + long ticks0 = FirstSolarTeamDayTicks + TicksPerYear * (year - 1900); + for (int i = 0; i < 24; i++) + { + days[i] = GetDays(ticks0 + SolarTeamMinutes[i] * TicksPerMinute) - _First; + } + return days; + } + + const long TicksPerYear = 0x11f0231a116b8L; + const long TicksPerMinute = 0x23c34600L; + static readonly long FirstSolarTeamDayTicks = (new DateTime(1900, 1, 6, 2, 5, 0)).Ticks; + static readonly int[] SolarTeamMinutes = new int[] { + 0, 21208, 42467, 63836, 85337, 107014, 128867, 150921, + 173149, 195551, 218072, 240693, 263343, 285989, 308563, 331033, + 353350, 375494, 397447, 419210, 440795, 462224, 483532, 504758 }; + } + + /// + /// + /// + sealed class WorkingDayArray : DayArray + { + public WorkingDayArray(int year) : base(year) + { + } + + private void AddDays(List days, ref int first, int length) + { + int len = length; + if (len + first > _Last) + { + len = _Last - first; + } + for (int i = 0; i < len; i++) + { + days.Add(i + first); + } + first += len + 1; + } + + #region ߼ + + private DateTime GetSpringFestivalDay(int year) + { + return GetLunarDay(year, 1, 1); + } + + private DateTime GetChingMingFestivalDay(int year) + { + return GetSolarTeamDay(year, 6); + } + + private DateTime GetDragonBoadDay(int year) + { + return GetLunarDay(year, 5, 5); + } + + private DateTime GetMidAutumnFestevalDay(int year) + { + return GetLunarDay(year, 8, 15); + } + + private void ReverseDay(List days, int day) + { + if (day < 0 || day >= _Last) + { + IndependentReversingDays.Current.Add(_First + day); + } + else + { + int index = days.BinarySearch(day); + if (index >= 0) + { + days.RemoveAt(index); + } + else + { + days.Insert(~index, day); + } + } + } + + private void ReverseDay(List days, DateTime day) + { + ReverseDay(days, GetDays(day) - _First); + } + + private void ReverseDays(List days, DateTime day, params int[] deltas) + { + int days0 = GetDays(day) - _First; + ReverseDay(days, days0); + if (deltas == null) + { + return; + } + if (deltas.Length == 0) + { + return; + } + foreach (int delta in deltas) + { + ReverseDay(days, days0 + delta); + } + } + + private void AddSequentialHoliday(List days, DateTime day) + { + switch (day.DayOfWeek) + { + case DayOfWeek.Sunday: + // գƵһ + ReverseDay(days, day.AddDays(1)); + break; + case DayOfWeek.Tuesday: + // ܶǰ + ReverseDays(days, day, -1, -2); + break; + case DayOfWeek.Wednesday: + // + ReverseDays(days, day, 1, 2, 3, 4); + break; + case DayOfWeek.Thursday: + // ģ + ReverseDays(days, day, 1, 3); + break; + case DayOfWeek.Saturday: + // ƶһ + ReverseDay(days, day.AddDays(2)); + break; + default: + // һ壬ֱӷת + ReverseDay(days, day); + break; + } + } + + private void AddGoldenweek(List days, DateTime firstDay, bool springFestival) + { + switch (firstDay.DayOfWeek) + { + case DayOfWeek.Sunday: + // գƵһ + ReverseDays(days, firstDay.AddDays(-1), 2, 3, 4, 5, 6, 8); + break; + case DayOfWeek.Monday: + // һֱӷת + ReverseDays(days, firstDay.AddDays(-2), 1, 2, 3, 4, 5, 6); + break; + case DayOfWeek.Tuesday: + // ܶǰ + if (springFestival) + { + ReverseDays(days, firstDay.AddDays(-3), 1, 3, 4, 5, 6, 9); + } + else + { + ReverseDays(days, firstDay.AddDays(-3), 1, 2, 3, 4, 5, 6); + } + break; + case DayOfWeek.Wednesday: + // + if (springFestival) + { + ReverseDays(days, firstDay.AddDays(-4), 1, 4, 5, 6, 9, 10); + } + else + { + ReverseDays(days, firstDay.AddDays(-4), 1, 2, 3, 4, 5, 6); + } + break; + case DayOfWeek.Thursday: + // ģ + ReverseDays(days, firstDay, 1, 4, 5, 6, 9, 10); + break; + case DayOfWeek.Friday: + // 壬ֱӷת + ReverseDays(days, firstDay, 3, 4, 5, 6, 8, 9); + break; + case DayOfWeek.Saturday: + // ƶһ + ReverseDays(days, firstDay.AddDays(2), 1, 2, 3, 4); + break; + } + } + + #endregion + + private DateTime GetSolarTeamDay(int year, int index) + { + DayArray days = GetSolarTeamDays(year); + return days[index]; + } + + private DateTime GetLunarDay(int year, int month, int day) + { + LunarDateUtil ldate = new LunarDateUtil(year, month, day, false); + return ldate.Date; + } + + protected override int[] CreateDays(int year) + { + List days = new List(); + int x = (_First + 1) % 7; + int i = 0; + while (i < _Last) + { + if (x == 0) + { + i++; + AddDays(days, ref i, 5); + } + else if (x == 6) + { + i += 2; + x = 0; + } + else + { + AddDays(days, ref i, 6 - x); + x = 0; + } + } + #region ҹ涨ĵ + AddSequentialHoliday(days, new DateTime(year, 1, 1)); // Ԫ + AddGoldenweek(days, new DateTime(year, 10, 1), false); // ʮһƽ + if (year < 2008) + { + AddGoldenweek(days, GetSpringFestivalDay(year), true); // ڻƽ + AddGoldenweek(days, new DateTime(year, 5, 1), false); // һƽ + } + else + { + AddGoldenweek(days, GetSpringFestivalDay(year).AddDays(-1), true); // ڻƽ + AddSequentialHoliday(days, new DateTime(year, 5, 1)); // һ + AddSequentialHoliday(days, GetChingMingFestivalDay(year)); // + AddSequentialHoliday(days, GetDragonBoadDay(year)); // + AddSequentialHoliday(days, GetMidAutumnFestevalDay(year)); // + } + #endregion + #region ܱݵķת + foreach (int d in IndependentReversingDays.Current.GetDays(_First, _First + _Last - 1)) + { + ReverseDay(days, d - _First); + } + #endregion + return days.ToArray(); + } + } + + #endregion + + /// + /// ڹ졣 + /// + /// ڡ + public LunarDateUtil(DateTime date) + { + _Date = date.Date; + _Year = 0; + _Month = 0; + _Day = 0; + _IsLeap = false; + DateChanged(); + } + + /// + /// ũڹ졣 + /// + /// ũꡣ + /// ũ¡ + /// ũա + /// Ƿũ¡ + public LunarDateUtil(int year, int month, int day, bool isLeap) + { + _Date = DateTime.MinValue; + _Year = year; + _Month = month; + _Day = day; + _IsLeap = isLeap; + LunarChanged(); + } + + private DateTime _Date; + private int _Year, _Month, _Day; + private bool _IsLeap; + + /// + /// ڱ仯ũڡ + /// + private void DateChanged() + { + DateTime d0 = new DateTime(1900, 1, 31); + if (_Date < d0 || _Date.Year > 2100) + { + throw new ArgumentOutOfRangeException("date"); + } + TimeSpan ts = _Date - d0; + int days = ts.Days + 1; + int year = 1900; + int t; + while (days > (t = DaysOfLunarYear(year))) + { + days -= t; + year ++; + } + int leap = LeapMonth(year); + int month = 0; + bool isLeap = false; + bool nextLeap = false; + do + { + if (!nextLeap) + { + month ++; + nextLeap = month == leap; + isLeap = false; + t = DaysOfMonth(year, month); + } + else + { + isLeap = true; + nextLeap = false; + // + t = DaysOfLeapMonth(year); + } + if (days > t) + { + days -= t; + } + else + { + break; + } + } while (true); + _Year = year; + _Month = month; + _Day = days; + _IsLeap = isLeap; + } + + /// + /// ũڱ仯㹫ڡ + /// + private void LunarChanged() + { + if (LunarIsValid()) + { + int x = _Day - 1; + // ũͷũ190011ռ + for (int year = _Year - 1; year >= 1900; year --) + { + x += DaysOfLunarYear(year); + } + int month = 1; + int leapMonth = LeapMonth(_Year); + bool nextLeap = false; + while (month < _Month) + { + if (month == leapMonth) + { + if (nextLeap) + { + nextLeap = false; + x += DaysOfLeapMonth(_Year); + month ++; + } + else + { + nextLeap = true; + x += DaysOfMonth(_Year, month); + } + } + else + { + x += DaysOfMonth(_Year, month); + month ++; + } + } + if (_IsLeap && leapMonth == _Month) + { + x += DaysOfMonth(_Year, _Month); + } + _Date = (new DateTime(1900, 1, 31)).AddDays(x); + } + else + { + _Date = DateTime.MinValue; + } + } + + /// + /// ȡڡ + /// + public DateTime Date + { + get + { + return _Date; + } + set + { + if (_Date != value.Date) + { + _Date = value; + DateChanged(); + } + } + } + + /// + /// ȡũꡣ + /// + public int Year + { + get + { + return _Year; + } + } + + /// + /// ȡũ¡ + /// + public int Month + { + get + { + return _Month; + } + } + + /// + /// ȡũա + /// + public int Day + { + get + { + return _Day; + } + } + + /// + /// ȡũ + /// + public string YearName + { + get + { + return string.Empty; + } + } + + /// + /// ȡũ + /// + public string MonthName + { + get + { + if (_Month > 0 && _Month <= 12) + { + return (_IsLeap ? "" : string.Empty) + ChMonths[_Month - 1] + ""; + } + return string.Empty; + } + } + + /// + /// ȡũ + /// + public string DayName + { + get + { + if (_Day == 20 || _Day == 30) + { + return ChDays[_Day / 10 - 1] + "ʮ"; + } + int day = _Day - 1; + if (day >= 0 && day < 10) + { + return "" + ChDays[day]; + } + if (day >= 10 && day < 19) + { + return "ʮ" + ChDays[day - 10]; + } + if (day >= 20 && day < 30) + { + return "إ" + ChDays[day - 20]; + } + return string.Empty; + } + } + + /// + /// ȡ + /// + /// + /// ޽򷵻ؿմ + /// + public string SolarName + { + get + { + DayArray dayArray = GetSolarTeamDays(this._Date.Year); + int index = dayArray.IndexOf(this._Date); + if (index >= 0) + { + return SolarTeamNames[index]; + } + return string.Empty; + } + } + + /// + /// ȡǷΪա + /// + /// + /// հ:ÿ,ÿ,Ԫ,ڻƽ,һƽ,ƽܡ + /// ƽʱԶȲ㷨,ο + /// + public bool IsHoliday + { + get + { + DayArray dayArray = GetWorkingDays(this._Date.Year); + return dayArray.IndexOf(_Date) < 0; + } + } + + /// + /// ȡָڵĹ + /// + /// ָĿڡ + /// + /// شӵǰڿʼָĿڼĹ + /// ָĿ򷵻ظ + public int GetWorkingDays(DateTime day) + { + return GetWorkingDays(_Date, day.Date); + } + + /// + /// ȡָպڡ + /// + /// + /// + /// ȡָպڡ + /// Ϊ򷵻ָ֮ǰڡ + /// + public DateTime GetWorkingDateAfter(int days) + { + return GetWorkingDayAfter(_Date, days); + } + + /// + /// ȡָǰڡ + /// + /// + /// + /// ȡָǰڡ + /// Ϊ򷵻ָ֮ڡ + /// + public DateTime GetWorkingDateBefore(int days) + { + return GetWorkingDayBefore(_Date, days); + } + + /// + /// ȡָ½ڱ + /// + /// ꡣ + /// ¡ + /// ϡ + public static int[] GetSolarTeamDays(int year, int month) + { + DayArray dayArray = GetSolarTeamDays(year); + DateTime d1 = dayArray[(month - 1) * 2]; + DateTime d2 = dayArray[(month - 1) * 2]; + return new int[] { d1.Day, d2.Day }; + } + + #region ڲ㷨 + + static readonly Int32[] LunarInfos = new int[] { + 0x4bd8,0x4ae0,0xa570,0x54d5,0xd260,0xd950,0x5554,0x56af,0x9ad0,0x55d2, + 0x4ae0,0xa5b6,0xa4d0,0xd250,0xd295,0xb54f,0xd6a0,0xada2,0x95b0,0x4977, + 0x497f,0xa4b0,0xb4b5,0x6a50,0x6d40,0xab54,0x2b6f,0x9570,0x52f2,0x4970, + 0x6566,0xd4a0,0xea50,0x6a95,0x5adf,0x2b60,0x86e3,0x92ef,0xc8d7,0xc95f, + 0xd4a0,0xd8a6,0xb55f,0x56a0,0xa5b4,0x25df,0x92d0,0xd2b2,0xa950,0xb557, + 0x6ca0,0xb550,0x5355,0x4daf,0xa5b0,0x4573,0x52bf,0xa9a8,0xe950,0x6aa0, + 0xaea6,0xab50,0x4b60,0xaae4,0xa570,0x5260,0xf263,0xd950,0x5b57,0x56a0, + 0x96d0,0x4dd5,0x4ad0,0xa4d0,0xd4d4,0xd250,0xd558,0xb540,0xb6a0,0x95a6, + 0x95bf,0x49b0,0xa974,0xa4b0,0xb27a,0x6a50,0x6d40,0xaf46,0xab60,0x9570, + 0x4af5,0x4970,0x64b0,0x74a3,0xea50,0x6b58,0x5ac0,0xab60,0x96d5,0x92e0, //1999 + 0xc960,0xd954,0xd4a0,0xda50,0x7552,0x56a0,0xabb7,0x25d0,0x92d0,0xcab5, + 0xa950,0xb4a0,0xbaa4,0xad50,0x55d9,0x4ba0,0xa5b0,0x5176,0x52bf,0xa930, + 0x7954,0x6aa0,0xad50,0x5b52,0x4b60,0xa6e6,0xa4e0,0xd260,0xea65,0xd530, + 0x5aa0,0x76a3,0x96d0,0x4afb,0x4ad0,0xa4d0,0xd0b6,0xd25f,0xd520,0xdd45, + 0xb5a0,0x56d0,0x55b2,0x49b0,0xa577,0xa4b0,0xaa50,0xb255,0x6d2f,0xada0, + 0x4b63,0x937f,0x49f8,0x4970,0x64b0,0x68a6,0xea5f,0x6b20,0xa6c4,0xaaef, + 0x92e0,0xd2e3,0xc960,0xd557,0xd4a0,0xda50,0x5d55,0x56a0,0xa6d0,0x55d4, + 0x52d0,0xa9b8,0xa950,0xb4a0,0xb6a6,0xad50,0x55a0,0xaba4,0xa5b0,0x52b0, + 0xb273,0x6930,0x7337,0x6aa0,0xad50,0x4b55,0x4b6f,0xa570,0x54e4,0xd260, + 0xe968,0xd520,0xdaa0,0x6aa6,0x56df,0x4ae0,0xa9d4,0xa4d0,0xd150,0xf252, + 0xd520}; + + static readonly string[] SolarTeamNames = new string[] { + "С","","","ˮ","","","","", + "","С","â","","С","","","", + "¶","","¶","˪","","Сѩ","ѩ",""}; + static readonly string[] ChMonths = new string[] { + "", "", "", "", "", "", "", "", "", "ʮ", "", "" }; + static readonly string[] ChDays = new string[] { + "һ", "", "", "", "", "", "", "", "", "ʮ" }; + + + static readonly object _SolarTeamDayArraysLocker = new object(); + static readonly object _WorkingDayArraysLocker = new object(); + static readonly Dictionary _SolarTeamDayArrays = new Dictionary(); + static readonly Dictionary _WorkingDayArrays = new Dictionary(); + + private static DayArray GetSolarTeamDays(int year) + { + lock (_SolarTeamDayArraysLocker) + { + if (_SolarTeamDayArrays.ContainsKey(year)) + { + return _SolarTeamDayArrays[year]; + } + DayArray dayArray = new SolarTeamDayArray(year); + _SolarTeamDayArrays.Add(year, dayArray); + return dayArray; + } + } + + private static DayArray GetWorkingDays(int year) + { + lock (_WorkingDayArraysLocker) + { + if (_WorkingDayArrays.ContainsKey(year)) + { + return _WorkingDayArrays[year]; + } + DayArray dayArray = new WorkingDayArray(year); + _WorkingDayArrays.Add(year, dayArray); + return dayArray; + } + } + + private bool LunarIsValid() + { + if (_Year > 2099 || _Year < 1901 || _Month > 12 || _Month < 1 || _Day > 30 || _Day < 1) + { + return false; + } + if (_IsLeap) + { + if (LeapMonth(_Year) == _Month) + { + return _Day <= DaysOfLeapMonth(_Year); + } + else + { + return false; + } + } + return _Day <= DaysOfMonth(_Year, _Month); + } + + private static int DaysOfLunarYear(int year) + { + int x = 348; + int i = 0x8000; + while (i > 8) + { + if ((LunarInfos[year - 1900] & i) > 0) + { + x ++; + } + i = i >> 1; + } + return x + DaysOfLeapMonth(year); + } + + private static int DaysOfLeapMonth(int year) + { + if (LeapMonth(year) > 0) + { + if ((LunarInfos[year - 1899] & 0xf) == 0xf) + { + return 30; + } + else + { + return 29; + } + } + return 0; + } + + private static int LeapMonth(int year) + { + int x = LunarInfos[year - 1900] & 0xf; + return x == 0xf ? 0: x; + } + + private static int DaysOfMonth(int year, int month) + { + int x = LunarInfos[year - 1900]; + int i = 0x8000; + if (month > 1) + { + i = 0x8000 >> (month - 1); + } + if ((x & i) > 0) + { + return 30; + } + return 29; + } + + private static int GetNextYearWorkingDays(int radix, int year, DateTime day) + { + DayArray dayArray = GetWorkingDays(year); + if (day.Year > year) + { + return GetNextYearWorkingDays(dayArray.Length + radix, year + 1, day); + } + int index = dayArray.IndexOf(day); + if (index < 0) + { + index = ~index; + return radix + index; + } + return radix + index + 1; + } + + private static int GetWorkingDays(DateTime day1, DateTime day2) + { + if (day1 == day2) + { + return 0; + } + // ǰĹ + if (day2 < day1) + { + return - GetWorkingDays(day2, day1); + } + DayArray dayArray = GetWorkingDays(day1.Year); + int index0 = dayArray.IndexOf(day1); + if (index0 < 0) + { + index0 = ~index0; + } + // + if (day2.Year > day1.Year) + { + return GetNextYearWorkingDays(dayArray.Length - index0 - 1, day1.Year + 1, day2); + } + // + int index1 = dayArray.IndexOf(day2); + if (index1 < 0) + { + index1 = ~index1; + index1--; + } + return index1 - index0; + } + + private static DateTime GetWorkingDayAfter(DateTime day, int days) + { + if (days < 0) + { + return GetWorkingDayBefore(day, - days); + } + DayArray dayArray = GetWorkingDays(day.Year); + int index = dayArray.IndexOf(day); + if (index < 0) + { + index = ~index; + } + int remains = dayArray.Length - index; + if (days >= remains) + { + // 裺ÿԪ1Ƿǹ + return GetWorkingDayAfter(new DateTime(day.Year + 1, 1, 1), days - remains); + } + return dayArray[index + days]; + } + + private static DateTime GetLastYearWorkingDay(int year, int days) + { + DayArray dayArray = GetWorkingDays(year); + if (dayArray.Length - days > 0) + { + return dayArray[dayArray.Length - days - 1]; + } + return GetLastYearWorkingDay(year - 1, days - dayArray.Length); + } + + private static DateTime GetWorkingDayBefore(DateTime day, int days) + { + if (days < 0) + { + return GetWorkingDayAfter(day, - days); + } + DayArray dayArray = GetWorkingDays(day.Year); + int index = dayArray.IndexOf(day); + if (index > 0) + { + if (index - days >= 0) + { + return dayArray[index - days]; + } + return GetLastYearWorkingDay(day.Year - 1, days - index - 1);//xiaoguohua:return GetLastYearWorkingDay(day.Year - 1, days - index) + } + index = ~index; + if (index == 0) + { + return GetLastYearWorkingDay(day.Year - 1, days); + } + index --; + if (index - days >= 0) + { + return dayArray[index - days]; + } + return GetLastYearWorkingDay(day.Year - 1, days - index-1); + } + + #endregion + } +} diff --git a/src/Kalman/Utilities/NetUtil.cs b/src/Kalman/Utilities/NetUtil.cs new file mode 100644 index 0000000..08a54f8 --- /dev/null +++ b/src/Kalman/Utilities/NetUtil.cs @@ -0,0 +1,88 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Net; +using System.Net.Sockets; + +namespace Kalman.Utilities +{ + /// + /// 网络应用相关工具类 + /// + public static class NetUtil + { + /// + /// 测试指定IP的服务器端口是否打开 + /// + /// ip地址 + /// 端口 + /// 错误信息 + /// + public static bool TestIpAndPort(string ip, int port,out string errMsg) + { + errMsg = string.Empty; + IPAddress ipAddress = IPAddress.Parse(ip); + try + { + IPEndPoint point = new IPEndPoint(ipAddress, port); + TcpClient tcp = new TcpClient(point); + + return true; + } + catch(Exception ex) + { + errMsg = ex.Message; + return false; + } + } + + /// + /// 获取客户端IP地址 + /// + /// ip地址 + public static string GetClientIP() + { + string result = String.Empty; + try + { + result = System.Web.HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"]; + + if (string.IsNullOrEmpty(result)) + result = System.Web.HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"]; + + if (string.IsNullOrEmpty(result)) + result = System.Web.HttpContext.Current.Request.UserHostAddress; + + //可能有代理 + if (result.IndexOf(".") == -1) //没有“.”肯定是非IPv4格式 + result = string.Empty; + else + { + if (result.IndexOf(",") != -1) + { + //有“,”,估计多个代理。取第一个不是内网的IP。 + result = result.Replace(" ", "").Replace("'", ""); + string[] temparyip = result.Split(",;".ToCharArray()); + for (int i = 0; i < temparyip.Length; i++) + { + if (RegexValidate.IsIP(temparyip[i]) + && temparyip[i].Substring(0, 3) != "10." + && temparyip[i].Substring(0, 7) != "192.168" + && temparyip[i].Substring(0, 7) != "172.16.") + { + return temparyip[i]; //找到不是内网的地址 + } + } + } + else if (RegexValidate.IsIP(result)) //代理即是IP格式 + return result; + else + result = string.Empty; //代理中的内容 非IP,取IP + } + } + catch { } + return result; + } + } +} diff --git a/src/Kalman/Utilities/RandomUtil.cs b/src/Kalman/Utilities/RandomUtil.cs new file mode 100644 index 0000000..fca43de --- /dev/null +++ b/src/Kalman/Utilities/RandomUtil.cs @@ -0,0 +1,121 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Kalman.Utilities +{ + /// + /// 跟随机数有关的工具类 + /// + public sealed class RandomUtil + { + /// + /// 生成指定长度的随机字符串 + /// + /// 生成的随机字符串的长度 + /// 产生随机字符串的字典内容,如:"0123456789" + /// + public static string BuildRandomString(int len, string dic) + { + CheckUtil.ArgumentNotNullOrEmpty(dic, "产生随机字符串的字典内容"); + int count = dic.Length; + StringBuilder sb = new StringBuilder(); + + for (int i = 0; i < len; i++) + { + + int idx = GetInteger(0, count); + sb.Append(dic[idx].ToString()); + } + + return sb.ToString(); + } + + #region 从一组对象里面随机获取一个 + + /// + /// 从一组字符串中随机获取一个 + /// + /// 字典 + /// + public static string GetRandomString(string[] dic) + { + int idx = GetInteger(0, dic.Length); + return dic[idx]; + } + + /// + /// 从一组字符串中随机获取一个 + /// + /// 字典 + /// + public static string GetRandomString(IList dic) + { + int idx = GetInteger(0, dic.Count); + return dic[idx]; + } + + /// + /// 从一组对象里面随机获取一个 + /// + /// + /// + public static object GetRandomObject(object[] dic) + { + int idx = GetInteger(0, dic.Length); + return dic[idx]; + } + + /// + /// 从一组对象里面随机获取一个 + /// + /// + /// + public static object GetRandomObject(IList dic) + { + int idx = GetInteger(0, dic.Count); + return dic[idx]; + } + + /// + /// 从一组对象里面随机获取一个 + /// + /// + /// + /// + public static T GetRandomObject(IList dic) + { + int idx = GetInteger(0, dic.Count); + return dic[idx]; + } + + #endregion + + /// + /// 获取一个随机整数 + /// + /// + /// + /// + public static int GetInteger(int min, int max) + { + //long tick = DateTime.Now.Ticks; + //Random rnd = new Random((int)(tick & 0xffffffffL) | (int)(tick >> 32)); + Random rnd = new Random(Guid.NewGuid().GetHashCode()); + int val = rnd.Next(min, max); + return val; + } + + /// + /// 获取一个随机小数 + /// + /// + public static double GetDouble() + { + Random rnd = new Random(Guid.NewGuid().GetHashCode()); + double val = rnd.NextDouble(); + return val; + } + } +} diff --git a/src/Kalman/Utilities/ReflectUtil.cs b/src/Kalman/Utilities/ReflectUtil.cs new file mode 100644 index 0000000..d1268c6 --- /dev/null +++ b/src/Kalman/Utilities/ReflectUtil.cs @@ -0,0 +1,148 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Reflection; +using System.Threading; +using System.IO; +using System.Diagnostics; + +namespace Kalman.Utilities +{ + /// + /// 反射工具类 + /// + public class ReflectUtil + { + /// + /// 从当前应用程序域中根据类型名称查找该类型所属的程序集 + /// + /// + /// + public static Assembly FindAssemblyFromCurrentAppDomain(string typeName) + { + AppDomain appDomain = AppDomain.CurrentDomain; + return FindAssemblyFromAppDomain(appDomain, typeName); + } + + /// + /// 从指定应用程序域中根据类型名称查找该类型所属的程序集 + /// + /// + /// + /// + public static Assembly FindAssemblyFromAppDomain(AppDomain appDomain, string typeName) + { + Assembly[] assemblies = appDomain.GetAssemblies(); + foreach (Assembly assembly in assemblies) + { + Type[] types = assembly.GetTypes(); + foreach (Type type in types) + { + if (type.FullName == typeName) + return assembly; + } + } + return null; + } + + /// + /// 从应用程序根目录的文件中根据类型名称查找该类型所属的程序集 + /// + /// + /// + public static Assembly FindAssemblyFromAppDirectory(string typeName) + { + string rootPath = AppDomain.CurrentDomain.BaseDirectory; + string binPath = Path.Combine(rootPath, "bin"); + DirectoryInfo dir = new DirectoryInfo(rootPath); + FileInfo[] files; + files = dir.GetFiles("*.dll", SearchOption.TopDirectoryOnly); + + foreach (FileInfo file in files) + { + Assembly assembly = Assembly.LoadFile(file.FullName); + Type[] types = assembly.GetTypes(); + foreach (Type type in types) + { + if (type.FullName == typeName) + return assembly; + } + } + + if (Directory.Exists(binPath) == false) + { + binPath = rootPath; + } + + dir = new DirectoryInfo(binPath); + files = dir.GetFiles("*.dll", SearchOption.TopDirectoryOnly); + foreach (FileInfo file in files) + { + Assembly assembly = Assembly.LoadFile(file.FullName); + Type[] types = assembly.GetTypes(); + foreach (Type type in types) + { + if (type.FullName == typeName) + return assembly; + } + } + + return null; + } + + /// + /// 获取当前正在执行的方法信息,如:ClassName->Method(arg1,arg2,out arg3) + /// + /// 堆栈上要跳过的帧数,直接调用该方法为1,间接调用请再加上封装的层次 + /// + public static string GetCurrentMethodInfo(int skipFrames) + { + StackFrame f = new StackFrame(skipFrames, true); //调用日志记录器的类所在的堆栈帧 + int lineNum = f.GetFileLineNumber(); + MethodBase method = f.GetMethod(); + Type classType = method.ReflectedType; + + StringBuilder sb = new StringBuilder(string.Format("{0}->{1}", classType.FullName, method.Name)); + if (method.IsGenericMethod) + { + Type[] ts = method.GetGenericArguments(); + sb.Append("<"); + for (int i = 0; i < ts.Length; i++) + { + sb.Append(ts[i].Name); + if (i != ts.Length - 1) + { + sb.Append(","); + } + } + sb.Append(">"); + } + + ParameterInfo[] ps = method.GetParameters(); + + sb.Append("("); + for (int i = 0; i < ps.Length; i++) + { + ParameterInfo p = ps[i]; + if (p.IsOut) + { + sb.Append("out " + p.Name); + } + else + { + sb.Append(p.Name); + } + + if (i != ps.Length - 1) + { + sb.Append(","); + } + } + + sb.Append(") at line" + lineNum); + return sb.ToString(); + + } + } +} diff --git a/src/Kalman/Utilities/SignUtil.cs b/src/Kalman/Utilities/SignUtil.cs new file mode 100644 index 0000000..3ba2675 --- /dev/null +++ b/src/Kalman/Utilities/SignUtil.cs @@ -0,0 +1,143 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Collections.Specialized; +using System.Security.Cryptography; +using Kalman.Security; +using Kalman.Extensions; + +namespace Kalman.Utilities +{ + /// + /// 签名工具类,用于计算接口调用时计算接口签名 + /// + public class SignUtil + { + HashAlgorithmType _HashAlgorithmType; + Encoding _Encoding; + + /// + /// 构造函数,初始化签名算法为MD5,编码为UTF-8 + /// + public SignUtil() + { + _HashAlgorithmType = HashAlgorithmType.MD5; + _Encoding = Encoding.UTF8; + } + + /// + /// 构造函数,初始化签名算法为MD5 + /// + /// + public SignUtil(Encoding encoding) + { + _HashAlgorithmType = HashAlgorithmType.MD5; + _Encoding = encoding; + } + + /// + /// 构造函数,初始化编码为UTF-8 + /// + public SignUtil(HashAlgorithmType hashAlgorithmType) + { + _HashAlgorithmType = hashAlgorithmType; + _Encoding = Encoding.UTF8; + } + + /// + /// 构造函数,需要指定签名算法及编码 + /// + public SignUtil(HashAlgorithmType hashAlgorithmType, Encoding encoding) + { + _HashAlgorithmType = hashAlgorithmType; + _Encoding = encoding; + } + + /// + /// 计算签名 + /// + /// 该集合保存签名相关参数的值 + /// 签名密钥 + /// + public string Sign(NameValueCollection nvc, string secretKey) + { + StringBuilder sb = new StringBuilder(); + + foreach (KeyValuePair temp in nvc) + { + sb.Append(temp.Value); + } + + sb.Append(secretKey); + + string s = HashCryto.GetHash2String(sb.ToString(), _HashAlgorithmType, _Encoding); + return s; + } + + /// + /// 生成带签名的url + /// + /// + /// + /// + public string SignUrl(string baseUrl, NameValueCollection urlParams, string secretKey) + { + var allKeys = urlParams.AllKeys; + + return SignUrl(baseUrl, urlParams, allKeys, secretKey); + } + + /// + /// 生成带签名的url,参数顺序按字母顺序 + /// + /// + /// + /// + public string SignUrlInAlphabeticalOrder(string baseUrl, NameValueCollection urlParams, string secretKey) + { + var allKeys = urlParams.AllKeys.OrderBy(p => p); + return SignUrl(baseUrl, urlParams, allKeys, secretKey); + } + + private string SignUrl(string baseUrl, NameValueCollection urlParams, IEnumerable allKeys, string key) + { + StringBuilder urlBuilder = new StringBuilder(baseUrl + "?"); + //创建待加密字符串 + StringBuilder paramString = new StringBuilder(); + + foreach (var k in allKeys) + { + paramString.Append(urlParams[k]); + urlBuilder.Append(string.Format("{0}={1}&", k, urlParams[k])); + } + + paramString.Append(key); + + //加密 + string signedString = HashCryto.GetHash2String(paramString.ToString(), _HashAlgorithmType, _Encoding); + + urlBuilder.Append(string.Format("{0}={1}", "sign", signedString)); + + return urlBuilder.ToString(); + } + + ///// + ///// MD5加密 + ///// + ///// + ///// + //public static string EncryptByMD5(string str) + //{ + // MD5 md5 = MD5.Create(); + // byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(str)); + // StringBuilder sBuilder = new StringBuilder(); + + // for (int i = 0; i < s.Length; i++) + // { + // sBuilder.Append(s[i].ToString("X2")); + // } + // return sBuilder.ToString(); + //} + } +} diff --git a/src/Kalman/Utilities/SpellUtil.cs b/src/Kalman/Utilities/SpellUtil.cs new file mode 100644 index 0000000..b417130 --- /dev/null +++ b/src/Kalman/Utilities/SpellUtil.cs @@ -0,0 +1,216 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Collections; + +namespace Kalman.Utilities +{ + /// + /// 中文拼音相关工具类 + /// + public sealed class SpellUtil + { + //获取拼音首字母 + + /// + /// 获取汉字拼音,拼音之间用空格隔开 + /// + /// 汉字 + /// 返回汉字拼音 + public static string GetSpell(string chinese) + { + return GetSpell(chinese, ""); + } + + /// + /// 获取汉字拼音 + /// + /// 汉字 + /// 拼音之间的分隔符号 + /// 返回汉字拼音 + public static string GetSpell(string chinese, string split) + { + try + { + Hashtable ht = GetHashData(); + + byte[] b = System.Text.Encoding.Default.GetBytes(chinese); + int p; + StringBuilder sb = new StringBuilder(); + + for (int i = 0; i < b.Length; i++) + { + p = (int)b[i]; + + if (p > 160) + { + p = p * 256 + b[++i] - 65536; + + if (p < -20319 || p > -10247) + //return ""; + continue; + + while (!ht.ContainsKey(p)) + p--; + + sb.Append(ht[p].ToString() + split); + } + else + { + //sb.Append(p.ToString() + split); + sb.Append(((char)p).ToString() + split); + } + } + + ht.Clear(); + return sb.ToString().TrimEnd(split.ToCharArray()); + } + catch + { + return ""; + } + } + + private static Hashtable GetHashData() + { + Hashtable ht = new Hashtable(); + + ht.Add(-20319, "a"); + ht.Add(-20317, "ai"); ht.Add(-20304, "an"); ht.Add(-20295, "ang"); + ht.Add(-20292, "ao"); ht.Add(-20283, "ba"); ht.Add(-20265, "bai"); + ht.Add(-20257, "ban"); ht.Add(-20242, "bang"); ht.Add(-20230, "bao"); + ht.Add(-20051, "bei"); ht.Add(-20036, "ben"); ht.Add(-20032, "beng"); + ht.Add(-20026, "bi"); ht.Add(-20002, "bian"); ht.Add(-19990, "biao"); + ht.Add(-19986, "bie"); ht.Add(-19982, "bin"); ht.Add(-19976, "bing"); + ht.Add(-19805, "bo"); ht.Add(-19784, "bu"); ht.Add(-19775, "ca"); + ht.Add(-19774, "cai"); ht.Add(-19763, "can"); ht.Add(-19756, "cang"); + ht.Add(-19751, "cao"); ht.Add(-19746, "ce"); ht.Add(-19741, "ceng"); + ht.Add(-19739, "cha"); ht.Add(-19728, "chai"); ht.Add(-19725, "chan"); + ht.Add(-19715, "chang"); ht.Add(-19540, "chao"); ht.Add(-19531, "che"); + ht.Add(-19525, "chen"); ht.Add(-19515, "cheng"); ht.Add(-19500, "chi"); + ht.Add(-19484, "chong"); ht.Add(-19479, "chou"); ht.Add(-19467, "chu"); + ht.Add(-19289, "chuai"); ht.Add(-19288, "chuan"); ht.Add(-19281, "chuang"); + ht.Add(-19275, "chui"); ht.Add(-19270, "chun"); ht.Add(-19263, "chuo"); + ht.Add(-19261, "ci"); ht.Add(-19249, "cong"); ht.Add(-19243, "cou"); + ht.Add(-19242, "cu"); ht.Add(-19238, "cuan"); ht.Add(-19235, "cui"); + ht.Add(-19227, "cun"); ht.Add(-19224, "cuo"); ht.Add(-19218, "da"); + ht.Add(-19212, "dai"); ht.Add(-19038, "dan"); ht.Add(-19023, "dang"); + ht.Add(-19018, "dao"); ht.Add(-19006, "de"); ht.Add(-19003, "deng"); + ht.Add(-18996, "di"); ht.Add(-18977, "dian"); ht.Add(-18961, "diao"); + ht.Add(-18952, "die"); ht.Add(-18783, "ding"); ht.Add(-18774, "diu"); + ht.Add(-18773, "dong"); ht.Add(-18763, "dou"); ht.Add(-18756, "du"); + ht.Add(-18741, "duan"); ht.Add(-18735, "dui"); ht.Add(-18731, "dun"); + ht.Add(-18722, "duo"); ht.Add(-18710, "e"); ht.Add(-18697, "en"); + ht.Add(-18696, "er"); ht.Add(-18526, "fa"); ht.Add(-18518, "fan"); + ht.Add(-18501, "fang"); ht.Add(-18490, "fei"); ht.Add(-18478, "fen"); + ht.Add(-18463, "feng"); ht.Add(-18448, "fo"); ht.Add(-18447, "fou"); + ht.Add(-18446, "fu"); ht.Add(-18239, "ga"); ht.Add(-18237, "gai"); + ht.Add(-18231, "gan"); ht.Add(-18220, "gang"); ht.Add(-18211, "gao"); + ht.Add(-18201, "ge"); ht.Add(-18184, "gei"); ht.Add(-18183, "gen"); + ht.Add(-18181, "geng"); ht.Add(-18012, "gong"); ht.Add(-17997, "gou"); + ht.Add(-17988, "gu"); ht.Add(-17970, "gua"); ht.Add(-17964, "guai"); + ht.Add(-17961, "guan"); ht.Add(-17950, "guang"); ht.Add(-17947, "gui"); + ht.Add(-17931, "gun"); ht.Add(-17928, "guo"); ht.Add(-17922, "ha"); + ht.Add(-17759, "hai"); ht.Add(-17752, "han"); ht.Add(-17733, "hang"); + ht.Add(-17730, "hao"); ht.Add(-17721, "he"); ht.Add(-17703, "hei"); + ht.Add(-17701, "hen"); ht.Add(-17697, "heng"); ht.Add(-17692, "hong"); + ht.Add(-17683, "hou"); ht.Add(-17676, "hu"); ht.Add(-17496, "hua"); + ht.Add(-17487, "huai"); ht.Add(-17482, "huan"); ht.Add(-17468, "huang"); + ht.Add(-17454, "hui"); ht.Add(-17433, "hun"); ht.Add(-17427, "huo"); + ht.Add(-17417, "ji"); ht.Add(-17202, "jia"); ht.Add(-17185, "jian"); + ht.Add(-16983, "jiang"); ht.Add(-16970, "jiao"); ht.Add(-16942, "jie"); + ht.Add(-16915, "jin"); ht.Add(-16733, "jing"); ht.Add(-16708, "jiong"); + ht.Add(-16706, "jiu"); ht.Add(-16689, "ju"); ht.Add(-16664, "juan"); + ht.Add(-16657, "jue"); ht.Add(-16647, "jun"); ht.Add(-16474, "ka"); + ht.Add(-16470, "kai"); ht.Add(-16465, "kan"); ht.Add(-16459, "kang"); + ht.Add(-16452, "kao"); ht.Add(-16448, "ke"); ht.Add(-16433, "ken"); + ht.Add(-16429, "keng"); ht.Add(-16427, "kong"); ht.Add(-16423, "kou"); + ht.Add(-16419, "ku"); ht.Add(-16412, "kua"); ht.Add(-16407, "kuai"); + ht.Add(-16403, "kuan"); ht.Add(-16401, "kuang"); ht.Add(-16393, "kui"); + ht.Add(-16220, "kun"); ht.Add(-16216, "kuo"); ht.Add(-16212, "la"); + ht.Add(-16205, "lai"); ht.Add(-16202, "lan"); ht.Add(-16187, "lang"); + ht.Add(-16180, "lao"); ht.Add(-16171, "le"); ht.Add(-16169, "lei"); + ht.Add(-16158, "leng"); ht.Add(-16155, "li"); ht.Add(-15959, "lia"); + ht.Add(-15958, "lian"); ht.Add(-15944, "liang"); ht.Add(-15933, "liao"); + ht.Add(-15920, "lie"); ht.Add(-15915, "lin"); ht.Add(-15903, "ling"); + ht.Add(-15889, "liu"); ht.Add(-15878, "long"); ht.Add(-15707, "lou"); + ht.Add(-15701, "lu"); ht.Add(-15681, "lv"); ht.Add(-15667, "luan"); + ht.Add(-15661, "lue"); ht.Add(-15659, "lun"); ht.Add(-15652, "luo"); + ht.Add(-15640, "ma"); ht.Add(-15631, "mai"); ht.Add(-15625, "man"); + ht.Add(-15454, "mang"); ht.Add(-15448, "mao"); ht.Add(-15436, "me"); + ht.Add(-15435, "mei"); ht.Add(-15419, "men"); ht.Add(-15416, "meng"); + ht.Add(-15408, "mi"); ht.Add(-15394, "mian"); ht.Add(-15385, "miao"); + ht.Add(-15377, "mie"); ht.Add(-15375, "min"); ht.Add(-15369, "ming"); + ht.Add(-15363, "miu"); ht.Add(-15362, "mo"); ht.Add(-15183, "mou"); + ht.Add(-15180, "mu"); ht.Add(-15165, "na"); ht.Add(-15158, "nai"); + ht.Add(-15153, "nan"); ht.Add(-15150, "nang"); ht.Add(-15149, "nao"); + ht.Add(-15144, "ne"); ht.Add(-15143, "nei"); ht.Add(-15141, "nen"); + ht.Add(-15140, "neng"); ht.Add(-15139, "ni"); ht.Add(-15128, "nian"); + ht.Add(-15121, "niang"); ht.Add(-15119, "niao"); ht.Add(-15117, "nie"); + ht.Add(-15110, "nin"); ht.Add(-15109, "ning"); ht.Add(-14941, "niu"); + ht.Add(-14937, "nong"); ht.Add(-14933, "nu"); ht.Add(-14930, "nv"); + ht.Add(-14929, "nuan"); ht.Add(-14928, "nue"); ht.Add(-14926, "nuo"); + ht.Add(-14922, "o"); ht.Add(-14921, "ou"); ht.Add(-14914, "pa"); + ht.Add(-14908, "pai"); ht.Add(-14902, "pan"); ht.Add(-14894, "pang"); + ht.Add(-14889, "pao"); ht.Add(-14882, "pei"); ht.Add(-14873, "pen"); + ht.Add(-14871, "peng"); ht.Add(-14857, "pi"); ht.Add(-14678, "pian"); + ht.Add(-14674, "piao"); ht.Add(-14670, "pie"); ht.Add(-14668, "pin"); + ht.Add(-14663, "ping"); ht.Add(-14654, "po"); ht.Add(-14645, "pu"); + ht.Add(-14630, "qi"); ht.Add(-14594, "qia"); ht.Add(-14429, "qian"); + ht.Add(-14407, "qiang"); ht.Add(-14399, "qiao"); ht.Add(-14384, "qie"); + ht.Add(-14379, "qin"); ht.Add(-14368, "qing"); ht.Add(-14355, "qiong"); + ht.Add(-14353, "qiu"); ht.Add(-14345, "qu"); ht.Add(-14170, "quan"); + ht.Add(-14159, "que"); ht.Add(-14151, "qun"); ht.Add(-14149, "ran"); + ht.Add(-14145, "rang"); ht.Add(-14140, "rao"); ht.Add(-14137, "re"); + ht.Add(-14135, "ren"); ht.Add(-14125, "reng"); ht.Add(-14123, "ri"); + ht.Add(-14122, "rong"); ht.Add(-14112, "rou"); ht.Add(-14109, "ru"); + ht.Add(-14099, "ruan"); ht.Add(-14097, "rui"); ht.Add(-14094, "run"); + ht.Add(-14092, "ruo"); ht.Add(-14090, "sa"); ht.Add(-14087, "sai"); + ht.Add(-14083, "san"); ht.Add(-13917, "sang"); ht.Add(-13914, "sao"); + ht.Add(-13910, "se"); ht.Add(-13907, "sen"); ht.Add(-13906, "seng"); + ht.Add(-13905, "sha"); ht.Add(-13896, "shai"); ht.Add(-13894, "shan"); + ht.Add(-13878, "shang"); ht.Add(-13870, "shao"); ht.Add(-13859, "she"); + ht.Add(-13847, "shen"); ht.Add(-13831, "sheng"); ht.Add(-13658, "shi"); + ht.Add(-13611, "shou"); ht.Add(-13601, "shu"); ht.Add(-13406, "shua"); + ht.Add(-13404, "shuai"); ht.Add(-13400, "shuan"); ht.Add(-13398, "shuang"); + ht.Add(-13395, "shui"); ht.Add(-13391, "shun"); ht.Add(-13387, "shuo"); + ht.Add(-13383, "si"); ht.Add(-13367, "song"); ht.Add(-13359, "sou"); + ht.Add(-13356, "su"); ht.Add(-13343, "suan"); ht.Add(-13340, "sui"); + ht.Add(-13329, "sun"); ht.Add(-13326, "suo"); ht.Add(-13318, "ta"); + ht.Add(-13147, "tai"); ht.Add(-13138, "tan"); ht.Add(-13120, "tang"); + ht.Add(-13107, "tao"); ht.Add(-13096, "te"); ht.Add(-13095, "teng"); + ht.Add(-13091, "ti"); ht.Add(-13076, "tian"); ht.Add(-13068, "tiao"); + ht.Add(-13063, "tie"); ht.Add(-13060, "ting"); ht.Add(-12888, "tong"); + ht.Add(-12875, "tou"); ht.Add(-12871, "tu"); ht.Add(-12860, "tuan"); + ht.Add(-12858, "tui"); ht.Add(-12852, "tun"); ht.Add(-12849, "tuo"); + ht.Add(-12838, "wa"); ht.Add(-12831, "wai"); ht.Add(-12829, "wan"); + ht.Add(-12812, "wang"); ht.Add(-12802, "wei"); ht.Add(-12607, "wen"); + ht.Add(-12597, "weng"); ht.Add(-12594, "wo"); ht.Add(-12585, "wu"); + ht.Add(-12556, "xi"); ht.Add(-12359, "xia"); ht.Add(-12346, "xian"); + ht.Add(-12320, "xiang"); ht.Add(-12300, "xiao"); ht.Add(-12120, "xie"); + ht.Add(-12099, "xin"); ht.Add(-12089, "xing"); ht.Add(-12074, "xiong"); + ht.Add(-12067, "xiu"); ht.Add(-12058, "xu"); ht.Add(-12039, "xuan"); + ht.Add(-11867, "xue"); ht.Add(-11861, "xun"); ht.Add(-11847, "ya"); + ht.Add(-11831, "yan"); ht.Add(-11798, "yang"); ht.Add(-11781, "yao"); + ht.Add(-11604, "ye"); ht.Add(-11589, "yi"); ht.Add(-11536, "yin"); + ht.Add(-11358, "ying"); ht.Add(-11340, "yo"); ht.Add(-11339, "yong"); + ht.Add(-11324, "you"); ht.Add(-11303, "yu"); ht.Add(-11097, "yuan"); + ht.Add(-11077, "yue"); ht.Add(-11067, "yun"); ht.Add(-11055, "za"); + ht.Add(-11052, "zai"); ht.Add(-11045, "zan"); ht.Add(-11041, "zang"); + ht.Add(-11038, "zao"); ht.Add(-11024, "ze"); ht.Add(-11020, "zei"); + ht.Add(-11019, "zen"); ht.Add(-11018, "zeng"); ht.Add(-11014, "zha"); + ht.Add(-10838, "zhai"); ht.Add(-10832, "zhan"); ht.Add(-10815, "zhang"); + ht.Add(-10800, "zhao"); ht.Add(-10790, "zhe"); ht.Add(-10780, "zhen"); + ht.Add(-10764, "zheng"); ht.Add(-10587, "zhi"); ht.Add(-10544, "zhong"); + ht.Add(-10533, "zhou"); ht.Add(-10519, "zhu"); ht.Add(-10331, "zhua"); + ht.Add(-10329, "zhuai"); ht.Add(-10328, "zhuan"); ht.Add(-10322, "zhuang"); + ht.Add(-10315, "zhui"); ht.Add(-10309, "zhun"); ht.Add(-10307, "zhuo"); + ht.Add(-10296, "zi"); ht.Add(-10281, "zong"); ht.Add(-10274, "zou"); + ht.Add(-10270, "zu"); ht.Add(-10262, "zuan"); ht.Add(-10260, "zui"); + ht.Add(-10256, "zun"); ht.Add(-10254, "zuo"); ht.Add(-10247, "zz"); + + return ht; + } + } +} diff --git a/src/Kalman/Utilities/StringUtilty/StringUtil.CodeBuilder.cs b/src/Kalman/Utilities/StringUtilty/StringUtil.CodeBuilder.cs new file mode 100644 index 0000000..4be359d --- /dev/null +++ b/src/Kalman/Utilities/StringUtilty/StringUtil.CodeBuilder.cs @@ -0,0 +1,132 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Kalman.Utilities +{ + /// + /// + /// + public static partial class StringUtil + { + #region 代码生成器常用的一些字符串处理方法,比如表名前缀的处理 + + /***************************************************************************************************** + * 在数据库设计中,常见的数据库对象的命名形式有一下几种 + * 1、Pascal大小写方式,如:User,UserName + * 2、加子系统或模块前缀,前缀后面遵循Pascal大小写方式,如:sys_User、sys_base_User + * 3、全部小写,单词之间用符合隔开,一般用下划线,如:user_name + * 4、加子系统或模块前缀,前缀后面全部小写,单词之间用符合隔开,一般用下划线,如:sys_user + * + * 在代码生成器中处理数据库对象的代码生成时,为了让生成的对象名称符合编程语言的设计规范, + * 因此要对数据库对象的名称进行处理,主要是处理前缀和大小写转换 + * 对于第一种命名方式,符合C#命名规范,一般不用处理,如果是其他语言,可能需要将其转换为驼峰命名方式 + * 对于其他三种命名方式,一般是先移除前缀,再对后面的名称做规范化处理 + *****************************************************************************************************/ + + /// + /// 将字符串的首字母转换成大写,比如将user转换成User + /// + /// + /// + public static string InitialToUpper(string s) + { + if (string.IsNullOrEmpty(s)) return s; + return string.Concat(s.Substring(0, 1).ToUpper(), s.Substring(1)); + } + + /// + /// 将字符串的首字母转换成小写,比如将User转换成user + /// + /// + /// + public static string InitialToLower(string s) + { + return string.Concat(s.Substring(0, 1).ToLower(), s.Substring(1)); + } + + /// + /// 专用方法,将类似aaa_bbb_ccc_ddd的字符串转换为AaaBbbCccDdd + /// + /// + /// + public static string InitialToUpperMulti(string s) + { + string[] ss = s.Split('_'); + StringBuilder sb = new StringBuilder(); + + foreach (string item in ss) + { + sb.Append(InitialToUpper(item)); + } + + return sb.ToString(); + } + + /// + /// 移除字符串的前缀,示例:RemovePrefix("aa_bb_cc_xxx","aa_bb_");结果为"cc_xxx"; + /// + /// + /// + /// + public static string RemovePrefix(string s, string prefix) + { + return s.TrimStart(prefix.ToCharArray()); + } + + /// + /// 移除字符串的前缀,默认前缀分隔符是下划线"_",示例:RemovePrefix("aa_bb_cc_xxx",2);结果为"cc_xxx"; + /// + /// + /// + /// + public static string RemovePrefix(string s, int level) + { + return RemovePrefix(s, "_", level); + } + + /// + /// 移除字符串的前缀,示例:RemovePrefix("aa_bb_cc_xxx","_",2);结果为"cc_xxx"; + /// + /// + /// 前缀分隔符,一般为下划线"_" + /// 前缀层次 + /// + public static string RemovePrefix(string s, string separator, int level) + { + if (string.IsNullOrEmpty(separator) == false) + { + for (int i = 0; i < level; i++) + { + int idx = s.IndexOf(separator) + 1; + if (idx == 0) break; + s = s.Remove(0, idx); + } + } + return s; + } + + public static string ToPascalName(string s, string separator) + { + string[] ss = s.Split(separator.ToCharArray()); + StringBuilder sb = new StringBuilder(); + foreach (string item in ss) + { + if (item.Length > 2) + { + sb.Append(item.Substring(0, 1).ToUpper() + item.Substring(1).ToLower()); + } + else + { + sb.Append(item.ToUpper()); + } + } + return sb.ToString(); + } + + + + #endregion + } +} diff --git a/src/Kalman/Utilities/StringUtilty/StringUtil.Html.cs b/src/Kalman/Utilities/StringUtilty/StringUtil.Html.cs new file mode 100644 index 0000000..5248e67 --- /dev/null +++ b/src/Kalman/Utilities/StringUtilty/StringUtil.Html.cs @@ -0,0 +1,127 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; + +namespace Kalman.Utilities +{ + public static partial class StringUtil + { + /// + /// 对Html文本字符串进行编码 + /// + /// + /// + public static string HtmlEncode(string s) + { + s = s.Replace("&", "&"); + //s = s.Replace("'", "''"); + s = s.Replace("'", "'"); + s = s.Replace("\"", """); + s = s.Replace(" ", " "); + s = s.Replace("<", "<"); + s = s.Replace(">", ">"); + s = s.Replace("\n", "
"); + return s; + } + + /// + /// 对Html文本字符串进行解码 + /// + public static string HtmlDecode(string s) + { + s = s.Replace("&", "&"); + s = s.Replace("'", "'"); + s = s.Replace(""", "\""); + s = s.Replace(" ", " "); + s = s.Replace(">", ">"); + s = s.Replace("<", "<"); + s = s.Replace("
", "\n"); + + return s; + } + + /// + /// 移除字符串中所有的HTML标签 + /// + /// + /// + public static string RemoveHtml(string s) + { + return RemoveHtmlInternal(s, null); + } + + /// + /// 移除字符串中在指定集合中所包含的HTML标签,标签名称不区分大小写 + /// + /// + /// + /// + public static string RemoveHtml(string s, IList removeTags) + { + if (removeTags == null) + throw new ArgumentNullException("removeTags"); + + return RemoveHtmlInternal(s, removeTags); + } + + private static string RemoveHtmlInternal(string s, IList removeTags) + { + List removeTagsUpper = null; + + if (removeTags != null) + { + removeTagsUpper = new List(removeTags.Count); + + foreach (string tag in removeTags) + { + removeTagsUpper.Add(tag.ToUpperInvariant()); + } + } + + Regex anyTag = new Regex(@"<[/]{0,1}\s*(?\w*)\s*(?.*?=['""].*?[""'])*?\s*[/]{0,1}>", RegexOptions.Compiled); + + return anyTag.Replace(s, delegate(Match match) + { + string tag = match.Groups["tag"].Value.ToUpperInvariant(); + + if (removeTagsUpper == null) + return string.Empty; + else if (removeTagsUpper.Contains(tag)) + return string.Empty; + else + return match.Value; + }); + } + + /// + /// 移除字符串不安全的HTML代码,例如"script,iframe"等 + /// + public static string RemoveUnsafeHtml(string s) + { + StringBuilder builder = new StringBuilder(s); + Regex regex = new Regex(@"[\s\S]*?", RegexOptions.IgnoreCase); + foreach (Match match in regex.Matches(builder.ToString())) + { + builder.Replace(match.Value, ""); + } + regex = new Regex(@"", RegexOptions.IgnoreCase); + foreach (Match match2 in regex.Matches(builder.ToString())) + { + builder.Replace(match2.Value, ""); + } + regex = new Regex(@"", RegexOptions.IgnoreCase); + foreach (Match match3 in regex.Matches(builder.ToString())) + { + builder.Replace(match3.Value, ""); + } + regex = new Regex(@"[\s\S]*?", RegexOptions.IgnoreCase); + foreach (Match match4 in regex.Matches(builder.ToString())) + { + builder.Replace(match4.Value, ""); + } + return builder.ToString(); + } + } +} diff --git a/src/Kalman/Utilities/StringUtilty/StringUtil.cs b/src/Kalman/Utilities/StringUtilty/StringUtil.cs new file mode 100644 index 0000000..64e1694 --- /dev/null +++ b/src/Kalman/Utilities/StringUtilty/StringUtil.cs @@ -0,0 +1,352 @@ +using Kalman.Data.SchemaObject; +using Kalman.Security; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Kalman.Utilities +{ + public static partial class StringUtil + { + /// + /// 转全角(SBC case) + /// + /// 任意字符串 + /// 全角字符串 + public static string ToSBC(string s) + { + char[] c = s.ToCharArray(); + for (int i = 0; i < c.Length; i++) + { + if (c[i] == 32) + { + c[i] = (char)12288; + continue; + } + if (c[i] < 127) + c[i] = (char)(c[i] + 65248); + } + return new string(c); + } + + /// + /// 转半角(DBC case) + /// + public static string ToDBC(string s) + { + char[] c = s.ToCharArray(); + for (int i = 0; i < c.Length; i++) + { + if (c[i] == 12288) + { + c[i] = (char)32; + continue; + } + if (c[i] > 65280 && c[i] < 65375) + c[i] = (char)(c[i] - 65248); + } + return new string(c); + } + + #region Cut String + + /// + /// 裁剪字符串,对Substring方法的改良,参数超出范围不抛出异常 + /// 若裁剪起始位置startIndex超出字符串长度,则返回空字符串,若裁剪长度length超出范围,则返回从startIndex开始的全部字符 + /// + /// + /// + /// + /// + public static string CutString(string s, int startIndex, int length) + { + //若裁剪起始位置超出字符串长度,则返回空字符串 + if (startIndex >= s.Length) return string.Empty; + + //字符串裁剪后的剩余长度 + int remainLength = s.Length - startIndex; + + if (length > remainLength) + return s.Substring(startIndex); + else + return s.Substring(startIndex, length); + } + + /// + /// 截断右边多余字符串 + /// + /// 字符串 + /// 保留字符串长度 + /// 截断后的字符串 + public static string CutRight(string s, int length) + { + return CutRight(s, length, "..."); + } + + /// + /// 截断右边多余字符串 + /// + /// 字符串 + /// 保留字符串长度 + /// 截断部分替代字符 + /// 截断后的字符串 + public static string CutRight(string s, int length, string suffix) + { + if (length < GetBitLength(s)) + { + return (GetLeftByteString(s, length) + suffix); + } + return s; + } + + /// + /// 获取字符串字节长度,中文字符算2个字符 + /// + /// 字符串 + /// 字符串长度 + [Obsolete("请改用GetByteLength方法")] + public static int GetBitLength(string s) + { + return Encoding.Default.GetBytes(s).Length; + } + + /// + /// 获取字符串长度,字节长度,一个中文字符长度为2 + /// + /// + /// 字符串编码 + /// + public static int GetByteLength(string s, Encoding encoding) + { + return encoding.GetByteCount(s); + } + + /// + /// 获取字符串长度,字节长度,一个中文字符长度为2 + /// + /// + /// + public static int GetByteLength(string s) + { + return GetByteLength(s, Encoding.Default); + } + + /// + /// 截断右边多余字符串 + /// + /// 字符串 + /// 字节长度 + /// 处理后的字符串 + public static string GetLeftByteString(string s, int byteLength) + { + char[] arr; + if (s.Length <= (byteLength / 2)) + { + return s; + } + StringBuilder sb = new StringBuilder(); + int num = 0; + if (s.Length < byteLength) + { + arr = s.ToCharArray(); + } + else + { + arr = s.ToCharArray(0, byteLength); + } + foreach (char ch in arr) + { + if (ch > '\x007f') + { + num += 2; + } + else + { + num++; + } + sb.Append(ch); + if (num >= byteLength) + { + break; + } + } + return sb.ToString(); + } + + #endregion + + /// + /// 返回指定加密哈希算法的字符串的副本 + /// + /// + /// 哈希算法 + /// + public static string ToHash(string s, HashAlgorithmType hashAlgorithm) + { + return HashCryto.GetHash2String(s, hashAlgorithm); + } + + /// + /// 判断字符串是否都是有空白字符组成,空字符串将返回false + /// + /// 如果该字符串都是空白字符,返回true ,否则返回false + public static bool IsWhiteSpace(string s) + { + if (s == null) + throw new ArgumentNullException("s"); + + if (s.Length == 0) + return false; + + for (int i = 0; i < s.Length; i++) + { + if (!char.IsWhiteSpace(s[i])) + return false; + } + + return true; + } + + /// + /// 判断字符串是否含有空白字符 + /// + /// 如果该字符串含有空白字符,返回true ,否则返回false + public static bool HasWhiteSpace(string s) + { + if (s == null) + throw new ArgumentNullException("s"); + + for (int i = 0; i < s.Length; i++) + { + if (char.IsWhiteSpace(s[i])) + return true; + } + return false; + } + + /// + /// 向字符串结尾附加换行符 + /// + /// + /// + public static string AppendNewLine(string s) + { + if (s == null) + throw new ArgumentNullException("s"); + + return s + Environment.NewLine; + } + + /// + /// 反转字符串,如:字符串“ABC”,反转后为“CBA” + /// + /// + public static string Reverse(string s) + { + if (string.IsNullOrEmpty(s)) + return s; + + char[] characters = s.ToCharArray(); + Array.Reverse(characters); + return new string(characters); + } + + /// + /// 将字符串编码成16进制字符串,比如12345->3132333435;张三->D5C5C8FD,使用当前系统默认编码 + /// + /// + /// + /// + public static string ToHexString(string s, Encoding encoding) + { + byte[] data = encoding.GetBytes(s); + string result = ByteUtil.ToHex(data); + return result; + } + + /// + /// 将字符串编码成16进制字符串,比如12345->3132333435;张三->D5C5C8FD,使用当前系统默认编码 + /// + /// + /// + public static string ToHexString(string s) + { + return ToHexString(s, Encoding.Default); + } + + /// + /// 将16进制编码字符串还原成编码前的字符串,比如:D5C5C8FD->张三,3132333435->12345,使用当前系统默认编码 + /// + /// + /// + /// + public static string FromHexString(string s, Encoding encoding) + { + List list = new List(); + + for (int i = 0; i < s.Length; i = i + 2) + { + string c = s.Substring(i, 2); + byte b = Convert.ToByte(c, 16); + list.Add(b); + } + + string result = encoding.GetString(list.ToArray()); + return result; + } + + /// + /// 将16进制编码字符串还原成编码前的字符串,比如:D5C5C8FD->张三,3132333435->12345,使用当前系统默认编码 + /// + /// + /// + public static string FromHexString(string s) + { + return FromHexString(s, Encoding.Default); + } + + /// + /// Base64加密 + /// + /// + /// + public static string Base64Encode(string s) + { + return Base64Encode(s, Encoding.Default); + } + + /// + /// Base64加密 + /// + /// + /// + /// + public static string Base64Encode(string s, Encoding encoding) + { + byte[] data = encoding.GetBytes(s); + return Convert.ToBase64String(data); + } + + /// + /// Base64解密 + /// + /// + /// + public static string Base64Decode(string s) + { + return Base64Decode(s, Encoding.Default); + } + + /// + /// Base64解密 + /// + /// + /// + /// + public static string Base64Decode(string s, Encoding encoding) + { + byte[] data = Convert.FromBase64String(s); + return encoding.GetString(data); + } + } +} diff --git a/src/Kalman/Utilities/TypeUtil.cs b/src/Kalman/Utilities/TypeUtil.cs new file mode 100644 index 0000000..f6337ad --- /dev/null +++ b/src/Kalman/Utilities/TypeUtil.cs @@ -0,0 +1,561 @@ +using System; +using System.Collections.Generic; +using System.Data; + +namespace Kalman.Utilities +{ + /// + /// + /// + public sealed class TypeUtil + { + /// + /// 获取对应的SqlServer特定数据类型 + /// + /// + /// + public static SqlDbType DbType2SqlDbType(DbType dbType) + { + switch (dbType) + { + case DbType.AnsiString: + return SqlDbType.VarChar; + case DbType.AnsiStringFixedLength: + return SqlDbType.Char; + case DbType.Binary: + return SqlDbType.VarBinary; + case DbType.Boolean: + return SqlDbType.Bit; + case DbType.Byte: + return SqlDbType.TinyInt; + case DbType.Currency: + return SqlDbType.Money; + case DbType.Date: + return SqlDbType.DateTime; + case DbType.DateTime: + return SqlDbType.DateTime; + case DbType.Decimal: + return SqlDbType.Decimal; + case DbType.Double: + return SqlDbType.Float; + case DbType.Guid: + return SqlDbType.UniqueIdentifier; + case DbType.Int16: + return SqlDbType.Int; + case DbType.Int32: + return SqlDbType.Int; + case DbType.Int64: + return SqlDbType.BigInt; + case DbType.Object: + return SqlDbType.Variant; + case DbType.SByte: + return SqlDbType.TinyInt; + case DbType.Single: + return SqlDbType.Real; + case DbType.String: + return SqlDbType.NVarChar; + case DbType.StringFixedLength: + return SqlDbType.NChar; + case DbType.Time: + return SqlDbType.DateTime; + case DbType.UInt16: + return SqlDbType.Int; + case DbType.UInt32: + return SqlDbType.Int; + case DbType.UInt64: + return SqlDbType.BigInt; + case DbType.VarNumeric: + return SqlDbType.Decimal; + + default: + return SqlDbType.VarChar; + } + } + + /// + /// 获取对应的数据类型 + /// + /// type由数据库元数据中定义的DataType转换而来 + /// + public static DbType Type2DbType(Type dataType) + { + DbType result; + + if (dataType == typeof(Int32)) + result = DbType.Int32; + else if (dataType == typeof(Int16)) + result = DbType.Int16; + else if (dataType == typeof(Int64)) + result = DbType.Int64; + + else if (dataType == typeof(DateTime)) + result = DbType.DateTime; + else if (dataType == typeof(float)) + result = DbType.Decimal; + else if (dataType == typeof(decimal)) + result = DbType.Decimal; + else if (dataType == typeof(double)) + result = DbType.Double; + else if (dataType == typeof(Guid)) + result = DbType.Guid; + else if (dataType == typeof(bool)) + result = DbType.Boolean; + else if (dataType == typeof(byte[])) + result = DbType.Byte; + else + result = DbType.String; + + return result; + } + + public static DbType OleDbADataType2DbType(string nativeType) + { + switch (nativeType.ToLower()) + { + case "11": + return DbType.Boolean; + + case "16": + case "17": + return DbType.Byte; + + case "128": + return DbType.Binary; + + case "6": + case "14": + case "131": + return DbType.Decimal; + + case "7": + case "133": + case "134": + case "135": + case "64": + return DbType.DateTime; + + case "5": + return DbType.Double; + + case "72": + return DbType.Guid; + + case "9": + case "13": + case "138": + case "12": + return DbType.Object; + + case "2": + return DbType.Int16; + + case "18": + return DbType.UInt16; + + case "3": + return DbType.Int32; + + case "19": + return DbType.UInt32; + + case "20": + return DbType.Int64; + + case "21": + return DbType.UInt64; + + case "4": + return DbType.Single; + } + return DbType.String; + } + + /// + /// 将System.Data.DbType类型转换为对应System.Type类型字符串 + /// + /// + /// + public static string DbType2TypeString(DbType dbType) + { + switch (dbType) + { + case DbType.AnsiString: + case DbType.AnsiStringFixedLength: + case DbType.String: + case DbType.StringFixedLength: + return "String"; + case DbType.Binary: + return "byte[]"; + case DbType.Boolean: + return "Boolean"; + case DbType.Byte://? + return "int"; + case DbType.Currency: + return "double"; + case DbType.Date: + return "Timestamp"; + case DbType.DateTime: + return "Timestamp"; + case DbType.DateTime2: + return "Timestamp"; + //case DbType.DateTimeOffset: + // return "DateTime"; + case DbType.Decimal: + return "BigDecimal"; + case DbType.Double: + return "double"; + case DbType.Guid: + return "Guid"; + case DbType.Int16: + return "short"; + case DbType.Int32: + return "int"; + case DbType.Int64: + return "long"; + case DbType.Object: + return "object"; + case DbType.SByte: + return "sbyte"; + case DbType.Single: + return "Single"; + case DbType.Time: + return "Timestamp"; + case DbType.UInt16: + return "UInt16"; + case DbType.UInt32: + return "UInt32"; + case DbType.UInt64: + return "UInt64"; + case DbType.VarNumeric: + return "BigDecimal"; + case DbType.Xml: + return "String"; + default: + return "String"; + } + } + + /// + /// 将System.Data.DbType类型转换为对应System.Type类型 + /// + /// + /// + public static Type DbType2Type(DbType dbType) + { + switch (dbType) + { + case DbType.String: + return typeof(string); + case DbType.UInt64: + return typeof(UInt64); + case DbType.Int64: + return typeof(Int64); + case DbType.Int32: + return typeof(Int32); + case DbType.UInt32: + return typeof(UInt32); + case DbType.Single: + return typeof(float); + case DbType.Date: + return typeof(DateTime); + case DbType.DateTime: + return typeof(DateTime); + case DbType.Time: + return typeof(DateTime); + case DbType.StringFixedLength: + return typeof(string); + case DbType.UInt16: + return typeof(UInt16); + case DbType.Int16: + return typeof(Int16); + case DbType.SByte: + return typeof(byte); + case DbType.Object: + return typeof(object); + case DbType.AnsiString: + return typeof(string); + case DbType.AnsiStringFixedLength: + return typeof(string); + case DbType.VarNumeric: + return typeof(decimal); + case DbType.Currency: + return typeof(double); + case DbType.Binary: + return typeof(byte[]); + case DbType.Decimal: + return typeof(decimal); + case DbType.Double: + return typeof(Double); + case DbType.Guid: + return typeof(Guid); + case DbType.Boolean: + return typeof(bool); + default: + return typeof(DBNull); + } //end switch + } + + #region 将不同数据库的数据类型转换成System.Data.DbType + + /// + /// 将数据库的原生数据类型转换成System.Data.DbType + /// 参考:http://msdn.microsoft.com/en-us/library/cc716729.aspx + /// + /// 数据库原生类型 + /// + public static DbType SqlServerDataType2DbType(string nativeType) + { + string type = nativeType.ToLower(); + if (nativeType.IndexOf('(') != -1) + {//如果原始类型类似varchar(50),decimal(10,2),则去掉括号内容 + type = type.Split('(')[0]; + } + + switch (type) + { + case "varchar": + return DbType.AnsiString; + case "nvarchar": + return DbType.String; + case "int": + return DbType.Int32; + case "uniqueidentifier": + return DbType.Guid; + case "datetime": + case "datetime2": + return DbType.DateTime; + case "bigint": + return DbType.Int64; + case "binary": + return DbType.Binary; + case "bit": + return DbType.Boolean; + case "char": + return DbType.AnsiStringFixedLength; + case "decimal": + return DbType.Decimal; + case "float": + return DbType.Double; + case "image": + return DbType.Binary; + case "money": + return DbType.Currency; + case "nchar": + return DbType.String; + case "ntext": + return DbType.String; + case "numeric": + return DbType.Decimal; + case "real": + return DbType.Single; + case "smalldatetime": + return DbType.DateTime; + case "smallint": + return DbType.Int16; + case "smallmoney": + return DbType.Currency; + case "sql_variant": + return DbType.String; + case "sysname": + return DbType.String; + case "text": + return DbType.AnsiString; + case "timestamp": + return DbType.Binary; + case "tinyint": + return DbType.Byte; + case "varbinary": + return DbType.Binary; + default: + return DbType.AnsiString; + } + } + + /// + /// 将数据库的原生数据类型转换成System.Data.DbType + /// + /// 数据库原生类型 + /// + public static DbType MySqlDataType2DbType(string nativeType) + { + switch (nativeType.ToLower()) + { + case "bit": + return DbType.Boolean; + + case "tinyint": + return DbType.SByte; + + case "smallint": + return DbType.Int16; + + case "enum": + return DbType.UInt16; + + case "mediumint": //占三个字节 + case "int": + case "year": //YYYY + return DbType.Int32; + + case "binary": + case "varbinary": + case "tinyblob": + case "mediumblob": + case "blob": + case "longblob": + return DbType.Binary; + + case "date": + case "time": + case "datetime": + case "timestamp": + return DbType.DateTime; + + //case "guid": + //case "uniqueidentifier": + // return DbType.Guid; + + case "decimal": + return DbType.Decimal; + + + case "bigint": + return DbType.Int64; + + case "double": + case "float": + case "real": + return DbType.Single; + + default: + return DbType.String; + } + } + + /// + /// 将数据库的原生数据类型转换成System.Data.DbType + /// 参考:http://msdn.microsoft.com/en-us/library/yk72thhd%28VS.80%29.aspx + /// http://msdn.microsoft.com/en-us/library/cc716726.aspx + /// + /// 数据库原生类型 + /// + public static DbType OracleDataType2DbType(string nativeType, int precision = 0, int scale = 0) + { + string type = nativeType.ToUpper(); + if (nativeType.IndexOf('(') != -1) + { + type = type.Split(new char[] { '(' })[0]; + } + switch (type) + { + case "INTEGER": + return DbType.Int32; + + case "NUMBER": + return DbType.Decimal; + case "LOG": + case "BFILE": + case "LONG RAW": + case "RAW": + case "BLOB": + return DbType.Binary; + + case "DATE": + case "TIMESTAMP": + return DbType.DateTime; + } + return DbType.String; + } + + /// + /// 将数据库的原生数据类型转换成System.Data.DbType + /// 参考: + /// + /// 数据库原生类型 + /// + public static DbType DB2DataType2DbType(string nativeType) + { + return DbType.String; + } + + /// + /// 将数据库的原生数据类型转换成System.Data.DbType + /// 参考: + /// + /// 数据库原生类型 + /// + public static DbType SQLiteDataType2DbType(string nativeType) + { + switch (nativeType.ToLower()) + { + case "bool": + case "boolean": + case "bit": + case "yesno": + case "logical": + return DbType.Boolean; + + case "tinyint": + return DbType.Byte; + + case "binary": + case "varbinary": + case "image": + case "graphic": + case "blob": + case "general": + return DbType.Binary; + + case "date": + case "time": + case "datetime": + case "datetext": + case "timestamp": + return DbType.DateTime; + + case "guid": + case "uniqueidentifier": + return DbType.Guid; + + case "smallint": + return DbType.Int16; + + case "int": + return DbType.Int32; + + case "autoinc": + case "autoincrement": + case "bigint": + case "counter": + case "identity": + case "int64": + case "integer": + case "long": + return DbType.Int64; + + case "dec": + case "decimal": + case "float": + case "money": + case "number": + case "numeric": + case "real": + case "smallmoney": + return DbType.Single; + + default: + return DbType.String; + } + } + + /// + /// 将数据库的原生数据类型转换成System.Data.DbType + /// + /// 数据库原生类型 + /// + //public static DbType DataType2DbType(string nativeType) + //{ + //} + #endregion + } +} diff --git a/src/Kalman/Web/ResponseFile.cs b/src/Kalman/Web/ResponseFile.cs new file mode 100644 index 0000000..0c3b0e2 --- /dev/null +++ b/src/Kalman/Web/ResponseFile.cs @@ -0,0 +1,92 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Web; +using System.IO; + +namespace Kalman.Web +{ + /// + /// 向客户端输出文件 + /// + public class ResponseFile + { + private HttpResponse response = HttpContext.Current.Response; + + public ResponseFile() + { + response = HttpContext.Current.Response; + + // 清空当前 HTTP 响应流(RESPONSE) + response.Clear(); + // 设置当前 HTTP 响应流(RESPONSE)的骗码. + response.Charset = "utf-8"; + // 设置缓冲输入. + response.Buffer = true; + // 设置内容类型 + response.ContentType = "application/octet-stream"; + // 设置当前 HTTP 响应流(RESPONSE)内容编码. + response.ContentEncoding = System.Text.Encoding.UTF8; + } + + /// + /// 获取或设置输出流的HTTP字符集,默认"utf-8" + /// + public string Charset + { + get { return response.Charset; } + set { response.Charset = value; } + } + + /// + /// 获取或设置一个值,该值指示是否缓冲输出,并在完成处理整个响应之后将其发送,默认true + /// + public bool Buffer + { + get { return response.Buffer; } + set { response.Buffer = value; } + } + + /// + /// 获取或设置输出流的 HTTP MIME 类型,默认"application/octet-stream" + /// + public string ContentType + { + get { return response.ContentType; } + set { response.ContentType = value; } + } + + /// + /// 获取或设置输出流的 HTTP 字符集,默认 + /// + public Encoding ContentEncoding + { + get { return response.ContentEncoding; } + set { response.ContentEncoding = value; } + } + + /// + /// 输出文件 + /// + /// 文件物理路径 + /// + public void Export(string path, string outputFilename) + { + // 判断是否为Firefox浏览器 + if (!HttpContext.Current.Request.Browser.Browser.Equals("Firefox")) + { + // 文件名编码处理 + outputFilename = HttpContext.Current.Server.UrlEncode(outputFilename); + } + + // 设置当前 HTTP 响应头.如果是下载,加上 attachment + response.AppendHeader("Content-Disposition", "attachment;filename=" + outputFilename); + // 文件写入响应流以便下载 + response.BinaryWrite(File.ReadAllBytes(path)); + // 向客户端清除当前所有缓存输出. + response.Flush(); + // 停止执行该页. + response.End(); + } + } +} diff --git a/src/Kalman/WebCacher.cs b/src/Kalman/WebCacher.cs new file mode 100644 index 0000000..e581afc --- /dev/null +++ b/src/Kalman/WebCacher.cs @@ -0,0 +1,252 @@ +using System; +using System.Collections; +using System.Text.RegularExpressions; +using System.Web; +using System.Web.Caching; + +namespace Kalman +{ + /// + /// + /// + public class WebCacher + { + /// + /// DayFactor + /// + public static readonly int DayFactor = 17280; + /// + /// HourFactor + /// + public static readonly int HourFactor = 720; + /// + /// MinuteFactor + /// + public static readonly int MinuteFactor = 12; + /// + /// SecondFactor + /// + public static readonly double SecondFactor = 0.2; + + private static readonly Cache _cache; + + private static int Factor = 5; + + /// + /// + /// + /// + public static void ReSetFactor(int cacheFactor) + { + Factor = cacheFactor; + } + + /// + /// ȷǰHttpContextֻһCacheʵ + /// + static WebCacher() + { + HttpContext context = HttpContext.Current; + if (context != null) + { + _cache = context.Cache; + } + else + { + _cache = HttpRuntime.Cache; + } + } + + /// + /// Cache + /// + public static void Clear() + { + IDictionaryEnumerator CacheEnum = _cache.GetEnumerator(); + + while (CacheEnum.MoveNext()) + { + _cache.Remove(CacheEnum.Key.ToString()); + } + } + + /// + /// ʽģʽƳCache + /// + /// ģʽ + public static void RemoveByPattern(string pattern) + { + IDictionaryEnumerator CacheEnum = _cache.GetEnumerator(); + Regex regex = new Regex(pattern, RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.Compiled); + while (CacheEnum.MoveNext()) + { + if (regex.IsMatch(CacheEnum.Key.ToString())) + _cache.Remove(CacheEnum.Key.ToString()); + } + } + + /// + /// ݼֵƳCache + /// + /// + public static void Remove(string key) + { + _cache.Remove(key); + } + + /// + /// ѶصCache + /// + /// + /// + public static void Insert(string key, object obj) + { + Insert(key, obj, null, 1); + } + + /// + /// ѶصCache,ӻϢ + /// + /// + /// + /// + public static void Insert(string key, object obj, CacheDependency dep) + { + Insert(key, obj, dep, MinuteFactor * 3); + } + + /// + /// ѶصCache,ӹʱϢ + /// + /// + /// + /// + public static void Insert(string key, object obj, int seconds) + { + Insert(key, obj, null, seconds); + } + + /// + /// ѶصCache,ӹʱϢȼ + /// + /// + /// + /// + /// + public static void Insert(string key, object obj, int seconds, CacheItemPriority priority) + { + Insert(key, obj, null, seconds, priority); + } + + /// + /// ѶصCache,ӻ͹ʱ() + /// (ĬȼΪNormal) + /// + /// + /// + /// + /// + public static void Insert(string key, object obj, CacheDependency dep, int seconds) + { + Insert(key, obj, dep, seconds, CacheItemPriority.Normal); + } + + /// + /// ѶصCache,ӻ͹ʱ()ȼ + /// + /// + /// + /// + /// + /// + public static void Insert(string key, object obj, CacheDependency dep, int seconds, CacheItemPriority priority) + { + if (obj != null) + { + _cache.Insert(key, obj, dep, DateTime.Now.AddSeconds(Factor * seconds), TimeSpan.Zero, priority, null); + } + + } + + /// + /// Ѷӵ沢ȼ + /// + /// + /// + /// + public static void MicroInsert(string key, object obj, int secondFactor) + { + if (obj != null) + { + _cache.Insert(key, obj, null, DateTime.Now.AddSeconds(Factor * secondFactor), TimeSpan.Zero); + } + } + + /// + /// Ѷӵ,ѹʱΪֵ + /// + /// + /// + public static void Max(string key, object obj) + { + Max(key, obj, null); + } + + /// + /// Ѷӵ,ѹʱΪֵ,ӻϢ + /// + /// + /// + /// + public static void Max(string key, object obj, CacheDependency dep) + { + if (obj != null) + { + _cache.Insert(key, obj, dep, DateTime.MaxValue, TimeSpan.Zero, CacheItemPriority.AboveNormal, null); + } + } + + /// + /// ־Ի + /// + /// + /// + public static void Permanent(string key, object obj) + { + Permanent(key, obj, null); + } + + /// + /// ־Ի,ӻ + /// + /// + /// + /// + public static void Permanent(string key, object obj, CacheDependency dep) + { + if (obj != null) + { + _cache.Insert(key, obj, dep, DateTime.MaxValue, TimeSpan.Zero, CacheItemPriority.NotRemovable, null); + } + } + + /// + /// ݼȡĶ + /// + /// + /// + public static object Get(string key) + { + return _cache[key]; + } + + /// + /// Return int of seconds * SecondFactor + /// + public static int SecondFactorCalculate(int seconds) + { + // Insert method below takes integer seconds, so we have to round any fractional values + return Convert.ToInt32(Math.Round((double)seconds * SecondFactor)); + } + } +} diff --git a/src/Kalman/packages.config b/src/Kalman/packages.config new file mode 100644 index 0000000..1391ebb --- /dev/null +++ b/src/Kalman/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file