VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/testmanager/webui/wuihlpform.py@ 83364

最後變更 在這個檔案從83364是 83364,由 vboxsync 提交於 5 年 前

TestManager: Adding test box selection to the scheduling group form (left over from r107843 where test boxes gained the ability to service more than one scheduling group).

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 55.6 KB
 
1# -*- coding: utf-8 -*-
2# $Id: wuihlpform.py 83364 2020-03-23 09:47:01Z vboxsync $
3
4"""
5Test Manager Web-UI - Form Helpers.
6"""
7
8__copyright__ = \
9"""
10Copyright (C) 2012-2020 Oracle Corporation
11
12This file is part of VirtualBox Open Source Edition (OSE), as
13available from http://www.alldomusa.eu.org. This file is free software;
14you can redistribute it and/or modify it under the terms of the GNU
15General Public License (GPL) as published by the Free Software
16Foundation, in version 2 as it comes in the "COPYING" file of the
17VirtualBox OSE distribution. VirtualBox OSE is distributed in the
18hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
19
20The contents of this file may alternatively be used under the terms
21of the Common Development and Distribution License Version 1.0
22(CDDL) only, as it comes in the "COPYING.CDDL" file of the
23VirtualBox OSE distribution, in which case the provisions of the
24CDDL are applicable instead of those of the GPL.
25
26You may elect to license modified versions of this file under the
27terms and conditions of either the GPL or the CDDL or both.
28"""
29__version__ = "$Revision: 83364 $"
30
31# Standard python imports.
32import copy;
33import sys;
34
35# Validation Kit imports.
36from common import utils;
37from common.webutils import escapeAttr, escapeElem;
38from testmanager import config;
39from testmanager.core.schedgroup import SchedGroupMemberData, SchedGroupDataEx;
40from testmanager.core.testcaseargs import TestCaseArgsData;
41from testmanager.core.testgroup import TestGroupMemberData, TestGroupDataEx;
42from testmanager.core.testbox import TestBoxDataForSchedGroup;
43
44# Python 3 hacks:
45if sys.version_info[0] >= 3:
46 unicode = str; # pylint: disable=redefined-builtin,invalid-name
47
48
49class WuiHlpForm(object):
50 """
51 Helper for constructing a form.
52 """
53
54 ksItemsList = 'ksItemsList'
55
56 ksOnSubmit_AddReturnToFieldWithCurrentUrl = '+AddReturnToFieldWithCurrentUrl+';
57
58 def __init__(self, sId, sAction, dErrors = None, fReadOnly = False, sOnSubmit = None):
59 self._fFinalized = False;
60 self._fReadOnly = fReadOnly;
61 self._dErrors = dErrors if dErrors is not None else dict();
62
63 if sOnSubmit == self.ksOnSubmit_AddReturnToFieldWithCurrentUrl:
64 sOnSubmit = u'return addRedirectToInputFieldWithCurrentUrl(this)';
65 if sOnSubmit is None: sOnSubmit = u'';
66 else: sOnSubmit = u' onsubmit=\"%s\"' % (escapeAttr(sOnSubmit),);
67
68 self._sBody = u'\n' \
69 u'<div id="%s" class="tmform">\n' \
70 u' <form action="%s" method="post"%s>\n' \
71 u' <ul>\n' \
72 % (sId, sAction, sOnSubmit);
73
74 def _add(self, sText):
75 """Internal worker for appending text to the body."""
76 assert not self._fFinalized;
77 if not self._fFinalized:
78 self._sBody += utils.toUnicode(sText, errors='ignore');
79 return True;
80 return False;
81
82 def _escapeErrorText(self, sText):
83 """Escapes error text, preserving some predefined HTML tags."""
84 if sText.find('<br>') >= 0:
85 asParts = sText.split('<br>');
86 for i, _ in enumerate(asParts):
87 asParts[i] = escapeElem(asParts[i].strip());
88 sText = '<br>\n'.join(asParts);
89 else:
90 sText = escapeElem(sText);
91 return sText;
92
93 def _addLabel(self, sName, sLabel, sDivSubClass = 'normal'):
94 """Internal worker for adding a label."""
95 if sName in self._dErrors:
96 sError = self._dErrors[sName];
97 if utils.isString(sError): # List error trick (it's an associative array).
98 return self._add(u' <li>\n'
99 u' <div class="tmform-field"><div class="tmform-field-%s">\n'
100 u' <label for="%s" class="tmform-error-label">%s\n'
101 u' <span class="tmform-error-desc">%s</span>\n'
102 u' </label>\n'
103 % (escapeAttr(sDivSubClass), escapeAttr(sName), escapeElem(sLabel),
104 self._escapeErrorText(sError), ) );
105 return self._add(u' <li>\n'
106 u' <div class="tmform-field"><div class="tmform-field-%s">\n'
107 u' <label for="%s">%s</label>\n'
108 % (escapeAttr(sDivSubClass), escapeAttr(sName), escapeElem(sLabel)) );
109
110
111 def finalize(self):
112 """
113 Finalizes the form and returns the body.
114 """
115 if not self._fFinalized:
116 self._add(u' </ul>\n'
117 u' </form>\n'
118 u'</div>\n'
119 u'<div class="clear"></div>\n' );
120 return self._sBody;
121
122 def addTextHidden(self, sName, sValue, sExtraAttribs = ''):
123 """Adds a hidden text input."""
124 return self._add(u' <div class="tmform-field-hidden">\n'
125 u' <input name="%s" id="%s" type="text" hidden%s value="%s" class="tmform-hidden">\n'
126 u' </div>\n'
127 u' </li>\n'
128 % ( escapeAttr(sName), escapeAttr(sName), sExtraAttribs, escapeElem(str(sValue)) ));
129 #
130 # Non-input stuff.
131 #
132 def addNonText(self, sValue, sLabel, sName = 'non-text', sPostHtml = ''):
133 """Adds a read-only text input."""
134 self._addLabel(sName, sLabel, 'string');
135 if sValue is None: sValue = '';
136 return self._add(u' <p>%s%s</p>\n'
137 u' </div></div>\n'
138 u' </li>\n'
139 % (escapeElem(unicode(sValue)), sPostHtml ));
140
141 def addRawHtml(self, sRawHtml, sLabel, sName = 'raw-html'):
142 """Adds a read-only text input."""
143 self._addLabel(sName, sLabel, 'string');
144 self._add(sRawHtml);
145 return self._add(u' </div></div>\n'
146 u' </li>\n');
147
148
149 #
150 # Text input fields.
151 #
152 def addText(self, sName, sValue, sLabel, sSubClass = 'string', sExtraAttribs = '', sPostHtml = ''):
153 """Adds a text input."""
154 if self._fReadOnly:
155 return self.addTextRO(sName, sValue, sLabel, sSubClass, sExtraAttribs);
156 if sSubClass not in ('int', 'long', 'string', 'uuid', 'timestamp', 'wide'): raise Exception(sSubClass);
157 self._addLabel(sName, sLabel, sSubClass);
158 if sValue is None: sValue = '';
159 return self._add(u' <input name="%s" id="%s" type="text"%s value="%s">%s\n'
160 u' </div></div>\n'
161 u' </li>\n'
162 % ( escapeAttr(sName), escapeAttr(sName), sExtraAttribs, escapeAttr(unicode(sValue)), sPostHtml ));
163
164 def addTextRO(self, sName, sValue, sLabel, sSubClass = 'string', sExtraAttribs = '', sPostHtml = ''):
165 """Adds a read-only text input."""
166 if sSubClass not in ('int', 'long', 'string', 'uuid', 'timestamp', 'wide'): raise Exception(sSubClass);
167 self._addLabel(sName, sLabel, sSubClass);
168 if sValue is None: sValue = '';
169 return self._add(u' <input name="%s" id="%s" type="text" readonly%s value="%s" class="tmform-input-readonly">'
170 u'%s\n'
171 u' </div></div>\n'
172 u' </li>\n'
173 % ( escapeAttr(sName), escapeAttr(sName), sExtraAttribs, escapeAttr(unicode(sValue)), sPostHtml ));
174
175 def addWideText(self, sName, sValue, sLabel, sExtraAttribs = '', sPostHtml = ''):
176 """Adds a wide text input."""
177 return self.addText(sName, sValue, sLabel, 'wide', sExtraAttribs, sPostHtml = sPostHtml);
178
179 def addWideTextRO(self, sName, sValue, sLabel, sExtraAttribs = '', sPostHtml = ''):
180 """Adds a wide read-only text input."""
181 return self.addTextRO(sName, sValue, sLabel, 'wide', sExtraAttribs, sPostHtml = sPostHtml);
182
183 def _adjustMultilineTextAttribs(self, sExtraAttribs, sValue):
184 """ Internal helper for setting good default sizes for textarea based on content."""
185 if sExtraAttribs.find('cols') < 0 and sExtraAttribs.find('width') < 0:
186 sExtraAttribs = 'cols="96%" ' + sExtraAttribs;
187
188 if sExtraAttribs.find('rows') < 0 and sExtraAttribs.find('width') < 0:
189 if sValue is None: sValue = '';
190 else: sValue = sValue.strip();
191
192 cRows = sValue.count('\n') + (not sValue.endswith('\n'));
193 if cRows * 80 < len(sValue):
194 cRows += 2;
195 cRows = max(min(cRows, 16), 2);
196 sExtraAttribs = ('rows="%s" ' % (cRows,)) + sExtraAttribs;
197
198 return sExtraAttribs;
199
200 def addMultilineText(self, sName, sValue, sLabel, sSubClass = 'string', sExtraAttribs = ''):
201 """Adds a multiline text input."""
202 if self._fReadOnly:
203 return self.addMultilineTextRO(sName, sValue, sLabel, sSubClass, sExtraAttribs);
204 if sSubClass not in ('int', 'long', 'string', 'uuid', 'timestamp'): raise Exception(sSubClass)
205 self._addLabel(sName, sLabel, sSubClass)
206 if sValue is None: sValue = '';
207 sNewValue = unicode(sValue) if not isinstance(sValue, list) else '\n'.join(sValue)
208 return self._add(u' <textarea name="%s" id="%s" %s>%s</textarea>\n'
209 u' </div></div>\n'
210 u' </li>\n'
211 % ( escapeAttr(sName), escapeAttr(sName), self._adjustMultilineTextAttribs(sExtraAttribs, sNewValue),
212 escapeElem(sNewValue)))
213
214 def addMultilineTextRO(self, sName, sValue, sLabel, sSubClass = 'string', sExtraAttribs = ''):
215 """Adds a multiline read-only text input."""
216 if sSubClass not in ('int', 'long', 'string', 'uuid', 'timestamp'): raise Exception(sSubClass)
217 self._addLabel(sName, sLabel, sSubClass)
218 if sValue is None: sValue = '';
219 sNewValue = unicode(sValue) if not isinstance(sValue, list) else '\n'.join(sValue)
220 return self._add(u' <textarea name="%s" id="%s" readonly %s>%s</textarea>\n'
221 u' </div></div>\n'
222 u' </li>\n'
223 % ( escapeAttr(sName), escapeAttr(sName), self._adjustMultilineTextAttribs(sExtraAttribs, sNewValue),
224 escapeElem(sNewValue)))
225
226 def addInt(self, sName, iValue, sLabel, sExtraAttribs = '', sPostHtml = ''):
227 """Adds an integer input."""
228 return self.addText(sName, unicode(iValue), sLabel, 'int', sExtraAttribs, sPostHtml = sPostHtml);
229
230 def addIntRO(self, sName, iValue, sLabel, sExtraAttribs = '', sPostHtml = ''):
231 """Adds an integer input."""
232 return self.addTextRO(sName, unicode(iValue), sLabel, 'int', sExtraAttribs, sPostHtml = sPostHtml);
233
234 def addLong(self, sName, lValue, sLabel, sExtraAttribs = '', sPostHtml = ''):
235 """Adds a long input."""
236 return self.addText(sName, unicode(lValue), sLabel, 'long', sExtraAttribs, sPostHtml = sPostHtml);
237
238 def addLongRO(self, sName, lValue, sLabel, sExtraAttribs = '', sPostHtml = ''):
239 """Adds a long input."""
240 return self.addTextRO(sName, unicode(lValue), sLabel, 'long', sExtraAttribs, sPostHtml = sPostHtml);
241
242 def addUuid(self, sName, uuidValue, sLabel, sExtraAttribs = '', sPostHtml = ''):
243 """Adds an UUID input."""
244 return self.addText(sName, unicode(uuidValue), sLabel, 'uuid', sExtraAttribs, sPostHtml = sPostHtml);
245
246 def addUuidRO(self, sName, uuidValue, sLabel, sExtraAttribs = '', sPostHtml = ''):
247 """Adds a read-only UUID input."""
248 return self.addTextRO(sName, unicode(uuidValue), sLabel, 'uuid', sExtraAttribs, sPostHtml = sPostHtml);
249
250 def addTimestampRO(self, sName, sTimestamp, sLabel, sExtraAttribs = '', sPostHtml = ''):
251 """Adds a read-only database string timstamp input."""
252 return self.addTextRO(sName, sTimestamp, sLabel, 'timestamp', sExtraAttribs, sPostHtml = sPostHtml);
253
254
255 #
256 # Text areas.
257 #
258
259
260 #
261 # Combo boxes.
262 #
263 def addComboBox(self, sName, sSelected, sLabel, aoOptions, sExtraAttribs = '', sPostHtml = ''):
264 """Adds a combo box."""
265 if self._fReadOnly:
266 return self.addComboBoxRO(sName, sSelected, sLabel, aoOptions, sExtraAttribs, sPostHtml);
267 self._addLabel(sName, sLabel, 'combobox');
268 self._add(' <select name="%s" id="%s" class="tmform-combobox"%s>\n'
269 % (escapeAttr(sName), escapeAttr(sName), sExtraAttribs));
270 sSelected = unicode(sSelected);
271 for iValue, sText, _ in aoOptions:
272 sValue = unicode(iValue);
273 self._add(' <option value="%s"%s>%s</option>\n'
274 % (escapeAttr(sValue), ' selected' if sValue == sSelected else '',
275 escapeElem(sText)));
276 return self._add(u' </select>' + sPostHtml + '\n'
277 u' </div></div>\n'
278 u' </li>\n');
279
280 def addComboBoxRO(self, sName, sSelected, sLabel, aoOptions, sExtraAttribs = '', sPostHtml = ''):
281 """Adds a read-only combo box."""
282 self.addTextHidden(sName, sSelected);
283 self._addLabel(sName, sLabel, 'combobox-readonly');
284 self._add(u' <select name="%s" id="%s" disabled class="tmform-combobox"%s>\n'
285 % (escapeAttr(sName), escapeAttr(sName), sExtraAttribs));
286 sSelected = unicode(sSelected);
287 for iValue, sText, _ in aoOptions:
288 sValue = unicode(iValue);
289 self._add(' <option value="%s"%s>%s</option>\n'
290 % (escapeAttr(sValue), ' selected' if sValue == sSelected else '',
291 escapeElem(sText)));
292 return self._add(u' </select>' + sPostHtml + '\n'
293 u' </div></div>\n'
294 u' </li>\n');
295
296 #
297 # Check boxes.
298 #
299 @staticmethod
300 def _reinterpretBool(fValue):
301 """Reinterprets a value as a boolean type."""
302 if fValue is not type(True):
303 if fValue is None:
304 fValue = False;
305 elif str(fValue) in ('True', 'true', '1'):
306 fValue = True;
307 else:
308 fValue = False;
309 return fValue;
310
311 def addCheckBox(self, sName, fChecked, sLabel, sExtraAttribs = ''):
312 """Adds an check box."""
313 if self._fReadOnly:
314 return self.addCheckBoxRO(sName, fChecked, sLabel, sExtraAttribs);
315 self._addLabel(sName, sLabel, 'checkbox');
316 fChecked = self._reinterpretBool(fChecked);
317 return self._add(u' <input name="%s" id="%s" type="checkbox"%s%s value="1" class="tmform-checkbox">\n'
318 u' </div></div>\n'
319 u' </li>\n'
320 % (escapeAttr(sName), escapeAttr(sName), ' checked' if fChecked else '', sExtraAttribs));
321
322 def addCheckBoxRO(self, sName, fChecked, sLabel, sExtraAttribs = ''):
323 """Adds an readonly check box."""
324 self._addLabel(sName, sLabel, 'checkbox');
325 fChecked = self._reinterpretBool(fChecked);
326 # Hack Alert! The onclick and onkeydown are for preventing editing and fake readonly/disabled.
327 return self._add(u' <input name="%s" id="%s" type="checkbox"%s readonly%s value="1" class="readonly"\n'
328 u' onclick="return false" onkeydown="return false">\n'
329 u' </div></div>\n'
330 u' </li>\n'
331 % (escapeAttr(sName), escapeAttr(sName), ' checked' if fChecked else '', sExtraAttribs));
332
333 #
334 # List of items to check
335 #
336 def _addList(self, sName, aoRows, sLabel, fUseTable = False, sId = 'dummy', sExtraAttribs = ''):
337 """
338 Adds a list of items to check.
339
340 @param sName Name of HTML form element
341 @param aoRows List of [sValue, fChecked, sName] sub-arrays.
342 @param sLabel Label of HTML form element
343 """
344 fReadOnly = self._fReadOnly; ## @todo add this as a parameter.
345 if fReadOnly:
346 sExtraAttribs += ' readonly onclick="return false" onkeydown="return false"';
347
348 self._addLabel(sName, sLabel, 'list');
349 if not aoRows:
350 return self._add('No items</div></div></li>')
351 sNameEscaped = escapeAttr(sName);
352
353 self._add(' <div class="tmform-checkboxes-container" id="%s">\n' % (escapeAttr(sId),));
354 if fUseTable:
355 self._add(' <table>\n');
356 for asRow in aoRows:
357 assert len(asRow) == 3; # Don't allow sloppy input data!
358 fChecked = self._reinterpretBool(asRow[1])
359 self._add(u' <tr>\n'
360 u' <td><input type="checkbox" name="%s" value="%s"%s%s></td>\n'
361 u' <td>%s</td>\n'
362 u' </tr>\n'
363 % ( sNameEscaped, escapeAttr(unicode(asRow[0])), ' checked' if fChecked else '', sExtraAttribs,
364 escapeElem(unicode(asRow[2])), ));
365 self._add(u' </table>\n');
366 else:
367 for asRow in aoRows:
368 assert len(asRow) == 3; # Don't allow sloppy input data!
369 fChecked = self._reinterpretBool(asRow[1])
370 self._add(u' <div class="tmform-checkbox-holder">'
371 u'<input type="checkbox" name="%s" value="%s"%s%s> %s</input></div>\n'
372 % ( sNameEscaped, escapeAttr(unicode(asRow[0])), ' checked' if fChecked else '', sExtraAttribs,
373 escapeElem(unicode(asRow[2])),));
374 return self._add(u' </div></div></div>\n'
375 u' </li>\n');
376
377
378 def addListOfOsArches(self, sName, aoOsArches, sLabel, sExtraAttribs = ''):
379 """
380 List of checkboxes for OS/ARCH selection.
381 asOsArches is a list of [sValue, fChecked, sName] sub-arrays.
382 """
383 return self._addList(sName, aoOsArches, sLabel, fUseTable = False, sId = 'tmform-checkbox-list-os-arches',
384 sExtraAttribs = sExtraAttribs);
385
386 def addListOfTypes(self, sName, aoTypes, sLabel, sExtraAttribs = ''):
387 """
388 List of checkboxes for build type selection.
389 aoTypes is a list of [sValue, fChecked, sName] sub-arrays.
390 """
391 return self._addList(sName, aoTypes, sLabel, fUseTable = False, sId = 'tmform-checkbox-list-build-types',
392 sExtraAttribs = sExtraAttribs);
393
394 def addListOfTestCases(self, sName, aoTestCases, sLabel, sExtraAttribs = ''):
395 """
396 List of checkboxes for test box (dependency) selection.
397 aoTestCases is a list of [sValue, fChecked, sName] sub-arrays.
398 """
399 return self._addList(sName, aoTestCases, sLabel, fUseTable = False, sId = 'tmform-checkbox-list-testcases',
400 sExtraAttribs = sExtraAttribs);
401
402 def addListOfResources(self, sName, aoTestCases, sLabel, sExtraAttribs = ''):
403 """
404 List of checkboxes for resource selection.
405 aoTestCases is a list of [sValue, fChecked, sName] sub-arrays.
406 """
407 return self._addList(sName, aoTestCases, sLabel, fUseTable = False, sId = 'tmform-checkbox-list-resources',
408 sExtraAttribs = sExtraAttribs);
409
410 def addListOfTestGroups(self, sName, aoTestGroups, sLabel, sExtraAttribs = ''):
411 """
412 List of checkboxes for test group selection.
413 aoTestGroups is a list of [sValue, fChecked, sName] sub-arrays.
414 """
415 return self._addList(sName, aoTestGroups, sLabel, fUseTable = False, sId = 'tmform-checkbox-list-testgroups',
416 sExtraAttribs = sExtraAttribs);
417
418 def addListOfTestCaseArgs(self, sName, aoVariations, sLabel): # pylint: disable=too-many-statements
419 """
420 Adds a list of test case argument variations to the form.
421
422 @param sName Name of HTML form element
423 @param aoVariations List of TestCaseArgsData instances.
424 @param sLabel Label of HTML form element
425 """
426 self._addLabel(sName, sLabel);
427
428 sTableId = u'TestArgsExtendingListRoot';
429 fReadOnly = self._fReadOnly; ## @todo argument?
430 sReadOnlyAttr = u' readonly class="tmform-input-readonly"' if fReadOnly else '';
431
432 sHtml = u'<li>\n'
433
434 #
435 # Define javascript function for extending the list of test case
436 # variations. Doing it here so we can use the python constants. This
437 # also permits multiple argument lists on one page should that ever be
438 # required...
439 #
440 if not fReadOnly:
441 sHtml += u'<script type="text/javascript">\n'
442 sHtml += u'\n';
443 sHtml += u'g_%s_aItems = { %s };\n' % (sName, ', '.join(('%s: 1' % (i,)) for i in range(len(aoVariations))),);
444 sHtml += u'g_%s_cItems = %s;\n' % (sName, len(aoVariations),);
445 sHtml += u'g_%s_iIdMod = %s;\n' % (sName, len(aoVariations) + 32);
446 sHtml += u'\n';
447 sHtml += u'function %s_removeEntry(sId)\n' % (sName,);
448 sHtml += u'{\n';
449 sHtml += u' if (g_%s_cItems > 1)\n' % (sName,);
450 sHtml += u' {\n';
451 sHtml += u' g_%s_cItems--;\n' % (sName,);
452 sHtml += u' delete g_%s_aItems[sId];\n' % (sName,);
453 sHtml += u' setElementValueToKeyList(\'%s\', g_%s_aItems);\n' % (sName, sName);
454 sHtml += u'\n';
455 for iInput in range(8):
456 sHtml += u' removeHtmlNode(\'%s[\' + sId + \'][%s]\');\n' % (sName, iInput,);
457 sHtml += u' }\n';
458 sHtml += u'}\n';
459 sHtml += u'\n';
460 sHtml += u'function %s_extendListEx(sSubName, cGangMembers, cSecTimeout, sArgs, sTestBoxReqExpr, sBuildReqExpr)\n' \
461 % (sName,);
462 sHtml += u'{\n';
463 sHtml += u' var oElement = document.getElementById(\'%s\');\n' % (sTableId,);
464 sHtml += u' var oTBody = document.createElement(\'tbody\');\n';
465 sHtml += u' var sHtml = \'\';\n';
466 sHtml += u' var sId;\n';
467 sHtml += u'\n';
468 sHtml += u' g_%s_iIdMod += 1;\n' % (sName,);
469 sHtml += u' sId = g_%s_iIdMod.toString();\n' % (sName,);
470
471 oVarDefaults = TestCaseArgsData();
472 oVarDefaults.convertToParamNull();
473 sHtml += u'\n';
474 sHtml += u' sHtml += \'<tr class="tmform-testcasevars-first-row">\';\n';
475 sHtml += u' sHtml += \' <td>Sub-Name:</td>\';\n';
476 sHtml += u' sHtml += \' <td class="tmform-field-subname">' \
477 '<input name="%s[\' + sId + \'][%s]" id="%s[\' + sId + \'][0]" value="\' + sSubName + \'"></td>\';\n' \
478 % (sName, TestCaseArgsData.ksParam_sSubName, sName,);
479 sHtml += u' sHtml += \' <td>Gang Members:</td>\';\n';
480 sHtml += u' sHtml += \' <td class="tmform-field-tiny-int">' \
481 '<input name="%s[\' + sId + \'][%s]" id="%s[\' + sId + \'][0]" value="\' + cGangMembers + \'"></td>\';\n' \
482 % (sName, TestCaseArgsData.ksParam_cGangMembers, sName,);
483 sHtml += u' sHtml += \' <td>Timeout:</td>\';\n';
484 sHtml += u' sHtml += \' <td class="tmform-field-int">' \
485 u'<input name="%s[\' + sId + \'][%s]" id="%s[\' + sId + \'][1]" value="\'+ cSecTimeout + \'"></td>\';\n' \
486 % (sName, TestCaseArgsData.ksParam_cSecTimeout, sName,);
487 sHtml += u' sHtml += \' <td><a href="#" onclick="%s_removeEntry(\\\'\' + sId + \'\\\');"> Remove</a></td>\';\n' \
488 % (sName, );
489 sHtml += u' sHtml += \' <td></td>\';\n';
490 sHtml += u' sHtml += \'</tr>\';\n'
491 sHtml += u'\n';
492 sHtml += u' sHtml += \'<tr class="tmform-testcasevars-inner-row">\';\n';
493 sHtml += u' sHtml += \' <td>Arguments:</td>\';\n';
494 sHtml += u' sHtml += \' <td class="tmform-field-wide100" colspan="6">' \
495 u'<input name="%s[\' + sId + \'][%s]" id="%s[\' + sId + \'][2]" value="\' + sArgs + \'"></td>\';\n' \
496 % (sName, TestCaseArgsData.ksParam_sArgs, sName,);
497 sHtml += u' sHtml += \' <td></td>\';\n';
498 sHtml += u' sHtml += \'</tr>\';\n'
499 sHtml += u'\n';
500 sHtml += u' sHtml += \'<tr class="tmform-testcasevars-inner-row">\';\n';
501 sHtml += u' sHtml += \' <td>TestBox Reqs:</td>\';\n';
502 sHtml += u' sHtml += \' <td class="tmform-field-wide100" colspan="6">' \
503 u'<input name="%s[\' + sId + \'][%s]" id="%s[\' + sId + \'][2]" value="\' + sTestBoxReqExpr' \
504 u' + \'"></td>\';\n' \
505 % (sName, TestCaseArgsData.ksParam_sTestBoxReqExpr, sName,);
506 sHtml += u' sHtml += \' <td></td>\';\n';
507 sHtml += u' sHtml += \'</tr>\';\n'
508 sHtml += u'\n';
509 sHtml += u' sHtml += \'<tr class="tmform-testcasevars-final-row">\';\n';
510 sHtml += u' sHtml += \' <td>Build Reqs:</td>\';\n';
511 sHtml += u' sHtml += \' <td class="tmform-field-wide100" colspan="6">' \
512 u'<input name="%s[\' + sId + \'][%s]" id="%s[\' + sId + \'][2]" value="\' + sBuildReqExpr + \'"></td>\';\n' \
513 % (sName, TestCaseArgsData.ksParam_sBuildReqExpr, sName,);
514 sHtml += u' sHtml += \' <td></td>\';\n';
515 sHtml += u' sHtml += \'</tr>\';\n'
516 sHtml += u'\n';
517 sHtml += u' oTBody.id = \'%s[\' + sId + \'][6]\';\n' % (sName,);
518 sHtml += u' oTBody.innerHTML = sHtml;\n';
519 sHtml += u'\n';
520 sHtml += u' oElement.appendChild(oTBody);\n';
521 sHtml += u'\n';
522 sHtml += u' g_%s_aItems[sId] = 1;\n' % (sName,);
523 sHtml += u' g_%s_cItems++;\n' % (sName,);
524 sHtml += u' setElementValueToKeyList(\'%s\', g_%s_aItems);\n' % (sName, sName);
525 sHtml += u'}\n';
526 sHtml += u'function %s_extendList()\n' % (sName,);
527 sHtml += u'{\n';
528 sHtml += u' %s_extendListEx("%s", "%s", "%s", "%s", "%s", "%s");\n' % (sName,
529 escapeAttr(unicode(oVarDefaults.sSubName)), escapeAttr(unicode(oVarDefaults.cGangMembers)),
530 escapeAttr(unicode(oVarDefaults.cSecTimeout)), escapeAttr(oVarDefaults.sArgs),
531 escapeAttr(oVarDefaults.sTestBoxReqExpr), escapeAttr(oVarDefaults.sBuildReqExpr), );
532 sHtml += u'}\n';
533 if config.g_kfVBoxSpecific:
534 sSecTimeoutDef = escapeAttr(unicode(oVarDefaults.cSecTimeout));
535 sHtml += u'function vbox_%s_add_uni()\n' % (sName,);
536 sHtml += u'{\n';
537 sHtml += u' %s_extendListEx("1-raw", "1", "%s", "--cpu-counts 1 --virt-modes raw", ' \
538 u' "", "");\n' % (sName, sSecTimeoutDef);
539 sHtml += u' %s_extendListEx("1-hw", "1", "%s", "--cpu-counts 1 --virt-modes hwvirt", ' \
540 u' "fCpuHwVirt is True", "");\n' % (sName, sSecTimeoutDef);
541 sHtml += u' %s_extendListEx("1-np", "1", "%s", "--cpu-counts 1 --virt-modes hwvirt-np", ' \
542 u' "fCpuNestedPaging is True", "");\n' % (sName, sSecTimeoutDef);
543 sHtml += u'}\n';
544 sHtml += u'function vbox_%s_add_uni_amd64()\n' % (sName,);
545 sHtml += u'{\n';
546 sHtml += u' %s_extendListEx("1-hw", "1", "%s", "--cpu-counts 1 --virt-modes hwvirt", ' \
547 u' "fCpuHwVirt is True", "");\n' % (sName, sSecTimeoutDef);
548 sHtml += u' %s_extendListEx("1-np", "%s", "--cpu-counts 1 --virt-modes hwvirt-np", ' \
549 u' "fCpuNestedPaging is True", "");\n' % (sName, sSecTimeoutDef);
550 sHtml += u'}\n';
551 sHtml += u'function vbox_%s_add_smp()\n' % (sName,);
552 sHtml += u'{\n';
553 sHtml += u' %s_extendListEx("2-hw", "1", "%s", "--cpu-counts 2 --virt-modes hwvirt",' \
554 u' "fCpuHwVirt is True and cCpus >= 2", "");\n' % (sName, sSecTimeoutDef);
555 sHtml += u' %s_extendListEx("2-np", "1", "%s", "--cpu-counts 2 --virt-modes hwvirt-np",' \
556 u' "fCpuNestedPaging is True and cCpus >= 2", "");\n' % (sName, sSecTimeoutDef);
557 sHtml += u' %s_extendListEx("3-hw", "1", "%s", "--cpu-counts 3 --virt-modes hwvirt",' \
558 u' "fCpuHwVirt is True and cCpus >= 3", "");\n' % (sName, sSecTimeoutDef);
559 sHtml += u' %s_extendListEx("4-np", "1", "%s", "--cpu-counts 4 --virt-modes hwvirt-np ",' \
560 u' "fCpuNestedPaging is True and cCpus >= 4", "");\n' % (sName, sSecTimeoutDef);
561 #sHtml += u' %s_extendListEx("6-hw", "1", "%s", "--cpu-counts 6 --virt-modes hwvirt",' \
562 # u' "fCpuHwVirt is True and cCpus >= 6", "");\n' % (sName, sSecTimeoutDef);
563 #sHtml += u' %s_extendListEx("8-np", "1", "%s", "--cpu-counts 8 --virt-modes hwvirt-np",' \
564 # u' "fCpuNestedPaging is True and cCpus >= 8", "");\n' % (sName, sSecTimeoutDef);
565 sHtml += u'}\n';
566 sHtml += u'</script>\n';
567
568
569 #
570 # List current entries.
571 #
572 sHtml += u'<input type="hidden" name="%s" id="%s" value="%s">\n' \
573 % (sName, sName, ','.join(unicode(i) for i in range(len(aoVariations))), );
574 sHtml += u' <table id="%s" class="tmform-testcasevars">\n' % (sTableId,)
575 if not fReadOnly:
576 sHtml += u' <caption>\n' \
577 u' <a href="#" onClick="%s_extendList()">Add</a>\n' % (sName,);
578 if config.g_kfVBoxSpecific:
579 sHtml += u' [<a href="#" onClick="vbox_%s_add_uni()">Single CPU Variations</a>\n' % (sName,);
580 sHtml += u' <a href="#" onClick="vbox_%s_add_uni_amd64()">amd64</a>]\n' % (sName,);
581 sHtml += u' [<a href="#" onClick="vbox_%s_add_smp()">SMP Variations</a>]\n' % (sName,);
582 sHtml += u' </caption>\n';
583
584 dSubErrors = {};
585 if sName in self._dErrors and isinstance(self._dErrors[sName], dict):
586 dSubErrors = self._dErrors[sName];
587
588 for iVar, _ in enumerate(aoVariations):
589 oVar = copy.copy(aoVariations[iVar]);
590 oVar.convertToParamNull();
591
592 sHtml += u'<tbody id="%s[%s][6]">\n' % (sName, iVar,)
593 sHtml += u' <tr class="tmform-testcasevars-first-row">\n' \
594 u' <td>Sub-name:</td>' \
595 u' <td class="tmform-field-subname"><input name="%s[%s][%s]" id="%s[%s][1]" value="%s"%s></td>\n' \
596 u' <td>Gang Members:</td>' \
597 u' <td class="tmform-field-tiny-int"><input name="%s[%s][%s]" id="%s[%s][1]" value="%s"%s></td>\n' \
598 u' <td>Timeout:</td>' \
599 u' <td class="tmform-field-int"><input name="%s[%s][%s]" id="%s[%s][2]" value="%s"%s></td>\n' \
600 % ( sName, iVar, TestCaseArgsData.ksParam_sSubName, sName, iVar, oVar.sSubName, sReadOnlyAttr,
601 sName, iVar, TestCaseArgsData.ksParam_cGangMembers, sName, iVar, oVar.cGangMembers, sReadOnlyAttr,
602 sName, iVar, TestCaseArgsData.ksParam_cSecTimeout, sName, iVar,
603 utils.formatIntervalSeconds2(oVar.cSecTimeout), sReadOnlyAttr, );
604 if not fReadOnly:
605 sHtml += u' <td><a href="#" onclick="%s_removeEntry(\'%s\');">Remove</a></td>\n' \
606 % (sName, iVar);
607 else:
608 sHtml += u' <td></td>\n';
609 sHtml += u' <td class="tmform-testcasevars-stupid-border-column"></td>\n' \
610 u' </tr>\n';
611
612 sHtml += u' <tr class="tmform-testcasevars-inner-row">\n' \
613 u' <td>Arguments:</td>' \
614 u' <td class="tmform-field-wide100" colspan="6">' \
615 u'<input name="%s[%s][%s]" id="%s[%s][3]" value="%s"%s></td>\n' \
616 u' <td></td>\n' \
617 u' </tr>\n' \
618 % ( sName, iVar, TestCaseArgsData.ksParam_sArgs, sName, iVar, escapeAttr(oVar.sArgs), sReadOnlyAttr)
619
620 sHtml += u' <tr class="tmform-testcasevars-inner-row">\n' \
621 u' <td>TestBox Reqs:</td>' \
622 u' <td class="tmform-field-wide100" colspan="6">' \
623 u'<input name="%s[%s][%s]" id="%s[%s][4]" value="%s"%s></td>\n' \
624 u' <td></td>\n' \
625 u' </tr>\n' \
626 % ( sName, iVar, TestCaseArgsData.ksParam_sTestBoxReqExpr, sName, iVar,
627 escapeAttr(oVar.sTestBoxReqExpr), sReadOnlyAttr)
628
629 sHtml += u' <tr class="tmform-testcasevars-final-row">\n' \
630 u' <td>Build Reqs:</td>' \
631 u' <td class="tmform-field-wide100" colspan="6">' \
632 u'<input name="%s[%s][%s]" id="%s[%s][5]" value="%s"%s></td>\n' \
633 u' <td></td>\n' \
634 u' </tr>\n' \
635 % ( sName, iVar, TestCaseArgsData.ksParam_sBuildReqExpr, sName, iVar,
636 escapeAttr(oVar.sBuildReqExpr), sReadOnlyAttr)
637
638
639 if iVar in dSubErrors:
640 sHtml += u' <tr><td colspan="4"><p align="left" class="tmform-error-desc">%s</p></td></tr>\n' \
641 % (self._escapeErrorText(dSubErrors[iVar]),);
642
643 sHtml += u'</tbody>\n';
644 sHtml += u' </table>\n'
645 sHtml += u'</li>\n'
646
647 return self._add(sHtml)
648
649 def addListOfTestGroupMembers(self, sName, aoTestGroupMembers, aoAllTestCases, sLabel, # pylint: disable=too-many-locals
650 fReadOnly = True):
651 """
652 For WuiTestGroup.
653 """
654 assert len(aoTestGroupMembers) <= len(aoAllTestCases);
655 self._addLabel(sName, sLabel);
656 if not aoAllTestCases:
657 return self._add('<li>No testcases.</li>\n')
658
659 self._add(u'<input name="%s" type="hidden" value="%s">\n'
660 % ( TestGroupDataEx.ksParam_aidTestCases,
661 ','.join([unicode(oTestCase.idTestCase) for oTestCase in aoAllTestCases]), ));
662
663 self._add(u'<table class="tmformtbl">\n'
664 u' <thead>\n'
665 u' <tr>\n'
666 u' <th rowspan="2"></th>\n'
667 u' <th rowspan="2">Test Case</th>\n'
668 u' <th rowspan="2">All Vars</th>\n'
669 u' <th rowspan="2">Priority [0..31]</th>\n'
670 u' <th colspan="4" align="center">Variations</th>\n'
671 u' </tr>\n'
672 u' <tr>\n'
673 u' <th>Included</th>\n'
674 u' <th>Gang size</th>\n'
675 u' <th>Timeout</th>\n'
676 u' <th>Arguments</th>\n'
677 u' </tr>\n'
678 u' </thead>\n'
679 u' <tbody>\n'
680 );
681
682 if self._fReadOnly:
683 fReadOnly = True;
684 sCheckBoxAttr = ' readonly onclick="return false" onkeydown="return false"' if fReadOnly else '';
685
686 oDefMember = TestGroupMemberData();
687 aoTestGroupMembers = list(aoTestGroupMembers); # Copy it so we can pop.
688 for iTestCase, _ in enumerate(aoAllTestCases):
689 oTestCase = aoAllTestCases[iTestCase];
690
691 # Is it a member?
692 oMember = None;
693 for i, _ in enumerate(aoTestGroupMembers):
694 if aoTestGroupMembers[i].oTestCase.idTestCase == oTestCase.idTestCase:
695 oMember = aoTestGroupMembers.pop(i);
696 break;
697
698 # Start on the rows...
699 sPrefix = u'%s[%d]' % (sName, oTestCase.idTestCase,);
700 self._add(u' <tr class="%s">\n'
701 u' <td rowspan="%d">\n'
702 u' <input name="%s[%s]" type="hidden" value="%s">\n' # idTestCase
703 u' <input name="%s[%s]" type="hidden" value="%s">\n' # idTestGroup
704 u' <input name="%s[%s]" type="hidden" value="%s">\n' # tsExpire
705 u' <input name="%s[%s]" type="hidden" value="%s">\n' # tsEffective
706 u' <input name="%s[%s]" type="hidden" value="%s">\n' # uidAuthor
707 u' <input name="%s" type="checkbox"%s%s value="%d" class="tmform-checkbox" title="#%d - %s">\n' #(list)
708 u' </td>\n'
709 % ( 'tmodd' if iTestCase & 1 else 'tmeven',
710 len(oTestCase.aoTestCaseArgs),
711 sPrefix, TestGroupMemberData.ksParam_idTestCase, oTestCase.idTestCase,
712 sPrefix, TestGroupMemberData.ksParam_idTestGroup, -1 if oMember is None else oMember.idTestGroup,
713 sPrefix, TestGroupMemberData.ksParam_tsExpire, '' if oMember is None else oMember.tsExpire,
714 sPrefix, TestGroupMemberData.ksParam_tsEffective, '' if oMember is None else oMember.tsEffective,
715 sPrefix, TestGroupMemberData.ksParam_uidAuthor, '' if oMember is None else oMember.uidAuthor,
716 TestGroupDataEx.ksParam_aoMembers, '' if oMember is None else ' checked', sCheckBoxAttr,
717 oTestCase.idTestCase, oTestCase.idTestCase, escapeElem(oTestCase.sName),
718 ));
719 self._add(u' <td rowspan="%d" align="left">%s</td>\n'
720 % ( len(oTestCase.aoTestCaseArgs), escapeElem(oTestCase.sName), ));
721
722 self._add(u' <td rowspan="%d" title="Include all variations (checked) or choose a set?">\n'
723 u' <input name="%s[%s]" type="checkbox"%s%s value="-1">\n'
724 u' </td>\n'
725 % ( len(oTestCase.aoTestCaseArgs),
726 sPrefix, TestGroupMemberData.ksParam_aidTestCaseArgs,
727 ' checked' if oMember is None or oMember.aidTestCaseArgs is None else '', sCheckBoxAttr, ));
728
729 self._add(u' <td rowspan="%d" align="center">\n'
730 u' <input name="%s[%s]" type="text" value="%s" style="max-width:3em;" %s>\n'
731 u' </td>\n'
732 % ( len(oTestCase.aoTestCaseArgs),
733 sPrefix, TestGroupMemberData.ksParam_iSchedPriority,
734 (oMember if oMember is not None else oDefMember).iSchedPriority,
735 ' readonly class="tmform-input-readonly"' if fReadOnly else '', ));
736
737 # Argument variations.
738 aidTestCaseArgs = [] if oMember is None or oMember.aidTestCaseArgs is None else oMember.aidTestCaseArgs;
739 for iVar in range(len(oTestCase.aoTestCaseArgs)):
740 oVar = oTestCase.aoTestCaseArgs[iVar];
741 if iVar > 0:
742 self._add(' <tr class="%s">\n' % ('tmodd' if iTestCase & 1 else 'tmeven',));
743 self._add(u' <td align="center">\n'
744 u' <input name="%s[%s]" type="checkbox"%s%s value="%d">'
745 u' </td>\n'
746 % ( sPrefix, TestGroupMemberData.ksParam_aidTestCaseArgs,
747 ' checked' if oVar.idTestCaseArgs in aidTestCaseArgs else '', sCheckBoxAttr, oVar.idTestCaseArgs,
748 ));
749 self._add(u' <td align="center">%s</td>\n'
750 u' <td align="center">%s</td>\n'
751 u' <td align="left">%s</td>\n'
752 % ( oVar.cGangMembers,
753 'Default' if oVar.cSecTimeout is None else oVar.cSecTimeout,
754 escapeElem(oVar.sArgs) ));
755
756 self._add(u' </tr>\n');
757
758
759
760 if not oTestCase.aoTestCaseArgs:
761 self._add(u' <td></td> <td></td> <td></td> <td></td>\n'
762 u' </tr>\n');
763 return self._add(u' </tbody>\n'
764 u'</table>\n');
765
766 def addListOfSchedGroupMembers(self, sName, aoSchedGroupMembers, aoAllRelevantTestGroups, # pylint: disable=too-many-locals
767 sLabel, fReadOnly = True):
768 """
769 For WuiAdminSchedGroup.
770 """
771 if fReadOnly is None or self._fReadOnly:
772 fReadOnly = self._fReadOnly;
773 assert len(aoSchedGroupMembers) <= len(aoAllRelevantTestGroups);
774 self._addLabel(sName, sLabel);
775 if not aoAllRelevantTestGroups:
776 return self._add(u'<li>No test groups.</li>\n')
777
778 self._add(u'<input name="%s" type="hidden" value="%s">\n'
779 % ( SchedGroupDataEx.ksParam_aidTestGroups,
780 ','.join([unicode(oTestGroup.idTestGroup) for oTestGroup in aoAllRelevantTestGroups]), ));
781
782 self._add(u'<table class="tmformtbl">\n'
783 u' <thead>\n'
784 u' <tr>\n'
785 u' <th></th>\n'
786 u' <th>Test Group</th>\n'
787 u' <th>Priority [0..31]</th>\n'
788 u' <th>Prerequisite Test Group</th>\n'
789 u' <th>Weekly schedule</th>\n'
790 u' </tr>\n'
791 u' </thead>\n'
792 u' <tbody>\n'
793 );
794
795 sCheckBoxAttr = u' readonly onclick="return false" onkeydown="return false"' if fReadOnly else '';
796 sComboBoxAttr = u' disabled' if fReadOnly else '';
797
798 oDefMember = SchedGroupMemberData();
799 aoSchedGroupMembers = list(aoSchedGroupMembers); # Copy it so we can pop.
800 for iTestGroup, _ in enumerate(aoAllRelevantTestGroups):
801 oTestGroup = aoAllRelevantTestGroups[iTestGroup];
802
803 # Is it a member?
804 oMember = None;
805 for i, _ in enumerate(aoSchedGroupMembers):
806 if aoSchedGroupMembers[i].oTestGroup.idTestGroup == oTestGroup.idTestGroup:
807 oMember = aoSchedGroupMembers.pop(i);
808 break;
809
810 # Start on the rows...
811 sPrefix = u'%s[%d]' % (sName, oTestGroup.idTestGroup,);
812 self._add(u' <tr class="%s">\n'
813 u' <td>\n'
814 u' <input name="%s[%s]" type="hidden" value="%s">\n' # idTestGroup
815 u' <input name="%s[%s]" type="hidden" value="%s">\n' # idSchedGroup
816 u' <input name="%s[%s]" type="hidden" value="%s">\n' # tsExpire
817 u' <input name="%s[%s]" type="hidden" value="%s">\n' # tsEffective
818 u' <input name="%s[%s]" type="hidden" value="%s">\n' # uidAuthor
819 u' <input name="%s" type="checkbox"%s%s value="%d" class="tmform-checkbox" title="#%d - %s">\n' #(list)
820 u' </td>\n'
821 % ( 'tmodd' if iTestGroup & 1 else 'tmeven',
822 sPrefix, SchedGroupMemberData.ksParam_idTestGroup, oTestGroup.idTestGroup,
823 sPrefix, SchedGroupMemberData.ksParam_idSchedGroup, -1 if oMember is None else oMember.idSchedGroup,
824 sPrefix, SchedGroupMemberData.ksParam_tsExpire, '' if oMember is None else oMember.tsExpire,
825 sPrefix, SchedGroupMemberData.ksParam_tsEffective, '' if oMember is None else oMember.tsEffective,
826 sPrefix, SchedGroupMemberData.ksParam_uidAuthor, '' if oMember is None else oMember.uidAuthor,
827 SchedGroupDataEx.ksParam_aoMembers, '' if oMember is None else ' checked', sCheckBoxAttr,
828 oTestGroup.idTestGroup, oTestGroup.idTestGroup, escapeElem(oTestGroup.sName),
829 ));
830 self._add(u' <td align="left">%s</td>\n' % ( escapeElem(oTestGroup.sName), ));
831
832 self._add(u' <td align="center">\n'
833 u' <input name="%s[%s]" type="text" value="%s" style="max-width:3em;" %s>\n'
834 u' </td>\n'
835 % ( sPrefix, SchedGroupMemberData.ksParam_iSchedPriority,
836 (oMember if oMember is not None else oDefMember).iSchedPriority,
837 ' readonly class="tmform-input-readonly"' if fReadOnly else '', ));
838
839 self._add(u' <td align="center">\n'
840 u' <select name="%s[%s]" id="%s[%s]" class="tmform-combobox"%s>\n'
841 u' <option value="-1"%s>None</option>\n'
842 % ( sPrefix, SchedGroupMemberData.ksParam_idTestGroupPreReq,
843 sPrefix, SchedGroupMemberData.ksParam_idTestGroupPreReq,
844 sComboBoxAttr,
845 ' selected' if oMember is None or oMember.idTestGroupPreReq is None else '',
846 ));
847 for oTestGroup2 in aoAllRelevantTestGroups:
848 if oTestGroup2 != oTestGroup:
849 fSelected = oMember is not None and oTestGroup2.idTestGroup == oMember.idTestGroupPreReq;
850 self._add(' <option value="%s"%s>%s</option>\n'
851 % ( oTestGroup2.idTestGroup, ' selected' if fSelected else '', escapeElem(oTestGroup2.sName), ));
852 self._add(u' </select>\n'
853 u' </td>\n');
854
855 self._add(u' <td align="left">\n'
856 u' Todo<input name="%s[%s]" type="hidden" value="%s">\n'
857 u' </td>\n'
858 % ( sPrefix, SchedGroupMemberData.ksParam_bmHourlySchedule,
859 '' if oMember is None else oMember.bmHourlySchedule, ));
860
861 self._add(u' </tr>\n');
862 return self._add(u' </tbody>\n'
863 u'</table>\n');
864
865 def addListOfSchedGroupBoxes(self, sName, aoSchedGroupBoxes, aoAllRelevantTestBoxes, # pylint: disable=too-many-locals
866 sLabel, fReadOnly = True): # (str, list[TestBoxDataEx], list[TestBoxDataEx], str, bool) -> str
867 """
868 For WuiAdminSchedGroup.
869 """
870 if fReadOnly is None or self._fReadOnly:
871 fReadOnly = self._fReadOnly;
872 assert len(aoSchedGroupBoxes) <= len(aoAllRelevantTestBoxes);
873 self._addLabel(sName, sLabel);
874 if not aoAllRelevantTestBoxes:
875 return self._add(u'<li>No test boxes.</li>\n')
876
877 self._add(u'<input name="%s" type="hidden" value="%s">\n'
878 % ( SchedGroupDataEx.ksParam_aidTestBoxes,
879 ','.join([unicode(oTestBox.idTestBox) for oTestBox in aoAllRelevantTestBoxes]), ));
880
881 ## @todo replace with tmform-field-list tricks.
882 self._add(u'<table class="tmformtbl">\n'
883 u' <thead>\n'
884 u' <tr>\n'
885 u' <th></th>\n'
886 u' <th>Test Box</th>\n'
887 u' <th>Priority [0..31]</th>\n'
888 u' </tr>\n'
889 u' </thead>\n'
890 u' <tbody>\n'
891 );
892
893 sCheckBoxAttr = u' readonly onclick="return false" onkeydown="return false"' if fReadOnly else '';
894
895 oDefMember = TestBoxDataForSchedGroup();
896 aoSchedGroupBoxes = list(aoSchedGroupBoxes); # Copy it so we can pop.
897 for iTestBox, _ in enumerate(aoAllRelevantTestBoxes):
898 oTestBox = aoAllRelevantTestBoxes[iTestBox];
899
900 # Is it a member?
901 oMember = None;
902 for i, _ in enumerate(aoSchedGroupBoxes):
903 if aoSchedGroupBoxes[i].oTestBox and aoSchedGroupBoxes[i].oTestBox.idTestBox == oTestBox.idTestBox:
904 oMember = aoSchedGroupBoxes.pop(i);
905 break;
906
907 # Start on the rows...
908 sPrefix = u'%s[%d]' % (sName, oTestBox.idTestBox,);
909 self._add(u' <tr class="%s">\n'
910 u' <td>\n'
911 u' <input name="%s[%s]" type="hidden" value="%s">\n' # idTestBox
912 u' <input name="%s[%s]" type="hidden" value="%s">\n' # idSchedGroup
913 u' <input name="%s[%s]" type="hidden" value="%s">\n' # tsExpire
914 u' <input name="%s[%s]" type="hidden" value="%s">\n' # tsEffective
915 u' <input name="%s[%s]" type="hidden" value="%s">\n' # uidAuthor
916 u' <input name="%s" type="checkbox"%s%s value="%d" class="tmform-checkbox" title="#%d - %s">\n' #(list)
917 u' </td>\n'
918 % ( 'tmodd' if iTestBox & 1 else 'tmeven',
919 sPrefix, TestBoxDataForSchedGroup.ksParam_idTestBox, oTestBox.idTestBox,
920 sPrefix, TestBoxDataForSchedGroup.ksParam_idSchedGroup, -1 if oMember is None else oMember.idSchedGroup,
921 sPrefix, TestBoxDataForSchedGroup.ksParam_tsExpire, '' if oMember is None else oMember.tsExpire,
922 sPrefix, TestBoxDataForSchedGroup.ksParam_tsEffective, '' if oMember is None else oMember.tsEffective,
923 sPrefix, TestBoxDataForSchedGroup.ksParam_uidAuthor, '' if oMember is None else oMember.uidAuthor,
924 SchedGroupDataEx.ksParam_aoTestBoxes, '' if oMember is None else ' checked', sCheckBoxAttr,
925 oTestBox.idTestBox, oTestBox.idTestBox, escapeElem(oTestBox.sName),
926 ));
927 self._add(u' <td align="left">%s</td>\n' % ( escapeElem(oTestBox.sName), ));
928
929 self._add(u' <td align="center">\n'
930 u' <input name="%s[%s]" type="text" value="%s" style="max-width:3em;" %s>\n'
931 u' </td>\n'
932 % ( sPrefix,
933 TestBoxDataForSchedGroup.ksParam_iSchedPriority,
934 (oMember if oMember is not None else oDefMember).iSchedPriority,
935 ' readonly class="tmform-input-readonly"' if fReadOnly else '', ));
936
937 self._add(u' </tr>\n');
938 return self._add(u' </tbody>\n'
939 u'</table>\n');
940
941 def addListOfSchedGroupsForTestBox(self, sName, aoInSchedGroups, aoAllSchedGroups, sLabel, # pylint: disable=too-many-locals
942 fReadOnly = None):
943 # type: (str, TestBoxInSchedGroupDataEx, SchedGroupData, str, bool) -> str
944 """
945 For WuiTestGroup.
946 """
947 from testmanager.core.testbox import TestBoxInSchedGroupData, TestBoxDataEx;
948
949 if fReadOnly is None or self._fReadOnly:
950 fReadOnly = self._fReadOnly;
951 assert len(aoInSchedGroups) <= len(aoAllSchedGroups);
952
953 # Only show selected groups in read-only mode.
954 if fReadOnly:
955 aoAllSchedGroups = [oCur.oSchedGroup for oCur in aoInSchedGroups]
956
957 self._addLabel(sName, sLabel);
958 if not aoAllSchedGroups:
959 return self._add('<li>No scheduling groups.</li>\n')
960
961 # Add special parameter with all the scheduling group IDs in the form.
962 self._add(u'<input name="%s" type="hidden" value="%s">\n'
963 % ( TestBoxDataEx.ksParam_aidSchedGroups,
964 ','.join([unicode(oSchedGroup.idSchedGroup) for oSchedGroup in aoAllSchedGroups]), ));
965
966 # Table header.
967 self._add(u'<table class="tmformtbl">\n'
968 u' <thead>\n'
969 u' <tr>\n'
970 u' <th rowspan="2"></th>\n'
971 u' <th rowspan="2">Schedulding Group</th>\n'
972 u' <th rowspan="2">Priority [0..31]</th>\n'
973 u' </tr>\n'
974 u' </thead>\n'
975 u' <tbody>\n'
976 );
977
978 # Table body.
979 if self._fReadOnly:
980 fReadOnly = True;
981 sCheckBoxAttr = ' readonly onclick="return false" onkeydown="return false"' if fReadOnly else '';
982
983 oDefMember = TestBoxInSchedGroupData();
984 aoInSchedGroups = list(aoInSchedGroups); # Copy it so we can pop.
985 for iSchedGroup, oSchedGroup in enumerate(aoAllSchedGroups):
986
987 # Is it a member?
988 oMember = None;
989 for i, _ in enumerate(aoInSchedGroups):
990 if aoInSchedGroups[i].idSchedGroup == oSchedGroup.idSchedGroup:
991 oMember = aoInSchedGroups.pop(i);
992 break;
993
994 # Start on the rows...
995 sPrefix = u'%s[%d]' % (sName, oSchedGroup.idSchedGroup,);
996 self._add(u' <tr class="%s">\n'
997 u' <td>\n'
998 u' <input name="%s[%s]" type="hidden" value="%s">\n' # idSchedGroup
999 u' <input name="%s[%s]" type="hidden" value="%s">\n' # idTestBox
1000 u' <input name="%s[%s]" type="hidden" value="%s">\n' # tsExpire
1001 u' <input name="%s[%s]" type="hidden" value="%s">\n' # tsEffective
1002 u' <input name="%s[%s]" type="hidden" value="%s">\n' # uidAuthor
1003 u' <input name="%s" type="checkbox"%s%s value="%d" class="tmform-checkbox" title="#%d - %s">\n' #(list)
1004 u' </td>\n'
1005 % ( 'tmodd' if iSchedGroup & 1 else 'tmeven',
1006 sPrefix, TestBoxInSchedGroupData.ksParam_idSchedGroup, oSchedGroup.idSchedGroup,
1007 sPrefix, TestBoxInSchedGroupData.ksParam_idTestBox, -1 if oMember is None else oMember.idTestBox,
1008 sPrefix, TestBoxInSchedGroupData.ksParam_tsExpire, '' if oMember is None else oMember.tsExpire,
1009 sPrefix, TestBoxInSchedGroupData.ksParam_tsEffective, '' if oMember is None else oMember.tsEffective,
1010 sPrefix, TestBoxInSchedGroupData.ksParam_uidAuthor, '' if oMember is None else oMember.uidAuthor,
1011 TestBoxDataEx.ksParam_aoInSchedGroups, '' if oMember is None else ' checked', sCheckBoxAttr,
1012 oSchedGroup.idSchedGroup, oSchedGroup.idSchedGroup, escapeElem(oSchedGroup.sName),
1013 ));
1014 self._add(u' <td align="left">%s</td>\n' % ( escapeElem(oSchedGroup.sName), ));
1015
1016 self._add(u' <td align="center">\n'
1017 u' <input name="%s[%s]" type="text" value="%s" style="max-width:3em;" %s>\n'
1018 u' </td>\n'
1019 % ( sPrefix, TestBoxInSchedGroupData.ksParam_iSchedPriority,
1020 (oMember if oMember is not None else oDefMember).iSchedPriority,
1021 ' readonly class="tmform-input-readonly"' if fReadOnly else '', ));
1022 self._add(u' </tr>\n');
1023
1024 return self._add(u' </tbody>\n'
1025 u'</table>\n');
1026
1027
1028 #
1029 # Buttons.
1030 #
1031 def addSubmit(self, sLabel = 'Submit'):
1032 """Adds the submit button to the form."""
1033 if self._fReadOnly:
1034 return True;
1035 return self._add(u' <li>\n'
1036 u' <br>\n'
1037 u' <div class="tmform-field"><div class="tmform-field-submit">\n'
1038 u' <label>&nbsp;</label>\n'
1039 u' <input type="submit" value="%s">\n'
1040 u' </div></div>\n'
1041 u' </li>\n'
1042 % (escapeElem(sLabel),));
1043
1044 def addReset(self):
1045 """Adds a reset button to the form."""
1046 if self._fReadOnly:
1047 return True;
1048 return self._add(u' <li>\n'
1049 u' <div class="tmform-button"><div class="tmform-button-reset">\n'
1050 u' <input type="reset" value="%s">\n'
1051 u' </div></div>\n'
1052 u' </li>\n');
1053
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette