import nl.idgis.giclient.gis.GIS; import nl.idgis.giclient.gis.CentreScale; import nl.idgis.giclient.webserviceconnector.MapConnector; import nl.idgis.giclient.gis.Layer; import nl.idgis.giclient.gui.ContainerContent; import mx.utils.Delegate; import mx.core.UIComponent; import mx.controls.TextInput; import mx.controls.CheckBox; import mx.controls.TextArea; import mx.controls.List; import mx.controls.Button; import nl.idgis.giclient.event.StateEvent; import nl.idgis.giclient.event.StateEventListener; import nl.idgis.giclient.util.Strings; import nl.idgis.giclient.framework.IDComboBox; import nl.idgis.giclient.framework.FrameWork; import nl.idgis.giclient.framework.Frame; import nl.idgis.giclient.print.PrintMovie; import nl.idgis.giclient.framework.buttons.ActionButton; import nl.idgis.giclient.framework.bars.ButtonBar; import nl.idgis.giclient.framework.buttons.ActionButtonConfig; import nl.idgis.giclient.framework.buttons.GIButton; import nl.idgis.giclient.framework.buttons.GIButtonEventListener; import nl.idgis.giclient.template.TemplateFactory; import nl.idgis.giclient.template.TemplateElement; import nl.idgis.giclient.template.TemplateMovie; import nl.idgis.giclient.template.PrintInstruction; import nl.idgis.giclient.template.Page; import nl.idgis.giclient.gis.Map; import nl.idgis.giclient.template.TemplateDesc; import nl.idgis.giclient.io.XMLServer; import nl.idgis.giclient.io.XMLResponseListener; import nl.idgis.giclient.io.XMLResponse; import nl.idgis.giclient.template.Dialog; import flash.display.BitmapData; import flash.geom.Matrix; import flash.geom.Rectangle; import nl.idgis.giclient.template.ReportRef; import nl.idgis.giclient.template.ResourceRef; import nl.idgis.giclient.util.XMLTools; import nl.idgis.giclient.GIClientConfig; import nl.idgis.giclient.framework.GIComponent; import nl.idgis.giclient.framework.SinglePaneComponent; import mx.controls.ProgressBar; import nl.idgis.giclient.gis.ActiveMapListener; /** * @author copierrj */ class nl.idgis.giclient.print.PrintDialog extends ContainerContent implements GIButtonEventListener, StateEventListener, ActiveMapListener { private var printMovie:MovieClip = null; private var templateComboBox:IDComboBox; private var templateInfo:MovieClip; private var formatTextField:TextField; private var orientationTextField:TextField; private var createButton:Button; private var printButton:Button; private var reportButton:Button; private var progressBar:ProgressBar; private var format:TextFormat = null; private var lastY:Number = 0; private var templateFactory:TemplateFactory = null; private var resourceRefs:Array; private var resourceRef:ResourceRef = null; private var tileWidth:Number = 250; private var tileHeight:Number = 250; private var contentWidth:Number = 0; private var dialogClosed:Boolean = false; private var preview:SinglePaneComponent = null; private function createDialogs() : Void { var maps:Array = ruler.getGIS().getMaps(); for(var i:Number = 0; i < maps.length; i++) { var map:Map = Map(maps[i]); var printTemplateNodes:Array = map.getPrintTemplates(); for(var j:Number = 0; j < printTemplateNodes.length; j++) { var templateDesc:TemplateDesc = templateFactory.parseTemplateDesc( XMLNode(printTemplateNodes[j])); var dialog:Dialog = templateDesc.getDialog(); drawDialog(dialog, "templateDialog_" + i + "_" + j, templateDesc, map); } var reportNodes:Array = map.getReports(); for(var j:Number = 0; j < reportNodes.length; j++) { var reportRef:ReportRef = templateFactory.parseReportRef( XMLNode(reportNodes[j])); var dialog:Dialog = reportRef.getDialog(); drawDialog(dialog, "reportDialog_" + i + "_" + j, reportRef, map); } } } private function fillResourceRefs() : Void { var map:Map = ruler.getGIS().getActiveMap(); var printTemplateNodes:Array = map.getPrintTemplates(); for(var s:String in this) { if(s.indexOf("Dialog") != -1) { if(this[s]["map"] == map) { resourceRefs.push(this[s]["resourceRef"]); } } } } function onLoad() { ruler.getGIS().gisEventDispatcher.addActiveMapListener(this); templateFactory = new TemplateFactory(ruler.getGIS(), ruler.getGIClientConfig().getLanguage()); format = new TextFormat(); format.font = "_sans"; format.size = 12; createDialogs(); resourceRefs = new Array(); fillResourceRefs(); lastY = 10; var printStrings:Strings = Strings.getFile("Print"); var templateTextField:TextField = createTextField("templateTextField", this.getNextHighestDepth(), 10, lastY, 100, 25); templateTextField.setNewTextFormat(format); templateTextField.text = printStrings.getString("Template"); templateComboBox = IDComboBox(attachMovie("IDComboBox", "templateChooser", this.getNextHighestDepth())); templateComboBox._x = 100; templateComboBox._y = lastY; templateComboBox.setEditable(true); templateComboBox.setDataProvider(resourceRefs); templateComboBox.labelFunction = function(obj:Object) { var printStrings2:Strings = Strings.getFile("Print"); return (obj instanceof ReportRef ? printStrings2.getString("Report") : printStrings.getString("Map")) + ": " + obj["title"]; }; var obj:Object = new Object(); obj.parent = this; obj.change = function(eventObject:Object) { this.parent.changeTemplate(ResourceRef(this.parent.templateComboBox.getSelectedItem())); }; templateComboBox.addEventListener("change", obj); templateComboBox.resize(); var comboWidth:Number = templateComboBox._x + templateComboBox.getWidth(); if (comboWidth > contentWidth) { contentWidth = comboWidth; } templateInfo = this.createEmptyMovieClip("templateInfo", this.getNextHighestDepth()); var formatTextFieldLabel:TextField = templateInfo.createTextField( "formatTextFieldLabel", templateInfo.getNextHighestDepth(), 0, 0, 300, 25); formatTextFieldLabel.setNewTextFormat(format); formatTextFieldLabel.text = printStrings.getString("Format"); formatTextField = templateInfo.createTextField("formatTextField", templateInfo.getNextHighestDepth(), 50, 0, 300, 25); formatTextField.setNewTextFormat(format); formatTextField.setEnabled(false); var orientationTextFieldLabel:TextField = templateInfo.createTextField( "orientationTextFieldLabel", templateInfo.getNextHighestDepth(), 90, 0, 300, 25); orientationTextFieldLabel.setNewTextFormat(format); orientationTextFieldLabel.text = printStrings.getString("Orientation"); orientationTextField = templateInfo.createTextField("orientationTextField", templateInfo.getNextHighestDepth(), 160, 0, 300, 25); orientationTextField.setNewTextFormat(format); orientationTextField.setEnabled(false); templateInfo._visible = false; templateInfo._x = 280; templateInfo._y = 10; lastY += 40; progressBar = ProgressBar(attachMovie("ProgressBar", "progressBar", getNextHighestDepth())); progressBar.label = ""; progressBar.mode = "manual"; progressBar.minimum = 0; progressBar._visible = false; if(resourceRefs.length == 1) { templateComboBox.setSelectedIndex(0); templateComboBox.enabled = false; changeTemplate(resourceRefs[0]); } frame.setSize(contentWidth + 20, 80); _parent.refreshPane(); preview = SinglePaneComponent(ruler.getGIClientConfig().getGIComponent("PrintPreview")); preview.addEventListener(this, StateEvent.CHANGE, "visible"); var thisDialog:SinglePaneComponent = SinglePaneComponent(ruler.getGIClientConfig().getGIComponent("PrintDialog")); thisDialog.addEventListener(this, StateEvent.CHANGE, "visible"); } private function checkResponse(xml:XML, expectedRoot:String) : Boolean { if(xml.firstChild.localName == expectedRoot) { return true; } else { var lang:String = ruler.getGIClientConfig().getLanguage(); if(xml.firstChild.firstChild.localName == "Message") { var message:String = XMLTools.getStringValue(lang, xml.firstChild.firstChild); if(message == null) { message = XMLTools.getStringValue("en", xml.firstChild.firstChild); } if(message != null) { FrameWork(_root["frameWork"]).message(message); } } else { // TODO: better error handling } return false; } } private function openReport():Void { var reportRef:ReportRef = ReportRef(getCurrentResourceRef()); var url:String = reportRef.getUrl(); var vars:Object = reportRef.getVars(); var loadVars:LoadVars = new LoadVars(); for(var str:String in vars) { if(vars[str] != null) { loadVars[str] = vars[str]; } } loadVars["request"] = "CreateReport"; var responseObj:Object = new Object(); responseObj.parent = this; responseObj.onHTTPStatus = function(httpStatus:Number) { trace("HTTP Status: " + httpStatus + "!!"); }; responseObj.onData = function(str:String) { var xml:XML = new XML(); xml.ignoreWhite = true; xml.parseXML(str); if(this.parent.checkResponse(xml, "Report")) { var reportUrl:String = XMLTools.getStringValue("Url", xml.firstChild); MovieClip(this.parent).getURL(reportUrl, "_blank"); } }; loadVars.contentType = "application/x-www-form-urlencoded; charset=utf-8"; loadVars.sendAndLoad(url, responseObj, "POST"); } private function loadTemplate():Void { var templateDesc:TemplateDesc = TemplateDesc(getCurrentResourceRef()); var url:String = templateDesc.getUrl(); var vars:Object = templateDesc.getVars(); var loadVars:LoadVars = new LoadVars(); for(var str:String in vars) { if(vars[str] != null) { loadVars[str] = vars[str]; } } var responseObj:Object = new Object(); responseObj.parent = this; responseObj.onHTTPStatus = function(httpStatus:Number) { trace("HTTP Status: " + httpStatus + "!!"); }; responseObj.onData = function(str:String) { var xml:XML = new XML(); xml.ignoreWhite = true; xml.parseXML(str); if(this.parent.checkResponse(xml, "PrintInstruction")) { this.parent.onLoadTemplateResponse(xml); } }; loadVars.contentType = "application/x-www-form-urlencoded; charset=utf-8"; loadVars.sendAndLoad(url, responseObj, "POST"); } private function changeTemplate(resourceRef:ResourceRef):Void { printButton.enabled = false; if(this.resourceRef != null) { var oldDialog:Dialog = this.resourceRef.getDialog(); if(oldDialog != null) { oldDialog.removeEventListener(this, StateEvent.CHANGE, "dirty"); } } this.resourceRef = resourceRef; var newDialog:Dialog = resourceRef.getDialog(); if(newDialog != null) { newDialog.addEventListener(this, StateEvent.CHANGE, "dirty"); } if(resourceRef instanceof TemplateDesc) { var templateDesc:TemplateDesc = TemplateDesc(resourceRef); formatTextField.text = templateDesc.getFormat(); orientationTextField.text = templateDesc.getOrientation(); } else { formatTextField.text = ""; orientationTextField.text = ""; } setDialog(lastY, resourceRef); } private function drawDialog(dialog:Dialog, movieClipName:String, resourceRef:ResourceRef, map:Map):Void { var dialog_mc:MovieClip = this.createEmptyMovieClip(movieClipName, this.getNextHighestDepth()); dialog_mc._visible = false; dialog_mc["resourceRef"] = resourceRef; dialog_mc["map"] = map; dialog.inflate(dialog_mc); } private function setDialog(startY:Number, resourceRef:ResourceRef):Number { var y:Number = startY; var dy:Number = 30; var templateDialog:MovieClip = null; for(var s:String in this) { if(s.indexOf("Dialog") != -1) { this[s]._visible = false; } } if(resourceRef != null) { for(var s:String in this) { if(this[s]["resourceRef"] != null) { if(ResourceRef(this[s]["resourceRef"]) == resourceRef) { templateDialog = this[s]; } } } if(resourceRef instanceof TemplateDesc) { templateInfo._visible = true; templateInfo._x = templateComboBox._x + templateComboBox.getWidth() + 10; templateInfo._y = 10; if(templateDialog != null) { if(templateDialog._width < 300) { templateInfo._x = 10; templateInfo._y = y; y += 25; } } } else { templateInfo._visible = false; } templateDialog._visible = true; templateDialog._x = 10; templateDialog._y = y; y += templateDialog._height; } var buttonsMovie:MovieClip = this["buttonsMovie"]; if(buttonsMovie == null) { buttonsMovie = this.createEmptyMovieClip("buttonsMovie", this.getNextHighestDepth()); createButton = Button(buttonsMovie.attachMovie("Button", "createButton", buttonsMovie.getNextHighestDepth(), {_visible: true, _width: 125, _x: 0, label: Strings.getFile("Print").getString("CreatePrint")})); createButton.addEventListener("click", Delegate.create(this, onClickCreateButton)); printButton = Button(buttonsMovie.attachMovie("Button", "printButton", buttonsMovie.getNextHighestDepth(), {_visible: true, _width: 125, _x: 125, label: Strings.getFile("Print").getString("PrintButtonLabel")})); printButton.addEventListener("click", Delegate.create(this, onClickPrintButton)); printButton.enabled = false; reportButton = Button(buttonsMovie.attachMovie("Button", "reportButton", buttonsMovie.getNextHighestDepth(), {_visible: false, _width: 125, _x: 0, label: "Report"})); reportButton.addEventListener("click", Delegate.create(this, onClickReportButton)); var buttonWidth:Number = printButton._x + printButton._width; if(buttonWidth > contentWidth){ contentWidth = buttonWidth; } } progressBar._x = 10; progressBar._y = y; y += dy; buttonsMovie._y = y; buttonsMovie._x = 10; y += dy; if(resourceRef == null) { reportButton._visible = false; createButton._visible = false; printButton._visible = false; } else { if(resourceRef instanceof TemplateDesc) { reportButton._visible = false; createButton._visible = true; printButton._visible = true; } else { reportButton._visible = true; createButton._visible = false; printButton._visible = false; } } var buttonsMovieWidth:Number = 200; var width:Number = 80;; var height:Number = y + 20; if(templateDialog != null) { width += templateDialog._width; if(width < buttonsMovieWidth + 80) { templateDialog._x += (buttonsMovieWidth + 80 - width) / 2; width = buttonsMovieWidth + 80; } buttonsMovie._x += (width - 80) / 2 - (buttonsMovieWidth / 2); } if(width < contentWidth + 50){ width = contentWidth + 50; } progressBar.setSize(width - 100, 20); frame.setSize(width, height); return y; } private function renderTile(renderState:Object, lastTile:Boolean) { var j:Number = renderState["j"]; var k:Number = renderState["k"]; var bitmaps:Array = renderState["bitmaps"]; var matrixScale:Number = renderState["matrixScale"]; var clip:MovieClip = renderState["clip"]; var content:MovieClip = renderState["content"]; var tileX:Number = j * tileWidth; var tileY:Number = k * tileHeight; var bitmap:BitmapData = new BitmapData(tileWidth, tileHeight, false, 0xffffff); bitmaps.push(bitmap); var matrix:Matrix = new Matrix(); matrix.scale(matrixScale, matrixScale); matrix.translate(-tileX, -tileY); bitmap.draw(clip, matrix); content.beginBitmapFill(bitmap); content.moveTo(tileX, tileY); content.lineTo(tileX + tileWidth, tileY); content.lineTo(tileX + tileWidth, tileY + tileHeight); content.lineTo(tileX, tileY + tileHeight); content.lineTo(tileX, tileY); if(lastTile) { _global["setTimeout"](this, "sendToPrinter", 1); } } private function renderPages() { var chain:Array = new Array(); for(var clipName:String in printMovie) { if(clipName.indexOf("print") != -1) { var clip:MovieClip = printMovie[clipName]; var page:Page = Page(clip["page"]); clip._xscale = 100; clip._yscale = 100; var dpi:Number = 600; if(TemplateDesc(this.getCurrentResourceRef()).getFormat() == "A3") { dpi = 300; } var matrixScale:Number = dpi / 72; var movieClipScale:Number = (72 / dpi) * 100; var width:Number = clip._width * matrixScale; var height:Number = clip._height * matrixScale; var xTiles:Number = Math.ceil(width / tileWidth); var yTiles:Number = Math.ceil(height / tileHeight); var depth:Number = _root.getNextHighestDepth(); var tmp:MovieClip = _root.createEmptyMovieClip("rasterPage" + depth, depth); var bitmaps:Array = new Array(); clip["render"] = tmp; clip["bitmaps"] = bitmaps; var content:MovieClip = tmp.createEmptyMovieClip("content", tmp.getNextHighestDepth()); content._visible = false; for(var j:Number = 0; j < xTiles; j++) { for(var k:Number = 0; k < yTiles; k++) { var renderState:Object = new Object(); renderState["bitmaps"] = bitmaps; renderState["matrixScale"] = matrixScale; renderState["clip"] = clip; renderState["content"] = content; renderState["j"] = j; renderState["k"] = k; chain.push(renderState); } } } } var obj:Object = new Object(); obj["chain"] = chain; obj["dialog"] = this; obj["progressBar"] = progressBar; obj["count"] = 0; obj["start"] = function() { _global["setTimeout"](this, "step", 1); }; obj["step"] = function() { if(this.dialog.dialogClosed) { this.progressBar._visible = false; this.dialog.printButton.enabled = this.dialog.preview.getPane() != null; this.dialog.createButton.enabled = true; return; } var command:Object = this.chain.pop(); if(this.chain.length == 0) { this.dialog.renderTile(command, true); } else { this.dialog.renderTile(command); _global["setTimeout"](this, "step", 1); } this.progressBar.setProgress(++this.count, this.progressBar.maximum); }; obj.start(); progressBar.maximum = chain.length; progressBar._visible = true; } function onClickPrintButton(event:Object):Void { printButton.enabled = false; createButton.enabled = false; renderPages(); } private function sendToPrinter():Void { progressBar._visible = false; var pages:Array = new Array(); for(var clipName:String in printMovie) { if(clipName.indexOf("print") != -1) { pages.push(printMovie[clipName]); } } var pj:PrintJob = new PrintJob(); if(pj.start()) { for(var i:Number = pages.length - 1; i >= 0; i--) { var clip:MovieClip = pages[i]; var dpi:Number = 600; if(TemplateDesc(this.getCurrentResourceRef()).getFormat() == "A3") { dpi = 300; } var matrixScale:Number = dpi / 72; var movieClipScale:Number = (72 / dpi) * 100; var width:Number = clip._width * matrixScale; var height:Number = clip._height * matrixScale; var tmp:MovieClip = clip["render"]; var bitmaps:Array = clip["bitmaps"]; var content:MovieClip = tmp["content"]; content._visible = true; var printMarginWidth:Number = pj.paperWidth - pj.pageWidth; var printMarginHeight:Number = pj.paperHeight - pj.pageHeight; var hPrintMarginWidth:Number = printMarginWidth / 2; var hPrintMarginHeight:Number = printMarginHeight / 2; var page:Page = Page(pages[i]["page"]); var xMin:Number = -(page.getLeftMargin() - hPrintMarginWidth) * matrixScale; var yMin:Number = -(page.getTopMargin() - hPrintMarginHeight) * matrixScale; var xMax:Number = width; var yMax:Number = height; if(printMarginHeight > page.getTopMargin() + page.getBottomMargin() || printMarginWidth > page.getLeftMargin() + page.getRightMargin() || hPrintMarginHeight > page.getTopMargin() || hPrintMarginHeight > page.getBottomMargin() || hPrintMarginWidth > page.getRightMargin() || hPrintMarginWidth > page.getLeftMargin() || pj.pageWidth < clip._width || pj.pageHeight < clip._height) { if(printMarginWidth > page.getTopMargin() + page.getBottomMargin() || printMarginHeight > page.getLeftMargin() + page.getRightMargin() || hPrintMarginWidth > page.getTopMargin() || hPrintMarginWidth > page.getBottomMargin() || hPrintMarginHeight > page.getRightMargin() || hPrintMarginHeight > page.getLeftMargin() || pj.pageWidth < clip._height || pj.pageHeight < clip._width) { FrameWork(_root["frameWork"]).message( Strings.getFile("Print").getString("ImageDoesNotFit") + " (" + (pages.length - i) + "/" + pages.length + ")"); } else { // Rotate rendered page content._rotation = 90; content._x = height; xMin = -(page.getBottomMargin() - hPrintMarginWidth) * matrixScale; yMin = -(page.getLeftMargin() - hPrintMarginHeight) * matrixScale; xMax = height; yMax = width; } } tmp._xscale = movieClipScale; tmp._yscale = movieClipScale; _root["frameWork"]["frames"]["printPreview"]["scrollpane_mc"]["content_mc"].setMask(null); pj.addPage(tmp, {xMin: xMin, yMin: yMin, xMax: xMax, yMax: yMax}, {printAsBitmap:false}); _root["frameWork"]["frames"]["printPreview"]["scrollpane_mc"]["content_mc"].setMask( _root["frameWork"]["frames"]["printPreview"]["scrollpane_mc"]["mask_mc"]); tmp.removeMovieClip(); for(var j = 0; j < bitmaps.length; j++) { BitmapData(bitmaps[j]).dispose(); } clip._xscale = 100 * PrintMovie.screenPrintFactor; clip._yscale = 100 * PrintMovie.screenPrintFactor; } pj.send(); } else { // Clean up for(var i:Number = pages.length - 1; i >= 0; i--) { var clip:MovieClip = pages[i]; var tmp:MovieClip = clip["render"]; var bitmaps:Array = clip["bitmaps"]; tmp.removeMovieClip(); for(var j = 0; j < bitmaps.length; j++) { BitmapData(bitmaps[j]).dispose(); } clip._xscale = 100 * PrintMovie.screenPrintFactor; clip._yscale = 100 * PrintMovie.screenPrintFactor; } } delete pj; printButton.enabled = true; createButton.enabled = true; } function onReleaseGIButton(giButton:GIButton):Void { trace("gedrukt"); } function onClickReportButton():Void { getCurrentResourceRef().execute(Delegate.create(this, openReport)); } function onClickCreateButton():Void { FrameWork(_root["frameWork"]).setBusy("print", "print"); dialogClosed = false; printButton.enabled = false; getCurrentResourceRef().execute(Delegate.create(this, loadTemplate)); } private function createPrint(printInstruction:PrintInstruction):Void { var config:GIClientConfig = ruler.getGIClientConfig(); var component:SinglePaneComponent = SinglePaneComponent(config.getGIComponent("PrintPreview")); var frame:Frame = component.showPane({}); var handler:Object = new Object(); handler.printButton = this["buttonsMovie"]["printButton"]; handler.onReady = function() { this.printButton.enabled = true; FrameWork(_root["frameWork"]).resetBusyType("print"); //trace("print ready"); }; printMovie = frame.getScrollContent(); PrintMovie(printMovie).renderPages(printInstruction.getPages(), handler); } private function getCurrentResourceRef():ResourceRef { return resourceRefs.length == 1 ? ResourceRef(resourceRefs[0]) : ResourceRef(templateComboBox.getSelectedItem()); } function onLoadTemplateResponse(templateNode:XMLNode) : Void { createPrint(templateFactory.parsePrintInstruction(templateNode.firstChild, getCurrentResourceRef().getDialog())); } function onStateEvent(stateEvent : StateEvent) : Void { if(stateEvent.getActionType() == StateEvent.CHANGE && stateEvent.getPropertyName() == "visible" && stateEvent.getSourceClassName() == "SinglePaneComponent") { if(SinglePaneComponent(stateEvent.getSource()).getPane() == null) { printButton.enabled = false; dialogClosed = true; } } else if(stateEvent.getActionType() == StateEvent.CHANGE && stateEvent.getPropertyName() == "dirty" && stateEvent.getSourceClassName() == "Dialog") { if(getCurrentResourceRef().getDialog().isDirty()) { printButton.enabled = false; } } } function beforeChangeActiveMap() : Void { } function afterChangeActiveMap() : Void { resourceRefs = new Array(); fillResourceRefs(); templateComboBox.setDataProvider(resourceRefs); templateComboBox.setSelectedIndex(-1); setDialog(lastY, null); this["templateInfo"]._visible = false; frame.setSize(contentWidth + 20, 80); _parent.refreshPane(); } }