/** * @author Apolo Pena * @version 1.0.1 * @description singleton class controls print functionality */ import com.vitesselearning.coursedesign.engine.*; import com.vitesselearning.coursedesign.debug.*; import com.vitesselearning.coursedesign.utilities.Timeout; import com.vitesselearning.coursedesign.utilities.GlobalText; import com.vitesselearning.coursedesign.utilities.StringUtility; import com.vitesselearning.coursedesign.engine.coursemodel.TierNode; class com.vitesselearning.coursedesign.engine.printing.VLPrintManager { // name of class for debugging private static var CLASSNAME:String = "VLPrintManager"; // name of package for debugging private static var CLASSPACKAGE:String = "com.vitesselearning.coursedesign.engine.glossary.VLPrintManager"; // version of class for debugging private static var CLASSVERSION:String = "1.0.1"; //singleton reference toVLPrintManager private static var instance:VLPrintManager; // a reference to the one and only VLCourse public var course:VLCourse; // a reference to the current PrintJob private var printJob:PrintJob; // the print_mc in the interface.fla private var printMc:MovieClip; // the text to print, passed in from the page private var bodyCopy:String; // the amount of time (in miliseconds) to wait for the fta fields in the printMc to populate private var printDelay:Number = 500; // singleton style constructor private function VLPrintManager (course:VLCourse) { this.course = course; } /** * singleton method * @param course a reference to VLCourse, you only need to do this if you are instantiating VLPrint manager for the first time * @return reference to single instance of VLPrintManager */ public static function getInstance (course:VLCourse):VLPrintManager { if (VLPrintManager.instance == null) { VLPrintManager.instance = new VLPrintManager (course); } return VLPrintManager.instance; } /** * returns boolean true or false depending on if there is suposed to a Print Certificate or not * * @param none * @return Boolean true or false depending on if there is suposed to a Print Certificate or not */ public function hasCertificate():Boolean { return course.hasCertificate(); } /** * print the certifiacte * @param none * @return true on success, false on failure */ public function printCertificate (mc:MovieClip):Boolean { var printCert_mc:MovieClip = course.userInterface.timeline.printCert_mc; // handle fatalities if (printCert_mc == undefined) { Debugger.trace (" FATAL PRINT ERROR-->VLPrintManager.printCertificate() Failed. The printCert_mc movieclip is either not present or not in the right place in the interface.fla", 0); return false; } printCert_mc.courseTitle = course.title; Debugger.trace("VLPrintManager.printCertificate()-->course.userName="+course.userName); printCert_mc.userName = parseUserName(course.userName); printCert_mc.completionDate = parseCompletionDate(course.completionDate); // having issues with the printed content not showing up? increase the printDelay variable in the class property declarations if the target machines are pathtically slow - Apolo Timeout.doTimeout (mx.utils.Delegate.create(this, doPrintCertificate), printDelay); return true; } /** * private, handles the print certificate functionality * @param none * @return true on success false on failure */ private function doPrintCertificate():Boolean { var pageCount:Number = 0; printJob = new PrintJob (); // all PrintJob.start() and addPage() calls must be error handled var isSuccessfulStart:Boolean = printJob.start (); if (isSuccessfulStart) { var isSuccessfulAdd:Boolean = printJob.addPage (course.userInterface.timeline.printCert_mc, undefined, {printAsBitmap:true}); if (isSuccessfulAdd) { pageCount++; } else { Debugger.trace (" FATAL PRINT ERROR-->VLPrintManager.doPrintCertificate() was unable to add the movieclip: "+course.userInterface.timeline.printCert_mc+" to the PrintJob for the print certificate.: "+pageCount, 0); delete printJob; return false; } } else { // inform the user of a canceled print job? For right now no... delete printJob; return false; } if (pageCount > 0) { printJob.send(); } delete printJob; return true; } /** * called from the page, prints whatever string it is passed and dynamically paginates * @param bodyCopy the content to print * @param moduleCopy OPTIONAL: send this parameter if you want specific content for the module information in the header. Aux pages must send their page title to adhear to standards. * @param canPrintBlankPage OPTIONAL boolean true=a fatal error will NOT be thrown if the print_mc contains no content. set this value to true when pritning from input field like in the study notes page */ public function printPage (bodyCopy:String, moduleCopy:String, canPrintBlankPage:Boolean):Void { this.bodyCopy = bodyCopy; // prompt the user, this takes awhile to show up, dunno why. course.userInterface.showLoader(); // populate the print_mc with content, sending the optional pageTitle argument is needed if (moduleCopy == undefined) { initPage (); } else { initPage (moduleCopy); } if (canPrintBlankPage) { // having issues with the printed content not showing up? increaDe the delay variable in the class property declarations if the target machines are pathtically slow - Apolo Timeout.doTimeout (mx.utils.Delegate.create(this, doPrint), printDelay, canPrintBlankPage); } else { // having issues with the printed content not showing up? increaDe the delay variable in the class property declarations if the target machines are pathtically slow - Apolo Timeout.doTimeout (mx.utils.Delegate.create(this, doPrint), printDelay); } } /** * populates the print_mc with content, pops a fatal error window if the course code doesn't end in double digits 9this is standard) * @param moduleCopy alternate content to show in place of the module infomationi n the header, aux pages must send this data to printPage to adhear to standards. * @return boolean true upon success, boolean false if failed */ private function initPage (moduleCopy:String):Boolean { printMc = course.userInterface.timeline.print_mc; // prep the content var modTier:TierNode = course.getModule (course.courseModel.currentNode); var modTitle:String = modTier.title; var modNum:Number = modTier.location[1]; var modLabel:String = GlobalText.getGlobalLabel ("module_label"); var courseLabel:String = GlobalText.getGlobalLabel ("course_label"); var courseNumSlice:String = course.courseId.slice(course.courseId.length - 2, course.courseId.length); var courseNum:Number = parseInt(courseNumSlice); // error handle, course codes must end in double digits if (isNaN(courseNum)) { Debugger.trace (" FATAL PRINT ERROR-->VLPrintManager.iniPage() Failed. The course code in the course.doc must end in double digits!", 0); return false; } // strip

tags courseLabel = StringUtility.replace(courseLabel, '

', ''); courseLabel = StringUtility.replace(courseLabel, '

', ''); modLabel = StringUtility.replace(modLabel, '

', ''); modLabel = StringUtility.replace(modLabel, '

', ''); if (moduleCopy == undefined) { var headerText:String = courseLabel+" "+courseNum+": "+course.title+"
"+modLabel+" "+modNum+": "+modTitle; } else { var headerText:String = courseLabel+" "+courseNum+": "+course.title+"
"+moduleCopy; } // populate printMc.header_mc.display_ta.setText (headerText, "printHeader"); printMc.body_mc.display_ta.setText (bodyCopy); printMc.footer_mc.display_ta.setText (GlobalText.getGlobalAlert ("footer_print_text"), "printFooter"); return true; } /** * private, handles the print functionality * @param canPrintBlankPage OPTIONAL boolean as to if a fatal error should be thrown when the print_mc contains no content, only pages printing from input fields should have to set this value to true * @return true on success false on failure */ private function doPrint (canPrintBlankPage:Boolean):Boolean { // BEGIN: reset scroll property var field = printMc.body_mc.display_ta.getTextField(); if (field.scroll > 1) { field.scroll = 1; } // END: reset scroll property // hide the user prompt course.userInterface.hideLoader(); var pageTotal = getPageTotal(); Debugger.trace("doPrint.pageTotal="+pageTotal); // BEGIN: error handling if (printMc.body_mc == undefined) { Debugger.trace ("FATAL PRINT ERROR-->VLPrintManager.doPrint() FAILED. The body_mc movieclip of the print_mc was not found. Aborting the process.", 0); } if (!printMc.body_mc.display_ta.hasContent () && !canPrintBlankPage) { Debugger.trace ("FATAL PRINT ERROR-->VLPrintManager.doPrint() FAILED. The VLTextArea in body_mc movieclip of the print_mc has no content. The culprit may be initPage().", 0); } // END: error handling // BEGIN: print routine var pageCount:Number = 0; printJob = new PrintJob (); // all PrintJob.start() and addPage() calls must be error handled var isSuccessfulStart:Boolean = printJob.start (); for (var i = 1; i <= pageTotal; i++) { if (isSuccessfulStart) { // set the page count label in the footer printMc.footer_mc.pageLabel_ta.setText("page "+i+ " of "+pageTotal, "printFooter"); var isSuccessfulAdd:Boolean = printJob.addPage (printMc, undefined, {printAsBitmap:true}); if (pageTotal > 1) { var field = printMc.body_mc.display_ta.getTextField(); field.scroll += field.bottomScroll; } if (isSuccessfulAdd) { pageCount++; } else { Debugger.trace (" FATAL PRINT ERROR-->VLPrintManager.doPrint() was unable to add the movieclip: "+printMc+" to the PrintJob for page: "+pageCount, 0); return false; } } else { //Debugger.trace ("Print Job Canceled", 0); return false; } } // if all is well spool up the printer if (pageCount>0) { printJob.send (); } delete printJob; return true; // END: print routine } /** * private, determines the total number of pages to print * @param none * @return the total number of pages that will be printed */ private function getPageTotal ():Number { var field = printMc.body_mc.display_ta.getTextField(); // determine a single page if (field.maxscroll == 1) { return 1; } var totalLines:Number = field.bottomScroll + field.maxscroll; var _return:Number = Math.ceil(totalLines / field.bottomScroll); return _return; } /** * private, parses a date object into a string with the following format: dd/mm/yyyy * @param date a date object * @return string version of the date using the following format: dd/mm/yyyy */ private function parseCompletionDate (date:Date):String { return (date.getMonth() + 1) + '/' + date.getDate() + '/' + date.getFullYear(); } /** * private, parses a SCORM standard return string for username, assumes argument string will be in the following format lastName, FirstName. If the data is not in the proper format then it is not parsed * @param none * @return a string in the following format: first name space last name */ private function parseUserName (userNameFromLms:String):String { // assume SCORM standards will always return lastName, FirstName if it doesnt then dont parse the return if (userNameFromLms.indexOf(',') == -1) { return userNameFromLms; } else { var chunks:Array = userNameFromLms.split(','); return chunks[1] + " " + chunks[0]; } } }