PageRenderTime 24ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/DotNetSCORM.LearningAPI/DotNetSCORMControlBase.cs

#
C# | 254 lines | 161 code | 20 blank | 73 comment | 15 complexity | a0c61282f7fae46eae36ea2765f90b38 MD5 | raw file
  1. /* Copyright (c) Microsoft Corporation. All rights reserved. */
  2. // MICROSOFT PROVIDES SAMPLE CODE "AS IS" AND WITH ALL FAULTS, AND WITHOUT ANY WARRANTY WHATSOEVER. 
  3. // MICROSOFT EXPRESSLY DISCLAIMS ALL WARRANTIES WITH RESPECT TO THE SOURCE CODE, INCLUDING BUT NOT
  4. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THERE IS
  5. // NO WARRANTY OF TITLE OR NONINFRINGEMENT FOR THE SOURCE CODE.
  6. // BasicWebPlayerBase.cs
  7. //
  8. // Contains classes that help implement the BasicWebPlayer application.
  9. //
  10. using System;
  11. using System.Collections.Generic;
  12. using System.Collections.ObjectModel;
  13. using System.Diagnostics;
  14. using System.Data;
  15. using System.IO;
  16. using System.Reflection;
  17. using System.Web;
  18. using System.Web.Configuration;
  19. using System.Web.UI;
  20. using System.Web.UI.HtmlControls;
  21. using System.Web.UI.WebControls;
  22. using System.Web.UI.WebControls.WebParts;
  23. using Microsoft.LearningComponents;
  24. using Microsoft.LearningComponents.Storage;
  25. using Schema = DotNetSCORM.LearningAPI.Schema;
  26. using DotNetSCORM.LearningAPI.LearningComponentsHelper;
  27. // <summary>
  28. // Base class for all pages in the BasicWebPlayer application. Contains functionality common to
  29. // the entire application.
  30. // </summary>
  31. //
  32. namespace DotNetSCORM.LearningAPI
  33. {
  34. public class DotNetSCORMControlBase : ControlHelper
  35. {
  36. /// <summary>
  37. /// Requests that the list of training for the current user be retrieved from the LearningStore
  38. /// database. Adds the request to a given <c>LearningStoreJob</c> for later execution.
  39. /// </summary>
  40. ///
  41. /// <param name="job">A <c>LearningStoreJob</c> to add the new query to.</param>
  42. ///
  43. /// <param name="packageId">To request information related to a single pass the
  44. /// <c>PackageItemIdentifier</c> of the package as this parameter. Otherwise, leave this
  45. /// parameter <c>null</c>.</param>
  46. ///
  47. /// <remarks>
  48. /// After executing this method, and later calling <c>Job.Execute</c>, call
  49. /// <c>GetMyTrainingResultsToHtml</c> to convert the <c>DataTable</c> returned by
  50. /// <c>Job.Execute</c> into HTML.
  51. /// </remarks>
  52. ///
  53. protected void RequestMyTraining(LearningStoreJob job,
  54. PackageItemIdentifier packageId)
  55. {
  56. LearningStoreQuery query = LStore.CreateQuery(Schema.MyAttemptsAndPackages.ViewName);
  57. query.AddColumn(Schema.MyAttemptsAndPackages.PackageId);
  58. query.AddColumn(Schema.MyAttemptsAndPackages.PackageFileName);
  59. query.AddColumn(Schema.MyAttemptsAndPackages.OrganizationId);
  60. query.AddColumn(Schema.MyAttemptsAndPackages.OrganizationTitle);
  61. query.AddColumn(Schema.MyAttemptsAndPackages.AttemptId);
  62. query.AddColumn(Schema.MyAttemptsAndPackages.UploadDateTime);
  63. query.AddColumn(Schema.MyAttemptsAndPackages.AttemptStatus);
  64. query.AddColumn(Schema.MyAttemptsAndPackages.TotalPoints);
  65. query.AddSort(Schema.MyAttemptsAndPackages.UploadDateTime,
  66. LearningStoreSortDirection.Ascending);
  67. query.AddSort(Schema.MyAttemptsAndPackages.OrganizationId,
  68. LearningStoreSortDirection.Ascending);
  69. if (packageId != null)
  70. {
  71. query.AddCondition(Schema.MyAttemptsAndPackages.PackageId,
  72. LearningStoreConditionOperator.Equal, packageId);
  73. }
  74. job.PerformQuery(query);
  75. }
  76. /// <summary>
  77. /// Reads a <c>DataTable</c>, returned by <c>Job.Execute</c>, containing the results requested
  78. /// by a previous call to <c>RequestMyTraining</c>. Converts the results to HTML rows, added
  79. /// to a given HTML table.
  80. /// </summary>
  81. ///
  82. /// <param name="dataTable">A <c>DataTable</c> returned from <c>Job.Execute</c>.</param>
  83. ///
  84. /// <param name="htmlTable">The HTML table to write to.</param>
  85. ///
  86. protected void GetMyTrainingResultsToHtml(DataTable dataTable,
  87. Table htmlTable)
  88. {
  89. // loop once for each organization of each package
  90. PackageItemIdentifier previousPackageId = null;
  91. foreach (DataRow dataRow in dataTable.Rows)
  92. {
  93. // extract information from <dataRow> into local variables
  94. PackageItemIdentifier packageId;
  95. LStoreHelper.CastNonNull(dataRow[Schema.MyAttemptsAndPackages.PackageId],
  96. out packageId);
  97. string packageFileName;
  98. LStoreHelper.CastNonNull(dataRow[Schema.MyAttemptsAndPackages.PackageFileName],
  99. out packageFileName);
  100. ActivityPackageItemIdentifier organizationId;
  101. LStoreHelper.CastNonNull(dataRow[Schema.MyAttemptsAndPackages.OrganizationId],
  102. out organizationId);
  103. string organizationTitle;
  104. LStoreHelper.CastNonNull(dataRow[Schema.MyAttemptsAndPackages.OrganizationTitle],
  105. out organizationTitle);
  106. AttemptItemIdentifier attemptId;
  107. LStoreHelper.Cast(dataRow[Schema.MyAttemptsAndPackages.AttemptId],
  108. out attemptId);
  109. DateTime? uploadDateTime;
  110. LStoreHelper.Cast(dataRow[Schema.MyAttemptsAndPackages.UploadDateTime],
  111. out uploadDateTime);
  112. AttemptStatus? attemptStatus;
  113. LStoreHelper.Cast(dataRow[Schema.MyAttemptsAndPackages.AttemptStatus],
  114. out attemptStatus);
  115. float? score;
  116. LStoreHelper.Cast(dataRow[Schema.MyAttemptsAndPackages.TotalPoints],
  117. out score);
  118. // if this <dataRow> is another organization (basically another "table of contents")
  119. // within the same package as the previous <dataRow>, set <samePackage> to true
  120. bool samePackage = ((previousPackageId != null) &&
  121. (packageId.GetKey() == previousPackageId.GetKey()));
  122. // begin the HTML table row
  123. TableRow htmlRow = new TableRow();
  124. htmlRow.ID = "Package" + packageId.GetKey().ToString();
  125. // set <trainingName> to a name to use for this row (i.e. one
  126. // organization of one package)
  127. string trainingName;
  128. if (organizationTitle.Length == 0)
  129. trainingName = packageFileName;
  130. else
  131. trainingName = String.Format("{0} - {1}", packageFileName, organizationTitle);
  132. // add the "Select" HTML cell, unless this row is for the same
  133. // package as the previous row
  134. TableCell htmlCell = new TableCell();
  135. if (samePackage)
  136. htmlCell.CssClass = "Select_ SamePackage_";
  137. else
  138. {
  139. htmlCell.CssClass = "Select_ NewPackage_";
  140. CheckBox checkBox = new CheckBox();
  141. checkBox.ID = "Select" + packageId.GetKey().ToString();
  142. checkBox.Attributes.Add("onclick", "OnSelectionChanged()");
  143. checkBox.ToolTip = "Select";
  144. htmlCell.Controls.Add(checkBox);
  145. //TODO:Fix this to get rid of the checkbox in the MyTraining and show in All Training
  146. htmlCell.Visible = false;
  147. }
  148. htmlRow.Cells.Add(htmlCell);
  149. // add the "Name" HTML cell
  150. htmlCell = new TableCell();
  151. htmlCell.CssClass = "Name_";
  152. HtmlAnchor anchor = new HtmlAnchor();
  153. if (attemptId == null)
  154. {
  155. // attempt has not yet been created for this training -- create an URL that begins
  156. // with "Org:", indicating that the ID is an OrganizationId which identifies
  157. // which organization of which package to launch
  158. anchor.HRef = String.Format("javascript:OpenTraining('Org:{0}')",
  159. organizationId.GetKey());
  160. // give this anchor an ID that allows client-side script to update its URL once
  161. // training has been launched
  162. anchor.ID = String.Format("Org_{0}", organizationId.GetKey());
  163. // provide a tooltip
  164. anchor.Attributes.Add("title", "Begin training");
  165. }
  166. else
  167. {
  168. // attempt was already created -- include its ID in the URL
  169. anchor.HRef = String.Format("javascript:OpenTraining('Att:{0}')",
  170. attemptId.GetKey());
  171. // provide a tooltip
  172. anchor.Attributes.Add("title", "Continue training");
  173. }
  174. anchor.InnerText = trainingName;
  175. htmlCell.Controls.Add(anchor);
  176. htmlRow.Cells.Add(htmlCell);
  177. // add the "Uploaded" HTML cell
  178. htmlCell = new TableCell();
  179. htmlCell.CssClass = "Uploaded_";
  180. htmlCell.Wrap = false;
  181. htmlCell.Text = NoBr(System.Web.HttpContext.Current.Server.HtmlEncode(
  182. String.Format("{0:d} {0:t}", uploadDateTime)));
  183. htmlRow.Cells.Add(htmlCell);
  184. // add the "Status" HTML cell
  185. string attemptStatusString;
  186. if (attemptStatus == null)
  187. attemptStatusString = "Not Started";
  188. else
  189. attemptStatusString = attemptStatus.ToString();
  190. htmlCell = new TableCell();
  191. htmlCell.CssClass = "Status_";
  192. htmlCell.Wrap = false;
  193. if (attemptId != null)
  194. {
  195. anchor = new HtmlAnchor();
  196. anchor.HRef = String.Format("javascript:ShowLog({0})", attemptId.GetKey());
  197. anchor.InnerHtml = NoBr(HttpContext.Current.Server.HtmlEncode(attemptStatusString));
  198. anchor.Attributes.Add("title", "Show Log");
  199. htmlCell.Controls.Add(anchor);
  200. }
  201. else
  202. htmlCell.Text = NoBr(HttpContext.Current.Server.HtmlEncode(attemptStatusString));
  203. htmlRow.Cells.Add(htmlCell);
  204. // add the "Score" HTML cell
  205. string scoreString;
  206. if (score == null)
  207. scoreString = "";
  208. else
  209. scoreString = String.Format("{0:0}%", Math.Round(score.Value));
  210. htmlCell = new TableCell();
  211. htmlCell.CssClass = "Score_";
  212. htmlCell.Wrap = false;
  213. htmlCell.Text = NoBr(HttpContext.Current.Server.HtmlEncode(scoreString));
  214. htmlRow.Cells.Add(htmlCell);
  215. // end the table HTML row; add it to the HTML table
  216. htmlTable.Rows.Add(htmlRow);
  217. previousPackageId = packageId;
  218. }
  219. }
  220. /// <summary>
  221. /// Adds "no-break" HTML elements around a given string of HTML.
  222. /// </summary>
  223. ///
  224. /// <remarks>
  225. /// <c>TableCell.Wrap = false</c> can also be used, but that approach won't work if script is
  226. /// used to copy table rows from one window to another at runtime.
  227. /// </remarks>
  228. ///
  229. protected static string NoBr(string html)
  230. {
  231. return "<nobr>" + html + "</nobr>";
  232. }
  233. }
  234. }