2016-06-18 12:46:12 +00:00
/*************************************************************************/
/* dependency_editor.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
2017-08-27 12:11:45 +00:00
/* https://godotengine.org */
2016-06-18 12:46:12 +00:00
/*************************************************************************/
2018-01-02 10:27:24 +00:00
/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
2016-06-18 12:46:12 +00:00
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
2015-08-23 23:15:56 +00:00
# include "dependency_editor.h"
2017-03-18 23:36:26 +00:00
# include "editor_node.h"
# include "io/resource_loader.h"
2015-08-23 23:15:56 +00:00
# include "os/file_access.h"
# include "scene/gui/margin_container.h"
2017-03-18 23:36:26 +00:00
void DependencyEditor : : _notification ( int p_what ) {
2015-08-23 23:15:56 +00:00
}
2017-03-18 23:36:26 +00:00
void DependencyEditor : : _searched ( const String & p_path ) {
2015-08-23 23:15:56 +00:00
2017-03-18 23:36:26 +00:00
Map < String , String > dep_rename ;
dep_rename [ replacing ] = p_path ;
2015-08-23 23:15:56 +00:00
2017-03-18 23:36:26 +00:00
ResourceLoader : : rename_dependencies ( editing , dep_rename ) ;
2015-08-23 23:15:56 +00:00
_update_list ( ) ;
_update_file ( ) ;
}
2017-03-18 23:36:26 +00:00
void DependencyEditor : : _load_pressed ( Object * p_item , int p_cell , int p_button ) {
2015-08-23 23:15:56 +00:00
2017-03-18 23:36:26 +00:00
TreeItem * ti = p_item - > cast_to < TreeItem > ( ) ;
2015-08-23 23:15:56 +00:00
String fname = ti - > get_text ( 0 ) ;
replacing = ti - > get_text ( 1 ) ;
2017-03-18 23:36:26 +00:00
search - > set_title ( TTR ( " Search Replacement For: " ) + " " + replacing . get_file ( ) ) ;
2015-08-23 23:15:56 +00:00
search - > clear_filters ( ) ;
List < String > ext ;
2017-03-18 23:36:26 +00:00
ResourceLoader : : get_recognized_extensions_for_type ( ti - > get_metadata ( 0 ) , & ext ) ;
for ( List < String > : : Element * E = ext . front ( ) ; E ; E = E - > next ( ) ) {
search - > add_filter ( " * " + E - > get ( ) ) ;
2015-08-23 23:15:56 +00:00
}
search - > popup_centered_ratio ( ) ;
}
2017-03-18 23:36:26 +00:00
void DependencyEditor : : _fix_and_find ( EditorFileSystemDirectory * efsd , Map < String , Map < String , String > > & candidates ) {
2015-08-23 23:15:56 +00:00
2017-03-18 23:36:26 +00:00
for ( int i = 0 ; i < efsd - > get_subdir_count ( ) ; i + + ) {
_fix_and_find ( efsd - > get_subdir ( i ) , candidates ) ;
2015-08-23 23:15:56 +00:00
}
2017-03-18 23:36:26 +00:00
for ( int i = 0 ; i < efsd - > get_file_count ( ) ; i + + ) {
2015-08-23 23:15:56 +00:00
String file = efsd - > get_file ( i ) ;
if ( ! candidates . has ( file ) )
continue ;
String path = efsd - > get_file_path ( i ) ;
2017-03-18 23:36:26 +00:00
for ( Map < String , String > : : Element * E = candidates [ file ] . front ( ) ; E ; E = E - > next ( ) ) {
2015-08-23 23:15:56 +00:00
2017-03-18 23:36:26 +00:00
if ( E - > get ( ) = = String ( ) ) {
E - > get ( ) = path ;
2015-08-23 23:15:56 +00:00
continue ;
}
//must match the best, using subdirs
2017-03-18 23:36:26 +00:00
String existing = E - > get ( ) . replace_first ( " res:// " , " " ) ;
String current = path . replace_first ( " res:// " , " " ) ;
String lost = E - > key ( ) . replace_first ( " res:// " , " " ) ;
2015-08-23 23:15:56 +00:00
2017-03-18 23:36:26 +00:00
Vector < String > existingv = existing . split ( " / " ) ;
2015-08-23 23:15:56 +00:00
existingv . invert ( ) ;
2017-03-18 23:36:26 +00:00
Vector < String > currentv = current . split ( " / " ) ;
2015-08-23 23:15:56 +00:00
currentv . invert ( ) ;
2017-03-18 23:36:26 +00:00
Vector < String > lostv = lost . split ( " / " ) ;
2015-08-23 23:15:56 +00:00
lostv . invert ( ) ;
2017-03-18 23:36:26 +00:00
int existing_score = 0 ;
int current_score = 0 ;
2015-08-23 23:15:56 +00:00
2017-03-18 23:36:26 +00:00
for ( int j = 0 ; j < lostv . size ( ) ; j + + ) {
2015-08-23 23:15:56 +00:00
2017-03-18 23:36:26 +00:00
if ( j < existingv . size ( ) & & lostv [ j ] = = existingv [ j ] ) {
2015-08-23 23:15:56 +00:00
existing_score + + ;
}
2017-03-18 23:36:26 +00:00
if ( j < currentv . size ( ) & & lostv [ j ] = = currentv [ j ] ) {
2015-08-23 23:15:56 +00:00
current_score + + ;
}
}
if ( current_score > existing_score ) {
//if it was the same, could track distance to new path but..
2017-03-18 23:36:26 +00:00
E - > get ( ) = path ; //replace by more accurate
2015-08-23 23:15:56 +00:00
}
}
}
}
2017-03-18 23:36:26 +00:00
void DependencyEditor : : _fix_all ( ) {
2015-08-23 23:15:56 +00:00
if ( ! EditorFileSystem : : get_singleton ( ) - > get_filesystem ( ) )
return ;
2017-03-18 23:36:26 +00:00
Map < String , Map < String , String > > candidates ;
2015-08-23 23:15:56 +00:00
2017-03-18 23:36:26 +00:00
for ( List < String > : : Element * E = missing . front ( ) ; E ; E = E - > next ( ) ) {
2015-08-23 23:15:56 +00:00
String base = E - > get ( ) . get_file ( ) ;
if ( ! candidates . has ( base ) ) {
2017-03-18 23:36:26 +00:00
candidates [ base ] = Map < String , String > ( ) ;
2015-08-23 23:15:56 +00:00
}
2017-03-18 23:36:26 +00:00
candidates [ base ] [ E - > get ( ) ] = " " ;
2015-08-23 23:15:56 +00:00
}
2017-03-18 23:36:26 +00:00
_fix_and_find ( EditorFileSystem : : get_singleton ( ) - > get_filesystem ( ) , candidates ) ;
2015-08-23 23:15:56 +00:00
2017-03-18 23:36:26 +00:00
Map < String , String > remaps ;
2015-08-23 23:15:56 +00:00
2017-03-18 23:36:26 +00:00
for ( Map < String , Map < String , String > > : : Element * E = candidates . front ( ) ; E ; E = E - > next ( ) ) {
2015-08-23 23:15:56 +00:00
2017-03-18 23:36:26 +00:00
for ( Map < String , String > : : Element * F = E - > get ( ) . front ( ) ; F ; F = F - > next ( ) ) {
2015-08-23 23:15:56 +00:00
2017-03-18 23:36:26 +00:00
if ( F - > get ( ) ! = String ( ) ) {
remaps [ F - > key ( ) ] = F - > get ( ) ;
2015-08-23 23:15:56 +00:00
}
}
}
if ( remaps . size ( ) ) {
2017-03-18 23:36:26 +00:00
ResourceLoader : : rename_dependencies ( editing , remaps ) ;
2015-08-23 23:15:56 +00:00
_update_list ( ) ;
_update_file ( ) ;
}
}
void DependencyEditor : : _update_file ( ) {
EditorFileSystem : : get_singleton ( ) - > update_file ( editing ) ;
}
void DependencyEditor : : _update_list ( ) {
List < String > deps ;
2017-03-18 23:36:26 +00:00
ResourceLoader : : get_dependencies ( editing , & deps , true ) ;
2015-08-23 23:15:56 +00:00
tree - > clear ( ) ;
missing . clear ( ) ;
TreeItem * root = tree - > create_item ( ) ;
2017-03-18 23:36:26 +00:00
Ref < Texture > folder = get_icon ( " folder " , " FileDialog " ) ;
2015-08-23 23:15:56 +00:00
2017-03-18 23:36:26 +00:00
bool broken = false ;
2015-08-23 23:15:56 +00:00
2017-03-18 23:36:26 +00:00
for ( List < String > : : Element * E = deps . front ( ) ; E ; E = E - > next ( ) ) {
2015-08-23 23:15:56 +00:00
TreeItem * item = tree - > create_item ( root ) ;
String n = E - > get ( ) ;
String path ;
String type ;
2017-03-18 23:36:26 +00:00
if ( n . find ( " :: " ) ! = - 1 ) {
path = n . get_slice ( " :: " , 0 ) ;
type = n . get_slice ( " :: " , 1 ) ;
2015-08-23 23:15:56 +00:00
} else {
2017-03-18 23:36:26 +00:00
path = n ;
type = " Resource " ;
2015-08-23 23:15:56 +00:00
}
String name = path . get_file ( ) ;
Ref < Texture > icon ;
2017-03-18 23:36:26 +00:00
if ( has_icon ( type , " EditorIcons " ) ) {
icon = get_icon ( type , " EditorIcons " ) ;
2015-08-23 23:15:56 +00:00
} else {
2017-03-18 23:36:26 +00:00
icon = get_icon ( " Object " , " EditorIcons " ) ;
2015-08-23 23:15:56 +00:00
}
2017-03-18 23:36:26 +00:00
item - > set_text ( 0 , name ) ;
item - > set_icon ( 0 , icon ) ;
item - > set_metadata ( 0 , type ) ;
item - > set_text ( 1 , path ) ;
2015-08-23 23:15:56 +00:00
if ( ! FileAccess : : exists ( path ) ) {
2017-03-18 23:36:26 +00:00
item - > set_custom_color ( 1 , Color ( 1 , 0.4 , 0.3 ) ) ;
2015-08-23 23:15:56 +00:00
missing . push_back ( path ) ;
2017-03-18 23:36:26 +00:00
broken = true ;
2015-08-23 23:15:56 +00:00
}
2017-03-18 23:36:26 +00:00
item - > add_button ( 1 , folder , 0 ) ;
2015-08-23 23:15:56 +00:00
}
fixdeps - > set_disabled ( ! broken ) ;
}
2017-03-18 23:36:26 +00:00
void DependencyEditor : : edit ( const String & p_path ) {
2015-08-23 23:15:56 +00:00
2017-03-18 23:36:26 +00:00
editing = p_path ;
set_title ( TTR ( " Dependencies For: " ) + " " + p_path . get_file ( ) ) ;
2015-08-23 23:15:56 +00:00
_update_list ( ) ;
popup_centered_ratio ( ) ;
if ( EditorNode : : get_singleton ( ) - > is_scene_open ( p_path ) ) {
2017-03-18 23:36:26 +00:00
EditorNode : : get_singleton ( ) - > show_warning ( vformat ( TTR ( " Scene '%s' is currently being edited. \n Changes will not take effect unless reloaded. " ) , p_path . get_file ( ) ) ) ;
2015-08-23 23:15:56 +00:00
} else if ( ResourceCache : : has ( p_path ) ) {
2017-03-18 23:36:26 +00:00
EditorNode : : get_singleton ( ) - > show_warning ( vformat ( TTR ( " Resource '%s' is in use. \n Changes will take effect when reloaded. " ) , p_path . get_file ( ) ) ) ;
2015-08-23 23:15:56 +00:00
}
}
void DependencyEditor : : _bind_methods ( ) {
2017-03-18 23:36:26 +00:00
ObjectTypeDB : : bind_method ( _MD ( " _searched " ) , & DependencyEditor : : _searched ) ;
ObjectTypeDB : : bind_method ( _MD ( " _load_pressed " ) , & DependencyEditor : : _load_pressed ) ;
ObjectTypeDB : : bind_method ( _MD ( " _fix_all " ) , & DependencyEditor : : _fix_all ) ;
2015-08-23 23:15:56 +00:00
}
DependencyEditor : : DependencyEditor ( ) {
2017-03-18 23:36:26 +00:00
VBoxContainer * vb = memnew ( VBoxContainer ) ;
2016-05-04 01:25:37 +00:00
vb - > set_name ( TTR ( " Dependencies " ) ) ;
2015-08-23 23:15:56 +00:00
add_child ( vb ) ;
set_child_rect ( vb ) ;
2017-03-18 23:36:26 +00:00
tree = memnew ( Tree ) ;
2015-08-23 23:15:56 +00:00
tree - > set_columns ( 2 ) ;
tree - > set_column_titles_visible ( true ) ;
2017-03-18 23:36:26 +00:00
tree - > set_column_title ( 0 , TTR ( " Resource " ) ) ;
tree - > set_column_title ( 1 , TTR ( " Path " ) ) ;
2015-08-23 23:15:56 +00:00
tree - > set_hide_root ( true ) ;
2017-03-18 23:36:26 +00:00
tree - > connect ( " button_pressed " , this , " _load_pressed " ) ;
2015-08-23 23:15:56 +00:00
2017-03-18 23:36:26 +00:00
HBoxContainer * hbc = memnew ( HBoxContainer ) ;
Label * label = memnew ( Label ( TTR ( " Dependencies: " ) ) ) ;
2015-08-23 23:15:56 +00:00
hbc - > add_child ( label ) ;
hbc - > add_spacer ( ) ;
2017-03-18 23:36:26 +00:00
fixdeps = memnew ( Button ( TTR ( " Fix Broken " ) ) ) ;
2015-08-23 23:15:56 +00:00
hbc - > add_child ( fixdeps ) ;
2017-03-18 23:36:26 +00:00
fixdeps - > connect ( " pressed " , this , " _fix_all " ) ;
2015-08-23 23:15:56 +00:00
vb - > add_child ( hbc ) ;
2017-03-18 23:36:26 +00:00
MarginContainer * mc = memnew ( MarginContainer ) ;
2015-08-23 23:15:56 +00:00
mc - > set_v_size_flags ( SIZE_EXPAND_FILL ) ;
mc - > add_child ( tree ) ;
vb - > add_child ( mc ) ;
2016-05-04 01:25:37 +00:00
set_title ( TTR ( " Dependency Editor " ) ) ;
2017-03-18 23:36:26 +00:00
search = memnew ( EditorFileDialog ) ;
search - > connect ( " file_selected " , this , " _searched " ) ;
2015-08-23 23:15:56 +00:00
search - > set_mode ( EditorFileDialog : : MODE_OPEN_FILE ) ;
2016-05-04 01:25:37 +00:00
search - > set_title ( TTR ( " Search Replacement Resource: " ) ) ;
2015-08-23 23:15:56 +00:00
add_child ( search ) ;
}
/////////////////////////////////////
2017-11-15 07:50:32 +00:00
void DependencyEditorOwners : : _list_rmb_select ( int p_item , const Vector2 & p_pos ) {
file_options - > clear ( ) ;
file_options - > set_size ( Size2 ( 1 , 1 ) ) ;
if ( p_item > = 0 ) {
file_options - > add_item ( TTR ( " Open " ) , FILE_OPEN ) ;
}
file_options - > set_pos ( owners - > get_global_pos ( ) + p_pos ) ;
file_options - > popup ( ) ;
}
void DependencyEditorOwners : : _select_file ( int p_idx ) {
String fpath = owners - > get_item_text ( p_idx ) ;
if ( ResourceLoader : : get_resource_type ( fpath ) = = " PackedScene " ) {
editor - > open_request ( fpath ) ;
hide ( ) ;
emit_signal ( " confirmed " ) ;
}
}
void DependencyEditorOwners : : _file_option ( int p_option ) {
switch ( p_option ) {
2017-12-11 14:18:06 +00:00
case FILE_OPEN : {
int idx = owners - > get_current ( ) ;
if ( idx < 0 | | idx > = owners - > get_item_count ( ) )
break ;
_select_file ( idx ) ;
} break ;
2017-11-15 07:50:32 +00:00
}
}
void DependencyEditorOwners : : _bind_methods ( ) {
ObjectTypeDB : : bind_method ( _MD ( " _list_rmb_select " ) , & DependencyEditorOwners : : _list_rmb_select ) ;
ObjectTypeDB : : bind_method ( _MD ( " _file_option " ) , & DependencyEditorOwners : : _file_option ) ;
ObjectTypeDB : : bind_method ( _MD ( " _select_file " ) , & DependencyEditorOwners : : _select_file ) ;
}
2015-08-23 23:15:56 +00:00
void DependencyEditorOwners : : _fill_owners ( EditorFileSystemDirectory * efsd ) {
if ( ! efsd )
return ;
2017-03-18 23:36:26 +00:00
for ( int i = 0 ; i < efsd - > get_subdir_count ( ) ; i + + ) {
2015-08-23 23:15:56 +00:00
_fill_owners ( efsd - > get_subdir ( i ) ) ;
}
2017-03-18 23:36:26 +00:00
for ( int i = 0 ; i < efsd - > get_file_count ( ) ; i + + ) {
2015-08-23 23:15:56 +00:00
Vector < String > deps = efsd - > get_file_deps ( i ) ;
//print_line(":::"+efsd->get_file_path(i));
2017-03-18 23:36:26 +00:00
bool found = false ;
for ( int j = 0 ; j < deps . size ( ) ; j + + ) {
2015-08-23 23:15:56 +00:00
//print_line("\t"+deps[j]+" vs "+editing);
2017-03-18 23:36:26 +00:00
if ( deps [ j ] = = editing ) {
2015-08-23 23:15:56 +00:00
//print_line("found");
2017-03-18 23:36:26 +00:00
found = true ;
2015-08-23 23:15:56 +00:00
break ;
}
}
if ( ! found )
continue ;
Ref < Texture > icon ;
2017-03-18 23:36:26 +00:00
String type = efsd - > get_file_type ( i ) ;
if ( ! has_icon ( type , " EditorIcons " ) ) {
icon = get_icon ( " Object " , " EditorIcons " ) ;
2015-08-23 23:15:56 +00:00
} else {
2017-03-18 23:36:26 +00:00
icon = get_icon ( type , " EditorIcons " ) ;
2015-08-23 23:15:56 +00:00
}
2017-03-18 23:36:26 +00:00
owners - > add_item ( efsd - > get_file_path ( i ) , icon ) ;
2015-08-23 23:15:56 +00:00
}
}
2017-03-18 23:36:26 +00:00
void DependencyEditorOwners : : show ( const String & p_path ) {
2015-08-23 23:15:56 +00:00
2017-03-18 23:36:26 +00:00
editing = p_path ;
2015-08-23 23:15:56 +00:00
owners - > clear ( ) ;
_fill_owners ( EditorFileSystem : : get_singleton ( ) - > get_filesystem ( ) ) ;
popup_centered_ratio ( ) ;
2017-03-18 23:36:26 +00:00
set_title ( TTR ( " Owners Of: " ) + " " + p_path . get_file ( ) ) ;
2015-08-23 23:15:56 +00:00
}
2017-11-15 07:50:32 +00:00
DependencyEditorOwners : : DependencyEditorOwners ( EditorNode * p_editor ) {
editor = p_editor ;
file_options = memnew ( PopupMenu ) ;
add_child ( file_options ) ;
file_options - > connect ( " item_pressed " , this , " _file_option " ) ;
2015-08-23 23:15:56 +00:00
2017-03-18 23:36:26 +00:00
owners = memnew ( ItemList ) ;
2017-11-15 07:50:32 +00:00
owners - > set_select_mode ( ItemList : : SELECT_SINGLE ) ;
owners - > connect ( " item_rmb_selected " , this , " _list_rmb_select " ) ;
owners - > connect ( " item_activated " , this , " _select_file " ) ;
owners - > set_allow_rmb_select ( true ) ;
2015-08-23 23:15:56 +00:00
add_child ( owners ) ;
set_child_rect ( owners ) ;
}
///////////////////////
void DependencyRemoveDialog : : _fill_owners ( EditorFileSystemDirectory * efsd ) {
if ( ! efsd )
return ;
2017-03-18 23:36:26 +00:00
for ( int i = 0 ; i < efsd - > get_subdir_count ( ) ; i + + ) {
2015-08-23 23:15:56 +00:00
_fill_owners ( efsd - > get_subdir ( i ) ) ;
}
2017-03-18 23:36:26 +00:00
for ( int i = 0 ; i < efsd - > get_file_count ( ) ; i + + ) {
2015-08-23 23:15:56 +00:00
Vector < String > deps = efsd - > get_file_deps ( i ) ;
//print_line(":::"+efsd->get_file_path(i));
Set < String > met ;
2017-03-18 23:36:26 +00:00
for ( int j = 0 ; j < deps . size ( ) ; j + + ) {
2015-08-23 23:15:56 +00:00
if ( files . has ( deps [ j ] ) ) {
met . insert ( deps [ j ] ) ;
}
}
if ( ! met . size ( ) )
continue ;
2017-03-18 23:36:26 +00:00
exist = true ;
2015-08-23 23:15:56 +00:00
Ref < Texture > icon ;
2017-03-18 23:36:26 +00:00
String type = efsd - > get_file_type ( i ) ;
if ( ! has_icon ( type , " EditorIcons " ) ) {
icon = get_icon ( " Object " , " EditorIcons " ) ;
2015-08-23 23:15:56 +00:00
} else {
2017-03-18 23:36:26 +00:00
icon = get_icon ( type , " EditorIcons " ) ;
2015-08-23 23:15:56 +00:00
}
2017-03-18 23:36:26 +00:00
for ( Set < String > : : Element * E = met . front ( ) ; E ; E = E - > next ( ) ) {
2015-08-23 23:15:56 +00:00
String which = E - > get ( ) ;
if ( ! files [ which ] ) {
2017-03-18 23:36:26 +00:00
TreeItem * ti = owners - > create_item ( owners - > get_root ( ) ) ;
ti - > set_text ( 0 , which . get_file ( ) ) ;
files [ which ] = ti ;
2015-08-23 23:15:56 +00:00
}
2017-03-18 23:36:26 +00:00
TreeItem * ti = owners - > create_item ( files [ which ] ) ;
ti - > set_text ( 0 , efsd - > get_file_path ( i ) ) ;
ti - > set_icon ( 0 , icon ) ;
2015-08-23 23:15:56 +00:00
}
}
}
void DependencyRemoveDialog : : show ( const Vector < String > & to_erase ) {
2017-03-18 23:36:26 +00:00
exist = false ;
2015-08-23 23:15:56 +00:00
owners - > clear ( ) ;
files . clear ( ) ;
2016-07-07 22:32:28 +00:00
owners - > create_item ( ) ; // root
2017-03-18 23:36:26 +00:00
for ( int i = 0 ; i < to_erase . size ( ) ; i + + ) {
files [ to_erase [ i ] ] = NULL ;
2015-08-23 23:15:56 +00:00
}
_fill_owners ( EditorFileSystem : : get_singleton ( ) - > get_filesystem ( ) ) ;
if ( exist ) {
owners - > show ( ) ;
2016-05-29 08:10:23 +00:00
text - > set_text ( TTR ( " The files being removed are required by other resources in order for them to work. \n Remove them anyway? (no undo) " ) ) ;
2017-03-18 23:36:26 +00:00
popup_centered_minsize ( Size2 ( 500 , 220 ) ) ;
2015-08-23 23:15:56 +00:00
} else {
owners - > hide ( ) ;
2016-05-04 01:25:37 +00:00
text - > set_text ( TTR ( " Remove selected files from the project? (no undo) " ) ) ;
2017-03-18 23:36:26 +00:00
popup_centered_minsize ( Size2 ( 400 , 100 ) ) ;
2015-08-23 23:15:56 +00:00
}
}
void DependencyRemoveDialog : : ok_pressed ( ) {
2017-12-11 14:18:06 +00:00
2015-08-23 23:15:56 +00:00
DirAccess * da = DirAccess : : create ( DirAccess : : ACCESS_RESOURCES ) ;
2017-03-18 23:36:26 +00:00
for ( Map < String , TreeItem * > : : Element * E = files . front ( ) ; E ; E = E - > next ( ) ) {
2017-12-11 14:18:06 +00:00
if ( da - > dir_exists ( E - > key ( ) ) ) {
2017-11-19 03:21:36 +00:00
String path = OS : : get_singleton ( ) - > get_resource_dir ( ) + E - > key ( ) . replace_first ( " res:// " , " / " ) ;
OS : : get_singleton ( ) - > move_path_to_trash ( path ) ;
EditorFileSystem : : get_singleton ( ) - > scan ( ) ;
} else {
if ( ResourceCache : : has ( E - > key ( ) ) ) {
Resource * res = ResourceCache : : get ( E - > key ( ) ) ;
res - > set_path ( " " ) ; //clear reference to path
}
da - > remove ( E - > key ( ) ) ;
EditorFileSystem : : get_singleton ( ) - > update_file ( E - > key ( ) ) ;
2016-06-10 00:43:28 +00:00
}
2015-08-23 23:15:56 +00:00
}
memdelete ( da ) ;
}
DependencyRemoveDialog : : DependencyRemoveDialog ( ) {
2017-03-18 23:36:26 +00:00
VBoxContainer * vb = memnew ( VBoxContainer ) ;
2015-08-23 23:15:56 +00:00
add_child ( vb ) ;
set_child_rect ( vb ) ;
2017-03-18 23:36:26 +00:00
text = memnew ( Label ) ;
2015-08-23 23:15:56 +00:00
vb - > add_child ( text ) ;
2017-03-18 23:36:26 +00:00
owners = memnew ( Tree ) ;
2015-08-23 23:15:56 +00:00
owners - > set_hide_root ( true ) ;
vb - > add_child ( owners ) ;
owners - > set_v_size_flags ( SIZE_EXPAND_FILL ) ;
2016-05-04 01:25:37 +00:00
get_ok ( ) - > set_text ( TTR ( " Remove " ) ) ;
2015-08-23 23:15:56 +00:00
}
//////////////
2017-03-18 23:36:26 +00:00
void DependencyErrorDialog : : show ( const String & p_for_file , const Vector < String > & report ) {
2015-08-23 23:15:56 +00:00
2017-03-18 23:36:26 +00:00
for_file = p_for_file ;
set_title ( TTR ( " Error loading: " ) + " " + p_for_file . get_file ( ) ) ;
2015-08-23 23:15:56 +00:00
files - > clear ( ) ;
TreeItem * root = files - > create_item ( NULL ) ;
2017-03-18 23:36:26 +00:00
for ( int i = 0 ; i < report . size ( ) ; i + + ) {
2015-08-23 23:15:56 +00:00
String dep ;
2017-03-18 23:36:26 +00:00
String type = " Object " ;
dep = report [ i ] . get_slice ( " :: " , 0 ) ;
if ( report [ i ] . get_slice_count ( " :: " ) > 0 )
type = report [ i ] . get_slice ( " :: " , 1 ) ;
2015-08-23 23:15:56 +00:00
Ref < Texture > icon ;
2017-03-18 23:36:26 +00:00
if ( ! has_icon ( type , " EditorIcons " ) ) {
icon = get_icon ( " Object " , " EditorIcons " ) ;
2015-08-23 23:15:56 +00:00
} else {
2017-03-18 23:36:26 +00:00
icon = get_icon ( type , " EditorIcons " ) ;
2015-08-23 23:15:56 +00:00
}
2017-03-18 23:36:26 +00:00
TreeItem * ti = files - > create_item ( root ) ;
ti - > set_text ( 0 , dep ) ;
ti - > set_icon ( 0 , icon ) ;
2015-08-23 23:15:56 +00:00
}
2017-03-18 23:36:26 +00:00
popup_centered_minsize ( Size2 ( 500 , 220 ) ) ;
2015-08-23 23:15:56 +00:00
}
void DependencyErrorDialog : : ok_pressed ( ) {
2017-03-18 23:36:26 +00:00
EditorNode : : get_singleton ( ) - > load_scene ( for_file , true ) ;
2015-08-23 23:15:56 +00:00
}
2017-03-18 23:36:26 +00:00
void DependencyErrorDialog : : custom_action ( const String & ) {
2015-08-23 23:15:56 +00:00
EditorNode : : get_singleton ( ) - > fix_dependencies ( for_file ) ;
}
DependencyErrorDialog : : DependencyErrorDialog ( ) {
2017-03-18 23:36:26 +00:00
VBoxContainer * vb = memnew ( VBoxContainer ) ;
2015-08-23 23:15:56 +00:00
add_child ( vb ) ;
set_child_rect ( vb ) ;
2017-03-18 23:36:26 +00:00
files = memnew ( Tree ) ;
2015-08-23 23:15:56 +00:00
files - > set_hide_root ( true ) ;
2017-03-18 23:36:26 +00:00
vb - > add_margin_child ( TTR ( " Scene failed to load due to missing dependencies: " ) , files , true ) ;
2015-08-23 23:15:56 +00:00
files - > set_v_size_flags ( SIZE_EXPAND_FILL ) ;
2016-05-04 01:25:37 +00:00
get_ok ( ) - > set_text ( TTR ( " Open Anyway " ) ) ;
2015-08-23 23:15:56 +00:00
2017-03-18 23:36:26 +00:00
text = memnew ( Label ) ;
2015-08-23 23:15:56 +00:00
vb - > add_child ( text ) ;
2016-05-04 01:25:37 +00:00
text - > set_text ( TTR ( " Which action should be taken? " ) ) ;
2015-08-23 23:15:56 +00:00
2017-03-18 23:36:26 +00:00
fdep = add_button ( TTR ( " Fix Dependencies " ) , true , " fixdeps " ) ;
2015-08-23 23:15:56 +00:00
2016-05-04 01:25:37 +00:00
set_title ( TTR ( " Errors loading! " ) ) ;
2015-08-23 23:15:56 +00:00
}
2015-11-29 04:08:31 +00:00
//////////////////////////////////////////////////////////////////////
void OrphanResourcesDialog : : ok_pressed ( ) {
paths . clear ( ) ;
2017-03-18 23:36:26 +00:00
_find_to_delete ( files - > get_root ( ) , paths ) ;
2015-11-29 04:08:31 +00:00
if ( paths . empty ( ) )
return ;
2017-03-18 23:36:26 +00:00
delete_confirm - > set_text ( vformat ( TTR ( " Permanently delete %d item(s)? (No undo!) " ) , paths . size ( ) ) ) ;
2015-11-29 04:08:31 +00:00
delete_confirm - > popup_centered_minsize ( ) ;
}
2017-03-18 23:36:26 +00:00
bool OrphanResourcesDialog : : _fill_owners ( EditorFileSystemDirectory * efsd , HashMap < String , int > & refs , TreeItem * p_parent ) {
2015-11-29 04:08:31 +00:00
if ( ! efsd )
return false ;
2017-03-18 23:36:26 +00:00
bool has_childs = false ;
2015-11-29 04:08:31 +00:00
2017-03-18 23:36:26 +00:00
for ( int i = 0 ; i < efsd - > get_subdir_count ( ) ; i + + ) {
2015-11-29 04:08:31 +00:00
2017-03-18 23:36:26 +00:00
TreeItem * dir_item = NULL ;
2015-11-29 04:08:31 +00:00
if ( p_parent ) {
dir_item = files - > create_item ( p_parent ) ;
2017-03-18 23:36:26 +00:00
dir_item - > set_text ( 0 , efsd - > get_subdir ( i ) - > get_name ( ) ) ;
dir_item - > set_icon ( 0 , get_icon ( " folder " , " FileDialog " ) ) ;
2015-11-29 04:08:31 +00:00
}
2017-03-18 23:36:26 +00:00
bool children = _fill_owners ( efsd - > get_subdir ( i ) , refs , dir_item ) ;
2015-11-29 04:08:31 +00:00
if ( p_parent ) {
if ( ! children ) {
memdelete ( dir_item ) ;
} else {
2017-03-18 23:36:26 +00:00
has_childs = true ;
2015-11-29 04:08:31 +00:00
}
}
}
2017-03-18 23:36:26 +00:00
for ( int i = 0 ; i < efsd - > get_file_count ( ) ; i + + ) {
2015-11-29 04:08:31 +00:00
if ( ! p_parent ) {
Vector < String > deps = efsd - > get_file_deps ( i ) ;
//print_line(":::"+efsd->get_file_path(i));
2017-03-18 23:36:26 +00:00
for ( int j = 0 ; j < deps . size ( ) ; j + + ) {
2015-11-29 04:08:31 +00:00
if ( ! refs . has ( deps [ j ] ) ) {
2017-03-18 23:36:26 +00:00
refs [ deps [ j ] ] = 1 ;
2015-11-29 04:08:31 +00:00
}
}
} else {
String path = efsd - > get_file_path ( i ) ;
if ( ! refs . has ( path ) ) {
2017-03-18 23:36:26 +00:00
TreeItem * ti = files - > create_item ( p_parent ) ;
ti - > set_cell_mode ( 0 , TreeItem : : CELL_MODE_CHECK ) ;
ti - > set_text ( 0 , efsd - > get_file ( i ) ) ;
ti - > set_editable ( 0 , true ) ;
2015-11-29 04:08:31 +00:00
2017-03-18 23:36:26 +00:00
String type = efsd - > get_file_type ( i ) ;
2015-11-29 04:08:31 +00:00
Ref < Texture > icon ;
2017-03-18 23:36:26 +00:00
if ( has_icon ( type , " EditorIcons " ) ) {
icon = get_icon ( type , " EditorIcons " ) ;
2015-11-29 04:08:31 +00:00
} else {
2017-03-18 23:36:26 +00:00
icon = get_icon ( " Object " , " EditorIcons " ) ;
2015-11-29 04:08:31 +00:00
}
2017-03-18 23:36:26 +00:00
ti - > set_icon ( 0 , icon ) ;
2015-11-29 04:08:31 +00:00
int ds = efsd - > get_file_deps ( i ) . size ( ) ;
2017-03-18 23:36:26 +00:00
ti - > set_text ( 1 , itos ( ds ) ) ;
2015-11-29 04:08:31 +00:00
if ( ds ) {
2017-03-18 23:36:26 +00:00
ti - > add_button ( 1 , get_icon ( " Visible " , " EditorIcons " ) ) ;
2015-11-29 04:08:31 +00:00
}
2017-03-18 23:36:26 +00:00
ti - > set_metadata ( 0 , path ) ;
has_childs = true ;
2015-11-29 04:08:31 +00:00
}
}
}
return has_childs ;
}
void OrphanResourcesDialog : : refresh ( ) {
2017-03-18 23:36:26 +00:00
HashMap < String , int > refs ;
_fill_owners ( EditorFileSystem : : get_singleton ( ) - > get_filesystem ( ) , refs , NULL ) ;
2015-11-29 04:08:31 +00:00
files - > clear ( ) ;
2017-03-18 23:36:26 +00:00
TreeItem * root = files - > create_item ( ) ;
_fill_owners ( EditorFileSystem : : get_singleton ( ) - > get_filesystem ( ) , refs , root ) ;
2015-11-29 04:08:31 +00:00
}
2017-03-18 23:36:26 +00:00
void OrphanResourcesDialog : : show ( ) {
2015-11-29 04:08:31 +00:00
refresh ( ) ;
popup_centered_ratio ( ) ;
}
2017-03-18 23:36:26 +00:00
void OrphanResourcesDialog : : _find_to_delete ( TreeItem * p_item , List < String > & paths ) {
2015-11-29 04:08:31 +00:00
2017-03-18 23:36:26 +00:00
while ( p_item ) {
2015-11-29 04:08:31 +00:00
2017-03-18 23:36:26 +00:00
if ( p_item - > get_cell_mode ( 0 ) = = TreeItem : : CELL_MODE_CHECK & & p_item - > is_checked ( 0 ) ) {
2015-11-29 04:08:31 +00:00
paths . push_back ( p_item - > get_metadata ( 0 ) ) ;
}
if ( p_item - > get_children ( ) ) {
2017-03-18 23:36:26 +00:00
_find_to_delete ( p_item - > get_children ( ) , paths ) ;
2015-11-29 04:08:31 +00:00
}
2017-03-18 23:36:26 +00:00
p_item = p_item - > get_next ( ) ;
2015-11-29 04:08:31 +00:00
}
}
void OrphanResourcesDialog : : _delete_confirm ( ) {
DirAccess * da = DirAccess : : create ( DirAccess : : ACCESS_RESOURCES ) ;
2017-03-18 23:36:26 +00:00
for ( List < String > : : Element * E = paths . front ( ) ; E ; E = E - > next ( ) ) {
2015-11-29 04:08:31 +00:00
da - > remove ( E - > get ( ) ) ;
EditorFileSystem : : get_singleton ( ) - > update_file ( E - > get ( ) ) ;
}
memdelete ( da ) ;
refresh ( ) ;
}
2017-03-18 23:36:26 +00:00
void OrphanResourcesDialog : : _button_pressed ( Object * p_item , int p_column , int p_id ) {
2015-11-29 04:08:31 +00:00
2017-03-18 23:36:26 +00:00
TreeItem * ti = p_item - > cast_to < TreeItem > ( ) ;
2015-11-29 04:08:31 +00:00
String path = ti - > get_metadata ( 0 ) ;
dep_edit - > edit ( path ) ;
}
void OrphanResourcesDialog : : _bind_methods ( ) {
2017-03-18 23:36:26 +00:00
ObjectTypeDB : : bind_method ( _MD ( " _delete_confirm " ) , & OrphanResourcesDialog : : _delete_confirm ) ;
ObjectTypeDB : : bind_method ( _MD ( " _button_pressed " ) , & OrphanResourcesDialog : : _button_pressed ) ;
2015-11-29 04:08:31 +00:00
}
2017-03-18 23:36:26 +00:00
OrphanResourcesDialog : : OrphanResourcesDialog ( ) {
2015-11-29 04:08:31 +00:00
2017-03-18 23:36:26 +00:00
VBoxContainer * vbc = memnew ( VBoxContainer ) ;
2015-11-29 04:08:31 +00:00
add_child ( vbc ) ;
set_child_rect ( vbc ) ;
2017-03-18 23:36:26 +00:00
files = memnew ( Tree ) ;
2015-11-29 04:08:31 +00:00
files - > set_columns ( 2 ) ;
files - > set_column_titles_visible ( true ) ;
2017-03-18 23:36:26 +00:00
files - > set_column_min_width ( 1 , 100 ) ;
files - > set_column_expand ( 0 , true ) ;
files - > set_column_expand ( 1 , false ) ;
files - > set_column_title ( 0 , TTR ( " Resource " ) ) ;
files - > set_column_title ( 1 , TTR ( " Owns " ) ) ;
2015-11-29 04:08:31 +00:00
files - > set_hide_root ( true ) ;
2017-03-18 23:36:26 +00:00
vbc - > add_margin_child ( TTR ( " Resources Without Explicit Ownership: " ) , files , true ) ;
2016-05-04 01:25:37 +00:00
set_title ( TTR ( " Orphan Resource Explorer " ) ) ;
2017-03-18 23:36:26 +00:00
delete_confirm = memnew ( ConfirmationDialog ) ;
2016-05-04 01:25:37 +00:00
delete_confirm - > set_text ( TTR ( " Delete selected files? " ) ) ;
get_ok ( ) - > set_text ( TTR ( " Delete " ) ) ;
2015-11-29 04:08:31 +00:00
add_child ( delete_confirm ) ;
2017-03-18 23:36:26 +00:00
dep_edit = memnew ( DependencyEditor ) ;
2015-11-29 04:08:31 +00:00
add_child ( dep_edit ) ;
2017-03-18 23:36:26 +00:00
files - > connect ( " button_pressed " , this , " _button_pressed " ) ;
delete_confirm - > connect ( " confirmed " , this , " _delete_confirm " ) ;
2015-11-29 04:08:31 +00:00
set_hide_on_ok ( false ) ;
}