forked from sascha/godot
Merge branch 'master' of https://github.com/okamstudio/godot
commit
63033aa646
@ -0,0 +1 @@
|
||||
filter=false
|
||||
@ -1,6 +0,0 @@
|
||||
/** Automatically generated file. DO NOT MODIFY */
|
||||
package com.android.vending.expansion.downloader;
|
||||
|
||||
public final class BuildConfig {
|
||||
public final static boolean DEBUG = false;
|
||||
}
|
||||
@ -1,73 +0,0 @@
|
||||
/* AUTO-GENERATED FILE. DO NOT MODIFY.
|
||||
*
|
||||
* This class was automatically generated by the
|
||||
* aapt tool from the resource data it found. It
|
||||
* should not be modified by hand.
|
||||
*/
|
||||
|
||||
package com.android.vending.expansion.downloader;
|
||||
|
||||
public final class R {
|
||||
public static final class attr {
|
||||
}
|
||||
public static final class drawable {
|
||||
public static int notify_panel_notification_icon_bg=0x7f020000;
|
||||
}
|
||||
public static final class id {
|
||||
public static int appIcon=0x7f060001;
|
||||
public static int description=0x7f060007;
|
||||
public static int notificationLayout=0x7f060000;
|
||||
public static int progress_bar=0x7f060006;
|
||||
public static int progress_bar_frame=0x7f060005;
|
||||
public static int progress_text=0x7f060002;
|
||||
public static int time_remaining=0x7f060004;
|
||||
public static int title=0x7f060003;
|
||||
}
|
||||
public static final class layout {
|
||||
public static int status_bar_ongoing_event_progress_bar=0x7f030000;
|
||||
}
|
||||
public static final class string {
|
||||
public static int kilobytes_per_second=0x7f040014;
|
||||
/** When a download completes, a notification is displayed, and this
|
||||
string is used to indicate that the download successfully completed.
|
||||
Note that such a download could have been initiated by a variety of
|
||||
applications, including (but not limited to) the browser, an email
|
||||
application, a content marketplace.
|
||||
*/
|
||||
public static int notification_download_complete=0x7f040000;
|
||||
/** When a download completes, a notification is displayed, and this
|
||||
string is used to indicate that the download failed.
|
||||
Note that such a download could have been initiated by a variety of
|
||||
applications, including (but not limited to) the browser, an email
|
||||
application, a content marketplace.
|
||||
*/
|
||||
public static int notification_download_failed=0x7f040001;
|
||||
public static int state_completed=0x7f040007;
|
||||
public static int state_connecting=0x7f040005;
|
||||
public static int state_downloading=0x7f040006;
|
||||
public static int state_failed=0x7f040013;
|
||||
public static int state_failed_cancelled=0x7f040012;
|
||||
public static int state_failed_fetching_url=0x7f040010;
|
||||
public static int state_failed_sdcard_full=0x7f040011;
|
||||
public static int state_failed_unlicensed=0x7f04000f;
|
||||
public static int state_fetching_url=0x7f040004;
|
||||
public static int state_idle=0x7f040003;
|
||||
public static int state_paused_by_request=0x7f04000a;
|
||||
public static int state_paused_network_setup_failure=0x7f040009;
|
||||
public static int state_paused_network_unavailable=0x7f040008;
|
||||
public static int state_paused_roaming=0x7f04000d;
|
||||
public static int state_paused_sdcard_unavailable=0x7f04000e;
|
||||
public static int state_paused_wifi_disabled=0x7f04000c;
|
||||
public static int state_paused_wifi_unavailable=0x7f04000b;
|
||||
public static int state_unknown=0x7f040002;
|
||||
public static int time_remaining=0x7f040015;
|
||||
public static int time_remaining_notification=0x7f040016;
|
||||
}
|
||||
public static final class style {
|
||||
public static int ButtonBackground=0x7f050003;
|
||||
public static int NotificationText=0x7f050000;
|
||||
public static int NotificationTextSecondary=0x7f050004;
|
||||
public static int NotificationTextShadow=0x7f050001;
|
||||
public static int NotificationTitle=0x7f050002;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,74 @@
|
||||
#include "instance_placeholder.h"
|
||||
|
||||
#include "scene/resources/packed_scene.h"
|
||||
#include "io/resource_loader.h"
|
||||
|
||||
bool InstancePlaceholder::_set(const StringName& p_name, const Variant& p_value) {
|
||||
|
||||
PropSet ps;
|
||||
ps.name=p_name;
|
||||
ps.value=p_value;
|
||||
stored_values.push_back(ps);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InstancePlaceholder::_get(const StringName& p_name,Variant &r_ret) const{
|
||||
|
||||
return false;
|
||||
}
|
||||
void InstancePlaceholder::_get_property_list( List<PropertyInfo> *p_list) const{
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void InstancePlaceholder::set_path(const String& p_name) {
|
||||
|
||||
path=p_name;
|
||||
}
|
||||
|
||||
String InstancePlaceholder::get_path() const {
|
||||
|
||||
return path;
|
||||
}
|
||||
void InstancePlaceholder::replace_by_instance(const Ref<PackedScene> &p_custom_scene){
|
||||
|
||||
ERR_FAIL_COND(!is_inside_tree());
|
||||
|
||||
Node *base = get_parent();
|
||||
if (!base)
|
||||
return;
|
||||
|
||||
Ref<PackedScene> ps;
|
||||
if (p_custom_scene.is_valid())
|
||||
ps = p_custom_scene;
|
||||
else
|
||||
ps = ResourceLoader::load(path,"PackedScene");
|
||||
|
||||
if (!ps.is_valid())
|
||||
return;
|
||||
Node *scene = ps->instance();
|
||||
scene->set_name(get_name());
|
||||
int pos = get_position_in_parent();
|
||||
|
||||
for(List<PropSet>::Element *E=stored_values.front();E;E=E->next()) {
|
||||
scene->set(E->get().name,E->get().value);
|
||||
}
|
||||
|
||||
queue_delete();
|
||||
|
||||
base->remove_child(this);
|
||||
base->add_child(scene);
|
||||
base->move_child(scene,pos);
|
||||
|
||||
}
|
||||
|
||||
void InstancePlaceholder::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("replace_by_instance","custom_scene:PackedScene"),&InstancePlaceholder::replace_by_instance,DEFVAL(Variant()));
|
||||
}
|
||||
|
||||
InstancePlaceholder::InstancePlaceholder() {
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
#ifndef INSTANCE_PLACEHOLDER_H
|
||||
#define INSTANCE_PLACEHOLDER_H
|
||||
|
||||
#include "scene/main/node.h"
|
||||
|
||||
class PackedScene;
|
||||
|
||||
class InstancePlaceholder : public Node {
|
||||
|
||||
OBJ_TYPE(InstancePlaceholder,Node);
|
||||
|
||||
String path;
|
||||
struct PropSet {
|
||||
StringName name;
|
||||
Variant value;
|
||||
};
|
||||
|
||||
List<PropSet> stored_values;
|
||||
|
||||
protected:
|
||||
bool _set(const StringName& p_name, const Variant& p_value);
|
||||
bool _get(const StringName& p_name,Variant &r_ret) const;
|
||||
void _get_property_list( List<PropertyInfo> *p_list) const;
|
||||
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
|
||||
void set_path(const String& p_name);
|
||||
String get_path() const;
|
||||
|
||||
void replace_by_instance(const Ref<PackedScene>& p_custom_scene=Ref<PackedScene>());
|
||||
|
||||
InstancePlaceholder();
|
||||
};
|
||||
|
||||
#endif // INSTANCE_PLACEHOLDER_H
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,792 @@
|
||||
#include "scene_format_text.h"
|
||||
|
||||
#include "globals.h"
|
||||
#include "version.h"
|
||||
#include "os/dir_access.h"
|
||||
|
||||
#define FORMAT_VERSION 1
|
||||
|
||||
void ResourceFormatSaverTextInstance::write_property(const String& p_name,const Variant& p_property,bool *r_ok) {
|
||||
|
||||
if (r_ok)
|
||||
*r_ok=false;
|
||||
|
||||
if (p_name!=String()) {
|
||||
f->store_string(p_name+" = ");
|
||||
}
|
||||
|
||||
switch( p_property.get_type() ) {
|
||||
|
||||
case Variant::NIL: {
|
||||
f->store_string("null");
|
||||
} break;
|
||||
case Variant::BOOL: {
|
||||
|
||||
f->store_string(p_property.operator bool() ? "true":"false" );
|
||||
} break;
|
||||
case Variant::INT: {
|
||||
|
||||
f->store_string( itos(p_property.operator int()) );
|
||||
} break;
|
||||
case Variant::REAL: {
|
||||
|
||||
f->store_string( rtoss(p_property.operator real_t()) );
|
||||
} break;
|
||||
case Variant::STRING: {
|
||||
|
||||
String str=p_property;
|
||||
|
||||
str="\""+str.c_escape()+"\"";
|
||||
f->store_string( str );
|
||||
} break;
|
||||
case Variant::VECTOR2: {
|
||||
|
||||
Vector2 v = p_property;
|
||||
f->store_string("Vector2( "+rtoss(v.x) +", "+rtoss(v.y)+" )" );
|
||||
} break;
|
||||
case Variant::RECT2: {
|
||||
|
||||
Rect2 aabb = p_property;
|
||||
f->store_string("Rect2( "+rtoss(aabb.pos.x) +", "+rtoss(aabb.pos.y) +", "+rtoss(aabb.size.x) +", "+rtoss(aabb.size.y)+" )" );
|
||||
|
||||
} break;
|
||||
case Variant::VECTOR3: {
|
||||
|
||||
Vector3 v = p_property;
|
||||
f->store_string("Vector3( "+rtoss(v.x) +", "+rtoss(v.y)+", "+rtoss(v.z)+" )");
|
||||
} break;
|
||||
case Variant::PLANE: {
|
||||
|
||||
Plane p = p_property;
|
||||
f->store_string("Plane( "+rtoss(p.normal.x) +", "+rtoss(p.normal.y)+", "+rtoss(p.normal.z)+", "+rtoss(p.d)+" )" );
|
||||
|
||||
} break;
|
||||
case Variant::_AABB: {
|
||||
|
||||
AABB aabb = p_property;
|
||||
f->store_string("AABB( "+rtoss(aabb.pos.x) +", "+rtoss(aabb.pos.y) +", "+rtoss(aabb.pos.z) +", "+rtoss(aabb.size.x) +", "+rtoss(aabb.size.y) +", "+rtoss(aabb.size.z)+" )" );
|
||||
|
||||
} break;
|
||||
case Variant::QUAT: {
|
||||
|
||||
Quat quat = p_property;
|
||||
f->store_string("Quat( "+rtoss(quat.x)+", "+rtoss(quat.y)+", "+rtoss(quat.z)+", "+rtoss(quat.w)+" )");
|
||||
|
||||
} break;
|
||||
case Variant::MATRIX32: {
|
||||
|
||||
String s="Matrix32( ";
|
||||
Matrix32 m3 = p_property;
|
||||
for (int i=0;i<3;i++) {
|
||||
for (int j=0;j<2;j++) {
|
||||
|
||||
if (i!=0 || j!=0)
|
||||
s+=", ";
|
||||
s+=rtoss( m3.elements[i][j] );
|
||||
}
|
||||
}
|
||||
|
||||
f->store_string(s+" )");
|
||||
|
||||
} break;
|
||||
case Variant::MATRIX3: {
|
||||
|
||||
String s="Matrix3( ";
|
||||
Matrix3 m3 = p_property;
|
||||
for (int i=0;i<3;i++) {
|
||||
for (int j=0;j<3;j++) {
|
||||
|
||||
if (i!=0 || j!=0)
|
||||
s+=", ";
|
||||
s+=rtoss( m3.elements[i][j] );
|
||||
}
|
||||
}
|
||||
|
||||
f->store_string(s+" )");
|
||||
|
||||
} break;
|
||||
case Variant::TRANSFORM: {
|
||||
|
||||
String s="Transform( ";
|
||||
Transform t = p_property;
|
||||
Matrix3 &m3 = t.basis;
|
||||
for (int i=0;i<3;i++) {
|
||||
for (int j=0;j<3;j++) {
|
||||
|
||||
if (i!=0 || j!=0)
|
||||
s+=", ";
|
||||
s+=rtoss( m3.elements[i][j] );
|
||||
}
|
||||
}
|
||||
|
||||
s=s+", "+rtoss(t.origin.x) +", "+rtoss(t.origin.y)+", "+rtoss(t.origin.z);
|
||||
|
||||
f->store_string(s+" )");
|
||||
} break;
|
||||
|
||||
// misc types
|
||||
case Variant::COLOR: {
|
||||
|
||||
Color c = p_property;
|
||||
f->store_string("Color( "+rtoss(c.r) +", "+rtoss(c.g)+", "+rtoss(c.b)+", "+rtoss(c.a)+" )");
|
||||
|
||||
} break;
|
||||
case Variant::IMAGE: {
|
||||
|
||||
|
||||
Image img=p_property;
|
||||
|
||||
if (img.empty()) {
|
||||
f->store_string("RawImage()");
|
||||
break;
|
||||
}
|
||||
|
||||
String imgstr="RawImage( ";
|
||||
imgstr+=itos(img.get_width());
|
||||
imgstr+=", "+itos(img.get_height());
|
||||
imgstr+=", "+itos(img.get_mipmaps());
|
||||
imgstr+=", ";
|
||||
|
||||
switch(img.get_format()) {
|
||||
|
||||
case Image::FORMAT_GRAYSCALE: imgstr+="GRAYSCALE"; break;
|
||||
case Image::FORMAT_INTENSITY: imgstr+="INTENSITY"; break;
|
||||
case Image::FORMAT_GRAYSCALE_ALPHA: imgstr+="GRAYSCALE_ALPHA"; break;
|
||||
case Image::FORMAT_RGB: imgstr+="RGB"; break;
|
||||
case Image::FORMAT_RGBA: imgstr+="RGBA"; break;
|
||||
case Image::FORMAT_INDEXED : imgstr+="INDEXED"; break;
|
||||
case Image::FORMAT_INDEXED_ALPHA: imgstr+="INDEXED_ALPHA"; break;
|
||||
case Image::FORMAT_BC1: imgstr+="BC1"; break;
|
||||
case Image::FORMAT_BC2: imgstr+="BC2"; break;
|
||||
case Image::FORMAT_BC3: imgstr+="BC3"; break;
|
||||
case Image::FORMAT_BC4: imgstr+="BC4"; break;
|
||||
case Image::FORMAT_BC5: imgstr+="BC5"; break;
|
||||
case Image::FORMAT_PVRTC2: imgstr+="PVRTC2"; break;
|
||||
case Image::FORMAT_PVRTC2_ALPHA: imgstr+="PVRTC2_ALPHA"; break;
|
||||
case Image::FORMAT_PVRTC4: imgstr+="PVRTC4"; break;
|
||||
case Image::FORMAT_PVRTC4_ALPHA: imgstr+="PVRTC4_ALPHA"; break;
|
||||
case Image::FORMAT_ETC: imgstr+="ETC"; break;
|
||||
case Image::FORMAT_ATC: imgstr+="ATC"; break;
|
||||
case Image::FORMAT_ATC_ALPHA_EXPLICIT: imgstr+="ATC_ALPHA_EXPLICIT"; break;
|
||||
case Image::FORMAT_ATC_ALPHA_INTERPOLATED: imgstr+="ATC_ALPHA_INTERPOLATED"; break;
|
||||
case Image::FORMAT_CUSTOM: imgstr+="CUSTOM"; break;
|
||||
default: {}
|
||||
}
|
||||
|
||||
|
||||
String s;
|
||||
|
||||
DVector<uint8_t> data = img.get_data();
|
||||
int len = data.size();
|
||||
DVector<uint8_t>::Read r = data.read();
|
||||
const uint8_t *ptr=r.ptr();;
|
||||
for (int i=0;i<len;i++) {
|
||||
|
||||
uint8_t byte = ptr[i];
|
||||
const char hex[16]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
|
||||
char str[3]={ hex[byte>>4], hex[byte&0xF], 0};
|
||||
s+=str;
|
||||
}
|
||||
|
||||
imgstr+=", ";
|
||||
f->store_string(imgstr);
|
||||
f->store_string(s);
|
||||
f->store_string(" )");
|
||||
} break;
|
||||
case Variant::NODE_PATH: {
|
||||
|
||||
String str=p_property;
|
||||
|
||||
str="NodePath(\""+str.c_escape()+"\")";
|
||||
f->store_string(str);
|
||||
|
||||
} break;
|
||||
|
||||
case Variant::OBJECT: {
|
||||
|
||||
RES res = p_property;
|
||||
if (res.is_null()) {
|
||||
f->store_string("null");
|
||||
if (r_ok)
|
||||
*r_ok=true;
|
||||
|
||||
break; // don't save it
|
||||
}
|
||||
|
||||
if (external_resources.has(res)) {
|
||||
|
||||
f->store_string("ExtResource( "+itos(external_resources[res]+1)+" )");
|
||||
} else {
|
||||
|
||||
if (internal_resources.has(res)) {
|
||||
f->store_string("SubResource( "+itos(internal_resources[res])+" )");
|
||||
} else if (res->get_path().length() && res->get_path().find("::")==-1) {
|
||||
|
||||
//external resource
|
||||
String path=relative_paths?local_path.path_to_file(res->get_path()):res->get_path();
|
||||
f->store_string("Resource( \""+path+"\" )");
|
||||
} else {
|
||||
f->store_string("null");
|
||||
ERR_EXPLAIN("Resource was not pre cached for the resource section, bug?");
|
||||
ERR_BREAK(true);
|
||||
//internal resource
|
||||
}
|
||||
}
|
||||
|
||||
} break;
|
||||
case Variant::INPUT_EVENT: {
|
||||
|
||||
f->store_string("InputEvent()"); //will be added later
|
||||
} break;
|
||||
case Variant::DICTIONARY: {
|
||||
|
||||
Dictionary dict = p_property;
|
||||
|
||||
List<Variant> keys;
|
||||
dict.get_key_list(&keys);
|
||||
keys.sort();
|
||||
|
||||
f->store_string("{ ");
|
||||
for(List<Variant>::Element *E=keys.front();E;E=E->next()) {
|
||||
|
||||
//if (!_check_type(dict[E->get()]))
|
||||
// continue;
|
||||
bool ok;
|
||||
write_property("",E->get(),&ok);
|
||||
ERR_CONTINUE(!ok);
|
||||
|
||||
f->store_string(":");
|
||||
write_property("",dict[E->get()],&ok);
|
||||
if (!ok)
|
||||
write_property("",Variant()); //at least make the file consistent..
|
||||
if (E->next())
|
||||
f->store_string(", ");
|
||||
}
|
||||
|
||||
|
||||
f->store_string(" }");
|
||||
|
||||
|
||||
} break;
|
||||
case Variant::ARRAY: {
|
||||
|
||||
f->store_string("[ ");
|
||||
Array array = p_property;
|
||||
int len=array.size();
|
||||
for (int i=0;i<len;i++) {
|
||||
|
||||
if (i>0)
|
||||
f->store_string(", ");
|
||||
write_property("",array[i]);
|
||||
|
||||
|
||||
}
|
||||
f->store_string(" ]");
|
||||
|
||||
} break;
|
||||
|
||||
case Variant::RAW_ARRAY: {
|
||||
|
||||
f->store_string("RawArray( ");
|
||||
String s;
|
||||
DVector<uint8_t> data = p_property;
|
||||
int len = data.size();
|
||||
DVector<uint8_t>::Read r = data.read();
|
||||
const uint8_t *ptr=r.ptr();;
|
||||
for (int i=0;i<len;i++) {
|
||||
|
||||
if (i>0)
|
||||
f->store_string(", ");
|
||||
uint8_t byte = ptr[i];
|
||||
const char hex[16]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
|
||||
char str[3]={ hex[byte>>4], hex[byte&0xF], 0};
|
||||
f->store_string(str);
|
||||
|
||||
}
|
||||
|
||||
f->store_string(" )");
|
||||
|
||||
} break;
|
||||
case Variant::INT_ARRAY: {
|
||||
|
||||
f->store_string("IntArray( ");
|
||||
DVector<int> data = p_property;
|
||||
int len = data.size();
|
||||
DVector<int>::Read r = data.read();
|
||||
const int *ptr=r.ptr();;
|
||||
|
||||
for (int i=0;i<len;i++) {
|
||||
|
||||
if (i>0)
|
||||
f->store_string(", ");
|
||||
|
||||
f->store_string(itos(ptr[i]));
|
||||
}
|
||||
|
||||
|
||||
f->store_string(" )");
|
||||
|
||||
} break;
|
||||
case Variant::REAL_ARRAY: {
|
||||
|
||||
f->store_string("FloatArray( ");
|
||||
DVector<real_t> data = p_property;
|
||||
int len = data.size();
|
||||
DVector<real_t>::Read r = data.read();
|
||||
const real_t *ptr=r.ptr();;
|
||||
|
||||
for (int i=0;i<len;i++) {
|
||||
|
||||
if (i>0)
|
||||
f->store_string(", ");
|
||||
f->store_string(rtoss(ptr[i]));
|
||||
}
|
||||
|
||||
f->store_string(" )");
|
||||
|
||||
} break;
|
||||
case Variant::STRING_ARRAY: {
|
||||
|
||||
f->store_string("StringArray( ");
|
||||
DVector<String> data = p_property;
|
||||
int len = data.size();
|
||||
DVector<String>::Read r = data.read();
|
||||
const String *ptr=r.ptr();;
|
||||
String s;
|
||||
//write_string("\n");
|
||||
|
||||
|
||||
|
||||
for (int i=0;i<len;i++) {
|
||||
|
||||
if (i>0)
|
||||
f->store_string(", ");
|
||||
String str=ptr[i];
|
||||
f->store_string(""+str.c_escape()+"\"");
|
||||
}
|
||||
|
||||
f->store_string(" )");
|
||||
|
||||
} break;
|
||||
case Variant::VECTOR2_ARRAY: {
|
||||
|
||||
f->store_string("Vector2Array( ");
|
||||
DVector<Vector2> data = p_property;
|
||||
int len = data.size();
|
||||
DVector<Vector2>::Read r = data.read();
|
||||
const Vector2 *ptr=r.ptr();;
|
||||
|
||||
for (int i=0;i<len;i++) {
|
||||
|
||||
if (i>0)
|
||||
f->store_string(", ");
|
||||
f->store_string(rtoss(ptr[i].x)+", "+rtoss(ptr[i].y) );
|
||||
}
|
||||
|
||||
f->store_string(" )");
|
||||
|
||||
} break;
|
||||
case Variant::VECTOR3_ARRAY: {
|
||||
|
||||
f->store_string("Vector3Array( ");
|
||||
DVector<Vector3> data = p_property;
|
||||
int len = data.size();
|
||||
DVector<Vector3>::Read r = data.read();
|
||||
const Vector3 *ptr=r.ptr();;
|
||||
|
||||
for (int i=0;i<len;i++) {
|
||||
|
||||
if (i>0)
|
||||
f->store_string(", ");
|
||||
f->store_string(rtoss(ptr[i].x)+", "+rtoss(ptr[i].y)+", "+rtoss(ptr[i].z) );
|
||||
}
|
||||
|
||||
f->store_string(" )");
|
||||
|
||||
} break;
|
||||
case Variant::COLOR_ARRAY: {
|
||||
|
||||
f->store_string("ColorArray( ");
|
||||
|
||||
DVector<Color> data = p_property;
|
||||
int len = data.size();
|
||||
DVector<Color>::Read r = data.read();
|
||||
const Color *ptr=r.ptr();;
|
||||
|
||||
for (int i=0;i<len;i++) {
|
||||
|
||||
if (i>0)
|
||||
f->store_string(", ");
|
||||
|
||||
f->store_string(rtoss(ptr[i].r)+", "+rtoss(ptr[i].g)+", "+rtoss(ptr[i].b)+", "+rtoss(ptr[i].a) );
|
||||
|
||||
}
|
||||
f->store_string(" )");
|
||||
|
||||
} break;
|
||||
default: {}
|
||||
|
||||
}
|
||||
|
||||
if (r_ok)
|
||||
*r_ok=true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void ResourceFormatSaverTextInstance::_find_resources(const Variant& p_variant,bool p_main) {
|
||||
|
||||
|
||||
switch(p_variant.get_type()) {
|
||||
case Variant::OBJECT: {
|
||||
|
||||
|
||||
RES res = p_variant.operator RefPtr();
|
||||
|
||||
if (res.is_null() || external_resources.has(res))
|
||||
return;
|
||||
|
||||
if (!p_main && (!bundle_resources ) && res->get_path().length() && res->get_path().find("::") == -1 ) {
|
||||
int index = external_resources.size();
|
||||
external_resources[res]=index;
|
||||
return;
|
||||
}
|
||||
|
||||
if (resource_set.has(res))
|
||||
return;
|
||||
|
||||
List<PropertyInfo> property_list;
|
||||
|
||||
res->get_property_list( &property_list );
|
||||
property_list.sort();
|
||||
|
||||
List<PropertyInfo>::Element *I=property_list.front();
|
||||
|
||||
while(I) {
|
||||
|
||||
PropertyInfo pi=I->get();
|
||||
|
||||
if (pi.usage&PROPERTY_USAGE_STORAGE || (bundle_resources && pi.usage&PROPERTY_USAGE_BUNDLE)) {
|
||||
|
||||
Variant v=res->get(I->get().name);
|
||||
_find_resources(v);
|
||||
}
|
||||
|
||||
I=I->next();
|
||||
}
|
||||
|
||||
resource_set.insert( res ); //saved after, so the childs it needs are available when loaded
|
||||
saved_resources.push_back(res);
|
||||
|
||||
} break;
|
||||
case Variant::ARRAY: {
|
||||
|
||||
Array varray=p_variant;
|
||||
int len=varray.size();
|
||||
for(int i=0;i<len;i++) {
|
||||
|
||||
Variant v=varray.get(i);
|
||||
_find_resources(v);
|
||||
}
|
||||
|
||||
} break;
|
||||
case Variant::DICTIONARY: {
|
||||
|
||||
Dictionary d=p_variant;
|
||||
List<Variant> keys;
|
||||
d.get_key_list(&keys);
|
||||
for(List<Variant>::Element *E=keys.front();E;E=E->next()) {
|
||||
|
||||
Variant v = d[E->get()];
|
||||
_find_resources(v);
|
||||
}
|
||||
} break;
|
||||
default: {}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
Error ResourceFormatSaverTextInstance::save(const String &p_path,const RES& p_resource,uint32_t p_flags) {
|
||||
|
||||
if (p_path.ends_with(".tscn")) {
|
||||
packed_scene=p_resource;
|
||||
}
|
||||
|
||||
Error err;
|
||||
f = FileAccess::open(p_path, FileAccess::WRITE,&err);
|
||||
ERR_FAIL_COND_V( err, ERR_CANT_OPEN );
|
||||
FileAccessRef _fref(f);
|
||||
|
||||
local_path = Globals::get_singleton()->localize_path(p_path);
|
||||
|
||||
relative_paths=p_flags&ResourceSaver::FLAG_RELATIVE_PATHS;
|
||||
skip_editor=p_flags&ResourceSaver::FLAG_OMIT_EDITOR_PROPERTIES;
|
||||
bundle_resources=p_flags&ResourceSaver::FLAG_BUNDLE_RESOURCES;
|
||||
takeover_paths=p_flags&ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS;
|
||||
if (!p_path.begins_with("res://")) {
|
||||
takeover_paths=false;
|
||||
}
|
||||
|
||||
// save resources
|
||||
_find_resources(p_resource,true);
|
||||
|
||||
if (packed_scene.is_valid()) {
|
||||
//add instances to external resources if saving a packed scene
|
||||
for(int i=0;i<packed_scene->get_state()->get_node_count();i++) {
|
||||
Ref<PackedScene> instance=packed_scene->get_state()->get_node_instance(i);
|
||||
if (instance.is_valid() && !external_resources.has(instance)) {
|
||||
int index = external_resources.size();
|
||||
external_resources[instance]=index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ERR_FAIL_COND_V(err!=OK,err);
|
||||
|
||||
{
|
||||
String title=packed_scene.is_valid()?"[gd_scene ":"[gd_resource ";
|
||||
if (packed_scene.is_null())
|
||||
title+="type=\""+p_resource->get_type()+"\" ";
|
||||
int load_steps=saved_resources.size()+external_resources.size();
|
||||
//if (packed_scene.is_valid()) {
|
||||
// load_steps+=packed_scene->get_node_count();
|
||||
//}
|
||||
//no, better to not use load steps from nodes, no point to that
|
||||
|
||||
if (load_steps>1) {
|
||||
title+="load_steps="+itos(load_steps)+" ";
|
||||
}
|
||||
title+="format="+itos(FORMAT_VERSION)+"";
|
||||
//title+="engine_version=\""+itos(VERSION_MAJOR)+"."+itos(VERSION_MINOR)+"\"";
|
||||
|
||||
f->store_string(title);
|
||||
f->store_line("]\n"); //one empty line
|
||||
}
|
||||
|
||||
|
||||
for(Map<RES,int>::Element *E=external_resources.front();E;E=E->next()) {
|
||||
|
||||
String p = E->key()->get_path();
|
||||
|
||||
f->store_string("[ext_resource path=\""+p+"\" type=\""+E->key()->get_save_type()+"\" id="+itos(E->get()+1)+"]\n"); //bundled
|
||||
}
|
||||
|
||||
if (external_resources.size())
|
||||
f->store_line(String()); //separate
|
||||
|
||||
Set<int> used_indices;
|
||||
|
||||
for(List<RES>::Element *E=saved_resources.front();E;E=E->next()) {
|
||||
|
||||
RES res = E->get();
|
||||
if (E->next() && (res->get_path()=="" || res->get_path().find("::") != -1 )) {
|
||||
|
||||
if (res->get_subindex()!=0) {
|
||||
if (used_indices.has(res->get_subindex())) {
|
||||
res->set_subindex(0); //repeated
|
||||
} else {
|
||||
used_indices.insert(res->get_subindex());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(List<RES>::Element *E=saved_resources.front();E;E=E->next()) {
|
||||
|
||||
RES res = E->get();
|
||||
ERR_CONTINUE(!resource_set.has(res));
|
||||
bool main = (E->next()==NULL);
|
||||
|
||||
if (main && packed_scene.is_valid())
|
||||
break; //save as a scene
|
||||
|
||||
if (main) {
|
||||
f->store_line("[resource]\n");
|
||||
} else {
|
||||
String line="[sub_resource ";
|
||||
if (res->get_subindex()==0) {
|
||||
int new_subindex=1;
|
||||
if (used_indices.size()) {
|
||||
new_subindex=used_indices.back()->get()+1;
|
||||
}
|
||||
|
||||
res->set_subindex(new_subindex);
|
||||
used_indices.insert(new_subindex);
|
||||
}
|
||||
|
||||
int idx = res->get_subindex();
|
||||
line+="type=\""+res->get_type()+"\" id="+itos(idx);
|
||||
f->store_line(line+"]\n");
|
||||
if (takeover_paths) {
|
||||
res->set_path(p_path+"::"+itos(idx),true);
|
||||
}
|
||||
|
||||
internal_resources[res]=idx;
|
||||
|
||||
}
|
||||
|
||||
|
||||
List<PropertyInfo> property_list;
|
||||
res->get_property_list(&property_list);
|
||||
// property_list.sort();
|
||||
for(List<PropertyInfo>::Element *PE = property_list.front();PE;PE=PE->next()) {
|
||||
|
||||
|
||||
if (skip_editor && PE->get().name.begins_with("__editor"))
|
||||
continue;
|
||||
|
||||
if (PE->get().usage&PROPERTY_USAGE_STORAGE || (bundle_resources && PE->get().usage&PROPERTY_USAGE_BUNDLE)) {
|
||||
|
||||
String name = PE->get().name;
|
||||
Variant value = res->get(name);
|
||||
|
||||
|
||||
if ((PE->get().usage&PROPERTY_USAGE_STORE_IF_NONZERO && value.is_zero())||(PE->get().usage&PROPERTY_USAGE_STORE_IF_NONONE && value.is_one()) )
|
||||
continue;
|
||||
|
||||
if (PE->get().type==Variant::OBJECT && value.is_zero())
|
||||
continue;
|
||||
|
||||
write_property(name,value);
|
||||
f->store_string("\n");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
f->store_string("\n");
|
||||
|
||||
}
|
||||
|
||||
if (packed_scene.is_valid()) {
|
||||
//if this is a scene, save nodes and connections!
|
||||
Ref<SceneState> state = packed_scene->get_state();
|
||||
for(int i=0;i<state->get_node_count();i++) {
|
||||
|
||||
StringName type = state->get_node_type(i);
|
||||
StringName name = state->get_node_name(i);
|
||||
NodePath path = state->get_node_path(i,true);
|
||||
NodePath owner = state->get_node_owner_path(i);
|
||||
Ref<PackedScene> instance = state->get_node_instance(i);
|
||||
Vector<StringName> groups = state->get_node_groups(i);
|
||||
|
||||
String header="[node";
|
||||
header+=" name=\""+String(name)+"\"";
|
||||
if (type!=StringName()) {
|
||||
header+=" type=\""+String(type)+"\"";
|
||||
}
|
||||
if (path!=NodePath()) {
|
||||
header+=" parent=\""+String(path.simplified())+"\"";
|
||||
}
|
||||
if (owner!=NodePath() && owner!=NodePath(".")) {
|
||||
header+=" owner=\""+String(owner.simplified())+"\"";
|
||||
}
|
||||
|
||||
if (groups.size()) {
|
||||
String sgroups=" groups=[ ";
|
||||
for(int j=0;j<groups.size();j++) {
|
||||
if (j>0)
|
||||
sgroups+=", ";
|
||||
sgroups+="\""+groups[i].operator String().c_escape()+"\"";
|
||||
}
|
||||
sgroups+=" ]";
|
||||
header+=sgroups;
|
||||
}
|
||||
|
||||
f->store_string(header);
|
||||
|
||||
if (instance.is_valid()) {
|
||||
f->store_string(" instance=");
|
||||
write_property("",instance);
|
||||
}
|
||||
|
||||
f->store_line("]\n");
|
||||
|
||||
for(int j=0;j<state->get_node_property_count(i);j++) {
|
||||
|
||||
write_property(state->get_node_property_name(i,j),state->get_node_property_value(i,j));
|
||||
f->store_line(String());
|
||||
|
||||
}
|
||||
|
||||
if (state->get_node_property_count(i)) {
|
||||
//add space
|
||||
f->store_line(String());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for(int i=0;i<state->get_connection_count();i++) {
|
||||
|
||||
String connstr="[connection";
|
||||
connstr+=" signal=\""+String(state->get_connection_signal(i))+"\"";
|
||||
connstr+=" from=\""+String(state->get_connection_source(i).simplified())+"\"";
|
||||
connstr+=" to=\""+String(state->get_connection_target(i).simplified())+"\"";
|
||||
connstr+=" method=\""+String(state->get_connection_method(i))+"\"";
|
||||
int flags = state->get_connection_flags(i);
|
||||
if (flags!=Object::CONNECT_PERSIST) {
|
||||
connstr+=" flags="+itos(flags);
|
||||
}
|
||||
|
||||
Array binds=state->get_connection_binds(i);
|
||||
f->store_string(connstr);
|
||||
if (binds.size()) {
|
||||
f->store_string(" binds=");
|
||||
write_property("",binds);
|
||||
}
|
||||
|
||||
f->store_line("]\n");
|
||||
}
|
||||
|
||||
f->store_line(String());
|
||||
|
||||
Vector<NodePath> editable_instances = state->get_editable_instances();
|
||||
for(int i=0;i<editable_instances.size();i++) {
|
||||
f->store_line("[editable path=\""+editable_instances[i].operator String()+"\"]");
|
||||
}
|
||||
}
|
||||
|
||||
if (f->get_error()!=OK && f->get_error()!=ERR_FILE_EOF) {
|
||||
f->close();
|
||||
return ERR_CANT_CREATE;
|
||||
}
|
||||
|
||||
f->close();
|
||||
//memdelete(f);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Error ResourceFormatSaverText::save(const String &p_path,const RES& p_resource,uint32_t p_flags) {
|
||||
|
||||
if (p_path.ends_with(".sct") && p_resource->get_type()!="PackedScene") {
|
||||
return ERR_FILE_UNRECOGNIZED;
|
||||
}
|
||||
|
||||
ResourceFormatSaverTextInstance saver;
|
||||
return saver.save(p_path,p_resource,p_flags);
|
||||
|
||||
}
|
||||
|
||||
bool ResourceFormatSaverText::recognize(const RES& p_resource) const {
|
||||
|
||||
|
||||
return true; // all recognized!
|
||||
}
|
||||
void ResourceFormatSaverText::get_recognized_extensions(const RES& p_resource,List<String> *p_extensions) const {
|
||||
|
||||
p_extensions->push_back("tres"); //text resource
|
||||
if (p_resource->get_type()=="PackedScene")
|
||||
p_extensions->push_back("tscn"); //text scene
|
||||
|
||||
}
|
||||
|
||||
ResourceFormatSaverText* ResourceFormatSaverText::singleton=NULL;
|
||||
ResourceFormatSaverText::ResourceFormatSaverText() {
|
||||
singleton=this;
|
||||
}
|
||||
@ -0,0 +1,46 @@
|
||||
#ifndef SCENE_FORMAT_TEXT_H
|
||||
#define SCENE_FORMAT_TEXT_H
|
||||
|
||||
#include "io/resource_loader.h"
|
||||
#include "io/resource_saver.h"
|
||||
#include "os/file_access.h"
|
||||
#include "scene/resources/packed_scene.h"
|
||||
|
||||
class ResourceFormatSaverTextInstance {
|
||||
|
||||
String local_path;
|
||||
|
||||
Ref<PackedScene> packed_scene;
|
||||
|
||||
bool takeover_paths;
|
||||
bool relative_paths;
|
||||
bool bundle_resources;
|
||||
bool skip_editor;
|
||||
FileAccess *f;
|
||||
Set<RES> resource_set;
|
||||
List<RES> saved_resources;
|
||||
Map<RES,int> external_resources;
|
||||
Map<RES,int> internal_resources;
|
||||
|
||||
void _find_resources(const Variant& p_variant,bool p_main=false);
|
||||
void write_property(const String& p_name,const Variant& p_property,bool *r_ok=NULL);
|
||||
|
||||
public:
|
||||
|
||||
Error save(const String &p_path,const RES& p_resource,uint32_t p_flags=0);
|
||||
|
||||
|
||||
};
|
||||
|
||||
class ResourceFormatSaverText : public ResourceFormatSaver {
|
||||
public:
|
||||
static ResourceFormatSaverText* singleton;
|
||||
virtual Error save(const String &p_path,const RES& p_resource,uint32_t p_flags=0);
|
||||
virtual bool recognize(const RES& p_resource) const;
|
||||
virtual void get_recognized_extensions(const RES& p_resource,List<String> *p_extensions) const;
|
||||
|
||||
ResourceFormatSaverText();
|
||||
};
|
||||
|
||||
|
||||
#endif // SCENE_FORMAT_TEXT_H
|
||||
Binary file not shown.
@ -0,0 +1,142 @@
|
||||
# Translations template for PROJECT.
|
||||
# Copyright (C) 2015 ORGANIZATION
|
||||
# This file is distributed under the same license as the PROJECT project.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2015.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: makedocs\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2015-10-07 11:47-0600\n"
|
||||
"PO-Revision-Date: 2015-10-07 13:10-0600\n"
|
||||
"Last-Translator: Jorge Araya Navarro <elcorreo@deshackra.com>\n"
|
||||
"Language-Team: \n"
|
||||
"Language: es\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 2.0\n"
|
||||
"X-Generator: Poedit 1.8.4\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: makedocs.py:74
|
||||
msgid ""
|
||||
"\"<code>{gclass}</code>(Go to page of class {gclass})\":/class_{lkclass}"
|
||||
msgstr ""
|
||||
"\"<code>{gclass}</code>(Ir a la pagina de la clase {gclass})\":/"
|
||||
"class_{lkclass}"
|
||||
|
||||
#: makedocs.py:76
|
||||
msgid ""
|
||||
"\"<code>{gclass}.{method}</code>(Go to page {gclass}, section {method})\":/"
|
||||
"class_{lkclass}#{lkmethod}"
|
||||
msgstr ""
|
||||
"\"<code>{gclass}.{method}</code>(Ir a la pagina {gclass}, sección "
|
||||
"{method})\":/class_{lkclass}#{lkmethod}"
|
||||
|
||||
#: makedocs.py:79
|
||||
msgid "\"<code>{method}</code>(Jump to method {method})\":#{lkmethod}"
|
||||
msgstr "\"<code>{method}</code>(Saltar al método {method})\":#{lkmethod}"
|
||||
|
||||
#: makedocs.py:81
|
||||
msgid " \"{rtype}(Go to page of class {rtype})\":/class_{link} "
|
||||
msgstr " \"{rtype}(Ir a la pagina de la clase {rtype})\":/class_{link} "
|
||||
|
||||
#: makedocs.py:82
|
||||
msgid ""
|
||||
"\"*{funcname}*(Jump to description for node {funcname})\":#{link} <b>(</b> "
|
||||
msgstr ""
|
||||
"\"*{funcname}*(Saltar a la descripción para el nodo {funcname})\":#{link} "
|
||||
"<b>(</b> "
|
||||
|
||||
#: makedocs.py:87
|
||||
msgid "h4. Inherits: "
|
||||
msgstr "h4. Hereda de: "
|
||||
|
||||
#: makedocs.py:232
|
||||
msgid "<doc>'s version attribute missing"
|
||||
msgstr "El atributo version de <doc> no existe"
|
||||
|
||||
#: makedocs.py:246
|
||||
msgid "|_. Index symbol |_. Class name |_. Index symbol |_. Class name |\n"
|
||||
msgstr ""
|
||||
"|_. Índice de símbolo |_. Nombre de la clase |_. Índice de símbolo |_. "
|
||||
"Nombre de la clase |\n"
|
||||
|
||||
#: makedocs.py:305
|
||||
msgid ""
|
||||
"h4. Category: {}\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
"h4. Categoría: {}\n"
|
||||
"\n"
|
||||
|
||||
#: makedocs.py:310
|
||||
msgid ""
|
||||
"h2. Brief Description\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
"h2. Descripción breve\n"
|
||||
"\n"
|
||||
|
||||
#: makedocs.py:312
|
||||
msgid ""
|
||||
"\"read more\":#more\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
"\"Leer más\":#more\n"
|
||||
"\n"
|
||||
|
||||
#: makedocs.py:317
|
||||
msgid ""
|
||||
"\n"
|
||||
"h3. Member Functions\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"h3. Funciones miembro\n"
|
||||
"\n"
|
||||
|
||||
#: makedocs.py:323
|
||||
msgid ""
|
||||
"\n"
|
||||
"h3. Signals\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"h3. Señales\n"
|
||||
"\n"
|
||||
|
||||
#: makedocs.py:331
|
||||
msgid ""
|
||||
"\n"
|
||||
"h3. Numeric Constants\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"h3. Constantes numéricas\n"
|
||||
"\n"
|
||||
|
||||
#: makedocs.py:347
|
||||
msgid ""
|
||||
"\n"
|
||||
"h3(#more). Description\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"h3(#more). Descripción\n"
|
||||
"\n"
|
||||
|
||||
#: makedocs.py:351
|
||||
msgid "_Nothing here, yet..._\n"
|
||||
msgstr "_Aún nada por aquí..._\n"
|
||||
|
||||
#: makedocs.py:355
|
||||
msgid ""
|
||||
"\n"
|
||||
"h3. Member Function Description\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"h3. Descripción de las funciones miembro\n"
|
||||
"\n"
|
||||
@ -0,0 +1,108 @@
|
||||
# Translations template for PROJECT.
|
||||
# Copyright (C) 2015 ORGANIZATION
|
||||
# This file is distributed under the same license as the PROJECT project.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2015.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: makedocs 0.1\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2015-10-07 11:47-0600\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 2.0\n"
|
||||
"X-Generator: Poedit 1.8.4\n"
|
||||
|
||||
#: makedocs.py:74
|
||||
msgid "\"<code>{gclass}</code>(Go to page of class {gclass})\":/class_{lkclass}"
|
||||
msgstr ""
|
||||
|
||||
#: makedocs.py:76
|
||||
msgid "\"<code>{gclass}.{method}</code>(Go to page {gclass}, section {method})\":/class_{lkclass}#{lkmethod}"
|
||||
msgstr ""
|
||||
|
||||
#: makedocs.py:79
|
||||
msgid "\"<code>{method}</code>(Jump to method {method})\":#{lkmethod}"
|
||||
msgstr ""
|
||||
|
||||
#: makedocs.py:81
|
||||
msgid " \"{rtype}(Go to page of class {rtype})\":/class_{link} "
|
||||
msgstr ""
|
||||
|
||||
#: makedocs.py:82
|
||||
msgid "\"*{funcname}*(Jump to description for node {funcname})\":#{link} <b>(</b> "
|
||||
msgstr ""
|
||||
|
||||
#: makedocs.py:87
|
||||
msgid "h4. Inherits: "
|
||||
msgstr ""
|
||||
|
||||
#: makedocs.py:232
|
||||
msgid "<doc>'s version attribute missing"
|
||||
msgstr ""
|
||||
|
||||
#: makedocs.py:246
|
||||
msgid "|_. Index symbol |_. Class name |_. Index symbol |_. Class name |\n"
|
||||
msgstr ""
|
||||
|
||||
#: makedocs.py:305
|
||||
msgid ""
|
||||
"h4. Category: {}\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
|
||||
#: makedocs.py:310
|
||||
msgid ""
|
||||
"h2. Brief Description\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
|
||||
#: makedocs.py:312
|
||||
msgid ""
|
||||
"\"read more\":#more\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
|
||||
#: makedocs.py:317
|
||||
msgid ""
|
||||
"\n"
|
||||
"h3. Member Functions\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
|
||||
#: makedocs.py:323
|
||||
msgid ""
|
||||
"\n"
|
||||
"h3. Signals\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
|
||||
#: makedocs.py:331
|
||||
msgid ""
|
||||
"\n"
|
||||
"h3. Numeric Constants\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
|
||||
#: makedocs.py:347
|
||||
msgid ""
|
||||
"\n"
|
||||
"h3(#more). Description\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
|
||||
#: makedocs.py:351
|
||||
msgid "_Nothing here, yet..._\n"
|
||||
msgstr ""
|
||||
|
||||
#: makedocs.py:355
|
||||
msgid ""
|
||||
"\n"
|
||||
"h3. Member Function Description\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
@ -0,0 +1,382 @@
|
||||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
#
|
||||
# makedocs.py: Generate documentation for Open Project Wiki
|
||||
# Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur.
|
||||
# Contributor: Jorge Araya Navarro <elcorreo@deshackra.com>
|
||||
#
|
||||
|
||||
# IMPORTANT NOTICE:
|
||||
# If you are going to modify anything from this file, please be sure to follow
|
||||
# the Style Guide for Python Code or often called "PEP8". To do this
|
||||
# automagically just install autopep8:
|
||||
#
|
||||
# $ sudo pip3 install autopep8
|
||||
#
|
||||
# and run:
|
||||
#
|
||||
# $ autopep8 makedocs.py
|
||||
#
|
||||
# Before committing your changes. Also be sure to delete any trailing
|
||||
# whitespace you may left.
|
||||
#
|
||||
# TODO:
|
||||
# * Refactor code.
|
||||
# * Adapt this script for generating content in other markup formats like
|
||||
# DokuWiki, Markdown, etc.
|
||||
#
|
||||
# Also check other TODO entries in this script for more information on what is
|
||||
# left to do.
|
||||
import argparse
|
||||
import gettext
|
||||
import logging
|
||||
import re
|
||||
from itertools import zip_longest
|
||||
from os import path, listdir
|
||||
from xml.etree import ElementTree
|
||||
|
||||
|
||||
# add an option to change the verbosity
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
|
||||
def getxmlfloc():
|
||||
""" Returns the supposed location of the XML file
|
||||
"""
|
||||
filepath = path.dirname(path.abspath(__file__))
|
||||
return path.join(filepath, "class_list.xml")
|
||||
|
||||
|
||||
def langavailable():
|
||||
""" Return a list of languages available for translation
|
||||
"""
|
||||
filepath = path.join(
|
||||
path.dirname(path.abspath(__file__)), "locales")
|
||||
files = listdir(filepath)
|
||||
choices = [x for x in files]
|
||||
choices.insert(0, "none")
|
||||
return choices
|
||||
|
||||
|
||||
desc = "Generates documentation from a XML file to different markup languages"
|
||||
|
||||
parser = argparse.ArgumentParser(description=desc)
|
||||
parser.add_argument("--input", dest="xmlfp", default=getxmlfloc(),
|
||||
help="Input XML file, default: {}".format(getxmlfloc()))
|
||||
parser.add_argument("--output-dir", dest="outputdir", required=True,
|
||||
help="Output directory for generated files")
|
||||
parser.add_argument("--language", choices=langavailable(), default="none",
|
||||
help=("Choose the language of translation"
|
||||
" for the output files. Default is English (none). "
|
||||
"Note: This is NOT for the documentation itself!"))
|
||||
# TODO: add an option for outputting different markup formats
|
||||
|
||||
args = parser.parse_args()
|
||||
# Let's check if the file and output directory exists
|
||||
if not path.isfile(args.xmlfp):
|
||||
logging.critical("File not found: {}".format(args.xmlfp))
|
||||
exit(1)
|
||||
elif not path.isdir(args.outputdir):
|
||||
logging.critical("Path does not exist: {}".format(args.outputdir))
|
||||
exit(1)
|
||||
|
||||
_ = gettext.gettext
|
||||
if args.language != "none":
|
||||
lang = gettext.translation(domain="makedocs",
|
||||
localedir="locales",
|
||||
languages=[args.language])
|
||||
lang.install()
|
||||
|
||||
_ = lang.gettext
|
||||
|
||||
# Strings
|
||||
C_LINK = _("\"<code>{gclass}</code>(Go to page of class"
|
||||
" {gclass})\":/class_{lkclass}")
|
||||
MC_LINK = _("\"<code>{gclass}.{method}</code>(Go "
|
||||
"to page {gclass}, section {method})\""
|
||||
":/class_{lkclass}#{lkmethod}")
|
||||
TM_JUMP = _("\"<code>{method}</code>(Jump to method"
|
||||
" {method})\":#{lkmethod}")
|
||||
GTC_LINK = _(" \"{rtype}(Go to page of class {rtype})\":/class_{link} ")
|
||||
DFN_JUMP = _("\"*{funcname}*(Jump to description for"
|
||||
" node {funcname})\":#{link} <b>(</b> ")
|
||||
M_ARG_DEFAULT = C_LINK + " {name}={default}"
|
||||
M_ARG = C_LINK + " {name}"
|
||||
|
||||
OPENPROJ_INH = _("h4. Inherits: ") + C_LINK + "\n\n"
|
||||
|
||||
|
||||
def tb(string):
|
||||
""" Return a byte representation of a string
|
||||
"""
|
||||
return bytes(string, "UTF-8")
|
||||
|
||||
|
||||
def sortkey(c):
|
||||
""" Symbols are first, letters second
|
||||
"""
|
||||
if "_" == c.attrib["name"][0]:
|
||||
return "A"
|
||||
else:
|
||||
return c.attrib["name"]
|
||||
|
||||
|
||||
def toOP(text):
|
||||
""" Convert commands in text to Open Project commands
|
||||
"""
|
||||
# TODO: Make this capture content between [command] ... [/command]
|
||||
groups = re.finditer((r'\[html (?P<command>/?\w+/?)(\]| |=)?(\]| |=)?(?P<a'
|
||||
'rg>\w+)?(\]| |=)?(?P<value>"[^"]+")?/?\]'), text)
|
||||
alignstr = ""
|
||||
for group in groups:
|
||||
gd = group.groupdict()
|
||||
if gd["command"] == "br/":
|
||||
text = text.replace(group.group(0), "\n\n", 1)
|
||||
elif gd["command"] == "div":
|
||||
if gd["value"] == '"center"':
|
||||
alignstr = ("{display:block; margin-left:auto;"
|
||||
" margin-right:auto;}")
|
||||
elif gd["value"] == '"left"':
|
||||
alignstr = "<"
|
||||
elif gd["value"] == '"right"':
|
||||
alignstr = ">"
|
||||
text = text.replace(group.group(0), "\n\n", 1)
|
||||
elif gd["command"] == "/div":
|
||||
alignstr = ""
|
||||
text = text.replace(group.group(0), "\n\n", 1)
|
||||
elif gd["command"] == "img":
|
||||
text = text.replace(group.group(0), "!{align}{src}!".format(
|
||||
align=alignstr, src=gd["value"].strip('"')), 1)
|
||||
elif gd["command"] == "b" or gd["command"] == "/b":
|
||||
text = text.replace(group.group(0), "*", 1)
|
||||
elif gd["command"] == "i" or gd["command"] == "/i":
|
||||
text = text.replace(group.group(0), "_", 1)
|
||||
elif gd["command"] == "u" or gd["command"] == "/u":
|
||||
text = text.replace(group.group(0), "+", 1)
|
||||
# Process other non-html commands
|
||||
groups = re.finditer((r'\[method ((?P<class>[aA0-zZ9_]+)(?:\.))'
|
||||
r'?(?P<method>[aA0-zZ9_]+)\]'), text)
|
||||
for group in groups:
|
||||
gd = group.groupdict()
|
||||
if gd["class"]:
|
||||
replacewith = (MC_LINK.format(gclass=gd["class"],
|
||||
method=gd["method"],
|
||||
lkclass=gd["class"].lower(),
|
||||
lkmethod=gd["method"].lower()))
|
||||
else:
|
||||
# The method is located in the same wiki page
|
||||
replacewith = (TM_JUMP.format(method=gd["method"],
|
||||
lkmethod=gd["method"].lower()))
|
||||
|
||||
text = text.replace(group.group(0), replacewith, 1)
|
||||
# Finally, [Classes] are around brackets, make them direct links
|
||||
groups = re.finditer(r'\[(?P<class>[az0-AZ0_]+)\]', text)
|
||||
for group in groups:
|
||||
gd = group.groupdict()
|
||||
replacewith = (C_LINK.
|
||||
format(gclass=gd["class"],
|
||||
lkclass=gd["class"].lower()))
|
||||
text = text.replace(group.group(0), replacewith, 1)
|
||||
|
||||
return text + "\n\n"
|
||||
|
||||
|
||||
def mkfn(node, is_signal=False):
|
||||
""" Return a string containing a unsorted item for a function
|
||||
"""
|
||||
finalstr = ""
|
||||
name = node.attrib["name"]
|
||||
rtype = node.find("return")
|
||||
if rtype:
|
||||
rtype = rtype.attrib["type"]
|
||||
else:
|
||||
rtype = "void"
|
||||
# write the return type and the function name first
|
||||
finalstr += "* "
|
||||
# return type
|
||||
if not is_signal:
|
||||
if rtype != "void":
|
||||
finalstr += GTC_LINK.format(
|
||||
rtype=rtype,
|
||||
link=rtype.lower())
|
||||
else:
|
||||
finalstr += " void "
|
||||
|
||||
# function name
|
||||
if not is_signal:
|
||||
finalstr += DFN_JUMP.format(
|
||||
funcname=name,
|
||||
link=name.lower())
|
||||
else:
|
||||
# Signals have no description
|
||||
finalstr += "*{funcname}* <b>(</b>".format(funcname=name)
|
||||
# loop for the arguments of the function, if any
|
||||
args = []
|
||||
for arg in sorted(
|
||||
node.iter(tag="argument"),
|
||||
key=lambda a: int(a.attrib["index"])):
|
||||
|
||||
ntype = arg.attrib["type"]
|
||||
nname = arg.attrib["name"]
|
||||
|
||||
if "default" in arg.attrib:
|
||||
args.insert(-1, M_ARG_DEFAULT.format(
|
||||
gclass=ntype,
|
||||
lkclass=ntype.lower(),
|
||||
name=nname,
|
||||
default=arg.attrib["default"]))
|
||||
else:
|
||||
# No default value present
|
||||
args.insert(-1, M_ARG.format(gclass=ntype,
|
||||
lkclass=ntype.lower(), name=nname))
|
||||
# join the arguments together
|
||||
finalstr += ", ".join(args)
|
||||
# and, close the function with a )
|
||||
finalstr += " <b>)</b>"
|
||||
# write the qualifier, if any
|
||||
if "qualifiers" in node.attrib:
|
||||
qualifier = node.attrib["qualifiers"]
|
||||
finalstr += " " + qualifier
|
||||
|
||||
finalstr += "\n"
|
||||
|
||||
return finalstr
|
||||
|
||||
# Let's begin
|
||||
tree = ElementTree.parse(args.xmlfp)
|
||||
root = tree.getroot()
|
||||
|
||||
# Check version attribute exists in <doc>
|
||||
if "version" not in root.attrib:
|
||||
logging.critical(_("<doc>'s version attribute missing"))
|
||||
exit(1)
|
||||
|
||||
version = root.attrib["version"]
|
||||
classes = sorted(root, key=sortkey)
|
||||
# first column is always longer, second column of classes should be shorter
|
||||
zclasses = zip_longest(classes[:int(len(classes) / 2 + 1)],
|
||||
classes[int(len(classes) / 2 + 1):],
|
||||
fillvalue="")
|
||||
|
||||
# We write the class_list file and also each class file at once
|
||||
with open(path.join(args.outputdir, "class_list.txt"), "wb") as fcl:
|
||||
# Write header of table
|
||||
fcl.write(tb("|^.\n"))
|
||||
fcl.write(tb(_("|_. Index symbol |_. Class name "
|
||||
"|_. Index symbol |_. Class name |\n")))
|
||||
fcl.write(tb("|-.\n"))
|
||||
|
||||
indexletterl = ""
|
||||
indexletterr = ""
|
||||
for gdclassl, gdclassr in zclasses:
|
||||
# write a row #
|
||||
# write the index symbol column, left
|
||||
if indexletterl != gdclassl.attrib["name"][0]:
|
||||
indexletterl = gdclassl.attrib["name"][0]
|
||||
fcl.write(tb("| *{}* |".format(indexletterl.upper())))
|
||||
else:
|
||||
# empty cell
|
||||
fcl.write(tb("| |"))
|
||||
# write the class name column, left
|
||||
fcl.write(tb(C_LINK.format(
|
||||
gclass=gdclassl.attrib["name"],
|
||||
lkclass=gdclassl.attrib["name"].lower())))
|
||||
|
||||
# write the index symbol column, right
|
||||
if isinstance(gdclassr, ElementTree.Element):
|
||||
if indexletterr != gdclassr.attrib["name"][0]:
|
||||
indexletterr = gdclassr.attrib["name"][0]
|
||||
fcl.write(tb("| *{}* |".format(indexletterr.upper())))
|
||||
else:
|
||||
# empty cell
|
||||
fcl.write(tb("| |"))
|
||||
# We are dealing with an empty string
|
||||
else:
|
||||
# two empty cell
|
||||
fcl.write(tb("| | |\n"))
|
||||
# We won't get the name of the class since there is no ElementTree
|
||||
# object for the right side of the tuple, so we iterate the next
|
||||
# tuple instead
|
||||
continue
|
||||
|
||||
# write the class name column (if any), right
|
||||
fcl.write(tb(C_LINK.format(
|
||||
gclass=gdclassl.attrib["name"],
|
||||
lkclass=gdclassl.attrib["name"].lower()) + "|\n"))
|
||||
|
||||
# row written #
|
||||
# now, let's write each class page for each class
|
||||
for gdclass in [gdclassl, gdclassr]:
|
||||
if not isinstance(gdclass, ElementTree.Element):
|
||||
continue
|
||||
|
||||
classname = gdclass.attrib["name"]
|
||||
with open(path.join(args.outputdir, "{}.txt".format(
|
||||
classname.lower())), "wb") as clsf:
|
||||
# First level header with the name of the class
|
||||
clsf.write(tb("h1. {}\n\n".format(classname)))
|
||||
# lay the attributes
|
||||
if "inherits" in gdclass.attrib:
|
||||
inh = gdclass.attrib["inherits"].strip()
|
||||
clsf.write(tb(OPENPROJ_INH.format(gclass=inh,
|
||||
lkclass=inh.lower())))
|
||||
if "category" in gdclass.attrib:
|
||||
clsf.write(tb(_("h4. Category: {}\n\n").
|
||||
format(gdclass.attrib["category"].strip())))
|
||||
# lay child nodes
|
||||
briefd = gdclass.find("brief_description")
|
||||
if briefd.text.strip():
|
||||
clsf.write(tb(_("h2. Brief Description\n\n")))
|
||||
clsf.write(tb(toOP(briefd.text.strip()) +
|
||||
_("\"read more\":#more\n\n")))
|
||||
|
||||
# Write the list of member functions of this class
|
||||
methods = gdclass.find("methods")
|
||||
if methods and len(methods) > 0:
|
||||
clsf.write(tb(_("\nh3. Member Functions\n\n")))
|
||||
for method in methods.iter(tag='method'):
|
||||
clsf.write(tb(mkfn(method)))
|
||||
|
||||
signals = gdclass.find("signals")
|
||||
if signals and len(signals) > 0:
|
||||
clsf.write(tb(_("\nh3. Signals\n\n")))
|
||||
for signal in signals.iter(tag='signal'):
|
||||
clsf.write(tb(mkfn(signal, True)))
|
||||
# TODO: <members> tag is necessary to process? it does not
|
||||
# exists in class_list.xml file.
|
||||
|
||||
consts = gdclass.find("constants")
|
||||
if consts and len(consts) > 0:
|
||||
clsf.write(tb(_("\nh3. Numeric Constants\n\n")))
|
||||
for const in sorted(consts, key=lambda k:
|
||||
k.attrib["name"]):
|
||||
if const.text.strip():
|
||||
clsf.write(tb("* *{name}* = *{value}* - {desc}\n".
|
||||
format(
|
||||
name=const.attrib["name"],
|
||||
value=const.attrib["value"],
|
||||
desc=const.text.strip())))
|
||||
else:
|
||||
# Constant have no description
|
||||
clsf.write(tb("* *{name}* = *{value}*\n".
|
||||
format(
|
||||
name=const.attrib["name"],
|
||||
value=const.attrib["value"])))
|
||||
descrip = gdclass.find("description")
|
||||
clsf.write(tb(_("\nh3(#more). Description\n\n")))
|
||||
if descrip.text:
|
||||
clsf.write(tb(descrip.text.strip() + "\n"))
|
||||
else:
|
||||
clsf.write(tb(_("_Nothing here, yet..._\n")))
|
||||
|
||||
# and finally, the description for each method
|
||||
if methods and len(methods) > 0:
|
||||
clsf.write(tb(_("\nh3. Member Function Description\n\n")))
|
||||
for method in methods.iter(tag='method'):
|
||||
clsf.write(tb("h4(#{n}). {name}\n\n".format(
|
||||
n=method.attrib["name"].lower(),
|
||||
name=method.attrib["name"])))
|
||||
clsf.write(tb(mkfn(method) + "\n"))
|
||||
clsf.write(tb(toOP(method.find(
|
||||
"description").text.strip())))
|
||||
Loading…
Reference in New Issue