/// <summary> /// Prompt the user to select plan exportation settings. /// </summary> /// <returns></returns> public static PlanExportSettings PromptUserForPlanExportSettings(Plan plan) { PlanExportSettings settings = Settings.Exportation.PlanToText; using (CopySaveOptionsWindow f = new CopySaveOptionsWindow(settings, plan, false)) { if (settings.Markup == MarkupType.Undefined) { settings.Markup = MarkupType.None; } f.ShowDialog(); if (f.DialogResult == DialogResult.Cancel) { return(null); } // Save the new settings if (!f.SetAsDefault) { return(settings); } Settings.Exportation.PlanToText = settings; Settings.Save(); return(settings); } }
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; }
public CopySaveOptionsWindow(PlanExportSettings pto, Plan p, bool isForCopy) : this() { m_planTextOptions = pto; m_plan = p; m_isForCopy = isForCopy; }
/// <summary> /// Toolbar > Copy to clipboard. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void tsbCopyForum_Click(object sender, EventArgs e) { // Prompt the user for settings. When null, the user cancelled. PlanExportSettings settings = UIHelper.PromptUserForPlanExportSettings(m_plan); if (settings == null) { return; } string output = PlanExporter.ExportAsText(m_plan, settings); // Copy the result to the clipboard. try { Clipboard.Clear(); Clipboard.SetText(output); MessageBox.Show("The skill plan has been copied to the clipboard in a " + "format suitable for forum posting.", "Plan Copied", MessageBoxButtons.OK, MessageBoxIcon.Information); } catch (ExternalException ex) { ExceptionHandler.LogException(ex, true); MessageBox.Show("The copy to clipboard has failed. You may retry later", "Plan Copy Failure", MessageBoxButtons.OK, MessageBoxIcon.Information); } }
/// <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> /// 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> /// Generate the plan or shopping list /// </summary> /// <param name="headers">headers for the request</param> /// <param name="sw">stream writer to output to</param> /// <param name="ci">character to use</param> private static void GeneratePlanOrShoppingOutput(string requestUrl, StreamWriter sw, Character ci) { // strip off the bad trailing / added by IGB (Trac ticket #425) if (requestUrl.EndsWith("/")) { requestUrl = requestUrl.Substring(0, requestUrl.Length - 1); } bool shopping = requestUrl.StartsWith("/shopping/"); string planName = HttpUtility.UrlDecode(requestUrl.Substring( shopping ? "/shopping/".Length : "/plan/".Length )); sw.WriteLine("<html><head><title>Plan</title></head><body>"); sw.WriteLine(String.Format("<h1>Plan: {0}</h1>", HttpUtility.HtmlEncode(planName))); sw.WriteLine("<hr><a href=\"/\">Back</a></hr></br></br>"); Plan p = ci.Plans[planName]; if (p == null) { sw.WriteLine("non-existant plan name"); } else { 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)); } sw.WriteLine("<hr><a href=\"/\">Back</a></hr>"); sw.WriteLine("</body></html>"); }
/// <summary> /// Displays the plan exportation window and then exports it. /// </summary> /// <param name="plan">The plan.</param> /// <param name="character">The character.</param> /// <returns></returns> /// <exception cref="System.ArgumentNullException"></exception> /// <exception cref="System.NotImplementedException"></exception> private static async Task ExportPlanAsync(Plan plan, Character character) { plan.ThrowIfNull(nameof(plan)); character.ThrowIfNull(nameof(character)); // Assemble an initial filename and remove prohibited characters string planSaveName = $"{character.Name} - {plan.Name}"; char[] invalidFileChars = Path.GetInvalidFileNameChars(); int fileInd = planSaveName.IndexOfAny(invalidFileChars); while (fileInd != -1) { planSaveName = planSaveName.Replace(planSaveName[fileInd], '-'); fileInd = planSaveName.IndexOfAny(invalidFileChars); } // Prompt the user to pick a file name using (SaveFileDialog sfdSave = new SaveFileDialog()) { sfdSave.FileName = planSaveName; sfdSave.Title = @"Save to File"; sfdSave.Filter = @"EVEMon Plan Format (*.emp)|*.emp|XML Format (*.xml)|*.xml|Text Format (*.txt)|*.txt"; sfdSave.FilterIndex = (int)PlanFormat.Emp; if (sfdSave.ShowDialog() == DialogResult.Cancel) { return; } // Serialize try { PlanFormat format = (PlanFormat)sfdSave.FilterIndex; string content; switch (format) { case PlanFormat.Emp: case PlanFormat.Xml: content = PlanIOHelper.ExportAsXML(plan); break; case PlanFormat.Text: // Prompts the user and returns if canceled PlanExportSettings settings = PromptUserForPlanExportSettings(plan); if (settings == null) { return; } content = PlanIOHelper.ExportAsText(plan, settings); break; default: throw new NotImplementedException(); } // Moves to the final file await FileHelper.OverwriteOrWarnTheUserAsync( sfdSave.FileName, async fs => { Stream stream = fs; // Emp is actually compressed text if (format == PlanFormat.Emp) { stream = new GZipStream(fs, CompressionMode.Compress); } using (StreamWriter writer = new StreamWriter(stream, Encoding.UTF8)) { await writer.WriteAsync(content); await writer.FlushAsync(); await stream.FlushAsync(); await fs.FlushAsync(); } return(true); }); } catch (IOException err) { ExceptionHandler.LogException(err, true); MessageBox.Show($"There was an error writing out the file:\n\n{err.Message}", @"Save Failed", MessageBoxButtons.OK, MessageBoxIcon.Error); } } }
/// <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 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> /// 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> /// 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) { 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 = ""; string boldStart = ""; string boldEnd = ""; switch (settings.Markup) { default: break; case MarkupType.Forum: boldStart = "[b]"; boldEnd = "[/b]"; break; case MarkupType.Html: lineFeed = "<br />"; boldStart = "<b>"; boldEnd = "</b>"; break; } // Header if (settings.IncludeHeader) { builder.Append(boldStart); if (settings.ShoppingList) { builder.Append("Shopping list for ").Append(character.Name); } else { builder.Append("Skill plan for ").Append(character.Name); } builder.Append(boldEnd); builder.AppendLine(lineFeed); builder.AppendLine(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.Append("***").Append(entry.Remapping.ToString()).Append("***"); builder.AppendLine(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.Append(index.ToString()).Append(". "); } // Name builder.Append(boldStart); if (settings.Markup == MarkupType.Html) { builder.Append("<a href=\"\" onclick=\"CCPEVE.showInfo(").Append(entry.Skill.ID.ToString()).Append(")\">"); } builder.Append(entry.Skill.Name); if (settings.Markup == MarkupType.Html) { builder.Append("</a>"); } if (!settings.ShoppingList) { builder.Append(' ').Append(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(Skill.TimeSpanToDescriptiveText(entry.TrainingTime, timeFormat)); } // Training start date if (settings.EntryStartDate) { if (needComma) { builder.Append("; "); } needComma = true; builder.Append("Start: ").Append(entry.StartTime.ToString()); } // Training end date if (settings.EntryFinishDate) { if (needComma) { builder.Append("; "); } needComma = true; builder.Append("Finish: ").Append(entry.EndTime.ToString()); } // Skill cost if (settings.EntryCost && shoppingListCandidate) { if (needComma) { builder.Append("; "); } needComma = true; builder.Append(entry.Skill.FormattedCost + " ISK"); } builder.Append(')'); } builder.AppendLine(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.Append(boldStart).Append(index.ToString()).Append(boldEnd); builder.Append((index == 1 ? " skill" : " skills")); needComma = true; } // Plan's training duration if (settings.FooterTotalTime) { if (needComma) { builder.Append("; "); } needComma = true; builder.Append("Total time: "); builder.Append(boldStart); builder.Append(Skill.TimeSpanToDescriptiveText(plan.GetTotalTime(null, true), timeFormat)); builder.Append(boldEnd); } // End training date if (settings.FooterDate) { if (needComma) { builder.Append("; "); } needComma = true; builder.Append("Completion: "); builder.Append(boldStart).Append(endTime.ToString()).Append(boldEnd); } // Total books cost if (settings.FooterCost) { if (needComma) { builder.Append("; "); } needComma = true; builder.Append("Cost: "); builder.Append(boldStart); builder.Append((plan.TotalBooksCost == 0 ? "0 ISK" : String.Format("{0:0,0,0} ISK", plan.TotalBooksCost))); builder.Append(boldEnd); } // Warning about skill costs builder.AppendLine(lineFeed); if (settings.FooterCost || settings.EntryCost) { builder.Append("N.B. Skill costs are based on CCP's database and are indicative only"); builder.AppendLine(lineFeed); } } // Returns the text representation. return(builder.ToString()); }
/// <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); }
/// <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>"); }