儲存庫 vbox 的更動 65350
- 時間撮記:
- 2017-1-17 下午03:35:59 (8 年 以前)
- 位置:
- trunk/src/VBox/ValidationKit/testmanager
- 檔案:
-
- 修改 18 筆資料
圖例:
- 未更動
- 新增
- 刪除
-
trunk/src/VBox/ValidationKit/testmanager/core/testbox.py
r65228 r65350 671 671 """ 672 672 673 kiSortColumn_sName = 0;674 kiSortColumn_sOs = 1;675 kiSortColumn_sOsVersion = 2;676 kiSortColumn_sCpuVendor = 3;677 kiSortColumn_sCpuArch = 4;678 kiSortColumn_lCpuRevision = 5;679 kiSortColumn_cCpus = 6;680 kiSortColumn_cMbMemory = 7;681 kiSortColumn_cMbScratch = 8;682 kiSortColumn_fCpuNestedPaging = 9;683 kiSortColumn_iTestBoxScriptRev = 1 0;684 kiSortColumn_iPythonHexVersion = 1 1;685 kcMaxSortColumns = 1 2;673 kiSortColumn_sName = 1; 674 kiSortColumn_sOs = 2; 675 kiSortColumn_sOsVersion = 3; 676 kiSortColumn_sCpuVendor = 4; 677 kiSortColumn_sCpuArch = 5; 678 kiSortColumn_lCpuRevision = 6; 679 kiSortColumn_cCpus = 7; 680 kiSortColumn_cMbMemory = 8; 681 kiSortColumn_cMbScratch = 9; 682 kiSortColumn_fCpuNestedPaging = 10; 683 kiSortColumn_iTestBoxScriptRev = 11; 684 kiSortColumn_iPythonHexVersion = 12; 685 kcMaxSortColumns = 13; 686 686 kdSortColumnMap = { 687 kiSortColumn_sName: 'TestBoxesWithStrings.sName', 688 kiSortColumn_sOs: 'TestBoxesWithStrings.sOs', 689 kiSortColumn_sOsVersion: 'TestBoxesWithStrings.sOsVersion', 690 kiSortColumn_sCpuVendor: 'TestBoxesWithStrings.sCpuVendor', 691 kiSortColumn_sCpuArch: 'TestBoxesWithStrings.sCpuArch', 692 kiSortColumn_lCpuRevision: 'TestBoxesWithStrings.lCpuRevision', 693 kiSortColumn_cCpus: 'TestBoxesWithStrings.cCpus', 694 kiSortColumn_cMbMemory: 'TestBoxesWithStrings.cMbMemory', 695 kiSortColumn_cMbScratch: 'TestBoxesWithStrings.cMbScratch', 696 kiSortColumn_fCpuNestedPaging: 'TestBoxesWithStrings.fCpuNestedPaging', 697 kiSortColumn_iTestBoxScriptRev: 'TestBoxesWithStrings.iTestBoxScriptRev', 698 kiSortColumn_iPythonHexVersion: 'TestBoxesWithStrings.iPythonHexVersion', 687 0: 'TestBoxesWithStrings.sName', 688 kiSortColumn_sName: 'TestBoxesWithStrings.sName', 689 -kiSortColumn_sName: 'TestBoxesWithStrings.sName DESC', 690 kiSortColumn_sOs: 'TestBoxesWithStrings.sOs', 691 -kiSortColumn_sOs: 'TestBoxesWithStrings.sOs DESC', 692 kiSortColumn_sOsVersion: 'TestBoxesWithStrings.sOsVersion', 693 -kiSortColumn_sOsVersion: 'TestBoxesWithStrings.sOsVersion DESC', 694 kiSortColumn_sCpuVendor: 'TestBoxesWithStrings.sCpuVendor', 695 -kiSortColumn_sCpuVendor: 'TestBoxesWithStrings.sCpuVendor DESC', 696 kiSortColumn_sCpuArch: 'TestBoxesWithStrings.sCpuArch', 697 -kiSortColumn_sCpuArch: 'TestBoxesWithStrings.sCpuArch DESC', 698 kiSortColumn_lCpuRevision: 'TestBoxesWithStrings.lCpuRevision', 699 -kiSortColumn_lCpuRevision: 'TestBoxesWithStrings.lCpuRevision DESC', 700 kiSortColumn_cCpus: 'TestBoxesWithStrings.cCpus', 701 -kiSortColumn_cCpus: 'TestBoxesWithStrings.cCpus DESC', 702 kiSortColumn_cMbMemory: 'TestBoxesWithStrings.cMbMemory', 703 -kiSortColumn_cMbMemory: 'TestBoxesWithStrings.cMbMemory DESC', 704 kiSortColumn_cMbScratch: 'TestBoxesWithStrings.cMbScratch', 705 -kiSortColumn_cMbScratch: 'TestBoxesWithStrings.cMbScratch DESC', 706 kiSortColumn_fCpuNestedPaging: 'TestBoxesWithStrings.fCpuNestedPaging', 707 -kiSortColumn_fCpuNestedPaging: 'TestBoxesWithStrings.fCpuNestedPaging DESC', 708 kiSortColumn_iTestBoxScriptRev: 'TestBoxesWithStrings.iTestBoxScriptRev', 709 -kiSortColumn_iTestBoxScriptRev: 'TestBoxesWithStrings.iTestBoxScriptRev DESC', 710 kiSortColumn_iPythonHexVersion: 'TestBoxesWithStrings.iPythonHexVersion', 711 -kiSortColumn_iPythonHexVersion: 'TestBoxesWithStrings.iPythonHexVersion DESC', 699 712 }; 700 713 -
trunk/src/VBox/ValidationKit/testmanager/webui/wuiadminbuild.py
r62484 r65350 78 78 """ 79 79 80 def __init__(self, aoEntries, iPage, cItemsPerPage, tsEffective, fnDPrint, oDisp ):80 def __init__(self, aoEntries, iPage, cItemsPerPage, tsEffective, fnDPrint, oDisp, aiSelectedSortColumns = None): 81 81 WuiListContentBase.__init__(self, aoEntries, iPage, cItemsPerPage, tsEffective, 82 sTitle = 'Builds', sId = 'builds', fnDPrint = fnDPrint, oDisp = oDisp); 82 sTitle = 'Builds', sId = 'builds', fnDPrint = fnDPrint, oDisp = oDisp, 83 aiSelectedSortColumns = aiSelectedSortColumns); 83 84 84 85 self._asColumnHeaders = ['ID', 'Product', 'Branch', 'Version', -
trunk/src/VBox/ValidationKit/testmanager/webui/wuiadminbuildblacklist.py
r62484 r65350 103 103 """ 104 104 105 def __init__(self, aoEntries, iPage, cItemsPerPage, tsEffective, fnDPrint, oDisp ):105 def __init__(self, aoEntries, iPage, cItemsPerPage, tsEffective, fnDPrint, oDisp, aiSelectedSortColumns = None): 106 106 WuiListContentBase.__init__(self, aoEntries, iPage, cItemsPerPage, tsEffective, 107 107 sTitle = 'Build Blacklist', sId = 'buildsBlacklist', 108 fnDPrint = fnDPrint, oDisp = oDisp );108 fnDPrint = fnDPrint, oDisp = oDisp, aiSelectedSortColumns = aiSelectedSortColumns); 109 109 110 110 self._asColumnHeaders = ['ID', 'Failure Reason', -
trunk/src/VBox/ValidationKit/testmanager/webui/wuiadminbuildcategory.py
r62484 r65350 42 42 """ 43 43 44 def __init__(self, aoEntries, iPage, cItemsPerPage, tsEffective, fnDPrint, oDisp ):44 def __init__(self, aoEntries, iPage, cItemsPerPage, tsEffective, fnDPrint, oDisp, aiSelectedSortColumns = None): 45 45 WuiListContentBase.__init__(self, aoEntries, iPage, cItemsPerPage, tsEffective, 46 46 sTitle = 'Build Categories', sId = 'buildcategories', 47 fnDPrint = fnDPrint, oDisp = oDisp );47 fnDPrint = fnDPrint, oDisp = oDisp, aiSelectedSortColumns = aiSelectedSortColumns); 48 48 self._asColumnHeaders = ([ 'ID', 'Product', 'Repository', 'Branch', 'Build Type', 'OS/Architectures', 'Actions' ]); 49 49 self._asColumnAttribs = (['align="right"', '', '', '', '', 'align="center"' ]); -
trunk/src/VBox/ValidationKit/testmanager/webui/wuiadminbuildsource.py
r62484 r65350 80 80 """ 81 81 82 def __init__(self, aoEntries, iPage, cItemsPerPage, tsEffective, fnDPrint, oDisp ):82 def __init__(self, aoEntries, iPage, cItemsPerPage, tsEffective, fnDPrint, oDisp, aiSelectedSortColumns = None): 83 83 WuiListContentBase.__init__(self, aoEntries, iPage, cItemsPerPage, tsEffective, 84 84 sTitle = 'Registered Build Sources', sId = 'build sources', 85 fnDPrint = fnDPrint, oDisp = oDisp );85 fnDPrint = fnDPrint, oDisp = oDisp, aiSelectedSortColumns = aiSelectedSortColumns); 86 86 self._asColumnHeaders = ['ID', 'Name', 'Description', 'Product', 87 87 'Branch', 'Build Types', 'OS/ARCH', 'First Revision', 'Last Revision', 'Max Age', -
trunk/src/VBox/ValidationKit/testmanager/webui/wuiadminfailurecategory.py
r62484 r65350 109 109 """ 110 110 111 def __init__(self, aoEntries, iPage, cItemsPerPage, tsEffective, fnDPrint, oDisp ):111 def __init__(self, aoEntries, iPage, cItemsPerPage, tsEffective, fnDPrint, oDisp, aiSelectedSortColumns = None): 112 112 WuiListContentBase.__init__(self, aoEntries, iPage, cItemsPerPage, tsEffective, 113 113 sTitle = 'Failure Categories', sId = 'failureCategories', 114 fnDPrint = fnDPrint, oDisp = oDisp );114 fnDPrint = fnDPrint, oDisp = oDisp, aiSelectedSortColumns = aiSelectedSortColumns); 115 115 116 116 self._asColumnHeaders = ['ID', 'Short Description', 'Full Description', 'Actions' ] -
trunk/src/VBox/ValidationKit/testmanager/webui/wuiadminfailurereason.py
r62484 r65350 124 124 """ 125 125 126 def __init__(self, aoEntries, iPage, cItemsPerPage, tsEffective, fnDPrint, oDisp ):126 def __init__(self, aoEntries, iPage, cItemsPerPage, tsEffective, fnDPrint, oDisp, aiSelectedSortColumns = None): 127 127 WuiListContentBase.__init__(self, aoEntries, iPage, cItemsPerPage, tsEffective, 128 128 sTitle = 'Failure Reasons', sId = 'failureReasons', 129 fnDPrint = fnDPrint, oDisp = oDisp );129 fnDPrint = fnDPrint, oDisp = oDisp, aiSelectedSortColumns = aiSelectedSortColumns); 130 130 131 131 self._asColumnHeaders = ['ID', 'Category', 'Short Description', -
trunk/src/VBox/ValidationKit/testmanager/webui/wuiadminglobalrsrc.py
r62484 r65350 88 88 """ 89 89 90 def __init__(self, aoEntries, iPage, cItemsPerPage, tsEffective, fnDPrint, oDisp ):90 def __init__(self, aoEntries, iPage, cItemsPerPage, tsEffective, fnDPrint, oDisp, aiSelectedSortColumns = None): 91 91 WuiListContentBase.__init__(self, aoEntries, iPage, cItemsPerPage, tsEffective, 92 92 sTitle = 'Global Resources', sId = 'globalResources', 93 fnDPrint = fnDPrint, oDisp = oDisp )93 fnDPrint = fnDPrint, oDisp = oDisp, aiSelectedSortColumns = aiSelectedSortColumns); 94 94 95 95 self._asColumnHeaders = ['ID', 'Name', 'Description', 'Enabled', 'Actions' ] -
trunk/src/VBox/ValidationKit/testmanager/webui/wuiadminschedgroup.py
r62484 r65350 94 94 """ 95 95 96 def __init__(self, aoEntries, iPage, cItemsPerPage, tsEffective, fnDPrint, oDisp ):96 def __init__(self, aoEntries, iPage, cItemsPerPage, tsEffective, fnDPrint, oDisp, aiSelectedSortColumns = None): 97 97 WuiListContentBase.__init__(self, aoEntries, iPage, cItemsPerPage, tsEffective, 98 98 sTitle = 'Registered Scheduling Groups', sId = 'schedgroups', 99 fnDPrint = fnDPrint, oDisp = oDisp );99 fnDPrint = fnDPrint, oDisp = oDisp, aiSelectedSortColumns = aiSelectedSortColumns); 100 100 101 101 self._asColumnHeaders = [ -
trunk/src/VBox/ValidationKit/testmanager/webui/wuiadminsystemchangelog.py
r65342 r65350 58 58 """ 59 59 60 def __init__(self, aoEntries, iPage, cItemsPerPage, tsEffective, fnDPrint, oDisp, cDaysBack ):60 def __init__(self, aoEntries, iPage, cItemsPerPage, tsEffective, fnDPrint, oDisp, cDaysBack, aiSelectedSortColumns = None): 61 61 WuiListContentBase.__init__(self, aoEntries, iPage, cItemsPerPage, tsEffective, 'System Changelog', 62 fnDPrint = fnDPrint, oDisp = oDisp );62 fnDPrint = fnDPrint, oDisp = oDisp, aiSelectedSortColumns = aiSelectedSortColumns); 63 63 self._asColumnHeaders = [ 'When', 'User', 'Event', 'Details' ]; 64 64 self._asColumnAttribs = [ 'align="center"', 'align="center"', '', '' ]; -
trunk/src/VBox/ValidationKit/testmanager/webui/wuiadminsystemlog.py
r62484 r65350 42 42 """ 43 43 44 def __init__(self, aoEntries, iPage, cItemsPerPage, tsEffective, fnDPrint, oDisp ):44 def __init__(self, aoEntries, iPage, cItemsPerPage, tsEffective, fnDPrint, oDisp, aiSelectedSortColumns = None): 45 45 WuiListContentBase.__init__(self, aoEntries, iPage, cItemsPerPage, tsEffective, 'System Log', 46 fnDPrint = fnDPrint, oDisp = oDisp );46 fnDPrint = fnDPrint, oDisp = oDisp, aiSelectedSortColumns = aiSelectedSortColumns); 47 47 self._asColumnHeaders = ['Date', 'Event', 'Message', 'Action']; 48 48 self._asColumnAttribs = ['', '', '', 'align="center"']; -
trunk/src/VBox/ValidationKit/testmanager/webui/wuiadmintestbox.py
r65228 r65350 180 180 kcSecMaxStatusDeltaAlive = 15*60 181 181 182 def __init__(self, aoEntries, iPage, cItemsPerPage, tsEffective, fnDPrint, oDisp ):182 def __init__(self, aoEntries, iPage, cItemsPerPage, tsEffective, fnDPrint, oDisp, aiSelectedSortColumns = None): 183 183 # type: (list[TestBoxDataForListing], int, int, datetime.datetime, ignore, WuiAdmin) -> None 184 184 WuiListContentWithActionBase.__init__(self, aoEntries, iPage, cItemsPerPage, tsEffective, 185 sTitle = 'TestBoxes', sId = 'users', fnDPrint = fnDPrint, oDisp = oDisp); 185 sTitle = 'TestBoxes', sId = 'users', fnDPrint = fnDPrint, oDisp = oDisp, 186 aiSelectedSortColumns = aiSelectedSortColumns); 186 187 self._asColumnHeaders.extend([ 'Name', 'LOM', 'Status', 'Cmd', 187 188 'Note', 'Script', 'Python', 'Group', -
trunk/src/VBox/ValidationKit/testmanager/webui/wuiadmintestcase.py
r62484 r65350 59 59 """ 60 60 61 def __init__(self, aoEntries, iPage, cItemsPerPage, tsEffective, fnDPrint, oDisp ):62 WuiListContentBase.__init__(self, aoEntries, iPage, cItemsPerPage, tsEffective, 63 sTitle = 'Test Cases', fnDPrint = fnDPrint, oDisp = oDisp);61 def __init__(self, aoEntries, iPage, cItemsPerPage, tsEffective, fnDPrint, oDisp, aiSelectedSortColumns = None): 62 WuiListContentBase.__init__(self, aoEntries, iPage, cItemsPerPage, tsEffective, sTitle = 'Test Cases', 63 fnDPrint = fnDPrint, oDisp = oDisp, aiSelectedSortColumns = aiSelectedSortColumns); 64 64 self._asColumnHeaders = \ 65 65 [ -
trunk/src/VBox/ValidationKit/testmanager/webui/wuiadmintestgroup.py
r62484 r65350 84 84 """ 85 85 86 def __init__(self, aoEntries, iPage, cItemsPerPage, tsEffective, fnDPrint, oDisp ):86 def __init__(self, aoEntries, iPage, cItemsPerPage, tsEffective, fnDPrint, oDisp, aiSelectedSortColumns = None): 87 87 assert len(aoEntries) == 0 or isinstance(aoEntries[0], TestGroupDataEx) 88 88 89 WuiListContentBase.__init__(self, aoEntries, iPage, cItemsPerPage, tsEffective, 90 sTitle = 'Test Groups', fnDPrint = fnDPrint, oDisp = oDisp);89 WuiListContentBase.__init__(self, aoEntries, iPage, cItemsPerPage, tsEffective, sTitle = 'Test Groups', 90 fnDPrint = fnDPrint, oDisp = oDisp, aiSelectedSortColumns = aiSelectedSortColumns); 91 91 self._asColumnHeaders = [ 'ID', 'Name', 'Description', 'Test Cases', 'Note', 'Actions' ]; 92 92 self._asColumnAttribs = [ 'align="right"', '', '', '', 'align="center"', 'align="center"' ]; -
trunk/src/VBox/ValidationKit/testmanager/webui/wuiadminuseraccount.py
r62484 r65350 67 67 """ 68 68 69 def __init__(self, aoEntries, iPage, cItemsPerPage, tsEffective, fnDPrint, oDisp ):69 def __init__(self, aoEntries, iPage, cItemsPerPage, tsEffective, fnDPrint, oDisp, aiSelectedSortColumns = None): 70 70 WuiListContentBase.__init__(self, aoEntries, iPage, cItemsPerPage, tsEffective, 71 sTitle = 'Registered User Accounts', sId = 'users', fnDPrint = fnDPrint, oDisp = oDisp); 71 sTitle = 'Registered User Accounts', sId = 'users', fnDPrint = fnDPrint, oDisp = oDisp, 72 aiSelectedSortColumns = aiSelectedSortColumns); 72 73 self._asColumnHeaders = ['User ID', 'Name', 'E-mail', 'Full Name', 'Login Name', 'Actions']; 73 74 self._asColumnAttribs = ['align="center"', 'align="center"', 'align="center"', 'align="center"', 'align="center"', -
trunk/src/VBox/ValidationKit/testmanager/webui/wuibase.py
r65226 r65350 804 804 cItemsPerPage = self.getIntParam(self.ksParamItemsPerPage, iMin = 2, iMax = 9999, iDefault = 300); 805 805 iPage = self.getIntParam(self.ksParamPageNo, iMin = 0, iMax = 999999, iDefault = 0); 806 aiSortColumnsDup = self.getListOfIntParams(self.ksParamSortColumns, iMin = 0, 806 aiSortColumnsDup = self.getListOfIntParams(self.ksParamSortColumns, 807 iMin = -getattr(oLogicType, 'kcMaxSortColumns', 0) + 1, 807 808 iMax = getattr(oLogicType, 'kcMaxSortColumns', 0), aiDefaults = []); 808 809 aiSortColumns = []; … … 814 815 aoEntries = oLogicType(self._oDb).fetchForListing(iPage * cItemsPerPage, cItemsPerPage + 1, tsEffective, aiSortColumns); 815 816 oContent = oListContentType(aoEntries, iPage, cItemsPerPage, tsEffective, 816 fnDPrint = self._oSrvGlue.dprint, oDisp = self );817 fnDPrint = self._oSrvGlue.dprint, oDisp = self, aiSelectedSortColumns = aiSortColumns); 817 818 (self._sPageTitle, self._sPageBody) = oContent.show(); 818 819 return True; -
trunk/src/VBox/ValidationKit/testmanager/webui/wuicontentbase.py
r65226 r65350 736 736 """ 737 737 738 def __init__(self, aoEntries, iPage, cItemsPerPage, tsEffectiveDate, sTitle, sId = None, fnDPrint = None, oDisp = None): 738 def __init__(self, aoEntries, iPage, cItemsPerPage, tsEffectiveDate, sTitle, sId = None, fnDPrint = None, 739 oDisp = None, aiSelectedSortColumns = None): 739 740 WuiContentBase.__init__(self, fnDPrint = fnDPrint, oDisp = oDisp); 740 741 self._aoEntries = aoEntries; ## @todo should replace this with a Logic object and define methods for querying. … … 750 751 self._asColumnAttribs = []; 751 752 self._aaiColumnSorting = []; ##< list of list of integers 753 self._aiSelectedSortColumns = aiSelectedSortColumns; ##< list of integers 752 754 753 755 def _formatCommentCell(self, sComment, cMaxLines = 3, cchMaxLine = 63): … … 937 939 return sNavigation; 938 940 941 def _isSortingByColumnAscending(self, aiColumns): 942 """ Checks if we're already sorting by this column in ascending order """ 943 # Just compare the first sorting column spec for now. 944 #if self._aiSelectedSortColumns is not None and len(aiColumns) <= len(self._aiSelectedSortColumns): 945 if len(aiColumns) <= len(self._aiSelectedSortColumns): 946 if list(aiColumns) == list(self._aiSelectedSortColumns[:len(aiColumns)]): 947 return True; 948 return False; 949 939 950 def _generateTableHeaders(self): 940 951 """ … … 950 961 elif iHeader < len(self._aaiColumnSorting) and self._aaiColumnSorting[iHeader] is not None: 951 962 sHtml += '<th>' 952 sHtml += '<a href="javascript:ahrefActionSortByColumns(\'%s\', [%s]);">' \ 953 % (WuiDispatcherBase.ksParamSortColumns, ','.join([str(i) for i in self._aaiColumnSorting[iHeader]])); 963 if not self._isSortingByColumnAscending(self._aaiColumnSorting[iHeader]): 964 sSortParams = ','.join([str(i) for i in self._aaiColumnSorting[iHeader]]); 965 else: 966 sSortParams = ','.join([str(-i) for i in self._aaiColumnSorting[iHeader]]); 967 sHtml += '<a href="javascript:ahrefActionSortByColumns(\'%s\',[%s]);">' \ 968 % (WuiDispatcherBase.ksParamSortColumns, sSortParams); 954 969 sHtml += webutils.escapeElem(oHeader) + '</a></th>'; 955 970 else: … … 1021 1036 """ 1022 1037 1023 def __init__(self, aoEntries, iPage, cItemsPerPage, tsEffectiveDate, sTitle, sId = None, fnDPrint = None, oDisp = None): 1024 WuiListContentBase.__init__(self, aoEntries, iPage, cItemsPerPage, tsEffectiveDate, sTitle, 1025 sId = sId, fnDPrint = fnDPrint, oDisp = oDisp); 1038 def __init__(self, aoEntries, iPage, cItemsPerPage, tsEffectiveDate, sTitle, sId = None, fnDPrint = None, 1039 oDisp = None, aiSelectedSortColumns = None): 1040 WuiListContentBase.__init__(self, aoEntries, iPage, cItemsPerPage, tsEffectiveDate, sTitle, sId = sId, 1041 fnDPrint = fnDPrint, oDisp = oDisp, aiSelectedSortColumns = aiSelectedSortColumns); 1026 1042 self._aoActions = None; # List of [ oValue, sText, sHover ] provided by the child class. 1027 1043 self._sAction = None; # Set by the child class. -
trunk/src/VBox/ValidationKit/testmanager/webui/wuitestresult.py
r62484 r65350 764 764 """ 765 765 766 def __init__(self, aoEntries, cEntriesCount, iPage, cItemsPerPage, tsEffective, fnDPrint, oDisp): 766 def __init__(self, aoEntries, cEntriesCount, iPage, cItemsPerPage, tsEffective, fnDPrint, oDisp, 767 aiSelectedSortColumns = None): 767 768 """Override initialization""" 768 769 WuiListContentBase.__init__(self, aoEntries, iPage, cItemsPerPage, tsEffective, 769 770 sTitle = 'Ungrouped (%d)' % cEntriesCount, sId = 'results', 770 fnDPrint = fnDPrint, oDisp = oDisp );771 fnDPrint = fnDPrint, oDisp = oDisp, aiSelectedSortColumns = aiSelectedSortColumns); 771 772 772 773 self._cEntriesCount = cEntriesCount
注意:
瀏覽 TracChangeset
來幫助您使用更動檢視器