DistexForm.cs 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Text;
  7. using System.Windows.Forms;
  8. using System.Threading;
  9. using System.Diagnostics;
  10. using System.IO;
  11. using System.Reflection;
  12. namespace distribution_explorer
  13. {
  14. /// <summary>
  15. /// Main distribution explorer.
  16. /// </summary>
  17. public partial class DistexForm : Form
  18. {
  19. EventLog log = new EventLog();
  20. /// <summary>
  21. /// Main form
  22. /// </summary>
  23. public DistexForm()
  24. {
  25. if (!EventLog.SourceExists("EventLogDistex"))
  26. {
  27. EventLog.CreateEventSource("EventLogDistex", "Application");
  28. }
  29. log.Source = "EventLogDistex";
  30. log.WriteEntry("DistexForm");
  31. InitializeComponent();
  32. Application.DoEvents();
  33. }
  34. private void Form_Load(object sender, EventArgs e)
  35. { // Load distribution & parameters names, and default values.
  36. try
  37. {
  38. // Create and show splash screen:
  39. this.Hide();
  40. distexSplash frmSplash = new distexSplash();
  41. frmSplash.Show();
  42. frmSplash.Update();
  43. // Now load our data while the splash is showing:
  44. if (boost_math.any_distribution.size() <= 0)
  45. {
  46. MessageBox.Show("Problem loading any distributions, size = " + boost_math.any_distribution.size().ToString());
  47. }
  48. for (int i = 0; i < boost_math.any_distribution.size(); ++i)
  49. {
  50. distribution.Items.Add(boost_math.any_distribution.distribution_name(i));
  51. }
  52. distribution.SelectedIndex = 0; // 1st in array, but could be any other.
  53. // All parameters are made zero by default, but updated from chosen distribution.
  54. parameter1.Text = boost_math.any_distribution.first_param_default(0).ToString();
  55. parameter2.Text = boost_math.any_distribution.second_param_default(0).ToString();
  56. parameter3.Text = boost_math.any_distribution.third_param_default(0).ToString();
  57. //
  58. // Sleep and then close splash;
  59. Thread.Sleep(3000);
  60. frmSplash.Close();
  61. this.Visible = true;
  62. }
  63. catch
  64. { //
  65. log.WriteEntry("DistexForm_load exception!");
  66. MessageBox.Show("Problem loading distributions, size = " + boost_math.any_distribution.size().ToString());
  67. }
  68. }
  69. private void distribution_SelectedIndexChanged(object sender, EventArgs e)
  70. {
  71. int i = distribution.SelectedIndex; // distribution tab.
  72. parameter1Label.Text = boost_math.any_distribution.first_param_name(i);
  73. parameterLabel1.Text = boost_math.any_distribution.first_param_name(i); // properties tab.
  74. parameter2Label.Text = boost_math.any_distribution.second_param_name(i);
  75. parameter3Label.Text = boost_math.any_distribution.third_param_name(i);
  76. if (boost_math.any_distribution.first_param_name(i).Length.CompareTo(0) != 0)
  77. { // Actually all the distributions have at least one parameters,
  78. parameter1.Visible = true; // so should always be true.
  79. parameterLabel1.Visible = true;
  80. }
  81. else
  82. { // If distribution chosen has no parameter name(s) then hide.
  83. parameter1.Visible = false;
  84. parameterLabel1.Visible = false;
  85. }
  86. parameter1.Text = boost_math.any_distribution.first_param_default(i).ToString();
  87. // Update parameter default to match distribution.
  88. if (boost_math.any_distribution.second_param_name(i).Length.CompareTo(0) != 0)
  89. {
  90. parameter2.Visible = true;
  91. parameterLabel2.Visible = true;
  92. parameter2ValueLabel.Visible = true;
  93. }
  94. else
  95. { // hide
  96. parameter2.Visible = false;
  97. parameterLabel2.Visible = false;
  98. parameter2ValueLabel.Visible = false;
  99. }
  100. parameter2.Text = boost_math.any_distribution.second_param_default(i).ToString();
  101. if (boost_math.any_distribution.third_param_name(i).Length.CompareTo(0) != 0)
  102. {
  103. parameter3.Visible = true;
  104. parameterLabel3.Visible = true;
  105. parameter3ValueLabel.Visible = true;
  106. }
  107. else
  108. { // hide
  109. parameter3.Visible = false;
  110. parameterLabel3.Visible = false;
  111. parameter3ValueLabel.Visible = false;
  112. }
  113. parameter3.Text = boost_math.any_distribution.third_param_default(i).ToString();
  114. // Update tool tips to show total and supported ranges.
  115. PropertiesTabPage.ToolTipText = "Shows properties and ranges of chosen distribution.";
  116. }
  117. private boost_math.any_distribution dist;
  118. private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
  119. { // Display a grid of pdf, cdf... values from user's random variate x value.
  120. try
  121. {
  122. if (e.ColumnIndex == 0)
  123. { // Clicked on left-most random variate x column to enter a value.
  124. int i = e.RowIndex;
  125. string s = CDF_data.Rows[i].Cells[0].Value.ToString();
  126. double x = double.Parse(s); // Get value of users random variate x.
  127. double pdf = dist.pdf(x); // Compute pdf values from x
  128. double cdf = dist.cdf(x); // & cdf
  129. double ccdf = dist.ccdf(x); // & complements.
  130. CDF_data.Rows[i].Cells[1].Value = pdf; // and display values.
  131. CDF_data.Rows[i].Cells[2].Value = cdf;
  132. CDF_data.Rows[i].Cells[3].Value = ccdf;
  133. }
  134. }
  135. catch (SystemException se)
  136. {
  137. MessageBox.Show("Error in random variable value: " + se.Message, "Calculation Error");
  138. }
  139. }
  140. private void tabPage2_Enter(object sender, EventArgs e)
  141. { // Properties tab shows distribution's mean, mode, median...
  142. try
  143. { // Show chosen distribution name, and parameter names & values.
  144. int i = distribution.SelectedIndex;
  145. distributionValueLabel.Text = boost_math.any_distribution.distribution_name(i).ToString();
  146. parameterLabel1.Text = boost_math.any_distribution.first_param_name(i).ToString();
  147. parameter1ValueLabel.Text = double.Parse(parameter1.Text).ToString();
  148. parameterLabel2.Text = boost_math.any_distribution.second_param_name(i).ToString();
  149. parameter2ValueLabel.Text = double.Parse(parameter2.Text).ToString();
  150. parameterLabel3.Text = boost_math.any_distribution.third_param_name(i).ToString();
  151. parameter3ValueLabel.Text = double.Parse(parameter3.Text).ToString();
  152. // Show computed properties of distribution.
  153. try
  154. {
  155. mean.Text = dist.mean().ToString();
  156. }
  157. catch
  158. {
  159. mean.Text = "Undefined.";
  160. }
  161. try
  162. {
  163. mode.Text = dist.mode().ToString();
  164. }
  165. catch
  166. {
  167. mode.Text = "Undefined.";
  168. }
  169. try
  170. {
  171. median.Text = dist.median().ToString();
  172. }
  173. catch
  174. {
  175. median.Text = "Undefined.";
  176. }
  177. try
  178. {
  179. variance.Text = dist.variance().ToString();
  180. }
  181. catch
  182. {
  183. variance.Text = "Undefined.";
  184. }
  185. try
  186. {
  187. standard_deviation.Text = dist.standard_deviation().ToString();
  188. }
  189. catch
  190. {
  191. standard_deviation.Text = "Undefined.";
  192. }
  193. try
  194. {
  195. skewness.Text = dist.skewness().ToString();
  196. }
  197. catch
  198. {
  199. skewness.Text = "Undefined.";
  200. }
  201. try
  202. {
  203. kurtosis.Text = dist.kurtosis().ToString();
  204. }
  205. catch
  206. {
  207. kurtosis.Text = "Undefined.";
  208. }
  209. try
  210. {
  211. kurtosis_excess.Text = dist.kurtosis_excess().ToString();
  212. }
  213. catch
  214. {
  215. kurtosis_excess.Text = "Undefined.";
  216. }
  217. try
  218. {
  219. coefficient_of_variation.Text = dist.coefficient_of_variation().ToString();
  220. }
  221. catch
  222. {
  223. coefficient_of_variation.Text = "Undefined.";
  224. }
  225. rangeLowestLabel.Text = dist.lowest().ToString();
  226. rangeGreatestLabel.Text = dist.uppermost().ToString();
  227. supportLowerLabel.Text = dist.lower().ToString();
  228. supportUpperLabel.Text = dist.upper().ToString();
  229. cdfTabPage.ToolTipText = "Random variate can range from " + rangeLowestLabel.Text
  230. + " to " + rangeGreatestLabel.Text
  231. + ",\nbut is said to be supported from " + supportLowerLabel.Text
  232. + " to " + supportUpperLabel.Text
  233. + "\nWithin this supported range the PDF and CDF have values between 0 and 1,\nbut below " + supportLowerLabel.Text + " both are zero, and above "
  234. + supportUpperLabel.Text + " both are unity";
  235. }
  236. catch (SystemException se)
  237. {
  238. MessageBox.Show(se.Message, "Calculation Error!");
  239. }
  240. }
  241. private void properties_tab_Deselecting(object sender, TabControlCancelEventArgs e)
  242. {
  243. try
  244. {
  245. if (e.TabPageIndex == 0)
  246. { // Update selected distribution object:
  247. double x = double.Parse(parameter1.Text);
  248. double y = double.Parse(parameter2.Text);
  249. double z = double.Parse(parameter3.Text);
  250. int i = distribution.SelectedIndex;
  251. dist = new boost_math.any_distribution(i, x, y, z);
  252. // Clear existing CDF data (has to be a better way?):
  253. while (CDF_data.Rows.Count > 1)
  254. {
  255. CDF_data.Rows.Remove(CDF_data.Rows[0]);
  256. }
  257. // Clear existing quantile data (has to be a better way?):
  258. while (QuantileData.Rows.Count > 1)
  259. {
  260. QuantileData.Rows.Remove(QuantileData.Rows[0]);
  261. }
  262. }
  263. }
  264. catch (SystemException se)
  265. {
  266. MessageBox.Show(se.Message +
  267. " Please check the distribution's parameters and try again.", "Distribution Error");
  268. this.propertiesTab.SelectedIndex = 0;
  269. e.Cancel = true;
  270. }
  271. }
  272. private void QuantileData_CellEndEdit(object sender, DataGridViewCellEventArgs e)
  273. { // aka Risk & critical values tab.
  274. try
  275. {
  276. if (e.ColumnIndex == 0)
  277. {
  278. int i = e.RowIndex;
  279. string s = QuantileData.Rows[i].Cells[0].Value.ToString();
  280. double x = double.Parse(s);
  281. // Remember x is alpha: 1 - the probability:
  282. double lcv = dist.quantile(x);
  283. double ucv = dist.quantile_c(x);
  284. QuantileData.Rows[i].Cells[1].Value = lcv;
  285. QuantileData.Rows[i].Cells[2].Value = ucv;
  286. }
  287. }
  288. catch (SystemException se)
  289. {
  290. // TODO add some proper handling here!
  291. MessageBox.Show("Error in probability value: " + se.Message, "Calculation Error");
  292. }
  293. }
  294. private void QuantileTab_Enter(object sender, EventArgs e)
  295. { // Evaluate critical values (quantiles) for pre-chosen risk level.
  296. // and then, optionally, for other user-provided risk levels.
  297. try
  298. {
  299. if (QuantileData.Rows.Count == 1)
  300. {
  301. // Add some defaults:
  302. QuantileData.Rows.Add(5); // 5 Risk levels.
  303. QuantileData.Rows[0].Cells[0].Value = "0.001"; // Risk values as text,
  304. QuantileData.Rows[0].Cells[1].Value = dist.quantile(0.001); // & as double.
  305. QuantileData.Rows[0].Cells[2].Value = dist.quantile_c(0.001);
  306. QuantileData.Rows[1].Cells[0].Value = "0.01";
  307. QuantileData.Rows[1].Cells[1].Value = dist.quantile(0.01); // 99% confidence.
  308. QuantileData.Rows[1].Cells[2].Value = dist.quantile_c(0.01);
  309. QuantileData.Rows[2].Cells[0].Value = "0.05";
  310. QuantileData.Rows[2].Cells[1].Value = dist.quantile(0.05);
  311. QuantileData.Rows[2].Cells[2].Value = dist.quantile_c(0.05);
  312. QuantileData.Rows[3].Cells[0].Value = "0.1";
  313. QuantileData.Rows[3].Cells[1].Value = dist.quantile(0.1);
  314. QuantileData.Rows[3].Cells[2].Value = dist.quantile_c(0.1);
  315. QuantileData.Rows[4].Cells[0].Value = "0.33333333333333333";
  316. QuantileData.Rows[4].Cells[1].Value = dist.quantile(0.33333333333333333);
  317. QuantileData.Rows[4].Cells[2].Value = dist.quantile_c(0.33333333333333333);
  318. }
  319. }
  320. catch (SystemException se)
  321. {
  322. // TODO add some proper handling here!
  323. MessageBox.Show(se.Message, "Calculation Error");
  324. }
  325. }
  326. private void properties_tab_SelectedIndexChanged(object sender, EventArgs e)
  327. {
  328. }
  329. private void tabPage1_Click(object sender, EventArgs e)
  330. {
  331. }
  332. private void CDF_data_CellContentClick(object sender, DataGridViewCellEventArgs e)
  333. {
  334. }
  335. distexAboutBox DistexAboutBox = new distexAboutBox();
  336. private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
  337. {
  338. DistexAboutBox.ShowDialog();
  339. }
  340. private void DistexForm_Activated(object sender, EventArgs e)
  341. {
  342. }
  343. /// get AssemblyDescription
  344. public string AssemblyDescription
  345. {
  346. get
  347. {
  348. // Get all Description attributes on this assembly
  349. object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false);
  350. // If there aren't any Description attributes, return an empty string
  351. if (attributes.Length == 0)
  352. return "";
  353. // If there is a Description attribute, return its value
  354. return ((AssemblyDescriptionAttribute)attributes[0]).Description;
  355. }
  356. }
  357. private void saveFileDialog1_FileOk(object sender, CancelEventArgs e)
  358. {
  359. using (StreamWriter sw = new StreamWriter(this.saveFileDialog.FileName))
  360. { // Write distribution info and properties to file.
  361. sw.WriteLine( AssemblyDescription);
  362. sw.WriteLine("Version " + Assembly.GetExecutingAssembly().GetName().Version.ToString());
  363. // Get parameter names (null "" if no parameter).
  364. int i = distribution.SelectedIndex;
  365. distributionValueLabel.Text = boost_math.any_distribution.distribution_name(i).ToString();
  366. sw.WriteLine(distributionValueLabel.Text + " distribution");
  367. parameterLabel1.Text = boost_math.any_distribution.first_param_name(i).ToString();
  368. parameterLabel2.Text = boost_math.any_distribution.second_param_name(i).ToString();
  369. parameterLabel3.Text = boost_math.any_distribution.third_param_name(i).ToString();
  370. string separator = "\t "; // , or tab or space?
  371. // Write parameter name & value.
  372. sw.WriteLine(parameterLabel1.Text + separator + this.parameter1.Text);
  373. if (boost_math.any_distribution.second_param_name(i).Length.CompareTo(0) != 0)
  374. { // Is a 2nd parameter.
  375. sw.WriteLine(parameterLabel2.Text + separator + this.parameter2.Text);
  376. }
  377. if (boost_math.any_distribution.third_param_name(i).Length.CompareTo(0) != 0)
  378. { // Is a 3rd parameter.
  379. sw.WriteLine(parameterLabel3.Text + separator + this.parameter3.Text);
  380. }
  381. sw.WriteLine();
  382. sw.WriteLine("Properties");
  383. // Show computed properties of distribution.
  384. double x = double.Parse(parameter1.Text);
  385. double y = double.Parse(parameter2.Text);
  386. double z = double.Parse(parameter3.Text);
  387. dist = new boost_math.any_distribution(i, x, y, z);
  388. // Note global dist might not have been calculated yet if no of the tabs clicked.
  389. try
  390. {
  391. mean.Text = dist.mean().ToString();
  392. }
  393. catch
  394. {
  395. mean.Text = "Undefined";
  396. }
  397. sw.WriteLine("Mean" + separator + mean.Text);
  398. try
  399. {
  400. mode.Text = dist.mode().ToString();
  401. }
  402. catch
  403. {
  404. mode.Text = "Undefined";
  405. }
  406. sw.WriteLine("mode" + separator + mode.Text);
  407. try
  408. {
  409. median.Text = dist.median().ToString();
  410. }
  411. catch
  412. {
  413. median.Text = "Undefined";
  414. }
  415. sw.WriteLine("Median" + separator + median.Text);
  416. try
  417. {
  418. variance.Text = dist.variance().ToString();
  419. }
  420. catch
  421. {
  422. variance.Text = "Undefined";
  423. }
  424. sw.WriteLine("Variance" + separator + variance.Text);
  425. try
  426. {
  427. standard_deviation.Text = dist.standard_deviation().ToString();
  428. }
  429. catch
  430. {
  431. standard_deviation.Text = "Undefined";
  432. }
  433. sw.WriteLine("Standard Deviation" + separator + standard_deviation.Text);
  434. try
  435. {
  436. skewness.Text = dist.skewness().ToString();
  437. }
  438. catch
  439. {
  440. skewness.Text = "Undefined";
  441. }
  442. sw.WriteLine("Skewness" + separator + skewness.Text);
  443. try
  444. {
  445. coefficient_of_variation.Text = dist.coefficient_of_variation().ToString();
  446. }
  447. catch
  448. {
  449. coefficient_of_variation.Text = "Undefined";
  450. }
  451. sw.WriteLine("Cofficient of variation" + separator + coefficient_of_variation.Text);
  452. try
  453. {
  454. kurtosis.Text = dist.kurtosis().ToString();
  455. }
  456. catch
  457. {
  458. kurtosis.Text = "Undefined";
  459. }
  460. sw.WriteLine("Kurtosis" + separator + kurtosis.Text);
  461. try
  462. {
  463. kurtosis_excess.Text = dist.kurtosis_excess().ToString();
  464. }
  465. catch
  466. {
  467. kurtosis_excess.Text = "Undefined";
  468. }
  469. sw.WriteLine("Kurtosis excess" + separator + kurtosis_excess.Text);
  470. sw.WriteLine();
  471. sw.WriteLine("Range from" + separator + dist.lowest().ToString() + separator +
  472. "to" + separator + dist.uppermost().ToString());
  473. sw.WriteLine("Support from " + separator + dist.lower().ToString() +separator+
  474. "to " + separator + dist.upper().ToString());
  475. sw.WriteLine();
  476. //
  477. sw.WriteLine("Quantiles");
  478. if (QuantileData.Rows.Count == 1)
  479. { // Add some defaults:
  480. QuantileData.Rows.Add(5); // 5 Risk levels.
  481. QuantileData.Rows[0].Cells[0].Value = "0.001"; // Risk values as text,
  482. QuantileData.Rows[0].Cells[1].Value = dist.quantile(0.001); // & as double.
  483. QuantileData.Rows[0].Cells[2].Value = dist.quantile_c(0.001);
  484. QuantileData.Rows[1].Cells[0].Value = "0.01";
  485. QuantileData.Rows[1].Cells[1].Value = dist.quantile(0.01); // 99% confidence.
  486. QuantileData.Rows[1].Cells[2].Value = dist.quantile_c(0.01);
  487. QuantileData.Rows[2].Cells[0].Value = "0.05";
  488. QuantileData.Rows[2].Cells[1].Value = dist.quantile(0.05);
  489. QuantileData.Rows[2].Cells[2].Value = dist.quantile_c(0.05);
  490. QuantileData.Rows[3].Cells[0].Value = "0.1";
  491. QuantileData.Rows[3].Cells[1].Value = dist.quantile(0.1);
  492. QuantileData.Rows[3].Cells[2].Value = dist.quantile_c(0.1);
  493. QuantileData.Rows[4].Cells[0].Value = "0.33333333333333333";
  494. QuantileData.Rows[4].Cells[1].Value = dist.quantile(0.33333333333333333);
  495. QuantileData.Rows[4].Cells[2].Value = dist.quantile_c(0.33333333333333333);
  496. }
  497. // else have already been calculated by entering the quantile tab.
  498. for (int r = 0; r < QuantileData.Rows.Count-1; r++)
  499. { // Show all the rows of quantiles, including any optional user values.
  500. sw.WriteLine(QuantileData.Rows[r].Cells[0].Value.ToString() + separator +
  501. QuantileData.Rows[r].Cells[1].Value.ToString() + separator +
  502. QuantileData.Rows[r].Cells[2].Value.ToString());
  503. }
  504. sw.WriteLine();
  505. sw.WriteLine("PDF, CDF & complement(s)");
  506. for (int r = 0; r < CDF_data.Rows.Count-1; r++)
  507. { // Show all the rows of pdf, cdf, including any optional user values.
  508. sw.WriteLine(CDF_data.Rows[r].Cells[0].Value.ToString() + separator + // x value.
  509. CDF_data.Rows[r].Cells[1].Value.ToString() + separator + // pdf
  510. CDF_data.Rows[r].Cells[2].Value.ToString() + separator + // cdf
  511. CDF_data.Rows[r].Cells[3].Value.ToString());// cdf complement.
  512. }
  513. sw.WriteLine();
  514. }
  515. } // saveFileDialog1_FileOk
  516. private void saveToolStripMenuItem_Click(object sender, EventArgs e)
  517. {
  518. this.saveFileDialog.ShowDialog();
  519. }
  520. private void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
  521. { // Same as Save.
  522. this.saveFileDialog.ShowDialog();
  523. }
  524. private void contentsToolStripMenuItem_Click(object sender, EventArgs e)
  525. { // In lieu of proper help.
  526. string helpText = "\n" + AssemblyDescription +
  527. "\nVersion " + Assembly.GetExecutingAssembly().GetName().Version.ToString() +
  528. "\nA Windows utility to show the properties of distributions " +
  529. "\nand permit calculation of probability density (or mass) function (PDF) " +
  530. "\nand cumulative distribution function (CDF) and complements from values provided." +
  531. "\nQuantiles are also calculated for typical risk (alpha) probabilities" +
  532. "\nand for probabilities provided by the user." +
  533. "\n" +
  534. "\nResults can be saved to text files using Save or SaveAs." +
  535. "\nAll the values on the four tabs are output to the file chosen," +
  536. "\nand are tab separated to assist input to other programs," +
  537. "\nfor example, spreadsheets or text editors." +
  538. "\nNote: when importing to Excel, by default only 10 decimal digits are shown by Excel:" +
  539. "\nit is necessary to format all cells to display the full 15 decimal digits," +
  540. "\nalthough not all computed values will be as accurate as this." +
  541. "\n\nValues shown as NaN cannot be calculated for the value given," +
  542. "\nmost commonly because the value is outside the range for the distribution." +
  543. "\n" +
  544. "\nFor more information, including downloads, see " +
  545. "\nhttp://sourceforge.net/projects/distexplorer/" +
  546. "\n(Note that .NET framework 4.0 and VC Redistribution X86 are requirements for this program.)" +
  547. "\n\nCopyright John Maddock & Paul A. Bristow 2007, 2009, 2010, 2012";
  548. MessageBox.Show("Statistical Distribution Explorer\n" + helpText);
  549. }
  550. private void newToolStripMenuItem_Click(object sender, EventArgs e)
  551. {
  552. MessageBox.Show("New is not yet implemented.");
  553. }
  554. private void openToolStripMenuItem_Click(object sender, EventArgs e)
  555. {
  556. MessageBox.Show("Open is not yet implemented.");
  557. }
  558. private void printToolStripMenuItem_Click(object sender, EventArgs e)
  559. {
  560. MessageBox.Show("Print is not yet implemented." +
  561. "\nSave all values to a text file and print that file.");
  562. }
  563. private void printPreviewToolStripMenuItem_Click(object sender, EventArgs e)
  564. {
  565. MessageBox.Show("Print Preview is not yet implemented." +
  566. "\nSave all values to a text file and print that file.");
  567. }
  568. private void exitToolStripMenuItem_Click(object sender, EventArgs e)
  569. { // exit DistexForm
  570. this.Close();
  571. }
  572. } // class DistexForm
  573. } // namespace distribution_explorer