<commit_before>#include "biont.hpp"
#include "shader.hpp"
#include "holobiont.hpp"
#include "symbiosis.hpp"
#include "symbiont_species.hpp"
#include "biont_struct.hpp"
#include "render_templates.hpp"
#include "code/ylikuutio/hierarchy/hierarchy_templates.hpp"

// Include GLM
#ifndef __GLM_GLM_HPP_INCLUDED
#define __GLM_GLM_HPP_INCLUDED
#include <glm/glm.hpp> // glm
#endif

// Include standard headers
#include <cstddef>  // std::size_t
#include <iostream> // std::cout, std::cin, std::cerr
#include <string>   // std::string

namespace yli
{
    namespace ontology
    {
        class Entity;

        void Biont::bind_to_parent()
        {
            // requirements:
            // `this->holobiont_parent` must not be `nullptr`.

            yli::ontology::Holobiont* const holobiont = this->holobiont_parent;

            if (holobiont == nullptr)
            {
                std::cerr << "ERROR: `Biont::bind_to_parent`: `holobiont` is `nullptr`!\n";
                return;
            }

            // get `childID` from `Holobiont` and set pointer to this `Biont`.
            holobiont->bind_biont(this);
        }

        void Biont::bind_to_symbiont_species()
        {
            // requirements:
            // `this->holobiont_parent` must not be `nullptr`.
            // `this->holobiont_parent->get_parent()` must not be `nullptr`.
            // `this->symbiont_species` must not be `nullptr`.

            const yli::ontology::Holobiont* const holobiont = this->holobiont_parent;

            if (holobiont == nullptr)
            {
                std::cerr << "ERROR: `Biont::bind_to_symbiont_species`: `holobiont` is `nullptr`!\n";
                return;
            }

            const yli::ontology::Symbiosis* const symbiosis = static_cast<yli::ontology::Symbiosis*>(holobiont->get_parent());

            if (symbiosis == nullptr)
            {
                std::cerr << "ERROR: `Biont::bind_to_symbiont_species`: `symbiosis` is `nullptr`!\n";
                return;
            }

            yli::ontology::SymbiontSpecies* const symbiont_species = this->symbiont_species;

            if (symbiont_species == nullptr)
            {
                std::cerr << "ERROR: `Biont::bind_to_symbiont_species`: `symbiont_species` is `nullptr`!\n";
                return;
            }

            symbiont_species->bind_biont(this);
        }

        void Biont::bind_to_new_parent(yli::ontology::Holobiont* const new_holobiont_parent)
        {
            // this method sets pointer to this `Biont` to `nullptr`, sets `parent` according to the input,
            // and requests a new `childID` from the new `Holobiont`.
            //
            // requirements:
            // `this->holobiont_parent` must not be `nullptr`.
            // `new_holobiont_parent` must not be `nullptr`.

            // unbind from the old parent `Holobiont`.
            if (this->holobiont_parent == nullptr)
            {
                std::cerr << "ERROR: `Biont::bind_to_new_parent`: `this->holobiont_parent` is `nullptr`!\n";
                return;
            }

            if (new_holobiont_parent == nullptr)
            {
                std::cerr << "ERROR: `Biont::bind_to_new_parent`: `new_holobiont_parent` is `nullptr`!\n";
                return;
            }

            this->holobiont_parent->unbind_biont(this->childID);

            // get `childID` from `Holobiont` and set pointer to this `Biont`.
            this->holobiont_parent = new_holobiont_parent;
            this->holobiont_parent->bind_biont(this);
        }

        Biont::~Biont()
        {
            // destructor.
            //
            // requirements:
            // `this->holobiont_parent` must not be `nullptr`.
            // `this->symbiont_species` must not be `nullptr`.

            std::cout << "Biont with childID " << std::dec << this->childID << " will be destroyed.\n";

            yli::ontology::Holobiont* const holobiont = this->holobiont_parent;

            if (holobiont == nullptr)
            {
                std::cerr << "ERROR: `Biont::~Biont`: `holobiont` is `nullptr`!\n";
                return;
            }

            yli::ontology::SymbiontSpecies* const symbiont_species = this->symbiont_species;

            if (symbiont_species == nullptr)
            {
                std::cerr << "ERROR: `Biont::~Biont`: `symbiont_species` is `nullptr`!\n";
                return;
            }

            // set pointer to this `Biont` to `nullptr`.
            symbiont_species->unbind_biont(this->childID);
            holobiont->unbind_biont(this->childID);
        }

        void Biont::render()
        {
            // render this `Biont`.
            //
            // requirements:
            // `this->holobiont_parent` must not be `nullptr`.
            // `this->holobiont_parent->get_parent()` must not be `nullptr`.

            const yli::ontology::Holobiont* const holobiont = this->holobiont_parent;

            if (holobiont == nullptr)
            {
                std::cerr << "ERROR: `Biont::render`: `holobiont` is `nullptr`!\n";
                return;
            }

            const yli::ontology::Symbiosis* const symbiosis = static_cast<yli::ontology::Symbiosis*>(holobiont->get_parent());

            if (symbiosis == nullptr)
            {
                std::cerr << "ERROR: `Biont::render`: `symbiosis` is `nullptr`!\n";
                return;
            }

            if (this->should_ylikuutio_render_this_biont)
            {
                this->prerender();
                this->render_this_biont(static_cast<yli::ontology::Shader*>(symbiosis->get_parent()));
                this->postrender();
            }
        }

        void Biont::render_this_biont(const yli::ontology::Shader* const shader)
        {
            // requirements:
            // `this->universe` must not be `nullptr`.
            // `shader` must not be `nullptr`.
            // `this->holobiont_parent` must not be `nullptr`.
            // `this->symbiont_species` must not be `nullptr`.

            yli::ontology::Universe* const universe = this->universe;

            if (universe == nullptr)
            {
                std::cerr << "ERROR: `Biont::render_this_biont`: `universe` is `nullptr`!\n";
                return;
            }

            if (shader == nullptr)
            {
                std::cerr << "ERROR: `Biont::render_this_biont`: `shader` is `nullptr`!\n";
                return;
            }

            const yli::ontology::Holobiont* const holobiont = this->holobiont_parent;

            if (holobiont == nullptr)
            {
                std::cerr << "ERROR: `Biont::render_this_biont`: `holobiont` is `nullptr`!\n";
                return;
            }

            yli::ontology::Symbiosis* const symbiosis = static_cast<yli::ontology::Symbiosis*>(holobiont->get_parent());

            if (symbiosis == nullptr)
            {
                std::cerr << "ERROR: `Biont::render_this_biont`: `symbiosis` is `nullptr`!\n";
                return;
            }

            const yli::ontology::SymbiontSpecies* const symbiont_species = this->symbiont_species;

            if (symbiont_species == nullptr)
            {
                std::cerr << "ERROR: `Biont::render_this_biont`: `symbiont_species` is `nullptr`!\n";
                return;
            }

            if (!this->has_entered)
            {
                this->model_matrix = glm::translate(glm::mat4(1.0f), this->cartesian_coordinates);

                const std::string model_file_format = symbiosis->get_model_file_format();

                if (model_file_format == "fbx" || model_file_format == "FBX")
                {
                    // Only FBX bionts need initial rotation.
                    this->model_matrix = glm::rotate(this->model_matrix, this->initial_rotate_angle, this->initial_rotate_vector);
                }

                this->model_matrix = glm::scale(this->model_matrix, this->original_scale_vector);

                // store the new coordinates to be used in the next update.
                this->cartesian_coordinates = glm::vec3(this->model_matrix[3][0], this->model_matrix[3][1], this->model_matrix[3][2]);
                this->has_entered = true;
            }
            else
            {
                // rotate.
                if (this->rotate_vector != glm::vec3(0.0f, 0.0f, 0.0f))
                {
                    if (this->quaternions_in_use)
                    {
                        // create `rotation_matrix` using quaternions.
                        glm::quat my_quaternion = glm::quat(DEGREES_TO_RADIANS(this->rotate_vector));
                        glm::mat4 rotation_matrix = glm::mat4_cast(my_quaternion);
                        this->model_matrix = rotation_matrix * this->model_matrix;
                    }
                    else
                    {
                        this->model_matrix = glm::rotate(this->model_matrix, this->rotate_angle, this->rotate_vector);
                    }
                }

                this->model_matrix = glm::translate(this->model_matrix, this->translate_vector);
                this->cartesian_coordinates = glm::vec3(this->model_matrix[3][0], this->model_matrix[3][1], this->model_matrix[3][2]);
            }

            this->MVP_matrix = universe->get_projection_matrix() * universe->get_view_matrix() * this->model_matrix;

            // Bind our texture in Texture Unit 0.
            glActiveTexture(GL_TEXTURE0);
            glBindTexture(GL_TEXTURE_2D, symbiosis->get_texture(this->biontID));
            // Set our "myTextureSampler" sampler to user Texture Unit 0.
            glUniform1i(symbiosis->get_openGL_textureID(this->biontID), 0);

            // '`Material`' part ends here.

            // '`Species`' part begins here.

            // Compute the MVP matrix from keyboard and mouse input.
            const glm::vec3& light_position = symbiosis->get_light_position(this->biontID);
            glUniform3f(
                    symbiosis->get_lightID(this->biontID),
                    light_position.x,
                    light_position.y,
                    light_position.z);

            // 1st attribute buffer : vertices.
            glEnableVertexAttribArray(symbiont_species->get_vertex_position_modelspaceID());

            // 2nd attribute buffer : UVs.
            glEnableVertexAttribArray(symbiont_species->get_vertexUVID());

            // 3rd attribute buffer : normals.
            glEnableVertexAttribArray(symbiont_species->get_vertex_normal_modelspaceID());

            // '`Species`' part ends here.

            // Send our transformation to the currently bound shader,
            // in the "MVP" uniform.
            glUniformMatrix4fv(shader->get_matrixID(), 1, GL_FALSE, &this->MVP_matrix[0][0]);
            glUniformMatrix4fv(shader->get_model_matrixID(), 1, GL_FALSE, &this->model_matrix[0][0]);

            GLuint vertexbuffer = symbiont_species->get_vertexbuffer();
            GLuint vertex_position_modelspaceID = symbiont_species->get_vertex_position_modelspaceID();
            GLuint uvbuffer = symbiont_species->get_uvbuffer();
            GLuint vertexUVID = symbiont_species->get_vertexUVID();
            GLuint normalbuffer = symbiont_species->get_normalbuffer();
            GLuint vertex_normal_modelspaceID = symbiont_species->get_vertex_normal_modelspaceID();
            GLuint elementbuffer = symbiont_species->get_elementbuffer();
            GLuint indices_size = symbiont_species->get_indices_size();

            // 1st attribute buffer : vertices.
            glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
            glVertexAttribPointer(
                    vertex_position_modelspaceID, // The attribute we want to configure
                    3,                           // size
                    GL_FLOAT,                    // type
                    GL_FALSE,                    // normalized?
                    0,                           // stride
                    (void*) 0                    // array buffer offset
                    );

            // 2nd attribute buffer : UVs.
            glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
            glVertexAttribPointer(
                    vertexUVID, // The attribute we want to configure
                    2,          // size : U+V => 2
                    GL_FLOAT,   // type
                    GL_FALSE,   // normalized?
                    0,          // stride
                    (void*) 0   // array buffer offset
                    );

            // 3rd attribute buffer : normals.
            glBindBuffer(GL_ARRAY_BUFFER, normalbuffer);
            glVertexAttribPointer(
                    vertex_normal_modelspaceID, // The attribute we want to configure
                    3,                         // size
                    GL_FLOAT,                  // type
                    GL_FALSE,                  // normalized?
                    0,                         // stride
                    (void*) 0                  // array buffer offset
                    );

            // Index buffer.
            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementbuffer);

            // Draw the triangles!
            glDrawElements(
                    GL_TRIANGLES,    // mode
                    indices_size,    // count
                    GL_UNSIGNED_INT, // type
                    (void*) 0        // element array buffer offset
                    );
        }

        yli::ontology::Entity* Biont::get_parent() const
        {
            return this->holobiont_parent;
        }

        std::size_t Biont::get_number_of_children() const
        {
            return 0; // `Biont` has no children.
        }

        std::size_t Biont::get_number_of_descendants() const
        {
            return 0; // `Biont` has no children.
        }
    }
}
<commit_msg>Bugfix: added missing `#include` line.<commit_after>#include "biont.hpp"
#include "shader.hpp"
#include "holobiont.hpp"
#include "symbiosis.hpp"
#include "symbiont_species.hpp"
#include "biont_struct.hpp"
#include "render_templates.hpp"
#include "code/ylikuutio/hierarchy/hierarchy_templates.hpp"

// Include GLEW
#include "code/ylikuutio/opengl/ylikuutio_glew.hpp" // GLfloat, GLuint etc.

// Include GLM
#ifndef __GLM_GLM_HPP_INCLUDED
#define __GLM_GLM_HPP_INCLUDED
#include <glm/glm.hpp> // glm
#endif

// Include standard headers
#include <cstddef>  // std::size_t
#include <iostream> // std::cout, std::cin, std::cerr
#include <string>   // std::string

namespace yli
{
    namespace ontology
    {
        class Entity;

        void Biont::bind_to_parent()
        {
            // requirements:
            // `this->holobiont_parent` must not be `nullptr`.

            yli::ontology::Holobiont* const holobiont = this->holobiont_parent;

            if (holobiont == nullptr)
            {
                std::cerr << "ERROR: `Biont::bind_to_parent`: `holobiont` is `nullptr`!\n";
                return;
            }

            // get `childID` from `Holobiont` and set pointer to this `Biont`.
            holobiont->bind_biont(this);
        }

        void Biont::bind_to_symbiont_species()
        {
            // requirements:
            // `this->holobiont_parent` must not be `nullptr`.
            // `this->holobiont_parent->get_parent()` must not be `nullptr`.
            // `this->symbiont_species` must not be `nullptr`.

            const yli::ontology::Holobiont* const holobiont = this->holobiont_parent;

            if (holobiont == nullptr)
            {
                std::cerr << "ERROR: `Biont::bind_to_symbiont_species`: `holobiont` is `nullptr`!\n";
                return;
            }

            const yli::ontology::Symbiosis* const symbiosis = static_cast<yli::ontology::Symbiosis*>(holobiont->get_parent());

            if (symbiosis == nullptr)
            {
                std::cerr << "ERROR: `Biont::bind_to_symbiont_species`: `symbiosis` is `nullptr`!\n";
                return;
            }

            yli::ontology::SymbiontSpecies* const symbiont_species = this->symbiont_species;

            if (symbiont_species == nullptr)
            {
                std::cerr << "ERROR: `Biont::bind_to_symbiont_species`: `symbiont_species` is `nullptr`!\n";
                return;
            }

            symbiont_species->bind_biont(this);
        }

        void Biont::bind_to_new_parent(yli::ontology::Holobiont* const new_holobiont_parent)
        {
            // this method sets pointer to this `Biont` to `nullptr`, sets `parent` according to the input,
            // and requests a new `childID` from the new `Holobiont`.
            //
            // requirements:
            // `this->holobiont_parent` must not be `nullptr`.
            // `new_holobiont_parent` must not be `nullptr`.

            // unbind from the old parent `Holobiont`.
            if (this->holobiont_parent == nullptr)
            {
                std::cerr << "ERROR: `Biont::bind_to_new_parent`: `this->holobiont_parent` is `nullptr`!\n";
                return;
            }

            if (new_holobiont_parent == nullptr)
            {
                std::cerr << "ERROR: `Biont::bind_to_new_parent`: `new_holobiont_parent` is `nullptr`!\n";
                return;
            }

            this->holobiont_parent->unbind_biont(this->childID);

            // get `childID` from `Holobiont` and set pointer to this `Biont`.
            this->holobiont_parent = new_holobiont_parent;
            this->holobiont_parent->bind_biont(this);
        }

        Biont::~Biont()
        {
            // destructor.
            //
            // requirements:
            // `this->holobiont_parent` must not be `nullptr`.
            // `this->symbiont_species` must not be `nullptr`.

            std::cout << "Biont with childID " << std::dec << this->childID << " will be destroyed.\n";

            yli::ontology::Holobiont* const holobiont = this->holobiont_parent;

            if (holobiont == nullptr)
            {
                std::cerr << "ERROR: `Biont::~Biont`: `holobiont` is `nullptr`!\n";
                return;
            }

            yli::ontology::SymbiontSpecies* const symbiont_species = this->symbiont_species;

            if (symbiont_species == nullptr)
            {
                std::cerr << "ERROR: `Biont::~Biont`: `symbiont_species` is `nullptr`!\n";
                return;
            }

            // set pointer to this `Biont` to `nullptr`.
            symbiont_species->unbind_biont(this->childID);
            holobiont->unbind_biont(this->childID);
        }

        void Biont::render()
        {
            // render this `Biont`.
            //
            // requirements:
            // `this->holobiont_parent` must not be `nullptr`.
            // `this->holobiont_parent->get_parent()` must not be `nullptr`.

            const yli::ontology::Holobiont* const holobiont = this->holobiont_parent;

            if (holobiont == nullptr)
            {
                std::cerr << "ERROR: `Biont::render`: `holobiont` is `nullptr`!\n";
                return;
            }

            const yli::ontology::Symbiosis* const symbiosis = static_cast<yli::ontology::Symbiosis*>(holobiont->get_parent());

            if (symbiosis == nullptr)
            {
                std::cerr << "ERROR: `Biont::render`: `symbiosis` is `nullptr`!\n";
                return;
            }

            if (this->should_ylikuutio_render_this_biont)
            {
                this->prerender();
                this->render_this_biont(static_cast<yli::ontology::Shader*>(symbiosis->get_parent()));
                this->postrender();
            }
        }

        void Biont::render_this_biont(const yli::ontology::Shader* const shader)
        {
            // requirements:
            // `this->universe` must not be `nullptr`.
            // `shader` must not be `nullptr`.
            // `this->holobiont_parent` must not be `nullptr`.
            // `this->symbiont_species` must not be `nullptr`.

            yli::ontology::Universe* const universe = this->universe;

            if (universe == nullptr)
            {
                std::cerr << "ERROR: `Biont::render_this_biont`: `universe` is `nullptr`!\n";
                return;
            }

            if (shader == nullptr)
            {
                std::cerr << "ERROR: `Biont::render_this_biont`: `shader` is `nullptr`!\n";
                return;
            }

            const yli::ontology::Holobiont* const holobiont = this->holobiont_parent;

            if (holobiont == nullptr)
            {
                std::cerr << "ERROR: `Biont::render_this_biont`: `holobiont` is `nullptr`!\n";
                return;
            }

            yli::ontology::Symbiosis* const symbiosis = static_cast<yli::ontology::Symbiosis*>(holobiont->get_parent());

            if (symbiosis == nullptr)
            {
                std::cerr << "ERROR: `Biont::render_this_biont`: `symbiosis` is `nullptr`!\n";
                return;
            }

            const yli::ontology::SymbiontSpecies* const symbiont_species = this->symbiont_species;

            if (symbiont_species == nullptr)
            {
                std::cerr << "ERROR: `Biont::render_this_biont`: `symbiont_species` is `nullptr`!\n";
                return;
            }

            if (!this->has_entered)
            {
                this->model_matrix = glm::translate(glm::mat4(1.0f), this->cartesian_coordinates);

                const std::string model_file_format = symbiosis->get_model_file_format();

                if (model_file_format == "fbx" || model_file_format == "FBX")
                {
                    // Only FBX bionts need initial rotation.
                    this->model_matrix = glm::rotate(this->model_matrix, this->initial_rotate_angle, this->initial_rotate_vector);
                }

                this->model_matrix = glm::scale(this->model_matrix, this->original_scale_vector);

                // store the new coordinates to be used in the next update.
                this->cartesian_coordinates = glm::vec3(this->model_matrix[3][0], this->model_matrix[3][1], this->model_matrix[3][2]);
                this->has_entered = true;
            }
            else
            {
                // rotate.
                if (this->rotate_vector != glm::vec3(0.0f, 0.0f, 0.0f))
                {
                    if (this->quaternions_in_use)
                    {
                        // create `rotation_matrix` using quaternions.
                        glm::quat my_quaternion = glm::quat(DEGREES_TO_RADIANS(this->rotate_vector));
                        glm::mat4 rotation_matrix = glm::mat4_cast(my_quaternion);
                        this->model_matrix = rotation_matrix * this->model_matrix;
                    }
                    else
                    {
                        this->model_matrix = glm::rotate(this->model_matrix, this->rotate_angle, this->rotate_vector);
                    }
                }

                this->model_matrix = glm::translate(this->model_matrix, this->translate_vector);
                this->cartesian_coordinates = glm::vec3(this->model_matrix[3][0], this->model_matrix[3][1], this->model_matrix[3][2]);
            }

            this->MVP_matrix = universe->get_projection_matrix() * universe->get_view_matrix() * this->model_matrix;

            // Bind our texture in Texture Unit 0.
            glActiveTexture(GL_TEXTURE0);
            glBindTexture(GL_TEXTURE_2D, symbiosis->get_texture(this->biontID));
            // Set our "myTextureSampler" sampler to user Texture Unit 0.
            glUniform1i(symbiosis->get_openGL_textureID(this->biontID), 0);

            // '`Material`' part ends here.

            // '`Species`' part begins here.

            // Compute the MVP matrix from keyboard and mouse input.
            const glm::vec3& light_position = symbiosis->get_light_position(this->biontID);
            glUniform3f(
                    symbiosis->get_lightID(this->biontID),
                    light_position.x,
                    light_position.y,
                    light_position.z);

            // 1st attribute buffer : vertices.
            glEnableVertexAttribArray(symbiont_species->get_vertex_position_modelspaceID());

            // 2nd attribute buffer : UVs.
            glEnableVertexAttribArray(symbiont_species->get_vertexUVID());

            // 3rd attribute buffer : normals.
            glEnableVertexAttribArray(symbiont_species->get_vertex_normal_modelspaceID());

            // '`Species`' part ends here.

            // Send our transformation to the currently bound shader,
            // in the "MVP" uniform.
            glUniformMatrix4fv(shader->get_matrixID(), 1, GL_FALSE, &this->MVP_matrix[0][0]);
            glUniformMatrix4fv(shader->get_model_matrixID(), 1, GL_FALSE, &this->model_matrix[0][0]);

            GLuint vertexbuffer = symbiont_species->get_vertexbuffer();
            GLuint vertex_position_modelspaceID = symbiont_species->get_vertex_position_modelspaceID();
            GLuint uvbuffer = symbiont_species->get_uvbuffer();
            GLuint vertexUVID = symbiont_species->get_vertexUVID();
            GLuint normalbuffer = symbiont_species->get_normalbuffer();
            GLuint vertex_normal_modelspaceID = symbiont_species->get_vertex_normal_modelspaceID();
            GLuint elementbuffer = symbiont_species->get_elementbuffer();
            GLuint indices_size = symbiont_species->get_indices_size();

            // 1st attribute buffer : vertices.
            glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
            glVertexAttribPointer(
                    vertex_position_modelspaceID, // The attribute we want to configure
                    3,                           // size
                    GL_FLOAT,                    // type
                    GL_FALSE,                    // normalized?
                    0,                           // stride
                    (void*) 0                    // array buffer offset
                    );

            // 2nd attribute buffer : UVs.
            glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
            glVertexAttribPointer(
                    vertexUVID, // The attribute we want to configure
                    2,          // size : U+V => 2
                    GL_FLOAT,   // type
                    GL_FALSE,   // normalized?
                    0,          // stride
                    (void*) 0   // array buffer offset
                    );

            // 3rd attribute buffer : normals.
            glBindBuffer(GL_ARRAY_BUFFER, normalbuffer);
            glVertexAttribPointer(
                    vertex_normal_modelspaceID, // The attribute we want to configure
                    3,                         // size
                    GL_FLOAT,                  // type
                    GL_FALSE,                  // normalized?
                    0,                         // stride
                    (void*) 0                  // array buffer offset
                    );

            // Index buffer.
            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementbuffer);

            // Draw the triangles!
            glDrawElements(
                    GL_TRIANGLES,    // mode
                    indices_size,    // count
                    GL_UNSIGNED_INT, // type
                    (void*) 0        // element array buffer offset
                    );
        }

        yli::ontology::Entity* Biont::get_parent() const
        {
            return this->holobiont_parent;
        }

        std::size_t Biont::get_number_of_children() const
        {
            return 0; // `Biont` has no children.
        }

        std::size_t Biont::get_number_of_descendants() const
        {
            return 0; // `Biont` has no children.
        }
    }
}
<|endoftext|>


<commit_before>// Ylikuutio - A 3D game and simulation engine.
//
// Copyright (C) 2015-2020 Antti Nuortimo.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.

#ifndef __YLIKUUTIO_ONTOLOGY_BRAIN_HPP_INCLUDED
#define __YLIKUUTIO_ONTOLOGY_BRAIN_HPP_INCLUDED

#include "entity.hpp"
#include "movable.hpp"
#include "child_module.hpp"
#include "master_module.hpp"
#include "brain_struct.hpp"

// Include standard headers
#include <cstddef>  // std::size_t
#include <memory>   // std::make_shared, std::shared_ptr
#include <queue>    // std::queue
#include <vector>   // std::vector

// `yli::ontology::Brain` is a general purpose AI and controller class for `Movable`s.
// Each `Brain` instance may do some actions for the `Movable`s bound to the `Brain`.
// The actions the defined in the callback, referenced using `this->callback_engine`.
// There are some callback snippets for `Brain` in `code/ylikuutio/brain_snippets.hpp`.
// In the future, some of the callbacks will process YliLisp, with an API offered
// to the YliLisp scripts. The API still needs to be defined.
//
// `Brain` does not own the `Movable`s it controls.
// Therefore, `Brain`-`Movable` relationship is not a parent-child relationship.
// Instead, `Brain`-`Movable` relationship is a master-apprentice relationship.
// Therefore, binding is done using `yli::hierarchy::bind_apprentice_to_master`.
//
// Each `Brain` acts upon its `Movable`s immediately after the physics simulation,
// still before rendering, on each frame.
//
// `Brain` actions should not be considered limited to the actions of living or
// conscious beings. For example, a planet `Movable` in a solar system may have a `Brain`
// that makes it orbit its host star, and likewise a moon `Movable` may have a `Brain` that
// makes it orbit its host planet. An electrical module `Movable` (e.g. a synthetizer module)
// may have a `Brain` that defines how it processes its inputs and what kind of output it sends.

namespace yli::callback
{
    class CallbackEngine;
}

namespace yli::ontology
{
    class Universe;
    class Scene;
    class ParentModule;

    class Brain: public yli::ontology::Entity
    {
        public:
            Brain(yli::ontology::Universe* const universe, const yli::ontology::BrainStruct& brain_struct, yli::ontology::ParentModule* const parent_module)
                : Entity(universe, brain_struct),
                child_of_scene(parent_module, this),
                master_of_movables(this)
            {
                // constructor.
                this->callback_engine    = brain_struct.callback_engine;

                // `yli::ontology::Entity` member variables begin here.
                this->type_string = "yli::ontology::Brain*";
                this->can_be_erased = true;
            }

            // destructor.
            ~Brain();

            yli::ontology::Entity* get_parent() const override;

            std::size_t get_number_of_apprentices() const;

            void act();

            yli::ontology::ChildModule child_of_scene;
            yli::ontology::MasterModule<yli::ontology::Brain*, yli::ontology::Movable*> master_of_movables;

        private:
            std::size_t get_number_of_children() const override;
            std::size_t get_number_of_descendants() const override;

            std::shared_ptr<yli::callback::CallbackEngine> callback_engine;
    };
}

#endif
<commit_msg>Reorder `#include` lines.<commit_after>// Ylikuutio - A 3D game and simulation engine.
//
// Copyright (C) 2015-2020 Antti Nuortimo.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.

#ifndef __YLIKUUTIO_ONTOLOGY_BRAIN_HPP_INCLUDED
#define __YLIKUUTIO_ONTOLOGY_BRAIN_HPP_INCLUDED

#include "entity.hpp"
#include "child_module.hpp"
#include "master_module.hpp"
#include "movable.hpp"
#include "brain_struct.hpp"

// Include standard headers
#include <cstddef>  // std::size_t
#include <memory>   // std::make_shared, std::shared_ptr
#include <queue>    // std::queue
#include <vector>   // std::vector

// `yli::ontology::Brain` is a general purpose AI and controller class for `Movable`s.
// Each `Brain` instance may do some actions for the `Movable`s bound to the `Brain`.
// The actions the defined in the callback, referenced using `this->callback_engine`.
// There are some callback snippets for `Brain` in `code/ylikuutio/brain_snippets.hpp`.
// In the future, some of the callbacks will process YliLisp, with an API offered
// to the YliLisp scripts. The API still needs to be defined.
//
// `Brain` does not own the `Movable`s it controls.
// Therefore, `Brain`-`Movable` relationship is not a parent-child relationship.
// Instead, `Brain`-`Movable` relationship is a master-apprentice relationship.
// Therefore, binding is done using `yli::hierarchy::bind_apprentice_to_master`.
//
// Each `Brain` acts upon its `Movable`s immediately after the physics simulation,
// still before rendering, on each frame.
//
// `Brain` actions should not be considered limited to the actions of living or
// conscious beings. For example, a planet `Movable` in a solar system may have a `Brain`
// that makes it orbit its host star, and likewise a moon `Movable` may have a `Brain` that
// makes it orbit its host planet. An electrical module `Movable` (e.g. a synthetizer module)
// may have a `Brain` that defines how it processes its inputs and what kind of output it sends.

namespace yli::callback
{
    class CallbackEngine;
}

namespace yli::ontology
{
    class Universe;
    class Scene;
    class ParentModule;

    class Brain: public yli::ontology::Entity
    {
        public:
            Brain(yli::ontology::Universe* const universe, const yli::ontology::BrainStruct& brain_struct, yli::ontology::ParentModule* const parent_module)
                : Entity(universe, brain_struct),
                child_of_scene(parent_module, this),
                master_of_movables(this)
            {
                // constructor.
                this->callback_engine    = brain_struct.callback_engine;

                // `yli::ontology::Entity` member variables begin here.
                this->type_string = "yli::ontology::Brain*";
                this->can_be_erased = true;
            }

            // destructor.
            ~Brain();

            yli::ontology::Entity* get_parent() const override;

            std::size_t get_number_of_apprentices() const;

            void act();

            yli::ontology::ChildModule child_of_scene;
            yli::ontology::MasterModule<yli::ontology::Brain*, yli::ontology::Movable*> master_of_movables;

        private:
            std::size_t get_number_of_children() const override;
            std::size_t get_number_of_descendants() const override;

            std::shared_ptr<yli::callback::CallbackEngine> callback_engine;
    };
}

#endif
<|endoftext|>


<commit_before>#ifndef PI
#define PI 3.14159265359f
#endif

#ifndef GLM_FORCE_RADIANS
#define GLM_FORCE_RADIANS
#define DEGREES_TO_RADIANS(x) (x * PI / 180.0f)
#endif

#include "scene.hpp"
#include "world.hpp"
#include "ground_level.hpp"
#include "shader.hpp"
#include "camera.hpp"
#include "render_templates.hpp"
#include "family_templates.hpp"
#include "code/ylikuutio/hierarchy/hierarchy_templates.hpp"
#include "code/ylikuutio/common/pi.hpp"

// Include GLEW
#ifndef __GL_GLEW_H_INCLUDED
#define __GL_GLEW_H_INCLUDED
#include <GL/glew.h> // GLfloat, GLuint etc.
#endif

// Include standard headers
#include <cmath>    // NAN, std::isnan, std::pow
#include <cstddef>  // std::size_t
#include <iostream> // std::cout, std::cin, std::cerr
#include <unordered_map> // std::unordered_map

namespace yli
{
    namespace ontology
    {
        void Scene::bind_shader(yli::ontology::Shader* const shader)
        {
            // get `childID` from `Scene` and set pointer to `shader`.
            yli::hierarchy::bind_child_to_parent<yli::ontology::Shader*>(
                    shader,
                    this->shader_pointer_vector,
                    this->free_shaderID_queue,
                    this->number_of_shaders);
        }

        void Scene::bind_camera(yli::ontology::Camera* const camera)
        {
            // get `childID` from `Scene` and set pointer to `camera`.
            yli::hierarchy::bind_child_to_parent<yli::ontology::Camera*>(
                    camera,
                    this->camera_pointer_vector,
                    this->free_cameraID_queue,
                    this->number_of_cameras);
        }

        void Scene::unbind_shader(const std::size_t childID)
        {
            yli::hierarchy::unbind_child_from_parent(
                    childID,
                    this->shader_pointer_vector,
                    this->free_shaderID_queue,
                    this->number_of_shaders);
        }

        void Scene::unbind_camera(const std::size_t childID)
        {
            yli::hierarchy::unbind_child_from_parent(
                    childID,
                    this->camera_pointer_vector,
                    this->free_cameraID_queue,
                    this->number_of_cameras);
        }

        void Scene::bind_to_parent()
        {
            // requirements:
            // `this->parent` must not be `nullptr`.
            yli::ontology::World* const world = this->parent;

            if (world == nullptr)
            {
                std::cerr << "ERROR: `Scene::bind_to_parent`: `world` is `nullptr`!\n";
                return;
            }

            // get `childID` from the `World` and set pointer to this `Scene`.
            world->bind_scene(this);
        }

        Scene::~Scene()
        {
            // destructor.
            std::cout << "Scene with childID " << std::dec << this->childID << " will be destroyed.\n";

            // destroy all `Shader`s of this `Scene`.
            std::cout << "All shaders of this scene will be destroyed.\n";
            yli::hierarchy::delete_children<yli::ontology::Shader*>(this->shader_pointer_vector, this->number_of_shaders);

            // destroy all `Camera`s of this `Scene`.
            std::cout << "All cameras of this scene will be destroyed.\n";
            yli::hierarchy::delete_children<yli::ontology::Camera*>(this->camera_pointer_vector, this->number_of_cameras);

            if (this->parent->get_active_scene() == this)
            {
                // Make this `Scene` no more the active `Scene`.
                this->parent->set_active_scene(nullptr);
            }

            // set pointer to this `Scene` to `nullptr`.
            this->parent->set_scene_pointer(this->childID, nullptr);
        }

        void Scene::render()
        {
            this->prerender();

            // render this `Scene` by calling `render()` function of each `Shader`.
            yli::ontology::render_children<yli::ontology::Shader*>(this->shader_pointer_vector);

            this->postrender();
        }

        yli::ontology::Camera* Scene::get_active_camera() const
        {
            return this->active_camera;
        }

        void Scene::set_active_camera(yli::ontology::Camera* camera)
        {
            this->active_camera = camera;

            if (this->active_camera != nullptr)
            {
                this->universe->current_camera_cartesian_coordinates = camera->get_cartesian_coordinates();
                this->universe->set_projection_matrix(camera->get_projection_matrix());
                this->universe->set_view_matrix(camera->get_view_matrix());
                this->universe->current_camera_horizontal_angle = camera->get_horizontal_angle();
                this->universe->current_camera_vertical_angle = camera->get_vertical_angle();
            }
        }

        yli::ontology::Entity* Scene::get_parent() const
        {
            return this->parent;
        }

        std::size_t Scene::get_number_of_children() const
        {
            return this->number_of_shaders + this->number_of_cameras;
        }

        std::size_t Scene::get_number_of_descendants() const
        {
            return yli::ontology::get_number_of_descendants(this->shader_pointer_vector) +
                yli::ontology::get_number_of_descendants(this->camera_pointer_vector);
        }

        // this method returns a pointer to an `Entity` using the name as key.
        yli::ontology::Entity* Scene::get_entity(const std::string name) const
        {
            if (this->name_map.count(name) != 1)
            {
                return nullptr;
            }

            return this->name_map.at(name);
        }

        float Scene::get_turbo_factor() const
        {
            if (this->parent == this->universe->get_active_world() && this == this->parent->get_active_scene())
            {
                return this->universe->turbo_factor;
            }

            return NAN;
        }

        void Scene::set_turbo_factor(float turbo_factor)
        {
            this->turbo_factor = turbo_factor;

            if (this->parent == this->universe->get_active_world() && this == this->parent->get_active_scene())
            {
                this->universe->turbo_factor = this->turbo_factor;
            }
        }

        float Scene::get_twin_turbo_factor() const
        {
            if (this->parent == this->universe->get_active_world() && this == this->parent->get_active_scene())
            {
                return this->universe->twin_turbo_factor;
            }

            return NAN;
        }

        void Scene::set_twin_turbo_factor(float twin_turbo_factor)
        {
            this->twin_turbo_factor = twin_turbo_factor;

            if (this->parent == this->universe->get_active_world() && this == this->parent->get_active_scene())
            {
                this->universe->twin_turbo_factor = this->twin_turbo_factor;
            }
        }

        float Scene::get_water_level() const
        {
            return this->water_level;
        }

        void Scene::set_shader_pointer(const std::size_t childID, yli::ontology::Shader* const child_pointer)
        {
            yli::hierarchy::set_child_pointer(childID, child_pointer, this->shader_pointer_vector, this->free_shaderID_queue, this->number_of_shaders);
        }

        void Scene::set_camera_pointer(const std::size_t childID, yli::ontology::Camera* const child_pointer)
        {
            yli::hierarchy::set_child_pointer(childID, child_pointer, this->camera_pointer_vector, this->free_cameraID_queue, this->number_of_cameras);
        }
    }
}
<commit_msg>`yli::ontology::Scene`: added checks for `nullptr`.<commit_after>#ifndef PI
#define PI 3.14159265359f
#endif

#ifndef GLM_FORCE_RADIANS
#define GLM_FORCE_RADIANS
#define DEGREES_TO_RADIANS(x) (x * PI / 180.0f)
#endif

#include "scene.hpp"
#include "world.hpp"
#include "ground_level.hpp"
#include "shader.hpp"
#include "camera.hpp"
#include "render_templates.hpp"
#include "family_templates.hpp"
#include "code/ylikuutio/hierarchy/hierarchy_templates.hpp"
#include "code/ylikuutio/common/pi.hpp"

// Include GLEW
#ifndef __GL_GLEW_H_INCLUDED
#define __GL_GLEW_H_INCLUDED
#include <GL/glew.h> // GLfloat, GLuint etc.
#endif

// Include standard headers
#include <cmath>    // NAN, std::isnan, std::pow
#include <cstddef>  // std::size_t
#include <iostream> // std::cout, std::cin, std::cerr
#include <unordered_map> // std::unordered_map

namespace yli
{
    namespace ontology
    {
        void Scene::bind_shader(yli::ontology::Shader* const shader)
        {
            // get `childID` from `Scene` and set pointer to `shader`.
            yli::hierarchy::bind_child_to_parent<yli::ontology::Shader*>(
                    shader,
                    this->shader_pointer_vector,
                    this->free_shaderID_queue,
                    this->number_of_shaders);
        }

        void Scene::bind_camera(yli::ontology::Camera* const camera)
        {
            // get `childID` from `Scene` and set pointer to `camera`.
            yli::hierarchy::bind_child_to_parent<yli::ontology::Camera*>(
                    camera,
                    this->camera_pointer_vector,
                    this->free_cameraID_queue,
                    this->number_of_cameras);
        }

        void Scene::unbind_shader(const std::size_t childID)
        {
            yli::hierarchy::unbind_child_from_parent(
                    childID,
                    this->shader_pointer_vector,
                    this->free_shaderID_queue,
                    this->number_of_shaders);
        }

        void Scene::unbind_camera(const std::size_t childID)
        {
            yli::hierarchy::unbind_child_from_parent(
                    childID,
                    this->camera_pointer_vector,
                    this->free_cameraID_queue,
                    this->number_of_cameras);
        }

        void Scene::bind_to_parent()
        {
            // requirements:
            // `this->parent` must not be `nullptr`.
            yli::ontology::World* const world = this->parent;

            if (world == nullptr)
            {
                std::cerr << "ERROR: `Scene::bind_to_parent`: `world` is `nullptr`!\n";
                return;
            }

            // get `childID` from the `World` and set pointer to this `Scene`.
            world->bind_scene(this);
        }

        Scene::~Scene()
        {
            // destructor.
            std::cout << "Scene with childID " << std::dec << this->childID << " will be destroyed.\n";

            // destroy all `Shader`s of this `Scene`.
            std::cout << "All shaders of this scene will be destroyed.\n";
            yli::hierarchy::delete_children<yli::ontology::Shader*>(this->shader_pointer_vector, this->number_of_shaders);

            // destroy all `Camera`s of this `Scene`.
            std::cout << "All cameras of this scene will be destroyed.\n";
            yli::hierarchy::delete_children<yli::ontology::Camera*>(this->camera_pointer_vector, this->number_of_cameras);

            if (this->parent->get_active_scene() == this)
            {
                // Make this `Scene` no more the active `Scene`.
                this->parent->set_active_scene(nullptr);
            }

            // set pointer to this `Scene` to `nullptr`.
            this->parent->set_scene_pointer(this->childID, nullptr);
        }

        void Scene::render()
        {
            this->prerender();

            // render this `Scene` by calling `render()` function of each `Shader`.
            yli::ontology::render_children<yli::ontology::Shader*>(this->shader_pointer_vector);

            this->postrender();
        }

        yli::ontology::Camera* Scene::get_active_camera() const
        {
            return this->active_camera;
        }

        void Scene::set_active_camera(yli::ontology::Camera* camera)
        {
            this->active_camera = camera;

            if (this->active_camera != nullptr)
            {
                this->universe->current_camera_cartesian_coordinates = camera->get_cartesian_coordinates();
                this->universe->set_projection_matrix(camera->get_projection_matrix());
                this->universe->set_view_matrix(camera->get_view_matrix());
                this->universe->current_camera_horizontal_angle = camera->get_horizontal_angle();
                this->universe->current_camera_vertical_angle = camera->get_vertical_angle();
            }
        }

        yli::ontology::Entity* Scene::get_parent() const
        {
            return this->parent;
        }

        std::size_t Scene::get_number_of_children() const
        {
            return this->number_of_shaders + this->number_of_cameras;
        }

        std::size_t Scene::get_number_of_descendants() const
        {
            return yli::ontology::get_number_of_descendants(this->shader_pointer_vector) +
                yli::ontology::get_number_of_descendants(this->camera_pointer_vector);
        }

        // this method returns a pointer to an `Entity` using the name as key.
        yli::ontology::Entity* Scene::get_entity(const std::string name) const
        {
            if (this->name_map.count(name) != 1)
            {
                return nullptr;
            }

            return this->name_map.at(name);
        }

        float Scene::get_turbo_factor() const
        {
            if (this->parent != nullptr &&
                    this->universe != nullptr &&
                    this->parent == this->universe->get_active_world() &&
                    this == this->parent->get_active_scene())
            {
                return this->universe->turbo_factor;
            }

            return NAN;
        }

        void Scene::set_turbo_factor(float turbo_factor)
        {
            this->turbo_factor = turbo_factor;

            if (this->parent != nullptr &&
                    this->universe != nullptr &&
                    this->parent == this->universe->get_active_world() &&
                    this == this->parent->get_active_scene())
            {
                this->universe->turbo_factor = this->turbo_factor;
            }
        }

        float Scene::get_twin_turbo_factor() const
        {
            if (this->parent != nullptr &&
                    this->universe != nullptr &&
                    this->parent == this->universe->get_active_world() &&
                    this == this->parent->get_active_scene())
            {
                return this->universe->twin_turbo_factor;
            }

            return NAN;
        }

        void Scene::set_twin_turbo_factor(float twin_turbo_factor)
        {
            this->twin_turbo_factor = twin_turbo_factor;

            if (this->parent != nullptr &&
                    this->universe != nullptr &&
                    this->parent == this->universe->get_active_world() &&
                    this == this->parent->get_active_scene())
            {
                this->universe->twin_turbo_factor = this->twin_turbo_factor;
            }
        }

        float Scene::get_water_level() const
        {
            return this->water_level;
        }

        void Scene::set_shader_pointer(const std::size_t childID, yli::ontology::Shader* const child_pointer)
        {
            yli::hierarchy::set_child_pointer(childID, child_pointer, this->shader_pointer_vector, this->free_shaderID_queue, this->number_of_shaders);
        }

        void Scene::set_camera_pointer(const std::size_t childID, yli::ontology::Camera* const child_pointer)
        {
            yli::hierarchy::set_child_pointer(childID, child_pointer, this->camera_pointer_vector, this->free_cameraID_queue, this->number_of_cameras);
        }
    }
}
<|endoftext|>


<commit_before>/*!
 * \copy
 *     Copyright (c)  2013, Cisco Systems
 *     All rights reserved.
 *
 *     Redistribution and use in source and binary forms, with or without
 *     modification, are permitted provided that the following conditions
 *     are met:
 *
 *        * Redistributions of source code must retain the above copyright
 *          notice, this list of conditions and the following disclaimer.
 *
 *        * Redistributions in binary form must reproduce the above copyright
 *          notice, this list of conditions and the following disclaimer in
 *          the documentation and/or other materials provided with the
 *          distribution.
 *
 *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *     "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *     LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *     FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *     COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *     BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *     CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *     LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *     ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *     POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include <stdlib.h>
#include <string.h>
#include "memory_align.h"
#include "macros.h"

namespace WelsCommon {

#ifdef MEMORY_CHECK
static FILE*    fpMemChkPoint;
static uint32_t nCountRequestNum;
static int32_t  g_iMemoryLength;
#endif

CMemoryAlign::CMemoryAlign (const uint32_t kuiCacheLineSize)
#ifdef MEMORY_MONITOR
  : m_nMemoryUsageInBytes (0)
#endif//MEMORY_MONITOR
{
  if ((kuiCacheLineSize == 0) || (kuiCacheLineSize & 0x0f))
    m_nCacheLineSize = 0x10;
  else
    m_nCacheLineSize = kuiCacheLineSize;
}

CMemoryAlign::~CMemoryAlign() {
#ifdef MEMORY_MONITOR
  assert (m_nMemoryUsageInBytes == 0);
#endif//MEMORY_MONITOR
}

void* WelsMalloc (const uint32_t kuiSize, const char* kpTag, const uint32_t kiAlign) {
  const int32_t kiSizeOfVoidPointer     = sizeof (void**);
  const int32_t kiSizeOfInt             = sizeof (int32_t);
  const int32_t kiAlignedBytes          = kiAlign - 1;
  const int32_t kiTrialRequestedSize    = kuiSize + kiAlignedBytes + kiSizeOfVoidPointer + kiSizeOfInt;
  const int32_t kiActualRequestedSize   = kiTrialRequestedSize;
  const uint32_t kiPayloadSize          = kuiSize;

  uint8_t* pBuf = (uint8_t*) malloc (kiActualRequestedSize);
  if (NULL == pBuf)
    return NULL;

#ifdef MEMORY_CHECK
  if (fpMemChkPoint == NULL) {
    fpMemChkPoint    = fopen ("./enc_mem_check_point.txt",  "at+");
    nCountRequestNum = 0;
  }

  if (fpMemChkPoint != NULL) {
    if (kpTag != NULL)
      fprintf (fpMemChkPoint, "WelsMalloc(), 0x%x : actual uiSize:\t%d\tbytes, input uiSize: %d bytes, %d - %s\n",
               (void*)pBuf, kiActualRequestedSize, kuiSize, nCountRequestNum++, kpTag);
    else
      fprintf (fpMemChkPoint, "WelsMalloc(), 0x%x : actual uiSize:\t%d\tbytes, input uiSize: %d bytes, %d \n", (void*)pBuf,
               kiActualRequestedSize, kuiSize, nCountRequestNum++);
    fflush (fpMemChkPoint);
  }
#endif
  uint8_t* pAlignedBuffer;
  pAlignedBuffer = pBuf + kiAlignedBytes + kiSizeOfVoidPointer + kiSizeOfInt;
  pAlignedBuffer -= ((uintptr_t) pAlignedBuffer & kiAlignedBytes);
  * ((void**) (pAlignedBuffer - kiSizeOfVoidPointer)) = pBuf;
  * ((int32_t*) (pAlignedBuffer - (kiSizeOfVoidPointer + kiSizeOfInt))) = kiPayloadSize;

  return pAlignedBuffer;
}

void WelsFree (void* pPointer, const char* kpTag) {
  if (pPointer) {
#ifdef MEMORY_CHECK
    if (fpMemChkPoint != NULL) {
      if (kpTag != NULL)
        fprintf (fpMemChkPoint, "WelsFree(), 0x%x - %s: \t%d\t bytes \n", (void*) (* (((void**) pPointer) - 1)), kpTag,
                 g_iMemoryLength);
      else
        fprintf (fpMemChkPoint, "WelsFree(), 0x%x \n", (void*) (* (((void**) pPointer) - 1)));
      fflush (fpMemChkPoint);
    }
#endif
    free (* (((void**) pPointer) - 1));
  }
}

void* CMemoryAlign::WelsMallocz (const uint32_t kuiSize, const char* kpTag) {
  void* pPointer = WelsMalloc (kuiSize, kpTag);
  if (NULL == pPointer) {
    return NULL;
  }
  // zero memory
  memset (pPointer, 0, kuiSize);

  return pPointer;
}

void* CMemoryAlign::WelsMalloc (const uint32_t kuiSize, const char* kpTag) {
  void* pPointer = WelsCommon::WelsMalloc (kuiSize, kpTag, m_nCacheLineSize);
#ifdef MEMORY_MONITOR
  if (pPointer != NULL) {
    const int32_t kiMemoryLength = * ((int32_t*) ((uint8_t*)pPointer - sizeof (void**) - sizeof (
                                        int32_t))) + m_nCacheLineSize - 1 + sizeof (void**) + sizeof (int32_t);
    m_nMemoryUsageInBytes += kiMemoryLength;
#ifdef MEMORY_CHECK
    g_iMemoryLength = kiMemoryLength;
#endif
  }
#endif//MEMORY_MONITOR
  return pPointer;
}

void CMemoryAlign::WelsFree (void* pPointer, const char* kpTag) {
#ifdef MEMORY_MONITOR
  if (pPointer) {
    const int32_t kiMemoryLength = * ((int32_t*) ((uint8_t*)pPointer - sizeof (void**) - sizeof (
                                        int32_t))) + m_nCacheLineSize - 1 + sizeof (void**) + sizeof (int32_t);
    m_nMemoryUsageInBytes -= kiMemoryLength;
#ifdef MEMORY_CHECK
    g_iMemoryLength = kiMemoryLength;
#endif
  }
#endif//MEMORY_MONITOR
  WelsCommon::WelsFree (pPointer, kpTag);
}

void* WelsMallocz (const uint32_t kuiSize, const char* kpTag) {
  void* pPointer = WelsMalloc (kuiSize, kpTag, 16);
  if (NULL == pPointer) {
    return NULL;
  }
  memset (pPointer, 0, kuiSize);
  return pPointer;
}

const uint32_t CMemoryAlign::WelsGetCacheLineSize() const {
  return m_nCacheLineSize;
}

const uint32_t CMemoryAlign::WelsGetMemoryUsage() const {
  return m_nMemoryUsageInBytes;
}

} // end of namespace WelsCommon
<commit_msg>fix warning in WelsMalloc function<commit_after>/*!
 * \copy
 *     Copyright (c)  2013, Cisco Systems
 *     All rights reserved.
 *
 *     Redistribution and use in source and binary forms, with or without
 *     modification, are permitted provided that the following conditions
 *     are met:
 *
 *        * Redistributions of source code must retain the above copyright
 *          notice, this list of conditions and the following disclaimer.
 *
 *        * Redistributions in binary form must reproduce the above copyright
 *          notice, this list of conditions and the following disclaimer in
 *          the documentation and/or other materials provided with the
 *          distribution.
 *
 *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *     "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *     LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *     FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *     COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *     BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *     CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *     LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *     ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *     POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include <stdlib.h>
#include <string.h>
#include "memory_align.h"
#include "macros.h"

namespace WelsCommon {

#ifdef MEMORY_CHECK
static FILE*    fpMemChkPoint;
static uint32_t nCountRequestNum;
static int32_t  g_iMemoryLength;
#endif

CMemoryAlign::CMemoryAlign (const uint32_t kuiCacheLineSize)
#ifdef MEMORY_MONITOR
  : m_nMemoryUsageInBytes (0)
#endif//MEMORY_MONITOR
{
  if ((kuiCacheLineSize == 0) || (kuiCacheLineSize & 0x0f))
    m_nCacheLineSize = 0x10;
  else
    m_nCacheLineSize = kuiCacheLineSize;
}

CMemoryAlign::~CMemoryAlign() {
#ifdef MEMORY_MONITOR
  assert (m_nMemoryUsageInBytes == 0);
#endif//MEMORY_MONITOR
}

void* WelsMalloc (const uint32_t kuiSize, const char* kpTag, const uint32_t kiAlign) {
  const uint32_t kiSizeOfVoidPointer     = sizeof (void**);
  const uint32_t kiSizeOfInt             = sizeof (int32_t);
  const uint32_t kiAlignedBytes          = kiAlign - 1;
  const uint32_t kiTrialRequestedSize    = kuiSize + kiAlignedBytes + kiSizeOfVoidPointer + kiSizeOfInt;
  const uint32_t kiActualRequestedSize   = kiTrialRequestedSize;
  const uint32_t kiPayloadSize          = kuiSize;

  uint8_t* pBuf = (uint8_t*) malloc (kiActualRequestedSize);
  if (NULL == pBuf)
    return NULL;

#ifdef MEMORY_CHECK
  if (fpMemChkPoint == NULL) {
    fpMemChkPoint    = fopen ("./enc_mem_check_point.txt",  "at+");
    nCountRequestNum = 0;
  }

  if (fpMemChkPoint != NULL) {
    if (kpTag != NULL)
      fprintf (fpMemChkPoint, "WelsMalloc(), 0x%x : actual uiSize:\t%d\tbytes, input uiSize: %d bytes, %d - %s\n",
               (void*)pBuf, kiActualRequestedSize, kuiSize, nCountRequestNum++, kpTag);
    else
      fprintf (fpMemChkPoint, "WelsMalloc(), 0x%x : actual uiSize:\t%d\tbytes, input uiSize: %d bytes, %d \n", (void*)pBuf,
               kiActualRequestedSize, kuiSize, nCountRequestNum++);
    fflush (fpMemChkPoint);
  }
#endif
  uint8_t* pAlignedBuffer;
  pAlignedBuffer = pBuf + kiAlignedBytes + kiSizeOfVoidPointer + kiSizeOfInt;
  pAlignedBuffer -= ((uintptr_t) pAlignedBuffer & kiAlignedBytes);
  * ((void**) (pAlignedBuffer - kiSizeOfVoidPointer)) = pBuf;
  * ((int32_t*) (pAlignedBuffer - (kiSizeOfVoidPointer + kiSizeOfInt))) = kiPayloadSize;

  return pAlignedBuffer;
}

void WelsFree (void* pPointer, const char* kpTag) {
  if (pPointer) {
#ifdef MEMORY_CHECK
    if (fpMemChkPoint != NULL) {
      if (kpTag != NULL)
        fprintf (fpMemChkPoint, "WelsFree(), 0x%x - %s: \t%d\t bytes \n", (void*) (* (((void**) pPointer) - 1)), kpTag,
                 g_iMemoryLength);
      else
        fprintf (fpMemChkPoint, "WelsFree(), 0x%x \n", (void*) (* (((void**) pPointer) - 1)));
      fflush (fpMemChkPoint);
    }
#endif
    free (* (((void**) pPointer) - 1));
  }
}

void* CMemoryAlign::WelsMallocz (const uint32_t kuiSize, const char* kpTag) {
  void* pPointer = WelsMalloc (kuiSize, kpTag);
  if (NULL == pPointer) {
    return NULL;
  }
  // zero memory
  memset (pPointer, 0, kuiSize);

  return pPointer;
}

void* CMemoryAlign::WelsMalloc (const uint32_t kuiSize, const char* kpTag) {
  void* pPointer = WelsCommon::WelsMalloc (kuiSize, kpTag, m_nCacheLineSize);
#ifdef MEMORY_MONITOR
  if (pPointer != NULL) {
    const int32_t kiMemoryLength = * ((int32_t*) ((uint8_t*)pPointer - sizeof (void**) - sizeof (
                                        int32_t))) + m_nCacheLineSize - 1 + sizeof (void**) + sizeof (int32_t);
    m_nMemoryUsageInBytes += kiMemoryLength;
#ifdef MEMORY_CHECK
    g_iMemoryLength = kiMemoryLength;
#endif
  }
#endif//MEMORY_MONITOR
  return pPointer;
}

void CMemoryAlign::WelsFree (void* pPointer, const char* kpTag) {
#ifdef MEMORY_MONITOR
  if (pPointer) {
    const int32_t kiMemoryLength = * ((int32_t*) ((uint8_t*)pPointer - sizeof (void**) - sizeof (
                                        int32_t))) + m_nCacheLineSize - 1 + sizeof (void**) + sizeof (int32_t);
    m_nMemoryUsageInBytes -= kiMemoryLength;
#ifdef MEMORY_CHECK
    g_iMemoryLength = kiMemoryLength;
#endif
  }
#endif//MEMORY_MONITOR
  WelsCommon::WelsFree (pPointer, kpTag);
}

void* WelsMallocz (const uint32_t kuiSize, const char* kpTag) {
  void* pPointer = WelsMalloc (kuiSize, kpTag, 16);
  if (NULL == pPointer) {
    return NULL;
  }
  memset (pPointer, 0, kuiSize);
  return pPointer;
}

const uint32_t CMemoryAlign::WelsGetCacheLineSize() const {
  return m_nCacheLineSize;
}

const uint32_t CMemoryAlign::WelsGetMemoryUsage() const {
  return m_nMemoryUsageInBytes;
}

} // end of namespace WelsCommon
<|endoftext|>


<commit_before>/*******************************************************************************
**
** Filename   : newfolderdialog.cpp
** Created on : 30 January, 2005
** Copyright  : (c) 2005 Till Adam
** Email      : adam@kde.org
**
*******************************************************************************/

/*******************************************************************************
**
**   This program is free software; you can redistribute it and/or modify
**   it under the terms of the GNU General Public License as published by
**   the Free Software Foundation; either version 2 of the License, or
**   (at your option) any later version.
**
**   In addition, as a special exception, the copyright holders give
**   permission to link the code of this program with any edition of
**   the Qt library by Trolltech AS, Norway (or with modified versions
**   of Qt that use the same license as Qt), and distribute linked
**   combinations including the two.  You must obey the GNU General
**   Public License in all respects for all of the code used other than
**   Qt.  If you modify this file, you may extend this exception to
**   your version of the file, but you are not obligated to do so.  If
**   you do not wish to do so, delete this exception statement from
**   your version.
*******************************************************************************/

#include <qvariant.h>
#include <qpushbutton.h>
#include <qlabel.h>
#include <qlineedit.h>
#include <qcombobox.h>
#include <qlayout.h>
#include <qtooltip.h>
#include <qwhatsthis.h>
#include <qregexp.h>

#include <klocale.h>
#include <kdialogbase.h>
#include <kmessagebox.h>

#include "newfolderdialog.h"
#include "kmfolder.h"
#include "folderstorage.h"
#include "kmfolderimap.h"
#include "kmfoldercachedimap.h"
#include "kmfoldermgr.h"
#include "kmfolderdir.h"
#include "folderstorage.h"
#include "kmailicalifaceimpl.h"
#include "kmacctimap.h"
#include "kmacctcachedimap.h"

using namespace KMail;

NewFolderDialog::NewFolderDialog( QWidget* parent, KMFolder *folder )
    : KDialogBase( parent, "new_folder_dialog", false, i18n( "New Folder" ),
                   KDialogBase::Ok|KDialogBase::Cancel,
                   KDialogBase::Ok, true ),
      mFolder( folder )
{
  setWFlags( getWFlags() | WDestructiveClose );
  if ( folder ) {
    setCaption( i18n("New Subfolder of %1").arg( folder->prettyURL() ) );
  }
  QWidget* privateLayoutWidget = new QWidget( this, "mTopLevelLayout" );
  privateLayoutWidget->setGeometry( QRect( 10, 10, 260, 80 ) );
  setMainWidget( privateLayoutWidget );
  mTopLevelLayout = new QVBoxLayout( privateLayoutWidget, 11, 6, "mTopLevelLayout");

  mNameHBox = new QHBoxLayout( 0, 0, 6, "mNameHBox");

  mNameLabel = new QLabel( privateLayoutWidget, "mNameLabel" );
  mNameLabel->setText( i18n( "&Name:" ) );
  mNameHBox->addWidget( mNameLabel );

  mNameLineEdit = new QLineEdit( privateLayoutWidget, "mNameLineEdit" );
  mNameLabel->setBuddy( mNameLineEdit );
  QWhatsThis::add( mNameLineEdit, i18n( "Enter a name for the new folder." ) );
  mNameLineEdit->setFocus();
  mNameHBox->addWidget( mNameLineEdit );
  mTopLevelLayout->addLayout( mNameHBox );
  connect( mNameLineEdit, SIGNAL( textChanged ( const QString & ) ), this, SLOT( slotFolderNameChanged( const QString & ) ) );

  if ( !mFolder ||
      ( mFolder->folderType() != KMFolderTypeImap &&
        mFolder->folderType() != KMFolderTypeCachedImap ) ) {
    mFormatHBox = new QHBoxLayout( 0, 0, 6, "mFormatHBox");
    mMailboxFormatLabel = new QLabel( privateLayoutWidget, "mMailboxFormatLabel" );
    mMailboxFormatLabel->setText( i18n( "Mailbox &format:" ) );
    mFormatHBox->addWidget( mMailboxFormatLabel );

    mFormatComboBox = new QComboBox( FALSE, privateLayoutWidget, "mFormatComboBox" );
    mMailboxFormatLabel->setBuddy( mFormatComboBox );
    QWhatsThis::add( mFormatComboBox, i18n( "Select whether you want to store the messages in this folder as one file per  message (maildir) or as one big file (mbox). KMail uses maildir by default and this only needs to be changed in rare circumstances. If you are unsure, leave this option as-is." ) );

    mFormatComboBox->insertItem("mbox", 0);
    mFormatComboBox->insertItem("maildir", 1);
    // does the below make any sense?
    //  mFormatComboBox->insertItem("search", 2);
    {
      KConfig *config = KMKernel::config();
      KConfigGroupSaver saver(config, "General");
      int type = config->readNumEntry("default-mailbox-format", 1);
      if ( type < 0 || type > 1 ) type = 1;
      mFormatComboBox->setCurrentItem( type );
    }
    mFormatHBox->addWidget( mFormatComboBox );
    mTopLevelLayout->addLayout( mFormatHBox );
  }

  // --- contents -----
  if ( kmkernel->iCalIface().isEnabled() ) {
    mContentsHBox = new QHBoxLayout( 0, 0, 6, "mContentsHBox");

    mContentsLabel = new QLabel( privateLayoutWidget, "mContentsLabel" );
    mContentsLabel->setText( i18n( "Folder &contains:" ) );
    mContentsHBox->addWidget( mContentsLabel );

    mContentsComboBox = new QComboBox( FALSE, privateLayoutWidget, "mContentsComboBox" );
    mContentsLabel->setBuddy( mContentsComboBox );
    QWhatsThis::add( mContentsComboBox, i18n( "Select whether you want the new folder to be used for mail storage of for storage of groupware items such as tasks or notes. The default is mail. If you are unsure, leave this option as-is." ) );
    mContentsComboBox->insertItem( i18n( "Mail" ) );
    mContentsComboBox->insertItem( i18n( "Calendar" ) );
    mContentsComboBox->insertItem( i18n( "Contacts" ) );
    mContentsComboBox->insertItem( i18n( "Notes" ) );
    mContentsComboBox->insertItem( i18n( "Tasks" ) );
    mContentsComboBox->insertItem( i18n( "Journal" ) );
    if ( mFolder ) // inherit contents type from papa
      mContentsComboBox->setCurrentItem( mFolder->storage()->contentsType() );
    mContentsHBox->addWidget( mContentsComboBox );
    mTopLevelLayout->addLayout( mContentsHBox );
  }

  if ( mFolder &&
      ( mFolder->folderType() == KMFolderTypeImap ||
        mFolder->folderType() == KMFolderTypeCachedImap ) ) {
    bool rootFolder = false;
    QStringList namespaces;
    if ( mFolder->folderType() == KMFolderTypeImap ) {
      ImapAccountBase* ai = static_cast<KMFolderImap*>(mFolder->storage())->account();
      if ( mFolder->storage() == ai->rootFolder() ) {
        rootFolder = true;
        namespaces = ai->namespaces()[ImapAccountBase::PersonalNS];
      }
    }
    if ( mFolder->folderType() == KMFolderTypeCachedImap ) {
      ImapAccountBase* ai = static_cast<KMFolderCachedImap*>(mFolder->storage())->account();
      if ( mFolder->storage() == ai->rootFolder() ) {
        rootFolder = true;
        namespaces = ai->namespaces()[ImapAccountBase::PersonalNS];
      }
    }
    if ( rootFolder && namespaces.count() > 1 ) {
      mNamespacesHBox = new QHBoxLayout( 0, 0, 6, "mNamespaceHBox");

      mNamespacesLabel = new QLabel( privateLayoutWidget, "mNamespacesLabel" );
      mNamespacesLabel->setText( i18n( "Namespace for &folder:" ) );
      mNamespacesHBox->addWidget( mNamespacesLabel );

      mNamespacesComboBox = new QComboBox( FALSE, privateLayoutWidget, "mNamespacesComboBox" );
      mNamespacesLabel->setBuddy( mNamespacesComboBox );
      QWhatsThis::add( mNamespacesComboBox, i18n( "Select the personal namespace the folder should be created in." ) );
      mNamespacesComboBox->insertStringList( namespaces );
      mNamespacesHBox->addWidget( mNamespacesComboBox );
      mTopLevelLayout->addLayout( mNamespacesHBox );
    } else {
      mNamespacesComboBox = 0;
    }
  }

  resize( QSize(282, 108).expandedTo(minimumSizeHint()) );
  clearWState( WState_Polished );
  slotFolderNameChanged( mNameLineEdit->text());
}

void NewFolderDialog::slotFolderNameChanged( const QString & _text)
{
  enableButtonOK( !_text.isEmpty() );
}

void NewFolderDialog::slotOk()
{
  const QString &fldName = mNameLineEdit->text();
  if ( fldName.isEmpty() ) {
     KMessageBox::error( this, i18n("Please specify a name for the new folder."),
        i18n( "No Name Specified" ) );
     return;
  }
  if ( fldName.find( '/' ) != -1 &&
    ( !mFolder
      || mFolder->folderType() == KMFolderTypeImap
      || mFolder->folderType() == KMFolderTypeCachedImap ) ) {
    KMessageBox::error( this, i18n( "Folder names cannot contain the / (slash) character; please choose another folder name." ) );
    return;
  }

  if ( fldName.startsWith( "." ) ) {
    KMessageBox::error( this, i18n( "Folder names cannot start with a . (dot) character; please choose another folder name." ) );
    return;
  } else if ( mFolder &&
      ( mFolder->folderType() == KMFolderTypeImap ||
        mFolder->folderType() == KMFolderTypeCachedImap ) ) {
    QString delimiter;
    if ( mFolder->folderType() == KMFolderTypeImap ) {
      KMAcctImap* ai = static_cast<KMFolderImap*>( mFolder->storage() )->account();
      delimiter = ai->delimiterForFolder( mFolder->storage() );
    } else {
      KMAcctCachedImap* ai = static_cast<KMFolderCachedImap*>( mFolder->storage() )->account();
      delimiter = ai->delimiterForFolder( mFolder->storage() );
    }
    if ( !delimiter.isEmpty() && fldName.find( delimiter ) != -1 ) {
      KMessageBox::error( this, i18n( "Your IMAP server does not allow the character '%1'; please choose another folder name." ).arg( delimiter ) );
      return;
    }
  }

  // default parent is Top Level local folders
  KMFolderDir * selectedFolderDir = &(kmkernel->folderMgr()->dir());
  // we got a parent, let's use that
  if ( mFolder )
    selectedFolderDir = mFolder->createChildFolder();

  // check if the folder already exists
  if( selectedFolderDir->hasNamedFolder( fldName )
      && ( !( mFolder
          && ( selectedFolderDir == mFolder->parent() )
          && ( mFolder->storage()->name() == fldName ) ) ) )
  {
    const QString message = i18n( "<qt>Failed to create folder %1, folder already exists.</qt>" ).arg(fldName);
    KMessageBox::error( this, message );
    return;
  }

  /* Ok, obvious errors caught, let's try creating it for real. */
  const QString message = i18n( "<qt>Failed to create folder %1."
            "</qt> " ).arg(fldName);
  bool success = false;
  KMFolder *newFolder = 0;

   if ( mFolder && mFolder->folderType() == KMFolderTypeImap ) {
    KMFolderImap* selectedStorage = static_cast<KMFolderImap*>( mFolder->storage() );
    KMAcctImap *anAccount = selectedStorage->account();
    // check if a connection is available BEFORE creating the folder
    if (anAccount->makeConnection() == ImapAccountBase::Connected) {
      newFolder = kmkernel->imapFolderMgr()->createFolder( fldName, FALSE, KMFolderTypeImap, selectedFolderDir );
      if ( newFolder ) {
        QString imapPath, parent;
        if ( mNamespacesComboBox ) {
          // create folder with namespace
          parent = anAccount->addPathToNamespace( mNamespacesComboBox->currentText() );
          imapPath = anAccount->createImapPath( parent, fldName );
        }
        KMFolderImap* newStorage = static_cast<KMFolderImap*>( newFolder->storage() );
        selectedStorage->createFolder(fldName, parent); // create it on the server
        newStorage->initializeFrom( selectedStorage, imapPath, QString::null );
        static_cast<KMFolderImap*>(mFolder->storage())->setAccount( selectedStorage->account() );
        success = true;
      }
    }
  } else if ( mFolder && mFolder->folderType() == KMFolderTypeCachedImap ) {
    newFolder = kmkernel->dimapFolderMgr()->createFolder( fldName, FALSE, KMFolderTypeCachedImap, selectedFolderDir );
    if ( newFolder ) {
      KMFolderCachedImap* selectedStorage = static_cast<KMFolderCachedImap*>( mFolder->storage() );
      KMFolderCachedImap* newStorage = static_cast<KMFolderCachedImap*>( newFolder->storage() );
      newStorage->initializeFrom( selectedStorage );
      if ( mNamespacesComboBox ) {
        // create folder with namespace
        QString path = selectedStorage->account()->createImapPath(
            mNamespacesComboBox->currentText(), fldName );
        newStorage->setImapPathForCreation( path );
      }
      success = true;
    }
  } else {
    // local folder
    if (mFormatComboBox->currentItem() == 1)
      newFolder = kmkernel->folderMgr()->createFolder(fldName, FALSE, KMFolderTypeMaildir, selectedFolderDir );
    else
      newFolder = kmkernel->folderMgr()->createFolder(fldName, FALSE, KMFolderTypeMbox, selectedFolderDir );
    if ( newFolder )
      success = true;
  }
  if ( !success ) {
    KMessageBox::error( this, message );
    return;
  }

  // Set type field
  if ( kmkernel->iCalIface().isEnabled() && mContentsComboBox ) {
    KMail::FolderContentsType type =
      static_cast<KMail::FolderContentsType>( mContentsComboBox->currentItem() );
    newFolder->storage()->setContentsType( type );
    newFolder->storage()->writeConfig(); // connected slots will read it
  }
  KDialogBase::slotOk();
}

#include "newfolderdialog.moc"
<commit_msg>Another margin/spacing fix.<commit_after>/*******************************************************************************
**
** Filename   : newfolderdialog.cpp
** Created on : 30 January, 2005
** Copyright  : (c) 2005 Till Adam
** Email      : adam@kde.org
**
*******************************************************************************/

/*******************************************************************************
**
**   This program is free software; you can redistribute it and/or modify
**   it under the terms of the GNU General Public License as published by
**   the Free Software Foundation; either version 2 of the License, or
**   (at your option) any later version.
**
**   In addition, as a special exception, the copyright holders give
**   permission to link the code of this program with any edition of
**   the Qt library by Trolltech AS, Norway (or with modified versions
**   of Qt that use the same license as Qt), and distribute linked
**   combinations including the two.  You must obey the GNU General
**   Public License in all respects for all of the code used other than
**   Qt.  If you modify this file, you may extend this exception to
**   your version of the file, but you are not obligated to do so.  If
**   you do not wish to do so, delete this exception statement from
**   your version.
*******************************************************************************/

#include <qvariant.h>
#include <qpushbutton.h>
#include <qlabel.h>
#include <qlineedit.h>
#include <qcombobox.h>
#include <qlayout.h>
#include <qtooltip.h>
#include <qwhatsthis.h>
#include <qregexp.h>

#include <klocale.h>
#include <kdialogbase.h>
#include <kmessagebox.h>

#include "newfolderdialog.h"
#include "kmfolder.h"
#include "folderstorage.h"
#include "kmfolderimap.h"
#include "kmfoldercachedimap.h"
#include "kmfoldermgr.h"
#include "kmfolderdir.h"
#include "folderstorage.h"
#include "kmailicalifaceimpl.h"
#include "kmacctimap.h"
#include "kmacctcachedimap.h"

using namespace KMail;

NewFolderDialog::NewFolderDialog( QWidget* parent, KMFolder *folder )
    : KDialogBase( parent, "new_folder_dialog", false, i18n( "New Folder" ),
                   KDialogBase::Ok|KDialogBase::Cancel,
                   KDialogBase::Ok, true ),
      mFolder( folder )
{
  setWFlags( getWFlags() | WDestructiveClose );
  if ( folder ) {
    setCaption( i18n("New Subfolder of %1").arg( folder->prettyURL() ) );
  }
  QWidget* privateLayoutWidget = new QWidget( this, "mTopLevelLayout" );
  privateLayoutWidget->setGeometry( QRect( 10, 10, 260, 80 ) );
  setMainWidget( privateLayoutWidget );
  mTopLevelLayout = new QVBoxLayout( privateLayoutWidget, 0, spacingHint(),
                                     "mTopLevelLayout");

  mNameHBox = new QHBoxLayout( 0, 0, 6, "mNameHBox");

  mNameLabel = new QLabel( privateLayoutWidget, "mNameLabel" );
  mNameLabel->setText( i18n( "&Name:" ) );
  mNameHBox->addWidget( mNameLabel );

  mNameLineEdit = new QLineEdit( privateLayoutWidget, "mNameLineEdit" );
  mNameLabel->setBuddy( mNameLineEdit );
  QWhatsThis::add( mNameLineEdit, i18n( "Enter a name for the new folder." ) );
  mNameLineEdit->setFocus();
  mNameHBox->addWidget( mNameLineEdit );
  mTopLevelLayout->addLayout( mNameHBox );
  connect( mNameLineEdit, SIGNAL( textChanged ( const QString & ) ), this, SLOT( slotFolderNameChanged( const QString & ) ) );

  if ( !mFolder ||
      ( mFolder->folderType() != KMFolderTypeImap &&
        mFolder->folderType() != KMFolderTypeCachedImap ) ) {
    mFormatHBox = new QHBoxLayout( 0, 0, 6, "mFormatHBox");
    mMailboxFormatLabel = new QLabel( privateLayoutWidget, "mMailboxFormatLabel" );
    mMailboxFormatLabel->setText( i18n( "Mailbox &format:" ) );
    mFormatHBox->addWidget( mMailboxFormatLabel );

    mFormatComboBox = new QComboBox( FALSE, privateLayoutWidget, "mFormatComboBox" );
    mMailboxFormatLabel->setBuddy( mFormatComboBox );
    QWhatsThis::add( mFormatComboBox, i18n( "Select whether you want to store the messages in this folder as one file per  message (maildir) or as one big file (mbox). KMail uses maildir by default and this only needs to be changed in rare circumstances. If you are unsure, leave this option as-is." ) );

    mFormatComboBox->insertItem("mbox", 0);
    mFormatComboBox->insertItem("maildir", 1);
    // does the below make any sense?
    //  mFormatComboBox->insertItem("search", 2);
    {
      KConfig *config = KMKernel::config();
      KConfigGroupSaver saver(config, "General");
      int type = config->readNumEntry("default-mailbox-format", 1);
      if ( type < 0 || type > 1 ) type = 1;
      mFormatComboBox->setCurrentItem( type );
    }
    mFormatHBox->addWidget( mFormatComboBox );
    mTopLevelLayout->addLayout( mFormatHBox );
  }

  // --- contents -----
  if ( kmkernel->iCalIface().isEnabled() ) {
    mContentsHBox = new QHBoxLayout( 0, 0, 6, "mContentsHBox");

    mContentsLabel = new QLabel( privateLayoutWidget, "mContentsLabel" );
    mContentsLabel->setText( i18n( "Folder &contains:" ) );
    mContentsHBox->addWidget( mContentsLabel );

    mContentsComboBox = new QComboBox( FALSE, privateLayoutWidget, "mContentsComboBox" );
    mContentsLabel->setBuddy( mContentsComboBox );
    QWhatsThis::add( mContentsComboBox, i18n( "Select whether you want the new folder to be used for mail storage of for storage of groupware items such as tasks or notes. The default is mail. If you are unsure, leave this option as-is." ) );
    mContentsComboBox->insertItem( i18n( "Mail" ) );
    mContentsComboBox->insertItem( i18n( "Calendar" ) );
    mContentsComboBox->insertItem( i18n( "Contacts" ) );
    mContentsComboBox->insertItem( i18n( "Notes" ) );
    mContentsComboBox->insertItem( i18n( "Tasks" ) );
    mContentsComboBox->insertItem( i18n( "Journal" ) );
    if ( mFolder ) // inherit contents type from papa
      mContentsComboBox->setCurrentItem( mFolder->storage()->contentsType() );
    mContentsHBox->addWidget( mContentsComboBox );
    mTopLevelLayout->addLayout( mContentsHBox );
  }

  if ( mFolder &&
      ( mFolder->folderType() == KMFolderTypeImap ||
        mFolder->folderType() == KMFolderTypeCachedImap ) ) {
    bool rootFolder = false;
    QStringList namespaces;
    if ( mFolder->folderType() == KMFolderTypeImap ) {
      ImapAccountBase* ai = static_cast<KMFolderImap*>(mFolder->storage())->account();
      if ( mFolder->storage() == ai->rootFolder() ) {
        rootFolder = true;
        namespaces = ai->namespaces()[ImapAccountBase::PersonalNS];
      }
    }
    if ( mFolder->folderType() == KMFolderTypeCachedImap ) {
      ImapAccountBase* ai = static_cast<KMFolderCachedImap*>(mFolder->storage())->account();
      if ( mFolder->storage() == ai->rootFolder() ) {
        rootFolder = true;
        namespaces = ai->namespaces()[ImapAccountBase::PersonalNS];
      }
    }
    if ( rootFolder && namespaces.count() > 1 ) {
      mNamespacesHBox = new QHBoxLayout( 0, 0, 6, "mNamespaceHBox");

      mNamespacesLabel = new QLabel( privateLayoutWidget, "mNamespacesLabel" );
      mNamespacesLabel->setText( i18n( "Namespace for &folder:" ) );
      mNamespacesHBox->addWidget( mNamespacesLabel );

      mNamespacesComboBox = new QComboBox( FALSE, privateLayoutWidget, "mNamespacesComboBox" );
      mNamespacesLabel->setBuddy( mNamespacesComboBox );
      QWhatsThis::add( mNamespacesComboBox, i18n( "Select the personal namespace the folder should be created in." ) );
      mNamespacesComboBox->insertStringList( namespaces );
      mNamespacesHBox->addWidget( mNamespacesComboBox );
      mTopLevelLayout->addLayout( mNamespacesHBox );
    } else {
      mNamespacesComboBox = 0;
    }
  }

  resize( QSize(282, 108).expandedTo(minimumSizeHint()) );
  clearWState( WState_Polished );
  slotFolderNameChanged( mNameLineEdit->text());
}

void NewFolderDialog::slotFolderNameChanged( const QString & _text)
{
  enableButtonOK( !_text.isEmpty() );
}

void NewFolderDialog::slotOk()
{
  const QString &fldName = mNameLineEdit->text();
  if ( fldName.isEmpty() ) {
     KMessageBox::error( this, i18n("Please specify a name for the new folder."),
        i18n( "No Name Specified" ) );
     return;
  }
  if ( fldName.find( '/' ) != -1 &&
    ( !mFolder
      || mFolder->folderType() == KMFolderTypeImap
      || mFolder->folderType() == KMFolderTypeCachedImap ) ) {
    KMessageBox::error( this, i18n( "Folder names cannot contain the / (slash) character; please choose another folder name." ) );
    return;
  }

  if ( fldName.startsWith( "." ) ) {
    KMessageBox::error( this, i18n( "Folder names cannot start with a . (dot) character; please choose another folder name." ) );
    return;
  } else if ( mFolder &&
      ( mFolder->folderType() == KMFolderTypeImap ||
        mFolder->folderType() == KMFolderTypeCachedImap ) ) {
    QString delimiter;
    if ( mFolder->folderType() == KMFolderTypeImap ) {
      KMAcctImap* ai = static_cast<KMFolderImap*>( mFolder->storage() )->account();
      delimiter = ai->delimiterForFolder( mFolder->storage() );
    } else {
      KMAcctCachedImap* ai = static_cast<KMFolderCachedImap*>( mFolder->storage() )->account();
      delimiter = ai->delimiterForFolder( mFolder->storage() );
    }
    if ( !delimiter.isEmpty() && fldName.find( delimiter ) != -1 ) {
      KMessageBox::error( this, i18n( "Your IMAP server does not allow the character '%1'; please choose another folder name." ).arg( delimiter ) );
      return;
    }
  }

  // default parent is Top Level local folders
  KMFolderDir * selectedFolderDir = &(kmkernel->folderMgr()->dir());
  // we got a parent, let's use that
  if ( mFolder )
    selectedFolderDir = mFolder->createChildFolder();

  // check if the folder already exists
  if( selectedFolderDir->hasNamedFolder( fldName )
      && ( !( mFolder
          && ( selectedFolderDir == mFolder->parent() )
          && ( mFolder->storage()->name() == fldName ) ) ) )
  {
    const QString message = i18n( "<qt>Failed to create folder %1, folder already exists.</qt>" ).arg(fldName);
    KMessageBox::error( this, message );
    return;
  }

  /* Ok, obvious errors caught, let's try creating it for real. */
  const QString message = i18n( "<qt>Failed to create folder %1."
            "</qt> " ).arg(fldName);
  bool success = false;
  KMFolder *newFolder = 0;

   if ( mFolder && mFolder->folderType() == KMFolderTypeImap ) {
    KMFolderImap* selectedStorage = static_cast<KMFolderImap*>( mFolder->storage() );
    KMAcctImap *anAccount = selectedStorage->account();
    // check if a connection is available BEFORE creating the folder
    if (anAccount->makeConnection() == ImapAccountBase::Connected) {
      newFolder = kmkernel->imapFolderMgr()->createFolder( fldName, FALSE, KMFolderTypeImap, selectedFolderDir );
      if ( newFolder ) {
        QString imapPath, parent;
        if ( mNamespacesComboBox ) {
          // create folder with namespace
          parent = anAccount->addPathToNamespace( mNamespacesComboBox->currentText() );
          imapPath = anAccount->createImapPath( parent, fldName );
        }
        KMFolderImap* newStorage = static_cast<KMFolderImap*>( newFolder->storage() );
        selectedStorage->createFolder(fldName, parent); // create it on the server
        newStorage->initializeFrom( selectedStorage, imapPath, QString::null );
        static_cast<KMFolderImap*>(mFolder->storage())->setAccount( selectedStorage->account() );
        success = true;
      }
    }
  } else if ( mFolder && mFolder->folderType() == KMFolderTypeCachedImap ) {
    newFolder = kmkernel->dimapFolderMgr()->createFolder( fldName, FALSE, KMFolderTypeCachedImap, selectedFolderDir );
    if ( newFolder ) {
      KMFolderCachedImap* selectedStorage = static_cast<KMFolderCachedImap*>( mFolder->storage() );
      KMFolderCachedImap* newStorage = static_cast<KMFolderCachedImap*>( newFolder->storage() );
      newStorage->initializeFrom( selectedStorage );
      if ( mNamespacesComboBox ) {
        // create folder with namespace
        QString path = selectedStorage->account()->createImapPath(
            mNamespacesComboBox->currentText(), fldName );
        newStorage->setImapPathForCreation( path );
      }
      success = true;
    }
  } else {
    // local folder
    if (mFormatComboBox->currentItem() == 1)
      newFolder = kmkernel->folderMgr()->createFolder(fldName, FALSE, KMFolderTypeMaildir, selectedFolderDir );
    else
      newFolder = kmkernel->folderMgr()->createFolder(fldName, FALSE, KMFolderTypeMbox, selectedFolderDir );
    if ( newFolder )
      success = true;
  }
  if ( !success ) {
    KMessageBox::error( this, message );
    return;
  }

  // Set type field
  if ( kmkernel->iCalIface().isEnabled() && mContentsComboBox ) {
    KMail::FolderContentsType type =
      static_cast<KMail::FolderContentsType>( mContentsComboBox->currentItem() );
    newFolder->storage()->setContentsType( type );
    newFolder->storage()->writeConfig(); // connected slots will read it
  }
  KDialogBase::slotOk();
}

#include "newfolderdialog.moc"
<|endoftext|>


<commit_before>/* KPilot
**
** Copyright (C) 1998-2001 by Dan Pilone
** Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
**
** This is a wrapper for pilot-link's general
** Pilot database structures. These records are
*** just collections of bits. See PilotAppCategory
** for interpreting the bits in a meaningful way.
**
** As a crufty hack, the non-inline parts of
** PilotAppCategory live in this file as well.
*/

/*
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation; either version 2.1 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public License
** along with this program in a file called COPYING; if not, write to
** the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
** MA 02111-1307, USA.
*/

/*
** Bug reports and questions can be sent to kde-pim@kde.org
*/
#include "options.h"

#include <string.h>

#include <qtextcodec.h>
#include <qregexp.h>

#include <kglobal.h>
#include <kcharsets.h>

// PilotAppCategory includes pilotRecord and we
// provide its implementation here as well.
//
#include "pilotAppCategory.h"

static const char *pilotRecord_id =
	"$Id$";

/* static */ int PilotRecord::fAllocated = 0;
/* static */ int PilotRecord::fDeleted = 0;

/* static */ void PilotRecord::allocationInfo()
{
#ifdef DEBUG
	FUNCTIONSETUP;
	DEBUGKPILOT << fname
		<< ": Allocated " << fAllocated
		<< "  Deleted " << fDeleted << endl;
#endif
}

PilotRecord::PilotRecord(void *data, int len, int attrib, int cat,
	pi_uid_t uid) :
	fData(0L),
	fLen(len),
	fAttrib(attrib),
	fCat(cat),
	fID(uid)
#if PILOT_LINK_NUMBER >= PILOT_LINK_0_12_0
	,
	fBuffer(0L)
#endif
{
	FUNCTIONSETUP;
	fData = new char[len];

	memcpy(fData, data, len);

	fAllocated++;
	(void) pilotRecord_id;
}

PilotRecord::PilotRecord(PilotRecord * orig) :
	fID(orig->id())
#if PILOT_LINK_NUMBER >= PILOT_LINK_0_12_0
	,
	fBuffer(0L)
#endif
{
	FUNCTIONSETUP;
	fData = new char[orig->getLen()];

	memcpy(fData, orig->getData(), orig->getLen());
	fLen = orig->getLen();
	fAttrib = orig->getAttrib();
	fCat = orig->category();
	fID = orig->id();

	fAllocated++;
}

PilotRecord & PilotRecord::operator = (PilotRecord & orig)
{
	FUNCTIONSETUP;
#if PILOT_LINK_NUMBER >= PILOT_LINK_0_12_0
	if (fBuffer)
	{
		pi_buffer_free(fBuffer);
		fBuffer=0L;
		fData=0L;
	}
#endif

	if (fData)
		delete[]fData;
	fData = new char[orig.getLen()];

	memcpy(fData, orig.getData(), orig.getLen());
	fLen = orig.getLen();
	fAttrib = orig.getAttrib();
	fCat = orig.category();
	fID = orig.id();
	return *this;
}

recordid_t PilotRecord::getID() const
{
	return id();
}

void PilotRecord::makeDeleted()
{
	setDeleted(true);
}

void PilotRecord::makeSecret()
{
	setSecret(true);
}

int PilotRecord::getCat() const
{
	return category();
}

void PilotRecord::setCat(int i)
{
	return setCategory(i);
}

void PilotRecord::setData(const char *data, int len)
{
	FUNCTIONSETUP;
	if (fData)
		delete[]fData;
	fData = new char[len];

	memcpy(fData, data, len);
	fLen = len;
}

/* static */ QTextCodec *PilotAppCategory::pilotCodec = 0L;

/* static */ QTextCodec *PilotAppCategory::setupPilotCodec(const QString &s)
{
	FUNCTIONSETUP;
	QString encoding(KGlobal::charsets()->encodingForName(s));

#ifdef DEBUG
	DEBUGKPILOT << fname << ": Creating codec " << encoding << endl;
#endif

	// if the desired codec can't be found, latin1 will be returned anyway, no need to do this manually
	pilotCodec = KGlobal::charsets()->codecForName(encoding);

#ifdef DEBUG
	DEBUGKPILOT << fname
		<< ": Got codec " << codecName() << " for setting "
		<< s << endl;
#endif
	return codec();
}

/* static */ QString PilotAppCategory::codecName()
{
	return QString::fromLatin1(codec()->name());
}

bool PilotAppCategory::setCat(struct CategoryAppInfo &info,const QString &label)
{
	int emptyAvailable = -1;
	if (label.isEmpty()) { setCat(0); return true; }
	for (int catId = 1; catId < 16; catId++)
	{
		QString aCat;
		if (!info.name[catId][0])
		{
			emptyAvailable=catId; continue;
		}
		aCat = codec()->toUnicode(info.name[catId]);
		if (label == aCat) { setCat(catId); return true; }
	}
	if (emptyAvailable<0) return false;
	strlcpy(info.name[emptyAvailable], codec()->fromUnicode(label), 16);
	setCat(emptyAvailable);
	return true;
}
<commit_msg>Don't spam debug with every record creation.<commit_after>/* KPilot
**
** Copyright (C) 1998-2001 by Dan Pilone
** Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
**
** This is a wrapper for pilot-link's general
** Pilot database structures. These records are
*** just collections of bits. See PilotAppCategory
** for interpreting the bits in a meaningful way.
**
** As a crufty hack, the non-inline parts of
** PilotAppCategory live in this file as well.
*/

/*
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation; either version 2.1 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public License
** along with this program in a file called COPYING; if not, write to
** the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
** MA 02111-1307, USA.
*/

/*
** Bug reports and questions can be sent to kde-pim@kde.org
*/
#include "options.h"

#include <string.h>

#include <qtextcodec.h>
#include <qregexp.h>

#include <kglobal.h>
#include <kcharsets.h>

// PilotAppCategory includes pilotRecord and we
// provide its implementation here as well.
//
#include "pilotAppCategory.h"

static const char *pilotRecord_id =
	"$Id$";

/* static */ int PilotRecord::fAllocated = 0;
/* static */ int PilotRecord::fDeleted = 0;

/* static */ void PilotRecord::allocationInfo()
{
#ifdef DEBUG
	FUNCTIONSETUP;
	DEBUGKPILOT << fname
		<< ": Allocated " << fAllocated
		<< "  Deleted " << fDeleted << endl;
#endif
}

PilotRecord::PilotRecord(void *data, int len, int attrib, int cat,
	pi_uid_t uid) :
	fData(0L),
	fLen(len),
	fAttrib(attrib),
	fCat(cat),
	fID(uid)
#if PILOT_LINK_NUMBER >= PILOT_LINK_0_12_0
	,
	fBuffer(0L)
#endif
{
	FUNCTIONSETUPL(4);
	fData = new char[len];

	memcpy(fData, data, len);

	fAllocated++;
	(void) pilotRecord_id;
}

PilotRecord::PilotRecord(PilotRecord * orig) :
	fID(orig->id())
#if PILOT_LINK_NUMBER >= PILOT_LINK_0_12_0
	,
	fBuffer(0L)
#endif
{
	FUNCTIONSETUPL(4);
	fData = new char[orig->getLen()];

	memcpy(fData, orig->getData(), orig->getLen());
	fLen = orig->getLen();
	fAttrib = orig->getAttrib();
	fCat = orig->category();
	fID = orig->id();

	fAllocated++;
}

PilotRecord & PilotRecord::operator = (PilotRecord & orig)
{
	FUNCTIONSETUP;
#if PILOT_LINK_NUMBER >= PILOT_LINK_0_12_0
	if (fBuffer)
	{
		pi_buffer_free(fBuffer);
		fBuffer=0L;
		fData=0L;
	}
#endif

	if (fData)
		delete[]fData;
	fData = new char[orig.getLen()];

	memcpy(fData, orig.getData(), orig.getLen());
	fLen = orig.getLen();
	fAttrib = orig.getAttrib();
	fCat = orig.category();
	fID = orig.id();
	return *this;
}

recordid_t PilotRecord::getID() const
{
	return id();
}

void PilotRecord::makeDeleted()
{
	setDeleted(true);
}

void PilotRecord::makeSecret()
{
	setSecret(true);
}

int PilotRecord::getCat() const
{
	return category();
}

void PilotRecord::setCat(int i)
{
	return setCategory(i);
}

void PilotRecord::setData(const char *data, int len)
{
	FUNCTIONSETUP;
	if (fData)
		delete[]fData;
	fData = new char[len];

	memcpy(fData, data, len);
	fLen = len;
}

/* static */ QTextCodec *PilotAppCategory::pilotCodec = 0L;

/* static */ QTextCodec *PilotAppCategory::setupPilotCodec(const QString &s)
{
	FUNCTIONSETUP;
	QString encoding(KGlobal::charsets()->encodingForName(s));

#ifdef DEBUG
	DEBUGKPILOT << fname << ": Creating codec " << encoding << endl;
#endif

	// if the desired codec can't be found, latin1 will be returned anyway, no need to do this manually
	pilotCodec = KGlobal::charsets()->codecForName(encoding);

#ifdef DEBUG
	DEBUGKPILOT << fname
		<< ": Got codec " << codecName() << " for setting "
		<< s << endl;
#endif
	return codec();
}

/* static */ QString PilotAppCategory::codecName()
{
	return QString::fromLatin1(codec()->name());
}

bool PilotAppCategory::setCat(struct CategoryAppInfo &info,const QString &label)
{
	int emptyAvailable = -1;
	if (label.isEmpty()) { setCat(0); return true; }
	for (int catId = 1; catId < 16; catId++)
	{
		QString aCat;
		if (!info.name[catId][0])
		{
			emptyAvailable=catId; continue;
		}
		aCat = codec()->toUnicode(info.name[catId]);
		if (label == aCat) { setCat(catId); return true; }
	}
	if (emptyAvailable<0) return false;
	strlcpy(info.name[emptyAvailable], codec()->fromUnicode(label), 16);
	setCat(emptyAvailable);
	return true;
}
<|endoftext|>