CC-3395: Play preview for playlists and timelines for shows should show a list under the pop-up player which will play the entire playlist.
Merge branch 'devel' of dev.sourcefabric.org:airtime into devel Conflicts: airtime_mvc/application/controllers/LibraryController.php airtime_mvc/public/js/airtime/library/library.js
|
@ -26,6 +26,7 @@ $ccAcl->add(new Zend_Acl_Resource('library'))
|
|||
->add(new Zend_Acl_Resource('recorder'))
|
||||
->add(new Zend_Acl_Resource('showbuilder'))
|
||||
->add(new Zend_Acl_Resource('auth'))
|
||||
->add(new Zend_Acl_Resource('playouthistory'))
|
||||
->add(new Zend_Acl_Resource('usersettings'));
|
||||
|
||||
/** Creating permissions */
|
||||
|
@ -44,6 +45,7 @@ $ccAcl->allow('G', 'index')
|
|||
->allow('H', 'search')
|
||||
->allow('H', 'playlist')
|
||||
->allow('H', 'showbuilder')
|
||||
->allow('A', 'playouthistory')
|
||||
->allow('A', 'user')
|
||||
->allow('A', 'systemstatus')
|
||||
->allow('A', 'preference');
|
||||
|
|
|
@ -11,9 +11,9 @@ $pages = array(
|
|||
array(
|
||||
'label' => 'Now Playing',
|
||||
'module' => 'default',
|
||||
'controller' => 'Nowplaying',
|
||||
'controller' => 'Showbuilder',
|
||||
'action' => 'index',
|
||||
'resource' => 'nowplaying'
|
||||
'resource' => 'showbuilder'
|
||||
),
|
||||
array(
|
||||
'label' => 'Add Media',
|
||||
|
@ -29,13 +29,6 @@ $pages = array(
|
|||
'action' => 'index',
|
||||
'resource' => 'library'
|
||||
),
|
||||
array(
|
||||
'label' => 'Airtimeline',
|
||||
'module' => 'default',
|
||||
'controller' => 'Showbuilder',
|
||||
'action' => 'index',
|
||||
'resource' => 'showbuilder'
|
||||
),
|
||||
array(
|
||||
'label' => 'Calendar',
|
||||
'module' => 'default',
|
||||
|
@ -85,7 +78,14 @@ $pages = array(
|
|||
'controller' => 'systemstatus',
|
||||
'action' => 'index',
|
||||
'resource' => 'systemstatus'
|
||||
)
|
||||
),
|
||||
array(
|
||||
'label' => 'Playout History',
|
||||
'module' => 'default',
|
||||
'controller' => 'playouthistory',
|
||||
'action' => 'index',
|
||||
'resource' => 'playouthistory'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
|
|
|
@ -29,9 +29,15 @@ class LibraryController extends Zend_Controller_Action
|
|||
|
||||
public function indexAction() {
|
||||
|
||||
global $CC_CONFIG;
|
||||
|
||||
$this->_helper->layout->setLayout('library');
|
||||
|
||||
$request = $this->getRequest();
|
||||
$baseUrl = $request->getBaseUrl();
|
||||
|
||||
$this->view->headScript()->appendFile($this->view->baseUrl('/js/airtime/library/events/library_playlistbuilder.js'),'text/javascript');
|
||||
$this->view->headScript()->appendFile($baseUrl.'/js/airtime/library/main_library.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
|
||||
$this->_helper->actionStack('library', 'library');
|
||||
$this->_helper->actionStack('index', 'playlist');
|
||||
|
@ -56,9 +62,10 @@ class LibraryController extends Zend_Controller_Action
|
|||
$this->view->headScript()->appendFile($baseUrl.'/js/datatables/plugin/dataTables.TableTools.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
|
||||
$this->view->headScript()->appendFile($baseUrl.'/js/airtime/buttons/buttons.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$this->view->headScript()->appendFile($baseUrl.'/js/airtime/utilities/utilities.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$this->view->headScript()->appendFile($baseUrl.'/js/airtime/library/library.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$this->view->headScript()->appendFile($baseUrl.'/js/airtime/library/main_library.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
|
||||
|
||||
$this->view->headLink()->appendStylesheet($baseUrl.'/css/media_library.css?'.$CC_CONFIG['airtime_version']);
|
||||
$this->view->headLink()->appendStylesheet($baseUrl.'/css/jquery.contextMenu.css?'.$CC_CONFIG['airtime_version']);
|
||||
$this->view->headLink()->appendStylesheet($baseUrl.'/css/datatables/css/ColVis.css?'.$CC_CONFIG['airtime_version']);
|
||||
|
|
|
@ -68,7 +68,7 @@ class LoginController extends Zend_Controller_Action
|
|||
$tempSess = new Zend_Session_Namespace("referrer");
|
||||
$tempSess->referrer = 'login';
|
||||
|
||||
$this->_redirect('Nowplaying');
|
||||
$this->_redirect('Showbuilder');
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -95,7 +95,7 @@ class LoginController extends Zend_Controller_Action
|
|||
public function logoutAction()
|
||||
{
|
||||
Zend_Auth::getInstance()->clearIdentity();
|
||||
$this->_redirect('login/index');
|
||||
$this->_redirect('showbuilder/index');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
<?php
|
||||
|
||||
class PlayoutHistoryController extends Zend_Controller_Action
|
||||
{
|
||||
public function init()
|
||||
{
|
||||
$ajaxContext = $this->_helper->getHelper('AjaxContext');
|
||||
$ajaxContext
|
||||
->addActionContext('playout-history-feed', 'json')
|
||||
->initContext();
|
||||
}
|
||||
|
||||
public function indexAction()
|
||||
{
|
||||
global $CC_CONFIG;
|
||||
|
||||
$this->_helper->layout->setLayout('playouthistory');
|
||||
|
||||
$request = $this->getRequest();
|
||||
$baseUrl = $request->getBaseUrl();
|
||||
|
||||
//default time is the last 24 hours.
|
||||
$now = time();
|
||||
$from = $request->getParam("from", $now - (24*60*60));
|
||||
$to = $request->getParam("to", $now);
|
||||
|
||||
$start = DateTime::createFromFormat("U", $from, new DateTimeZone("UTC"));
|
||||
$start->setTimezone(new DateTimeZone(date_default_timezone_get()));
|
||||
$end = DateTime::createFromFormat("U", $to, new DateTimeZone("UTC"));
|
||||
$end->setTimezone(new DateTimeZone(date_default_timezone_get()));
|
||||
|
||||
$form = new Application_Form_DateRange();
|
||||
$form->populate(array(
|
||||
'his_date_start' => $start->format("Y-m-d"),
|
||||
'his_time_start' => $start->format("H:i"),
|
||||
'his_date_end' => $end->format("Y-m-d"),
|
||||
'his_time_end' => $end->format("H:i")
|
||||
));
|
||||
|
||||
$this->view->date_form = $form;
|
||||
|
||||
$this->view->headScript()->appendFile($baseUrl.'/js/contextmenu/jquery.contextMenu.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$this->view->headScript()->appendFile($baseUrl.'/js/datatables/js/jquery.dataTables.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$this->view->headScript()->appendFile($baseUrl.'/js/datatables/plugin/dataTables.pluginAPI.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$this->view->headScript()->appendFile($baseUrl.'/js/datatables/plugin/dataTables.fnSetFilteringDelay.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$this->view->headScript()->appendFile($baseUrl.'/js/datatables/plugin/TableTools/js/ZeroClipboard.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$this->view->headScript()->appendFile($baseUrl.'/js/datatables/plugin/TableTools/js/TableTools.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
|
||||
$offset = date("Z") * -1;
|
||||
$this->view->headScript()->appendScript("var serverTimezoneOffset = {$offset}; //in seconds");
|
||||
$this->view->headScript()->appendFile($baseUrl.'/js/timepicker/jquery.ui.timepicker.js','text/javascript');
|
||||
$this->view->headScript()->appendFile($baseUrl.'/js/airtime/buttons/buttons.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$this->view->headScript()->appendFile($baseUrl.'/js/airtime/utilities/utilities.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$this->view->headScript()->appendFile($baseUrl.'/js/airtime/playouthistory/historytable.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
|
||||
$this->view->headLink()->appendStylesheet($baseUrl.'/js/datatables/plugin/TableTools/css/TableTools.css?'.$CC_CONFIG['airtime_version']);
|
||||
//$this->view->headLink()->appendStylesheet($baseUrl.'/js/datatables/plugin/TableTools/css/TableTools_JUI.css?'.$CC_CONFIG['airtime_version']);
|
||||
|
||||
$this->view->headLink()->appendStylesheet($baseUrl.'/css/jquery.ui.timepicker.css');
|
||||
}
|
||||
|
||||
public function playoutHistoryFeedAction()
|
||||
{
|
||||
$request = $this->getRequest();
|
||||
$current_time = time();
|
||||
|
||||
$params = $request->getParams();
|
||||
|
||||
$starts_epoch = $request->getParam("start", $current_time - (60*60*24));
|
||||
$ends_epoch = $request->getParam("end", $current_time);
|
||||
|
||||
$startsDT = DateTime::createFromFormat("U", $starts_epoch, new DateTimeZone("UTC"));
|
||||
$endsDT = DateTime::createFromFormat("U", $ends_epoch, new DateTimeZone("UTC"));
|
||||
|
||||
Logging::log("history starts {$startsDT->format("Y-m-d H:i:s")}");
|
||||
Logging::log("history ends {$endsDT->format("Y-m-d H:i:s")}");
|
||||
|
||||
$history = new Application_Model_PlayoutHistory($startsDT, $endsDT, $params);
|
||||
|
||||
$r = $history->getItems();
|
||||
|
||||
$this->view->sEcho = $r["sEcho"];
|
||||
$this->view->iTotalDisplayRecords = $r["iTotalDisplayRecords"];
|
||||
$this->view->iTotalRecords = $r["iTotalRecords"];
|
||||
$this->view->history = $r["history"];
|
||||
}
|
||||
}
|
|
@ -10,6 +10,7 @@ class ShowbuilderController extends Zend_Controller_Action
|
|||
->addActionContext('schedule-add', 'json')
|
||||
->addActionContext('schedule-remove', 'json')
|
||||
->addActionContext('builder-dialog', 'json')
|
||||
->addActionContext('check-builder-feed', 'json')
|
||||
->addActionContext('builder-feed', 'json')
|
||||
->initContext();
|
||||
}
|
||||
|
@ -17,10 +18,80 @@ class ShowbuilderController extends Zend_Controller_Action
|
|||
public function indexAction() {
|
||||
|
||||
$this->_helper->layout->setLayout('builder');
|
||||
|
||||
$this->view->headScript()->appendFile($this->view->baseUrl('/js/airtime/library/events/library_showbuilder.js'),'text/javascript');
|
||||
$this->_helper->viewRenderer->setResponseSegment('dialog');
|
||||
|
||||
$this->_helper->actionStack('library', 'library');
|
||||
global $CC_CONFIG;
|
||||
|
||||
$request = $this->getRequest();
|
||||
$baseUrl = $request->getBaseUrl();
|
||||
|
||||
$this->view->headScript()->appendFile($this->view->baseUrl('/js/airtime/library/events/library_showbuilder.js?'.$CC_CONFIG['airtime_version']),'text/javascript');
|
||||
|
||||
$refer_sses = new Zend_Session_Namespace('referrer');
|
||||
$userInfo = Zend_Auth::getInstance()->getStorage()->read();
|
||||
$user = new Application_Model_User($userInfo->id);
|
||||
|
||||
if ($request->isPost()) {
|
||||
$form = new Application_Form_RegisterAirtime();
|
||||
|
||||
$values = $request->getPost();
|
||||
if ($values["Publicise"] != 1 && $form->isValid($values)) {
|
||||
Application_Model_Preference::SetSupportFeedback($values["SupportFeedback"]);
|
||||
|
||||
if (isset($values["Privacy"])) {
|
||||
Application_Model_Preference::SetPrivacyPolicyCheck($values["Privacy"]);
|
||||
}
|
||||
// unset session
|
||||
Zend_Session::namespaceUnset('referrer');
|
||||
}
|
||||
else if ($values["Publicise"] == '1' && $form->isValid($values)) {
|
||||
Application_Model_Preference::SetHeadTitle($values["stnName"], $this->view);
|
||||
Application_Model_Preference::SetPhone($values["Phone"]);
|
||||
Application_Model_Preference::SetEmail($values["Email"]);
|
||||
Application_Model_Preference::SetStationWebSite($values["StationWebSite"]);
|
||||
Application_Model_Preference::SetPublicise($values["Publicise"]);
|
||||
|
||||
$form->Logo->receive();
|
||||
$imagePath = $form->Logo->getFileName();
|
||||
|
||||
Application_Model_Preference::SetStationCountry($values["Country"]);
|
||||
Application_Model_Preference::SetStationCity($values["City"]);
|
||||
Application_Model_Preference::SetStationDescription($values["Description"]);
|
||||
Application_Model_Preference::SetStationLogo($imagePath);
|
||||
Application_Model_Preference::SetSupportFeedback($values["SupportFeedback"]);
|
||||
|
||||
if (isset($values["Privacy"])){
|
||||
Application_Model_Preference::SetPrivacyPolicyCheck($values["Privacy"]);
|
||||
}
|
||||
// unset session
|
||||
Zend_Session::namespaceUnset('referrer');
|
||||
}
|
||||
else {
|
||||
$logo = Application_Model_Preference::GetStationLogo();
|
||||
if ($logo) {
|
||||
$this->view->logoImg = $logo;
|
||||
}
|
||||
$this->view->dialog = $form;
|
||||
$this->view->headScript()->appendFile($baseUrl.'/js/airtime/nowplaying/register.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
}
|
||||
}
|
||||
else {
|
||||
//popup if previous page was login
|
||||
if ($refer_sses->referrer == 'login' && Application_Model_Nowplaying::ShouldShowPopUp()
|
||||
&& !Application_Model_Preference::GetSupportFeedback() && $user->isAdmin()){
|
||||
|
||||
$form = new Application_Form_RegisterAirtime();
|
||||
|
||||
$logo = Application_Model_Preference::GetStationLogo();
|
||||
if ($logo) {
|
||||
$this->view->logoImg = $logo;
|
||||
}
|
||||
$this->view->dialog = $form;
|
||||
$this->view->headScript()->appendFile($baseUrl.'/js/airtime/nowplaying/register.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
}
|
||||
}
|
||||
|
||||
$this->_helper->actionStack('library', 'library');
|
||||
$this->_helper->actionStack('builder', 'showbuilder');
|
||||
}
|
||||
|
||||
|
@ -33,7 +104,7 @@ class ShowbuilderController extends Zend_Controller_Action
|
|||
|
||||
$now = time();
|
||||
$from = $request->getParam("from", $now);
|
||||
$to = $request->getParam("to", $now+(24*60*60));
|
||||
$to = $request->getParam("to", $now + (24*60*60));
|
||||
|
||||
$start = DateTime::createFromFormat("U", $from, new DateTimeZone("UTC"));
|
||||
$start->setTimezone(new DateTimeZone(date_default_timezone_get()));
|
||||
|
@ -52,12 +123,12 @@ class ShowbuilderController extends Zend_Controller_Action
|
|||
|
||||
$offset = date("Z") * -1;
|
||||
$this->view->headScript()->appendScript("var serverTimezoneOffset = {$offset}; //in seconds");
|
||||
$this->view->headScript()->appendFile($baseUrl.'/js/timepicker/jquery.ui.timepicker.js','text/javascript');
|
||||
$this->view->headScript()->appendFile($baseUrl.'/js/airtime/showbuilder/builder.js','text/javascript');
|
||||
$this->view->headScript()->appendFile($baseUrl.'/js/airtime/showbuilder/main_builder.js','text/javascript');
|
||||
$this->view->headScript()->appendFile($baseUrl.'/js/timepicker/jquery.ui.timepicker.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$this->view->headScript()->appendFile($baseUrl.'/js/airtime/showbuilder/builder.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$this->view->headScript()->appendFile($baseUrl.'/js/airtime/showbuilder/main_builder.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
|
||||
$this->view->headLink()->appendStylesheet($baseUrl.'/css/jquery.ui.timepicker.css');
|
||||
$this->view->headLink()->appendStylesheet($baseUrl.'/css/showbuilder.css');
|
||||
$this->view->headLink()->appendStylesheet($baseUrl.'/css/jquery.ui.timepicker.css?'.$CC_CONFIG['airtime_version']);
|
||||
$this->view->headLink()->appendStylesheet($baseUrl.'/css/showbuilder.css?'.$CC_CONFIG['airtime_version']);
|
||||
}
|
||||
|
||||
public function builderDialogAction() {
|
||||
|
@ -88,6 +159,37 @@ class ShowbuilderController extends Zend_Controller_Action
|
|||
$this->view->dialog = $this->view->render('showbuilder/builderDialog.phtml');
|
||||
}
|
||||
|
||||
public function checkBuilderFeedAction() {
|
||||
|
||||
$request = $this->getRequest();
|
||||
$current_time = time();
|
||||
|
||||
$starts_epoch = $request->getParam("start", $current_time);
|
||||
//default ends is 24 hours after starts.
|
||||
$ends_epoch = $request->getParam("end", $current_time + (60*60*24));
|
||||
$show_filter = intval($request->getParam("showFilter", 0));
|
||||
$my_shows = intval($request->getParam("myShows", 0));
|
||||
$timestamp = intval($request->getParam("timestamp", -1));
|
||||
|
||||
$startsDT = DateTime::createFromFormat("U", $starts_epoch, new DateTimeZone("UTC"));
|
||||
$endsDT = DateTime::createFromFormat("U", $ends_epoch, new DateTimeZone("UTC"));
|
||||
|
||||
Logging::log("showbuilder starts {$startsDT->format("Y-m-d H:i:s")}");
|
||||
Logging::log("showbuilder ends {$endsDT->format("Y-m-d H:i:s")}");
|
||||
|
||||
$opts = array("myShows" => $my_shows, "showFilter" => $show_filter);
|
||||
$showBuilder = new Application_Model_ShowBuilder($startsDT, $endsDT, $opts);
|
||||
|
||||
//only send the schedule back if updates have been made.
|
||||
// -1 default will always call the schedule to be sent back if no timestamp is defined.
|
||||
if ($showBuilder->hasBeenUpdatedSince($timestamp)) {
|
||||
$this->view->update = true;
|
||||
}
|
||||
else {
|
||||
$this->view->update = false;
|
||||
}
|
||||
}
|
||||
|
||||
public function builderFeedAction() {
|
||||
|
||||
$request = $this->getRequest();
|
||||
|
@ -98,6 +200,7 @@ class ShowbuilderController extends Zend_Controller_Action
|
|||
$ends_epoch = $request->getParam("end", $current_time + (60*60*24));
|
||||
$show_filter = intval($request->getParam("showFilter", 0));
|
||||
$my_shows = intval($request->getParam("myShows", 0));
|
||||
$timestamp = intval($request->getParam("timestamp", -1));
|
||||
|
||||
$startsDT = DateTime::createFromFormat("U", $starts_epoch, new DateTimeZone("UTC"));
|
||||
$endsDT = DateTime::createFromFormat("U", $ends_epoch, new DateTimeZone("UTC"));
|
||||
|
@ -109,6 +212,7 @@ class ShowbuilderController extends Zend_Controller_Action
|
|||
$showBuilder = new Application_Model_ShowBuilder($startsDT, $endsDT, $opts);
|
||||
|
||||
$this->view->schedule = $showBuilder->GetItems();
|
||||
$this->view->timestamp = $current_time;
|
||||
}
|
||||
|
||||
public function scheduleAddAction() {
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
|
||||
class Application_Form_DateRange extends Zend_Form_SubForm
|
||||
{
|
||||
|
||||
public function init()
|
||||
{
|
||||
$this->setDecorators(array(
|
||||
array('ViewScript', array('viewScript' => 'form/daterange.phtml'))
|
||||
));
|
||||
|
||||
// Add start date element
|
||||
$startDate = new Zend_Form_Element_Text('his_date_start');
|
||||
$startDate->class = 'input_text';
|
||||
$startDate->setRequired(true)
|
||||
->setLabel('Date Start:')
|
||||
->setValue(date("Y-m-d"))
|
||||
->setFilters(array('StringTrim'))
|
||||
->setValidators(array(
|
||||
'NotEmpty',
|
||||
array('date', false, array('YYYY-MM-DD'))))
|
||||
->setDecorators(array('ViewHelper'));
|
||||
$startDate->setAttrib('alt', 'date');
|
||||
$this->addElement($startDate);
|
||||
|
||||
// Add start time element
|
||||
$startTime = new Zend_Form_Element_Text('his_time_start');
|
||||
$startTime->class = 'input_text';
|
||||
$startTime->setRequired(true)
|
||||
->setValue('00:00')
|
||||
->setFilters(array('StringTrim'))
|
||||
->setValidators(array(
|
||||
'NotEmpty',
|
||||
array('date', false, array('HH:mm')),
|
||||
array('regex', false, array('/^[0-9:]+$/', 'messages' => 'Invalid character entered'))))
|
||||
->setDecorators(array('ViewHelper'));
|
||||
$startTime->setAttrib('alt', 'time');
|
||||
$this->addElement($startTime);
|
||||
|
||||
// Add end date element
|
||||
$endDate = new Zend_Form_Element_Text('his_date_end');
|
||||
$endDate->class = 'input_text';
|
||||
$endDate->setRequired(true)
|
||||
->setLabel('Date End:')
|
||||
->setValue(date("Y-m-d"))
|
||||
->setFilters(array('StringTrim'))
|
||||
->setValidators(array(
|
||||
'NotEmpty',
|
||||
array('date', false, array('YYYY-MM-DD'))))
|
||||
->setDecorators(array('ViewHelper'));
|
||||
$endDate->setAttrib('alt', 'date');
|
||||
$this->addElement($endDate);
|
||||
|
||||
// Add end time element
|
||||
$endTime = new Zend_Form_Element_Text('his_time_end');
|
||||
$endTime->class = 'input_text';
|
||||
$endTime->setRequired(true)
|
||||
->setValue('01:00')
|
||||
->setFilters(array('StringTrim'))
|
||||
->setValidators(array(
|
||||
'NotEmpty',
|
||||
array('date', false, array('HH:mm')),
|
||||
array('regex', false, array('/^[0-9:]+$/', 'messages' => 'Invalid character entered'))))
|
||||
->setDecorators(array('ViewHelper'));
|
||||
$endTime->setAttrib('alt', 'time');
|
||||
$this->addElement($endTime);
|
||||
}
|
||||
}
|
|
@ -11,6 +11,12 @@ class Application_Form_ShowBuilder extends Zend_Form_SubForm
|
|||
array('ViewScript', array('viewScript' => 'form/showbuilder.phtml'))
|
||||
));
|
||||
|
||||
//set value to -1 originally to ensure we grab the schedule on first call.
|
||||
$timestamp = new Zend_Form_Element_Hidden('sb_timestamp');
|
||||
$timestamp->setValue(-1)
|
||||
->setDecorators(array('ViewHelper'));
|
||||
$this->addElement($timestamp);
|
||||
|
||||
// Add start date element
|
||||
$startDate = new Zend_Form_Element_Text('sb_date_start');
|
||||
$startDate->class = 'input_text';
|
||||
|
|
|
@ -23,5 +23,8 @@
|
|||
<div id="library_content" class="tabs ui-widget ui-widget-content block-shadow alpha-block padded" style="display:none"><?php echo $this->layout()->library ?></div>
|
||||
<div id="show_builder" class="ui-widget ui-widget-content block-shadow omega-block padded"><?php echo $this->layout()->builder ?></div>
|
||||
</div>
|
||||
|
||||
<?php echo $this->layout()->dialog ?>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
<div class="wrapper">
|
||||
<!--Set to z-index 254 to make it lower than the top-panel and the ZFDebug info bar, but higher than the side-playlist-->
|
||||
<div id="library_content" class="ui-widget ui-widget-content block-shadow alpha-block padded" style="z-index:254"><?php echo $this->layout()->library ?></div>
|
||||
<div id="side_playlist" class="ui-widget ui-widget-content block-shadow omega-block"><?php echo $this->layout()->spl ?></div>
|
||||
<div id="side_playlist" class="ui-widget ui-widget-content block-shadow omega-block padded"><?php echo $this->layout()->spl ?></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
<?php echo $this->doctype() ?>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<?php echo $this->headTitle() ?>
|
||||
<?php echo $this->headScript() ?>
|
||||
<?php echo $this->headLink() ?>
|
||||
<?php echo isset($this->google_analytics)?$this->google_analytics:"" ?>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="Panel">
|
||||
<div class="logo"></div>
|
||||
<?php echo $this->versionNotify() ?>
|
||||
<?php echo $this->partial('partialviews/header.phtml', array("user" => $this->loggedInAs(), "is_trial"=>$this->isTrial(), "trial_remain"=> $this->trialRemaining())) ?>
|
||||
|
||||
<?php $partial = array('menu.phtml', 'default');
|
||||
$this->navigation()->menu()->setPartial($partial); ?>
|
||||
|
||||
<?php echo $this->navigation()->menu() ?>
|
||||
</div>
|
||||
|
||||
<div class="wrapper">
|
||||
<div id="history_content" class="ui-widget ui-widget-content block-shadow alpha-block padded"><?php echo $this->layout()->content ?></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,109 @@
|
|||
<?php
|
||||
|
||||
class Application_Model_Datatables {
|
||||
|
||||
/*
|
||||
* query used to return data for a paginated/searchable datatable.
|
||||
*/
|
||||
public static function findEntries($con, $displayColumns, $fromTable, $data, $dataProp = "aaData")
|
||||
{
|
||||
$where = array();
|
||||
|
||||
if ($data["sSearch"] !== "") {
|
||||
$searchTerms = explode(" ", $data["sSearch"]);
|
||||
}
|
||||
|
||||
$selectorCount = "SELECT COUNT(*) ";
|
||||
$selectorRows = "SELECT ".join(",", $displayColumns)." ";
|
||||
|
||||
$sql = $selectorCount." FROM ".$fromTable;
|
||||
$sqlTotalRows = $sql;
|
||||
|
||||
if (isset($searchTerms)) {
|
||||
$searchCols = array();
|
||||
for ($i = 0; $i < $data["iColumns"]; $i++) {
|
||||
if ($data["bSearchable_".$i] == "true") {
|
||||
$searchCols[] = $data["mDataProp_{$i}"];
|
||||
}
|
||||
}
|
||||
|
||||
$outerCond = array();
|
||||
|
||||
foreach ($searchTerms as $term) {
|
||||
$innerCond = array();
|
||||
|
||||
foreach ($searchCols as $col) {
|
||||
$escapedTerm = pg_escape_string($term);
|
||||
$innerCond[] = "{$col}::text ILIKE '%{$escapedTerm}%'";
|
||||
}
|
||||
$outerCond[] = "(".join(" OR ", $innerCond).")";
|
||||
}
|
||||
$where[] = "(".join(" AND ", $outerCond).")";
|
||||
}
|
||||
// End Where clause
|
||||
|
||||
// Order By clause
|
||||
$orderby = array();
|
||||
for ($i = 0; $i < $data["iSortingCols"]; $i++){
|
||||
$num = $data["iSortCol_".$i];
|
||||
$orderby[] = $data["mDataProp_{$num}"]." ".$data["sSortDir_".$i];
|
||||
}
|
||||
$orderby[] = "id";
|
||||
$orderby = join("," , $orderby);
|
||||
// End Order By clause
|
||||
|
||||
$displayLength = intval($data["iDisplayLength"]);
|
||||
if (count($where) > 0) {
|
||||
$where = join(" AND ", $where);
|
||||
$sql = $selectorCount." FROM ".$fromTable." WHERE ".$where;
|
||||
$sqlTotalDisplayRows = $sql;
|
||||
|
||||
$sql = $selectorRows." FROM ".$fromTable." WHERE ".$where." ORDER BY ".$orderby;
|
||||
|
||||
//limit the results returned.
|
||||
if ($displayLength !== -1) {
|
||||
$sql .= " OFFSET ".$data["iDisplayStart"]." LIMIT ".$displayLength;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$sql = $selectorRows." FROM ".$fromTable." ORDER BY ".$orderby;
|
||||
|
||||
//limit the results returned.
|
||||
if ($displayLength !== -1) {
|
||||
$sql .= " OFFSET ".$data["iDisplayStart"]." LIMIT ".$displayLength;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$r = $con->query($sqlTotalRows);
|
||||
Logging::log($sqlTotalRows);
|
||||
$totalRows = $r->fetchColumn(0);
|
||||
|
||||
if (isset($sqlTotalDisplayRows)) {
|
||||
$r = $con->query($sqlTotalDisplayRows);
|
||||
Logging::log($sqlTotalDisplayRows);
|
||||
$totalDisplayRows = $r->fetchColumn(0);
|
||||
}
|
||||
else {
|
||||
$totalDisplayRows = $totalRows;
|
||||
}
|
||||
|
||||
$r = $con->query($sql);
|
||||
$r->setFetchMode(PDO::FETCH_ASSOC);
|
||||
$results = $r->fetchAll();
|
||||
}
|
||||
catch (Exception $e) {
|
||||
Logging::log($e->getMessage());
|
||||
}
|
||||
|
||||
//display sql executed in airtime log for testing
|
||||
Logging::log($sql);
|
||||
|
||||
return array(
|
||||
"sEcho" => intval($data["sEcho"]),
|
||||
"iTotalDisplayRecords" => intval($totalDisplayRows),
|
||||
"iTotalRecords" => intval($totalRows),
|
||||
$dataProp => $results
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
<?php
|
||||
|
||||
require_once 'formatters/LengthFormatter.php';
|
||||
|
||||
class Application_Model_PlayoutHistory {
|
||||
|
||||
private $con;
|
||||
private $timezone;
|
||||
|
||||
//in UTC timezone
|
||||
private $startDT;
|
||||
//in UTC timezone
|
||||
private $endDT;
|
||||
|
||||
private $epoch_now;
|
||||
private $opts;
|
||||
|
||||
private $mDataPropMap = array(
|
||||
"artist" => "file.artist_name",
|
||||
"title" => "file.track_title",
|
||||
"played" => "playout.played",
|
||||
"length" => "file.length",
|
||||
"composer" => "file.composer",
|
||||
"copyright" => "file.copyright",
|
||||
);
|
||||
|
||||
public function __construct($p_startDT, $p_endDT, $p_opts) {
|
||||
|
||||
$this->con = Propel::getConnection(CcSchedulePeer::DATABASE_NAME);
|
||||
$this->startDT = $p_startDT;
|
||||
$this->endDT = $p_endDT;
|
||||
$this->timezone = date_default_timezone_get();
|
||||
$this->epoch_now = time();
|
||||
$this->opts = $p_opts;
|
||||
}
|
||||
|
||||
/*
|
||||
* map front end mDataProp labels to proper column names for searching etc.
|
||||
*/
|
||||
private function translateColumns() {
|
||||
|
||||
for ($i = 0; $i < $this->opts["iColumns"]; $i++){
|
||||
|
||||
$this->opts["mDataProp_{$i}"] = $this->mDataPropMap[$this->opts["mDataProp_{$i}"]];
|
||||
}
|
||||
}
|
||||
|
||||
public function getItems() {
|
||||
|
||||
$this->translateColumns();
|
||||
|
||||
$select = array(
|
||||
"file.track_title as title",
|
||||
"file.artist_name as artist",
|
||||
"playout.played",
|
||||
"playout.file_id",
|
||||
"file.composer",
|
||||
"file.copyright",
|
||||
"file.length"
|
||||
);
|
||||
|
||||
$start = $this->startDT->format("Y-m-d H:i:s");
|
||||
$end = $this->endDT->format("Y-m-d H:i:s");
|
||||
|
||||
$historyTable = "(
|
||||
select count(schedule.file_id) as played, schedule.file_id as file_id
|
||||
from cc_schedule as schedule
|
||||
where schedule.starts >= '{$start}' and schedule.starts < '{$end}'
|
||||
group by schedule.file_id
|
||||
)
|
||||
AS playout left join cc_files as file on (file.id = playout.file_id)";
|
||||
|
||||
$results = Application_Model_Datatables::findEntries($this->con, $select, $historyTable, $this->opts, "history");
|
||||
|
||||
foreach ($results["history"] as &$row) {
|
||||
$formatter = new LengthFormatter($row['length']);
|
||||
$row['length'] = $formatter->format();
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
}
|
|
@ -162,7 +162,7 @@ class Application_Model_Show {
|
|||
->find($con);
|
||||
|
||||
foreach ($instances as $instance) {
|
||||
$instance->updateScheduleStatus();
|
||||
$instance->updateScheduleStatus($con);
|
||||
}
|
||||
|
||||
$con->commit();
|
||||
|
@ -1448,7 +1448,8 @@ class Application_Model_Show {
|
|||
}
|
||||
|
||||
$sql = "SELECT starts, ends, record, rebroadcast, instance_id, show_id, name,
|
||||
color, background_color, file_id, cc_show_instances.id AS instance_id
|
||||
color, background_color, file_id, cc_show_instances.id AS instance_id,
|
||||
last_scheduled
|
||||
FROM cc_show_instances
|
||||
LEFT JOIN cc_show ON cc_show.id = cc_show_instances.show_id
|
||||
WHERE cc_show_instances.modified_instance = FALSE";
|
||||
|
@ -1479,6 +1480,9 @@ class Application_Model_Show {
|
|||
$sql = $sql." AND ({$exclude})";
|
||||
}
|
||||
|
||||
//Logging::log("getShows");
|
||||
//Logging::log($sql);
|
||||
|
||||
return $CC_DBC->GetAll($sql);
|
||||
}
|
||||
|
||||
|
|
|
@ -6,13 +6,19 @@ require_once 'formatters/TimeFilledFormatter.php';
|
|||
class Application_Model_ShowBuilder {
|
||||
|
||||
private $timezone;
|
||||
|
||||
//in UTC timezone
|
||||
private $startDT;
|
||||
//in UTC timezone
|
||||
private $endDT;
|
||||
|
||||
private $user;
|
||||
private $opts;
|
||||
|
||||
private $contentDT;
|
||||
private $epoch_now;
|
||||
|
||||
private $hasCurrent;
|
||||
|
||||
private $defaultRowArray = array(
|
||||
"header" => false,
|
||||
|
@ -47,6 +53,8 @@ class Application_Model_ShowBuilder {
|
|||
$this->user = Application_Model_User::GetCurrentUser();
|
||||
$this->opts = $p_opts;
|
||||
$this->epoch_now = time();
|
||||
|
||||
$this->hasCurrent = false;
|
||||
}
|
||||
|
||||
//check to see if this row should be editable.
|
||||
|
@ -59,12 +67,12 @@ class Application_Model_ShowBuilder {
|
|||
|
||||
$showStartDT = new DateTime($p_item["si_starts"], new DateTimeZone("UTC"));
|
||||
$schedStartDT = new DateTime($p_item["sched_starts"], new DateTimeZone("UTC"));
|
||||
|
||||
|
||||
$showStartEpoch = intval($showStartDT->format('U'));
|
||||
$schedStartEpoch = intval($schedStartDT->format('U'));
|
||||
|
||||
//can only schedule the show if item hasn't started and you are allowed.
|
||||
if ($this->epoch_now < max($showStartEpoch, $schedStartEpoch)
|
||||
if ($this->epoch_now < max($showStartEpoch, $schedStartEpoch)
|
||||
&& $this->user->canSchedule($p_item["show_id"]) == true) {
|
||||
$row["allowed"] = true;
|
||||
}
|
||||
|
@ -89,11 +97,13 @@ class Application_Model_ShowBuilder {
|
|||
}
|
||||
|
||||
private function isCurrent($p_epochItemStart, $p_epochItemEnd, &$row) {
|
||||
|
||||
|
||||
if ($this->epoch_now >= $p_epochItemStart && $this->epoch_now < $p_epochItemEnd) {
|
||||
$row["current"] = true;
|
||||
//how many seconds the view should wait to redraw itself.
|
||||
$row["refresh"] = $p_epochItemEnd - $this->epoch_now;
|
||||
|
||||
$this->hasCurrent = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -111,6 +121,7 @@ class Application_Model_ShowBuilder {
|
|||
|
||||
$row["header"] = true;
|
||||
$row["starts"] = $showStartDT->format("Y-m-d H:i");
|
||||
$row["timeUntil"] = intval($showStartDT->format("U")) - $this->epoch_now;
|
||||
$row["ends"] = $showEndDT->format("Y-m-d H:i");
|
||||
$row["duration"] = $showEndDT->format("U") - $showStartDT->format("U");
|
||||
$row["title"] = $p_item["show_name"];
|
||||
|
@ -194,6 +205,39 @@ class Application_Model_ShowBuilder {
|
|||
return $row;
|
||||
}
|
||||
|
||||
/*
|
||||
* @param int $timestamp Unix timestamp in seconds.
|
||||
*
|
||||
* @return boolean whether the schedule in the show builder's range has been updated.
|
||||
*
|
||||
*/
|
||||
public function hasBeenUpdatedSince($timestamp) {
|
||||
$outdated = false;
|
||||
|
||||
Logging::log("checking if show builder has been updated since {$timestamp}");
|
||||
|
||||
$shows = Application_Model_Show::getShows($this->startDT, $this->endDT);
|
||||
|
||||
foreach ($shows as $show) {
|
||||
|
||||
if (isset($show["last_scheduled"])) {
|
||||
$dt = new DateTime($show["last_scheduled"], new DateTimeZone("UTC"));
|
||||
|
||||
//check if any of the shows have a more recent timestamp.
|
||||
if ($timestamp < intval($dt->format("U"))) {
|
||||
$outdated = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (count($shows) == 0) {
|
||||
$outdated = true;
|
||||
}
|
||||
|
||||
return $outdated;
|
||||
}
|
||||
|
||||
public function GetItems() {
|
||||
|
||||
$current_id = -1;
|
||||
|
@ -229,7 +273,7 @@ class Application_Model_ShowBuilder {
|
|||
//pass in the previous row as it's the last row for the previous show.
|
||||
$display_items[] = $this->makeFooterRow($scheduled_items[$i-1]);
|
||||
}
|
||||
|
||||
|
||||
$display_items[] = $this->makeHeaderRow($item);
|
||||
|
||||
$current_id = $item["si_id"];
|
||||
|
@ -247,6 +291,10 @@ class Application_Model_ShowBuilder {
|
|||
if (count($scheduled_items) > 0) {
|
||||
$display_items[] = $this->makeFooterRow($scheduled_items[count($scheduled_items)-1]);
|
||||
}
|
||||
|
||||
if (!$this->hasCurrent) {
|
||||
|
||||
}
|
||||
|
||||
return $display_items;
|
||||
}
|
||||
|
|
|
@ -395,7 +395,7 @@ class Application_Model_StoredFile {
|
|||
}
|
||||
|
||||
private function constructGetFileUrl($p_serverName, $p_serverPort){
|
||||
Logging::log("getting media! - 2");
|
||||
Logging::log("getting media! - 2");
|
||||
return "http://$p_serverName:$p_serverPort/api/get-media/file/".$this->getGunId().".".$this->getFileExtension();
|
||||
}
|
||||
|
||||
|
@ -660,7 +660,7 @@ Logging::log("getting media! - 2");
|
|||
|
||||
if($type == "au"){//&& isset( $audioResults )) {
|
||||
$row['audioFile'] = $row['gunid'].".".pathinfo($row['filepath'], PATHINFO_EXTENSION);
|
||||
$row['image'] = '<div class="big_play"><img src="/css/images/icon_audioclip.png"></div>';
|
||||
$row['image'] = '<img src="/css/images/icon_audioclip.png">';
|
||||
}
|
||||
else {
|
||||
$row['image'] = '<img src="/css/images/icon_playlist.png">';
|
||||
|
@ -669,22 +669,22 @@ Logging::log("getting media! - 2");
|
|||
|
||||
return $results;
|
||||
}
|
||||
|
||||
|
||||
public static function searchFiles($displayColumns, $fromTable, $data)
|
||||
{
|
||||
$con = Propel::getConnection(CcFilesPeer::DATABASE_NAME);
|
||||
$where = array();
|
||||
|
||||
|
||||
if ($data["sSearch"] !== "") {
|
||||
$searchTerms = explode(" ", $data["sSearch"]);
|
||||
}
|
||||
|
||||
|
||||
$selectorCount = "SELECT COUNT(*) ";
|
||||
$selectorRows = "SELECT ".join(",", $displayColumns)." ";
|
||||
|
||||
|
||||
$sql = $selectorCount." FROM ".$fromTable;
|
||||
$sqlTotalRows = $sql;
|
||||
|
||||
|
||||
if (isset($searchTerms)) {
|
||||
$searchCols = array();
|
||||
for ($i = 0; $i < $data["iColumns"]; $i++) {
|
||||
|
@ -692,12 +692,12 @@ Logging::log("getting media! - 2");
|
|||
$searchCols[] = $data["mDataProp_{$i}"];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$outerCond = array();
|
||||
|
||||
|
||||
foreach ($searchTerms as $term) {
|
||||
$innerCond = array();
|
||||
|
||||
|
||||
foreach ($searchCols as $col) {
|
||||
$escapedTerm = pg_escape_string($term);
|
||||
$innerCond[] = "{$col}::text ILIKE '%{$escapedTerm}%'";
|
||||
|
@ -707,7 +707,7 @@ Logging::log("getting media! - 2");
|
|||
$where[] = "(".join(" AND ", $outerCond).")";
|
||||
}
|
||||
// End Where clause
|
||||
|
||||
|
||||
// Order By clause
|
||||
$orderby = array();
|
||||
for ($i = 0; $i < $data["iSortingCols"]; $i++){
|
||||
|
@ -717,22 +717,22 @@ Logging::log("getting media! - 2");
|
|||
$orderby[] = "id";
|
||||
$orderby = join("," , $orderby);
|
||||
// End Order By clause
|
||||
|
||||
|
||||
if (count($where) > 0) {
|
||||
$where = join(" AND ", $where);
|
||||
$sql = $selectorCount." FROM ".$fromTable." WHERE ".$where;
|
||||
$sqlTotalDisplayRows = $sql;
|
||||
|
||||
|
||||
$sql = $selectorRows." FROM ".$fromTable." WHERE ".$where." ORDER BY ".$orderby." OFFSET ".$data["iDisplayStart"]." LIMIT ".$data["iDisplayLength"];
|
||||
}
|
||||
else {
|
||||
$sql = $selectorRows." FROM ".$fromTable." ORDER BY ".$orderby." OFFSET ".$data["iDisplayStart"]." LIMIT ".$data["iDisplayLength"];
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
$r = $con->query($sqlTotalRows);
|
||||
$totalRows = $r->fetchColumn(0);
|
||||
|
||||
|
||||
if (isset($sqlTotalDisplayRows)) {
|
||||
$r = $con->query($sqlTotalDisplayRows);
|
||||
$totalDisplayRows = $r->fetchColumn(0);
|
||||
|
@ -740,7 +740,7 @@ Logging::log("getting media! - 2");
|
|||
else {
|
||||
$totalDisplayRows = $totalRows;
|
||||
}
|
||||
|
||||
|
||||
$r = $con->query($sql);
|
||||
$r->setFetchMode(PDO::FETCH_ASSOC);
|
||||
$results = $r->fetchAll();
|
||||
|
@ -748,10 +748,10 @@ Logging::log("getting media! - 2");
|
|||
catch (Exception $e) {
|
||||
Logging::log($e->getMessage());
|
||||
}
|
||||
|
||||
|
||||
//display sql executed in airtime log for testing
|
||||
Logging::log($sql);
|
||||
|
||||
|
||||
return array("sEcho" => intval($data["sEcho"]), "iTotalDisplayRecords" => $totalDisplayRows, "iTotalRecords" => $totalRows, "aaData" => $results);
|
||||
}
|
||||
|
||||
|
@ -764,15 +764,15 @@ Logging::log("getting media! - 2");
|
|||
header("Cache-Control: no-store, no-cache, must-revalidate");
|
||||
header("Cache-Control: post-check=0, pre-check=0", false);
|
||||
header("Pragma: no-cache");
|
||||
|
||||
|
||||
// Settings
|
||||
$cleanupTargetDir = false; // Remove old files
|
||||
$maxFileAge = 60 * 60; // Temp file age in seconds
|
||||
|
||||
|
||||
// 5 minutes execution time
|
||||
@set_time_limit(5 * 60);
|
||||
// usleep(5000);
|
||||
|
||||
|
||||
// Get parameters
|
||||
$chunk = isset($_REQUEST["chunk"]) ? $_REQUEST["chunk"] : 0;
|
||||
$chunks = isset($_REQUEST["chunks"]) ? $_REQUEST["chunks"] : 0;
|
||||
|
@ -781,29 +781,29 @@ Logging::log("getting media! - 2");
|
|||
// Clean the fileName for security reasons
|
||||
//this needs fixing for songs not in ascii.
|
||||
//$fileName = preg_replace('/[^\w\._]+/', '', $fileName);
|
||||
|
||||
|
||||
// Create target dir
|
||||
if (!file_exists($p_targetDir))
|
||||
@mkdir($p_targetDir);
|
||||
|
||||
|
||||
// Remove old temp files
|
||||
if (is_dir($p_targetDir) && ($dir = opendir($p_targetDir))) {
|
||||
while (($file = readdir($dir)) !== false) {
|
||||
$filePath = $p_targetDir . DIRECTORY_SEPARATOR . $file;
|
||||
|
||||
|
||||
// Remove temp files if they are older than the max age
|
||||
if (preg_match('/\.tmp$/', $file) && (filemtime($filePath) < time() - $maxFileAge))
|
||||
@unlink($filePath);
|
||||
}
|
||||
|
||||
|
||||
closedir($dir);
|
||||
} else
|
||||
die('{"jsonrpc" : "2.0", "error" : {"code": 100, "message": "Failed to open temp directory."}, "id" : "id"}');
|
||||
|
||||
|
||||
// Look for the content type header
|
||||
if (isset($_SERVER["HTTP_CONTENT_TYPE"]))
|
||||
$contentType = $_SERVER["HTTP_CONTENT_TYPE"];
|
||||
|
||||
|
||||
if (isset($_SERVER["CONTENT_TYPE"]))
|
||||
$contentType = $_SERVER["CONTENT_TYPE"];
|
||||
|
||||
|
@ -819,13 +819,13 @@ Logging::log("getting media! - 2");
|
|||
if ($out) {
|
||||
// Read binary input stream and append it to temp file
|
||||
$in = fopen($_FILES['file']['tmp_name'], "rb");
|
||||
|
||||
|
||||
if ($in) {
|
||||
while ($buff = fread($in, 4096))
|
||||
fwrite($out, $buff);
|
||||
} else
|
||||
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}');
|
||||
|
||||
|
||||
fclose($out);
|
||||
unlink($_FILES['file']['tmp_name']);
|
||||
} else
|
||||
|
@ -838,18 +838,18 @@ Logging::log("getting media! - 2");
|
|||
if ($out) {
|
||||
// Read binary input stream and append it to temp file
|
||||
$in = fopen("php://input", "rb");
|
||||
|
||||
|
||||
if ($in) {
|
||||
while ($buff = fread($in, 4096))
|
||||
fwrite($out, $buff);
|
||||
} else
|
||||
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}');
|
||||
|
||||
|
||||
fclose($out);
|
||||
} else
|
||||
die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"}');
|
||||
}
|
||||
|
||||
|
||||
return $tempFilePath;
|
||||
}
|
||||
|
||||
|
@ -899,7 +899,7 @@ Logging::log("getting media! - 2");
|
|||
Logging::log("copyFileToStor: moving file $audio_file to $audio_stor");
|
||||
//Martin K.: changed to rename: Much less load + quicker since this is an atomic operation
|
||||
$r = @rename($audio_file, $audio_stor);
|
||||
|
||||
|
||||
if ($r === false) {
|
||||
#something went wrong likely there wasn't enough space in the audio_stor to move the file too.
|
||||
#warn the user that the file wasn't uploaded and they should check if there is enough disk space.
|
||||
|
|
|
@ -19,6 +19,7 @@ class TimeFilledFormatter {
|
|||
{
|
||||
$formatted = "";
|
||||
$sign = ($this->_seconds < 0) ? "-" : "+";
|
||||
$perfect = true;
|
||||
|
||||
$time = Application_Model_Playlist::secondsToPlaylistTime(abs($this->_seconds));
|
||||
Logging::log("time is: ".$time);
|
||||
|
@ -29,16 +30,24 @@ class TimeFilledFormatter {
|
|||
if (intval($info[0]) > 0) {
|
||||
$info[0] = ltrim($info[0], "0");
|
||||
$formatted .= " {$info[0]}h";
|
||||
$perfect = false;
|
||||
}
|
||||
|
||||
if (intval($info[1]) > 0) {
|
||||
$info[1] = ltrim($info[1], "0");
|
||||
$formatted .= " {$info[1]}m";
|
||||
$perfect = false;
|
||||
}
|
||||
|
||||
if (intval($info[2]) > 0) {
|
||||
$sec = round($info[2], 0);
|
||||
$formatted .= " {$sec}s";
|
||||
$perfect = false;
|
||||
}
|
||||
|
||||
//0 over/under lap of content.
|
||||
if ($perfect === true) {
|
||||
$formatted = "+ 0s";
|
||||
}
|
||||
|
||||
return $formatted;
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
<div class="his-timerange">
|
||||
<?php echo $this->element->getElement('his_date_start') ?>
|
||||
<?php echo $this->element->getElement('his_time_start') ?>
|
||||
<?php echo $this->element->getElement('his_date_end') ?>
|
||||
<?php echo $this->element->getElement('his_time_end') ?>
|
||||
<input type="button" id="his_submit" class="ui-button ui-state-default" value="GO"></input>
|
||||
</div>
|
|
@ -1,4 +1,5 @@
|
|||
<div class="sb-timerange">
|
||||
<?php echo $this->element->getElement('sb_timestamp') ?>
|
||||
<?php echo $this->element->getElement('sb_date_start') ?>
|
||||
<?php echo $this->element->getElement('sb_time_start') ?>
|
||||
<?php echo $this->element->getElement('sb_date_end') ?>
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
<?php echo $this->date_form; ?>
|
||||
<table id="history_table" cellpadding="0" cellspacing="0" class="datatable"></table>
|
|
@ -0,0 +1 @@
|
|||
<?php echo $this->dialog ?>
|
|
@ -1,7 +1,7 @@
|
|||
#library_content {
|
||||
float: left;
|
||||
width: 50%;
|
||||
min-height: 475px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#library_display {
|
||||
|
@ -9,10 +9,6 @@
|
|||
table-layout:fixed;
|
||||
}
|
||||
|
||||
#library_display th {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
#library_content #library_display {
|
||||
width:100%;
|
||||
}
|
||||
|
@ -80,7 +76,8 @@
|
|||
text-align: center;
|
||||
}
|
||||
|
||||
.library_sr,
|
||||
.library_bitrate {
|
||||
text-align: right;
|
||||
}
|
||||
td.library_track,
|
||||
td.library_sr,
|
||||
td.library_bitrate {
|
||||
text-align: right;
|
||||
}
|
|
@ -1,9 +1,7 @@
|
|||
#side_playlist {
|
||||
width: 40%;
|
||||
min-height: 475px;
|
||||
padding: 8px;
|
||||
padding-bottom: 0px;
|
||||
font-size: 16px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
#side_playlist,
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#show_builder {
|
||||
width:95%;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
#show_builder_table th {
|
||||
|
@ -47,10 +48,22 @@ tr.cursor-selected-row .marker {
|
|||
.ui-dialog .wrapper {
|
||||
margin: 0;
|
||||
padding: 10px 0 0 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.ui-dialog #library_content {
|
||||
margin: 0 10px 10px 0;
|
||||
overflow: auto;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.ui-dialog #show_builder {
|
||||
width:45%;
|
||||
margin: 0 0 10px 0;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.ui-dialog .padded {
|
||||
padding: 5px 10px 5px 8px;
|
||||
}
|
||||
|
||||
.ui-dialog .ui-buttonset {
|
||||
|
|
|
@ -9,7 +9,7 @@ body {
|
|||
padding: 0;
|
||||
}
|
||||
html, body {
|
||||
height: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#login-page {
|
||||
|
@ -366,7 +366,7 @@ select {
|
|||
|
||||
.wrapper {
|
||||
margin: 0 20px 0 20px;
|
||||
padding:20px 0 0 0;
|
||||
padding:10px 0 0 0;
|
||||
}
|
||||
|
||||
.alpha-block {
|
||||
|
@ -510,6 +510,11 @@ dl.inline-list dd {
|
|||
border-width: 1px 1px 1px 1px;
|
||||
width:100%;
|
||||
}
|
||||
|
||||
.datatable th {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.datatable tr td, .datatable tr th {
|
||||
border-color: #b1b1b1;
|
||||
border-style: solid;
|
||||
|
@ -554,6 +559,14 @@ dl.inline-list dd {
|
|||
border-width: 0px 1px 0 1px;
|
||||
}
|
||||
|
||||
.dataTables_scrolling {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.dataTables_scrolling table{
|
||||
border-width: 0px 1px 0 1px;
|
||||
}
|
||||
|
||||
.DataTables_sort_wrapper .ui-icon {
|
||||
display: block;
|
||||
float: left;
|
||||
|
@ -577,7 +590,7 @@ dl.inline-list dd {
|
|||
line-height:22px;
|
||||
}
|
||||
.dataTables_filter {
|
||||
margin:8px 0 0 8px;
|
||||
margin:0 0 0 8px;
|
||||
}
|
||||
.dataTables_filter .auto-search {
|
||||
width:55%;
|
||||
|
@ -611,6 +624,7 @@ dl.inline-list dd {
|
|||
.dataTables_paginate {
|
||||
float: right;
|
||||
padding: 8px 0 8px 8px;
|
||||
clear: left;
|
||||
}
|
||||
.dataTables_paginate .ui-button {
|
||||
font-size:12px;
|
||||
|
@ -623,7 +637,7 @@ dl.inline-list dd {
|
|||
width: 55%;
|
||||
border: 1px solid #5B5B5B;
|
||||
margin-left: -8px;
|
||||
padding: 4px 3px 4px 25px;
|
||||
padding: 5px 3px 4px 25px;
|
||||
}
|
||||
.dataTables_length select {
|
||||
background-color: #DDDDDD;
|
||||
|
@ -662,7 +676,6 @@ button.ColVis_Button.ColVis_ShowAll {
|
|||
|
||||
.library_length {
|
||||
text-align: right;
|
||||
padding-right: 1em !important;
|
||||
}
|
||||
|
||||
/*----END Data Table----*/
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
var AIRTIME = (function(AIRTIME){
|
||||
var AIRTIME = (function(AIRTIME) {
|
||||
var mod,
|
||||
libraryInit;
|
||||
|
||||
|
@ -42,14 +42,17 @@
|
|||
};
|
||||
|
||||
libraryInit = function() {
|
||||
var oTable;
|
||||
var oTable,
|
||||
libContentDiv = $("#library_content");
|
||||
tableHeight = libContentDiv.height() - 140;
|
||||
|
||||
oTable = $('#library_display').dataTable( {
|
||||
|
||||
//put hidden columns at the top to insure they can never be visible on the table through column reordering.
|
||||
"aoColumns": [
|
||||
/* Checkbox */ {"sTitle": "<input type='checkbox' name='pl_cb_all'>", "mDataProp": "checkbox", "bSortable": false, "bSearchable": false, "sWidth": "25px", "sClass": "library_checkbox"},
|
||||
/* Type */ {"sTitle": "", "mDataProp": "image", "bSearchable": false, "sWidth": "25px", "sClass": "library_type", "iDataSort": 2},
|
||||
/* ftype */ {"sTitle": "", "mDataProp": "ftype", "bSearchable": false, "bVisible": false},
|
||||
/* Checkbox */ {"sTitle": "<input type='checkbox' name='pl_cb_all'>", "mDataProp": "checkbox", "bSortable": false, "bSearchable": false, "sWidth": "25px", "sClass": "library_checkbox"},
|
||||
/* Type */ {"sTitle": "", "mDataProp": "image", "bSearchable": false, "sWidth": "25px", "sClass": "library_type", "iDataSort": 0},
|
||||
/* Title */ {"sTitle": "Title", "mDataProp": "track_title", "sClass": "library_title"},
|
||||
/* Creator */ {"sTitle": "Creator", "mDataProp": "artist_name", "sClass": "library_creator"},
|
||||
/* Album */ {"sTitle": "Album", "mDataProp": "album_title", "sClass": "library_album"},
|
||||
|
@ -58,7 +61,7 @@
|
|||
/* Length */ {"sTitle": "Length", "mDataProp": "length", "sClass": "library_length", "sWidth": "80px"},
|
||||
/* Upload Time */ {"sTitle": "Uploaded", "mDataProp": "utime", "sClass": "library_upload_time"},
|
||||
/* Last Modified */ {"sTitle": "Last Modified", "mDataProp": "mtime", "bVisible": false, "sClass": "library_modified_time"},
|
||||
/* Track Number */ {"sTitle": "Track", "mDataProp": "track_number", "bSearchable": false, "bVisible": false, "sClass": "library_track"},
|
||||
/* Track Number */ {"sTitle": "Track", "mDataProp": "track_number", "bSearchable": false, "bVisible": false, "sClass": "library_track", "sWidth": "65px"},
|
||||
/* Mood */ {"sTitle": "Mood", "mDataProp": "mood", "bSearchable": false, "bVisible": false, "sClass": "library_mood"},
|
||||
/* BPM */ {"sTitle": "BPM", "mDataProp": "bpm", "bSearchable": false, "bVisible": false, "sClass": "library_bpm"},
|
||||
/* Composer */ {"sTitle": "Composer", "mDataProp": "composer", "bSearchable": false, "bVisible": false, "sClass": "library_composer"},
|
||||
|
@ -232,9 +235,9 @@
|
|||
"oLanguage": {
|
||||
"sSearch": ""
|
||||
},
|
||||
|
||||
|
||||
// R = ColReorder, C = ColVis, T = TableTools
|
||||
"sDom": 'Rl<"#library_display_type">fr<"H"T<"library_toolbar"C>>t<"F"ip>',
|
||||
"sDom": 'Rl<"#library_display_type">fr<"H"T<"library_toolbar"C>><"dataTables_scrolling"t><"F"ip>',
|
||||
|
||||
"oTableTools": {
|
||||
"sRowSelect": "multi",
|
||||
|
@ -290,6 +293,8 @@
|
|||
|
||||
});
|
||||
oTable.fnSetFilteringDelay(350);
|
||||
|
||||
libContentDiv.find(".dataTables_scrolling").css("max-height", tableHeight);
|
||||
|
||||
AIRTIME.library.events.setupLibraryToolbar(oTable);
|
||||
|
||||
|
@ -469,9 +474,9 @@
|
|||
|
||||
return AIRTIME;
|
||||
|
||||
}(AIRTIME || {}));
|
||||
}(AIRTIME || {}));
|
||||
|
||||
function addToolBarButtonsLibrary(aButtons) {
|
||||
function addToolBarButtonsLibrary(aButtons) {
|
||||
var i,
|
||||
length = aButtons.length,
|
||||
libToolBar = $(".library_toolbar"),
|
||||
|
@ -511,9 +516,9 @@
|
|||
}(i));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function checkImportStatus(){
|
||||
function checkImportStatus(){
|
||||
$.getJSON('/Preference/is-import-in-progress', function(data){
|
||||
var div = $('#import_status');
|
||||
if (data == true){
|
||||
|
@ -523,9 +528,9 @@
|
|||
div.hide();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function addProgressIcon(id) {
|
||||
function addProgressIcon(id) {
|
||||
var tr = $("#au_"+id),
|
||||
span;
|
||||
|
||||
|
@ -539,9 +544,9 @@
|
|||
tr.find("td.library_title")
|
||||
.append('<span class="small-icon progress"></span>');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function checkSCUploadStatus(){
|
||||
function checkSCUploadStatus(){
|
||||
|
||||
var url = '/Library/get-upload-to-soundcloud-status';
|
||||
|
||||
|
@ -563,9 +568,9 @@
|
|||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function addQtipToSCIcons(){
|
||||
function addQtipToSCIcons(){
|
||||
$(".progress, .soundcloud, .sc-error").live('mouseover', function(){
|
||||
|
||||
var id = $(this).parent().parent().data("aData").id;
|
||||
|
@ -644,8 +649,7 @@
|
|||
});
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
var audio_preview_window = null;
|
||||
|
||||
|
@ -662,4 +666,3 @@ function open_audio_preview(fileID, index) {
|
|||
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1 +1,16 @@
|
|||
$(document).ready(AIRTIME.library.libraryInit);
|
||||
$(document).ready(function() {
|
||||
var viewport = AIRTIME.utilities.findViewportDimensions(),
|
||||
lib = $("#library_content"),
|
||||
pl = $("#side_playlist"),
|
||||
widgetHeight = viewport.height - 185,
|
||||
width = Math.floor(viewport.width - 110);
|
||||
|
||||
lib.height(widgetHeight)
|
||||
.width(Math.floor(width * 0.55));
|
||||
|
||||
pl.height(widgetHeight)
|
||||
.width(Math.floor(width * 0.45));
|
||||
|
||||
AIRTIME.library.libraryInit();
|
||||
|
||||
});
|
|
@ -0,0 +1,133 @@
|
|||
var AIRTIME = (function(AIRTIME) {
|
||||
var mod;
|
||||
|
||||
if (AIRTIME.history === undefined) {
|
||||
AIRTIME.history = {};
|
||||
}
|
||||
mod = AIRTIME.history;
|
||||
|
||||
mod.historyTable = function() {
|
||||
var oTable,
|
||||
historyContentDiv = $("#history_content"),
|
||||
historyTableDiv = historyContentDiv.find("#history_table"),
|
||||
tableHeight = historyContentDiv.height() - 140,
|
||||
fnServerData;
|
||||
|
||||
fnServerData = function ( sSource, aoData, fnCallback ) {
|
||||
|
||||
if (fnServerData.hasOwnProperty("start")) {
|
||||
aoData.push( { name: "start", value: fnServerData.start} );
|
||||
}
|
||||
if (fnServerData.hasOwnProperty("end")) {
|
||||
aoData.push( { name: "end", value: fnServerData.end} );
|
||||
}
|
||||
|
||||
aoData.push( { name: "format", value: "json"} );
|
||||
|
||||
$.ajax( {
|
||||
"dataType": 'json',
|
||||
"type": "GET",
|
||||
"url": sSource,
|
||||
"data": aoData,
|
||||
"success": fnCallback
|
||||
} );
|
||||
};
|
||||
|
||||
oTable = historyTableDiv.dataTable( {
|
||||
|
||||
"aoColumns": [
|
||||
{"sTitle": "Title", "mDataProp": "title", "sClass": "his_title"}, /* Title */
|
||||
{"sTitle": "Artist", "mDataProp": "artist", "sClass": "his_artist"}, /* Creator */
|
||||
{"sTitle": "Played", "mDataProp": "played", "sClass": "his_artist"}, /* times played */
|
||||
{"sTitle": "Length", "mDataProp": "length", "sClass": "his_length library_length"}, /* Length */
|
||||
{"sTitle": "Composer", "mDataProp": "composer", "sClass": "his_composer"}, /* Composer */
|
||||
{"sTitle": "Copyright", "mDataProp": "copyright", "sClass": "his_copyright"} /* Copyright */
|
||||
],
|
||||
|
||||
"bProcessing": true,
|
||||
"bServerSide": true,
|
||||
"sAjaxSource": "/Playouthistory/playout-history-feed",
|
||||
"sAjaxDataProp": "history",
|
||||
|
||||
"fnServerData": fnServerData,
|
||||
|
||||
"oLanguage": {
|
||||
"sSearch": ""
|
||||
},
|
||||
|
||||
"aLengthMenu": [[50, 100, 500, -1], [50, 100, 500, "All"]],
|
||||
"iDisplayLength": 50,
|
||||
|
||||
"sPaginationType": "full_numbers",
|
||||
"bJQueryUI": true,
|
||||
"bAutoWidth": true,
|
||||
|
||||
"sDom": 'lfr<"H"T><"dataTables_scrolling"t><"F"ip>',
|
||||
|
||||
"oTableTools": {
|
||||
"sSwfPath": "/js/datatables/plugin/TableTools/swf/copy_cvs_xls_pdf.swf"
|
||||
}
|
||||
});
|
||||
oTable.fnSetFilteringDelay(350);
|
||||
|
||||
return oTable;
|
||||
};
|
||||
|
||||
return AIRTIME;
|
||||
|
||||
}(AIRTIME || {}));
|
||||
|
||||
$(document).ready(function(){
|
||||
|
||||
var viewport = AIRTIME.utilities.findViewportDimensions(),
|
||||
history_content = $("#history_content"),
|
||||
widgetHeight = viewport.height - 185,
|
||||
screenWidth = Math.floor(viewport.width - 110),
|
||||
oBaseDatePickerSettings,
|
||||
oBaseTimePickerSettings,
|
||||
oTable,
|
||||
dateStartId = "#his_date_start",
|
||||
timeStartId = "#his_time_start",
|
||||
dateEndId = "#his_date_end",
|
||||
timeEndId = "#his_time_end";
|
||||
|
||||
history_content
|
||||
.height(widgetHeight)
|
||||
.width(screenWidth);
|
||||
|
||||
oBaseDatePickerSettings = {
|
||||
dateFormat: 'yy-mm-dd',
|
||||
onSelect: function(sDate, oDatePicker) {
|
||||
$(this).datepicker( "setDate", sDate );
|
||||
}
|
||||
};
|
||||
|
||||
oBaseTimePickerSettings = {
|
||||
showPeriodLabels: false,
|
||||
showCloseButton: true,
|
||||
showLeadingZero: false,
|
||||
defaultTime: '0:00'
|
||||
};
|
||||
|
||||
oTable = AIRTIME.history.historyTable();
|
||||
|
||||
history_content.find(dateStartId).datepicker(oBaseDatePickerSettings);
|
||||
history_content.find(timeStartId).timepicker(oBaseTimePickerSettings);
|
||||
history_content.find(dateEndId).datepicker(oBaseDatePickerSettings);
|
||||
history_content.find(timeEndId).timepicker(oBaseTimePickerSettings);
|
||||
|
||||
|
||||
history_content.find("#his_submit").click(function(ev){
|
||||
var fn,
|
||||
oRange;
|
||||
|
||||
oRange = AIRTIME.utilities.fnGetScheduleRange(dateStartId, timeStartId, dateEndId, timeEndId);
|
||||
|
||||
fn = oTable.fnSettings().fnServerData;
|
||||
fn.start = oRange.start;
|
||||
fn.end = oRange.end;
|
||||
|
||||
oTable.fnDraw();
|
||||
});
|
||||
|
||||
});
|
|
@ -100,15 +100,32 @@ function buildScheduleDialog (json) {
|
|||
|
||||
var dialog = $(json.dialog),
|
||||
viewport = findViewportDimensions(),
|
||||
height = viewport.height * 0.96,
|
||||
width = viewport.width * 0.96,
|
||||
fnServer = AIRTIME.showbuilder.fnServerData;
|
||||
|
||||
height = Math.floor(viewport.height * 0.96),
|
||||
width = Math.floor(viewport.width * 0.96),
|
||||
fnServer = AIRTIME.showbuilder.fnServerData,
|
||||
//subtract padding in pixels
|
||||
widgetWidth = width - 50,
|
||||
libWidth = Math.floor(widgetWidth * 0.5),
|
||||
builderWidth = Math.floor(widgetWidth * 0.5),
|
||||
libLength,
|
||||
libType,
|
||||
libFilter;
|
||||
|
||||
dialog.find("#library_content")
|
||||
.height(height - 110)
|
||||
.width(libWidth);
|
||||
|
||||
dialog.find("#show_builder")
|
||||
.height(height - 110)
|
||||
.width(builderWidth);
|
||||
|
||||
dialog.dialog({
|
||||
autoOpen: false,
|
||||
title: json.title,
|
||||
width: width,
|
||||
height: height,
|
||||
resizable: false,
|
||||
draggable: false,
|
||||
modal: true,
|
||||
close: closeDialog,
|
||||
buttons: {"Ok": function() {
|
||||
|
@ -116,7 +133,7 @@ function buildScheduleDialog (json) {
|
|||
$("#schedule_calendar").fullCalendar( 'refetchEvents' );
|
||||
}}
|
||||
});
|
||||
|
||||
|
||||
//set the start end times so the builder datatables knows its time range.
|
||||
fnServer.start = json.start;
|
||||
fnServer.end = json.end;
|
||||
|
@ -124,7 +141,17 @@ function buildScheduleDialog (json) {
|
|||
AIRTIME.library.libraryInit();
|
||||
AIRTIME.showbuilder.builderDataTable();
|
||||
|
||||
dialog.find(".dataTables_scrolling")
|
||||
.css("max-height", height - 110 - 155);
|
||||
|
||||
dialog.dialog('open');
|
||||
|
||||
//calculate dynamically width for the library search input.
|
||||
libLength = dialog.find("#library_display_length");
|
||||
libType = dialog.find("#library_display_type");
|
||||
libFilter = dialog.find("#library_display_filter");
|
||||
|
||||
libFilter.find("input").width(libFilter.width() - libType.width() - libLength.width() - 80);
|
||||
}
|
||||
|
||||
function buildContentDialog (json){
|
||||
|
|
|
@ -14,6 +14,34 @@ var AIRTIME = (function(AIRTIME){
|
|||
}
|
||||
}
|
||||
|
||||
mod.timeout = undefined;
|
||||
|
||||
mod.resetTimestamp = function() {
|
||||
var timestamp = $("#sb_timestamp");
|
||||
//reset timestamp value since input values could have changed.
|
||||
timestamp.val(-1);
|
||||
};
|
||||
|
||||
mod.setTimestamp = function(timestamp) {
|
||||
$("#sb_timestamp").val(timestamp);
|
||||
};
|
||||
|
||||
mod.getTimestamp = function() {
|
||||
var timestamp = $("#sb_timestamp"),
|
||||
val;
|
||||
|
||||
//if the timestamp field is on the page return it, or give the default of -1
|
||||
//to ensure a page refresh.
|
||||
if (timestamp.length === 1) {
|
||||
val = timestamp.val();
|
||||
}
|
||||
else {
|
||||
val = -1;
|
||||
}
|
||||
|
||||
return val;
|
||||
};
|
||||
|
||||
mod.fnAdd = function(aMediaIds, aSchedIds) {
|
||||
var oLibTT = TableTools.fnGetInstance('library_display');
|
||||
|
||||
|
@ -47,6 +75,8 @@ var AIRTIME = (function(AIRTIME){
|
|||
};
|
||||
|
||||
fnServerData = function ( sSource, aoData, fnCallback ) {
|
||||
|
||||
aoData.push( { name: "timestamp", value: AIRTIME.showbuilder.getTimestamp()} );
|
||||
aoData.push( { name: "format", value: "json"} );
|
||||
|
||||
if (fnServerData.hasOwnProperty("start")) {
|
||||
|
@ -65,7 +95,10 @@ var AIRTIME = (function(AIRTIME){
|
|||
"type": "GET",
|
||||
"url": sSource,
|
||||
"data": aoData,
|
||||
"success": fnCallback
|
||||
"success": function(json) {
|
||||
AIRTIME.showbuilder.setTimestamp(json.timestamp);
|
||||
fnCallback(json);
|
||||
}
|
||||
} );
|
||||
};
|
||||
|
||||
|
@ -74,7 +107,8 @@ var AIRTIME = (function(AIRTIME){
|
|||
mod.builderDataTable = function() {
|
||||
var tableDiv = $('#show_builder_table'),
|
||||
oTable,
|
||||
fnRemoveSelectedItems;
|
||||
fnRemoveSelectedItems,
|
||||
tableHeight;
|
||||
|
||||
fnRemoveSelectedItems = function() {
|
||||
var oTT = TableTools.fnGetInstance('show_builder_table'),
|
||||
|
@ -269,7 +303,11 @@ var AIRTIME = (function(AIRTIME){
|
|||
markerDiv,
|
||||
td,
|
||||
$lib = $("#library_content"),
|
||||
tr;
|
||||
tr,
|
||||
oTable = $('#show_builder_table').dataTable(),
|
||||
aData;
|
||||
|
||||
clearTimeout(AIRTIME.showbuilder.timeout);
|
||||
|
||||
//only create the cursor arrows if the library is on the page.
|
||||
if ($lib.length > 0 && $lib.filter(":visible").length > 0) {
|
||||
|
@ -297,21 +335,37 @@ var AIRTIME = (function(AIRTIME){
|
|||
|
||||
//if the now playing song is visible set a timeout to redraw the table at the start of the next song.
|
||||
tr = tableDiv.find("tr.sb-now-playing");
|
||||
|
||||
if (tr.length > 0) {
|
||||
var oTable = $('#show_builder_table').dataTable(),
|
||||
aData = tr.data("aData");
|
||||
aData = tr.data("aData");
|
||||
|
||||
setTimeout(function(){
|
||||
AIRTIME.showbuilder.resetTimestamp();
|
||||
oTable.fnDraw();
|
||||
}, aData.refresh * 1000); //need refresh in milliseconds
|
||||
}
|
||||
//current song is not set, set a timeout to refresh when the first item on the timeline starts.
|
||||
else {
|
||||
tr = tableDiv.find("tbody tr.sb-allowed.sb-header:first");
|
||||
|
||||
if (tr.length > 0) {
|
||||
aData = tr.data("aData");
|
||||
|
||||
AIRTIME.showbuilder.timeout = setTimeout(function(){
|
||||
AIRTIME.showbuilder.resetTimestamp();
|
||||
oTable.fnDraw();
|
||||
}, aData.timeUntil * 1000); //need refresh in milliseconds
|
||||
}
|
||||
}
|
||||
},
|
||||
"fnHeaderCallback": function(nHead) {
|
||||
$(nHead).find("input[type=checkbox]").attr("checked", false);
|
||||
},
|
||||
//remove any selected nodes before the draw.
|
||||
"fnPreDrawCallback": function( oSettings ) {
|
||||
var oTT = TableTools.fnGetInstance('show_builder_table');
|
||||
var oTT;
|
||||
|
||||
oTT = TableTools.fnGetInstance('show_builder_table');
|
||||
oTT.fnSelectNone();
|
||||
},
|
||||
|
||||
|
@ -371,7 +425,7 @@ var AIRTIME = (function(AIRTIME){
|
|||
},
|
||||
|
||||
// R = ColReorderResize, C = ColVis, T = TableTools
|
||||
"sDom": 'Rr<"H"CT>t<"F">',
|
||||
"sDom": 'Rr<"H"CT>t',
|
||||
|
||||
"sAjaxDataProp": "schedule",
|
||||
"sAjaxSource": "/showbuilder/builder-feed"
|
||||
|
|
|
@ -1,8 +1,24 @@
|
|||
$(document).ready(function(){
|
||||
|
||||
var oBaseDatePickerSettings,
|
||||
var viewport = AIRTIME.utilities.findViewportDimensions(),
|
||||
lib = $("#library_content"),
|
||||
builder = $("#show_builder"),
|
||||
widgetHeight = viewport.height - 185,
|
||||
screenWidth = Math.floor(viewport.width - 110),
|
||||
oBaseDatePickerSettings,
|
||||
oBaseTimePickerSettings,
|
||||
oRange;
|
||||
oRange,
|
||||
dateStartId = "#sb_date_start",
|
||||
timeStartId = "#sb_time_start",
|
||||
dateEndId = "#sb_date_end",
|
||||
timeEndId = "#sb_time_end";
|
||||
|
||||
//set the heights of the main widgets.
|
||||
lib.height(widgetHeight);
|
||||
|
||||
//builder takes all the screen on first load
|
||||
builder.height(widgetHeight)
|
||||
.width(screenWidth);
|
||||
|
||||
oBaseDatePickerSettings = {
|
||||
dateFormat: 'yy-mm-dd',
|
||||
|
@ -18,78 +34,10 @@ $(document).ready(function(){
|
|||
defaultTime: '0:00'
|
||||
};
|
||||
|
||||
/*
|
||||
* Get the schedule range start in unix timestamp form (in seconds).
|
||||
* defaults to NOW if nothing is selected.
|
||||
*
|
||||
* @param String sDatePickerId
|
||||
*
|
||||
* @param String sTimePickerId
|
||||
*
|
||||
* @return Number iTime
|
||||
*/
|
||||
function fnGetTimestamp(sDatePickerId, sTimePickerId) {
|
||||
var date,
|
||||
time,
|
||||
iTime,
|
||||
iServerOffset,
|
||||
iClientOffset;
|
||||
|
||||
if ($(sDatePickerId).val() === "") {
|
||||
return 0;
|
||||
}
|
||||
|
||||
date = $(sDatePickerId).val();
|
||||
time = $(sTimePickerId).val();
|
||||
|
||||
date = date.split("-");
|
||||
time = time.split(":");
|
||||
|
||||
//0 based month in js.
|
||||
oDate = new Date(date[0], date[1]-1, date[2], time[0], time[1]);
|
||||
|
||||
iTime = oDate.getTime(); //value is in millisec.
|
||||
iTime = Math.round(iTime / 1000);
|
||||
iServerOffset = serverTimezoneOffset;
|
||||
iClientOffset = oDate.getTimezoneOffset() * -60;//function returns minutes
|
||||
|
||||
//adjust for the fact the the Date object is in client time.
|
||||
iTime = iTime + iClientOffset + iServerOffset;
|
||||
|
||||
return iTime;
|
||||
}
|
||||
/*
|
||||
* Returns an object containing a unix timestamp in seconds for the start/end range
|
||||
*
|
||||
* @return Object {"start", "end", "range"}
|
||||
*/
|
||||
function fnGetScheduleRange() {
|
||||
var iStart,
|
||||
iEnd,
|
||||
iRange,
|
||||
DEFAULT_RANGE = 60*60*24;
|
||||
|
||||
iStart = fnGetTimestamp("#sb_date_start", "#sb_time_start");
|
||||
iEnd = fnGetTimestamp("#sb_date_end", "#sb_time_end");
|
||||
|
||||
iRange = iEnd - iStart;
|
||||
|
||||
if (iRange === 0 || iEnd < iStart) {
|
||||
iEnd = iStart + DEFAULT_RANGE;
|
||||
iRange = DEFAULT_RANGE;
|
||||
}
|
||||
|
||||
return {
|
||||
start: iStart,
|
||||
end: iEnd,
|
||||
range: iRange
|
||||
};
|
||||
}
|
||||
|
||||
$("#sb_date_start").datepicker(oBaseDatePickerSettings);
|
||||
$("#sb_time_start").timepicker(oBaseTimePickerSettings);
|
||||
$("#sb_date_end").datepicker(oBaseDatePickerSettings);
|
||||
$("#sb_time_end").timepicker(oBaseTimePickerSettings);
|
||||
builder.find(dateStartId).datepicker(oBaseDatePickerSettings);
|
||||
builder.find(timeStartId).timepicker(oBaseTimePickerSettings);
|
||||
builder.find(dateEndId).datepicker(oBaseDatePickerSettings);
|
||||
builder.find(timeEndId).timepicker(oBaseTimePickerSettings);
|
||||
|
||||
$("#sb_submit").click(function(ev){
|
||||
var fn,
|
||||
|
@ -97,7 +45,10 @@ $(document).ready(function(){
|
|||
op,
|
||||
oTable = $('#show_builder_table').dataTable();
|
||||
|
||||
oRange = fnGetScheduleRange();
|
||||
//reset timestamp value since input values could have changed.
|
||||
AIRTIME.showbuilder.resetTimestamp();
|
||||
|
||||
oRange = AIRTIME.utilities.fnGetScheduleRange(dateStartId, timeStartId, dateEndId, timeEndId);
|
||||
|
||||
fn = oTable.fnSettings().fnServerData;
|
||||
fn.start = oRange.start;
|
||||
|
@ -120,40 +71,70 @@ $(document).ready(function(){
|
|||
var $button = $(this),
|
||||
$lib = $("#library_content"),
|
||||
$builder = $("#show_builder"),
|
||||
oTable = $("#show_builder_table").dataTable();
|
||||
schedTable = $("#show_builder_table").dataTable();
|
||||
|
||||
if ($button.hasClass("sb-edit")) {
|
||||
|
||||
//reset timestamp to redraw the cursors.
|
||||
AIRTIME.showbuilder.resetTimestamp();
|
||||
|
||||
$lib.show();
|
||||
$lib.width("45%");
|
||||
$builder.width("50%");
|
||||
$lib.width(Math.floor(screenWidth * 0.5));
|
||||
$builder.width(Math.floor(screenWidth * 0.5));
|
||||
|
||||
$button.removeClass("sb-edit");
|
||||
$button.addClass("sb-finish-edit");
|
||||
$button.val("Close Library");
|
||||
}
|
||||
else if($button.hasClass("sb-finish-edit")) {
|
||||
else if ($button.hasClass("sb-finish-edit")) {
|
||||
|
||||
$lib.hide();
|
||||
$builder.width("95%");
|
||||
$builder.width(screenWidth);
|
||||
|
||||
$button.removeClass("sb-finish-edit");
|
||||
$button.addClass("sb-edit");
|
||||
$button.val("Add Files");
|
||||
}
|
||||
|
||||
oTable.fnDraw();
|
||||
|
||||
schedTable.fnDraw();
|
||||
});
|
||||
|
||||
oRange = fnGetScheduleRange();
|
||||
oRange = AIRTIME.utilities.fnGetScheduleRange(dateStartId, timeStartId, dateEndId, timeEndId);
|
||||
AIRTIME.showbuilder.fnServerData.start = oRange.start;
|
||||
AIRTIME.showbuilder.fnServerData.end = oRange.end;
|
||||
|
||||
|
||||
AIRTIME.library.libraryInit();
|
||||
AIRTIME.showbuilder.builderDataTable();
|
||||
|
||||
//check if the timeline viewed needs updating.
|
||||
setInterval(function(){
|
||||
var oTable = $('#show_builder_table').dataTable();
|
||||
oTable.fnDraw();
|
||||
}, 20 * 1000); //need refresh in milliseconds
|
||||
var data = {},
|
||||
oTable = $('#show_builder_table').dataTable(),
|
||||
fn = oTable.fnSettings().fnServerData,
|
||||
start = fn.start,
|
||||
end = fn.end;
|
||||
|
||||
data["format"] = "json";
|
||||
data["start"] = start;
|
||||
data["end"] = end;
|
||||
data["timestamp"] = AIRTIME.showbuilder.getTimestamp();
|
||||
|
||||
if (fn.hasOwnProperty("ops")) {
|
||||
data["myShows"] = fn.ops.myShows;
|
||||
data["showFilter"] = fn.ops.showFilter;
|
||||
}
|
||||
|
||||
$.ajax( {
|
||||
"dataType": "json",
|
||||
"type": "GET",
|
||||
"url": "/showbuilder/check-builder-feed",
|
||||
"data": data,
|
||||
"success": function(json) {
|
||||
if (json.update === true) {
|
||||
oTable.fnDraw();
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
}, 5 * 1000); //need refresh in milliseconds
|
||||
});
|
|
@ -0,0 +1,113 @@
|
|||
var AIRTIME = (function(AIRTIME){
|
||||
var mod;
|
||||
|
||||
if (AIRTIME.utilities === undefined) {
|
||||
AIRTIME.utilities = {};
|
||||
}
|
||||
mod = AIRTIME.utilities;
|
||||
|
||||
mod.findViewportDimensions = function() {
|
||||
var viewportwidth,
|
||||
viewportheight;
|
||||
|
||||
// the more standards compliant browsers (mozilla/netscape/opera/IE7) use
|
||||
// window.innerWidth and window.innerHeight
|
||||
if (typeof window.innerWidth != 'undefined') {
|
||||
viewportwidth = window.innerWidth, viewportheight = window.innerHeight;
|
||||
}
|
||||
// IE6 in standards compliant mode (i.e. with a valid doctype as the first
|
||||
// line in the document)
|
||||
else if (typeof document.documentElement != 'undefined'
|
||||
&& typeof document.documentElement.clientWidth != 'undefined'
|
||||
&& document.documentElement.clientWidth != 0) {
|
||||
viewportwidth = document.documentElement.clientWidth;
|
||||
viewportheight = document.documentElement.clientHeight;
|
||||
}
|
||||
// older versions of IE
|
||||
else {
|
||||
viewportwidth = document.getElementsByTagName('body')[0].clientWidth;
|
||||
viewportheight = document.getElementsByTagName('body')[0].clientHeight;
|
||||
}
|
||||
|
||||
return {
|
||||
width: viewportwidth,
|
||||
height: viewportheight
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
* Get the schedule range start in unix timestamp form (in seconds).
|
||||
* defaults to NOW if nothing is selected.
|
||||
*
|
||||
* @param String sDatePickerId
|
||||
*
|
||||
* @param String sTimePickerId
|
||||
*
|
||||
* @return Number iTime
|
||||
*/
|
||||
mod.fnGetTimestamp = function(sDateId, sTimeId) {
|
||||
var date,
|
||||
time,
|
||||
iTime,
|
||||
iServerOffset,
|
||||
iClientOffset,
|
||||
temp;
|
||||
|
||||
temp = $(sDateId).val();
|
||||
if ( temp === "") {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
date = temp;
|
||||
}
|
||||
|
||||
time = $(sTimeId).val();
|
||||
|
||||
date = date.split("-");
|
||||
time = time.split(":");
|
||||
|
||||
//0 based month in js.
|
||||
oDate = new Date(date[0], date[1]-1, date[2], time[0], time[1]);
|
||||
|
||||
iTime = oDate.getTime(); //value is in millisec.
|
||||
iTime = Math.round(iTime / 1000);
|
||||
iServerOffset = serverTimezoneOffset;
|
||||
iClientOffset = oDate.getTimezoneOffset() * -60;//function returns minutes
|
||||
|
||||
//adjust for the fact the the Date object is in client time.
|
||||
iTime = iTime + iClientOffset + iServerOffset;
|
||||
|
||||
return iTime;
|
||||
};
|
||||
|
||||
/*
|
||||
* Returns an object containing a unix timestamp in seconds for the start/end range
|
||||
*
|
||||
* @return Object {"start", "end", "range"}
|
||||
*/
|
||||
mod.fnGetScheduleRange = function(dateStart, timeStart, dateEnd, timeEnd) {
|
||||
var iStart,
|
||||
iEnd,
|
||||
iRange,
|
||||
DEFAULT_RANGE = 60*60*24;
|
||||
|
||||
iStart = AIRTIME.utilities.fnGetTimestamp(dateStart, timeStart);
|
||||
iEnd = AIRTIME.utilities.fnGetTimestamp(dateEnd, timeEnd);
|
||||
|
||||
iRange = iEnd - iStart;
|
||||
|
||||
if (iRange === 0 || iEnd < iStart) {
|
||||
iEnd = iStart + DEFAULT_RANGE;
|
||||
iRange = DEFAULT_RANGE;
|
||||
}
|
||||
|
||||
return {
|
||||
start: iStart,
|
||||
end: iEnd,
|
||||
range: iRange
|
||||
};
|
||||
};
|
||||
|
||||
return AIRTIME;
|
||||
|
||||
}(AIRTIME || {}));
|
|
@ -0,0 +1,221 @@
|
|||
/* Compile using: mxmlc --target-player=10.0.0 ZeroClipboard.as */
|
||||
package {
|
||||
import flash.display.Stage;
|
||||
import flash.display.Sprite;
|
||||
import flash.display.LoaderInfo;
|
||||
import flash.display.StageScaleMode;
|
||||
import flash.events.*;
|
||||
import flash.display.StageAlign;
|
||||
import flash.display.StageScaleMode;
|
||||
import flash.external.ExternalInterface;
|
||||
import flash.system.Security;
|
||||
import flash.utils.*;
|
||||
import flash.system.System;
|
||||
import flash.net.FileReference;
|
||||
import flash.net.FileFilter;
|
||||
|
||||
public class ZeroClipboard extends Sprite {
|
||||
|
||||
private var domId:String = '';
|
||||
private var button:Sprite;
|
||||
private var clipText:String = 'blank';
|
||||
private var fileName:String = '';
|
||||
private var action:String = 'copy';
|
||||
private var incBom:Boolean = true;
|
||||
private var charSet:String = 'utf8';
|
||||
|
||||
|
||||
public function ZeroClipboard() {
|
||||
// constructor, setup event listeners and external interfaces
|
||||
stage.scaleMode = StageScaleMode.EXACT_FIT;
|
||||
flash.system.Security.allowDomain("*");
|
||||
|
||||
// import flashvars
|
||||
var flashvars:Object = LoaderInfo( this.root.loaderInfo ).parameters;
|
||||
domId = flashvars.id;
|
||||
|
||||
// invisible button covers entire stage
|
||||
button = new Sprite();
|
||||
button.buttonMode = true;
|
||||
button.useHandCursor = true;
|
||||
button.graphics.beginFill(0x00FF00);
|
||||
button.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
|
||||
button.alpha = 0.0;
|
||||
addChild(button);
|
||||
|
||||
button.addEventListener(MouseEvent.CLICK, clickHandler);
|
||||
button.addEventListener(MouseEvent.MOUSE_OVER, function(event:Event):void {
|
||||
ExternalInterface.call( 'ZeroClipboard.dispatch', domId, 'mouseOver', null );
|
||||
} );
|
||||
button.addEventListener(MouseEvent.MOUSE_OUT, function(event:Event):void {
|
||||
ExternalInterface.call( 'ZeroClipboard.dispatch', domId, 'mouseOut', null );
|
||||
} );
|
||||
button.addEventListener(MouseEvent.MOUSE_DOWN, function(event:Event):void {
|
||||
ExternalInterface.call( 'ZeroClipboard.dispatch', domId, 'mouseDown', null );
|
||||
} );
|
||||
button.addEventListener(MouseEvent.MOUSE_UP, function(event:Event):void {
|
||||
ExternalInterface.call( 'ZeroClipboard.dispatch', domId, 'mouseUp', null );
|
||||
} );
|
||||
|
||||
// External functions - readd whenever the stage is made active for IE
|
||||
addCallbacks();
|
||||
stage.addEventListener(Event.ACTIVATE, addCallbacks);
|
||||
|
||||
// signal to the browser that we are ready
|
||||
ExternalInterface.call( 'ZeroClipboard.dispatch', domId, 'load', null );
|
||||
}
|
||||
|
||||
public function addCallbacks ():void {
|
||||
ExternalInterface.addCallback("setHandCursor", setHandCursor);
|
||||
ExternalInterface.addCallback("clearText", clearText);
|
||||
ExternalInterface.addCallback("setText", setText);
|
||||
ExternalInterface.addCallback("appendText", appendText);
|
||||
ExternalInterface.addCallback("setFileName", setFileName);
|
||||
ExternalInterface.addCallback("setAction", setAction);
|
||||
ExternalInterface.addCallback("setCharSet", setCharSet);
|
||||
ExternalInterface.addCallback("setBomInc", setBomInc);
|
||||
}
|
||||
|
||||
|
||||
public function setCharSet(newCharSet:String):void {
|
||||
if ( newCharSet == 'UTF16LE' ) {
|
||||
charSet = newCharSet;
|
||||
} else {
|
||||
charSet = 'UTF8';
|
||||
}
|
||||
}
|
||||
|
||||
public function setBomInc(newBomInc:Boolean):void {
|
||||
incBom = newBomInc;
|
||||
}
|
||||
|
||||
public function clearText():void {
|
||||
clipText = '';
|
||||
}
|
||||
|
||||
public function appendText(newText:String):void {
|
||||
clipText += newText;
|
||||
}
|
||||
|
||||
public function setText(newText:String):void {
|
||||
clipText = newText;
|
||||
}
|
||||
|
||||
public function setFileName(newFileName:String):void {
|
||||
fileName = newFileName;
|
||||
}
|
||||
|
||||
public function setAction(newAction:String):void {
|
||||
action = newAction;
|
||||
}
|
||||
|
||||
public function setHandCursor(enabled:Boolean):void {
|
||||
// control whether the hand cursor is shown on rollover (true)
|
||||
// or the default arrow cursor (false)
|
||||
button.useHandCursor = enabled;
|
||||
}
|
||||
|
||||
|
||||
private function clickHandler(event:Event):void {
|
||||
var fileRef:FileReference = new FileReference();
|
||||
fileRef.addEventListener(Event.COMPLETE, saveComplete);
|
||||
|
||||
if ( action == "save" ) {
|
||||
/* Save as a file */
|
||||
if ( charSet == 'UTF16LE' ) {
|
||||
fileRef.save( strToUTF16LE(clipText), fileName );
|
||||
} else {
|
||||
fileRef.save( strToUTF8(clipText), fileName );
|
||||
}
|
||||
} else if ( action == "pdf" ) {
|
||||
fileRef.save( "This instance of ZeroClipboard is not configured for PDF export. "+
|
||||
"Please use the PDF export version.", fileName+".txt" );
|
||||
} else {
|
||||
/* Copy the text to the clipboard. Note charset and BOM have no effect here */
|
||||
System.setClipboard( clipText );
|
||||
ExternalInterface.call( 'ZeroClipboard.dispatch', domId, 'complete', clipText );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private function saveComplete(event:Event):void {
|
||||
ExternalInterface.call( 'ZeroClipboard.dispatch', domId, 'complete', clipText );
|
||||
}
|
||||
|
||||
|
||||
private function getProp( prop:String, opts:Array ):String
|
||||
{
|
||||
var i:int, iLen:int;
|
||||
for ( i=0, iLen=opts.length ; i<iLen ; i++ )
|
||||
{
|
||||
if ( opts[i].indexOf( prop+":" ) != -1 )
|
||||
{
|
||||
return opts[i].replace( prop+":", "" );
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Function: strToUTF8
|
||||
* Purpose: Convert a string to the output utf-8
|
||||
* Returns: ByteArray
|
||||
* Inputs: String
|
||||
*/
|
||||
private function strToUTF8( str:String ):ByteArray {
|
||||
var utf8:ByteArray = new ByteArray();
|
||||
|
||||
/* BOM first */
|
||||
if ( incBom ) {
|
||||
utf8.writeByte( 0xEF );
|
||||
utf8.writeByte( 0xBB );
|
||||
utf8.writeByte( 0xBF );
|
||||
}
|
||||
utf8.writeUTFBytes( str );
|
||||
|
||||
return utf8;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Function: strToUTF16LE
|
||||
* Purpose: Convert a string to the output utf-16
|
||||
* Returns: ByteArray
|
||||
* Inputs: String
|
||||
* Notes: The fact that this function is needed is a little annoying. Basically, strings in
|
||||
* AS3 are UTF-16 (with surrogate pairs and everything), but characters which take up less
|
||||
* than 8 bytes appear to be stored as only 8 bytes. This function effective adds the
|
||||
* padding required, and the BOM
|
||||
*/
|
||||
private function strToUTF16LE( str:String ):ByteArray {
|
||||
var utf16:ByteArray = new ByteArray();
|
||||
var iChar:uint;
|
||||
var i:uint=0, iLen:uint = str.length;
|
||||
|
||||
/* BOM first */
|
||||
if ( incBom ) {
|
||||
utf16.writeByte( 0xFF );
|
||||
utf16.writeByte( 0xFE );
|
||||
}
|
||||
|
||||
while ( i < iLen ) {
|
||||
iChar = str.charCodeAt(i);
|
||||
|
||||
if ( iChar < 0xFF ) {
|
||||
/* one byte char */
|
||||
utf16.writeByte( iChar );
|
||||
utf16.writeByte( 0 );
|
||||
} else {
|
||||
/* two byte char */
|
||||
utf16.writeByte( iChar & 0x00FF );
|
||||
utf16.writeByte( iChar >> 8 );
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return utf16;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,310 @@
|
|||
/* Compile using: mxmlc --target-player=10.0.0 -static-link-runtime-shared-libraries=true -library-path+=lib ZeroClipboardPdf.as */
|
||||
package {
|
||||
import flash.display.Stage;
|
||||
import flash.display.Sprite;
|
||||
import flash.display.LoaderInfo;
|
||||
import flash.display.StageScaleMode;
|
||||
import flash.events.*;
|
||||
import flash.display.StageAlign;
|
||||
import flash.display.StageScaleMode;
|
||||
import flash.external.ExternalInterface;
|
||||
import flash.system.Security;
|
||||
import flash.utils.*;
|
||||
import flash.system.System;
|
||||
import flash.net.FileReference;
|
||||
import flash.net.FileFilter;
|
||||
|
||||
/* PDF imports */
|
||||
import org.alivepdf.pdf.PDF;
|
||||
import org.alivepdf.data.Grid;
|
||||
import org.alivepdf.data.GridColumn;
|
||||
import org.alivepdf.layout.Orientation;
|
||||
import org.alivepdf.layout.Size;
|
||||
import org.alivepdf.layout.Unit;
|
||||
import org.alivepdf.display.Display;
|
||||
import org.alivepdf.saving.Method;
|
||||
import org.alivepdf.fonts.FontFamily;
|
||||
import org.alivepdf.fonts.Style;
|
||||
import org.alivepdf.fonts.CoreFont;
|
||||
import org.alivepdf.colors.RGBColor;
|
||||
|
||||
public class ZeroClipboard extends Sprite {
|
||||
|
||||
private var domId:String = '';
|
||||
private var button:Sprite;
|
||||
private var clipText:String = 'blank';
|
||||
private var fileName:String = '';
|
||||
private var action:String = 'copy';
|
||||
private var incBom:Boolean = true;
|
||||
private var charSet:String = 'utf8';
|
||||
|
||||
|
||||
public function ZeroClipboard() {
|
||||
// constructor, setup event listeners and external interfaces
|
||||
stage.scaleMode = StageScaleMode.EXACT_FIT;
|
||||
flash.system.Security.allowDomain("*");
|
||||
|
||||
// import flashvars
|
||||
var flashvars:Object = LoaderInfo( this.root.loaderInfo ).parameters;
|
||||
domId = flashvars.id;
|
||||
|
||||
// invisible button covers entire stage
|
||||
button = new Sprite();
|
||||
button.buttonMode = true;
|
||||
button.useHandCursor = true;
|
||||
button.graphics.beginFill(0x00FF00);
|
||||
button.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
|
||||
button.alpha = 0.0;
|
||||
addChild(button);
|
||||
|
||||
button.addEventListener(MouseEvent.CLICK, function(event:Event):void {
|
||||
clickHandler(event);
|
||||
} );
|
||||
button.addEventListener(MouseEvent.MOUSE_OVER, function(event:Event):void {
|
||||
ExternalInterface.call( 'ZeroClipboard.dispatch', domId, 'mouseOver', null );
|
||||
} );
|
||||
button.addEventListener(MouseEvent.MOUSE_OUT, function(event:Event):void {
|
||||
ExternalInterface.call( 'ZeroClipboard.dispatch', domId, 'mouseOut', null );
|
||||
} );
|
||||
button.addEventListener(MouseEvent.MOUSE_DOWN, function(event:Event):void {
|
||||
ExternalInterface.call( 'ZeroClipboard.dispatch', domId, 'mouseDown', null );
|
||||
} );
|
||||
button.addEventListener(MouseEvent.MOUSE_UP, function(event:Event):void {
|
||||
ExternalInterface.call( 'ZeroClipboard.dispatch', domId, 'mouseUp', null );
|
||||
} );
|
||||
|
||||
// External functions - readd whenever the stage is made active for IE
|
||||
addCallbacks();
|
||||
stage.addEventListener(Event.ACTIVATE, addCallbacks);
|
||||
|
||||
// signal to the browser that we are ready
|
||||
ExternalInterface.call( 'ZeroClipboard.dispatch', domId, 'load', null );
|
||||
}
|
||||
|
||||
public function addCallbacks ():void {
|
||||
ExternalInterface.addCallback("setHandCursor", setHandCursor);
|
||||
ExternalInterface.addCallback("clearText", clearText);
|
||||
ExternalInterface.addCallback("setText", setText);
|
||||
ExternalInterface.addCallback("appendText", appendText);
|
||||
ExternalInterface.addCallback("setFileName", setFileName);
|
||||
ExternalInterface.addCallback("setAction", setAction);
|
||||
ExternalInterface.addCallback("setCharSet", setCharSet);
|
||||
ExternalInterface.addCallback("setBomInc", setBomInc);
|
||||
}
|
||||
|
||||
|
||||
public function setCharSet(newCharSet:String):void {
|
||||
if ( newCharSet == 'UTF16LE' ) {
|
||||
charSet = newCharSet;
|
||||
} else {
|
||||
charSet = 'UTF8';
|
||||
}
|
||||
}
|
||||
|
||||
public function setBomInc(newBomInc:Boolean):void {
|
||||
incBom = newBomInc;
|
||||
}
|
||||
|
||||
public function clearText():void {
|
||||
clipText = '';
|
||||
}
|
||||
|
||||
public function appendText(newText:String):void {
|
||||
clipText += newText;
|
||||
}
|
||||
|
||||
public function setText(newText:String):void {
|
||||
clipText = newText;
|
||||
}
|
||||
|
||||
public function setFileName(newFileName:String):void {
|
||||
fileName = newFileName;
|
||||
}
|
||||
|
||||
public function setAction(newAction:String):void {
|
||||
action = newAction;
|
||||
}
|
||||
|
||||
public function setHandCursor(enabled:Boolean):void {
|
||||
// control whether the hand cursor is shown on rollover (true)
|
||||
// or the default arrow cursor (false)
|
||||
button.useHandCursor = enabled;
|
||||
}
|
||||
|
||||
|
||||
private function clickHandler(event:Event):void {
|
||||
var fileRef:FileReference = new FileReference();
|
||||
fileRef.addEventListener(Event.COMPLETE, saveComplete);
|
||||
|
||||
if ( action == "save" ) {
|
||||
/* Save as a file */
|
||||
if ( charSet == 'UTF16LE' ) {
|
||||
fileRef.save( strToUTF16LE(clipText), fileName );
|
||||
} else {
|
||||
fileRef.save( strToUTF8(clipText), fileName );
|
||||
}
|
||||
} else if ( action == "pdf" ) {
|
||||
/* Save as a PDF */
|
||||
var pdf:PDF = configPdf();
|
||||
fileRef.save( pdf.save( Method.LOCAL ), fileName );
|
||||
} else {
|
||||
/* Copy the text to the clipboard. Note charset and BOM have no effect here */
|
||||
System.setClipboard( clipText );
|
||||
ExternalInterface.call( 'ZeroClipboard.dispatch', domId, 'complete', clipText );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private function saveComplete(event:Event):void {
|
||||
ExternalInterface.call( 'ZeroClipboard.dispatch', domId, 'complete', clipText );
|
||||
}
|
||||
|
||||
|
||||
private function getProp( prop:String, opts:Array ):String
|
||||
{
|
||||
var i:int, iLen:int;
|
||||
for ( i=0, iLen=opts.length ; i<iLen ; i++ )
|
||||
{
|
||||
if ( opts[i].indexOf( prop+":" ) != -1 )
|
||||
{
|
||||
return opts[i].replace( prop+":", "" );
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
private function configPdf():PDF
|
||||
{
|
||||
var
|
||||
pdf:PDF,
|
||||
i:int, iLen:int,
|
||||
splitText:Array = clipText.split("--/TableToolsOpts--\n"),
|
||||
opts:Array = splitText[0].split("\n"),
|
||||
dataIn:Array = splitText[1].split("\n"),
|
||||
aColRatio:Array = getProp( 'colWidth', opts ).split('\t'),
|
||||
title:String = getProp( 'title', opts ),
|
||||
message:String = getProp( 'message', opts ),
|
||||
orientation:String = getProp( 'orientation', opts ),
|
||||
size:String = getProp( 'size', opts ),
|
||||
iPageWidth:int = 0,
|
||||
dataOut:Array = [],
|
||||
columns:Array = [],
|
||||
headers:Array,
|
||||
y:int = 0;
|
||||
|
||||
/* Create the PDF */
|
||||
pdf = new PDF( Orientation[orientation.toUpperCase()], Unit.MM, Size[size.toUpperCase()] );
|
||||
pdf.setDisplayMode( Display.FULL_WIDTH );
|
||||
pdf.addPage();
|
||||
iPageWidth = pdf.getCurrentPage().w-20;
|
||||
pdf.textStyle( new RGBColor(0), 1 );
|
||||
|
||||
/* Add the title / message if there is one */
|
||||
pdf.setFont( new CoreFont(FontFamily.HELVETICA), 14 );
|
||||
if ( title != "" )
|
||||
{
|
||||
pdf.writeText(11, title+"\n");
|
||||
}
|
||||
|
||||
pdf.setFont( new CoreFont(FontFamily.HELVETICA), 11 );
|
||||
if ( message != "" )
|
||||
{
|
||||
pdf.writeText(11, message+"\n");
|
||||
}
|
||||
|
||||
/* Data setup. Split up the headers, and then construct the columns */
|
||||
for ( i=0, iLen=dataIn.length ; i<iLen ; i++ )
|
||||
{
|
||||
if ( dataIn[i] != "" )
|
||||
{
|
||||
dataOut.push( dataIn[i].split("\t") );
|
||||
}
|
||||
}
|
||||
headers = dataOut.shift();
|
||||
|
||||
for ( i=0, iLen=headers.length ; i<iLen ; i++ )
|
||||
{
|
||||
columns.push( new GridColumn( " \n"+headers[i]+"\n ", i.toString(), aColRatio[i]*iPageWidth, 'C' ) );
|
||||
}
|
||||
|
||||
var grid:Grid = new Grid(
|
||||
dataOut, /* 1. data */
|
||||
iPageWidth, /* 2. width */
|
||||
100, /* 3. height */
|
||||
new RGBColor (0xE0E0E0), /* 4. headerColor */
|
||||
new RGBColor (0xFFFFFF), /* 5. backgroundColor */
|
||||
true, /* 6. alternateRowColor */
|
||||
new RGBColor ( 0x0 ), /* 7. borderColor */
|
||||
.1, /* 8. border alpha */
|
||||
null, /* 9. joins */
|
||||
columns /* 10. columns */
|
||||
);
|
||||
|
||||
pdf.addGrid( grid, 0, y );
|
||||
return pdf;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Function: strToUTF8
|
||||
* Purpose: Convert a string to the output utf-8
|
||||
* Returns: ByteArray
|
||||
* Inputs: String
|
||||
*/
|
||||
private function strToUTF8( str:String ):ByteArray {
|
||||
var utf8:ByteArray = new ByteArray();
|
||||
|
||||
/* BOM first */
|
||||
if ( incBom ) {
|
||||
utf8.writeByte( 0xEF );
|
||||
utf8.writeByte( 0xBB );
|
||||
utf8.writeByte( 0xBF );
|
||||
}
|
||||
utf8.writeUTFBytes( str );
|
||||
|
||||
return utf8;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Function: strToUTF16LE
|
||||
* Purpose: Convert a string to the output utf-16
|
||||
* Returns: ByteArray
|
||||
* Inputs: String
|
||||
* Notes: The fact that this function is needed is a little annoying. Basically, strings in
|
||||
* AS3 are UTF-16 (with surrogate pairs and everything), but characters which take up less
|
||||
* than 8 bytes appear to be stored as only 8 bytes. This function effective adds the
|
||||
* padding required, and the BOM
|
||||
*/
|
||||
private function strToUTF16LE( str:String ):ByteArray {
|
||||
var utf16:ByteArray = new ByteArray();
|
||||
var iChar:uint;
|
||||
var i:uint=0, iLen:uint = str.length;
|
||||
|
||||
/* BOM first */
|
||||
if ( incBom ) {
|
||||
utf16.writeByte( 0xFF );
|
||||
utf16.writeByte( 0xFE );
|
||||
}
|
||||
|
||||
while ( i < iLen ) {
|
||||
iChar = str.charCodeAt(i);
|
||||
|
||||
if ( iChar < 0xFF ) {
|
||||
/* one byte char */
|
||||
utf16.writeByte( iChar );
|
||||
utf16.writeByte( 0 );
|
||||
} else {
|
||||
/* two byte char */
|
||||
utf16.writeByte( iChar & 0x00FF );
|
||||
utf16.writeByte( iChar >> 8 );
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return utf16;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,264 @@
|
|||
/*
|
||||
* File: TableTools.css
|
||||
* Description: Styles for TableTools 2
|
||||
* Author: Allan Jardine (www.sprymedia.co.uk)
|
||||
* Language: Javascript
|
||||
* License: LGPL / 3 point BSD
|
||||
* Project: DataTables
|
||||
*
|
||||
* Copyright 2010 Allan Jardine, all rights reserved.
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* CSS name space:
|
||||
* DTTT DataTables TableTools
|
||||
*
|
||||
* Colour dictionary:
|
||||
* Button border #d0d0d0
|
||||
* Button border hover #999999
|
||||
* Hover background #f0f0f0
|
||||
* Action blue #4b66d9
|
||||
*
|
||||
* Style sheet provides:
|
||||
* CONTAINER TableTools container element and styles applying to all components
|
||||
* BUTTON_STYLES Action specific button styles
|
||||
* SELECTING Row selection styles
|
||||
* COLLECTIONS Drop down list (collection) styles
|
||||
* PRINTING Print display styles
|
||||
* MISC Minor misc styles
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* CONTAINER
|
||||
* TableTools container element and styles applying to all components
|
||||
*/
|
||||
div.DTTT_container {
|
||||
position: relative;
|
||||
float: right;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
button.DTTT_button {
|
||||
position: relative;
|
||||
float: left;
|
||||
height: 30px;
|
||||
margin-right: 3px;
|
||||
padding: 3px 5px;
|
||||
border: 1px solid #d0d0d0;
|
||||
background-color: #fff;
|
||||
cursor: pointer;
|
||||
*cursor: hand;
|
||||
}
|
||||
|
||||
button.DTTT_button::-moz-focus-inner {
|
||||
border: none !important;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* BUTTON_STYLES
|
||||
* Action specific button styles
|
||||
*/
|
||||
|
||||
button.DTTT_button_csv {
|
||||
padding-right: 30px;
|
||||
background: #6E6E6E url(../images/csv.png) no-repeat center right !important;
|
||||
}
|
||||
|
||||
button.DTTT_button_csv_hover {
|
||||
padding-right: 30px;
|
||||
background: #868686 url(../images/csv_hover.png) no-repeat center right !important;
|
||||
}
|
||||
|
||||
|
||||
button.DTTT_button_xls {
|
||||
padding-right: 30px;
|
||||
background: #6E6E6E url(../images/xls.png) no-repeat center right !important;
|
||||
}
|
||||
|
||||
button.DTTT_button_xls_hover {
|
||||
padding-right: 30px;
|
||||
border: 1px solid #999;
|
||||
background: #868686 url(../images/xls_hover.png) no-repeat center right !important;
|
||||
}
|
||||
|
||||
|
||||
button.DTTT_button_copy {
|
||||
padding-right: 30px;
|
||||
background: #6E6E6E url(../images/copy.png) no-repeat center right !important;
|
||||
}
|
||||
|
||||
button.DTTT_button_copy_hover {
|
||||
padding-right: 30px;
|
||||
border: 1px solid #999;
|
||||
background: #868686 url(../images/copy_hover.png) no-repeat center right !important;
|
||||
}
|
||||
|
||||
|
||||
button.DTTT_button_pdf {
|
||||
padding-right: 30px;
|
||||
background: #6E6E6E url(../images/pdf.png) no-repeat center right !important;
|
||||
}
|
||||
|
||||
button.DTTT_button_pdf_hover {
|
||||
padding-right: 30px;
|
||||
border: 1px solid #999;
|
||||
background: #868686 url(../images/pdf_hover.png) no-repeat center right !important;
|
||||
}
|
||||
|
||||
|
||||
button.DTTT_button_print {
|
||||
padding-right: 30px;
|
||||
background: #6E6E6E url(../images/print.png) no-repeat center right !important;
|
||||
}
|
||||
|
||||
button.DTTT_button_print_hover {
|
||||
padding-right: 30px;
|
||||
border: 1px solid #999;
|
||||
background: #868686 url(../images/print_hover.png) no-repeat center right !important;
|
||||
}
|
||||
|
||||
|
||||
button.DTTT_button_text {
|
||||
}
|
||||
|
||||
button.DTTT_button_text_hover {
|
||||
border: 1px solid #999;
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
|
||||
|
||||
button.DTTT_button_collection {
|
||||
padding-right: 17px;
|
||||
background: url(../images/collection.png) no-repeat center right;
|
||||
}
|
||||
|
||||
button.DTTT_button_collection_hover {
|
||||
padding-right: 17px;
|
||||
border: 1px solid #999;
|
||||
background: #f0f0f0 url(../images/collection_hover.png) no-repeat center right;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* SELECTING
|
||||
* Row selection styles
|
||||
*/
|
||||
table.DTTT_selectable tbody tr {
|
||||
cursor: pointer;
|
||||
*cursor: hand;
|
||||
}
|
||||
|
||||
tr.DTTT_selected.odd {
|
||||
background-color: #9FAFD1;
|
||||
}
|
||||
|
||||
tr.DTTT_selected.odd td.sorting_1 {
|
||||
background-color: #9FAFD1;
|
||||
}
|
||||
|
||||
tr.DTTT_selected.odd td.sorting_2 {
|
||||
background-color: #9FAFD1;
|
||||
}
|
||||
|
||||
tr.DTTT_selected.odd td.sorting_3 {
|
||||
background-color: #9FAFD1;
|
||||
}
|
||||
|
||||
|
||||
tr.DTTT_selected.even {
|
||||
background-color: #B0BED9;
|
||||
}
|
||||
|
||||
tr.DTTT_selected.even td.sorting_1 {
|
||||
background-color: #B0BED9;
|
||||
}
|
||||
|
||||
tr.DTTT_selected.even td.sorting_2 {
|
||||
background-color: #B0BED9;
|
||||
}
|
||||
|
||||
tr.DTTT_selected.even td.sorting_3 {
|
||||
background-color: #B0BED9;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* COLLECTIONS
|
||||
* Drop down list (collection) styles
|
||||
*/
|
||||
|
||||
div.DTTT_collection {
|
||||
width: 150px;
|
||||
padding: 3px;
|
||||
border: 1px solid #ccc;
|
||||
background-color: #f3f3f3;
|
||||
overflow: hidden;
|
||||
z-index: 2002;
|
||||
}
|
||||
|
||||
div.DTTT_collection_background {
|
||||
background: transparent url(../images/background.png) repeat top left;
|
||||
z-index: 2001;
|
||||
}
|
||||
|
||||
div.DTTT_collection button.DTTT_button {
|
||||
float: none;
|
||||
width: 100%;
|
||||
margin-bottom: 2px;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* PRINTING
|
||||
* Print display styles
|
||||
*/
|
||||
|
||||
.DTTT_print_info {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: 400px;
|
||||
height: 150px;
|
||||
margin-left: -200px;
|
||||
margin-top: -75px;
|
||||
text-align: center;
|
||||
background-color: #3f3f3f;
|
||||
color: white;
|
||||
padding: 10px 30px;
|
||||
|
||||
opacity: 0.9;
|
||||
|
||||
border-radius: 5px;
|
||||
-moz-border-radius: 5px;
|
||||
-webkit-border-radius: 5px;
|
||||
|
||||
box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
|
||||
-moz-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
|
||||
-webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.DTTT_print_info h6 {
|
||||
font-weight: normal;
|
||||
font-size: 28px;
|
||||
line-height: 28px;
|
||||
margin: 1em;
|
||||
}
|
||||
|
||||
.DTTT_print_info p {
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* MISC
|
||||
* Minor misc styles
|
||||
*/
|
||||
|
||||
.DTTT_disabled {
|
||||
color: #999;
|
||||
}
|
|
@ -0,0 +1,183 @@
|
|||
/*
|
||||
* File: TableTools.css
|
||||
* Description: Styles for TableTools 2 with JUI theming
|
||||
* Author: Allan Jardine (www.sprymedia.co.uk)
|
||||
* Language: Javascript
|
||||
* License: LGPL / 3 point BSD
|
||||
* Project: DataTables
|
||||
*
|
||||
* Copyright 2010 Allan Jardine, all rights reserved.
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Notes:
|
||||
* Generally speaking, please refer to the TableTools.css file - this file contains basic
|
||||
* modifications to that 'master' stylesheet for ThemeRoller.
|
||||
*
|
||||
* CSS name space:
|
||||
* DTTT DataTables TableTools
|
||||
*
|
||||
* Colour dictionary:
|
||||
* Button border #d0d0d0
|
||||
* Button border hover #999999
|
||||
* Hover background #f0f0f0
|
||||
* Action blue #4b66d9
|
||||
*
|
||||
* Style sheet provides:
|
||||
* CONTAINER TableTools container element and styles applying to all components
|
||||
* SELECTING Row selection styles
|
||||
* COLLECTIONS Drop down list (collection) styles
|
||||
* PRINTING Print display styles
|
||||
* MISC Minor misc styles
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* CONTAINER
|
||||
* TableTools container element and styles applying to all components
|
||||
*/
|
||||
div.DTTT_container {
|
||||
position: relative;
|
||||
float: left;
|
||||
}
|
||||
|
||||
button.DTTT_button {
|
||||
position: relative;
|
||||
float: left;
|
||||
height: 24px;
|
||||
margin-right: 3px;
|
||||
padding: 3px 10px;
|
||||
border: 1px solid #d0d0d0;
|
||||
background-color: #fff;
|
||||
cursor: pointer;
|
||||
*cursor: hand;
|
||||
}
|
||||
|
||||
button.DTTT_button::-moz-focus-inner {
|
||||
border: none !important;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* SELECTING
|
||||
* Row selection styles
|
||||
*/
|
||||
table.DTTT_selectable tbody tr {
|
||||
cursor: pointer;
|
||||
*cursor: hand;
|
||||
}
|
||||
|
||||
tr.DTTT_selected.odd {
|
||||
background-color: #9FAFD1;
|
||||
}
|
||||
|
||||
tr.DTTT_selected.odd td.sorting_1 {
|
||||
background-color: #9FAFD1;
|
||||
}
|
||||
|
||||
tr.DTTT_selected.odd td.sorting_2 {
|
||||
background-color: #9FAFD1;
|
||||
}
|
||||
|
||||
tr.DTTT_selected.odd td.sorting_3 {
|
||||
background-color: #9FAFD1;
|
||||
}
|
||||
|
||||
|
||||
tr.DTTT_selected.even {
|
||||
background-color: #B0BED9;
|
||||
}
|
||||
|
||||
tr.DTTT_selected.even td.sorting_1 {
|
||||
background-color: #B0BED9;
|
||||
}
|
||||
|
||||
tr.DTTT_selected.even td.sorting_2 {
|
||||
background-color: #B0BED9;
|
||||
}
|
||||
|
||||
tr.DTTT_selected.even td.sorting_3 {
|
||||
background-color: #B0BED9;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* COLLECTIONS
|
||||
* Drop down list (collection) styles
|
||||
*/
|
||||
|
||||
div.DTTT_collection {
|
||||
width: 150px;
|
||||
background-color: #f3f3f3;
|
||||
overflow: hidden;
|
||||
z-index: 2002;
|
||||
|
||||
box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
|
||||
-moz-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
|
||||
-webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
div.DTTT_collection_background {
|
||||
background: url(../images/background.png) repeat top left;
|
||||
z-index: 2001;
|
||||
}
|
||||
|
||||
div.DTTT_collection button.DTTT_button {
|
||||
float: none;
|
||||
width: 100%;
|
||||
margin-bottom: -0.1em;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* PRINTING
|
||||
* Print display styles
|
||||
*/
|
||||
|
||||
.DTTT_print_info {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: 400px;
|
||||
height: 150px;
|
||||
margin-left: -200px;
|
||||
margin-top: -75px;
|
||||
text-align: center;
|
||||
background-color: #3f3f3f;
|
||||
color: white;
|
||||
padding: 10px 30px;
|
||||
|
||||
opacity: 0.9;
|
||||
|
||||
border-radius: 5px;
|
||||
-moz-border-radius: 5px;
|
||||
-webkit-border-radius: 5px;
|
||||
|
||||
box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
|
||||
-moz-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
|
||||
-webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.DTTT_print_info h6 {
|
||||
font-weight: normal;
|
||||
font-size: 28px;
|
||||
line-height: 28px;
|
||||
margin: 1em;
|
||||
}
|
||||
|
||||
.DTTT_print_info p {
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* MISC
|
||||
* Minor misc styles
|
||||
*/
|
||||
|
||||
.DTTT_disabled {
|
||||
color: #999;
|
||||
}
|
After Width: | Height: | Size: 944 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 2.0 KiB |
|
@ -0,0 +1,81 @@
|
|||
// Simple Set Clipboard System
|
||||
// Author: Joseph Huckaby
|
||||
var ZeroClipboard={version:"1.0.4-TableTools2",clients:{},moviePath:"",nextId:1,$:function(a){"string"==typeof a&&(a=document.getElementById(a));if(!a.addClass)a.hide=function(){this.style.display="none"},a.show=function(){this.style.display=""},a.addClass=function(a){this.removeClass(a);this.className+=" "+a},a.removeClass=function(a){this.className=this.className.replace(RegExp("\\s*"+a+"\\s*")," ").replace(/^\s+/,"").replace(/\s+$/,"")},a.hasClass=function(a){return!!this.className.match(RegExp("\\s*"+
|
||||
a+"\\s*"))};return a},setMoviePath:function(a){this.moviePath=a},dispatch:function(a,b,c){(a=this.clients[a])&&a.receiveEvent(b,c)},register:function(a,b){this.clients[a]=b},getDOMObjectPosition:function(a){var b={left:0,top:0,width:a.width?a.width:a.offsetWidth,height:a.height?a.height:a.offsetHeight};if(""!=a.style.width)b.width=a.style.width.replace("px","");if(""!=a.style.height)b.height=a.style.height.replace("px","");for(;a;)b.left+=a.offsetLeft,b.top+=a.offsetTop,a=a.offsetParent;return b},
|
||||
Client:function(a){this.handlers={};this.id=ZeroClipboard.nextId++;this.movieId="ZeroClipboardMovie_"+this.id;ZeroClipboard.register(this.id,this);a&&this.glue(a)}};
|
||||
ZeroClipboard.Client.prototype={id:0,ready:!1,movie:null,clipText:"",fileName:"",action:"copy",handCursorEnabled:!0,cssEffects:!0,handlers:null,sized:!1,glue:function(a,b){this.domElement=ZeroClipboard.$(a);var c=99;this.domElement.style.zIndex&&(c=parseInt(this.domElement.style.zIndex)+1);var d=ZeroClipboard.getDOMObjectPosition(this.domElement);this.div=document.createElement("div");var e=this.div.style;e.position="absolute";e.left=this.domElement.offsetLeft+"px";e.top=this.domElement.offsetTop+
|
||||
"px";e.width=d.width+"px";e.height=d.height+"px";e.zIndex=c;if("undefined"!=typeof b&&""!=b)this.div.title=b;if(0!=d.width&&0!=d.height)this.sized=!0;this.domElement.parentNode.appendChild(this.div);this.div.innerHTML=this.getHTML(d.width,d.height)},positionElement:function(){var a=ZeroClipboard.getDOMObjectPosition(this.domElement),b=this.div.style;b.position="absolute";b.left=this.domElement.offsetLeft+"px";b.top=this.domElement.offsetTop+"px";b.width=a.width+"px";b.height=a.height+"px";if(0!=a.width&&
|
||||
0!=a.height)this.sized=!0,b=this.div.childNodes[0],b.width=a.width,b.height=a.height},getHTML:function(a,b){var c="",d="id="+this.id+"&width="+a+"&height="+b;if(navigator.userAgent.match(/MSIE/))var e=location.href.match(/^https/i)?"https://":"http://",c=c+('<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="'+e+'download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=10,0,0,0" width="'+a+'" height="'+b+'" id="'+this.movieId+'" align="middle"><param name="allowScriptAccess" value="always" /><param name="allowFullScreen" value="false" /><param name="movie" value="'+
|
||||
ZeroClipboard.moviePath+'" /><param name="loop" value="false" /><param name="menu" value="false" /><param name="quality" value="best" /><param name="bgcolor" value="#ffffff" /><param name="flashvars" value="'+d+'"/><param name="wmode" value="transparent"/></object>');else c+='<embed id="'+this.movieId+'" src="'+ZeroClipboard.moviePath+'" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="'+a+'" height="'+b+'" name="'+this.movieId+'" align="middle" allowScriptAccess="always" allowFullScreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="'+
|
||||
d+'" wmode="transparent" />';return c},hide:function(){if(this.div)this.div.style.left="-2000px"},show:function(){this.reposition()},destroy:function(){if(this.domElement&&this.div){this.hide();this.div.innerHTML="";var a=document.getElementsByTagName("body")[0];try{a.removeChild(this.div)}catch(b){}this.div=this.domElement=null}},reposition:function(a){if(a)(this.domElement=ZeroClipboard.$(a))||this.hide();if(this.domElement&&this.div){var a=ZeroClipboard.getDOMObjectPosition(this.domElement),b=
|
||||
this.div.style;b.left=""+a.left+"px";b.top=""+a.top+"px"}},clearText:function(){this.clipText="";this.ready&&this.movie.clearText()},appendText:function(a){this.clipText+=a;this.ready&&this.movie.appendText(a)},setText:function(a){this.clipText=a;this.ready&&this.movie.setText(a)},setCharSet:function(a){this.charSet=a;this.ready&&this.movie.setCharSet(a)},setBomInc:function(a){this.incBom=a;this.ready&&this.movie.setBomInc(a)},setFileName:function(a){this.fileName=a;this.ready&&this.movie.setFileName(a)},
|
||||
setAction:function(a){this.action=a;this.ready&&this.movie.setAction(a)},addEventListener:function(a,b){a=a.toString().toLowerCase().replace(/^on/,"");this.handlers[a]||(this.handlers[a]=[]);this.handlers[a].push(b)},setHandCursor:function(a){this.handCursorEnabled=a;this.ready&&this.movie.setHandCursor(a)},setCSSEffects:function(a){this.cssEffects=!!a},receiveEvent:function(a,b){a=a.toString().toLowerCase().replace(/^on/,"");switch(a){case "load":this.movie=document.getElementById(this.movieId);
|
||||
if(!this.movie){var c=this;setTimeout(function(){c.receiveEvent("load",null)},1);return}if(!this.ready&&navigator.userAgent.match(/Firefox/)&&navigator.userAgent.match(/Windows/)){c=this;setTimeout(function(){c.receiveEvent("load",null)},100);this.ready=!0;return}this.ready=!0;this.movie.clearText();this.movie.appendText(this.clipText);this.movie.setFileName(this.fileName);this.movie.setAction(this.action);this.movie.setCharSet(this.charSet);this.movie.setBomInc(this.incBom);this.movie.setHandCursor(this.handCursorEnabled);
|
||||
break;case "mouseover":this.domElement&&this.cssEffects&&this.recoverActive&&this.domElement.addClass("active");break;case "mouseout":if(this.domElement&&this.cssEffects&&(this.recoverActive=!1,this.domElement.hasClass("active")))this.domElement.removeClass("active"),this.recoverActive=!0;break;case "mousedown":this.domElement&&this.cssEffects&&this.domElement.addClass("active");break;case "mouseup":if(this.domElement&&this.cssEffects)this.domElement.removeClass("active"),this.recoverActive=!1}if(this.handlers[a])for(var d=
|
||||
0,e=this.handlers[a].length;d<e;d++){var f=this.handlers[a][d];if("function"==typeof f)f(this,b);else if("object"==typeof f&&2==f.length)f[0][f[1]](this,b);else if("string"==typeof f)window[f](this,b)}}};
|
||||
|
||||
|
||||
/*
|
||||
* File: TableTools.min.js
|
||||
* Version: 2.0.2
|
||||
* Author: Allan Jardine (www.sprymedia.co.uk)
|
||||
*
|
||||
* Copyright 2009-2011 Allan Jardine, all rights reserved.
|
||||
*
|
||||
* This source file is free software, under either the GPL v2 license or a
|
||||
* BSD (3 point) style license, as supplied with this software.
|
||||
*
|
||||
* This source file is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
|
||||
*/
|
||||
var TableTools;
|
||||
(function(e,n,h){TableTools=function(a,b){(!this.CLASS||"TableTools"!=this.CLASS)&&alert("Warning: TableTools must be initialised with the keyword 'new'");this.s={that:this,dt:null,print:{saveStart:-1,saveLength:-1,saveScroll:-1,funcEnd:function(){}},buttonCounter:0,select:{type:"",selected:[],preRowSelect:null,postSelected:null,postDeselected:null,all:!1,selectedClass:""},custom:{},swfPath:"",buttonSet:[],master:!1};this.dom={container:null,table:null,print:{hidden:[],message:null},collection:{collection:null,
|
||||
background:null}};this.fnSettings=function(){return this.s};"undefined"==typeof b&&(b={});this.s.dt=a.fnSettings();this._fnConstruct(b);return this};TableTools.prototype={fnGetSelected:function(){return this._fnGetMasterSettings().select.selected},fnGetSelectedData:function(){for(var a=this._fnGetMasterSettings().select.selected,b=[],c=0,d=a.length;c<d;c++)b.push(this.s.dt.oInstance.fnGetData(a[c]));return b},fnIsSelected:function(a){for(var b=this.fnGetSelected(),c=0,d=b.length;c<d;c++)if(a==b[c])return!0;
|
||||
return!1},fnSelectAll:function(){this._fnGetMasterSettings().that._fnRowSelectAll()},fnSelectNone:function(){this._fnGetMasterSettings().that._fnRowDeselectAll()},fnSelect:function(a){this.fnIsSelected(a)||("single"==this.s.select.type?this._fnRowSelectSingle(a):"multi"==this.s.select.type&&this._fnRowSelectMulti(a))},fnDeselect:function(a){this.fnIsSelected(a)&&("single"==this.s.select.type?this._fnRowSelectSingle(a):"multi"==this.s.select.type&&this._fnRowSelectMulti(a))},fnGetTitle:function(a){var b=
|
||||
"";if("undefined"!=typeof a.sTitle&&""!==a.sTitle)b=a.sTitle;else if(a=h.getElementsByTagName("title"),0<a.length)b=a[0].innerHTML;return 4>"\u00a1".toString().length?b.replace(/[^a-zA-Z0-9_\u00A1-\uFFFF\.,\-_ !\(\)]/g,""):b.replace(/[^a-zA-Z0-9_\.,\-_ !\(\)]/g,"")},fnCalcColRatios:function(a){var b=this.s.dt.aoColumns,a=this._fnColumnTargets(a.mColumns),c=[],d=0,e=0,f,g;for(f=0,g=a.length;f<g;f++)if(a[f])d=b[f].nTh.offsetWidth,e+=d,c.push(d);for(f=0,g=c.length;f<g;f++)c[f]/=e;return c.join("\t")},
|
||||
fnGetTableData:function(a){if(this.s.dt)return this._fnGetDataTablesData(a)},fnSetText:function(a,b){this._fnFlashSetText(a,b)},fnResizeButtons:function(){for(var a in ZeroClipboard.clients)if(a){var b=ZeroClipboard.clients[a];"undefined"!=typeof b.domElement&&b.domElement.parentNode==this.dom.container&&b.positionElement()}},fnResizeRequired:function(){for(var a in ZeroClipboard.clients)if(a){var b=ZeroClipboard.clients[a];if("undefined"!=typeof b.domElement&&b.domElement.parentNode==this.dom.container&&
|
||||
!1===b.sized)return!0}return!1},_fnConstruct:function(a){var b=this;this._fnCustomiseSettings(a);this.dom.container=h.createElement("div");this.dom.container.className=!this.s.dt.bJUI?"DTTT_container":"DTTT_container ui-buttonset ui-buttonset-multi";"none"!=this.s.select.type&&this._fnRowSelectConfig();this._fnButtonDefinations(this.s.buttonSet,this.dom.container);this.s.dt.aoDestroyCallback.push({sName:"TableTools",fn:function(){b.dom.container.innerHTML=""}})},_fnCustomiseSettings:function(a){if("undefined"==
|
||||
typeof this.s.dt._TableToolsInit)this.s.master=!0,this.s.dt._TableToolsInit=!0;this.dom.table=this.s.dt.nTable;this.s.custom=e.extend({},TableTools.DEFAULTS,a);this.s.swfPath=this.s.custom.sSwfPath;if("undefined"!=typeof ZeroClipboard)ZeroClipboard.moviePath=this.s.swfPath;this.s.select.type=this.s.custom.sRowSelect;this.s.select.preRowSelect=this.s.custom.fnPreRowSelect;this.s.select.postSelected=this.s.custom.fnRowSelected;this.s.select.postDeselected=this.s.custom.fnRowDeselected;this.s.select.selectedClass=
|
||||
this.s.custom.sSelectedClass;this.s.buttonSet=this.s.custom.aButtons},_fnButtonDefinations:function(a,b){for(var c,d=0,j=a.length;d<j;d++){if("string"==typeof a[d]){if("undefined"==typeof TableTools.BUTTONS[a[d]]){alert("TableTools: Warning - unknown button type: "+a[d]);continue}c=e.extend({},TableTools.BUTTONS[a[d]],!0)}else{if("undefined"==typeof TableTools.BUTTONS[a[d].sExtends]){alert("TableTools: Warning - unknown button type: "+a[d].sExtends);continue}c=e.extend({},TableTools.BUTTONS[a[d].sExtends],
|
||||
!0);c=e.extend(c,a[d],!0)}this.s.dt.bJUI&&(c.sButtonClass+=" ui-button ui-state-default",c.sButtonClassHover+=" ui-state-hover");b.appendChild(this._fnCreateButton(c))}},_fnCreateButton:function(a){var b="div"==a.sAction?this._fnDivBase(a):this._fnButtonBase(a);"print"==a.sAction?this._fnPrintConfig(b,a):a.sAction.match(/flash/)?this._fnFlashConfig(b,a):"text"==a.sAction?this._fnTextConfig(b,a):"div"==a.sAction?this._fnTextConfig(b,a):"collection"==a.sAction&&(this._fnTextConfig(b,a),this._fnCollectionConfig(b,
|
||||
a));return b},_fnButtonBase:function(a){var b=h.createElement("button"),c=h.createElement("span"),d=this._fnGetMasterSettings();b.className="DTTT_button "+a.sButtonClass;b.setAttribute("id","ToolTables_"+this.s.dt.sInstance+"_"+d.buttonCounter);b.appendChild(c);c.innerHTML=a.sButtonText;d.buttonCounter++;return b},_fnDivBase:function(a){var b=h.createElement("div"),c=this._fnGetMasterSettings();b.className=a.sButtonClass;b.setAttribute("id","ToolTables_"+this.s.dt.sInstance+"_"+c.buttonCounter);b.innerHTML=
|
||||
a.sButtonText;null!==a.nContent&&b.appendChild(a.nContent);c.buttonCounter++;return b},_fnGetMasterSettings:function(){if(this.s.master)return this.s;for(var a=TableTools._aInstances,b=0,c=a.length;b<c;b++)if(this.dom.table==a[b].s.dt.nTable)return a[b].s},_fnCollectionConfig:function(a,b){var c=h.createElement("div");c.style.display="none";c.className=!this.s.dt.bJUI?"DTTT_collection":"DTTT_collection ui-buttonset ui-buttonset-multi";b._collection=c;this._fnButtonDefinations(b.aButtons,c)},_fnCollectionShow:function(a,
|
||||
b){var c=this,d=e(a).offset(),j=b._collection,f=d.left,d=d.top+e(a).outerHeight(),g=e(n).height(),l=e(h).height(),m=e(n).width(),o=e(h).width();j.style.position="absolute";j.style.left=f+"px";j.style.top=d+"px";j.style.display="block";e(j).css("opacity",0);var k=h.createElement("div");k.style.position="absolute";k.style.left="0px";k.style.top="0px";k.style.height=(g>l?g:l)+"px";k.style.width=(m>o?m:o)+"px";k.className="DTTT_collection_background";e(k).css("opacity",0);h.body.appendChild(k);h.body.appendChild(j);
|
||||
g=e(j).outerWidth();m=e(j).outerHeight();if(f+g>o)j.style.left=o-g+"px";if(d+m>l)j.style.top=d-m-e(a).outerHeight()+"px";this.dom.collection.collection=j;this.dom.collection.background=k;setTimeout(function(){e(j).animate({opacity:1},500);e(k).animate({opacity:0.25},500)},10);e(k).click(function(){c._fnCollectionHide.call(c,null,null)})},_fnCollectionHide:function(a,b){if(!(null!==b&&"collection"==b.sExtends)&&null!==this.dom.collection.collection)e(this.dom.collection.collection).animate({opacity:0},
|
||||
500,function(){this.style.display="none"}),e(this.dom.collection.background).animate({opacity:0},500,function(){this.parentNode.removeChild(this)}),this.dom.collection.collection=null,this.dom.collection.background=null},_fnRowSelectConfig:function(){if(this.s.master){var a=this;e(a.s.dt.nTable).addClass("DTTT_selectable");e("tr",a.s.dt.nTBody).live("click",function(b){if(this.parentNode==a.s.dt.nTBody){var c=a.s.dt.oInstance.fnGetNodes();-1===e.inArray(this,c)||null!==a.s.select.preRowSelect&&!a.s.select.preRowSelect.call(a,
|
||||
b)||("single"==a.s.select.type?a._fnRowSelectSingle.call(a,this):a._fnRowSelectMulti.call(a,this))}});a.s.dt.aoDrawCallback.push({fn:function(){a.s.select.all&&a.s.dt.oFeatures.bServerSide&&a.fnSelectAll()},sName:"TableTools_select"})}},_fnRowSelectSingle:function(a){this.s.master&&!e("td",a).hasClass(this.s.dt.oClasses.sRowEmpty)&&(e(a).hasClass(this.s.select.selectedClass)?this._fnRowDeselect(a):(0!==this.s.select.selected.length&&this._fnRowDeselectAll(),this.s.select.selected.push(a),e(a).addClass(this.s.select.selectedClass),
|
||||
null!==this.s.select.postSelected&&this.s.select.postSelected.call(this,a)),TableTools._fnEventDispatch(this,"select",a))},_fnRowSelectMulti:function(a){this.s.master&&!e("td",a).hasClass(this.s.dt.oClasses.sRowEmpty)&&(e(a).hasClass(this.s.select.selectedClass)?this._fnRowDeselect(a):(this.s.select.selected.push(a),e(a).addClass(this.s.select.selectedClass),null!==this.s.select.postSelected&&this.s.select.postSelected.call(this,a)),TableTools._fnEventDispatch(this,"select",a))},_fnRowSelectAll:function(){if(this.s.master){for(var a,
|
||||
b=0,c=this.s.dt.aiDisplayMaster.length;b<c;b++)a=this.s.dt.aoData[this.s.dt.aiDisplayMaster[b]].nTr,e(a).hasClass(this.s.select.selectedClass)||(this.s.select.selected.push(a),e(a).addClass(this.s.select.selectedClass));null!==this.s.select.postSelected&&this.s.select.postSelected.call(this,null);this.s.select.all=!0;TableTools._fnEventDispatch(this,"select",null)}},_fnRowDeselectAll:function(){if(this.s.master){for(var a=this.s.select.selected.length-1;0<=a;a--)this._fnRowDeselect(a,!1);null!==this.s.select.postDeselected&&
|
||||
this.s.select.postDeselected.call(this,null);this.s.select.all=!1;TableTools._fnEventDispatch(this,"select",null)}},_fnRowDeselect:function(a,b){"undefined"!=typeof a.nodeName&&(a=e.inArray(a,this.s.select.selected));var c=this.s.select.selected[a];e(c).removeClass(this.s.select.selectedClass);this.s.select.selected.splice(a,1);("undefined"==typeof b||b)&&null!==this.s.select.postDeselected&&this.s.select.postDeselected.call(this,c);this.s.select.all=!1},_fnTextConfig:function(a,b){var c=this;null!==
|
||||
b.fnInit&&b.fnInit.call(this,a,b);if(""!==b.sToolTip)a.title=b.sToolTip;e(a).hover(function(){e(a).addClass(b.sButtonClassHover);null!==b.fnMouseover&&b.fnMouseover.call(this,a,b,null)},function(){e(a).removeClass(b.sButtonClassHover);null!==b.fnMouseout&&b.fnMouseout.call(this,a,b,null)});null!==b.fnSelect&&TableTools._fnEventListen(this,"select",function(d){b.fnSelect.call(c,a,b,d)});e(a).click(function(d){d.preventDefault();null!==b.fnClick&&b.fnClick.call(c,a,b,null);null!==b.fnComplete&&b.fnComplete.call(c,
|
||||
a,b,null,null);c._fnCollectionHide(a,b)})},_fnFlashConfig:function(a,b){var c=this,d=new ZeroClipboard.Client;null!==b.fnInit&&b.fnInit.call(this,a,b);d.setHandCursor(!0);"flash_save"==b.sAction?(d.setAction("save"),d.setCharSet("utf16le"==b.sCharSet?"UTF16LE":"UTF8"),d.setBomInc(b.bBomInc),d.setFileName(b.sFileName.replace("*",this.fnGetTitle(b)))):"flash_pdf"==b.sAction?(d.setAction("pdf"),d.setFileName(b.sFileName.replace("*",this.fnGetTitle(b)))):d.setAction("copy");d.addEventListener("mouseOver",
|
||||
function(){e(a).addClass(b.sButtonClassHover);null!==b.fnMouseover&&b.fnMouseover.call(c,a,b,d)});d.addEventListener("mouseOut",function(){e(a).removeClass(b.sButtonClassHover);null!==b.fnMouseout&&b.fnMouseout.call(c,a,b,d)});d.addEventListener("mouseDown",function(){null!==b.fnClick&&b.fnClick.call(c,a,b,d)});d.addEventListener("complete",function(e,f){null!==b.fnComplete&&b.fnComplete.call(c,a,b,d,f);c._fnCollectionHide(a,b)});this._fnFlashGlue(d,a,b.sToolTip)},_fnFlashGlue:function(a,b,c){var d=
|
||||
this,e=b.getAttribute("id");if(h.getElementById(e)){if(a.glue(b,c),a.domElement.parentNode!=a.div.parentNode&&"undefined"==typeof d.__bZCWarning)d.s.dt.oApi._fnLog(this.s.dt,0,"It looks like you are using the version of ZeroClipboard which came with TableTools 1. Please update to use the version that came with TableTools 2."),d.__bZCWarning=!0}else setTimeout(function(){d._fnFlashGlue(a,b,c)},100)},_fnFlashSetText:function(a,b){var c=this._fnChunkData(b,8192);a.clearText();for(var d=0,e=c.length;d<
|
||||
e;d++)a.appendText(c[d])},_fnColumnTargets:function(a){var b=[],c=this.s.dt;if("object"==typeof a){for(i=0,iLen=c.aoColumns.length;i<iLen;i++)b.push(!1);for(i=0,iLen=a.length;i<iLen;i++)b[a[i]]=!0}else if("visible"==a)for(i=0,iLen=c.aoColumns.length;i<iLen;i++)b.push(c.aoColumns[i].bVisible?!0:!1);else if("hidden"==a)for(i=0,iLen=c.aoColumns.length;i<iLen;i++)b.push(c.aoColumns[i].bVisible?!1:!0);else if("sortable"==a)for(i=0,iLen=c.aoColumns.length;i<iLen;i++)b.push(c.aoColumns[i].bSortable?!0:!1);
|
||||
else for(i=0,iLen=c.aoColumns.length;i<iLen;i++)b.push(!0);return b},_fnNewline:function(a){return"auto"==a.sNewLine?navigator.userAgent.match(/Windows/)?"\r\n":"\n":a.sNewLine},_fnGetDataTablesData:function(a){var b,c,d,j,f="",g="",h=this.s.dt,m=RegExp(a.sFieldBoundary,"g"),o=this._fnColumnTargets(a.mColumns),k=this._fnNewline(a),n="undefined"!=typeof a.bSelectedOnly?a.bSelectedOnly:!1;if(a.bHeader){for(b=0,c=h.aoColumns.length;b<c;b++)o[b]&&(g=h.aoColumns[b].sTitle.replace(/\n/g," ").replace(/<.*?>/g,
|
||||
"").replace(/^\s+|\s+$/g,""),g=this._fnHtmlDecode(g),f+=this._fnBoundData(g,a.sFieldBoundary,m)+a.sFieldSeperator);f=f.slice(0,-1*a.sFieldSeperator.length);f+=k}for(d=0,j=h.aiDisplay.length;d<j;d++)if("none"==this.s.select.type||n&&e(h.aoData[h.aiDisplay[d]].nTr).hasClass(this.s.select.selectedClass)||n&&0==this.s.select.selected.length){for(b=0,c=h.aoColumns.length;b<c;b++)o[b]&&(g=h.oApi._fnGetCellData(h,h.aiDisplay[d],b,"display"),a.fnCellRender?g=a.fnCellRender(g,b)+"":"string"==typeof g?(g=g.replace(/\n/g,
|
||||
" "),g=g.replace(/<img.*?\s+alt\s*=\s*(?:"([^"]+)"|'([^']+)'|([^\s>]+)).*?>/gi,"$1$2$3"),g=g.replace(/<.*?>/g,"")):g+="",g=g.replace(/^\s+/,"").replace(/\s+$/,""),g=this._fnHtmlDecode(g),f+=this._fnBoundData(g,a.sFieldBoundary,m)+a.sFieldSeperator);f=f.slice(0,-1*a.sFieldSeperator.length);f+=k}f.slice(0,-1);if(a.bFooter){for(b=0,c=h.aoColumns.length;b<c;b++)o[b]&&null!==h.aoColumns[b].nTf&&(g=h.aoColumns[b].nTf.innerHTML.replace(/\n/g," ").replace(/<.*?>/g,""),g=this._fnHtmlDecode(g),f+=this._fnBoundData(g,
|
||||
a.sFieldBoundary,m)+a.sFieldSeperator);f=f.slice(0,-1*a.sFieldSeperator.length)}return _sLastData=f},_fnBoundData:function(a,b,c){return""===b?a:b+a.replace(c,b+b)+b},_fnChunkData:function(a,b){for(var c=[],d=a.length,e=0;e<d;e+=b)e+b<d?c.push(a.substring(e,e+b)):c.push(a.substring(e,d));return c},_fnHtmlDecode:function(a){if(-1==a.indexOf("&"))return a;var a=this._fnChunkData(a,2048),b=h.createElement("div"),c,d,e,f="";for(c=0,d=a.length;c<d;c++)e=a[c].lastIndexOf("&"),-1!=e&&8<=a[c].length&&e>a[c].length-
|
||||
8&&(a[c].substr(e),a[c]=a[c].substr(0,e)),b.innerHTML=a[c],f+=b.childNodes[0].nodeValue;return f},_fnPrintConfig:function(a,b){var c=this;null!==b.fnInit&&b.fnInit.call(this,a,b);if(""!==b.sToolTip)a.title=b.sToolTip;e(a).hover(function(){e(a).addClass(b.sButtonClassHover)},function(){e(a).removeClass(b.sButtonClassHover)});null!==b.fnSelect&&TableTools._fnEventListen(this,"select",function(d){b.fnSelect.call(c,a,b,d)});e(a).click(function(d){d.preventDefault();c._fnPrintStart.call(c,d,b);null!==
|
||||
b.fnClick&&b.fnClick.call(c,a,b,null);null!==b.fnComplete&&b.fnComplete.call(c,a,b,null,null);c._fnCollectionHide(a,b)})},_fnPrintStart:function(a,b){var c=this,d=this.s.dt;this._fnPrintHideNodes(d.nTable);this.s.print.saveStart=d._iDisplayStart;this.s.print.saveLength=d._iDisplayLength;if(b.bShowAll)d._iDisplayStart=0,d._iDisplayLength=-1,d.oApi._fnCalculateEnd(d),d.oApi._fnDraw(d);(""!==d.oScroll.sX||""!==d.oScroll.sY)&&this._fnPrintScrollStart(d);var d=d.aanFeatures,j;for(j in d)if("i"!=j&&"t"!=
|
||||
j&&1==j.length)for(var f=0,g=d[j].length;f<g;f++)this.dom.print.hidden.push({node:d[j][f],display:"block"}),d[j][f].style.display="none";e(h.body).addClass("DTTT_Print");if(""!==b.sInfo){var l=h.createElement("div");l.className="DTTT_print_info";l.innerHTML=b.sInfo;h.body.appendChild(l);setTimeout(function(){e(l).fadeOut("normal",function(){h.body.removeChild(l)})},2E3)}if(""!==b.sMessage)this.dom.print.message=h.createElement("div"),this.dom.print.message.className="DTTT_PrintMessage",this.dom.print.message.innerHTML=
|
||||
b.sMessage,h.body.insertBefore(this.dom.print.message,h.body.childNodes[0]);this.s.print.saveScroll=e(n).scrollTop();n.scrollTo(0,0);this.s.print.funcEnd=function(a){c._fnPrintEnd.call(c,a)};e(h).bind("keydown",null,this.s.print.funcEnd)},_fnPrintEnd:function(a){if(27==a.keyCode){a.preventDefault();var a=this.s.dt,b=this.s.print,c=this.dom.print;this._fnPrintShowNodes();(""!==a.oScroll.sX||""!==a.oScroll.sY)&&this._fnPrintScrollEnd();n.scrollTo(0,b.saveScroll);if(null!==c.message)h.body.removeChild(c.message),
|
||||
c.message=null;e(h.body).removeClass("DTTT_Print");a._iDisplayStart=b.saveStart;a._iDisplayLength=b.saveLength;a.oApi._fnCalculateEnd(a);a.oApi._fnDraw(a);e(h).unbind("keydown",this.s.print.funcEnd);this.s.print.funcEnd=null}},_fnPrintScrollStart:function(){var a=this.s.dt;a.nScrollHead.getElementsByTagName("div")[0].getElementsByTagName("table");var b=a.nTable.parentNode,c=a.nTable.getElementsByTagName("thead");0<c.length&&a.nTable.removeChild(c[0]);null!==a.nTFoot&&(c=a.nTable.getElementsByTagName("tfoot"),
|
||||
0<c.length&&a.nTable.removeChild(c[0]));c=a.nTHead.cloneNode(!0);a.nTable.insertBefore(c,a.nTable.childNodes[0]);null!==a.nTFoot&&(c=a.nTFoot.cloneNode(!0),a.nTable.insertBefore(c,a.nTable.childNodes[1]));if(""!==a.oScroll.sX)a.nTable.style.width=e(a.nTable).outerWidth()+"px",b.style.width=e(a.nTable).outerWidth()+"px",b.style.overflow="visible";if(""!==a.oScroll.sY)b.style.height=e(a.nTable).outerHeight()+"px",b.style.overflow="visible"},_fnPrintScrollEnd:function(){var a=this.s.dt,b=a.nTable.parentNode;
|
||||
if(""!==a.oScroll.sX)b.style.width=a.oApi._fnStringToCss(a.oScroll.sX),b.style.overflow="auto";if(""!==a.oScroll.sY)b.style.height=a.oApi._fnStringToCss(a.oScroll.sY),b.style.overflow="auto"},_fnPrintShowNodes:function(){for(var a=this.dom.print.hidden,b=0,c=a.length;b<c;b++)a[b].node.style.display=a[b].display;a.splice(0,a.length)},_fnPrintHideNodes:function(a){for(var b=this.dom.print.hidden,c=a.parentNode,d=c.childNodes,j=0,f=d.length;j<f;j++)if(d[j]!=a&&1==d[j].nodeType){var g=e(d[j]).css("display");
|
||||
if("none"!=g)b.push({node:d[j],display:g}),d[j].style.display="none"}"BODY"!=c.nodeName&&this._fnPrintHideNodes(c)}};TableTools._aInstances=[];TableTools._aListeners=[];TableTools.fnGetMasters=function(){for(var a=[],b=0,c=TableTools._aInstances.length;b<c;b++)TableTools._aInstances[b].s.master&&a.push(TableTools._aInstances[b]);return a};TableTools.fnGetInstance=function(a){"object"!=typeof a&&(a=h.getElementById(a));for(var b=0,c=TableTools._aInstances.length;b<c;b++)if(TableTools._aInstances[b].s.master&&
|
||||
TableTools._aInstances[b].dom.table==a)return TableTools._aInstances[b];return null};TableTools._fnEventListen=function(a,b,c){TableTools._aListeners.push({that:a,type:b,fn:c})};TableTools._fnEventDispatch=function(a,b,c){for(var d=TableTools._aListeners,e=0,f=d.length;e<f;e++)a.dom.table==d[e].that.dom.table&&d[e].type==b&&d[e].fn(c)};TableTools.BUTTONS={csv:{sAction:"flash_save",sCharSet:"utf8",bBomInc:!1,sFileName:"*.csv",sFieldBoundary:'"',sFieldSeperator:",",sNewLine:"auto",sTitle:"",sToolTip:"",
|
||||
sButtonClass:"DTTT_button_csv",sButtonClassHover:"DTTT_button_csv_hover",sButtonText:"CSV",mColumns:"all",bHeader:!0,bFooter:!0,bSelectedOnly:!1,fnMouseover:null,fnMouseout:null,fnClick:function(a,b,c){this.fnSetText(c,this.fnGetTableData(b))},fnSelect:null,fnComplete:null,fnInit:null,fnCellRender:null},xls:{sAction:"flash_save",sCharSet:"utf16le",bBomInc:!0,sFileName:"*.csv",sFieldBoundary:"",sFieldSeperator:"\t",sNewLine:"auto",sTitle:"",sToolTip:"",sButtonClass:"DTTT_button_xls",sButtonClassHover:"DTTT_button_xls_hover",
|
||||
sButtonText:"Excel",mColumns:"all",bHeader:!0,bFooter:!0,bSelectedOnly:!1,fnMouseover:null,fnMouseout:null,fnClick:function(a,b,c){this.fnSetText(c,this.fnGetTableData(b))},fnSelect:null,fnComplete:null,fnInit:null,fnCellRender:null},copy:{sAction:"flash_copy",sFieldBoundary:"",sFieldSeperator:"\t",sNewLine:"auto",sToolTip:"",sButtonClass:"DTTT_button_copy",sButtonClassHover:"DTTT_button_copy_hover",sButtonText:"Copy",mColumns:"all",bHeader:!0,bFooter:!0,bSelectedOnly:!1,fnMouseover:null,fnMouseout:null,
|
||||
fnClick:function(a,b,c){this.fnSetText(c,this.fnGetTableData(b))},fnSelect:null,fnComplete:function(a,b,c,d){a=d.split("\n").length;a=null===this.s.dt.nTFoot?a-1:a-2;alert("Copied "+a+" row"+(1==a?"":"s")+" to the clipboard")},fnInit:null,fnCellRender:null},pdf:{sAction:"flash_pdf",sFieldBoundary:"",sFieldSeperator:"\t",sNewLine:"\n",sFileName:"*.pdf",sToolTip:"",sTitle:"",sButtonClass:"DTTT_button_pdf",sButtonClassHover:"DTTT_button_pdf_hover",sButtonText:"PDF",mColumns:"all",bHeader:!0,bFooter:!1,
|
||||
bSelectedOnly:!1,fnMouseover:null,fnMouseout:null,sPdfOrientation:"portrait",sPdfSize:"A4",sPdfMessage:"",fnClick:function(a,b,c){this.fnSetText(c,"title:"+this.fnGetTitle(b)+"\nmessage:"+b.sPdfMessage+"\ncolWidth:"+this.fnCalcColRatios(b)+"\norientation:"+b.sPdfOrientation+"\nsize:"+b.sPdfSize+"\n--/TableToolsOpts--\n"+this.fnGetTableData(b))},fnSelect:null,fnComplete:null,fnInit:null,fnCellRender:null},print:{sAction:"print",sInfo:"<h6>Print view</h6><p>Please use your browser's print function to print this table. Press escape when finished.",
|
||||
sMessage:"",bShowAll:!0,sToolTip:"View print view",sButtonClass:"DTTT_button_print",sButtonClassHover:"DTTT_button_print_hover",sButtonText:"Print",fnMouseover:null,fnMouseout:null,fnClick:null,fnSelect:null,fnComplete:null,fnInit:null,fnCellRender:null},text:{sAction:"text",sToolTip:"",sButtonClass:"DTTT_button_text",sButtonClassHover:"DTTT_button_text_hover",sButtonText:"Text button",mColumns:"all",bHeader:!0,bFooter:!0,bSelectedOnly:!1,fnMouseover:null,fnMouseout:null,fnClick:null,fnSelect:null,
|
||||
fnComplete:null,fnInit:null,fnCellRender:null},select:{sAction:"text",sToolTip:"",sButtonClass:"DTTT_button_text",sButtonClassHover:"DTTT_button_text_hover",sButtonText:"Select button",mColumns:"all",bHeader:!0,bFooter:!0,fnMouseover:null,fnMouseout:null,fnClick:null,fnSelect:function(a){0!==this.fnGetSelected().length?e(a).removeClass("DTTT_disabled"):e(a).addClass("DTTT_disabled")},fnComplete:null,fnInit:function(a){e(a).addClass("DTTT_disabled")},fnCellRender:null},select_single:{sAction:"text",
|
||||
sToolTip:"",sButtonClass:"DTTT_button_text",sButtonClassHover:"DTTT_button_text_hover",sButtonText:"Select button",mColumns:"all",bHeader:!0,bFooter:!0,fnMouseover:null,fnMouseout:null,fnClick:null,fnSelect:function(a){1==this.fnGetSelected().length?e(a).removeClass("DTTT_disabled"):e(a).addClass("DTTT_disabled")},fnComplete:null,fnInit:function(a){e(a).addClass("DTTT_disabled")},fnCellRender:null},select_all:{sAction:"text",sToolTip:"",sButtonClass:"DTTT_button_text",sButtonClassHover:"DTTT_button_text_hover",
|
||||
sButtonText:"Select all",mColumns:"all",bHeader:!0,bFooter:!0,fnMouseover:null,fnMouseout:null,fnClick:function(){this.fnSelectAll()},fnSelect:function(a){this.fnGetSelected().length==this.s.dt.fnRecordsDisplay()?e(a).addClass("DTTT_disabled"):e(a).removeClass("DTTT_disabled")},fnComplete:null,fnInit:null,fnCellRender:null},select_none:{sAction:"text",sToolTip:"",sButtonClass:"DTTT_button_text",sButtonClassHover:"DTTT_button_text_hover",sButtonText:"Deselect all",mColumns:"all",bHeader:!0,bFooter:!0,
|
||||
fnMouseover:null,fnMouseout:null,fnClick:function(){this.fnSelectNone()},fnSelect:function(a){0!==this.fnGetSelected().length?e(a).removeClass("DTTT_disabled"):e(a).addClass("DTTT_disabled")},fnComplete:null,fnInit:function(a){e(a).addClass("DTTT_disabled")},fnCellRender:null},ajax:{sAction:"text",sFieldBoundary:"",sFieldSeperator:"\t",sNewLine:"\n",sAjaxUrl:"/xhr.php",sToolTip:"",sButtonClass:"DTTT_button_text",sButtonClassHover:"DTTT_button_text_hover",sButtonText:"Ajax button",mColumns:"all",bHeader:!0,
|
||||
bFooter:!0,bSelectedOnly:!1,fnMouseover:null,fnMouseout:null,fnClick:function(a,b){var c=this.fnGetTableData(b);e.ajax({url:b.sAjaxUrl,data:[{name:"tableData",value:c}],success:b.fnAjaxComplete,dataType:"json",type:"POST",cache:!1,error:function(){alert("Error detected when sending table data to server")}})},fnSelect:null,fnComplete:null,fnInit:null,fnAjaxComplete:function(){alert("Ajax complete")},fnCellRender:null},div:{sAction:"div",sToolTip:"",sButtonClass:"DTTT_nonbutton",sButtonClassHover:"",
|
||||
sButtonText:"Text button",fnMouseover:null,fnMouseout:null,fnClick:null,fnSelect:null,fnComplete:null,fnInit:null,nContent:null,fnCellRender:null},collection:{sAction:"collection",sToolTip:"",sButtonClass:"DTTT_button_collection",sButtonClassHover:"DTTT_button_collection_hover",sButtonText:"Collection",fnMouseover:null,fnMouseout:null,fnClick:function(a,b){this._fnCollectionShow(a,b)},fnSelect:null,fnComplete:null,fnInit:null,fnCellRender:null}};TableTools.DEFAULTS={sSwfPath:"media/swf/copy_cvs_xls_pdf.swf",
|
||||
sRowSelect:"none",sSelectedClass:"DTTT_selected",fnPreRowSelect:null,fnRowSelected:null,fnRowDeselected:null,aButtons:["copy","csv","xls","pdf","print"]};TableTools.prototype.CLASS="TableTools";TableTools.VERSION="2.0.2";TableTools.prototype.VERSION=TableTools.VERSION;"function"==typeof e.fn.dataTable&&"function"==typeof e.fn.dataTableExt.fnVersionCheck&&e.fn.dataTableExt.fnVersionCheck("1.8.2")?e.fn.dataTableExt.aoFeatures.push({fnInit:function(a){a=new TableTools(a.oInstance,"undefined"!=typeof a.oInit.oTableTools?
|
||||
a.oInit.oTableTools:{});TableTools._aInstances.push(a);return a.dom.container},cFeature:"T",sFeature:"TableTools"}):alert("Warning: TableTools 2 requires DataTables 1.8.2 or newer - www.datatables.net/download")})(jQuery,window,document);
|
|
@ -0,0 +1,367 @@
|
|||
// Simple Set Clipboard System
|
||||
// Author: Joseph Huckaby
|
||||
|
||||
var ZeroClipboard = {
|
||||
|
||||
version: "1.0.4-TableTools2",
|
||||
clients: {}, // registered upload clients on page, indexed by id
|
||||
moviePath: '', // URL to movie
|
||||
nextId: 1, // ID of next movie
|
||||
|
||||
$: function(thingy) {
|
||||
// simple DOM lookup utility function
|
||||
if (typeof(thingy) == 'string') thingy = document.getElementById(thingy);
|
||||
if (!thingy.addClass) {
|
||||
// extend element with a few useful methods
|
||||
thingy.hide = function() { this.style.display = 'none'; };
|
||||
thingy.show = function() { this.style.display = ''; };
|
||||
thingy.addClass = function(name) { this.removeClass(name); this.className += ' ' + name; };
|
||||
thingy.removeClass = function(name) {
|
||||
this.className = this.className.replace( new RegExp("\\s*" + name + "\\s*"), " ").replace(/^\s+/, '').replace(/\s+$/, '');
|
||||
};
|
||||
thingy.hasClass = function(name) {
|
||||
return !!this.className.match( new RegExp("\\s*" + name + "\\s*") );
|
||||
}
|
||||
}
|
||||
return thingy;
|
||||
},
|
||||
|
||||
setMoviePath: function(path) {
|
||||
// set path to ZeroClipboard.swf
|
||||
this.moviePath = path;
|
||||
},
|
||||
|
||||
dispatch: function(id, eventName, args) {
|
||||
// receive event from flash movie, send to client
|
||||
var client = this.clients[id];
|
||||
if (client) {
|
||||
client.receiveEvent(eventName, args);
|
||||
}
|
||||
},
|
||||
|
||||
register: function(id, client) {
|
||||
// register new client to receive events
|
||||
this.clients[id] = client;
|
||||
},
|
||||
|
||||
getDOMObjectPosition: function(obj) {
|
||||
// get absolute coordinates for dom element
|
||||
var info = {
|
||||
left: 0,
|
||||
top: 0,
|
||||
width: obj.width ? obj.width : obj.offsetWidth,
|
||||
height: obj.height ? obj.height : obj.offsetHeight
|
||||
};
|
||||
|
||||
if ( obj.style.width != "" )
|
||||
info.width = obj.style.width.replace("px","");
|
||||
|
||||
if ( obj.style.height != "" )
|
||||
info.height = obj.style.height.replace("px","");
|
||||
|
||||
while (obj) {
|
||||
info.left += obj.offsetLeft;
|
||||
info.top += obj.offsetTop;
|
||||
obj = obj.offsetParent;
|
||||
}
|
||||
|
||||
return info;
|
||||
},
|
||||
|
||||
Client: function(elem) {
|
||||
// constructor for new simple upload client
|
||||
this.handlers = {};
|
||||
|
||||
// unique ID
|
||||
this.id = ZeroClipboard.nextId++;
|
||||
this.movieId = 'ZeroClipboardMovie_' + this.id;
|
||||
|
||||
// register client with singleton to receive flash events
|
||||
ZeroClipboard.register(this.id, this);
|
||||
|
||||
// create movie
|
||||
if (elem) this.glue(elem);
|
||||
}
|
||||
};
|
||||
|
||||
ZeroClipboard.Client.prototype = {
|
||||
|
||||
id: 0, // unique ID for us
|
||||
ready: false, // whether movie is ready to receive events or not
|
||||
movie: null, // reference to movie object
|
||||
clipText: '', // text to copy to clipboard
|
||||
fileName: '', // default file save name
|
||||
action: 'copy', // action to perform
|
||||
handCursorEnabled: true, // whether to show hand cursor, or default pointer cursor
|
||||
cssEffects: true, // enable CSS mouse effects on dom container
|
||||
handlers: null, // user event handlers
|
||||
sized: false,
|
||||
|
||||
glue: function(elem, title) {
|
||||
// glue to DOM element
|
||||
// elem can be ID or actual DOM element object
|
||||
this.domElement = ZeroClipboard.$(elem);
|
||||
|
||||
// float just above object, or zIndex 99 if dom element isn't set
|
||||
var zIndex = 99;
|
||||
if (this.domElement.style.zIndex) {
|
||||
zIndex = parseInt(this.domElement.style.zIndex) + 1;
|
||||
}
|
||||
|
||||
// find X/Y position of domElement
|
||||
var box = ZeroClipboard.getDOMObjectPosition(this.domElement);
|
||||
|
||||
// create floating DIV above element
|
||||
this.div = document.createElement('div');
|
||||
var style = this.div.style;
|
||||
style.position = 'absolute';
|
||||
style.left = (this.domElement.offsetLeft)+'px';
|
||||
//style.left = (this.domElement.offsetLeft+2)+'px';
|
||||
style.top = this.domElement.offsetTop+'px';
|
||||
style.width = (box.width) + 'px';
|
||||
//style.width = (box.width-4) + 'px';
|
||||
style.height = box.height + 'px';
|
||||
style.zIndex = zIndex;
|
||||
if ( typeof title != "undefined" && title != "" ) {
|
||||
this.div.title = title;
|
||||
}
|
||||
if ( box.width != 0 && box.height != 0 ) {
|
||||
this.sized = true;
|
||||
}
|
||||
|
||||
// style.backgroundColor = '#f00'; // debug
|
||||
this.domElement.parentNode.appendChild(this.div);
|
||||
|
||||
this.div.innerHTML = this.getHTML( box.width, box.height );
|
||||
},
|
||||
|
||||
positionElement: function() {
|
||||
var box = ZeroClipboard.getDOMObjectPosition(this.domElement);
|
||||
var style = this.div.style;
|
||||
|
||||
style.position = 'absolute';
|
||||
style.left = (this.domElement.offsetLeft)+'px';
|
||||
style.top = this.domElement.offsetTop+'px';
|
||||
style.width = box.width + 'px';
|
||||
style.height = box.height + 'px';
|
||||
|
||||
if ( box.width != 0 && box.height != 0 ) {
|
||||
this.sized = true;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
var flash = this.div.childNodes[0];
|
||||
flash.width = box.width;
|
||||
flash.height = box.height;
|
||||
},
|
||||
|
||||
getHTML: function(width, height) {
|
||||
// return HTML for movie
|
||||
var html = '';
|
||||
var flashvars = 'id=' + this.id +
|
||||
'&width=' + width +
|
||||
'&height=' + height;
|
||||
|
||||
if (navigator.userAgent.match(/MSIE/)) {
|
||||
// IE gets an OBJECT tag
|
||||
var protocol = location.href.match(/^https/i) ? 'https://' : 'http://';
|
||||
html += '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="'+protocol+'download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=10,0,0,0" width="'+width+'" height="'+height+'" id="'+this.movieId+'" align="middle"><param name="allowScriptAccess" value="always" /><param name="allowFullScreen" value="false" /><param name="movie" value="'+ZeroClipboard.moviePath+'" /><param name="loop" value="false" /><param name="menu" value="false" /><param name="quality" value="best" /><param name="bgcolor" value="#ffffff" /><param name="flashvars" value="'+flashvars+'"/><param name="wmode" value="transparent"/></object>';
|
||||
}
|
||||
else {
|
||||
// all other browsers get an EMBED tag
|
||||
html += '<embed id="'+this.movieId+'" src="'+ZeroClipboard.moviePath+'" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="'+width+'" height="'+height+'" name="'+this.movieId+'" align="middle" allowScriptAccess="always" allowFullScreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="'+flashvars+'" wmode="transparent" />';
|
||||
}
|
||||
return html;
|
||||
},
|
||||
|
||||
hide: function() {
|
||||
// temporarily hide floater offscreen
|
||||
if (this.div) {
|
||||
this.div.style.left = '-2000px';
|
||||
}
|
||||
},
|
||||
|
||||
show: function() {
|
||||
// show ourselves after a call to hide()
|
||||
this.reposition();
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
// destroy control and floater
|
||||
if (this.domElement && this.div) {
|
||||
this.hide();
|
||||
this.div.innerHTML = '';
|
||||
|
||||
var body = document.getElementsByTagName('body')[0];
|
||||
try { body.removeChild( this.div ); } catch(e) {;}
|
||||
|
||||
this.domElement = null;
|
||||
this.div = null;
|
||||
}
|
||||
},
|
||||
|
||||
reposition: function(elem) {
|
||||
// reposition our floating div, optionally to new container
|
||||
// warning: container CANNOT change size, only position
|
||||
if (elem) {
|
||||
this.domElement = ZeroClipboard.$(elem);
|
||||
if (!this.domElement) this.hide();
|
||||
}
|
||||
|
||||
if (this.domElement && this.div) {
|
||||
var box = ZeroClipboard.getDOMObjectPosition(this.domElement);
|
||||
var style = this.div.style;
|
||||
style.left = '' + box.left + 'px';
|
||||
style.top = '' + box.top + 'px';
|
||||
}
|
||||
},
|
||||
|
||||
clearText: function() {
|
||||
// clear the text to be copy / saved
|
||||
this.clipText = '';
|
||||
if (this.ready) this.movie.clearText();
|
||||
},
|
||||
|
||||
appendText: function(newText) {
|
||||
// append text to that which is to be copied / saved
|
||||
this.clipText += newText;
|
||||
if (this.ready) { this.movie.appendText(newText) ;}
|
||||
},
|
||||
|
||||
setText: function(newText) {
|
||||
// set text to be copied to be copied / saved
|
||||
this.clipText = newText;
|
||||
if (this.ready) { this.movie.setText(newText) ;}
|
||||
},
|
||||
|
||||
setCharSet: function(charSet) {
|
||||
// set the character set (UTF16LE or UTF8)
|
||||
this.charSet = charSet;
|
||||
if (this.ready) { this.movie.setCharSet(charSet) ;}
|
||||
},
|
||||
|
||||
setBomInc: function(bomInc) {
|
||||
// set if the BOM should be included or not
|
||||
this.incBom = bomInc;
|
||||
if (this.ready) { this.movie.setBomInc(bomInc) ;}
|
||||
},
|
||||
|
||||
setFileName: function(newText) {
|
||||
// set the file name
|
||||
this.fileName = newText;
|
||||
if (this.ready) this.movie.setFileName(newText);
|
||||
},
|
||||
|
||||
setAction: function(newText) {
|
||||
// set action (save or copy)
|
||||
this.action = newText;
|
||||
if (this.ready) this.movie.setAction(newText);
|
||||
},
|
||||
|
||||
addEventListener: function(eventName, func) {
|
||||
// add user event listener for event
|
||||
// event types: load, queueStart, fileStart, fileComplete, queueComplete, progress, error, cancel
|
||||
eventName = eventName.toString().toLowerCase().replace(/^on/, '');
|
||||
if (!this.handlers[eventName]) this.handlers[eventName] = [];
|
||||
this.handlers[eventName].push(func);
|
||||
},
|
||||
|
||||
setHandCursor: function(enabled) {
|
||||
// enable hand cursor (true), or default arrow cursor (false)
|
||||
this.handCursorEnabled = enabled;
|
||||
if (this.ready) this.movie.setHandCursor(enabled);
|
||||
},
|
||||
|
||||
setCSSEffects: function(enabled) {
|
||||
// enable or disable CSS effects on DOM container
|
||||
this.cssEffects = !!enabled;
|
||||
},
|
||||
|
||||
receiveEvent: function(eventName, args) {
|
||||
// receive event from flash
|
||||
eventName = eventName.toString().toLowerCase().replace(/^on/, '');
|
||||
|
||||
// special behavior for certain events
|
||||
switch (eventName) {
|
||||
case 'load':
|
||||
// movie claims it is ready, but in IE this isn't always the case...
|
||||
// bug fix: Cannot extend EMBED DOM elements in Firefox, must use traditional function
|
||||
this.movie = document.getElementById(this.movieId);
|
||||
if (!this.movie) {
|
||||
var self = this;
|
||||
setTimeout( function() { self.receiveEvent('load', null); }, 1 );
|
||||
return;
|
||||
}
|
||||
|
||||
// firefox on pc needs a "kick" in order to set these in certain cases
|
||||
if (!this.ready && navigator.userAgent.match(/Firefox/) && navigator.userAgent.match(/Windows/)) {
|
||||
var self = this;
|
||||
setTimeout( function() { self.receiveEvent('load', null); }, 100 );
|
||||
this.ready = true;
|
||||
return;
|
||||
}
|
||||
|
||||
this.ready = true;
|
||||
this.movie.clearText();
|
||||
this.movie.appendText( this.clipText );
|
||||
this.movie.setFileName( this.fileName );
|
||||
this.movie.setAction( this.action );
|
||||
this.movie.setCharSet( this.charSet );
|
||||
this.movie.setBomInc( this.incBom );
|
||||
this.movie.setHandCursor( this.handCursorEnabled );
|
||||
break;
|
||||
|
||||
case 'mouseover':
|
||||
if (this.domElement && this.cssEffects) {
|
||||
//this.domElement.addClass('hover');
|
||||
if (this.recoverActive) this.domElement.addClass('active');
|
||||
}
|
||||
break;
|
||||
|
||||
case 'mouseout':
|
||||
if (this.domElement && this.cssEffects) {
|
||||
this.recoverActive = false;
|
||||
if (this.domElement.hasClass('active')) {
|
||||
this.domElement.removeClass('active');
|
||||
this.recoverActive = true;
|
||||
}
|
||||
//this.domElement.removeClass('hover');
|
||||
}
|
||||
break;
|
||||
|
||||
case 'mousedown':
|
||||
if (this.domElement && this.cssEffects) {
|
||||
this.domElement.addClass('active');
|
||||
}
|
||||
break;
|
||||
|
||||
case 'mouseup':
|
||||
if (this.domElement && this.cssEffects) {
|
||||
this.domElement.removeClass('active');
|
||||
this.recoverActive = false;
|
||||
}
|
||||
break;
|
||||
} // switch eventName
|
||||
|
||||
if (this.handlers[eventName]) {
|
||||
for (var idx = 0, len = this.handlers[eventName].length; idx < len; idx++) {
|
||||
var func = this.handlers[eventName][idx];
|
||||
|
||||
if (typeof(func) == 'function') {
|
||||
// actual function reference
|
||||
func(this, args);
|
||||
}
|
||||
else if ((typeof(func) == 'object') && (func.length == 2)) {
|
||||
// PHP style object + method, i.e. [myObject, 'myMethod']
|
||||
func[0][ func[1] ](this, args);
|
||||
}
|
||||
else if (typeof(func) == 'string') {
|
||||
// name of function
|
||||
window[func](this, args);
|
||||
}
|
||||
} // foreach event handler defined
|
||||
} // user defined handler for event
|
||||
}
|
||||
|
||||
};
|
|
@ -104,6 +104,7 @@ class PypoPush(Thread):
|
|||
track, so let's push it now so that Liquidsoap can start playing
|
||||
it immediately after (and prepare crossfades if need be).
|
||||
"""
|
||||
self.logger.debug("Push track immediately.")
|
||||
self.telnet_to_liquidsoap(media_item)
|
||||
self.last_end_time = media_item["end"]
|
||||
else:
|
||||
|
@ -111,11 +112,13 @@ class PypoPush(Thread):
|
|||
this media item does not start right after a current playing track.
|
||||
We need to sleep, and then wake up when this track starts.
|
||||
"""
|
||||
self.logger.debug("sleep until track start.")
|
||||
self.sleep_until_start(media_item)
|
||||
|
||||
self.telnet_to_liquidsoap(media_item)
|
||||
self.last_end_time = media_item["end"]
|
||||
except Exception, e:
|
||||
self.logger.error('Pypo Push Exception: %s', e)
|
||||
return False
|
||||
|
||||
return True
|
||||
|
|