/**
* Printer Handler. Will recognise if CTRL+P is pressed / the menu has been used
* It is important to use the internal functions to trigger printing or it can not
* be assured that all pages have been laoded and the report is being printed with
* all of its content
*
* @namespace
*/
/* global debug */
/* global updateInputValue */
/* global MenubarActions */
/* global getId */
/* global LoadingView */
/* global loadpage */
/* global _pageCache */
/* global getTranslation */
/* global documentExport */
/* global generator */
var printListener = {
printMenu: false,
didShowError: false,
printingFormats : [],
isOnline: true,
/**
* Attach the print dialog to a button
* @param {object} button to use as base for the print menu
* @param {object} element to prepend the new button to
* @param {boolean} isOnline if the browser is online. Otherwise: no need for extra print methods.
* @function
*/
buildPrint: function (parentButton, insertBefore, isOnline) {
var menu = new generator.submenuContainer(parentButton);
menu.menuContainer.addClassName('__complexSubmenu');
printListener.printMenu = menu;
printListener.isOnline = isOnline;
if (typeof insertBefore != 'undefined') {
getId('__menuBar').insertBefore(menu.submenu, insertBefore);
} else {
getId('__menuBar').appendChild(menu.submenu);
}
},
/**
* Show the print dialog if there are more than one handler. If exactly one: execute
* @param {object} event the triggered event
*/
showPrint: function () {
var isOpen = printListener.printMenu.menuContainer.hasClassName('open');
if (!isOpen) {
if ( !printListener.isOnline ) {
// If the viewer is offline, we only need the browser printing.
printListener.resetPrintingFormats();
}
// open Elements will be closed but not the other way arround.
if ( printListener.printingFormats.length < 1 ) { return true; }
else if ( printListener.printingFormats.length == 1 ) { setTimeout( printListener.printingFormats[0].executeFunction ); return true; }
printListener.printMenu.clear();
printListener.printingFormats.forEach(function (value) {
var elem = document.createElement('div');
elem.appendChild(document.createTextNode(getTranslation(value.printerName)));
elem.addClassName('right');
generator.addDescription(elem, value.description);
printListener.printMenu.addEntry(elem, function() {
value.executeFunction.call();
printListener.showPrint.call();
}, false, false, true);
});
}
printListener.printMenu.menuContainer.addRemoveClass('open', !isOpen);
printListener.printMenu.parentElement.setIsCurrent(!isOpen);
return true;
},
/**
* Add a printing format to the print listener
* @param {string} name the name of the listener (can be a translation key)
* @param {string} description the description of the listener (can be a translation key)
* @param {function} executeFunction the function to execute when this print format is selected
*/
addFormat: function(name, description, executeFunction) {
var format = {
// Default print function
printerName: name,
description: description,
executeFunction: executeFunction
};
// Check for existing entries of same name
var existing = printListener.printingFormats.filter(function(element){
return (element.printerName == format.printerName );
});
// Add only once
if ( existing.length === 0 ) {
printListener.printingFormats.push( format );
}
},
/**
* Clears the printing formats list and adds the default browser printing.
*/
resetPrintingFormats: function() {
// Add the default print listener
printListener.printingFormats = [];
printListener.addFormat( 'print.browserPrint', 'menuBar.print.hint', browserPrint.print);
},
/**
* Do something before printing is switched on (media query)
* @param {object} e the event
*/
beforePrint: function (_e) {
debug("Changed to printing");
},
/**
* Do something after printing is switched back (media query)
* @param {object} e the event
*/
afterPrint: function (_e) {
debug("Changed back to normal");
},
handleMediaChange: function (mql) {
if (mql.matches) {
printListener.beforePrint(mql);
} else {
printListener.afterPrint(mql);
}
}
};
/**
* Default browser printing handler. Will trigger the multipage to be loaded.
* After that the browsers printing capabilities will be used.
*
* If a threshhold (99 pages by default) is exceeded, a PDF will be generated instead
*
* @namespace
*/
var browserPrint = {
pageCount: 1,
maxPagesToPrint: 99,
timeoutHandler: null,
/**
* Trigger the printing using command and window print.
*/
printInternal : function() {
window.fireEvent('htmlviewer.print');
},
/**
* This should be the only way to trigger printing
*/
print: function () {
var menu = MenubarActions();
if (browserPrint.maxPagesToPrint < parseInt(menu.maxPages) && documentExport ) {
return documentExport.printPDF();
}
// Check for all Pages to be loaded (synchronously!)
browserPrint.switchMode(function (finishFunction) {
debug("loaded");
var loadPrintPages = function () {
browserPrint.pageCount = menu.maxPages;
var checkCountOrLoad = function () {
if (--browserPrint.pageCount > 0) {
loadNextPage(browserPrint.pageCount);
} else {
clearTimeout( browserPrint.timeoutHandler );
browserPrint.timeoutHandler = setTimeout(function () {
// Reset
browserPrint.pageCount = 1;
(new LoadingView()).hide();
setTimeout(browserPrint.printInternal);
}, 1000);
}
(new LoadingView()).hide();
};
var loadNextPage = function (nextPage) {
(new LoadingView()).show(getTranslation("print.browserPrint") + " " + (menu.maxPages - nextPage + 1) + "/" + menu.maxPages);
var loadThePage = new loadpage(nextPage, null, null, true);
loadThePage.pageFinished = function (_wasFullyLoaded) {
// wait until all images are loaded.
debug("Page " + nextPage + " is Finished, now wait for all images to be ready.");
/*if (wasFullyLoaded) { // 2018-06-27 - redundant?!
debug("This page had been loaded alread.");
// checkCountOrLoad();
return;
}*/
var page = _pageCache.getPage(loadThePage.ajax).pageCurrent();
var images = getId(page).getElementsByTagName('img');
var wait = function () {
for(var i = 0; i < images.length; i++) {
if (!images[i].complete) {
setTimeout(wait, 200);
return;
}
}
checkCountOrLoad();
};
wait();
};
debug("Starting to Load Page " + nextPage + ".");
loadThePage.startLoading();
};
loadNextPage(browserPrint.pageCount);
};
if (typeof finishFunction == 'function') {
finishFunction(loadPrintPages);
} else {
loadPrintPages();
}
});
(new LoadingView()).show();
},
switchMode: function (finishFunction) {
if (!getId('endless-mode').isCurrent()) {
(new MenubarActions()).endlessMode(true, finishFunction);
} else if (typeof finishFunction == 'function') {
finishFunction();
}
}
};
window.addEvent( 'htmlviewer.print', function(){
var didPrint = false;
try {
didPrint = document.execCommand('print', true, false );
} catch(e){
debug(e);
}
didPrint || window.print();
});
printListener.resetPrintingFormats();
$.Events.addInitEvent(function () {
try {
var mpl = window.matchMedia("print");
mpl.addListener(updateInputValue(printListener.handleMediaChange, 250, "mediaChange"));
} catch (e) {
debug("matchMedia not available " + e);
}
});