#region Top Part //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ // SmesaSearch2.cs from SmesaSearch1 //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ // v5.3.4.28 22-July SmesaSearch.cs rockin' // -=[ Design Revision 4 ]=- My Custom Type. // v5.3.4.29 25-Jul-2019 Spelling things out // Class{in-Class{in-Class}}; Custom Types: // v5.3.5.30 30-July ReCoded4 WorkList2 // v5.3.5.31 03-Aug ReCoded4 WorkList2 // v5.4.5.32 07-Aug-2019 Search & Replace. // v5.4.5.34 16-Aug Migrating New Code Here. // v5.4.6.36 29-Aug Work down testwells & // BreakPoints, Clean and Polish++ // v5.4.6.37 14-Sep GetFileData2(); // re-re-Designed & // v5.4.6.38 16-Sep GetFileData2 re-Written. // v5.4.7.39 24-Sep-2019 Settling down after // some evolution during tracing & testing. // v5.4.7.40 01-Oct-2019 Heavy Hacking S&R. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ using System; using System.Collections.Generic; using System.Collections.ObjectModel; // Class Aliases using System.Drawing; using System.IO; using System.Windows.Forms; using MyCustomLibrary; using MCD = MyCustomLibrary.Dialogs; using MMF = MyCustomLibrary.MemoryMapper; using MCT = MyCustomLibrary.MyToolbox; using MSF = MyCustomLibrary.SearchForm; //using MST = MyCustomLibrary.MySearchType; // Property Aliases using SMR = MyEditor.Properties.Resources; using SMS = MyEditor.Properties.Settings; #endregion Pop Tart namespace MyEditor { public partial class Smesa // <-==<< { #region GetFileData Method Group /// strings to Custom TYPE; /// called from the loop body above. /// So each record can have multiple /// points, or hits, (Therein) i.e. /// Occurances of the searchString. /// DON'T FORGET TO REMEMBER: EATs /// Empty Line Between Saved Records. /// Comes setup except for the Files. /// reWrite GetFileData and simplify /// v5.4.6.38 14-Sep-2019 -JpE- /// Okay, so, this... /// Method Group written bottom up /// Logical inside to outside whereas /// Starting from here down is most /// readable codewise & Design-Wise. /// Structurably, Architecturally: /// Our Custom Type(s) & Composits /// of other Custom "SearchTypes.cs" /// Confered and tied into this also. /// The WorkList2 Layer: /// /// /// /// /// static WorkList2 GetFileData( IList bools, IList texts, IList readStrings) { return new WorkList2( GetFiles(readStrings)) // <-===<< { CaseCheck = Convert .ToBoolean(bools[0]), WordCheck = Convert .ToBoolean(bools[1]), FindThis = texts[0], Change2 = texts[1], }; } // ><><><><><><><><><><><><><><><><> static int RedNum{ get; set; }// <-===<< /// The Files Layer /// Remember that readStrings[0] & [1] /// have already been used to define /// both CheckBoxes [0] & Search & /// Replace strings [1] So, offset by 2. /// /// /// static Collection GetFiles(IList redStrings) { RedNum = 1; var files = new Collection(); while (++RedNum < redStrings.Count) { var r = redStrings[RedNum]; if (string.IsNullOrEmpty(r) || r.Equals(MCT.Special) ) continue; var test = GetFile(redStrings); if ( test != null && test.Line != null && test.Line.Count > 0 ) files.Add(test); } return files; } static Files GetFile( IList redstrs) { var named = redstrs[RedNum]; var lines = GetLines(redstrs); if (lines == null || lines.Count < 1 || lines[0].Equals(null) ) return null; var t = new Files(lines) { Name = named }; return t; } // ><><><><><><><><><><><><><><><><><><> /// The Lines Layer (Plural) /// /// /// static Collection GetLines(IList readStrings) { var lines = new Collection(); while (++RedNum < readStrings.Count) { var r = readStrings[RedNum--]; if (string.IsNullOrEmpty(r) || r.Equals(MCT.Special) ) break; var test = GetLine(readStrings); if ( test != null && test.Star != null && test.Star.Count > 0) lines.Add(test); else break; } return lines; } /// The Line Layer (Singular) /// /// /// static Lines GetLine( IList redStrings) { var hits = GetHits(redStrings); if (hits.Count< 2) return null; var l2 = hits[0]; hits.RemoveAt(0); var line = new Lines(hits) { LineNumber = l2 }; return line; } // ><><><><><><><><><><><><><><><><><> /// The "hits" Layer (inner) /// The so-called X Coordinates of /// the scheme, The Start Position /// of The FOUND string, allowing /// for more than 1 per line, etc. /// /// /// static Collection GetHits( IList redStrings) { var hits = new Collection(); while (++RedNum < redStrings.Count) { var red = redStrings[RedNum]; if (string.IsNullOrEmpty(red) || red.Equals(MCT.Special) || !red.Contains(",")) { --RedNum; break; } var ints = redStrings[RedNum].Split(','); if (ints.Length < 2) return null; foreach (var n in ints) { try { hits.Add( Convert.ToInt32(n)); } catch (FormatException) { break; } catch(OverflowException){ break; } } } return hits; } #endregion GetFileData Methods reWritten //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ #region Search & Replace Tracking void FindNextMatch() { // testwell &/or FindNextMatch Tracker = GetRtbCoords( // & Adjust WorkList.File.Lines to active RTB.Lines really fast! Track2Next()); // <-= Take Guesses... ^ SetSelectedText(); } // Highlight this Find in Editor. void SetSelectedText() { // testwell SetSelected(); var tab = GetTabNum( WorkList.File[Tracker.File].Name);// var rtb = GetRtB(tab); if (tab < 0 || rtb == null || rtb.Lines.Length < 1) return; rtb.SelectionStart = rtb.GetCharIndexFromPosition( new Point( WorkList // Y .File[Tracker.File] .Line[Tracker.Line] .LineNumber, WorkList // X .File[Tracker.File] .Line[Tracker.Line] .Star[Tracker.Star])); rtb.SelectionLength = WorkList.FindThis.Length; } /**************************************/ //halt: Heavy Construction, Bridge Out! /**************************************/ // Actual Tracking adjusts WorkList // Lines and Starts, to actual real // time numerations when needed. // Updates WorkList.Files[x].Line // & Star(ts), to rtb.Lines real fast. // Uses a lot of existing code so that // is a definite perk & good news // for testing, as that's proven code. P3D GetRtbCoords(P3D p) { // testwell design GRC var rtb = GetRtB(GetTabNum( WorkList.File[p.File].Name)); var lns = WorkList.File[p.File].Line; // hack: Evolve in Trace. RedNum = -1; // As indexer. var cls = GetLines(rtb.Lines); if (cls == null // Collection of Lines ||cls.Count < 1 ||cls.Equals(lns)) return p; var fil = new Files(cls); // 1 file. var pos = WorkList.File.IndexOf(fil); WorkList.File.RemoveAt(pos); WorkList.File.Insert(pos, fil); //develop: calibration ^ may be needed. TrackTo = GetTrackMax(); return AdjustTracker(fil); } // Now align Tracker with new // WorkList.File[p.File].Lines. P3D AdjustTracker(Files fls) // 1 file. { // design hack testwell AdjustTracker var p3 = new P3D(); foreach (var ln in fls.Line) { var p1 = p3.Line; var nm = ln.LineNumber; var st = ln.Star; wait what? } return p3; } // Set Tracker to the NEXT // Matching Block's P3D location ahead. // (if any) REM: All Zero on FindFirst(); P3D Track2Next() { // testwell design Track2Next() var trakWas = Tracker; var trackTo = new P3D(); // hack Track2Next(next find) return trackTo; } /* Design Note: ************** Okay, so it needs to use Tracker to keep track of where we were in the WorkList, and increment to the next record in the current WorkList on demand from "remote" commands. */ RichTextBox GetRtB(int tab) { return TabControl.TabPages[tab] .Controls[_index] as RichTextBox; } static int GetTabNum(string fn) { // testwell GetTabNum(); if (string.IsNullOrEmpty(fn) || !SMS.Default .FileNames.Contains(fn) || !File.Exists(fn)) return -1; return SMS.Default .FileNames.IndexOf(fn); } // Ta-da! Easy with Custom Types! void ReplaceSelection() { // testwell ReplaceCurrentSelection var rtb = GetRtB(GetTabNum(WorkList .File[Tracker.File].Name)); if (rtb == null || rtb.Lines == null ||rtb.Lines.Length < 1) return; var tst = rtb.Lines[Tracker.Line]; if (!tst.Contains( WorkList.FindThis)) return; // halt what do these contain after? var len = WorkList.FindThis.Length; var fst = tst.Substring( 0, Tracker.Star + len); var lst = tst.Substring( Tracker.Star + len); // Evolve as needed. fst = fst.Replace(WorkList .FindThis, WorkList.Change2); rtb.Lines[Tracker.Line] = fst + lst; } #endregion Search And Replace Tracking //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ } }