@@ -12,10 +12,355 @@ tvheadend.tvhlog = function(panel, index) {
1212 tracesubs . setDisabled ( ! trace . getValue ( ) || trace . disabled ) ;
1313 }
1414
15+ //START SUBSYSTEM SELECTION WINDOW CODE
16+
17+ //Define some variables local to this module.
18+ let debugSubsystemsSaved = "" ;
19+ let traceSubsystemsSaved = "" ;
20+
21+ let debugBoxUI = { } ;
22+ let traceBoxUI = { } ;
23+
24+ let subsystemStore = { } ;
25+
26+ //Create a button to show in the TVH config/debug toolbar.
27+ //When pressed, this will display the subsystem selection window.
28+ let subsystemsButton = {
29+ name : 'subsys' ,
30+ builder : function ( ) {
31+ return new Ext . Toolbar . Button ( {
32+ tooltip : _ ( 'Select trace/debug options from a list of subsystems.' ) ,
33+ iconCls : 'list' ,
34+ text : _ ( 'Select Subsystems' ) ,
35+ disabled : false
36+ } ) ;
37+ } ,
38+ callback : function ( conf , e , store , select ) {
39+
40+ //Get a list of the subsystems currently entered
41+ //Do it this way instead of looking at the current status from
42+ //the API because the user may be in the middle of a manual change
43+ //and it would be polite to preserve those manual changes.
44+ let debugBox = document . getElementsByName ( "debugsubs" ) ;
45+ let traceBox = document . getElementsByName ( "tracesubs" ) ;
46+
47+ //These are the existing text UI text boxes.
48+ debugBoxUI = debugBox [ 0 ] ;
49+ traceBoxUI = traceBox [ 0 ] ;
50+
51+ //Save the initial UI text box values for a potential
52+ //reset at a later time.
53+ debugSubsystemsSaved = debugBoxUI . value ;
54+ traceSubsystemsSaved = traceBoxUI . value ;
55+
56+ //Break down the existing text box values into arrays.
57+ let debugArray = debugBoxUI . value . split ( "," ) ;
58+ let traceArray = traceBoxUI . value . split ( "," ) ;
59+
60+ //Grab the list of subsystems from the server.
61+ //Note that this is an asynchronous call and the
62+ //rest of the module needs to be contained within
63+ //the 'success' method in order to work.
64+ let subsystemList = Ext . Ajax . request ( {
65+ url : 'api/tvhlog/subsystem/grid' ,
66+ success : function ( d ) {
67+
68+ //Parse the results of the call and extract the 'entries'.
69+ let subsystemResponse = JSON . parse ( d . responseText ) ;
70+ subsystemList = subsystemResponse . entries ;
71+
72+ //Add 'all' to the beginning of the list.
73+ //Subsystem 'all' is not a valid subsystem per-se,
74+ //however, TVH uses it internally to enable all subsystems.
75+ let tempSub = {
76+ id : - 1 ,
77+ subsystem : 'all' ,
78+ description : _ ( 'All subsystems' ) ,
79+ debug : false ,
80+ trace : false
81+ } ;
82+ subsystemList . unshift ( tempSub ) ;
83+
84+ //Load the starting conditions from the text boxes
85+ //because the user may have already made some manual changes.
86+ let i = 0 ;
87+
88+ while ( i < subsystemList . length ) {
89+ subsystemList [ i ] . debug = debugArray . includes ( subsystemList [ i ] . subsystem ) ;
90+ subsystemList [ i ] . trace = traceArray . includes ( subsystemList [ i ] . subsystem ) ;
91+ i ++ ;
92+ }
93+
94+ //Create the reset buttons for the bottom of the window.
95+ let buttons = [ ] ;
96+ buttons . push ( new Ext . Toolbar . Button ( {
97+ handler : function ( ) {
98+ windowButtons ( 10 )
99+ } ,
100+ iconCls : 'delete' ,
101+ text : _ ( 'Clear Debug' ) ,
102+ tooltip : _ ( 'Clear all debug subsystems.' ) ,
103+ } ) ) ;
104+ buttons . push ( new Ext . Toolbar . Button ( {
105+ handler : function ( ) {
106+ windowButtons ( 11 )
107+ } ,
108+ iconCls : 'delete' ,
109+ text : _ ( 'Clear Trace' ) ,
110+ tooltip : _ ( 'Clear all trace subsystems.' ) ,
111+ } ) ) ;
112+ buttons . push ( new Ext . Toolbar . Button ( {
113+ handler : function ( ) {
114+ windowButtons ( 0 )
115+ } ,
116+ iconCls : 'undo' ,
117+ text : _ ( 'Restore Debug' ) ,
118+ tooltip : _ ( 'Restore the debug subsystems to their initial state.' ) ,
119+ } ) ) ;
120+ buttons . push ( new Ext . Toolbar . Button ( {
121+ handler : function ( ) {
122+ windowButtons ( 1 )
123+ } ,
124+ iconCls : 'undo' ,
125+ text : _ ( 'Restore Trace' ) ,
126+ tooltip : _ ( 'Restore the trace subsystems to their initial state.' ) ,
127+ } ) ) ;
128+
129+ //This array will contain all of the elements to be
130+ //rendered onto the subsystem selection window.
131+ let windowItems = [ ] ;
132+
133+ //Create the data store that feeds the grid.
134+ //It takes the JSON response from TVH as its source.
135+ subsystemStore = new Ext . data . JsonStore ( {
136+ root : 'entries' ,
137+ data : subsystemResponse ,
138+ autoLoad : true ,
139+ id : 'id' ,
140+ fields : [ 'debug' , 'trace' , 'subsystem' , 'description' ] ,
141+ remoteSort : false ,
142+ } ) ;
143+
144+ //Take a boolean field and display checkboxes instead
145+ //using existing ExtJS styles to match the TVH look-and-feel.
146+ function subsystemBooleanRenderer ( val ) {
147+ if ( val ) {
148+ return '<div class="x-grid3-check-col-on"> </div>' ;
149+ } else {
150+ return '<div class="x-grid3-check-col"> </div>' ;
151+ }
152+ }
153+
154+ //Define the column mode to be used. Note the custom
155+ //rendering for the boolean fields.
156+ let subsystemColumnModel = new Ext . grid . ColumnModel ( {
157+ columns : [ {
158+ header : _ ( "Debug" ) ,
159+ width : 50 ,
160+ id : 'debug' ,
161+ renderer : subsystemBooleanRenderer
162+ } ,
163+ {
164+ header : _ ( "Trace" ) ,
165+ width : 50 ,
166+ id : 'trace' ,
167+ renderer : subsystemBooleanRenderer
168+ } ,
169+ {
170+ header : _ ( "Subsystem" ) ,
171+ width : 80 ,
172+ id : 'subsystem'
173+ } ,
174+ {
175+ header : _ ( "Description" ) ,
176+ width : 280 ,
177+ id : 'description'
178+ }
179+ ] ,
180+ defaults : {
181+ sortable : false ,
182+ menuDisabled : true ,
183+ width : 100
184+ }
185+ } ) ;
186+
187+
188+ //Read through all of the subsystems and build a UI string.
189+ function getSubsystemString ( checkList ) {
190+ let debugList = [ ] ;
191+ let traceList = [ ] ;
192+
193+ i = 0 ;
194+ while ( i < checkList . length ) {
195+
196+ if ( checkList [ i ] . debug ) {
197+ debugList . push ( checkList [ i ] . subsystem ) ;
198+ }
199+
200+ if ( checkList [ i ] . trace ) {
201+ traceList . push ( checkList [ i ] . subsystem ) ;
202+ }
203+
204+ i ++ ;
205+ }
206+
207+ return {
208+ debug : debugList . toString ( ) ,
209+ trace : traceList . toString ( )
210+ } ;
211+
212+ } //END getSubsystemString
213+
214+
215+ //Take the supplied strings and update the UI text boxes.
216+ function updateSubsystemUI ( stringValues ) {
217+ debugBoxUI . value = stringValues . debug ;
218+ traceBoxUI . value = stringValues . trace ;
219+ }
220+
221+ //Taking the row and column coordinates of the grid cell,
222+ //update the boolean values for each debug/trace and then
223+ //update the UI.
224+ function updateSubsystemActions ( row , column ) {
225+
226+ let myRecord ;
227+
228+ //Toggle the debug subsystem
229+ if ( column == 0 ) {
230+ subsystemList [ row ] . debug = ! subsystemList [ row ] . debug ;
231+ myRecord = subsystemStore . getAt ( row ) ;
232+ myRecord . set ( 'debug' , subsystemList [ row ] . debug ) ;
233+ }
234+
235+ //Toggle the trace subsystem
236+ if ( column == 1 ) {
237+ subsystemList [ row ] . trace = ! subsystemList [ row ] . trace ;
238+ myRecord = subsystemStore . getAt ( row ) ;
239+ myRecord . set ( 'trace' , subsystemList [ row ] . trace ) ;
240+ }
241+
242+ //Toggle both subsystems
243+ if ( column == 2 ) {
244+
245+ //If either is off, turn them both on
246+ if ( ! subsystemList [ row ] . debug || ! subsystemList [ row ] . trace ) {
247+ subsystemList [ row ] . debug = true ;
248+ subsystemList [ row ] . trace = true ;
249+ } else {
250+ subsystemList [ row ] . debug = false ;
251+ subsystemList [ row ] . trace = false ;
252+ }
253+
254+ myRecord = subsystemStore . getAt ( row ) ;
255+ myRecord . set ( 'debug' , subsystemList [ row ] . debug ) ;
256+ myRecord . set ( 'trace' , subsystemList [ row ] . trace ) ;
257+ }
258+
259+ //Update the existing UI text fields with the new values.
260+ updateSubsystemUI ( getSubsystemString ( subsystemList ) ) ;
261+ } //END updateSubsystemActions
262+
263+ //Reset the subsystem selection to its original value.
264+ function resetSubsystems ( propertyName , textBoxUI , newValues ) {
265+
266+ let newArray = newValues . split ( "," ) ;
267+
268+ //Reset the text box to the previous values
269+ textBoxUI . value = newValues ;
270+
271+ //Loop through all of the subsystems and update their state
272+ //in the array and the store based on the saved state.
273+ let i = 0 ;
274+ while ( i < subsystemList . length ) {
275+
276+ subsystemList [ i ] [ propertyName ] = newArray . includes ( subsystemList [ i ] . subsystem ) ;
277+ let myRecord = subsystemStore . getAt ( i ) ;
278+ myRecord . set ( propertyName , subsystemList [ i ] [ propertyName ] ) ;
279+ i ++ ;
280+ } //END while loop
281+ } //END reset subsystems
282+
283+
284+ //Handle the buttons at the bottom of the window.
285+ function windowButtons ( button ) {
286+
287+ if ( button == 0 ) {
288+ resetSubsystems ( "debug" , debugBoxUI , debugSubsystemsSaved ) ;
289+ }
290+
291+ if ( button == 1 ) {
292+ resetSubsystems ( "trace" , traceBoxUI , traceSubsystemsSaved ) ;
293+ }
294+
295+ if ( button == 10 ) {
296+ resetSubsystems ( "debug" , debugBoxUI , "" ) ;
297+ }
298+
299+ if ( button == 11 ) {
300+ resetSubsystems ( "trace" , traceBoxUI , "" ) ;
301+ }
302+
303+
304+ } //End window button handlers.
305+
306+
307+ //Creeate the grid to be shown on the subsystem selection window.
308+ let grid = new Ext . grid . GridPanel ( {
309+ flex : 1 ,
310+ autoWidth : true ,
311+ autoScroll : true ,
312+ stripeRows : true ,
313+ store : subsystemStore ,
314+ cm : subsystemColumnModel ,
315+ border : false ,
316+ viewConfig : {
317+ markDirty : false //Hide the red tag that highlights changed records.
318+ } ,
319+ listeners : {
320+ cellclick : function ( gridView , htmlElement , columnIndex , dataRecord ) {
321+ updateSubsystemActions ( htmlElement , columnIndex ) ;
322+ }
323+ } //END listeners
324+ } ) ;
325+
326+ //Add the grid to the list of items to be rendered on the window.
327+ windowItems . push ( grid ) ;
328+
329+ //Create a window to display the list of subsystems.
330+ let windowHeight = Ext . getBody ( ) . getViewSize ( ) . height - 150 ;
331+ let subsysWin = new Ext . Window ( {
332+ title : _ ( 'Select Subsystems' ) ,
333+ iconCls : 'debug' ,
334+ layout : 'fit' ,
335+ width : 500 ,
336+ height : windowHeight ,
337+ constrainHeader : true ,
338+ buttons : buttons ,
339+ buttonAlign : 'center' ,
340+ autoScroll : true ,
341+ items : windowItems
342+ } ) ;
343+
344+ //Display the subsystem selection window.
345+ subsysWin . show ( ) ;
346+
347+ } , //END AJAX OK
348+ failure : function ( response , options ) {
349+ Ext . MessageBox . alert ( _ ( 'Listing Subsystems' ) , response . statusText ) ;
350+ return "" ;
351+ }
352+ } ) ; //END Ajax request for subsystems list.
353+ } //END button callback.
354+ } ; //END button object.
355+
356+ //END SUBSYSTEM SELECTION WINDOW CODE
357+
358+ //This is the standard debug config screen.
15359 tvheadend . idnode_simple ( panel , {
16360 url : 'api/tvhlog/config' ,
17361 title : _ ( 'Configuration' ) ,
18362 iconCls : 'debug' ,
363+ tbar : [ subsystemsButton ] , //Add the button to list the subsystems
19364 tabIndex : index ,
20365 comet : 'tvhlog_conf' ,
21366 labelWidth : 180 ,
0 commit comments