diff --git a/airtime_mvc/public/css/media_library.css b/airtime_mvc/public/css/media_library.css
index 3b0db5046..06120698d 100644
--- a/airtime_mvc/public/css/media_library.css
+++ b/airtime_mvc/public/css/media_library.css
@@ -146,7 +146,7 @@ td.library_bitrate {
}
-.fg-toolbar .btn-toolbar {margin: 6px 5px 6px 2px;}
+.fg-toolbar .btn-toolbar {margin: 6px 5px -6px 5px;}
/* ///////////////////// ADVANCED SEARCH ///////////////////// */
diff --git a/airtime_mvc/public/js/airtime/buttons/buttons.js b/airtime_mvc/public/js/airtime/buttons/buttons.js
index 7af88e352..23a904001 100644
--- a/airtime_mvc/public/js/airtime/buttons/buttons.js
+++ b/airtime_mvc/public/js/airtime/buttons/buttons.js
@@ -1,39 +1,45 @@
-var AIRTIME = (function(AIRTIME){
- var mod,
- DEFAULT_CLASS = 'ui-button ui-state-default',
- DISABLED_CLASS = 'ui-state-disabled';
-
- if (AIRTIME.button === undefined) {
- AIRTIME.button = {};
- }
- mod = AIRTIME.button;
-
- mod.isDisabled = function(c) {
- var button = $("."+c);
-
- if (button.hasClass(DISABLED_CLASS)) {
- return true;
- }
-
- return false;
- };
-
- mod.enableButton = function(c) {
- var button = $("."+c);
-
- if (button.hasClass(DISABLED_CLASS)) {
- button.removeClass(DISABLED_CLASS);
- }
- };
+var AIRTIME = (function(AIRTIME) {
+ var mod, DEFAULT_CLASS = 'ui-button ui-state-default', DISABLED_CLASS = 'ui-state-disabled';
+
+ if (AIRTIME.button === undefined) {
+ AIRTIME.button = {};
+ }
+ mod = AIRTIME.button;
+
+ mod.isDisabled = function(c) {
+ var button = $("." + c);
+
+ if (button.hasClass(DISABLED_CLASS)) {
+ return true;
+ }
+
+ return false;
+ };
+
+ mod.enableButton = function(c, useParent) {
+ if (useParent) {
+ var button = $("." + c).parent();
+ } else {
+ var button = $("." + c);
+ }
+
+ if (button.hasClass(DISABLED_CLASS)) {
+ button.removeClass(DISABLED_CLASS);
+ }
+ };
+
+ mod.disableButton = function(c, useParent) {
+ if (useParent) {
+ var button = $("." + c).parent();
+ } else {
+ var button = $("." + c);
+ }
+
+ if (!button.hasClass(DISABLED_CLASS)) {
+ button.addClass(DISABLED_CLASS);
+ }
+ };
+
+ return AIRTIME;
- mod.disableButton = function(c) {
- var button = $("."+c);
-
- if (!button.hasClass(DISABLED_CLASS)) {
- button.addClass(DISABLED_CLASS);
- }
- };
-
- return AIRTIME;
-
}(AIRTIME || {}));
\ No newline at end of file
diff --git a/airtime_mvc/public/js/airtime/library/events/library_playlistbuilder.js b/airtime_mvc/public/js/airtime/library/events/library_playlistbuilder.js
index 6ade8636f..cc9d6596b 100644
--- a/airtime_mvc/public/js/airtime/library/events/library_playlistbuilder.js
+++ b/airtime_mvc/public/js/airtime/library/events/library_playlistbuilder.js
@@ -1,169 +1,156 @@
-var AIRTIME = (function(AIRTIME){
- var mod;
-
- if (AIRTIME.library === undefined) {
- AIRTIME.library = {};
- }
-
- mod = AIRTIME.library;
+var AIRTIME = (function(AIRTIME) {
+ var mod;
+
+ if (AIRTIME.library === undefined) {
+ AIRTIME.library = {};
+ }
+
+ mod = AIRTIME.library;
mod.checkAddButton = function() {
- var selected = mod.getChosenItemsLength(),
- sortable = $('#spl_sortable'),
- check = false;
-
- //make sure audioclips are selected and a playlist is currently open.
- if (selected !== 0 && sortable.length !== 0) {
- check = true;
- }
-
- if (check === true) {
- AIRTIME.button.enableButton("lib-button-add");
- }
- else {
- AIRTIME.button.disableButton("lib-button-add");
- }
+ var selected = mod.getChosenItemsLength(), sortable = $('#spl_sortable'), check = false;
+
+ // make sure audioclips are selected and a playlist is currently open.
+ if (selected !== 0 && sortable.length !== 0) {
+ check = true;
+ }
+
+ if (check === true) {
+ AIRTIME.button.enableButton("icon-plus", true);
+ } else {
+ AIRTIME.button.disableButton("icon-plus", true);
+ }
};
-
- mod.fnRowCallback = function( nRow, aData, iDisplayIndex, iDisplayIndexFull ) {
- var $nRow = $(nRow);
- if (aData.ftype === "audioclip") {
- $nRow.addClass("lib-audio");
- } else if (aData.ftype === "stream"){
+
+ mod.fnRowCallback = function(nRow, aData, iDisplayIndex, iDisplayIndexFull) {
+ var $nRow = $(nRow);
+ if (aData.ftype === "audioclip") {
+ $nRow.addClass("lib-audio");
+ } else if (aData.ftype === "stream") {
$nRow.addClass("lib-stream");
- } else if (aData.ftype === "block") {
- $nRow.addClass("lib-block");
- } else {
- $nRow.addClass("lib-pl");
- }
-
- $nRow.attr("id", aData["tr_id"])
- .data("aData", aData)
- .data("screen", "playlist");
-
- if (aData["bl_type"] !== undefined) {
- $nRow.attr("bl_type", aData["bl_type"]);
- }
- };
-
- mod.fnDrawCallback = function() {
-
- mod.redrawChosen();
- mod.checkToolBarIcons();
-
- $('#library_display tr.lib-audio, tr.lib-stream, tr.lib-pl, tr.lib-block').draggable({
- helper: function(){
-
- var $el = $(this),
- selected = mod.getChosenAudioFilesLength(),
- container,
- message,
- li = $("#side_playlist ul li:first"),
- width = li.width(),
- height = li.height();
-
- //dragging an element that has an unselected checkbox.
- if (mod.isChosenItem($el) === false) {
- selected++;
- }
-
- if (selected === 1) {
- message = "Adding 1 Item.";
- }
- else {
- message = "Adding "+selected+" Items.";
- }
-
- container = $('
')
- .append("
")
- .find("li")
- .addClass("ui-state-default")
- .append("
")
- .find("div")
- .addClass("list-item-container")
- .append(message)
- .end()
- .width(width)
- .height(height)
- .end();
-
- return container;
- },
- cursor: 'pointer',
- connectToSortable: '#spl_sortable'
- });
- };
-
- mod.dblClickAdd = function(data, type) {
- var i,
- aMediaIds = [];
-
- //process selected files/playlists.
+ } else if (aData.ftype === "block") {
+ $nRow.addClass("lib-block");
+ } else {
+ $nRow.addClass("lib-pl");
+ }
+
+ $nRow.attr("id", aData["tr_id"]).data("aData", aData).data("screen",
+ "playlist");
+
+ if (aData["bl_type"] !== undefined) {
+ $nRow.attr("bl_type", aData["bl_type"]);
+ }
+ };
+
+ mod.fnDrawCallback = function() {
+
+ mod.redrawChosen();
+ mod.checkToolBarIcons();
+
+ $('#library_display tr.lib-audio, tr.lib-stream, tr.lib-pl, tr.lib-block')
+ .draggable(
+ {
+ helper : function() {
+
+ var $el = $(this), selected = mod
+ .getChosenAudioFilesLength(), container, message, li = $("#side_playlist ul li:first"), width = li
+ .width(), height = li.height();
+
+ // dragging an element that has an unselected
+ // checkbox.
+ if (mod.isChosenItem($el) === false) {
+ selected++;
+ }
+
+ if (selected === 1) {
+ message = "Adding 1 Item.";
+ } else {
+ message = "Adding " + selected + " Items.";
+ }
+
+ container = $('
').append(
+ "
").find("li").addClass(
+ "ui-state-default").append("
")
+ .find("div").addClass(
+ "list-item-container").append(
+ message).end().width(width)
+ .height(height).end();
+
+ return container;
+ },
+ cursor : 'pointer',
+ connectToSortable : '#spl_sortable'
+ });
+ };
+
+ mod.dblClickAdd = function(data, type) {
+ var i, aMediaIds = [];
+
+ // process selected files/playlists.
aMediaIds.push(new Array(data.id, data.ftype));
-
- //check if a playlist/block is open before adding items
- if ($('input[id="obj_type"]').val() == 'playlist' || $('input[id="obj_type"]').val() == 'block') {
+
+ // check if a playlist/block is open before adding items
+ if ($('input[id="obj_type"]').val() == 'playlist'
+ || $('input[id="obj_type"]').val() == 'block') {
AIRTIME.playlist.fnAddItems(aMediaIds, undefined, 'after');
}
- };
-
- mod.setupLibraryToolbar = function() {
- var $toolbar = $(".lib-content .fg-toolbar:first");
-
- $toolbar
- .append("
")
- .find('ul')
- .append('
')
- .append('
')
- .append('
');
-
- //add to playlist button
- $toolbar.find('.lib-button-add')
- .click(function() {
-
- if (AIRTIME.button.isDisabled('lib-button-add') === true) {
- return;
- }
-
- var aData = AIRTIME.library.getSelectedData(),
- i,
- temp,
- length,
- aMediaIds = [];
-
- //process selected files/playlists.
- for (i = 0, length = aData.length; i < length; i++) {
- temp = aData[i];
- if (temp.ftype === "audioclip" || temp.ftype === "block" ||
- (temp.ftype === "stream" && $("#obj_type").val() === "playlist")) {
- aMediaIds.push(new Array (temp.id, temp.ftype));
- }
- }
- if (aMediaIds.length > 0) {
- AIRTIME.playlist.fnAddItems(aMediaIds, undefined, 'after');
- } else {
- if ($('#obj_type').val() == 'block') {
- alert('You can only add tracks to smart blocks.');
- } else if ($('#obj_type').val() == 'playlist') {
- alert('You can only add tracks, smart blocks, and webstreams to playlists.');
- }
- }
- });
-
- //delete from library.
- $toolbar.find('.lib-button-delete')
- .click(function() {
-
- if (AIRTIME.button.isDisabled('lib-button-delete') === true) {
- return;
- }
-
- AIRTIME.library.fnDeleteSelectedItems();
- });
-
- mod.createToolbarDropDown();
- };
-
- return AIRTIME;
-
+ };
+
+ mod.setupLibraryToolbar = function() {
+ var $toolbar = $(".lib-content .fg-toolbar:first");
+
+ mod.createToolbarButtons();
+
+ $toolbar.append($menu);
+
+
+ // add to playlist button
+ $toolbar
+ .find('.icon-plus').parent()
+ .click(function() {
+
+ if (AIRTIME.button.isDisabled('icon-plus') === true) {
+ return;
+ }
+
+ var aData = AIRTIME.library.getSelectedData(), i, temp, length, aMediaIds = [];
+
+ // process selected files/playlists.
+ for (i = 0, length = aData.length; i < length; i++) {
+ temp = aData[i];
+ if (temp.ftype === "audioclip"
+ || temp.ftype === "block"
+ || (temp.ftype === "stream" && $(
+ "#obj_type").val() === "playlist")) {
+ aMediaIds.push(new Array(temp.id,
+ temp.ftype));
+ }
+ }
+ if (aMediaIds.length > 0) {
+ AIRTIME.playlist.fnAddItems(aMediaIds,
+ undefined, 'after');
+ } else {
+ if ($('#obj_type').val() == 'block') {
+ alert('You can only add tracks to smart blocks.');
+ } else if ($('#obj_type').val() == 'playlist') {
+ alert('You can only add tracks, smart blocks, and webstreams to playlists.');
+ }
+ }
+ });
+
+ // delete from library.
+ $toolbar.find('.icon-trash').parent().click(function() {
+
+ if (AIRTIME.button.isDisabled('icon-trash') === true) {
+ return;
+ }
+
+ AIRTIME.library.fnDeleteSelectedItems();
+ });
+
+ mod.createToolbarDropDown();
+ };
+
+ return AIRTIME;
+
}(AIRTIME || {}));
diff --git a/airtime_mvc/public/js/airtime/library/events/library_showbuilder.js b/airtime_mvc/public/js/airtime/library/events/library_showbuilder.js
index ea33951fc..1e10fd7a4 100644
--- a/airtime_mvc/public/js/airtime/library/events/library_showbuilder.js
+++ b/airtime_mvc/public/js/airtime/library/events/library_showbuilder.js
@@ -1,182 +1,173 @@
-var AIRTIME = (function(AIRTIME){
- var mod;
-
- if (AIRTIME.library === undefined) {
- AIRTIME.library = {};
- }
-
- mod = AIRTIME.library;
-
- mod.checkAddButton = function() {
- var selected = mod.getChosenItemsLength(),
- $cursor = $('tr.cursor-selected-row'),
- check = false;
-
- //make sure library items are selected and a cursor is selected.
- if (selected !== 0 && $cursor.length !== 0) {
- check = true;
- }
-
- if (check === true) {
- AIRTIME.button.enableButton("lib-button-add");
- }
- else {
- AIRTIME.button.disableButton("lib-button-add");
- }
+var AIRTIME = (function(AIRTIME) {
+ var mod;
+
+ if (AIRTIME.library === undefined) {
+ AIRTIME.library = {};
+ }
+
+ mod = AIRTIME.library;
+
+ mod.checkAddButton = function() {
+ var selected = mod.getChosenItemsLength(), $cursor = $('tr.cursor-selected-row'), check = false;
+
+ // make sure library items are selected and a cursor is selected.
+ if (selected !== 0 && $cursor.length !== 0) {
+ check = true;
+ }
+
+ if (check === true) {
+ AIRTIME.button.enableButton("icon-plus", true);
+ } else {
+ AIRTIME.button.disableButton("icon-plus", true);
+ }
};
-
- mod.fnRowCallback = function( nRow, aData, iDisplayIndex, iDisplayIndexFull ) {
- var $nRow = $(nRow);
-
- if (aData.ftype === "audioclip") {
- $nRow.addClass("lib-audio");
- } else if (aData.ftype === "stream"){
+
+ mod.fnRowCallback = function(nRow, aData, iDisplayIndex, iDisplayIndexFull) {
+ var $nRow = $(nRow);
+
+ if (aData.ftype === "audioclip") {
+ $nRow.addClass("lib-audio");
+ } else if (aData.ftype === "stream") {
$nRow.addClass("lib-stream");
} else {
- $nRow.addClass("lib-pl");
- }
-
- $nRow.attr("id", aData["tr_id"])
- .data("aData", aData)
- .data("screen", "timeline");
- };
-
- mod.fnDrawCallback = function fnLibDrawCallback() {
-
- mod.redrawChosen();
- mod.checkToolBarIcons();
-
- $('#library_display tr.lib-audio, tr.lib-pl, tr.lib-stream').draggable({
- helper: function(){
-
- var $el = $(this),
- selected = mod.getChosenItemsLength(),
- container,
- thead = $("#show_builder_table thead"),
- colspan = thead.find("th").length,
- width = thead.find("tr:first").width(),
- message;
-
- //dragging an element that has an unselected checkbox.
- if (mod.isChosenItem($el) === false) {
- selected++;
- }
-
- if (selected === 1) {
- message = "Adding 1 Item.";
- }
- else {
- message = "Adding "+selected+" Items.";
- }
-
- container = $('
').attr('id', 'draggingContainer')
- .append('
|
')
- .find("tr")
- .append('
| ')
- .find("td")
- .attr("colspan", colspan)
- .width(width)
- .addClass("ui-state-highlight")
- .append(message)
- .end()
- .end();
-
- return container;
- },
- cursor: 'pointer',
- connectToSortable: '#show_builder_table'
- });
- };
-
- mod.dblClickAdd = function(data, type) {
- var i,
- length,
- temp,
- aMediaIds = [],
- aSchedIds = [],
- aData = [];
-
- //process selected files/playlists.
- aMediaIds.push({"id": data.id, "type": type});
-
- $("#show_builder_table tr.cursor-selected-row").each(function(i, el){
+ $nRow.addClass("lib-pl");
+ }
+
+ $nRow.attr("id", aData["tr_id"]).data("aData", aData).data("screen",
+ "timeline");
+ };
+
+ mod.fnDrawCallback = function fnLibDrawCallback() {
+
+ mod.redrawChosen();
+ mod.checkToolBarIcons();
+
+ $('#library_display tr.lib-audio, tr.lib-pl, tr.lib-stream')
+ .draggable(
+ {
+ helper : function() {
+
+ var $el = $(this), selected = mod
+ .getChosenItemsLength(), container, thead = $("#show_builder_table thead"), colspan = thead
+ .find("th").length, width = thead.find(
+ "tr:first").width(), message;
+
+ // dragging an element that has an unselected
+ // checkbox.
+ if (mod.isChosenItem($el) === false) {
+ selected++;
+ }
+
+ if (selected === 1) {
+ message = "Adding 1 Item.";
+ } else {
+ message = "Adding " + selected + " Items.";
+ }
+
+ container = $('
').attr('id',
+ 'draggingContainer').append('
|
')
+ .find("tr").append('
| ').find("td")
+ .attr("colspan", colspan).width(width)
+ .addClass("ui-state-highlight").append(
+ message).end().end();
+
+ return container;
+ },
+ cursor : 'pointer',
+ connectToSortable : '#show_builder_table'
+ });
+ };
+
+ mod.dblClickAdd = function(data, type) {
+ var i, length, temp, aMediaIds = [], aSchedIds = [], aData = [];
+
+ // process selected files/playlists.
+ aMediaIds.push( {
+ "id" : data.id,
+ "type" : type
+ });
+
+ $("#show_builder_table tr.cursor-selected-row").each(function(i, el) {
aData.push($(el).prev().data("aData"));
});
-
- //process selected schedule rows to add media after.
- for (i=0, length = aData.length; i < length; i++) {
+
+ // process selected schedule rows to add media after.
+ for (i = 0, length = aData.length; i < length; i++) {
temp = aData[i];
- aSchedIds.push({"id": temp.id, "instance": temp.instance, "timestamp": temp.timestamp});
+ aSchedIds.push( {
+ "id" : temp.id,
+ "instance" : temp.instance,
+ "timestamp" : temp.timestamp
+ });
}
-
- if(aSchedIds.length == 0){
+
+ if (aSchedIds.length == 0) {
alert("Please select a cursor position on timeline.");
return false;
}
console.log(aMediaIds);
AIRTIME.showbuilder.fnAdd(aMediaIds, aSchedIds);
- };
-
- mod.setupLibraryToolbar = function() {
- var $toolbar = $(".lib-content .fg-toolbar:first");
-
- $toolbar
- .append("
")
- .find('ul')
- .append('
')
- .append('
')
- .append('
');
-
- //add to timeline button
- $toolbar.find('.lib-button-add')
- .click(function() {
-
- if (AIRTIME.button.isDisabled('lib-button-add') === true) {
- return;
- }
-
- var selected = AIRTIME.library.getSelectedData(),
- data,
- i,
- length,
- temp,
- aMediaIds = [],
- aSchedIds = [],
- aData = [];
-
- //process selected files/playlists.
- for (i = 0, length = selected.length; i < length; i++) {
- data = selected[i];
- aMediaIds.push({"id": data.id, "type": data.ftype});
- }
-
- $("#show_builder_table tr.cursor-selected-row").each(function(i, el){
- aData.push($(el).prev().data("aData"));
- });
-
- //process selected schedule rows to add media after.
- for (i=0, length = aData.length; i < length; i++) {
- temp = aData[i];
- aSchedIds.push({"id": temp.id, "instance": temp.instance, "timestamp": temp.timestamp});
- }
-
- AIRTIME.showbuilder.fnAdd(aMediaIds, aSchedIds);
- });
-
- //delete from library.
- $toolbar.find('.lib-button-delete')
- .click(function() {
-
- if (AIRTIME.button.isDisabled('lib-button-delete') === true) {
- return;
- }
-
- AIRTIME.library.fnDeleteSelectedItems();
- });
-
- mod.createToolbarDropDown();
- };
-
- return AIRTIME;
-
+ };
+
+ mod.setupLibraryToolbar = function() {
+ var $toolbar = $(".lib-content .fg-toolbar:first");
+
+ mod.createToolbarButtons();
+
+ $toolbar.append($menu);
+ // add to timeline button
+ $toolbar
+ .find('.icon-plus').parent()
+ .click(
+ function() {
+
+ if (AIRTIME.button.isDisabled('icon-plus') === true) {
+ return;
+ }
+
+ var selected = AIRTIME.library.getSelectedData(), data, i, length, temp, aMediaIds = [], aSchedIds = [], aData = [];
+
+ // process selected files/playlists.
+ for (i = 0, length = selected.length; i < length; i++) {
+ data = selected[i];
+ aMediaIds.push( {
+ "id" : data.id,
+ "type" : data.ftype
+ });
+ }
+
+ $("#show_builder_table tr.cursor-selected-row")
+ .each(function(i, el) {
+ aData.push($(el).prev().data("aData"));
+ });
+
+ // process selected schedule rows to add media
+ // after.
+ for (i = 0, length = aData.length; i < length; i++) {
+ temp = aData[i];
+ aSchedIds.push( {
+ "id" : temp.id,
+ "instance" : temp.instance,
+ "timestamp" : temp.timestamp
+ });
+ }
+
+ AIRTIME.showbuilder.fnAdd(aMediaIds, aSchedIds);
+ });
+
+ // delete from library.
+ $toolbar.find('.icon-trash').parent().click(function() {
+
+ if (AIRTIME.button.isDisabled('icon-trash') === true) {
+ return;
+ }
+
+ AIRTIME.library.fnDeleteSelectedItems();
+ });
+
+ mod.createToolbarDropDown();
+ };
+
+ return AIRTIME;
+
}(AIRTIME || {}));
diff --git a/airtime_mvc/public/js/airtime/library/library.js b/airtime_mvc/public/js/airtime/library/library.js
index e3d8cea40..24800133a 100644
--- a/airtime_mvc/public/js/airtime/library/library.js
+++ b/airtime_mvc/public/js/airtime/library/library.js
@@ -96,18 +96,35 @@ var AIRTIME = (function(AIRTIME) {
return count;
};
+ mod.createToolbarButtons = function() {
+ $menu = $("
");
+ $menu
+ .append("
" +
+ "" +
+ "" +
+ "
")
+ .append("
" +
+ "" +
+ "
")
+ .append("
" +
+ "" +
+ "
");
+ }
+
mod.createToolbarDropDown = function() {
-
- $.contextMenu({
- selector: '#library_content .ui-icon-document-b',
- trigger: "left",
- ignoreRightClick: true,
- items: {
- "sp": {name: "Select This Page", callback: mod.selectCurrentPage},
- "dp": {name: "Deselect This Page", callback: mod.deselectCurrentPage},
- "sn": {name: "Deselect All", callback: mod.selectNone}
- }
- });
+ $('#sb-select-page').click(function(){mod.selectCurrentPage();});
+ $('#sb-dselect-page').click(function(){mod.deselectCurrentPage();});
+ $('#sb-dselect-all').click(function(){mod.selectNone();});
};
mod.checkDeleteButton = function() {
@@ -119,10 +136,10 @@ var AIRTIME = (function(AIRTIME) {
}
if (check === true) {
- AIRTIME.button.enableButton("lib-button-delete");
+ AIRTIME.button.enableButton("btn-group #sb-trash", true);
}
else {
- AIRTIME.button.disableButton("lib-button-delete");
+ AIRTIME.button.disableButton("btn-group #sb-trash", true);
}
};
diff --git a/airtime_mvc/public/js/airtime/library/spl.js b/airtime_mvc/public/js/airtime/library/spl.js
index 4cc478f6a..11d5221c6 100644
--- a/airtime_mvc/public/js/airtime/library/spl.js
+++ b/airtime_mvc/public/js/airtime/library/spl.js
@@ -307,6 +307,7 @@ var AIRTIME = (function(AIRTIME){
setCueEvents();
setFadeEvents();
setModified(json.modified);
+ AIRTIME.playlist.validatePlaylistElements();
redrawLib();
}
@@ -409,8 +410,6 @@ var AIRTIME = (function(AIRTIME){
$pl.delegate(".spl_cue",
{"click": openCueEditor});
-
- mod.validatePlaylistElements();
$pl.delegate(".spl_block_expand",
{"click": function(ev){
@@ -773,6 +772,7 @@ var AIRTIME = (function(AIRTIME){
}());
$pl.find("#spl_sortable").sortable(sortableConf);
+ AIRTIME.playlist.validatePlaylistElements();
}
mod.fnNew = function() {
diff --git a/airtime_mvc/public/js/airtime/showbuilder/builder.js b/airtime_mvc/public/js/airtime/showbuilder/builder.js
index 8af595775..942bfbf0d 100644
--- a/airtime_mvc/public/js/airtime/showbuilder/builder.js
+++ b/airtime_mvc/public/js/airtime/showbuilder/builder.js
@@ -66,10 +66,10 @@ var AIRTIME = (function(AIRTIME){
var $selectable = $sbTable.find("tbody").find("input:checkbox");
if ($selectable.length !== 0) {
- AIRTIME.button.enableButton("sb-button-select");
+ AIRTIME.button.enableButton("btn-group #timeline-select", true);
}
else {
- AIRTIME.button.disableButton("sb-button-select");
+ AIRTIME.button.disableButton("btn-group #timeline-select", true);
}
};
@@ -77,10 +77,10 @@ var AIRTIME = (function(AIRTIME){
var $over = $sbTable.find(".sb-over.sb-allowed");
if ($over.length !== 0) {
- AIRTIME.button.enableButton("sb-button-trim");
+ AIRTIME.button.enableButton("icon-cut", true);
}
else {
- AIRTIME.button.disableButton("sb-button-trim");
+ AIRTIME.button.disableButton("icon-cut", true);
}
};
@@ -88,10 +88,10 @@ var AIRTIME = (function(AIRTIME){
var $selected = $sbTable.find("tbody").find("input:checkbox").filter(":checked");
if ($selected.length !== 0) {
- AIRTIME.button.enableButton("sb-button-delete");
+ AIRTIME.button.enableButton("icon-trash", true);
}
else {
- AIRTIME.button.disableButton("sb-button-delete");
+ AIRTIME.button.disableButton("icon-trash", true);
}
};
@@ -99,10 +99,10 @@ var AIRTIME = (function(AIRTIME){
var $current = $sbTable.find("."+NOW_PLAYING_CLASS);
if ($current.length !== 0) {
- AIRTIME.button.enableButton("sb-button-current");
+ AIRTIME.button.enableButton("icon-step-forward", true);
}
else {
- AIRTIME.button.disableButton("sb-button-current");
+ AIRTIME.button.disableButton("icon-step-forward", true);
}
};
@@ -113,10 +113,10 @@ var AIRTIME = (function(AIRTIME){
userType = localStorage.getItem('user-type');
if ($current.length !== 0 && (userType === 'A' || userType === 'P')) {
- AIRTIME.button.enableButton("sb-button-cancel");
+ AIRTIME.button.enableButton("icon-ban-circle", true);
}
else {
- AIRTIME.button.disableButton("sb-button-cancel");
+ AIRTIME.button.disableButton("icon-ban-circle", true);
}
};
@@ -333,15 +333,15 @@ var AIRTIME = (function(AIRTIME){
/*
* Icon hover states in the toolbar.
*/
- $sbContent.on("mouseenter", ".fg-toolbar ul li", function(ev) {
+ $sbContent.on("mouseenter", "#timeline-select .dropdown-toggle", function(ev) {
$el = $(this);
if (!$el.hasClass("ui-state-disabled")) {
$el.addClass("ui-state-hover");
- $("#show_builder .ui-icon-document-b").contextMenu(true);
+ $("#timeline-select .caret").contextMenu(true);
}
else {
- $("#show_builder .ui-icon-document-b").contextMenu(false);
+ $("#timeline-select .caret").contextMenu(false);
}
});
$sbContent.on("mouseleave", ".fg-toolbar ul li", function(ev) {
@@ -958,37 +958,44 @@ var AIRTIME = (function(AIRTIME){
//start setup of the builder toolbar.
$toolbar = $(".sb-content .fg-toolbar");
+
+ $menu = $("
");
+ $menu.append("
" +
+ "" +
+ "" +
+ "
")
+ .append("
" +
+ "
")
+ .append("
" +
+ "
")
+ .append("
" +
+ "
")
+ .append("
" +
+ "
");
+
+ $toolbar.append($menu);
+ $menu = undefined;
- $ul = $("
");
- $ul.append('
')
- .append('
')
- .append('
');
- $toolbar.append($ul);
+ $('#timeline-sa').click(function(){mod.selectAll();});
+ $('#timeline-sn').click(function(){mod.selectNone();});
- $ul = $("
");
- $ul.append('
')
- .append('
');
- $toolbar.append($ul);
- $ul = undefined;
-
- $.contextMenu({
- selector: '#show_builder .ui-icon-document-b',
- trigger: "left",
- ignoreRightClick: true,
- items: {
- "sa": {name: "Select All", callback: mod.selectAll},
- "sn": {name: "Select None", callback: mod.selectNone}
- }
- });
-
- //jump to current
- $toolbar.find('.sb-button-cancel')
+ //cancel current show
+ $toolbar.find('.icon-ban-circle')
.click(function() {
var $tr,
data,
msg = 'Cancel Current Show?';
- if (AIRTIME.button.isDisabled('sb-button-cancel') === true) {
+ if (AIRTIME.button.isDisabled('icon-ban-circle') === true) {
return;
}
@@ -1016,10 +1023,10 @@ var AIRTIME = (function(AIRTIME){
});
//jump to current
- $toolbar.find('.sb-button-current')
+ $toolbar.find('.icon-step-forward')
.click(function() {
- if (AIRTIME.button.isDisabled('sb-button-current') === true) {
+ if (AIRTIME.button.isDisabled('icon-step-forward') === true) {
return;
}
@@ -1033,10 +1040,10 @@ var AIRTIME = (function(AIRTIME){
});
//delete overbooked tracks.
- $toolbar.find('.sb-button-trim')
+ $toolbar.find('.icon-cut')
.click(function() {
- if (AIRTIME.button.isDisabled('sb-button-trim') === true) {
+ if (AIRTIME.button.isDisabled('icon-cut') === true) {
return;
}
@@ -1053,10 +1060,10 @@ var AIRTIME = (function(AIRTIME){
});
//delete selected tracks
- $toolbar.find('.sb-button-delete')
+ $toolbar.find('.icon-trash')
.click(function() {
- if (AIRTIME.button.isDisabled('sb-button-delete') === true) {
+ if (AIRTIME.button.isDisabled('icon-trash') === true) {
return;
}
diff --git a/airtime_mvc/public/js/airtime/showbuilder/main_builder.js b/airtime_mvc/public/js/airtime/showbuilder/main_builder.js
index 7f02199c8..dc286f5da 100644
--- a/airtime_mvc/public/js/airtime/showbuilder/main_builder.js
+++ b/airtime_mvc/public/js/airtime/showbuilder/main_builder.js
@@ -15,7 +15,7 @@ AIRTIME = (function(AIRTIME) {
timeStartId = "#sb_time_start",
dateEndId = "#sb_date_end",
timeEndId = "#sb_time_end",
- $toggleLib = $('
'),
+ $toggleLib = $("
Schedule files"),
$libClose = $('
', {
"class": "close-round",
"href": "#",
diff --git a/airtime_mvc/public/js/datatables/plugin/AIRTIME_DEV_README b/airtime_mvc/public/js/datatables/plugin/AIRTIME_DEV_README_COLUMN_FILTER
similarity index 100%
rename from airtime_mvc/public/js/datatables/plugin/AIRTIME_DEV_README
rename to airtime_mvc/public/js/datatables/plugin/AIRTIME_DEV_README_COLUMN_FILTER
diff --git a/airtime_mvc/public/js/datatables/plugin/AIRTIME_DEV_README_COL_VIS b/airtime_mvc/public/js/datatables/plugin/AIRTIME_DEV_README_COL_VIS
new file mode 100644
index 000000000..c332d036e
--- /dev/null
+++ b/airtime_mvc/public/js/datatables/plugin/AIRTIME_DEV_README_COL_VIS
@@ -0,0 +1,33 @@
+Before you overwrite dataTables.ColVis.js, note that we have changed a few lines
+in this file.
+
+The following function has been modified:
+
+_fnDomBaseButton
+
+The new _fnDomBaseButton looks like this:
+
+ "_fnDomBaseButton": function ( text )
+ {
+ var
+ that = this,
+ nButton = document.createElement('button'),
+ nSpan = document.createElement('span'),
+ sEvent = this.s.activate=="mouseover" ? "mouseover" : "click";
+
+ //nButton.className = !this.s.dt.bJUI ? "ColVis_Button TableTools_Button" :
+ //"ColVis_Button TableTools_Button ui-button ui-state-default";
+ nButton.className = "btn-toolbar btn btn-small dropdown-toggle ColVis_MasterButton";
+
+ nButton.appendChild( nSpan );
+ $(nButton).append("
");
+ nSpan.innerHTML = text;
+
+ $(nButton).bind( 'click', function (e) {
+ that._fnCollectionShow();
+ e.preventDefault();
+ } );
+
+ return nButton;
+ },
+
\ No newline at end of file
diff --git a/airtime_mvc/public/js/datatables/plugin/dataTables.ColVis.js b/airtime_mvc/public/js/datatables/plugin/dataTables.ColVis.js
index 19d91d39b..2f1c8ed02 100644
--- a/airtime_mvc/public/js/datatables/plugin/dataTables.ColVis.js
+++ b/airtime_mvc/public/js/datatables/plugin/dataTables.ColVis.js
@@ -29,861 +29,864 @@
*/
ColVis = function( oDTSettings, oInit )
{
- /* Santiy check that we are a new instance */
- if ( !this.CLASS || this.CLASS != "ColVis" )
- {
- alert( "Warning: ColVis must be initialised with the keyword 'new'" );
- }
-
- if ( typeof oInit == 'undefined' )
- {
- oInit = {};
- }
-
-
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * Public class variables
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
- /**
- * @namespace Settings object which contains customisable information for ColVis instance
- */
- this.s = {
- /**
- * DataTables settings object
- * @property dt
- * @type Object
- * @default null
- */
- "dt": null,
-
- /**
- * Customisation object
- * @property oInit
- * @type Object
- * @default passed in
- */
- "oInit": oInit,
-
- /**
- * Callback function to tell the user when the state has changed
- * @property fnStateChange
- * @type function
- * @default null
- */
- "fnStateChange": null,
-
- /**
- * Mode of activation. Can be 'click' or 'mouseover'
- * @property activate
- * @type String
- * @default click
- */
- "activate": "click",
-
- /**
- * Position of the collection menu when shown - align "left" or "right"
- * @property sAlign
- * @type String
- * @default right
- */
- "sAlign": "left",
-
- /**
- * Text used for the button
- * @property buttonText
- * @type String
- * @default Show / hide columns
- */
- "buttonText": "Show / hide columns",
-
- /**
- * Flag to say if the collection is hidden
- * @property hidden
- * @type boolean
- * @default true
- */
- "hidden": true,
-
- /**
- * List of columns (integers) which should be excluded from the list
- * @property aiExclude
- * @type Array
- * @default []
- */
- "aiExclude": [],
-
- /**
- * Store the original viisbility settings so they could be restored
- * @property abOriginal
- * @type Array
- * @default []
- */
- "abOriginal": [],
-
- /**
- * Show Show-All button
- * @property bShowAll
- * @type Array
- * @default []
- */
- "bShowAll": false,
-
- /**
- * Show All button text
- * @property sShowAll
- * @type String
- * @default Restore original
- */
- "sShowAll": "Show All",
-
- /**
- * Show restore button
- * @property bRestore
- * @type Array
- * @default []
- */
- "bRestore": false,
-
- /**
- * Restore button text
- * @property sRestore
- * @type String
- * @default Restore original
- */
- "sRestore": "Restore original",
-
- /**
- * Overlay animation duration in mS
- * @property iOverlayFade
- * @type Integer
- * @default 500
- */
- "iOverlayFade": 500,
-
- /**
- * Label callback for column names. Takes three parameters: 1. the column index, 2. the column
- * title detected by DataTables and 3. the TH node for the column
- * @property fnLabel
- * @type Function
- * @default null
- */
- "fnLabel": null,
-
- /**
- * Indicate if ColVis should automatically calculate the size of buttons or not. The default
- * is for it to do so. Set to "css" to disable the automatic sizing
- * @property sSize
- * @type String
- * @default auto
- */
- "sSize": "auto",
-
- /**
- * Indicate if the column list should be positioned by Javascript, visually below the button
- * or allow CSS to do the positioning
- * @property bCssPosition
- * @type boolean
- * @default false
- */
- "bCssPosition": false
- };
-
-
- /**
- * @namespace Common and useful DOM elements for the class instance
- */
- this.dom = {
- /**
- * Wrapper for the button - given back to DataTables as the node to insert
- * @property wrapper
- * @type Node
- * @default null
- */
- "wrapper": null,
-
- /**
- * Activation button
- * @property button
- * @type Node
- * @default null
- */
- "button": null,
-
- /**
- * Collection list node
- * @property collection
- * @type Node
- * @default null
- */
- "collection": null,
-
- /**
- * Background node used for shading the display and event capturing
- * @property background
- * @type Node
- * @default null
- */
- "background": null,
-
- /**
- * Element to position over the activation button to catch mouse events when using mouseover
- * @property catcher
- * @type Node
- * @default null
- */
- "catcher": null,
-
- /**
- * List of button elements
- * @property buttons
- * @type Array
- * @default []
- */
- "buttons": [],
-
- /**
- * Restore button
- * @property restore
- * @type Node
- * @default null
- */
- "restore": null
- };
-
- /* Store global reference */
- ColVis.aInstances.push( this );
-
- /* Constructor logic */
- this.s.dt = oDTSettings;
- this._fnConstruct();
- return this;
+ /* Santiy check that we are a new instance */
+ if ( !this.CLASS || this.CLASS != "ColVis" )
+ {
+ alert( "Warning: ColVis must be initialised with the keyword 'new'" );
+ }
+
+ if ( typeof oInit == 'undefined' )
+ {
+ oInit = {};
+ }
+
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Public class variables
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+ /**
+ * @namespace Settings object which contains customisable information for ColVis instance
+ */
+ this.s = {
+ /**
+ * DataTables settings object
+ * @property dt
+ * @type Object
+ * @default null
+ */
+ "dt": null,
+
+ /**
+ * Customisation object
+ * @property oInit
+ * @type Object
+ * @default passed in
+ */
+ "oInit": oInit,
+
+ /**
+ * Callback function to tell the user when the state has changed
+ * @property fnStateChange
+ * @type function
+ * @default null
+ */
+ "fnStateChange": null,
+
+ /**
+ * Mode of activation. Can be 'click' or 'mouseover'
+ * @property activate
+ * @type String
+ * @default click
+ */
+ "activate": "click",
+
+ /**
+ * Position of the collection menu when shown - align "left" or "right"
+ * @property sAlign
+ * @type String
+ * @default right
+ */
+ "sAlign": "left",
+
+ /**
+ * Text used for the button
+ * @property buttonText
+ * @type String
+ * @default Show / hide columns
+ */
+ "buttonText": "Show / hide columns",
+
+ /**
+ * Flag to say if the collection is hidden
+ * @property hidden
+ * @type boolean
+ * @default true
+ */
+ "hidden": true,
+
+ /**
+ * List of columns (integers) which should be excluded from the list
+ * @property aiExclude
+ * @type Array
+ * @default []
+ */
+ "aiExclude": [],
+
+ /**
+ * Store the original viisbility settings so they could be restored
+ * @property abOriginal
+ * @type Array
+ * @default []
+ */
+ "abOriginal": [],
+
+ /**
+ * Show Show-All button
+ * @property bShowAll
+ * @type Array
+ * @default []
+ */
+ "bShowAll": false,
+
+ /**
+ * Show All button text
+ * @property sShowAll
+ * @type String
+ * @default Restore original
+ */
+ "sShowAll": "Show All",
+
+ /**
+ * Show restore button
+ * @property bRestore
+ * @type Array
+ * @default []
+ */
+ "bRestore": false,
+
+ /**
+ * Restore button text
+ * @property sRestore
+ * @type String
+ * @default Restore original
+ */
+ "sRestore": "Restore original",
+
+ /**
+ * Overlay animation duration in mS
+ * @property iOverlayFade
+ * @type Integer
+ * @default 500
+ */
+ "iOverlayFade": 500,
+
+ /**
+ * Label callback for column names. Takes three parameters: 1. the column index, 2. the column
+ * title detected by DataTables and 3. the TH node for the column
+ * @property fnLabel
+ * @type Function
+ * @default null
+ */
+ "fnLabel": null,
+
+ /**
+ * Indicate if ColVis should automatically calculate the size of buttons or not. The default
+ * is for it to do so. Set to "css" to disable the automatic sizing
+ * @property sSize
+ * @type String
+ * @default auto
+ */
+ "sSize": "auto",
+
+ /**
+ * Indicate if the column list should be positioned by Javascript, visually below the button
+ * or allow CSS to do the positioning
+ * @property bCssPosition
+ * @type boolean
+ * @default false
+ */
+ "bCssPosition": false
+ };
+
+
+ /**
+ * @namespace Common and useful DOM elements for the class instance
+ */
+ this.dom = {
+ /**
+ * Wrapper for the button - given back to DataTables as the node to insert
+ * @property wrapper
+ * @type Node
+ * @default null
+ */
+ "wrapper": null,
+
+ /**
+ * Activation button
+ * @property button
+ * @type Node
+ * @default null
+ */
+ "button": null,
+
+ /**
+ * Collection list node
+ * @property collection
+ * @type Node
+ * @default null
+ */
+ "collection": null,
+
+ /**
+ * Background node used for shading the display and event capturing
+ * @property background
+ * @type Node
+ * @default null
+ */
+ "background": null,
+
+ /**
+ * Element to position over the activation button to catch mouse events when using mouseover
+ * @property catcher
+ * @type Node
+ * @default null
+ */
+ "catcher": null,
+
+ /**
+ * List of button elements
+ * @property buttons
+ * @type Array
+ * @default []
+ */
+ "buttons": [],
+
+ /**
+ * Restore button
+ * @property restore
+ * @type Node
+ * @default null
+ */
+ "restore": null
+ };
+
+ /* Store global reference */
+ ColVis.aInstances.push( this );
+
+ /* Constructor logic */
+ this.s.dt = oDTSettings;
+ this._fnConstruct();
+ return this;
};
ColVis.prototype = {
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * Public methods
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
- /**
- * Rebuild the list of buttons for this instance (i.e. if there is a column header update)
- * @method fnRebuild
- * @returns void
- */
- "fnRebuild": function ()
- {
- /* Remove the old buttons */
- for ( var i=this.dom.buttons.length-1 ; i>=0 ; i-- )
- {
- if ( this.dom.buttons[i] !== null )
- {
- this.dom.collection.removeChild( this.dom.buttons[i] );
- }
- }
- this.dom.buttons.splice( 0, this.dom.buttons.length );
-
- if ( this.dom.restore )
- {
- this.dom.restore.parentNode( this.dom.restore );
- }
-
- /* Re-add them (this is not the optimal way of doing this, it is fast and effective) */
- this._fnAddButtons();
-
- /* Update the checkboxes */
- this._fnDrawCallback();
- },
-
-
-
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * Private methods (they are of course public in JS, but recommended as private)
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
- /**
- * Constructor logic
- * @method _fnConstruct
- * @returns void
- * @private
- */
- "_fnConstruct": function ()
- {
- this._fnApplyCustomisation();
-
- var that = this;
- this.dom.wrapper = document.createElement('div');
- this.dom.wrapper.className = "ColVis TableTools";
-
- this.dom.button = this._fnDomBaseButton( this.s.buttonText );
- this.dom.button.className += " ColVis_MasterButton";
- this.dom.wrapper.appendChild( this.dom.button );
-
- this.dom.catcher = this._fnDomCatcher();
- this.dom.collection = this._fnDomCollection();
- this.dom.background = this._fnDomBackground();
-
- this._fnAddButtons();
-
- /* Store the original visbility information */
- for ( var i=0, iLen=this.s.dt.aoColumns.length ; i
=0 ; i-- )
+ {
+ if ( this.dom.buttons[i] !== null )
+ {
+ this.dom.collection.removeChild( this.dom.buttons[i] );
+ }
+ }
+ this.dom.buttons.splice( 0, this.dom.buttons.length );
+
+ if ( this.dom.restore )
+ {
+ this.dom.restore.parentNode( this.dom.restore );
+ }
+
+ /* Re-add them (this is not the optimal way of doing this, it is fast and effective) */
+ this._fnAddButtons();
+
+ /* Update the checkboxes */
+ this._fnDrawCallback();
+ },
+
+
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Private methods (they are of course public in JS, but recommended as private)
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+ /**
+ * Constructor logic
+ * @method _fnConstruct
+ * @returns void
+ * @private
+ */
+ "_fnConstruct": function ()
+ {
+ this._fnApplyCustomisation();
+
+ var that = this;
+ this.dom.wrapper = document.createElement('div');
+ this.dom.wrapper.className = "ColVis TableTools";
+
+ this.dom.button = this._fnDomBaseButton( this.s.buttonText );
+ this.dom.button.className += " ColVis_MasterButton";
+ this.dom.wrapper.appendChild( this.dom.button );
+
+ this.dom.catcher = this._fnDomCatcher();
+ this.dom.collection = this._fnDomCollection();
+ this.dom.background = this._fnDomBackground();
+
+ this._fnAddButtons();
+
+ /* Store the original visbility information */
+ for ( var i=0, iLen=this.s.dt.aoColumns.length ; i'+this.s.sRestore+'' );
-
- $(nButton).click( function (e) {
- for ( var i=0, iLen=that.s.abOriginal.length ; i'+this.s.sShowAll+'' );
-
- $(nButton).click( function (e) {
- for ( var i=0, iLen=that.s.abOriginal.length ; i'+
- ''+sTitle+'' );
-
- $(nButton).click( function (e) {
- var showHide = !$('input', this).is(":checked");
- if ( e.target.nodeName.toLowerCase() == "input" )
- {
- showHide = $('input', this).is(":checked");
- }
-
- /* Need to consider the case where the initialiser created more than one table - change the
- * API index that DataTables is using
- */
- var oldIndex = $.fn.dataTableExt.iApiIndex;
- $.fn.dataTableExt.iApiIndex = that._fnDataTablesApiIndex.call(that);
+ if ( typeof oConfig.bCssPosition != 'undefined' )
+ {
+ this.s.bCssPosition = oConfig.bCssPosition;
+ }
+ },
+
+
+ /**
+ * On each table draw, check the visiblity checkboxes as needed. This allows any process to
+ * update the table's column visiblity and ColVis will still be accurate.
+ * @method _fnDrawCallback
+ * @returns void
+ * @private
+ */
+ "_fnDrawCallback": function ()
+ {
+ var aoColumns = this.s.dt.aoColumns;
+
+ for ( var i=0, iLen=aoColumns.length ; i'+this.s.sRestore+'' );
+
+ $(nButton).click( function (e) {
+ for ( var i=0, iLen=that.s.abOriginal.length ; i'+this.s.sShowAll+'' );
+
+ $(nButton).click( function (e) {
+ for ( var i=0, iLen=that.s.abOriginal.length ; i'+
+ ''+sTitle+'' );
+
+ $(nButton).click( function (e) {
+ var showHide = !$('input', this).is(":checked");
+ if ( e.target.nodeName.toLowerCase() == "input" )
+ {
+ showHide = $('input', this).is(":checked");
+ }
+
+ /* Need to consider the case where the initialiser created more than one table - change the
+ * API index that DataTables is using
+ */
+ var oldIndex = $.fn.dataTableExt.iApiIndex;
+ $.fn.dataTableExt.iApiIndex = that._fnDataTablesApiIndex.call(that);
- // Optimisation for server-side processing when scrolling - don't do a full redraw
- if ( dt.oFeatures.bServerSide && (dt.oScroll.sX !== "" || dt.oScroll.sY !== "" ) )
- {
- that.s.dt.oInstance.fnSetColumnVis( i, showHide, false );
- that.s.dt.oInstance.oApi._fnScrollDraw( that.s.dt );
- that._fnDrawCallback();
- }
- else
- {
- that.s.dt.oInstance.fnSetColumnVis( i, showHide );
- }
+ // Optimisation for server-side processing when scrolling - don't do a full redraw
+ if ( dt.oFeatures.bServerSide && (dt.oScroll.sX !== "" || dt.oScroll.sY !== "" ) )
+ {
+ that.s.dt.oInstance.fnSetColumnVis( i, showHide, false );
+ that.s.dt.oInstance.oApi._fnScrollDraw( that.s.dt );
+ that._fnDrawCallback();
+ }
+ else
+ {
+ that.s.dt.oInstance.fnSetColumnVis( i, showHide );
+ }
- $.fn.dataTableExt.iApiIndex = oldIndex; /* Restore */
-
- if ( that.s.fnStateChange !== null )
- {
- that.s.fnStateChange.call( that, i, showHide );
- }
- } );
-
- return nButton;
- },
-
-
- /**
- * Get the position in the DataTables instance array of the table for this instance of ColVis
- * @method _fnDataTablesApiIndex
- * @returns {int} Index
- * @private
- */
- "_fnDataTablesApiIndex": function ()
- {
- for ( var i=0, iLen=this.s.dt.oInstance.length ; iiDocHeight)? iWinHeight : iDocHeight) +"px";
- nBackground.style.width = ((iWinWidth");
+ nSpan.innerHTML = text;
+
+ $(nButton).bind( 'click', function (e) {
+ that._fnCollectionShow();
+ e.preventDefault();
+ } );
+
+ return nButton;
+ },
+
+
+ /**
+ * Create the element used to contain list the columns (it is shown and hidden as needed)
+ * @method _fnDomCollection
+ * @returns {Node} div container for the collection
+ * @private
+ */
+ "_fnDomCollection": function ()
+ {
+ var that = this;
+ var nHidden = document.createElement('div');
+ nHidden.style.display = "none";
+ nHidden.className = !this.s.dt.bJUI ? "ColVis_collection TableTools_collection" :
+ "ColVis_collection TableTools_collection ui-buttonset ui-buttonset-multi";
+
+ if ( !this.s.bCssPosition )
+ {
+ nHidden.style.position = "absolute";
+ }
+ $(nHidden).css('opacity', 0);
+
+ return nHidden;
+ },
+
+
+ /**
+ * An element to be placed on top of the activate button to catch events
+ * @method _fnDomCatcher
+ * @returns {Node} div container for the collection
+ * @private
+ */
+ "_fnDomCatcher": function ()
+ {
+ var
+ that = this,
+ nCatcher = document.createElement('div');
+ nCatcher.className = "ColVis_catcher TableTools_catcher";
+
+ $(nCatcher).click( function () {
+ that._fnCollectionHide.call( that, null, null );
+ } );
+
+ return nCatcher;
+ },
+
+
+ /**
+ * Create the element used to shade the background, and capture hide events (it is shown and
+ * hidden as needed)
+ * @method _fnDomBackground
+ * @returns {Node} div container for the background
+ * @private
+ */
+ "_fnDomBackground": function ()
+ {
+ var that = this;
+
+ var nBackground = document.createElement('div');
+ nBackground.style.position = "absolute";
+ nBackground.style.left = "0px";
+ nBackground.style.top = "0px";
+ nBackground.className = "ColVis_collectionBackground TableTools_collectionBackground";
+ $(nBackground).css('opacity', 0);
+
+ $(nBackground).click( function () {
+ that._fnCollectionHide.call( that, null, null );
+ } );
+
+ /* When considering a mouse over action for the activation, we also consider a mouse out
+ * which is the same as a mouse over the background - without all the messing around of
+ * bubbling events. Use the catcher element to avoid messing around with bubbling
+ */
+ if ( this.s.activate == "mouseover" )
+ {
+ $(nBackground).mouseover( function () {
+ that.s.overcollection = false;
+ that._fnCollectionHide.call( that, null, null );
+ } );
+ }
+
+ return nBackground;
+ },
+
+
+ /**
+ * Show the show / hide list and the background
+ * @method _fnCollectionShow
+ * @returns void
+ * @private
+ */
+ "_fnCollectionShow": function ()
+ {
+ var that = this, i, iLen;
+ var oPos = $(this.dom.button).offset();
+ var nHidden = this.dom.collection;
+ var nBackground = this.dom.background;
+ var iDivX = parseInt(oPos.left, 10);
+ var iDivY = parseInt(oPos.top + $(this.dom.button).outerHeight(), 10);
+
+ if ( !this.s.bCssPosition )
+ {
+ nHidden.style.top = iDivY+"px";
+ nHidden.style.left = iDivX+"px";
+ }
+ nHidden.style.display = "block";
+ $(nHidden).css('opacity',0);
+
+ var iWinHeight = $(window).height(), iDocHeight = $(document).height(),
+ iWinWidth = $(window).width(), iDocWidth = $(document).width();
+
+ nBackground.style.height = ((iWinHeight>iDocHeight)? iWinHeight : iDocHeight) +"px";
+ nBackground.style.width = ((iWinWidth iDocWidth )
- {
- nHidden.style.left = (iDocWidth-iDivWidth)+"px";
- }
- }
-
- /* This results in a very small delay for the end user but it allows the animation to be
- * much smoother. If you don't want the animation, then the setTimeout can be removed
- */
- setTimeout( function () {
- $(nHidden).animate({"opacity": 1}, that.s.iOverlayFade);
- $(nBackground).animate({"opacity": 0.1}, that.s.iOverlayFade, 'linear', function () {
- /* In IE6 if you set the checked attribute of a hidden checkbox, then this is not visually
- * reflected. As such, we need to do it here, once it is visible. Unbelievable.
- */
- if ( jQuery.browser.msie && jQuery.browser.version == "6.0" )
- {
- that._fnDrawCallback();
- }
- });
- }, 10 );
-
- this.s.hidden = false;
- },
-
-
- /**
- * Hide the show / hide list and the background
- * @method _fnCollectionHide
- * @returns void
- * @private
- */
- "_fnCollectionHide": function ( )
- {
- var that = this;
-
- if ( !this.s.hidden && this.dom.collection !== null )
- {
- this.s.hidden = true;
-
- $(this.dom.collection).animate({"opacity": 0}, that.s.iOverlayFade, function (e) {
- this.style.display = "none";
- } );
-
- $(this.dom.background).animate({"opacity": 0}, that.s.iOverlayFade, function (e) {
- document.body.removeChild( that.dom.background );
- document.body.removeChild( that.dom.catcher );
- } );
- }
- },
-
-
- /**
- * Alter the colspan on any fnOpen rows
- */
- "_fnAdjustOpenRows": function ()
- {
- var aoOpen = this.s.dt.aoOpenRows;
- var iVisible = this.s.dt.oApi._fnVisbleColumns( this.s.dt );
-
- for ( var i=0, iLen=aoOpen.length ; i iDocWidth )
+ {
+ nHidden.style.left = (iDocWidth-iDivWidth)+"px";
+ }
+ }
+
+ /* This results in a very small delay for the end user but it allows the animation to be
+ * much smoother. If you don't want the animation, then the setTimeout can be removed
+ */
+ setTimeout( function () {
+ $(nHidden).animate({"opacity": 1}, that.s.iOverlayFade);
+ $(nBackground).animate({"opacity": 0.1}, that.s.iOverlayFade, 'linear', function () {
+ /* In IE6 if you set the checked attribute of a hidden checkbox, then this is not visually
+ * reflected. As such, we need to do it here, once it is visible. Unbelievable.
+ */
+ if ( jQuery.browser.msie && jQuery.browser.version == "6.0" )
+ {
+ that._fnDrawCallback();
+ }
+ });
+ }, 10 );
+
+ this.s.hidden = false;
+ },
+
+
+ /**
+ * Hide the show / hide list and the background
+ * @method _fnCollectionHide
+ * @returns void
+ * @private
+ */
+ "_fnCollectionHide": function ( )
+ {
+ var that = this;
+
+ if ( !this.s.hidden && this.dom.collection !== null )
+ {
+ this.s.hidden = true;
+
+ $(this.dom.collection).animate({"opacity": 0}, that.s.iOverlayFade, function (e) {
+ this.style.display = "none";
+ } );
+
+ $(this.dom.background).animate({"opacity": 0}, that.s.iOverlayFade, function (e) {
+ document.body.removeChild( that.dom.background );
+ document.body.removeChild( that.dom.catcher );
+ } );
+ }
+ },
+
+
+ /**
+ * Alter the colspan on any fnOpen rows
+ */
+ "_fnAdjustOpenRows": function ()
+ {
+ var aoOpen = this.s.dt.aoOpenRows;
+ var iVisible = this.s.dt.oApi._fnVisbleColumns( this.s.dt );
+
+ for ( var i=0, iLen=aoOpen.length ; i=0 ; i-- )
+ {
+ if ( this.dom.buttons[i] !== null )
+ {
+ this.dom.collection.removeChild( this.dom.buttons[i] );
+ }
+ }
+ this.dom.buttons.splice( 0, this.dom.buttons.length );
+
+ if ( this.dom.restore )
+ {
+ this.dom.restore.parentNode( this.dom.restore );
+ }
+
+ /* Re-add them (this is not the optimal way of doing this, it is fast and effective) */
+ this._fnAddButtons();
+
+ /* Update the checkboxes */
+ this._fnDrawCallback();
+ },
+
+
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Private methods (they are of course public in JS, but recommended as private)
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+ /**
+ * Constructor logic
+ * @method _fnConstruct
+ * @returns void
+ * @private
+ */
+ "_fnConstruct": function ()
+ {
+ this._fnApplyCustomisation();
+
+ var that = this;
+ this.dom.wrapper = document.createElement('div');
+ this.dom.wrapper.className = "ColVis TableTools";
+
+ this.dom.button = this._fnDomBaseButton( this.s.buttonText );
+ this.dom.button.className += " ColVis_MasterButton";
+ this.dom.wrapper.appendChild( this.dom.button );
+
+ this.dom.catcher = this._fnDomCatcher();
+ this.dom.collection = this._fnDomCollection();
+ this.dom.background = this._fnDomBackground();
+
+ this._fnAddButtons();
+
+ /* Store the original visbility information */
+ for ( var i=0, iLen=this.s.dt.aoColumns.length ; i'+this.s.sRestore+'' );
+
+ $(nButton).click( function (e) {
+ for ( var i=0, iLen=that.s.abOriginal.length ; i'+this.s.sShowAll+'' );
+
+ $(nButton).click( function (e) {
+ for ( var i=0, iLen=that.s.abOriginal.length ; i'+
+ ''+sTitle+'' );
+
+ $(nButton).click( function (e) {
+ var showHide = !$('input', this).is(":checked");
+ if ( e.target.nodeName.toLowerCase() == "input" )
+ {
+ showHide = $('input', this).is(":checked");
+ }
+
+ /* Need to consider the case where the initialiser created more than one table - change the
+ * API index that DataTables is using
+ */
+ var oldIndex = $.fn.dataTableExt.iApiIndex;
+ $.fn.dataTableExt.iApiIndex = that._fnDataTablesApiIndex.call(that);
+
+ // Optimisation for server-side processing when scrolling - don't do a full redraw
+ if ( dt.oFeatures.bServerSide && (dt.oScroll.sX !== "" || dt.oScroll.sY !== "" ) )
+ {
+ that.s.dt.oInstance.fnSetColumnVis( i, showHide, false );
+ that.s.dt.oInstance.oApi._fnScrollDraw( that.s.dt );
+ that._fnDrawCallback();
+ }
+ else
+ {
+ that.s.dt.oInstance.fnSetColumnVis( i, showHide );
+ }
+
+ $.fn.dataTableExt.iApiIndex = oldIndex; /* Restore */
+
+ if ( that.s.fnStateChange !== null )
+ {
+ that.s.fnStateChange.call( that, i, showHide );
+ }
+ } );
+
+ return nButton;
+ },
+
+
+ /**
+ * Get the position in the DataTables instance array of the table for this instance of ColVis
+ * @method _fnDataTablesApiIndex
+ * @returns {int} Index
+ * @private
+ */
+ "_fnDataTablesApiIndex": function ()
+ {
+ for ( var i=0, iLen=this.s.dt.oInstance.length ; iiDocHeight)? iWinHeight : iDocHeight) +"px";
+ nBackground.style.width = ((iWinWidth iDocWidth )
+ {
+ nHidden.style.left = (iDocWidth-iDivWidth)+"px";
+ }
+ }
+
+ /* This results in a very small delay for the end user but it allows the animation to be
+ * much smoother. If you don't want the animation, then the setTimeout can be removed
+ */
+ setTimeout( function () {
+ $(nHidden).animate({"opacity": 1}, that.s.iOverlayFade);
+ $(nBackground).animate({"opacity": 0.1}, that.s.iOverlayFade, 'linear', function () {
+ /* In IE6 if you set the checked attribute of a hidden checkbox, then this is not visually
+ * reflected. As such, we need to do it here, once it is visible. Unbelievable.
+ */
+ if ( jQuery.browser.msie && jQuery.browser.version == "6.0" )
+ {
+ that._fnDrawCallback();
+ }
+ });
+ }, 10 );
+
+ this.s.hidden = false;
+ },
+
+
+ /**
+ * Hide the show / hide list and the background
+ * @method _fnCollectionHide
+ * @returns void
+ * @private
+ */
+ "_fnCollectionHide": function ( )
+ {
+ var that = this;
+
+ if ( !this.s.hidden && this.dom.collection !== null )
+ {
+ this.s.hidden = true;
+
+ $(this.dom.collection).animate({"opacity": 0}, that.s.iOverlayFade, function (e) {
+ this.style.display = "none";
+ } );
+
+ $(this.dom.background).animate({"opacity": 0}, that.s.iOverlayFade, function (e) {
+ document.body.removeChild( that.dom.background );
+ document.body.removeChild( that.dom.catcher );
+ } );
+ }
+ },
+
+
+ /**
+ * Alter the colspan on any fnOpen rows
+ */
+ "_fnAdjustOpenRows": function ()
+ {
+ var aoOpen = this.s.dt.aoOpenRows;
+ var iVisible = this.s.dt.oApi._fnVisbleColumns( this.s.dt );
+
+ for ( var i=0, iLen=aoOpen.length ; i= 6: ss = seconds[1][0:6]
- else: ss = seconds[1][0:]
- return "%s:%s:%s.%s" % (h, m, s, ss)
-
def truncate_to_length(item, length):
if isinstance(item, int): item = str(item)
if isinstance(item, basestring):
@@ -202,6 +182,11 @@ class Metadata(Loggable):
self.__metadata = Metadata.airtime_dict(full_mutagen)
# Now we extra the special values that are calculated from the mutagen
# object itself:
+
+ # Hickity Hackity for .wav files. Properly do this later
+ if mmp.extension(fpath) == 'wav':
+ full_mutagen.set_length(mmp.read_wave_duration(fpath))
+
for special_key,f in airtime_special.iteritems():
try:
new_val = f(full_mutagen)
@@ -211,15 +196,6 @@ class Metadata(Loggable):
self.logger.info("Could not get special key %s for %s" %
(special_key, fpath))
self.logger.info(str(e))
-
- # Hickity Hackity for .wav files. Properly do this later
- if mmp.extension(fpath) == 'wav':
- with contextlib.closing(wave.open(fpath,'r')) as f:
- frames = f.getnframes()
- rate = f.getframerate()
- duration = frames/float(rate)
- full_mutagen.set_length(duration)
-
# Finally, we "normalize" all the metadata here:
self.__metadata = mmp.normalized_metadata(self.__metadata, fpath)
# Now we must load the md5:
diff --git a/python_apps/media-monitor2/media/monitor/organizer.py b/python_apps/media-monitor2/media/monitor/organizer.py
index 449a44d97..7bead4e21 100644
--- a/python_apps/media-monitor2/media/monitor/organizer.py
+++ b/python_apps/media-monitor2/media/monitor/organizer.py
@@ -8,6 +8,7 @@ from media.monitor.exceptions import BadSongFile
from media.monitor.events import OrganizeFile
from pydispatch import dispatcher
from os.path import dirname
+import os.path
class Organizer(ReportHandler,Loggable):
"""
@@ -55,8 +56,13 @@ class Organizer(ReportHandler,Loggable):
# Do we need to "massage" the path using mmp.organized_path?
target_path = self.recorded_path if event.metadata.is_recorded() \
else self.target_path
- new_path = mmp.organized_path(event.path, target_path,
- event.metadata.extract())
+ # nasty hack do this properly
+ owner_id = mmp.owner_id(event.path)
+ if owner_id != -1:
+ target_path = os.path.join(target_path, unicode(owner_id))
+
+ mdata = event.metadata.extract()
+ new_path = mmp.organized_path(event.path, target_path, mdata)
# See hack in mmp.magic_move
def new_dir_watch(d):
@@ -68,7 +74,12 @@ class Organizer(ReportHandler,Loggable):
mmp.magic_move(event.path, new_path,
after_dir_make=new_dir_watch(dirname(new_path)))
- owners.add_file_owner(new_path, mmp.owner_id(event.path) )
+ # The reason we need to go around saving the owner in this ass
+ # backwards way is bewcause we are unable to encode the owner id
+ # into the file itself so that the StoreWatchListener listener can
+ # detect it from the file
+ owners.add_file_owner(new_path, owner_id )
+
self.logger.info('Organized: "%s" into "%s"' %
(event.path, new_path))
except BadSongFile as e:
diff --git a/python_apps/media-monitor2/media/monitor/pure.py b/python_apps/media-monitor2/media/monitor/pure.py
index 5a0cf9b90..910ff2c2e 100644
--- a/python_apps/media-monitor2/media/monitor/pure.py
+++ b/python_apps/media-monitor2/media/monitor/pure.py
@@ -3,6 +3,8 @@ import copy
import subprocess
import os
import math
+import wave
+import contextlib
import shutil
import re
import sys
@@ -97,6 +99,13 @@ def is_airtime_recorded(md):
if not 'MDATA_KEY_CREATOR' in md: return False
return md['MDATA_KEY_CREATOR'] == u'Airtime Show Recorder'
+def read_wave_duration(path):
+ with contextlib.closing(wave.open(path,'r')) as f:
+ frames = f.getnframes()
+ rate = f.getframerate()
+ duration = frames/float(rate)
+ return duration
+
def clean_empty_dirs(path):
"""
walks path and deletes every empty directory it finds
@@ -246,8 +255,8 @@ def normalized_metadata(md, original_path):
format_rules = {
'MDATA_KEY_TRACKNUMBER' : parse_int,
'MDATA_KEY_FILEPATH' : lambda x: os.path.normpath(x),
- #'MDATA_KEY_MIME' : lambda x: x.replace('-','/'),
'MDATA_KEY_BPM' : lambda x: x[0:8],
+ 'MDATA_KEY_MIME' : lambda x: x.replace('audio/vorbis','audio/ogg'),
}
new_md = remove_whitespace(new_md) # remove whitespace fields
@@ -263,16 +272,10 @@ def normalized_metadata(md, original_path):
if new_md['MDATA_KEY_BPM'] is None:
del new_md['MDATA_KEY_BPM']
- if is_airtime_recorded(new_md):
- #hour,minute,second,name = new_md['MDATA_KEY_TITLE'].split("-",3)
- #new_md['MDATA_KEY_TITLE'] = u'%s-%s-%s:%s:%s' % \
- #(name, new_md['MDATA_KEY_YEAR'], hour, minute, second)
- # We changed show recorder to output correct metadata for recorded
- # shows
- pass
- else:
+ if not is_airtime_recorded(new_md):
# Read title from filename if it does not exist
default_title = no_extension_basename(original_path)
+ default_title = re.sub(r'__\d+\.',u'.', default_title)
if re.match(".+-%s-.+$" % unicode_unknown, default_title):
default_title = u''
new_md = default_to(dictionary=new_md, keys=['MDATA_KEY_TITLE'],
@@ -306,6 +309,7 @@ def organized_path(old_path, root_path, orig_md):
# MDATA_KEY_BITRATE is in bytes/second i.e. (256000) we want to turn this
# into 254kbps
+
# Some metadata elements cannot be empty, hence we default them to some
# value just so that we can create a correct path
normal_md = default_to_f(orig_md, path_md, unicode_unknown, default_f)
@@ -341,6 +345,8 @@ def organized_path(old_path, root_path, orig_md):
filepath = os.path.join(path, fname)
return filepath
+# TODO : Get rid of this function and every one of its uses. We no longer use
+# the md5 signature of a song for anything
def file_md5(path,max_length=100):
"""
Get md5 of file path (if it exists). Use only max_length characters to save
@@ -353,7 +359,7 @@ def file_md5(path,max_length=100):
# whatever it was able to read which is acceptable behaviour
m.update(f.read(max_length))
return m.hexdigest()
- else: raise ValueError("'%s' must exist to find its md5")
+ else: raise ValueError("'%s' must exist to find its md5" % path)
def encode_to(obj, encoding='utf-8'):
# TODO : add documentation + unit tests for this function
@@ -473,12 +479,12 @@ def file_playable(pathname):
"""
Returns True if 'pathname' is playable by liquidsoap. False otherwise.
"""
- #when there is an single apostrophe inside of a string quoted by
- #apostrophes, we can only escape it by replace that apostrophe with '\''.
- #This breaks the string into two, and inserts an escaped single quote in
- #between them. We run the command as pypo because otherwise the target file
- #is opened with write permissions, and this causes an inotify ON_CLOSE_WRITE
- #event to be fired :/
+ # when there is an single apostrophe inside of a string quoted by
+ # apostrophes, we can only escape it by replace that apostrophe with
+ # '\''. This breaks the string into two, and inserts an escaped
+ # single quote in between them. We run the command as pypo because
+ # otherwise the target file is opened with write permissions, and
+ # this causes an inotify ON_CLOSE_WRITE event to be fired :/
command = ("airtime-liquidsoap -c 'output.dummy" + \
"(audio_to_stereo(single(\"%s\")))' > /dev/null 2>&1") % \
pathname.replace("'", "'\\''")