home *** CD-ROM | disk | FTP | other *** search
Wrap
Text File | 2009-10-26 | 54.6 KB | 1,484 lines
package com.livebrush.data { import com.adobe.images.PNGEncoder; import com.livebrush.Main; import com.livebrush.events.FileEvent; import com.livebrush.graphics.canvas.Canvas; import com.livebrush.styles.DecoAsset; import com.livebrush.ui.UI; import flash.data.EncryptedLocalStore; import flash.desktop.NativeApplication; import flash.display.BitmapData; import flash.display.Loader; import flash.events.Event; import flash.events.EventDispatcher; import flash.events.IOErrorEvent; import flash.filesystem.*; import flash.net.FileFilter; import flash.net.URLLoader; import flash.net.URLLoaderDataFormat; import flash.net.URLRequest; import flash.utils.ByteArray; import flash.utils.setTimeout; import org.casalib.util.NavigateUtil; public class FileManager extends EventDispatcher { private static var singleton:FileManager; public static const PROJECT:String = "project"; public static const DECOSET:String = "decoList"; public static const STYLE:String = "style"; public static const DECO:String = "deco"; public static const LAYER_IMAGE:String = "layerImage"; public static const INPUT_SWF:String = "inputSWF"; public static const SWF:String = "SWF"; public static const SVG:String = "SVG"; public static const ONLINE_VERSION_PATH:String = "http://www.livebrush.com/version.txt"; private var _recentOpenDir:String = ""; private var _bitmapData:BitmapData; private var showVersionCheckResult:Boolean = false; private var svgData:XML; private var help:Help; public var projectStyles:XML; private var appSettings:Settings; private var _projectIsTemp:Boolean; private var _canvasSizeIndex:int = -1; public var layerData:XML; private var decoFilesLoaded:Array; private var activeFile:File; private var tempProjectDir:String; private var decoAssetsLoaded:Array; private var firstRun:Boolean; public var decoSetData:XML; public var lastFileLoaded:String; private var sessionProjectDir:String; public var styleData:XML; private var _recentSaveDir:String = ""; public function FileManager() { super(); this.help = Help.getInstance(this); } public static function removeWhiteSpace(str:String, replace:String = "-") : String { return str.split(" ").join(replace); } public static function loadAsset(path:String, listener:Function = null) : Loader { return FileManager.getInstance()._loadMedia(path,listener); } public static function getInstance() : FileManager { var instance:FileManager = null; if(singleton == null) { singleton = new FileManager(); instance = singleton; } else { instance = singleton; } return instance; } public static function loadLayerImage(path:String = "", completeListener:Function = null, errorListener:Function = null) : Loader { return loadImage(FileManager.getInstance().currentProjectDir + "/Layer Images/" + path,completeListener,errorListener); } public static function loadImage(path:String = "", completeListener:Function = null, errorListener:Function = null) : Loader { return FileManager.getInstance()._loadMedia(path,completeListener,errorListener); } public static function createNameDup(list:Array = null, name:String = null, prop:String = null) : String { var dup:int = 0; var rootName:String = name; for(var i:int = 0; i < list.length; i++) { if(prop == null) { if(list[i] == name) { dup++; } } else if(list[i][prop] == name) { dup++; } } if(dup > 0) { do { name = rootName + " (" + (dup + 1) + ")"; dup++; } while(name != createNameDup(list,name,prop)); } return name; } public static function copyFileToUnique(fromFile:File, toFile:File, dupNameSuffix:String = "") : String { var newFile:File = null; if(toFile.exists) { newFile = getUniqueFile(toFile); fromFile.copyTo(newFile,true); toFile = newFile; } else { fromFile.copyTo(toFile,true); } return toFile.name; } public static function getUniqueFile(file:File, dupNameSuffix:String = "") : File { var dirFileNames:Array = null; var list:Array = null; var i:uint = 0; var newFileName:String = file.name; if(file.exists) { dirFileNames = []; list = file.parent.getDirectoryListing(); for(i = 0; i < list.length; dirFileNames.push(FileManager.getInstance().removeExtension(list[i].name)),i++) { } newFileName = FileManager.getInstance().createFileNameDup(dirFileNames,file); } return new File(file.parent.nativePath + "/" + newFileName); } public static function get missingLayerFile() : File { return File.applicationDirectory.resolvePath("AppFiles/Assets/Layer Images/missingLayer.jpg"); } public static function checkForUpdates(showResult:Boolean = false) : void { getInstance().showVersionCheckResult = showResult; FileManager.getInstance().checkVersionOnline(); } public static function getURL(s:String) : void { NavigateUtil.openUrl(s); } private function openDecoListener(e:Event) : void { this.activeFile.removeEventListener(Event.SELECT,this.openDecoListener); this.importDeco(File(e.target).nativePath,this.initDecoImportListener); } public function exportImage(file:File) : void { if(file.extension != null) { file = file.resolvePath(this.removeExtension(file.nativePath)); } file = new File(file.nativePath + ".png"); try { this.writeImage(this._bitmapData,file); } catch(e:Error) { UI.MAIN_UI.alert({ "message":"Error Saving: Out of memory.\nPlease close any other applications and try again.", "id":"saveImageError" }); } finally { this._bitmapData.dispose(); } } private function saveStyleListener(e:Event) : void { e.target.removeEventListener(Event.SELECT,this.saveStyleListener); this.exportStyle(e.target as File); } public function importStyle(path:String = "", dispatch:Boolean = true) : String { var styleData:String = null; var styleXML:XML = null; var decoChild:String = null; var inputSWFFile:File = null; var decoPath:String = null; var sourceDecoFile:File = null; var assetLoaded:String = null; this.lastFileLoaded = STYLE; styleData = this.loadXML(path); styleXML = new XML(styleData); var decoSetXML:XML = new XML(<decoList></decoList>); if(styleXML.name() != STYLE) { dispatchEvent(new FileEvent(FileEvent.WRONG_FILE,true,false,FileEvent.OPEN,STYLE,styleXML.name())); } else { if(styleXML.line.inputSWF.length() > 0 && styleXML.line.inputSWF.toString() != "" && styleXML.line.inputSWF.toString() != "null") { inputSWFFile = new File().resolvePath(new File(path).parent.nativePath + "/Assets/" + styleXML.line.inputSWF); styleXML.line.inputSWF = this.importInputSWF(inputSWFFile.nativePath,null,false); } for(decoChild in styleXML.deco.decoList.deco) { decoPath = styleXML.deco.decoList.deco[decoChild].@value; sourceDecoFile = new File(); sourceDecoFile = sourceDecoFile.resolvePath(new File(path).parent.nativePath + "/Assets/" + decoPath); assetLoaded = this.importDeco(sourceDecoFile.nativePath); if(assetLoaded != FileEvent.FILE_NOT_FOUND) { decoSetXML.appendChild(<deco value={assetLoaded}></deco>); } } styleXML.deco.decoList = decoSetXML; if(dispatch) { dispatchEvent(new FileEvent(FileEvent.IO_EVENT,true,false,FileEvent.OPEN,STYLE,styleXML.toString())); } } return styleXML; } private function get currentProjectDir() : String { return this.sessionProjectDir; } public function importDecoSet(path:String = "", listener:Function = null) : void { var decoSetData:String = null; var decoSetXML:XML = null; var decoChild:String = null; var decoPath:String = null; var sourceDecoFile:File = null; this.lastFileLoaded = DECOSET; decoSetData = this.loadXML(path); decoSetXML = new XML(decoSetData); if(decoSetXML.name() != DECOSET) { dispatchEvent(new FileEvent(FileEvent.WRONG_FILE,true,false,FileEvent.OPEN,DECOSET,decoSetXML.name())); } else { for(decoChild in decoSetXML.deco) { decoPath = decoSetXML.deco[decoChild].@value; sourceDecoFile = new File(new File(path).parent.nativePath + "/Assets/" + decoPath); this.importDeco(sourceDecoFile.nativePath,listener); } } } private function saveDecoSetListener(e:Event) : void { e.target.removeEventListener(Event.SELECT,this.saveDecoSetListener); this.exportDecoSet(e.target as File); } private function initOpenFile(path:String, title:String, listener:Function, fileFilters:Array) : void { if(path != "") { this.activeFile = new File(path).parent; } else { this.activeFile = new File(this._recentOpenDir == "" ? this.getRecentProjectPath() : this._recentOpenDir).parent; } this.activeFile.browseForOpen(title,fileFilters); this.activeFile.addEventListener(Event.SELECT,this.setRecentOpenDir); this.activeFile.addEventListener(Event.SELECT,listener); } public function openDeco(path:String = null) : void { path = path == null ? this.openRecentProjectDir : path; this.initOpenFile(path,"Import Decoration",this.openDecoListener,[new FileFilter("All Formats (*.jpg,*.gif,*.png,*.swf)","*.jpg;*.gif;*.png;*.swf","JPEG;jp2_;GIFF;SWFL")]); } public function removeExtension(fileName:String) : String { return fileName.substring(0,fileName.lastIndexOf(".")); } public function importInputSWF(path:String = "", listener:Function = null, dispatch:Boolean = true) : String { var newFile:* = undefined; var fileName:String = null; var swfFile:File = new File(path); var newName:String = swfFile.name; if(swfFile.exists) { newFile = new File(this.currentProjectDir + "/Styles/Assets/" + swfFile.name); fileName = copyFileToUnique(swfFile,newFile); newFile = new File(this.currentProjectDir + "/Styles/Assets/" + fileName); newName = newFile.name; this.decoAssetsLoaded.push({ "fileName":newName, "asset":null }); if(dispatch) { dispatchEvent(new FileEvent(FileEvent.IO_EVENT,true,false,FileEvent.OPEN,INPUT_SWF,newFile)); } return newName; } return ""; } private function _loadMedia(path:String, completeListener:Function = null, errorListener:Function = null) : Loader { var file:File = new File(path); var loader:Loader = new Loader(); if(completeListener != null) { loader.contentLoaderInfo.addEventListener(Event.COMPLETE,completeListener); } if(errorListener != null) { loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,errorListener); } if(file.exists) { try { loader.load(new URLRequest(file.url)); } catch(error:Error) { } return loader; } loader.load(new URLRequest(file.url)); return loader; } public function decoLoader(fileName:String) : Loader { this.decoFilesLoaded.push(fileName); return this._loadMedia(this.currentProjectDir + "/Styles/Assets/" + fileName); } private function exportDecoSet(file:File, createDirectory:Boolean = true) : File { var decoDestFile:File; var decoSourceFile:File = null; var decoChild:String = null; if(createDirectory) { if(file.extension != null) { file = file.resolvePath(this.removeExtension(file.nativePath)); } file.createDirectory(); file = new File(file.nativePath + "/" + file.name); if(!file.extension || file.extension.toLowerCase() != "xml") { file.nativePath += ".xml"; } } decoDestFile = new File(file.parent.nativePath + "/Assets/" + file.name); for(decoChild in this.decoSetData.deco) { decoSourceFile = new File(this.currentProjectDir + "/Styles/Assets/" + this.decoSetData.deco[decoChild].@value); decoDestFile = new File(file.parent.nativePath + "/Assets/" + decoSourceFile.name); try { decoSourceFile.copyTo(decoDestFile); } catch(e:Error) { } } if(createDirectory) { this.save(file,this.decoSetData); } return decoDestFile.parent; } private function checkVersionOnline() : void { var versionLoader:URLLoader = new URLLoader(); versionLoader.dataFormat = URLLoaderDataFormat.VARIABLES; versionLoader.addEventListener(Event.COMPLETE,this.versionCheckComplete); versionLoader.load(new URLRequest(ONLINE_VERSION_PATH)); } private function exportSVG(file:File) : void { if(!file.extension || file.extension.toLowerCase() != "xml") { file.nativePath += ".svg"; } this.save(file,this.svgData); } public function deleteSessionProject() : void { var sessionDir:File = new File(this.sessionProjectDir); if(sessionDir.exists) { sessionDir.deleteDirectory(true); } this.saveLocalString("sessionProjectDir","deleted"); } public function saveDecoSet(decoSet:XML) : void { this.decoSetData = decoSet; this.initSaveFile("Export Decoration Set",this.saveDecoSetListener); } private function writeProject(file:File) : void { var recentProjectFile:File = null; var newProjectFile:File = null; var projectXML:XML = null; var style:String = null; var styleFile:File = null; try { if(file.extension != null) { file = file.resolvePath(this.removeExtension(file.nativePath)); } file.createDirectory(); recentProjectFile = new File(this.recentProject); newProjectFile = recentProjectFile.name != file.name + ".lbp" ? this.renameFile(new File(this.currentProject),file.name + ".lbp") : new File(this.currentProject); projectXML = new XML(<LiveBrushProject size={Canvas.SIZE_INDEX} width={Canvas.WIDTH} height={Canvas.HEIGHT} name={file.name} version="1"></LiveBrushProject>); projectXML.appendChild(<styles></styles>); projectXML.appendChild(this.layerData); for(style in this.projectStyles.style) { styleFile = new File(this.currentProjectDir).resolvePath(this.currentProjectDir + "/Styles/" + this.projectStyles.style[style].@name + ".xml"); this.save(styleFile,this.projectStyles.style[style].toString()); projectXML.styles.appendChild(<style xml={styleFile.name}/>); } this.save(newProjectFile,projectXML.toString()); new File(this.currentProjectDir).copyTo(file,true); this.setProject(file.resolvePath(file.name + ".lbp")); this.deleteTempProject(); dispatchEvent(new FileEvent(FileEvent.SAVE,true,false,FileEvent.PROJECT_SAVED,PROJECT)); } catch(error:Error) { writeProjectBackup(); dispatchEvent(new FileEvent(FileEvent.IO_ERROR,true,false,FileEvent.SAVE,PROJECT)); } UI.setStatus("Ready"); } public function saveStyle(style:XML) : void { this.styleData = style; this.initSaveFile("Export Style",this.saveStyleListener); } private function checkValidSavePath(e:Event) : void { var file:File = e.target as File; var projectDir:File = new File(this.recentProjectDir); var layersDir:File = new File(this.recentProjectDir + "/Layer Images"); var stylesDir:File = new File(this.recentProjectDir + "/Styles"); var styleAssetsDir:File = new File(this.recentProjectDir + "/Styles/Assets"); if(file.parent.nativePath == projectDir.nativePath || file.parent.nativePath == layersDir.nativePath || file.parent.nativePath == stylesDir.nativePath || file.parent.nativePath == styleAssetsDir.nativePath) { e.stopImmediatePropagation(); UI.MAIN_UI.alert({ "message":"Save Location Error\nYou can\'t save to a project folder (or its subfolders). Please save to another location.", "id":"saveLocationAlert" }); } else { this._recentOpenDir = e.target.nativePath; } } private function get recentProject() : String { return this.loadLocalString("recentProject"); } private function compareVersion(s:String = null) : String { var storedVersion:String = null; var pointVersion:Array = null; var pointStoredVersion:Array = null; var version:String = "newer"; if(s == null) { storedVersion = this.loadLocalString("version"); } else { storedVersion = s; } if(storedVersion != null) { pointVersion = this.appSettings.version.split("."); pointStoredVersion = storedVersion.split("."); if(pointVersion[0] > pointStoredVersion[0]) { version = "newMajor"; } else if(pointVersion[0] == pointStoredVersion[0]) { if(pointVersion[1] > pointStoredVersion[1]) { version = "newer"; } else if(pointVersion[1] == pointStoredVersion[1]) { if(pointVersion[2] > pointStoredVersion[2]) { version = "newer"; } else if(pointVersion[2] == pointStoredVersion[2]) { version = "current"; } else { version = "older"; } } else { version = "older"; } } else { version = "older"; } } return version; } private function openProjectListener(e:Event) : void { dispatchEvent(new FileEvent(FileEvent.IO_EVENT,true,false,FileEvent.CLOSE,PROJECT)); this.activeFile.removeEventListener(Event.SELECT,this.openProjectListener); this.loadProject(File(e.target).nativePath); } public function loadHelp() : XML { return new XML(this.open(this.helpFile)); } private function openLayerImageListener(e:Event) : void { this.activeFile.removeEventListener(Event.SELECT,this.openLayerImageListener); var fileName:String = copyFileToUnique(this.activeFile,new File(this.layerImagesDir + "/" + this.activeFile.name)); var type:String = this.activeFile.extension.toUpperCase(); type = type.indexOf("SWF") > -1 ? SWF : LAYER_IMAGE; dispatchEvent(new FileEvent(FileEvent.IO_EVENT,true,false,FileEvent.OPEN,type,fileName)); } private function open(file:File) : String { var stream:FileStream = new FileStream(); stream.open(file,FileMode.READ); var fileData:String = stream.readUTFBytes(stream.bytesAvailable); stream.close(); return fileData; } public function get projectName() : String { return this.removeExtension(new File(this.loadLocalString("recentProject")).name); } private function createSessionProjectDir() : void { this.sessionProjectDir = this.loadLocalString("sessionProjectDir"); if(this.sessionProjectDir != "deleted" && this.sessionProjectDir != null) { this.cleanup(); } this.saveLocalString("sessionProjectDir",File.createTempDirectory().nativePath); this.sessionProjectDir = this.loadLocalString("sessionProjectDir"); } private function loadXML(path:String) : String { var file:File = new File(path); var fileData:String = "no file: " + path; if(file.exists) { fileData = this.open(file); } return fileData; } public function loadProject(path:String) : String { var layerData:String = null; var styleChild:String = null; var stylePath:String = null; var styleFile:File = null; var styleData:String = null; dispatchEvent(new FileEvent(FileEvent.BEGIN_LOAD,true,false,FileEvent.OPEN,PROJECT)); this.lastFileLoaded = PROJECT; this.decoFilesLoaded = []; this.decoAssetsLoaded = []; var projectFile:File = new File(path); this.setProject(projectFile); this.createSessionProjectDir(); new File(this.recentProjectDir).copyTo(new File(this.sessionProjectDir),true); layerData = this.loadXML(path); var projectXML:XML = new XML(layerData); if(this._canvasSizeIndex != -1) { projectXML.@size = this._canvasSizeIndex; this._canvasSizeIndex = -1; } for(styleChild in projectXML.styles.style) { stylePath = projectXML.styles.style[styleChild].@xml; styleFile = new File(this.currentProjectDir + "/Styles/" + stylePath); if(styleFile.exists) { styleData = this.loadStyle(styleFile.nativePath); } } layerData = projectXML.toXMLString(); dispatchEvent(new FileEvent(FileEvent.IO_EVENT,true,false,FileEvent.OPEN,PROJECT,layerData)); return layerData; } private function setProject(file:File) : void { this.saveLocalString("recentProject",file.nativePath); } public function newProject(sizeIndex:int = 2) : void { this._canvasSizeIndex = sizeIndex; this.cleanup(); this.createBaseProject(); this.loadProject(this.getRecentProjectPath()); } private function get helpFile() : File { return File.applicationDirectory.resolvePath("AppFiles/Help.xml"); } public function loadInputSWF(fileName:String, completeListener:Function = null, errorListener:Function = null) : Loader { return this._loadMedia(this.currentProjectDir + "/Styles/Assets/" + fileName,completeListener,errorListener); } public function get projectFileName() : String { return this.projectName + ".lbp"; } private function openStyleListener(e:Event) : void { this.activeFile.removeEventListener(Event.SELECT,this.openStyleListener); this.importStyle(File(e.target).nativePath); } private function get currentProject() : String { return this.sessionProjectDir + "/" + this.projectName + ".lbp"; } private function versionCheckComplete(e:Event) : void { var currentMajorVersion:int = int(e.target.data.currentMajorVersion); var version:String = String(e.target.data["version" + Main.MAJOR_VERSION]); var vString:String = this.compareVersion(version); if(vString == "older") { dispatchEvent(new FileEvent(FileEvent.VERSION_UPDATE,false,false,null,FileEvent.UPDATE_VERSION,{ "currentVersion":this.appSettings.version, "newVersion":version })); } else if(vString == "current") { if(currentMajorVersion > Main.MAJOR_VERSION) { dispatchEvent(new FileEvent(FileEvent.VERSION_UPDATE,false,false,null,FileEvent.NEW_VERSION,{ "currentVersion":Main.MAJOR_VERSION, "newVersion":currentMajorVersion })); } else if(this.showVersionCheckResult) { dispatchEvent(new FileEvent(FileEvent.VERSION_UPDATE,false,false,null,FileEvent.CURRENT_VERSION,{ "currentVersion":this.appSettings.version, "newVersion":version })); } } else if(vString == "newer") { } this.showVersionCheckResult = false; } public function copyAppFiles() : void { this.appFiles.copyTo(File.applicationStorageDirectory,true); } private function createBaseProject() : void { var baseProjectDir:File = new File(); baseProjectDir.nativePath = File.applicationStorageDirectory.nativePath + "/Presets/BaseProject"; var newProjectDir:File = this.createTempProjectDir(); baseProjectDir.copyTo(newProjectDir,true); var baseProjectFile:File = newProjectDir.resolvePath("BaseProject.lbp"); var newProjectFile:* = newProjectDir.resolvePath("New Project.lbp"); baseProjectFile.moveTo(newProjectFile); this.setProject(newProjectFile); } public function openProject(path:String = "") : void { if(this.projectIsTemp) { path = File.desktopDirectory.nativePath; } else { path = new File(this.getRecentProjectPath()).parent.nativePath; } this.initOpenFile(path,"Open A LiveBrush Project",this.openProjectListener,[new FileFilter("LiveBrush Project (*.lbp)","*.lbp;")]); } public function loadStyle(path:String = "", dispatch:Boolean = true) : String { var styleData:String = null; var styleXML:XML = null; var checkStyleXML:XML = null; var decoChild:String = null; var decoPath:String = null; if(new File(path).exists) { this.lastFileLoaded = STYLE; styleData = this.loadXML(path); styleXML = new XML(styleData); checkStyleXML = new XML(styleData); for(decoChild in styleXML.deco.decoList.deco) { decoPath = styleXML.deco.decoList.deco[decoChild].@value; } styleXML = checkStyleXML; if(dispatch) { dispatchEvent(new FileEvent(FileEvent.IO_EVENT,true,false,FileEvent.OPEN,STYLE,styleXML.toString())); } return styleXML.toString(); } dispatchEvent(new FileEvent(FileEvent.FILE_NOT_FOUND,true,false,FileEvent.OPEN,STYLE,"Styles/" + new File(path).name)); return FileEvent.FILE_NOT_FOUND; } public function openLayerImage(path:String = null) : void { path = path == null ? this.openRecentProjectDir : path; this.initOpenFile(path,"Import Layer Image",this.openLayerImageListener,[new FileFilter("All Formats (*.jpg,*.gif,*.png,*.swf)","*.jpg;*.gif;*.png;*.swf;","JPEG;jp2_;GIFF;")]); } private function exportStyle(file:File, createDirectory:Boolean = true) : void { var styleAssetDir:File = null; if(createDirectory) { if(file.extension != null) { file = file.resolvePath(this.removeExtension(file.nativePath)); } file.createDirectory(); file = new File(file.nativePath + "/" + file.name); if(!file.extension || file.extension.toLowerCase() != "xml") { file.nativePath += ".xml"; } } this.decoSetData = XML(this.styleData.deco.decoList); if(createDirectory) { styleAssetDir = this.exportDecoSet(file.parent); } else { styleAssetDir = this.exportDecoSet(file,false); } if(this.styleData.line.inputSWF.length() > 0 && this.styleData.line.inputSWF.toString() != "" && this.styleData.line.inputSWF.toString() != "null") { this.exportDynamicInput(styleAssetDir,this.styleData.line.inputSWF); } this.save(file,this.styleData); } private function saveSVGListener(e:Event) : void { e.target.removeEventListener(Event.SELECT,this.saveSVGListener); this.exportSVG(e.target as File); } private function save(file:File, data:String) : void { data = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + data; var stream:FileStream = new FileStream(); stream.open(file,FileMode.WRITE); stream.writeUTFBytes(data); stream.close(); } public function copyDecoToLayer(path:String, batch:Boolean = false) : void { var decoFile:File = new File(this.decoAssetsDir + "/" + path); var fileName:String = copyFileToUnique(decoFile,new File(this.layerImagesDir + "/" + decoFile.name)); var type:String = decoFile.extension.toUpperCase(); type = type.indexOf("SWF") > -1 ? SWF : LAYER_IMAGE; dispatchEvent(new FileEvent(FileEvent.IO_EVENT,true,false,batch ? FileEvent.BATCH_OPEN : FileEvent.OPEN,type,fileName)); } public function openStyle(path:String = null) : void { path = path == null ? this.openRecentProjectDir : path; this.initOpenFile(path,"Import Style",this.openStyleListener,[new FileFilter("LiveBrush Style (*.xml)","*.xml;")]); } private function importProjectListener(e:Event) : void { this.activeFile.removeEventListener(Event.SELECT,this.importProjectListener); this._importProject(File(e.target).nativePath); } public function getExtension(fileName:String) : String { return fileName.substr(fileName.lastIndexOf(".")); } public function saveAsProject(layerXML:XML, stylesXML:XML) : void { this.layerData = layerXML; this.projectStyles = stylesXML; this.initSaveFile("Save As Project",this.saveProjectListener); } public function getDecoAsset(path:String, enabled:Boolean = true, forceNew:Boolean = false) : DecoAsset { var i:int = 0; var decoAsset:DecoAsset = null; if(this.decoAssetsLoaded.length == 0 || forceNew) { decoAsset = new DecoAsset(path); decoAsset.enabled = enabled; this.decoAssetsLoaded.push({ "fileName":path, "asset":decoAsset }); } else { for(i = 0; i < this.decoAssetsLoaded.length; i++) { if(this.decoAssetsLoaded[i].fileName == path) { decoAsset = this.decoAssetsLoaded[i].asset; break; } } if(decoAsset == null) { decoAsset = new DecoAsset(path); decoAsset.enabled = enabled; this.decoAssetsLoaded.push({ "fileName":path, "asset":decoAsset }); } } return decoAsset; } private function get recentProjectDir() : String { return new File(this.loadLocalString("recentProject")).parent.nativePath; } public function revertProject() : void { if(!this.projectIsTemp) { dispatchEvent(new FileEvent(FileEvent.IO_EVENT,true,false,FileEvent.CLOSE,PROJECT)); this.loadProject(this.recentProject); } } private function loadLocalString(label:String) : String { var storedValue:ByteArray = EncryptedLocalStore.getItem(label); if(storedValue != null) { return storedValue.readUTFBytes(storedValue.length); } return null; } public function get projectIsTemp() : Boolean { return this._projectIsTemp; } public function loadAppSettings() : void { var settingsXML:XML = NativeApplication.nativeApplication.applicationDescriptor; var ns:Namespace = settingsXML.namespace(); this.appSettings = new Settings(); this.appSettings.version = settingsXML.ns::version; this.getGlobalSettings(); } private function exportDynamicInput(file:File, inputFileName:String) : void { try { new File(this.currentProjectDir + "/Styles/Assets/" + inputFileName).copyTo(new File(file.nativePath + "/" + inputFileName)); } catch(e:Error) { } } private function writeProjectBackup() : File { var desktopProject:File = null; var dup:int = 0; do { desktopProject = File.desktopDirectory.resolvePath(this.projectName + " Backup " + (dup + 1)); dup++; } while(desktopProject.exists); desktopProject.createDirectory(); new File(this.currentProjectDir).copyTo(desktopProject,true); return desktopProject; } private function get layerImagesDir() : String { return this.sessionProjectDir + "/Layer Images"; } private function saveLocalString(label:String, data:String) : void { var bytes:ByteArray = new ByteArray(); bytes.writeUTFBytes(data); EncryptedLocalStore.setItem(label,bytes); } public function saveSVG(svg:XML) : void { this.svgData = svg; this.initSaveFile("Export SVG",this.saveSVGListener); } public function cleanup() : void { this.deleteSessionProject(); this.deleteTempProject(); } private function saveProjectListener(e:Event) : void { e.target.removeEventListener(Event.SELECT,this.saveProjectListener); UI.setStatus("Saving Project..."); setTimeout(this.writeProject,25,e.target as File); } private function get lbUserDocsDir() : File { return File.documentsDirectory.resolvePath("LiveBrush"); } private function saveImageListener(e:Event) : void { e.target.removeEventListener(Event.SELECT,this.saveImageListener); this.exportImage(e.target as File); } public function loadDeco(path:String = "", listener:Function = null) : String { var loader:Loader = null; var decoFile:File = new File(path); if(decoFile.exists) { loader = this._loadMedia(decoFile.nativePath); if(listener != null) { loader.contentLoaderInfo.addEventListener(Event.INIT,listener); } return decoFile.name; } dispatchEvent(new FileEvent(FileEvent.FILE_NOT_FOUND,true,false,FileEvent.OPEN,DECO,"Assets/" + decoFile.name)); return FileEvent.FILE_NOT_FOUND; } public function importProject(path:String = "") : void { path = new File(this.getRecentProjectPath()).parent.nativePath; this.initOpenFile(path,"Import A LiveBrush Project",this.importProjectListener,[new FileFilter("LiveBrush Project (*.lbp)","*.lbp;")]); } private function openDecoSetListener(e:Event) : void { this.activeFile.removeEventListener(Event.SELECT,this.openDecoSetListener); this.importDecoSet(File(e.target).nativePath,this.initDecoImportListener); } private function deleteLocalString(label:String) : void { EncryptedLocalStore.removeItem(label); } private function setRecentSaveDir(e:Event) : void { this.activeFile.removeEventListener(Event.SELECT,this.setRecentSaveDir); this._recentSaveDir = e.target.nativePath; } private function _importProject(path:String) : String { var layerData:String = null; var layer:String = null; var styleChild:String = null; var layerType:String = null; var layerFile:File = null; var newFile:File = null; var fileName:String = null; var stylePath:String = null; var styleFile:File = null; var styleData:String = null; this.lastFileLoaded = PROJECT; var projectFile:File = new File(path); layerData = this.loadXML(path); var projectXML:XML = new XML(layerData); for(layer in projectXML.layers.layer) { layerType = projectXML.layers.layer[layer].@type; if(layerType == "image" || layerType == "swf") { layerFile = new File(projectFile.parent.nativePath + "/Layer Images/" + projectXML.layers.layer[layer].solid.@src); newFile = new File(this.currentProjectDir + "/Layer Images/" + layerFile.name); if(layerFile.exists) { fileName = copyFileToUnique(layerFile,newFile); newFile = new File(this.currentProjectDir + "/Layer Images/" + fileName); } projectXML.layers.layer[layer].solid.@src = newFile.name; projectXML.layers.layer[layer].@label = newFile.name; } } layerData = projectXML.toXMLString(); for(styleChild in projectXML.styles.style) { stylePath = projectXML.styles.style[styleChild].@xml; styleFile = new File(projectFile.parent.nativePath + "/Styles/" + stylePath); if(styleFile.exists) { styleData = this.importStyle(styleFile.nativePath); } } dispatchEvent(new FileEvent(FileEvent.IO_EVENT,true,false,FileEvent.IMPORT,PROJECT,layerData)); return layerData; } private function initDecoImportListener(e:Event) : void { e.target.removeEventListener(Event.INIT,this.initDecoImportListener); dispatchEvent(new FileEvent(FileEvent.IO_EVENT,true,false,FileEvent.OPEN,DECO,e.target)); } public function openInputSWF(path:String = null) : void { path = this.appFiles.nativePath + "/Presets/Behaviors/SmoothRandom-AS3-F9.swf"; try { this.initOpenFile(path,"Import Flash Player 9 (ActionScript 3) File",this.importInputSWFListener,[new FileFilter("Flash Player 9 SWF (*.swf)","*.swf;")]); } catch(e:Error) { copyAppFiles(); initOpenFile(path,"Import Flash Player 9 (ActionScript 3) File",importInputSWFListener,[new FileFilter("Flash Player 9 SWF (*.swf)","*.swf;")]); } } public function saveGlobalSettings() : void { this.saveLocalString("TEMP_CACHE_LAYERS",String(GlobalSettings.TEMP_CACHE_LAYERS)); this.saveLocalString("CACHE_DECOS",String(GlobalSettings.CACHE_DECOS)); this.saveLocalString("CACHE_DELAY",String(GlobalSettings.CACHE_DELAY)); this.saveLocalString("CACHE_REALTIME",String(GlobalSettings.CACHE_REALTIME)); this.saveLocalString("FIRST_SAVE",String(GlobalSettings.FIRST_SAVE)); this.saveLocalString("FIRST_DECOSET_EXPORT",String(GlobalSettings.FIRST_DECOSET_EXPORT)); this.saveLocalString("FIRST_STYLE_EXPORT",String(GlobalSettings.FIRST_STYLE_EXPORT)); this.saveLocalString("CHECK_FOR_UPDATES",String(GlobalSettings.CHECK_FOR_UPDATES)); this.saveLocalString("REGISTERED_EMAIL",String(GlobalSettings.REGISTERED_EMAIL)); this.saveLocalString("SHOW_BUSY_WARNINGS",String(GlobalSettings.SHOW_BUSY_WARNINGS)); this.saveLocalString("DRAW_MODE",String(GlobalSettings.DRAW_MODE)); this.saveLocalString("STROKE_BUFFER",String(GlobalSettings.STROKE_BUFFER)); } private function createTempProjectDir() : File { var tempDir:File = File.createTempDirectory(); this.saveLocalString("tempProjectDir",tempDir.nativePath); this.tempProjectDir = this.loadLocalString("tempProjectDir"); this._projectIsTemp = true; return tempDir; } private function exportProject(file:File) : void { var style:String = null; var layer:String = null; var styleFile:File = null; var layerType:String = null; var layerFile:File = null; var newFile:File = null; var fileName:String = null; var newProjectFile:File = file; var projectXML:XML = new XML(<LiveBrushProject size={Canvas.SIZE_INDEX} width={Canvas.WIDTH} height={Canvas.HEIGHT} name={file.name} date="08/03/82" version="1"></LiveBrushProject>); projectXML.appendChild(<styles></styles>); projectXML.appendChild(this.layerData); for(style in this.projectStyles.style) { styleFile = new File(this.currentProjectDir).resolvePath(this.currentProjectDir + "/Styles/" + this.projectStyles.style[style].@name + ".xml"); this.styleData = this.projectStyles.style[style]; this.exportStyle(new File(file.parent.nativePath + "/Styles/" + styleFile.name),false); projectXML.styles.appendChild(<style xml={styleFile.name}/>); } this.save(newProjectFile,projectXML.toString()); new File(file.parent.nativePath + "/Layer Images").createDirectory(); new File(file.parent.nativePath + "/Styles").createDirectory(); new File(file.parent.nativePath + "/Styles/Assets").createDirectory(); for(layer in projectXML.layers.layer) { layerType = projectXML.layers.layer[layer].@type; if(layerType == "image" || layerType == "swf") { layerFile = new File(this.currentProjectDir + "/Layer Images/" + projectXML.layers.layer[layer].solid.@src); newFile = new File(file.parent.nativePath + "/Layer Images/" + layerFile.name); if(layerFile.exists) { try { fileName = copyFileToUnique(layerFile,newFile); } catch(e:Error) { } continue; } } } } private function setRecentOpenDir(e:Event) : void { this.activeFile.removeEventListener(Event.SELECT,this.setRecentOpenDir); this._recentOpenDir = e.target.nativePath; } private function initSaveFile(title:String, listener:Function) : void { this.activeFile = this._recentSaveDir == "" ? File.desktopDirectory : new File(this._recentSaveDir).parent; this.activeFile.browseForSave(title); this.activeFile.addEventListener(Event.SELECT,this.checkValidSavePath); this.activeFile.addEventListener(Event.SELECT,listener); } public function openDecoSet(path:String = null) : void { path = path == null ? this.openRecentProjectDir : path; this.initOpenFile(path,"Import Decoration Set",this.openDecoSetListener,[new FileFilter("LiveBrush DecoSet (*.xml)","*.xml;")]); } public function getRecentProjectPath() : String { if(this.recentProject == null) { this.createBaseProject(); } else if(!new File(this.recentProject).exists) { this.createBaseProject(); } return this.recentProject; } public function saveFlattenedLayerImage(bmp:BitmapData, name:String, unique:Boolean = true) : String { var file:File = new File(this.layerImagesDir + "/" + name + ".png"); if(unique) { file = getUniqueFile(file); } this.writeImage(bmp,file); bmp.dispose(); return file.name; } public function copyLayerToDeco(path:String) : String { var layerFile:File = new File(this.layerImagesDir + "/" + path); return copyFileToUnique(layerFile,new File(this.decoAssetsDir + "/" + layerFile.name)); } public function cleanupProject(layerXML:XML, stylesXML:XML) : void { var projectDir:File; var projectBackup:File; var tempDir:File = File.createTempDirectory(); this.layerData = layerXML; this.projectStyles = stylesXML; this.exportProject(new File(tempDir.nativePath + "/" + this.projectFileName)); projectDir = new File(this.recentProjectDir); projectBackup = this.writeProjectBackup(); try { projectDir.deleteDirectory(true); projectDir.createDirectory(); tempDir.copyTo(projectDir,true); tempDir.deleteDirectory(true); } catch(e:Error) { UI.MAIN_UI.showErrorDialog({"message":"CLEANUP ERROR\nProject assets open or in-use by another application.\nA backup has been saved to your desktop."}); } this.revertProject(); try { projectBackup.deleteDirectory(true); } catch(e:Error) { } } private function get appFiles() : File { return File.applicationDirectory.resolvePath("AppFiles"); } private function get openRecentProjectDir() : String { return this.projectIsTemp ? File.documentsDirectory.nativePath : new File(this.loadLocalString("recentProject")).parent.nativePath; } private function renameFile(file:File, newName:String) : File { var newFile:File = file.resolvePath("../" + newName); file.moveTo(newFile,true); return newFile; } public function saveProject(layerXML:XML, stylesXML:XML) : void { if(this.projectIsTemp) { this.saveAsProject(layerXML,stylesXML); } else { this.layerData = layerXML; this.projectStyles = stylesXML; UI.setStatus("Saving Project..."); setTimeout(this.writeProject,25,new File(this.recentProjectDir)); } } private function get decoAssetsDir() : String { return this.sessionProjectDir + "/Styles/Assets"; } public function checkFirstRun() : void { var versionType:String; this.firstRun = !File.applicationStorageDirectory.exists; versionType = this.compareVersion(); if(this.firstRun) { this.copyAppFiles(); this.saveLocalString("version",this.appSettings.version); setTimeout(UI.MAIN_UI.confirmActionDialog,20000,{ "message":"Would like to automatically check for updates?\nYou can change this setting at any time.", "yesFunction":function():* { GlobalSettings.CHECK_FOR_UPDATES = true; checkForUpdates(); }, "noFunction":function():* { GlobalSettings.CHECK_FOR_UPDATES = false; } }); } else if(!this.firstRun && versionType == "newer") { this.copyAppFiles(); this.saveLocalString("version",this.appSettings.version); if(GlobalSettings.CHECK_FOR_UPDATES) { setTimeout(checkForUpdates,20000); } } else if(!this.firstRun && versionType == "current") { if(GlobalSettings.CHECK_FOR_UPDATES) { setTimeout(checkForUpdates,20000); } } else if(!(!this.firstRun && versionType == "older")) { if(versionType == "newMajor") { if(GlobalSettings.CHECK_FOR_UPDATES) { setTimeout(checkForUpdates,20000); } } } } public function saveImage(bmp:BitmapData) : void { this._bitmapData = bmp; this.initSaveFile("Save Image",this.saveImageListener); } private function writeImage(bmp:BitmapData, file:File) : void { var png:* = PNGEncoder.encode(bmp); var stream:FileStream = new FileStream(); stream.open(file,FileMode.WRITE); stream.writeBytes(png,0,0); stream.close(); } private function getGlobalSettings() : void { GlobalSettings.setProperty("CACHE_LAYERS",this.loadLocalString("TEMP_CACHE_LAYERS")); GlobalSettings.setProperty("CACHE_DECOS",this.loadLocalString("CACHE_DECOS")); GlobalSettings.setProperty("CACHE_DELAY",this.loadLocalString("CACHE_DELAY")); GlobalSettings.setProperty("CACHE_REALTIME",this.loadLocalString("CACHE_REALTIME")); GlobalSettings.setProperty("FIRST_SAVE",this.loadLocalString("FIRST_SAVE")); GlobalSettings.setProperty("FIRST_DECOSET_EXPORT",this.loadLocalString("FIRST_DECOSET_EXPORT")); GlobalSettings.setProperty("FIRST_STYLE_EXPORT",this.loadLocalString("FIRST_STYLE_EXPORT")); GlobalSettings.setProperty("CHECK_FOR_UPDATES",this.loadLocalString("CHECK_FOR_UPDATES")); GlobalSettings.setProperty("REGISTERED_EMAIL",this.loadLocalString("REGISTERED_EMAIL")); GlobalSettings.setProperty("SHOW_BUSY_WARNINGS",this.loadLocalString("SHOW_BUSY_WARNINGS")); GlobalSettings.setProperty("DRAW_MODE",this.loadLocalString("DRAW_MODE")); GlobalSettings.setProperty("STROKE_BUFFER",this.loadLocalString("STROKE_BUFFER")); } private function importInputSWFListener(e:Event) : void { e.target.removeEventListener(Event.INIT,this.importInputSWFListener); this.importInputSWF(File(e.target).nativePath); } public function importDeco(path:String = "", listener:Function = null) : String { var newFile:* = undefined; var fileName:String = null; this.lastFileLoaded = DECO; var decoFile:File = new File(path); if(decoFile.exists) { newFile = new File(this.currentProjectDir + "/Styles/Assets/" + decoFile.name); fileName = copyFileToUnique(decoFile,newFile); newFile = new File(this.currentProjectDir + "/Styles/Assets/" + fileName); this.loadDeco(newFile.nativePath,listener); return newFile.name; } return this.loadDeco(decoFile.nativePath); } public function createFileNameDup(list:Array, file:File, prop:String = null) : String { return createNameDup(list,this.removeExtension(file.name),prop) + this.getExtension(file.name); } public function deleteTempProject() : void { var tempDir:File = null; this.tempProjectDir = this.loadLocalString("tempProjectDir"); this._projectIsTemp = false; if(this.tempProjectDir != "deleted" && this.tempProjectDir != null) { tempDir = new File(this.tempProjectDir); if(tempDir.exists) { tempDir.deleteDirectory(true); } this.saveLocalString("tempProjectDir","deleted"); } } } }