Example #1
0
 //! Return complete string (for debugging purposes)
 std::string get_string(const String& s, size_t depth = 0) const
 { return s->substr(depth); }
Example #2
0
	/**
	 * Return a DirectoryEntry object.
	 */
	void PhoneGapFile::actionGetDirectory(JSONMessage& message)
	{
		String callbackID = message.getParam("PhoneGapCallBackId");

		String fullPath = message.getArgsField("fullPath");
		String path = message.getArgsField("path");
		String fullFilePath = fullPath + "/" + path;

		// Add a trailing slash if not present. MoSync API requires this.
		if (fullFilePath[fullFilePath.size() - 1] != '/')
		{
			fullFilePath += "/";
		}

		// Get flags "create" and "exclusive".
		bool create = false;
		bool exclusive = false;
		bool success = message.getJSONParamsOptionsCreateExclusive(create, exclusive);
		if (!success)
		{
			callFileError(callbackID, FILEERROR_NO_MODIFICATION_ALLOWED_ERR);
			return;
		}

		// Create directory if requested.
		if (create)
		{
			if (exclusive)
			{
				// The file must not exist if "exclusive" is true.
				if (FileExists(fullFilePath))
				{
					callFileError(callbackID, FILEERROR_PATH_EXISTS_ERR);
					return;
				}
			}

			if (!FileExists(fullFilePath))
			{
				// Create the directory.
				// TODO: Invoke error if parent directory does not
				// exist to be compatible with the PhoneGap spec.
				bool created = FileCreatePath(fullFilePath);
				if (!created)
				{
					callFileError(callbackID, FILEERROR_NO_MODIFICATION_ALLOWED_ERR);
					return;
				}
			}
		}

		// Send back DirectoryEntry data.
		String directoryEntry = emitDirectoryEntry(
			path,
			// Remove the trailing slash from the full path.
			fullFilePath.substr(0, fullFilePath.size() - 1));
		callSuccess(
			callbackID,
			directoryEntry,
			"window.localFileSystem._castEntry");
	}
Example #3
0
Error BitmapFont::create_from_fnt(const String &p_file) {
	//fnt format used by angelcode bmfont
	//http://www.angelcode.com/products/bmfont/

	FileAccess *f = FileAccess::open(p_file, FileAccess::READ);

	if (!f) {
		ERR_EXPLAIN("Can't open font: " + p_file);
		ERR_FAIL_V(ERR_FILE_NOT_FOUND);
	}

	clear();

	while (true) {

		String line = f->get_line();

		int delimiter = line.find(" ");
		String type = line.substr(0, delimiter);
		int pos = delimiter + 1;
		Map<String, String> keys;

		while (pos < line.size() && line[pos] == ' ')
			pos++;

		while (pos < line.size()) {

			int eq = line.find("=", pos);
			if (eq == -1)
				break;
			String key = line.substr(pos, eq - pos);
			int end = -1;
			String value;
			if (line[eq + 1] == '"') {
				end = line.find("\"", eq + 2);
				if (end == -1)
					break;
				value = line.substr(eq + 2, end - 1 - eq - 1);
				pos = end + 1;
			} else {
				end = line.find(" ", eq + 1);
				if (end == -1)
					end = line.size();

				value = line.substr(eq + 1, end - eq);

				pos = end;
			}

			while (pos < line.size() && line[pos] == ' ')
				pos++;

			keys[key] = value;
		}

		if (type == "info") {

			if (keys.has("face"))
				set_name(keys["face"]);
			/*
			if (keys.has("size"))
				font->set_height(keys["size"].to_int());
			*/

		} else if (type == "common") {

			if (keys.has("lineHeight"))
				set_height(keys["lineHeight"].to_int());
			if (keys.has("base"))
				set_ascent(keys["base"].to_int());

		} else if (type == "page") {

			if (keys.has("file")) {

				String file = keys["file"];
				file = p_file.get_base_dir() + "/" + file;
				Ref<Texture> tex = ResourceLoader::load(file);
				if (tex.is_null()) {
					ERR_PRINT("Can't load font texture!");
				} else {
					add_texture(tex);
				}
			}
		} else if (type == "char") {

			CharType idx = 0;
			if (keys.has("id"))
				idx = keys["id"].to_int();

			Rect2 rect;

			if (keys.has("x"))
				rect.position.x = keys["x"].to_int();
			if (keys.has("y"))
				rect.position.y = keys["y"].to_int();
			if (keys.has("width"))
				rect.size.width = keys["width"].to_int();
			if (keys.has("height"))
				rect.size.height = keys["height"].to_int();

			Point2 ofs;

			if (keys.has("xoffset"))
				ofs.x = keys["xoffset"].to_int();
			if (keys.has("yoffset"))
				ofs.y = keys["yoffset"].to_int();

			int texture = 0;
			if (keys.has("page"))
				texture = keys["page"].to_int();
			int advance = -1;
			if (keys.has("xadvance"))
				advance = keys["xadvance"].to_int();

			add_char(idx, texture, rect, ofs, advance);

		} else if (type == "kerning") {

			CharType first = 0, second = 0;
			int k = 0;

			if (keys.has("first"))
				first = keys["first"].to_int();
			if (keys.has("second"))
				second = keys["second"].to_int();
			if (keys.has("amount"))
				k = keys["amount"].to_int();

			add_kerning_pair(first, second, -k);
		}

		if (f->eof_reached())
			break;
	}

	memdelete(f);

	return OK;
}
EditorAutoloadSettings::EditorAutoloadSettings() {

	// Make first cache
	List<PropertyInfo> props;
	ProjectSettings::get_singleton()->get_property_list(&props);
	for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {

		const PropertyInfo &pi = E->get();

		if (!pi.name.begins_with("autoload/"))
			continue;

		String name = pi.name.get_slice("/", 1);
		String path = ProjectSettings::get_singleton()->get(pi.name);

		if (name.empty())
			continue;

		AutoLoadInfo info;
		info.is_singleton = path.begins_with("*");

		if (info.is_singleton) {
			path = path.substr(1, path.length());
		}

		info.name = name;
		info.path = path;
		info.order = ProjectSettings::get_singleton()->get_order(pi.name);

		if (info.is_singleton) {
			// Make sure name references work before parsing scripts
			for (int i = 0; i < ScriptServer::get_language_count(); i++) {
				ScriptServer::get_language(i)->add_named_global_constant(info.name, Variant());
			}
		}

		autoload_cache.push_back(info);
	}

	for (List<AutoLoadInfo>::Element *E = autoload_cache.front(); E; E = E->next()) {
		AutoLoadInfo &info = E->get();

		info.node = _create_autoload(info.path);

		if (info.node) {
			Ref<Script> scr = info.node->get_script();
			info.in_editor = scr.is_valid() && scr->is_tool();
			info.node->set_name(info.name);
		}

		if (info.is_singleton) {
			for (int i = 0; i < ScriptServer::get_language_count(); i++) {
				ScriptServer::get_language(i)->add_named_global_constant(info.name, info.node);
			}
		}

		if (!info.is_singleton && !info.in_editor) {
			memdelete(info.node);
			info.node = NULL;
		}
	}

	autoload_changed = "autoload_changed";

	updating_autoload = false;
	selected_autoload = "";

	HBoxContainer *hbc = memnew(HBoxContainer);
	add_child(hbc);

	Label *l = memnew(Label);
	l->set_text(TTR("Path:"));
	hbc->add_child(l);

	autoload_add_path = memnew(EditorLineEditFileChooser);
	autoload_add_path->set_h_size_flags(SIZE_EXPAND_FILL);
	autoload_add_path->get_file_dialog()->set_mode(EditorFileDialog::MODE_OPEN_FILE);
	autoload_add_path->get_file_dialog()->connect("file_selected", this, "_autoload_file_callback");
	hbc->add_child(autoload_add_path);

	l = memnew(Label);
	l->set_text(TTR("Node Name:"));
	hbc->add_child(l);

	autoload_add_name = memnew(LineEdit);
	autoload_add_name->set_h_size_flags(SIZE_EXPAND_FILL);
	hbc->add_child(autoload_add_name);

	Button *add_autoload = memnew(Button);
	add_autoload->set_text(TTR("Add"));
	add_autoload->connect("pressed", this, "_autoload_add");
	hbc->add_child(add_autoload);

	tree = memnew(Tree);
	tree->set_hide_root(true);
	tree->set_select_mode(Tree::SELECT_MULTI);
	tree->set_allow_reselect(true);

	tree->set_drag_forwarding(this);

	tree->set_columns(4);
	tree->set_column_titles_visible(true);

	tree->set_column_title(0, TTR("Name"));
	tree->set_column_expand(0, true);
	tree->set_column_min_width(0, 100);

	tree->set_column_title(1, TTR("Path"));
	tree->set_column_expand(1, true);
	tree->set_column_min_width(1, 100);

	tree->set_column_title(2, TTR("Singleton"));
	tree->set_column_expand(2, false);
	tree->set_column_min_width(2, 80 * EDSCALE);

	tree->set_column_expand(3, false);
	tree->set_column_min_width(3, 120 * EDSCALE);

	tree->connect("cell_selected", this, "_autoload_selected");
	tree->connect("item_edited", this, "_autoload_edited");
	tree->connect("button_pressed", this, "_autoload_button_pressed");
	tree->connect("item_activated", this, "_autoload_activated");
	tree->set_v_size_flags(SIZE_EXPAND_FILL);

	add_child(tree, true);
}
Example #5
0
String ID3v2::Tag::genre() const
{
  // TODO: In the next major version (TagLib 2.0) a list of multiple genres
  // should be separated by " / " instead of " ".  For the moment to keep
  // the behavior the same as released versions it is being left with " ".

  if(!d->frameListMap["TCON"].isEmpty() &&
     dynamic_cast<TextIdentificationFrame *>(d->frameListMap["TCON"].front()))
  {
    Frame *frame = d->frameListMap["TCON"].front();

    // ID3v2.4 lists genres as the fields in its frames field list.  If the field
    // is simply a number it can be assumed that it is an ID3v1 genre number.
    // Here was assume that if an ID3v1 string is present that it should be
    // appended to the genre string.  Multiple fields will be appended as the
    // string is built.

    if(d->header.majorVersion() == 4) {
      TextIdentificationFrame *f = static_cast<TextIdentificationFrame *>(frame);
      StringList fields = f->fieldList();

      String genreString;
      bool hasNumber = false;

      for(StringList::ConstIterator it = fields.begin(); it != fields.end(); ++it) {
        bool isNumber = true;
        for(String::ConstIterator charIt = (*it).begin();
            isNumber && charIt != (*it).end();
            ++charIt)
        {
          isNumber = *charIt >= '0' && *charIt <= '9';
        }

        if(!genreString.isEmpty())
          genreString.append(' ');

        if(isNumber) {
          int number = (*it).toInt();
          if(number >= 0 && number <= 255) {
            hasNumber = true;
            genreString.append(ID3v1::genre(number));
          }
        }
        else
          genreString.append(*it);
      }
      if(hasNumber)
        return genreString;
    }

    String s = frame->toString();

    // ID3v2.3 "content type" can contain a ID3v1 genre number in parenthesis at
    // the beginning of the field.  If this is all that the field contains, do a
    // translation from that number to the name and return that.  If there is a
    // string folloing the ID3v1 genre number, that is considered to be
    // authoritative and we return that instead.  Or finally, the field may
    // simply be free text, in which case we just return the value.

    int closing = s.find(")");
    if(s.substr(0, 1) == "(" && closing > 0) {
      if(closing == int(s.size() - 1))
        return ID3v1::genre(s.substr(1, s.size() - 2).toInt());
      else
        return s.substr(closing + 1);
    }
    return s;
  }
  return String::null;
}
Example #6
0
void FileSystemDock::_move_operation(const String& p_to_path) {

	if (p_to_path==path) {
		EditorNode::get_singleton()->show_warning(TTR("Same source and destination paths, doing nothing."));
		return;
	}

	//find files inside dirs to be moved

	Vector<String> inside_files;

	for(int i=0;i<move_dirs.size();i++) {
		if (p_to_path.begins_with(move_dirs[i])) {
			EditorNode::get_singleton()->show_warning(TTR("Can't move directories to within themselves."));
			return;
		}

		EditorFileSystemDirectory *efsd=EditorFileSystem::get_singleton()->get_path(move_dirs[i]);
		if (!efsd)
			continue;
		_find_inside_move_files(efsd,inside_files);
	}

	//make list of remaps
	Map<String,String> renames;
	String repfrom=path=="res://"?path:String(path+"/");
	String repto=p_to_path=="res://"?p_to_path:String(p_to_path+"/");

	for(int i=0;i<move_files.size();i++) {
		renames[move_files[i]]=move_files[i].replace_first(repfrom,repto);
		print_line("move file "+move_files[i]+" -> "+renames[move_files[i]]);
	}
	for(int i=0;i<inside_files.size();i++) {
		renames[inside_files[i]]=inside_files[i].replace_first(repfrom,repto);
		print_line("inside file "+inside_files[i]+" -> "+renames[inside_files[i]]);
	}

	//make list of files that will be run the remapping
	List<String> remap;

	_find_remaps(EditorFileSystem::get_singleton()->get_filesystem(),renames,remap);
	print_line("found files to remap: "+itos(remap.size()));

	//perform remaps
	for(List<String>::Element *E=remap.front();E;E=E->next()) {

		Error err = ResourceLoader::rename_dependencies(E->get(),renames);
		print_line("remapping: "+E->get());

		if (err!=OK) {
			EditorNode::get_singleton()->add_io_error("Can't rename deps for:\n"+E->get()+"\n");
		}
	}

	//finally, perform moves

	DirAccess *da=DirAccess::create(DirAccess::ACCESS_RESOURCES);

	for(int i=0;i<move_files.size();i++) {

		String to = move_files[i].replace_first(repfrom,repto);
		Error err = da->rename(move_files[i],to);
		print_line("moving file "+move_files[i]+" to "+to);
		if (err!=OK) {
			EditorNode::get_singleton()->add_io_error("Error moving file:\n"+move_files[i]+"\n");
		}
	}

	for(int i=0;i<move_dirs.size();i++) {

		String mdir = move_dirs[i];
		if (mdir=="res://")
			continue;

		if (mdir.ends_with("/")) {
			mdir=mdir.substr(0,mdir.length()-1);
		}

		String to = p_to_path.plus_file(mdir.get_file());
		Error err = da->rename(mdir,to);
		print_line("moving dir "+mdir+" to "+to);
		if (err!=OK) {
			EditorNode::get_singleton()->add_io_error("Error moving dir:\n"+move_dirs[i]+"\n");
		}
	}

	memdelete(da);
	//rescan everything
	print_line("call rescan!");
	_rescan();

}
void EditorAutoloadSettings::_autoload_edited() {

	if (updating_autoload)
		return;

	TreeItem *ti = tree->get_edited();
	int column = tree->get_edited_column();

	UndoRedo *undo_redo = EditorNode::get_undo_redo();

	if (column == 0) {
		String name = ti->get_text(0);
		String old_name = selected_autoload.get_slice("/", 1);

		if (name == old_name)
			return;

		String error;
		if (!_autoload_name_is_valid(name, &error)) {
			ti->set_text(0, old_name);
			EditorNode::get_singleton()->show_warning(error);
			return;
		}

		if (ProjectSettings::get_singleton()->has_setting("autoload/" + name)) {
			ti->set_text(0, old_name);
			EditorNode::get_singleton()->show_warning(vformat(TTR("Autoload '%s' already exists!"), name));
			return;
		}

		updating_autoload = true;

		name = "autoload/" + name;

		int order = ProjectSettings::get_singleton()->get_order(selected_autoload);
		String path = ProjectSettings::get_singleton()->get(selected_autoload);

		undo_redo->create_action(TTR("Rename Autoload"));

		undo_redo->add_do_property(ProjectSettings::get_singleton(), name, path);
		undo_redo->add_do_method(ProjectSettings::get_singleton(), "set_order", name, order);
		undo_redo->add_do_method(ProjectSettings::get_singleton(), "clear", selected_autoload);

		undo_redo->add_undo_property(ProjectSettings::get_singleton(), selected_autoload, path);
		undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set_order", selected_autoload, order);
		undo_redo->add_undo_method(ProjectSettings::get_singleton(), "clear", name);

		undo_redo->add_do_method(this, "call_deferred", "update_autoload");
		undo_redo->add_undo_method(this, "call_deferred", "update_autoload");

		undo_redo->add_do_method(this, "emit_signal", autoload_changed);
		undo_redo->add_undo_method(this, "emit_signal", autoload_changed);

		undo_redo->commit_action();

		selected_autoload = name;
	} else if (column == 2) {
		updating_autoload = true;

		bool checked = ti->is_checked(2);
		String base = "autoload/" + ti->get_text(0);

		int order = ProjectSettings::get_singleton()->get_order(base);
		String path = ProjectSettings::get_singleton()->get(base);

		if (path.begins_with("*"))
			path = path.substr(1, path.length());

		// Singleton autoloads are represented with a leading "*" in their path.
		if (checked)
			path = "*" + path;

		undo_redo->create_action(TTR("Toggle AutoLoad Globals"));

		undo_redo->add_do_property(ProjectSettings::get_singleton(), base, path);
		undo_redo->add_undo_property(ProjectSettings::get_singleton(), base, ProjectSettings::get_singleton()->get(base));

		undo_redo->add_do_method(ProjectSettings::get_singleton(), "set_order", base, order);
		undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set_order", base, order);

		undo_redo->add_do_method(this, "call_deferred", "update_autoload");
		undo_redo->add_undo_method(this, "call_deferred", "update_autoload");

		undo_redo->add_do_method(this, "emit_signal", autoload_changed);
		undo_redo->add_undo_method(this, "emit_signal", autoload_changed);

		undo_redo->commit_action();
	}

	updating_autoload = false;
}
Example #8
0
	void ok_pressed() {

		if (!_test_path())
			return;

		String dir;

		if (import_mode) {
			dir=project_path->get_text();


		} else {
			DirAccess *d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);

			if (d->change_dir(project_path->get_text())!=OK) {
				error->set_text("Invalid Path for Project (changed anything?)");
				memdelete(d);
				return;
			}

			dir=d->get_current_dir();
			memdelete(d);

			FileAccess *f = FileAccess::open(dir.plus_file("/engine.cfg"),FileAccess::WRITE);
			if (!f) {
				error->set_text("Couldn't create engine.cfg in project path");
			} else {

				f->store_line("; Engine configuration file.");
				f->store_line("; It's best to edit using the editor UI, not directly,");
				f->store_line("; becausethe parameters that go here are not obvious.");
				f->store_line("; ");
				f->store_line("; Format: ");
				f->store_line(";   [section] ; section goes between []");
				f->store_line(";   param=value ; assign values to parameters");
				f->store_line("\n");
				f->store_line("[application]");
				f->store_line("name=\""+project_name->get_text()+"\"");
				f->store_line("icon=\"icon.png\"");

				memdelete(f);

				ResourceSaver::save(dir.plus_file("/icon.png"),get_icon("DefaultProjectIcon","EditorIcons"));
			}



		}

		dir=dir.replace("\\","/");
		if (dir.ends_with("/"))
			dir=dir.substr(0,dir.length()-1);
		String proj=dir.replace("/","::");
		EditorSettings::get_singleton()->set("projects/"+proj,dir);
		EditorSettings::get_singleton()->save();



		hide();
		emit_signal("project_created");

	}
uint8 OgreMaxUtilities::ParseRenderQueue(const String& renderQueue)
{
    static std::map<String, uint8> nameToNumber;
    if (nameToNumber.empty())
    {
        nameToNumber["background"] = RENDER_QUEUE_BACKGROUND;
        nameToNumber["skiesearly"] = RENDER_QUEUE_SKIES_EARLY;
        nameToNumber["queue1"] = RENDER_QUEUE_1;
        nameToNumber["queue2"] = RENDER_QUEUE_2;
		nameToNumber["worldgeometry1"] = RENDER_QUEUE_WORLD_GEOMETRY_1;
        nameToNumber["queue3"] = RENDER_QUEUE_3;
        nameToNumber["queue4"] = RENDER_QUEUE_4;
		nameToNumber["main"] = RENDER_QUEUE_MAIN;
        nameToNumber["queue6"] = RENDER_QUEUE_6;
        nameToNumber["queue7"] = RENDER_QUEUE_7;
		nameToNumber["worldgeometry2"] = RENDER_QUEUE_WORLD_GEOMETRY_2;
        nameToNumber["queue8"] = RENDER_QUEUE_8;
        nameToNumber["queue9"] = RENDER_QUEUE_9;
        nameToNumber["skieslate"] = RENDER_QUEUE_SKIES_LATE;
        nameToNumber["overlay"] = RENDER_QUEUE_OVERLAY;
		nameToNumber["max"] = RENDER_QUEUE_MAX;
    }

    if (renderQueue.empty())
        return RENDER_QUEUE_MAIN;
    else if (AllDigits(renderQueue))
        return (uint8)StringConverter::parseUnsignedInt(renderQueue);
    else
    {
        //The render queue name, lowercase
        String renderQueueLower;

        //Get the offset that comes after the +, if any
        uint8 offset = 0;
        size_t plusFoundAt = renderQueue.find('+');
        if (plusFoundAt != String::npos)
        {
            //Parse the number
            String offsetText = renderQueue.substr(plusFoundAt + 1);
            StringUtil::trim(offsetText);

            offset = (uint8)StringConverter::parseUnsignedInt(offsetText);

            //Remove the "+offset" substring from the render queue name
            renderQueueLower = renderQueue.substr(0, plusFoundAt);
            StringUtil::trim(renderQueueLower);
        }
        else
            renderQueueLower = renderQueue;
        StringUtil::toLowerCase(renderQueueLower);

        //Look up the render queue and return it
        std::map<String, uint8>::iterator item = nameToNumber.find(renderQueueLower);
        if (item != nameToNumber.end())
        {
            //Don't let the render queue exceed the maximum
            return std::min((uint8)(item->second + offset), (uint8)RENDER_QUEUE_MAX);
        }
        else
        {
            StringUtil::StrStreamType errorMessage;
            errorMessage << "Invalid render queue specified: " << renderQueue;

            OGRE_EXCEPT
                (
                Exception::ERR_INVALIDPARAMS,
	            errorMessage.str(),
	            "OgreMaxUtilities::ParseRenderQueue"
                );
        }
    }
}
Example #10
0
//----------------------------------------------------------------------------//
void FalagardEditbox::render()
{
    Editbox* w = static_cast<Editbox*>(d_window);
    const StateImagery* imagery;

    // draw container etc
    // get WidgetLookFeel for the assigned look.
    const WidgetLookFeel& wlf = getLookNFeel();
    // try and get imagery for the approprite state.
    imagery = &wlf.getStateImagery(
        w->isDisabled() ? "Disabled" : (w->isReadOnly() ? "ReadOnly" : "Enabled"));

    // peform the rendering operation for the container.
    imagery->render(*w);

    // get destination area for text
    const Rect textArea(wlf.getNamedArea("TextArea").getArea().getPixelRect(*w));

    //
    // Required preliminary work for text rendering operations
    //
    Font* font = w->getFont();

    // no font == no more rendering
    if (!font)
        return;

    // This will point to the final string to be used for rendering.  Useful
    // because it means we do not have to have duplicate code or be copying
    // getText() for handling masked/unmasked text.
    String* editText;

    // Create a 'masked' version of the string if needed.
    String maskedText, windowText;
    if (w->isTextMasked())
    {
        maskedText.insert(0, w->getText().length(), w->getMaskCodePoint());
        editText = &maskedText;
    }
    // text not masked to editText will be the windows getText() String.
    else
    {
        windowText = w->getTextVisual();
        editText = &windowText;
    }

    // calculate best position to render text to ensure carat is always visible
    float textOffset;
    size_t cartIndex = w->getCaratIndex();

#ifdef CEGUI_BIDI_SUPPORT
    // the char before the cart bidi type
    bool currCharIsRtl = false;
    if ((editText->size() > 0) && (cartIndex > 0))
    {
        size_t curCartIndex = w->getCaratIndex();
        BidiCharType charBeforeCartType = w->getBiDiVisualMapping()->
            getBidiCharType((*editText)[curCartIndex - 1]);
        // for neutral chars you decide by the char after
        for (; BCT_NEUTRAL == charBeforeCartType &&
               (editText->size() > curCartIndex); curCartIndex++)
        {
            charBeforeCartType = w->getBiDiVisualMapping()->
                getBidiCharType((*editText)[curCartIndex - 1]);
        }

        currCharIsRtl  = (BCT_RIGHT_TO_LEFT == charBeforeCartType);
    }

    bool isFirstChar = cartIndex == 0;

    // the pos is by the char before
    if (!isFirstChar)
        cartIndex--;

    // we need to find the cart pos by the logical to visual map
    if (w->getBiDiVisualMapping()->getV2lMapping().size() > cartIndex)
        cartIndex = w->getBiDiVisualMapping()->getL2vMapping()[cartIndex];

    // for non RTL char - the cart pos is after the char
    if (!currCharIsRtl)
        cartIndex++;

    // if first char is not rtl - we need to stand at the start of the line
    if (isFirstChar)
    {
        bool firstCharRtl =
            (editText->size() > 0) &&
            (BCT_RIGHT_TO_LEFT == w->getBiDiVisualMapping()->
                getBidiCharType((*editText)[0]));

        if (!firstCharRtl)
            cartIndex--;
    }
#endif

    float extentToCarat = font->getTextExtent(editText->substr(0, cartIndex));

    // get carat imagery
    const ImagerySection& caratImagery = wlf.getImagerySection("Carat");
    // store carat width
    float caratWidth = caratImagery.getBoundingRect(*w, textArea).getWidth();

    // if box is inactive
    if (!w->hasInputFocus())
        textOffset = d_lastTextOffset;
    // if carat is to the left of the box
    else if ((d_lastTextOffset + extentToCarat) < 0)
        textOffset = -extentToCarat;
    // if carat is off to the right.
    else if ((d_lastTextOffset + extentToCarat) >= (textArea.getWidth() - caratWidth))
        textOffset = textArea.getWidth() - extentToCarat - caratWidth;
    // else carat is already within the box
    else
        textOffset = d_lastTextOffset;

    ColourRect colours;
    float alpha_comp = w->getEffectiveAlpha();

    //
    // Draw label text
    //
    // setup initial rect for text formatting
    Rect text_part_rect(textArea);
    // allow for scroll position
    text_part_rect.d_left += textOffset;
    // centre text vertically within the defined text area
    text_part_rect.d_top += (textArea.getHeight() - font->getFontHeight()) * 0.5f;

    // get unhighlighted text colour (saves accessing property twice)
    colour unselectedColour(getUnselectedTextColour());

    // see if the editbox is active or inactive.
    bool active = (!w->isReadOnly()) && w->hasInputFocus();

#ifdef CEGUI_BIDI_SUPPORT
    if (w->getSelectionLength() == 0)
    {
        // no highlighted text - we can draw the whole thing
        colours.setColours(unselectedColour);
        colours.modulateAlpha(alpha_comp);
        font->drawText(w->getGeometryBuffer(), *editText,
                       text_part_rect.getPosition(), &textArea, colours);

        // adjust rect for next section
        text_part_rect.d_left += font->getTextExtent(*editText);

    }
    else
    {
        // there is highlighted text - because of the BiDi support - the
        // highlighted area can be in some cases nonconsecutive.
        // So - we need to draw it char by char (I guess we can optimize it more
        // but this is not that big performance hit because it only happens if
        // we have highlighted text - not that common...)
        for (size_t i = 0 ; i < editText->size() ; i++)
        {
            // get the char
            String currChar = editText->substr(i, 1);
            size_t realPos = 0;

            // get he visual pos of the char
            if (w->getBiDiVisualMapping()->getV2lMapping().size() > i)
            {
                realPos = w->getBiDiVisualMapping()->getV2lMapping()[i];
            }

            // check if it is in the highlighted region
            bool highlighted =
                realPos >= w->getSelectionStartIndex() &&
                realPos < w->getSelectionStartIndex() + w->getSelectionLength();

            float charAdvance = font->getGlyphData(currChar[0])->getAdvance(1.0f);

            if (highlighted)
            {
                colours.setColours(getSelectedTextColour());
                colours.modulateAlpha(alpha_comp);

                {

                    // calculate area for selection imagery.
                    Rect hlarea(textArea);
                    hlarea.d_left = text_part_rect.d_left ;
                    hlarea.d_right = text_part_rect.d_left + charAdvance ;

                    // render the selection imagery.
                    wlf.getStateImagery(active ? "ActiveSelection" :
                                                 "InactiveSelection").
                        render(*w, hlarea, 0, &textArea);
                }

            }
            else
            {
                colours.setColours(unselectedColour);
                colours.modulateAlpha(alpha_comp);
            }
            font->drawText(w->getGeometryBuffer(), currChar,
                           text_part_rect.getPosition(), &textArea, colours);

            // adjust rect for next section
            text_part_rect.d_left += charAdvance;

        }
    }
#else
    //
    // Render selection imagery.
    //
    if (w->getSelectionLength() != 0)
    {
        // calculate required start and end offsets of selection imagery.
        float selStartOffset =
            font->getTextExtent(editText->substr(0, w->getSelectionStartIndex()));
        float selEndOffset =
            font->getTextExtent(editText->substr(0, w->getSelectionEndIndex()));

        // calculate area for selection imagery.
        Rect hlarea(textArea);
        hlarea.d_left += textOffset + selStartOffset;
        hlarea.d_right = hlarea.d_left + (selEndOffset - selStartOffset);

        // render the selection imagery.
        wlf.getStateImagery(active ? "ActiveSelection" :
                                     "InactiveSelection").
            render(*w, hlarea, 0, &textArea);
    }

    // draw pre-highlight text
    String sect = editText->substr(0, w->getSelectionStartIndex());
    colours.setColours(unselectedColour);
    colours.modulateAlpha(alpha_comp);
    font->drawText(w->getGeometryBuffer(), sect, text_part_rect.getPosition(),
                   &textArea, colours);

    // adjust rect for next section
    text_part_rect.d_left += font->getTextExtent(sect);

    // draw highlight text
    sect = editText->substr(w->getSelectionStartIndex(), w->getSelectionLength());
    colours.setColours(getSelectedTextColour());
    colours.modulateAlpha(alpha_comp);
    font->drawText(w->getGeometryBuffer(), sect, text_part_rect.getPosition(),
                   &textArea, colours);

    // adjust rect for next section
    text_part_rect.d_left += font->getTextExtent(sect);

    // draw post-highlight text
    sect = editText->substr(w->getSelectionEndIndex());
    colours.setColours(unselectedColour);
    colours.modulateAlpha(alpha_comp);
    font->drawText(w->getGeometryBuffer(), sect, text_part_rect.getPosition(),
                   &textArea, colours);

    // remember this for next time.
    d_lastTextOffset = textOffset;
#endif

    //
    // Render carat
    //
    if (active && (!d_blinkCaret || d_showCaret))
    {
        Rect caratRect(textArea);
        caratRect.d_left += extentToCarat + textOffset;

        caratImagery.render(*w, caratRect, 0, &textArea);
    }
}
Example #11
0
//==============================================================================
String File::GetCanonicalPath(const String& path)
{
	//
	// Deal with the empty string right away
	//
	if(path.empty())
	{
		return String();
	}

	//
	// The prefix is copied to the output unchanged
	//
	size_t prefixLen = FileSystem::GetFileSystem()->getPrefixLength(path);
	String ret = path.substr(0, prefixLen);

	//
	// The remainder of the path represents a sequence of names
	// separated by the path separator character.
	//
	StringTokenizer tokenizer(path.substr(prefixLen), GetSeparator());
	String sequence;
	
	const CharType sep = GetSeparatorChar();
	
	while(tokenizer.hasMoreTokens())
	{
		const String& name = tokenizer.nextToken();
		if(name == QC_T("."))
		{
			continue;
		}
		else if(name == QC_T(".."))
		{
			size_t pos = sequence.find_last_of(sep);
			if(pos != String::npos)
			{
				sequence.erase(pos);
			}
			else
			{
				// This is an error.  We have a ".." with no preceding
				// name.  We've gone back as far as we could!
				sequence += sep;
				sequence += name;
			}
		}
		else
		{
			sequence += sep;
			sequence += name;
		}
	}

	if(!sequence.empty())
	{
		//
		// erase the trailing separator from the prefix (if any)
		//
		if(prefixLen && ret[prefixLen-1] == sep)
		{
			ret.erase(prefixLen-1);
		}
		ret += sequence;
	}

	return ret;
}
Example #12
0
File * APKFile::CreateFromAssets(const FilePath &filePath, uint32 attributes)
{
    LockGuard<Mutex> guard(mutex);

    FileSystem * fileSystem = FileSystem::Instance();
	for (List<FileSystem::ResourceArchiveItem>::iterator ai = fileSystem->resourceArchiveList.begin();
         ai != fileSystem->resourceArchiveList.end(); ++ai)
	{
		FileSystem::ResourceArchiveItem & item = *ai;
        
		String filenamecpp = filePath.GetAbsolutePathname();
        
		String::size_type pos = filenamecpp.find(item.attachPath);
		if (0 == pos)
		{
			String relfilename = filenamecpp.substr(item.attachPath.length());
			int32 size = item.archive->LoadResource(relfilename, 0);
			if (-1 == size)
			{
				return 0;
			}
            
			uint8 * buffer = new uint8[size];
			item.archive->LoadResource(relfilename, buffer);

            APKFile *fileInstance = CreateFromData(relfilename, buffer, size, attributes);
            SafeDeleteArray(buffer);
			return fileInstance;
		}
	}
    
    bool isDirectory = FileSystem::Instance()->IsDirectory(filePath);
    if(isDirectory)
    {
        Logger::Error("[APKFile::CreateFromAssets] Can't create file because of it is directory (%s)", filePath.GetAbsolutePathname().c_str());
        return NULL;
    }
    
    AssetsManager* assetsManager = AssetsManager::Instance();
    DVASSERT_MSG(assetsManager, "[APKFile::CreateFromAssets] Need to create AssetsManager before loading files");

    zip* package = assetsManager->GetApplicationPackage();
    if (NULL == package)
    {
        DVASSERT_MSG(false, "[APKFile::CreateFromAssets] Package file should be initialized.");
        return NULL;
    }

    String assetFileStr = filePath.GetAbsolutePathname();

    int index = zip_name_locate(package, assetFileStr.c_str(), 0);
    if (-1 == index)
    {
        Logger::Error("[APKFile::CreateFromAssets] Can't locate file in the archive: %s", assetFileStr.c_str());
        return NULL;
    }

    struct zip_stat stat;

    int32 error = zip_stat_index(package, index, 0, &stat);
    if (-1 == error)
    {
        Logger::Error("[APKFile::CreateFromAssets] Can't get file info: %s", assetFileStr.c_str());
        return NULL;
    }

    zip_file* file = zip_fopen_index(package, index, 0);
    if (NULL == file)
    {
        Logger::Error("[APKFile::CreateFromAssets] Can't open file in the archive: %s", assetFileStr.c_str());
        return NULL;
    }

    DVASSERT(stat.size >= 0);
    uint8 *data = new uint8[stat.size];

    if (zip_fread(file, data, stat.size) != stat.size)
    {
        Logger::Error("[APKFile::CreateFromAssets] Error reading file: %s", assetFileStr.c_str());
        SafeDeleteArray(data);
        zip_fclose(file);
        return NULL;
    }

    APKFile *fileInstance = CreateFromData(filePath, data, stat.size, attributes);
    DVASSERT_MSG(fileInstance, "[APKFile::CreateFromAssets] Can't create dynamic file from memory");

    SafeDeleteArray(data);
    zip_fclose(file);
    return fileInstance;
}
Example #13
0
static void CopyPathInfo(Array& server,
                         Transport *transport,
                         const RequestURI& r,
                         const VirtualHost *vhost) {
  server.set(s_REQUEST_URI, String(transport->getUrl(), CopyString));
  server.set(s_SCRIPT_URL, r.originalURL());
  String prefix(transport->isSSL() ? "https://" : "http://");

  // Need to append port
  assert(server.exists(s_SERVER_PORT));
  std::string serverPort = "80";
  if (server.exists(s_SERVER_PORT)) {
    Variant port = server[s_SERVER_PORT];
    always_assert(port.isInteger() || port.isString());
    if (port.isInteger()) {
      serverPort = folly::to<std::string>(port.toInt32());
    } else {
      serverPort = port.toString().data();
    }
  }

  String port_suffix("");
  if (!transport->isSSL() && serverPort != "80") {
    port_suffix = folly::format(":{}", serverPort).str();
  }

  string hostHeader;
  if (server.exists(s_HTTP_HOST)) {
    hostHeader = server[s_HTTP_HOST].toCStrRef().data();
  }
  String hostName;
  if (server.exists(s_SERVER_NAME)) {
    assert(server[s_SERVER_NAME].isString());
    hostName = server[s_SERVER_NAME].toCStrRef();
  }
  server.set(s_SCRIPT_URI,
             String(prefix + (hostHeader.empty() ? hostName + port_suffix :
                              String(hostHeader)) + r.originalURL()));

  if (r.rewritten()) {
    // when URL is rewritten, PHP decided to put original URL as SCRIPT_NAME
    String name = r.originalURL();
    if (!r.pathInfo().empty()) {
      int pos = name.find(r.pathInfo());
      if (pos >= 0) {
        name = name.substr(0, pos);
      }
    }
    if (r.defaultDoc()) {
      if (!name.empty() && name[name.length() - 1] != '/') {
        name += "/";
      }
      name += String(RuntimeOption::DefaultDocument);
    }
    server.set(s_SCRIPT_NAME, name);
  } else {
    server.set(s_SCRIPT_NAME, r.resolvedURL());
  }

  if (r.rewritten()) {
    server.set(s_PHP_SELF, r.originalURL());
  } else {
    server.set(s_PHP_SELF, r.resolvedURL() + r.origPathInfo());
  }

  String documentRoot = transport->getDocumentRoot();
  if (documentRoot.empty()) {
    // Right now this is just RuntimeOption::SourceRoot but mwilliams wants to
    // fix it so it is settable, so I'll leave this for now
    documentRoot = vhost->getDocumentRoot();
  }
  if (documentRoot != s_forwardslash &&
      documentRoot[documentRoot.length() - 1] == '/') {
    documentRoot = documentRoot.substr(0, documentRoot.length() - 1);
  }
  server.set(s_DOCUMENT_ROOT, documentRoot);
  server.set(s_SCRIPT_FILENAME, r.absolutePath());

  if (r.pathInfo().empty()) {
    server.set(s_PATH_TRANSLATED, r.absolutePath());
  } else {
    assert(server.exists(s_DOCUMENT_ROOT));
    assert(server[s_DOCUMENT_ROOT].isString());
    // reset path_translated back to the transport if it has it.
    auto const& pathTranslated = transport->getPathTranslated();
    if (!pathTranslated.empty()) {
      if (documentRoot == s_forwardslash) {
        // path outside document root or / is document root
        server.set(s_PATH_TRANSLATED, String(pathTranslated));
      } else {
        server.set(s_PATH_TRANSLATED,
                   String(server[s_DOCUMENT_ROOT].toCStrRef() +
                          s_forwardslash + pathTranslated));
      }
    } else {
      server.set(s_PATH_TRANSLATED,
                 String(server[s_DOCUMENT_ROOT].toCStrRef() +
                        server[s_SCRIPT_NAME].toCStrRef() +
                        r.pathInfo().data()));
    }
    server.set(s_PATH_INFO, r.pathInfo());
  }

  switch (transport->getMethod()) {
  case Transport::Method::GET:  server.set(s_REQUEST_METHOD, s_GET);  break;
  case Transport::Method::HEAD: server.set(s_REQUEST_METHOD, s_HEAD); break;
  case Transport::Method::POST:
    if (transport->getExtendedMethod() == nullptr) {
      server.set(s_REQUEST_METHOD, s_POST);
    } else {
      server.set(s_REQUEST_METHOD, transport->getExtendedMethod());
    }
    break;
  default:
    server.set(s_REQUEST_METHOD, empty_string); break;
  }
  server.set(s_HTTPS, transport->isSSL() ? s_on : empty_string);
  server.set(s_QUERY_STRING, r.queryString());

  server.set(s_argv, make_packed_array(r.queryString()));
  server.set(s_argc, 1);
}
Example #14
0
bool Console::GetSpecialInputDown( int key )
{
	if( !IsEnabled() )
		return false;

	if( key == GLFW_KEY_ESC || key == GetToggleConsoleKey() )
	{
		Enable(false);
	}
	else if( key == GLFW_KEY_ENTER )
	{
		AcceptCurrentInput();
		_autoCompleteList.clear();
	}
	else if( key == GLFW_KEY_TAB )
	{
		AcceptAutocomplete();
	}
    else if( key == GLFW_KEY_DEL )
    {
        if (_cursorPos < _currentInput.length())
        {
            String oldInput = _currentInput;

            _currentInput = oldInput.substr( 0, _cursorPos );
            _currentInput += oldInput.substr(_cursorPos+1, oldInput.length());

            _autoCompleteList = GetCompletions(_currentInput);
        }

    }
	else if( key == GLFW_KEY_BACKSPACE )
	{
		if( _cursorPos > 0 )
		{
            String oldInput = _currentInput;

			_currentInput = oldInput.substr( 0, _cursorPos-1 );

            if (_cursorPos < oldInput.length())
            {
                _currentInput += oldInput.substr(_cursorPos, oldInput.length());
            }

            --_cursorPos;

			_autoCompleteList = GetCompletions(_currentInput);
		}
	}
	else if( key == GLFW_KEY_UP ) 
	{
		AdvanceInputHistory( -1 );
	}
	else if( key == GLFW_KEY_DOWN )
	{
		AdvanceInputHistory( 1 );
	}
    else if( key == GLFW_KEY_RIGHT ) 
    {
        if (_cursorPos < _currentInput.length())
        {
            ++_cursorPos;
        }
    }
    else if( key == GLFW_KEY_LEFT )
    {
        if (_cursorPos > 0)
        {
            --_cursorPos;
        }
    }
    else if( key == GLFW_KEY_END )
    {
        _cursorPos = _currentInput.length();
    }
    else if( key == GLFW_KEY_HOME )
    {
        _cursorPos = 0;
    }
	//TODO: Restore
	//else if( key == GLFW_KEY_PAGEUP )
	//{
	//	AdvanceConsoleLog(-1);
	//}
	//else if( key == GLFW_KEY_PAGEDOWN )
	//{
	//	AdvanceConsoleLog(1);
	//}

	return true;

}
void RegistrationResult::read(const String &line) {
  algebra::VectorD<4> quaternion;
  String s = line;
  size_t n;
  n = s.find("|");
  set_image_index(std::atoi(s.substr(0, n).c_str()));
  s = s.substr(n + 1);
  n = s.find("|");
  set_projection_index(std::atoi(s.substr(0, n).c_str()));
  s = s.substr(n + 1);
  n = s.find("|");
  phi_ = std::atof(s.substr(0, n).c_str());
  s = s.substr(n + 1);
  n = s.find("|");
  theta_ = std::atof(s.substr(0, n).c_str());
  s = s.substr(n + 1);
  n = s.find("|");
  psi_ = std::atof(s.substr(0, n).c_str());
  s = s.substr(n + 1);
  n = s.find("|");
  quaternion[0] = std::atof(s.substr(0, n).c_str());
  s = s.substr(n + 1);
  n = s.find("|");
  quaternion[1] = std::atof(s.substr(0, n).c_str());
  s = s.substr(n + 1);
  n = s.find("|");
  quaternion[2] = std::atof(s.substr(0, n).c_str());
  s = s.substr(n + 1);
  n = s.find("|");
  quaternion[3] = std::atof(s.substr(0, n).c_str());
  s = s.substr(n + 1);
  n = s.find("|");
  shift_[0] = std::atof(s.substr(0, n).c_str());
  s = s.substr(n + 1);
  n = s.find("|");
  shift_[1] = std::atof(s.substr(0, n).c_str());
  s = s.substr(n + 1);
  n = s.find("|");
  set_ccc(std::atof(s.substr(0, n).c_str()));
  R_ = algebra::get_rotation_from_vector4d(quaternion);
}
Example #16
0
bool compiler::compile_struct_pointer(codegen & cg, struct_pointer_node * sn)
{
	FKLOG("[compiler] compile_struct_pointer %p", sn);

	fake * fk = m_fk;

	String name = sn->str;
	std::vector<String> tmp;
	do
	{
		int pos = name.find("->");
		if (pos == -1)
		{
			tmp.push_back(name);
			break;
		}
		tmp.push_back(name.substr(0, pos));
		name = name.substr(pos + 2);
	}
	while (1);

	if (tmp.size() < 2)
	{
		FKERR("[compiler] compile_struct_pointer pointer %s fail", sn->str.c_str());
		return false;
	}

	String connname = tmp[0];
	
	// 编译con
	command con = 0;
	
	// 看看是否是全局常量定义
	variant * gcv = m_fk->pa.get_const_define(connname.c_str());
	if (gcv)
	{
		int pos = cg.getconst(*gcv);
		con = MAKE_ADDR(ADDR_CONST, pos);
	}
	else
	{
		int pos = cg.getvariable(connname);
		if (pos == -1)
		{
			FKERR("[compiler] compile_struct_pointer variable not found %s", connname.c_str());
			compile_seterror(sn, m_fk, efk_compile_variable_not_found, "variable %s not found", connname.c_str());
			return false;
		}
		con = MAKE_ADDR(ADDR_STACK, pos);
	}
	
	for (int i = 1; i < (int)tmp.size(); i++)
	{
		String keystr = tmp[i];
		
		// 编译key
		variant v;
		v = fk->sh.allocsysstr(keystr.c_str());
		int pos = cg.getconst(v);
		command key = MAKE_ADDR(ADDR_CONST, pos);

		// 获取容器的位置
		int addrpos = cg.getcontaineraddr(con, key);
		m_cur_addr = MAKE_ADDR(ADDR_CONTAINER, addrpos);
		con = m_cur_addr;
	}

	FKLOG("[compiler] compile_struct_pointer %p OK", sn);

	return true;
}
Example #17
0
void FileSystemDock::drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from){

	if (!can_drop_data_fw(p_point,p_data,p_from))
		return;
	Dictionary drag_data = p_data;

	if (drag_data.has("type") && String(drag_data["type"])=="favorite") {

		//moving favorite around
		TreeItem *ti = tree->get_item_at_pos(p_point);
		if (!ti)
			return;

		Vector<String> files = drag_data["files"];

		ERR_FAIL_COND(files.size()!=1);

		String swap = files[0];
		if (swap!="res://" && swap.ends_with("/")) {
			swap=swap.substr(0,swap.length()-1);
		}

		int what = tree->get_drop_section_at_pos(p_point);

		TreeItem *swap_item=NULL;

		if (ti==tree->get_root()->get_children()) {
			swap_item=tree->get_root()->get_children()->get_children();

		} else if (ti->get_parent() && tree->get_root()->get_children()==ti->get_parent()) {
			if (what==-1) {
				swap_item=ti;
			} else {
				swap_item=ti->get_next();
			}
		}

		String swap_with;

		if (swap_item) {
			swap_with=swap_item->get_metadata(0);
			if (swap_with!="res://" && swap_with.ends_with("/")) {
				swap_with=swap_with.substr(0,swap_with.length()-1);
			}
		}

		if (swap==swap_with)
			return;

		Vector<String> dirs = EditorSettings::get_singleton()->get_favorite_dirs();

		ERR_FAIL_COND(dirs.find(swap)==-1);
		ERR_FAIL_COND(swap_with!=String() && dirs.find(swap_with)==-1);

		dirs.erase(swap);

		if (swap_with==String()) {
			dirs.push_back(swap);
		} else {
			int idx = dirs.find(swap_with);
			dirs.insert(idx,swap);
		}

		EditorSettings::get_singleton()->set_favorite_dirs(dirs);
		_update_tree();
		return;

	}

	if (drag_data.has("type") && String(drag_data["type"])=="resource") {
		Ref<Resource> res = drag_data["resource"];

		if (!res.is_valid()) {
			return;
		}


		if (p_from==tree) {

			TreeItem *ti = tree->get_item_at_pos(p_point);
			if (!ti)
				return;
			String path = ti->get_metadata(0);

			if (path==String())
				return;

			EditorNode::get_singleton()->save_resource_as(res,path);
			return;

		}

		if (p_from==files) {
			String save_path=path;

			int at_pos = files->get_item_at_pos(p_point);
			if (at_pos!=-1) {
				String to_dir = files->get_item_metadata(at_pos);
				if (to_dir.ends_with("/")) {
					save_path=to_dir;
					if (save_path!="res://")
						save_path=save_path.substr(0,save_path.length()-1);
				}

			}

			EditorNode::get_singleton()->save_resource_as(res,save_path);
			return;
		}
	}

	if (drag_data.has("type") && ( String(drag_data["type"])=="files" || String(drag_data["type"])=="files_and_dirs")) {

		if (p_from==files || p_from==tree) {

			String to_dir;

			if (p_from==files) {

				int at_pos = files->get_item_at_pos(p_point);
				ERR_FAIL_COND(at_pos==-1);
				to_dir = files->get_item_metadata(at_pos);
			}  else {
				TreeItem *ti = tree->get_item_at_pos(p_point);
				if (!ti)
					return;
				to_dir = ti->get_metadata(0);
				ERR_FAIL_COND(to_dir==String());

			}

			if (to_dir!="res://" && to_dir.ends_with("/")) {
				to_dir=to_dir.substr(0,to_dir.length()-1);
			}

			Vector<String> fnames = drag_data["files"];
			move_files.clear();
			move_dirs.clear();

			for(int i=0;i<fnames.size();i++) {
				if (fnames[i].ends_with("/"))
					move_dirs.push_back(fnames[i]);
				else
					move_files.push_back(fnames[i]);
			}

			_move_operation(to_dir);
		}
	}

}
String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, GeneratedCode& r_gen_code, IdentifierActions &p_actions, const DefaultIdentifierActions &p_default_actions) {

	String code;

	switch(p_node->type) {

		case SL::Node::TYPE_SHADER: {

			SL::ShaderNode *pnode=(SL::ShaderNode*)p_node;

			for(int i=0;i<pnode->render_modes.size();i++) {

				if (p_default_actions.render_mode_defines.has(pnode->render_modes[i]) && !used_rmode_defines.has(pnode->render_modes[i])) {

					r_gen_code.defines.push_back(p_default_actions.render_mode_defines[pnode->render_modes[i]].utf8());
					used_rmode_defines.insert(pnode->render_modes[i]);
				}

				if (p_actions.render_mode_flags.has(pnode->render_modes[i])) {
					*p_actions.render_mode_flags[pnode->render_modes[i]]=true;
				}

				if (p_actions.render_mode_values.has(pnode->render_modes[i])) {
					Pair<int*,int> &p = p_actions.render_mode_values[pnode->render_modes[i]];
					*p.first=p.second;
				}
			}


			int max_texture_uniforms=0;
			int max_uniforms=0;

			for(Map<StringName,SL::ShaderNode::Uniform>::Element *E=pnode->uniforms.front();E;E=E->next()) {
				if (SL::is_sampler_type(E->get().type))
					max_texture_uniforms++;
				else
					max_uniforms++;
			}

			r_gen_code.texture_uniforms.resize(max_texture_uniforms);
			r_gen_code.texture_hints.resize(max_texture_uniforms);

			Vector<int> uniform_sizes;
			Vector<int> uniform_alignments;
			Vector<StringName> uniform_defines;
			uniform_sizes.resize(max_uniforms);
			uniform_alignments.resize(max_uniforms);
			uniform_defines.resize(max_uniforms);

			for(Map<StringName,SL::ShaderNode::Uniform>::Element *E=pnode->uniforms.front();E;E=E->next()) {

				String ucode;

				if (SL::is_sampler_type(E->get().type)) {
					ucode="uniform ";
				}

				ucode+=_prestr(E->get().precission);
				ucode+=_typestr(E->get().type);
				ucode+=" "+_mkid(E->key());
				ucode+=";\n";
				if (SL::is_sampler_type(E->get().type)) {
					r_gen_code.vertex_global+=ucode;
					r_gen_code.fragment_global+=ucode;
					r_gen_code.texture_uniforms[E->get().texture_order]=_mkid(E->key());
					r_gen_code.texture_hints[E->get().texture_order]=E->get().hint;
				} else {
					if (r_gen_code.uniforms.empty()) {

						r_gen_code.defines.push_back(String("#define USE_MATERIAL\n").ascii());
					}
					uniform_defines[E->get().order]=ucode;
					uniform_sizes[E->get().order]=_get_datatype_size(E->get().type);
					uniform_alignments[E->get().order]=MIN(16,_get_datatype_size(E->get().type));
				}

				p_actions.uniforms->insert(E->key(),E->get());

			}

			for(int i=0;i<max_uniforms;i++) {
				r_gen_code.uniforms+=uniform_defines[i];
			}
			// add up
			for(int i=0;i<uniform_sizes.size();i++) {

				if (i>0) {

					int align = uniform_sizes[i-1] % uniform_alignments[i];
					if (align!=0) {
						uniform_sizes[i-1]+=uniform_alignments[i]-align;
					}

					uniform_sizes[i]=uniform_sizes[i]+uniform_sizes[i-1];

				}
			}
			//offset
			r_gen_code.uniform_offsets.resize(uniform_sizes.size());
			for(int i=0;i<uniform_sizes.size();i++) {

				if (i>0)
					r_gen_code.uniform_offsets[i]=uniform_sizes[i-1];
				else
					r_gen_code.uniform_offsets[i]=0;


			}
/*
			for(Map<StringName,SL::ShaderNode::Uniform>::Element *E=pnode->uniforms.front();E;E=E->next()) {

				if (SL::is_sampler_type(E->get().type)) {
					continue;
				}

				print_line("u - "+String(E->key())+" offset: "+itos(r_gen_code.uniform_offsets[E->get().order]));

			}

*/
			if (uniform_sizes.size()) {
				r_gen_code.uniform_total_size=uniform_sizes[ uniform_sizes.size() -1 ];
			} else {
				r_gen_code.uniform_total_size=0;
			}

			for(Map<StringName,SL::ShaderNode::Varying>::Element *E=pnode->varyings.front();E;E=E->next()) {

				String vcode;
				vcode+=_prestr(E->get().precission);
				vcode+=_typestr(E->get().type);
				vcode+=" "+String(E->key());
				vcode+=";\n";
				r_gen_code.vertex_global+="out "+vcode;
				r_gen_code.fragment_global+="in "+vcode;
			}

			Map<StringName,String> function_code;

			//code for functions
			for(int i=0;i<pnode->functions.size();i++) {
				SL::FunctionNode *fnode=pnode->functions[i].function;
				function_code[fnode->name]=_dump_node_code(fnode->body,p_level+1,r_gen_code,p_actions,p_default_actions);
			}

			//place functions in actual code

			Set<StringName> added_vtx;
			Set<StringName> added_fragment; //share for light

			for(int i=0;i<pnode->functions.size();i++) {

				SL::FunctionNode *fnode=pnode->functions[i].function;

				current_func_name=fnode->name;

				if (fnode->name=="vertex") {

					_dump_function_deps(pnode,fnode->name,function_code,r_gen_code.vertex_global,added_vtx);
					r_gen_code.vertex=function_code["vertex"];
				}

				if (fnode->name=="fragment") {

					_dump_function_deps(pnode,fnode->name,function_code,r_gen_code.fragment_global,added_fragment);
					r_gen_code.fragment=function_code["fragment"];
				}

				if (fnode->name=="light") {

					_dump_function_deps(pnode,fnode->name,function_code,r_gen_code.fragment_global,added_fragment);
					r_gen_code.light=function_code["light"];
				}
			}

			//code+=dump_node_code(pnode->body,p_level);
		} break;
		case SL::Node::TYPE_FUNCTION: {

		} break;
		case SL::Node::TYPE_BLOCK: {
			SL::BlockNode *bnode=(SL::BlockNode*)p_node;

			//variables
			code+=_mktab(p_level-1)+"{\n";
			for(Map<StringName,SL::BlockNode::Variable>::Element *E=bnode->variables.front();E;E=E->next()) {

				code+=_mktab(p_level)+_prestr(E->get().precision)+_typestr(E->get().type)+" "+_mkid(E->key())+";\n";
			}

			for(int i=0;i<bnode->statements.size();i++) {

				String scode = _dump_node_code(bnode->statements[i],p_level,r_gen_code,p_actions,p_default_actions);

				if (bnode->statements[i]->type==SL::Node::TYPE_CONTROL_FLOW || bnode->statements[i]->type==SL::Node::TYPE_CONTROL_FLOW) {
					code+=scode; //use directly
				} else {
					code+=_mktab(p_level)+scode+";\n";
				}
			}
			code+=_mktab(p_level-1)+"}\n";


		} break;
		case SL::Node::TYPE_VARIABLE: {
			SL::VariableNode *vnode=(SL::VariableNode*)p_node;

			if (p_default_actions.usage_defines.has(vnode->name) && !used_name_defines.has(vnode->name)) {
				String define = p_default_actions.usage_defines[vnode->name];
				if (define.begins_with("@")) {
					define = p_default_actions.usage_defines[define.substr(1,define.length())];
				}
				r_gen_code.defines.push_back(define.utf8());
				used_name_defines.insert(vnode->name);
			}

			if (p_actions.usage_flag_pointers.has(vnode->name) && !used_flag_pointers.has(vnode->name)) {
				*p_actions.usage_flag_pointers[vnode->name]=true;
				used_flag_pointers.insert(vnode->name);
			}

			if (p_default_actions.renames.has(vnode->name))
				code=p_default_actions.renames[vnode->name];
			else
				code=_mkid(vnode->name);

			if (vnode->name==time_name) {
				if (current_func_name==vertex_name) {
					r_gen_code.uses_vertex_time=true;
				}
				if (current_func_name==fragment_name) {
					r_gen_code.uses_fragment_time=true;
				}
			}

		} break;
		case SL::Node::TYPE_CONSTANT: {
			SL::ConstantNode *cnode=(SL::ConstantNode*)p_node;
			return get_constant_text(cnode->datatype,cnode->values);

		} break;
		case SL::Node::TYPE_OPERATOR: {
			SL::OperatorNode *onode=(SL::OperatorNode*)p_node;


			switch(onode->op) {

				case SL::OP_ASSIGN:
				case SL::OP_ASSIGN_ADD:
				case SL::OP_ASSIGN_SUB:
				case SL::OP_ASSIGN_MUL:
				case SL::OP_ASSIGN_DIV:
				case SL::OP_ASSIGN_SHIFT_LEFT:
				case SL::OP_ASSIGN_SHIFT_RIGHT:
				case SL::OP_ASSIGN_MOD:
				case SL::OP_ASSIGN_BIT_AND:
				case SL::OP_ASSIGN_BIT_OR:
				case SL::OP_ASSIGN_BIT_XOR:
					code=_dump_node_code(onode->arguments[0],p_level,r_gen_code,p_actions,p_default_actions)+_opstr(onode->op)+_dump_node_code(onode->arguments[1],p_level,r_gen_code,p_actions,p_default_actions);
					break;
				case SL::OP_BIT_INVERT:
				case SL::OP_NEGATE:
				case SL::OP_NOT:
				case SL::OP_DECREMENT:
				case SL::OP_INCREMENT:
					code=_opstr(onode->op)+_dump_node_code(onode->arguments[0],p_level,r_gen_code,p_actions,p_default_actions);
					break;
				case SL::OP_POST_DECREMENT:
				case SL::OP_POST_INCREMENT:
					code=_dump_node_code(onode->arguments[0],p_level,r_gen_code,p_actions,p_default_actions)+_opstr(onode->op);
					break;
				case SL::OP_CALL:
				case SL::OP_CONSTRUCT: {

					ERR_FAIL_COND_V(onode->arguments[0]->type!=SL::Node::TYPE_VARIABLE,String());

					SL::VariableNode *vnode=(SL::VariableNode*)onode->arguments[0];

					if (onode->op==SL::OP_CONSTRUCT) {
						code+=String(vnode->name);
					} else {

						if (internal_functions.has(vnode->name)) {
							code+=vnode->name;
						} else if (p_default_actions.renames.has(vnode->name)) {
							code+=p_default_actions.renames[vnode->name];
						} else {
							code+=_mkid(vnode->name);
						}
					}

					code+="(";

					for(int i=1;i<onode->arguments.size();i++) {
						if (i>1)
							code+=", ";
						code+=_dump_node_code(onode->arguments[i],p_level,r_gen_code,p_actions,p_default_actions);
					}
					code+=")";
				} break;
				default: {

					code="("+_dump_node_code(onode->arguments[0],p_level,r_gen_code,p_actions,p_default_actions)+_opstr(onode->op)+_dump_node_code(onode->arguments[1],p_level,r_gen_code,p_actions,p_default_actions)+")";
					break;

				}
			}

		} break;
		case SL::Node::TYPE_CONTROL_FLOW: {
			SL::ControlFlowNode *cfnode=(SL::ControlFlowNode*)p_node;
			if (cfnode->flow_op==SL::FLOW_OP_IF) {

				code+=_mktab(p_level)+"if ("+_dump_node_code(cfnode->expressions[0],p_level,r_gen_code,p_actions,p_default_actions)+")\n";
				code+=_dump_node_code(cfnode->blocks[0],p_level+1,r_gen_code,p_actions,p_default_actions);
				if (cfnode->blocks.size()==2) {

					code+=_mktab(p_level)+"else\n";
					code+=_dump_node_code(cfnode->blocks[1],p_level+1,r_gen_code,p_actions,p_default_actions);
				}


			} else if (cfnode->flow_op==SL::FLOW_OP_RETURN) {

				if (cfnode->blocks.size()) {
					code="return "+_dump_node_code(cfnode->blocks[0],p_level,r_gen_code,p_actions,p_default_actions);
				} else {
					code="return";
				}
			}

		} break;
		case SL::Node::TYPE_MEMBER: {
			SL::MemberNode *mnode=(SL::MemberNode*)p_node;
			code=_dump_node_code(mnode->owner,p_level,r_gen_code,p_actions,p_default_actions)+"."+mnode->name;

		} break;
	}

	return code;

}
Example #19
0
void FileSystemDock::_file_option(int p_option) {

	switch(p_option) {


		case FILE_SHOW_IN_EXPLORER:
		case FILE_OPEN: {
			int idx=-1;
			for(int i=0;i<files->get_item_count();i++) {
				if (files->is_selected(i)) {
					idx=i;
					break;
				}
			}

			if (idx<0)
				return;



			String path = files->get_item_metadata(idx);
			if (p_option == FILE_SHOW_IN_EXPLORER) {
				String dir = Globals::get_singleton()->globalize_path(path);
				dir = dir.substr(0, dir.find_last("/"));
				OS::get_singleton()->shell_open(String("file://")+dir);
				return;
			}

			if (path.ends_with("/")) {
				if (path!="res://") {
					path=path.substr(0,path.length()-1);
				}
				this->path=path;
				_update_files(false);
				current_path->set_text(path);
				_push_to_history();
			} else {

				if (ResourceLoader::get_resource_type(path)=="PackedScene") {

					editor->open_request(path);
				} else {

					editor->load_resource(path);
				}
			}
		} break;
		case FILE_INSTANCE: {

			Vector<String> paths;

			for (int i = 0; i<files->get_item_count(); i++) {
				if (!files->is_selected(i))
					continue;
				String path =files->get_item_metadata(i);
				if (EditorFileSystem::get_singleton()->get_file_type(path)=="PackedScene") {
					paths.push_back(path);
				}
			}

			if (!paths.empty()) {
				emit_signal("instance", paths);
			}
		} break;
		case FILE_DEPENDENCIES: {

			int idx = files->get_current();
			if (idx<0 || idx>=files->get_item_count())
				break;
			String path = files->get_item_metadata(idx);
			deps_editor->edit(path);
		} break;
		case FILE_OWNERS: {

			int idx = files->get_current();
			if (idx<0 || idx>=files->get_item_count())
				break;
			String path = files->get_item_metadata(idx);
			owners_editor->show(path);
		} break;
		case FILE_MOVE: {

			move_dirs.clear();;
			move_files.clear();

			for(int i=0;i<files->get_item_count();i++) {

				String path = files->get_item_metadata(i);
				if (!files->is_selected(i))
					continue;

				 if (files->get_item_text(i)=="..") {
					 EditorNode::get_singleton()->show_warning(TTR("Can't operate on '..'"));
					 return;
				 }

				if (path.ends_with("/")) {
					move_dirs.push_back(path.substr(0,path.length()-1));
				} else {
					move_files.push_back(path);
				}
			}


			if (move_dirs.empty() && move_files.size()==1) {

				rename_dialog->clear_filters();
				rename_dialog->add_filter("*."+move_files[0].extension());
				rename_dialog->set_mode(EditorFileDialog::MODE_SAVE_FILE);
				rename_dialog->set_current_path(move_files[0]);
				rename_dialog->popup_centered_ratio();
				rename_dialog->set_title(TTR("Pick New Name and Location For:")+" "+move_files[0].get_file());


			} else {
				//just move
				move_dialog->popup_centered_ratio();
			}


		} break;
		case FILE_REMOVE: {

			Vector<String> torem;

			for(int i=0;i<files->get_item_count();i++) {

				String path = files->get_item_metadata(i);
				if (path.ends_with("/") || !files->is_selected(i))
					continue;
				torem.push_back(path);

			}

			if (torem.empty()) {
				EditorNode::get_singleton()->show_warning(TTR("No files selected!"));
				break;
			}

			remove_dialog->show(torem);
			//1) find if used
			//2) warn

		} break;
		case FILE_INFO: {

		} break;
		case FILE_REIMPORT: {


			Vector<String> reimport;
			for(int i=0;i<files->get_item_count();i++) {

				if (!files->is_selected(i))
					continue;

				String path = files->get_item_metadata(i);
				reimport.push_back(path);
			}

			ERR_FAIL_COND(reimport.size()==0);

			Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(reimport[0]);
			ERR_FAIL_COND(!rimd.is_valid());
			String editor=rimd->get_editor();

			if (editor.begins_with("texture_")) { //compatibility fix for old texture format
				editor="texture";
			}

			Ref<EditorImportPlugin> rimp = EditorImportExport::get_singleton()->get_import_plugin_by_name(editor);
			ERR_FAIL_COND(!rimp.is_valid());

			if (reimport.size()==1) {
				rimp->import_dialog(reimport[0]);
			} else {
				rimp->reimport_multiple_files(reimport);

			}

		} break;
		case FILE_COPY_PATH:

			int idx = files->get_current();
			if (idx<0 || idx>=files->get_item_count())
				break;
			String path = files->get_item_metadata(idx);
			OS::get_singleton()->set_clipboard(path);
	}
}
Example #20
0
Ref<Texture> EditorScriptPreviewPlugin::generate(const RES &p_from) {

	Ref<Script> scr = p_from;
	if (scr.is_null())
		return Ref<Texture>();

	String code = scr->get_source_code().strip_edges();
	if (code == "")
		return Ref<Texture>();

	List<String> kwors;
	scr->get_language()->get_reserved_words(&kwors);

	Set<String> keywords;

	for (List<String>::Element *E = kwors.front(); E; E = E->next()) {

		keywords.insert(E->get());
	}

	int line = 0;
	int col = 0;
	int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size");
	thumbnail_size *= EDSCALE;
	Ref<Image> img;
	img.instance();
	img->create(thumbnail_size, thumbnail_size, 0, Image::FORMAT_RGBA8);

	Color bg_color = EditorSettings::get_singleton()->get("text_editor/highlighting/background_color");
	bg_color.a = 1.0;
	Color keyword_color = EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color");
	Color text_color = EditorSettings::get_singleton()->get("text_editor/highlighting/text_color");
	Color symbol_color = EditorSettings::get_singleton()->get("text_editor/highlighting/symbol_color");

	img->lock();

	for (int i = 0; i < thumbnail_size; i++) {
		for (int j = 0; j < thumbnail_size; j++) {
			img->set_pixel(i, j, bg_color);
		}
	}

	bool prev_is_text = false;
	bool in_keyword = false;
	for (int i = 0; i < code.length(); i++) {

		CharType c = code[i];
		if (c > 32) {
			if (col < thumbnail_size) {
				Color color = text_color;

				if (c != '_' && ((c >= '!' && c <= '/') || (c >= ':' && c <= '@') || (c >= '[' && c <= '`') || (c >= '{' && c <= '~') || c == '\t')) {
					//make symbol a little visible
					color = symbol_color;
					in_keyword = false;
				} else if (!prev_is_text && _is_text_char(c)) {
					int pos = i;

					while (_is_text_char(code[pos])) {
						pos++;
					}
					String word = code.substr(i, pos - i);
					if (keywords.has(word))
						in_keyword = true;

				} else if (!_is_text_char(c)) {
					in_keyword = false;
				}

				if (in_keyword)
					color = keyword_color;

				Color ul = color;
				ul.a *= 0.5;
				img->set_pixel(col, line * 2, bg_color.blend(ul));
				img->set_pixel(col, line * 2 + 1, color);

				prev_is_text = _is_text_char(c);
			}
		} else {

			prev_is_text = false;
			in_keyword = false;

			if (c == '\n') {
				col = 0;
				line++;
				if (line >= thumbnail_size / 2)
					break;
			} else if (c == '\t') {
				col += 3;
			}
		}
		col++;
	}

	img->unlock();

	Ref<ImageTexture> ptex = Ref<ImageTexture>(memnew(ImageTexture));

	ptex->create_from_image(img, 0);
	return ptex;
}
void EditorAutoloadSettings::update_autoload() {

	if (updating_autoload)
		return;

	updating_autoload = true;

	Map<String, AutoLoadInfo> to_remove;
	List<AutoLoadInfo *> to_add;

	for (List<AutoLoadInfo>::Element *E = autoload_cache.front(); E; E = E->next()) {
		AutoLoadInfo &info = E->get();
		to_remove.insert(info.name, info);
	}

	autoload_cache.clear();

	tree->clear();
	TreeItem *root = tree->create_item();

	List<PropertyInfo> props;
	ProjectSettings::get_singleton()->get_property_list(&props);

	for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {

		const PropertyInfo &pi = E->get();

		if (!pi.name.begins_with("autoload/"))
			continue;

		String name = pi.name.get_slice("/", 1);
		String path = ProjectSettings::get_singleton()->get(pi.name);

		if (name.empty())
			continue;

		AutoLoadInfo info;
		info.is_singleton = path.begins_with("*");

		if (info.is_singleton) {
			path = path.substr(1, path.length());
		}

		info.name = name;
		info.path = path;
		info.order = ProjectSettings::get_singleton()->get_order(pi.name);

		bool need_to_add = true;
		if (to_remove.has(name)) {
			AutoLoadInfo &old_info = to_remove[name];
			if (old_info.path == info.path) {
				// Still the same resource, check status
				info.node = old_info.node;
				if (info.node) {
					Ref<Script> scr = info.node->get_script();
					info.in_editor = scr.is_valid() && scr->is_tool();
					if (info.is_singleton == old_info.is_singleton && info.in_editor == old_info.in_editor) {
						to_remove.erase(name);
						need_to_add = false;
					} else {
						info.node = NULL;
					}
				}
			}
		}

		autoload_cache.push_back(info);

		if (need_to_add) {
			to_add.push_back(&(autoload_cache.back()->get()));
		}

		TreeItem *item = tree->create_item(root);
		item->set_text(0, name);
		item->set_editable(0, true);

		item->set_text(1, path);
		item->set_selectable(1, true);

		item->set_cell_mode(2, TreeItem::CELL_MODE_CHECK);
		item->set_editable(2, true);
		item->set_text(2, TTR("Enable"));
		item->set_checked(2, info.is_singleton);
		item->add_button(3, get_icon("FileList", "EditorIcons"), BUTTON_OPEN);
		item->add_button(3, get_icon("MoveUp", "EditorIcons"), BUTTON_MOVE_UP);
		item->add_button(3, get_icon("MoveDown", "EditorIcons"), BUTTON_MOVE_DOWN);
		item->add_button(3, get_icon("Remove", "EditorIcons"), BUTTON_DELETE);
		item->set_selectable(3, false);
	}

	// Remove deleted/changed autoloads
	for (Map<String, AutoLoadInfo>::Element *E = to_remove.front(); E; E = E->next()) {
		AutoLoadInfo &info = E->get();
		if (info.is_singleton) {
			for (int i = 0; i < ScriptServer::get_language_count(); i++) {
				ScriptServer::get_language(i)->remove_named_global_constant(info.name);
			}
		}
		if (info.in_editor) {
			ERR_CONTINUE(!info.node);
			get_tree()->get_root()->remove_child(info.node);
		}

		if (info.node) {
			memdelete(info.node);
			info.node = NULL;
		}
	}

	// Load new/changed autoloads
	List<Node *> nodes_to_add;
	for (List<AutoLoadInfo *>::Element *E = to_add.front(); E; E = E->next()) {
		AutoLoadInfo *info = E->get();

		info->node = _create_autoload(info->path);

		ERR_CONTINUE(!info->node);
		info->node->set_name(info->name);

		Ref<Script> scr = info->node->get_script();
		info->in_editor = scr.is_valid() && scr->is_tool();

		if (info->in_editor) {
			//defer so references are all valid on _ready()
			nodes_to_add.push_back(info->node);
		}

		if (info->is_singleton) {
			for (int i = 0; i < ScriptServer::get_language_count(); i++) {
				ScriptServer::get_language(i)->add_named_global_constant(info->name, info->node);
			}
		}

		if (!info->in_editor && !info->is_singleton) {
			// No reason to keep this node
			memdelete(info->node);
			info->node = NULL;
		}
	}

	for (List<Node *>::Element *E = nodes_to_add.front(); E; E = E->next()) {
		get_tree()->get_root()->add_child(E->get());
	}

	updating_autoload = false;
}
Example #22
0
/** A hint is formed by
 *    1. an insertion of a parameter, <param-..>...</param->.
 *    2. a <hint-1> or <hint-2> tag
 *   
 *  Hints have the following meaning:
 *   -  "<hint-1>xxx(yyy)zzz"       ---> "xxxzzz"     (singular)
 *   -  "<hint-2>xxx(yyy)zzz"       ---> "xxxyyyzzz"  (plural)
 *   -  "[^., ]a <param-..>[aeiou]" ---> "\1 an \2"   (articla 'an', case insensitive)
 *   -  "<hint-?>"                  ---> ""           (remove <hint>s afterwards)
 *
 *  Note: there is no close tags for hints
 */
String process_english_hints(const String& str) {
	String ret; ret.reserve(str.size());
	// have we seen a <hint-1/2>?
	// 1 for singular, 2 for plural
	int singplur = 0;
	for (size_t i = 0 ; i < str.size() ; ) {
		Char c = str.GetChar(i);
		if (is_substr(str, i, _("<hint-"))) {
			Char h = str.GetChar(i + 6); // hint code
			if (h == _('1')) {
				singplur = 1;
			} else if (h == _('2')) {
				singplur = 2;
			}
			i = skip_tag(str, i);
		} else if (is_substr(str, i, _("<param-"))) {
			size_t after = skip_tag(str, i);
			if (after != String::npos) {
				Char c = str.GetChar(after);
				if (singplur == 1 && is_substr(str, after, _("a</param-"))) {
					// a -> an, where the a originates from english_number_a(1)
					size_t after_end = skip_tag(str,after+1);
					if (after_end == String::npos) {
						throw Error(_("Incomplete </param> tag"));
					}
					if (after_end != String::npos && after_end + 1 < str.size()
					&& isSpace(str.GetChar(after_end)) && is_vowel(str.GetChar(after_end+1))) {
						ret.append(str,i,after-i);
						ret += _("an");
						i = after + 1;
						continue;
					}
				} else if (is_vowel(c) && ret.size() >= 2) {
					// a -> an?
					// is there "a" before this?
					String last = ret.substr(ret.size() - 2);
					if ( (ret.size() == 2 || !isAlpha(ret.GetChar(ret.size() - 3))) &&
						(last == _("a ") || last == _("A ")) ) {
						ret.insert(ret.size() - 1, _('n'));
					}
				} else if (is_substr(str, after, _("</param-")) && ret.size() >= 1 &&
							ret.GetChar(ret.size() - 1) == _(' ')) {
					// empty param, drop space before it
					ret.resize(ret.size() - 1);
				}
			}
			ret.append(str,i,min(after,str.size())-i);
			i = after;
		} else if (is_substr(str, i, _("<singular>"))) {
			// singular -> keep, plural -> drop
			size_t start = skip_tag(str, i);
			size_t end   = match_close_tag(str, start);
			if (singplur == 1 && end != String::npos) {
				ret += str.substr(start, end - start);
			}
			singplur = 0;
			i = skip_tag(str, end);
		} else if (is_substr(str, i, _("<plural>"))) {
			// singular -> drop, plural -> keep
			size_t start = skip_tag(str, i);
			size_t end   = match_close_tag(str, start);
			if (singplur == 2 && end != String::npos) {
				ret += str.substr(start, end - start);
			}
			singplur = 0;
			i = skip_tag(str, end);
		} else if (c == _('(') && singplur) {
			// singular -> drop (...), plural -> keep it
			size_t end = str.find_first_of(_(')'), i);
			if (end != String::npos) {
				if (singplur == 2) {
					ret += str.substr(i + 1, end - i - 1);
				}
				i = end + 1;
			} else { // handle like normal
				ret += c;
				++i;
			}
			singplur = 0;
		} else if (c == _('<')) {
			size_t after = skip_tag(str, i);
			ret.append(str,i,min(after,str.size())-i);
			i = after;
		} else {
			ret += c;
			++i;
		}
	}
	return ret;
}
Example #23
0
bool CHttpServer::send_file(String const &path, HeaderList const &hdrs)
{
    String fullPath = CFilePath::normalizePath(path);

    if (String_startsWith(fullPath,"/app/db/db-files") )
        fullPath = CFilePath::join( rho_native_rhodbpath(), path.substr(4) );
    else if (fullPath.find(m_root) != 0 && fullPath.find(m_strRhoRoot) != 0 && fullPath.find(m_strRuntimeRoot) != 0 && fullPath.find(m_userroot) != 0 && fullPath.find(m_strRhoUserRoot) != 0)
        fullPath = CFilePath::join( m_root, path );
	
    struct stat st;
    bool bCheckExist = true;
#ifdef RHODES_EMULATOR
    String strPlatform = RHOSIMCONF().getString("platform");
    if ( strPlatform.length() > 0 )
    {
        String fullPath1 = fullPath;
        int nDot = fullPath1.rfind('.');
        if ( nDot >= 0 )
            fullPath1.insert(nDot, String(".") + strPlatform);
        else
            fullPath1 += String(".") + strPlatform;

        if (stat(fullPath1.c_str(), &st) == 0 && S_ISREG(st.st_mode))
        {
            fullPath = fullPath1;
            bCheckExist = false;
        }
    }

#endif

    bool doesNotExists = bCheckExist && (stat(fullPath.c_str(), &st) != 0 || !S_ISREG(st.st_mode));
    if ( doesNotExists ) {
        // looking for files at 'rho/apps' at runtime folder
        fullPath = CFilePath::join( m_strRuntimeRoot, path );
    }

    if (verbose) RAWTRACE1("Sending file %s...", fullPath.c_str());

    if ( doesNotExists ) {
        if ( stat(fullPath.c_str(), &st) != 0 || !S_ISREG(st.st_mode) ) {
            doesNotExists = true;
        }else
            doesNotExists = false;
    }

#ifdef RHODES_EMULATOR
    if ( doesNotExists )
    {
        CTokenizer oTokenizer( RHOSIMCONF().getString("ext_path"), ";" );
	    while (oTokenizer.hasMoreTokens()) 
        {
		    String tok = oTokenizer.nextToken();
		    tok = String_trim(tok);
            
            String fullPath1 = CFilePath::join( tok, path );
            if (stat(fullPath1.c_str(), &st) == 0 && S_ISREG(st.st_mode))
            {
                fullPath = fullPath1;
                doesNotExists = false;
                break;
            }

        }
    }
#endif

    if ( doesNotExists ) {
        RAWLOG_ERROR1("The file %s was not found", path.c_str());
        String error = "<!DOCTYPE html><html><font size=\"+4\"><h2>404 Not Found.</h2> The file " + path + " was not found.</font></html>";
        send_response(create_response("404 Not Found",error));
        return false;
    }

    PROF_START("LOW_FILE");
    FILE *fp = fopen(fullPath.c_str(), "rb");
    PROF_STOP("LOW_FILE");
    if (!fp) {
        RAWLOG_ERROR1("The file %s could not be opened", path.c_str());
        String error = "<!DOCTYPE html><html><font size=\"+4\"><h2>404 Not Found.</h2> The file " + path + " could not be opened.</font></html";
        send_response(create_response("404 Not Found",error));
        return false;
    }
    
    HeaderList headers;
    
    // Detect mime type
    headers.push_back(Header("Content-Type", get_mime_type(path)));
    if ( String_startsWith(path, "/public") )
    {
        headers.push_back(Header("Expires", "Thu, 15 Apr 2020 20:00:00 GMT") );
        headers.push_back(Header("Cache-Control", "max-age=2592000") );
    }

    // Content length
    char* buf = new char[FILE_BUF_SIZE];
    
    String start_line;
    
    size_t file_size = st.st_size;
    size_t range_begin = 0, range_end = file_size - 1;
    size_t content_size = file_size;
    if (parse_range(hdrs, &range_begin, &range_end))
    {
        if (range_end >= file_size)
            range_end = file_size - 1;
        if (range_begin >= range_end)
            range_begin = range_end - 1;
        content_size = range_end - range_begin + 1;
        
        if (fseek(fp, range_begin, SEEK_SET) == -1) {
            RAWLOG_ERROR1("Can not seek to specified range start: %lu", (unsigned long)range_begin);
			snprintf(buf, FILE_BUF_SIZE, "bytes */%lu", (unsigned long)file_size);
			headers.push_back(Header("Content-Range", buf));
			send_response(create_response("416 Request Range Not Satisfiable",headers));
            fclose(fp);
            delete buf;
            return false;
        }
		
		snprintf(buf, FILE_BUF_SIZE, "bytes %lu-%lu/%lu", (unsigned long)range_begin,
                 (unsigned long)range_end, (unsigned long)file_size);
        headers.push_back(Header("Content-Range", buf));
        
        start_line = "206 Partial Content";
    }
    else {
        start_line = "200 OK";
    }

    
    snprintf(buf, FILE_BUF_SIZE, "%lu", (unsigned long)content_size);
    headers.push_back(Header("Content-Length", buf));
    
    // Send headers
    if (!send_response(create_response(start_line, headers))) {
        RAWLOG_ERROR1("Can not send headers while sending file %s", path.c_str());
        fclose(fp);
        delete buf;
        return false;
    }
    
    // Send body
    for (size_t start = range_begin; start < range_end + 1;) {
        size_t need_to_read = range_end - start + 1;
        if (need_to_read == 0)
            break;
        
        if (need_to_read > FILE_BUF_SIZE)
            need_to_read = FILE_BUF_SIZE;

PROF_START("LOW_FILE");
        size_t n = fread(buf, 1, need_to_read, fp);//fread(buf, 1, need_to_read, fp);
PROF_STOP("LOW_FILE");
        if (n < need_to_read) {
			if (ferror(fp) ) {
				RAWLOG_ERROR2("Can not read part of file (at position %lu): %s", (unsigned long)start, strerror(errno));
			} else if ( feof(fp) ) {
				RAWLOG_ERROR1("End of file reached, but we expect data (%lu bytes)", (unsigned long)need_to_read);
			}
            fclose(fp);
            delete buf;
            return false;
        }
        
        start += n;
        
        if (!send_response_body(String(buf, n))) {
            RAWLOG_ERROR1("Can not send part of data while sending file %s", path.c_str());
            fclose(fp);
            delete buf;
            return false;
        }
    }

PROF_START("LOW_FILE");
    fclose(fp);
PROF_STOP("LOW_FILE");
    delete buf;
    if (verbose) RAWTRACE1("File %s was sent successfully", path.c_str());
    return false;
}
Example #24
0
//----------------------------------------------------------------------------//
void FalagardEditbox::renderTextNoBidi(const WidgetLookFeel& wlf,
                                       const String& text,
                                       const Rectf& text_area,
                                       float text_offset)
{
    const Font* font = d_window->getFont();

    // setup initial rect for text formatting
    Rectf text_part_rect(text_area);
    // allow for scroll position
    text_part_rect.d_min.d_x += text_offset;
    // centre text vertically within the defined text area
    text_part_rect.d_min.d_y += (text_area.getHeight() - font->getFontHeight()) * 0.5f;

    ColourRect colours;
    const float alpha_comp = d_window->getEffectiveAlpha();
    // get unhighlighted text colour (saves accessing property twice)
    ColourRect unselectedColours;
    setColourRectToUnselectedTextColour(unselectedColours);
    // see if the editbox is active or inactive.
    Editbox* const w = static_cast<Editbox*>(d_window);
    const bool active = editboxIsFocussed();

    if (w->getSelectionLength() != 0)
    {
        // calculate required start and end offsets of selection imagery.
        float selStartOffset =
            font->getTextAdvance(text.substr(0, w->getSelectionStartIndex()));
        float selEndOffset =
            font->getTextAdvance(text.substr(0, w->getSelectionEndIndex()));

        // calculate area for selection imagery.
        Rectf hlarea(text_area);
        hlarea.d_min.d_x += text_offset + selStartOffset;
        hlarea.d_max.d_x = hlarea.d_min.d_x + (selEndOffset - selStartOffset);

        // render the selection imagery.
        wlf.getStateImagery(active ? "ActiveSelection" :
                                     "InactiveSelection").
            render(*w, hlarea, 0, &text_area);
    }

    // draw pre-highlight text
    String sect = text.substr(0, w->getSelectionStartIndex());
    colours = unselectedColours;
    colours.modulateAlpha(alpha_comp);
    text_part_rect.d_min.d_x =
        font->drawText(w->getGeometryBuffer(), sect,
                       text_part_rect.getPosition(), &text_area, colours);

    // draw highlight text
    sect = text.substr(w->getSelectionStartIndex(), w->getSelectionLength());
    setColourRectToSelectedTextColour(colours);
    colours.modulateAlpha(alpha_comp);
    text_part_rect.d_min.d_x =
        font->drawText(w->getGeometryBuffer(), sect,
                       text_part_rect.getPosition(), &text_area, colours);

    // draw post-highlight text
    sect = text.substr(w->getSelectionEndIndex());
    colours = unselectedColours;
    colours.modulateAlpha(alpha_comp);
    font->drawText(w->getGeometryBuffer(), sect, text_part_rect.getPosition(),
                   &text_area, colours);
}
Example #25
0
Error HTTPClient::poll() {

	switch (status) {

		case STATUS_RESOLVING: {
			ERR_FAIL_COND_V(resolving == IP::RESOLVER_INVALID_ID, ERR_BUG);

			IP::ResolverStatus rstatus = IP::get_singleton()->get_resolve_item_status(resolving);
			switch (rstatus) {
				case IP::RESOLVER_STATUS_WAITING:
					return OK; // Still resolving

				case IP::RESOLVER_STATUS_DONE: {

					IP_Address host = IP::get_singleton()->get_resolve_item_address(resolving);
					Error err = tcp_connection->connect_to_host(host, conn_port);
					IP::get_singleton()->erase_resolve_item(resolving);
					resolving = IP::RESOLVER_INVALID_ID;
					if (err) {
						status = STATUS_CANT_CONNECT;
						return err;
					}

					status = STATUS_CONNECTING;
				} break;
				case IP::RESOLVER_STATUS_NONE:
				case IP::RESOLVER_STATUS_ERROR: {

					IP::get_singleton()->erase_resolve_item(resolving);
					resolving = IP::RESOLVER_INVALID_ID;
					close();
					status = STATUS_CANT_RESOLVE;
					return ERR_CANT_RESOLVE;
				} break;
			}
		} break;
		case STATUS_CONNECTING: {

			StreamPeerTCP::Status s = tcp_connection->get_status();
			switch (s) {

				case StreamPeerTCP::STATUS_CONNECTING: {
					return OK;
				} break;
				case StreamPeerTCP::STATUS_CONNECTED: {
					if (ssl) {
						Ref<StreamPeerSSL> ssl;
						if (!handshaking) {
							// Connect the StreamPeerSSL and start handshaking
							ssl = Ref<StreamPeerSSL>(StreamPeerSSL::create());
							ssl->set_blocking_handshake_enabled(false);
							Error err = ssl->connect_to_stream(tcp_connection, ssl_verify_host, conn_host);
							if (err != OK) {
								close();
								status = STATUS_SSL_HANDSHAKE_ERROR;
								return ERR_CANT_CONNECT;
							}
							connection = ssl;
							handshaking = true;
						} else {
							// We are already handshaking, which means we can use your already active SSL connection
							ssl = static_cast<Ref<StreamPeerSSL> >(connection);
							ssl->poll(); // Try to finish the handshake
						}

						if (ssl->get_status() == StreamPeerSSL::STATUS_CONNECTED) {
							// Handshake has been successful
							handshaking = false;
							status = STATUS_CONNECTED;
							return OK;
						} else if (ssl->get_status() != StreamPeerSSL::STATUS_HANDSHAKING) {
							// Handshake has failed
							close();
							status = STATUS_SSL_HANDSHAKE_ERROR;
							return ERR_CANT_CONNECT;
						}
						// ... we will need to poll more for handshake to finish
					} else {
						status = STATUS_CONNECTED;
					}
					return OK;
				} break;
				case StreamPeerTCP::STATUS_ERROR:
				case StreamPeerTCP::STATUS_NONE: {

					close();
					status = STATUS_CANT_CONNECT;
					return ERR_CANT_CONNECT;
				} break;
			}
		} break;
		case STATUS_CONNECTED: {
			// Connection established, requests can now be made
			return OK;
		} break;
		case STATUS_REQUESTING: {

			while (true) {
				uint8_t byte;
				int rec = 0;
				Error err = _get_http_data(&byte, 1, rec);
				if (err != OK) {
					close();
					status = STATUS_CONNECTION_ERROR;
					return ERR_CONNECTION_ERROR;
				}

				if (rec == 0)
					return OK; // Still requesting, keep trying!

				response_str.push_back(byte);
				int rs = response_str.size();
				if (
						(rs >= 2 && response_str[rs - 2] == '\n' && response_str[rs - 1] == '\n') ||
						(rs >= 4 && response_str[rs - 4] == '\r' && response_str[rs - 3] == '\n' && response_str[rs - 2] == '\r' && response_str[rs - 1] == '\n')) {

					// End of response, parse.
					response_str.push_back(0);
					String response;
					response.parse_utf8((const char *)response_str.ptr());
					Vector<String> responses = response.split("\n");
					body_size = -1;
					chunked = false;
					body_left = 0;
					chunk_left = 0;
					read_until_eof = false;
					response_str.clear();
					response_headers.clear();
					response_num = RESPONSE_OK;

					// Per the HTTP 1.1 spec, keep-alive is the default, but in practice
					// it's safe to assume it only if the explicit header is found, allowing
					// to handle body-up-to-EOF responses on naive servers; that's what Curl
					// and browsers do
					bool keep_alive = false;

					for (int i = 0; i < responses.size(); i++) {

						String header = responses[i].strip_edges();
						String s = header.to_lower();
						if (s.length() == 0)
							continue;
						if (s.begins_with("content-length:")) {
							body_size = s.substr(s.find(":") + 1, s.length()).strip_edges().to_int();
							body_left = body_size;

						} else if (s.begins_with("transfer-encoding:")) {
							String encoding = header.substr(header.find(":") + 1, header.length()).strip_edges();
							if (encoding == "chunked") {
								chunked = true;
							}
						} else if (s.begins_with("connection: keep-alive")) {
							keep_alive = true;
						}

						if (i == 0 && responses[i].begins_with("HTTP")) {

							String num = responses[i].get_slicec(' ', 1);
							response_num = num.to_int();
						} else {

							response_headers.push_back(header);
						}
					}

					if (body_size != -1 || chunked) {

						status = STATUS_BODY;
					} else if (!keep_alive) {

						read_until_eof = true;
						status = STATUS_BODY;
					} else {

						status = STATUS_CONNECTED;
					}
					return OK;
				}
			}
			// Wait for response
			return OK;
		} break;
		case STATUS_DISCONNECTED: {
			return ERR_UNCONFIGURED;
		} break;
		case STATUS_CONNECTION_ERROR: {
			return ERR_CONNECTION_ERROR;
		} break;
		case STATUS_CANT_CONNECT: {
			return ERR_CANT_CONNECT;
		} break;
		case STATUS_CANT_RESOLVE: {
			return ERR_CANT_RESOLVE;
		} break;
	}

	return OK;
}
Example #26
0
//----------------------------------------------------------------------------//
void FalagardEditbox::renderTextBidi(const WidgetLookFeel& wlf,
                                     const String& text,
                                     const Rectf& text_area,
                                     float text_offset)
{
#ifdef CEGUI_BIDI_SUPPORT
    const Font* const font = d_window->getFont();

    // setup initial rect for text formatting
    Rectf text_part_rect(text_area);
    // allow for scroll position
    text_part_rect.d_min.d_x += text_offset;
    // centre text vertically within the defined text area
    text_part_rect.d_min.d_y += (text_area.getHeight() - font->getFontHeight()) * 0.5f;

    ColourRect colours;
    const float alpha_comp = d_window->getEffectiveAlpha();
    // get unhighlighted text colour (saves accessing property twice)
    ColourRect unselectedColour;
    setColourRectToUnselectedTextColour(unselectedColour);
    // see if the editbox is active or inactive.
    Editbox* const w = static_cast<Editbox*>(d_window);
    const bool active = editboxIsFocussed();

    if (w->getSelectionLength() == 0)
    {
        // no highlighted text - we can draw the whole thing
        colours = unselectedColour;
        colours.modulateAlpha(alpha_comp);
        text_part_rect.d_min.d_x =
            font->drawText(w->getGeometryBuffer(), text,
                           text_part_rect.getPosition(), &text_area, colours);
    }
    else
    {
        // there is highlighted text - because of the Bidi support - the
        // highlighted area can be in some cases nonconsecutive.
        // So - we need to draw it char by char (I guess we can optimize it more
        // but this is not that big performance hit because it only happens if
        // we have highlighted text - not that common...)
        for (size_t i = 0 ; i < text.size() ; i++)
        {
            // get the char
            String currChar = text.substr(i, 1);
            size_t realPos = 0;

            // get he visual pos of the char
            if (w->getBidiVisualMapping()->getV2lMapping().size() > i)
            {
                realPos = w->getBidiVisualMapping()->getV2lMapping()[i];
            }

            // check if it is in the highlighted region
            bool highlighted =
                realPos >= w->getSelectionStartIndex() &&
                realPos < w->getSelectionStartIndex() + w->getSelectionLength();

            float charAdvance = font->getGlyphData(currChar[0])->getAdvance(1.0f);

            if (highlighted)
            {
                setColourRectToSelectedTextColour(colours);
                colours.modulateAlpha(alpha_comp);

                {

                    // calculate area for selection imagery.
                    Rectf hlarea(text_area);
                    hlarea.d_min.d_x = text_part_rect.d_min.d_x ;
                    hlarea.d_max.d_x = text_part_rect.d_min.d_x + charAdvance ;

                    // render the selection imagery.
                    wlf.getStateImagery(active ? "ActiveSelection" :
                                                 "InactiveSelection").
                        render(*w, hlarea, 0, &text_area);
                }

            }
            else
            {
                colours = unselectedColour;
                colours.modulateAlpha(alpha_comp);
            }
            font->drawText(w->getGeometryBuffer(), currChar,
                           text_part_rect.getPosition(), &text_area, colours);

            // adjust rect for next section
            text_part_rect.d_min.d_x += charAdvance;

        }
    }
#else
    CEGUI_UNUSED(wlf);
    CEGUI_UNUSED(text);
    CEGUI_UNUSED(text_area);
    CEGUI_UNUSED(text_offset);
#endif
}
Example #27
0
	// mosync://PhoneGap?service=File&action=readEntries&args={"fullPath":"/mnt/sdcard/fob1"}&
	// PhoneGapCallBackId=File21
	void PhoneGapFile::actionReadEntries(JSONMessage& message)
	{
		String callbackID = message.getParam("PhoneGapCallBackId");

		String path = message.getArgsField("fullPath");

		// Open entry array.
		String entries = "[";

		char nameBuf[2048];

		// Make sure path end with a slash.
		FileMakeDirectoryPath(path);

		// Open directory listing.
		MAHandle list = maFileListStart(
			path.c_str(),
			"",
			MA_FL_SORT_NAME | MA_FL_ORDER_ASCENDING);
		if (list < 0)
		{
			callFileError(callbackID, FILEERROR_NOT_FOUND_ERR);
			return;
		}

		// List all files in this directory.
		while (true)
		{
			// Move to next file.
			int result = maFileListNext(list, nameBuf, 2048);
			if (0 == result)
			{
				// No more files.
				break;
			}
			if (0 > result)
			{
				maFileListClose(list);
				callFileError(callbackID, FILEERROR_NOT_FOUND_ERR);
				return;
			}

			// Add separating comma if needed.
			if (entries.size() > 1)
			{
				entries += ",";
			}

			// Full path to entry.
			String fullPath = path + nameBuf;

			// Is this a directory?
			if ('/' == nameBuf[result - 1])
			{
				// We remove the trailing slash of the directory.
				String pathWithNoSlash = fullPath.substr(0, fullPath.size() - 1);
				String entry = emitDirectoryEntry(
					FileGetName(pathWithNoSlash),
					pathWithNoSlash);
				entries += entry;
			}
			else
			{
				String entry = emitFileEntry(
					FileGetName(fullPath),
					fullPath);
				entries += entry;
			}
		}

		// Close the directory listing.
		maFileListClose(list);

		// Close entry array.
		entries += "]";

		// Return result to PhoneGap.
		callSuccess(
			callbackID,
			entries,
			"window.localFileSystem._castEntries");
	}
Example #28
0
void ResultScreen::SaveResults()
{
    Core *core=DAVA::Core::Instance();
    Vector2 screenSize(core->GetVirtualScreenWidth(), core->GetVirtualScreenHeight());

    Image* image = resultSprite->GetTexture()->CreateImageFromMemory(RenderState::RENDERSTATE_2D_BLEND);
    FilePath saveFileName = FileSystem::Instance()->GetUserDocumentsPath();
    saveFileName += filename.GetFilename() + ".png";
    ImageLoader::Save(image, saveFileName);

    Map<String, String> results;
    Map<String, Texture *> textures;
    results["TextureMemorySize"] = Format("%.2f Mb", testData.GetTextureMemorySize()/(1024.f * 1024.f));
    results["TextureFilesSize"] = Format("%.2f Mb", testData.GetTexturesFilesSize()/(1024.f * 1024.f));


    float32 avFps = 0.f;
    int32 count = testData.GetItemCount();
    results["FPS items count"] = Format("%d", count);
    for(int32 i = 0; i < count; ++i)
    {
        const FpsStatItem& item = testData.GetItem(i);

        float32 avPerItem = 0.f;

        for(int32 fps = 0; fps < SECTORS_COUNT; ++fps)
        {
            avPerItem += item.avFps[fps];
        }

        avPerItem /= (float32)SECTORS_COUNT;

        results[Format("FPS average fps per %d item", i)] = Format("%f fps", avPerItem);

        avFps += avPerItem;
    }

    if(count)
    {
        results["FPS average value"] = Format("%f fps", avFps / (float32)count);
    }
    else
    {
        results["FPS average value"] = "0 fps";
    }



    String filePath = testData.GetSceneFilePath().GetAbsolutePathname();
    results["SceneFilePath"] = filePath.substr(filePath.find("Maps"));

    FilePath folderPathname("~doc:/PerformanceTestResult/");
    FileSystem::Instance()->CreateDirectory(folderPathname);
    FilePath statFileName = folderPathname + FilePath::CreateWithNewExtension(filename, ".txt").GetFilename();
    File* file = File::Create(statFileName, File::CREATE | File::WRITE);
    if (file)
    {
        Map<String, String>::const_iterator it = results.begin();
        for(; it != results.end(); it++)
        {
            // "Format" sometimes doesn't work correct with strings on some platforms
            file->WriteLine(((*it).first + ": " + (*it).second).c_str());
        }

        SafeRelease(file);
    }

    FilePath levelName = FilePath::CreateWithNewExtension(filename, "").GetFilename();

    if(!GameCore::Instance()->FlushToDB(levelName, results, saveFileName))
        Logger::Debug("Error sending data to DB (connection is lost) !!!");

    state = RESULT_STATE_FINISHED;
}
	bool WaveformObjImporter::convertToPropellerModel(String filename, ModelStream &stream)
	{
		struct Float3
		{
			float v[3];
		};

		struct FaceData
		{
			FaceData() {}
			FaceData(unsigned vertexIndex, unsigned texCoordIndex, unsigned normalIndex)
				: vertexIndex(vertexIndex)
				, texCoordIndex(texCoordIndex)
				, normalIndex(normalIndex)
			{ }

			unsigned vertexIndex;
			unsigned texCoordIndex;
			unsigned normalIndex;
		};

		struct Face
		{
			FaceData v[3];
		};

		LOG_INFO("importing file from .obj!");

		std::ifstream file(filename); //HACK: Editor is windows only, not using wrappers

		if (!file.is_open())
			return false;

		std::vector<Float3> objVertices;
		std::vector<Float3> objTexCoords;
		std::vector<Float3> objNormals;
		std::vector<Face> objFaces;

		String line;
		while (std::getline(file, line))
		{
			if (line.substr(0, 1) == "#")
				continue; // comment

			if (line.substr(0, 2) == "v ")
			{
				std::vector<String> parts;
				engine::util::explode(&parts, line, ' ');

				Float3 f3;


				f3.v[0] = boost::lexical_cast<float>(parts[1]);
				f3.v[1] = boost::lexical_cast<float>(parts[2]);
				f3.v[2] = boost::lexical_cast<float>(parts[3]);

				objVertices.push_back(f3);
				continue;
			}

			if (line.substr(0, 3) == "vn ")
			{
				std::vector<String> parts;
				engine::util::explode(&parts, line, ' ');

				Float3 f3;

				f3.v[0] = boost::lexical_cast<float>(parts[1]);
				f3.v[1] = boost::lexical_cast<float>(parts[2]);
				f3.v[2] = boost::lexical_cast<float>(parts[3]);

				objNormals.push_back(f3);
				continue;
			}

			if (line.substr(0, 3) == "vt ")
			{
				std::vector<String> parts;
				engine::util::explode(&parts, line, ' ');

				Float3 f3;

				f3.v[0] = boost::lexical_cast<float>(parts[1]);
				f3.v[1] = boost::lexical_cast<float>(parts[2]);
				f3.v[2] = boost::lexical_cast<float>(parts[3]);

				objTexCoords.push_back(f3);
				continue;
			}

			if (line.substr(0, 2) == "f ")
			{
				std::vector<String> parts;
				engine::util::explode(&parts, line, ' ');

				String faceStrings[3];

				faceStrings[0] = parts[1];
				faceStrings[1] = parts[2];
				faceStrings[2] = parts[3];

				Face face;

				for (unsigned i = 0; i < 3; ++i)
				{
					std::vector <String> parts;
					engine::util::explode(&parts, faceStrings[i], '/');

					face.v[i] = FaceData(boost::lexical_cast<unsigned>(parts[0]), boost::lexical_cast<unsigned>(parts[1]), boost::lexical_cast<unsigned>(parts[2]));
				}

				objFaces.push_back(face);

				continue;
			}

			DEBUG_PRINT("Line ignored: " << line);
		}

		LOG_INFO("Reading data from .obj file done.");

		// .PropellerModel header
		stream.write(PROPELLER_MODEL_IDENTIFIER, PROPELLER_MODEL_IDENTIFIER_SIZE);
		stream.write(unsigned(2)); //This is version 1 writer

		// face is one vertex, vertex has 3 floats, 3 normal and 3 texCoords floats(4bit).
		//   3 * 9 -> 27
		stream.write(unsigned(objFaces.size() * 27)); 
		

		for (unsigned i = 0; i < objFaces.size(); ++i)
		{
			// vertex 3 + normal + 3  (float)
			//DEBUG_PRINT("write > face: " << i << "vertexIndex:" << objFaces[i].v[0].vertexIndex);
			stream.write(objVertices[objFaces[i].v[0].vertexIndex - 1].v[0]);
			stream.write(objVertices[objFaces[i].v[0].vertexIndex - 1].v[1]);
			stream.write(objVertices[objFaces[i].v[0].vertexIndex - 1].v[2]);

			//DEBUG_PRINT("write > texCoord: " << i << "texCoordIndex:" << objFaces[i].v[0].texCoordIndex);
			stream.write(objTexCoords[objFaces[i].v[0].texCoordIndex - 1].v[0]);
			stream.write(objTexCoords[objFaces[i].v[0].texCoordIndex - 1].v[1]);
			stream.write(objTexCoords[objFaces[i].v[0].texCoordIndex - 1].v[2]);

			//DEBUG_PRINT("write > normal: " << i << "normalIndex:" << objFaces[i].v[0].normalIndex);
			stream.write(objNormals[objFaces[i].v[0].normalIndex - 1].v[0]);
			stream.write(objNormals[objFaces[i].v[0].normalIndex - 1].v[1]);
			stream.write(objNormals[objFaces[i].v[0].normalIndex - 1].v[2]);

			//#

			//DEBUG_PRINT("write > face: " << i << "vertexIndex:" << objFaces[i].v[1].vertexIndex);
			stream.write(objVertices[objFaces[i].v[1].vertexIndex - 1].v[0]);
			stream.write(objVertices[objFaces[i].v[1].vertexIndex - 1].v[1]);
			stream.write(objVertices[objFaces[i].v[1].vertexIndex - 1].v[2]);


			//DEBUG_PRINT("write > texCoord: " << i << "texCoordIndex:" << objFaces[i].v[1].texCoordIndex);
			stream.write(objTexCoords[objFaces[i].v[1].texCoordIndex - 1].v[0]);
			stream.write(objTexCoords[objFaces[i].v[1].texCoordIndex - 1].v[1]);
			stream.write(objTexCoords[objFaces[i].v[1].texCoordIndex - 1].v[2]);

			//DEBUG_PRINT("write > normal: " << i << "normalIndex:" << objFaces[i].v[1].normalIndex);
			stream.write(objNormals[objFaces[i].v[1].normalIndex - 1].v[0]);
			stream.write(objNormals[objFaces[i].v[1].normalIndex - 1].v[1]);
			stream.write(objNormals[objFaces[i].v[1].normalIndex - 1].v[2]);

			//#

			//DEBUG_PRINT("write > face: " << i << "vertexIndex:" << objFaces[i].v[2].vertexIndex);
			stream.write(objVertices[objFaces[i].v[2].vertexIndex - 1].v[0]);
			stream.write(objVertices[objFaces[i].v[2].vertexIndex - 1].v[1]);
			stream.write(objVertices[objFaces[i].v[2].vertexIndex - 1].v[2]);


			//DEBUG_PRINT("write > texCoord: " << i << "texCoordIndex:" << objFaces[i].v[2].texCoordIndex);
			stream.write(objTexCoords[objFaces[i].v[2].texCoordIndex - 1].v[0]);
			stream.write(objTexCoords[objFaces[i].v[2].texCoordIndex - 1].v[1]);
			stream.write(objTexCoords[objFaces[i].v[2].texCoordIndex - 1].v[2]);

			//DEBUG_PRINT("write > normal: " << i << "normalIndex:" << objFaces[i].v[2].normalIndex);
			stream.write(objNormals[objFaces[i].v[2].normalIndex - 1].v[0]);
			stream.write(objNormals[objFaces[i].v[2].normalIndex - 1].v[1]);
			stream.write(objNormals[objFaces[i].v[2].normalIndex - 1].v[2]);
		}

		// INDICES ARE JUST LIST FROM 0 TO FACECOUNT
		// CONSIDER DROPPING/OPTIMIZING THESE
		stream.write(unsigned(objFaces.size() * 3));

		for (unsigned i = 0; i < (objFaces.size() * 3); ++i)
			stream.write(uint16_t(i));

		return true; 
	}
	RenderWindow* Win32GLSupport::createWindow(bool autoCreateWindow, GLRenderSystem* renderSystem, const String& windowTitle)
	{
		if (autoCreateWindow)
        {
            ConfigOptionMap::iterator opt = mOptions.find("Full Screen");
            if (opt == mOptions.end())
                OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find full screen options!", "Win32GLSupport::createWindow");
            bool fullscreen = (opt->second.currentValue == "Yes");

            opt = mOptions.find("Video Mode");
            if (opt == mOptions.end())
                OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find video mode options!", "Win32GLSupport::createWindow");
            String val = opt->second.currentValue;
            String::size_type pos = val.find('x');
            if (pos == String::npos)
                OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Invalid Video Mode provided", "Win32GLSupport::createWindow");

			unsigned int w = StringConverter::parseUnsignedInt(val.substr(0, pos));
            unsigned int h = StringConverter::parseUnsignedInt(val.substr(pos + 1));

			// Parse optional parameters
			NameValuePairList winOptions;
			opt = mOptions.find("Colour Depth");
			if (opt == mOptions.end())
				OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find Colour Depth options!", "Win32GLSupport::createWindow");
			unsigned int colourDepth =
				StringConverter::parseUnsignedInt(opt->second.currentValue);
			winOptions["colourDepth"] = StringConverter::toString(colourDepth);

			opt = mOptions.find("VSync");
			if (opt == mOptions.end())
				OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find VSync options!", "Win32GLSupport::createWindow");
			bool vsync = (opt->second.currentValue == "Yes");
			winOptions["vsync"] = StringConverter::toString(vsync);
			renderSystem->setWaitForVerticalBlank(vsync);

			opt = mOptions.find("VSync Interval");
			if (opt == mOptions.end())
				OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find VSync Interval options!", "Win32GLSupport::createWindow");
			winOptions["vsyncInterval"] = opt->second.currentValue;


			opt = mOptions.find("Display Frequency");
			if (opt != mOptions.end())
			{
				unsigned int displayFrequency =
					StringConverter::parseUnsignedInt(opt->second.currentValue);
				winOptions["displayFrequency"] = StringConverter::toString(displayFrequency);
			}

			opt = mOptions.find("FSAA");
			if (opt == mOptions.end())
				OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find FSAA options!", "Win32GLSupport::createWindow");
			StringVector aavalues = StringUtil::split(opt->second.currentValue, " ", 1);
			unsigned int multisample = StringConverter::parseUnsignedInt(aavalues[0]);
			String multisample_hint;
			if (aavalues.size() > 1)
				multisample_hint = aavalues[1];

#ifdef RTSHADER_SYSTEM_BUILD_CORE_SHADERS
			opt = mOptions.find("Fixed Pipeline Enabled");
			if (opt == mOptions.end())
				OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find Fixed Pipeline enabled options!", "Win32GLSupport::createWindow");
			bool enableFixedPipeline = (opt->second.currentValue == "Yes");
			renderSystem->setFixedPipelineEnabled(enableFixedPipeline);
#endif

			winOptions["FSAA"] = StringConverter::toString(multisample);
			winOptions["FSAAHint"] = multisample_hint;

			opt = mOptions.find("sRGB Gamma Conversion");
			if (opt == mOptions.end())
				OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find sRGB options!", "Win32GLSupport::createWindow");
			bool hwGamma = (opt->second.currentValue == "Yes");
			winOptions["gamma"] = StringConverter::toString(hwGamma);

            return renderSystem->_createRenderWindow(windowTitle, w, h, fullscreen, &winOptions);
        }
        else
        {
            // XXX What is the else?
			return NULL;
        }
	}