From 5b4ef14e049de27535c18d41b7e3e59bd70510b6 Mon Sep 17 00:00:00 2001 From: Matt Meents Date: Tue, 12 Sep 2023 00:10:40 -0400 Subject: [PATCH] Initial Commit --- Coder.sln | 25 + Coder/App.config | 6 + Coder/Form1.Designer.cs | 735 +++++++++++ Coder/Form1.cs | 378 ++++++ Coder/Form1.resx | 302 +++++ Coder/Models/CObjects.cs | 264 ++++ Coder/Models/CryptoKey.cs | 88 ++ Coder/Models/Exceptions.cs | 22 + Coder/Models/Extensions.cs | 256 ++++ Coder/Models/IniFiles.cs | 1553 ++++++++++++++++++++++++ Coder/Models/ItemCaster.cs | 535 ++++++++ Coder/Models/TypeCaster.cs | 180 +++ Coder/Program.cs | 19 + Coder/Prompter.csproj | 132 ++ Coder/Properties/AssemblyInfo.cs | 36 + Coder/Properties/Resources.Designer.cs | 63 + Coder/Properties/Resources.resx | 117 ++ Coder/Properties/Settings.Designer.cs | 26 + Coder/Properties/Settings.settings | 7 + Coder/flame-_1_.ico | Bin 0 -> 1150 bytes 20 files changed, 4744 insertions(+) create mode 100644 Coder.sln create mode 100644 Coder/App.config create mode 100644 Coder/Form1.Designer.cs create mode 100644 Coder/Form1.cs create mode 100644 Coder/Form1.resx create mode 100644 Coder/Models/CObjects.cs create mode 100644 Coder/Models/CryptoKey.cs create mode 100644 Coder/Models/Exceptions.cs create mode 100644 Coder/Models/Extensions.cs create mode 100644 Coder/Models/IniFiles.cs create mode 100644 Coder/Models/ItemCaster.cs create mode 100644 Coder/Models/TypeCaster.cs create mode 100644 Coder/Program.cs create mode 100644 Coder/Prompter.csproj create mode 100644 Coder/Properties/AssemblyInfo.cs create mode 100644 Coder/Properties/Resources.Designer.cs create mode 100644 Coder/Properties/Resources.resx create mode 100644 Coder/Properties/Settings.Designer.cs create mode 100644 Coder/Properties/Settings.settings create mode 100644 Coder/flame-_1_.ico diff --git a/Coder.sln b/Coder.sln new file mode 100644 index 0000000..3a1716c --- /dev/null +++ b/Coder.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.6.33815.320 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Prompter", "Coder\Prompter.csproj", "{DD3E6F4C-042E-4511-929D-4477727CC879}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {DD3E6F4C-042E-4511-929D-4477727CC879}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DD3E6F4C-042E-4511-929D-4477727CC879}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DD3E6F4C-042E-4511-929D-4477727CC879}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DD3E6F4C-042E-4511-929D-4477727CC879}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {34C3BEEE-190F-4786-8991-C75BDC4441AC} + EndGlobalSection +EndGlobal diff --git a/Coder/App.config b/Coder/App.config new file mode 100644 index 0000000..193aecc --- /dev/null +++ b/Coder/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Coder/Form1.Designer.cs b/Coder/Form1.Designer.cs new file mode 100644 index 0000000..03a8f33 --- /dev/null +++ b/Coder/Form1.Designer.cs @@ -0,0 +1,735 @@ +namespace Prompter { + partial class Form1 { + /// + /// 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(Form1)); + this.tabControl1 = new System.Windows.Forms.TabControl(); + this.tabPage1 = new System.Windows.Forms.TabPage(); + this.edError = new System.Windows.Forms.TextBox(); + this.button2 = new System.Windows.Forms.Button(); + this.button1 = new System.Windows.Forms.Button(); + this.label2 = new System.Windows.Forms.Label(); + this.label1 = new System.Windows.Forms.Label(); + this.edPassword = new System.Windows.Forms.TextBox(); + this.edFileName = new System.Windows.Forms.TextBox(); + this.tabPage2 = new System.Windows.Forms.TabPage(); + this.scRoot = new System.Windows.Forms.SplitContainer(); + this.tvTools = new System.Windows.Forms.TreeView(); + this.imageList1 = new System.Windows.Forms.ImageList(this.components); + this.panel1 = new System.Windows.Forms.Panel(); + this.scRoot2 = new System.Windows.Forms.SplitContainer(); + this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components); + this.deleteToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.saveToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.contextMenuStrip2 = new System.Windows.Forms.ContextMenuStrip(this.components); + this.clearToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.copyToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.pasteToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.odMain = new System.Windows.Forms.OpenFileDialog(); + this.panel3 = new System.Windows.Forms.Panel(); + this.props = new PropertyGridEx.PropertyGridEx(); + this.splitContainer1 = new System.Windows.Forms.SplitContainer(); + this.tabControl2 = new System.Windows.Forms.TabControl(); + this.tabPage3 = new System.Windows.Forms.TabPage(); + this.edOutput = new FastColoredTextBoxNS.FastColoredTextBox(); + this.tabPage4 = new System.Windows.Forms.TabPage(); + this.edInput = new FastColoredTextBoxNS.FastColoredTextBox(); + this.tvBuilder = new System.Windows.Forms.TreeView(); + this.panel2 = new System.Windows.Forms.Panel(); + this.parseToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.label3 = new System.Windows.Forms.Label(); + this.btnPaste = new System.Windows.Forms.Button(); + this.btnClear = new System.Windows.Forms.Button(); + this.btnInput = new System.Windows.Forms.Button(); + this.cbPrompt = new System.Windows.Forms.CheckBox(); + this.tabControl1.SuspendLayout(); + this.tabPage1.SuspendLayout(); + this.tabPage2.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.scRoot)).BeginInit(); + this.scRoot.Panel1.SuspendLayout(); + this.scRoot.Panel2.SuspendLayout(); + this.scRoot.SuspendLayout(); + this.panel1.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.scRoot2)).BeginInit(); + this.scRoot2.Panel1.SuspendLayout(); + this.scRoot2.Panel2.SuspendLayout(); + this.scRoot2.SuspendLayout(); + this.contextMenuStrip1.SuspendLayout(); + this.contextMenuStrip2.SuspendLayout(); + this.panel3.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); + this.splitContainer1.Panel1.SuspendLayout(); + this.splitContainer1.Panel2.SuspendLayout(); + this.splitContainer1.SuspendLayout(); + this.tabControl2.SuspendLayout(); + this.tabPage3.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.edOutput)).BeginInit(); + this.tabPage4.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.edInput)).BeginInit(); + this.panel2.SuspendLayout(); + this.SuspendLayout(); + // + // tabControl1 + // + 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.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); + this.tabControl1.Name = "tabControl1"; + this.tabControl1.SelectedIndex = 0; + this.tabControl1.Size = new System.Drawing.Size(1022, 854); + this.tabControl1.TabIndex = 0; + this.tabControl1.SelectedIndexChanged += new System.EventHandler(this.tabControl1_SelectedIndexChanged); + this.tabControl1.Selecting += new System.Windows.Forms.TabControlCancelEventHandler(this.tabControl1_Selecting); + // + // tabPage1 + // + this.tabPage1.Controls.Add(this.edError); + this.tabPage1.Controls.Add(this.button2); + this.tabPage1.Controls.Add(this.button1); + this.tabPage1.Controls.Add(this.label2); + this.tabPage1.Controls.Add(this.label1); + this.tabPage1.Controls.Add(this.edPassword); + this.tabPage1.Controls.Add(this.edFileName); + this.tabPage1.Location = new System.Drawing.Point(4, 32); + this.tabPage1.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); + this.tabPage1.Name = "tabPage1"; + this.tabPage1.Padding = new System.Windows.Forms.Padding(3, 4, 3, 4); + this.tabPage1.Size = new System.Drawing.Size(1012, 923); + this.tabPage1.TabIndex = 0; + this.tabPage1.Text = "Setup"; + this.tabPage1.UseVisualStyleBackColor = true; + // + // edError + // + this.edError.Location = new System.Drawing.Point(89, 519); + this.edError.Multiline = true; + this.edError.Name = "edError"; + this.edError.Size = new System.Drawing.Size(809, 182); + this.edError.TabIndex = 6; + this.edError.Visible = false; + this.edError.WordWrap = false; + // + // button2 + // + this.button2.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(192)))), ((int)(((byte)(255)))), ((int)(((byte)(255))))); + this.button2.FlatAppearance.BorderColor = System.Drawing.Color.DodgerBlue; + this.button2.FlatAppearance.MouseDownBackColor = System.Drawing.Color.Cyan; + this.button2.FlatAppearance.MouseOverBackColor = System.Drawing.Color.Teal; + this.button2.Location = new System.Drawing.Point(376, 276); + this.button2.Name = "button2"; + this.button2.Size = new System.Drawing.Size(111, 45); + this.button2.TabIndex = 5; + this.button2.Text = "Open"; + this.button2.UseVisualStyleBackColor = false; + this.button2.Click += new System.EventHandler(this.button2_Click); + // + // button1 + // + this.button1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(192)))), ((int)(((byte)(255)))), ((int)(((byte)(255))))); + this.button1.FlatAppearance.BorderColor = System.Drawing.Color.DodgerBlue; + this.button1.FlatAppearance.MouseDownBackColor = System.Drawing.Color.Cyan; + this.button1.FlatAppearance.MouseOverBackColor = System.Drawing.Color.Teal; + this.button1.Location = new System.Drawing.Point(836, 109); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(75, 30); + this.button1.TabIndex = 4; + this.button1.Text = "Open"; + this.button1.UseVisualStyleBackColor = false; + this.button1.Click += new System.EventHandler(this.button1_Click); + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(85, 163); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(114, 23); + this.label2.TabIndex = 3; + this.label2.Text = "File Password:"; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(68, 112); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(131, 23); + this.label1.TabIndex = 2; + this.label1.Text = "Coder data file: "; + // + // edPassword + // + this.edPassword.Location = new System.Drawing.Point(205, 163); + this.edPassword.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); + this.edPassword.Name = "edPassword"; + this.edPassword.Size = new System.Drawing.Size(163, 30); + this.edPassword.TabIndex = 1; + this.edPassword.Text = "mm"; + // + // edFileName + // + this.edFileName.Location = new System.Drawing.Point(205, 109); + this.edFileName.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); + this.edFileName.Name = "edFileName"; + this.edFileName.Size = new System.Drawing.Size(625, 30); + this.edFileName.TabIndex = 0; + this.edFileName.Text = "C:\\ProgramData\\MMCommons\\Prompter001.cdf"; + // + // tabPage2 + // + this.tabPage2.Controls.Add(this.scRoot); + this.tabPage2.Location = new System.Drawing.Point(4, 32); + this.tabPage2.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); + this.tabPage2.Name = "tabPage2"; + this.tabPage2.Padding = new System.Windows.Forms.Padding(3, 4, 3, 4); + this.tabPage2.Size = new System.Drawing.Size(1014, 818); + this.tabPage2.TabIndex = 1; + this.tabPage2.Text = "Builder"; + this.tabPage2.UseVisualStyleBackColor = true; + // + // scRoot + // + this.scRoot.Dock = System.Windows.Forms.DockStyle.Fill; + this.scRoot.Location = new System.Drawing.Point(3, 4); + this.scRoot.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); + this.scRoot.Name = "scRoot"; + // + // scRoot.Panel1 + // + this.scRoot.Panel1.Controls.Add(this.tvTools); + this.scRoot.Panel1.Controls.Add(this.panel1); + // + // scRoot.Panel2 + // + this.scRoot.Panel2.Controls.Add(this.scRoot2); + this.scRoot.Size = new System.Drawing.Size(1008, 810); + this.scRoot.SplitterDistance = 232; + this.scRoot.TabIndex = 1; + // + // tvTools + // + this.tvTools.AllowDrop = true; + this.tvTools.Dock = System.Windows.Forms.DockStyle.Fill; + this.tvTools.ImageIndex = 0; + this.tvTools.ImageList = this.imageList1; + this.tvTools.Location = new System.Drawing.Point(0, 88); + this.tvTools.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); + this.tvTools.Name = "tvTools"; + this.tvTools.SelectedImageIndex = 0; + this.tvTools.Size = new System.Drawing.Size(232, 722); + this.tvTools.TabIndex = 1; + this.tvTools.ItemDrag += new System.Windows.Forms.ItemDragEventHandler(this.tvTools_ItemDrag); + this.tvTools.DragOver += new System.Windows.Forms.DragEventHandler(this.tvTools_DragOver); + // + // imageList1 + // + this.imageList1.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageList1.ImageStream"))); + this.imageList1.TransparentColor = System.Drawing.Color.Transparent; + this.imageList1.Images.SetKeyName(0, "collection-710-16.png"); + this.imageList1.Images.SetKeyName(1, "server-38-16.png"); + this.imageList1.Images.SetKeyName(2, "server-53-16.png"); + this.imageList1.Images.SetKeyName(3, "folder-457-16.png"); + this.imageList1.Images.SetKeyName(4, "coupon-316-16.png"); + this.imageList1.Images.SetKeyName(5, "data-331-16.png"); + this.imageList1.Images.SetKeyName(6, "gift-551-16 (1).png"); + this.imageList1.Images.SetKeyName(7, "find-228-16.png"); + this.imageList1.Images.SetKeyName(8, "scanning-92-16.png"); + this.imageList1.Images.SetKeyName(9, "news-773-16.png"); + this.imageList1.Images.SetKeyName(10, "lookup-61-16.png"); + this.imageList1.Images.SetKeyName(11, "gift-551-16.png"); + this.imageList1.Images.SetKeyName(12, "add-50-16.png"); + this.imageList1.Images.SetKeyName(13, "play-277-16.png"); + this.imageList1.Images.SetKeyName(14, "stop-62-16.png"); + this.imageList1.Images.SetKeyName(15, "delete-1203-16.png"); + this.imageList1.Images.SetKeyName(16, "label-387-16.png"); + this.imageList1.Images.SetKeyName(17, "share-978-16.png"); + this.imageList1.Images.SetKeyName(18, "set-up-1014-16.png"); + this.imageList1.Images.SetKeyName(19, "flame-_1_.ico"); + // + // panel1 + // + this.panel1.Controls.Add(this.btnPaste); + this.panel1.Controls.Add(this.btnClear); + this.panel1.Controls.Add(this.btnInput); + this.panel1.Dock = System.Windows.Forms.DockStyle.Top; + this.panel1.Location = new System.Drawing.Point(0, 0); + this.panel1.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(232, 88); + this.panel1.TabIndex = 0; + // + // scRoot2 + // + this.scRoot2.Dock = System.Windows.Forms.DockStyle.Fill; + this.scRoot2.Location = new System.Drawing.Point(0, 0); + this.scRoot2.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); + this.scRoot2.Name = "scRoot2"; + this.scRoot2.Orientation = System.Windows.Forms.Orientation.Horizontal; + // + // scRoot2.Panel1 + // + this.scRoot2.Panel1.Controls.Add(this.splitContainer1); + this.scRoot2.Panel1.Controls.Add(this.panel3); + // + // scRoot2.Panel2 + // + this.scRoot2.Panel2.Controls.Add(this.props); + this.scRoot2.Size = new System.Drawing.Size(772, 810); + this.scRoot2.SplitterDistance = 596; + this.scRoot2.TabIndex = 0; + this.scRoot2.SplitterMoved += new System.Windows.Forms.SplitterEventHandler(this.scRoot2_SplitterMoved); + // + // contextMenuStrip1 + // + this.contextMenuStrip1.ImageScalingSize = new System.Drawing.Size(20, 20); + this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.deleteToolStripMenuItem, + this.saveToolStripMenuItem}); + this.contextMenuStrip1.Name = "contextMenuStrip1"; + this.contextMenuStrip1.Size = new System.Drawing.Size(123, 52); + this.contextMenuStrip1.Opening += new System.ComponentModel.CancelEventHandler(this.contextMenuStrip1_Opening); + // + // deleteToolStripMenuItem + // + this.deleteToolStripMenuItem.Name = "deleteToolStripMenuItem"; + this.deleteToolStripMenuItem.Size = new System.Drawing.Size(122, 24); + this.deleteToolStripMenuItem.Text = "Delete"; + this.deleteToolStripMenuItem.Click += new System.EventHandler(this.deleteToolStripMenuItem_Click); + // + // saveToolStripMenuItem + // + this.saveToolStripMenuItem.Name = "saveToolStripMenuItem"; + this.saveToolStripMenuItem.Size = new System.Drawing.Size(122, 24); + this.saveToolStripMenuItem.Text = "Save"; + // + // contextMenuStrip2 + // + this.contextMenuStrip2.ImageScalingSize = new System.Drawing.Size(20, 20); + this.contextMenuStrip2.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.clearToolStripMenuItem, + this.copyToolStripMenuItem, + this.pasteToolStripMenuItem, + this.parseToolStripMenuItem}); + this.contextMenuStrip2.Name = "contextMenuStrip2"; + this.contextMenuStrip2.Size = new System.Drawing.Size(113, 100); + this.contextMenuStrip2.Opening += new System.ComponentModel.CancelEventHandler(this.contextMenuStrip2_Opening); + // + // clearToolStripMenuItem + // + this.clearToolStripMenuItem.Name = "clearToolStripMenuItem"; + this.clearToolStripMenuItem.Size = new System.Drawing.Size(112, 24); + this.clearToolStripMenuItem.Text = "Clear"; + this.clearToolStripMenuItem.Click += new System.EventHandler(this.btnClear_Click); + // + // copyToolStripMenuItem + // + this.copyToolStripMenuItem.Name = "copyToolStripMenuItem"; + this.copyToolStripMenuItem.Size = new System.Drawing.Size(112, 24); + this.copyToolStripMenuItem.Text = "Copy"; + this.copyToolStripMenuItem.Click += new System.EventHandler(this.copyToolStripMenuItem_Click); + // + // pasteToolStripMenuItem + // + this.pasteToolStripMenuItem.Name = "pasteToolStripMenuItem"; + this.pasteToolStripMenuItem.Size = new System.Drawing.Size(112, 24); + this.pasteToolStripMenuItem.Text = "Paste"; + this.pasteToolStripMenuItem.Click += new System.EventHandler(this.pasteToolStripMenuItem_Click); + // + // odMain + // + this.odMain.CheckFileExists = false; + this.odMain.DefaultExt = "cdf"; + // + // panel3 + // + this.panel3.Controls.Add(this.label3); + this.panel3.Dock = System.Windows.Forms.DockStyle.Top; + this.panel3.Location = new System.Drawing.Point(0, 0); + this.panel3.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); + this.panel3.Name = "panel3"; + this.panel3.Size = new System.Drawing.Size(772, 60); + this.panel3.TabIndex = 2; + // + // props + // + // + // + // + this.props.DocCommentDescription.AutoEllipsis = true; + this.props.DocCommentDescription.Cursor = System.Windows.Forms.Cursors.Default; + this.props.DocCommentDescription.Location = new System.Drawing.Point(4, 29); + this.props.DocCommentDescription.Margin = new System.Windows.Forms.Padding(32, 0, 32, 0); + this.props.DocCommentDescription.Name = ""; + this.props.DocCommentDescription.Size = new System.Drawing.Size(764, 40); + this.props.DocCommentDescription.TabIndex = 1; + this.props.DocCommentImage = null; + // + // + // + this.props.DocCommentTitle.Cursor = System.Windows.Forms.Cursors.Default; + this.props.DocCommentTitle.Font = new System.Drawing.Font("Segoe UI", 10.2F, System.Drawing.FontStyle.Bold); + this.props.DocCommentTitle.Location = new System.Drawing.Point(4, 4); + this.props.DocCommentTitle.Margin = new System.Windows.Forms.Padding(32, 0, 32, 0); + this.props.DocCommentTitle.Name = ""; + this.props.DocCommentTitle.Size = new System.Drawing.Size(764, 25); + this.props.DocCommentTitle.TabIndex = 0; + this.props.DocCommentTitle.UseMnemonic = false; + this.props.Dock = System.Windows.Forms.DockStyle.Fill; + this.props.Location = new System.Drawing.Point(0, 0); + this.props.Margin = new System.Windows.Forms.Padding(4, 7, 4, 7); + this.props.Name = "props"; + this.props.Size = new System.Drawing.Size(772, 210); + this.props.TabIndex = 1; + // + // + // + this.props.ToolStrip.AccessibleName = "Property Grid"; + this.props.ToolStrip.AccessibleRole = System.Windows.Forms.AccessibleRole.ToolBar; + this.props.ToolStrip.AllowMerge = false; + this.props.ToolStrip.AutoSize = false; + this.props.ToolStrip.CanOverflow = false; + this.props.ToolStrip.Dock = System.Windows.Forms.DockStyle.None; + this.props.ToolStrip.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden; + this.props.ToolStrip.ImageScalingSize = new System.Drawing.Size(20, 20); + this.props.ToolStrip.Location = new System.Drawing.Point(0, 1); + this.props.ToolStrip.Name = ""; + this.props.ToolStrip.Padding = new System.Windows.Forms.Padding(21, 0, 14, 0); + this.props.ToolStrip.Size = new System.Drawing.Size(772, 31); + this.props.ToolStrip.TabIndex = 1; + this.props.ToolStrip.TabStop = true; + this.props.ToolStrip.Text = "PropertyGridToolBar"; + this.props.PropertyValueChanged += new System.Windows.Forms.PropertyValueChangedEventHandler(this.props_PropertyValueChanged); + // + // splitContainer1 + // + this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill; + this.splitContainer1.Location = new System.Drawing.Point(0, 60); + this.splitContainer1.Name = "splitContainer1"; + // + // splitContainer1.Panel1 + // + this.splitContainer1.Panel1.Controls.Add(this.panel2); + this.splitContainer1.Panel1.Controls.Add(this.tvBuilder); + // + // splitContainer1.Panel2 + // + this.splitContainer1.Panel2.Controls.Add(this.tabControl2); + this.splitContainer1.Size = new System.Drawing.Size(772, 536); + this.splitContainer1.SplitterDistance = 257; + this.splitContainer1.TabIndex = 3; + // + // tabControl2 + // + this.tabControl2.Controls.Add(this.tabPage3); + this.tabControl2.Controls.Add(this.tabPage4); + this.tabControl2.Dock = System.Windows.Forms.DockStyle.Fill; + this.tabControl2.Location = new System.Drawing.Point(0, 0); + this.tabControl2.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); + this.tabControl2.Name = "tabControl2"; + this.tabControl2.SelectedIndex = 0; + this.tabControl2.Size = new System.Drawing.Size(511, 536); + this.tabControl2.TabIndex = 4; + this.tabControl2.SelectedIndexChanged += new System.EventHandler(this.tabControl2_SelectedIndexChanged); + // + // tabPage3 + // + this.tabPage3.Controls.Add(this.edOutput); + this.tabPage3.Location = new System.Drawing.Point(4, 32); + this.tabPage3.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); + this.tabPage3.Name = "tabPage3"; + this.tabPage3.Padding = new System.Windows.Forms.Padding(3, 4, 3, 4); + this.tabPage3.Size = new System.Drawing.Size(503, 500); + this.tabPage3.TabIndex = 0; + this.tabPage3.Text = "Ouput"; + this.tabPage3.UseVisualStyleBackColor = true; + // + // edOutput + // + this.edOutput.AutoCompleteBracketsList = new char[] { + '(', + ')', + '{', + '}', + '[', + ']', + '\"', + '\"', + '\'', + '\''}; + this.edOutput.AutoIndentCharsPatterns = ""; + this.edOutput.AutoScrollMinSize = new System.Drawing.Size(0, 21); + this.edOutput.BackBrush = null; + this.edOutput.CharHeight = 19; + this.edOutput.CharWidth = 10; + this.edOutput.CommentPrefix = "--"; + this.edOutput.ContextMenuStrip = this.contextMenuStrip2; + this.edOutput.Cursor = System.Windows.Forms.Cursors.IBeam; + this.edOutput.DisabledColor = System.Drawing.Color.FromArgb(((int)(((byte)(100)))), ((int)(((byte)(180)))), ((int)(((byte)(180)))), ((int)(((byte)(180))))); + this.edOutput.Dock = System.Windows.Forms.DockStyle.Fill; + this.edOutput.Font = new System.Drawing.Font("Courier New", 10.2F); + this.edOutput.IsReplaceMode = false; + this.edOutput.LeftBracket = '('; + this.edOutput.Location = new System.Drawing.Point(3, 4); + this.edOutput.Name = "edOutput"; + this.edOutput.Paddings = new System.Windows.Forms.Padding(0, 2, 0, 0); + this.edOutput.RightBracket = ')'; + this.edOutput.SelectionColor = System.Drawing.Color.FromArgb(((int)(((byte)(60)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(255))))); + this.edOutput.ServiceColors = ((FastColoredTextBoxNS.ServiceColors)(resources.GetObject("edOutput.ServiceColors"))); + this.edOutput.Size = new System.Drawing.Size(497, 492); + this.edOutput.TabIndex = 0; + this.edOutput.WordWrap = true; + this.edOutput.Zoom = 100; + // + // tabPage4 + // + this.tabPage4.Controls.Add(this.edInput); + this.tabPage4.Location = new System.Drawing.Point(4, 32); + this.tabPage4.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); + this.tabPage4.Name = "tabPage4"; + this.tabPage4.Padding = new System.Windows.Forms.Padding(3, 4, 3, 4); + this.tabPage4.Size = new System.Drawing.Size(758, 576); + this.tabPage4.TabIndex = 1; + this.tabPage4.Text = "Input"; + this.tabPage4.UseVisualStyleBackColor = true; + // + // edInput + // + this.edInput.AutoCompleteBracketsList = new char[] { + '(', + ')', + '{', + '}', + '[', + ']', + '\"', + '\"', + '\'', + '\''}; + this.edInput.AutoIndentCharsPatterns = "\r\n^\\s*[\\w\\.]+(\\s\\w+)?\\s*(?=)\\s*(?[^;]+);\r\n^\\s*(case|default)\\s*[^:]" + + "*(?:)\\s*(?[^;]+);\r\n"; + this.edInput.AutoScrollMinSize = new System.Drawing.Size(2, 21); + this.edInput.BackBrush = null; + this.edInput.BracketsHighlightStrategy = FastColoredTextBoxNS.BracketsHighlightStrategy.Strategy2; + this.edInput.CharHeight = 19; + this.edInput.CharWidth = 10; + this.edInput.ContextMenuStrip = this.contextMenuStrip2; + this.edInput.Cursor = System.Windows.Forms.Cursors.IBeam; + this.edInput.DisabledColor = System.Drawing.Color.FromArgb(((int)(((byte)(100)))), ((int)(((byte)(180)))), ((int)(((byte)(180)))), ((int)(((byte)(180))))); + this.edInput.Dock = System.Windows.Forms.DockStyle.Fill; + this.edInput.Font = new System.Drawing.Font("Courier New", 10.2F); + this.edInput.IsReplaceMode = false; + this.edInput.LeftBracket = '('; + this.edInput.LeftBracket2 = '{'; + this.edInput.Location = new System.Drawing.Point(3, 4); + this.edInput.Name = "edInput"; + this.edInput.Paddings = new System.Windows.Forms.Padding(0, 2, 0, 0); + this.edInput.RightBracket = ')'; + this.edInput.RightBracket2 = '}'; + this.edInput.SelectionColor = System.Drawing.Color.FromArgb(((int)(((byte)(60)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(255))))); + this.edInput.ServiceColors = ((FastColoredTextBoxNS.ServiceColors)(resources.GetObject("edInput.ServiceColors"))); + this.edInput.Size = new System.Drawing.Size(752, 568); + this.edInput.TabIndex = 0; + this.edInput.Zoom = 100; + // + // tvBuilder + // + this.tvBuilder.AllowDrop = true; + this.tvBuilder.ContextMenuStrip = this.contextMenuStrip1; + this.tvBuilder.Dock = System.Windows.Forms.DockStyle.Bottom; + this.tvBuilder.ImageIndex = 0; + this.tvBuilder.ImageList = this.imageList1; + this.tvBuilder.Location = new System.Drawing.Point(0, -51); + this.tvBuilder.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); + this.tvBuilder.Name = "tvBuilder"; + this.tvBuilder.SelectedImageIndex = 0; + this.tvBuilder.Size = new System.Drawing.Size(257, 587); + this.tvBuilder.TabIndex = 3; + this.tvBuilder.BeforeExpand += new System.Windows.Forms.TreeViewCancelEventHandler(this.tvBuilder_BeforeExpand); + this.tvBuilder.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.tvBuilder_AfterSelect); + this.tvBuilder.DragDrop += new System.Windows.Forms.DragEventHandler(this.tvBuilder_DragDrop); + this.tvBuilder.DragEnter += new System.Windows.Forms.DragEventHandler(this.tvBuilder_DragEnter); + this.tvBuilder.DragOver += new System.Windows.Forms.DragEventHandler(this.tvBuilder_DragOver); + // + // panel2 + // + this.panel2.Controls.Add(this.cbPrompt); + this.panel2.Dock = System.Windows.Forms.DockStyle.Top; + this.panel2.Location = new System.Drawing.Point(0, 0); + this.panel2.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); + this.panel2.Name = "panel2"; + this.panel2.Size = new System.Drawing.Size(257, 28); + this.panel2.TabIndex = 4; + // + // parseToolStripMenuItem + // + this.parseToolStripMenuItem.Name = "parseToolStripMenuItem"; + this.parseToolStripMenuItem.Size = new System.Drawing.Size(112, 24); + this.parseToolStripMenuItem.Text = "Parse"; + this.parseToolStripMenuItem.Click += new System.EventHandler(this.btnInput_Click); + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(17, 19); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(55, 23); + this.label3.TabIndex = 3; + this.label3.Text = "label3"; + // + // btnPaste + // + this.btnPaste.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.btnPaste.Location = new System.Drawing.Point(160, 11); + this.btnPaste.Name = "btnPaste"; + this.btnPaste.Size = new System.Drawing.Size(69, 39); + this.btnPaste.TabIndex = 5; + this.btnPaste.Text = "Paste"; + this.btnPaste.UseVisualStyleBackColor = true; + this.btnPaste.Click += new System.EventHandler(this.pasteToolStripMenuItem_Click); + // + // btnClear + // + this.btnClear.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.btnClear.Location = new System.Drawing.Point(78, 12); + this.btnClear.Name = "btnClear"; + this.btnClear.Size = new System.Drawing.Size(77, 38); + this.btnClear.TabIndex = 4; + this.btnClear.Text = "Clear"; + this.btnClear.UseVisualStyleBackColor = true; + this.btnClear.Click += new System.EventHandler(this.btnClear_Click); + // + // btnInput + // + this.btnInput.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.btnInput.Location = new System.Drawing.Point(3, 12); + this.btnInput.Name = "btnInput"; + this.btnInput.Size = new System.Drawing.Size(69, 39); + this.btnInput.TabIndex = 3; + this.btnInput.Text = "Parse"; + this.btnInput.UseVisualStyleBackColor = true; + this.btnInput.Visible = false; + this.btnInput.Click += new System.EventHandler(this.btnInput_Click); + // + // cbPrompt + // + this.cbPrompt.AutoSize = true; + this.cbPrompt.Checked = true; + this.cbPrompt.CheckState = System.Windows.Forms.CheckState.Checked; + this.cbPrompt.Location = new System.Drawing.Point(20, -1); + this.cbPrompt.Name = "cbPrompt"; + this.cbPrompt.Size = new System.Drawing.Size(164, 27); + this.cbPrompt.TabIndex = 0; + this.cbPrompt.Text = "Generate Prompt"; + this.cbPrompt.UseVisualStyleBackColor = true; + // + // Form1 + // + this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 23F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(1022, 854); + this.Controls.Add(this.tabControl1); + this.Font = new System.Drawing.Font("Segoe UI", 10.2F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); + this.Name = "Form1"; + this.Text = "Prompter"; + this.Shown += new System.EventHandler(this.Form1_Shown); + this.Resize += new System.EventHandler(this.Form1_Resize); + this.tabControl1.ResumeLayout(false); + this.tabPage1.ResumeLayout(false); + this.tabPage1.PerformLayout(); + this.tabPage2.ResumeLayout(false); + this.scRoot.Panel1.ResumeLayout(false); + this.scRoot.Panel2.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.scRoot)).EndInit(); + this.scRoot.ResumeLayout(false); + this.panel1.ResumeLayout(false); + this.scRoot2.Panel1.ResumeLayout(false); + this.scRoot2.Panel2.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.scRoot2)).EndInit(); + this.scRoot2.ResumeLayout(false); + this.contextMenuStrip1.ResumeLayout(false); + this.contextMenuStrip2.ResumeLayout(false); + this.panel3.ResumeLayout(false); + this.panel3.PerformLayout(); + this.splitContainer1.Panel1.ResumeLayout(false); + this.splitContainer1.Panel2.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit(); + this.splitContainer1.ResumeLayout(false); + this.tabControl2.ResumeLayout(false); + this.tabPage3.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.edOutput)).EndInit(); + this.tabPage4.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.edInput)).EndInit(); + this.panel2.ResumeLayout(false); + this.panel2.PerformLayout(); + 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 scRoot; + private System.Windows.Forms.TreeView tvTools; + private System.Windows.Forms.Panel panel1; + private System.Windows.Forms.SplitContainer scRoot2; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.TextBox edPassword; + private System.Windows.Forms.TextBox edFileName; + private System.Windows.Forms.OpenFileDialog odMain; + private System.Windows.Forms.Button button1; + private System.Windows.Forms.Button button2; + private System.Windows.Forms.TextBox edError; + private System.Windows.Forms.ImageList imageList1; + private System.Windows.Forms.ContextMenuStrip contextMenuStrip1; + private System.Windows.Forms.ToolStripMenuItem deleteToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem saveToolStripMenuItem; + private System.Windows.Forms.ContextMenuStrip contextMenuStrip2; + private System.Windows.Forms.ToolStripMenuItem copyToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem pasteToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem clearToolStripMenuItem; + private System.Windows.Forms.Panel panel3; + private PropertyGridEx.PropertyGridEx props; + private System.Windows.Forms.SplitContainer splitContainer1; + private System.Windows.Forms.Panel panel2; + private System.Windows.Forms.TreeView tvBuilder; + private System.Windows.Forms.TabControl tabControl2; + private System.Windows.Forms.TabPage tabPage3; + private FastColoredTextBoxNS.FastColoredTextBox edOutput; + private System.Windows.Forms.TabPage tabPage4; + private FastColoredTextBoxNS.FastColoredTextBox edInput; + private System.Windows.Forms.ToolStripMenuItem parseToolStripMenuItem; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Button btnPaste; + private System.Windows.Forms.Button btnClear; + private System.Windows.Forms.Button btnInput; + private System.Windows.Forms.CheckBox cbPrompt; + } +} + diff --git a/Coder/Form1.cs b/Coder/Form1.cs new file mode 100644 index 0000000..6b61385 --- /dev/null +++ b/Coder/Form1.cs @@ -0,0 +1,378 @@ +using System; +using System.IO; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using Prompter.Models; +using System.Runtime.InteropServices; +using PropertyGridEx; +using static System.Net.Mime.MediaTypeNames; +using FastColoredTextBoxNS; + +namespace Prompter { + public partial class Form1:Form { + + private string _fileName; + private string _folder; + private CryptoKey _key; + private Types _types; + private ItemCaster _itemCaster; + private Item _inEditItem = null; + public Form1() { + InitializeComponent(); + } + + private void logMsg(string msg) { + if (!edError.Visible) edError.Visible = true; + edError.Text = msg+ Environment.NewLine+ edError.Text; + } + private void tabControl1_Selecting(object sender, TabControlCancelEventArgs e) { + if (e.TabPageIndex == 1) { + try { + _fileName = edFileName.Text; + int fnl = _fileName.ParseLast("\\").Length + 1; + _folder = _fileName.Substring(0, _fileName.Length - fnl); + string pw = edPassword.Text; + _key = new CryptoKey(); + _key.SetCryptoKey(pw); + _itemCaster = new ItemCaster(_key, _fileName); + e.Cancel= (!(pw.Length>0)) || (!(Directory.Exists(_folder))); + } catch (Exception ex) { + logMsg(ex.Message); + e.Cancel = true; + } + } + } + private void tabControl1_SelectedIndexChanged(object sender, EventArgs e) { + this.Text = (tabControl1.SelectedIndex == 0) ? "Prompter Setup":$"Prompter {_fileName}"; + if (tabControl1.SelectedIndex == 1) { + LoadtvTools(); + _itemCaster.LoadTreeviewItemsAsync(tvBuilder); + } + } + + private void LoadtvTools() { + _types=new Types(); + tvTools.Nodes.Clear(); + tvTools.Nodes.Add(_types[18]); + tvTools.Nodes.Add(_types[19]); + tvTools.Nodes.Add(_types[20]); + tvTools.Nodes.Add(_types[21]); + tvTools.Nodes.Add(_types[22]); + tvTools.Nodes.Add(_types[23]); + } + + private void button1_Click(object sender, EventArgs e) { + if (edFileName.Text == "") { + odMain.InitialDirectory = Ext.MMCommonsFolder(); + } else { + string s = edFileName.Text.ParseLast("/"); + odMain.InitialDirectory = edFileName.Text.Substring(0, s.Length); + } + DialogResult res = odMain.ShowDialog(); + if (res == DialogResult.OK) { + edFileName.Text = odMain.FileName; + } + } + + private void button2_Click(object sender, EventArgs e) { + tabControl1.SelectedIndex=1; + } + + private void tvTools_ItemDrag(object sender, ItemDragEventArgs e) { + if(e.Button==MouseButtons.Left) { + DoDragDrop(e.Item, DragDropEffects.Copy); + } + } + + private void tvTools_DragOver(object sender, DragEventArgs e) { + e.Effect = DragDropEffects.None; + } + + private void tvBuilder_BeforeExpand(object sender, TreeViewCancelEventArgs e) { + Item tn = (Item)e.Node; + if(tn!=null) { + var items = _itemCaster.GetOwnersItemsAsync(tn); + e.Cancel=false; + } + } + + private void tvBuilder_DragEnter(object sender, DragEventArgs e) { + e.Effect= DragDropEffects.None; + } + + private void tvBuilder_DragOver(object sender, DragEventArgs e) { + if(e.Data!=null) { + ItemType sn = (ItemType)e.Data.GetData(typeof(ItemType)); + if(sn!=null) { + Point targetPt = tvBuilder.PointToClient(new Point(e.X, e.Y)); + Item tn = (Item)tvBuilder.GetNodeAt(targetPt); + if(tn!=null) { + e.Effect=DragDropEffects.None; + if(!tn.IsExpanded) tn.Expand(); + + if(sn.TypeId==(int)TnType.Template&& ( tn.TypeId==(int)TnType.Project || tn.TypeId==(int)TnType.Template)) e.Effect=DragDropEffects.Copy; + if(sn.TypeId==(int)TnType.Chapters&&tn.TypeId==(int)TnType.Project) e.Effect=DragDropEffects.Copy; + if(sn.TypeId==(int)TnType.Chapter&&tn.TypeId==(int)TnType.Chapters) e.Effect=DragDropEffects.Copy; + if(sn.TypeId==(int)TnType.Section&&tn.TypeId==(int)TnType.Chapter) e.Effect=DragDropEffects.Copy; + if(sn.TypeId==(int)TnType.SubSection&& (tn.TypeId==(int)TnType.Section)||(tn.TypeId==(int)TnType.SubSection)) e.Effect=DragDropEffects.Copy; + + } else { + if(sn.TypeId==(int)TnType.Project) { + e.Effect=DragDropEffects.Copy; + } else { + e.Effect=DragDropEffects.None; + } + } + } + } + } + + private void tvBuilder_DragDrop(object sender, DragEventArgs e) { + Point targetPt = tvBuilder.PointToClient(new Point(e.X, e.Y)); + Item tn = (Item)tvBuilder.GetNodeAt(targetPt); + if(tn!=null&&e.Data!=null) { + ItemType draggedNode = (ItemType)e.Data.GetData(typeof(ItemType)); + if (draggedNode.TypeId==(int)TnType.Template&& (tn.TypeId==(int)TnType.Project||tn.TypeId==(int)TnType.Template)) { + var nn = _itemCaster.SaveNewItemFromType(tn, draggedNode); + } else if((draggedNode.TypeId==(int)TnType.SubSection)&&(tn.TypeId==(int)TnType.Section||tn.TypeId == (int)TnType.SubSection)) { + var nn = _itemCaster.SaveNewItemFromType(tn, draggedNode); + } else if((draggedNode.TypeId==(int)TnType.Section&&tn.TypeId==(int)TnType.Chapter)) { + var fnn=_itemCaster.SaveNewItemFromType(tn, draggedNode); + } else if((draggedNode.TypeId==(int)TnType.Chapters&&tn.TypeId==(int)TnType.Project)) { + var fnn = _itemCaster.SaveNewItemFromType(tn, draggedNode); + } else if((draggedNode.TypeId==(int)TnType.Chapter&&tn.TypeId==(int)TnType.Chapters)) { + var fnn = _itemCaster.SaveNewItemFromType(tn, draggedNode); + } + } else { + if(e.Data!=null) { + ItemType draggedNode = (ItemType)e.Data.GetData(typeof(ItemType)); + if(draggedNode!=null) { + if(draggedNode.TypeId==(int)TnType.Project) { + var newItem = _itemCaster.SaveNewItemFromType(null, draggedNode); + tvBuilder.Nodes.Add(newItem); + } + } + } + } + } + + private void tvBuilder_AfterSelect(object sender, TreeViewEventArgs e) { + if(e?.Node==null) return; + _inEditItem=(Item)e.Node; + if(_inEditItem==null) return; + ResetPropEditors(_inEditItem); + } + + private void ResetPropEditors(Item item) { + props.SelectedObject=item; + props.ShowCustomProperties=true; + + props.Item.Clear(); + if( + item.TypeId==(int)TnType.Project|| + item.TypeId==(int)TnType.Template|| + item.TypeId==(int)TnType.Chapters|| + item.TypeId==(int)TnType.Chapter|| + item.TypeId==(int)TnType.Section|| + item.TypeId==(int)TnType.SubSection + ) { + ItemType it = _types[item.TypeId]; + ItemType itCat = _types[it.CatagoryTypeId]; + var cp = new PropertyGridEx.CustomProperty("Name", item.Text, it.Readonly, itCat.Text, it.Desc, it.Visible); + props.Item.Add(cp); + + var al = _types.GetChildrenItems(43).ToArray(); + var customProperty = new PropertyGridEx.CustomProperty() { + Name="Prompt", Category=itCat.Text, Description=it.Desc, Value=_types[item.ValueTypeId].Name, + DisplayMember="Text", ValueMember="TypeId", Datasource=al, Visible=true, IsReadOnly=false, IsDropdownResizable=true + }; + props.Item.Add(customProperty); + } + + props.Refresh(); + + if(_inEditItem != null) { + PopulateEditors(_inEditItem); + } + ResetbtnInputVisibility(); + } + private void props_PropertyValueChanged(object s, PropertyValueChangedEventArgs e) { + if(_inEditItem!=null) { + foreach(CustomProperty y in props.Item) { + if(y.Name=="Name") { + if(Convert.ToString(y.Value)!=_inEditItem.Name) { + _inEditItem.Text=Convert.ToString(y.Value); + } + } else if(y.Name=="Prompt") { + if(Convert.ToInt32(y.SelectedValue)!=_inEditItem.ValueTypeId) { + _inEditItem.ValueTypeId=Convert.ToInt32(y.SelectedValue); + } + } + } + if(_inEditItem.Dirty) { + _itemCaster.SaveItem( _inEditItem ); + PopulateEditors(_inEditItem); + } + } + } + + private void contextMenuStrip1_Opening(object sender, CancelEventArgs e) { + if (_inEditItem == null) { e.Cancel = true; return; } + if (_inEditItem.Dirty ) { + saveToolStripMenuItem.Enabled = true; + } else { + saveToolStripMenuItem.Enabled = false; + } + if(_inEditItem.Nodes.Count==0) { + deleteToolStripMenuItem.Enabled = true; + } else { + deleteToolStripMenuItem.Enabled = false; + } + } + + private void deleteToolStripMenuItem_Click(object sender, EventArgs e) { + if(_inEditItem==null) return; + Item item = _inEditItem; + //DialogResult dr = MessageBox.Show($"Delete {item.Text} ", "Confirm Delete", MessageBoxButtons.OKCancel); + //if(dr==DialogResult.OK) { + Item ParentItem = (Item)item.Parent; + ParentItem.Nodes.Remove(item); + _itemCaster.RemoveItem(item); + tvBuilder.SelectedNode=ParentItem; + //} + } + + private void btnClear_Click(object sender, EventArgs e) { + FastColoredTextBox ed = tabControl2.SelectedIndex==0 ? edOutput : edInput; + ed.Text = ""; + } + + public void PopulateEditors(Item it) { + ProcessEditOut(it); + ResetbtnInputVisibility(); + label3.Text = (_inEditItem==null) ? "" : _inEditItem.Text; + } + private void ResetbtnInputVisibility() { + btnInput.Visible=(tabControl2.SelectedIndex==1); + btnInput.Enabled=(_inEditItem!=null)&&(edInput.Text.Length>0)&&( + _inEditItem.TypeId==(int)TnType.Template + ||_inEditItem.TypeId==(int)TnType.Chapters + ||_inEditItem.TypeId==(int)TnType.Chapter + ||_inEditItem.TypeId==(int)TnType.Section + ||_inEditItem.TypeId==(int)TnType.SubSection + ); + } + + private void tabControl2_SelectedIndexChanged(object sender, EventArgs e) { + ResetbtnInputVisibility(); + } + + private void btnInput_Click(object sender, EventArgs e) { + if(_inEditItem==null) { return;} + string content = edInput.Text; + int dropTypeId = _inEditItem.TypeId; + if (dropTypeId==(int)TnType.Project ||dropTypeId==(int)TnType.Template) { + _ = _itemCaster.SaveNewChildItemsFromText(_inEditItem, _types[(int)TnType.Template], content); + } else if(dropTypeId==(int)TnType.Chapters) { + _=_itemCaster.SaveNewChildItemsFromText(_inEditItem, _types[(int)TnType.Chapter], content); + } else if(dropTypeId==(int)TnType.Chapter) { + _=_itemCaster.SaveNewChildItemsFromText(_inEditItem, _types[(int)TnType.Section], content); + } else if(dropTypeId==(int)TnType.Section || dropTypeId==(int) TnType.SubSection) { + _=_itemCaster.SaveNewChildItemsFromText(_inEditItem, _types[(int)TnType.SubSection], content); + } + } + + private void contextMenuStrip2_Opening(object sender, CancelEventArgs e) { + FastColoredTextBox ed = tabControl2.SelectedIndex == 0 ? edOutput : edInput ; + string selection = ed.SelectedText; + copyToolStripMenuItem.Enabled = true; + pasteToolStripMenuItem.Enabled = true; + parseToolStripMenuItem.Enabled = (_inEditItem!=null)&&(edInput.Text.Length>0)&&( + _inEditItem.TypeId==(int)TnType.Template + ||_inEditItem.TypeId==(int)TnType.Chapters + ||_inEditItem.TypeId==(int)TnType.Chapter + ||_inEditItem.TypeId==(int)TnType.Section + ||_inEditItem.TypeId==(int)TnType.SubSection + ); + } + + private void copyToolStripMenuItem_Click(object sender, EventArgs e) { + FastColoredTextBox ed = tabControl2.SelectedIndex==0 ? edOutput: edInput; + if (ed.SelectedText.Length == 0) ed.SelectAll(); + Clipboard.SetText(ed.SelectedText); + } + + private void pasteToolStripMenuItem_Click(object sender, EventArgs e) { + if (tabControl2.SelectedIndex ==0) { + edOutput.Text = Clipboard.GetText(); + } else { + edInput.Text=Clipboard.GetText(); + } + ResetbtnInputVisibility(); + } + + private void ProcessEditOut(Item it) { + if (cbPrompt.Checked &&it.ValueTypeId>0) { + string promptTemplate = _types[it.ValueTypeId].Desc; + string GrandParent="", Parent="", Node = ""; + if(it.OwnerId>0) { + if(it.Parent!=null) { + Parent= it.Parent.Text; + if(((Item)it.Parent).OwnerId>0&&it.Parent.Parent!=null) { + GrandParent=it.Parent.Parent.Text; + } + } + } + edOutput.Text = promptTemplate.Replace("[NODE]", it.Text).Replace("[PARENT]", Parent).Replace("[GRANDPARENT]", GrandParent); + } else { + string s = it.Text+Cs.nl+Cs.nl; + if (it.OwnerId > 0) { + if (it.Parent !=null) { + s = it.Parent.Text + Cs.nl+Cs.nl+s; + if (((Item)it.Parent).OwnerId > 0 && it.Parent.Parent !=null) { + s = it.Parent.Parent.Text + Cs.nl+Cs.nl + s; + } + } + } + string tag = ""; + foreach(Item c in it.Nodes) { + string childContent = GetChildContent(c); + if(c.Text[0]=='[') { + tag = c.Text.Insert(1,"/"); + s = s + Cs.nl+ c.Text+Cs.nl+childContent+Cs.nl+tag; + } else { + s= s + Cs.nl + c.Text+Cs.nl+childContent+Cs.nl; + } + s= s+Cs.nl; + } + edOutput.Text = s+Cs.nl; + } + } + + private string GetChildContent(Item it) { + string s = ""; + foreach(Item c in it.Nodes) { + s = s + (s=="" ? c.Text:Cs.nl+c.Text); + } + return s; + } + + private void Form1_Resize(object sender, EventArgs e) { + tvBuilder.Height = splitContainer1.Height - panel2.Height - 2; + } + + private void Form1_Shown(object sender, EventArgs e) { + Form1_Resize(null, null); + } + + private void scRoot2_SplitterMoved(object sender, SplitterEventArgs e) { + tvBuilder.Height=splitContainer1.Height-panel2.Height-2; + } + } +} diff --git a/Coder/Form1.resx b/Coder/Form1.resx new file mode 100644 index 0000000..efe8c76 --- /dev/null +++ b/Coder/Form1.resx @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + 147, 17 + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w + LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 + ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAADW + FwAAAk1TRnQBSQFMAgEBFAEAAWABAAFgAQABEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo + AwABQAMAAWADAAEBAQABCAYAARgYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA + 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//8A/wD/AP8AOQAB9AEH + AfQC/wH0AQcB/zcAAbwBEAH0AfMC7AHzAfQBEQHwCQAB8QMUAf8KAAb0Af8KAAHtAhQB7AgAAbwBAAH3 + Af8BDwIAAQ8B/wH3AQAB8AcAAfEBEwIAAfQBFAH/BwAB8AEUBuwBEwFtBwAB8AEUAe8CAAG8ARQBBwUA + AfQBDgEAAbwB8gQAAfIBvAEAAQ4B/wUAAfEBEwEAAfABuwEAAfQBFAH/BgABFAgAARIB/wUAARIB6wYA + AewBEwQAAfcCAAHvAf8BEAIAARAB/wHvAgAB7wQAAfIBEwEAAfIBAAG6AbsBAAH0ARQB/wUAARQIAAHs + AfMEAAHzAewIAAH3AbwDAAEUAgABEAL0AhEC9AEPAgABEwMAAfMBFAIAAroBAAG6AgAB9AHqBQABFAMA + AfQEAAHsAfMEAAG8AQcCAAHyAtoBvAIAAfEB9wMAAQ4DAAFDBPQBEQMAAQ4DAAEUAf8DAAG7AboEAAEU + BQABFAMAAdoEAAHsAfMEAAG8AQcCAAHaAgAB2gIAAfEB9wMAAQ4EAAEQAvMBEAQAAQ4DAAEUAgABEwEU + Af8BuwG6AgAB7QGSBQABFAMAArsDAAHsAfMEAAG8AQcCAAHaAv8B2gIAAfEB9wMAARIFAAIPBQAB6gMA + AW0B/wG8Ae8B9AHsAQABvAEAAZIBbQYAARQEAAHaAfIIAAG8AQcCAAH/AtoB9AIAAfEB9wMAAQcMAAHw + AwAB7wHxAf8CFAHzAgABkgHqBwABFAUAAdoBuwEAAdoFAAH/ARIIAAFtAfIDAAH/AeoBAAERARAHAAFt + Af8DAAHyAZIFAAH3AeoIAAEUAf8FAAG7AtoGAAGSARQB9AQAAf8BEwHsBQAB/wEUAe8B7AYAARMB/wUA + AhQBbQHvAfIB7AHqCQAB9AUUAQABugHaAdsHAAH/ARIB6gH/AQABbQETAf8HAAH/AfQB8QUAAeoB/wgA + Af8B8AGSAfAdAAHzARMBFAHxCwAB/wEUAwAB7AH/OgAB8gIAAZIB/zwAAQcB7wsAAf8B9wStAfcB/xgA + Af8B7AQAAesB/xcAAbQIrQG0FgAB6wEVAf8EAAH/ARMB6hUAAYsKrQGLBAAB9AHvDgABEAHyCAAB9AcA + AfAFEwESAfEFAAG0DK0BtAMAAfQCAAH0CwAB7AHyCwAB8wQAAbwBbQH/BAAB/wHqAfEDAAH/Bq0C8wat + Af8CAAH0AQABEgEAARUJAAH/ARUMAAFDAf8DAAEUAgAB8AIAAfEBAAH/ARMDAAH3Bq0C/watAfcCAAH0 + AgAB/wIAAe8HAAHsAf8DAAEQBOwBEAMAAf8B7QMAARQCAAHaAgAB2gIAARQDAAetAv8HrQIAAfQEAAG8 + AgAB9AoAAewEAAHsCAABFAIAAdoCAAHaAgABFAMABK0B8wb/AfMErQIAAfQGAAESAQABFQkAAewEAAHs + CAABFAIAAdoCAAHaAgABFAMABK0B8wb/AfMErQIAAfQGAAESAQABFQkAAewEAAHsCAABFAIAAbsCAAG7 + AgABFAMAB60C/wetAgAB9AQAAbwCAAH0CgAB7AQAAewIAAEUCAABFAMAAfcGrQL/Bq0B9wIAAfQCAAH/ + AgAB7wcAAewB/wMAARAE7AEQAwAB/wHsAgABEwoUARMCAAH/Bq0C8watAf8CAAH0AQABEgEAARUJAAH/ + AUMMAAEVAf8EAAEUBgABFAUAAbQMrQG0AwAB9AIAAfQLAAHsAfIKAAHyAewFAAEUAfIE9AHwARMGAAGL + Cq0BiwQAAfQB7w4AARAB8ggAAfIBEAYAAf8B7QTsAZIIAAG1CK0BtBYAAewBQwH/BAAB/wFDAewXAAH/ + AfcErQH3Af8YAAH/AewEAAHsAf+YAAH/AfMB/wMAAfMB/wkAAf8BEwH0FAAB7wESBwAB8QS8AfAB/wcA + AfABFAHtAfACAAH/Ae0C6ggAAewB8gETAewMAAHvAxQBbQH/AQcB6gYAAf8BFAH3BAcB7wEUAfMGAAEU + CAAB6gH/BQAB7AIUAf8BAAH3BBQB8wYAARQB9wMAAfMBFAHxBwAB7QHyAgAB8wG7AgAB/wETBgABFAgA + AewB8wQAAZIB7wgAAf8BFAUAARMB8gYAARQB/wYAAewB9AIAAfMBuwMAARQGAAH0CAAB/wUAARMKAAFt + Af8DAAH0AeoHAAHzAW0GAAHsAfQCAAHzAbsDAAEUBgAB8gm7BQABEwIABdoDAAFtAf8DAAH3AfEIAAEU + BgAB7AH0AgAB/wHyAwABFAYAAf8I8wH0BQABEwoAAW0B/wMAAewB9AYAAdoBAAEUBgABEwkUAf8FAAHv + CAAB7wH/BAABEwIABtoB8AEAAW0B/wMAAgcFAAH/AdoBAAEUBQAB8wHsCAAB9AFtBQABFAgAAewB8wQA + ARMKAAFtAf8EAAEUAwAB/wHwAdoB/wLvBQAB/wETCPQB7AHvBQABEwH0BwABFAUAAewBvAkAARQFAAH3 + AesCAAK7Af8B8wEUBwAB8wHrAW0B7AESARMB7AJtAQcGAAH/ARMBFAFtAgAB9AIUAfEGAAHqCRQB8AYA + AfcBFAEHAfQB8gHqARMJAAH/ARQB7wEUARMB9wETAfQpAAH/AQcB7AGSAfQLAAH/AbwCAAHwAfT/ABoA + AbwEBwHwCwAB8QS8AfAB/woAAfAC7AEHCQAB7AgUARMGAAEUAe8EvAHvARQB8gcAAf8BFAH3BAcB7wEU + AfMHAAHyARQB9wL0Ae8BFAEHBgAB8wFtAgAB9AH/BAAB8QFtBAAB/wESBwABFAcAAe0B8gIAAfMBuwIA + Af8BEwYAAfIBEwYAAW0B7wUAAe8B8QIAAbsB8QUAARQEAAH/AeoHAAHsAfMGAAHsAfQCAAHzAbsDAAEU + BgABFAEAAbsBvAUAARQB/wQAAQcBFAH/BwACEwQAAf8B6gEAAfAD2gG6AQABkgHyBgAB7AH0AgAB8wG7 + AwABFAUAAfIB7AEAAfMC2gG7AwABvAHvBQAB/wHqAQABuwHxAwAB8wHsBQAB/wHqBwABkgHyBgAB7AH0 + AgAB/wHyAwABFAUAAZIB8gIAAdoB/wHwAdoCAAH/AeoFAAEHAewBAAG8AfMDAAH/ARIFAAH/AeoBAAH/ + ArwB9AIAAZIB8gYAARMJFAH/BAABkgHyAgAB8QG6AQAB2gH/AQAB/wHqBAAB7wHsAgAB9AH/BAABvAEU + BAAB/wHqAQAB/wLwAf8CAAGSAfIFAAHzAewIAAH0AW0EAAHyAewDAAG7AdoBugG7AQABvAHvBAABBwG8 + AgABuwHxBQABFAUAARQHAAGSAfIFAAH/ARMI9AHsAe8FAAEUBQAB8AHaAQABFAH/BAAB/wEUAf8HAAFt + AQcFAAETAfMGAAHsAfMGAAHzAesBbQHsARIBEwHsAm0BBwYAAfIBEwYAAW0B7wYAAfQB6gcTAQcHAAET + ARQE6gITCAAB/wEUAe8BFAETAfcBEwH0CAAB8gEUAfcC9AHvARQBBykAAf8BvAIAAfAB9AsAAfAC7AEH + mQAB9AEQAQAB7AgAAfQGAAH/AvQB/ycAAZICAAGSAf8MAAHvCgAB7wMAAfQBEgoTARIB9AUAAesBEwH/ + AgAB9AETAewEAAERAwAB8AHzBAABDgETBwAB7QH0BgAB9AHtBQABEQoUAREGAAESAf8BEwMSAf8BFAgA + AfAB8wYAARQDAAH0DgAC9A4AAfQEAAEUAgAC/wIAARQIAAHwAfMEAAH/AQABDgMAAfQOAAL0DgAB9AQA + ARQGAAEUCAAB8AHzCgAB9AMAAfIB7wHrAhMBbQHvAfIDAAL0DgAB9AMAAf8BFAYAARQB/wcAAfAB8woA + AfQFAAEPAhQBDwUAAvQOAAH0AgAB/wEUAfQGAAHzARQB/wYAAfAB8wEAAbwGAAEOAQAB9AEAAesB/wgA + Af8B6wEAAvQOAAH0AgABFAH0BAAB8ALaAQAB9AEUBgAB8AHzAQAB/wYAAW0BAAH0DgAC9A4AAfQCAAEU + AZIB8AH/AgAB2gEAAf8B8AHtARMGAAHwAfMBAAH/BgABbQEAAfQOAAL0DgAB9AMAAfIB7wHqAe0BAAH0 + AewB6gHvAfIHAAHxAfMBAAEVBhQBDgEAAfQCAAHvARAGAAEQAe8CAAL0DgAB9AYAARQCAAEUCgAB8QHz + AQAB/wYAAW0BAAH0AwAB6gEHAfIC9AHyAQcB6gMAAvQFAAEHBhMBEQgAAQcC7AHwCgAB8QHzAQAB/wYA + AW0BAAH0AQAB/woAAf8BAAL0BAAB/wEABhQBEgH0CAAB7AHtBwABbQMAAfEB8wEAAfQGAAEUBAAB7QH0 + BgAB9AHtBQABEQITAQ4BDxoAAfECAAHsAf8MAAHvCgAB7wMAAfQBEgMUAf8cAAH/AREBAAHsCAAB9AYA + Af8C9AH/FgABQgFNAT4HAAE+AwABKAMAAUADAAFgAwABAQEAAQEGAAEDFgAD/4EABv8B8AEPBv8B4AEH + AfwBHwH4AQ8B/AE/AcABAwH5AY8B4AEHAfEBjwGAAQEB8gFHAe8B8wLnAYABAQHlASMB7wHzAc8B8wGA + AQEBzAGzAe4B8wHMATMBgAEBAc4BewHuAfMBzQGzAYABAQHYATMB7gFzAcwBMwGAAQEBwAGnAe8BPwHM + ATMBgAEBAcABzwHvAZcBzwHzAYABAQHPAZ8B5wHHAeMBxwHAAQMB4AE/AeABRwHwAY8B4AEHAfgBfwL/ + AfwBPwH4AQ8G/wH8AR8G/wH+AX8B8AEPAv8B8AEPAv8B4AEHAv8B4wHHAv8BwAEDAc8B/wHPAfcB8AEP + AYABAQHDAf8BnwH9AeMBxwIAAcEB/wE/AfwB7QGnAgAByAF/ATgBHAHtAbcCAAHOAR8BewHeAe0BtwIA + Ac8BjwF7Ad4B7QG3AgABzwGPAXsB3gHtAbcCAAHOAR8BewHeAe8B9wIAAcgBfwE4ARwBwAEDAgABwQH/ + AT8B/AH3Ae8BgAEBAcMB/wGfAfkB8AEPAcABAwHPAf8BzwHzAfABHwHgAQcC/wHjAccC/wHwAQ8C/wHw + AQ8S/wHxAc8B+AL/AfMB+AEPAeEBhwH4AX8B+AEHAeABBwHvAfMB4QEDAfMBjwHmAWcB7wHzAc8B8wLn + AeYBdwHvAfcB3wH5Ac8B5wHmAXcB4AEHAdgBOQHPAfcB5gF3AeABBwHfAfkBzwHXAeABAwHvAfMB2AEJ + Ac8BlwHPAfMB7wHzAd8B+QHuAQcBwAEDAecB9wHPAfsB5gEPAeABBwHhAYcB4AEDAfABHwHwAQ8E/wH4 + AT8B+QGfIv8B8AE/AfgBDwH8AT8B4AEHAeABDwHgAQcB8AEPAcwB8wHPAe8B5gFnAucBzAH7Ac8B5wHm + AXcB6QHzAccB8wHIAScB5gF3AcgBcwHkAecBzwHnAeYBdwHMATMB5AHnAcgBZwHgAQMBzAGTAcwB8wHI + AWcBzwHzAc4BEwHMAfsB7wHnAcABAwHvAZMBxwHzAucB4AEHAucB4AEHAfABDwHwAQ8B8AEPBP8B+QGf + AfwBPxL/AeQBAAH8AT8E/wGAAQABwAEDAYABAQHxAY8CAAGHAeEBgAEBAfABDwEAATABPwH8AT8B/AH2 + AW8BAAEQAT8B/AE/AfwB9wHvAgABMAEMAT8B/ALnBAABPwH8AccB4wEAAfwBDwHwAT8B/AHPARMBAAH8 + AT8B/AE/AfwBwwFDAQAB/AE/AfwBPwH8AeEBBwIAASABBAE/AfwB/QG/AQAB/AIAATwBAQH8AT8BAAH8 + AR8B+AE4AQEB/gF/AQAB/AGHAeEBgQP/AYABAAHAAQMBgQP/AeQBAAH8AT8C/ws= + + + + 277, 17 + + + 463, 17 + + + 17, 17 + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdGYXN0Q29sb3JlZFRleHRCb3gsIFZlcnNpb249Mi4xNi4yNC4w + LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWZiOGFhMTJiOTk0ZWY2MWIMAwAAAFFTeXN0 + ZW0uRHJhd2luZywgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2Vu + PWIwM2Y1ZjdmMTFkNTBhM2EFAQAAACJGYXN0Q29sb3JlZFRleHRCb3hOUy5TZXJ2aWNlQ29sb3JzBgAA + ACg8Q29sbGFwc2VNYXJrZXJGb3JlQ29sb3I+a19fQmFja2luZ0ZpZWxkKDxDb2xsYXBzZU1hcmtlckJh + Y2tDb2xvcj5rX19CYWNraW5nRmllbGQqPENvbGxhcHNlTWFya2VyQm9yZGVyQ29sb3I+a19fQmFja2lu + Z0ZpZWxkJjxFeHBhbmRNYXJrZXJGb3JlQ29sb3I+a19fQmFja2luZ0ZpZWxkJjxFeHBhbmRNYXJrZXJC + YWNrQ29sb3I+a19fQmFja2luZ0ZpZWxkKDxFeHBhbmRNYXJrZXJCb3JkZXJDb2xvcj5rX19CYWNraW5n + RmllbGQEBAQEBAQUU3lzdGVtLkRyYXdpbmcuQ29sb3IDAAAAFFN5c3RlbS5EcmF3aW5nLkNvbG9yAwAA + ABRTeXN0ZW0uRHJhd2luZy5Db2xvcgMAAAAUU3lzdGVtLkRyYXdpbmcuQ29sb3IDAAAAFFN5c3RlbS5E + cmF3aW5nLkNvbG9yAwAAABRTeXN0ZW0uRHJhd2luZy5Db2xvcgMAAAACAAAABfz///8UU3lzdGVtLkRy + YXdpbmcuQ29sb3IEAAAABG5hbWUFdmFsdWUKa25vd25Db2xvcgVzdGF0ZQEAAAAJBwcDAAAACgAAAAAA + AAAAlgABAAH7/////P///woAAAAAAAAAAKQAAQAB+v////z///8KAAAAAAAAAACWAAEAAfn////8//// + CgAAAAAAAAAAjQABAAH4/////P///woAAAAAAAAAAKQAAQAB9/////z///8KAAAAAAAAAACWAAEACw== + + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdGYXN0Q29sb3JlZFRleHRCb3gsIFZlcnNpb249Mi4xNi4yNC4w + LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWZiOGFhMTJiOTk0ZWY2MWIMAwAAAFFTeXN0 + ZW0uRHJhd2luZywgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2Vu + PWIwM2Y1ZjdmMTFkNTBhM2EFAQAAACJGYXN0Q29sb3JlZFRleHRCb3hOUy5TZXJ2aWNlQ29sb3JzBgAA + ACg8Q29sbGFwc2VNYXJrZXJGb3JlQ29sb3I+a19fQmFja2luZ0ZpZWxkKDxDb2xsYXBzZU1hcmtlckJh + Y2tDb2xvcj5rX19CYWNraW5nRmllbGQqPENvbGxhcHNlTWFya2VyQm9yZGVyQ29sb3I+a19fQmFja2lu + Z0ZpZWxkJjxFeHBhbmRNYXJrZXJGb3JlQ29sb3I+a19fQmFja2luZ0ZpZWxkJjxFeHBhbmRNYXJrZXJC + YWNrQ29sb3I+a19fQmFja2luZ0ZpZWxkKDxFeHBhbmRNYXJrZXJCb3JkZXJDb2xvcj5rX19CYWNraW5n + RmllbGQEBAQEBAQUU3lzdGVtLkRyYXdpbmcuQ29sb3IDAAAAFFN5c3RlbS5EcmF3aW5nLkNvbG9yAwAA + ABRTeXN0ZW0uRHJhd2luZy5Db2xvcgMAAAAUU3lzdGVtLkRyYXdpbmcuQ29sb3IDAAAAFFN5c3RlbS5E + cmF3aW5nLkNvbG9yAwAAABRTeXN0ZW0uRHJhd2luZy5Db2xvcgMAAAACAAAABfz///8UU3lzdGVtLkRy + YXdpbmcuQ29sb3IEAAAABG5hbWUFdmFsdWUKa25vd25Db2xvcgVzdGF0ZQEAAAAJBwcDAAAACgAAAAAA + AAAAlgABAAH7/////P///woAAAAAAAAAAKQAAQAB+v////z///8KAAAAAAAAAACWAAEAAfn////8//// + CgAAAAAAAAAAjQABAAH4/////P///woAAAAAAAAAAKQAAQAB9/////z///8KAAAAAAAAAACWAAEACw== + + + + + + AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAAHYAAAB2AAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAHwAAAHMAAAAsAAAAAwAAAAIAAAApAAAAbgAAABwAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAZQAAAOoAAAAeAAAAMQAAAKEAAAChAAAAMAAAACAAAADmAAAAWwAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAZQAAAP8AAACPAAAAFAAAAO8AAAD/AAAA/wAAAO4AAAATAAAAkAAA + AP4AAABbAAAAAAAAAAAAAAAAAAAAIAAAAPUAAAD/AAAAYwAAAEUAAAD/AAAA/wAAAP8AAAD/AAAARAAA + AGQAAAD/AAAA8wAAABkAAAAAAAAAAAAAAI8AAAD/AAAA/wAAAIMAAAAXAAAA7AAAAP8AAAD/AAAA6wAA + ABUAAACHAAAA/wAAAP8AAACHAAAAAAAAAAAAAADZAAAA/wAAAP8AAADrAAAAIwAAAC0AAADnAAAA5wAA + AC0AAAAkAAAA7gAAAP8AAAD/AAAA0wAAAAAAAAAAAAAA+gAAAP8AAAD/AAAA/wAAAOMAAAAmAAAAIAAA + ACAAAAAmAAAA5AAAAP8AAAD/AAAA/wAAAPYAAAAAAAAAAAAAAPQAAAD/AAAA/wAAAP8AAAD/AAAA6QAA + ADQAAAA0AAAA6QAAAP8AAAD/AAAA/wAAAP8AAAD2AAAAAAAAAAAAAADNAAAA/wAAAP8AAAD/AAAA/wAA + AP8AAADwAAAA8AAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAyQAAAAAAAAAAAAAAbQAAAP8AAAD/AAAA/wAA + AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAFwAAAAAAAAAAAAAAAQAAADJAAAA/wAA + AOcAAADtAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAMIAAAACAAAAAAAAAAAAAAAAAAAAFgAA + ANYAAACDAAAAqgAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAANQAAAASAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAWAAAAJgAAAFEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAMcAAAAVAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAADAAAA2AAAAP8AAAD/AAAA/wAAALAAAAAJAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEcAAAD9AAAA/wAAAJoAAAADAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdwAAAIQAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA8A8AAOAHAADAAwAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAADAAwAA4AcAAPgP + AAD8HwAA/n8AAA== + + + \ No newline at end of file diff --git a/Coder/Models/CObjects.cs b/Coder/Models/CObjects.cs new file mode 100644 index 0000000..bc2bbcb --- /dev/null +++ b/Coder/Models/CObjects.cs @@ -0,0 +1,264 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.IO; + +namespace Prompter.Models { + public interface ICObjectItem { + string Key { get; set; } + string Value { get; set; } + } + public interface ICObject : IDictionary { + bool Contains(string key); + new ICObjectItem this[string key] { get; set; } + new void Remove(string key); + } + + public class CObject : ConcurrentDictionary, ICObject { + public CObject() : base() { } + public virtual Boolean Contains(String key) { + try { + return (!(base[key] is null)); + } catch { + return false; + } + } + public virtual new ICObjectItem this[string key] { + get { return Contains(key) ? base[key] : null; } + set { if (value != null) { base[key] = value; } else { Remove(key); } } + } + public virtual void Remove(string key) { if (Contains(key)) { _ = base.TryRemove(key, out _); } } + } + + public interface IVariableItem : ICObjectItem { + IVariables Owner { get; set; } + bool ValueChanged { get; set; } + string AsChunk(); + IVariableItem FromChunk(string chunk); + } + + public class CVariableItem : IVariableItem { + public CVariableItem(IVariables owner, string key, string value) { + Owner = owner; + Key = key; + _value = value; + } + public IVariables Owner { get; set; } + public string Key { get; set; } = string.Empty; + + private bool _valueChanged = false; + public bool ValueChanged { + get { return _valueChanged; } + set { + _valueChanged = value; + if (value) { + _valueChanged = false; + Owner[Key] = this; + } + } + } + + private string _value; + public string Value { + get { return _value; } + set { _value = value; ValueChanged = true; } + } + public string AsChunk() { + return $"{Key.AsBase64Encoded()} {Value.AsBase64Encoded()}".AsBase64Encoded(); + } + public virtual IVariableItem FromChunk(string chunk) { + string base1 = chunk.AsBase64Decoded(); + _valueChanged = false; + Key = base1.ParseFirst(" ").AsBase64Decoded(); + string val = base1.ParseString(" ", 1); + _value = string.IsNullOrEmpty(val) ? "" : val.AsBase64Decoded(); + return this; + } + } + + public interface IVariables : ICObject { + string FileName { get; set; } + void SetVarValue(string name, IVariableItem value); + IVariableItem GetVarValue(string name); + new IVariableItem this[string key] { get; set; } + } + + public class Variables : CObject, IVariables { + public Variables() : base() { } + public string FileName { get; set; } = string.Empty; + public virtual void SetVarValue(string key, IVariableItem value) { + if (!string.IsNullOrEmpty(FileName) && !string.IsNullOrEmpty(key)) { + if (value == null) { + RemoveVar(key); + } else { + IniFile f = IniFile.FromFile(FileName); + f["Variables"][key] = value.AsChunk(); + f.Save(FileName); + base[key] = value; + value.ValueChanged = false; + } + } + } + public virtual IVariableItem GetVarValue(string key) { + if (!string.IsNullOrEmpty(FileName) && !string.IsNullOrEmpty(key)) { + if (this.Contains(key)) { + if (base[key] is IVariableItem value) { + return value; + } + } + + IniFile f = IniFile.FromFile(FileName); + var itemChunk = f["Variables"][key]; + IVariableItem item = (itemChunk != null ? + new CVariableItem(this, key, "").FromChunk(itemChunk) : + new CVariableItem(this, key, "")); + this[key] = item; + return item; + } + throw new CryptoKeyNotSetException(); + } + + public void RemoveVar(string key) { + IniFile f = IniFile.FromFile(FileName); + f["Variables"].DeleteKey(key); + f.Save(FileName); + if (this.Contains(key)) { + _ = base.TryRemove(key, out _); + } + } + + public ReadOnlyCollection GetKeys() { + IniFile f = IniFile.FromFile(FileName); + return f["Variables"].GetKeys(); + } + + public new IVariableItem this[string key] { + get { return GetVarValue(key); } + set { SetVarValue(key, value); } + } + + + } + + + public interface ICryptoVarItem : IVariableItem { + new ICryptoVars Owner { get; set; } + new string AsChunk(); + new ICryptoVarItem FromChunk(string chunk); + } + + public class CryptoVarItem : CVariableItem, ICryptoVarItem { + public CryptoVarItem(ICryptoVars owner, string key, string value) : base(owner, key, value) { + Owner = owner; + } + public string encodedValue = ""; + public new ICryptoVars Owner { get; set; } + public new string AsChunk() { + return $"{Key.AsBase64Encoded()} {encodedValue}".AsBase64Encoded(); + } + public new ICryptoVarItem FromChunk(string chunk) { + string base1 = chunk.AsBase64Decoded(); + Key = base1.ParseFirst(" ").AsBase64Decoded(); + string val = base1.ParseString(" ", 1); + encodedValue = string.IsNullOrEmpty(val) ? "" : val; + return this; + } + + public new string Value { + get { + var cryptoKey = Owner?.EncryptionKey; + if ((!(cryptoKey is null)) && cryptoKey.HasCryptoKey) { + if (string.IsNullOrEmpty(encodedValue)) { + return ""; + } else { + return Task.Run(async () => await cryptoKey.AsDecipherStringAsync(encodedValue)).Result; + } + } + throw new CryptoKeyNotSetException(); + } + set { + var cryptoKey = Owner?.EncryptionKey; + if ((!(cryptoKey is null)) && cryptoKey.HasCryptoKey) { + encodedValue = string.IsNullOrEmpty(value) + ? "" : Task.Run(async () => await cryptoKey.ToCipherStringAsync(value)).Result; + ValueChanged = true; + } else + throw new CryptoKeyNotSetException(); + } + } + + private bool _valueChanged = false; + public new bool ValueChanged { + get { return _valueChanged; } + set { + _valueChanged = value; + if (value) { + _valueChanged = false; + Owner.SetVarValue(Key, this); + } + } + } + } + + public interface ICryptoVars : IVariables { + ICryptoKey EncryptionKey { get; set; } + void SetVarValue(string key, ICryptoVarItem value); + new ICryptoVarItem GetVarValue(string key); + } + + public class CryptoVars : Variables, ICryptoVars { + public ICryptoKey EncryptionKey { get; set; } + public CryptoVars(): base() { } + public void SetKey(CryptoKey cryptoKey) { + EncryptionKey = cryptoKey ?? throw new ArgumentNullException(nameof(cryptoKey)); + if (!string.IsNullOrEmpty(FileName) && File.Exists(FileName)) { + this.LoadValues(); + } + } + + public void SetVarValue(string key, ICryptoVarItem value) { + if (!string.IsNullOrEmpty(FileName) && (!(EncryptionKey is null)) && !string.IsNullOrEmpty(key)) { + if (value == null) { + RemoveVar(key); + } else { + base.SetVarValue(key, value); + } + } + } + + public new ICryptoVarItem GetVarValue(string key) { + if (!string.IsNullOrEmpty(FileName) && (!(EncryptionKey is null)) && !string.IsNullOrEmpty(key)) { + if (this.Contains(key)) { + var valueAtBase = base.GetVarValue(key); + if (valueAtBase is ICryptoVarItem item1) { + return item1; + } + } + + IniFile f = IniFile.FromFile(FileName); + var itemChunk = f["Variables"][key]; + ICryptoVarItem item = (itemChunk != null ? + new CryptoVarItem(this, key, "").FromChunk(itemChunk) : + new CryptoVarItem(this, key, "")); + this[key] = item; + return item; + } + throw new CryptoKeyNotSetException(); + } + + public void LoadValues() { + foreach (string key in this.GetKeys()) { + _ = this[key]; + } + } + public new ICryptoVarItem this[string key] { + get { return GetVarValue(key); } + set { SetVarValue(key, value); } + } + } + +} diff --git a/Coder/Models/CryptoKey.cs b/Coder/Models/CryptoKey.cs new file mode 100644 index 0000000..175ad0b --- /dev/null +++ b/Coder/Models/CryptoKey.cs @@ -0,0 +1,88 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Security.Cryptography; +using System.Text; +using System.Threading.Tasks; + +namespace Prompter.Models { + + public interface IHasCryptoKey { + bool HasCryptoKey { get; } + } + public interface ICryptoKey : IHasCryptoKey { + void SetCryptoKey(string cryptoKey); + Task ToCipherStringAsync(string messageToEncode); + Task ToCipherBitsAsync(string messageToEncode); + Task AsDecipherStringAsync(string encodedMessage); + Task AsDecipherBitsAsync(string encodedMessage); + } + + public class CryptoKey : ICryptoKey { + private readonly byte[] _salt; + private byte[] _key; + private byte[] _iv; + private bool _hasKey = false; + public CryptoKey() { + _salt = Encoding.UTF8.GetBytes("7B381455F3BF4F7A"); + } + public bool HasCryptoKey => _hasKey; + public void SetCryptoKey(string cryptoKey) { + + if (string.IsNullOrEmpty(cryptoKey)) throw new ArgumentNullException(nameof(cryptoKey)); + using (var pdb = new Rfc2898DeriveBytes(cryptoKey, _salt, 100000, HashAlgorithmName.SHA256)) { + _key = pdb.GetBytes(32); + _iv = pdb.GetBytes(16); + _hasKey = true; + } + } + + public async Task ToCipherStringAsync(string messageToEncode) { + if (string.IsNullOrEmpty(messageToEncode)) throw new ArgumentNullException(nameof(messageToEncode)); + var mb = await ToCipherBitsAsync(messageToEncode); + return Convert.ToBase64String(mb).Replace('=', '?'); + } + + public async Task ToCipherBitsAsync(string messageToEncode) { + if (string.IsNullOrEmpty(messageToEncode)) throw new ArgumentNullException(nameof(messageToEncode)); + if (_key is null) throw new CryptoKeyNotSetException(); + if (_iv is null) throw new CryptoKeyNotSetException(); + using(Aes aes = Aes.Create()) { + aes.Key = _key; + aes.IV = _iv; + MemoryStream memoryStream = new MemoryStream(); + CryptoStream encodedStream = new CryptoStream(memoryStream, aes.CreateEncryptor(), CryptoStreamMode.Write); + StreamWriter writer = new StreamWriter(encodedStream); + await writer.WriteAsync(messageToEncode.AsBase64Encoded()); + writer.Close(); + encodedStream.Close(); + return memoryStream.ToArray(); + } + } + + public async Task AsDecipherStringAsync(string encodedMessage) { + if (string.IsNullOrEmpty(encodedMessage)) throw new ArgumentNullException(nameof(encodedMessage)); + var bits = await AsDecipherBitsAsync(encodedMessage); + return Encoding.UTF8.GetString(bits); + } + + public async Task AsDecipherBitsAsync(string encodedMessage) { + if (string.IsNullOrEmpty(encodedMessage)) throw new ArgumentNullException(nameof(encodedMessage)); + if (_key is null) throw new CryptoKeyNotSetException(); + if (_iv is null) throw new CryptoKeyNotSetException(); + using( Aes aes = Aes.Create()) { + aes.Key = _key; + aes.IV = _iv; + var debase64decode = Convert.FromBase64String(encodedMessage.Replace('?', '=')); + MemoryStream ms = new MemoryStream(debase64decode); + CryptoStream cs = new CryptoStream(ms, aes.CreateDecryptor(), CryptoStreamMode.Read); + StreamReader sr = new StreamReader(cs); + var val = await sr.ReadToEndAsync(); + return Convert.FromBase64String(val.Replace('?', '=')); + } + } + + } + +} diff --git a/Coder/Models/Exceptions.cs b/Coder/Models/Exceptions.cs new file mode 100644 index 0000000..347d1a8 --- /dev/null +++ b/Coder/Models/Exceptions.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Serialization; +using System.Text; +using System.Threading.Tasks; + +namespace Prompter.Models { + /// + /// Example of how to create a decendent exception. + /// + [Serializable] + public class CryptoKeyNotSetException : Exception { + public CryptoKeyNotSetException() : base() { } + public CryptoKeyNotSetException(string message) : base(message) { } + public CryptoKeyNotSetException(string message, Exception innerException) : base(message, innerException) { } + protected CryptoKeyNotSetException(SerializationInfo info, StreamingContext context) : base(info, context) { } + public override void GetObjectData(SerializationInfo info, StreamingContext context) { + base.GetObjectData(info, context); + } + } +} diff --git a/Coder/Models/Extensions.cs b/Coder/Models/Extensions.cs new file mode 100644 index 0000000..896947c --- /dev/null +++ b/Coder/Models/Extensions.cs @@ -0,0 +1,256 @@ +using System; +using System.Linq; +using System.Text; + +namespace Prompter.Models { + + public static class Cs { + public static string nl { get { return Environment.NewLine; } } + + public static string GetNamespaceText(string sDB) { + return + "using Dapper; // data io is based on Dapper."+nl+ + "using System.Data;"+nl+ + // "using System.Data.SqlClient; // from nuget as well."+nl+ + // "using StaticExtensions; // see StaticExtensions in nuget."+nl+nl+ + $"namespace {sDB}"+"{"+nl+nl; + } + + public static string SQLDefNullValueSQL(string sqlType) { + string w = sqlType.ToLower().ParseString(" ()", 0); + string result = ""; + if(w=="char") result="''"; + else if(w=="varchar") result="''"; + else if(w=="int") result="0"; + else if(w=="bigint") result="0"; + else if(w=="binary") result="null"; + else if(w=="bit") result="0"; + else if(w=="datetime") result="null"; + else if(w=="decimal") result="0.0"; + else if(w=="float") result="0.0"; + else if(w=="image") result="null"; + else if(w=="money") result="0.0"; + else if(w=="numeric") result="0.0"; + else if(w=="nchar") result="''"; + else if(w=="ntext") result="''"; + else if(w=="nvarchar") result="''"; + else if(w=="real") result="0.0"; + else if(w=="smallint") result="0"; + else if(w=="smallmoney") result="0.0"; + else if(w=="smalldatetime") result="null"; + else if(w=="text") result="''"; + else if(w=="timestamp") result="null"; + else if(w=="tinyint") result="0"; + else if(w=="uniqueidentifier") result="''"; + else if(w=="varbinary") result="null"; + return result; + } + + public static string GetCTypeFromSQLType(string sqlType) { + string w = sqlType.ToLower().ParseString(" ()", 0); + string result = ""; + if(w=="char") result="string "; + else if(w=="varchar") result="string"; + else if(w=="int") result="int"; + else if(w=="bigint") result="long"; + else if(w=="binary") result="byte"; + else if(w=="bit") result="bool"; + else if(w=="datetime") result="DateTime"; + else if(w=="decimal") result="decimal"; + else if(w=="float") result="float"; + else if(w=="image") result="Image"; + else if(w=="money") result="decimal"; + else if(w=="numeric") result="decimal"; + else if(w=="nchar") result="byte"; + else if(w=="ntext") result="string"; + else if(w=="nvarchar") result="string"; + else if(w=="real") result="decimal"; + else if(w=="smallint") result="short"; + else if(w=="smallmoney") result="decimal"; + else if(w=="smalldatetime") result="DateTime"; + else if(w=="text") result="string"; + else if(w=="timestamp") result="DateTime"; + else if(w=="tinyint") result="short"; + else if(w=="uniqueidentifier") result="string"; + else if(w=="varbinary") result="byte"; + return result; + } + + public static string SQLDefNullValueCSharp(string sqlType) { + string w = sqlType.ToLower().ParseString(" ()", 0); + string result = ""; + if(w=="char") result="\"\""; + else if(w=="varchar") result="\"\""; + else if(w=="int") result="0"; + else if(w=="bigint") result="0"; + else if(w=="binary") result="null"; + else if(w=="bit") result="false"; + else if(w=="datetime") result="null"; + else if(w=="decimal") result="0.0"; + else if(w=="float") result="0.0"; + else if(w=="image") result="null"; + else if(w=="money") result="0.0"; + else if(w=="numeric") result="0.0"; + else if(w=="nchar") result="\"\""; + else if(w=="ntext") result="\"\""; + else if(w=="nvarchar") result="\"\""; + else if(w=="real") result="0.0"; + else if(w=="smallint") result="0"; + else if(w=="smallmoney") result="0.0"; + else if(w=="smalldatetime") result="null"; + else if(w=="text") result="\"\""; + else if(w=="timestamp") result="null"; + else if(w=="tinyint") result="0"; + else if(w=="uniqueidentifier") result="\"\""; + else if(w=="varbinary") result="null"; + return result; + } + + } + + public static class Ext { + // + // Summary: + // Splits content by delims and count + // + // Returns: + // int + public static int ParseCount(this string content, string delims) { + return content.Split(delims.ToCharArray(), StringSplitOptions.RemoveEmptyEntries).Length; + } + + // + // Summary: + // Splits contents by delims into an array and returns item at take + // + // Returns: + // string + public static string ParseString(this string content, string delims, int take) { + string[] array = content.Split(delims.ToCharArray(), StringSplitOptions.RemoveEmptyEntries); + if(take0) { + return sr[sr.Length-1]; + } + return ""; + } + + public static string[] Parse(this string content, string delims) { + string[] sr = content.Split(delims.ToCharArray(), StringSplitOptions.RemoveEmptyEntries); + return sr; + } + + + // + // Summary: + // Casts object as string, null is Exception + // + // Returns: + // string + public static string AsString(this object obj) { + try { + return Convert.ToString(obj)??string.Empty; + } catch { + return string.Empty; + } + } + public static int AsInt(this string obj) { + return int.TryParse(obj, out int r) ? r : 0; + } + // + // Summary: + // Base 64 encodes string variant uses ? as fillers instead of = for inifiles. + // + // Returns: + // Base64 encoded string + public static string AsBase64Encoded(this string Text) { + return Convert.ToBase64String(Encoding.UTF8.GetBytes(Text)).Replace('=', '?'); + } + + // + // Summary: + // Base 64 decodes string variant uses converts ? back to = as fillers for inifiles. + // + // Returns: + // Base 64 decoded string + public static string AsBase64Decoded(this string Text) { + byte[] bytes = Convert.FromBase64String(Text.Replace('?', '=')); + return Encoding.UTF8.GetString(bytes); + } + + // + // Summary: + // General Location to put program data + // + // Remarks: + // string C:\ProgramData\MMCommons + public static string MMCommonsFolder() { + return "C:\\ProgramData\\MMCommons"; + } + + // + // Summary: + // Remove all instances of CToRemove from content + // + // Returns: + // string + public static string RemoveChar(this string content, char CToRemove) { + string text = content; + while(text.Contains(CToRemove)) { + text=text.Remove(text.IndexOf(CToRemove), 1); + } + + return text; + } + + // + // Summary: + // lower case first letter of content concat with remainder. + // + // Parameters: + // content: + // + // Returns: + // string + public static string AsLowerCaseFirstLetter(this string content) { + return content.Substring(0, 1).ToLower()+content.Substring(1); + } + + // + // Summary: + // Uppercase first letter of content concat with rest of content. + // + // Parameters: + // content: + // + // Returns: + // string + public static string AsUpperCaseFirstLetter(this string content) { + return content.Substring(0, 1).ToUpper()+content.Substring(1); + } + + } +} diff --git a/Coder/Models/IniFiles.cs b/Coder/Models/IniFiles.cs new file mode 100644 index 0000000..86908de --- /dev/null +++ b/Coder/Models/IniFiles.cs @@ -0,0 +1,1553 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; +using System.IO; + +namespace Prompter.Models { + /// StreamReader implementation, which read from an INI file. + /// IniFileReader DOES NOT override any StreamReader methods. New ones are added. + public class IniFileReader : StreamReader + { + /// Initializes a new instance of IniFileReader from specified stream. + public IniFileReader(Stream str) : base(str) + { + } + /// Initializes a new instance of IniFileReader from specified stream and encoding. + public IniFileReader(Stream str, Encoding enc) : base(str, enc) + { + } + /// Initializes a new instance of IniFileReader from specified path. + public IniFileReader(string path) : base(path) + { + } + /// Initializes a new instance of IniFileReader from specified path and encoding. + public IniFileReader(string path, Encoding enc) : base(path, enc) + { + } + + IniFileElement current = null; + + /// Parses a single line. + /// Text to parse. + public static IniFileElement ParseLine(string line) + { + if (line == null) + return null; + if (line.Contains("\n")) + throw new ArgumentException("String passed to the ParseLine method cannot contain more than one line."); + string trim = line.Trim(); + IniFileElement elem = null; + if (IniFileBlankLine.IsLineValid(trim)) + elem = new IniFileBlankLine(1); + else if (IniFileCommentary.IsLineValid(line)) + elem = new IniFileCommentary(line); + else if (IniFileSectionStart.IsLineValid(trim)) + elem = new IniFileSectionStart(line); + else if (IniFileValue.IsLineValid(trim)) + elem = new IniFileValue(line); + return elem ?? new IniFileElement(line); + } + /// Parses given text. + /// Text to parse. + public static List ParseText(string text) + { + if (text == null) + return null; + List ret = new List(); + IniFileElement currEl, lastEl = null; + string[] lines = text.Split(new string[] { Environment.NewLine }, StringSplitOptions.None); + for (int i = 0; i < lines.Length; i++) { + currEl = ParseLine(lines[i]); + if (IniFileSettings.GroupElements) { + if (lastEl != null) { + if (currEl is IniFileBlankLine && lastEl is IniFileBlankLine) { + ((IniFileBlankLine)lastEl).Amount++; + continue; + } + else if (currEl is IniFileCommentary && lastEl is IniFileCommentary) { + ((IniFileCommentary)lastEl).Comment += Environment.NewLine + ((IniFileCommentary)currEl).Comment; + continue; + } + } + else + lastEl = currEl; + } + lastEl = currEl; + ret.Add(currEl); + } + return ret; + } + /// Reads and parses next line from the config file. + /// Created ConfigFileElement. + public IniFileElement ReadElement() + { + current = ParseLine(base.ReadLine()); + return current; + } + /// Reads all files + /// All new elements which was added. + public List ReadElementsToEnd() + { + List ret = ParseText(base.ReadToEnd()); + return ret; + } + /// Seeks to the section of specified name. If such section is not found, + /// the function returns NULL and leaves the stream at the end of file. + /// Name of section to find. + public IniFileSectionStart GotoSection(string sectionName) + { + IniFileSectionStart sect = null; + string str; + while (true) { + str = ReadLine(); + if (str == null) { + current = null; + return null; + } + if (IniFileSectionStart.IsLineValid(str)) { + sect = ParseLine(str) as IniFileSectionStart; + if (sect != null && (sect.SectionName == sectionName || (!IniFileSettings.CaseSensitive && sect.SectionName.ToLowerInvariant() == sectionName))) { + current = sect; + return sect; + } + } + } + } + /// Returns a list of IniFileElement object in the currect section. The first element of + /// returned collection will be a IniFileSectionStart. + /// A stream is not currently at the IniFileSectionStart. + public List ReadSection() + { + if (current == null || !(current is IniFileSectionStart)) + throw new InvalidOperationException("The current position of the reader must be at IniFileSectionStart. Use GotoSection method"); + List ret = new List(); + IniFileElement theCurrent = current; + ret.Add(theCurrent); + string text = "", temp; + while ((temp = base.ReadLine()) != null) { + if (IniFileSectionStart.IsLineValid(temp.Trim())) { + current = new IniFileSectionStart(temp); + break; + } + text += temp + Environment.NewLine; + } + if (text.EndsWith(Environment.NewLine) && text != Environment.NewLine) + text = text.Substring(0, text.Length - Environment.NewLine.Length); + ret.AddRange(ParseText(text)); + return ret; + } + /// Gets a recently parsed IniFileElement. + public IniFileElement Current + { + get { return current; } + } + /// Gets values of the current section. + /// A stream is not currently at the IniFileSectionStart. + public List ReadSectionValues() + { + List elements = ReadSection(); + List ret = new List(); + for (int i = 0; i < elements.Count; i++) + if (elements[i] is IniFileValue) + ret.Add((IniFileValue)elements[i]); + return ret; + } + /// Searches the current section for a value of specified key. If such key is not found, + /// the function returns NULL and leaves the stream at next section. + /// Key to find. + public IniFileValue GotoValue(string key) + { + return GotoValue(key, false); + } + /// Searches for a value of specified key. If such key is not found, + /// the function returns NULL and leaves the stream at next section. + /// Key to find. + /// Sets a search scope. If true, function will not stop at the next IniFileSectionStart. + public IniFileValue GotoValue(string key, bool searchWholeFile) + { + IniFileValue val; + string str; + while (true) { + str = ReadLine(); + if (str == null) + return null; + if (IniFileValue.IsLineValid(str.Trim())) { + val = ParseLine(str) as IniFileValue; + if (val != null && (val.Key == key || (!IniFileSettings.CaseSensitive && val.Key.ToLowerInvariant() == key.ToLowerInvariant()))) + return val; + } + if (!searchWholeFile && IniFileSectionStart.IsLineValid(str.Trim())) + return null; + + } + } + } + /// StreamWriter implementation which writes an INI file. + /// IniFileWriter DOES NOT override any StreamReader methods. New ones are added. + public class IniFileWriter : StreamWriter + { + /// Initializes a new instance of IniFileReader from specified stream. + public IniFileWriter(Stream str) : base(str) + { + } + /// Initializes a new instance of IniFileReader from specified path. + public IniFileWriter(string str) : base(str) + { + } + /// Initializes a new instance of IniFileReader from specified stream and encoding. + public IniFileWriter(Stream str, Encoding enc) : base(str, enc) + { + } + /// Initializes a new instance of IniFileReader from specified path and encoding. + public IniFileWriter(string str, bool append) : base(str, append) + { + } + /// Writes INI file element to the file. + /// Element to write. + public void WriteElement(IniFileElement element) + { + if (!IniFileSettings.PreserveFormatting) + element.FormatDefault(); + // do not write if: + if (!( // 1) element is a blank line AND blank lines are not allowed + (element is IniFileBlankLine && !IniFileSettings.AllowBlankLines) + // 2) element is an empty value AND empty values are not allowed + || (!IniFileSettings.AllowEmptyValues && element is IniFileValue && ((IniFileValue)element).Value == ""))) + base.WriteLine(element.Line); + } + /// Writes collection of INI file elements to the file. + /// Elements collection to write. + public void WriteElements(IEnumerable elements) + { + lock (elements) + foreach (IniFileElement el in elements) + WriteElement(el); + } + /// Writes a whole INI to a file + /// Section to write. + public void WriteIniFile(IniFile file) + { + WriteElements(file.elements); + } + /// Writes a section to a file + /// Section to write. + public void WriteSection(IniFileSection section) + { + WriteElement(section.sectionStart); + for (int i = section.parent.elements.IndexOf(section.sectionStart) + 1; i < section.parent.elements.Count; i++) { + if (section.parent.elements[i] is IniFileSectionStart) + break; + WriteElement(section.parent.elements[i]); + } + } + + } + /// Object model for INI file, which stores a whole structure in memory. + public class IniFile + { + internal List sections = new List(); + internal List elements = new List(); + + /// Creates new instance of IniFile. + public IniFile() + { + } + /// Gets a IniFileSection object from it's name + /// Name of section to search for. If not found, new one is created. + public IniFileSection this[string sectionName] + { + get + { + IniFileSection sect = getSection(sectionName); + if (sect != null) + return sect; + IniFileSectionStart start; + if (sections.Count > 0) { + IniFileSectionStart prev = sections[sections.Count - 1].sectionStart; + start = prev.CreateNew(sectionName); + } + else + start = IniFileSectionStart.FromName(sectionName); + elements.Add(start); + sect = new IniFileSection(this, start); + sections.Add(sect); + return sect; + } + } + + IniFileSection getSection(string name) + { + string lower = name.ToLowerInvariant(); + for (int i = 0; i < sections.Count; i++) + if (sections[i].Name == name || (!IniFileSettings.CaseSensitive && sections[i].Name.ToLowerInvariant() == lower)) + return sections[i]; + return null; + } + /// Gets an array of names of sections in this INI file. + public string[] GetSectionNames() + { + string[] ret = new string[sections.Count]; + for (int i = 0; i < sections.Count; i++) + ret[i] = sections[i].Name; + return ret; + } + + /// Reads a INI file from a file or creates one. + public static IniFile FromFile(string path) + { + if (!System.IO.File.Exists(path)) { + System.IO.File.Create(path).Close(); + return new IniFile(); + } + IniFileReader reader = new IniFileReader(path); + IniFile ret = FromStream(reader); + reader.Close(); + return ret; + } + /// Creates a new IniFile from elements collection (Advanced member). + /// Elements collection. + public static IniFile FromElements(IEnumerable elemes) + { + IniFile ret = new IniFile(); + ret.elements.AddRange(elemes); + if (ret.elements.Count > 0) { + IniFileSection section = null; + IniFileElement el; + + if (ret.elements[ret.elements.Count - 1] is IniFileBlankLine) + ret.elements.RemoveAt(ret.elements.Count - 1); + for (int i = 0; i < ret.elements.Count; i++) { + el = ret.elements[i]; + if (el is IniFileSectionStart) { + section = new IniFileSection(ret, (IniFileSectionStart)el); + ret.sections.Add(section); + } + else if (section != null) + section.elements.Add(el); + else if (ret.sections.Exists(delegate(IniFileSection a) { return a.Name == ""; })) + ret.sections[0].elements.Add(el); + else if (el is IniFileValue) { + section = new IniFileSection(ret, IniFileSectionStart.FromName("")); + section.elements.Add(el); + ret.sections.Add(section); + } + } + } + return ret; + } + /// Reads a INI file from a stream. + public static IniFile FromStream(IniFileReader reader) + { + return FromElements(reader.ReadElementsToEnd()); + } + /// Writes a INI file to a disc, using options in IniFileSettings class + public void Save(string path) + { + IniFileWriter writer = new IniFileWriter(path); + Save(writer); + writer.Close(); + } + /// Writes a INI file to a stream, using options in IniFileSettings class + public void Save(IniFileWriter writer) + { + writer.WriteIniFile(this); + } + /// Deletes a section and all it's values and comments. No exception is thrown if there is no section of requested name. + /// Name of section to delete. + public void DeleteSection(string name) + { + IniFileSection section = getSection(name); + if (section == null) + return; + IniFileSectionStart sect = section.sectionStart; + elements.Remove(sect); + for (int i = elements.IndexOf(sect) + 1; i < elements.Count; i++) { + if (elements[i] is IniFileSectionStart) + break; + elements.RemoveAt(i); + } + } + /// Formats whole INI file. + /// If true, old intendation will be standarized but not removed. + public void Format(bool preserveIntendation) + { + string lastSectIntend = ""; + string lastValIntend = ""; + IniFileElement el; + for (int i = 0; i < elements.Count; i++) { + el = elements[i]; + if (preserveIntendation) { + if (el is IniFileSectionStart) + lastValIntend = lastSectIntend = el.Intendation; + else if (el is IniFileValue) + lastValIntend = el.Intendation; + } + el.FormatDefault(); + if (preserveIntendation) { + if (el is IniFileSectionStart) + el.Intendation = lastSectIntend; + else if (el is IniFileCommentary && i != elements.Count - 1 && !(elements[i + 1] is IniFileBlankLine)) + el.Intendation = elements[i + 1].Intendation; + else + el.Intendation = lastValIntend; + } + } + } + /// Joins sections which are definied more than one time. + public void UnifySections() + { + Dictionary dict = new Dictionary(); + IniFileSection sect; + IniFileElement el; + IniFileValue val; + int index; + for (int i = 0; i < sections.Count; i++) { + sect = sections[i]; + if (dict.ContainsKey(sect.Name)) { + index = dict[sect.Name] + 1; + elements.Remove(sect.sectionStart); + sections.Remove(sect); + for (int j = sect.elements.Count - 1; j >= 0; j--) { + el = sect.elements[j]; + if (!(j == sect.elements.Count - 1 && el is IniFileCommentary)) + elements.Remove(el); + if (!(el is IniFileBlankLine)) { + elements.Insert(index, el); + val = this[sect.Name].firstValue(); + if (val != null) + el.Intendation = val.Intendation; + else + el.Intendation = this[sect.Name].sectionStart.Intendation; + } + } + } + else + dict.Add(sect.Name, elements.IndexOf(sect.sectionStart)); + } + } + /// Gets or sets a header commentary of an INI file. Header comment must if separate from + /// comment of a first section except when IniFileSetting.SeparateHeader is set to false. + public string Header + { + get + { + if (elements.Count > 0) + if (elements[0] is IniFileCommentary && !(!IniFileSettings.SeparateHeader + && elements.Count > 1 && !(elements[1] is IniFileBlankLine))) + return ((IniFileCommentary)elements[0]).Comment; + return ""; + } + set + { + if (elements.Count > 0 && elements[0] is IniFileCommentary && !(!IniFileSettings.SeparateHeader + && elements.Count > 1 && !(elements[1] is IniFileBlankLine))) { + if (value == "") { + elements.RemoveAt(0); + if (IniFileSettings.SeparateHeader && elements.Count > 0 && elements[0] is IniFileBlankLine) + elements.RemoveAt(0); + } + else + ((IniFileCommentary)elements[0]).Comment = value; + } + else if (value != "") { + if ((elements.Count == 0 || !(elements[0] is IniFileBlankLine)) && IniFileSettings.SeparateHeader) + elements.Insert(0, new IniFileBlankLine(1)); + elements.Insert(0, IniFileCommentary.FromComment(value)); + } + } + } + /// Gets or sets a commentary at the end of an INI file. + public string Foot + { + get + { + if (elements.Count > 0) { + if (elements[elements.Count - 1] is IniFileCommentary) + return ((IniFileCommentary)elements[elements.Count - 1]).Comment; + } + return ""; + } + set + { + if (value == "") { + if (elements.Count > 0 && elements[elements.Count - 1] is IniFileCommentary) { + elements.RemoveAt(elements.Count - 1); + if (elements.Count > 0 && elements[elements.Count - 1] is IniFileBlankLine) + elements.RemoveAt(elements.Count - 1); + } + } + else { + if (elements.Count > 0) { + if (elements[elements.Count - 1] is IniFileCommentary) + ((IniFileCommentary)elements[elements.Count - 1]).Comment = value; + else + elements.Add(IniFileCommentary.FromComment(value)); + if (elements.Count > 2) { + if (!(elements[elements.Count - 2] is IniFileBlankLine) && IniFileSettings.SeparateHeader) + elements.Insert(elements.Count - 1, new IniFileBlankLine(1)); + else if (value == "") + elements.RemoveAt(elements.Count - 2); + } + } + else + elements.Add(IniFileCommentary.FromComment(value)); + } + } + } + } + /// Object model for a section in an INI file, which stores a all values in memory. + public class IniFileSection + { + internal List elements = new List(); + internal IniFileSectionStart sectionStart; + internal IniFile parent; + + internal IniFileSection(IniFile _parent, IniFileSectionStart sect) + { + sectionStart = sect; + parent = _parent; + } + /// Gets or sets the name of the section + public string Name + { + get { return sectionStart.SectionName; } + set { sectionStart.SectionName = value; } + } + /// Gets or sets comment associated with this section. In the file a comment must appear exactly + /// above section's declaration. Returns "" if no comment is provided. + public string Comment + { + get { return Name == "" ? "" : getComment(sectionStart); + } + set + { + if (Name != "") + setComment(sectionStart, value); + } + } + void setComment(IniFileElement el, string comment) + { + int index = parent.elements.IndexOf(el); + if (IniFileSettings.CommentChars.Length == 0) + throw new NotSupportedException("Comments are currently disabled. Setup ConfigFileSettings.CommentChars property to enable them."); + IniFileCommentary com; + if (index > 0 && parent.elements[index - 1] is IniFileCommentary) { + com = ((IniFileCommentary)parent.elements[index - 1]); + if (comment == "") + parent.elements.Remove(com); + else { + com.Comment = comment; + com.Intendation = el.Intendation; + } + } + else if (comment != "") { + com = IniFileCommentary.FromComment(comment); + com.Intendation = el.Intendation; + parent.elements.Insert(index, com); + } + } + string getComment(IniFileElement el) + { + int index = parent.elements.IndexOf(el); + if (index != 0 && parent.elements[index - 1] is IniFileCommentary) + return ((IniFileCommentary)parent.elements[index - 1]).Comment; + else return ""; + } + IniFileValue getValue(string key) + { + string lower = key.ToLowerInvariant(); + IniFileValue val; + for (int i = 0; i < elements.Count; i++) + if (elements[i] is IniFileValue) { + val = (IniFileValue)elements[i]; + if (val.Key == key || (!IniFileSettings.CaseSensitive && val.Key.ToLowerInvariant() == lower)) + return val; + } + return null; + } + /// Sets the comment for given key. + public void SetComment(string key, string comment) + { + IniFileValue val = getValue(key); + if (val == null) return; + setComment(val, comment); + } + /// Sets the inline comment for given key. + public void SetInlineComment(string key, string comment) + { + IniFileValue val = getValue(key); + if (val == null) return; + val.InlineComment = comment; + } + /// Gets the inline comment for given key. + public string GetInlineComment(string key) + { + IniFileValue val = getValue(key); + if (val == null) return null; + return val.InlineComment; + } + /// Gets or sets the inline for this section. + public string InlineComment + { + get { return sectionStart.InlineComment; } + set { sectionStart.InlineComment = value; } + } + /// Gets the comment associated to given key. If there is no comment, empty string is returned. + /// If the key does not exist, NULL is returned. + public string GetComment(string key) + { + IniFileValue val = getValue(key); + if (val == null) return null; + return getComment(val); + } + /// Renames a key. + public void RenameKey(string key, string newName) + { + IniFileValue v = getValue(key); + if (key == null) return; + v.Key = newName; + } + /// Deletes a key. + public void DeleteKey(string key) + { + IniFileValue v = getValue(key); + if (key == null) return; + parent.elements.Remove(v); + elements.Remove(v); + } + /// Gets or sets value of the key + /// Name of key. + public string this[string key] + { + get + { + IniFileValue v = getValue(key); + return v == null ? null : v.Value; + } + set + { + IniFileValue v; + v = getValue(key); + //if (!IniFileSettings.AllowEmptyValues && value == "") { + // if (v != null) { + // elements.Remove(v); + // parent.elements.Remove(v); + // return; + // } + //} + if (v != null) { + v.Value = value; + return; + } + setValue(key, value); + } + } + /// Gets or sets value of a key. + /// Name of the key. + /// A value to return if the requested key was not found. + public string this[string key, string defaultValue] + { + get + { + string val = this[key]; + if (val == "" || val == null) + return defaultValue; + return val; + } + set { this[key] = value; } + } + private void setValue(string key, string value) + { + IniFileValue ret = null; + IniFileValue prev = lastValue(); + + if (IniFileSettings.PreserveFormatting) { + if (prev != null && prev.Intendation.Length >= sectionStart.Intendation.Length) + ret = prev.CreateNew(key, value); + else { + IniFileElement el; + bool valFound = false; + for (int i = parent.elements.IndexOf(sectionStart) - 1; i >= 0; i--) { + el = parent.elements[i]; + if (el is IniFileValue) { + ret = ((IniFileValue)el).CreateNew(key, value); + valFound = true; + break; + } + } + if (!valFound) + ret = IniFileValue.FromData(key, value); + if (ret.Intendation.Length < sectionStart.Intendation.Length) + ret.Intendation = sectionStart.Intendation; + } + } + else + ret = IniFileValue.FromData(key, value); + if (prev == null) { + elements.Insert(elements.IndexOf(sectionStart) + 1, ret); + parent.elements.Insert(parent.elements.IndexOf(sectionStart) + 1, ret); + } + else { + elements.Insert(elements.IndexOf(prev) + 1, ret); + parent.elements.Insert(parent.elements.IndexOf(prev) + 1, ret); + } + } + internal IniFileValue lastValue() + { + for (int i = elements.Count - 1; i >= 0; i--) { + if (elements[i] is IniFileValue) + return (IniFileValue)elements[i]; + } + return null; + } + internal IniFileValue firstValue() + { + for (int i = 0; i < elements.Count; i++) { + if (elements[i] is IniFileValue) + return (IniFileValue)elements[i]; + } + return null; + } + /// Gets an array of names of values in this section. + public System.Collections.ObjectModel.ReadOnlyCollection GetKeys() + { + List list = new List(elements.Count); + for (int i = 0; i < elements.Count; i++) + if (elements[i] is IniFileValue) + list.Add(((IniFileValue)elements[i]).Key); + return new System.Collections.ObjectModel.ReadOnlyCollection(list); ; + } + /// Gets a string representation of this IniFileSectionReader object. + public override string ToString() + { + return sectionStart.ToString() + " (" + elements.Count.ToString() + " elements)"; + } + /// Formats whole section. + /// Determines whether intendation should be preserved. + public void Format(bool preserveIntendation) + { + IniFileElement el; + string lastIntend; + for (int i = 0; i < elements.Count; i++) { + el = elements[i]; + lastIntend = el.Intendation; + el.FormatDefault(); + if (preserveIntendation) + el.Intendation = lastIntend; + } + } + } + /// Static class containing format settings for INI files. + public static class IniFileSettings + { + private static iniFlags flags = (iniFlags)255; + private static string[] commentChars = { ";", "#" }; + private static char? quoteChar = null; + private static string defaultValueFormatting = "?=$ ;"; + private static string defaultSectionFormatting = "[$] ;"; + private static string sectionCloseBracket = "]"; + private static string equalsString = "="; + private static string tabReplacement = " "; + private static string sectionOpenBracket = "["; + + private enum iniFlags { PreserveFormatting = 1, AllowEmptyValues = 2, AllowTextOnTheRight = 4, + GroupElements = 8, CaseSensitive = 16, SeparateHeader = 32, AllowBlankLines = 64, + AllowInlineComments = 128} + //private static string DefaultCommentaryFormatting = ";$"; + + #region Public properties + + /// Inficates whether parser should preserve formatting. Default TRUE. + public static bool PreserveFormatting + { + get { return (flags & iniFlags.PreserveFormatting) == iniFlags.PreserveFormatting; } + set + { + if (value) + flags = flags | iniFlags.PreserveFormatting; + else + flags = flags & ~iniFlags.PreserveFormatting; + } + } + /// If true empty keys will not be removed. Default TRUE. + public static bool AllowEmptyValues + { + get { return (flags & iniFlags.AllowEmptyValues) == iniFlags.AllowEmptyValues; } + set + { + if (value) + flags = flags | iniFlags.AllowEmptyValues; + else + flags = flags & ~iniFlags.AllowEmptyValues; + } + } + /// If Quotes are on, then it in such situation: |KEY = "VALUE" blabla|, 'blabla' is + /// a "text on the right". If this field is set to False, then such string will be ignored. + public static bool AllowTextOnTheRight + { + get { return (flags & iniFlags.AllowTextOnTheRight) == iniFlags.AllowTextOnTheRight; } + set + { + if (value) + flags = flags | iniFlags.AllowTextOnTheRight; + else + flags = flags & ~iniFlags.AllowTextOnTheRight; + } + } + /// Indicates whether comments and blank lines should be grouped + /// (if true then multiple line comment will be parsed to the one single IniFileComment object). + /// Otherwise, one IniFileElement will be always representing one single line in the file. Default TRUE. + public static bool GroupElements + { + get { return (flags & iniFlags.GroupElements) == iniFlags.GroupElements; } + set + { + if (value) + flags = flags | iniFlags.GroupElements; + else + flags = flags & ~iniFlags.GroupElements; + } + } + /// Determines whether all searching/testing operation are case-sensitive. Default TRUE. + public static bool CaseSensitive + { + get { return (flags & iniFlags.CaseSensitive) == iniFlags.CaseSensitive; } + set + { + if (value) + flags = flags | iniFlags.CaseSensitive; + else + flags = flags & ~iniFlags.CaseSensitive; + } + } + /// Determines whether a header comment of an INI file is separate from a comment of first section. + /// If false, comment at the beginning of file may be considered both as header and commentary of the first section. Default TRUE. + public static bool SeparateHeader + { + get { return (flags & iniFlags.SeparateHeader) == iniFlags.SeparateHeader; } + set + { + if (value) + flags = flags | iniFlags.SeparateHeader; + else + flags = flags & ~iniFlags.SeparateHeader; + } + } + /// If true, blank lines will be written to a file. Otherwise, they will ignored. + public static bool AllowBlankLines + { + get { return (flags & iniFlags.AllowBlankLines) == iniFlags.AllowBlankLines; } + set + { + if (value) + flags = flags | iniFlags.AllowBlankLines; + else + flags = flags & ~iniFlags.AllowBlankLines; + } + } + /// If true, blank lines will be written to a file. Otherwise, they will ignored. + public static bool AllowInlineComments + { + get { return (flags & iniFlags.AllowInlineComments) != 0; } + set + { + if (value) flags |= iniFlags.AllowInlineComments; + else flags &= ~iniFlags.AllowInlineComments; + } + } + /// A string which represents close bracket for a section. If empty or null, sections will + /// disabled. Default "]" + public static string SectionCloseBracket + { + get { return IniFileSettings.sectionCloseBracket; } + set + { + if (value == null) + throw new ArgumentNullException("SectionCloseBracket"); + IniFileSettings.sectionCloseBracket = value; + } + } + /// Gets or sets array of strings which start a comment line. + /// Default is {"#" (hash), ";" (semicolon)}. If empty or null, commentaries + /// will not be allowed. + public static string[] CommentChars + { + get { return IniFileSettings.commentChars; } + set + { + if (value == null) + throw new ArgumentNullException("CommentChars", "Use empty array to disable comments instead of null"); + IniFileSettings.commentChars = value; + } + } + /// Gets or sets a character which is used as quote. Default null (not using quotation marks). + public static char? QuoteChar + { + get { return IniFileSettings.quoteChar; } + set { IniFileSettings.quoteChar = value; } + } + /// A string which determines default formatting of section headers used in Format() method. + /// '$' (dollar) means a section's name; '[' and ']' mean brackets; optionally, ';' is an inline comment. Default is "[$] ;" (e.g. "[Section] ;comment") + public static string DefaultSectionFormatting + { + get { return IniFileSettings.defaultSectionFormatting; } + set + { + if (value == null) + throw new ArgumentNullException("DefaultSectionFormatting"); + string test = value.Replace("$", "").Replace("[", "").Replace("]", "").Replace(";", ""); + if (test.TrimStart().Length > 0) + throw new ArgumentException("DefaultValueFormatting property cannot contain other characters than [,$,] and white spaces."); + if (!(value.IndexOf('[') < value.IndexOf('$') && value.IndexOf('$') < value.IndexOf(']') + && (value.IndexOf(';') == -1 || value.IndexOf(']') < value.IndexOf(';')))) + throw new ArgumentException("Special charcters in the formatting strings are in the incorrect order. The valid is: [, $, ]."); + IniFileSettings.defaultSectionFormatting = value; + } + } + /// A string which determines default formatting of values used in Format() method. '?' (question mark) means a key, + /// '$' (dollar) means a value and '=' (equality sign) means EqualsString; optionally, ';' is an inline comment. + /// If QouteChar is not null, '$' will be automatically surrounded with qouetes. Default "?=$ ;" (e.g. "Key=Value ;comment". + public static string DefaultValueFormatting + { + get { return IniFileSettings.defaultValueFormatting; } + set + { + if (value == null) + throw new ArgumentNullException("DefaultValueFormatting"); + string test = value.Replace("?", "").Replace("$", "").Replace("=", "").Replace(";", ""); + if (test.TrimStart().Length > 0) + throw new ArgumentException("DefaultValueFormatting property cannot contain other characters than ?,$,= and white spaces."); + if (!(((value.IndexOf('?') < value.IndexOf('=') && value.IndexOf('=') < value.IndexOf('$')) + || (value.IndexOf('=') == -1 && test.IndexOf('?') < value.IndexOf('$'))) + && (value.IndexOf(';') == -1 || value.IndexOf('$') < value.IndexOf(';')))) + throw new ArgumentException("Special charcters in the formatting strings are in the incorrect order. The valid is: ?, =, $."); + IniFileSettings.defaultValueFormatting = value; + } + } + + /// A string which represents open bracket for a section. If empty or null, sections will + /// disabled. Default "[". + public static string SectionOpenBracket + { + get { return IniFileSettings.sectionOpenBracket; } + set + { + if (value == null) + throw new ArgumentNullException("SectionCloseBracket"); + IniFileSettings.sectionOpenBracket = value; + } + } + /// Gets or sets string used as equality sign (which separates value from key). Default "=". + public static string EqualsString + { + get { return IniFileSettings.equalsString; } + set + { + if (value == null) + throw new ArgumentNullException("EqualsString"); + IniFileSettings.equalsString = value; + } + } + /// The string which all tabs in intendentation will be replaced with. If null, tabs will not be replaced. Default " " (four spaces). + public static string TabReplacement + { + get { return IniFileSettings.tabReplacement; } + set { IniFileSettings.tabReplacement = value; } + } + #endregion + + internal static string trimLeft(ref string str) + { + int i = 0; + StringBuilder ret = new StringBuilder(); + while (i < str.Length && char.IsWhiteSpace(str, i)) { + ret.Append(str[i]); + i++; + } + if (str.Length > i) + str = str.Substring(i); + else + str = ""; + return ret.ToString(); + } + internal static string trimRight(ref string str) + { + int i = str.Length - 1; + StringBuilder build = new StringBuilder(); + while (i >= 0 && char.IsWhiteSpace(str, i)) { + build.Append(str[i]); + i--; + } + StringBuilder reversed = new StringBuilder(); + for (int j = build.Length - 1; j >= 0; j--) + reversed.Append(build[j]); + if (str.Length - i > 0) + str = str.Substring(0, i + 1); + else + str = ""; + return reversed.ToString(); + } + internal static string startsWith(string line, string[] array) + { + if (array == null) return null; + for (int i = 0; i < array.Length; i++) + if (line.StartsWith(array[i])) + return array[i]; + return null; + } + internal struct indexOfAnyResult + { + public int index; + public string any; + public indexOfAnyResult(int i, string _any) + { + any = _any; index = i; + } + } + internal static indexOfAnyResult indexOfAny(string text, string[] array) + { + for (int i = 0; i < array.Length; i++) + if (text.Contains(array[i])) + return new indexOfAnyResult(text.IndexOf(array[i]), array[i]); + return new indexOfAnyResult(-1, null); + } + internal static string ofAny(int index, string text, string[] array) + { + for (int i = 0; i < array.Length; i++) + if (text.Length - index >= array[i].Length && text.Substring(index, array[i].Length) == array[i]) + return array[i]; + return null; + } + //internal static string endsWith(string line, string[] array) + //{ + // if (array == null) return null; + // for (int i = 0; i < array.Length; i++) + // if (line.EndsWith(array[i])) + // return array[i]; + // return null; + //} + } + + /// Base class for all Config File elements. + public class IniFileElement { + private string line; + /// Same as Formatting + protected string formatting = ""; + + + /// Initializes a new, empty instance IniFileElement + protected IniFileElement() { + line = ""; + } + /// Initializes a new instance IniFileElement + /// Actual content of a line in a INI file. + public IniFileElement(string _content) { + line = _content.TrimEnd(); + } + /// Gets or sets a formatting string of this INI file element, spicific to it's type. + /// See DefaultFormatting property in IniFileSettings for more info. + public string Formatting { + get { return formatting; } + set { formatting = value; } + } + /// Gets or sets a string of white characters which precedes any meaningful content of a line. + public string Intendation { + get { + StringBuilder intend = new StringBuilder(); + for (int i = 0; i < formatting.Length; i++) { + if (!char.IsWhiteSpace(formatting[i])) break; + intend.Append(formatting[i]); + } + return intend.ToString(); + } + set { + if (value.TrimStart().Length > 0) + throw new ArgumentException("Intendation property cannot contain any characters which are not condsidered as white ones."); + if (IniFileSettings.TabReplacement != null) + value = value.Replace("\t", IniFileSettings.TabReplacement); + formatting = value + formatting.TrimStart(); + line = value + line.TrimStart(); + } + } + /// Gets full text representation of a config file element, excluding intendation. + public string Content { + get { return line.TrimStart(); } + protected set { line = value; } + } + /// Gets full text representation of a config file element, including intendation. + public string Line { + get { + string intendation = Intendation; + if (line.Contains(Environment.NewLine)) { + string[] lines = line.Split(new string[] { Environment.NewLine }, StringSplitOptions.None); + StringBuilder ret = new StringBuilder(); + ret.Append(lines[0]); + for (int i = 1; i < lines.Length; i++) + ret.Append(Environment.NewLine + intendation + lines[i]); + return ret.ToString(); + } else + return line; + } + } + /// Gets a string representation of this IniFileElement object. + public override string ToString() { + return "Line: \"" + line + "\""; + } + /// Formats this config element + public virtual void FormatDefault() { + Intendation = ""; + } + } + /// Represents section's start line, e.g. "[SectionName]". + public class IniFileSectionStart : IniFileElement { + private string sectionName; + private string textOnTheRight; // e.g. "[SectionName] some text" + private string inlineComment, inlineCommentChar; + + private IniFileSectionStart() : base() { + } + /// Initializes a new instance IniFileSectionStart + /// Actual content of a line in an INI file. Initializer assumes that it is valid. + public IniFileSectionStart(string content) + : base(content) { + //content = Content; + formatting = ExtractFormat(content); + content = content.TrimStart(); + if (IniFileSettings.AllowInlineComments) { + IniFileSettings.indexOfAnyResult result = IniFileSettings.indexOfAny(content, IniFileSettings.CommentChars); + if (result.index > content.IndexOf(IniFileSettings.SectionCloseBracket)) { + inlineComment = content.Substring(result.index + result.any.Length); + inlineCommentChar = result.any; + content = content.Substring(0, result.index); + } + } + if (IniFileSettings.AllowTextOnTheRight) { + int closeBracketPos = content.LastIndexOf(IniFileSettings.SectionCloseBracket); + if (closeBracketPos != content.Length - 1) { + textOnTheRight = content.Substring(closeBracketPos + 1); + content = content.Substring(0, closeBracketPos); + } + } + sectionName = content.Substring(IniFileSettings.SectionOpenBracket.Length, content.Length - IniFileSettings.SectionCloseBracket.Length - IniFileSettings.SectionOpenBracket.Length).Trim(); + Content = content; + Format(); + } + /// Gets or sets a secion's name. + public string SectionName { + get { return sectionName; } + set { + sectionName = value; + Format(); + } + } + /// Gets or sets an inline comment, which appear after the value. + public string InlineComment { + get { return inlineComment; } + set { + if (!IniFileSettings.AllowInlineComments || IniFileSettings.CommentChars.Length == 0) + throw new NotSupportedException("Inline comments are disabled."); + inlineComment = value; Format(); + } + } + /// Determines whether specified string is a representation of particular IniFileElement object. + /// Trimmed test string. + public static bool IsLineValid(string testString) { + return testString.StartsWith(IniFileSettings.SectionOpenBracket) && testString.EndsWith(IniFileSettings.SectionCloseBracket); + } + /// Gets a string representation of this IniFileSectionStart object. + public override string ToString() { + return "Section: \"" + sectionName + "\""; + } + /// Creates a new IniFileSectionStart object basing on a name of section and the formatting style of this section. + /// Name of the new section + public IniFileSectionStart CreateNew(string sectName) { + IniFileSectionStart ret = new IniFileSectionStart(); + ret.sectionName = sectName; + if (IniFileSettings.PreserveFormatting) { + ret.formatting = formatting; + ret.Format(); + } else + ret.Format(); + return ret; + } + /// Creates a formatting string basing on an actual content of a line. + public static string ExtractFormat(string content) { + bool beforeS = false; + bool afterS = false; + bool beforeEvery = true; + char currC; string comChar; string insideWhiteChars = ""; + StringBuilder form = new StringBuilder(); + for (int i = 0; i < content.Length; i++) { + currC = content[i]; + if (char.IsLetterOrDigit(currC) && beforeS) { + afterS = true; beforeS = false; form.Append('$'); + } else if (afterS && char.IsLetterOrDigit(currC)) { + insideWhiteChars = ""; + } else if (content.Length - i >= IniFileSettings.SectionOpenBracket.Length && content.Substring(i, IniFileSettings.SectionOpenBracket.Length) == IniFileSettings.SectionOpenBracket && beforeEvery) { + beforeS = true; beforeEvery = false; form.Append('['); + } else if (content.Length - i >= IniFileSettings.SectionCloseBracket.Length && content.Substring(i, IniFileSettings.SectionOpenBracket.Length) == IniFileSettings.SectionCloseBracket && afterS) { + form.Append(insideWhiteChars); + afterS = false; form.Append(IniFileSettings.SectionCloseBracket); + } else if ((comChar = IniFileSettings.ofAny(i, content, IniFileSettings.CommentChars)) != null) { + form.Append(';'); + } else if (char.IsWhiteSpace(currC)) { + if (afterS) insideWhiteChars += currC; + else form.Append(currC); + } + } + string ret = form.ToString(); + if (ret.IndexOf(';') == -1) + ret += " ;"; + return ret; + } + /// Formats the IniFileElement object using default format specified in IniFileSettings. + public override void FormatDefault() { + Formatting = IniFileSettings.DefaultSectionFormatting; + Format(); + } + /// Formats this element using a formatting string in Formatting property. + public void Format() { + Format(formatting); + } + /// Formats this element using given formatting string + /// Formatting template, where '['-open bracket, '$'-section name, ']'-close bracket, ';'-inline comments. + public void Format(string formatting) { + char currC; + StringBuilder build = new StringBuilder(); + for (int i = 0; i < formatting.Length; i++) { + currC = formatting[i]; + if (currC == '$') + build.Append(sectionName); + else if (currC == '[') + build.Append(IniFileSettings.SectionOpenBracket); + else if (currC == ']') + build.Append(IniFileSettings.SectionCloseBracket); + else if (currC == ';' && IniFileSettings.CommentChars.Length > 0 && inlineComment != null) + build.Append(IniFileSettings.CommentChars[0]).Append(inlineComment); + else if (char.IsWhiteSpace(formatting[i])) + build.Append(formatting[i]); + } + Content = build.ToString().TrimEnd() + (IniFileSettings.AllowTextOnTheRight ? textOnTheRight : ""); + } + /// Crates a IniFileSectionStart object from name of a section. + /// Name of a section + public static IniFileSectionStart FromName(string sectionName) { + IniFileSectionStart ret = new IniFileSectionStart(); + ret.SectionName = sectionName; + ret.FormatDefault(); + return ret; + } + } + /// Represents one or more blank lines within a config file. + public class IniFileBlankLine : IniFileElement { + /// Initializes a new instance IniFileBlankLine + /// Number of blank lines. + public IniFileBlankLine(int amount) + : base("") { + Amount = amount; + } + /// Gets or sets a number of blank lines. + public int Amount { + get { return Line.Length / Environment.NewLine.Length + 1; } + set { + if (value < 1) + throw new ArgumentOutOfRangeException("Cannot set Amount to less than 1."); + StringBuilder build = new StringBuilder(); + for (int i = 1; i < value; i++) + build.Append(Environment.NewLine); + Content = build.ToString(); + } + } + /// Determines whether specified string is a representation of particular IniFileElement object. + /// Trimmed test string. + public static bool IsLineValid(string testString) { + return testString == ""; + } + /// Gets a string representation of this IniFileBlankLine object. + public override string ToString() { + return Amount.ToString() + " blank line(s)"; + } + /// Formats the IniFileElement object using directions in IniFileSettings. + public override void FormatDefault() { + Amount = 1; + base.FormatDefault(); + } + } + /// Represents one or more comment lines in a config file. + public class IniFileCommentary : IniFileElement { + private string comment; + private string commentChar; + + private IniFileCommentary() { + } + /// Initializes a new instance IniFileCommentary + /// Actual content of a line in a INI file. + public IniFileCommentary(string content) + : base(content) { + if (IniFileSettings.CommentChars.Length == 0) + throw new NotSupportedException("Comments are disabled. Set the IniFileSettings.CommentChars property to turn them on."); + commentChar = IniFileSettings.startsWith(Content, IniFileSettings.CommentChars); + if (Content.Length > commentChar.Length) + comment = Content.Substring(commentChar.Length); + else + comment = ""; + } + /// Gets or sets comment char used in the config file for this comment. + public string CommentChar { + get { return commentChar; } + set { + if (commentChar != value) { + commentChar = value; rewrite(); + } + } + } + /// Gets or sets a commentary string. + public string Comment { + get { return comment; } + set { + if (comment != value) { + comment = value; rewrite(); + } + } + } + void rewrite() { + StringBuilder newContent = new StringBuilder(); + string[] lines = comment.Split(new string[] { Environment.NewLine }, StringSplitOptions.None); + newContent.Append(commentChar + lines[0]); + for (int i = 1; i < lines.Length; i++) + newContent.Append(Environment.NewLine + commentChar + lines[i]); + Content = newContent.ToString(); + } + /// Determines whether specified string is a representation of particular IniFileElement object. + /// Trimmed test string. + public static bool IsLineValid(string testString) { + return IniFileSettings.startsWith(testString.TrimStart(), IniFileSettings.CommentChars) != null; + } + /// Gets a string representation of this IniFileCommentary object. + public override string ToString() { + return "Comment: \"" + comment + "\""; + } + /// Gets an IniFileCommentary object from commentary text. + /// Commentary text. + public static IniFileCommentary FromComment(string comment) { + if (IniFileSettings.CommentChars.Length == 0) + throw new NotSupportedException("Comments are disabled. Set the IniFileSettings.CommentChars property to turn them on."); + IniFileCommentary ret = new IniFileCommentary(); + ret.comment = comment; + ret.CommentChar = IniFileSettings.CommentChars[0]; + return ret; + } + /// Formats IniFileCommentary object to default appearance. + public override void FormatDefault() { + base.FormatDefault(); + CommentChar = IniFileSettings.CommentChars[0]; + rewrite(); + } + } + /// Represents one key-value pair. + public class IniFileValue : IniFileElement { + private string key; + private string value; + private string textOnTheRight; // only if qoutes are on, e.g. "Name = 'Jack' text-on-the-right" + private string inlineComment, inlineCommentChar; + + private IniFileValue() + : base() { + } + /// Initializes a new instance IniFileValue. + /// Actual content of a line in an INI file. Initializer assumes that it is valid. + public IniFileValue(string content) + : base(content) { + string[] split = Content.Split(new string[] { IniFileSettings.EqualsString }, StringSplitOptions.None); + formatting = ExtractFormat(content); + string split0 = split[0].Trim(); + string split1 = split.Length >= 1 ? + split[1].Trim() + : ""; + + if (split0.Length > 0) { + if (IniFileSettings.AllowInlineComments) { + IniFileSettings.indexOfAnyResult result = IniFileSettings.indexOfAny(split1, IniFileSettings.CommentChars); + if (result.index != -1) { + inlineComment = split1.Substring(result.index + result.any.Length); + split1 = split1.Substring(0, result.index).TrimEnd(); + inlineCommentChar = result.any; + } + } + if (IniFileSettings.QuoteChar != null && split1.Length >= 2) { + char quoteChar = (char)IniFileSettings.QuoteChar; + if (split1[0] == quoteChar) { + int lastQuotePos; + if (IniFileSettings.AllowTextOnTheRight) { + lastQuotePos = split1.LastIndexOf(quoteChar); + if (lastQuotePos != split1.Length - 1) + textOnTheRight = split1.Substring(lastQuotePos + 1); + } else + lastQuotePos = split1.Length - 1; + if (lastQuotePos > 0) { + if (split1.Length == 2) + split1 = ""; + else + split1 = split1.Substring(1, lastQuotePos - 1); + } + } + } + key = split0; + value = split1; + } + Format(); + } + /// Gets or sets a name of value. + public string Key { + get { return key; } + set { key = value; Format(); } + } + /// Gets or sets a value. + public string Value { + get { return value; } + set { this.value = value; Format(); } + } + /// Gets or sets an inline comment, which appear after the value. + public string InlineComment { + get { return inlineComment; } + set { + if (!IniFileSettings.AllowInlineComments || IniFileSettings.CommentChars.Length == 0) + throw new NotSupportedException("Inline comments are disabled."); + if (inlineCommentChar == null) + inlineCommentChar = IniFileSettings.CommentChars[0]; + inlineComment = value; Format(); + } + } + enum feState // stare of format extractor (ExtractFormat method) + { + BeforeEvery, AfterKey, BeforeVal, AfterVal + } + /// Creates a formatting string basing on an actual content of a line. + public string ExtractFormat(string content) { + //bool afterKey = false; bool beforeVal = false; bool beforeEvery = true; bool afterVal = false; + //return IniFileSettings.DefaultValueFormatting; + feState pos = feState.BeforeEvery; + char currC; string comChar; string insideWhiteChars = ""; string theWhiteChar; ; + StringBuilder form = new StringBuilder(); + for (int i = 0; i < content.Length; i++) { + currC = content[i]; + if (char.IsLetterOrDigit(currC)) { + if (pos == feState.BeforeEvery) { + form.Append('?'); + pos = feState.AfterKey; + //afterKey = true; beforeEvery = false; ; + } else if (pos == feState.BeforeVal) { + form.Append('$'); + pos = feState.AfterVal; + } + } else if (pos == feState.AfterKey && content.Length - i >= IniFileSettings.EqualsString.Length && content.Substring(i, IniFileSettings.EqualsString.Length) == IniFileSettings.EqualsString) { + form.Append(insideWhiteChars); + pos = feState.BeforeVal; + //afterKey = false; beforeVal = true; + form.Append('='); + } else if ((comChar = IniFileSettings.ofAny(i, content, IniFileSettings.CommentChars)) != null) { + form.Append(insideWhiteChars); + form.Append(';'); + } else if (char.IsWhiteSpace(currC)) { + if (currC == '\t' && IniFileSettings.TabReplacement != null) + theWhiteChar = IniFileSettings.TabReplacement; + else + theWhiteChar = currC.ToString(); + if (pos == feState.AfterKey || pos == feState.AfterVal) { + insideWhiteChars += theWhiteChar; + continue; + } else + form.Append(theWhiteChar); + } + insideWhiteChars = ""; + } + if (pos == feState.BeforeVal) { + form.Append('$'); + pos = feState.AfterVal; + } + string ret = form.ToString(); + if (ret.IndexOf(';') == -1) + ret += " ;"; + return ret; + } + + /// Formats this element using the format string in Formatting property. + public void Format() { + Format(formatting); + } + /// Formats this element using given formatting string + /// Formatting template, where '?'-key, '='-equality sign, '$'-value, ';'-inline comments. + public void Format(string formatting) { + char currC; + StringBuilder build = new StringBuilder(); + for (int i = 0; i < formatting.Length; i++) { + currC = formatting[i]; + if (currC == '?') + build.Append(key); + else if (currC == '$') { + if (IniFileSettings.QuoteChar != null) { + char quoteChar = (char)IniFileSettings.QuoteChar; + build.Append(quoteChar).Append(value).Append(quoteChar); + } else + build.Append(value); + } else if (currC == '=') + build.Append(IniFileSettings.EqualsString); + else if (currC == ';') + build.Append(inlineCommentChar + inlineComment); + else if (char.IsWhiteSpace(formatting[i])) + build.Append(currC); + } + Content = build.ToString().TrimEnd() + (IniFileSettings.AllowTextOnTheRight ? textOnTheRight : ""); + } + /// Formats content using a scheme specified in IniFileSettings.DefaultValueFormatting. + public override void FormatDefault() { + Formatting = IniFileSettings.DefaultValueFormatting; + Format(); + } + /// Creates a new IniFileValue object basing on a key and a value and the formatting of this IniFileValue. + /// Name of value + /// Value + public IniFileValue CreateNew(string key, string value) { + IniFileValue ret = new IniFileValue(); + ret.key = key; ret.value = value; + if (IniFileSettings.PreserveFormatting) { + ret.formatting = formatting; + if (IniFileSettings.AllowInlineComments) + ret.inlineCommentChar = inlineCommentChar; + ret.Format(); + } else + ret.FormatDefault(); + return ret; + } + /// Determines whether specified string is a representation of particular IniFileElement object. + /// Trimmed test string. + public static bool IsLineValid(string testString) { + int index = testString.IndexOf(IniFileSettings.EqualsString); + return index > 0; + } + /// Sets both key and values. Recommended when both properties have to be changed. + public void Set(string key, string value) { + this.key = key; this.value = value; + Format(); + } + /// Gets a string representation of this IniFileValue object. + public override string ToString() { + return "Value: \"" + key + " = " + value + "\""; + } + /// Crates a IniFileValue object from it's data. + /// Value name. + /// Associated value. + public static IniFileValue FromData(string key, string value) { + IniFileValue ret = new IniFileValue(); + ret.key = key; ret.value = value; + ret.FormatDefault(); + return ret; + } + } + + + +} diff --git a/Coder/Models/ItemCaster.cs b/Coder/Models/ItemCaster.cs new file mode 100644 index 0000000..be8c216 --- /dev/null +++ b/Coder/Models/ItemCaster.cs @@ -0,0 +1,535 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Data.SqlClient; +using System.Drawing.Imaging; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace Prompter.Models { + public class Item:TreeNode { + private int _typeId = 0; + private int _statusId = 0; + private int _itemRank = 0; + private int _valueTypeId = 0; + + public bool Dirty = false; + public Item() : base() { } + public int Id { get; set; } = 0; + public int OwnerId { get; set; } = 0; + public int TypeId { + get { return _typeId; } + set { + Dirty=true; + _typeId=value; + switch(this.TypeId) { + case (int)TnType.Project: + this.ImageIndex=(int)Tii.Gift; + this.SelectedImageIndex=(int)Tii.Gift; + break; + case (int)TnType.Template: + this.ImageIndex=(int)Tii.Label; + this.SelectedImageIndex=(int)Tii.Label; + break; + case (int)TnType.Chapters: + this.ImageIndex=(int)Tii.Folder; + this.SelectedImageIndex=(int)Tii.Folder; + break; + case (int)TnType.Chapter: + this.ImageIndex=(int)Tii.View; + this.SelectedImageIndex=(int)Tii.View; + break; + case (int)TnType.Section: + this.ImageIndex=(int)Tii.Internal; + this.SelectedImageIndex=(int)Tii.Internal; + break; + case (int)TnType.SubSection: + this.ImageIndex=(int)Tii.News; + this.SelectedImageIndex=(int)Tii.News; + break; + } + } + } + public int StatusId { get { return _statusId; } set { _statusId=value; Dirty=true; } } + public int ItemRank { get { return _itemRank; } set { _itemRank=value; Dirty=true; } } + public new string Text { get { return base.Text; } set { base.Text=value; Dirty=true; } } + + public int ValueTypeId { get { return _valueTypeId; } set { _valueTypeId=value; Dirty=true; } } + + public string AsChunk() { + return $"{Id} {OwnerId} {_typeId} {_statusId} {_itemRank} {_valueTypeId} {base.Text.AsBase64Encoded()}".AsBase64Encoded(); + } + public Item FromChunk(string chunk) { + string base1 = chunk.AsBase64Decoded(); + Id=base1.ParseString(" ", 0).AsInt(); + OwnerId= base1.ParseString(" ", 1).AsInt(); + TypeId=base1.ParseString(" ", 2).AsInt(); + _statusId=base1.ParseString(" ", 3).AsInt(); + _itemRank=base1.ParseString(" ", 4).AsInt(); + _valueTypeId=base1.ParseString(" ", 5).AsInt(); + base.Text = base1.ParseString(" ", 6).AsBase64Decoded(); + Dirty = false; + return this; + } + } + + public class Items : ConcurrentDictionary { + public Items() : base() { } + public virtual Boolean Contains(int id) { + try { + return !(base[id] is null); + } catch { + return false; + } + } + public virtual new Item this[int id] { + get { return Contains(id) ? base[id] : null; } + set { if(value!=null) { base[id]=value; } else { Remove(id); } } + } + public virtual void Remove(int id) { if(Contains(id)) { _=base.TryRemove(id, out _); } } + + public IEnumerable GetChildrenItems(int id) { + return this.Select(x => x.Value).Where(x => x.OwnerId==id).OrderBy(x => x.ItemRank); + } + public int GetNextId() { + int max = 0; + if (this.Keys.Count > 0) { + max = this.Select(x=>x.Value).Max(x=>x.Id); + } + return max + 1; + } + } + + public class ItemCaster { + private CryptoVars _cryptoVars; + private Items _items; + + public ItemCaster(CryptoKey key, string fileName) { + _items = new Items(); + _cryptoVars=new CryptoVars(); + _cryptoVars.FileName=fileName; + _cryptoVars.SetKey(key); + _cryptoVars.LoadValues(); + + foreach(string k in _cryptoVars.Keys) { + Item x = new Item().FromChunk(_cryptoVars[k].Value); + _items[x.Id] = x; + } + } + + public void LoadTreeviewItemsAsync(System.Windows.Forms.TreeView ownerItem) { + ownerItem.Nodes.Clear(); + IEnumerable result = _items.GetChildrenItems(0); + foreach(Item item in result) { + ownerItem.Nodes.Add(LoadChildren(item)); + } + } + + public Item LoadChildren(Item item) { + var items = GetOwnersItemsAsync(item.Id); + if(item.Nodes.Count>0) item.Nodes.Clear(); + foreach(Item it in items) { + item.Nodes.Add(it); + } + item.Dirty=false; + return item; + } + + public IEnumerable GetOwnersItemsAsync(int ownerItemId) { + IEnumerable result = _items.GetChildrenItems(ownerItemId); + return result; + } + + public Item GetOwnersItemsAsync(Item ownerItem) { + foreach(Item item in ownerItem.Nodes) { + ReloadChildren(LoadChildren(item)); + } + return ownerItem; + } + + public Item ReloadChildren(Item child) { + List temp = new List(); + foreach(Item item in child.Nodes) { + temp.Add(item); + } + foreach(Item item in temp) { + child.Nodes.Remove(item); + child.Nodes.Add(LoadChildren(item)); + } + child.Dirty=false; + return child; + } + + public Item SaveItem(Item item) { + if(item==null) return null; + if(item.Id ==0) { + item.Id = _items.GetNextId(); + } + _items[item.Id] = item; + _cryptoVars[item.Id.AsString()].Value = item.AsChunk(); + return item; + } + + public Item SaveNewItemFromType(Item ownerItem, ItemType itemType) { + Item dbs; + if(ownerItem==null) { + dbs=new Item() { + Id=0, + OwnerId=0, + ItemRank=1, + StatusId=0, + TypeId=itemType.TypeId, + Text=itemType.Name, + ValueTypeId=0 + }; + } else { + dbs=new Item() { + Id=0, + OwnerId=ownerItem.Id, + ItemRank=ownerItem.Nodes.Count+1, + StatusId=0, + TypeId=itemType.TypeId, + Text=itemType.Name, + ValueTypeId=0 + }; + } + SaveItem(dbs); + if(ownerItem!=null) { + ownerItem.Nodes.Add(dbs); + ownerItem.Expand(); + } + return dbs; + } + + public Item SaveNewChildItemsFromText(Item ownerItem, ItemType itemType, string text) { + string[] lines = text.Parse(Environment.NewLine); + if (lines.Count() > 0) { + foreach (string line in lines) { + Item dbs = new Item() { + Id=0, + OwnerId=ownerItem.Id, + ItemRank= ownerItem.Nodes.Count+1, + StatusId=0, + TypeId=itemType.TypeId, + Text=line, + ValueTypeId =0 + }; + SaveItem(dbs); + ownerItem.Nodes.Add(dbs ); + } + ownerItem.Expand(); + } + return ownerItem; + } + + public void RemoveItem(Item item) { + if(item==null) return; + if(item.Nodes.Count==0) { + _cryptoVars.RemoveVar(item.Id.AsString()); + _items.Remove(item.Id); + } + } + + } + + public static class Ic { + public static string GenerateSqlCreateTable(this Item tnTable, Types types) { + string r = $"-- a table create {Cs.nl}Create Table {tnTable.Text}({Cs.nl}"; + foreach(Item tn in tnTable.Nodes) { + if(tn.Text.ToLower()=="id") { + r+=" "+tn.Text+" [int] NOT NULL IDENTITY(1,1),"+Cs.nl; + } else { + r+=" "+tn.Text+" "+types[tn.ValueTypeId].Desc+" NULL,"+Cs.nl; + } + } + r+=$" CONSTRAINT [PK_{tnTable.Text}_Id] PRIMARY KEY CLUSTERED ([ID]) {Cs.nl})"; + return r; + } + + + public static string GetSqlTypeFromStatusIdString(this int ValueTypeId, Types types) { + return types[ValueTypeId].Desc; + } + + public static string GenerateSQLAddUpdateStoredProc(this Item tnTable, Types types) { + Item cn = tnTable; + string nl = Environment.NewLine; + string tblText = tnTable.Text; + string tblTitle = tnTable.Text.RemoveChar('.'); + string sSQLParam1 = tnTable.GetSQLParamList(types); + string sInsertListAsSQlParams = tnTable.GetSQLInsertListAsSQLParam(); + string sColList = tnTable.GetSQLColumnList(false); + string sAssignColSQL = GetAssignChildSQLColList(tnTable); + string sKeyType = "", sKey = "", sKeyB = ""; + Item keyCol; + if(tnTable.Nodes.Count>0) { + keyCol=(Item)tnTable.Nodes[0]; + sKey=keyCol.Text; + sKeyB="["+sKey+"]"; + sKeyType=types[keyCol.ValueTypeId].Desc; + } + string sDefNullValue = Cs.SQLDefNullValueSQL(sKeyType); + return + "-- Add Update SQL Stored Proc for "+tblText+""+nl+ + "Create Procedure dbo.sp_AddUpdate"+tblTitle+" ("+nl+ + " "+sSQLParam1+nl+ + ") as "+nl+ + " set nocount on "+nl+ + $" declare @a {sKeyType} set @a = case when (@{sKey}=0) then 0 else isnull((select "+sKeyB+" from "+tblText+ + " with(nolock) where "+sKeyB+" = @"+sKey+"), "+sDefNullValue+") end "+nl+ + " if (@a = "+sDefNullValue+") begin"+nl+ + " Insert into "+tblText+" ("+nl+ + " "+sColList+nl+ + " ) values ("+nl+" "+sInsertListAsSQlParams+")"+nl+ + " set @a = @@Identity "+nl+ + " end else begin"+nl+ + " Update "+tblText+ + " set"+nl+sAssignColSQL+nl+ + " where "+sKeyB+" = @a"+nl+ + " end"+nl+ + " select @a "+sKey+nl+"return"; + } + + public static string GenerateSQLStoredProc(this Item tnProc, Types types) { + Item cn = tnProc; + string tblText = tnProc.Text; + string sSQLParam1 = tnProc.GetSQLParamList(types); + string sSqlDeclare = tnProc.GetDeclareSQLParam(types); + return + "-- Add Update SQL Stored Proc for "+tblText+""+Cs.nl+ + "Create Procedure "+tblText+" ("+Cs.nl+ + " "+sSQLParam1+Cs.nl+ + ") as "+Cs.nl+ + " set nocount on "+Cs.nl+Cs.nl+ + "return"+Cs.nl+Cs.nl+ + "-- call to execute"+Cs.nl+ + sSqlDeclare+Cs.nl+ + $"Exec {tnProc.Text} {tnProc.GetSQLInsertListAsSQLParam(true)}"; + } + + public static string GenerateSQLFunction(this Item tnFunction, Types types) { + Item cn = tnFunction; + string tblText = tnFunction.Text; + string sSQLParam1 = tnFunction.GetSQLParamList(types); + return + "-- Add Update SQL Stored Proc for "+tblText+""+Cs.nl+ + "Create Function "+tblText+" ("+Cs.nl+ + " "+sSQLParam1+Cs.nl+ + ") as "+Cs.nl+ + " "+Cs.nl+Cs.nl+ + "return"; + } + + public static string GetSQLParamList(this Item tnTable, Types types) { + string sRes = ""; + foreach(Item tnColumn in tnTable.Nodes) { + if(sRes=="") { + sRes="@"+tnColumn.Text+$" {types[tnColumn.ValueTypeId].Desc}"; + } else { + sRes=sRes+","+Environment.NewLine+" @"+tnColumn.Text+$" {types[tnColumn.ValueTypeId].Desc}"; + } + } + return sRes; + } + + public static string GetSQLInsertListAsSQLParam(this Item tnTable, bool IncludeFirstCol = false) { + string sRes = ""; string sFTT = "true"; + foreach(Item tn in tnTable.Nodes) { + if(sFTT=="true") { + sFTT="false"; + if(IncludeFirstCol) { + sRes="@"+tn.Text; + } + } else { + if(sRes=="") { + sRes="@"+tn.Text; + } else { + sRes=sRes+", @"+tn.Text; + } + } + } + return sRes; + } + + public static string GetSQLColumnList(this Item tnTable, Boolean IncludeKeyField) { + string sRes = ""; string sFTT = (IncludeKeyField ? "false" : "true"); + foreach(Item tn in tnTable.Nodes) { + if(sFTT=="true") { + sFTT="false"; // don't include the first Keyfield. + } else { + if(sRes=="") { + sRes="["+tn.Text+"]"; + } else { + sRes=sRes+", ["+tn.Text+"]"; + } + } + } + return sRes; + } + + public static string GetAssignChildSQLColList(this Item tnTable) { + string sRes = ""; string sFTT = "true"; + foreach(Item tn in tnTable.Nodes) { + string sCurCol = tn.Text; + if(sFTT=="true") { + sFTT="false"; + } else { + if(sRes=="") { + sRes=" ["+sCurCol+"] = @"+sCurCol; + } else { + sRes=sRes+","+Environment.NewLine+" ["+sCurCol+"] = @"+sCurCol; + } + } + } + return sRes; + } + + public static string GetDeclareSQLParam(this Item tnStProc) { + string s = ""; + foreach(Item cn in tnStProc.Nodes) { + s=s+"declare "+cn.Text+" set "+cn.Text.ParseFirst(" ")+" = "+Cs.SQLDefNullValueSQL(cn.Text.ParseLast(" "))+";"+Cs.nl; + } + return s; + } + public static string GetExecSQLStoredProcedure(this Item tnStProc) { + return "-- the call to execute "+Cs.nl + +GetDeclareSQLParam(tnStProc)+Cs.nl + +$"Exec {tnStProc.Text} {tnStProc.GetSQLInsertListAsSQLParam(true)}"; + } + + public static string GetCSharpColAsProps(this Item cn, Types types) { + string sRes = ""; + string nl = Environment.NewLine; + foreach(Item tn in cn.Nodes) { + string scol = tn.Text.AsUpperCaseFirstLetter(); + sRes=sRes+$" public {Cs.GetCTypeFromSQLType(types[tn.ValueTypeId].Desc)} {scol}"+"{get; set;} = "+Cs.SQLDefNullValueCSharp(types[tn.ValueTypeId].Desc)+";"+nl; + } + return sRes; + } + + public static string GenerateCSharpRepoLikeClassFromTable(this Item tnTable, Types types, bool IncludeNamespace = true) { + Item cn = tnTable; + string tblName = cn.Text; + String sDB = cn.Parent.Parent.Text; + string sColListb = cn.GetSQLColumnList(true); + string nl = Environment.NewLine; + string sFirstCol; + string sKeyType = "", sKey = ""; + if(cn.Nodes.Count>0) { + Item keyCol = (Item)cn.Nodes[0]; + sFirstCol=keyCol.Text; + sKey=sFirstCol.AsLowerCaseFirstLetter(); + sKeyType=Cs.GetCTypeFromSQLType(types[keyCol.ValueTypeId].Desc); + } + string a = ""; + string d = ""; + for(Int32 i = 0; i {className}IndexAsync()"+"{"+nl+ + $" IEnumerable<{className}> result;"+nl+ + " string connectionString = GetConnectionString();"+nl+ + " using (SqlConnection connection = new SqlConnection(connectionString)) {"+nl+ + $" result = await connection.QueryAsync<{className}>("+nl+ + $" \"select {sColListb} from {tblName} \");"+nl+ + " }"+nl+ + " return Ok(result);"+nl+ + " }"+nl+nl+ + " // C Dapper Load single Item"+nl+ + $" public async Task {className}ItemAsync({sKeyType} {sKey})"+"{"+nl+ + " string connectionString = GetConnectionString();"+nl+ + $" {className} result;"+nl+ + " using (SqlConnection connection = new SqlConnection(connectionString)) {"+nl+ + " var param = new {"+sKey+"};"+nl+ + $" result = await connection.QueryFirstOrDefaultAsync<{className}>("+nl+ + $" \"select {sColListb} from {tblName} where {sKey} = @{sKey} \", param);"+nl+ + " }"+nl+ + " return Ok($\"{result.AsJson()}\");"+nl+ + " }"+nl+nl+ + " // C Dapper Edit via Add Update stored procdure"+nl+ + $" public async Task {className}EditAsync({className} {classVarName}) "+"{"+nl+ + " string connectionString = GetConnectionString();"+nl+ + $" int result = 0;"+nl+ + " using (SqlConnection connection = new SqlConnection(connectionString)) {"+nl+ + $" result = await connection.QueryFirstOrDefaultAsync("+nl+ + $" \"dbo.sp_AddUpdate{className}\", {classVarName}, commandType: CommandType.StoredProcedure);"+nl+ + " }"+nl+ + " return result;"+nl+ + " }"+nl+nl+ + " // C Dapper Edit via Add Update stored procdure x2"+nl+ + $" public async Task {className}Edit2Async({d}) "+"{"+nl+ + " string connectionString = GetConnectionString();"+nl+ + $" int result = 0;"+nl+ + " using (SqlConnection connection = new SqlConnection(connectionString)) {"+nl+ + $" {className} {classVarName} = new {className}(){{ {a} }};"+nl+ + $" result = await connection.QueryFirstOrDefaultAsync("+nl+ + $" \"dbo.sp_AddUpdate{className}\", {classVarName}, commandType: CommandType.StoredProcedure);"+nl+ + " }"+nl+ + " return result;"+nl+ + " }"+nl+nl+ + " // C Dapper delete via Execute"+nl+ + $" public async Task {className}DeleteAsync({sKeyType}{sKey})"+"{"+nl+ + " int result = 0;"+nl+ + " string connectionString = GetConnectionString();"+nl+ + " var param = new {"+$"{sKey}"+"};"+nl+ + " using (SqlConnection connection = new SqlConnection(connectionString)) {"+nl+ + " result = await connection.ExecuteAsync("+nl+ + " \"delete from "+$"{tblName} where [{sKey}] = @{sKey} "+"\", param);"+nl+ + " }"+nl+ + " return Ok(result == 1);"+nl+ + " }"+nl+ + " }"+nl+ + (IncludeNamespace ? "}" : ""); + + + } + + public static string GenerateCSharpExecStoredProc(this Item tnStProc, Types types) { + string sDBName = tnStProc.Parent.Text.ParseFirst(":"); + string a = ""; + string d = ""; + for(Int32 i = 0; i Exec{className}Async({d}) "+"{"+Cs.nl+ + $" string connectionString = Settings.GetConnectionString(\"{sDBName}\");"+Cs.nl+ + $" {className}Result result;"+Cs.nl+ + " var params = new {"+$"{a}"+"};"+Cs.nl+ + " using (SqlConnection connection = new SqlConnection(connectionString)) {"+Cs.nl+ + $" result = await connection.QueryAsync<{className}Result>(\"{tnStProc.Text.ParseFirst(" ")}\", params, commandType: CommandType.StoredProcedure);"+Cs.nl+ + " }"+Cs.nl+ + " return Ok(result.ToJson());"+Cs.nl+ + " }"+Cs.nl+Cs.nl; + return s; + } + + public static string GetDeclareSQLParam(this Item tnStProc, Types types) { + string s = ""; + foreach(Item cn in tnStProc.Nodes) { + s=s+$"declare @{cn.Text} {types[cn.ValueTypeId].Desc} set @"+cn.Text+" = "+Cs.SQLDefNullValueSQL(types[cn.ValueTypeId].Desc)+";"+Cs.nl; + } + return s; + } + + } + +} diff --git a/Coder/Models/TypeCaster.cs b/Coder/Models/TypeCaster.cs new file mode 100644 index 0000000..7c5d2d7 --- /dev/null +++ b/Coder/Models/TypeCaster.cs @@ -0,0 +1,180 @@ +using System; +using System.Collections.Generic; +using System.Data.SqlClient; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace Prompter.Models { + public enum TnType { + Types = 1, + Project = 18, + Template = 19, + + // folders + Chapters = 20, + Chapter = 21, + Section = 22, + SubSection = 23, + + } + + public enum Tii { + Internal = 0, + Server = 1, + Database = 2, + Folder = 3, + View = 4, + Table = 5, + Procedure = 6, + Function = 7, + Column = 8, + News = 9, + Search = 10, + Gift = 11, + Add = 12, + Play = 13, + Stop = 14, + Delete = 15, + Label = 16, + Share = 17, + Setup = 18, + logo = 19 + } + public class ItemType:TreeNode { + public ItemType() { } + private int _id; + public int TypeId { + get { return _id; } + set { + _id=value; + switch(this.TypeId) { + case (int)TnType.Project: + this.ImageIndex=(int)Tii.Gift; + this.SelectedImageIndex=(int)Tii.Gift; + break; + case (int)TnType.Template: + this.ImageIndex=(int)Tii.Label; + this.SelectedImageIndex=(int)Tii.Label; + break; + case (int)TnType.Chapters: + this.ImageIndex=(int)Tii.Folder; + this.SelectedImageIndex=(int)Tii.Folder; + break; + case (int)TnType.Chapter: + this.ImageIndex=(int)Tii.View; + this.SelectedImageIndex=(int)Tii.View; + break; + case (int)TnType.Section: + this.ImageIndex=(int)Tii.Internal; + this.SelectedImageIndex=(int)Tii.Internal; + break; + case (int)TnType.SubSection: + this.ImageIndex=(int)Tii.News; + this.SelectedImageIndex=(int)Tii.News; + break; + } + } + } + public int OwnerTypeId { get; set; } = 0; + public int CatagoryTypeId { get; set; } = 0; + public int EditorTypeId { get; set; } = 0; + public int TypeRank { get; set; } = 0; + public int TypeEnum { get; set; } = 0; + public new string Name { get { return base.Text; } set { base.Text=value; } } + public bool Visible { get; set; } = false; + public string Desc { get; set; } = ""; + public bool Readonly { get; set; } = false; + + } + + + public class Types:Dictionary { + public Types() : base() { + Load(); + } + public void Load() { + base.Clear(); + this[0]=new ItemType() { TypeId=0, OwnerTypeId=0, CatagoryTypeId=0, EditorTypeId=0, TypeRank=0, TypeEnum=0, Name="none", Visible=true, Readonly=true, Desc="" }; + + this[1]=new ItemType() { TypeId=1, OwnerTypeId=1, CatagoryTypeId=0, EditorTypeId=10, TypeRank=1, TypeEnum=1, Visible=false, Readonly=true, Name="Internal", Desc="Root " }; + this[2]=new ItemType() { TypeId=2, OwnerTypeId=1, CatagoryTypeId=2, EditorTypeId=10, TypeRank=1, TypeEnum=1, Visible=false, Readonly=true, Name="CatagoryTypes", Desc="Catagory Type" }; + this[7]=new ItemType() {TypeId=7, OwnerTypeId=1, CatagoryTypeId=3, EditorTypeId=10, TypeRank=1, TypeEnum=1, Visible=false, Readonly=true, Name="EditorTypes", Desc="Editor Type" }; + this[17]=new ItemType() {TypeId=17, OwnerTypeId=1, CatagoryTypeId=4, EditorTypeId=10, TypeRank=1, TypeEnum=1, Visible=false, Readonly=true, Name="thisTypes", Desc="Model Type" }; + this[28]=new ItemType() {TypeId=28, OwnerTypeId=1, CatagoryTypeId=3, EditorTypeId=10, TypeRank=1, TypeEnum=1, Visible=false, Readonly=true, Name="Lookups", Desc="Lookup Editors" }; + + this[3]=new ItemType() {TypeId=3, OwnerTypeId=2, CatagoryTypeId=3, EditorTypeId=10, TypeRank=1, TypeEnum=1, Visible=false, Readonly=true, Name="Internal", Desc="Catagory Internal" }; + this[4]=new ItemType() {TypeId=4, OwnerTypeId=2, CatagoryTypeId=4, EditorTypeId=10, TypeRank=2, TypeEnum=2, Visible=true, Readonly=true, Name="Display", Desc="Catagory Display" }; + + this[8]=new ItemType() {TypeId=8, OwnerTypeId=7, CatagoryTypeId=3, EditorTypeId=8, TypeRank=1, TypeEnum=1, Visible=true, Readonly=true, Name="Int", Desc="The Int Editor " }; + this[9]=new ItemType() {TypeId=9, OwnerTypeId=7, CatagoryTypeId=3, EditorTypeId=9, TypeRank=2, TypeEnum=2, Visible=true, Readonly=true, Name="String", Desc="The String Editor" }; + this[10]=new ItemType() {TypeId=10, OwnerTypeId=7, CatagoryTypeId=3, EditorTypeId=10, TypeRank=0, TypeEnum=0, Visible=false, Readonly=true, Name="Hidden", Desc="The Hidden Editor" }; + this[11]=new ItemType() {TypeId=11, OwnerTypeId=7, CatagoryTypeId=3, EditorTypeId=11, TypeRank=3, TypeEnum=3, Visible=true, Readonly=true, Name="Lookup", Desc="The Lookup Editor" }; + this[12]=new ItemType() {TypeId=12, OwnerTypeId=7, CatagoryTypeId=3, EditorTypeId=12, TypeRank=4, TypeEnum=4, Visible=true, Readonly=true, Name="DateTime", Desc="The DateTime Editor" }; + this[13]=new ItemType() {TypeId=13, OwnerTypeId=7, CatagoryTypeId=3, EditorTypeId=13, TypeRank=5, TypeEnum=5, Visible=true, Readonly=true, Name="Bool", Desc="The Bool Editor" }; + this[14]=new ItemType() {TypeId=14, OwnerTypeId=7, CatagoryTypeId=3, EditorTypeId=14, TypeRank=6, TypeEnum=6, Visible=true, Readonly=true, Name="Color", Desc="The Color Editor" }; + this[15]=new ItemType() {TypeId=15, OwnerTypeId=7, CatagoryTypeId=3, EditorTypeId=15, TypeRank=7, TypeEnum=7, Visible=true, Readonly=true, Name="Filename", Desc="The Filename Editor" }; + this[16]=new ItemType() {TypeId=16, OwnerTypeId=7, CatagoryTypeId=3, EditorTypeId=16, TypeRank=8, TypeEnum=8, Visible=true, Readonly=true, Name="Password", Desc="The Password Editor" }; + this[42]=new ItemType() {TypeId=42, OwnerTypeId=7, CatagoryTypeId=3, EditorTypeId=42, TypeRank=9, TypeEnum=9, Visible=true, Readonly=true, Name="Decimal", Desc="The Decimal Editor" }; + + + this[18]=new ItemType() { TypeId=18, OwnerTypeId=17, CatagoryTypeId=4, EditorTypeId=9, TypeRank=1, TypeEnum=1, Visible=true, Readonly=false, Name="Project", Desc="Project Type" }; + this[19]=new ItemType() { TypeId=19, OwnerTypeId=18, CatagoryTypeId=4, EditorTypeId=9, TypeRank=1, TypeEnum=2, Visible=true, Readonly=false, Name="Template", Desc="Tempate Type" }; + this[20]=new ItemType() { TypeId=20, OwnerTypeId=19, CatagoryTypeId=4, EditorTypeId=9, TypeRank=1, TypeEnum=3, Visible=true, Readonly=false, Name="Chapters", Desc="Chapter Type" }; + this[21]=new ItemType() { TypeId=21, OwnerTypeId=20, CatagoryTypeId=4, EditorTypeId=9, TypeRank=1, TypeEnum=3, Visible=true, Readonly=false, Name="Chapter", Desc="Chapter Type" }; + this[22]=new ItemType() { TypeId=22, OwnerTypeId=21, CatagoryTypeId=4, EditorTypeId=9, TypeRank=2, TypeEnum=4, Visible=true, Readonly=false, Name="Section", Desc="Views Type" }; + this[23]=new ItemType() { TypeId=23, OwnerTypeId=22, CatagoryTypeId=4, EditorTypeId=9, TypeRank=3, TypeEnum=5, Visible=true, Readonly=false, Name="SubSection", Desc="Procedures Type" }; + + + this[29]=new ItemType() { TypeId=29, OwnerTypeId=28, CatagoryTypeId=3, EditorTypeId=11, TypeRank=1, TypeEnum=1, Visible=false, Readonly=true, Name="Table Columns", Desc="Table Column Type Lookup" }; + + this[30]=new ItemType() { TypeId=30, OwnerTypeId=29, CatagoryTypeId=4, EditorTypeId=8, TypeRank=1, TypeEnum=1, Visible=false, Readonly=true, Name="int", Desc="int" }; + this[31]=new ItemType() { TypeId=31, OwnerTypeId=29, CatagoryTypeId=4, EditorTypeId=8, TypeRank=2, TypeEnum=2, Visible=false, Readonly=true, Name="bigint", Desc="bigint" }; + this[32]=new ItemType() { TypeId=32, OwnerTypeId=29, CatagoryTypeId=4, EditorTypeId=13, TypeRank=3, TypeEnum=3, Visible=false, Readonly=true, Name="bit", Desc="bit" }; + this[33]=new ItemType() { TypeId=33, OwnerTypeId=29, CatagoryTypeId=4, EditorTypeId=12, TypeRank=4, TypeEnum=4, Visible=false, Readonly=true, Name="datetime", Desc="datetime" }; + this[34]=new ItemType() { TypeId=34, OwnerTypeId=29, CatagoryTypeId=4, EditorTypeId=9, TypeRank=5, TypeEnum=5, Visible=false, Readonly=true, Name="zip", Desc="nvarchar(6)" }; + this[35]=new ItemType() { TypeId=35, OwnerTypeId=29, CatagoryTypeId=4, EditorTypeId=9, TypeRank=6, TypeEnum=6, Visible=false, Readonly=true, Name="phone", Desc="nvarchar(15)" }; + this[36]=new ItemType() { TypeId=36, OwnerTypeId=29, CatagoryTypeId=4, EditorTypeId=9, TypeRank=7, TypeEnum=7, Visible=false, Readonly=true, Name="name", Desc="nvarchar(100)" }; + this[37]=new ItemType() { TypeId=37, OwnerTypeId=29, CatagoryTypeId=4, EditorTypeId=9, TypeRank=8, TypeEnum=8, Visible=false, Readonly=true, Name="desc", Desc="nvarchar(max)" }; + this[38]=new ItemType() { TypeId=38, OwnerTypeId=29, CatagoryTypeId=4, EditorTypeId=42, TypeRank=9, TypeEnum=9, Visible=false, Readonly=true, Name="decimal 7x2", Desc="decimal(9,2)" }; + this[39]=new ItemType() { TypeId=39, OwnerTypeId=29, CatagoryTypeId=4, EditorTypeId=42, TypeRank=10, TypeEnum=10, Visible=false, Readonly=true, Name="decimal 17x2", Desc="decimal(19,2)" }; + this[40]=new ItemType() { TypeId=40, OwnerTypeId=29, CatagoryTypeId=4, EditorTypeId=42, TypeRank=11, TypeEnum=11, Visible=false, Readonly=true, Name="decimal 17x4", Desc="decimal(19,4)" }; + this[41]=new ItemType() { TypeId=41, OwnerTypeId=29, CatagoryTypeId=4, EditorTypeId=42, TypeRank=12, TypeEnum=12, Visible=false, Readonly=true, Name="decimal 17x8", Desc="decimal(19,8)" }; + + this[43]=new ItemType() { TypeId=43, OwnerTypeId=28, CatagoryTypeId=3, EditorTypeId=11, TypeRank=1, TypeEnum=1, Visible=false, Readonly=true, Name="Prompt Types", Desc="Prompt Type Lookups" }; + + this[44]=new ItemType() { TypeId=44, OwnerTypeId=43, CatagoryTypeId=4, EditorTypeId=9, TypeRank=1, TypeEnum=1, Visible=false, Readonly=true, Name="Hook", Desc="brainstorm 10 story hooks for a Creative Descriptive Objective Expository Narrative Technical Review for [NODE] " }; + this[45]=new ItemType() { TypeId=45, OwnerTypeId=43, CatagoryTypeId=4, EditorTypeId=9, TypeRank=2, TypeEnum=2, Visible=false, Readonly=true, Name="Expository Hook's ending", Desc= $"in context of '[PARENT]', based on the premise of [NODE] hook, can we brainstorm 10 different threads of detail and order them by importance?" }; + this[46]=new ItemType() { TypeId=46, OwnerTypeId=43, CatagoryTypeId=4, EditorTypeId=9, TypeRank=3, TypeEnum=3, Visible=false, Readonly=true, Name="Expository Synopsis", Desc=$"Given the following premise and ending, devise a detailed story synopsis that is structured as \"[PARENT]\". Make sure to include plenty of detail and examples. Premise: [GRANDPARENT]. Ending: [NODE]." }; + + + + + + } + + public IEnumerable GetChildrenItems(int id) { + return this.Select(x => x.Value).Where(x => (x.OwnerTypeId==id)).OrderBy(x => x.TypeRank); + } + + public ItemType LoadSubtypes(ItemType item) { + var items = GetOwnersTypes(item.TypeId); + if(item.Nodes.Count>0) item.Nodes.Clear(); + foreach(ItemType it in items) { + item.Nodes.Add(it); + } + return item; + } + + public IEnumerable GetOwnersTypes(int ownerTypeId) { + try { + IEnumerable result=GetChildrenItems(ownerTypeId); + return result; + } catch(Exception ex) { + return null; + } + } + } + +} diff --git a/Coder/Program.cs b/Coder/Program.cs new file mode 100644 index 0000000..fae2b89 --- /dev/null +++ b/Coder/Program.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace Prompter { + internal static class Program { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new Form1()); + } + } +} diff --git a/Coder/Prompter.csproj b/Coder/Prompter.csproj new file mode 100644 index 0000000..41c83fd --- /dev/null +++ b/Coder/Prompter.csproj @@ -0,0 +1,132 @@ + + + + + Debug + AnyCPU + {DD3E6F4C-042E-4511-929D-4477727CC879} + WinExe + Prompter + Prompter + v4.8 + 512 + true + true + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + flame-_1_.ico + + + + + + + + + + + + + + + + + Form + + + Form1.cs + + + + + + + + + + + + Form1.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + + 2.16.24 + + + 1.0.0 + + + + + + + + False + Microsoft .NET Framework 4.8 %28x86 and x64%29 + true + + + False + .NET Framework 3.5 SP1 + false + + + + \ No newline at end of file diff --git a/Coder/Properties/AssemblyInfo.cs b/Coder/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..2e5d2d5 --- /dev/null +++ b/Coder/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Prompter")] +[assembly: AssemblyDescription("Ai Prompt Manager")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Sky High Productions LLC")] +[assembly: AssemblyProduct("Prompter")] +[assembly: AssemblyCopyright("Copyright © Sky High Productions LLC 2023")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("dd3e6f4c-042e-4511-929d-4477727cc879")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Coder/Properties/Resources.Designer.cs b/Coder/Properties/Resources.Designer.cs new file mode 100644 index 0000000..2839c3e --- /dev/null +++ b/Coder/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Prompter.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.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() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [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("Prompter.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [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/Coder/Properties/Resources.resx b/Coder/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/Coder/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/Coder/Properties/Settings.Designer.cs b/Coder/Properties/Settings.Designer.cs new file mode 100644 index 0000000..0acd614 --- /dev/null +++ b/Coder/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Prompter.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.6.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/Coder/Properties/Settings.settings b/Coder/Properties/Settings.settings new file mode 100644 index 0000000..3964565 --- /dev/null +++ b/Coder/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/Coder/flame-_1_.ico b/Coder/flame-_1_.ico new file mode 100644 index 0000000000000000000000000000000000000000..61c9ef7e965685bc983c6604e0103be43dcd1897 GIT binary patch literal 1150 zcmb7@%PT}-7{=c*Q?fF-jMQXKktmAtCz!0Q*`aLMD3%mu$=c4=%AX(`Sy<7;P7%3J zxg@#$o_t?@oz9%ebNZd{d9Tx)Ib)XL%IA%HWV1Q5f|>OJDKdX~4l`>yX@=r0bipueJBBzTxPl2tl4gHk1KQxp#mYTGD{R6y#CJsGUO~N6PO6MXZGNH zt@(ZGdM`s22r8i8ZwG44o=|InBx#49^*AKWACT93P)}JJP9fZ}OWag%FsP5=zd$>- kKs*1dB?i{ghN{hG=Z$82Y+uQwqaO9XGxJ&EkGO313tAJ64gdfE literal 0 HcmV?d00001