//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ // OptionsMiscAlternate.cs//\\//\\//\\//\\//\\// //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ // Global Access Software InTernational//\\// // Copyrighted (c)2013 by John P. Edwards/\\//\\ // *** Sunday, July 21, 2013 8:01:09 AM/\\//\\// // M Saturday, July 27, 2013 10:45:09 PM//\\//\\ // ReSharper7 Approved by -JpE- v1.4.1.2x\//\\// // Friday, August 09, 2013 11:19:04 PM\\//\\//\\ // Friday, July 25, 2014 08:25 PM/\\//\\//\\// //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ // Split out from OptionsMisc.cs\\//\\//\\//\\// // v4.6.7.76 Jan 28 2017 Isolated to here!\\//\\ // This Source File is like 150 Lines atm.//\\// // Including the Comments and Design Ideas\\//\\ // and everything else roughed except that//\\// // The HelpButtonClick is pretty finished \\//\\ // codewise. Just need to complete that file\\// // v4.6.7.78 Jan 30 2017 in Design Phase. \\//\\ // v4.6.7.87 Feb 09 2017 Early Alpha 1st phase./ // v4.6.7.95 Feb 11 2017 Alpha-Beta Stages. //\\ // I am working on the ListBox Hovers or trying/ // v4.6.7.98 Feb 11 2017 Everything works 4 AFF\ // But it's not yet hooked up to anything in IF/ // v4.6.8.23 Feb 27 2017 Touching Up Final. //\\ // v4.6.8.43 Mar 15 2017 Reworked MoveExisting./ // v4.6.9.63 Mar 26 Added "Select File" to\\//\\ // Context Menu Items along with supporting/\\// // Methods. Tests Very Well Indeed.\//\\//\\//\\ // v4.6.9.64 Added Context Menu Item that\//\\// // Lets the User Select a New Reports Folder//\\ // For this Data Folder. Mar 26 2017\\//\\//\\// // v4.6.9.76 Mar 30 2017//\\//\\//\\//\\//\\//\\ // v4.6.9.77 Mar 30 Upgraded to ObjectModel!\\// // Context Menu for Data Folders improved with\\ // v4.6.9.82 Mar 31 2017 File Print Options.\\// // v4.6.9.87 Apr 04 2017 UpGraded Context Menus! // v4.7.0.04 Apr 12 2017 More On The End there! // v4.7.0.07 Apr 14 2017 Finishing ^ & DoW-Mods. // v4.7.1.24 Apr 20 Integration & Consolidation. // v4.7.1.31 Apr 22 Added List Restore Contexts. // v4.7.1.35 Apr 24 and perfected them & all. // v4.7.2.53 May 05 Restore methods almost done. // v4.7.2.61 May 09 Backup methods nearly done. // v4.7.3.65 May 11 Nearly Clear, Final Testing. // v4.7.3.77 May 17 ViewAllPrefs & ViewAllAss. // Revamped Overloads and such for DisplayResults // & DisplayResults() to work with ViewALL-Mods. // v4.7.3.78 Added the lil Quick-Launch Feature! // Resources straightened out and a new Icon for // the QS & fixed & organized right all around. // v4.7.3.85 Adds AYS to MinVerb YesNo's, etc. // Perfecting MoveUp-Data & Testing all more. // v4.7.3.93 May 30 2017 Better Default Mods // for the Selector index mods. // v4.7.3.96 May 31 2017 Fixed ViewAllAss! // v4.7.5.19 12Jun17 Caps a lot of mods here // including the Backup/Restore for Both Lists // and all the called methods therefor. i.e. // The Big 4 and Supporting Methods Regions. // and mostly in AppCode4 for the RecNum stuff. // OMA now @ 2776 Lines! BackupListsAuto added. // BLA is called from AppCode2.Restore4() now // as part of the Scheduled Maintenance now. // v4.7.5.20 12Jun Integration & Wipe Testings. // v4.7.5.25 14Jun Split the Big 4 n2 the Big 2! // with a few specific methods & reUses mostly. // v4.7.5.28 Final Details of Formatting Code // Files and make as readable as possible. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ // "NameSpaces" Included. using System; using System.IO; using System.Linq; using System.Drawing; using System.Collections; using System.Windows.Forms; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Collections.Specialized; // Code File "Aliases" to shorten. using IF = WhoAreYou.InfoForm; using AST = WhoAreYou.AppStatic; using APS = WhoAreYou.Properties.AppSettings; using OPS = WhoAreYou.Properties.OptionsSettings; using AUS = WhoAreYou.Properties.AppUserSettings; using ORS = WhoAreYou.Properties.OptionsResources; using PMS = WhoAreYou.Properties.PrintMasterSettings; namespace WhoAreYou { public partial class OptionsForm // <-= NOTE! { #region Alternate Folder Finder /* Design Ideas and other imagineering: * ************************************ * Okay, so like this Region and Methods herein are all about the * AlternateFolderFinder or AFF. The ListBoxs will Allow a Collection * of Paths to be Stored. So I need to "hook" it into the * Data and Reports TextBoxes without altering anything there, * but to Collect those paths, anytime there is a new one. * * So then, I'll need to compare those to Entries and so on. * And I'll need Settings to store the Collections and retrieve them, etc. * * Then, when there is a Collection of at least the Current few we can know that * the paths are valid or they wouldn't be in the Data or ReportsTextBox.Text! * * Initial Values are the good old AppDir+"\\" + Home and... * AppDir + "\\" + Home + "\\" + Reports * that the App defaults-to on startup and so forth. (AppCode4.cs) * * Then DataSelect Button Click or Double Mouse Click on the Selected Index * will simply put that Entry into the Data or ReportsTextBox.text, etc. * * Also, maybe, if the Open Button is Clicked when a Listbox Item is * highlighted, it opens that folder. ***See Context Menu Items*** * * Then I guess Clicking the Select Button will basically put the Selected * index item into the DataTextBox.Text (or Reports L8r) and do the same * basic things as happen after the folderBrowser Dialog; PopulateListBoxes, etc. * SelectedPath returns to top of list, right below default. * * -JpE- (I totally love this phase when there's so much potential * and ideas are flowing freely and merging into real concepts and code.) * Feb 01-15 2017 * Apr 04 2017 and nearly 1,000 lines of code later. IT'S FUCKING WONDERFUL! * Much more than I'd originally envisioned, with the new Context Menu Item * UpDates, at the Bottom, and so forth that all tie into everything nicely. * Great Job on Creating, Designing, Writing, Testing and Upgrading Integrations. */ #region Collection Methods /// Add initial default paths to BOTH Collections. /// Called Once for Data Path, once for Reports Path. /// called from OptionsFormLoad(); each instance if count /// is less than 2. /// /// private void AddDefaultsToPathCollectionsLocal(bool dataPath) { AddDefaultsToPathCollections(dataPath); PopulateListBoxes(); } /// Add initial default paths to BOTH Collections. /// True for Data Path, False for Reports Path. /// as of v4.7.1.24 Apr 20 2017, ReUsed by AppCode5 Class. /// /// public static void AddDefaultsToPathCollections(bool dataPath) { // adds defaults to initial collections... string path; // true if DataCollection, false if ReportsCollection. if (dataPath.Equals(true)) { path = AUS.Default.AppDir + "\\" + APS.Default.Home; OPS.Default.dataListBoxItems.Add(path); } else { path = AUS.Default.AppDir + "\\" + APS.Default.Home + "\\" + PMS.Default.Reports; OPS.Default.reportsListBoxItems.Add(path); } OPS.Default.Save(); // doesn't have to be created, just added to as a Setting. } private void AddToPathCollection(string path, bool which) { AddToPathCollectionPublic(path, which); PopulateListBoxes(); // NOTE! Only difference locally. } /// Grabs the current path to see... /// if it's in the collection and adds it to the /// pertinent collection when it isn't already there. /// sender == true is DataList, sender == false is ReportsList. /// /// public static void AddToPathCollectionPublic(string path, bool which) { if (which.Equals(true)) { if (CheckForItem(path, true).Equals(false)) { // check if collection is full then delete least used if it is... SizeCollection(true); if (OPS.Default.dataListBoxItems.Count > 1) { OPS.Default.dataListBoxItems.Insert(1, path); } else OPS.Default.dataListBoxItems.Add(path); } else // otherwise it already exists and we... { MoveExistingItemTo2NdInList(path, true); } } else // If path ^v is NOT already in collection, add it. { if (CheckForItem(path, false).Equals(false)) { SizeCollection(false); if (OPS.Default.reportsListBoxItems.Count > 1) { OPS.Default.reportsListBoxItems.Insert(1, path); } else OPS.Default.reportsListBoxItems.Add(path); } else // otherwise it already exists and we... { MoveExistingItemTo2NdInList(path, false); } } OPS.Default.Save(); } /// Item is already in the collection, /// move it to 2nd Unless already 1st or 2nd(default); /// (i.e. Index 0 or 1 in the List.) -ed /// Leaves 0 and 1 alone, no changes needed. /// true to access dataListBoxItems, /// false to access reportsListBoxItems. -JpE- /// /// /// private static void MoveExistingItemTo2NdInList(string path, bool which) { // Find index of Item and move it to Position 1. // If which is true it's Data Path, if false it's Reports. if (which.Equals(true)) { if (OPS.Default // clone 2 of 3 v4.6.8.43 .dataListBoxItems.IndexOf(path) < 2) return; if (OPS.Default.dataListBoxItems.Count > 1) { OPS.Default.dataListBoxItems.Remove(path); OPS.Default.dataListBoxItems.Insert(1, path); } else OPS.Default.dataListBoxItems.Add(path); } else // NOTE: Default is always kept at Position Zero. { if (OPS.Default // clone 3 of 3 .reportsListBoxItems.IndexOf(path) < 2) return; if (OPS.Default.reportsListBoxItems.Count > 1) { OPS.Default.reportsListBoxItems.Remove(path); OPS.Default.reportsListBoxItems.Insert(1, path); } else OPS.Default.reportsListBoxItems.Add(path); } //OPS.Default.Save(); } /// Removes Items Beyond Default Item Count. /// p = true is Data, p = false is Reports. /// /// v4.7.1.25 Apr 21 2017 /// Makes Count = 49 thus 50 paths stored. (see AppSettings) /// /// /// private static void SizeCollection(bool p) { if (p.Equals(true)) // Data Code Path. { var count = OPS.Default.dataListBoxItems.Count; if (count > APS.Default.Count) { OPS.Default.dataListBoxItems.RemoveAt(count - 1); } // Remove Last Path in List if Collection is "full." } else // Reports Code Path. { var count = OPS.Default.reportsListBoxItems.Count; if (count > APS.Default.Count) // testswell! // > 4 { OPS.Default.reportsListBoxItems.RemoveAt(count - 1); } } } /// return false if path is NOT already in collection. /// If path "is" already in collection forget it, return true. /// /// /// /// private static bool CheckForItem(string path, bool which) { // if check is false, it is not in the collection. if (which.Equals(true)) // it's a Data Path. { if (OPS.Default.dataListBoxItems.Contains(path)) return true; } else // it's a Reports Path. if (OPS.Default.reportsListBoxItems.Contains(path)) return true; return false; } #endregion Collection Methods //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ #region Action Methods private void PopulateListBoxes() { OPS.Default.Save(); // Initialize and Populate both ListBoxes with appropriate collections. var hasno = false; var invalid = new Collection(); dataListBox.Items.Clear(); reportsListBox.Items.Clear(); if (OPS.Default.dataListBoxItems.Count < 1) AddDefaultsToPathCollectionsLocal(true); if (OPS.Default.reportsListBoxItems.Count < 1) AddDefaultsToPathCollectionsLocal(false); IF.CheckBothFolderCollections(); // <-= v4.7.1.33 foreach (var item in OPS.Default.dataListBoxItems) { if (!ValidateItem(item, true)) { hasno = true; invalid.Add(item); continue; } dataListBox.Items.Add(item); } dataListBox.SelectedIndex = OPS.Default.dataListBoxItems // v4.7.0.03 .IndexOf(OPS.Default.dataListBoxItems.Contains(PreviouslySelectedDir1) ? PreviouslySelectedDir1 : OPS.Default.PrefRootDir); if (hasno) RemoveInvalidFolders(true, invalid); hasno = false; invalid.Clear(); // And do similarly for reportsListBox.Items. if (OPS.Default.reportsListBoxItems.Count < 1) { OPS.Default.reportsListBoxItems .Add(ReportsTextBox.Text); OPS.Default.Save(); } foreach (var item in OPS.Default.reportsListBoxItems) { if (!ValidateItem(item, false)) { hasno = true; invalid.Add(item); continue; } reportsListBox.Items.Add(item); } reportsListBox.SelectedIndex = OPS.Default.reportsListBoxItems // v4.7.0.03 .IndexOf(OPS.Default.reportsListBoxItems.Contains(PreviouslySelectedDir2) ? PreviouslySelectedDir2 : OPS.Default.PrefReportsDir); if (hasno) RemoveInvalidFolders(false, invalid); } /// Select Previously Selected Index Mods; Set Previous. /// v4.7.0.03 v PSD1&2C vars Used Above ONLY. Set to Prefs on FormLoad. /// These EVENT Handlers are called on changes and these vars only change herein. /// /// /// private void SelectedIndex1Change(object sender, EventArgs e) { PreviouslySelectedDir1 = dataListBox.SelectedItem.ToString(); } private void SelectedIndex2Change(object sender, EventArgs e) { PreviouslySelectedDir2 = reportsListBox.SelectedItem.ToString(); } private void RemoveInvalidFolders (bool data, ICollection list) { if (list.Count < 1) return; var default1 = OPS.Default.dataListBoxItems[0]; var default2 = OPS.Default.reportsListBoxItems[0]; if (data) { if (list.Contains(default1)) list.Remove(default1); foreach (var item in list) OPS.Default.dataListBoxItems.Remove(item); } else { if (list.Contains(default2)) list.Remove(default2); foreach (var item in list) OPS.Default.reportsListBoxItems.Remove(item); } PopulateListBoxes(); } /// Verify Folder Exists and /// in the case of DataFolder, that data files exist. /// /// /// /// private static bool ValidateItem(string item, bool path) { var test = false; if (path.Equals(true)) // Data Folder. { if (Directory.Exists(item) && HasDataFiles(item)) test = true; } else // Reports Folder. { if (Directory.Exists(item)) test = true; } return test; } /// Make Sure Data Folder has data files. /// Rev v4.7.1.24 April 20 2017 and made public. /// /// /// public static bool HasDataFiles(string folder) { return (from file in Directory.EnumerateFiles(folder) let extension = Path.GetExtension(file) where !string.IsNullOrEmpty(extension) && !string.IsNullOrEmpty(file) where extension.Equals(APS.Default.Ext) && !file.Contains("Bac_") && !file.Contains(APS.Default._drf) && !file.Equals(APS.Default.NewFile) select extension).Any(); } private void DataSelectButtonClick(object sender, EventArgs e) { var path = dataListBox.Text; // NOTE: Every time a Path is reSelected, it needs be put back on top. var test = OPS.Default.dataListBoxItems.IndexOf(path); if (test > 1) // if default path or 2nd leave it alone. { MoveExistingItemTo2NdInList(path, true); } // Now put that path into the dataTextBox.Text and Save Changes. folderBrowser.SelectedPath = path; DataChanges(); } private void ReportsSelectButtonClick (object sender, EventArgs e) { var path = reportsListBox.Text; var test = OPS.Default.reportsListBoxItems.IndexOf(path); if (test > 1) MoveExistingItemTo2NdInList(path, false); folderBrowser.SelectedPath = path; ReportsChanges(); } #endregion Action Methods //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ #region Context Menu Items /* DOC: * \\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\// * The Context Menu 1 items and true args are DataFolder * Specific and the Context Menu 2 items and false args * are Reports Folder Specific throughout. * * NOTE: Numerous Updates were done after the initial code. * See notes and Docs for each Below. * \\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\// */ #region Original Context Menu Items private void ViewToolStrip1MenuItemClick(object sender, EventArgs e) { MessageBox.Show(dataListBox.SelectedItem.ToString()); } private void OpenToolStrip1MenuItemClick(object sender, EventArgs e) { if (!OPS.Default.MiniVerb && !OPS.Default.AreYouSure) if (!AST.YesNoDialog("Open This Folder?")) return; var folder = dataListBox.SelectedItem.ToString(); AST.OpenFolder(folder); } private void RemoveToolStrip1MenuItemClick(object sender, EventArgs e) { var item = dataListBox.SelectedIndex; if (item.Equals(0)) { MessageBox.Show(ORS.OF_Remove); return; } if (item.Equals(1)) { MessageBox.Show(ORS.OF_Reselect); return; } if (!OPS.Default.MiniVerb)// && !OPS.Default.AreYouSure) if (!AST.YesNoDialog(string.Format( "Remove this Folder from the List?\n{0}", dataListBox.Items[item]))) return; OPS.Default.dataListBoxItems.RemoveAt(item); PopulateListBoxes(); } private void ClearToolStrip1MenuItemClick(object sender, EventArgs e) { var test = OPS.Default.dataListBoxItems.Count; if (test < 2) return; // Keep The Default. if (!OPS.Default.MiniVerb)// && !OPS.Default.AreYouSure) if (!AST.YesNoDialog("Clear This Entire List?")) return; OPS.Default.dataListBoxItems.Clear(); AddDefaultsToPathCollectionsLocal(true); DataTextBox.Text = OPS.Default.dataListBoxItems[0]; } private void OpenToolStrip2MenuItemClick(object sender, EventArgs e) { if (OPS.Default.reportsListBoxItems.Count < 2) return; if (!OPS.Default.MiniVerb && !OPS.Default.AreYouSure) if (!AST.YesNoDialog("Open This Folder?")) return; var folder = reportsListBox.SelectedItem.ToString(); AST.OpenFolder(folder); } private void RemoveToolStrip2MenuItemClick(object sender, EventArgs e) { var item = reportsListBox.SelectedIndex; if (item.Equals(0)) { MessageBox.Show(ORS.OF_Remove); return; } if (item.Equals(1)) { MessageBox.Show(ORS.OF_Reselect); return; } if (!OPS.Default.MiniVerb) if (!AST.YesNoDialog(string.Format( "Remove this Folder from the List?\n{0}", reportsListBox.Items[item]))) return; OPS.Default.reportsListBoxItems.RemoveAt(item); PopulateListBoxes(); } private void ClearToolStrip2MenuItemClick(object sender, EventArgs e) { if (OPS.Default.reportsListBoxItems.Count < 2) return; // ^ Keep The Default. if (!OPS.Default.MiniVerb) //&& !OPS.Default.AreYouSure if (!AST.YesNoDialog("Clear This Entire List?")) return; OPS.Default.reportsListBoxItems.Clear(); AddDefaultsToPathCollectionsLocal(false); ReportsTextBox.Text = OPS.Default.reportsListBoxItems[0]; } private void ViewToolStripMenuItem2Click(object sender, EventArgs e) { MessageBox.Show(reportsListBox.SelectedItem.ToString()); } #endregion Original Context Menu Items //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ #region v4.6.9.67 Mar 27 2017 private void SelectFileToolStrip1MenuItemClick (object sender, EventArgs e) { if (!OPS.Default.MiniVerb && !OPS.Default.AreYouSure) if (!AST.YesNoDialog( "Select a Data File for this Folder?")) return; // Now do it! var dir = dataListBox.SelectedItem.ToString(); if (!Directory.Exists(dir) || !HasDataFiles(dir)) { PopulateListBoxes(); return; } var files = GetDataFileList(dir); // v4.7.3.93 May 30 2017 vvvvvvv var index = 0; var test = GetPrefFileName(dir); if (files.Contains(test)) index = files.IndexOf(test); else if (files.Contains(OPS.Default.PrefFileName)) index = files.IndexOf(OPS.Default.PrefFileName); else if (files.Contains(AUS.Default.FileName)) index = files.IndexOf(AUS.Default.FileName); else if (files.Contains(PMS.Default.Bac_PrefFileName)) index = files.IndexOf(PMS.Default.Bac_PrefFileName); else if (files.Contains(APS.Default.defaultFilename)) index = files.IndexOf(APS.Default.defaultFilename); // Selected index Mods ^^^^^^^^^ var size = AUS.Default.OMA_FileSelect_Size; var location = AUS.Default.OMA_FileSelect_Location; var choice = SelectOne(files, ref size, ref location, "", index); AUS.Default.OMA_FileSelect_Size = size; AUS.Default.OMA_FileSelect_Location = location; AUS.Default.Save(); if (string.IsNullOrEmpty(choice) || !File.Exists(dir + "\\" + choice)) return; if (OPS.Default.dataListBoxItems.IndexOf(dir).Equals(1)) { OPS.Default.PrefFileName = FileName = choice; } RememberThis2(choice, dir); if (!OPS.Default.MiniVerb) Feedback(); } private static void Feedback() { const string text = "Your Preferences Have Been Saved."; MessageBox.Show(text); } /// Get List of strings of DataFile Names /// That Exist on this particular Directory. Linq vers. /// /// public static Collection GetDataFileList(string folder) { #region Was //// optimized only after testing and noting original. //var list = new List(); //foreach (var file in Directory.EnumerateFiles( // OPS.Default.PrefRootDir)) //{ // var name = Path.GetFileName(file); // var extension = Path.GetExtension(file); // if ( string.IsNullOrEmpty(extension) // || string.IsNullOrEmpty(name) // || !extension.Equals(APS.Default.Ext) // || name.Contains(APS.Default._drf) // || name.Equals(APS.Default.NewFile) // || name.Contains("Bac_")) continue; // list.Add(name); //} //return list; //// Converted to Linq it's... #endregion Was return new Collection((from file in Directory.EnumerateFiles(folder) let name = Path.GetFileName(file) let extension = Path.GetExtension(file) where !string.IsNullOrEmpty(extension) && !string.IsNullOrEmpty(name) && extension.Equals(APS.Default.Ext) && !name.Contains(APS.Default._drf) && !name.Equals(APS.Default.NewFile) && !name.Contains("Bac_") select name).ToList()); } // write file to dir indicating pref Filename for this Dir. private static void RememberThis2(string filename, string dir) { var contents = filename + "\n" + GetStoredReportsDirPref(dir) + "\nOMA_RememberThis2();"; var file = dir + "\\" + APS.Default.PrefFile; File.WriteAllText(file, contents); } // Get it & put it right back in with different filename. private static string GetStoredReportsDirPref(string dir) { var pref = OPS.Default.PrefReportsDir; var file = dir + "\\" + APS.Default.PrefFile; if (File.Exists(file)) { var path = File.ReadAllText(file).Split('\n')[1]; // grabs second line of file only. if (!path.Contains("()") && !path.Contains(";") && Directory.Exists(path) ) pref = path; } return pref; } // v4.6.9.67 Mar 27 2017 private void SelectReportsFolderToolStrip1MenuItemClick (object sender, EventArgs e) { if (!OPS.Default.MiniVerb && !OPS.Default.AreYouSure) if (!AST.YesNoDialog( "Select a Reports Folder" + " for this Data Folder?")) return; var dir = dataListBox.SelectedItem.ToString(); var list = OPS.Default.reportsListBoxItems; var relist = new Collection(); // <-= v4.6.9.77! foreach (var path in list) // Convert from Specialized String Collection { relist.Add(path); } // to a Generic ObjectModel.Collection // SelectorForm Use and Example thereof. // v4.7.3.95 Index Mods extended to these. var index = 0; var test = GetStoredReportsDirPref(dir); if (relist.Contains(test)) index = relist.IndexOf(test); else if (relist.Contains(OPS.Default.PrefReportsDir)) index = relist.IndexOf(OPS.Default.PrefReportsDir); else if (relist.Contains(PMS.Default.ReportsFolder)) index = relist.IndexOf(PMS.Default.ReportsFolder); // else default to the index[0] default. // ^ v4.7.3.93 May 30 2017 const string text = "Select a Reports Folder:"; var size = AUS.Default.OMA_ReportsSelect_Size; var locate = AUS.Default.OMA_ReportsSelect_Location; var selected = SelectOne(relist, ref size, ref locate, text, index); AUS.Default.OMA_ReportsSelect_Size = size; AUS.Default.OMA_ReportsSelect_Location = locate; AUS.Default.Save(); if (string.IsNullOrEmpty(selected)) return; // v4.6.9.87 Apr 04 2017 - All Four Possibles Tested. // If it's the default data dir it moves the pref reports // folder to the 2nd-position* or leaves it alone if it's the // default or pref reports dir already. (*2nd in the list, index[1].) if (dir.Equals(OPS.Default.PrefRootDir)) { if (selected != list[0]) { MoveExistingItemTo2NdInList(selected, false); PopulateListBoxes(); } ReportsTextBox.Text = PreviouslySelectedDir2 = OPS.Default.PrefReportsDir = selected; } RememberThis3(selected, dir); if (!OPS.Default.MiniVerb) Feedback(); } // write file to dataDir indicating selected ^ private void RememberThis3 (string selectedReportsDir, string dataDir) { var contents = GetPrefFileName(dataDir) + "\n" + selectedReportsDir + "\n" + "OMA_RememberThis3();"; var prefFile = dataDir + "\\" + APS.Default.PrefFile; File.WriteAllText(prefFile, contents); } // Get it & put it right back in ^ with different Reports Pref. private string GetPrefFileName(string dir) { var pref = FileName; // as default value. var file = dir + "\\" + APS.Default.PrefFile; if (File.Exists(file)) { var name = File.ReadAllText(file).Split('\n')[0]; // Reads First Line of File Only. ^ if (!string.IsNullOrEmpty(name) && File.Exists(dir + "\\" + name)) pref = name; } return pref; } #endregion v4.6.9.67 Mar 27 2017 //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ #region Upgrade 4.6.9.87 Apr 04 2017 /* Upgrade adds two context menu items, to each context menu, * For Move-Up & Move-Down of selected item. 1st item cannot * be moved. 2nd Item cannot be moved. If 3rd item is moved to 2nd * then we prompt them to make this the prefFolder or back out, * leaving things be. Only if 3rd item is moved up AND made the pref * does the 2nd (Pref) item fall to 3rd. Nothing can be moved higher than * 2nd, the default stays on top no matter what. The pref is 2nd no matter * what, except if default path. The bottom item cannot be moved down. * Folder must exist. Data folders must contain data files. */ /// The ProtoType For All The Below. /// Event handler for the Move Up Context Menus. Item /// selected is moved up the list unless already 1st or 2nd. /// If 3rd is moved up it requires approval to become Pref. /// /// See Called Methods below, some shared and so forth. /// /// /// private void MoveUpToolStrip1MenuItemClick(object sender, EventArgs e) { // Data Collection if (dataListBox.Items.Count < 3) { MessageBox.Show(ORS.OMA_MoveItem); return; // Remove Short Lists from the equation. } var dir = dataListBox.SelectedItem.ToString(); if (!Directory.Exists(dir) || !HasDataFiles(dir)) { OPS.Default.dataListBoxItems.Remove(dir); PopulateListBoxes(); MessageBox.Show(string.Format( "The Directory:\n{0}\n\nDoes NOT Exist, or Data Files\n" + " could no longer be found on it.\n\n" + "It was removed from the list.", dir)); return; // Eliminate Non Existent Folders. } var index = OPS.Default.dataListBoxItems.IndexOf(dir); if (index < 2) { MessageBox.Show(ORS.OMA_Cannot); return; } if (index.Equals(2)) { // 3rd Item needs approval to move up. if (!MakeThisThePreference(dir, true)) return; } // A Last Chance to Abort. if ( !OPS.Default.MiniVerb && !OPS.Default.AreYouSure && !index.Equals(2)) if (!AST.YesNoDialog(ORS.OMA_Up)) return; // Now do it! MoveData(true, index); if (index.Equals(2)) { // Make it the Pref folderBrowser.SelectedPath = dir; DataChanges(); } else PopulateListBoxes(); } private void MoveUpToolStrip2MenuItemClick(object sender, EventArgs e) { // Reports Collection if (reportsListBox.Items.Count < 3) { MessageBox.Show(ORS.OMA_MoveItem); return; // Remove Short Lists from the equation. } var dir = reportsListBox.SelectedItem.ToString(); if (!Directory.Exists(dir)) { OPS.Default.reportsListBoxItems.Remove(dir); PopulateListBoxes(); MessageBox.Show(string.Format( "The Directory:\n{0}\n\n" + "Does NOT Exist and was removed from the list.", dir)); return; // Eliminate Non Existent Folders. } var index = OPS.Default.reportsListBoxItems.IndexOf(dir); if (index < 2) { MessageBox.Show(ORS.OMA_Cannot); return; } if (index.Equals(2)) { // 3rd Item needs approval to move up. if (!MakeThisThePreference(dir, false)) return; } // A Last Chance to Abort. if ( !OPS.Default.MiniVerb && !OPS.Default.AreYouSure && !index.Equals(2)) if (!AST.YesNoDialog(ORS.OMA_Up)) return; // Now do it! MoveReports(true, index); if (index.Equals(2)) { // Making it the Pref if now 2nd in List. folderBrowser.SelectedPath = dir; ReportsChanges(); } else PopulateListBoxes(); } /// Event Handler for Move Down Context Menu Item /// This version for the Data List. Clone below for Reports. /// /// /// private void MoveDownToolStrip1MenuItemClick(object sender, EventArgs e) { // Data Collection var count = dataListBox.Items.Count; if (count < 3) { // Remove Short Lists from the equation. MessageBox.Show(ORS.OMA_MoveItem); return; } var dir = dataListBox.SelectedItem.ToString(); if (!Directory.Exists(dir) || !HasDataFiles(dir)) { OPS.Default.dataListBoxItems.Remove(dir); MessageBox.Show(string.Format( "The Directory:\n{0}\n\nDoes NOT Exist, or Data Files\n" + " could no longer be found on it.\n\n" + "It was removed from the list.", dir)); return; // Eliminate Non Existent Folders. } var index = OPS.Default.dataListBoxItems.IndexOf(dir); if (index < 2) { MessageBox.Show(ORS.OMA_Cannot); return; // Remove Items 1 and 2 from the equation. ^ } if (index + 1 == count) { MessageBox.Show(ORS.OMA_Last); return; // Can't Move Last item Down Msg. } if (!OPS.Default.MiniVerb && !OPS.Default.AreYouSure) if (!AST.YesNoDialog(ORS.OMA_Down)) return; // Last Chance to BackOut. // And finally, if everything above checks out, Move it. MoveData(false, index); PopulateListBoxes(); } //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ // Design Algorithm - Graphic for Move Down visualization. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ // index[0] = item1 can't be moved. ***Handled*** // index[1] = item2 can't be moved. ***Handled*** // index[2] = item3 can be moved down, by removing and inserting. // index[N] = itemN etc, etc. ^^^ ^^^^^^^^^^^^^^^^^^ // index[N] = by removing and inserting ***Handled*** v // index[N] by removing and inserting ***Handled*** v for N iterations. // index[x] = item-x 3rd from End can be moved, by removing and inserting. // index[y] = item-y 2nd from End can be moved, by removing & ADDING ONLY! ***OK*** // index[z] = item-z Last item can't be moved down. ***Handled*** //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ private void MoveDownToolStrip2MenuItemClick(object sender, EventArgs e) { // Reports Collection var count = reportsListBox.Items.Count; if (count < 3) { // Remove Short Lists from the equation. MessageBox.Show(ORS.OMA_MoveItem); return; } // <-= Show msg, do Nothing. ^ var dir = reportsListBox.SelectedItem.ToString(); if (!Directory.Exists(dir)) { OPS.Default.reportsListBoxItems.Remove(dir); MessageBox.Show(string.Format( "The Directory:\n{0}\n\nDoes NOT Exist, or Data Files\n" + " could no longer be found on it.\n\n" + "It was removed from the list.", dir)); return; // Eliminate Non Existent Folders. } var index = OPS.Default.reportsListBoxItems.IndexOf(dir); if (index < 2) { MessageBox.Show(ORS.OMA_Cannot); return; // Remove Items 1 and 2 from the equation. } if (index + 1 == count) { MessageBox.Show(ORS.OMA_Last); return; // Can't Move Last item Down Msg. } if (!OPS.Default.MiniVerb && !OPS.Default.AreYouSure) if (!AST.YesNoDialog(ORS.OMA_Down)) return; // Last Chance to BackOut if Not MiniVerb or AYS. // And finally, if everything above checks out, Move it. MoveReports(false, index); PopulateListBoxes(); } /// Moves Data List Items Up or Down. /// Clone below does the same for the Reports List. /// /// /// private static void MoveData(bool up, int index) { var add = false; var dir = OPS.Default.dataListBoxItems[index]; var count = OPS.Default.dataListBoxItems.Count; OPS.Default.dataListBoxItems.RemoveAt(index); if (up) index--; else { // if down... if (index + 2 == count) add = true; index++; // ^ 2nd to last has to be added not inserted. v } if (add) OPS.Default.dataListBoxItems.Add(dir); else OPS.Default.dataListBoxItems.Insert(index, dir); } private static void MoveReports(bool up, int index) { var add = false; var dir = OPS.Default.reportsListBoxItems[index]; var count = OPS.Default.reportsListBoxItems.Count; OPS.Default.reportsListBoxItems.RemoveAt(index); if (up) index--; else { // down... if (index + 2 == count) add = true; index++; } if (add) OPS.Default.reportsListBoxItems.Add(dir); else OPS.Default.reportsListBoxItems.Insert(index, dir); } /// Specialized Dialog Gets Approval for Preference Setting. /// Used by both Reports and Data Move Up Methods. Not needed in down. /// /// /// /// private static bool MakeThisThePreference(string dir, bool data) { // New conditional v4.7.3.83 if (OPS.Default.MiniVerb) return true; const string title = "Make This the Preference?"; var text = "Your New Reports Directory Preference."; if (data) text = "Your New Data-Directory-Preference."; return MessageBox.Show(string.Format( "This will make:\n{0}\n\n" + text + "\n\nAre You Sure?", dir), title, MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2 ).Equals(DialogResult.Yes); } #endregion Upgrade 4.6.9.87 Apr 04 2017 //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ #region Upgrade v4.7.1.23 Upgrade SubSection Apr 19 2017 private void RestoreOldPrefsClick(object sender, EventArgs e) { if (!OPS.Default.MiniVerb && !OPS.Default.AreYouSure) if (!AST.YesNoDialog( "Bring Back All preference files?")) return; var pref = APS.Default.PrefFile; foreach (var item in OPS.Default.dataListBoxItems) { if (!Directory.Exists(item)) continue; var source = item + "\\" + "old" + pref; if (!File.Exists(source)) continue; var destin = item + "\\" + pref; if (File.Exists(destin)) { if ( !OPS.Default.MiniVerb && !OPS.Default.AreYouSure) if (!AST.YesNoDialog( "Replace Existing preference file?")) continue; File.Delete(destin); } File.Move(source, destin); } } private void WipePrefsClick(object sender, EventArgs e) { int mover; bool preserver; if (!OPS.Default.MiniVerb)// && !OPS.Default.AreYouSure) { const string text1 = "Clear ALL preference files from entire\n" + "Data Folder collection?", text2 = "This is not recommended.\n\n" + "Do you really need to start fresh?", text3 = "Do you want to preserve the\n" + "preferences for the default Directory?", text4 = "Rename instead of Delete,\n" + "So they can be restored if needed?"; if (!OPS.Default.AreYouSure) if (!AST.YesNoDialog(text1)) return; if (!AST.YesNoDialog(text2)) return; preserver = OPS.Default.AreYouSure || AST.YesNoDialog(text3); mover = AST.YesNoDialog(text4) ? 1 : 0; } // v made reUsable v4.7.1.23br else { preserver = true; mover = 1; } BackupPreferences(preserver, mover, false); } private void BackupAllPrefsToolStripMenuItemClick (object sender, EventArgs e) { if (!OPS.Default.MiniVerb) if (!AST.YesNoDialog( "Backup ALL preference files,\nOver Writing " + "any previous backups...\n\nAre You Sure?")) return; BackupPreferences(false, 2, true); ShowResult(2); } /// This 1 overload is not really connected /// to the others of nearly the same name here, which are, /// for the most part, interconnected and cross dependant. /// /// private static void ShowResult(int moveIt) { if (OPS.Default.MiniVerb) return; var msg = ""; if (moveIt < 0 || moveIt > 2) msg = "Error in OMA!"; if (moveIt.Equals(0)) msg = "All Preference Files Have Been Deleted."; if (moveIt.Equals(1)) msg = "All Preference Files Have Been ReNamed."; if (moveIt.Equals(2)) msg = "All Preference Files Have Been Backed up."; MessageBox.Show(msg); } /// ReWritten to accomodate both of the above calls, etc. /// v4.7.1.23 Apr 19 2017 Could be called elsewhere: /// Also Called from Restore3() if Scheduled Maint is due. /// /// /// /// public static void BackupPreferences(bool preserve, int moveIt, bool auto) { var pref = APS.Default.PrefFile; foreach (var dir in OPS.Default .dataListBoxItems.Cast() .Where(Directory.Exists)) { if (preserve.Equals(true)) { preserve = false; continue; } var source = dir + "\\" + pref; var destin = dir + "\\" + "old" + pref; if (!File.Exists(source)) continue; if (File.Exists(destin)) { if ( !OPS.Default.MiniVerb && !OPS.Default.AreYouSure && !auto) if (!AST.YesNoDialog( "Delete old preference backup?")) continue; File.Delete(destin); } if (moveIt == 0) File.Delete(source); if (moveIt == 1) File.Move(source, destin); if (moveIt == 2) File.Copy(source, destin); } if (!auto) ShowResult(moveIt); } #endregion subregion v4.7.1.23 Upgrade SubSection //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ #region Upgrade 4.7.3.73 Updates older & adds new "View-All Options". // ContextMenuStrip1 Item for Data Dirs. private void ViewPrefsToolStrip1MenuItemClick(object sender, EventArgs e) { const string text1 = "The Reports Folder Associated with this Data Folder is:", text2 = "The File Name Associated with this Data Folder is:"; string dir = dataListBox.SelectedItem.ToString(), text3 = "", test1 = OPS.Default.PrefRootDir, filename = GetPrefFileName(dir), reports = GetStoredReportsDirPref(dir); if (dir.Equals(test1)) text3 = "\nThis is your Currently Preferred Folder and Data File."; var msg = string.Format( text1 + "\n{0}\n\n" + text2 + "\n{1}\n" + text3, reports, filename); DisplayResults(msg,""); } // Upgrade v4.7.3.71 May 17 2017, // Similar to above but foreach item in DataListBox. private void ViewAllPrefsClick(object sender, EventArgs e) { const string title = "View ALL Preferences:", text1 = "The Reports Folder Associated with this Data Folder is:", text2 = "The File Name Associated with this Data Folder is:"; var text = ""; var pref = OPS.Default.PrefRootDir; var list = OPS.Default.dataListBoxItems; foreach (var dir in list) { var top = string.Format("Results for:\n{0}\n\n", dir); var msg = ""; if (dir.Equals(pref)) msg = "This is your Currently Preferred Folder and Data File.\n\n"; msg = top + msg; text += string.Format(msg + text1 + "\n{0}\n\n" + text2 + "\n{1}\n\n\n", GetStoredReportsDirPref(dir), GetPrefFileName(dir)); } var size = AUS.Default.OMA_D1_Size; var loca = AUS.Default.OMA_D1_Loca; DisplayResults(text, title, ref size, ref loca); AUS.Default.OMA_D1_Size = size; AUS.Default.OMA_D1_Loca = loca; AUS.Default.Save(); } /// These are an interconnected group of /// overloaded methods to handle various needs. /// This one defaults to a Title of "View Preferences" /// and calls the next one down and so on. /// Combines: DisplayResult, DisplayResults & DisplayOutCome. /// if title is empty default as shown. /// This one has it's own Settings for Form Size & Location. /// /// /// private static void DisplayResults(string text, string title) { if (string.IsNullOrEmpty(title)) title = "View Preferences:"; var size = AUS.Default.OMA_DOC_Size; var loca = AUS.Default.OMA_DOC_Loc; DisplayResults(text, title, ref size, ref loca); AUS.Default.OMA_DOC_Size = size; AUS.Default.OMA_DOC_Loc = loca; AUS.Default.Save(); } /// Original v4.6.9.95 Apr 07 2017 /// Given a List of two strings, each, in a Generic Dictionary Collection, /// Call the common GetDisplayString() and then the DisplayResults(); /// Rebuilt with OverLoads above for ViewAllAssociations v4.7.3.73 May 15 /// It directly calls the Mother Method of them all below the next one, /// As does the next one. /// /// private void DisplayResults(Dictionary dic) { var dir = reportsListBox.SelectedItem.ToString(); var text = GetDisplayString(dic, dir); var size = AUS.Default.OMA_Display_Size; var loca = AUS.Default.OMA_Display_Loc; const string title = ""; DisplayResults(text, title, ref size, ref loca); AUS.Default.OMA_Display_Size = size; AUS.Default.OMA_Display_Loc = loca; AUS.Default.Save(); } /// This one accepts the Collection of Dictionaries for /// ViewAllAssociations(); Has it's own special Size & Location Settings. /// It directly calls the Mother Method of them all below this one. /// NOTE: "var x = ..." below does a ton of work, /// & faster because instead of a loop it's a LINQ query! /// /// private static void DisplayResults (IEnumerable> listOfLists) { #region was //var i = 0; //var x = ""; //foreach (var dic in listOfLists) // x += GetDisplayString(dic, OPS.Default.reportsListBoxItems[i++]); #endregion was var i = 0; var x = listOfLists.Aggregate("", (current, dic) => current + GetDisplayString(dic, OPS.Default.reportsListBoxItems[i++]) + "========================"); const string t = ""; var s = AUS.Default.OMA_D4_S; var l = AUS.Default.OMA_D4_L; DisplayResults(x, t, ref s, ref l); AUS.Default.OMA_D4_S = s; AUS.Default.OMA_D4_L = l; AUS.Default.Save(); } /// This overload is where all end up. /// It allows for total flexibility of usages for all args. /// While providing critical defaults to reduce duplicity. /// if title is empty it defaults to: /// "Folder Associations Information:" /// /// /// /// /// private static void DisplayResults (string x, string t, ref Size s, ref Point l) { if (string.IsNullOrEmpty(t)) t = "Folder Associations Information:"; using (var f = new ShowMeForm(x, t)) { f.Size = s; f.Location = l; f.ShowDialog(); l = f.Location; s = f.Size; } } /// This was split out so it can be used by both /// the View2Associations and the ViewAllAssociations: v4.7.3.75 /// Added the string dir arg to the sig to interface it with both. /// /// /// /// private static string GetDisplayString (Dictionary dic, string dir) { // Sweet! Great integration. #region Was //foreach (var pair in list) //{ // // Concatenate the text string and show it. // text += "The Data Folder:\n" + pair.Key + // "\n\nWhich is set to the Data file: \n" + // pair.Value + "\n\n"; //} #endregion Was var text = string.Format("\nResults for: {0}\n\n" + "The following currently use this Reports Folder:\n\n", dir); return dic.Aggregate(text, (current, pair) => current + ("The Data Folder:\n" + pair.Key + "\n\nWhich is set to the Data file: \n" + pair.Value + "\n\n")); } /// Upgrade v4.7.3.96 May 30 2017 /// Similar to the View2Ass but foreach item in ReportsListBox. /// Design hopped up the Engine below for usage here by splitting /// the existing EventHandler v into two parts, /// the 2nd of which (the engine) I can reuse here. /// NOTE use of Collection of Dictionaries. Very powerful and /// especially when you consider that Dictionaries are Generic! /// this calls a special overload of DisplayResults(list); /// /// /// private void ViewAllAssociationsClick(object sender, EventArgs e) { var none = new Collection(); var list = new Collection>(); var dirs = OPS.Default.reportsListBoxItems; foreach (var dir in dirs.Cast() .Where(dir => !string.IsNullOrEmpty(dir) && Directory.Exists(dir))) { var dict = new Dictionary(); View2AssociationsEngine(dir, ref dict, true); if (dict.Count < 1) { #region Rev Doc // collect the unused paths HERE and do the Yes/No-remove // later after this loop. The "true" in the call to the engine // (above View2Ass) skips that in there now. v4.7.3.72 -JpE- #endregion Rev Doc none.Add(dir); continue; } list.Add(dict); } if (list.Count > 0) DisplayResults(list); if (none.Count > 0) BatchRemove(none); } private void BatchRemove(ICollection unused) { #region was //foreach (var path in unused) //{ // if (OPS.Default.reportsListBoxItems.IndexOf(path) < 1) continue; // var text = ORS.OMA_ViewAss + "\n\nPath:\n" + path; // if (MessageBox.Show(text, ORS.OMA_ViewAssTitle, // MessageBoxButtons.YesNo, MessageBoxIcon.Question, // MessageBoxDefaultButton.Button2) // != DialogResult.Yes) continue; // if (path.Equals(OPS.Default.PrefReportsDir)) // { // var target = // OPS.Default.reportsListBoxItems.IndexOf(path) + 1; // // if Pref Adopt next in List automatically as new Pref. // if (target == unused.Count) target = 0; // ReportsTextBox.Text = WhatWasItB2 = // OPS.Default.PrefReportsDir = // OPS.Default.reportsListBoxItems[target]; // if (target < 1) continue; // } // OPS.Default.reportsListBoxItems.Remove(path); //} #endregion was foreach (var path in from path in unused where OPS.Default.reportsListBoxItems.IndexOf(path) >= 1 let text = ORS.OMA_ViewAss + "\n\nPath:\n" + path where AST.YesNoDialog(text, ORS.OMA_ViewAssTitle) || OPS.Default.MiniVerb //|| OPS.Default.AreYouSure select path) { if (path.Equals(OPS.Default.PrefReportsDir)) { var target = OPS.Default.reportsListBoxItems.IndexOf(path) + 1; // if Pref Adopt next in List automatically as new Pref. if (target == unused.Count) target = 0; ReportsTextBox.Text = WhatWasItB2 = OPS.Default.PrefReportsDir = OPS.Default.reportsListBoxItems[target]; if (target < 1) continue; } OPS.Default.reportsListBoxItems.Remove(path); } PopulateListBoxes(); } /// ContextMenuStrip2 Item for Reports Dirs. This one was funner, /// it will flip through the data folder list and get the prefs info for /// Reports Folder and Collate a list of those that use the Selected Reports Folder /// and the pref filename for each. plagarized from myself in this reWrite for /// Collections.Generic.Dictionary: v4.6.9.94 Apr 06 2017 -JpE- /// Split into this and the Engine below for ViewAll mods v4.7.3.73 May 15 2017 /// /// /// private void View2AssociationsToolStrip2MenuItemClick(object sender, EventArgs e) { var dir = reportsListBox.SelectedItem.ToString(); var dic = new Dictionary(); View2AssociationsEngine(dir, ref dic, false); // !all = single path if (dic.Count > 0) DisplayResults(dic); } /// Split from the above for ReUse with ViewAllAss Mods v4.7.3.74 /// NOTE that if all == true then it cuts short at the comment defering removals. /// Hand crafted to work with ViewAllAssociationsClick(); -JpE- May 17 2017 /// /// /// /// private void View2AssociationsEngine (string selected, ref Dictionary dirFileNameList, bool all) { var invalid = new Collection(); var nth = 0; try { foreach (var dataPath in OPS.Default.dataListBoxItems) { if (!Directory.Exists(dataPath)) { invalid.Add(dataPath); continue; } if (!selected.Equals(GetStoredReportsDirPref(dataPath))) continue; // else it found one... var key = string.Format("{0}) ", ++nth) + dataPath; var prefsFilesName = GetPrefFileName(dataPath); if (string.IsNullOrEmpty(prefsFilesName)) { prefsFilesName = "None Associated"; } dirFileNameList.Add(key, prefsFilesName); } } // <-= End of Loop. catch (ArgumentException exception) { if (IF.Testing) MessageBox.Show(exception.ToString()); return; } if (invalid.Count > 0) RemoveInvalidFolders(true, invalid); // Apt identifiers. // v reworked to do a BatchRemove call in ViewAllAss v72... if (all || dirFileNameList.Count > 0) return; // ^ ...& defer removes when "all" arg is true. // ViewALL returns here skipping the rest each iteration. So... //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ #region View2 call only sees the rest of this. if (!AST.YesNoDialog(ORS.OMA_ViewAss, ORS.OMA_ViewAssTitle)) return; if (OPS.Default.reportsListBoxItems.IndexOf(selected) < 1) { MessageBox.Show(ORS.OF_Remove); return; } if (selected.Equals(OPS.Default.PrefReportsDir)) { var target = OPS.Default .reportsListBoxItems.IndexOf(selected) + 1; if (target == OPS.Default.reportsListBoxItems.Count) target = 0; // if Pref, Adopt next in List automatically as new Pref. ReportsTextBox.Text = WhatWasItB2 = OPS.Default.PrefReportsDir = OPS.Default.reportsListBoxItems[target]; if (target == 0) return; } // either way, it's history... OPS.Default.reportsListBoxItems.Remove(selected); PopulateListBoxes(); #endregion View2 call only section. } // v4.7.3.70 May 14 2017 // Took these to a ShowMe calling DisplayResults() private void ViewBackupDataList(object sender, EventArgs e) { var flag = false; var text = "There is no Backup for this List."; if (PMS.Default.Bac_dataCollection != null && PMS.Default.Bac_dataCollection.Count > 0) { flag = true; text = PMS.Default.Bac_dataCollection.Cast() .Aggregate("Data Collection:\n\n", (current, dir) => current + (dir + "\n")); } if (!flag) { MessageBox.Show(text); return; } const string title = "Backup Data Folder List"; var size = AUS.Default.OMA_D2_Size; var loca = AUS.Default.OMA_D2_Loca; DisplayResults(text, title, ref size, ref loca); AUS.Default.OMA_D2_Size = size; AUS.Default.OMA_D2_Loca = loca; AUS.Default.Save(); } private void ViewBackupReportsList(object sender, EventArgs e) { var flag = false; var text = "There is no Backup for this List."; if (PMS.Default.Bac_reportsCollection != null && PMS.Default.Bac_reportsCollection.Count > 0) { flag = true; text = PMS.Default.Bac_reportsCollection.Cast() .Aggregate("Reports Collection:\n\n", (current, dir) => current + (dir + "\n")); } if (!flag) { MessageBox.Show(text); return; } const string title = "Backup Reports Folder List"; var size = AUS.Default.OMA_D3_Size; var loca = AUS.Default.OMA_D3_Loca; DisplayResults(text, title, ref size, ref loca); AUS.Default.OMA_D3_Size = size; AUS.Default.OMA_D3_Loca = loca; AUS.Default.Save(); } #endregion Upgrade 4.7.3.73 Updates to existing and new. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ #region v4.7.5.25 14Jun17 -=[ THE BIG 2 ]=- /* Upgrade Adds The Context Menu Items to Backup & Restore * The Lists Which are already Saved in PrintMasterSettings. * The Save and Restore of Lists is already in & tested. -JpE- * Retain/Revert/Cancel is in and tested. The Big 2 methods here * are the EventHandlers for these Context Menu Options in each ListBox. * They are known here, affectionately, as the Big 2. Each Full Featured. * * The rest of the NEXT #region is the various ReUsable Methods that support * the Big 2. I wanted to make everything modular and these support methods are * very flexible and get used by all 4 of the EventHandlers. Each support method * has at least 2 code paths (data true or false) and most have 4 for each occasion. * BackupDataList, BackupReportsList, RestoreDataList & RestoreReportsList. * I was practicing making things compact and reusable and reducing total code. * Updated v4.7.5.28 Jun 16 2017 for the AutoBackup and everything called from * AppCode2.Restore4(); for Maintenance. * */ #region Backup & Backup Specific /// BackupDataList Context Menu EventHandler /// Split out & consolidated to BackupLists which /// now does both. v4.7.5.21 12Jun17 /// /// /// private void BackupDataList(object sender, EventArgs e) { const bool data = true, auto = false; BackupLists(data, auto); } /// AutoMode Tricks. v4.7.5.15 10Jun17 /// v4.7.5.12.3 Jun 08 17 Mods adds BackupListsAuto(); /// to Restore3, Scheduler Call. Setting sender here /// makes it auto-mode there. /// So... sig is (bool data, bool auto) /// v4.7.5.19 Perfected and Final Testing. 12Jun17 /// Constructor in OF makes this possible though /// it is not static, through an instantiation. /// public void BackupListsAuto() { //BackupLists( data, auto); // por exemplar BackupLists( true, true); // datafolders BackupLists(false, true); // reportsfolders } /// BackupReportsList Context Menu EventHandler /// Split out & consolidated to BackupLists which /// now does both. v4.7.5.21 12Jun17 /// /// /// private void BackupReportsList(object sender, EventArgs e) { const bool data = false, auto = false; BackupLists(data, auto); } /// All-In-One Backup Module /// RetroFit for automode v4.7.5.23 /// 12-Jun-2017 /// /// /// private void BackupLists(bool data, bool auto) { if (!AskUser(data, auto)) return; const bool backup = true; var merge = false; StringCollection unique; if (HasUniquePath(data, out unique, backup)) { // Backup has something unique. if (auto) merge = true; else merge = OPS.Default.MiniVerb || AST.YesNoDialog(ORS.OMA_B1, 1); } var what = 0; var both = BothHaveBoth(ref what, data); if (!merge && unique.Count > 0) { var r = AST.YesNoCancel(ORS.OMA_B2, 1); if (r == 3) return; // Cancel Clicked. if (r == 1) { DontMerge(data); what = 1; both = false; unique.Clear(); } if (r == 2) merge = true; } var rr = 0; if (!auto) if (both && merge) rr = RetainRevert(ORS.OMA_B3); if (rr > 2) return; var retain = rr < 2; if (!both) { if (what < 2) retain = true; if (what == 2) retain = false; } // what == 1 (is) only in OS, 2 only in PMS, 0 == Neither. if (what < 1 && !auto) { if (data) SoWhat(); // and here else SoWhatElse(); } Merger(retain, unique, backup, data, auto); // replace 2nd true for data var inside. OPS.Default.Save(); PMS.Default.Save(); if (OPS.Default.MiniVerb || auto) return; ShowBackupResult(true, merge, retain); } /// Ask for for User Input to Proceed. /// but there is no more Big Four it's the Big two now LoL /// The Big two each ate one of the Big 4 but didn't grow. /// /// /// /// private static bool AskUser(bool data, bool auto) { // Split out from BackupLists v4.7.5.21 if (data) { if (OPS.Default.dataListBoxItems.Count < 1) { if (!auto) MessageBox.Show(ORS.OMA_E2); return false; } if (!OPS.Default.MiniVerb && !OPS.Default.AreYouSure && !auto) if (!AST.YesNoDialog(ORS.OMA_BDL)) return false; } else // if not data it is reports calling. { if (OPS.Default.reportsListBoxItems.Count < 1) { if (!auto) MessageBox.Show(ORS.OMA_E3); return false; } if (!OPS.Default.MiniVerb && !OPS.Default.AreYouSure && !auto) if (!AST.YesNoDialog(ORS.OMA_BRL)) return false; // Skips in AutoMode. } return true; } /// Straight Backup No Merge. /// Split out from BackupLists v4.7.5.24 /// June 13 2017 /// /// private static void DontMerge(bool data) { if (data) { PMS.Default.Bac_PrefRootDir = OPS.Default.PrefRootDir; PMS.Default.Bac_PrefFileName = OPS.Default.PrefFileName; } else { PMS.Default.ReportsFolder = OPS.Default.PrefReportsDir; } PMS.Default.Save(); } /// Display results of Backup /// Works for either List retrofit and /// Split out v4.7.5.24 June 13 2017 /// /// /// /// private static void ShowBackupResult(bool data, bool merge, bool retain) { // Skip-All Setting & AutoMode skip Display Msg. var text = ORS.OMA_DLB; // only this var varies. if (!data) text = ORS.OMA_RLB; if (merge) { text = retain // True/False, Left to Right as assignment. ? ORS.OMA_B4 : ORS.OMA_B5; text += "\n\n" + ORS.OMA_B6; } MessageBox.Show(text); } #endregion Backup & Backup Specific //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ #region Restore & Restore Specific /* Early Analysis and Design Notes: * * 1) Which methods from DataList are reUseable? * a) Houston() * b) Obviously, YesNoDialog() LoL * c) HasUniquePath(false, out unique) is it. (false is Reports) * d) RetainRevert & the RetainRevertCancel Object are very reUsable. * e) AddUnique() is reUsable with false for reports. * f) A Reports-Folder-Select thingy exists somewhere in this source code file. * * 2) Which are not, AND which will be needed? (ie. rewritten for Reports.) * a) BothHaveBoth can be BothHaveIt() for reports List. * b) Merger(), RevertPrefs and MergeLists() will all have to be at-least * edited for ReportsList. Maybe modified to do both or cloned out to it's own method. * c) A desperate call to SoWhat() may be needed. The else branch of * the DataList version seems reUsable enough maybe? * d) SelectRootDir() can be cloned and edited easily enough. * * 3) Which are not, but will not be needed? * b) I'm not sure ReCheck() in any form will be needed. Maybe something else? * * 4) What methods will be completely new in ReportsList? * a) All of them LOL, they evolved to be 4 function each for backups and restores * b) and for data and reports. Most go all four ways LoL. v4.7.3.65 May 11 2017 * By: * John.P.Edwards dba Global Access Software Intl. * Designed, Produced, Coded, Tested and Developed by -JpE- (C) 2011-2026 */ private void RestoreDataList(object sender, EventArgs e) { const bool data = true; RestoreLists(data); } private void RestoreReportsList(object sender, EventArgs e) { const bool data = false; RestoreLists(data); } private void RestoreLists(bool data) { // Store & Retrieve PrefRoot, Reports and FileName as well. // Retain members of this list that do not appear in the backup? if (!AskUser2(data)) return; const bool backup = false, auto = false; var merge = false; StringCollection unique; if (HasUniquePath(data, out unique, backup)) merge = OPS.Default.MiniVerb || AST.YesNoDialog(ORS.OMA_R1, 1); var what = 0; var both = BothHaveBoth(ref what, data); // if (!both && which == 1 = only in OS, 2 = only in PMS, // 0 = Neither has needed Info. if (!merge && unique.Count > 0) { // v added v4.7.2.55 May 05 var r = AST.YesNoCancel(ORS.OMA_R2, 1); if (r == 3) return; if (r == 1) { DontMerge2(data); what = 2; both = false; unique.Clear(); } if (r == 2) merge = true; } var rr = 0; // Retain the Preferred Folders // ...and FileName or revert to backup? if (both && merge) rr = RetainRevert(); // ^ returns 1 if retain & 2 if revert, 3 if Cancel. if (rr > 2) return; // Cancel. // Which leaves only 0, 1 & 2 on the table. var retain = rr < 2;// == 1; // retain = true is retain, false is revert. if (!both) { if (what < 2) retain = true; if (what == 2) retain = false; } if (what.Equals(0)) { if (data) SoWhat(); else SoWhatElse(); } // All set, let's do it! Merger(retain, unique, backup, data, auto); Changes(data); // And now that it is restored... if (OPS.Default.MiniVerb) return; ShowRestoreResult(data, merge, retain); } private void Changes(bool data) { if (data) { folderBrowser.SelectedPath = OPS.Default.PrefRootDir; DataChanges(); } else { folderBrowser.SelectedPath = OPS.Default.PrefReportsDir; ReportsChanges(); } } private static void DontMerge2(bool data) { if (data) { OPS.Default.PrefFileName = PMS.Default.Bac_PrefFileName; OPS.Default.PrefRootDir = PMS.Default.Bac_PrefRootDir; OPS.Default.PrefReportsDir = PMS.Default.ReportsFolder; } else OPS.Default.PrefReportsDir = PMS.Default.ReportsFolder; } private static bool AskUser2(bool data) { if (Houston()) { // aka We have a problem! MessageBox.Show(ORS.OMA_E1); return false; } var msg = ORS.OMA_RDL; if (!data) msg = ORS.OMA_RRL; if ( !OPS.Default.MiniVerb && !OPS.Default.AreYouSure) if (!AST.YesNoDialog(msg)) return false; return true; } private static void ShowRestoreResult (bool data, bool merge, bool retain) { var text = ORS.OMA_DLR; if (!data) text = ORS.OMA_RLR; if (merge) { text = retain ? ORS.OMA_R3 : ORS.OMA_R4; text += "\n\n" + ORS.OMA_R5; } MessageBox.Show(text); } #endregion Restore & Restore Specific //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ #endregion v4.7.2.56-65 May 06-11 2017 -=[ THE BIG 2 ]=- //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ #region Supporting Methods FOR 4 way w/ -=[ THE BIG 2 ]=- // NOTE: retain == true to retain, false to revert. // what == 1 means only in OS, 2 means only in PMS, // (retain defaults to true if what==1, false if what==2) // both == true means Both Have BOTH PrefRootDir & PrefFileName. /// Quad Function Router for the Big 2 Method Groups: /// BackupDataList, RestoreDataList, BackupReports & RestoreReports. /// Retain and Revert Logic Switched up on Backups and Worded differently /// in the RetainRevert() call. Feature adds full functionality for Lists. /// 4 code paths for backup and data, true or false as illustrated. /// backup true - data true, backup true - data false, backup false - data true, /// and backup false - data false. Are all covered here for the Big 4 Methods. /// And further switched herein by retain. For 8 possible code paths in one here. /// auto is only true if this is an Automatic-Backup of either List. /// v4.7.5.25 Compatible, nothing changed down here, just in the Big 2 above. /// /// /// /// /// /// private void Merger( bool retain, StringCollection unique, bool backup, bool data, bool auto) { if (!backup) { if (!retain) RevertPrefs(data); } // if retain we're already set. else { // backup == true if (retain) { if (data) { // DataList, Backup, Retain. PMS.Default.Bac_PrefRootDir = OPS.Default.PrefRootDir; PMS.Default.Bac_PrefFileName = OPS.Default.PrefFileName; } else PMS.Default.ReportsFolder = OPS.Default.PrefReportsDir; // Rprts. } else { // if (!retain && backup) Revert Backup to Backup Prefs. var c = unique.Count; if (data) { // Data List, Backup, Revert. (True/False v) var dir = c > 0 ? unique[0] : PMS.Default.Bac_PrefRootDir; if (Directory.Exists(dir)) PMS.Default.Bac_PrefRootDir = dir; else if (!auto) SoWhat(); var fn = GetPrefFileName(dir); if (File.Exists(dir + "\\" + fn)) PMS.Default.Bac_PrefFileName = fn; else if (!auto) SoWhat(); } else { // Reports List Backup, Revert. var dir = c > 0 ? unique[0] : PMS.Default.ReportsFolder; if (Directory.Exists(dir)) PMS.Default.ReportsFolder = dir; else if (!auto) SoWhatElse(); } } // Then just flip it on Backups, for best affect. ;-) retain = !retain; } // Now Merge them according to retain, backup & data. if (data) MergeDataLists(retain, unique, backup); else MergeReportsLists(retain, unique, backup); // ^ Data/Reports Differs here+Backup/Restore ^ differs there. } /// Runs only from the 2 Restore Tasks. /// Reverts the Current Prefs to the Backup Prefs. /// data == true is Data LIst, false is Reports. /// /// private void RevertPrefs(bool data) { if (data) { // Use Prefs from PMS. var dir = DataTextBox.Text = WhatWasItB4 = OPS.Default.PrefRootDir = PMS.Default.Bac_PrefRootDir; var fnp = GetPrefFileName(dir); var rec = GetStoredReportsDirPref(dir); var tea = false; if (!File.Exists(dir + "\\" + fnp)) { SoWhat(); tea = true; } if (!Directory.Exists(rec)) { SoWhatElse(); tea = true; } if (tea) return;// tea time, bye! // ^^^^ I bet flow never gets to either, but Justin Case. OPS.Default.PrefFileName = fnp; ReportsTextBox.Text = OPS.Default.PrefReportsDir = rec; } else { var or = OPS.Default.PrefReportsDir; var pr = PMS.Default.ReportsFolder; if (Directory.Exists(pr)) ReportsTextBox.Text = OPS.Default.PrefReportsDir = WhatWasItB2 = pr; else { if (Directory.Exists(or)) return; SoWhatElse(); if (Directory.Exists(OPS.Default.PrefReportsDir)) return; var ok = ReportsTextBox.Text = OPS.Default.PrefReportsDir = OPS.Default.PrefRootDir + "\\" + PMS.Default.Reports; if (!Directory.Exists(ok)) Directory.CreateDirectory(ok); } } } /// if backup == false then it's a Restore Task. /// If Revert, it tacks the diffs on the end, (retain==false) /// if Retain, it puts them up top. NOTE: Reversed for Backups! /// if backup == true then it's a little different logic circuit: /// Retain puts the diffs from backup at the bottom, keeping the Current. /// Revert puts the diffs from backup at the Top of the List. /// Merges the two Data Folder Lists. /// /// /// /// private static void MergeDataLists (bool retain, IEnumerable unique, bool backup) { if (backup) // We're backing up the Current List. { if (PMS.Default.Bac_dataCollection == null) PMS.Default.Bac_dataCollection = new StringCollection(); var _default = OPS.Default.dataListBoxItems[0]; PMS.Default.Bac_dataCollection.Clear(); PMS.Default.Bac_dataCollection.Add(_default); var enumerable = unique as object[] ?? unique.Cast().ToArray(); if (retain) AddUnique(true, enumerable, true); foreach (var dir in OPS.Default .dataListBoxItems.Cast() .Where(Directory.Exists) .Where(dir => !dir.Equals(_default))) PMS.Default.Bac_dataCollection.Add(dir); if (!retain) AddUnique(true, enumerable, true); } else // It's a Restore Task. { // Either way, We will clear and refill the List. // But grab the default and keep it up Top always. if (PMS.Default.Bac_dataCollection == null) PMS.Default.Bac_dataCollection = new StringCollection(); var _default = OPS.Default.dataListBoxItems[0]; OPS.Default.dataListBoxItems.Clear(); OPS.Default.dataListBoxItems.Add(_default); // if Retain, Put the diffs up Top. var enumerable = unique as object[] ?? unique.Cast().ToArray(); if (retain) AddUnique(true, enumerable, false); foreach (var dir in PMS.Default .Bac_dataCollection.Cast() .Where(Directory.Exists) .Where(dir => !dir.Equals(_default))) OPS.Default.dataListBoxItems.Add(dir); // Else, Tack diffs on the end. if (!retain) AddUnique(true, enumerable, false); } } /// if backup == false then it's a Restore Task. /// If Revert, it tacks the diffs on the end, (retain==false) /// if Retain, it puts them up top. NOTE: Reversed for Backups! /// if backup == true then it's a little different logic circuit: /// Retain puts the diffs from backup at the bottom, keeping the Current. /// Revert puts the diffs from backup at the Top of the List. /// Merges the two Reports Folder Lists. /// /// /// /// private static void MergeReportsLists (bool retain, IEnumerable unique, bool backup) { if (backup) // it's a Backup Task. { if (PMS.Default.Bac_reportsCollection.Equals(null)) PMS.Default.Bac_reportsCollection = new StringCollection(); var d = OPS.Default.reportsListBoxItems[0]; PMS.Default.Bac_reportsCollection.Clear(); PMS.Default.Bac_reportsCollection.Add(d); var e = unique as object[] ?? unique.Cast().ToArray(); if (retain) AddUnique(false, e, true); foreach (var dir in OPS.Default .reportsListBoxItems.Cast() .Where(Directory.Exists) .Where(dir => !dir.Equals(d))) PMS.Default.Bac_reportsCollection.Add(dir); if (!retain) AddUnique(false, e, true); } else // it's a restore task. (already tested below) { if (PMS.Default.Bac_reportsCollection.Equals(null)) PMS.Default.Bac_reportsCollection = new StringCollection(); var d = OPS.Default.reportsListBoxItems[0]; OPS.Default.reportsListBoxItems.Clear(); OPS.Default.reportsListBoxItems.Add(d); var e = unique as object[] ?? unique.Cast().ToArray(); if (retain) AddUnique(false, e, false); foreach (var dir in PMS.Default .Bac_reportsCollection.Cast() .Where(Directory.Exists) .Where(dir => !dir.Equals(d))) OPS.Default.reportsListBoxItems.Add(dir); if (!retain) AddUnique(false, e, false); } } /// Adds the unique paths to the appropriate collection: /// if data == true then it's Data Folders, if false it's Reports. /// if backup == true it's a backup Task, if false it's a Restore Task. /// NOTE: The if (backup) lines and their else makes it quad function. /// /// /// /// private static void AddUnique (bool data, IEnumerable unique, bool backup) { if (data) // Data List. { foreach (var dir in unique.Cast() .Where(dir => Directory.Exists(dir) && HasDataFiles(dir))) { // if added to make universal v4.7.2.58 if (backup) PMS.Default.Bac_dataCollection.Add(dir); else OPS.Default.dataListBoxItems.Add(dir); } } else // Reports List. { foreach (var dir in unique.Cast() .Where(Directory.Exists)) { // if added to make universal v4.7.2.58 if (backup) PMS.Default.Bac_reportsCollection.Add(dir); else OPS.Default.reportsListBoxItems.Add(dir); } } } /// 1 = only in OS, 2 = only in PMS, 0 = Neither. /// What's up with what: True = Yes, Both. what = 0; in call btw. /// Just Check; that current and backup collections both have; /// both PrefFileName and PrefRootDir. (BothHaveBoth!) /// For Reports (data==false); it Checks if Both Have IT. /// (PrefReportsDir) Same Logic. And Same for Backup & Restore. /// So that doesn't matter here. All 4 of the Big 4 call this method. /// It's results are just interpreted differently during a Backup /// back in the calling methods. No differentiation here for that. /// /// /// /// private bool BothHaveBoth(ref int what, bool data) { var result = false; if (!data) { var or = OPS.Default.PrefReportsDir; var pr = PMS.Default.ReportsFolder; var ol = OPS.Default.reportsListBoxItems; var pl = PMS.Default.Bac_reportsCollection; if (Directory.Exists(or) && ol.Contains(or)) what = 1; if (Directory.Exists(pr) && pl.Contains(pr)) { if (what == 1) result = true; what = 2; } return result; } // else it is Data... var osF = OPS.Default.PrefFileName; var osR = OPS.Default.PrefRootDir; var psF = PMS.Default.Bac_PrefFileName; var psR = PMS.Default.Bac_PrefRootDir; if (Directory.Exists(osR)) { if (File.Exists(osR + "\\" + osF)) what = 1;} if (Directory.Exists(psR)) { if (File.Exists(psR + "\\" + psF)) { if (what.Equals(1)) result = true; what = 2; } } // If one does not, try to use the pref.lbs before final assessment. if (what == 1) // (2) pms does not. Backup does not. False. { if (ReCheck(false)) result = true; } if (what == 2 && result.Equals(false)) // (1) os does not. True. // Fat chance but I'll cover it anyway. LoL. { if (ReCheck(true)) result = true; } return result; } // os false is re check pms, // os true is re check os. Hello!!! // (not likely, but covered anyway.) private bool ReCheck(bool ops) { var found1 = false; if (ops) found1 = ReCheckOps(); else { // pms var list = PMS.Default.Bac_dataCollection; int count = list.Count, index = 1; if (count < 1) return false; for (; index < count; ++index) { var dir = list[index]; var filename = FileName; FileName = ""; var file = GetPrefFileName(dir); FileName = filename; var path = PMS.Default.ReportsFolder; PMS.Default.ReportsFolder = ""; var repo = GetStoredReportsDirPref(dir); PMS.Default.ReportsFolder = path; if (!Directory.Exists(dir) || !HasDataFiles(dir) || !File.Exists(dir + "\\" + file) || string.IsNullOrEmpty(file) || string.IsNullOrEmpty(repo)) continue; PMS.Default.Bac_PrefFileName = file; PMS.Default.Bac_PrefRootDir = dir; found1 = true; if (Directory.Exists(repo)) PMS.Default.ReportsFolder = repo; else { var test = OPS.Default.PrefReportsDir; if (Directory.Exists(test)) { PMS.Default.ReportsFolder = test; } else { test = AUS.Default.RootDir; if (Directory.Exists(test)) PMS.Default.ReportsFolder = test; else { var check = AUS.Default.AppDir + "\\" + APS.Default.Home + "\\" + PMS.Default.Reports; if (Directory.Exists(check)) PMS.Default.ReportsFolder = check; else found1 = false; } } } break; } // end of For Loop. } return found1; } private bool ReCheckOps() { var found = false; var list = OPS.Default.dataListBoxItems; var count = list.Count; if (count < 1) return false; var index = 1; for (;index < count; ++index) { var dir = list[index]; var filename = FileName; FileName = ""; var file = GetPrefFileName(dir); FileName = filename; var path = OPS.Default.PrefReportsDir; OPS.Default.PrefReportsDir = ""; var repo = GetStoredReportsDirPref(dir); OPS.Default.PrefReportsDir = path; if (!Directory.Exists(dir) || !HasDataFiles(dir) || !File.Exists(dir + "\\" + file) || string.IsNullOrEmpty(file) || string.IsNullOrEmpty(repo)) continue; OPS.Default.PrefFileName = file; OPS.Default.PrefRootDir = dir; found = true; if (Directory.Exists(repo)) OPS.Default.PrefReportsDir = repo; else { var test = OPS.Default.PrefReportsDir; if (Directory.Exists(test)) OPS.Default.PrefReportsDir = test; else { test = AUS.Default.RootDir; if (Directory.Exists(test)) OPS.Default.PrefReportsDir = test; else { var check = AUS.Default.AppDir + "\\" + APS.Default.Home + "\\" + PMS.Default.Reports; if (Directory.Exists(check)) OPS.Default.PrefReportsDir = check; else found = false; } } } break; } // end of For Loop. return found; } private void SoWhat() { var x = OPS.Default.dataListBoxItems.Count < 2 ? 0 : 1; var d = OPS.Default.PrefRootDir = OPS.Default.dataListBoxItems[x]; // this ^ one has already been tested for Dir.Exists and HasDataFiles. if (string.IsNullOrEmpty(d) // All 3 If Needed <-= v || !Directory.Exists(d)) d = SelectRootDir(); // <-= TestsWell! var f = GetPrefFileName(d); var r = GetStoredReportsDirPref(d); var t = false; if (File.Exists(d + "\\" + f)) { t = true; // true testswell, false too. OPS.Default.PrefFileName = f; } if (!t) { var size = AUS.Default.OMA_FileSelect_Size; var location = AUS.Default.OMA_FileSelect_Location; var list = GetDataFileList(d); // v4.7.3.93 index mods var index = 0; var test = GetPrefFileName(OPS.Default.PrefRootDir); if (list.Contains(test)) index = list.IndexOf(test); else if (list.Contains(OPS.Default.PrefFileName)) index = list.IndexOf(OPS.Default.PrefFileName); else if (list.Contains(PMS.Default.Bac_PrefFileName)) index = list.IndexOf(PMS.Default.Bac_PrefFileName); else if (list.Contains(AUS.Default.FileName)) index = list.IndexOf(AUS.Default.FileName); else if (list.Contains(APS.Default.defaultFilename)) index = list.IndexOf(APS.Default.defaultFilename); // else default to the index[0] default. // ^ v4.7.3.93 May 30 2017 var choice = SelectOne(list, ref size, ref location, "", index); // <-=/\/\/\/\/\ AUS.Default.OMA_FileSelect_Size = size; AUS.Default.OMA_FileSelect_Location = location; AUS.Default.Save(); if (string.IsNullOrEmpty(choice)) choice = list[index]; OPS.Default.PrefFileName = choice; } if (Directory.Exists(r)) OPS.Default.PrefReportsDir = r; else SoWhatElse(); } /// Split out and ReUsed by RestoreReportsList() v4.7.2.51 /// This was the else portion of SoWhat() btw. LoL /// Aptly named therefor. /// private void SoWhatElse() { var list7 = OPS.Default.reportsListBoxItems; var list8 = new Collection(); const string title = "Select a Reports Folder:"; foreach (var path in list7.Cast() .Where(Directory.Exists)) list8.Add(path); // vvvvvvvvvv v4.7.3.93 May 30 2017 var index = 0; var test = GetStoredReportsDirPref(OPS.Default.PrefRootDir); if (list8.Contains(test)) index = list8.IndexOf(test); else if (list8.Contains(OPS.Default.PrefReportsDir)) index = list8.IndexOf(OPS.Default.PrefReportsDir); else if (list8.Contains(PMS.Default.ReportsFolder)) index = list8.IndexOf(PMS.Default.ReportsFolder); // else default to the index[0] default. // ^ v4.7.3.93 May 30 2017 var size = AUS.Default.OMA_ReportsSelect_Size; var locate = AUS.Default.OMA_ReportsSelect_Location; var report = SelectOne(list8, ref size, ref locate, title, index); // <-=/\/\/\/\/\ AUS.Default.OMA_ReportsSelect_Size = size; AUS.Default.OMA_ReportsSelect_Location = locate; AUS.Default.Save(); if (string.IsNullOrEmpty(report)) report = list8[index]; OPS.Default.PrefReportsDir = report; } private string SelectRootDir() { var d = AUS.Default.AppDir + "\\" + APS.Default.Home; var c = OPS.Default.dataListBoxItems.Count; if (c == 1) d = OPS.Default.dataListBoxItems[0]; if (c < 2) return d; // So, whereever there are two or more. var list = new Collection(); foreach (var dir in OPS.Default.dataListBoxItems .Cast().Where(dir => Directory.Exists(dir) && HasDataFiles(dir))) list.Add(dir); if (list.Count < 2) return list.Count == 1 ? list[0] : d; // vvvvvvvvvv v4.7.3.93 var index = 0; var test = OPS.Default.PrefRootDir; if (list.Contains(test)) index = list.IndexOf(test); else if (list.Contains(AUS.Default.RootDir)) index = list.IndexOf(AUS.Default.RootDir); else if (list.Contains(PMS.Default.Bac_PrefRootDir)) index = list.IndexOf(PMS.Default.Bac_PrefRootDir); // else default to the index[0] default. // ^^^^^ v4.7.3.93 May 30 2017 const string title = "Please Select a Data Folder:"; var s = AUS.Default.OMA_ReportsSelect_Size; var l = AUS.Default.OMA_ReportsSelect_Location; var a = SelectOne(list, ref s, ref l, title, index); // <<=====<< AUS.Default.OMA_ReportsSelect_Location = l; AUS.Default.OMA_ReportsSelect_Size = s; AUS.Default.Save(); if (string.IsNullOrEmpty(a) || !Directory.Exists(a)) a = list[index]; return a; } /// See if the Current List has anything Unique, /// / Not in the Backup. Adds these to the unique Collection. /// bool = true is Data Folders, false is Reports folder lists. /// /// /// /// /// private bool HasUniquePath (bool data, out StringCollection unique, bool backup) { CheckPrefs(); unique = new StringCollection(); var list1 = OPS.Default.dataListBoxItems; var list2 = PMS.Default.Bac_dataCollection; if (!data) // Defaults ^ to Data, false for Reports Collection. { list1 = OPS.Default.reportsListBoxItems; list2 = PMS.Default.Bac_reportsCollection; } if (backup) // Then just... { foreach (var path in from string path in list2 where !list1.Contains(path) where Directory.Exists(path) select path) unique.Add(path); } else // Below Well Tested Restore Mods. { foreach (var path in from string path in list1 where !list2.Contains(path) where Directory.Exists(path) select path) unique.Add(path); } return unique.Count > 0; } /// Check for any Problems /// with the Collections & PrefFileName, etc. /// /// private static bool Houston() { // Justin Case it's a WipEd RuN. if (PMS.Default.Bac_dataCollection.Equals(null)) PMS.Default.Bac_dataCollection = new StringCollection(); if (PMS.Default.Bac_reportsCollection.Equals(null)) PMS.Default.Bac_reportsCollection = new StringCollection(); return PMS.Default.Bac_dataCollection.Count < 1 || PMS.Default.Bac_reportsCollection.Count < 1 || string.IsNullOrEmpty(PMS.Default.Bac_PrefFileName) || string.IsNullOrEmpty(PMS.Default.Bac_PrefRootDir) || string.IsNullOrEmpty(PMS.Default.ReportsFolder); // Check for string.nullorempty ^ in which case: show msg. } /// returns 1 if Retain, 2 if Revert, 3 if Cancel. /// Send it the public Properties LabelText, FormLocation, /// FormForeColor, FormBackColor. LabelText is Optional as /// are the others of course. TestsWell! v4.7.1.38 /// /// private int RetainRevert() { const string txt = ""; return RetainRevert(txt); } private int RetainRevert(string txt) { int chosen; using (var rrc = new RetainRevertCancel()) { // ReUsable Custom Class ^ Object Instantiation. rrc.LabelText = txt; // default if empty. rrc.FormLocation = AUS.Default.RRC_Location; rrc.FormForeColor = TabForeColor; rrc.FormBackColor = TabBackColor; rrc.ShowDialog(); // <-=/\/\/\/\/\/\/\/\/\/**** AUS.Default.RRC_Location = rrc.Location; AUS.Default.Save(); chosen = rrc.ButtonClicked; } return chosen; } #endregion Supporting Methods for the Big 2 Above. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ #endregion Context Menu Items //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ #region Upgrade 4.7.0.07 Apr 13 2017 /// Checks for a pref.lbs and gets the pref Reports folder from it. /// Then AddsToPathCollection(path, false) or whatever. /// /// Called only in OptionsFormLoad(); on entry. /// private void CheckReportsCollection() { var invalid = new List(); var missing = new List(); foreach (var dataPath in OPS.Default.dataListBoxItems) { if (!Directory.Exists(dataPath)) { invalid.Add(dataPath); continue; } // else... var reports = GetStoredReportsDirPref(dataPath); if (!OPS.Default.reportsListBoxItems.Contains(reports) && Directory.Exists(reports) && !missing.Contains(reports)) { missing.Add(reports); } } // Last line here ^ should fix dup reports dirs. v4.7.0.05 Apr 13 if (missing.Count > 0) { if (AST.YesNoDialog("Add Missing Reports Folders to the Collection?")) { var _default = AUS.Default.AppDir + "\\" + APS.Default.Home + "\\" + PMS.Default.Reports; var count = OPS.Default.reportsListBoxItems.Count; if (count < 2 || !OPS.Default.reportsListBoxItems.Contains(_default)) { if (OPS.Default.reportsListBoxItems.Contains(_default) && OPS.Default.reportsListBoxItems.IndexOf(_default) > 0) { OPS.Default.reportsListBoxItems.Remove(_default); --count; } if (!OPS.Default.reportsListBoxItems.Contains(_default)) { if (count.Equals(0)) OPS.Default.reportsListBoxItems.Add(_default); else OPS.Default.reportsListBoxItems.Insert(0, _default); } } if (missing.Contains(_default)) missing.Remove(_default); foreach (var dir in missing) { OPS.Default.reportsListBoxItems.Add(dir); } } } RemoveInvalidFolders(true, invalid); } /// Stores everything in OMA Settings Wise on FormLoad. /// so it can be brought back on Cancel/Abort/Red-X. /// private void SaveInitialSettings() { CreateNewDetectionStrings(); // ^ Added v4.7.0.07 _data.Clear(); foreach (var str in OPS.Default.dataListBoxItems) { _data.Add(str); } _reports.Clear(); foreach (var str in OPS.Default.reportsListBoxItems) { _reports.Add(str); } if (!OPS.Default.Schedule1 || OPS.Default.Scheduled1 < DateTime.Now.AddYears(-1)) { // wipe bugg fixed ^v v4.7.2.44 Apr 29 2017 OPS.Default.Schedule1 = true; OPS.Default.Scheduled1 = DateTime.Now; OPS.Default.Save(); } _scheduler[0] = OPS.Default.Schedule1; _scheduler[1] = OPS.Default.Schedule3; _scheduler[2] = OPS.Default.Schedule5; if (_scheduler[0]) _scheduled[0] = OPS.Default.Scheduled1; if (_scheduler[1]) _scheduled[1] = OPS.Default.Scheduled3; if (_scheduler[2]) _scheduled[2] = OPS.Default.Scheduled5; CheckPrefs(); // <-= WipeSchedule Bugg Fixed v4.7.2.44 // v v4.7.0.07 Scheduler Upgrade Apr 14 2017 DayOfWeekCheckBox.Checked = DayOfWeek = OPS.Default.DoW; Change = false; } private void CreateNewDetectionStrings() { Data = OPS.Default.dataListBoxItems.Cast() .Aggregate((current, str) => current + str); Reports = OPS.Default.reportsListBoxItems.Cast() .Aggregate((current, str) => current + str); } /// Then comes back here from FormClosing for the Below. /// Because of Change == false; above, But only if !ForReal == true; /// If (ForReal == true) then nothing needs to be brought back at-all. /// private void AbortChanges() { OPS.Default.dataListBoxItems.Clear(); foreach (var str in _data) { OPS.Default.dataListBoxItems.Add(str); } OPS.Default.reportsListBoxItems.Clear(); foreach (var str in _reports) { OPS.Default.reportsListBoxItems.Add(str); } OPS.Default.Schedule1 = _scheduler[0]; OPS.Default.Schedule3 = _scheduler[1]; OPS.Default.Schedule5 = _scheduler[2]; OPS.Default.Scheduled1 = _scheduled[0]; OPS.Default.Scheduled3 = _scheduled[1]; OPS.Default.Scheduled5 = _scheduled[2]; if (!string.IsNullOrEmpty(PrefFilename)) OPS.Default.PrefFileName = PrefFilename; if (!string.IsNullOrEmpty(PrefRootDir)) OPS.Default.PrefRootDir = PrefRootDir; if (!string.IsNullOrEmpty(PrefReports)) OPS.Default.PrefReportsDir = PrefReports; OPS.Default.DoW = DayOfWeek; OPS.Default.Save(); } /// returns true if anything changed this run. /// /// private bool SettingsChanged() { if (CheckPrefs()) return true; bool s1 = _scheduler[0], s3 = _scheduler[1], s5 = _scheduler[2]; DateTime t1 = _scheduled[0], t3 = _scheduled[1], t5 = _scheduled[2]; return !s1.Equals(OPS.Default.Schedule1) || !s3.Equals(OPS.Default.Schedule3) || !s5.Equals(OPS.Default.Schedule5) || s1 && !t1.Equals(OPS.Default.Scheduled1) || s3 && !t3.Equals(OPS.Default.Scheduled3) || s5 && !t5.Equals(OPS.Default.Scheduled5) || CheckCollections() || !PrefFilename.Equals(OPS.Default.PrefFileName) || !PrefRootDir .Equals(OPS.Default.PrefRootDir) || !PrefReports .Equals(OPS.Default.PrefReportsDir) || !DayOfWeek .Equals(OPS.Default.DoW); } // Added v4.7.2.44 Apr 29 2017 private bool CheckPrefs() { var result = false; if (string.IsNullOrEmpty(PrefFilename)) { result = true; var pf = AUS.Default.FileName; if (!string.IsNullOrEmpty(pf) && File.Exists(AUS.Default.RootDir + "\\" + pf)) PrefFilename = OPS.Default.PrefFileName = pf; else PrefFilename = OPS.Default.PrefFileName = APS.Default.defaultFilename; } if (string.IsNullOrEmpty(PrefRootDir)) { result = true; var pr = AUS.Default.RootDir; if (!string.IsNullOrEmpty(pr) && Directory.Exists(pr)) PrefRootDir = OPS.Default.PrefRootDir = pr; else PrefRootDir = OPS.Default.PrefRootDir = AUS.Default.AppDir + "\\" + APS.Default.Home; } if (string.IsNullOrEmpty(PrefReports)) { result = true; var rp = PMS.Default.ReportsFolder; if (!string.IsNullOrEmpty(rp) && Directory.Exists(rp)) PrefReports = OPS.Default.PrefReportsDir = rp; else PrefReports = OPS.Default.PrefReportsDir = AUS.Default.AppDir + "\\" + APS.Default.Home + "\\" + PMS.Default.Reports; } if (PMS.Default.Bac_dataCollection.Equals(null)) { result = true; PMS.Default.Bac_dataCollection = new StringCollection(); } if (PMS.Default.Bac_reportsCollection.Equals(null)) { result = true; PMS.Default.Bac_reportsCollection = new StringCollection(); } if (result) OPS.Default.Save(); return result; } // ^v Both Return true if anything has changed. private bool CheckCollections() { var line1 = Data; var line2 = Reports; CreateNewDetectionStrings(); return !line1.Equals(Data) || !line2.Equals(Reports); } #endregion Upgrade 4.7.0.07 Apr 13 2017 //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ #endregion Alternate Folder Finder //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ } }