/// <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> /// 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"></param> public static void ExportPlan(Plan plan) { var character = (Character)plan.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 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; DialogResult dr = sfdSave.ShowDialog(); if (dr == DialogResult.Cancel) { return; } // Serialize try { var format = (PlanFormat)sfdSave.FilterIndex; string content; switch (format) { case PlanFormat.Emp: case PlanFormat.Xml: content = PlanExporter.ExportAsXML(plan); break; case PlanFormat.Text: // Prompts the user and returns if he canceled var settings = PromptUserForPlanExportSettings(plan); if (settings == null) { return; } content = PlanExporter.ExportAsText(plan, settings); break; default: throw new NotImplementedException(); } // Moves to the final file FileHelper.OverwriteOrWarnTheUser(sfdSave.FileName, fs => { Stream s = fs; // Emp is actually compressed text if (format == PlanFormat.Emp) { s = new GZipStream(fs, CompressionMode.Compress); } using (s) using (var writer = new StreamWriter(s, Encoding.UTF8)) { writer.Write(content); writer.Flush(); s.Flush(); fs.Flush(); } 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); } }
private void OptionChange() { UpdateOptions(); tbPreview.Text = PlanExporter.ExportAsText(m_plan, m_planTextOptions); }
/// <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); }