OpenSencillo  2016.106
Long live the simplicity of PHP
 All Data Structures Namespaces Files Functions Pages
ZeroClipboardPdf.as
1 /* Compile using: mxmlc --target-player=10.0.0 -static-link-runtime-shared-libraries=true -library-path+=lib ZeroClipboardPdf.as */
2 package {
3  import flash.display.Stage;
4  import flash.display.Sprite;
5  import flash.display.LoaderInfo;
6  import flash.display.StageScaleMode;
7  import flash.events.*;
8  import flash.display.StageAlign;
9  import flash.display.StageScaleMode;
10  import flash.external.ExternalInterface;
11  import flash.system.Security;
12  import flash.utils.*;
13  import flash.system.System;
14  import flash.net.FileReference;
15  import flash.net.FileFilter;
16 
17  /* PDF imports */
18  import org.alivepdf.pdf.PDF;
19  import org.alivepdf.data.Grid;
20  import org.alivepdf.data.GridColumn;
21  import org.alivepdf.layout.Orientation;
22  import org.alivepdf.layout.Size;
23  import org.alivepdf.layout.Unit;
24  import org.alivepdf.display.Display;
25  import org.alivepdf.saving.Method;
26  import org.alivepdf.fonts.FontFamily;
27  import org.alivepdf.fonts.Style;
28  import org.alivepdf.fonts.CoreFont;
29  import org.alivepdf.colors.RGBColor;
30 
31  public class ZeroClipboard extends Sprite {
32 
33  private var domId:String = '';
34  private var button:Sprite;
35  private var clipText:String = 'blank';
36  private var fileName:String = '';
37  private var action:String = 'copy';
38  private var incBom:Boolean = true;
39  private var charSet:String = 'utf8';
40 
41 
42  public function ZeroClipboard() {
43  // constructor, setup event listeners and external interfaces
44  stage.scaleMode = StageScaleMode.EXACT_FIT;
45  flash.system.Security.allowDomain("*");
46 
47  // import flashvars
48  var flashvars:Object = LoaderInfo( this.root.loaderInfo ).parameters;
49  domId = flashvars.id.split("\\").join("\\\\");
50 
51  // Validate id to prevent scripting attacks. The id given is an integer
52  if ( domId !== parseInt( domId, 10 ).toString() ) {
53  throw new Error( 'Invalid DOM id' );
54  }
55 
56  // invisible button covers entire stage
57  button = new Sprite();
58  button.buttonMode = true;
59  button.useHandCursor = true;
60  button.graphics.beginFill(0x00FF00);
61  button.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
62  button.alpha = 0.0;
63  addChild(button);
64 
65  button.addEventListener(MouseEvent.CLICK, function(event:Event):void {
66  clickHandler(event);
67  } );
68  button.addEventListener(MouseEvent.MOUSE_OVER, function(event:Event):void {
69  ExternalInterface.call( 'ZeroClipboard_TableTools.dispatch', domId, 'mouseOver', null );
70  } );
71  button.addEventListener(MouseEvent.MOUSE_OUT, function(event:Event):void {
72  ExternalInterface.call( 'ZeroClipboard_TableTools.dispatch', domId, 'mouseOut', null );
73  } );
74  button.addEventListener(MouseEvent.MOUSE_DOWN, function(event:Event):void {
75  ExternalInterface.call( 'ZeroClipboard_TableTools.dispatch', domId, 'mouseDown', null );
76  } );
77  button.addEventListener(MouseEvent.MOUSE_UP, function(event:Event):void {
78  ExternalInterface.call( 'ZeroClipboard_TableTools.dispatch', domId, 'mouseUp', null );
79  } );
80 
81  // External functions - readd whenever the stage is made active for IE
82  addCallbacks();
83  stage.addEventListener(Event.ACTIVATE, addCallbacks);
84 
85  // signal to the browser that we are ready
86  ExternalInterface.call( 'ZeroClipboard_TableTools.dispatch', domId, 'load', null );
87  }
88 
89  public function addCallbacks (evt:Event = null):void {
90  ExternalInterface.addCallback("setHandCursor", setHandCursor);
91  ExternalInterface.addCallback("clearText", clearText);
92  ExternalInterface.addCallback("setText", setText);
93  ExternalInterface.addCallback("appendText", appendText);
94  ExternalInterface.addCallback("setFileName", setFileName);
95  ExternalInterface.addCallback("setAction", setAction);
96  ExternalInterface.addCallback("setCharSet", setCharSet);
97  ExternalInterface.addCallback("setBomInc", setBomInc);
98  }
99 
100 
101  public function setCharSet(newCharSet:String):void {
102  if ( newCharSet == 'UTF16LE' ) {
103  charSet = newCharSet;
104  } else {
105  charSet = 'UTF8';
106  }
107  }
108 
109  public function setBomInc(newBomInc:Boolean):void {
110  incBom = newBomInc;
111  }
112 
113  public function clearText():void {
114  clipText = '';
115  }
116 
117  public function appendText(newText:String):void {
118  clipText += newText;
119  }
120 
121  public function setText(newText:String):void {
122  clipText = newText;
123  }
124 
125  public function setFileName(newFileName:String):void {
126  fileName = newFileName;
127  }
128 
129  public function setAction(newAction:String):void {
130  action = newAction;
131  }
132 
133  public function setHandCursor(enabled:Boolean):void {
134  // control whether the hand cursor is shown on rollover (true)
135  // or the default arrow cursor (false)
136  button.useHandCursor = enabled;
137  }
138 
139 
140  private function clickHandler(event:Event):void {
141  var fileRef:FileReference = new FileReference();
142  fileRef.addEventListener(Event.COMPLETE, saveComplete);
143 
144  if ( action == "save" ) {
145  /* Save as a file */
146  if ( charSet == 'UTF16LE' ) {
147  fileRef.save( strToUTF16LE(clipText), fileName );
148  } else {
149  fileRef.save( strToUTF8(clipText), fileName );
150  }
151  } else if ( action == "pdf" ) {
152  /* Save as a PDF */
153  var pdf:PDF = configPdf();
154  fileRef.save( pdf.save( Method.LOCAL ), fileName );
155  } else {
156  /* Copy the text to the clipboard. Note charset and BOM have no effect here */
157  System.setClipboard( clipText );
158  ExternalInterface.call( 'ZeroClipboard_TableTools.dispatch', domId, 'complete', clipText );
159  }
160  }
161 
162 
163  private function saveComplete(event:Event):void {
164  ExternalInterface.call( 'ZeroClipboard_TableTools.dispatch', domId, 'complete', clipText );
165  }
166 
167 
168  private function getProp( prop:String, opts:Array ):String
169  {
170  var i:int, iLen:int;
171  for ( i=0, iLen=opts.length ; i<iLen ; i++ )
172  {
173  if ( opts[i].indexOf( prop+":" ) != -1 )
174  {
175  return opts[i].replace( prop+":", "" );
176  }
177  }
178  return "";
179  }
180 
181 
182  private function configPdf():PDF
183  {
184  var
185  pdf:PDF,
186  i:int, iLen:int,
187  splitText:Array = clipText.split("--/TableToolsOpts--\n"),
188  opts:Array = splitText[0].split("\n"),
189  dataIn:Array = splitText[1].split("\n"),
190  aColRatio:Array = getProp( 'colWidth', opts ).split('\t'),
191  title:String = getProp( 'title', opts ),
192  message:String = getProp( 'message', opts ),
193  orientation:String = getProp( 'orientation', opts ),
194  size:String = getProp( 'size', opts ),
195  iPageWidth:int = 0,
196  dataOut:Array = [],
197  columns:Array = [],
198  headers:Array,
199  y:int = 0;
200 
201  /* Create the PDF */
202  pdf = new PDF( Orientation[orientation.toUpperCase()], Unit.MM, Size[size.toUpperCase()] );
203  pdf.setDisplayMode( Display.FULL_WIDTH );
204  pdf.addPage();
205  iPageWidth = pdf.getCurrentPage().w-20;
206  pdf.textStyle( new RGBColor(0), 1 );
207 
208  /* Add the title / message if there is one */
209  pdf.setFont( new CoreFont(FontFamily.HELVETICA), 14 );
210  if ( title != "" )
211  {
212  pdf.writeText(11, title+"\n");
213  }
214 
215  pdf.setFont( new CoreFont(FontFamily.HELVETICA), 11 );
216  if ( message != "" )
217  {
218  pdf.writeText(11, message+"\n");
219  }
220 
221  /* Data setup. Split up the headers, and then construct the columns */
222  for ( i=0, iLen=dataIn.length ; i<iLen ; i++ )
223  {
224  if ( dataIn[i] != "" )
225  {
226  dataOut.push( dataIn[i].split("\t") );
227  }
228  }
229  headers = dataOut.shift();
230 
231  for ( i=0, iLen=headers.length ; i<iLen ; i++ )
232  {
233  columns.push( new GridColumn( " \n"+headers[i]+"\n ", i.toString(), aColRatio[i]*iPageWidth, 'C' ) );
234  }
235 
236  var grid:Grid = new Grid(
237  dataOut, /* 1. data */
238  iPageWidth, /* 2. width */
239  100, /* 3. height */
240  new RGBColor (0xE0E0E0), /* 4. headerColor */
241  new RGBColor (0xFFFFFF), /* 5. backgroundColor */
242  true, /* 6. alternateRowColor */
243  new RGBColor ( 0x0 ), /* 7. borderColor */
244  .1, /* 8. border alpha */
245  null, /* 9. joins */
246  columns /* 10. columns */
247  );
248 
249  pdf.addGrid( grid, 0, y );
250  return pdf;
251  }
252 
253 
254  /*
255  * Function: strToUTF8
256  * Purpose: Convert a string to the output utf-8
257  * Returns: ByteArray
258  * Inputs: String
259  */
260  private function strToUTF8( str:String ):ByteArray {
261  var utf8:ByteArray = new ByteArray();
262 
263  /* BOM first */
264  if ( incBom ) {
265  utf8.writeByte( 0xEF );
266  utf8.writeByte( 0xBB );
267  utf8.writeByte( 0xBF );
268  }
269  utf8.writeUTFBytes( str );
270 
271  return utf8;
272  }
273 
274 
275  /*
276  * Function: strToUTF16LE
277  * Purpose: Convert a string to the output utf-16
278  * Returns: ByteArray
279  * Inputs: String
280  * Notes: The fact that this function is needed is a little annoying. Basically, strings in
281  * AS3 are UTF-16 (with surrogate pairs and everything), but characters which take up less
282  * than 8 bytes appear to be stored as only 8 bytes. This function effective adds the
283  * padding required, and the BOM
284  */
285  private function strToUTF16LE( str:String ):ByteArray {
286  var utf16:ByteArray = new ByteArray();
287  var iChar:uint;
288  var i:uint=0, iLen:uint = str.length;
289 
290  /* BOM first */
291  if ( incBom ) {
292  utf16.writeByte( 0xFF );
293  utf16.writeByte( 0xFE );
294  }
295 
296  while ( i < iLen ) {
297  iChar = str.charCodeAt(i);
298 
299  if ( iChar < 0xFF ) {
300  /* one byte char */
301  utf16.writeByte( iChar );
302  utf16.writeByte( 0 );
303  } else {
304  /* two byte char */
305  utf16.writeByte( iChar & 0x00FF );
306  utf16.writeByte( iChar >> 8 );
307  }
308 
309  i++;
310  }
311 
312  return utf16;
313  }
314  }
315 }