Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

423 lines
13 KiB

  1. // Functions for the Remove page
  2. /*-------------------------------------------------------------------------
  3. Purpose: Called when ARP switches to the Remove pane
  4. */
  5. function Remove_Activate()
  6. {
  7. // We need some utility functions
  8. LoadScriptFile("idScriptUtil", "util.js");
  9. LoadScriptFile("idScriptBplate", "bplate.js");
  10. InitBoilerPlateClass();
  11. // Show the relavent rows
  12. g_docAll.idTrHeadMargin_Remove.style.display = 'block';
  13. g_docAll.idTrHead_Remove.style.display = 'block';
  14. g_docAll.idTrBody_Remove.style.display = 'block';
  15. // Is this an alpha machine?
  16. if (g_bIsAlpha)
  17. {
  18. // Yes; turn on the check box and set the 'force x86' property
  19. g_docAll.idTrFoot_Remove.style.display = 'block';
  20. g_docAll.idChkRemoveForcex86.attachEvent("onclick", new Function ("idCtlAppsDso.Forcex86 = idChkRemoveForcex86.checked"));
  21. }
  22. // Is this pane being activated for the first time?
  23. if (false == g_bRemovePageLoaded)
  24. {
  25. // Yes
  26. // Check policies for any restrictions
  27. if (Dso_IsRestricted("NoSupportInfo"))
  28. g_bShowSupportInfo = false;
  29. g_docAll.idSelSortBy.onchange = _SortDataSource;
  30. // Connect the remove listbox to the datasource
  31. g_docAll.idRemoveListbox.dataSource = "idCtlAppsDso.Remove";
  32. /* Fake version
  33. g_docAll.idRemoveListbox.dataSource = "idCtlRemoveApps";
  34. */
  35. Dso_GetCtl("Remove").attachEvent("ondatasetcomplete", Remove_OnDatasetComplete);
  36. // Set the initial focus to the listbox, and refresh the listbox
  37. // so it gets its data.
  38. //
  39. g_docAll.idRemoveListbox.Refresh();
  40. g_bRemovePageLoaded = true;
  41. }
  42. g_bReenumAddList = false;
  43. Remove_SetFocus();
  44. }
  45. /*-------------------------------------------------------------------------
  46. Purpose: Set the initial focus
  47. */
  48. function Remove_SetFocus()
  49. {
  50. g_docAll.idRemoveListbox.focus();
  51. }
  52. /*-------------------------------------------------------------------------
  53. Purpose: Called when the Remove page is switched away
  54. */
  55. function Remove_Deactivate()
  56. {
  57. // Hide the relavent rows
  58. g_docAll.idTrHeadMargin_Remove.style.display = 'none';
  59. g_docAll.idTrHead_Remove.style.display = 'none';
  60. g_docAll.idTrFoot_Remove.style.display = 'none';
  61. g_docAll.idTrBody_Remove.style.display = 'none';
  62. if (g_bReenumAddList)
  63. {
  64. Dso_Refresh("Add");
  65. }
  66. }
  67. /*-------------------------------------------------------------------------
  68. Purpose: Handler for the 'onSetFocus' listbox event.
  69. */
  70. function Remove_OnSetFocus()
  71. {
  72. var evt = window.event;
  73. ApplyExtraStyles(evt.srcChild, evt.bFocus);
  74. }
  75. /*-------------------------------------------------------------------------
  76. Purpose: Handler for the 'onCustomDraw' listbox event. Fixup the element objects
  77. as appropriate.
  78. */
  79. function Remove_OnCustomDraw()
  80. {
  81. var evt = window.event;
  82. var tblElem = evt.srcChild; // the contents of the row is another table
  83. if (evt.bSelected)
  84. {
  85. // Item is being selected
  86. var dwCapability = evt.Recordset("capability");
  87. if ('prepaint' == evt.drawStage)
  88. {
  89. // Prepaint stuff
  90. // alert("Capability=" + dwCapability);
  91. // Show the right set of buttons
  92. // Does this support separate modify/remove buttons?
  93. if (dwCapability & APPCAP_MODIFYREMOVE)
  94. {
  95. // No
  96. evt.srcElement.EnableTemplate('idTrMultiBtns', false);
  97. evt.srcElement.EnableTemplate('idTrSingleBtns', true);
  98. }
  99. else
  100. {
  101. // Yes; show separate modify/remove buttons
  102. evt.srcElement.EnableTemplate('idTrMultiBtns', true);
  103. evt.srcElement.EnableTemplate('idTrSingleBtns', false);
  104. }
  105. }
  106. else
  107. {
  108. // Postpaint stuff
  109. var bplate = new BoilerPlate();
  110. bplate.Parse(evt.Recordset("supportinfo"));
  111. // Does this app have any need for the support info dialog?
  112. //
  113. // (Having just the 'displayname' as support info isn't helpful enough
  114. // to merit showing the dialog)
  115. //
  116. // alert("bplate.Length = " + bplate.Length() + "; displayname = " + bplate.Get("displayname"));
  117. if (!g_bShowSupportInfo ||
  118. !(dwCapability & APPCAP_REPAIR) &&
  119. (1 > bplate.Length() ||
  120. 1 == bplate.Length() && null != bplate.Get("displayname")))
  121. {
  122. // No; then hide the link to the dialog
  123. tblElem.all('idTdInfoDesc').style.visibility = 'hidden';
  124. }
  125. // Attach events and stuff now that the elements have been added
  126. // to the document tree.
  127. // Does this support separate modify and remove buttons?
  128. if (dwCapability & APPCAP_MODIFYREMOVE)
  129. {
  130. // No
  131. tblElem.all('idBtnBoth').onclick = _ModifyOrRemove;
  132. // Disable buttons according to policy
  133. if ( !(dwCapability & APPCAP_UNINSTALL) )
  134. tblElem.all('idBtnBoth').disabled = true;
  135. }
  136. else
  137. {
  138. // Yes
  139. tblElem.all('idBtnModify').onclick = _ModifyOrRemove;
  140. tblElem.all('idBtnRemove').onclick = _ModifyOrRemove;
  141. // Disable buttons according to policy
  142. if ( !(dwCapability & APPCAP_MODIFY) )
  143. tblElem.all('idBtnModify').disabled = true;
  144. if ( !(dwCapability & APPCAP_UNINSTALL) )
  145. tblElem.all('idBtnRemove').disabled = true;
  146. }
  147. // Are we sorting by name or size?
  148. var szSort = g_docAll.idSelSortBy.options(g_docAll.idSelSortBy.selectedIndex).value;
  149. if ("displayname" == szSort || "size" == szSort || "timesused" == szSort)
  150. {
  151. // Yes; then allow the size field in the properties (the 'index
  152. // value') to be an anchor so the user can click it for a
  153. // definition.
  154. var spnValue = evt.srcRow.all("idSpnIndexValue");
  155. var tdValue = spnValue.parentElement;
  156. var tdId = ("timesused" == szSort ? "idAFrequency" : "idASize");
  157. tdValue._szInner = tdValue.innerHTML;
  158. // If there is nothing to go inside of the 'anchor', then don't create the
  159. // span elements. We will still replace it with the old _szInner later.
  160. if (tdValue.innerText != "")
  161. {
  162. tdValue.innerHTML =
  163. "<SPAN id=" +
  164. tdId +
  165. " class='FakeAnchor' tabIndex=0 onKeyDown='_OnKeyDownFakeAnchor()' onClick='_OpenDefinition();'> " +
  166. "&nbsp;<U>" +
  167. tdValue._szInner +
  168. "</U></SPAN>";
  169. }
  170. }
  171. // Use the focus state provided by the event
  172. ApplyExtraStyles(tblElem, evt.bFocus);
  173. }
  174. }
  175. else
  176. {
  177. // Item is being deselected
  178. if ('prepaint' == evt.drawStage)
  179. {
  180. // Remove the anchor element from the value field
  181. var spnValue = evt.srcRow.all("idSpnIndexValue");
  182. var tdValue = spnValue.parentElement.parentElement.parentElement;
  183. if (null != tdValue._szInner)
  184. {
  185. tdValue.innerHTML = tdValue._szInner;
  186. tdValue._szInner = null;
  187. }
  188. // Say focus==false so the style reverts to the default setting
  189. ApplyExtraStyles(tblElem, false);
  190. }
  191. }
  192. }
  193. /*-------------------------------------------------------------------------
  194. Purpose: Display the Support Info dialog
  195. */
  196. function _OpenSupportInfo()
  197. {
  198. // Display the Support Info dialog
  199. var szFeatures = g_szSupportInfoSize + "; resizable:no; help:no";
  200. window.showModalDialog("support.htm", window, szFeatures);
  201. // Don't let the 'A' elem navigate
  202. window.event.returnValue = false;
  203. window.event.cancelBubble = true;
  204. }
  205. /*-------------------------------------------------------------------------
  206. Purpose: Display a definition dialog according to the field that was clicked.
  207. */
  208. function _OpenDefinition()
  209. {
  210. var elemSrc = window.event.srcElement;
  211. // We are trying to get the most specific id for looking up a
  212. // definition. We prefer idAFrequency or idASize. If we
  213. // get nothing or idSpnIndexValue, check to see if the parent
  214. // tag is more specific. It either will be or it will not exist.
  215. if (("idSpnIndexValue" == elemSrc.id) && ("" != elemSrc.parentElement.parentElement.id))
  216. {
  217. elemSrc = elemSrc.parentElement.parentElement;
  218. }
  219. if ("" == elemSrc.id)
  220. {
  221. elemSrc = elemSrc.parentElement;
  222. }
  223. if ("idAFrequency" == elemSrc.id)
  224. {
  225. var szFeatures = "dialogWidth:20em; dialogHeight:16em; resizable:no; help:no";
  226. window.showModalDialog("def_freq.htm", window, szFeatures);
  227. }
  228. else if ("idASize" == elemSrc.id || "idSpnIndexValue" == elemSrc.id)
  229. {
  230. var szFeatures = "dialogWidth:20em; dialogHeight:10.7em; resizable:no; help:no";
  231. window.showModalDialog("def_size.htm", window, szFeatures);
  232. }
  233. // Don't let the 'A' elem navigate
  234. window.event.returnValue = false;
  235. window.event.cancelBubble = true;
  236. }
  237. /*-------------------------------------------------------------------------
  238. Purpose: Re-sort the given data source object according to the current selection
  239. */
  240. function _SortDataSource()
  241. {
  242. var selElem = window.event.srcElement;
  243. var optCur = selElem.options(selElem.selectedIndex);
  244. Dso_Sort("Remove", optCur.value);
  245. }
  246. /*-------------------------------------------------------------------------
  247. Purpose: Modify or remove the current app (the current recordset)
  248. */
  249. function _ModifyOrRemove()
  250. {
  251. var rsCur = Dso_GetRecordset("Remove");
  252. var nRec = rsCur.AbsolutePosition;
  253. switch(event.srcElement.id)
  254. {
  255. case "idBtnBoth":
  256. g_docAll.idCtlAppsDso.Exec("Remove", "uninstall", nRec);
  257. break;
  258. case "idBtnModify":
  259. g_docAll.idCtlAppsDso.Exec("Remove", "modify", nRec);
  260. break;
  261. case "idBtnRemove":
  262. g_docAll.idCtlAppsDso.Exec("Remove", "uninstall", nRec);
  263. break;
  264. }
  265. /* Fake version
  266. switch(event.srcElement.id)
  267. {
  268. case "idBtnBoth":
  269. alert('Remove ' + rsCur("displayname"));
  270. break;
  271. case "idBtnModify":
  272. alert('Change ' + rsCur("displayname"));
  273. break;
  274. case "idBtnRemove":
  275. alert('Remove ' + rsCur("displayname"));
  276. break;
  277. }
  278. */
  279. if ("idBtnRemove" == event.srcElement.id)
  280. {
  281. // Now cause the 'Add' page to re-enumerate since an app may have been
  282. // removed. Ideally we'd only do this when we know an app successfully
  283. // removed, but I'm lazy about trying to figure that out!
  284. g_bReenumAddList = true;
  285. }
  286. }
  287. /*-------------------------------------------------------------------------
  288. Purpose: Called by the Support Info help window. This repairs the given app.
  289. */
  290. function SupportInfo_Repair(nRecordNumber)
  291. {
  292. var rsCur = Dso_GetRecordset("Remove");
  293. var nRecordSav = rsCur.AbsolutePosition;
  294. window.focus();
  295. rsCur.AbsolutePosition = nRecordNumber;
  296. g_docAll.idCtlAppsDso.Exec("Remove", "repair", nRecordNumber);
  297. /* Fake version
  298. alert('Repair app ' + rsCur("displayname"));
  299. */
  300. rsCur.AbsolutePosition = nRecordSav;
  301. }
  302. /*-------------------------------------------------------------------------
  303. Purpose: Called by the Support Info help window. This returns the structured
  304. record string containing all info that the Support Info needs.
  305. */
  306. function SupportInfo_Query()
  307. {
  308. // Compose the record string. See comments in support.htm for
  309. // details on the format.
  310. var rsCur = Dso_GetRecordset("Remove");
  311. var szRecord = "<recordnumber " + rsCur.AbsolutePosition + ">";
  312. szRecord += rsCur("supportinfo");
  313. szRecord += "<capability " + rsCur("capability") + ">";
  314. return szRecord;
  315. }
  316. /*-------------------------------------------------------------------------
  317. Purpose: Called by the Support Info help window. Returns the string
  318. specifying the intended size of the window. This is a hack
  319. since Trident doesn't provide this for us.
  320. */
  321. function SupportInfo_GetDlgSize()
  322. {
  323. return g_szSupportInfoSize;
  324. }
  325. /*-------------------------------------------------------------------------
  326. Purpose: Handle 'ondatasetcomplete' event fired from DSO
  327. */
  328. function Remove_OnDatasetComplete()
  329. {
  330. // Is this dataset complete for Remove?
  331. if (window.event.qualifier == "Remove")
  332. {
  333. // Yes; show this text if the dataset is empty
  334. var L_RemoveNoneAvailable_Text = "There are no programs installed on this computer";
  335. Dso_FeedbackIfEmpty("Remove", g_docAll.idRemoveListbox, L_RemoveNoneAvailable_Text);
  336. }
  337. }