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