diff options
author | Juan Linietsky <reduzio@gmail.com> | 2016-03-12 10:44:12 -0300 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2016-03-12 10:46:38 -0300 |
commit | 8b1dcbfe4d92f9d7273bbd2f1eb805e5c508961a (patch) | |
tree | 77bd972e494e7deeef49bfa271c94d03ef2af749 /tools/editor | |
parent | d85f06c42d54971af5da826581c75d1ed001475e (diff) |
-Made editor support SSL certs by default (embedded them)
-Made asset sharing support https
-Many fixes to HTTPRequest
-Added an asset installer dialog
-Visual cleanups to asset sharing tab
-Fixed some issues in ScrollContainer, hope it does not break things
-Asset sharing tab is not visible (hidden on purpose) for now.
Diffstat (limited to 'tools/editor')
-rw-r--r-- | tools/editor/SCsub | 28 | ||||
-rw-r--r-- | tools/editor/addon_editor_plugin.cpp | 351 | ||||
-rw-r--r-- | tools/editor/addon_editor_plugin.h | 78 | ||||
-rw-r--r-- | tools/editor/editor_asset_installer.cpp | 327 | ||||
-rw-r--r-- | tools/editor/editor_asset_installer.h | 28 | ||||
-rw-r--r-- | tools/editor/editor_initialize_ssl.cpp | 21 | ||||
-rw-r--r-- | tools/editor/editor_initialize_ssl.h | 6 | ||||
-rw-r--r-- | tools/editor/editor_node.cpp | 6 | ||||
-rw-r--r-- | tools/editor/editor_node.h | 2 | ||||
-rw-r--r-- | tools/editor/icons/icon_rating_no_star.png | bin | 476 -> 288 bytes | |||
-rw-r--r-- | tools/editor/icons/icon_rating_star.png | bin | 896 -> 289 bytes | |||
-rw-r--r-- | tools/editor/progress_dialog.cpp | 4 | ||||
-rw-r--r-- | tools/editor/progress_dialog.h | 2 | ||||
-rw-r--r-- | tools/editor/project_settings.cpp | 7 | ||||
-rw-r--r-- | tools/editor/project_settings.h | 6 |
15 files changed, 836 insertions, 30 deletions
diff --git a/tools/editor/SCsub b/tools/editor/SCsub index cd46ff8353..34651b36f2 100644 --- a/tools/editor/SCsub +++ b/tools/editor/SCsub @@ -26,6 +26,31 @@ def make_doc_header(target,source,env): +def make_certs_header(target,source,env): + + src = source[0].srcnode().abspath + dst = target[0].srcnode().abspath + f = open(src,"rb") + g = open(dst,"wb") + buf = f.read() + decomp_size = len(buf) + import zlib + buf = zlib.compress(buf) + + + g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") + g.write("#ifndef _CERTS_RAW_H\n") + g.write("#define _CERTS_RAW_H\n") + g.write("static const int _certs_compressed_size="+str(len(buf))+";\n") + g.write("static const int _certs_uncompressed_size="+str(decomp_size)+";\n") + g.write("static const unsigned char _certs_compressed[]={\n") + for i in range(len(buf)): + g.write(str(ord(buf[i]))+",\n") + g.write("};\n") + g.write("#endif") + + + @@ -47,6 +72,9 @@ if (env["tools"]=="yes"): env.Depends("#tools/editor/doc_data_compressed.h","#doc/base/classes.xml") env.Command("#tools/editor/doc_data_compressed.h","#doc/base/classes.xml",make_doc_header) + env.Depends("#tools/editor/certs_compressed.h","#tools/certs/ca-certificates.crt") + env.Command("#tools/editor/certs_compressed.h","#tools/certs/ca-certificates.crt",make_certs_header) + #make_doc_header(env.File("#tools/editor/doc_data_raw.h").srcnode().abspath,env.File("#doc/base/classes.xml").srcnode().abspath,env) env.add_source_files(env.tool_sources,"*.cpp") diff --git a/tools/editor/addon_editor_plugin.cpp b/tools/editor/addon_editor_plugin.cpp index 82c2d3de64..4dfb8ff553 100644 --- a/tools/editor/addon_editor_plugin.cpp +++ b/tools/editor/addon_editor_plugin.cpp @@ -1,6 +1,6 @@ #include "addon_editor_plugin.h" #include "editor_node.h" - +#include "editor_settings.h" @@ -142,6 +142,7 @@ void EditorAddonLibraryItemDescription::set_image(int p_type,int p_index,const R case EditorAddonLibrary::IMAGE_QUEUE_ICON: { item->call("set_image",p_type,p_index,p_image); + icon=p_image; } break; case EditorAddonLibrary::IMAGE_QUEUE_THUMBNAIL: { @@ -166,12 +167,30 @@ void EditorAddonLibraryItemDescription::set_image(int p_type,int p_index,const R void EditorAddonLibraryItemDescription::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_image"),&EditorAddonLibraryItemDescription::set_image); + ObjectTypeDB::bind_method(_MD("_link_click"),&EditorAddonLibraryItemDescription::_link_click); + +} + +void EditorAddonLibraryItemDescription::_link_click(const String& p_url) { + + ERR_FAIL_COND(!p_url.begins_with("http")); + OS::get_singleton()->shell_open(p_url); } -void EditorAddonLibraryItemDescription::configure(const String& p_title,int p_asset_id,const String& p_category,int p_category_id,const String& p_author,int p_author_id,int p_rating,const String& p_cost,const String& p_description) { +void EditorAddonLibraryItemDescription::configure(const String& p_title,int p_asset_id,const String& p_category,int p_category_id,const String& p_author,int p_author_id,int p_rating,const String& p_cost,const String& p_version,const String& p_description,const String& p_download_url,const String& p_browse_url) { + asset_id=p_asset_id; + title=p_title; + download_url=p_download_url; item->configure(p_title,p_asset_id,p_category,p_category_id,p_author,p_author_id,p_rating,p_cost); - description->parse_bbcode(p_description); + description->clear(); + description->add_text("Version: "+p_version+"\n"); + description->add_text("Contents: "); + description->push_meta(p_browse_url); + description->add_text("View Files"); + description->pop(); + description->add_text("\nDescription:\n\n"); + description->append_bbcode(p_description); set_title(p_title); } @@ -215,6 +234,7 @@ EditorAddonLibraryItemDescription::EditorAddonLibraryItemDescription() { desc_bg->set_v_size_flags(SIZE_EXPAND_FILL); description = memnew( RichTextLabel ); + description->connect("meta_clicked",this,"_link_click"); //desc_vbox->add_child(description); desc_bg->add_child(description); desc_bg->add_style_override("panel",get_stylebox("normal","TextEdit")); @@ -242,6 +262,205 @@ EditorAddonLibraryItemDescription::EditorAddonLibraryItemDescription() { } +/////////////////////////////////////////////////////////////////////////////////// + +void EditorAddonLibraryItemDownload::_http_download_completed(int p_status, int p_code, const StringArray& headers, const ByteArray& p_data) { + + + String error_text; + + switch(p_status) { + + case HTTPRequest::RESULT_CANT_RESOLVE: { + error_text=("Can't resolve hostname: "+host); + status->set_text("Can't resolve."); + } break; + case HTTPRequest::RESULT_BODY_SIZE_LIMIT_EXCEEDED: + case HTTPRequest::RESULT_CONNECTION_ERROR: + case HTTPRequest::RESULT_CHUNKED_BODY_SIZE_MISMATCH: { + error_text=("Connection error, please try again."); + status->set_text("Can't connect."); + } break; + case HTTPRequest::RESULT_SSL_HANDSHAKE_ERROR: + case HTTPRequest::RESULT_CANT_CONNECT: { + error_text=("Can't connect to host: "+host); + status->set_text("Can't connect."); + } break; + case HTTPRequest::RESULT_NO_RESPONSE: { + error_text=("No response from host: "+host); + status->set_text("No response."); + } break; + case HTTPRequest::RESULT_REQUEST_FAILED: { + error_text=("Request failed, return code: "+itos(p_code)); + status->set_text("Req. Failed."); + } break; + case HTTPRequest::RESULT_REDIRECT_LIMIT_REACHED: { + error_text=("Request failed, too many redirects"); + status->set_text("Redirect Loop."); + } break; + default: { + if (p_code!=200) { + error_text=("Request failed, return code: "+itos(p_code)); + status->set_text("Failed: "+itos(p_code)); + } else { + + //all good + } + } break; + + } + + if (error_text!=String()) { + download_error->set_text("Asset Download Error:\n"+error_text); + download_error->popup_centered_minsize(); + return; + + } + + progress->set_max( download->get_body_size() ); + progress->set_val(download->get_downloaded_bytes()); + + print_line("max: "+itos(download->get_body_size())+" bytes: "+itos(download->get_downloaded_bytes())); + install->set_disabled(false); + + status->set_text("Success!"); + set_process(false); +} + + +void EditorAddonLibraryItemDownload::configure(const String& p_title,int p_asset_id,const Ref<Texture>& p_preview, const String& p_download_url) { + + title->set_text(p_title); + icon->set_texture(p_preview); + asset_id=p_asset_id; + if (!p_preview.is_valid()) + icon->set_texture(get_icon("GodotAssetDefault","EditorIcons")); + + host=p_download_url; + set_process(true); + download->set_download_file(EditorSettings::get_singleton()->get_settings_path().plus_file("tmp").plus_file("tmp_asset_"+itos(p_asset_id))+".zip"); + Error err = download->request(p_download_url); + ERR_FAIL_COND(err!=OK); + asset_installer->connect("confirmed",this,"_close"); + dismiss->set_normal_texture(get_icon("Close","EditorIcons")); + + +} + + +void EditorAddonLibraryItemDownload::_notification(int p_what) { + + if (p_what==NOTIFICATION_PROCESS) { + + progress->set_max( download->get_body_size() ); + progress->set_val(download->get_downloaded_bytes()); + + int cstatus = download->get_http_client_status(); + if (cstatus!=prev_status) { + switch(cstatus) { + + case HTTPClient::STATUS_RESOLVING: { + status->set_text("Resolving.."); + } break; + case HTTPClient::STATUS_CONNECTING: { + status->set_text("Connecting.."); + } break; + case HTTPClient::STATUS_REQUESTING: { + status->set_text("Requesting.."); + } break; + case HTTPClient::STATUS_BODY: { + status->set_text("Downloading.."); + } break; + default: {} + } + prev_status=cstatus; + } + + } +} +void EditorAddonLibraryItemDownload::_close() { + + DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + da->remove(download->get_download_file()); //clean up removed file + memdelete(da); + queue_delete(); +} + +void EditorAddonLibraryItemDownload::_install() { + + String file = download->get_download_file(); + asset_installer->open(file,1); +} + +void EditorAddonLibraryItemDownload::_bind_methods() { + + ObjectTypeDB::bind_method("_http_download_completed",&EditorAddonLibraryItemDownload::_http_download_completed); + ObjectTypeDB::bind_method("_install",&EditorAddonLibraryItemDownload::_install); + ObjectTypeDB::bind_method("_close",&EditorAddonLibraryItemDownload::_close); + +} + +EditorAddonLibraryItemDownload::EditorAddonLibraryItemDownload() { + + HBoxContainer *hb = memnew( HBoxContainer); + add_child(hb); + icon = memnew( TextureFrame ); + hb->add_child(icon); + + VBoxContainer *vb = memnew( VBoxContainer ); + hb->add_child(vb); + vb->set_h_size_flags(SIZE_EXPAND_FILL); + + HBoxContainer *title_hb = memnew( HBoxContainer); + vb->add_child(title_hb); + title = memnew( Label ); + title_hb->add_child(title); + title->set_h_size_flags(SIZE_EXPAND_FILL); + + dismiss = memnew( TextureButton ); + dismiss->connect("pressed",this,"_close"); + title_hb->add_child(dismiss); + + title->set_clip_text(true); + + vb->add_spacer(); + + status = memnew (Label("Idle")); + vb->add_child(status); + status->add_color_override("font_color", Color(0.5,0.5,0.5) ); + progress = memnew( ProgressBar ); + vb->add_child(progress); + + + + HBoxContainer *hb2 = memnew( HBoxContainer ); + vb->add_child(hb2); + hb2->add_spacer(); + + install = memnew( Button ); + install->set_text("Install"); + install->set_disabled(true); + install->connect("pressed",this,"_install"); + + hb2->add_child(install); + set_custom_minimum_size(Size2(250,0)); + + download = memnew( HTTPRequest ); + add_child(download); + download->connect("request_completed",this,"_http_download_completed"); + + download_error = memnew( AcceptDialog ); + add_child(download_error); + download_error->set_title("Download Error"); + + asset_installer = memnew( EditorAssetInstaller ); + add_child(asset_installer); + + prev_status=-1; + + +} + //////////////////////////////////////////////////////////////////////////////// @@ -261,7 +480,7 @@ void EditorAddonLibrary::_notification(int p_what) { HTTPClient::Status s = request->get_http_client_status(); bool visible = s!=HTTPClient::STATUS_DISCONNECTED; - if (visible !=load_status->is_visible()) { + if (visible != !load_status->is_hidden()) { load_status->set_hidden(!visible); } @@ -280,14 +499,41 @@ void EditorAddonLibrary::_notification(int p_what) { case HTTPClient::STATUS_BODY: { load_status->set_val(0.4); } break; + default: {} } } + + bool no_downloads = downloads_hb->get_child_count()==0; + if (no_downloads != downloads_scroll->is_hidden()) { + downloads_scroll->set_hidden(no_downloads); + } } } +void EditorAddonLibrary::_install_asset() { + + ERR_FAIL_COND(!description); + + for(int i=0;i<downloads_hb->get_child_count();i++) { + + EditorAddonLibraryItemDownload *d = downloads_hb->get_child(i)->cast_to<EditorAddonLibraryItemDownload>(); + if (d && d->get_asset_id() == description->get_asset_id()) { + + EditorNode::get_singleton()->show_warning("Download for this asset is already in progress!"); + return; + } + } + + + EditorAddonLibraryItemDownload * download = memnew( EditorAddonLibraryItemDownload ); + downloads_hb->add_child(download); + download->configure(description->get_title(),description->get_asset_id(),description->get_preview_icon(),description->get_download_url()); + +} + const char* EditorAddonLibrary::sort_key[SORT_MAX]={ "rating", "downloads", @@ -708,15 +954,23 @@ void EditorAddonLibrary::_http_request_completed(int p_status, int p_code, const Dictionary r = d["info"]; + r["download_url"]="https://github.com/reduz/godot-test-addon/archive/master.zip"; + r["browse_url"]="https://github.com/reduz/godot-test-addon"; + r["version"]="1.1"; + ERR_FAIL_COND(!r.has("title")); ERR_FAIL_COND(!r.has("asset_id")); ERR_FAIL_COND(!r.has("author")); ERR_FAIL_COND(!r.has("author_id")); + ERR_FAIL_COND(!r.has("version")); ERR_FAIL_COND(!r.has("category")); ERR_FAIL_COND(!r.has("category_id")); ERR_FAIL_COND(!r.has("rating")); ERR_FAIL_COND(!r.has("cost")); ERR_FAIL_COND(!r.has("description")); + ERR_FAIL_COND(!r.has("download_url")); + ERR_FAIL_COND(!r.has("browse_url")); + if (description) { memdelete(description); @@ -725,8 +979,9 @@ void EditorAddonLibrary::_http_request_completed(int p_status, int p_code, const description = memnew( EditorAddonLibraryItemDescription ); add_child(description); description->popup_centered_minsize(); + description->connect("confirmed",this,"_install_asset"); - description->configure(r["title"],r["asset_id"],r["category"],r["category_id"],r["author"],r["author_id"],r["rating"],r["cost"],r["description"]); + description->configure(r["title"],r["asset_id"],r["category"],r["category_id"],r["author"],r["author_id"],r["rating"],r["cost"],r["version"],r["description"],r["download_url"],r["browse_url"]); /*item->connect("asset_selected",this,"_select_asset"); item->connect("author_selected",this,"_select_author"); item->connect("category_selected",this,"_category_selected");*/ @@ -764,6 +1019,34 @@ void EditorAddonLibrary::_http_request_completed(int p_status, int p_code, const } + +void EditorAddonLibrary::_asset_file_selected(const String& p_file) { + + if (asset_installer) { + memdelete( asset_installer ); + asset_installer=NULL; + } + + asset_installer = memnew( EditorAssetInstaller ); + add_child(asset_installer); + asset_installer->open(p_file); + + +} + +void EditorAddonLibrary::_asset_open() { + + asset_open->popup_centered_ratio(); +} + +void EditorAddonLibrary::_manage_plugins() { + + ProjectSettings::get_singleton()->popup_project_settings(); + ProjectSettings::get_singleton()->set_plugins_page(); +} + + + void EditorAddonLibrary::_bind_methods() { ObjectTypeDB::bind_method("_http_request_completed",&EditorAddonLibrary::_http_request_completed); @@ -772,40 +1055,35 @@ void EditorAddonLibrary::_bind_methods() { ObjectTypeDB::bind_method("_select_category",&EditorAddonLibrary::_select_category); ObjectTypeDB::bind_method("_image_request_completed",&EditorAddonLibrary::_image_request_completed); ObjectTypeDB::bind_method("_search",&EditorAddonLibrary::_search,DEFVAL(0)); + ObjectTypeDB::bind_method("_install_asset",&EditorAddonLibrary::_install_asset); + ObjectTypeDB::bind_method("_manage_plugins",&EditorAddonLibrary::_manage_plugins); + ObjectTypeDB::bind_method("_asset_open",&EditorAddonLibrary::_asset_open); + ObjectTypeDB::bind_method("_asset_file_selected",&EditorAddonLibrary::_asset_file_selected); } EditorAddonLibrary::EditorAddonLibrary() { - tabs = memnew( TabContainer ); - tabs->set_v_size_flags(SIZE_EXPAND_FILL); - add_child(tabs); - - installed = memnew( EditorPluginSettings ); - installed->set_name("Installed"); - tabs->add_child(installed); Ref<StyleBoxEmpty> border; border.instance(); border->set_default_margin(MARGIN_LEFT,15); border->set_default_margin(MARGIN_RIGHT,15); - border->set_default_margin(MARGIN_BOTTOM,15); + border->set_default_margin(MARGIN_BOTTOM,5); border->set_default_margin(MARGIN_TOP,5); - PanelContainer *margin_panel = memnew( PanelContainer ); - - margin_panel->set_name("Online"); - margin_panel->add_style_override("panel",border); - tabs->add_child(margin_panel); + add_style_override("panel",border); VBoxContainer *library_main = memnew( VBoxContainer ); - margin_panel->add_child(library_main); + add_child(library_main); HBoxContainer *search_hb = memnew( HBoxContainer ); library_main->add_child(search_hb); - library_main->add_constant_override("separation",20); + library_main->add_constant_override("separation",10); + + search_hb->add_child( memnew( Label("Search: "))); filter =memnew( LineEdit ); @@ -815,6 +1093,20 @@ EditorAddonLibrary::EditorAddonLibrary() { search = memnew( Button("Search")); search->connect("pressed",this,"_search"); search_hb->add_child(search); + + search_hb->add_child(memnew( VSeparator )); + + Button * open_asset = memnew( Button ); + open_asset->set_text("Import"); + search_hb->add_child(open_asset); + open_asset->connect("pressed",this,"_asset_open"); + + Button * plugins = memnew( Button ); + plugins->set_text("Plugins"); + search_hb->add_child(plugins); + plugins->connect("pressed",this,"_manage_plugins"); + + library_vb->add_child(search_hb); HBoxContainer *search_hb2 = memnew( HBoxContainer ); @@ -907,6 +1199,7 @@ EditorAddonLibrary::EditorAddonLibrary() { add_child(request); request->connect("request_completed",this,"_http_request_completed"); + last_queue_id=0; library_vb->add_constant_override("separation",20); @@ -928,6 +1221,24 @@ EditorAddonLibrary::EditorAddonLibrary() { //host="http://localhost:8000"; host="http://godotengine.org/addonlib"; set_process(true); + + downloads_scroll = memnew( ScrollContainer ); + downloads_scroll->set_enable_h_scroll(true); + downloads_scroll->set_enable_v_scroll(false); + library_main->add_child(downloads_scroll); + downloads_hb = memnew( HBoxContainer ); + downloads_scroll->add_child(downloads_hb); + + asset_open = memnew( EditorFileDialog ); + + asset_open->set_access(EditorFileDialog::ACCESS_FILESYSTEM); + asset_open->add_filter("*.zip ; Assets ZIP File"); + asset_open->set_mode(EditorFileDialog::MODE_OPEN_FILE); + add_child(asset_open); + asset_open->connect("file_selected",this,"_asset_file_selected"); + + asset_installer=NULL; + } diff --git a/tools/editor/addon_editor_plugin.h b/tools/editor/addon_editor_plugin.h index 2a3ffb576e..9cd604a319 100644 --- a/tools/editor/addon_editor_plugin.h +++ b/tools/editor/addon_editor_plugin.h @@ -20,6 +20,7 @@ #include "editor_plugin_settings.h" #include "scene/main/http_request.h" +#include "editor_asset_installer.h" class EditorAssetLibraryItem : public PanelContainer { @@ -77,25 +78,79 @@ class EditorAddonLibraryItemDescription : public ConfirmationDialog { void set_image(int p_type,int p_index,const Ref<Texture>& p_image); + int asset_id; + String download_url; + String title; + Ref<Texture> icon; + + void _link_click(const String& p_url); protected: static void _bind_methods(); public: - void configure(const String& p_title,int p_asset_id,const String& p_category,int p_category_id,const String& p_author,int p_author_id,int p_rating,const String& p_cost,const String& p_description); + void configure(const String& p_title,int p_asset_id,const String& p_category,int p_category_id,const String& p_author,int p_author_id,int p_rating,const String& p_cost,const String& p_version,const String& p_description,const String& p_download_url,const String& p_browse_url); void add_preview(int p_id, bool p_video,const String& p_url); + String get_title() { return title; } + Ref<Texture> get_preview_icon() { return icon; } + String get_download_url() { return download_url; } + int get_asset_id() { return asset_id; } EditorAddonLibraryItemDescription(); }; -class EditorAddonLibrary : public VBoxContainer { - OBJ_TYPE(EditorAddonLibrary,VBoxContainer); +class EditorAddonLibraryItemDownload : public PanelContainer { + + OBJ_TYPE(EditorAddonLibraryItemDownload, PanelContainer); + + + TextureFrame *icon; + Label* title; + ProgressBar *progress; + Button *install; + TextureButton *dismiss; + + AcceptDialog *download_error; + HTTPRequest *download; + String host; + Label *status; + + int prev_status; + + int asset_id; + + EditorAssetInstaller *asset_installer; + + void _close(); + void _install(); + void _http_download_completed(int p_status, int p_code, const StringArray& headers, const ByteArray& p_data); + +protected: + + void _notification(int p_what); + static void _bind_methods(); +public: + + int get_asset_id() { return asset_id; } + void configure(const String& p_title,int p_asset_id,const Ref<Texture>& p_preview, const String& p_download_url); + EditorAddonLibraryItemDownload(); + +}; + +class EditorAddonLibrary : public PanelContainer { + OBJ_TYPE(EditorAddonLibrary,PanelContainer); String host; - TabContainer *tabs; - EditorPluginSettings *installed; + EditorFileDialog *asset_open; + EditorAssetInstaller *asset_installer; + + + void _asset_open(); + void _asset_file_selected(const String& p_file); + + ScrollContainer *library_scroll; VBoxContainer *library_vb; LineEdit *filter; @@ -116,6 +171,7 @@ class EditorAddonLibrary : public VBoxContainer { HTTPRequest *request; + enum SortOrder { SORT_RATING, SORT_DOWNLOADS, @@ -155,6 +211,7 @@ class EditorAddonLibrary : public VBoxContainer { void _image_request_completed(int p_status, int p_code, const StringArray& headers, const ByteArray& p_data, int p_queue_id); + void _request_image(ObjectID p_for,int p_asset_id,ImageType p_type,int p_image_index); void _update_image_queue(); @@ -174,13 +231,24 @@ class EditorAddonLibrary : public VBoxContainer { RequestType requesting; + + ScrollContainer *downloads_scroll; + HBoxContainer *downloads_hb; + + + + void _install_asset(); + void _select_author(int p_id); void _select_category(int p_id); void _select_asset(int p_id); + void _manage_plugins(); + void _search(int p_page=0); void _api_request(const String& p_request, const String &p_arguments=""); void _http_request_completed(int p_status, int p_code, const StringArray& headers, const ByteArray& p_data); + void _http_download_completed(int p_status, int p_code, const StringArray& headers, const ByteArray& p_data); friend class EditorAddonLibraryItemDescription; friend class EditorAssetLibraryItem; diff --git a/tools/editor/editor_asset_installer.cpp b/tools/editor/editor_asset_installer.cpp new file mode 100644 index 0000000000..2967abbc0a --- /dev/null +++ b/tools/editor/editor_asset_installer.cpp @@ -0,0 +1,327 @@ +#include "editor_asset_installer.h" +#include "io/zip_io.h" +#include "os/dir_access.h" +#include "os/file_access.h" +#include "editor_node.h" +void EditorAssetInstaller::_update_subitems(TreeItem* p_item,bool p_check,bool p_first) { + + + if (p_check) { + if (p_item->get_custom_color(0)==Color()) { + p_item->set_checked(0,true); + } + } else { + p_item->set_checked(0,false); + + } + + if (p_item->get_children()) { + _update_subitems(p_item->get_children(),p_check); + } + + if (!p_first && p_item->get_next()) { + _update_subitems(p_item->get_next(),p_check); + } + +} + +void EditorAssetInstaller::_item_edited() { + + + if (updating) + return; + + TreeItem *item = tree->get_edited(); + if (!item) + return; + + + String path=item->get_metadata(0); + + updating=true; + if (path==String()) { //a dir + _update_subitems(item,item->is_checked(0),true); + } + + if (item->is_checked(0)) { + while(item) { + item->set_checked(0,true); + item=item->get_parent(); + } + + } + updating=false; + +} + +void EditorAssetInstaller::open(const String& p_path,int p_depth) { + + + package_path=p_path; + Set<String> files_sorted; + + FileAccess *src_f=NULL; + zlib_filefunc_def io = zipio_create_io_from_file(&src_f); + + unzFile pkg = unzOpen2(p_path.utf8().get_data(), &io); + if (!pkg) { + + error->set_text("Error opening package file, not in zip format."); + return; + } + + int ret = unzGoToFirstFile(pkg); + + + while(ret==UNZ_OK) { + + //get filename + unz_file_info info; + char fname[16384]; + ret = unzGetCurrentFileInfo(pkg,&info,fname,16384,NULL,0,NULL,0); + + String name=fname; + files_sorted.insert(name); + + ret = unzGoToNextFile(pkg); + } + + + Map<String,Ref<Texture> > extension_guess; + { + extension_guess["png"]=get_icon("Texture","EditorIcons"); + extension_guess["jpg"]=get_icon("Texture","EditorIcons"); + extension_guess["tex"]=get_icon("Texture","EditorIcons"); + extension_guess["atex"]=get_icon("Texture","EditorIcons"); + extension_guess["dds"]=get_icon("Texture","EditorIcons"); + extension_guess["scn"]=get_icon("PackedScene","EditorIcons"); + extension_guess["tscn"]=get_icon("PackedScene","EditorIcons"); + extension_guess["xml"]=get_icon("PackedScene","EditorIcons"); + extension_guess["xscn"]=get_icon("PackedScene","EditorIcons"); + extension_guess["mtl"]=get_icon("Material","EditorIcons"); + extension_guess["shd"]=get_icon("Shader","EditorIcons"); + extension_guess["gd"]=get_icon("GDScript","EditorIcons"); + } + + Ref<Texture> generic_extension = get_icon("Object","EditorIcons"); + + + unzClose(pkg); + + updating=true; + tree->clear(); + TreeItem *root=tree->create_item(); + root->set_cell_mode(0,TreeItem::CELL_MODE_CHECK); + root->set_checked(0,true); + root->set_icon(0,get_icon("folder","FileDialog")); + root->set_text(0,"res://"); + root->set_editable(0,true); + Map<String,TreeItem*> dir_map; + + for(Set<String>::Element *E=files_sorted.front();E;E=E->next()) { + + String path = E->get(); + int depth=p_depth; + bool skip=false; + while(depth>0) { + int pp = path.find("/"); + if (pp==-1) { + skip=true; + break; + } + path=path.substr(pp+1,path.length()); + depth--; + } + + if (skip || path==String()) + continue; + + bool isdir=false; + + if (path.ends_with("/")) { + //a directory + path=path.substr(0,path.length()-1); + isdir=true; + } + + int pp = path.find_last("/"); + + + TreeItem *parent; + if (pp==-1) { + parent=root; + } else { + String ppath=path.substr(0,pp); + print_line("PPATH IS: "+ppath); + ERR_CONTINUE(!dir_map.has(ppath)); + parent=dir_map[ppath]; + + } + + TreeItem *ti = tree->create_item(parent); + ti->set_cell_mode(0,TreeItem::CELL_MODE_CHECK); + ti->set_checked(0,true); + ti->set_editable(0,true); + if (isdir) { + dir_map[path]=ti; + ti->set_text(0,path.get_file()+"/"); + ti->set_icon(0,get_icon("folder","FileDialog")); + } else { + String file = path.get_file(); + String extension = file.extension().to_lower(); + if (extension_guess.has(extension)) { + ti->set_icon(0,extension_guess[extension]); + } else { + ti->set_icon(0,generic_extension); + } + ti->set_text(0,file); + + + String res_path = "res://"+path; + if (FileAccess::exists(res_path)) { + ti->set_custom_color(0,Color(1,0.3,0.2)); + ti->set_tooltip(0,res_path+" (Already Exists)"); + ti->set_checked(0,false); + } else { + ti->set_tooltip(0,res_path); + + } + + ti->set_metadata(0,res_path); + + } + + status_map[E->get()]=ti; + + + + } + popup_centered_ratio(); + updating=false; + +} + +void EditorAssetInstaller::ok_pressed() { + + FileAccess *src_f=NULL; + zlib_filefunc_def io = zipio_create_io_from_file(&src_f); + + unzFile pkg = unzOpen2(package_path.utf8().get_data(), &io); + if (!pkg) { + + error->set_text("Error opening package file, not in zip format."); + return; + } + + int ret = unzGoToFirstFile(pkg); + + Vector<String> failed_files; + + ProgressDialog::get_singleton()->add_task("uncompress","Uncompressing Assets",status_map.size()); + + int idx=0; + while(ret==UNZ_OK) { + + //get filename + unz_file_info info; + char fname[16384]; + ret = unzGetCurrentFileInfo(pkg,&info,fname,16384,NULL,0,NULL,0); + + String name=fname; + + if (status_map.has(name) && status_map[name]->is_checked(0)) { + + String path = status_map[name]->get_metadata(0); + if (path==String()) { // a dir + + String dirpath; + TreeItem *t = status_map[name]; + while(t) { + dirpath=t->get_text(0)+dirpath; + t=t->get_parent(); + } + + if (dirpath.ends_with("/")) { + dirpath=dirpath.substr(0,dirpath.length()-1); + } + + DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES); + da->make_dir(dirpath); + memdelete(da); + + } else { + + Vector<uint8_t> data; + data.resize(info.uncompressed_size); + + //read + unzOpenCurrentFile(pkg); + unzReadCurrentFile(pkg,data.ptr(),data.size()); + unzCloseCurrentFile(pkg); + + FileAccess *f=FileAccess::open(path,FileAccess::WRITE); + if (f) { + f->store_buffer(data.ptr(),data.size()); + memdelete(f); + } else { + failed_files.push_back(path); + } + + ProgressDialog::get_singleton()->task_step("uncompress",path,idx); + } + + } + + idx++; + ret = unzGoToNextFile(pkg); + } + + ProgressDialog::get_singleton()->end_task("uncompress"); + unzClose(pkg); + + if (failed_files.size()) { + String msg="The following files failed extraction from package:\n\n"; + for(int i=0;i<failed_files.size();i++) { + + if (i>15) { + msg+="\nAnd "+itos(failed_files.size()-i)+" more files."; + break; + } + msg+=failed_files[i]; + } + EditorNode::get_singleton()->show_warning(msg); + } else { + EditorNode::get_singleton()->show_warning("Package Installed Successfully!","Success!"); + } + + + + +} + +void EditorAssetInstaller::_bind_methods() { + + ObjectTypeDB::bind_method("_item_edited",&EditorAssetInstaller::_item_edited); + +} + +EditorAssetInstaller::EditorAssetInstaller() { + + VBoxContainer *vb = memnew( VBoxContainer ); + add_child(vb); + set_child_rect(vb); + + tree = memnew( Tree ); + vb->add_margin_child("Package Contents:",tree,true); + tree->connect("item_edited",this,"_item_edited"); + + error = memnew( AcceptDialog) ; + add_child(error); + get_ok()->set_text("Install"); + set_title("Package Installer"); + + updating=false; + + set_hide_on_ok(true); +} + diff --git a/tools/editor/editor_asset_installer.h b/tools/editor/editor_asset_installer.h new file mode 100644 index 0000000000..713c5f14f1 --- /dev/null +++ b/tools/editor/editor_asset_installer.h @@ -0,0 +1,28 @@ +#ifndef EDITORASSETINSTALLER_H +#define EDITORASSETINSTALLER_H + + +#include "scene/gui/dialogs.h" +#include "scene/gui/tree.h" +class EditorAssetInstaller : public ConfirmationDialog { + + OBJ_TYPE( EditorAssetInstaller, ConfirmationDialog ); + + Tree *tree; + String package_path; + AcceptDialog *error; + Map<String,TreeItem*> status_map; + bool updating; + void _update_subitems(TreeItem* p_item,bool p_check,bool p_first=false); + void _item_edited(); + virtual void ok_pressed(); +protected: + + static void _bind_methods(); +public: + + void open(const String& p_path,int p_depth=0); + EditorAssetInstaller(); +}; + +#endif // EDITORASSETINSTALLER_H diff --git a/tools/editor/editor_initialize_ssl.cpp b/tools/editor/editor_initialize_ssl.cpp new file mode 100644 index 0000000000..e0602a88c7 --- /dev/null +++ b/tools/editor/editor_initialize_ssl.cpp @@ -0,0 +1,21 @@ +#include "editor_initialize_ssl.h" +#include "certs_compressed.h" +#include "io/stream_peer_ssl.h" +#include "io/compression.h" + +void editor_initialize_certificates() { + + + ByteArray data; + data.resize(_certs_uncompressed_size); + { + ByteArray::Write w = data.write(); + Compression::decompress(w.ptr(),_certs_uncompressed_size,_certs_compressed,_certs_compressed_size,Compression::MODE_DEFLATE); + } + + StreamPeerSSL::load_certs_from_memory(data); + + +} + + diff --git a/tools/editor/editor_initialize_ssl.h b/tools/editor/editor_initialize_ssl.h new file mode 100644 index 0000000000..4eaf387a0a --- /dev/null +++ b/tools/editor/editor_initialize_ssl.h @@ -0,0 +1,6 @@ +#ifndef EDITOR_INITIALIZE_SSL_H +#define EDITOR_INITIALIZE_SSL_H + +void editor_initialize_certificates(); + +#endif // EDITOR_INITIALIZE_SSL_H diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp index dfc1c7455c..02b0e9447a 100644 --- a/tools/editor/editor_node.cpp +++ b/tools/editor/editor_node.cpp @@ -107,7 +107,7 @@ #include "tools/editor/io_plugins/editor_export_scene.h" #include "plugins/editor_preview_plugins.h" - +#include "editor_initialize_ssl.h" #include "script_editor_debugger.h" EditorNode *EditorNode::singleton=NULL; @@ -4145,9 +4145,10 @@ Error EditorNode::export_platform(const String& p_platform, const String& p_path return OK; } -void EditorNode::show_warning(const String& p_text) { +void EditorNode::show_warning(const String& p_text, const String &p_title) { warning->set_text(p_text); + warning->set_title(p_title); warning->popup_centered_minsize(); } @@ -4950,6 +4951,7 @@ EditorNode::EditorNode() { EditorHelp::generate_doc(); //before any editor classes are crated SceneState::set_disable_placeholders(true); + editor_initialize_certificates(); //for asset sharing InputDefault *id = Input::get_singleton()->cast_to<InputDefault>(); diff --git a/tools/editor/editor_node.h b/tools/editor/editor_node.h index 5d26bae369..b8fabb4c55 100644 --- a/tools/editor/editor_node.h +++ b/tools/editor/editor_node.h @@ -655,7 +655,7 @@ public: Ref<Theme> get_editor_theme() const { return theme; } - void show_warning(const String& p_text); + void show_warning(const String& p_text,const String& p_title="Warning!"); Error export_platform(const String& p_platform, const String& p_path, bool p_debug,const String& p_password,bool p_quit_after=false); diff --git a/tools/editor/icons/icon_rating_no_star.png b/tools/editor/icons/icon_rating_no_star.png Binary files differindex 35bfe6a5c6..76f1127ccc 100644 --- a/tools/editor/icons/icon_rating_no_star.png +++ b/tools/editor/icons/icon_rating_no_star.png diff --git a/tools/editor/icons/icon_rating_star.png b/tools/editor/icons/icon_rating_star.png Binary files differindex c4ed418ebd..ff52bddba0 100644 --- a/tools/editor/icons/icon_rating_star.png +++ b/tools/editor/icons/icon_rating_star.png diff --git a/tools/editor/progress_dialog.cpp b/tools/editor/progress_dialog.cpp index d072ce7f83..2814101a27 100644 --- a/tools/editor/progress_dialog.cpp +++ b/tools/editor/progress_dialog.cpp @@ -140,6 +140,9 @@ void BackgroundProgress::end_task(const String& p_task){ //////////////////////////////////////////////// + +ProgressDialog *ProgressDialog::singleton=NULL; + void ProgressDialog::_notification(int p_what) { switch(p_what) { @@ -237,4 +240,5 @@ ProgressDialog::ProgressDialog() { main->set_area_as_parent_rect(); set_exclusive(true); last_progress_tick=0; + singleton=this; } diff --git a/tools/editor/progress_dialog.h b/tools/editor/progress_dialog.h index 539eaa8737..c254d45753 100644 --- a/tools/editor/progress_dialog.h +++ b/tools/editor/progress_dialog.h @@ -86,12 +86,14 @@ class ProgressDialog : public Popup { VBoxContainer *main; uint64_t last_progress_tick; + static ProgressDialog *singleton; void _popup(); protected: void _notification(int p_what); public: + static ProgressDialog *get_singleton() { return singleton; } void add_task(const String& p_task,const String& p_label, int p_steps); void task_step(const String& p_task, const String& p_state, int p_step=-1, bool p_force_redraw=true); void end_task(const String& p_task); diff --git a/tools/editor/project_settings.cpp b/tools/editor/project_settings.cpp index 4a7388fd54..34bc31d20c 100644 --- a/tools/editor/project_settings.cpp +++ b/tools/editor/project_settings.cpp @@ -1396,6 +1396,11 @@ void ProjectSettings::_clear_search_box() { globals_editor->get_property_editor()->update_tree(); } +void ProjectSettings::set_plugins_page() { + + tab_container->set_current_tab( plugin_settings->get_index() ); +} + void ProjectSettings::_bind_methods() { ObjectTypeDB::bind_method(_MD("_item_selected"),&ProjectSettings::_item_selected); @@ -1452,7 +1457,7 @@ ProjectSettings::ProjectSettings(EditorData *p_data) { data=p_data; - TabContainer *tab_container = memnew( TabContainer ); + tab_container = memnew( TabContainer ); add_child(tab_container); set_child_rect(tab_container); diff --git a/tools/editor/project_settings.h b/tools/editor/project_settings.h index 922608fb9a..113cc49b7c 100644 --- a/tools/editor/project_settings.h +++ b/tools/editor/project_settings.h @@ -34,7 +34,7 @@ #include "optimized_save_dialog.h" #include "undo_redo.h" #include "editor_data.h" - +#include "scene/gui/tab_container.h" #include "editor_plugin_settings.h" //#include "project_export_settings.h" @@ -42,6 +42,9 @@ class ProjectSettings : public AcceptDialog { OBJ_TYPE( ProjectSettings, AcceptDialog ); + + TabContainer *tab_container; + Timer *timer; InputEvent::Type add_type; String add_at; @@ -164,6 +167,7 @@ public: void add_translation(const String& p_translation); static ProjectSettings *get_singleton() { return singleton; } void popup_project_settings(); + void set_plugins_page(); void queue_save(); |