<commit_before>/*
 * main.cpp (Tutorial05_RenderTarget)
 *
 * This file is part of the "LLGL" project (Copyright (c) 2015 by Lukas Hermanns)
 * See "LICENSE.txt" for license information.
 */

#include "../tutorial.h"

// Enable multi-sampling
#define ENABLE_MULTISAMPLING

// Enable custom multi-sampling by rendering directly into a multi-sample texture
#define ENABLE_CUSTOM_MULTISAMPLING

#ifndef ENABLE_MULTISAMPLING
#undef ENABLE_CUSTOM_MULTISAMPLING
#endif

class Tutorial05 : public Tutorial
{

    LLGL::ShaderProgram*    shaderProgram       = nullptr;

    LLGL::GraphicsPipeline* pipeline            = nullptr;

    LLGL::Buffer*           vertexBuffer        = nullptr;
    LLGL::Buffer*           indexBuffer         = nullptr;
    LLGL::Buffer*           constantBuffer      = nullptr;

    LLGL::Texture*          colorMap            = nullptr;
    LLGL::Sampler*          samplerState        = nullptr;

    LLGL::RenderTarget*     renderTarget        = nullptr;
    LLGL::Texture*          renderTargetTex     = nullptr;

    Gs::Matrix4f            renderTargetProj;

    const Gs::Vector2ui     renderTargetSize    = Gs::Vector2ui(
        #ifdef ENABLE_CUSTOM_MULTISAMPLING
        64
        #else
        512
        #endif
    );

    struct Settings
    {
        Gs::Matrix4f        wvpMatrix;
        int                 useTexture2DMS = 0;
        int                 _pad0[3];
    }
    settings;

public:

    Tutorial05() :
        Tutorial( L"LLGL Tutorial 05: RenderTarget" )
    {
        // Create all graphics objects
        auto vertexFormat = CreateBuffers();
        LoadShaders(vertexFormat);
        CreatePipelines();
        CreateColorMap();
        CreateRenderTarget();

        // Show some information
        std::cout << "press LEFT MOUSE BUTTON and move the mouse on the X-axis to rotate the OUTER cube" << std::endl;
        std::cout << "press RIGHT MOUSE BUTTON and move the mouse on the X-axis to rotate the INNER cube" << std::endl;
        std::cout << "press RETURN KEY to save the render target texture to a PNG file" << std::endl;
    }

    LLGL::VertexFormat CreateBuffers()
    {
        // Specify vertex format
        LLGL::VertexFormat vertexFormat;
        vertexFormat.AppendAttribute({ "position", LLGL::VectorType::Float3 });
        vertexFormat.AppendAttribute({ "texCoord", LLGL::VectorType::Float2 });

        // Initialize vertices (scale texture-coordiantes a little bit, to show the texture border)
        auto vertices = GenerateTexturedCubeVertices();

        for (auto& v : vertices)
            v.texCoord = (v.texCoord - Gs::Vector2f(0.5f))*1.05f + Gs::Vector2f(0.5f);

        // Create vertex, index, and constant buffer
        vertexBuffer = CreateVertexBuffer(vertices, vertexFormat);
        indexBuffer = CreateIndexBuffer(GenerateTexturedCubeTriangleIndices(), LLGL::DataType::UInt32);
        constantBuffer = CreateConstantBuffer(settings);

        return vertexFormat;
    }

    void LoadShaders(const LLGL::VertexFormat& vertexFormat)
    {
        {
            // Load shader program
            if (renderer->GetRenderingCaps().shadingLanguage >= LLGL::ShadingLanguage::HLSL_2_0)
            {
                shaderProgram = LoadShaderProgram(
                    {
                        { LLGL::ShaderType::Vertex, "shader.hlsl", "VS", "vs_5_0" },
                        { LLGL::ShaderType::Fragment, "shader.hlsl", "PS", "ps_5_0" }
                    },
                    vertexFormat
                );
            }
            else
            {
                shaderProgram = LoadShaderProgram(
                    {
                        { LLGL::ShaderType::Vertex, "vertex.glsl" },
                        #ifdef __APPLE__
                        { LLGL::ShaderType::Fragment, "fragment.410core.glsl" }
                        #else
                        { LLGL::ShaderType::Fragment, "fragment.glsl" }
                        #endif
                    },
                    vertexFormat
                );
            }
        }
    }

    void CreatePipelines()
    {
        // Create common graphics pipeline for scene rendering
        LLGL::GraphicsPipelineDescriptor pipelineDesc;
        {
            pipelineDesc.shaderProgram              = shaderProgram;

            pipelineDesc.depth.testEnabled          = true;
            pipelineDesc.depth.writeEnabled         = true;

            pipelineDesc.rasterizer.cullMode        = LLGL::CullMode::Back;
            #ifdef ENABLE_MULTISAMPLING
            pipelineDesc.rasterizer.multiSampling   = LLGL::MultiSamplingDescriptor(8);
            #endif
        }
        pipeline = renderer->CreateGraphicsPipeline(pipelineDesc);
    }

    void CreateColorMap()
    {
        // Load color map texture from file
        colorMap = LoadTexture("colorMap.jpg");

        // Create common sampler state for all textures
        LLGL::SamplerDescriptor samplerDesc;
        {
            samplerDesc.textureWrapU    = LLGL::TextureWrap::Border;
            samplerDesc.textureWrapV    = LLGL::TextureWrap::Border;
            samplerDesc.maxAnisotropy   = 8;
            samplerDesc.borderColor     = { 0, 0, 0, 1 };
        }
        samplerState = renderer->CreateSampler(samplerDesc);
    }

    void CreateRenderTarget()
    {
        // Create render-target with multi-sampling
        LLGL::RenderTargetDescriptor renderTargetDesc;
        {
            #ifdef ENABLE_MULTISAMPLING
            renderTargetDesc.multiSampling          = LLGL::MultiSamplingDescriptor(8);
            #   ifdef ENABLE_CUSTOM_MULTISAMPLING
            renderTargetDesc.customMultiSampling    = true;
            #   endif
            #endif
        }
        renderTarget = renderer->CreateRenderTarget(renderTargetDesc);

        // Create empty render-target texture
        #ifdef ENABLE_CUSTOM_MULTISAMPLING

        renderTargetTex = renderer->CreateTexture(
            LLGL::Texture2DMSDesc(LLGL::TextureFormat::RGBA, renderTargetSize.x, renderTargetSize.y, renderTargetDesc.multiSampling.samples)
        );

        #else

        renderTargetTex = renderer->CreateTexture(
            LLGL::Texture2DDesc(LLGL::TextureFormat::RGBA, renderTargetSize.x, renderTargetSize.y)
        );

        #endif

        // Generate all MIP-map levels
        renderer->GenerateMips(*renderTargetTex);

        // Attach depth buffer to render-target
        renderTarget->AttachDepthBuffer(renderTargetSize);

        // Attach texture (first MIP-map level) to render-target
        renderTarget->AttachTexture(*renderTargetTex, {});

        // Initialize projection matrix for render-target scene rendering
        renderTargetProj = Gs::ProjectionMatrix4f::Perspective(1.0f, 0.1f, 100.0f, Gs::Deg2Rad(45.0f)).ToMatrix4();
    }

private:

    void UpdateModelTransform(const Gs::Matrix4f& proj, float rotation, const Gs::Vector3f& axis = { 0, 1, 0 })
    {
        settings.wvpMatrix = proj;
        Gs::Translate(settings.wvpMatrix, { 0, 0, 5 });
        Gs::RotateFree(settings.wvpMatrix, axis.Normalized(), rotation);
    }

    void OnDrawFrame() override
    {
        static const auto shaderStages = LLGL::ShaderStageFlags::VertexStage | LLGL::ShaderStageFlags::FragmentStage;

        // Update scene animation (simple rotation)
        static float rot0, rot1;

        if (input->KeyPressed(LLGL::Key::LButton))
            rot0 += static_cast<float>(input->GetMouseMotion().x)*0.005f;
        if (input->KeyPressed(LLGL::Key::RButton))
            rot1 += static_cast<float>(input->GetMouseMotion().x)*0.005f;

        // Set common buffers and sampler states
        commands->SetIndexBuffer(*indexBuffer);
        commands->SetVertexBuffer(*vertexBuffer);
        commands->SetConstantBuffer(*constantBuffer, 0, shaderStages);
        commands->SetSampler(*samplerState, 0, shaderStages);

        // Set graphics pipeline state
        commands->SetGraphicsPipeline(*pipeline);

        if (IsOpenGL())
        {
            /*
            Set graphics API dependent state to be uniform between OpenGL and Direct3D:
            A huge difference between OpenGL and Direct3D is,
            that OpenGL stores image data from the lower-left to the upper-right in a texture,
            but Direct3D stores image data from the upper-left to the lower-right in a texture.
            The default screen-space origin of LLGL is the upper-left, so when rendering into a texture,
            we need to render vertically flipped when OpenGL is used.
            To do this we flip the Y-axis of the world-view-projection matrix and invert the front-facing,
            so that the face-culling works as excepted.
            */
            LLGL::GraphicsAPIDependentStateDescriptor apiState;
            {
                apiState.stateOpenGL.invertFrontFace = true;
            }
            commands->SetGraphicsAPIDependentState(apiState);
        }

        // Draw scene into render-target
        commands->SetRenderTarget(*renderTarget);
        {
            // Set viewport for render target
            commands->SetViewport({ 0, 0, static_cast<float>(renderTargetSize.x), static_cast<float>(renderTargetSize.y) });

            // Clear color and depth buffers of active framebuffer (i.e. the render target)
            commands->SetClearColor({ 0.2f, 0.7f, 0.1f });
            commands->Clear(LLGL::ClearFlags::Color | LLGL::ClearFlags::Depth);

            // Set color map texture
            commands->SetTexture(*colorMap, 0, shaderStages);

            // Update model transformation with render-target projection
            UpdateModelTransform(renderTargetProj, rot1, Gs::Vector3f(1));

            if (IsOpenGL())
            {
                /*
                Now flip the Y-axis (0 for X-axis, 1 for Y-axis, 2 for Z-axis) of the
                world-view-projection matrix to render vertically flipped into the render-target
                */
                Gs::FlipAxis(settings.wvpMatrix, 1);
            }

            #ifdef ENABLE_CUSTOM_MULTISAMPLING

            // Disable multi-sample texture in fragment shader
            settings.useTexture2DMS = 0;

            #endif

            UpdateBuffer(constantBuffer, settings);

            // Draw scene
            commands->DrawIndexed(36, 0);
        }
        commands->SetRenderTarget(*context);

        // Generate MIP-maps again after texture has been written by the render-target
        renderer->GenerateMips(*renderTargetTex);

        if (IsOpenGL())
        {
            // Reset graphics API dependent state
            commands->SetGraphicsAPIDependentState({});
        }

        // Reset viewport for the screen
        auto resolution = context->GetVideoMode().resolution.Cast<float>();
        commands->SetViewport({ 0, 0, resolution.x, resolution.y });

        // Clear color and depth buffers of active framebuffer (i.e. the screen)
        commands->SetClearColor(defaultClearColor);
        commands->Clear(LLGL::ClearFlags::Color | LLGL::ClearFlags::Depth);

        #ifdef ENABLE_CUSTOM_MULTISAMPLING

        // Set multi-sample render-target texture
        commands->SetTexture(*renderTargetTex, 1, shaderStages);

        #else

        // Set render-target texture
        commands->SetTexture(*renderTargetTex, 0, shaderStages);

        #endif

        #ifdef ENABLE_CUSTOM_MULTISAMPLING

        // Enable multi-sample texture in fragment shader
        settings.useTexture2DMS = 1;

        #endif

        // Update model transformation with standard projection
        UpdateModelTransform(projection, rot0);
        UpdateBuffer(constantBuffer, settings);

        // Draw scene
        commands->DrawIndexed(36, 0);

        // Present result on the screen
        context->Present();

        // Check if user wants to sage the render target texture to file
        if (input->KeyDown(LLGL::Key::Return))
            SaveTexture(*renderTargetTex, "RenderTargetTexture.png");
    }

};

LLGL_IMPLEMENT_TUTORIAL(Tutorial05);

<commit_msg>Added small workaround to Tutorial05 for unsupported mouse events on MacOS port.<commit_after>/*
 * main.cpp (Tutorial05_RenderTarget)
 *
 * This file is part of the "LLGL" project (Copyright (c) 2015 by Lukas Hermanns)
 * See "LICENSE.txt" for license information.
 */

#include "../tutorial.h"

// Enable multi-sampling
#define ENABLE_MULTISAMPLING

// Enable custom multi-sampling by rendering directly into a multi-sample texture
//#define ENABLE_CUSTOM_MULTISAMPLING

#ifndef ENABLE_MULTISAMPLING
#undef ENABLE_CUSTOM_MULTISAMPLING
#endif

class Tutorial05 : public Tutorial
{

    LLGL::ShaderProgram*    shaderProgram       = nullptr;

    LLGL::GraphicsPipeline* pipeline            = nullptr;

    LLGL::Buffer*           vertexBuffer        = nullptr;
    LLGL::Buffer*           indexBuffer         = nullptr;
    LLGL::Buffer*           constantBuffer      = nullptr;

    LLGL::Texture*          colorMap            = nullptr;
    LLGL::Sampler*          samplerState        = nullptr;

    LLGL::RenderTarget*     renderTarget        = nullptr;
    LLGL::Texture*          renderTargetTex     = nullptr;

    Gs::Matrix4f            renderTargetProj;

    const Gs::Vector2ui     renderTargetSize    = Gs::Vector2ui(
        #ifdef ENABLE_CUSTOM_MULTISAMPLING
        64
        #else
        512
        #endif
    );

    struct Settings
    {
        Gs::Matrix4f        wvpMatrix;
        int                 useTexture2DMS = 0;
        int                 _pad0[3];
    }
    settings;

public:

    Tutorial05() :
        Tutorial( L"LLGL Tutorial 05: RenderTarget" )
    {
        // Create all graphics objects
        auto vertexFormat = CreateBuffers();
        LoadShaders(vertexFormat);
        CreatePipelines();
        CreateColorMap();
        CreateRenderTarget();

        // Show some information
        std::cout << "press LEFT MOUSE BUTTON and move the mouse on the X-axis to rotate the OUTER cube" << std::endl;
        std::cout << "press RIGHT MOUSE BUTTON and move the mouse on the X-axis to rotate the INNER cube" << std::endl;
        std::cout << "press RETURN KEY to save the render target texture to a PNG file" << std::endl;
    }

    LLGL::VertexFormat CreateBuffers()
    {
        // Specify vertex format
        LLGL::VertexFormat vertexFormat;
        vertexFormat.AppendAttribute({ "position", LLGL::VectorType::Float3 });
        vertexFormat.AppendAttribute({ "texCoord", LLGL::VectorType::Float2 });

        // Initialize vertices (scale texture-coordiantes a little bit, to show the texture border)
        auto vertices = GenerateTexturedCubeVertices();

        for (auto& v : vertices)
            v.texCoord = (v.texCoord - Gs::Vector2f(0.5f))*1.05f + Gs::Vector2f(0.5f);

        // Create vertex, index, and constant buffer
        vertexBuffer = CreateVertexBuffer(vertices, vertexFormat);
        indexBuffer = CreateIndexBuffer(GenerateTexturedCubeTriangleIndices(), LLGL::DataType::UInt32);
        constantBuffer = CreateConstantBuffer(settings);

        return vertexFormat;
    }

    void LoadShaders(const LLGL::VertexFormat& vertexFormat)
    {
        {
            // Load shader program
            if (renderer->GetRenderingCaps().shadingLanguage >= LLGL::ShadingLanguage::HLSL_2_0)
            {
                shaderProgram = LoadShaderProgram(
                    {
                        { LLGL::ShaderType::Vertex, "shader.hlsl", "VS", "vs_5_0" },
                        { LLGL::ShaderType::Fragment, "shader.hlsl", "PS", "ps_5_0" }
                    },
                    vertexFormat
                );
            }
            else
            {
                shaderProgram = LoadShaderProgram(
                    {
                        { LLGL::ShaderType::Vertex, "vertex.glsl" },
                        #ifdef __APPLE__
                        { LLGL::ShaderType::Fragment, "fragment.410core.glsl" }
                        #else
                        { LLGL::ShaderType::Fragment, "fragment.glsl" }
                        #endif
                    },
                    vertexFormat
                );
            }
        }
    }

    void CreatePipelines()
    {
        // Create common graphics pipeline for scene rendering
        LLGL::GraphicsPipelineDescriptor pipelineDesc;
        {
            pipelineDesc.shaderProgram              = shaderProgram;

            pipelineDesc.depth.testEnabled          = true;
            pipelineDesc.depth.writeEnabled         = true;

            pipelineDesc.rasterizer.cullMode        = LLGL::CullMode::Back;
            #ifdef ENABLE_MULTISAMPLING
            pipelineDesc.rasterizer.multiSampling   = LLGL::MultiSamplingDescriptor(8);
            #endif
        }
        pipeline = renderer->CreateGraphicsPipeline(pipelineDesc);
    }

    void CreateColorMap()
    {
        // Load color map texture from file
        colorMap = LoadTexture("colorMap.jpg");

        // Create common sampler state for all textures
        LLGL::SamplerDescriptor samplerDesc;
        {
            samplerDesc.textureWrapU    = LLGL::TextureWrap::Border;
            samplerDesc.textureWrapV    = LLGL::TextureWrap::Border;
            samplerDesc.maxAnisotropy   = 8;
            samplerDesc.borderColor     = { 0, 0, 0, 1 };
        }
        samplerState = renderer->CreateSampler(samplerDesc);
    }

    void CreateRenderTarget()
    {
        // Create render-target with multi-sampling
        LLGL::RenderTargetDescriptor renderTargetDesc;
        {
            #ifdef ENABLE_MULTISAMPLING
            renderTargetDesc.multiSampling          = LLGL::MultiSamplingDescriptor(8);
            #   ifdef ENABLE_CUSTOM_MULTISAMPLING
            renderTargetDesc.customMultiSampling    = true;
            #   endif
            #endif
        }
        renderTarget = renderer->CreateRenderTarget(renderTargetDesc);

        // Create empty render-target texture
        #ifdef ENABLE_CUSTOM_MULTISAMPLING

        renderTargetTex = renderer->CreateTexture(
            LLGL::Texture2DMSDesc(LLGL::TextureFormat::RGBA, renderTargetSize.x, renderTargetSize.y, renderTargetDesc.multiSampling.samples)
        );

        #else

        renderTargetTex = renderer->CreateTexture(
            LLGL::Texture2DDesc(LLGL::TextureFormat::RGBA, renderTargetSize.x, renderTargetSize.y)
        );

        #endif

        // Generate all MIP-map levels
        renderer->GenerateMips(*renderTargetTex);

        // Attach depth buffer to render-target
        renderTarget->AttachDepthBuffer(renderTargetSize);

        // Attach texture (first MIP-map level) to render-target
        renderTarget->AttachTexture(*renderTargetTex, {});

        // Initialize projection matrix for render-target scene rendering
        renderTargetProj = Gs::ProjectionMatrix4f::Perspective(1.0f, 0.1f, 100.0f, Gs::Deg2Rad(45.0f)).ToMatrix4();
    }

private:

    void UpdateModelTransform(const Gs::Matrix4f& proj, float rotation, const Gs::Vector3f& axis = { 0, 1, 0 })
    {
        settings.wvpMatrix = proj;
        Gs::Translate(settings.wvpMatrix, { 0, 0, 5 });
        Gs::RotateFree(settings.wvpMatrix, axis.Normalized(), rotation);
    }

    void OnDrawFrame() override
    {
        static const auto shaderStages = LLGL::ShaderStageFlags::VertexStage | LLGL::ShaderStageFlags::FragmentStage;

        // Update scene animation (simple rotation)
        static float rot0, rot1;

        #ifdef __APPLE__ // Workaround for currently unsupported mouse movement events
        rot0 += 0.0025f;
        rot1 += 0.005f;
        #else
        if (input->KeyPressed(LLGL::Key::LButton))
            rot0 += static_cast<float>(input->GetMouseMotion().x)*0.005f;
        if (input->KeyPressed(LLGL::Key::RButton))
            rot1 += static_cast<float>(input->GetMouseMotion().x)*0.005f;
        #endif

        // Set common buffers and sampler states
        commands->SetIndexBuffer(*indexBuffer);
        commands->SetVertexBuffer(*vertexBuffer);
        commands->SetConstantBuffer(*constantBuffer, 0, shaderStages);
        commands->SetSampler(*samplerState, 0, shaderStages);

        // Set graphics pipeline state
        commands->SetGraphicsPipeline(*pipeline);

        if (IsOpenGL())
        {
            /*
            Set graphics API dependent state to be uniform between OpenGL and Direct3D:
            A huge difference between OpenGL and Direct3D is,
            that OpenGL stores image data from the lower-left to the upper-right in a texture,
            but Direct3D stores image data from the upper-left to the lower-right in a texture.
            The default screen-space origin of LLGL is the upper-left, so when rendering into a texture,
            we need to render vertically flipped when OpenGL is used.
            To do this we flip the Y-axis of the world-view-projection matrix and invert the front-facing,
            so that the face-culling works as excepted.
            */
            LLGL::GraphicsAPIDependentStateDescriptor apiState;
            {
                apiState.stateOpenGL.invertFrontFace = true;
            }
            commands->SetGraphicsAPIDependentState(apiState);
        }

        // Draw scene into render-target
        commands->SetRenderTarget(*renderTarget);
        {
            // Set viewport for render target
            commands->SetViewport({ 0, 0, static_cast<float>(renderTargetSize.x), static_cast<float>(renderTargetSize.y) });

            // Clear color and depth buffers of active framebuffer (i.e. the render target)
            commands->SetClearColor({ 0.2f, 0.7f, 0.1f });
            commands->Clear(LLGL::ClearFlags::Color | LLGL::ClearFlags::Depth);

            // Set color map texture
            commands->SetTexture(*colorMap, 0, shaderStages);

            // Update model transformation with render-target projection
            UpdateModelTransform(renderTargetProj, rot1, Gs::Vector3f(1));

            if (IsOpenGL())
            {
                /*
                Now flip the Y-axis (0 for X-axis, 1 for Y-axis, 2 for Z-axis) of the
                world-view-projection matrix to render vertically flipped into the render-target
                */
                Gs::FlipAxis(settings.wvpMatrix, 1);
            }

            #ifdef ENABLE_CUSTOM_MULTISAMPLING

            // Disable multi-sample texture in fragment shader
            settings.useTexture2DMS = 0;

            #endif

            UpdateBuffer(constantBuffer, settings);

            // Draw scene
            commands->DrawIndexed(36, 0);
        }
        commands->SetRenderTarget(*context);

        // Generate MIP-maps again after texture has been written by the render-target
        renderer->GenerateMips(*renderTargetTex);

        if (IsOpenGL())
        {
            // Reset graphics API dependent state
            commands->SetGraphicsAPIDependentState({});
        }

        // Reset viewport for the screen
        auto resolution = context->GetVideoMode().resolution.Cast<float>();
        commands->SetViewport({ 0, 0, resolution.x, resolution.y });

        // Clear color and depth buffers of active framebuffer (i.e. the screen)
        commands->SetClearColor(defaultClearColor);
        commands->Clear(LLGL::ClearFlags::Color | LLGL::ClearFlags::Depth);

        #ifdef ENABLE_CUSTOM_MULTISAMPLING

        // Set multi-sample render-target texture
        commands->SetTexture(*renderTargetTex, 1, shaderStages);

        #else

        // Set render-target texture
        commands->SetTexture(*renderTargetTex, 0, shaderStages);

        #endif

        #ifdef ENABLE_CUSTOM_MULTISAMPLING

        // Enable multi-sample texture in fragment shader
        settings.useTexture2DMS = 1;

        #endif

        // Update model transformation with standard projection
        UpdateModelTransform(projection, rot0);
        UpdateBuffer(constantBuffer, settings);

        // Draw scene
        commands->DrawIndexed(36, 0);

        // Present result on the screen
        context->Present();

        // Check if user wants to sage the render target texture to file
        if (input->KeyDown(LLGL::Key::Return))
            SaveTexture(*renderTargetTex, "RenderTargetTexture.png");
    }

};

LLGL_IMPLEMENT_TUTORIAL(Tutorial05);

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: constants.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-07 16:34:46 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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 library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

 #ifndef _CONSTANTS_HXX_
 #define _CONSTANTS_HXX_

extern const int MSWORD;
extern const int MSEXCEL;
extern const int MSPOWERPOINT;
extern const int DEFAULT_HTML_EDITOR_FOR_IE;
extern const int HTML_EDITOR;
extern const int DEFAULT_SHELL_HTML_EDITOR;

 #endif

<commit_msg>INTEGRATION: CWS changefileheader (1.2.260); FILE MERGED 2008/03/31 16:07:59 rt 1.2.260.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: constants.hxx,v $
 * $Revision: 1.3 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

 #ifndef _CONSTANTS_HXX_
 #define _CONSTANTS_HXX_

extern const int MSWORD;
extern const int MSEXCEL;
extern const int MSPOWERPOINT;
extern const int DEFAULT_HTML_EDITOR_FOR_IE;
extern const int HTML_EDITOR;
extern const int DEFAULT_SHELL_HTML_EDITOR;

 #endif

<|endoftext|>


<commit_before>#include "./texture2d.h"
#include "./texture_container.h"

namespace Graphics
{

Texture2d::Texture2d(TextureContainer *container, int sliceCount)
  : container(container), sliceCount(sliceCount)
{
}

Texture2d::~Texture2d()
{
  free();
  container->virtualFree(sliceCount);
}

const TextureContainer *Texture2d::getTextureContainer() const
{
  return container;
}

int Texture2d::getSliceCount() const
{
  return sliceCount;
}

TextureAddress Texture2d::address() const
{
  printf(" %f %f:\n", static_cast<float>(width) / container->getWidth(),
         static_cast<float>(height) / container->getHeight());

  return { container->getHandle(),
           static_cast<float>(sliceCount),
           0,
           { static_cast<float>(width) / container->getWidth(),
             static_cast<float>(height) / container->getHeight() } };
}

void Texture2d::commit()
{
  container->commit(this);
}

void Texture2d::free()
{
  container->free(this);
}

void Texture2d::compressedTexSubImage2D(int level, int xOffset,
                                        int yOffset, int width,
                                        int height, int format,
                                        int imageSize, const void *data)
{
  this->width = width;
  this->height = height;

  container->compressedTexSubImage3d(level, xOffset, yOffset, sliceCount, width,
                                     height, 1, format, imageSize, data);
}

void Texture2d::texSubImage2D(int level, int xOffset, int yOffset,
                              int width, int height, int format,
                              int type, const void *data)
{
  this->width = width;
  this->height = height;

  container->texSubImage3d(level, xOffset, yOffset, sliceCount, width, height,
                           1, format, type, data);
}

}  // namespace Graphics
<commit_msg>Minor: delete printf and reformatting.<commit_after>#include "./texture2d.h"
#include "./texture_container.h"

namespace Graphics
{

Texture2d::Texture2d(TextureContainer *container, int sliceCount)
  : container(container), sliceCount(sliceCount)
{
}

Texture2d::~Texture2d()
{
  free();
  container->virtualFree(sliceCount);
}

const TextureContainer *Texture2d::getTextureContainer() const
{
  return container;
}

int Texture2d::getSliceCount() const
{
  return sliceCount;
}

TextureAddress Texture2d::address() const
{
  return { container->getHandle(),
           static_cast<float>(sliceCount),
           0,
           { static_cast<float>(width) / container->getWidth(),
             static_cast<float>(height) / container->getHeight() } };
}

void Texture2d::commit()
{
  container->commit(this);
}

void Texture2d::free()
{
  container->free(this);
}

void Texture2d::compressedTexSubImage2D(int level, int xOffset, int yOffset,
                                        int width, int height, int format,
                                        int imageSize, const void *data)
{
  this->width = width;
  this->height = height;

  container->compressedTexSubImage3d(level, xOffset, yOffset, sliceCount, width,
                                     height, 1, format, imageSize, data);
}

void Texture2d::texSubImage2D(int level, int xOffset, int yOffset, int width,
                              int height, int format, int type,
                              const void *data)
{
  this->width = width;
  this->height = height;

  container->texSubImage3d(level, xOffset, yOffset, sliceCount, width, height,
                           1, format, type, data);
}

}  // namespace Graphics
<|endoftext|>


<commit_before>#ifndef MATRIXOPERATIONS__HPP__
#define MATRIXOPERATIONS__HPP__

#include <vector>

namespace basicAdt {

  template<class _T>
  class CW {
  public:
    void rotate(_T &upperLCorner, _T &upperRCorner, _T &lowerLCorner, _T &lowerRCorner){
      _T temp = upperLCorner;
      upperLCorner = lowerLCorner;
      lowerLCorner = lowerRCorner;
      lowerRCorner = upperRCorner;
      upperRCorner = temp;
    }
  };

  template<class _T>
  class CCW {
  public:
    void rotate(_T &upperLCorner, _T &upperRCorner, _T &lowerLCorner, _T &lowerRCorner){
      _T temp = upperLCorner;
      upperLCorner = upperRCorner;
      upperRCorner = lowerRCorner;
      lowerRCorner = lowerLCorner;
      lowerLCorner = temp;
    }
  };

  template<template<typename> class DirectionPolicy, class _Type>
	class Rotate {
    DirectionPolicy<_Type> direction;
	public:
    Rotate(std::vector<std::vector<_Type> > &squareMatrix){
      int n = squareMatrix.size() - 1;
      int outerEnd = squareMatrix.size() / 2;
      int innerEnd = (squareMatrix.size() + 1) / 2;
      for (int i = 0; i != outerEnd; ++i) {
        for (int j = 0; j != innerEnd; ++j) {
          direction.rotate(squareMatrix[i][j], squareMatrix[j][n - i],
            squareMatrix[n - j][i], squareMatrix[n - i][n - j]);
        }
      }
    }
	};

}

#endif<commit_msg>Added problem description<commit_after>#ifndef MATRIXOPERATIONS__HPP__
#define MATRIXOPERATIONS__HPP__

#include <vector>

namespace basicAdt {

template<class _T>
class CW {
public:
  void rotate(_T &upperLCorner, _T &upperRCorner, _T &lowerLCorner, _T &lowerRCorner){
    _T temp = upperLCorner;
    upperLCorner = lowerLCorner;
    lowerLCorner = lowerRCorner;
    lowerRCorner = upperRCorner;
    upperRCorner = temp;
  }
};

template<class _T>
class CCW {
public:
  void rotate(_T &upperLCorner, _T &upperRCorner, _T &lowerLCorner, _T &lowerRCorner){
    _T temp = upperLCorner;
    upperLCorner = upperRCorner;
    upperRCorner = lowerRCorner;
    lowerRCorner = lowerLCorner;
    lowerLCorner = temp;
  }
};

/*! Given an image represented by an NxN matrix, where each pixel in the image is
 *  4 bytes, write a method to rotate the image by 90 degrees. IN PLACE
 */
template<template<typename> class DirectionPolicy, class _Type>
class Rotate {
  DirectionPolicy<_Type> direction;
public:
  Rotate(std::vector<std::vector<_Type> > &squareMatrix){
    int n = squareMatrix.size() - 1;
    int outerEnd = squareMatrix.size() / 2;
    int innerEnd = (squareMatrix.size() + 1) / 2;
    for (int i = 0; i != outerEnd; ++i) {
      for (int j = 0; j != innerEnd; ++j) {
        direction.rotate(squareMatrix[i][j], squareMatrix[j][n - i],
          squareMatrix[n - j][i], squareMatrix[n - i][n - j]);
      }
    }
  }
};

}

#endif<|endoftext|>


<commit_before>//
// Created by marandil on 03.09.15.
//

//
// Created by marandil on 03.09.15.
//

#include <utility>
#include <vector>

#include <gtest/gtest.h>

#include <mdlutils/types/range.hpp>

class RangeTest : public ::testing::Test
{
protected:
    template<typename T>
    struct args
    {
        T s, e, o;
    };

    std::vector<std::pair<args<int>, std::vector<int>>> pythonRRT;

public:
    RangeTest()
    {
        // Python random range emulation tests:
        // ( check gen_range_tests.py for details on generation )
#include "pythonrtt.inc"
    }
};

template<typename T>
void test_range(T first, T last, T offset, mdl::range<T> r)
{
    size_t n(0);

    // count the actual number of occurrences in the classic range case
    if (offset > 0)
        for (T i = first; i < last; i += offset)
            n++;
    else
        for (T i = first; i > last; i += offset)
            n++;

    for (T i : r)
    {
        n--;
        EXPECT_EQ(first, i);
        first += offset;
    }
    EXPECT_EQ(0, n);
}

template<typename T>
void test_simple_range(T last)
{
    mdl::range<T> r(last);
    T first(0), offset(1);

    test_range(first, last, offset, r);
}

template<typename T>
void test_se_range(T first, T last)
{
    mdl::range<T> r(first, last);
    T offset(1);

    test_range(first, last, offset, r);
}

template<typename T>
void test_seo_range(T first, T last, T offset)
{
    mdl::range<T> r(first, last, offset);

    test_range(first, last, offset, r);
}

TEST_F(RangeTest, IntSimple)
{
    test_simple_range(0);
    test_simple_range(1);
    test_simple_range(2);
    test_simple_range(10);
}

TEST_F(RangeTest, IntStartStop)
{
    test_se_range(0, 0);
    test_se_range(0, 1);
    test_se_range(0, 2);
    test_se_range(0, 10);

    test_se_range(-7, 0);
    test_se_range(12, 1);
    test_se_range(2, 2);
    test_se_range(-10, 10);
}

TEST_F(RangeTest, IntStartStopOff)
{
    test_seo_range(0, 0, 1);
    test_seo_range(0, 1, 1);
    test_seo_range(0, 2, 1);
    test_seo_range(0, 10, 1);

    test_seo_range(-7, 0, 1);
    test_seo_range(12, 1, -1);
    test_seo_range(2, 2, 10);
    test_seo_range(-10, 10, 5);
}

TEST_F(RangeTest, PythonRRT)
{
    for (auto &item : pythonRRT)
    {
        mdl::range<int> r(item.first.s, item.first.e, item.first.o);
        std::vector<int> test(r.begin(), r.end());
        EXPECT_EQ(test, item.second);
    }
}
<commit_msg>Added size-checking to range (python RRT) unit tests.<commit_after>//
// Created by marandil on 03.09.15.
//

//
// Created by marandil on 03.09.15.
//

#include <utility>
#include <vector>

#include <gtest/gtest.h>

#include <mdlutils/types/range.hpp>

class RangeTest : public ::testing::Test
{
protected:
    template<typename T>
    struct args
    {
        T s, e, o;
    };

    std::vector<std::pair<args<int>, std::vector<int>>> pythonRRT;

public:
    RangeTest()
    {
        // Python random range emulation tests:
        // ( check gen_range_tests.py for details on generation )
#include "pythonrtt.inc"
    }
};

template<typename T>
void test_range(T first, T last, T offset, mdl::range<T> r)
{
    size_t n(0);

    // count the actual number of occurrences in the classic range case
    if (offset > 0)
        for (T i = first; i < last; i += offset)
            n++;
    else
        for (T i = first; i > last; i += offset)
            n++;

    for (T i : r)
    {
        n--;
        EXPECT_EQ(first, i);
        first += offset;
    }
    EXPECT_EQ(0, n);
}

template<typename T>
void test_simple_range(T last)
{
    mdl::range<T> r(last);
    T first(0), offset(1);

    test_range(first, last, offset, r);
}

template<typename T>
void test_se_range(T first, T last)
{
    mdl::range<T> r(first, last);
    T offset(1);

    test_range(first, last, offset, r);
}

template<typename T>
void test_seo_range(T first, T last, T offset)
{
    mdl::range<T> r(first, last, offset);

    test_range(first, last, offset, r);
}

TEST_F(RangeTest, IntSimple)
{
    test_simple_range(0);
    test_simple_range(1);
    test_simple_range(2);
    test_simple_range(10);
}

TEST_F(RangeTest, IntStartStop)
{
    test_se_range(0, 0);
    test_se_range(0, 1);
    test_se_range(0, 2);
    test_se_range(0, 10);

    test_se_range(-7, 0);
    test_se_range(12, 1);
    test_se_range(2, 2);
    test_se_range(-10, 10);
}

TEST_F(RangeTest, IntStartStopOff)
{
    test_seo_range(0, 0, 1);
    test_seo_range(0, 1, 1);
    test_seo_range(0, 2, 1);
    test_seo_range(0, 10, 1);

    test_seo_range(-7, 0, 1);
    test_seo_range(12, 1, -1);
    test_seo_range(2, 2, 10);
    test_seo_range(-10, 10, 5);
}

TEST_F(RangeTest, PythonRRT)
{
    for (auto &item : pythonRRT)
    {
        mdl::range<int> r(item.first.s, item.first.e, item.first.o);
        std::vector<int> test(r.begin(), r.end());
        EXPECT_EQ(test, item.second);
        EXPECT_EQ(test.size(), r.size());
        EXPECT_EQ(item.second.size(), r.size());
    }
}
<|endoftext|>


<commit_before>#ifndef MXPFIT_SELF_ADJOINT_CONEIGENSOLVER_HPP
#define MXPFIT_SELF_ADJOINT_CONEIGENSOLVER_HPP

#include <cassert>
#include <type_traits>

#include <Eigen/Core>
#include <Eigen/QR>

#include <mxpfit/jacobi_svd.hpp>

namespace mxpfit
{
///
/// ### SelfAdjointConeigenSolver
///
/// \brief Compute con-eigenvalue decomposition of self-adjoint matrix having a
///        rank-revealing decomposition
///
/// \tparam T  Scalar type of matrix to be decomposed.
///
/// Let \f$A\f$ be an \f$n \times n\f$ self-adjoint matrix having a rank
/// revealing decomposition of the form
///
/// \f[ A = X D^2 X^{\ast},\f]
///
/// where \f$X\f$ is a \f$n \times k \, (n \geq k)\f$ matrix and \f$D\f$ is a
/// \f$k \times k\f$ diagonal matrix with non-negative entries. This class
/// computes a con-eigenvalue decomposition of matrix \f$A\f$ defined as
///
/// \f[
///   A = \overline{U} \Sigma U^{\ast}
/// \f]
///
/// where \f$U\f$ is a \f$n \times k\f$ matrix satisfying \f$U^{-1}=U^{T},\f$
/// and overline denotes the element-wise complex conjugate of a matrix.
/// \f$\Sigma=\mathrm{diag}(\sigma_{1},\dots,\sigma_{k})\f$ is a \f$k \times
/// k\f$ diagonal matrix with \f$\sigma_{1}\geq\sigma_{2}\geq \cdots \geq
/// \sigma_{k} > 0.\f$ The con-eigenvalue decomposition defined above is a
/// special case of singular value decomposition (SVD) \f$A=W\Sigma V^{\ast}\f$,
/// where \f$ W=\overline{U} \f$ and \f$V=U.\f$
///
/// The con-eigenvalue decomposition is computed in high-relative accuracy using
/// the algorithm developed by Haut and Beylkin. The algorithm can also be
/// regarded as modification of Demmel's algorithm for high accuracy SVD of a
/// matrix with rank-revealing decomposition. See the references listed below
/// for the details.
///
///
/// #### References
///
/// 1. T. S. Haut and G. Beylkin, "FAST AND ACCURATE CON-EIGENVALUE
/// ALGORITHM
///    FOR OPTIMAL RATIONAL APPROXIMATIONS", SIAM J. Matrix Anal. Appl.
///    **33** (2012) 1101-1125. [DOI: https://doi.org/10.1137/110821901]
/// 2. J. Demmel, "ACCURATE SINGULAR VALUE DECOMPOSITIONS OF STRUCTURED
///    MATRICES", SIAM J. Matrix Anal. Appl. **21** (1999) 562-580.
///    [DOI: https://doi.org/10.1137/S0895479897328716]
/// 3. J. Demmel, M. Gu, S. Eisenstat, I. Slapnicar, K. Veselic, and Z. Drmac,
///    "ACCURATE SINGULAR VALUE DECOMPOSITIONS OF STRUCTURED MATRICES", SIAM J.
///    Linear Algebra Appl. **299** (1999) 21-80. [DOI:
///    https://doi.org/10.1016/S0024-3795(99)00134-2]
///
template <typename T>
class SelfAdjointConeigenSolver
{
public:
    using Index         = Eigen::Index;
    using Scalar        = T;
    using RealScalar    = typename Eigen::NumTraits<Scalar>::Real;
    using ComplexScalar = std::complex<RealScalar>;

    using MatrixType = Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic>;
    using VectorType = Eigen::Matrix<Scalar, Eigen::Dynamic, 1>;
    using RealVectorType = Eigen::Matrix<RealScalar, Eigen::Dynamic, 1>;

    using ConeigenvalueType = Eigen::Matrix<RealScalar, Eigen::Dynamic, 1>;

protected:
    enum
    {
        IsComplex  = Eigen::NumTraits<Scalar>::IsComplex,
        PacketSize = Eigen::internal::packet_traits<Scalar>::size,
        Alignment  = Eigen::internal::traits<MatrixType>::Alignment,
        // Alignment  = Eigen::internal::unpacket_traits<PacketType>::alignment
    };

    using MappedMatrix = Eigen::Map<MatrixType, Alignment>;
    using PacketType   = typename Eigen::internal::packet_traits<Scalar>::type;

    MatrixType m_ceigvecs;     // m x n (m >= n)
    RealVectorType m_ceigvals; // n
    MatrixType m_mat_work1;    // n x n
    MatrixType m_mat_work2;    // n x n

public:
    SelfAdjointConeigenSolver()                                 = default;
    SelfAdjointConeigenSolver(const SelfAdjointConeigenSolver&) = default;

    explicit SelfAdjointConeigenSolver(Index size, Index rank)
        : m_ceigvecs(size, rank),
          m_ceigvals(rank),
          m_mat_work1(rank, rank),
          m_mat_work2(rank, rank)
    {
        assert(size >= rank);
    }

    ~SelfAdjointConeigenSolver() = default;

    template <typename InputMatrix, typename InputVector>
    void compute(const Eigen::MatrixBase<InputMatrix>& matX,
                 const Eigen::MatrixBase<InputVector>& vecD);

    const MatrixType& coneigenvectors() const
    {
        return m_ceigvecs;
    }

    const RealVectorType& coneigenvalues() const
    {
        return m_ceigvals;
    }

protected:
    void resize(Index m, Index n)
    {
        m_ceigvecs.resize(m, n);
        m_ceigvals.resize(n);
        m_mat_work1.resize(n, n);
        m_mat_work2.resize(n, n);
    }
};

template <typename T>
template <typename InputMatrix, typename InputVector>
void SelfAdjointConeigenSolver<T>::compute(
    const Eigen::MatrixBase<InputMatrix>& matX,
    const Eigen::MatrixBase<InputVector>& vecD)
{
    EIGEN_STATIC_ASSERT_VECTOR_ONLY(InputVector);

    assert(matX.rows() >= matX.cols());
    assert(vecD.size() == matX.cols());

    const Index m = matX.rows();
    const Index n = matX.cols();
    resize(m, n);

    // Aliases
    // MatrixType& matG = m_mat_work1;              // D * X^T * X * D
    // MappedMatrix matR1(m_ceigvecs.data(), n, n); // D^{-1} * R * D^{-1}
    // MatrixType& matRt     = m_mat_work2;         // R^{T}
    // RealVectorType& sigma = m_ceigvals;
    // MatrixType& matU      = m_mat_work1; // left singular vectors of R
    // MatrixType& matY1     = m_mat_work2; // D^{-1} * U * S^{1/2}

    MappedMatrix matG(m_ceigvecs.data(), n, n);

    //
    // Form G = D * (X.st() * X) * D
    //
    matG.noalias() = matX.transpose() * matX;
    for (Index j = 0; j < n; ++j)
    {
        for (Index i = 0; i < n; ++i)
        {
            matG(i, j) *= vecD(i) * vecD(j);
        }
    }
    //
    // Compute G = Q * R by Householder QR factorization. G is overwritten by QR
    // factors.
    //
    Eigen::HouseholderQR<Eigen::Ref<MatrixType>> qr(matG);

    //
    // Compute SVD of `R = U S V^H` with high relative accuracy using the
    // one-sided Jacobi SVD algorithm. Only the singular values and left
    // singular vectors U are computed. The obtained singular values coincide
    // with coneigenvalues of input matrix
    //
    // Applying the one-sided Jacobi SVD to the matrix X = R^H is much faster
    // than applying the algorithm to R directly. This is because `R R^H` is
    // more diagonal than `R^H R`. Thus, `U` is computed as right singular
    // vectors of R^H.
    //
    MatrixType& matRt = m_mat_work1;
    matRt.setZero();
    matRt            = matG.template triangularView<Eigen::Upper>().adjoint();
    MatrixType& matU = m_mat_work2;
    const RealScalar tol_svd = Eigen::NumTraits<RealScalar>::epsilon() *
                               Eigen::numext::sqrt(RealScalar(n));
    one_sided_jacobi_svd(matRt, m_ceigvals, matU, tol_svd);

    //-------------------------------------------------------------------------
    //
    // The eigenvectors of A * conj(A) are given as
    //
    //   conj(X') = X * D * V * S^{-1/2}.
    //
    // However, direct evaluation of eigenvectors with this formula might be
    // inaccurate since D is ill-conditioned. The following formula are used
    // instead.
    //
    //   conj(X') = X * D * R.inv() * U * S^{1/2}
    //            = X * (D.inv() * R * D.inv()).inv() * (D.inv() * U *
    //            S^{1/2})
    //            = X * R1.inv() * X1
    //
    //-------------------------------------------------------------------------
    // Matrix R is stored on upper triangular part of G
    auto matR1 = matG.template triangularView<Eigen::Upper>();
    //
    // Compute R1 = D^(-1) * R * D^(-1). The upper triangular part of `matG` is
    // overwritten by R1.
    //
    for (Index j = 0; j < n; ++j)
    {
        const auto dj = vecD(j);
        for (Index i = 0; i <= j; ++i)
        {
            const auto di = vecD(i);
            matR1(i, j) = matR1(i, j) / (di * dj);
        }
    }
    //
    // Compute X1 = D^{-1} * U * S^{1/2}, and then solve R1 * Y1 = X1 in-place.
    // Matrix `matU` is overwritten by X1 and then overwritten by Y1.
    //
    MatrixType& matY1 = matU;
    for (Index j = 0; j < n; ++j)
    {
        const auto sj = Eigen::numext::sqrt(m_ceigvals(j));
        for (Index i = 0; i < n; ++i)
        {
            matY1(i, j) *= sj / vecD(i);
        }
    }

    matR1.solveInPlace(matY1);
    //
    // Compute con-eigenvectors U = conj(X) * conj(Y).
    //
    m_ceigvecs.noalias() = matX.conjugate() * matY1.conjugate();

    if (IsComplex)
    {
        //
        // Adjust phase factor of each con-eigenvectors, so that U^{T} * U = I
        //
        for (Index j = 0; j < n; ++j)
        {
            auto xj          = m_ceigvecs.col(j);
            const auto t     = (xj.transpose() * xj).value();
            const auto phase = t / std::abs(t);
            const auto scale = std::sqrt(Eigen::numext::conj(phase));
            xj *= scale;
        }
    }
}

} // namespace: mxpfit

#endif /* MXPFIT_SELF_ADJOINT_CONEIGENSOLVER_HPP */
<commit_msg>Add option to decide not to compute con-eigenvectors<commit_after>/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2017 Hidekazu Ikeno
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

///
/// \file self_adjoint_coneigensolver.hpp
///
#ifndef MXPFIT_SELF_ADJOINT_CONEIGENSOLVER_HPP
#define MXPFIT_SELF_ADJOINT_CONEIGENSOLVER_HPP

#include <cassert>
#include <type_traits>

#include <Eigen/Core>
#include <Eigen/QR>

#include <mxpfit/jacobi_svd.hpp>

namespace mxpfit
{
///
/// ### SelfAdjointConeigenSolver
///
/// \brief Compute con-eigenvalue decomposition of self-adjoint matrix having a
///        rank-revealing decomposition
///
/// \tparam T  Scalar type of matrix to be decomposed.
///
/// Let \f$A\f$ be an \f$n \times n\f$ self-adjoint matrix having a rank
/// revealing decomposition of the form
///
/// \f[ A = X D^2 X^{\ast},\f]
///
/// where \f$X\f$ is a \f$n \times k \, (n \geq k)\f$ matrix and \f$D\f$ is a
/// \f$k \times k\f$ diagonal matrix with non-negative entries. This class
/// computes a con-eigenvalue decomposition of matrix \f$A\f$ defined as
///
/// \f[
///   A = \overline{U} \Sigma U^{\ast}
/// \f]
///
/// where \f$U\f$ is a \f$n \times k\f$ matrix satisfying \f$U^{-1}=U^{T},\f$
/// and overline denotes the element-wise complex conjugate of a matrix.
/// \f$\Sigma=\mathrm{diag}(\sigma_{1},\dots,\sigma_{k})\f$ is a \f$k \times
/// k\f$ diagonal matrix with \f$\sigma_{1}\geq\sigma_{2}\geq \cdots \geq
/// \sigma_{k} > 0.\f$ The con-eigenvalue decomposition defined above is a
/// special case of singular value decomposition (SVD) \f$A=W\Sigma V^{\ast}\f$,
/// where \f$ W=\overline{U} \f$ and \f$V=U.\f$
///
/// The con-eigenvalue decomposition is computed in high-relative accuracy using
/// the algorithm developed by Haut and Beylkin. The algorithm can also be
/// regarded as modification of Demmel's algorithm for high accuracy SVD of a
/// matrix with rank-revealing decomposition. See the references listed below
/// for the details.
///
///
/// #### References
///
/// 1. T. S. Haut and G. Beylkin, "FAST AND ACCURATE CON-EIGENVALUE
/// ALGORITHM
///    FOR OPTIMAL RATIONAL APPROXIMATIONS", SIAM J. Matrix Anal. Appl.
///    **33** (2012) 1101-1125. [DOI: https://doi.org/10.1137/110821901]
/// 2. J. Demmel, "ACCURATE SINGULAR VALUE DECOMPOSITIONS OF STRUCTURED
///    MATRICES", SIAM J. Matrix Anal. Appl. **21** (1999) 562-580.
///    [DOI: https://doi.org/10.1137/S0895479897328716]
/// 3. J. Demmel, M. Gu, S. Eisenstat, I. Slapnicar, K. Veselic, and Z. Drmac,
///    "ACCURATE SINGULAR VALUE DECOMPOSITIONS OF STRUCTURED MATRICES", SIAM J.
///    Linear Algebra Appl. **299** (1999) 21-80. [DOI:
///    https://doi.org/10.1016/S0024-3795(99)00134-2]
///

enum DecompositionOption
{
    ConeigenvaluesOnly,
    ComputeConeigenvectors
};

template <typename T>
class SelfAdjointConeigenSolver
{
public:
    using Index         = Eigen::Index;
    using Scalar        = T;
    using RealScalar    = typename Eigen::NumTraits<Scalar>::Real;
    using ComplexScalar = std::complex<RealScalar>;

    using MatrixType = Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic>;
    using VectorType = Eigen::Matrix<Scalar, Eigen::Dynamic, 1>;
    using RealVectorType = Eigen::Matrix<RealScalar, Eigen::Dynamic, 1>;

    using ConeigenvalueType = Eigen::Matrix<RealScalar, Eigen::Dynamic, 1>;

protected:
    enum
    {
        IsComplex  = Eigen::NumTraits<Scalar>::IsComplex,
        PacketSize = Eigen::internal::packet_traits<Scalar>::size,
        Alignment  = Eigen::internal::traits<MatrixType>::Alignment,
        // Alignment  = Eigen::internal::unpacket_traits<PacketType>::alignment
    };

    using MappedMatrix = Eigen::Map<MatrixType, Alignment>;
    using PacketType   = typename Eigen::internal::packet_traits<Scalar>::type;

    MatrixType m_ceigvecs;     // m x n (m >= n)
    RealVectorType m_ceigvals; // n
    MatrixType m_mat_work1;    // n x n
    MatrixType m_mat_work2;    // n x n

public:
    SelfAdjointConeigenSolver()                                 = default;
    SelfAdjointConeigenSolver(const SelfAdjointConeigenSolver&) = default;

    explicit SelfAdjointConeigenSolver(Index size, Index rank)
        : m_ceigvecs(size, rank),
          m_ceigvals(rank),
          m_mat_work1(rank, rank),
          m_mat_work2(rank, rank)
    {
        assert(size >= rank);
    }

    ~SelfAdjointConeigenSolver() = default;

    template <typename InputMatrix, typename InputVector>
    void compute(const Eigen::MatrixBase<InputMatrix>& matX,
                 const Eigen::MatrixBase<InputVector>& vecD,
                 DecompositionOption option = ComputeConeigenvectors);

    const MatrixType& coneigenvectors() const
    {
        return m_ceigvecs;
    }

    const RealVectorType& coneigenvalues() const
    {
        return m_ceigvals;
    }

protected:
    void resize(Index m, Index n)
    {
        m_ceigvecs.resize(m, n);
        m_ceigvals.resize(n);
        m_mat_work1.resize(n, n);
        m_mat_work2.resize(n, n);
    }
};

template <typename T>
template <typename InputMatrix, typename InputVector>
void SelfAdjointConeigenSolver<T>::compute(
    const Eigen::MatrixBase<InputMatrix>& matX,
    const Eigen::MatrixBase<InputVector>& vecD, DecompositionOption option)
{
    EIGEN_STATIC_ASSERT_VECTOR_ONLY(InputVector);

    assert(matX.rows() >= matX.cols());
    assert(vecD.size() == matX.cols());

    const Index m = matX.rows();
    const Index n = matX.cols();
    resize(m, n);

    MappedMatrix matG(m_ceigvecs.data(), n, n);

    //
    // Form G = D * (X.st() * X) * D
    //
    matG.noalias() = matX.transpose() * matX;
    for (Index j = 0; j < n; ++j)
    {
        for (Index i = 0; i < n; ++i)
        {
            matG(i, j) *= vecD(i) * vecD(j);
        }
    }
    //
    // Compute G = Q * R by Householder QR factorization. G is overwritten by QR
    // factors.
    //
    Eigen::HouseholderQR<Eigen::Ref<MatrixType>> qr(matG);

    //
    // Compute SVD of `R = U S V^H` with high relative accuracy using the
    // one-sided Jacobi SVD algorithm. Only the singular values and left
    // singular vectors U are computed. The obtained singular values coincide
    // with coneigenvalues of input matrix
    //
    // Applying the one-sided Jacobi SVD to the matrix X = R^H is much faster
    // than applying the algorithm to R directly. This is because `R R^H` is
    // more diagonal than `R^H R`. Thus, `U` is computed as right singular
    // vectors of R^H.
    //
    MatrixType& matRt = m_mat_work1;
    matRt.setZero();
    matRt            = matG.template triangularView<Eigen::Upper>().adjoint();
    MatrixType& matU = m_mat_work2;
    const RealScalar tol_svd = Eigen::NumTraits<RealScalar>::epsilon() *
                               Eigen::numext::sqrt(RealScalar(n));
    one_sided_jacobi_svd(matRt, m_ceigvals, matU, tol_svd);

    //
    // Quick return if no con-eigenvector is required.
    //
    if (option == ConeigenvaluesOnly)
    {
        return;
    }

    //-------------------------------------------------------------------------
    //
    // The eigenvectors of A * conj(A) are given as
    //
    //   conj(X') = X * D * V * S^{-1/2}.
    //
    // However, direct evaluation of eigenvectors with this formula might be
    // inaccurate since D is ill-conditioned. The following formula are used
    // instead.
    //
    //   conj(X') = X * D * R.inv() * U * S^{1/2}
    //            = X * (D.inv() * R * D.inv()).inv() * (D.inv() * U *
    //            S^{1/2})
    //            = X * R1.inv() * X1
    //
    //-------------------------------------------------------------------------
    // Matrix R is stored on upper triangular part of G
    auto matR1 = matG.template triangularView<Eigen::Upper>();
    //
    // Compute R1 = D^(-1) * R * D^(-1). The upper triangular part of `matG` is
    // overwritten by R1.
    //
    for (Index j = 0; j < n; ++j)
    {
        const auto dj = vecD(j);
        for (Index i = 0; i <= j; ++i)
        {
            const auto di = vecD(i);
            matR1(i, j) = matR1(i, j) / (di * dj);
        }
    }
    //
    // Compute X1 = D^{-1} * U * S^{1/2}, and then solve R1 * Y1 = X1 in-place.
    // Matrix `matU` is overwritten by X1 and then overwritten by Y1.
    //
    MatrixType& matY1 = matU;
    for (Index j = 0; j < n; ++j)
    {
        const auto sj = Eigen::numext::sqrt(m_ceigvals(j));
        for (Index i = 0; i < n; ++i)
        {
            matY1(i, j) *= sj / vecD(i);
        }
    }

    matR1.solveInPlace(matY1);
    //
    // Compute con-eigenvectors U = conj(X) * conj(Y).
    //
    m_ceigvecs.noalias() = matX.conjugate() * matY1.conjugate();

    if (IsComplex)
    {
        //
        // Adjust phase factor of each con-eigenvectors, so that U^{T} * U = I
        //
        for (Index j = 0; j < n; ++j)
        {
            auto xj          = m_ceigvecs.col(j);
            const auto t     = (xj.transpose() * xj).value();
            const auto phase = t / std::abs(t);
            const auto scale = std::sqrt(Eigen::numext::conj(phase));
            xj *= scale;
        }
    }
}

} // namespace: mxpfit

#endif /* MXPFIT_SELF_ADJOINT_CONEIGENSOLVER_HPP */
<|endoftext|>


<commit_before>// Copyright (c) 2013, German Neuroinformatics Node (G-Node)
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted under the terms of the BSD License. See
// LICENSE file in the root of the Project.

#include <nix/hdf5/DimensionHDF5.hpp>

using namespace std;

namespace nix {
namespace hdf5 {

DimensionType dimensionTypeFromStr(const string &str) {
    if (str == "set") {
        return DimensionType::Set;
    } else if (str == "range") {
        return DimensionType::Range;
    } else if (str == "sample") {
        return DimensionType::Sample;
    } else {
        throw runtime_error("Not a valid dimension name");
    }
}

std::string dimensionTypeToStr(DimensionType dim) {

    //The way this switch + string.empty() checking is
    // done here might seem a bit convoluted, but the
    // idea behind it is:
    // a) have no default case in the switch to get a
    //    compile warning in case a new element is
    //    added to the enum
    // b) still be safe and throw an exception in case
    //    not all enum cases are handled properly

    std::string dimType;

    switch (dim) {
        case DimensionType::Set:
            dimType = "set";
        case DimensionType::Range:
            dimType = "range";
        case DimensionType::Sample:
            dimType = "sample";
    }

    if (dimType.empty()) {
        throw runtime_error("Not a valid dimension type");
    }

    return dimType;

}

// Implementation of Dimension

DimensionHDF5::DimensionHDF5(Group group, size_t id)
    : group(group), dim_id(id)
{
}

DimensionHDF5::DimensionHDF5(const DimensionHDF5 &other)
    : group(other.group), dim_id(other.dim_id)
{
}

void DimensionHDF5::setType() {
    group.setAttr("dimension_type", dimensionTypeToStr(dimensionType()));
}

void DimensionHDF5::swap(DimensionHDF5 &other) {
    using std::swap;
    swap(group, other.group);
    swap(dim_id, other.dim_id);
}

bool DimensionHDF5::operator==(const DimensionHDF5 &other) const {
    return group == other.group;
}

bool DimensionHDF5::operator!=(const DimensionHDF5 &other) const {
    return !(*this == other);
}

DimensionHDF5::~DimensionHDF5() {}

//--------------------------------------------------------------
// Implementation of SampledDimension
//--------------------------------------------------------------

SampledDimensionHDF5::SampledDimensionHDF5(Group group, size_t id)
    : DimensionHDF5(group, id)
{
    setType();
}

SampledDimensionHDF5::SampledDimensionHDF5(const SampledDimensionHDF5 &other)
    : DimensionHDF5(other.group, other.dim_id)
{
    setType();
}

DimensionType SampledDimensionHDF5::dimensionType() const {
    return DimensionType::Sample;
}

string SampledDimensionHDF5::label() const {
    string label;
    group.getAttr("label", label);
    return label;
}

void SampledDimensionHDF5::label(const string &label) {
    group.setAttr("label", label);
}

string SampledDimensionHDF5::unit() const {
    string unit;
    group.getAttr("unit", unit);
    return unit;
}

void SampledDimensionHDF5::unit(const string &unit) {
    group.setAttr("unit", unit);
}

double SampledDimensionHDF5::samplingInterval() const {
    double sampling_interval = 1;
    group.getAttr("sampling_interval", sampling_interval);
    return sampling_interval;
}

void SampledDimensionHDF5::samplingInterval(double sampling_interval) {
    group.setAttr("sampling_interval", sampling_interval);
}

boost::optional<double> SampledDimensionHDF5::offset() const {
    boost::optional<double> ret;
    double offset = 0;
    if(group.getAttr("offset", offset)){
        ret = offset;
    }
    return offset;
}

void SampledDimensionHDF5::offset(double offset) {
    group.setAttr("offset", offset);
}

void SampledDimensionHDF5::offset(const none_t t) {
    if(group.hasAttr("offset")) {
        group.removeAttr("offset");
    }
}

SampledDimensionHDF5& SampledDimensionHDF5::operator=(const SampledDimensionHDF5 &other) {
    SampledDimensionHDF5 tmp(other);
    swap(tmp);
    return *this;
}

SampledDimensionHDF5::~SampledDimensionHDF5() {}

//--------------------------------------------------------------
// Implementation of SetDimensionHDF5
//--------------------------------------------------------------

SetDimensionHDF5::SetDimensionHDF5(Group group, size_t id)
    : DimensionHDF5(group, id)
{
    setType();
}

SetDimensionHDF5::SetDimensionHDF5(const SetDimensionHDF5 &other)
    : DimensionHDF5(other.group, other.dim_id)
{
    setType();
}

DimensionType SetDimensionHDF5::dimensionType() const {
    return DimensionType::Set;
}

vector<string> SetDimensionHDF5::labels() const {
    vector<string> labels;

    group.getData("labels", labels);
    return labels;
}

void SetDimensionHDF5::labels(const vector<string> &labels) {
   group.setData("labels", labels);
}

void SetDimensionHDF5::labels(const none_t t) {
    if(group.hasAttr("offset")) {
        group.removeAttr("offset");
    }
}

SetDimensionHDF5& SetDimensionHDF5::operator=(const SetDimensionHDF5 &other) {
    SetDimensionHDF5 tmp(other);
    swap(tmp);
    return *this;
}

SetDimensionHDF5::~SetDimensionHDF5() {}

//--------------------------------------------------------------
// Implementation of RangeDimensionHDF5
//--------------------------------------------------------------

RangeDimensionHDF5::RangeDimensionHDF5(Group group, size_t id)
    : DimensionHDF5(group, id)
{
    setType();
}

RangeDimensionHDF5::RangeDimensionHDF5(const RangeDimensionHDF5 &other)
    : DimensionHDF5(other.group, other.dim_id)
{
    setType();
}

DimensionType RangeDimensionHDF5::dimensionType() const {
    return DimensionType::Range;
}

string RangeDimensionHDF5::label() const {
    string label;
    group.getAttr("label", label);
    return label;
}

void RangeDimensionHDF5::label(const string &label) {
    group.setAttr("label", label);
}

string RangeDimensionHDF5::unit() const {
    string unit;
    group.getAttr("unit", unit);
    return unit;
}

void RangeDimensionHDF5::unit(const string &unit) {
    group.setAttr("unit", unit);
}

RangeDimensionHDF5& RangeDimensionHDF5::operator=(const RangeDimensionHDF5 &other) {
    RangeDimensionHDF5 tmp(other);
    swap(tmp);
    return *this;
}

vector<double> RangeDimensionHDF5::tics() const {
    vector<double> tics;
    group.getData("tics", tics);
    return tics;
}

void RangeDimensionHDF5::tics(const vector<double> &tics) {
    group.setData("tics", tics);
}

RangeDimensionHDF5::~RangeDimensionHDF5() {}

} // namespace hdf5
} // namespace nix

<commit_msg>DimensionHDF5: Fix broken switch (missing break)<commit_after>// Copyright (c) 2013, German Neuroinformatics Node (G-Node)
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted under the terms of the BSD License. See
// LICENSE file in the root of the Project.

#include <nix/hdf5/DimensionHDF5.hpp>

using namespace std;

namespace nix {
namespace hdf5 {

DimensionType dimensionTypeFromStr(const string &str) {
    if (str == "set") {
        return DimensionType::Set;
    } else if (str == "range") {
        return DimensionType::Range;
    } else if (str == "sample") {
        return DimensionType::Sample;
    } else {
        throw runtime_error("Not a valid dimension name");
    }
}

std::string dimensionTypeToStr(DimensionType dim) {

    //The way this switch + string.empty() checking is
    // done here might seem a bit convoluted, but the
    // idea behind it is:
    // a) have no default case in the switch to get a
    //    compile warning in case a new element is
    //    added to the enum
    // b) still be safe and throw an exception in case
    //    not all enum cases are handled properly

    std::string dimType;

    switch (dim) {
        case DimensionType::Set:
            dimType = "set";
            break;
        case DimensionType::Range:
            dimType = "range";
            break;
        case DimensionType::Sample:
            dimType = "sample";
            break;
    }

    if (dimType.empty()) {
        throw runtime_error("Not a valid dimension type");
    }

    return dimType;

}

// Implementation of Dimension

DimensionHDF5::DimensionHDF5(Group group, size_t id)
    : group(group), dim_id(id)
{
}

DimensionHDF5::DimensionHDF5(const DimensionHDF5 &other)
    : group(other.group), dim_id(other.dim_id)
{
}

void DimensionHDF5::setType() {
    group.setAttr("dimension_type", dimensionTypeToStr(dimensionType()));
}

void DimensionHDF5::swap(DimensionHDF5 &other) {
    using std::swap;
    swap(group, other.group);
    swap(dim_id, other.dim_id);
}

bool DimensionHDF5::operator==(const DimensionHDF5 &other) const {
    return group == other.group;
}

bool DimensionHDF5::operator!=(const DimensionHDF5 &other) const {
    return !(*this == other);
}

DimensionHDF5::~DimensionHDF5() {}

//--------------------------------------------------------------
// Implementation of SampledDimension
//--------------------------------------------------------------

SampledDimensionHDF5::SampledDimensionHDF5(Group group, size_t id)
    : DimensionHDF5(group, id)
{
    setType();
}

SampledDimensionHDF5::SampledDimensionHDF5(const SampledDimensionHDF5 &other)
    : DimensionHDF5(other.group, other.dim_id)
{
    setType();
}

DimensionType SampledDimensionHDF5::dimensionType() const {
    return DimensionType::Sample;
}

string SampledDimensionHDF5::label() const {
    string label;
    group.getAttr("label", label);
    return label;
}

void SampledDimensionHDF5::label(const string &label) {
    group.setAttr("label", label);
}

string SampledDimensionHDF5::unit() const {
    string unit;
    group.getAttr("unit", unit);
    return unit;
}

void SampledDimensionHDF5::unit(const string &unit) {
    group.setAttr("unit", unit);
}

double SampledDimensionHDF5::samplingInterval() const {
    double sampling_interval = 1;
    group.getAttr("sampling_interval", sampling_interval);
    return sampling_interval;
}

void SampledDimensionHDF5::samplingInterval(double sampling_interval) {
    group.setAttr("sampling_interval", sampling_interval);
}

boost::optional<double> SampledDimensionHDF5::offset() const {
    boost::optional<double> ret;
    double offset = 0;
    if(group.getAttr("offset", offset)){
        ret = offset;
    }
    return offset;
}

void SampledDimensionHDF5::offset(double offset) {
    group.setAttr("offset", offset);
}

void SampledDimensionHDF5::offset(const none_t t) {
    if(group.hasAttr("offset")) {
        group.removeAttr("offset");
    }
}

SampledDimensionHDF5& SampledDimensionHDF5::operator=(const SampledDimensionHDF5 &other) {
    SampledDimensionHDF5 tmp(other);
    swap(tmp);
    return *this;
}

SampledDimensionHDF5::~SampledDimensionHDF5() {}

//--------------------------------------------------------------
// Implementation of SetDimensionHDF5
//--------------------------------------------------------------

SetDimensionHDF5::SetDimensionHDF5(Group group, size_t id)
    : DimensionHDF5(group, id)
{
    setType();
}

SetDimensionHDF5::SetDimensionHDF5(const SetDimensionHDF5 &other)
    : DimensionHDF5(other.group, other.dim_id)
{
    setType();
}

DimensionType SetDimensionHDF5::dimensionType() const {
    return DimensionType::Set;
}

vector<string> SetDimensionHDF5::labels() const {
    vector<string> labels;

    group.getData("labels", labels);
    return labels;
}

void SetDimensionHDF5::labels(const vector<string> &labels) {
   group.setData("labels", labels);
}

void SetDimensionHDF5::labels(const none_t t) {
    if(group.hasAttr("offset")) {
        group.removeAttr("offset");
    }
}

SetDimensionHDF5& SetDimensionHDF5::operator=(const SetDimensionHDF5 &other) {
    SetDimensionHDF5 tmp(other);
    swap(tmp);
    return *this;
}

SetDimensionHDF5::~SetDimensionHDF5() {}

//--------------------------------------------------------------
// Implementation of RangeDimensionHDF5
//--------------------------------------------------------------

RangeDimensionHDF5::RangeDimensionHDF5(Group group, size_t id)
    : DimensionHDF5(group, id)
{
    setType();
}

RangeDimensionHDF5::RangeDimensionHDF5(const RangeDimensionHDF5 &other)
    : DimensionHDF5(other.group, other.dim_id)
{
    setType();
}

DimensionType RangeDimensionHDF5::dimensionType() const {
    return DimensionType::Range;
}

string RangeDimensionHDF5::label() const {
    string label;
    group.getAttr("label", label);
    return label;
}

void RangeDimensionHDF5::label(const string &label) {
    group.setAttr("label", label);
}

string RangeDimensionHDF5::unit() const {
    string unit;
    group.getAttr("unit", unit);
    return unit;
}

void RangeDimensionHDF5::unit(const string &unit) {
    group.setAttr("unit", unit);
}

RangeDimensionHDF5& RangeDimensionHDF5::operator=(const RangeDimensionHDF5 &other) {
    RangeDimensionHDF5 tmp(other);
    swap(tmp);
    return *this;
}

vector<double> RangeDimensionHDF5::tics() const {
    vector<double> tics;
    group.getData("tics", tics);
    return tics;
}

void RangeDimensionHDF5::tics(const vector<double> &tics) {
    group.setData("tics", tics);
}

RangeDimensionHDF5::~RangeDimensionHDF5() {}

} // namespace hdf5
} // namespace nix

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: module.cxx,v $
 *
 *  $Revision: 1.12 $
 *
 *  last change: $Author: obo $ $Date: 2004-11-19 11:31:40 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library 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 library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef GCC
#pragma hdrstop
#endif

#include <stdio.h>
#include <tools/rcid.h>

#include <cstdarg>
#include "module.hxx"
#include "app.hxx"
#include "arrdecl.hxx"
#include "sfxresid.hxx"
#include "msgpool.hxx"
#include "tbxctrl.hxx"
#include "stbitem.hxx"
#include "mnuitem.hxx"
#include "childwin.hxx"
#include "mnumgr.hxx"
#include "docfac.hxx"
#include "accmgr.hxx"
#include "objface.hxx"
#include "viewfrm.hxx"

#define SfxModule
#include "sfxslots.hxx"

static SfxModuleArr_Impl* pModules=0;

class SfxModule_Impl
{
public:

    SfxSlotPool*                pSlotPool;
    SfxTbxCtrlFactArr_Impl*     pTbxCtrlFac;
    SfxStbCtrlFactArr_Impl*     pStbCtrlFac;
    SfxMenuCtrlFactArr_Impl*    pMenuCtrlFac;
    SfxChildWinFactArr_Impl*    pFactArr;
    ImageList*                  pImgListSmall;
    ImageList*                  pImgListBig;
    ImageList*                  pImgListHiSmall;
    ImageList*                  pImgListHiBig;

                                SfxModule_Impl();
                                ~SfxModule_Impl();
    ImageList*                  GetImageList( ResMgr*, BOOL, BOOL bHiContrast = FALSE );
};

SfxModule_Impl::SfxModule_Impl()
 : pSlotPool(0)
{
}

SfxModule_Impl::~SfxModule_Impl()
{
    delete pSlotPool;
    delete pTbxCtrlFac;
    delete pStbCtrlFac;
    delete pMenuCtrlFac;
    delete pFactArr;
    delete pImgListSmall;
    delete pImgListBig;
    delete pImgListHiSmall;
    delete pImgListHiBig;
}

ImageList* SfxModule_Impl::GetImageList( ResMgr* pResMgr, BOOL bBig, BOOL bHiContrast )
{
    ImageList*& rpList = bBig ? ( bHiContrast ? pImgListHiBig: pImgListBig ) :
                                ( bHiContrast ? pImgListHiSmall : pImgListSmall );
    if ( !rpList )
    {
        ResId aResId( bBig ? ( bHiContrast ? RID_DEFAULTIMAGELIST_LCH : RID_DEFAULTIMAGELIST_LC ) :
                             ( bHiContrast ? RID_DEFAULTIMAGELIST_SCH : RID_DEFAULTIMAGELIST_SC ), pResMgr );
        aResId.SetRT( RSC_IMAGELIST );

        DBG_ASSERT( pResMgr->IsAvailable(aResId), "No default ImageList!" );

        if ( pResMgr->IsAvailable(aResId) )
            rpList = new ImageList( aResId );
        else
            rpList = new ImageList();
    }

    return rpList; }

TYPEINIT1(SfxModule, SfxShell);

//=========================================================================

SFX_IMPL_INTERFACE(SfxModule,SfxShell,SfxResId(0))
{
}

//====================================================================
/*

ModalDialog* SfxModule::CreateAboutDialog()
{
    return SFX_APP()->CreateAboutDialog();
}

BOOL SfxModule::QueryUnload()
{
    return TRUE;
}

SfxModule* SfxModule::Load()
{
    return 0;
}

void SfxModule::Free()
{
}
*/

//====================================================================

ResMgr* SfxModule::GetResMgr()
{
    return pResMgr;
}

//====================================================================
/*
SfxModule::SfxModule( ResMgr* pMgrP, BOOL bDummyP,
                      SfxObjectFactory* pFactoryP )
    : pResMgr( pMgrP ), bDummy( bDummyP ), pImpl(0L)
{
    Construct_Impl();
    if ( pFactoryP )
        pFactoryP->SetModule_Impl( this );
}
*/
SfxModule::SfxModule( ResMgr* pMgrP, BOOL bDummyP,
                      SfxObjectFactory* pFactoryP, ... )
    : pResMgr( pMgrP ), bDummy( bDummyP ), pImpl(0L)
{
    Construct_Impl();
    va_list pVarArgs;
    va_start( pVarArgs, pFactoryP );
    for ( SfxObjectFactory *pArg = pFactoryP; pArg;
         pArg = va_arg( pVarArgs, SfxObjectFactory* ) )
        pArg->SetModule_Impl( this );
    va_end(pVarArgs);
}

void SfxModule::Construct_Impl()
{
    if( !bDummy )
    {
        SfxApplication *pApp = SFX_APP();
        SfxModuleArr_Impl& rArr = GetModules_Impl();
        SfxModule* pPtr = (SfxModule*)this;
        rArr.C40_INSERT( SfxModule, pPtr, rArr.Count() );
        pImpl = new SfxModule_Impl;
        pImpl->pSlotPool = new SfxSlotPool( &pApp->GetAppSlotPool_Impl(), pResMgr );

        pImpl->pTbxCtrlFac=0;
        pImpl->pStbCtrlFac=0;
        pImpl->pMenuCtrlFac=0;
        pImpl->pFactArr=0;
        pImpl->pImgListSmall=0;
        pImpl->pImgListBig=0;
        pImpl->pImgListHiSmall=0;
        pImpl->pImgListHiBig=0;

        SetPool( &pApp->GetPool() );
    }
}

//====================================================================

SfxModule::~SfxModule()
{
    if( !bDummy )
    {
        if ( SFX_APP()->Get_Impl() )
        {
            // Das Modul wird noch vor dem DeInitialize zerst"ort, also auis dem Array entfernen
            SfxModuleArr_Impl& rArr = GetModules_Impl();
            for( USHORT nPos = rArr.Count(); nPos--; )
            {
                if( rArr[ nPos ] == this )
                {
                    rArr.Remove( nPos );
                    break;
                }
            }

            delete pImpl;
        }

        delete pResMgr;
    }
}

//-------------------------------------------------------------------------

SfxSlotPool* SfxModule::GetSlotPool() const
{
    return pImpl->pSlotPool;
}

//-------------------------------------------------------------------------

void SfxModule::RegisterChildWindow(SfxChildWinFactory *pFact)
{
    DBG_ASSERT( pImpl, "Kein echtes Modul!" );

    if (!pImpl->pFactArr)
        pImpl->pFactArr = new SfxChildWinFactArr_Impl;

//#ifdef DBG_UTIL
    for (USHORT nFactory=0; nFactory<pImpl->pFactArr->Count(); ++nFactory)
    {
        if (pFact->nId ==  (*pImpl->pFactArr)[nFactory]->nId)
        {
            pImpl->pFactArr->Remove( nFactory );
            DBG_ERROR("ChildWindow mehrfach registriert!");
            return;
        }
    }
//#endif

    pImpl->pFactArr->C40_INSERT(
        SfxChildWinFactory, pFact, pImpl->pFactArr->Count() );
}

//-------------------------------------------------------------------------

void SfxModule::RegisterChildWindowContext( USHORT nId,
        SfxChildWinContextFactory *pFact)
{
    DBG_ASSERT( pImpl, "Kein echtes Modul!" );

    USHORT nCount = pImpl->pFactArr->Count();
    for (USHORT nFactory=0; nFactory<nCount; ++nFactory)
    {
        SfxChildWinFactory *pF = (*pImpl->pFactArr)[nFactory];
        if ( nId == pF->nId )
        {
            if ( !pF->pArr )
                pF->pArr = new SfxChildWinContextArr_Impl;
            pF->pArr->C40_INSERT( SfxChildWinContextFactory, pFact, pF->pArr->Count() );
            return;
        }
    }

    DBG_ERROR( "Kein ChildWindow fuer diesen Context!" );
}

//-------------------------------------------------------------------------

void SfxModule::RegisterToolBoxControl( SfxTbxCtrlFactory *pFact )
{
    if (!pImpl->pTbxCtrlFac)
        pImpl->pTbxCtrlFac = new SfxTbxCtrlFactArr_Impl;

#ifdef DBG_UTIL
    for ( USHORT n=0; n<pImpl->pTbxCtrlFac->Count(); n++ )
    {
        SfxTbxCtrlFactory *pF = (*pImpl->pTbxCtrlFac)[n];
        if ( pF->nTypeId && pF->nTypeId == pFact->nTypeId &&
            (pF->nSlotId == pFact->nSlotId || pF->nSlotId == 0) )
        {
            DBG_WARNING("TbxController-Registrierung ist nicht eindeutig!");
        }
    }
#endif

    pImpl->pTbxCtrlFac->C40_INSERT( SfxTbxCtrlFactory, pFact, pImpl->pTbxCtrlFac->Count() );
}

//-------------------------------------------------------------------------

void SfxModule::RegisterStatusBarControl( SfxStbCtrlFactory *pFact )
{
    if (!pImpl->pStbCtrlFac)
        pImpl->pStbCtrlFac = new SfxStbCtrlFactArr_Impl;

#ifdef DBG_UTIL
    for ( USHORT n=0; n<pImpl->pStbCtrlFac->Count(); n++ )
    {
        SfxStbCtrlFactory *pF = (*pImpl->pStbCtrlFac)[n];
        if ( pF->nTypeId && pF->nTypeId == pFact->nTypeId &&
            (pF->nSlotId == pFact->nSlotId || pF->nSlotId == 0) )
        {
            DBG_WARNING("StbController-Registrierung ist nicht eindeutig!");
        }
    }
#endif

    pImpl->pStbCtrlFac->C40_INSERT( SfxStbCtrlFactory, pFact, pImpl->pStbCtrlFac->Count() );
}

//-------------------------------------------------------------------------

void SfxModule::RegisterMenuControl( SfxMenuCtrlFactory *pFact )
{
    if (!pImpl->pMenuCtrlFac)
        pImpl->pMenuCtrlFac = new SfxMenuCtrlFactArr_Impl;

#ifdef DBG_UTIL
    for ( USHORT n=0; n<pImpl->pMenuCtrlFac->Count(); n++ )
    {
        SfxMenuCtrlFactory *pF = (*pImpl->pMenuCtrlFac)[n];
        if ( pF->nTypeId && pF->nTypeId == pFact->nTypeId &&
            (pF->nSlotId == pFact->nSlotId || pF->nSlotId == 0) )
        {
            DBG_WARNING("MenuController-Registrierung ist nicht eindeutig!");
        }
    }
#endif

    pImpl->pMenuCtrlFac->C40_INSERT( SfxMenuCtrlFactory, pFact, pImpl->pMenuCtrlFac->Count() );
}

//-------------------------------------------------------------------------

SfxTbxCtrlFactArr_Impl*  SfxModule::GetTbxCtrlFactories_Impl() const
{
    return pImpl->pTbxCtrlFac;
}

//-------------------------------------------------------------------------

SfxStbCtrlFactArr_Impl*  SfxModule::GetStbCtrlFactories_Impl() const
{
    return pImpl->pStbCtrlFac;
}

//-------------------------------------------------------------------------

SfxMenuCtrlFactArr_Impl* SfxModule::GetMenuCtrlFactories_Impl() const
{
    return pImpl->pMenuCtrlFac;
}

//-------------------------------------------------------------------------

SfxChildWinFactArr_Impl* SfxModule::GetChildWinFactories_Impl() const
{
    return pImpl->pFactArr;
}

ImageList* SfxModule::GetImageList_Impl( BOOL bBig )
{
    return pImpl->GetImageList( pResMgr, bBig, FALSE );
}

ImageList* SfxModule::GetImageList_Impl( BOOL bBig, BOOL bHiContrast )
{
    return pImpl->GetImageList( pResMgr, bBig, bHiContrast );
}

SfxTabPage* SfxModule::CreateTabPage( USHORT nId, Window* pParent, const SfxItemSet& rSet )
{
    return NULL;
}

SfxModuleArr_Impl& SfxModule::GetModules_Impl()
{
    if( !pModules )
        pModules = new SfxModuleArr_Impl;
    return *pModules;
};

void SfxModule::DestroyModules_Impl()
{
    if ( pModules )
    {
        SfxModuleArr_Impl& rModules = *pModules;
        for( USHORT nPos = rModules.Count(); nPos--; )
    {
        SfxModule* pMod = rModules.GetObject(nPos);
        delete pMod;
    }
    }
}

void SfxModule::Invalidate( USHORT nId )
{
    for( SfxViewFrame* pFrame = SfxViewFrame::GetFirst(); pFrame; pFrame = SfxViewFrame::GetNext( *pFrame ) )
        if ( pFrame->GetObjectShell()->GetModule() == this )
            Invalidate_Impl( pFrame->GetBindings(), nId );
}

BOOL SfxModule::IsActive()
{
    SfxViewFrame* pFrame = SfxViewFrame::Current();
    if ( pFrame && pFrame->GetObjectShell()->GetFactory().GetModule() == this )
        return TRUE;
    return FALSE;
}

<commit_msg>INTEGRATION: CWS fwkbugfix04 (1.12.6); FILE MERGED 2004/12/06 17:53:03 mba 1.12.6.1: #i38334#: get rid of all code based on SfxConfigManager<commit_after>/*************************************************************************
 *
 *  $RCSfile: module.cxx,v $
 *
 *  $Revision: 1.13 $
 *
 *  last change: $Author: kz $ $Date: 2005-01-18 16:04:01 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library 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 library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef GCC
#pragma hdrstop
#endif

#include <stdio.h>
#include <tools/rcid.h>

#include <cstdarg>
#include "module.hxx"
#include "app.hxx"
#include "arrdecl.hxx"
#include "sfxresid.hxx"
#include "msgpool.hxx"
#include "tbxctrl.hxx"
#include "stbitem.hxx"
#include "mnuitem.hxx"
#include "childwin.hxx"
#include "mnumgr.hxx"
#include "docfac.hxx"
#include "objface.hxx"
#include "viewfrm.hxx"

#define SfxModule
#include "sfxslots.hxx"

static SfxModuleArr_Impl* pModules=0;

class SfxModule_Impl
{
public:

    SfxSlotPool*                pSlotPool;
    SfxTbxCtrlFactArr_Impl*     pTbxCtrlFac;
    SfxStbCtrlFactArr_Impl*     pStbCtrlFac;
    SfxMenuCtrlFactArr_Impl*    pMenuCtrlFac;
    SfxChildWinFactArr_Impl*    pFactArr;
    ImageList*                  pImgListSmall;
    ImageList*                  pImgListBig;
    ImageList*                  pImgListHiSmall;
    ImageList*                  pImgListHiBig;

                                SfxModule_Impl();
                                ~SfxModule_Impl();
    ImageList*                  GetImageList( ResMgr*, BOOL, BOOL bHiContrast = FALSE );
};

SfxModule_Impl::SfxModule_Impl()
 : pSlotPool(0)
{
}

SfxModule_Impl::~SfxModule_Impl()
{
    delete pSlotPool;
    delete pTbxCtrlFac;
    delete pStbCtrlFac;
    delete pMenuCtrlFac;
    delete pFactArr;
    delete pImgListSmall;
    delete pImgListBig;
    delete pImgListHiSmall;
    delete pImgListHiBig;
}

ImageList* SfxModule_Impl::GetImageList( ResMgr* pResMgr, BOOL bBig, BOOL bHiContrast )
{
    ImageList*& rpList = bBig ? ( bHiContrast ? pImgListHiBig: pImgListBig ) :
                                ( bHiContrast ? pImgListHiSmall : pImgListSmall );
    if ( !rpList )
    {
        ResId aResId( bBig ? ( bHiContrast ? RID_DEFAULTIMAGELIST_LCH : RID_DEFAULTIMAGELIST_LC ) :
                             ( bHiContrast ? RID_DEFAULTIMAGELIST_SCH : RID_DEFAULTIMAGELIST_SC ), pResMgr );
        aResId.SetRT( RSC_IMAGELIST );

        DBG_ASSERT( pResMgr->IsAvailable(aResId), "No default ImageList!" );

        if ( pResMgr->IsAvailable(aResId) )
            rpList = new ImageList( aResId );
        else
            rpList = new ImageList();
    }

    return rpList; }

TYPEINIT1(SfxModule, SfxShell);

//=========================================================================

SFX_IMPL_INTERFACE(SfxModule,SfxShell,SfxResId(0))
{
}

//====================================================================
/*

ModalDialog* SfxModule::CreateAboutDialog()
{
    return SFX_APP()->CreateAboutDialog();
}

BOOL SfxModule::QueryUnload()
{
    return TRUE;
}

SfxModule* SfxModule::Load()
{
    return 0;
}

void SfxModule::Free()
{
}
*/

//====================================================================

ResMgr* SfxModule::GetResMgr()
{
    return pResMgr;
}

//====================================================================
/*
SfxModule::SfxModule( ResMgr* pMgrP, BOOL bDummyP,
                      SfxObjectFactory* pFactoryP )
    : pResMgr( pMgrP ), bDummy( bDummyP ), pImpl(0L)
{
    Construct_Impl();
    if ( pFactoryP )
        pFactoryP->SetModule_Impl( this );
}
*/
SfxModule::SfxModule( ResMgr* pMgrP, BOOL bDummyP,
                      SfxObjectFactory* pFactoryP, ... )
    : pResMgr( pMgrP ), bDummy( bDummyP ), pImpl(0L)
{
    Construct_Impl();
    va_list pVarArgs;
    va_start( pVarArgs, pFactoryP );
    for ( SfxObjectFactory *pArg = pFactoryP; pArg;
         pArg = va_arg( pVarArgs, SfxObjectFactory* ) )
        pArg->SetModule_Impl( this );
    va_end(pVarArgs);
}

void SfxModule::Construct_Impl()
{
    if( !bDummy )
    {
        SfxApplication *pApp = SFX_APP();
        SfxModuleArr_Impl& rArr = GetModules_Impl();
        SfxModule* pPtr = (SfxModule*)this;
        rArr.C40_INSERT( SfxModule, pPtr, rArr.Count() );
        pImpl = new SfxModule_Impl;
        pImpl->pSlotPool = new SfxSlotPool( &pApp->GetAppSlotPool_Impl(), pResMgr );

        pImpl->pTbxCtrlFac=0;
        pImpl->pStbCtrlFac=0;
        pImpl->pMenuCtrlFac=0;
        pImpl->pFactArr=0;
        pImpl->pImgListSmall=0;
        pImpl->pImgListBig=0;
        pImpl->pImgListHiSmall=0;
        pImpl->pImgListHiBig=0;

        SetPool( &pApp->GetPool() );
    }
}

//====================================================================

SfxModule::~SfxModule()
{
    if( !bDummy )
    {
        if ( SFX_APP()->Get_Impl() )
        {
            // Das Modul wird noch vor dem DeInitialize zerst"ort, also auis dem Array entfernen
            SfxModuleArr_Impl& rArr = GetModules_Impl();
            for( USHORT nPos = rArr.Count(); nPos--; )
            {
                if( rArr[ nPos ] == this )
                {
                    rArr.Remove( nPos );
                    break;
                }
            }

            delete pImpl;
        }

        delete pResMgr;
    }
}

//-------------------------------------------------------------------------

SfxSlotPool* SfxModule::GetSlotPool() const
{
    return pImpl->pSlotPool;
}

//-------------------------------------------------------------------------

void SfxModule::RegisterChildWindow(SfxChildWinFactory *pFact)
{
    DBG_ASSERT( pImpl, "Kein echtes Modul!" );

    if (!pImpl->pFactArr)
        pImpl->pFactArr = new SfxChildWinFactArr_Impl;

//#ifdef DBG_UTIL
    for (USHORT nFactory=0; nFactory<pImpl->pFactArr->Count(); ++nFactory)
    {
        if (pFact->nId ==  (*pImpl->pFactArr)[nFactory]->nId)
        {
            pImpl->pFactArr->Remove( nFactory );
            DBG_ERROR("ChildWindow mehrfach registriert!");
            return;
        }
    }
//#endif

    pImpl->pFactArr->C40_INSERT(
        SfxChildWinFactory, pFact, pImpl->pFactArr->Count() );
}

//-------------------------------------------------------------------------

void SfxModule::RegisterChildWindowContext( USHORT nId,
        SfxChildWinContextFactory *pFact)
{
    DBG_ASSERT( pImpl, "Kein echtes Modul!" );

    USHORT nCount = pImpl->pFactArr->Count();
    for (USHORT nFactory=0; nFactory<nCount; ++nFactory)
    {
        SfxChildWinFactory *pF = (*pImpl->pFactArr)[nFactory];
        if ( nId == pF->nId )
        {
            if ( !pF->pArr )
                pF->pArr = new SfxChildWinContextArr_Impl;
            pF->pArr->C40_INSERT( SfxChildWinContextFactory, pFact, pF->pArr->Count() );
            return;
        }
    }

    DBG_ERROR( "Kein ChildWindow fuer diesen Context!" );
}

//-------------------------------------------------------------------------

void SfxModule::RegisterToolBoxControl( SfxTbxCtrlFactory *pFact )
{
    if (!pImpl->pTbxCtrlFac)
        pImpl->pTbxCtrlFac = new SfxTbxCtrlFactArr_Impl;

#ifdef DBG_UTIL
    for ( USHORT n=0; n<pImpl->pTbxCtrlFac->Count(); n++ )
    {
        SfxTbxCtrlFactory *pF = (*pImpl->pTbxCtrlFac)[n];
        if ( pF->nTypeId && pF->nTypeId == pFact->nTypeId &&
            (pF->nSlotId == pFact->nSlotId || pF->nSlotId == 0) )
        {
            DBG_WARNING("TbxController-Registrierung ist nicht eindeutig!");
        }
    }
#endif

    pImpl->pTbxCtrlFac->C40_INSERT( SfxTbxCtrlFactory, pFact, pImpl->pTbxCtrlFac->Count() );
}

//-------------------------------------------------------------------------

void SfxModule::RegisterStatusBarControl( SfxStbCtrlFactory *pFact )
{
    if (!pImpl->pStbCtrlFac)
        pImpl->pStbCtrlFac = new SfxStbCtrlFactArr_Impl;

#ifdef DBG_UTIL
    for ( USHORT n=0; n<pImpl->pStbCtrlFac->Count(); n++ )
    {
        SfxStbCtrlFactory *pF = (*pImpl->pStbCtrlFac)[n];
        if ( pF->nTypeId && pF->nTypeId == pFact->nTypeId &&
            (pF->nSlotId == pFact->nSlotId || pF->nSlotId == 0) )
        {
            DBG_WARNING("StbController-Registrierung ist nicht eindeutig!");
        }
    }
#endif

    pImpl->pStbCtrlFac->C40_INSERT( SfxStbCtrlFactory, pFact, pImpl->pStbCtrlFac->Count() );
}

//-------------------------------------------------------------------------

void SfxModule::RegisterMenuControl( SfxMenuCtrlFactory *pFact )
{
    if (!pImpl->pMenuCtrlFac)
        pImpl->pMenuCtrlFac = new SfxMenuCtrlFactArr_Impl;

#ifdef DBG_UTIL
    for ( USHORT n=0; n<pImpl->pMenuCtrlFac->Count(); n++ )
    {
        SfxMenuCtrlFactory *pF = (*pImpl->pMenuCtrlFac)[n];
        if ( pF->nTypeId && pF->nTypeId == pFact->nTypeId &&
            (pF->nSlotId == pFact->nSlotId || pF->nSlotId == 0) )
        {
            DBG_WARNING("MenuController-Registrierung ist nicht eindeutig!");
        }
    }
#endif

    pImpl->pMenuCtrlFac->C40_INSERT( SfxMenuCtrlFactory, pFact, pImpl->pMenuCtrlFac->Count() );
}

//-------------------------------------------------------------------------

SfxTbxCtrlFactArr_Impl*  SfxModule::GetTbxCtrlFactories_Impl() const
{
    return pImpl->pTbxCtrlFac;
}

//-------------------------------------------------------------------------

SfxStbCtrlFactArr_Impl*  SfxModule::GetStbCtrlFactories_Impl() const
{
    return pImpl->pStbCtrlFac;
}

//-------------------------------------------------------------------------

SfxMenuCtrlFactArr_Impl* SfxModule::GetMenuCtrlFactories_Impl() const
{
    return pImpl->pMenuCtrlFac;
}

//-------------------------------------------------------------------------

SfxChildWinFactArr_Impl* SfxModule::GetChildWinFactories_Impl() const
{
    return pImpl->pFactArr;
}

ImageList* SfxModule::GetImageList_Impl( BOOL bBig )
{
    return pImpl->GetImageList( pResMgr, bBig, FALSE );
}

ImageList* SfxModule::GetImageList_Impl( BOOL bBig, BOOL bHiContrast )
{
    return pImpl->GetImageList( pResMgr, bBig, bHiContrast );
}

SfxTabPage* SfxModule::CreateTabPage( USHORT nId, Window* pParent, const SfxItemSet& rSet )
{
    return NULL;
}

SfxModuleArr_Impl& SfxModule::GetModules_Impl()
{
    if( !pModules )
        pModules = new SfxModuleArr_Impl;
    return *pModules;
};

void SfxModule::DestroyModules_Impl()
{
    if ( pModules )
    {
        SfxModuleArr_Impl& rModules = *pModules;
        for( USHORT nPos = rModules.Count(); nPos--; )
    {
        SfxModule* pMod = rModules.GetObject(nPos);
        delete pMod;
    }
    }
}

void SfxModule::Invalidate( USHORT nId )
{
    for( SfxViewFrame* pFrame = SfxViewFrame::GetFirst(); pFrame; pFrame = SfxViewFrame::GetNext( *pFrame ) )
        if ( pFrame->GetObjectShell()->GetModule() == this )
            Invalidate_Impl( pFrame->GetBindings(), nId );
}

BOOL SfxModule::IsActive()
{
    SfxViewFrame* pFrame = SfxViewFrame::Current();
    if ( pFrame && pFrame->GetObjectShell()->GetFactory().GetModule() == this )
        return TRUE;
    return FALSE;
}

<|endoftext|>