diff --git a/CONTROL/control b/CONTROL/control index 7e180ba..e5e8bf4 100644 --- a/CONTROL/control +++ b/CONTROL/control @@ -1,9 +1,9 @@ Package: sweeper Priority: optional Section: misc -Version: 1.0.13 +Version: 1.0.14 Architecture: mipsel Maintainer: af123@hummypkg.org.uk -Depends: webif(>=1.0.14-2) +Depends: webif(>=1.0.14-3) Description: Automatically manage single recording files. [Web Interface. Multi-folder support.] Tags: http://hummy.tv/forum/threads/3843/ diff --git a/webif/plugin/sweeper/auto.hook b/webif/plugin/sweeper/auto.hook index e9c8fbc..63d38f9 100644 --- a/webif/plugin/sweeper/auto.hook +++ b/webif/plugin/sweeper/auto.hook @@ -57,7 +57,7 @@ proc ::sweeper::strcontains {ref val} { } ###################################################################### -# Rule clauses +# Rule criteria proc ::sweeper::flag {ts flag} { return [$ts flag $flag] @@ -124,15 +124,23 @@ proc ::sweeper::genre {ts genre} { proc ::sweeper::lock {ts g} { if {$g} { - log "Locked recording." 0 - $ts lock + if {![$ts flag Locked]} { + log "Locked recording." 0 + $ts lock + } } else { - log "Unlocked recording." 0 - $ts unlock + if {[$ts flag Locked]} { + log "Unlocked recording." 0 + $ts unlock + } } return 1 } +proc ::sweeper::folder_fflag {ts flag} { + return [file exists "[file dirname [$ts get file]]/.$flag"] +} + ###################################################################### proc ::sweeper::action {ts cmds} { @@ -172,6 +180,20 @@ proc ::sweeper::action {ts cmds} { } return 1 } + lock { + if {![$ts flag Locked]} { + log "Locked [$ts get file]" 0 + $ts lock + } + return 0 + } + unlock { + if {[$ts flag Locked]} { + log "Unlocked [$ts get file]" 0 + $ts unlock + } + return 0 + } default { log "Unknown action '$cmd'" 0 } @@ -195,6 +217,32 @@ proc ::sweeper::find {root target orig} { return "" } +proc ::sweeper::folder_apply {dir callback} { + log "Applying action to recordings in $dir" 2 + foreach e [readdir -nocomplain $dir] { + if {![string match {*.ts} $e]} continue + set entry "$dir/$e" + + log "+ folder_apply processing $entry" 2 + + if {[catch {set ts [ts fetch $entry]} msg} { + log "Error reading TS file, $msg" 0 + continue + } + + if {$ts == "0"} { + log "Invalid TS file." 2 + continue + } + + if {[$ts inuse]} { + log "Recording in use." 2 + continue + } + $callback $ts + } +} + proc ::sweeper:folder_merge {src dst} { if {$src eq $dst} return log "Moving recordings from $src to $dst" 0 @@ -287,6 +335,24 @@ proc ::sweeper::folder_action {ts cmds} { ::sweeper:folder_merge $folder $target return 1 } + lock { + ::sweeper::folder_apply $folder [lambda {ts} { + if {![$ts flag Locked]} { + log "Locked [$ts get file]" 0 + $ts lock + } + }] + return 0 + } + unlock { + ::sweeper::folder_apply $folder [lambda {ts} { + if {[$ts flag Locked]} { + log "Unlocked [$ts get file]" 0 + $ts unlock + } + }] + return 0 + } default { log "Unknown action '$cmd'" 0 } @@ -384,7 +450,9 @@ proc ::sweeper::apply {dir cf} { if {[string match {\[*} $e]} continue if {$e eq $dustbin} continue - log "+ Sweeper processing folder $entry" 2 + log "" 2 + log "==== folder $entry ====" 2 + log "" 2 if {![file exists "$entry/.series"]} { log "Not series folder." 2 diff --git a/webif/plugin/sweeper/config.jim b/webif/plugin/sweeper/config.jim index 469515d..784407f 100755 --- a/webif/plugin/sweeper/config.jim +++ b/webif/plugin/sweeper/config.jim @@ -6,9 +6,14 @@ require system.class httpheader "text/javascript" -puts { - -var showraw = true; - +set raw 0 +if {[file exists /mod/webif/plugin/sweeper/.raw]} { + set raw 1 } +puts " + +var showraw = $raw; + +" + diff --git a/webif/plugin/sweeper/edit.jim b/webif/plugin/sweeper/edit.jim index e9081e5..061fed0 100755 --- a/webif/plugin/sweeper/edit.jim +++ b/webif/plugin/sweeper/edit.jim @@ -39,6 +39,14 @@ puts {
+
+Add pre-defined ruleset: + + +
+ + + } footer diff --git a/webif/plugin/sweeper/img/arrow.png b/webif/plugin/sweeper/img/arrow.png new file mode 100644 index 0000000..1e027b1 Binary files /dev/null and b/webif/plugin/sweeper/img/arrow.png differ diff --git a/webif/plugin/sweeper/img/disable.png b/webif/plugin/sweeper/img/disable.png new file mode 100644 index 0000000..26fbe85 Binary files /dev/null and b/webif/plugin/sweeper/img/disable.png differ diff --git a/webif/plugin/sweeper/img/redstripes.gif b/webif/plugin/sweeper/img/redstripes.gif new file mode 100644 index 0000000..cac008c Binary files /dev/null and b/webif/plugin/sweeper/img/redstripes.gif differ diff --git a/webif/plugin/sweeper/rules_json.jim b/webif/plugin/sweeper/rules_json.jim index c827c7c..ff2d486 100755 --- a/webif/plugin/sweeper/rules_json.jim +++ b/webif/plugin/sweeper/rules_json.jim @@ -48,6 +48,12 @@ proc quot {str} { proc rule {id rule} { global clausedescr lcomment + set enabled 1 + if {[lindex $rule 0] eq "##"} { + set enabled 0 + set rule [lrange $rule 1 end] + } + if {$lcomment eq ""} { set lcomment "Unnamed rule" } if {[lindex $rule 0] eq "folder"} { set type "folder" @@ -61,14 +67,17 @@ proc rule {id rule} { add_json " \"raw\": \"[quot $rule]\",\n" add_json " \"name\": \"[quot $lcomment]\",\n" add_json " \"type\": \"$type\",\n" + add_json " \"enabled\": \"$enabled\",\n" add_json " \"criteria\": \[\n" set lcomment "" set c 0 + set lockfound -1 while {[llength $rule] > 1} { set rule [lassign $rule cmd arg] if {$cmd eq "action"} break + if {$cmd eq "lock"} { set lockfound $arg } if {$c} { add_json ",\n" } incr c @@ -78,7 +87,17 @@ proc rule {id rule} { add_json " }" } add_json "\n" - if {$cmd ne "action"} { set arg "continue" } + if {$cmd ne "action"} { + if {$lockfound != -1} { + if {$lockfound == "1"} { + set arg "lock" + } else { + set arg "unlock" + } + } else { + set arg "continue" + } + } lassign $arg cmd arg if {$cmd eq "preserve"} { set cmd 'stop' } add_json " ],\n" @@ -95,8 +114,8 @@ foreach rule $rules { if {[string index $rule 0] eq "#"} { if {[string index $rule 1] ne "#"} { comment $n [string range $rule 1 end] + continue } - continue } if {[llength $rule] < 2} continue incr n diff --git a/webif/plugin/sweeper/save.jim b/webif/plugin/sweeper/save.jim index 86a8249..dd23042 100755 --- a/webif/plugin/sweeper/save.jim +++ b/webif/plugin/sweeper/save.jim @@ -6,6 +6,21 @@ require system.class httpheader +set act [cgi_get act "save"] + +switch $act { + raw { + set val [cgi_get val 0] + if {$val} { + file touch /mod/webif/plugin/sweeper/.raw + } else { + file delete -force /mod/webif/plugin/sweeper/.raw + } + puts "Done." + exit; + } +} + set dir [cgi_get dir ""] set root [system mediaroot] diff --git a/webif/plugin/sweeper/schema.js b/webif/plugin/sweeper/schema.js index 32e3e45..cd91d9b 100644 --- a/webif/plugin/sweeper/schema.js +++ b/webif/plugin/sweeper/schema.js @@ -1,56 +1,67 @@ var schema = { criterion: { lcn: { + 'class': 'all', type: 'int', desc: 'Logical Channel Number', def: "0" }, duration: { + 'class': 'all', type: 'int', desc: 'Recording duration (in minutes)', def: "0" }, schedduration: { + 'class': 'all', type: 'int', desc: 'Scheduled duration (in minutes)', def: "0" }, size: { + 'class': 'all', type: 'int', desc: 'Recording size (in bytes)', def: "0" }, hour: { + 'class': 'all', type: 'int', desc: 'Hour in which the recording started', def: "0" }, age: { + 'class': 'all', type: 'int', desc: 'Age (in hours)', def: "0" }, wage: { + 'class': 'all', type: 'int', desc: 'Time since last watched, or recorded (in hours)', def: "0" }, title: { + 'class': 'all', type: 'substr', desc: 'Recording Title contains', def: 'Enter text here...' }, synopsis: { + 'class': 'all', type: 'substr', desc: 'Synopsis contains', def: 'Enter text here...' }, guidance: { + 'class': 'all', type: 'substr', desc: 'Guidance Text contains', def: 'Enter text here...' }, genre: { + 'class': 'all', type: 'select', desc: 'Recording Genre', select: { @@ -67,6 +78,7 @@ var schema = { def: 'Unclassified' }, definition: { + 'class': 'all', type: 'select', desc: 'Recording Definition', select: { @@ -76,6 +88,7 @@ var schema = { def: 'SD' }, flag: { + 'class': 'all', type: 'select', desc: 'Recording Flagged as', select: { @@ -90,13 +103,21 @@ var schema = { def: 'New' }, lock: { + 'class': 'all', type: 'select', desc: 'Change Recording Lock', select: { 1: 'Lock Recording', 0: 'Unlock Recording' }, - def: 1 + def: 1, + deprecated: true + }, + fflag: { + 'class': 'folder', + type: 'string', + desc: 'Folder flagged as', + def: 'noflatten' } }, action: { @@ -104,50 +125,224 @@ var schema = { 'class': 'all', argtype: 'none', desc: 'Continue on to next rule', - showcont: false + continues: true }, stop: { 'class': 'all', argtype: 'none', desc: 'Do nothing and stop processing rules', - showcont: false + continues: false }, move: { 'class': 'all', argtype: 'folder', desc: 'Move recording to folder...', - showcont: true + continues: false + }, + lock: { + 'class': 'all', + argtype: 'none', + desc: 'Lock recordings', + continues: true + }, + unlock: { + 'class': 'all', + argtype: 'none', + desc: 'Unlock recordings', + continues: true }, movecreate: { 'class': 'all', argtype: 'folder', desc: 'Move recording to folder (creating if necessary)', - showcont: true + continues: false }, fileunder: { 'class': 'folder', argtype: 'folder', desc: 'Merge into first folder of same name found under...', - showcont: true + continues: false }, fileundercreate: { 'class': 'folder', argtype: 'folder', desc: 'Merge into or create folder of ' + 'same name found under...', - showcont: true + continues: false } } }; -var select_criteria = {}; +var macros = { + seriesfiler: { + desc: 'Series-Filer', + rules: [ + { + "raw": "action {fileunder ""}", + "name": "Emulate Seriesfiler", + "type": "folder", + "enabled": "1", + "criteria": [], + "action": { + "cmd": "fileunder", + "arg": "" + } + } + ] + }, + example: { + desc: 'Example rules', + rules: [ + { + "raw": "lcn {>= 70} lcn {<= 79} duration {>= 90} action {move Children/Films}", + "name": "Move any Children's films (by length)", + "type": "file", + "enabled": "0", + "criteria": [ + { + "cmd": "lcn", + "arg": ">= 70" + }, + { + "cmd": "lcn", + "arg": "<= 79" + }, + { + "cmd": "duration", + "arg": ">= 90" + } + ], + "action": { + "cmd": "move", + "arg": "Children/Films" + } + }, + { + "raw": "lcn {>= 70} lcn {<= 79} genre Film action {move Children/Films}", + "name": "Move any Children's films (by genre)", + "type": "file", + "enabled": "0", + "criteria": [ + { + "cmd": "lcn", + "arg": ">= 70" + }, + { + "cmd": "lcn", + "arg": "<= 79" + }, + { + "cmd": "genre", + "arg": "Film" + } + ], + "action": { + "cmd": "move", + "arg": "Children/Films" + } + }, + { + "raw": "lcn {>= 70} lcn {<= 79} action {move Children/Miscellaneous}", + "name": "Move anything else recorded from a children's channel", + "type": "file", + "enabled": "0", + "criteria": [ + { + "cmd": "lcn", + "arg": ">= 70" + }, + { + "cmd": "lcn", + "arg": "<= 79" + } + ], + "action": { + "cmd": "move", + "arg": "Children/Miscellaneous" + } + }, + { + "raw": "lcn {>= 70} lcn {<= 79} action {fileundercreate Children}", + "name": "Move any series recordings from a Children's channel (folder rule)", + "type": "folder", + "enabled": "0", + "criteria": [ + { + "cmd": "lcn", + "arg": ">= 70" + }, + { + "cmd": "lcn", + "arg": "<= 79" + } + ], + "action": { + "cmd": "fileundercreate", + "arg": "Children" + } + }, + { + "raw": "title {Formula 1} action {move F1}", + "name": "Move any one-off Formula 1 recordings into the F1 folder", + "type": "file", + "enabled": "0", + "criteria": [ + { + "cmd": "title", + "arg": "Formula 1" + } + ], + "action": { + "cmd": "move", + "arg": "F1" + } + }, + { + "raw": "age {> 120} action {movecreate Misc}", + "name": "Move any one-off recordings into a folder called Misc after a while", + "type": "file", + "enabled": "0", + "criteria": [ + { + "cmd": "age", + "arg": "> 120" + } + ], + "action": { + "cmd": "movecreate", + "arg": "Misc" + } + } +] + } + +}; + +var select_file_criteria = {}; +var select_folder_criteria = {}; $.each(schema.criterion, function(k, v) { - select_criteria[k] = v.desc; + if (v.deprecated) + return; + switch (v['class']) + { + case 'file': + select_file_criteria[k] = v.desc; + break; + case 'folder': + select_folder_criteria[k] = v.desc; + break; + case 'all': + select_file_criteria[k] = v.desc; + select_folder_criteria[k] = v.desc; + break; + } }); var select_file_actions = {}; var select_folder_actions = {}; $.each(schema.action, function(k, v) { + if (v.deprecated) + return; switch (v['class']) { case 'file': diff --git a/webif/plugin/sweeper/script.js b/webif/plugin/sweeper/script.js index 97a7d72..f86037d 100644 --- a/webif/plugin/sweeper/script.js +++ b/webif/plugin/sweeper/script.js @@ -6,7 +6,7 @@ function quot(str) if (!str) return '""'; - if (str.indexOf(" ") == -1) + if (str.indexOf(" ") == -1 && str.indexOf('"') == -1) return str; return '{' + str + '}'; } @@ -15,6 +15,11 @@ function fixupdown() { $('#ruleset a.uprule').enable().filter(':first').disable(); $('#ruleset a.downrule').enable().filter(':last').disable(); + + $('#ruleset a.uprule img').attr('src', '/img/nav/up.png') + .first().attr('src', '/img/nav/up-grey.png'); + $('#ruleset a.downrule img').attr('src', '/img/nav/down.png') + .last().attr('src', '/img/nav/down-grey.png'); } function changed(c) @@ -23,12 +28,12 @@ function changed(c) return; if (c) { - $('#b_save,#b_revert').enable(); + $('#b_save,#b_revert').button('enable'); $('#pendingnote').show(); } else { - $('#b_save,#b_revert').disable(); + $('#b_save,#b_revert').button('disable'); $('#pendingnote').hide(); } changed.last = c; @@ -52,6 +57,9 @@ var setters = { substr: function(cmd, a) { return a; }, + 'string': function(cmd, a) { + return a; + }, select: function(cmd, a) { return schema.criterion[cmd].select[a]; } @@ -70,6 +78,9 @@ var getters = { substr: function(cmd, a) { return a; }, + 'string': function(cmd, a) { + return a; + }, select: function(cmd, a) { var c = schema.criterion[cmd].select; for (key in c) @@ -83,11 +94,13 @@ function ruleconf(rule) { var s = ''; - if ($(rule).attr('type') == 'folder') + if (rule.hasClass('ruledisabled')) + s += '## '; + if (rule.attr('type') == 'folder') s += 'folder '; - $(rule).find('tr.clause').each(function(i) { - cmd = $(this).find('th').attr('cmd'); + rule.find('tr.clause').each(function(i) { + cmd = $(this).find('th.cmd').attr('cmd'); c = schema.criterion[cmd]; val = $.trim($(this).find('td.val').text()); if (getters[c.type]) @@ -96,12 +109,17 @@ function ruleconf(rule) s += cmd + ' ' + quot(val) + ' '; }); - act = $(rule).find('tr.action th').attr('cmd'); - arg = $.trim($(rule).find('tr.action td.val').text()); + act = rule.find('tr.action th.cmd').attr('cmd'); + arg = $.trim(rule.find('tr.action td.val').text()); if (schema.action[act].argtype == 'folder' && arg == mroot) arg = ''; if (act != 'continue') - s += 'action {' + act + ' ' + quot(arg) + '}'; + { + if (schema.action[act].argtype == 'none') + s += 'action ' + act; + else + s += 'action {' + act + ' ' + quot(arg) + '}'; + } return s; } @@ -120,12 +138,22 @@ function conffile() function rulerefresh(rule) { + if (!showraw) + rule.find('.raw').hide(); rule.find('.raw').html(ruleconf(rule)); - rule.find('tr.clause td.title').text('And:').first().text('If:'); + rule.find('tr.clause th.title').text('And:').first().text('If:'); if (rule.find('tr.clause').length < 1) - rule.find('tr.action td.title').text('Always:'); + { + rule.find('tr.action th.title').text('Always:'); + rule.find('tr.otherwise').hide(); + rule.find('div.criteria,div.arrow').hide(); + } else - rule.find('tr.action td.title').text('Then:'); + { + rule.find('tr.action th.title').text('Then:'); + rule.find('tr.otherwise').show(); + rule.find('div.criteria,div.arrow').show(); + } } function criterion(data) @@ -133,8 +161,9 @@ function criterion(data) var c = schema.criterion[data.cmd]; var s; - s = 'And:' + - '' + c.desc + ''; + s = 'And:' + + '' + + c.desc + ''; if (setters[c.type]) s += setters[c.type](data.cmd, data.arg); @@ -160,16 +189,26 @@ function action(data) data.arg = mroot; s = '' + - 'Then:' + - '' + c.desc + '' + + 'Then:' + + '' + c.desc + '' + '' + data.arg + '' + '' + '' + ''; - if (c.showcont) - s += 'Else:' + - 'Continue on to next rule.'; + if (data.cmd != 'continue') + { + if (c.continues) + s += 'And:' + + 'Continue to next rule.'; + else if (data.cmd != 'stop') + s += 'And:' + + 'Stop processing rules.'; + + s += ' ' + + 'Otherwise:' + + 'Continue to next rule.'; + } return s; } @@ -196,16 +235,25 @@ function addrule(id, data) var $c = rule.find('table.criteria'); $.each(data.criteria, function(key, val) { + if (val.cmd == 'lock' && ( + data.action.cmd == 'lock' || data.action.cmd == 'unlock')) + return; $c.find('tbody').append(criterion(val)); }); - $c.find('td.title:first').text('If:'); + $c.find('th.title:first').text('If:'); rule.find('table.action tbody').append(action(data.action)); + if (data.enabled == 0) + { + rule.addClass('ruledisabled'); + rule.find('span.disabledtext').removeClass('hidden'); + } + $('#ruleset').append(rule); - rule.find('button.addcriterion') - .button({icons: { primary: "ui-icon-plus"}}); +// rule.find('button.addcriterion') +// .button({icons: { primary: "ui-icon-plus"}}); rulerefresh(rule); @@ -241,6 +289,8 @@ function edit_text(obj, title, text, callback) } } }); + if (text == 'Enter text here...') + $('#edit_text_field').focus().select(); } function edit_int(obj, title, op, val, callback) @@ -310,10 +360,10 @@ function edit_select(obj, title, options, val, callback) function edit_clause(obj) { - var cmd = $(obj).find('th').attr('cmd'); + var cmd = $(obj).find('th.cmd').attr('cmd'); var target = $(obj).find('td.val'); var val = $.trim($(target).text()); - var title = $(obj).find('th').html(); + var title = $(obj).find('th.cmd').html(); if (!schema.criterion[cmd]) { alert('Unhandled command (' + cmd + ')'); @@ -364,7 +414,7 @@ function loadrules(dir) if (!data.length) { $('#ruleset').attr('empty', true) - .html('No rules defined for this folder.'); + .html($('#empty_rulebase').html()); return; } $.each(data, function(key, val) { @@ -412,18 +462,18 @@ $('#b_add').button({icons: {primary: "ui-icon-plus"}}) } }); $('#newrule_type_file').prop('checked', true); - $('#newrule_comment').focus().val('').val('Unnamed rule'); + $('#newrule_comment').focus().val('').val('Unnamed rule').select(); }); -$('#b_save').button({icons: {primary: "ui-icon-disk"}}) - .on('click', function(e) { +$('#b_save').button({icons: {primary: "ui-icon-disk"}}); +$('#buttons') + .on('click', '#b_save', function(e) { e.preventDefault(); $(this).dojConfirmAction({ question: 'Save changes?', yesAnswer: 'Yes', cancelAnswer: 'No' }, function(el) { - $('.jcaquestion').fadeOut(300); $.post('save.jim', { dir: $('span.dir').text(), data: conffile() @@ -435,15 +485,15 @@ $('#b_save').button({icons: {primary: "ui-icon-disk"}}) }); }); -$('#b_revert').button({icons: {primary: "ui-icon-arrowrefresh-1-w"}}) - .on('click', function(e) { +$('#b_revert').button({icons: {primary: "ui-icon-arrowrefresh-1-w"}}); +$('#buttons') + .on('click', '#b_revert', function(e) { e.preventDefault(); $(this).dojConfirmAction({ question: 'Discard changes?', yesAnswer: 'Yes', cancelAnswer: 'No' }, function(el) { - $('.jcaquestion').fadeOut(300); loadrules($('span.dir').text()); changed(0); }); @@ -470,6 +520,32 @@ $('#b_show').button({icons: {primary: "ui-icon-clipboard"}}) $('#b_raw').button({icons: {primary: "ui-icon-gear"}}) .on('click', function(e) { $('#ruleset div.raw').toggle('slow'); + showraw = !showraw; + $.get('save.jim?act=raw&val=' + (showraw ? 1 : 0)); +}); + +$('#b_macro').button({disabled: true, icons: {primary: "ui-icon-plus"}}); +$('#macros').on('click', '#b_macro', function(e) { + e.preventDefault(); + var set = $('#macroselect').val(); + if (!set) return; + var desc = macros[set].desc; + $(this).dojConfirmAction({ + question: 'Add ' + desc + '?', + yesAnswer: 'Yes', + cancelAnswer: 'No' + }, function(el) { + $('.jcaquestion').remove(); + $.each(macros[set].rules, function(k, v) { + addrule(last_ruleid + 1, v).hide().addClass('hl'); + }); + $('.hl').slideDown('slow', function() { + $(this).removeClass('hl'); + }); + fixupdown(); + changed(1); + $('#macroselect').val(0); + }); }); changed(0); @@ -479,11 +555,17 @@ $('#ruleset') e.preventDefault(); edit_clause($(this).closest('tr.clause')); }) - .on('click', 'button.addcriterion', function(e) { + .on('click', 'a.addcriterion', function(e) { e.preventDefault(); var rule = $(this).closest('div.rule'); - edit_select(rule, 'Select new criterion', - select_criteria, '', function(rule, val) { + var type = rule.attr('type'); + + if (type == 'folder') + options = select_folder_criteria; + else + options = select_file_criteria; + edit_select(rule, 'Add new condition', + options, '', function(rule, val) { var id = rule.attr('id'); rule.find('table.criteria tbody') .append(criterion({ @@ -537,6 +619,35 @@ $('#ruleset') }); }); }) + .on('click', 'a.cprule', function(e) { + e.preventDefault(); + $(this).dojConfirmAction({ + question: 'Duplicate rule?', + yesAnswer: 'Yes', + cancelAnswer: 'No' + }, function(el) { + $('.jcaquestion').remove(); + var rule = $(el).closest('div.rule'); + rule.clone() + .attr('id', 'rule_' + ++last_ruleid) + .addClass('hl').hide() + .insertAfter(rule) + .slideDown('slow', function() { + $(this).removeClass('hl'); + changed(1); + }) + .find('span.comment').append(' (copy)'); + }); + }) + .on('click', 'a.enadisrule', function(e) { + e.preventDefault(); + var rule = $(this).closest('div.rule') + .toggleClass('ruledisabled'); + rule.find('span.disabledtext').toggleClass('hidden', + !rule.hasClass('ruledisabled')); + rulerefresh(rule); + changed(1); + }) .on('click', 'a.editaction', function(e) { e.preventDefault(); @@ -555,7 +666,7 @@ $('#ruleset') ); }); - var cmd = rule.find('tr.action th').attr('cmd'); + var cmd = rule.find('tr.action th.cmd').attr('cmd'); var arg = rule.find('tr.action td.val').html(); if (schema.action[cmd].argtype == 'none') @@ -596,11 +707,10 @@ $('#ruleset') .on('click', 'a.delclause', function(e) { e.preventDefault(); $(this).dojConfirmAction({ - question: 'Delete criterion?', + question: 'Delete condition?', yesAnswer: 'Yes', cancelAnswer: 'No' }, function(el) { - $('.jcaquestion').fadeOut(300); var rule = $(el).closest('div.rule'); $(el).closest('tr.clause').fadeOut('slow', function() { $(this).remove(); @@ -616,19 +726,33 @@ $('#ruleset') yesAnswer: 'Yes', cancelAnswer: 'No' }, function(el) { - $('.jcaquestion').fadeOut(300); - $(el).closest('div.rule').slideUp('slow', function() { + $(el).closest('div.rule') + .addClass('hl') + .slideUp('slow', function() { $(this).remove(); changed(1); fixupdown(); if ($('div.rule').length < 1) $('#ruleset').attr('empty', true) - .html('No rules defined for this ' + - 'folder.'); + .html($('#empty_rulebase').html()); }); }); }); + // Set up macros + $.each(macros, function(key, val) { + $('#macroselect').append( + $('').attr('value', key).text(val.desc) + ); + }); + + $('#macroselect').on('change', function(el) { + if ($(this).val() == "0") + $('#b_macro').button('disable'); + else + $('#b_macro').button('enable'); + }); + loadrules($('span.dir').text()); }); diff --git a/webif/plugin/sweeper/style.css b/webif/plugin/sweeper/style.css index 4d46b47..ffbc131 100644 --- a/webif/plugin/sweeper/style.css +++ b/webif/plugin/sweeper/style.css @@ -1,4 +1,9 @@ +a +{ + outline: 0; +} + span.ruleicon img { height: 21px; @@ -20,15 +25,30 @@ img background: yellow; } +.ruledisabled +{ + background: #663436 url(img/redstripes.gif) repeat; +} + div.action { - padding-left: 1em; float: left; } +a.addcriterion +{ + padding: 4px 2px 0 0; + float: left; + clear: left; +} + div.criteria { - clear: left; + float: left; +} + +div.arrow +{ float: left; } @@ -47,11 +67,9 @@ div#buttons padding-top: 1em; } -td.title,th.title +div#macros { - line-height: 1em; - text-align: left !important; - background: #eee !important; + padding-top: 1em; } div.rule @@ -86,3 +104,47 @@ span.legendright background: transparent; } +table +{ + border: 0; +} + +table th +{ + background: #ccff99; + font-weight: bold; + text-align: right; + color: black; + xpadding: 0.5em; +} + +table td +{ + background: #ffffcc; + color: black; +} + +td.title,th.title +{ + line-height: 1em; + background: #eee !important; + font-style: italic; +} + +td.title +{ + text-align: left !important; +} + +th.title +{ + font-weight: normal; + text-align: right !important; +} + +tr.blank td +{ + background: transparent; + line-height: 7px; +} +