summaryrefslogtreecommitdiff
path: root/tools/editor
diff options
context:
space:
mode:
Diffstat (limited to 'tools/editor')
-rw-r--r--tools/editor/SCsub28
-rw-r--r--tools/editor/addon_editor_plugin.cpp351
-rw-r--r--tools/editor/addon_editor_plugin.h78
-rw-r--r--tools/editor/editor_asset_installer.cpp327
-rw-r--r--tools/editor/editor_asset_installer.h28
-rw-r--r--tools/editor/editor_initialize_ssl.cpp21
-rw-r--r--tools/editor/editor_initialize_ssl.h6
-rw-r--r--tools/editor/editor_node.cpp6
-rw-r--r--tools/editor/editor_node.h2
-rw-r--r--tools/editor/icons/icon_rating_no_star.pngbin476 -> 288 bytes
-rw-r--r--tools/editor/icons/icon_rating_star.pngbin896 -> 289 bytes
-rw-r--r--tools/editor/progress_dialog.cpp4
-rw-r--r--tools/editor/progress_dialog.h2
-rw-r--r--tools/editor/project_settings.cpp7
-rw-r--r--tools/editor/project_settings.h6
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
index 35bfe6a5c6..76f1127ccc 100644
--- a/tools/editor/icons/icon_rating_no_star.png
+++ b/tools/editor/icons/icon_rating_no_star.png
Binary files differ
diff --git a/tools/editor/icons/icon_rating_star.png b/tools/editor/icons/icon_rating_star.png
index c4ed418ebd..ff52bddba0 100644
--- a/tools/editor/icons/icon_rating_star.png
+++ b/tools/editor/icons/icon_rating_star.png
Binary files differ
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();