/// <summary> /// Initializes a new instance of the <see cref="CopySaveOptionsWindow"/> class. /// </summary> /// <param name="pto">The pto.</param> /// <param name="plan">The p.</param> /// <param name="isForCopy">if set to <c>true</c> [is for copy].</param> public CopySaveOptionsWindow(PlanExportSettings pto, Plan plan, bool isForCopy) : this() { m_planTextOptions = pto; m_plan = plan; m_isForCopy = isForCopy; }
public PrintOptionsDialog(PlanExportSettings pto, PrintDocument doc) { InitializeComponent(); int index; string curPrinter = doc.PrinterSettings.PrinterName; m_pto = pto; foreach (String printer in PrinterSettings.InstalledPrinters) { index = comboPrinters.Items.Add(printer); doc.PrinterSettings.PrinterName = printer; if (doc.PrinterSettings.IsDefaultPrinter) comboPrinters.SelectedIndex = index; } // If this dialog is cancelled, we dont want the name of the printer to have changed doc.PrinterSettings.PrinterName = curPrinter; EntryFinishDate = pto.EntryFinishDate; EntryNumber = pto.EntryNumber; EntryStartDate = pto.EntryStartDate; EntryTrainingTimes = pto.EntryTrainingTimes; EntryNotes = pto.EntryNotes; FooterCount = pto.FooterCount; FooterDate = pto.FooterDate; FooterTotalTime = pto.FooterTotalTime; IncludeHeader = pto.IncludeHeader; }
/// <summary> /// Constructor /// </summary> /// <param name="plan">The plan.</param> private PlanPrinter(Plan plan) { m_plan = plan; m_plan.UpdateStatistics(); m_character = (Character)plan.Character; m_settings = Settings.Exportation.PlanToText; m_font = FontFactory.GetFont("Arial", 10); m_boldFont = FontFactory.GetFont("Arial", 10, FontStyle.Bold | FontStyle.Underline); }
/// <summary> /// Initializes a new instance of the <see cref="ExportationSettings"/> class. /// </summary> public ExportationSettings() { PlanToText = new PlanExportSettings(); }
/// <summary> /// Exports the plan under a text format. /// </summary> /// <param name="planToExport"></param> /// <param name="settings"></param> /// <param name="exportActions"></param> /// <returns></returns> public static string ExportAsText(Plan planToExport, PlanExportSettings settings, ExportPlanEntryActions exportActions) { var plan = new PlanScratchpad(planToExport.Character, planToExport); plan.Sort(planToExport.SortingPreferences); plan.UpdateStatistics(); var builder = new StringBuilder(); var timeFormat = DescriptiveTextOptions.FullText | DescriptiveTextOptions.IncludeCommas | DescriptiveTextOptions.SpaceText; var character = (Character)plan.Character; // Initialize constants string lineFeed = Environment.NewLine; string boldStart = String.Empty; string boldEnd = String.Empty; switch (settings.Markup) { default: break; case MarkupType.Forum: boldStart = "[b]"; boldEnd = "[/b]"; break; case MarkupType.Html: lineFeed = String.Format(CultureInfo.InvariantCulture, "<br />{0}", Environment.NewLine); boldStart = "<b>"; boldEnd = "</b>"; break; } // Header if (settings.IncludeHeader) { builder.Append(boldStart); if (settings.ShoppingList) { builder.AppendFormat(CultureConstants.DefaultCulture, "Shopping list for {0}", character.Name); } else { builder.AppendFormat(CultureConstants.DefaultCulture, "Skill plan for {0}", character.Name); } builder.Append(boldEnd); builder.Append(lineFeed); builder.Append(lineFeed); } // Scroll through entries int index = 0; DateTime endTime = DateTime.Now; foreach (PlanEntry entry in plan) { // Remapping point if (!settings.ShoppingList && entry.Remapping != null) { builder.AppendFormat(CultureConstants.DefaultCulture, "***{0}***", entry.Remapping); builder.Append(lineFeed); } // Skip is we're only build a shopping list bool shoppingListCandidate = !(entry.CharacterSkill.IsKnown || entry.Level != 1 || entry.CharacterSkill.IsOwned); if (settings.ShoppingList && !shoppingListCandidate) continue; // Entry's index index++; if (settings.EntryNumber) builder.AppendFormat(CultureConstants.DefaultCulture, "{0}. ", index); // Name builder.Append(boldStart); if (settings.Markup.Equals(MarkupType.Html)) { if (!settings.ShoppingList) { builder.AppendFormat(CultureConstants.DefaultCulture, "<a href=\"\" onclick=\"CCPEVE.showInfo({0})\">", entry.Skill.ID); } else { builder.AppendFormat(CultureConstants.DefaultCulture, "<a href=\"\" onclick=\"CCPEVE.showMarketDetails({0})\">", entry.Skill.ID); } } builder.Append(entry.Skill.Name); if (settings.Markup == MarkupType.Html) builder.Append("</a>"); if (!settings.ShoppingList) builder.AppendFormat(CultureConstants.DefaultCulture, " {0}", Skill.GetRomanForInt(entry.Level)); builder.Append(boldEnd); // Training time if (settings.EntryTrainingTimes || settings.EntryStartDate || settings.EntryFinishDate || (settings.EntryCost && shoppingListCandidate)) { builder.Append(" ("); bool needComma = false; // Training time if (settings.EntryTrainingTimes) { needComma = true; builder.Append(entry.TrainingTime.ToDescriptiveText(timeFormat)); } // Training start date if (settings.EntryStartDate) { if (needComma) builder.Append("; "); needComma = true; builder.AppendFormat(CultureConstants.DefaultCulture, "Start: {0}", entry.StartTime); } // Training end date if (settings.EntryFinishDate) { if (needComma) builder.Append("; "); needComma = true; builder.AppendFormat(CultureConstants.DefaultCulture, "Finish: {0}", entry.EndTime); } // Skill cost if (settings.EntryCost && shoppingListCandidate) { if (needComma) builder.Append("; "); needComma = true; builder.AppendFormat(CultureConstants.DefaultCulture, "{0} ISK", entry.Skill.FormattedCost); } builder.Append(')'); } if (exportActions != null) exportActions(builder, entry, settings); builder.Append(lineFeed); // End time endTime = entry.EndTime; } // Footer if (settings.FooterCount || settings.FooterTotalTime || settings.FooterDate || settings.FooterCost) { builder.AppendLine(lineFeed); bool needComma = false; // Skills count if (settings.FooterCount) { builder.AppendFormat(CultureConstants.DefaultCulture, "{0}{1}{2}", boldStart, index, boldEnd); builder.Append((index == 1 ? " skill" : " skills")); needComma = true; } // Plan's training duration if (settings.FooterTotalTime) { if (needComma) builder.Append("; "); needComma = true; builder.AppendFormat(CultureConstants.DefaultCulture, "Total time: {0}{1}{2}", boldStart, plan.GetTotalTime(null, true).ToDescriptiveText(timeFormat), boldEnd); } // End training date if (settings.FooterDate) { if (needComma) builder.Append("; "); needComma = true; builder.AppendFormat(CultureConstants.DefaultCulture, "Completion: {0}{1}{2}", boldStart, endTime, boldEnd); } // Total books cost if (settings.FooterCost) { if (needComma) builder.Append("; "); needComma = true; string formattedIsk = String.Format(CultureConstants.TidyInteger, "{0:n}", plan.NotKnownSkillBooksCost); builder.AppendFormat(CultureConstants.DefaultCulture, "Cost: {0}{1}{2}", boldStart, formattedIsk, boldEnd); } // Warning about skill costs builder.Append(lineFeed); if (settings.FooterCost || settings.EntryCost) builder.Append("N.B. Skill costs are based on CCP's database and are indicative only"); } // Returns the text representation. return builder.ToString(); }
/// <summary> /// Exports the plan under a text format. /// </summary> /// <param name="planToExport"></param> /// <param name="settings"></param> /// <returns></returns> public static string ExportAsText(Plan planToExport, PlanExportSettings settings) { return ExportAsText(planToExport, settings, null); }
/// <summary> /// Exports the plan under a text format. /// </summary> /// <param name="planToExport">The plan to export.</param> /// <param name="settings">The settings.</param> /// <param name="exportActions">The export actions.</param> /// <returns></returns> /// <exception cref="System.ArgumentNullException"> /// planToExport /// or /// settings /// </exception> /// <exception cref="System.NotImplementedException"></exception> /// <exception cref="System.ArgumentNullException">planToExport or settings</exception> public static string ExportAsText(Plan planToExport, PlanExportSettings settings, Action<StringBuilder, PlanEntry, PlanExportSettings> exportActions = null) { planToExport.ThrowIfNull(nameof(planToExport)); settings.ThrowIfNull(nameof(settings)); PlanScratchpad plan = new PlanScratchpad(planToExport.Character, planToExport); plan.Sort(planToExport.SortingPreferences); plan.UpdateStatistics(); StringBuilder builder = new StringBuilder(); Character character = (Character)plan.Character; // Initialize constants string lineFeed = Environment.NewLine; string boldStart = String.Empty; string boldEnd = String.Empty; switch (settings.Markup) { case MarkupType.Forum: boldStart = "[b]"; boldEnd = "[/b]"; break; case MarkupType.Html: lineFeed = $"<br />{Environment.NewLine}"; boldStart = "<b>"; boldEnd = "</b>"; break; case MarkupType.Undefined: case MarkupType.None: break; default: throw new NotImplementedException(); } // Header if (settings.IncludeHeader) { builder.Append(boldStart) .Append($"{(settings.ShoppingList ? "Shopping list " : "Skill plan ")} for {character.Name}") .Append(boldEnd) .Append(lineFeed) .Append(lineFeed); } // Scroll through entries int index = 0; DateTime endTime = DateTime.Now; foreach (PlanEntry entry in plan) { // Skip is we're only build a shopping list bool shoppingListCandidate = !(entry.CharacterSkill.IsKnown || entry.Level != 1 || entry.CharacterSkill.IsOwned); if (settings.ShoppingList && !shoppingListCandidate) continue; // Remapping point if (!settings.ShoppingList && (entry.Remapping != null) && settings.RemappingPoints) { builder .Append($"***{entry.Remapping}***") .Append(lineFeed); } // Entry's index index++; if (settings.EntryNumber) builder.Append($"{index}. "); // Name builder.Append(boldStart); AddName(settings, entry, builder); builder.Append(boldEnd); // Training time AddTrainingTime(settings, shoppingListCandidate, entry, builder); exportActions?.Invoke(builder, entry, settings); builder.Append(lineFeed); // End time endTime = entry.EndTime; } // Footer AddFooter(settings, boldEnd, index, endTime, builder, lineFeed, plan, boldStart); // Returns the text representation. return builder.ToString().TrimEnd(Environment.NewLine.ToCharArray()); }
/// <summary> /// Adds the training time. /// </summary> /// <param name="settings">The settings.</param> /// <param name="shoppingListCandidate">if set to <c>true</c> [shopping list candidate].</param> /// <param name="entry">The entry.</param> /// <param name="builder">The builder.</param> private static void AddTrainingTime(PlanExportSettings settings, bool shoppingListCandidate, PlanEntry entry, StringBuilder builder) { if (!settings.EntryTrainingTimes && !settings.EntryStartDate && !settings.EntryFinishDate && (!settings.EntryCost || !shoppingListCandidate)) return; const DescriptiveTextOptions TimeFormat = DescriptiveTextOptions.FullText | DescriptiveTextOptions.IncludeCommas | DescriptiveTextOptions.SpaceText; builder.Append(" ("); bool needComma = false; // Training time if (settings.EntryTrainingTimes) { needComma = true; builder.Append(entry.TrainingTime.ToDescriptiveText(TimeFormat)); } // Training start date if (settings.EntryStartDate) { if (needComma) builder.Append("; "); needComma = true; builder.Append($"Start: {entry.StartTime.ToUniversalTime().DateTimeToTimeString()} UTC"); } // Training end date if (settings.EntryFinishDate) { if (needComma) builder.Append("; "); needComma = true; builder.Append($"Finish: {entry.EndTime.ToUniversalTime().DateTimeToTimeString()} UTC"); } // Skill cost if (settings.EntryCost && shoppingListCandidate) { if (needComma) builder.Append("; "); builder.Append(FormattableString.Invariant($"Cost: {entry.Skill.Cost:N0} ISK")); } builder.Append(')'); }
/// <summary> /// Adds the name. /// </summary> /// <param name="settings">The settings.</param> /// <param name="entry">The entry.</param> /// <param name="builder">The builder.</param> private static void AddName(PlanExportSettings settings, ISkillLevel entry, StringBuilder builder) { if (settings.Markup == MarkupType.Html) { builder.Append("<a href=\"\" onclick=\"CCPEVE.show" + $"{(!settings.ShoppingList ? "Info" : "MarketDetails")}({entry.Skill.ID})\">"); } builder.Append(entry.Skill.Name); if (settings.Markup == MarkupType.Html) builder.Append("</a>"); if (!settings.ShoppingList) builder.Append($" {Skill.GetRomanFromInt(entry.Level)}"); }
/// <summary> /// Adds the footer. /// </summary> /// <param name="settings">The settings.</param> /// <param name="boldEnd">The bold end.</param> /// <param name="index">The index.</param> /// <param name="endTime">The end time.</param> /// <param name="builder">The builder.</param> /// <param name="lineFeed">The line feed.</param> /// <param name="plan">The plan.</param> /// <param name="boldStart">The bold start.</param> private static void AddFooter(PlanExportSettings settings, string boldEnd, int index, DateTime endTime, StringBuilder builder, string lineFeed, BasePlan plan, string boldStart) { if (!settings.FooterCount && !settings.FooterTotalTime && !settings.FooterDate && !settings.FooterCost) return; builder.AppendLine(lineFeed); bool needComma = false; // Skills count if (settings.FooterCount) { builder .Append($"{boldStart}{plan.GetUniqueSkillsCount()}{boldEnd} " + $"unique skill{(plan.GetUniqueSkillsCount() == 1 ? String.Empty : "s")}, ") .Append($"{boldStart}{index}{boldEnd} skill level{(index == 1 ? String.Empty : "s")}"); needComma = true; } // Plan's training duration if (settings.FooterTotalTime) { const DescriptiveTextOptions TimeFormat = DescriptiveTextOptions.FullText | DescriptiveTextOptions.IncludeCommas | DescriptiveTextOptions.SpaceText; if (needComma) builder.Append("; "); needComma = true; builder.Append($"Total time: {boldStart}{plan.TotalTrainingTime.ToDescriptiveText(TimeFormat)}{boldEnd}"); } // End training date if (settings.FooterDate) { if (needComma) builder.Append("; "); needComma = true; builder.Append($"Completion: {boldStart}{endTime.ToUniversalTime().DateTimeToTimeString()}{boldEnd} UTC"); } // Total books cost if (settings.FooterCost) { if (needComma) builder.Append("; "); string formattedIsk = FormattableString.Invariant($"{plan.NotKnownSkillBooksCost:N0}"); builder.Append($"Cost: {boldStart}{formattedIsk}{boldEnd} ISK"); } // Warning about skill costs builder.Append(lineFeed); if (settings.FooterCost || settings.EntryCost) builder.Append("N.B. Skill costs are based on CCP's database and are indicative only"); }
/// <summary> /// Outputs a plan or shopping list for a given character to a stream writer. /// </summary> /// <param name="context">context of the request</param> /// <param name="requestPath">url of the request</param> /// <param name="sw">stream writer to output to</param> /// <param name="character">character to use</param> private static void GeneratePlanOrShoppingOutput(string context, string requestPath, TextWriter sw, Character character) { sw.WriteLine("<h1>Hello, {0}</h1>", HttpUtility.HtmlEncode(character.Name)); sw.WriteLine("<a href=\"/characters\">List all characters</a><hr/>"); sw.WriteLine("<a href=\"{0}\">Character overview</a>", context); Regex regex = new Regex( @"\/(owned\/(?'skillId'[^\/]+)\/(?'markOwned'[^\/]+)\/)?(?'requestType'shopping|plan)\/(?'planName'[^\/]+)(.*)", RegexOptions.CultureInvariant | RegexOptions.Compiled); Match match = regex.Match(requestPath); if (match.Success) { string requestType = match.Groups["requestType"].Value; bool shopping = requestType.Equals("shopping", StringComparison.OrdinalIgnoreCase); string planName = HttpUtility.UrlDecode(match.Groups["planName"].Value); int skillId; bool setAsOwned; if (match.Groups["skillId"].Success && match.Groups["markOwned"].Success && Int32.TryParse(match.Groups["skillId"].Value, out skillId) && Boolean.TryParse(match.Groups["markOwned"].Value, out setAsOwned)) { Skill skill = character.Skills.FirstOrDefault(x => x.ID == skillId); if (skill != null) { sw.WriteLine("<h2>Skillbook shopping result</h2>"); skill.IsOwned = setAsOwned; sw.WriteLine("<a href=\"\" onclick=\"CCPEVE.showInfo({0})\">{1}</a> is now marked as {2} owned.", skill.ID, HttpUtility.HtmlEncode(skill.Name), skill.IsOwned ? String.Empty : "not"); } else { // Display an error message sw.WriteLine("<h2>Error Message</h2>"); sw.WriteLine("Skill with id '{0}' could not be found", skillId); } sw.WriteLine("<hr/>"); } Plan plan = character.Plans[planName]; if (plan == null) { // Display an error message sw.WriteLine("<h2>Error Message</h2>"); sw.WriteLine("A plan named \"{0}\" does not exist.", HttpUtility.HtmlEncode(planName)); } else { sw.WriteLine("<h2>Plan: {0}</h2>", HttpUtility.HtmlEncode(plan.Name)); PlanExportSettings x = new PlanExportSettings { // Only if not shopping EntryTrainingTimes = !shopping, // Only if not shopping EntryStartDate = !shopping, // Only if not shopping EntryFinishDate = !shopping, // Only if not shopping FooterTotalTime = !shopping, // Only if not shopping FooterDate = !shopping, FooterCount = true, ShoppingList = shopping, EntryCost = true, FooterCost = true, Markup = MarkupType.Html }; sw.Write(PlanIOHelper.ExportAsText(plan, x, ExportActions(context, requestType, plan))); } } else { sw.WriteLine("<h2>Error Message</h2>"); sw.WriteLine("Invalid request"); } sw.WriteLine("<br/><br/><a href=\"{0}\">Character overview</a>", context); sw.WriteLine("<hr/><a href=\"/characters\">List all characters</a>"); }
/// <summary> /// Outputs a plan or shopping list for a given character to a stream writer /// </summary> /// <param name="context">context of the request</param> /// <param name="requestUrl">url of the request</param> /// <param name="sw">stream writer to output to</param> /// <param name="character">character to use</param> private static void GeneratePlanOrShoppingOutput(string context, string requestUrl, StreamWriter sw, Character character) { WriteDocumentHeader(sw); sw.WriteLine("<h1>Hello, {0}</h1>", HttpUtility.HtmlEncode(character.Name)); sw.WriteLine("<a href=\"/characters\">List all characters</a><hr/>"); sw.WriteLine("<a href=\"{0}\">Character overview</a>", context); var regex = new Regex(@"\/(owned\/(?'skillId'[^\/]+)\/(?'markOwned'[^\/]+)\/)?(?'requestType'shopping|plan)\/(?'planName'[^\/]+)(.*)", RegexOptions.CultureInvariant | RegexOptions.Compiled); var match = regex.Match(requestUrl); if (match.Success) { var requestType = match.Groups["requestType"].Value; var shopping = requestType.Equals("shopping", StringComparison.OrdinalIgnoreCase); var planName = HttpUtility.UrlDecode(match.Groups["planName"].Value); int skillId; bool setAsOwned; if (match.Groups["skillId"].Success && match.Groups["markOwned"].Success && Int32.TryParse(match.Groups["skillId"].Value, out skillId) && Boolean.TryParse(match.Groups["markOwned"].Value, out setAsOwned)) { var skill = character.Skills.FirstOrDefault(x => x.ID == skillId); if (skill != null) { sw.WriteLine("<h2>Skillbook shopping result</h2>"); Dispatcher.Invoke(() => skill.IsOwned = setAsOwned); sw.WriteLine("<a href=\"\" onclick=\"CCPEVE.showInfo({0})\">{1}</a> is now marked as {2} owned.", skill.ID, HttpUtility.HtmlEncode(skill.Name), skill.IsOwned ? String.Empty : "not"); } else { // Display an error message sw.WriteLine("<h2>Error Message</h2>"); sw.WriteLine("Skill with id '{0}' could not be found", skillId); } sw.WriteLine("<hr/>"); } Plan p = character.Plans[planName]; if (p == null) { // Display an error message sw.WriteLine("<h2>Error Message</h2>"); sw.WriteLine("A plan named \"{0}\" does not exist.", HttpUtility.HtmlEncode(planName)); } else { sw.WriteLine("<h2>Plan: {0}</h2>", HttpUtility.HtmlEncode(p.Name)); PlanExportSettings x = new PlanExportSettings(); x.EntryTrainingTimes = !shopping; // only if not shopping x.EntryStartDate = !shopping; // only if not shopping x.EntryFinishDate = !shopping; // only if not shopping x.FooterTotalTime = !shopping; // only if not shopping x.FooterCount = true; x.FooterDate = !shopping; // only if not shopping x.ShoppingList = shopping; x.EntryCost = true; x.FooterCost = true; x.Markup = MarkupType.Html; sw.Write(PlanExporter.ExportAsText(p, x, (builder, entry, settings) => { if (settings.Markup != MarkupType.Html) return; // Skill is known if (entry.CharacterSkill.IsKnown || entry.Level != 1) return; builder.AppendFormat(CultureConstants.DefaultCulture, " <a href='{0}/owned/{1}/{2}/{4}/{5}'>{3}</a>", context, entry.Skill.ID, !entry.CharacterSkill.IsOwned, HttpUtility.HtmlEncode(!entry.CharacterSkill.IsOwned ? "Mark as owned" : "Mark as not owned"), requestType, HttpUtility.HtmlEncode(p.Name)); })); } } else { sw.WriteLine("<h2>Error Message</h2>"); sw.WriteLine("Invalid request"); } sw.WriteLine("<br/><br/><a href=\"{0}\">Character overview</a>", context); sw.WriteLine("<hr/><a href=\"/characters\">List all characters</a>"); WriteDocumentFooter(sw); }