private void RunQuery() { ProgressDialog dialog; EventHandler<ProgressEventArgs> handler = null; // update our internal representation of the search boxes m_clauses = GetWhereClauses(m_searchControls); // run the query on the asset database again try { // create dialog dialog = new ProgressDialog(); // create the handler for price query updates handler = delegate(object sender, ProgressEventArgs e) { if (e.Max < 1) return; dialog.Update("Updating market prices...", e.Progress, e.Max); }; Program.PriceProvider.UpdateProgress += handler; // initialize the dialog and display it dialog.Update(0, 1); dialog.AddTask(UpdateAssetTable); dialog.Show(); // display the fresh asset data in the grid grid.DataSource = m_assets.DefaultView; grid.AutoResizeColumns(); UpdateAssetCount(); } catch (ProgressException ex) { ShowException(ex); } finally { if (handler != null) Program.PriceProvider.UpdateProgress -= handler; } }
private void GenerateReport(string defaultTitle, string fileFilter, string defaultExt, GenerateReportDelegate reportMethod) { List<WhereClause> clauses; DataTable assets; ProgressDialog dialog; ReportOptionsDialog options; ReportOptionsDialog.AssetSourceType sourceType; EventHandler<ProgressEventArgs> handler = null; int savedSearchID = -1; // ask the user some stuff options = new ReportOptionsDialog(fileFilter, defaultExt); options.ReportTitle = defaultTitle; if (options.ShowDialog(this) == DialogResult.Cancel) return; sourceType = options.AssetSource; if (sourceType == ReportOptionsDialog.AssetSourceType.SavedSearch) savedSearchID = options.SavedSearchID; // create clauses clauses = new List<WhereClause>(); try { // create dialog dialog = new ProgressDialog(); // create the handler for price query updates handler = delegate(object sender, ProgressEventArgs e) { if (e.Max < 1) return; dialog.Update("Updating market prices...", e.Progress, e.Max); }; Program.PriceProvider.UpdateProgress += handler; // add the progress task dialog.AddTask(delegate(IProgressDialog p) { // create our clauses and get assets p.Update("Querying assets..."); switch (sourceType) { case ReportOptionsDialog.AssetSourceType.All: assets = AssetCache.GetAssetTable(clauses); break; case ReportOptionsDialog.AssetSourceType.Current: if (m_assets == null) throw new ApplicationException("There are no current search results to use."); assets = m_assets; break; case ReportOptionsDialog.AssetSourceType.SavedSearch: clauses.AddRange(GetWhereClausesForSavedSearch(savedSearchID)); assets = AssetCache.GetAssetTable(clauses); break; default: throw new ApplicationException("Don't know how to get assets for source type " + sourceType.ToString()); } // generate report p.Update("Generating report..."); reportMethod(assets, options.ReportTitle, options.ReportPath); }); // run it! dialog.Show(); } catch (Exception ex) { // let the user know we failed ShowException("Failed to generate report:", ex); // try to get rid of the partially-written file try { if (File.Exists(options.ReportPath)) File.Delete(options.ReportPath); } catch { /* pass */ } // get outta here, she's gonna blow! return; } finally { if (handler != null) Program.PriceProvider.UpdateProgress -= handler; } // open the report if (Program.OptionsDialog["Reports.OpenReport"].ValueAsBoolean) System.Diagnostics.Process.Start(options.ReportPath); }
private void menu_options_refresh_Click(object sender, EventArgs e) { ProgressDialog dialog; // refresh our asset data from EVE try { dialog = new ProgressDialog(); dialog.AddTask(RefreshAssets); dialog.Show(); } catch (ProgressException ex) { ShowException(ex); return; } finally { // give the user feedback on the new state of the cache, successful or not BeginCheckAssets(); } // re-run the query RunQuery(); }
private void search_button_Click(object sender, EventArgs e) { ProgressDialog progress; DataTable results = null; progress = new ProgressDialog(); progress.AutoAdvance = true; progress.AddTask((p) => { p.Update("Querying compendium..."); // create the data table results = new DataTable("Monsters"); results.Columns.Add("ID", typeof(int)); results.Columns.Add("Name", typeof(string)); results.Columns.Add("Level", typeof(int)); results.Columns.Add("GroupRole", typeof(string)); results.Columns.Add("CombatRole", typeof(string)); results.Columns.Add("SourceBook", typeof(string)); results.BeginLoadData(); // query the web service, create the document, and select nodes using (Stream s = m_helper.SearchMonsters(name_box.Text)) { XPathDocument doc = new XPathDocument(s); XPathNavigator nav = doc.CreateNavigator(); XPathNodeIterator iter = nav.Select("/Data/Results/Monster"); // load the rows while (iter.MoveNext()) { results.LoadDataRow(new object[] { iter.Current.SelectSingleNode("ID").ValueAsInt, iter.Current.SelectSingleNode("Name").Value, iter.Current.SelectSingleNode("Level").ValueAsInt, iter.Current.SelectSingleNode("GroupRole").Value, iter.Current.SelectSingleNode("CombatRole").Value, iter.Current.SelectSingleNode("SourceBook").Value, }, false); } } // complete load results.AcceptChanges(); results.DefaultView.Sort = "Level ASC, Name ASC"; results.EndLoadData(); }); try { progress.Show(); grid.DataSource = results; } catch (Exception ex) { MessageBox.Show(this, ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
private void refresh_button_Click(object sender, EventArgs e) { ProgressDialog dialog; try { // grids freak out if we modify their data sources in another thread grid_keys.DataSource = null; grid_characters.DataSource = null; // refresh using a user-friendly progress dialog dialog = new ProgressDialog(); dialog.AddTask(Program.RefreshCharacters); dialog.Show(); // re-attach grids BindGrids(); } catch (Exception ex) { MainForm.ShowException(this, "Failed to refresh characters", ex); } }
private void go_button_Click(object sender, EventArgs e) { ProgressDialog d = new ProgressDialog(); string character_path = character_box.Text; string macro_path = macro_box.Text; List<PowerInfo> powers = new List<PowerInfo>(); Dictionary<string, int> skills = new Dictionary<string, int>(); System.Text.RegularExpressions.Regex img_remover = new System.Text.RegularExpressions.Regex(@"<img.*?>", System.Text.RegularExpressions.RegexOptions.IgnoreCase); // save the value of the checkbox m_use_compendium = compendium_check.Checked; d.AddTask((progress) => { progress.Update("Scanning character sheet..."); using (FileStream fs = File.OpenRead(character_path)) { XPathDocument doc = new XPathDocument(fs); XPathNavigator nav = doc.CreateNavigator(); XPathNodeIterator power_iter, weapon_iter; // select all power nodes power_iter = nav.Select("/D20Character/CharacterSheet/PowerStats/Power"); // update the progress steps progress.Update(0, power_iter.Count); // iterate them while (power_iter.MoveNext()) { string name; string action_type; List<string> compendium_info = new List<string>(); PowerUsage usage; XPathNavigator power_url_nav = null; try { // read the basic stuff name = power_iter.Current.SelectSingleNode("@name").Value; usage = Util.EnumParse<PowerUsage>(power_iter.Current.SelectSingleNode("specific[@name = 'Power Usage']").Value.Replace("-", "")); action_type = power_iter.Current.SelectSingleNode("specific[@name = 'Action Type']").Value.Trim(); // get the url for the power in the compendium if (m_use_compendium) power_url_nav = nav.SelectSingleNode("//RulesElementTally/RulesElement[@name = \"" + name + "\"]/@url"); // ...and if we did that, pull down the power description if (power_url_nav != null) { HtmlAgilityPack.HtmlDocument scraper_doc = new HtmlAgilityPack.HtmlDocument(); HtmlAgilityPack.HtmlNodeNavigator scraper_result; XPathNodeIterator content_iter; XPathNavigator scraper_nav = null; // slurp try { using (Stream s = m_compendium.GetEntryByUrl(power_url_nav.Value)) { scraper_doc.Load(s, new UTF8Encoding()); scraper_nav = scraper_doc.CreateNavigator(); } } catch (Exception ex) { // if the user clicked cancel, stop attempting compendium stuff if (ex is ApplicationException && ex.Message.ToLowerInvariant().Contains("user refused")) m_use_compendium = false; else MessageBox.Show(ex.ToString(), "Compendium Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } // if the web request succeeded... if (scraper_nav != null) { // select all the detail p tags content_iter = scraper_nav.Select("//div[@id = 'detail']/p"); // loop through them while (content_iter.MoveNext()) { string line; // cast to HtmlNodeNavigator scraper_result = content_iter.Current as HtmlAgilityPack.HtmlNodeNavigator; // skip publishing stuff if (scraper_result == null || scraper_result.CurrentNode.InnerHtml.ToLowerInvariant().Contains("published in")) continue; // grab the line, strip images, and remove [] stuff line = scraper_result.CurrentNode.InnerHtml; line = img_remover.Replace(line, "-"); line = line.Replace("[W]", "<i>W</i>"); // add the line compendium_info.Add(line); } } } // select weapons weapon_iter = power_iter.Current.Select("Weapon"); // some powers aren't attacks or don't use weapons if (weapon_iter.Count < 1) { powers.Add(new PowerInfo(name, compendium_info, WEAPON_NONE, usage, action_type)); } else { while (weapon_iter.MoveNext()) { PowerInfo power = new PowerInfo(name, compendium_info, weapon_iter.Current.SelectSingleNode("@name").Value, usage, action_type); // when there is more than one weapon, skip the Unarmed weapon if (power.Weapon == WEAPON_UNARMED && weapon_iter.Count > 1) continue; // read the attack info power.AttackBonus = weapon_iter.Current.SelectSingleNode("AttackBonus").ValueAsInt; power.AttackStat = weapon_iter.Current.SelectSingleNode("AttackStat").Value.Trim(); power.DamageExpression = weapon_iter.Current.SelectSingleNode("Damage").Value.Trim(); power.Defense = weapon_iter.Current.SelectSingleNode("Defense").Value.Trim(); // all powers list an Unarmed weapon, even if they don't include an attack, set these to WEAPON_NONE if (power.Defense == "") power.Weapon = WEAPON_NONE; // add it to the list powers.Add(power); } } } catch (Exception ex) { MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } // wait briefly to avoid spamming compendium if (m_use_compendium) System.Threading.Thread.Sleep(200); // advance progress progress.Advance(); } // detect skills from the RulesElementTally power_iter = nav.Select("//RulesElementTally/RulesElement[@type = 'Skill']/@name"); // read the value for each one while (power_iter.MoveNext()) { string name = power_iter.Current.Value; int value; XPathNavigator value_node = nav.SelectSingleNode("/D20Character/CharacterSheet/StatBlock/Stat[@name = '" + name + "']/@value"); if (value_node != null && int.TryParse(value_node.Value, out value)) skills[name] = value; } } }); d.AddTask((progress) => { progress.Update("Writing macros..."); using (FileStream fs = File.Open(macro_path, FileMode.Create, FileAccess.Write)) { XmlWriterSettings settings; settings = new XmlWriterSettings(); settings.Encoding = new System.Text.ASCIIEncoding(); settings.Indent = true; settings.IndentChars = " "; settings.OmitXmlDeclaration = false; using (XmlWriter w = XmlWriter.Create(fs, settings)) { w.WriteStartDocument(); w.WriteStartElement("list"); foreach (PowerInfo power in powers) { StringBuilder command = new StringBuilder(); string text, background; // skip basic attacks with no weapons if (IsPowerBasicAttack(power.Name) && power.Weapon == WEAPON_NONE) continue; // begin macro definition w.WriteStartElement(MACRO_ELEMENT_NAME); w.WriteElementString("saveLocation", "Token"); w.WriteElementString("label", power.Name); w.WriteElementString("autoExecute", "true"); w.WriteElementString("sortby", GetSortPriority(power)); // set colors based on usage limits if (GetColors(power.Usage, out text, out background)) { w.WriteElementString("fontColorKey", text); w.WriteElementString("colorKey", background); } // start with the table and header command.AppendLine("<table border=\"0\">"); command.AppendFormat("<tr bgcolor=\"{0}\" style=\"color: white;\">", background); command.AppendLine(); command.AppendFormat("<th align=\"left\" style=\"font-size: 1.1em; padding: 2px 4px;\">{0}</th>", power.Name); command.AppendLine(); command.AppendFormat("<td align=\"right\" valign=\"middle\" style=\"padding: 2px 4px;\"><i>{0}</i></td></tr>", power.Weapon == WEAPON_NONE ? "" : power.Weapon); command.AppendLine(); command.AppendLine("</tr>"); // write compendium info foreach (string line in power.CompendiumInfo) command.AppendLine("<tr><td colspan=\"2\">" + line + "</td></tr>"); // when we have a weapon, put the macro in the weapon's group and include the rolls if (power.Weapon != WEAPON_NONE) { w.WriteElementString("group", "Attacks - " + power.Weapon); command.AppendFormat("<tr><td nowrap><b>[1d20+{0}]</b></td><td><b>vs. {1}</b></td></tr>", power.AttackBonus, power.Defense); command.AppendLine(); command.AppendFormat("<tr><td nowrap>[{0}]</td><td>damage</td></tr>", power.DamageExpression); command.AppendLine(); } // finish up the command command.AppendLine("</table>"); // write the command and end element w.WriteElementString("command", command.ToString()); w.WriteEndElement(); // MACRO_ELEMENT_NAME } // write skill check macros foreach (KeyValuePair<string, int> skill in skills) { // begin macro definition w.WriteStartElement(MACRO_ELEMENT_NAME); w.WriteElementString("saveLocation", "Token"); w.WriteElementString("label", skill.Key); w.WriteElementString("autoExecute", "true"); w.WriteElementString("group", "Skills"); w.WriteElementString("command", string.Format("<p><b>{0} Check</b> [1d20+{1}]</p>", skill.Key, skill.Value)); w.WriteEndElement(); // MACRO_ELEMENT_NAME } w.WriteEndDocument(); } } }); try { d.Show(); } catch (Exception ex) { MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } }