123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484 |
- package hide.view;
- typedef ExtensionOptions = {
- ?icon : String,
- ?createNew : String,
- };
- typedef ExtensionDesc = {
- var component : String;
- var extensions : Array<String>;
- var options : ExtensionOptions;
- }
- class FileTree extends FileView {
- var tree : hide.comp.IconTree<String>;
- var ignorePatterns : Array<EReg> = [];
- public function new(state) {
- super(state);
- var exclPatterns : Array<String> = ide.currentConfig.get("filetree.excludes", []);
- for(pat in exclPatterns)
- ignorePatterns.push(new EReg(pat, "i"));
- if( state.path == null ) {
- ide.chooseDirectory(function(dir) {
- if( dir == null ) {
- close();
- return;
- }
- state.path = dir.split("\\").join("/")+"/";
- saveState();
- rebuild();
- },true);
- }
- keys.register("search", function() tree.openFilter());
- }
- override function canSave() {
- return false;
- }
- static function getExtension( file : String ) {
- var ext = new haxe.io.Path(file).ext;
- if( ext == null ) return null;
- ext = ext.toLowerCase();
- if( ext == "json" ) {
- try {
- var obj : Dynamic = haxe.Json.parse(sys.io.File.getContent(file));
- if( obj.type != null && Std.is(obj.type, String) ) {
- var e = EXTENSIONS.get("json." + obj.type);
- if( e != null ) return e;
- }
- } catch( e : Dynamic ) {
- }
- }
- return EXTENSIONS.get(ext);
- }
- override function getTitle() {
- if( state.path == "" )
- return "Resources";
- if( state.path == null )
- return "";
- return super.getTitle();
- }
- override function onFileChanged(wasDeleted:Bool, rebuildView:Bool = true) {
- }
- override function onDisplay() {
- if( state.path == null ) return;
- var panel = new Element("<div class='hide-scroll'>").appendTo(element);
- tree = new hide.comp.IconTree(null,panel);
- tree.async = true;
- tree.allowRename = true;
- tree.saveDisplayKey = saveDisplayKey;
- tree.element.addClass("small");
- tree.get = function(path) {
- if( path == null ) path = "";
- var basePath = getFilePath(path);
- var content = new Array<hide.comp.IconTree.IconTreeItem<String>>();
- for( c in sys.FileSystem.readDirectory(basePath) ) {
- var fullPath = basePath + "/" + c;
- if( isIgnored(fullPath) ) continue;
- var isDir = sys.FileSystem.isDirectory(fullPath);
- var ext = getExtension(fullPath);
- var id = ( path == "" ? c : path+"/"+c );
- content.push({
- value : id,
- text : c,
- icon : "ico ico-" + (isDir ? "folder" : (ext != null && ext.options.icon != null ? ext.options.icon : "file-text")),
- children : isDir,
- });
- }
- watch(basePath, function() rebuild(),{checkDelete:true});
- content.sort(function(a,b) { if( a.children != b.children ) return a.children?-1:1; return Reflect.compare(a.text,b.text); });
- return content;
- };
- tree.onRename = onRename;
- element.contextmenu(function(e) {
- var current = tree.getCurrentOver();
- if( current != null )
- tree.setSelection([current]);
- e.preventDefault();
- var allowedNew : Array<String> = config.get("filetree.allowednew");
- function allowed( ext : String ) return allowedNew.indexOf(ext) >= 0 || allowedNew.indexOf("*") >= 0;
- var newMenu = [for( e in EXTENSIONS ) if( e.options.createNew != null && Lambda.exists(e.extensions, allowed) ) {
- label : e.options.createNew,
- click : createNew.bind(current, e),
- icon : e.options.icon,
- }];
- if( allowed("dir") )
- newMenu.unshift({
- label : "Directory",
- click : createNew.bind(current, { options : { createNew : "Directory" }, extensions : null, component : null }),
- icon : "folder",
- });
- new hide.comp.ContextMenu([
- { label : "New..", menu:newMenu },
- { label : "", isSeparator: true },
- { label : "Explore", enabled : current != null, click : function() { onExploreFile(current); } },
- { label : "Copy Path", enabled : current != null, click : function() { ide.setClipboard(current); } },
- { label : "", isSeparator: true },
- { label : "Clone", enabled : current != null, click : function() {
- try {
- if (onCloneFile(current)) {
- tree.refresh();
- }
- } catch (e : Dynamic) {
- js.Browser.window.alert(e);
- }
- } },
- { label : "Rename", enabled : current != null, click : function() {
- try {
- onRenameFile(current);
- } catch (e : Dynamic) {
- js.Browser.window.alert(e);
- }
- } },
- { label : "Move", enabled : current != null, click : function() {
- ide.chooseDirectory(function(dir) {
- onRename(current, "/"+dir+"/"+current.split("/").pop());
- });
- }},
- { label : "Delete", enabled : current != null, click : function() {
- if( js.Browser.window.confirm("Delete " + current + "?") ) {
- onDeleteFile(current);
- tree.refresh();
- }
- }},
- ]);
- });
- tree.onDblClick = onOpenFile;
- tree.init();
- }
- function onRenameFile( path : String ) {
- var newFilename = ide.ask("New name:", path.substring( path.lastIndexOf("/") + 1 ));
- while ( newFilename != null && sys.FileSystem.exists(ide.getPath(newFilename))) {
- newFilename = ide.ask("This file already exists. Another new name:");
- }
- if (newFilename == null) {
- return false;
- }
- onRename(path, newFilename);
- return true;
- }
- function onRename(path:String, name:String) {
- var parts = path.split("/");
- parts.pop();
- for( n in name.split("/") ) {
- if( n == ".." )
- parts.pop();
- else
- parts.push(n);
- }
- var newPath = name.charAt(0) == "/" ? name.substr(1) : parts.join("/");
- if( newPath == path )
- return false;
- if( sys.FileSystem.exists(ide.getPath(newPath)) ) {
- function addPath(path:String,rand:String) {
- var p = path.split(".");
- if( p.length > 1 )
- p[p.length-2] += rand;
- else
- p[p.length-1] += rand;
- return p.join(".");
- }
- if( path.toLowerCase() == newPath.toLowerCase() ) {
- // case change
- var rand = "__tmp"+Std.random(10000);
- onRename(path, "/"+addPath(path,rand));
- onRename(addPath(path,rand), name);
- } else {
- if( !ide.confirm(newPath+" already exists, invert files?") )
- return false;
- var rand = "__tmp"+Std.random(10000);
- onRename(path, "/"+addPath(path,rand));
- onRename(newPath, "/"+path);
- onRename(addPath(path,rand), name);
- }
- return false;
- }
- var isDir = sys.FileSystem.isDirectory(ide.getPath(path));
- var wasRenamed = false;
- var isSVNRepo = sys.FileSystem.exists(ide.projectDir+"/.svn") || js.node.ChildProcess.spawnSync("svn",["info"], { cwd : ide.resourceDir }).status == 0; // handle not root dirs
- if( isSVNRepo ) {
- if( js.node.ChildProcess.spawnSync("svn",["--version"]).status != 0 ) {
- if( isDir && !ide.confirm("Renaming a SVN directory, but 'svn' system command was not found. Continue ?") )
- return false;
- } else {
- var cwd = Sys.getCwd();
- Sys.setCwd(ide.resourceDir);
- var code = Sys.command("svn",["rename",path,newPath]);
- Sys.setCwd(cwd);
- if( code == 0 )
- wasRenamed = true;
- else {
- if( !ide.confirm("SVN rename failure, perform file rename ?") )
- return false;
- }
- }
- }
- if( !wasRenamed )
- sys.FileSystem.rename(ide.getPath(path), ide.getPath(newPath));
- var changed = false;
- function filter(p:String) {
- if( p == null )
- return null;
- if( p == path ) {
- changed = true;
- return newPath;
- }
- if( p == "/"+path ) {
- changed = true;
- return "/"+newPath;
- }
- if( isDir ) {
- if( StringTools.startsWith(p,path+"/") ) {
- changed = true;
- return newPath + p.substr(path.length);
- }
- if( StringTools.startsWith(p,"/"+path+"/") ) {
- changed = true;
- return "/"+newPath + p.substr(path.length+1);
- }
- }
- return p;
- }
- ide.filterPrefabs(function(p:hrt.prefab.Prefab) {
- changed = false;
- p.source = filter(p.source);
- var h = p.getHideProps();
- if( h.onResourceRenamed != null )
- h.onResourceRenamed(filter);
- else {
- var visited = new Array<Dynamic>();
- function browseRec(obj:Dynamic) : Dynamic {
- switch( Type.typeof(obj) ) {
- case TObject:
- if( visited.indexOf(obj) >= 0 ) return null;
- visited.push(obj);
- for( f in Reflect.fields(obj) ) {
- var v : Dynamic = Reflect.field(obj, f);
- v = browseRec(v);
- if( v != null ) Reflect.setField(obj, f, v);
- }
- case TClass(Array):
- if( visited.indexOf(obj) >= 0 ) return null;
- visited.push(obj);
- var arr : Array<Dynamic> = obj;
- for( i in 0...arr.length ) {
- var v : Dynamic = arr[i];
- v = browseRec(v);
- if( v != null ) arr[i] = v;
- }
- case TClass(String):
- return filter(obj);
- default:
- }
- return null;
- }
- for( f in Reflect.fields(p) ) {
- var v = browseRec(Reflect.field(p,f));
- if( v != null ) Reflect.setField(p,f,v);
- }
- }
- return changed;
- });
- changed = false;
- var tmpSheets = [];
- for( sheet in ide.database.sheets ) {
- if( sheet.props.dataFiles != null && sheet.lines == null ) {
- // we already updated prefabs, no need to load data files
- tmpSheets.push(sheet);
- @:privateAccess sheet.sheet.lines = [];
- }
- for( c in sheet.columns ) {
- switch( c.type ) {
- case TFile:
- for( o in sheet.getLines() ) {
- var v : Dynamic = filter(Reflect.field(o, c.name));
- if( v != null ) Reflect.setField(o, c.name, v);
- }
- default:
- }
- }
- }
- if( changed ) {
- ide.saveDatabase();
- hide.comp.cdb.Editor.refreshAll(true);
- }
- for( sheet in tmpSheets )
- @:privateAccess sheet.sheet.lines = null;
- var dataDir = new haxe.io.Path(path);
- if( dataDir.ext != "dat" ) {
- dataDir.ext = "dat";
- var dataPath = dataDir.toString();
- if( sys.FileSystem.isDirectory(ide.getPath(dataPath)) ) {
- var destPath = new haxe.io.Path(name);
- destPath.ext = "dat";
- onRename(dataPath, destPath.toString());
- }
- }
- return true;
- }
- public static function exploreFile(path : String) {
- var fullPath = sys.FileSystem.absolutePath(path);
- Sys.command("explorer.exe /select," + fullPath);
- }
- function onExploreFile( path : String ) {
- exploreFile(getFilePath(path));
- }
- function onCloneFile( path : String ) {
- var sourcePath = getFilePath(path);
- var nameNewFile = ide.ask("New filename:", new haxe.io.Path(sourcePath).file);
- if (nameNewFile == null || nameNewFile.length == 0) {
- return false;
- }
- var targetPath = new haxe.io.Path(sourcePath).dir + "/" + nameNewFile;
- if ( sys.FileSystem.exists(targetPath) ) {
- throw "File already exists";
- }
- if( sys.FileSystem.isDirectory(sourcePath) ) {
- sys.FileSystem.createDirectory(targetPath + "/");
- for( f in sys.FileSystem.readDirectory(sourcePath) ) {
- sys.io.File.saveBytes(targetPath + "/" + f, sys.io.File.getBytes(sourcePath + "/" + f));
- }
- } else {
- var extensionNewFile = getExtension(targetPath);
- if (extensionNewFile == null) {
- var extensionSourceFile = getExtension(sourcePath).extensions[0];
- if (extensionSourceFile != null) {
- targetPath = targetPath + "." + extensionSourceFile;
- }
- }
- sys.io.File.saveBytes(targetPath, sys.io.File.getBytes(sourcePath));
- }
- return true;
- }
- function onDeleteFile( path : String ) {
- var fullPath = getFilePath(path);
- if( sys.FileSystem.isDirectory(fullPath) ) {
- for( f in sys.FileSystem.readDirectory(fullPath) )
- onDeleteFile(path + "/" + f);
- sys.FileSystem.deleteDirectory(fullPath);
- } else
- sys.FileSystem.deleteFile(fullPath);
- }
- function getFilePath(path:String) {
- if( path == "" )
- return ide.getPath(state.path).substr(0, -1);
- return ide.getPath(state.path) + path;
- }
- function onOpenFile( path : String ) {
- var fullPath = getFilePath(path);
- if( sys.FileSystem.isDirectory(fullPath) )
- return false;
- var ext = getExtension(fullPath);
- if( ext == null )
- return false;
- ide.openFile(fullPath);
- tree.closeFilter();
- return true;
- }
- public function revealNode( path : String ) {
- function doreveal() {
- tree.revealNode(path);
- tree.setSelection([path]);
- }
- if( tree.async ) {
- tree.async = false;
- tree.refresh(doreveal);
- }
- else
- doreveal();
- }
- function createNew( basePath : String, ext : ExtensionDesc ) {
- if( basePath == null )
- basePath = "";
- var fullPath = getFilePath(basePath);
- if( !sys.FileSystem.isDirectory(fullPath) ) {
- basePath = new haxe.io.Path(basePath).dir;
- if( basePath == null ) basePath = "";
- fullPath = getFilePath(basePath);
- }
- var file = ide.ask(ext.options.createNew + " name:");
- if( file == null ) return;
- if( file.indexOf(".") < 0 && ext.extensions != null )
- file += "." + ext.extensions[0].split(".").shift();
- if( sys.FileSystem.exists(fullPath + "/" + file) ) {
- ide.error("File '" + file+"' already exists");
- createNew(basePath, ext);
- return;
- }
- // directory
- if( ext.component == null ) {
- sys.FileSystem.createDirectory(fullPath + "/" + file);
- return;
- }
- var view : hide.view.FileView = Type.createEmptyInstance(Type.resolveClass(ext.component));
- view.ide = ide;
- sys.io.File.saveBytes(fullPath + "/" + file, view.getDefaultContent());
- var fpath = basePath == "" ? file : basePath + "/" + file;
- tree.refresh(function() tree.setSelection([fpath]));
- onOpenFile(fpath);
- }
- function isIgnored( fullpath : String ) {
- for(pat in ignorePatterns) {
- if(pat.match(fullpath))
- return true;
- }
- return false;
- }
- static var EXTENSIONS = new Map<String,ExtensionDesc>();
- public static function registerExtension<T>( c : Class<hide.ui.View<T>>, extensions : Array<String>, ?options : ExtensionOptions ) {
- hide.ui.View.register(c);
- if( options == null ) options = {};
- var obj = { component : Type.getClassName(c), options : options, extensions : extensions };
- for( e in extensions )
- EXTENSIONS.set(e, obj);
- return null;
- }
- static var _ = hide.ui.View.register(FileTree, { width : 350, position : Left });
- }
|