]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
Rebase after PR #381
authorIan <ian@sproink.co.uk>
Sat, 24 May 2014 22:28:07 +0000 (23:28 +0100)
committerIan <ian@sproink.co.uk>
Sat, 24 May 2014 22:28:07 +0000 (23:28 +0100)
Conflicts:
src/webui/static/app/config.js
src/webui/static/app/dvr.js
src/webui/static/app/timeshift.js

1  2 
src/webui/static/app/config.js
src/webui/static/app/dvr.js
src/webui/static/app/timeshift.js

index 41dcbbf1397a999edab15a087a1053279c51f631,8a87d25f28dae6e14b8bafccf57dbaa43af0058d..ab90701ef51f708986b38ca2d0fa837981931bbd
@@@ -33,262 -33,243 +33,269 @@@ tvheadend.comet.on('config', function(m
  
  tvheadend.miscconf = function() {
  
-       /*
-        * Basic Config
-        */
-       var confreader = new Ext.data.JsonReader({
-               root : 'config'
-       }, [ 'muxconfpath', 'language',
-        'tvhtime_update_enabled', 'tvhtime_ntp_enabled',
-        'tvhtime_tolerance', 'transcoding_enabled']);
-       /* ****************************************************************
-        * Form Fields
-        * ***************************************************************/
-   /*
-    * DVB path
-    */
-       var dvbscanPath = new Ext.form.TextField({
-               fieldLabel : 'DVB scan files path',
-               name : 'muxconfpath',
-               allowBlank : true,
-               width: 400
-       });
+     /*
 -     * Basic Config
 -     */
++    * Basic Config
++    */
 +
-       var dvbscanWrap = new Ext.form.FieldSet({
-               title: 'DVB Scan Files',
-               width: 700,
-               autoHeight: true,
-               collapsible: true,
-               animCollapse: true,
-               items : [ dvbscanPath ]
-       });
-   /*
-    * Language
-    */
-       var language = new Ext.ux.ItemSelector({
-               name: 'language',
-               fromStore: tvheadend.languages,
-               toStore: tvheadend.config_languages,
-               fieldLabel: 'Default Language(s)',
-               dataFields:['identifier', 'name'],
-               msWidth: 190,
-               msHeight: 150,
-               valueField: 'identifier',
-               displayField: 'name',
-               imagePath: 'static/multiselect/resources',
-               toLegend: 'Selected',
-               fromLegend: 'Available'
-       });
-       var languageWrap = new Ext.form.FieldSet({
-               title: 'Language Settings',
-               width: 700,
-               autoHeight: true,
-               collapsible: true,
-               animCollapse: true,
-               items : [ language ]
-       });
-   /*
-    * Time/Date
-    */
-   var tvhtimeUpdateEnabled = new Ext.form.Checkbox({
-     name: 'tvhtime_update_enabled',
-     fieldLabel: 'Update time'
-   });
-   
-   var tvhtimeNtpEnabled = new Ext.form.Checkbox({
-     name: 'tvhtime_ntp_enabled',
-     fieldLabel: 'Enable NTP driver'
-   });
-   var tvhtimeTolerance = new Ext.form.NumberField({
-     name: 'tvhtime_tolerance',
-     fieldLabel: 'Update tolerance (ms)'
-   });
-   var tvhtimePanel = new Ext.form.FieldSet({
-     title: 'Time Update',
-     width: 700,
-     autoHeight: true,
-     collapsible: true,
-       animCollapse: true,
-     items : [ tvhtimeUpdateEnabled, tvhtimeNtpEnabled, tvhtimeTolerance ]
-   });
-   /*
-    * Image cache
-    */
-   if (tvheadend.capabilities.indexOf('imagecache') != -1) {
-     var imagecache_reader = new Ext.data.JsonReader({
-       root        : 'entries'
+     var confreader = new Ext.data.JsonReader({
+         root: 'config'
      },
      [
-        'enabled', 'ok_period', 'fail_period', 'ignore_sslcert',
+         'muxconfpath', 'language',
+         'tvhtime_update_enabled', 'tvhtime_ntp_enabled',
+         'tvhtime_tolerance', 'transcoding_enabled'
      ]);
  
-     var imagecacheEnabled = new Ext.ux.form.XCheckbox({
-       name: 'enabled',
-       fieldLabel: 'Enabled',
+     /* ****************************************************************
 -     * Form Fields
 -     * ***************************************************************/
++    * Form Fields
++    * ***************************************************************/
+     /*
 -     * DVB path
 -     */
++    * DVB path
++    */
+     var dvbscanPath = new Ext.form.TextField({
+         fieldLabel: 'DVB scan files path',
+         name: 'muxconfpath',
+         allowBlank: true,
+         width: 400
      });
  
-     var imagecacheOkPeriod = new Ext.form.NumberField({
-       name: 'ok_period',
-       fieldLabel: 'Re-fetch period (hours)'
++      var dvbscanWrap = new Ext.form.FieldSet({
++        title: 'DVB Scan Files',
++        width: 700,
++        autoHeight: true,
++        collapsible: true,
++        animCollapse: true,
++        items : [ dvbscanPath ]
 +    });
 +
-     var imagecacheFailPeriod = new Ext.form.NumberField({
-       name: 'fail_period',
-       fieldLabel: 'Re-try period (hours)',
+     /*
 -     * Language
 -     */
++    * Language
++    */
+     var language = new Ext.ux.ItemSelector({
+         name: 'language',
+         fromStore: tvheadend.languages,
+         toStore: tvheadend.config_languages,
+         fieldLabel: 'Default Language(s)',
+         dataFields: ['identifier', 'name'],
+         msWidth: 190,
+         msHeight: 150,
+         valueField: 'identifier',
+         displayField: 'name',
+         imagePath: 'static/multiselect/resources',
+         toLegend: 'Selected',
+         fromLegend: 'Available'
      });
  
-     var imagecacheIgnoreSSLCert = new Ext.ux.form.XCheckbox({
-       name: 'ignore_sslcert',
-       fieldLabel: 'Ignore invalid SSL certificate'
++      var languageWrap = new Ext.form.FieldSet({
++        title: 'Language Settings',
++        width: 700,
++        autoHeight: true,
++        collapsible: true,
++        animCollapse: true,
++        items : [ language ]
++    });
++
+     /*
 -     * Time/Date
 -     */
++    * Time/Date
++    */
++
+     var tvhtimeUpdateEnabled = new Ext.form.Checkbox({
+         name: 'tvhtime_update_enabled',
+         fieldLabel: 'Update time'
      });
  
-     var imagecachePanel = new Ext.form.FieldSet({
-       title: 'Image Caching',
-       width: 700,
-       autoHeight: true,
-       collapsible: true,
-       animCollapse: true,
-       items : [ imagecacheEnabled, imagecacheOkPeriod, imagecacheFailPeriod,
-                 imagecacheIgnoreSSLCert ]
+     var tvhtimeNtpEnabled = new Ext.form.Checkbox({
+         name: 'tvhtime_ntp_enabled',
+         fieldLabel: 'Enable NTP driver'
      });
  
-     var imagecache_form = new Ext.form.FormPanel({
-       border : false,
-       labelAlign : 'left',
-       labelWidth : 200,
-       waitMsgTarget : true,
-       reader: imagecache_reader,
-       layout : 'form',
-       defaultType : 'textfield',
-       autoHeight : true,
-       animCollapse: true,
-       items : [ imagecachePanel ]
+     var tvhtimeTolerance = new Ext.form.NumberField({
+         name: 'tvhtime_tolerance',
+         fieldLabel: 'Update tolerance (ms)'
      });
-   } else {
-     var imagecache_form = null;
-   }
-   /*
-    * Transcoding
-    */
-   var transcodingEnabled = new Ext.form.Checkbox({
-     name: 'transcoding_enabled',
-     fieldLabel: 'Enabled',
-   });
-   var transcodingPanel = new Ext.form.FieldSet({
-     title: 'Transcoding',
-     width: 700,
-     autoHeight: true,
-     collapsible: true,
-     animCollapse: true,
-     items : [ transcodingEnabled ]
-   });
-   if (tvheadend.capabilities.indexOf('transcoding') == -1)
-     transcodingPanel.hide();
-       /* ****************************************************************
-        * Form
-        * ***************************************************************/
-       var saveButton = new Ext.Button({
-               text : "Save configuration",
-               tooltip : 'Save changes made to configuration below',
-               iconCls : 'save',
-               handler : saveChanges
-       });
-       var helpButton = new Ext.Button({
-               text : 'Help',
-               handler : function() {
-                       new tvheadend.help('General Configuration', 'config_misc.html');
-               }
-       });
-       var confpanel = new Ext.form.FormPanel({
-               labelAlign : 'left',
-               labelWidth : 200,
-               border : false,
-               waitMsgTarget : true,
-               reader : confreader,
-               layout : 'form',
-               defaultType : 'textfield',
-               autoHeight : true,
-               items : [ languageWrap, dvbscanWrap,
-                         tvhtimePanel,
-                         transcodingPanel]
-       });
-   var _items = [confpanel];
-   if (imagecache_form)
-     _items.push(imagecache_form);
-   var panel = new Ext.Panel({
-               title : 'General',
-               iconCls : 'wrench',
-               border : false,
-               bodyStyle : 'padding:15px',
-               layout : 'form',
-     items: _items,
-               tbar : [ saveButton, '->', helpButton ]
-   });
-       /* ****************************************************************
-        * Load/Save
-        * ***************************************************************/
-       confpanel.on('render', function() {
-               confpanel.getForm().load({
-                       url : 'config',
-                       params : {
-                               op : 'loadSettings'
-                       },
-                       success : function(form, action) {
-                               confpanel.enable();
-                       }
-               });
-               if (imagecache_form)
-       imagecache_form.getForm().load({
-         url     : 'api/imagecache/config/load',
-         success : function (form, action) {
-           imagecache_form.enable();
+     var tvhtimePanel = new Ext.form.FieldSet({
+         title: 'Time Update',
+         width: 700,
+         autoHeight: true,
+         collapsible: true,
++        animCollapse: true,
+         items: [tvhtimeUpdateEnabled, tvhtimeNtpEnabled, tvhtimeTolerance]
+     });
+     /*
 -     * Image cache
 -     */
++    * Image cache
++    */
++
+     if (tvheadend.capabilities.indexOf('imagecache') !== -1) {
+         var imagecache_reader = new Ext.data.JsonReader({
+             root: 'entries'
          },
-         failure : function (form, action) {
-           alert("FAILED");
-         }
-       });
-       });
-       function saveChanges() {
-               confpanel.getForm().submit({
-                       url : 'config',
-                       params : {
-                               op : 'saveSettings'
-                       },
-                       waitMsg : 'Saving Data...',
-                       failure : function(form, action) {
-                               Ext.Msg.alert('Save failed', action.result.errormsg);
-                       }
-               });
-               if (imagecache_form)
-       imagecache_form.getForm().submit({
-         url     : 'api/imagecache/config/save',
-         waitMsg : 'Saving data...',
-         failure : function(form, action) {
-           Ext.Msg.alert('Imagecache save failed', action.result.errormsg);
+         [
+             'enabled', 'ok_period', 'fail_period', 'ignore_sslcert'
+         ]);
+         var imagecacheEnabled = new Ext.ux.form.XCheckbox({
+             name: 'enabled',
+             fieldLabel: 'Enabled'
+         });
+         var imagecacheOkPeriod = new Ext.form.NumberField({
+             name: 'ok_period',
+             fieldLabel: 'Re-fetch period (hours)'
+         });
+         var imagecacheFailPeriod = new Ext.form.NumberField({
+             name: 'fail_period',
+             fieldLabel: 'Re-try period (hours)'
+         });
+         var imagecacheIgnoreSSLCert = new Ext.ux.form.XCheckbox({
+             name: 'ignore_sslcert',
+             fieldLabel: 'Ignore invalid SSL certificate'
+         });
+         var imagecachePanel = new Ext.form.FieldSet({
+             title: 'Image Caching',
+             width: 700,
+             autoHeight: true,
+             collapsible: true,
++            animCollapse: true,
+             items: [imagecacheEnabled, imagecacheOkPeriod, imagecacheFailPeriod,
+                 imagecacheIgnoreSSLCert]
+         });
+         var imagecache_form = new Ext.form.FormPanel({
+             border: false,
+             labelAlign: 'left',
+             labelWidth: 200,
+             waitMsgTarget: true,
+             reader: imagecache_reader,
+             layout: 'form',
+             defaultType: 'textfield',
+             autoHeight: true,
+             items: [imagecachePanel]
+         });
+     } else {
+         var imagecache_form = null;
+     }
+     /*
 -     * Transcoding
 -     */
++    * Transcoding
++    */
++
+     var transcodingEnabled = new Ext.form.Checkbox({
+         name: 'transcoding_enabled',
+         fieldLabel: 'Enabled'
+     });
+     var transcodingPanel = new Ext.form.FieldSet({
+         title: 'Transcoding',
+         width: 700,
+         autoHeight: true,
+         collapsible: true,
++        animCollapse: true,
+         items: [transcodingEnabled]
+     });
++
+     if (tvheadend.capabilities.indexOf('transcoding') === -1)
+         transcodingPanel.hide();
+     /* ****************************************************************
 -     * Form
 -     * ***************************************************************/
++    * Form
++    * ***************************************************************/
+     var saveButton = new Ext.Button({
+         text: "Save configuration",
+         tooltip: 'Save changes made to configuration below',
+         iconCls: 'save',
+         handler: saveChanges
+     });
+     var helpButton = new Ext.Button({
+         text: 'Help',
+         handler: function() {
+             new tvheadend.help('General Configuration', 'config_misc.html');
          }
-       });
-       }
+     });
+     var confpanel = new Ext.form.FormPanel({
+         labelAlign: 'left',
+         labelWidth: 200,
+         border: false,
+         waitMsgTarget: true,
+         reader: confreader,
+         layout: 'form',
+         defaultType: 'textfield',
+         autoHeight: true,
 -        items: [language, dvbscanPath,
 -            tvhtimePanel,
 -            transcodingPanel]
++        items: [languageWrap, dvbscanWrap, tvhtimePanel, transcodingPanel]
+     });
+     var _items = [confpanel];
++
+     if (imagecache_form)
+         _items.push(imagecache_form);
++
+     var panel = new Ext.Panel({
+         title: 'General',
+         iconCls: 'wrench',
+         border: false,
+         bodyStyle: 'padding:15px',
+         layout: 'form',
+         items: _items,
+         tbar: [saveButton, '->', helpButton]
+     });
+     /* ****************************************************************
 -     * Load/Save
 -     * ***************************************************************/
++    * Load/Save
++    * ***************************************************************/
+     confpanel.on('render', function() {
+         confpanel.getForm().load({
+             url: 'config',
+             params: {
+                 op: 'loadSettings'
+             },
+             success: function(form, action) {
+                 confpanel.enable();
+             }
+         });
+         if (imagecache_form)
+             imagecache_form.getForm().load({
+                 url: 'api/imagecache/config/load',
+                 success: function(form, action) {
+                     imagecache_form.enable();
+                 },
+                 failure: function(form, action) {
+                     alert("FAILED");
+                 }
+             });
+     });
+     function saveChanges() {
+         confpanel.getForm().submit({
+             url: 'config',
+             params: {
+                 op: 'saveSettings'
+             },
+             waitMsg: 'Saving Data...',
+             failure: function(form, action) {
+                 Ext.Msg.alert('Save failed', action.result.errormsg);
+             }
+         });
+         if (imagecache_form)
+             imagecache_form.getForm().submit({
+                 url: 'api/imagecache/config/save',
+                 waitMsg: 'Saving data...',
+                 failure: function(form, action) {
+                     Ext.Msg.alert('Imagecache save failed', action.result.errormsg);
+                 }
+             });
+     }
  
-       return panel;
- }
+     return panel;
+ };
index 2ccf5574797ea32bbb7061ea0f0496d59c4e6f81,eddf34b0398e43f41788474a4c01072692a12797..305b907213210f68187be599f7ccd1e1d09ef368
@@@ -7,39 -7,39 +7,37 @@@ tvheadend.weekdays = new Ext.data.Simpl
  
  //This should be loaded from tvheadend
  tvheadend.dvrprio = new Ext.data.SimpleStore({
-       fields : [ 'identifier', 'name' ],
-       id : 0,
-       data : [ [ 'important', 'Important' ], [ 'high', 'High' ],
-               [ 'normal', 'Normal' ], [ 'low', 'Low' ],
-               [ 'unimportant', 'Unimportant' ] ]
+     fields: ['identifier', 'name'],
+     id: 0,
+     data: [['important', 'Important'], ['high', 'High'],
+         ['normal', 'Normal'], ['low', 'Low'],
+         ['unimportant', 'Unimportant']]
  });
  
--
  //For the container configuration
  tvheadend.containers = new Ext.data.JsonStore({
-       autoLoad : true,
-       root : 'entries',
-       fields : [ 'name', 'description' ],
-       id : 'name',
-       url : 'dvr_containers',
-       baseParams : {
-               op : 'list'
-       }
+     autoLoad: true,
+     root: 'entries',
+     fields: ['name', 'description'],
+     id: 'name',
+     url: 'dvr_containers',
+     baseParams: {
+         op: 'list'
+     }
  });
  
  //For the cache configuration
  tvheadend.caches = new Ext.data.JsonStore({
-       autoLoad : true,
-       root : 'entries',
-       fields : [ 'index', 'description' ],
-       id : 'name',
-       url : 'dvr_caches',
-       baseParams : {
-               op : 'list'
-       }
+     autoLoad: true,
+     root: 'entries',
+     fields: ['index', 'description'],
+     id: 'name',
+     url: 'dvr_caches',
+     baseParams: {
+         op: 'list'
+     }
  });
  
--
  /**
   * Configuration names
   */
@@@ -162,300 -160,271 +158,299 @@@ tvheadend.dvrDetails = function(entry) 
   */
  tvheadend.dvrschedule = function(title, iconCls, dvrStore) {
  
-       var actions = new Ext.ux.grid.RowActions({
-               header : '',
-               dataIndex : 'actions',
-               width : 45,
-               actions : [ {
-                       iconIndex : 'schedstate'
-               } ]
-       });
-       function renderDate(value) {
-               var dt = new Date(value);
-               return dt.format('D j M H:i');
-       }
-       function renderDuration(value) {
-               value = value / 60; /* Nevermind the seconds */
-               if (value >= 60) {
-                       var min = parseInt(value % 60);
-                       var hours = parseInt(value / 60);
-                       if (min == 0) {
-                               return hours + ' hrs';
-                       }
-                       return hours + ' hrs, ' + min + ' min';
-               }
-               else {
-                       return parseInt(value) + ' min';
-               }
-       }
-       function renderSize(value)
-       {
-               if (value == null)
-                       return '';
-               return parseInt(value / 1000000) + ' MB';
-       }
-       function renderPri(value) {
-               return tvheadend.dvrprio.getById(value).data.name;
-       }
-       var dvrCm = new Ext.grid.ColumnModel([ actions, {
-               width : 250,
-               id : 'title',
-               header : "Title",
-               dataIndex : 'title'
-       }, {
-               width : 100,
-               id : 'episode',
-               header : "Episode",
-               dataIndex : 'episode'
-       }, {
-               width : 100,
-               id : 'pri',
-               header : "Priority",
-               dataIndex : 'pri',
-               renderer : renderPri,
-               hidden : iconCls != 'clock',
-       }, {
-               width : 100,
-               id : 'start',
-               header : iconCls == 'clock' ? "Start" : "Date/Time",
-               dataIndex : 'start',
-               renderer : renderDate
-       }, {
-               width : 100,
-               hidden : true,
-               id : 'end',
-               header : "End",
-               dataIndex : 'end',
-               renderer : renderDate
-       }, {
-               width : 100,
-               id : 'duration',
-               header : "Duration",
-               dataIndex : 'duration',
-               renderer : renderDuration
-       }, {
-               width : 100,
-               id : 'filesize',
-               header : "Filesize",
-               dataIndex : 'filesize',
-               renderer : renderSize,
-               hidden : iconCls != 'television'
-       }, {
-               width : 250,
-               id : 'channel',
-               header : "Channel",
-               dataIndex : 'channel'
-       }, {
-               width : 200,
-               id : 'creator',
-               header : "Created by",
-               hidden : true,
-               dataIndex : 'creator'
-       }, {
-               width : 200,
-               id : 'config_name',
-               header : "DVR Configuration",
-               renderer : function(value, metadata, record, row, col, store) {
-                       if (!value) {
-                               return '<span class="tvh-grid-unset">(default)</span>';
-                       }
-                       else {
-                               return value;
-                       }
-               },
-               dataIndex : 'config_name',
-               hidden: iconCls != 'clock'
-       }, {
-               width : 200,
-               id : 'status',
-               header : "Status",
-               dataIndex : 'status',
-               hidden: iconCls != 'exclamation'
-       } ]);
-       function addEntry() {
-               function createRecording() {
-                       panel.getForm().submit({
-                               params : {
-                                       'op' : 'createEntry'
-                               },
-                               url : 'dvr/addentry',
-                               waitMsg : 'Creating entry...',
-                               failure : function(response, options) {
-                                       Ext.MessageBox.alert('Server Error', 'Unable to create entry');
-                               },
-                               success : function() {
-                                       win.close();
-                               }
-                       });
-               }
-               var panel = new Ext.FormPanel({
-                       frame : true,
-                       border : true,
-                       bodyStyle : 'padding:5px',
-                       labelAlign : 'right',
-                       labelWidth : 110,
-                       defaultType : 'textfield',
-                       items : [ new Ext.form.ComboBox({
-                               fieldLabel : 'Channel',
-                               name : 'channel',
-                               hiddenName : 'channelid',
-                               editable : false,
-                               allowBlank : false,
-                               displayField : 'val',
-                               valueField : 'key',
-                               mode : 'remote',
-                               triggerAction : 'all',
-                               store : tvheadend.channels
-                       }), new Ext.form.DateField({
-                               allowBlank : false,
-                               fieldLabel : 'Date',
-                               name : 'date'
-                       }), new Ext.form.TimeField({
-                               allowBlank : false,
-                               fieldLabel : 'Start time',
-                               name : 'starttime',
-                               increment : 10,
-                               format : 'H:i'
-                       }), new Ext.form.TimeField({
-                               allowBlank : false,
-                               fieldLabel : 'Stop time',
-                               name : 'stoptime',
-                               increment : 10,
-                               format : 'H:i'
-                       }), new Ext.form.ComboBox({
-                               store : tvheadend.dvrprio,
-                               value : "normal",
-                               triggerAction : 'all',
-                               mode : 'local',
-                               fieldLabel : 'Priority',
-                               valueField : 'identifier',
-                               displayField : 'name',
-                               name : 'pri'
-                       }), {
-                               allowBlank : false,
-                               fieldLabel : 'Title',
-                               name : 'title'
-                       }, new Ext.form.ComboBox({
-                               store : tvheadend.configNames,
-                               triggerAction : 'all',
-                               mode : 'local',
-                               fieldLabel : 'DVR Configuration',
-                               valueField : 'identifier',
-                               displayField : 'name',
-                               name : 'config_name',
-                               emptyText : '(default)',
-                               value : '',
-                               editable : false
-                       }) ],
-                       buttons : [ {
-                               text : 'Create',
-                               handler : createRecording
-                       } ]
-               });
-               win = new Ext.Window({
-                       title : 'Add single recording',
-                       layout : 'fit',
-                       width : 500,
-                       height : 300,
-                       plain : true,
-                       items : panel
-               });
-               win.show();
-               new Ext.form.ComboBox({
-                       store : tvheadend.configNames,
-                       triggerAction : 'all',
-                       mode : 'local',
-                       fieldLabel : 'DVR Configuration',
-                       valueField : 'identifier',
-                       displayField : 'name',
-                       name : 'config_name',
-                       emptyText : '(default)',
-                       value : '',
-                       editable : false
-               })
-       }
-       ;
+     var actions = new Ext.ux.grid.RowActions({
+         header: '',
+         dataIndex: 'actions',
+         width: 45,
+         actions: [{
+                 iconIndex: 'schedstate'
+             }]
+     });
+     function renderDate(value) {
+         var dt = new Date(value);
+         return dt.format('D j M H:i');
+     }
+     function renderDuration(value) {
+         value = value / 60; /* Nevermind the seconds */
+         if (value >= 60) {
+             var min = parseInt(value % 60);
+             var hours = parseInt(value / 60);
+             if (min === 0) {
+                 return hours + ' hrs';
+             }
+             return hours + ' hrs, ' + min + ' min';
+         }
+         else {
+             return parseInt(value) + ' min';
+         }
+     }
+     function renderSize(value)
+     {
+         if (value == null)
+             return '';
+         return parseInt(value / 1000000) + ' MB';
+     }
+     function renderPri(value) {
+         return tvheadend.dvrprio.getById(value).data.name;
+     }
+     var dvrCm = new Ext.grid.ColumnModel([actions, {
+             width: 250,
+             id: 'title',
+             header: "Title",
+             dataIndex: 'title'
+         }, {
+             width: 100,
+             id: 'episode',
+             header: "Episode",
+             dataIndex: 'episode'
+         }, {
+             width: 100,
+             id: 'pri',
+             header: "Priority",
+             dataIndex: 'pri',
+             renderer: renderPri,
+             hidden: iconCls !== 'clock'
+         }, {
+             width: 100,
+             id: 'start',
+             header: iconCls === 'clock' ? "Start" : "Date/Time",
+             dataIndex: 'start',
+             renderer: renderDate
+         }, {
+             width: 100,
+             hidden: true,
+             id: 'end',
+             header: "End",
+             dataIndex: 'end',
+             renderer: renderDate
+         }, {
+             width: 100,
+             id: 'duration',
+             header: "Duration",
+             dataIndex: 'duration',
+             renderer: renderDuration
+         }, {
+             width: 100,
+             id: 'filesize',
+             header: "Filesize",
+             dataIndex: 'filesize',
+             renderer: renderSize,
+             hidden: iconCls !== 'television'
+         }, {
+             width: 250,
+             id: 'channel',
+             header: "Channel",
+             dataIndex: 'channel'
+         }, {
+             width: 200,
+             id: 'creator',
+             header: "Created by",
+             hidden: true,
+             dataIndex: 'creator'
+         }, {
+             width: 200,
+             id: 'config_name',
+             header: "DVR Configuration",
+             renderer: function(value, metadata, record, row, col, store) {
+                 if (!value) {
+                     return '<span class="tvh-grid-unset">(default)</span>';
+                 }
+                 else {
+                     return value;
+                 }
+             },
+             dataIndex: 'config_name',
+             hidden: iconCls !== 'clock'
+         }, {
+             width: 200,
+             id: 'status',
+             header: "Status",
+             dataIndex: 'status',
+             hidden: iconCls !== 'exclamation'
+         }]);
+     function addEntry() {
+         function createRecording() {
+             panel.getForm().submit({
+                 params: {
+                     'op': 'createEntry'
+                 },
+                 url: 'dvr/addentry',
+                 waitMsg: 'Creating entry...',
+                 failure: function(response, options) {
+                     Ext.MessageBox.alert('Server Error', 'Unable to create entry');
+                 },
+                 success: function() {
+                     win.close();
+                 }
+             });
+         }
+         var panel = new Ext.FormPanel({
+             frame: true,
+             border: true,
+             bodyStyle: 'padding:5px',
+             labelAlign: 'right',
+             labelWidth: 110,
+             defaultType: 'textfield',
+             items: [new Ext.form.ComboBox({
+                     fieldLabel: 'Channel',
+                     name: 'channel',
+                     hiddenName: 'channelid',
+                     editable: false,
+                     allowBlank: false,
+                     displayField: 'val',
+                     valueField: 'key',
+                     mode: 'remote',
+                     triggerAction: 'all',
+                     store: tvheadend.channels
+                 }), new Ext.form.DateField({
+                     allowBlank: false,
+                     fieldLabel: 'Date',
+                     name: 'date'
+                 }), new Ext.form.TimeField({
+                     allowBlank: false,
+                     fieldLabel: 'Start time',
+                     name: 'starttime',
+                     increment: 10,
+                     format: 'H:i'
+                 }), new Ext.form.TimeField({
+                     allowBlank: false,
+                     fieldLabel: 'Stop time',
+                     name: 'stoptime',
+                     increment: 10,
+                     format: 'H:i'
+                 }), new Ext.form.ComboBox({
+                     store: tvheadend.dvrprio,
+                     value: "normal",
+                     triggerAction: 'all',
+                     mode: 'local',
+                     fieldLabel: 'Priority',
+                     valueField: 'identifier',
+                     displayField: 'name',
+                     name: 'pri'
+                 }), {
+                     allowBlank: false,
+                     fieldLabel: 'Title',
+                     name: 'title'
+                 }, new Ext.form.ComboBox({
+                     store: tvheadend.configNames,
+                     triggerAction: 'all',
+                     mode: 'local',
+                     fieldLabel: 'DVR Configuration',
+                     valueField: 'identifier',
+                     displayField: 'name',
+                     name: 'config_name',
+                     emptyText: '(default)',
+                     value: '',
+                     editable: false
+                 })],
+             buttons: [{
+                     text: 'Create',
+                     handler: createRecording
+                 }]
 -
+         });
+         win = new Ext.Window({
+             title: 'Add single recording',
+             layout: 'fit',
+             width: 500,
+             height: 300,
+             plain: true,
+             items: panel
+         });
+         win.show();
+         new Ext.form.ComboBox({
+             store: tvheadend.configNames,
+             triggerAction: 'all',
+             mode: 'local',
+             fieldLabel: 'DVR Configuration',
+             valueField: 'identifier',
+             displayField: 'name',
+             name: 'config_name',
+             emptyText: '(default)',
+             value: '',
+             editable: false
+         });
+     }
+     ;
  
-       var itemPageCombo = new Ext.form.ComboBox({
-           name : 'itemsperpage',
-               width: 50,
-               mode : 'local',
-               store: new Ext.data.ArrayStore({
-                       fields: ['perpage'],
-                       data  : [ ['10'], ['20'], ['30'], ['40'], ['50'], ['60'], ['70'], ['80'], ['90'], ['100']       ]
-               }),
-               value : '20',
-               listWidth : 40,
-               triggerAction : 'all',
-               displayField : 'perpage',
-               valueField : 'perpage',
-               editable : true,
-               forceSelection : true,
-               listeners : {
-                       scope: this,
-                       'select' : function(combo, record) {
-                           bbar.pageSize = parseInt(record.get('perpage'), 10);
-                               bbar.doLoad(bbar.cursor);
-                       }
-               }
-       });
 +    /* Create combobox to allow user to select page size for upcoming/completed/failed recordings */
 +
-       var bbar = new Ext.PagingToolbar({
-               store : dvrStore,
-               displayInfo : true,
-               items   :    [ '-',     'Recordings per page: ', itemPageCombo  ],
-               displayMsg : 'Programs {0} - {1} of {2}',
-               emptyMsg : "No programs to display"
-       });
-       var panel = new Ext.grid.GridPanel({
-               loadMask : true,
-               stripeRows : true,
-               disableSelection : true,
-               title : title,
-               iconCls : iconCls,
-               store : dvrStore,
-               cm : dvrCm,
-               plugins : [ actions ],
-               viewConfig : {
-                       forceFit : true
-               },
-               tbar : [ {
-                       tooltip : 'Schedule a new recording session on the server.',
-                       iconCls : 'add',
-                       text : 'Add entry',
-                       handler : addEntry
-               }, '->', {
-                       text : 'Help',
-                       handler : function() {
-                               new tvheadend.help('Digital Video Recorder', 'dvrlog.html');
-                       }
-               } ],
-               bbar : bbar
-       });
-       panel.on('rowclick', rowclicked);
-       function rowclicked(grid, index) {
-               new tvheadend.dvrDetails(grid.getStore().getAt(index).data);
-       }
-       return panel;
- }
++    var itemPageCombo = new Ext.form.ComboBox({
++        name : 'itemsperpage',
++        width: 50,
++        mode : 'local',
++        store: new Ext.data.ArrayStore({
++            fields: ['perpage'],
++            data  : [['10'],['20'],['30'],['40'],['50'],['60'],['70'],['80'],['90'],['100']]
++        }),
++        value : '20',
++        listWidth : 40,
++        triggerAction : 'all',
++        displayField : 'perpage',
++        valueField : 'perpage',
++        editable : true,
++        forceSelection : true,
++        listeners : {
++            scope: this,
++            'select' : function(combo, record) {
++                bbar.pageSize = parseInt(record.get('perpage'), 10);
++                bbar.doLoad(bbar.cursor);
++            }
++        }
++    });
 +
 +    /* Bottom toolbar to include default previous/goto-page/next and refresh buttons, also number-of-items combobox */
 +    
 -        bbar: new Ext.PagingToolbar({
 -            store: dvrStore,
 -            pageSize: 20,
 -            displayInfo: true,
 -            displayMsg: 'Programs {0} - {1} of {2}',
 -            emptyMsg: "No programs to display"
 -        })
 -
++    var bbar = new Ext.PagingToolbar({
++        store : dvrStore,
++        displayInfo : true,
++        items : ['-','Recordings per page: ',itemPageCombo],
++        displayMsg : 'Programs {0} - {1} of {2}',
++        emptyMsg : "No programs to display"
++    });
++
+     var panel = new Ext.grid.GridPanel({
+         loadMask: true,
+         stripeRows: true,
+         disableSelection: true,
+         title: title,
+         iconCls: iconCls,
+         store: dvrStore,
+         cm: dvrCm,
+         plugins: [actions],
+         viewConfig: {
+             forceFit: true
+         },
+         tbar: [{
+                 tooltip: 'Schedule a new recording session on the server.',
+                 iconCls: 'add',
+                 text: 'Add entry',
+                 handler: addEntry
+             }, '->', {
+                 text: 'Help',
+                 handler: function() {
+                     new tvheadend.help('Digital Video Recorder', 'dvrlog.html');
+                 }
+             }],
++        bbar: bbar
+     });
+     panel.on('rowclick', rowclicked);
+     function rowclicked(grid, index) {
+         new tvheadend.dvrDetails(grid.getStore().getAt(index).data);
+     }
+     return panel;
+ };
  
  /**
   *
   *
   */
  tvheadend.autoreceditor = function() {
-       var fm = Ext.form;
-       var cm = new Ext.grid.ColumnModel({
-   defaultSortable: true,
-   columns :
-         [
-             {
-               header: 'Enabled',
-               dataIndex: 'enabled',
-               width: 30,
-               xtype: 'checkcolumn'
-             },
-                       {
-                               header : "Title (Regexp)",
-                               dataIndex : 'title',
-                               editor : new fm.TextField({
-                                       allowBlank : true
-                               })
-                       },
-                       {
-                               header : "Channel",
-                               dataIndex : 'channel',
-                               editor : new Ext.form.ComboBox({
-                                       loadingText : 'Loading...',
-                                       displayField : 'val',
-                                         valueField: 'key',
-                                       store : tvheadend.channels,
-                                       mode : 'local',
-                                       editable : false,
-                                       triggerAction : 'all',
-                                       emptyText : 'Only include channel...'
-                               }),
-                                 renderer : function (v, m, r) {
-                                   var i = tvheadend.channels.find('key', v);
-                                   if (i != -1)
-                                     v = tvheadend.channels.getAt(i).get('val')
-                                   return v
-                                 }
-                       },
-       {
-         header    : "SeriesLink",
-         dataIndex : 'serieslink',
-         renderer  : function(v) {
-           return v ? 'yes' : 'no';
-         }
-                       },
-                       {
-                               header : "Channel tag",
-                               dataIndex : 'tag',
-                               editor : new Ext.form.ComboBox({
-                                       displayField : 'name',
-                                       store : tvheadend.channelTags,
-                                       mode : 'local',
-                                       editable : false,
-                                       triggerAction : 'all',
-                                       emptyText : 'Only include tag...'
-                               })
-                       },
-                       {
-                               header : "Genre",
-                               dataIndex : 'contenttype',
-                               renderer : function(v) {
-                                       return tvheadend.contentGroupLookupName(v);
-                               },
-                               editor : new Ext.form.ComboBox({
-                                       valueField : 'code',
-                                       displayField : 'name',
-                                       store : tvheadend.ContentGroupStore,
-                                       mode : 'local',
-                                       editable : false,
-                                       triggerAction : 'all',
-                                       emptyText : 'Only include content...'
-                               })
-                       },
-                       {
-                               header : "Weekdays",
-                               dataIndex : 'weekdays',
-                               renderer : function(value, metadata, record, row, col, store) {
-                                         if (value.split) value = value.split(',')
-                                         if (value.length == 7) return 'All days';
-                                         if (value.length == 0 || value[0] == "") return 'No days';
-                                       ret = [];
-                                       tags = value;
-                                       for ( var i = 0; i < tags.length; i++) {
-                                               var tag = tvheadend.weekdays.getById(tags[i]);
-                                               if (typeof tag !== 'undefined') ret.push(tag.data.name);
-                                       }
-                                       return ret.join(', ');
-                               },
-                               editor : new Ext.ux.form.LovCombo({
-                                       store : tvheadend.weekdays,
-                                       mode : 'local',
-                                       valueField : 'identifier',
-                                       displayField : 'name'
-                               })
-                       }, {
-                               header : "Starting Around",
-                               dataIndex : 'approx_time',
-                               renderer : function(value, metadata, record, row, col, store) {
-                                       if (typeof value === 'string') return value;
-                                       if (value === 0) return '';
-                                       var hours = Math.floor(value / 60);
-                                       var mins = value % 60;
-                                       var dt = new Date();
-                                       dt.setHours(hours);
-                                       dt.setMinutes(mins);
-                                       return dt.format('H:i');
-                               },
-                               editor : new Ext.form.TimeField({
-                                       allowBlank : true,
-                                       increment : 10,
-                                       format : 'H:i'
-                               })
-                       }, {
-                               header : "Priority",
-                               dataIndex : 'pri',
-                               width : 100,
-                               renderer : function(value, metadata, record, row, col, store) {
-                                       return tvheadend.dvrprio.getById(value).data.name;
-                               },
-                               editor : new fm.ComboBox({
-                                       store : tvheadend.dvrprio,
-                                       triggerAction : 'all',
-                                       mode : 'local',
-                                       valueField : 'identifier',
-                                       displayField : 'name'
-                               })
-                       }, {
-                               header : "DVR Configuration",
-                               dataIndex : 'config_name',
-                               renderer : function(value, metadata, record, row, col, store) {
-                                       if (!value) {
-                                               return '<span class="tvh-grid-unset">(default)</span>';
-                                       }
-                                       else {
-                                               return value;
-                                       }
-                               },
-                               editor : new Ext.form.ComboBox({
-                                       store : tvheadend.configNames,
-                                       triggerAction : 'all',
-                                       mode : 'local',
-                                       valueField : 'identifier',
-                                       displayField : 'name',
-                                       name : 'config_name',
-                                       emptyText : '(default)',
-                                       editable : false
-                               })
-                       }, {
-                               header : "Created by",
-                               dataIndex : 'creator',
-                               editor : new fm.TextField({
-                                       allowBlank : false
-                               })
-                       }, {
-                               header : "Comment",
-                               dataIndex : 'comment',
-                               editor : new fm.TextField({
-                                       allowBlank : false
-                               })
-                       } ]});
-       return new tvheadend.tableEditor('Automatic Recorder', 'autorec', cm,
-               tvheadend.autorecRecord, [], tvheadend.autorecStore,
-               'autorec.html', 'wand');
- }
+     var fm = Ext.form;
 -
+     var cm = new Ext.grid.ColumnModel({
+         defaultSortable: true,
+         columns:
+                 [
+                     {
+                         header: 'Enabled',
+                         dataIndex: 'enabled',
+                         width: 30,
+                         xtype: 'checkcolumn'
+                     },
+                     {
+                         header: "Title (Regexp)",
+                         dataIndex: 'title',
+                         editor: new fm.TextField({
+                             allowBlank: true
+                         })
+                     },
+                     {
+                         header: "Channel",
+                         dataIndex: 'channel',
+                         editor: new Ext.form.ComboBox({
+                             loadingText: 'Loading...',
+                             displayField: 'val',
+                             valueField: 'key',
+                             store: tvheadend.channels,
+                             mode: 'local',
+                             editable: false,
+                             triggerAction: 'all',
+                             emptyText: 'Only include channel...'
+                         }),
+                         renderer: function(v, m, r) {
+                             var i = tvheadend.channels.find('key', v);
+                             if (i !== -1)
+                                 v = tvheadend.channels.getAt(i).get('val');
+                             return v;
+                         }
+                     },
+                     {
+                         header: "SeriesLink",
+                         dataIndex: 'serieslink',
+                         renderer: function(v) {
+                             return v ? 'yes' : 'no';
+                         }
+                     },
+                     {
+                         header: "Channel tag",
+                         dataIndex: 'tag',
+                         editor: new Ext.form.ComboBox({
+                             displayField: 'name',
+                             store: tvheadend.channelTags,
+                             mode: 'local',
+                             editable: false,
+                             triggerAction: 'all',
+                             emptyText: 'Only include tag...'
+                         })
+                     },
+                     {
+                         header: "Genre",
+                         dataIndex: 'contenttype',
+                         renderer: function(v) {
+                             return tvheadend.contentGroupLookupName(v);
+                         },
+                         editor: new Ext.form.ComboBox({
+                             valueField: 'code',
+                             displayField: 'name',
+                             store: tvheadend.ContentGroupStore,
+                             mode: 'local',
+                             editable: false,
+                             triggerAction: 'all',
+                             emptyText: 'Only include content...'
+                         })
+                     },
+                     {
+                         header: "Weekdays",
+                         dataIndex: 'weekdays',
+                         renderer: function(value, metadata, record, row, col, store) {
+                             if (value.split)
+                                 value = value.split(',');
+                             if (value.length === 7)
+                                 return 'All days';
+                             if (value.length === 0 || value[0] === "")
+                                 return 'No days';
+                             ret = [];
+                             tags = value;
+                             for (var i = 0; i < tags.length; i++) {
+                                 var tag = tvheadend.weekdays.getById(tags[i]);
+                                 if (typeof tag !== 'undefined')
+                                     ret.push(tag.data.name);
+                             }
+                             return ret.join(', ');
+                         },
+                         editor: new Ext.ux.form.LovCombo({
+                             store: tvheadend.weekdays,
+                             mode: 'local',
+                             valueField: 'identifier',
+                             displayField: 'name'
+                         })
+                     }, {
+                         header: "Starting Around",
+                         dataIndex: 'approx_time',
+                         renderer: function(value, metadata, record, row, col, store) {
+                             if (typeof value === 'string')
+                                 return value;
+                             if (value === 0)
+                                 return '';
+                             var hours = Math.floor(value / 60);
+                             var mins = value % 60;
+                             var dt = new Date();
+                             dt.setHours(hours);
+                             dt.setMinutes(mins);
+                             return dt.format('H:i');
+                         },
+                         editor: new Ext.form.TimeField({
+                             allowBlank: true,
+                             increment: 10,
+                             format: 'H:i'
+                         })
+                     }, {
+                         header: "Priority",
+                         dataIndex: 'pri',
+                         width: 100,
+                         renderer: function(value, metadata, record, row, col, store) {
+                             return tvheadend.dvrprio.getById(value).data.name;
+                         },
+                         editor: new fm.ComboBox({
+                             store: tvheadend.dvrprio,
+                             triggerAction: 'all',
+                             mode: 'local',
+                             valueField: 'identifier',
+                             displayField: 'name'
+                         })
+                     }, {
+                         header: "DVR Configuration",
+                         dataIndex: 'config_name',
+                         renderer: function(value, metadata, record, row, col, store) {
+                             if (!value) {
+                                 return '<span class="tvh-grid-unset">(default)</span>';
+                             }
+                             else {
+                                 return value;
+                             }
+                         },
+                         editor: new Ext.form.ComboBox({
+                             store: tvheadend.configNames,
+                             triggerAction: 'all',
+                             mode: 'local',
+                             valueField: 'identifier',
+                             displayField: 'name',
+                             name: 'config_name',
+                             emptyText: '(default)',
+                             editable: false
+                         })
+                     }, {
+                         header: "Created by",
+                         dataIndex: 'creator',
+                         editor: new fm.TextField({
+                             allowBlank: false
+                         })
+                     }, {
+                         header: "Comment",
+                         dataIndex: 'comment',
+                         editor: new fm.TextField({
+                             allowBlank: false
+                         })
+                     }]});
+     return new tvheadend.tableEditor('Automatic Recorder', 'autorec', cm,
+             tvheadend.autorecRecord, [], tvheadend.autorecStore,
+             'autorec.html', 'wand');
+ };
  /**
   *
   */
@@@ -771,359 -746,339 +771,359 @@@ tvheadend.dvr = function() 
   */
  tvheadend.dvrsettings = function() {
  
-       var confreader = new Ext.data.JsonReader({
-               root : 'dvrSettings'
-       }, [ 'storage', 'filePermissions', 'dirPermissions', 'postproc', 'retention', 'dayDirs', 'channelDirs',
-               'channelInTitle', 'container', 'cache', 'dateInTitle', 'timeInTitle',
-               'preExtraTime', 'postExtraTime', 'whitespaceInTitle', 'titleDirs',
-               'episodeInTitle', 'cleanTitle', 'tagFiles', 'commSkip', 'subtitleInTitle', 
-               'episodeBeforeDate', 'rewritePAT', 'rewritePMT' ]);
-       var confcombo = new Ext.form.ComboBox({
-               store : tvheadend.configNames,
-               triggerAction : 'all',
-               mode : 'local',
-               displayField : 'name',
-               name : 'config_name',
-               emptyText : '(default)',
-               value : '',
-               editable : true
-       });
-       var delButton = new Ext.Toolbar.Button({
-               tooltip : 'Delete named configuration',
-               iconCls : 'remove',
-               text : "Delete configuration",
-               handler : deleteConfiguration,
-               disabled : true
-       });
- /* Config panel variables */
- /* DVR Behaviour */
-       var recordingContainer = new Ext.form.ComboBox({
-               store : tvheadend.containers,
-               fieldLabel : 'Media container',
-               triggerAction : 'all',
-               displayField : 'description',
-               valueField : 'name',
-               editable : false,
-               width : 200,
-               hiddenName : 'container' 
-       });
-       
-       var cacheScheme = new Ext.form.ComboBox({
-               store : tvheadend.caches,
-               fieldLabel : 'Cache scheme',
-               triggerAction : 'all',
-               displayField : 'description',
-               valueField : 'index',
-               editable : false,
-               width : 200,
-               hiddenName : 'cache'
-       });
-       var logRetention = new Ext.form.NumberField({
-               allowNegative : false,
-               allowDecimals : false,
-               minValue : 1,
-               fieldLabel : 'DVR Log retention time (days)',
-               name : 'retention'
-       });
-       var timeBefore = new Ext.form.NumberField({
-               allowDecimals : false,
-               fieldLabel : 'Extra time before recordings (minutes)',
-               name : 'preExtraTime'
+     var confreader = new Ext.data.JsonReader({
+         root: 'dvrSettings'
+     }, ['storage', 'filePermissions', 'dirPermissions', 'postproc', 'retention', 'dayDirs', 'channelDirs',
+         'channelInTitle', 'container', 'cache', 'dateInTitle', 'timeInTitle',
+         'preExtraTime', 'postExtraTime', 'whitespaceInTitle', 'titleDirs',
+         'episodeInTitle', 'cleanTitle', 'tagFiles', 'commSkip', 'subtitleInTitle',
+         'episodeBeforeDate', 'rewritePAT', 'rewritePMT']);
+     var confcombo = new Ext.form.ComboBox({
+         store: tvheadend.configNames,
+         triggerAction: 'all',
+         mode: 'local',
+         displayField: 'name',
+         name: 'config_name',
+         emptyText: '(default)',
+         value: '',
+         editable: true
+     });
+     var delButton = new Ext.Toolbar.Button({
+         tooltip: 'Delete named configuration',
+         iconCls: 'remove',
+         text: "Delete configuration",
+         handler: deleteConfiguration,
+         disabled: true
+     });
    /* Config panel variables */
    /* DVR Behaviour */
+     var recordingContainer = new Ext.form.ComboBox({
+         store: tvheadend.containers,
+         fieldLabel: 'Media container',
+         triggerAction: 'all',
+         displayField: 'description',
+         valueField: 'name',
+         editable: false,
+         width: 200,
+         hiddenName: 'container'
+     });
+     var cacheScheme = new Ext.form.ComboBox({
+         store: tvheadend.caches,
+         fieldLabel: 'Cache scheme',
+         triggerAction: 'all',
+         displayField: 'description',
+         valueField: 'index',
+         editable: false,
+         width: 200,
+         hiddenName: 'cache'
+     });
+     var logRetention = new Ext.form.NumberField({
+         allowNegative: false,
+         allowDecimals: false,
+         minValue: 1,
+         fieldLabel: 'DVR Log retention time (days)',
+         name: 'retention'
+     });
+     var timeBefore = new Ext.form.NumberField({
+         allowDecimals: false,
+         fieldLabel: 'Extra time before recordings (minutes)',
+         name: 'preExtraTime'
      });
-         
      var timeAfter = new Ext.form.NumberField({
-         allowDecimals : false,
-         fieldLabel : 'Extra time after recordings (minutes)',
-         name : 'postExtraTime'
-       }); 
-       
-       var postProcessing = new Ext.form.TextField({
-               width : 300,
-               fieldLabel : 'Post-processor command',
-               name : 'postproc'
-       });
- /* Recording File Options */
-       var recordingPath = new Ext.form.TextField({
-               width : 300,
-               fieldLabel : 'Recording system path',
-               name : 'storage'
-       });
- /* NB: recordingPermissions is defined as a TextField for validation purposes (leading zeros), but is ultimately a number */
-       
-       var recordingPermissions = new Ext.form.TextField({
-               regex : /^[0][0-7]{3}$/,
-           maskRe : /[0-7]/,
-               width : 100,
-               allowBlank : false,
-               blankText : 'You must provide a value - use octal chmod notation, e.g. 0664',
-               fieldLabel : 'File permissions (octal, e.g. 0664)',
-               name : 'filePermissions'
-       });
- /* TO DO - Add 'override user umask?' option, then trigger fchmod in mkmux.c, muxer_pass.c after file created */
-               
-       var PATrewrite = new Ext.form.Checkbox({
-               fieldLabel : 'Rewrite PAT in passthrough mode',
-               name : 'rewritePAT'
-       });
-               
-       var PMTrewrite = new Ext.form.Checkbox({
-               fieldLabel : 'Rewrite PMT in passthrough mode',
-               name : 'rewritePMT'
-       }); 
-               
-       var tagMetadata = new Ext.form.Checkbox({
-               fieldLabel : 'Tag files with metadata',
-               name : 'tagFiles'
-       });
-                
-       var skipCommercials = new Ext.form.Checkbox({
-               fieldLabel : 'Skip commercials',
-               name : 'commSkip'
-       }); 
-               
- /* Subdirectories and filename handling */
- /* NB: directoryPermissions is defined as a TextField for validation purposes (leading zeros), but is ultimately a number */
-       var directoryPermissions = new Ext.form.TextField({
-               regex : /^[0][0-7]{3}$/,
-           maskRe : /[0-7]/,
-               width : 100,
-               allowBlank : false,
-               blankText : 'You must provide a value - use octal chmod notation, e.g. 0775',
-               fieldLabel : 'Directory permissions (octal, e.g. 0775)',
-               name : 'dirPermissions'
-       });
-       
- /* TO DO - Add 'override user umask?' option, then trigger fchmod in utils.c after directory created */
-       
-       var dirsPerDay = new Ext.form.Checkbox({
-               fieldLabel : 'Make subdirectories per day',
-               name : 'dayDirs'
-       }); 
-               
-       var dirsPerChannel = new Ext.form.Checkbox({
-               fieldLabel : 'Make subdirectories per channel',
-               name : 'channelDirs'
-       }); 
-               
-       var dirsPerTitle = new Ext.form.Checkbox({
-               fieldLabel : 'Make subdirectories per title',
-               name : 'titleDirs'
-       }); 
-               
-       var incChannelInTitle = new Ext.form.Checkbox({
-               fieldLabel : 'Include channel name in filename',
-               name : 'channelInTitle'
-       });
-               
-       var incDateInTitle = new Ext.form.Checkbox({
-               fieldLabel : 'Include date in filename',
-               name : 'dateInTitle'
-       });
-               
-       var incTimeInTitle = new Ext.form.Checkbox({
-               fieldLabel : 'Include time in filename',
-               name : 'timeInTitle'
-       });
-                
-       var incEpisodeInTitle = new Ext.form.Checkbox({
-               fieldLabel : 'Include episode in filename',
-               name : 'episodeInTitle'
-       });
-       
-       var incSubtitleInTitle = new Ext.form.Checkbox({
-               fieldLabel : 'Include subtitle in filename',
-               name : 'subtitleInTitle'
-       }); 
-       
-       var episodeFirst = new Ext.form.Checkbox({
-               fieldLabel : 'Put episode in filename before date and time',
-               name : 'episodeBeforeDate'
-       }); 
-       
-       var stripUnsafeChars = new Ext.form.Checkbox({
-               fieldLabel : 'Remove all unsafe characters from filename',
-               name : 'cleanTitle'
-       });
-                
-       var stripWhitespace = new Ext.form.Checkbox({
-               fieldLabel : 'Replace whitespace in title with \'-\'',
-               name : 'whitespaceInTitle'
-       }); 
-       
- /* Sub-Panel - DVR behaviour */
-               
-       var DVRBehaviour = new Ext.form.FieldSet({
-               title: 'DVR Behaviour',
-               width: 700,
-               autoHeight: true,
-               collapsible: true,
-               animCollapse : true,
-               items : [ recordingContainer, cacheScheme, logRetention, timeBefore, timeAfter, postProcessing ]
-       });
- /* Sub-Panel - File Output */
-       var FileOutputPanel = new Ext.form.FieldSet({
-               title: 'Recording File Options',
-               width: 700,
-               autoHeight: true,
-               collapsible: true,
-               animCollapse : true,
-               items : [ recordingPath, recordingPermissions, PATrewrite, PMTrewrite, tagMetadata, skipCommercials ]
-       });
- /* Sub-Panel - Directory operations */
-       var DirHandlingPanel = new Ext.form.FieldSet({
-               title: 'Subdirectory Options',
-               width: 700,
-               autoHeight: true,
-               collapsible: true,
-               animCollapse : true,
-               items : [ directoryPermissions, dirsPerDay, dirsPerChannel, dirsPerTitle ]
-       });
-               
- /* Sub-Panel - File operations - Break into two 4-item panels */
-       var FileHandlingPanelA = new Ext.form.FieldSet({
-               width: 350,
-               border: false,
-               autoHeight: true,
-               items : [ incChannelInTitle, incDateInTitle, incTimeInTitle, incEpisodeInTitle ]
-       });
-       var FileHandlingPanelB = new Ext.form.FieldSet({
-               width: 350,
-               border: false,
-               autoHeight: true,
-               items : [ incSubtitleInTitle, episodeFirst, stripUnsafeChars, stripWhitespace ]
-       });
-       var FileHandlingPanel = new Ext.form.FieldSet({
-               title: 'Filename Options',
-               width: 700,
-               autoHeight: true,
-               collapsible: true,
-               animCollapse : true,
-               items : [{ 
-                       layout: 'column', 
-                       border: false, 
-                       items : [ FileHandlingPanelA, FileHandlingPanelB ] 
-               }]
-       });
- /* Main (form) panel */
-                               
-       var confpanel = new Ext.FormPanel({
-               title : 'Digital Video Recorder',
-               iconCls : 'drive',
-               border : false,
-               bodyStyle : 'padding:15px',
-               anchor : '100% 50%',
-               labelAlign : 'right',
-               labelWidth : 250,
-               waitMsgTarget : true,
-               reader : confreader,
-               defaultType : 'textfield',
-               layout : 'form',
-               items : [ DVRBehaviour, FileOutputPanel, DirHandlingPanel, FileHandlingPanel ],
-               
-               tbar : [ confcombo, {
-                       tooltip : 'Save changes made to dvr configuration below',
-                       iconCls : 'save',
-                       text : "Save configuration",
-                       handler : saveChanges
-               }, delButton, '->', {
-                       text : 'Help',
-                       handler : function() {
-                               new tvheadend.help('DVR configuration', 'config_dvr.html');
-                       }
-               } ]
-       });
-       function loadConfig() {
-               confpanel.getForm().load({
-                       url : 'dvr',
-                       params : {
-                               'op' : 'loadSettings',
-                               'config_name' : confcombo.getValue()
-                       },
-                       success : function(form, action) {
-                               confpanel.enable();
-                       }
-               });
-       }
-       confcombo.on('select', function() {
-               if (confcombo.getValue() == '') delButton.disable();
-               else delButton.enable();
-               loadConfig();
-       });
-       confpanel.on('render', function() {
-               loadConfig();
-       });
-       function saveChanges() {
-               var config_name = confcombo.getValue();
-               confpanel.getForm().submit({
-                       url : 'dvr',
-                       params : {
-                               'op' : 'saveSettings',
-                               'config_name' : config_name
-                       },
-                       waitMsg : 'Saving Data...',
-                       success : function(form, action) {
-                               confcombo.setValue(config_name);
-                               confcombo.fireEvent('select');
-                       },
-                       failure : function(form, action) {
-                               Ext.Msg.alert('Save failed', action.result.errormsg);
-                       }
-               });
-       }
-       function deleteConfiguration() {
-               if (confcombo.getValue() != "") {
-                       Ext.MessageBox.confirm('Message',
-                               'Do you really want to delete DVR configuration \''
-                                       + confcombo.getValue() + '\'?', deleteAction);
-               }
-       }
-       function deleteAction(btn) {
-               if (btn == 'yes') {
-                       confpanel.getForm().submit({
-                               url : 'dvr',
-                               params : {
-                                       'op' : 'deleteSettings',
-                                       'config_name' : confcombo.getValue()
-                               },
-                               waitMsg : 'Deleting Data...',
-                               success : function(form, action) {
-                                       confcombo.setValue('');
-                                       confcombo.fireEvent('select');
-                               },
-                               failure : function(form, action) {
-                                       Ext.Msg.alert('Delete failed', action.result.errormsg);
-                               }
-                       });
-               }
-       }
-       return confpanel;
- }
+         allowDecimals: false,
+         fieldLabel: 'Extra time after recordings (minutes)',
+         name: 'postExtraTime'
+     });
+     var postProcessing = new Ext.form.TextField({
+         width: 300,
+         fieldLabel: 'Post-processor command',
+         name: 'postproc'
+     });
+     /* Recording File Options */
+     var recordingPath = new Ext.form.TextField({
+         width: 300,
+         fieldLabel: 'Recording system path',
+         name: 'storage'
+     });
+     /* NB: recordingPermissions is defined as a TextField for validation purposes (leading zeros), but is ultimately a number */
+     var recordingPermissions = new Ext.form.TextField({
+         regex: /^[0][0-7]{3}$/,
+         maskRe: /[0-7]/,
+         width: 100,
+         allowBlank: false,
+         blankText: 'You must provide a value - use octal chmod notation, e.g. 0664',
+         fieldLabel: 'File permissions (octal, e.g. 0664)',
+         name: 'filePermissions'
+     });
+     /* TO DO - Add 'override user umask?' option, then trigger fchmod in mkmux.c, muxer_pass.c after file created */
+     var PATrewrite = new Ext.form.Checkbox({
+         fieldLabel: 'Rewrite PAT in passthrough mode',
+         name: 'rewritePAT'
+     });
+     var PMTrewrite = new Ext.form.Checkbox({
+         fieldLabel: 'Rewrite PMT in passthrough mode',
+         name: 'rewritePMT'
+     });
+     var tagMetadata = new Ext.form.Checkbox({
+         fieldLabel: 'Tag files with metadata',
+         name: 'tagFiles'
+     });
+     var skipCommercials = new Ext.form.Checkbox({
+         fieldLabel: 'Skip commercials',
+         name: 'commSkip'
+     });
+     /* Subdirectories and filename handling */
+     /* NB: directoryPermissions is defined as a TextField for validation purposes (leading zeros), but is ultimately a number */
+     var directoryPermissions = new Ext.form.TextField({
+         regex: /^[0][0-7]{3}$/,
+         maskRe: /[0-7]/,
+         width: 100,
+         allowBlank: false,
+         blankText: 'You must provide a value - use octal chmod notation, e.g. 0775',
+         fieldLabel: 'Directory permissions (octal, e.g. 0775)',
+         name: 'dirPermissions'
+     });
+     /* TO DO - Add 'override user umask?' option, then trigger fchmod in utils.c after directory created */
+     var dirsPerDay = new Ext.form.Checkbox({
+         fieldLabel: 'Make subdirectories per day',
+         name: 'dayDirs'
+     });
+     var dirsPerChannel = new Ext.form.Checkbox({
+         fieldLabel: 'Make subdirectories per channel',
+         name: 'channelDirs'
+     });
+     var dirsPerTitle = new Ext.form.Checkbox({
+         fieldLabel: 'Make subdirectories per title',
+         name: 'titleDirs'
+     });
+     var incChannelInTitle = new Ext.form.Checkbox({
+         fieldLabel: 'Include channel name in filename',
+         name: 'channelInTitle'
+     });
+     var incDateInTitle = new Ext.form.Checkbox({
+         fieldLabel: 'Include date in filename',
+         name: 'dateInTitle'
+     });
+     var incTimeInTitle = new Ext.form.Checkbox({
+         fieldLabel: 'Include time in filename',
+         name: 'timeInTitle'
+     });
+     var incEpisodeInTitle = new Ext.form.Checkbox({
+         fieldLabel: 'Include episode in filename',
+         name: 'episodeInTitle'
+     });
+     var incSubtitleInTitle = new Ext.form.Checkbox({
+         fieldLabel: 'Include subtitle in filename',
+         name: 'subtitleInTitle'
+     });
+     var episodeFirst = new Ext.form.Checkbox({
+         fieldLabel: 'Put episode in filename before date and time',
+         name: 'episodeBeforeDate'
+     });
+     var stripUnsafeChars = new Ext.form.Checkbox({
+         fieldLabel: 'Remove all unsafe characters from filename',
+         name: 'cleanTitle'
+     });
+     var stripWhitespace = new Ext.form.Checkbox({
+         fieldLabel: 'Replace whitespace in title with \'-\'',
+         name: 'whitespaceInTitle'
+     });
 -
+     /* Sub-Panel - DVR behaviour */
+     var DVRBehaviour = new Ext.form.FieldSet({
+         title: 'DVR Behaviour',
+         width: 700,
+         autoHeight: true,
+         collapsible: true,
++        animCollapse: true,
+         items: [recordingContainer, cacheScheme, logRetention, timeBefore, timeAfter, postProcessing]
+     });
+     /* Sub-Panel - File Output */
+     var FileOutputPanel = new Ext.form.FieldSet({
+         title: 'Recording File Options',
+         width: 700,
+         autoHeight: true,
+         collapsible: true,
++        animCollapse: true,
+         items: [recordingPath, recordingPermissions, PATrewrite, PMTrewrite, tagMetadata, skipCommercials]
+     });
+     /* Sub-Panel - Directory operations */
+     var DirHandlingPanel = new Ext.form.FieldSet({
+         title: 'Subdirectory Options',
+         width: 700,
+         autoHeight: true,
+         collapsible: true,
++        animCollapse: true,
+         items: [directoryPermissions, dirsPerDay, dirsPerChannel, dirsPerTitle]
+     });
 -    /* Sub-Panel - File operations */
++    /* Sub-Panel - File operations - Break into two 4-item panels */
++
++    var FileHandlingPanelA = new Ext.form.FieldSet({
++        width: 350,
++        border: false,
++        autoHeight: true,
++        items : [incChannelInTitle, incDateInTitle, incTimeInTitle, incEpisodeInTitle]
++    });
++
++    var FileHandlingPanelB = new Ext.form.FieldSet({
++        width: 350,
++        border: false,
++        autoHeight: true,
++        items : [incSubtitleInTitle, episodeFirst, stripUnsafeChars, stripWhitespace]
++    });
+     var FileHandlingPanel = new Ext.form.FieldSet({
+         title: 'Filename Options',
+         width: 700,
+         autoHeight: true,
+         collapsible: true,
 -        items: [incChannelInTitle, incDateInTitle, incTimeInTitle, incEpisodeInTitle,
 -            incSubtitleInTitle, episodeFirst, stripUnsafeChars, stripWhitespace]
++        animCollapse : true,
++        items : [{
++            layout: 'column',
++            border: false,
++            items : [FileHandlingPanelA, FileHandlingPanelB] 
++        }]
+     });
+     /* Main (form) panel */
+     var confpanel = new Ext.FormPanel({
+         title: 'Digital Video Recorder',
+         iconCls: 'drive',
+         border: false,
+         bodyStyle: 'padding:15px',
+         anchor: '100% 50%',
+         labelAlign: 'right',
+         labelWidth: 250,
+         waitMsgTarget: true,
+         reader: confreader,
+         defaultType: 'textfield',
+         layout: 'form',
+         items: [DVRBehaviour, FileOutputPanel, DirHandlingPanel, FileHandlingPanel],
+         tbar: [confcombo, {
+                 tooltip: 'Save changes made to dvr configuration below',
+                 iconCls: 'save',
+                 text: "Save configuration",
+                 handler: saveChanges
+             }, delButton, '->', {
+                 text: 'Help',
+                 handler: function() {
+                     new tvheadend.help('DVR configuration', 'config_dvr.html');
+                 }
+             }]
+     });
+     function loadConfig() {
+         confpanel.getForm().load({
+             url: 'dvr',
+             params: {
+                 'op': 'loadSettings',
+                 'config_name': confcombo.getValue()
+             },
+             success: function(form, action) {
+                 confpanel.enable();
+             }
+         });
+     }
+     confcombo.on('select', function() {
+         if (confcombo.getValue() === '')
+             delButton.disable();
+         else
+             delButton.enable();
+         loadConfig();
+     });
+     confpanel.on('render', function() {
+         loadConfig();
+     });
+     function saveChanges() {
+         var config_name = confcombo.getValue();
+         confpanel.getForm().submit({
+             url: 'dvr',
+             params: {
+                 'op': 'saveSettings',
+                 'config_name': config_name
+             },
+             waitMsg: 'Saving Data...',
+             success: function(form, action) {
+                 confcombo.setValue(config_name);
+                 confcombo.fireEvent('select');
+             },
+             failure: function(form, action) {
+                 Ext.Msg.alert('Save failed', action.result.errormsg);
+             }
+         });
+     }
+     function deleteConfiguration() {
+         if (confcombo.getValue() !== "") {
+             Ext.MessageBox.confirm('Message',
+                     'Do you really want to delete DVR configuration \''
+                     + confcombo.getValue() + '\'?', deleteAction);
+         }
+     }
+     function deleteAction(btn) {
+         if (btn === 'yes') {
+             confpanel.getForm().submit({
+                 url: 'dvr',
+                 params: {
+                     'op': 'deleteSettings',
+                     'config_name': confcombo.getValue()
+                 },
+                 waitMsg: 'Deleting Data...',
+                 success: function(form, action) {
+                     confcombo.setValue('');
+                     confcombo.fireEvent('select');
+                 },
+                 failure: function(form, action) {
+                     Ext.Msg.alert('Delete failed', action.result.errormsg);
+                 }
+             });
+         }
+     }
+     return confpanel;
+ };
index 1a6c15896123b6a6442a721efa5c93cb7b7d94a9,472312ebb5c43aab3aa8743241813707b8e052bb..9e03c43ae5de92b8de119b209ef6572d0ac62113
  tvheadend.timeshift = function() {
  
-   /* ****************************************************************
-    * Data
-    * ***************************************************************/
-   var confreader = new Ext.data.JsonReader(
-     {
-       root: 'config'
-     },
+     /* ****************************************************************
+      * Data
+      * ***************************************************************/
+     var confreader = new Ext.data.JsonReader(
+             {
+                 root: 'config'
+             },
      [
-       'timeshift_enabled', 'timeshift_ondemand',
-       'timeshift_path',
-       'timeshift_unlimited_period', 'timeshift_max_period',
-       'timeshift_unlimited_size', 'timeshift_max_size'
+         'timeshift_enabled', 'timeshift_ondemand',
+         'timeshift_path',
+         'timeshift_unlimited_period', 'timeshift_max_period',
+         'timeshift_unlimited_size', 'timeshift_max_size'
      ]
-   );
+             );
 -
 +  
-   /* ****************************************************************
-    * Fields
-    * ***************************************************************/
-   var timeshiftEnabled = new Ext.form.Checkbox({
-     fieldLabel: 'Enabled',
-     name: 'timeshift_enabled',
-     width: 300
-   });
-   var timeshiftOndemand = new Ext.form.Checkbox({
-     fieldLabel: 'On-Demand',
-     name: 'timeshift_ondemand',
-     width: 300
-   });
-   var timeshiftPath = new Ext.form.TextField({
-     fieldLabel: 'Storage Path',
-     name: 'timeshift_path',
-     allowBlank: true,
-     width: 300
-   });
-   var timeshiftMaxPeriod = new Ext.form.NumberField({
-     fieldLabel: 'Max. Period (mins)',
-     name: 'timeshift_max_period',
-     allowBlank: false,
-     width: 300
-   });
-   var timeshiftUnlPeriod = new Ext.form.Checkbox({
-     fieldLabel: 'Unlimited time',
-     name: 'timeshift_unlimited_period',
-     Width: 300
-   });
-   var timeshiftMaxSize = new Ext.form.NumberField({
-     fieldLabel: 'Max. Size (MB)',
-     name: 'timeshift_max_size',
-     allowBlank: false,
-     width: 300
-   });
-   var timeshiftUnlSize = new Ext.form.Checkbox({
-     fieldLabel: 'Unlimited size',
-     name: 'timeshift_unlimited_size',
-     Width: 300
-   });
-   /* ****************************************************************
-    * Events
-    * ***************************************************************/
-   timeshiftUnlPeriod.on('check', function(e, c){
-     timeshiftMaxPeriod.setDisabled(c);
-   });
-   timeshiftUnlSize.on('check', function(e, c){
-     timeshiftMaxSize.setDisabled(c);
-   });
-   /* ****************************************************************
-    * Form
-    * ***************************************************************/
-   var saveButton = new Ext.Button({
-     text : "Save configuration",
-     tooltip : 'Save changes made to configuration below',
-     iconCls : 'save',
-     handler : saveChanges
-   });
-   var helpButton = new Ext.Button({
-     text : 'Help',
-     handler : function() {
-       new tvheadend.help('Timeshift Configuration', 'config_timeshift.html');
+     /* ****************************************************************
+      * Fields
+      * ***************************************************************/
+     var timeshiftEnabled = new Ext.form.Checkbox({
+         fieldLabel: 'Enabled',
+         name: 'timeshift_enabled',
+         width: 300
+     });
+     var timeshiftOndemand = new Ext.form.Checkbox({
+         fieldLabel: 'On-Demand',
+         name: 'timeshift_ondemand',
+         width: 300
+     });
+     var timeshiftPath = new Ext.form.TextField({
+         fieldLabel: 'Storage Path',
+         name: 'timeshift_path',
+         allowBlank: true,
+         width: 300
+     });
+     var timeshiftMaxPeriod = new Ext.form.NumberField({
+         fieldLabel: 'Max. Period (mins)',
+         name: 'timeshift_max_period',
+         allowBlank: false,
+         width: 300
+     });
+     var timeshiftUnlPeriod = new Ext.form.Checkbox({
 -        fieldLabel: '&nbsp;&nbsp;&nbsp;(unlimited)',
++        fieldLabel: 'Unlimited time',
+         name: 'timeshift_unlimited_period',
 -        Width: 300
++        width: 300
+     });
+     var timeshiftMaxSize = new Ext.form.NumberField({
+         fieldLabel: 'Max. Size (MB)',
+         name: 'timeshift_max_size',
+         allowBlank: false,
+         width: 300
+     });
+     var timeshiftUnlSize = new Ext.form.Checkbox({
 -        fieldLabel: '&nbsp;&nbsp;&nbsp;(unlimited)',
++        fieldLabel: 'Unlimited size',
+         name: 'timeshift_unlimited_size',
 -        Width: 300
++        width: 300
+     });
+     /* ****************************************************************
+      * Events
+      * ***************************************************************/
 -    timeshiftUnlPeriod.on('check', function(e, c) {
++    timeshiftUnlPeriod.on('check', function(e, c){
+         timeshiftMaxPeriod.setDisabled(c);
+     });
 -    timeshiftUnlSize.on('check', function(e, c) {
++
++    timeshiftUnlSize.on('check', function(e, c){
+         timeshiftMaxSize.setDisabled(c);
+     });
+     /* ****************************************************************
+      * Form
+      * ***************************************************************/
+     var saveButton = new Ext.Button({
+         text: "Save configuration",
+         tooltip: 'Save changes made to configuration below',
+         iconCls: 'save',
+         handler: saveChanges
+     });
+     var helpButton = new Ext.Button({
+         text: 'Help',
+         handler: function() {
+             new tvheadend.help('Timeshift Configuration', 'config_timeshift.html');
+         }
+     });
 -    var confpanel = new Ext.FormPanel({
 -        title: 'Timeshift',
 -        iconCls: 'clock',
++    var timeshiftPanelA = new Ext.form.FieldSet({
++        width: 500,
++        autoHeight: true,
++        border: false,
++          items : [timeshiftMaxPeriod, timeshiftMaxSize]
++    });
++
++    var timeshiftPanelB = new Ext.form.FieldSet({
++        width: 200,
++        autoHeight: true,
+         border: false,
 -        bodyStyle: 'padding:15px',
 -        labelAlign: 'left',
 -        labelWidth: 150,
 -        waitMsgTarget: true,
 -        reader: confreader,
 -        layout: 'form',
 -        defaultType: 'textfield',
++        items : [timeshiftUnlPeriod,timeshiftUnlSize]
++    });
++
++    var timeshiftPanel = new Ext.form.FieldSet({
++        title: 'Timeshift Options',
++        width: 700,
+         autoHeight: true,
 -        items: [
 -            timeshiftEnabled, timeshiftOndemand,
++        collapsible: true,
++        animCollapse: true,
++        items : [
++            timeshiftEnabled, 
++            timeshiftOndemand, 
+             timeshiftPath,
 -            timeshiftMaxPeriod, timeshiftUnlPeriod,
 -            timeshiftMaxSize, timeshiftUnlSize
 -        ],
 -        tbar: [saveButton, '->', helpButton]
++            {
++                layout: 'column', 
++                border: false,
++                items: [timeshiftPanelA, timeshiftPanelB]
++            } 
++        ]
++    });
++
++    var confpanel = new Ext.form.FormPanel({
++        title : 'Timeshift',
++        iconCls : 'clock',
++        border : false,
++        bodyStyle : 'padding:15px',
++        labelAlign : 'left',
++        labelWidth : 150,
++        waitMsgTarget : true,
++        reader : confreader,
++        layout : 'form',
++        defaultType : 'textfield',
++        autoHeight : true,
++        animCollapse : true,
++      items : [timeshiftPanel],
++        tbar : [saveButton, '->', helpButton]
+     });
+     /* ****************************************************************
+      * Load/Save
+      * ***************************************************************/
+     confpanel.on('render', function() {
+         confpanel.getForm().load({
+             url: 'timeshift',
+             params: {
+                 'op': 'loadSettings'
+             },
+             success: function() {
+                 confpanel.enable();
+                 timeshiftMaxPeriod.setDisabled(timeshiftUnlPeriod.getValue());
+                 timeshiftMaxSize.setDisabled(timeshiftUnlSize.getValue());
+             }
+         });
+     });
+     function saveChanges() {
+         confpanel.getForm().submit({
+             url: 'timeshift',
+             params: {
+                 op: 'saveSettings'
+             },
+             waitMsg: 'Saving Data...',
+             success: function(form, action) {
+             },
+             failure: function(form, action) {
+                 Ext.Msg.alert('Save failed', action.result.errormsg);
+             }
+         });
      }
-   });
-       var timeshiftPanelA = new Ext.form.FieldSet({
-               width: 500,
-               autoHeight: true,
-               border: false,
-                   items : [ timeshiftMaxPeriod, timeshiftMaxSize ]
-       });
-       var timeshiftPanelB = new Ext.form.FieldSet({
-               width: 200,
-               autoHeight: true,
-               border: false,
-           items : [ timeshiftUnlPeriod,timeshiftUnlSize ]
-       });
-       var timeshiftPanel = new Ext.form.FieldSet({
-               title: 'Timeshift Options',
-               width: 700,
-               autoHeight: true,
-               collapsible: true,
-               animCollapse: true,
-           items : [
-                       timeshiftEnabled, 
-                       timeshiftOndemand, 
-                       timeshiftPath,
-                       {
-                               layout: 'column', 
-                               border: false,
-                               items: [ timeshiftPanelA, timeshiftPanelB]
-                       }       
-               ]
-       });
-   var confpanel = new Ext.form.FormPanel({
-     title : 'Timeshift',
-     iconCls : 'clock',
-     border : false,
-     bodyStyle : 'padding:15px',
-     labelAlign : 'left',
-     labelWidth : 150,
-     waitMsgTarget : true,
-     reader : confreader,
-     layout : 'form',
-     defaultType : 'textfield',
-     autoHeight : true,
-       animCollapse : true,
-       items : [ timeshiftPanel ],
-     tbar : [ saveButton, '->', helpButton ]
-   });
-   /* ****************************************************************
-    * Load/Save
-    * ***************************************************************/
-   confpanel.on('render', function() {
-     confpanel.getForm().load({
-       url: 'timeshift',
-       params: {
-         'op': 'loadSettings'
-       },
-       success: function() {
-         confpanel.enable();
-         timeshiftMaxPeriod.setDisabled(timeshiftUnlPeriod.getValue());
-         timeshiftMaxSize.setDisabled(timeshiftUnlSize.getValue());
-       }
-     });
-   });
-   function saveChanges() {
-     confpanel.getForm().submit({
-       url : 'timeshift',
-       params : {
-         op : 'saveSettings',
-       },
-       waitMsg : 'Saving Data...',
-       success : function(form, action) {
-       },
-       failure : function(form, action) {
-         Ext.Msg.alert('Save failed', action.result.errormsg);
-       }
-     });
-   }
-   return confpanel;
- }
+     return confpanel;
+ };