//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ // PrintForm3.cs 30-Apr v4.3.5.51n //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ // Run This On a Worker Thread // so it's independent of Smesa // as an App within an App. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ // Brought to PrintBlaster NameSpace // v2.3.7.28 21-Jan-2018 (Beginning) //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ // v2.5.9.31 09-Feb-2018 Isolated & // Ready for Further Development! // v3.2.3.47 05-Apr-2018 ^ Beginning // v3.2.4.47 09 Near Total Concept! // v3.3.4.48 18-Apr-2018 // v4.3.5.49 22-Apr-2018 Integrated. // v4.3.5.51 Mmf2-Data Mechanisms. // v4.3.5.52 9-May-18 Up/Down Move. // Perfected 11-May-2018 // v4.4.5.52 Finally Fixes it RIGHT! // v4.9.3.87 14-Nov-2018 Removals. // v4.9.4.88 17-Nov Evolved touches. // v4.9.4.90 27-Nov-2018 ReadRemovals() and // GetSelectedIndex() integration completed. // NOTE: See calls to GetSelectedIndex(); // v4.9.4.91 01-Dec-2018 Integration ^ // v4.9.4.92 04-Dec-2018 Killed.sme Mods. // v4.9.5.93 08-Dec-2018 ME.WriteShared // for Killed file passback to Blaster // v4.9.5.94 10-Dec Polish and Read Thru. // v4.9.5.94 13-Dec-2018 ME2PB Killed 1 & 2 //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ using System; using System.Collections.ObjectModel; using System.Collections.Specialized; using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Windows.Forms; using System.Collections.Generic; // Class Aliases using MyCustomLibrary; using MyEditor; using MCD = MyCustomLibrary.Dialogs; using MCT = MyCustomLibrary.MyToolbox; // Property Aliases using PFR = PrintBlaster.Properties.Resources; using PFS = PrintBlaster.Properties.Settings; namespace PrintBlaster { public partial class PrintForm1 { #region NOTE: // Several of the Context Menu items are simply sent to the existing Menu item handler. (And vise-versa.) #endregion #region Up/Down Method Group /// This Method calls all /// others in the below Method Group. /// They've been split-out to /// simplify this method's reading /// and compartmentalize the tasking. /// Perfected 11-May-2018 v4.4.5.52 /// /// /// private void MoveClick( object sender, EventArgs e) { var dir = GetDirectional(sender); if (dir.Equals(0)) return;// err handled. var ct = listBox1.SelectedItems.Count; var indices = new int[ct]; var items = new string[ct]; GetArrays(ref indices, ref items); var up = dir < 0; var last = listBox1.Items.Count - 1; // v if it's Up from the top... if (up && indices.Contains(0) // v ...or if it's Down from the bottom: || !up && indices.Contains(last)) QuickMove(up);// Wrap around! else // <-= no indices contain 0 OR last! MoveSelected(indices, items, up); // then reSelect previously selected items. for (var i = 0; i < ct; ++i) listBox1.SetSelected( listBox1.Items.IndexOf(items[i]), true); } // Nice when wrapping is easier! private void QuickMove(bool up) { if (up) { // from the top... var item = listBox1.Items[0]; listBox1.Items.RemoveAt(0); listBox1.Items.Add(item); // ^ ...to the bottom. } else { // Or from the bottom... var last = listBox1.Items.Count - 1; var item = listBox1.Items[last]; listBox1.Items.RemoveAt(last); listBox1.Items.Insert(0, item); } // ...to the top! (Swap) } // ^ thus Nothing is top or bottom here! private void MoveSelected( IList indices, IList items, bool up) { if (up) { // Move em Up... var c = listBox1 .SelectedItems.Count; for (var i = 0; i < c; ++i) { // Highest 1st For Up ^ var item = items[i]; var to = indices[i]; listBox1.Items.Remove(item); listBox1.Items.Insert(--to, item); } } else { // v if Down... var last = listBox1.Items.Count - 1; for (var i = listBox1.SelectedItems .Count -1; i > -1; --i)// <-count down { // Lowest first For ^ Down! var item = items[i]; var jp = indices[i]; listBox1.Items.Remove(item); if (++jp < last) listBox1.Items .Insert(jp, item); else // it's last. (Add last) listBox1.Items.Add(item); } } Validate(); } private static int GetDirectional(object sender) { var dir = 0; // dir == direction; var str = Convert.ToString(sender); if (str.Contains("Up")) dir = -1; else if (str.Contains("Down")) dir = 1; return dir; } private void GetArrays(// indirectional ref int[] indices, ref string[] items) { var ct = listBox1.SelectedItems.Count; try { for (var i = 0; i < ct; ++i) { indices[i] = Convert.ToInt32( listBox1.SelectedIndices[i]); items[i] = listBox1 .SelectedItems[i].ToString(); } } catch (Exception e) { if (!MCT.Testing) return; MessageBox.Show(e.ToString()); throw new InvalidCastException( "Get Arrays"); } } #endregion Up/Down Method Group //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ #region Favorites Mods from PB to ME private void RemoveFromListClick( object sender, EventArgs e) { if (!MCD.YesNoDialog( PFR.Remove)) return; var s = listBox1.SelectedItems; var z = new StringCollection(); foreach (var w in from object o in s select Convert.ToString(o) into w where !string.IsNullOrEmpty(w) && File.Exists(w) && !z.Contains(w) select w) z.Add(w); // REM: Remove from Bottom up. for (var i = s.Count - 1; i > -1; --i) listBox1.Items.Remove(s[i]); var n = z.Cast().ToList(); var t = new Thread( ReSetFavoritesSetting); t.Start(n); } private void DeleteFromDiskClick( object sender, EventArgs e) { if (!MCD.YesNoDialog( PFR.Delete)) return; var was = MCT.Skip; MCT.Skip = false; if (!MCD.YesNoDialog(PFR.Sure)) { MCT.Skip = was; return; } MCT.Skip = was; var s = listBox1.SelectedItems; var z = new StringCollection(); foreach (var w in from object o in s select Convert.ToString(o) into w where !string.IsNullOrEmpty(w) && File.Exists(w) // v4.9.3.87 && !z.Contains(w) // <======<< select w) z.Add(w); // Nice! for (var i = s.Count-1; i > -1; --i) { if (!MCT.Testing) File.Delete(s[i].ToString()); listBox1.Items.Remove(s[i]); } var n = z.Cast().ToList(); var t = new Thread( ReSetFavoritesSetting); t.Start(n); } // Have this worker thread send // a mmf msg to ME telling it the file // Removals for ResetFavorites(), but // if ME not running, add to Removals. private void ReSetFavoritesSetting(object n) { var fn = Path.GetDirectoryName( EdPath) + PFR.Favs; var list = n as Collection; // handle both remove AND delete. if ( list == null || list.Count < 1 || !File.Exists(fn) || !MCT.RemoveFromFavoritesFile( list, fn) // v4.9.4.91 || !MCD.YesNoDialog( PFR.ReSet, PFR.ReSetTtl, 1) ) return; // else let's getter done.0 if (MyEditorIsRunning()) ReSet2(list); else AppendToRemovals(list); // Worker thread requires. v if (CountLabel2.InvokeRequired) Invoke(new Invoker1(GetFileCount)); else GetFileCount(); } private void ReSet2( Collection list) { var file = Path.GetDirectoryName( EdPath)+ PFR.MMF1; var name = Path. GetFileNameWithoutExtension(file); var args = new object[] { file, PFS.Default.EditorSize, PFS.Default.EditorOffset2, list, true, name, false, // Uses... PFS.Default.EditorView2 //<-= ALL 8 }; MemoryMapper.WriteStrings(args); } private void GetFileCount() { CountLabel2.Text = Convert.ToString( listBox1.Items.Count); CountLabel2.Text = CountLabel2.Text.PadLeft(4); } // NOW: When MyEditor is NOT Running... // do it this way in case they accumulate. // (Named like a mmf, but it's a text file.) // v4.9.4.88RC 17-Nov-2018 private void AppendToRemovals( IList list) { if (list == null ||list.Count < 1) return; var path = Path.GetDirectoryName( EdPath) + PFR.Removals; if (File.Exists(path)) { var coun = list.Count; var copy = new string[coun]; for (var i = 0; i < coun; ++i) copy[i] = list[i]; var removes = File.ReadAllLines( path, Encoding.Unicode); // When already in there forget it. foreach (var file in copy.Where( file => removes.Contains(file) && File.Exists(file))) list.Remove(file); } if (list.Count > 0) File.AppendAllLines( path, list, Encoding.Unicode); } #endregion Favorites Mods from PB to ME //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ #region Favorites Mods from ME to PB /// For Removals while RUNNING /// Checks for List of Strings /// Passed in via the mmf Killed1.sme /// from MyEditor.WriteShared.Kill1(); /// Calls Reset with List of files /// to Remove from listBox1 & Settings. /// private void SetupKilledWatcher() { KilledWatcher.NotifyFilter = NotifyFilters.FileName; KilledWatcher.InternalBufferSize = 8192; KilledWatcher.EnableRaisingEvents = false; KilledWatcher.Path = WriteShared.AppRoot; KilledWatcher.Filter = Path.GetFileName(PFR.KillNow); KilledWatcher.Created += KilledEventHandler; KilledWatcher.EnableRaisingEvents = true; } /// Go ahead and handle Kills: /// (above) Removing them from listBox1 /// and the corresponding Setting. /// REM: Favorites.sme data file /// has already been taken care of. /// (Worker Thread) Thread Safe, /// File-Safe via MMF Class I wrote. /// /// /// private void KilledEventHandler( object sender, FileSystemEventArgs e) { var file = WriteShared .AppRoot + PFR.KillNow; if (string.IsNullOrEmpty(file) || !File.Exists(file)) throw new ArgumentException(PFR.Err6); var args = new object[] { file, 0, 0, null, true, Path. GetFileNameWithoutExtension(file), true // <-= Delete v file once read. }; var data = MemoryMapper.ReadStrings(args); if ( data == null || data.Count < 1) return; if (listBox1.InvokeRequired) Invoke(new Invoker2( KillFileNames), data); else KillFileNames( data); // REM: Favorites.sme and MyEditor... // Setting, both handled by that side. } /// (worker) Handles Killed /// Files from Settings for file list /// sent from MyEditor, Using file /// system Watcher & Eventhandler /// for Killed1.sme and method group. /// NOT TO BE CONFUSED W/ Favorites.sme /// Which is already handled elsewhere. /// That goes from PB2ME and this one /// goes from ME2PB. /// v4.9.4.92 06-Dec-2018 by -JpE- /// /// private void KillFileNames(object parms) { using (new Mutex(false, PFR.Killer)) { if (parms == null) throw new ArgumentException(PFR.Err4); var data = parms as Collection; if (data == null || data.Count < 1) return; // REM: Direct to OverLoad below. RoadKill(data); } } /// Checks for Killed2.sme Files /// on Launch When Blaster was NOT Running: /// Similar to the above but not; as this 1 /// While the above handles it when running. /// (Reads Killed2.sme File on Launch) /// private void RoadKill() { // Executes on Startup Only! var dir = WriteShared.AppRoot; using (File.Create(dir + PFR.PB)){} // Set PB is Now Running flag! ^ var fn = dir + PFR.KillLater;// | if (!File.Exists(fn)) return; var files = File.ReadAllLines( fn, Encoding.Unicode); if (files.Length < 1) return; // Now, just "getter" Done. RoadKill(files); if (File.Exists(fn)) File.Delete(fn); } /// OverLoad for special Call /// from KillFileNames(); /// For better ReUse of TestedCode. /// /// private void RoadKill( IEnumerable files) { using (new Mutex(false, PFR.RoadKill)) { foreach (var file in files) { if (PFS.Default.Files.Contains(file)) PFS.Default.Files.Remove(file); if (listBox1 == null || listBox1.Items.Count < 1) break; if (listBox1.Items.Cast() .Contains(file)) listBox1.Items.Remove(file); } PFS.Default.Save(); } } #endregion Favorites Mods from ME to PB //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ } }