<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 .
 */

#include "tablehandles.hxx"

#include <vcl/svapp.hxx>
#include <vcl/outdev.hxx>
#include <vcl/canvastools.hxx>
#include <vcl/hatch.hxx>
#include <basegfx/polygon/b2dpolygon.hxx>
#include <basegfx/polygon/b2dpolypolygontools.hxx>
#include <basegfx/range/b2drectangle.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <svx/sdr/overlay/overlayobject.hxx>
#include <svx/sdr/overlay/overlaymanager.hxx>
#include <svx/sdrpagewindow.hxx>
#include <svx/sdrpaintwindow.hxx>
#include <svx/svdmrkv.hxx>
#include <svx/svdpagv.hxx>
#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
#include <sdr/overlay/overlayrectangle.hxx>
#include <drawinglayer/primitive2d/hiddengeometryprimitive2d.hxx>

namespace sdr { namespace table {

class OverlayTableEdge : public sdr::overlay::OverlayObject
{
protected:
    basegfx::B2DPolyPolygon maPolyPolygon;
    bool                    mbVisible;

    // geometry creation for OverlayObject
    virtual drawinglayer::primitive2d::Primitive2DSequence createOverlayObjectPrimitive2DSequence() SAL_OVERRIDE;

public:
    OverlayTableEdge( const basegfx::B2DPolyPolygon& rPolyPolygon, bool bVisible );
    virtual ~OverlayTableEdge();
};

TableEdgeHdl::TableEdgeHdl( const Point& rPnt, bool bHorizontal, sal_Int32 nMin, sal_Int32 nMax, sal_Int32 nEdges )
: SdrHdl( rPnt, HDL_USER )
, mbHorizontal( bHorizontal )
, mnMin( nMin )
, mnMax( nMax )
, maEdges(nEdges)
{
}

void TableEdgeHdl::SetEdge( sal_Int32 nEdge, sal_Int32 nStart, sal_Int32 nEnd, TableEdgeState eState )
{
    if( (nEdge >= 0) && (nEdge <= sal::static_int_cast<sal_Int32>(maEdges.size())) )
    {
        maEdges[nEdge].mnStart = nStart;
        maEdges[nEdge].mnEnd = nEnd;
        maEdges[nEdge].meState = eState;
    }
    else
    {
        OSL_FAIL( "sdr::table::TableEdgeHdl::SetEdge(), invalid edge!" );
    }
}

Pointer TableEdgeHdl::GetPointer() const
{
    if( mbHorizontal )
        return POINTER_VSPLIT;
    else
        return POINTER_HSPLIT;
}

sal_Int32 TableEdgeHdl::GetValidDragOffset( const SdrDragStat& rDrag ) const
{
    return std::min( std::max( static_cast<sal_Int32>(mbHorizontal ? rDrag.GetDY() : rDrag.GetDX()), mnMin ), mnMax );
}

basegfx::B2DPolyPolygon TableEdgeHdl::getSpecialDragPoly(const SdrDragStat& rDrag) const
{
    basegfx::B2DPolyPolygon aVisible;
    basegfx::B2DPolyPolygon aInvisible;

    // create and return visible and non-visible parts for drag
    getPolyPolygon(aVisible, aInvisible, &rDrag);
    aVisible.append(aInvisible);

    return aVisible;
}

void TableEdgeHdl::getPolyPolygon(basegfx::B2DPolyPolygon& rVisible, basegfx::B2DPolyPolygon& rInvisible, const SdrDragStat* pDrag) const
{
    // changed method to create visible and invisible partial polygons in one run in
    // separate PolyPolygons; both kinds are used
    basegfx::B2DPoint aOffset(aPos.X(), aPos.Y());
    rVisible.clear();
    rInvisible.clear();

    if( pDrag )
    {
        int n = mbHorizontal ? 1 : 0;
        aOffset[n] = aOffset[n] + GetValidDragOffset( *pDrag );
    }

    basegfx::B2DPoint aStart(aOffset), aEnd(aOffset);
    int nPos = mbHorizontal ? 0 : 1;
    TableEdgeVector::const_iterator aIter( maEdges.begin() );

    while( aIter != maEdges.end() )
    {
        TableEdge aEdge(*aIter++);

        aStart[nPos] = aOffset[nPos] + aEdge.mnStart;
        aEnd[nPos] = aOffset[nPos] + aEdge.mnEnd;

        basegfx::B2DPolygon aPolygon;
        aPolygon.append( aStart );
        aPolygon.append( aEnd );

        if(aEdge.meState == Visible)
        {
            rVisible.append(aPolygon);
        }
        else
        {
            rInvisible.append(aPolygon);
        }
    }
}

void TableEdgeHdl::CreateB2dIAObject()
{
    GetRidOfIAObject();

    if(pHdlList && pHdlList->GetView() && !pHdlList->GetView()->areMarkHandlesHidden())
    {
        SdrMarkView* pView = pHdlList->GetView();
        SdrPageView* pPageView = pView->GetSdrPageView();

        if(pPageView)
        {
            basegfx::B2DPolyPolygon aVisible;
            basegfx::B2DPolyPolygon aInvisible;

            // get visible and invisible parts
            getPolyPolygon(aVisible, aInvisible, 0);

            if(aVisible.count() || aInvisible.count())
            {
                for(sal_uInt32 nWindow = 0; nWindow < pPageView->PageWindowCount(); nWindow++)
                {
                    const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(nWindow);

                    if(rPageWindow.GetPaintWindow().OutputToWindow())
                    {
                        rtl::Reference< ::sdr::overlay::OverlayManager > xManager = rPageWindow.GetOverlayManager();
                        if (xManager.is())
                        {
                            if(aVisible.count())
                            {
                                // create overlay object for visible parts
                                sdr::overlay::OverlayObject* pOverlayObject = new OverlayTableEdge(aVisible, true);
                                xManager->add(*pOverlayObject);
                                maOverlayGroup.append(*pOverlayObject);
                            }

                            if(aInvisible.count())
                            {
                                // also create overlay object vor invisible parts to allow
                                // a standard HitTest using the primitives from that overlay object
                                // (see OverlayTableEdge implementation)
                                sdr::overlay::OverlayObject* pOverlayObject = new OverlayTableEdge(aInvisible, false);
                                xManager->add(*pOverlayObject);
                                maOverlayGroup.append(*pOverlayObject);
                            }
                        }
                    }
                }
            }
        }
    }
}

OverlayTableEdge::OverlayTableEdge( const basegfx::B2DPolyPolygon& rPolyPolygon, bool bVisible )
:   OverlayObject(Color(COL_GRAY))
,   maPolyPolygon( rPolyPolygon )
,   mbVisible(bVisible)
{
}

OverlayTableEdge::~OverlayTableEdge()
{
}

drawinglayer::primitive2d::Primitive2DSequence OverlayTableEdge::createOverlayObjectPrimitive2DSequence()
{
    drawinglayer::primitive2d::Primitive2DSequence aRetval;

    if(maPolyPolygon.count())
    {
        // Discussed with CL. Currently i will leave the transparence out since this
        // a little bit expensive. We may check the look with drag polygons later
        const drawinglayer::primitive2d::Primitive2DReference aReference(
            new drawinglayer::primitive2d::PolyPolygonHairlinePrimitive2D(
                maPolyPolygon,
                getBaseColor().getBColor()));

        if(mbVisible)
        {
            // visible, just return as sequence
            aRetval = drawinglayer::primitive2d::Primitive2DSequence(&aReference, 1);
        }
        else
        {
            // embed in HiddenGeometryPrimitive2D to support HitTest of this invisible
            // overlay object
            const drawinglayer::primitive2d::Primitive2DSequence aSequence(&aReference, 1);
            const drawinglayer::primitive2d::Primitive2DReference aNewReference(
                new drawinglayer::primitive2d::HiddenGeometryPrimitive2D(aSequence));
            aRetval = drawinglayer::primitive2d::Primitive2DSequence(&aNewReference, 1);
        }
    }

    return aRetval;
}

TableBorderHdl::TableBorderHdl(
    const Rectangle& rRect,
    bool bAnimate)
:   SdrHdl(rRect.TopLeft(), HDL_MOVE),
    maRectangle(rRect),
    mbAnimate(bAnimate)
{
}

Pointer TableBorderHdl::GetPointer() const
{
    return POINTER_MOVE;
}

// create marker for this kind
void TableBorderHdl::CreateB2dIAObject()
{
    GetRidOfIAObject();

    if(pHdlList && pHdlList->GetView() && !pHdlList->GetView()->areMarkHandlesHidden())
    {
        SdrMarkView* pView = pHdlList->GetView();
        SdrPageView* pPageView = pView->GetSdrPageView();

        if(pPageView)
        {
            for(sal_uInt32 nWindow = 0; nWindow < pPageView->PageWindowCount(); nWindow++)
            {
                const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(nWindow);

                if(rPageWindow.GetPaintWindow().OutputToWindow())
                {
                    rtl::Reference< ::sdr::overlay::OverlayManager > xManager = rPageWindow.GetOverlayManager();
                    if (xManager.is())
                    {
                        const basegfx::B2DRange aRange(vcl::unotools::b2DRectangleFromRectangle(maRectangle));
                        const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer;
                        const Color aHilightColor(aSvtOptionsDrawinglayer.getHilightColor());
                        const double fTransparence(aSvtOptionsDrawinglayer.GetTransparentSelectionPercent() * 0.01);

                        sdr::overlay::OverlayObject* pOverlayObject = new sdr::overlay::OverlayRectangle(
                            aRange.getMinimum(),
                            aRange.getMaximum(),
                            aHilightColor,
                            fTransparence,
                            6.0,
                            0.0,
                            0.0,
                            500,
                            // make animation dependent from text edit active, because for tables
                            // this handle is also used when text edit *is* active for it. This
                            // interferes too much concerning repaint stuff (at least as long as
                            // text edit is not yet on the overlay)
                            getAnimate());

                        xManager->add(*pOverlayObject);
                        maOverlayGroup.append(*pOverlayObject);
                    }
                }
            }
        }
    }
}

} // end of namespace table
} // end of namespace sdr

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>cleanup tableBorderHdl::CreateB2dIAObject<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 .
 */

#include "tablehandles.hxx"

#include <vcl/svapp.hxx>
#include <vcl/outdev.hxx>
#include <vcl/canvastools.hxx>
#include <vcl/hatch.hxx>
#include <basegfx/polygon/b2dpolygon.hxx>
#include <basegfx/polygon/b2dpolypolygontools.hxx>
#include <basegfx/range/b2drectangle.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <svx/sdr/overlay/overlayobject.hxx>
#include <svx/sdr/overlay/overlaymanager.hxx>
#include <svx/sdrpagewindow.hxx>
#include <svx/sdrpaintwindow.hxx>
#include <svx/svdmrkv.hxx>
#include <svx/svdpagv.hxx>
#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
#include <sdr/overlay/overlayrectangle.hxx>
#include <drawinglayer/primitive2d/hiddengeometryprimitive2d.hxx>

namespace sdr { namespace table {

class OverlayTableEdge : public sdr::overlay::OverlayObject
{
protected:
    basegfx::B2DPolyPolygon maPolyPolygon;
    bool                    mbVisible;

    // geometry creation for OverlayObject
    virtual drawinglayer::primitive2d::Primitive2DSequence createOverlayObjectPrimitive2DSequence() SAL_OVERRIDE;

public:
    OverlayTableEdge( const basegfx::B2DPolyPolygon& rPolyPolygon, bool bVisible );
    virtual ~OverlayTableEdge();
};

TableEdgeHdl::TableEdgeHdl( const Point& rPnt, bool bHorizontal, sal_Int32 nMin, sal_Int32 nMax, sal_Int32 nEdges )
: SdrHdl( rPnt, HDL_USER )
, mbHorizontal( bHorizontal )
, mnMin( nMin )
, mnMax( nMax )
, maEdges(nEdges)
{
}

void TableEdgeHdl::SetEdge( sal_Int32 nEdge, sal_Int32 nStart, sal_Int32 nEnd, TableEdgeState eState )
{
    if( (nEdge >= 0) && (nEdge <= sal::static_int_cast<sal_Int32>(maEdges.size())) )
    {
        maEdges[nEdge].mnStart = nStart;
        maEdges[nEdge].mnEnd = nEnd;
        maEdges[nEdge].meState = eState;
    }
    else
    {
        OSL_FAIL( "sdr::table::TableEdgeHdl::SetEdge(), invalid edge!" );
    }
}

Pointer TableEdgeHdl::GetPointer() const
{
    if( mbHorizontal )
        return POINTER_VSPLIT;
    else
        return POINTER_HSPLIT;
}

sal_Int32 TableEdgeHdl::GetValidDragOffset( const SdrDragStat& rDrag ) const
{
    return std::min( std::max( static_cast<sal_Int32>(mbHorizontal ? rDrag.GetDY() : rDrag.GetDX()), mnMin ), mnMax );
}

basegfx::B2DPolyPolygon TableEdgeHdl::getSpecialDragPoly(const SdrDragStat& rDrag) const
{
    basegfx::B2DPolyPolygon aVisible;
    basegfx::B2DPolyPolygon aInvisible;

    // create and return visible and non-visible parts for drag
    getPolyPolygon(aVisible, aInvisible, &rDrag);
    aVisible.append(aInvisible);

    return aVisible;
}

void TableEdgeHdl::getPolyPolygon(basegfx::B2DPolyPolygon& rVisible, basegfx::B2DPolyPolygon& rInvisible, const SdrDragStat* pDrag) const
{
    // changed method to create visible and invisible partial polygons in one run in
    // separate PolyPolygons; both kinds are used
    basegfx::B2DPoint aOffset(aPos.X(), aPos.Y());
    rVisible.clear();
    rInvisible.clear();

    if( pDrag )
    {
        int n = mbHorizontal ? 1 : 0;
        aOffset[n] = aOffset[n] + GetValidDragOffset( *pDrag );
    }

    basegfx::B2DPoint aStart(aOffset), aEnd(aOffset);
    int nPos = mbHorizontal ? 0 : 1;
    TableEdgeVector::const_iterator aIter( maEdges.begin() );

    while( aIter != maEdges.end() )
    {
        TableEdge aEdge(*aIter++);

        aStart[nPos] = aOffset[nPos] + aEdge.mnStart;
        aEnd[nPos] = aOffset[nPos] + aEdge.mnEnd;

        basegfx::B2DPolygon aPolygon;
        aPolygon.append( aStart );
        aPolygon.append( aEnd );

        if(aEdge.meState == Visible)
        {
            rVisible.append(aPolygon);
        }
        else
        {
            rInvisible.append(aPolygon);
        }
    }
}

void TableEdgeHdl::CreateB2dIAObject()
{
    GetRidOfIAObject();

    if(pHdlList && pHdlList->GetView() && !pHdlList->GetView()->areMarkHandlesHidden())
    {
        SdrMarkView* pView = pHdlList->GetView();
        SdrPageView* pPageView = pView->GetSdrPageView();

        if(pPageView)
        {
            basegfx::B2DPolyPolygon aVisible;
            basegfx::B2DPolyPolygon aInvisible;

            // get visible and invisible parts
            getPolyPolygon(aVisible, aInvisible, 0);

            if(aVisible.count() || aInvisible.count())
            {
                for(sal_uInt32 nWindow = 0; nWindow < pPageView->PageWindowCount(); nWindow++)
                {
                    const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(nWindow);

                    if(rPageWindow.GetPaintWindow().OutputToWindow())
                    {
                        rtl::Reference< ::sdr::overlay::OverlayManager > xManager = rPageWindow.GetOverlayManager();
                        if (xManager.is())
                        {
                            if(aVisible.count())
                            {
                                // create overlay object for visible parts
                                sdr::overlay::OverlayObject* pOverlayObject = new OverlayTableEdge(aVisible, true);
                                xManager->add(*pOverlayObject);
                                maOverlayGroup.append(*pOverlayObject);
                            }

                            if(aInvisible.count())
                            {
                                // also create overlay object vor invisible parts to allow
                                // a standard HitTest using the primitives from that overlay object
                                // (see OverlayTableEdge implementation)
                                sdr::overlay::OverlayObject* pOverlayObject = new OverlayTableEdge(aInvisible, false);
                                xManager->add(*pOverlayObject);
                                maOverlayGroup.append(*pOverlayObject);
                            }
                        }
                    }
                }
            }
        }
    }
}

OverlayTableEdge::OverlayTableEdge( const basegfx::B2DPolyPolygon& rPolyPolygon, bool bVisible )
:   OverlayObject(Color(COL_GRAY))
,   maPolyPolygon( rPolyPolygon )
,   mbVisible(bVisible)
{
}

OverlayTableEdge::~OverlayTableEdge()
{
}

drawinglayer::primitive2d::Primitive2DSequence OverlayTableEdge::createOverlayObjectPrimitive2DSequence()
{
    drawinglayer::primitive2d::Primitive2DSequence aRetval;

    if(maPolyPolygon.count())
    {
        // Discussed with CL. Currently i will leave the transparence out since this
        // a little bit expensive. We may check the look with drag polygons later
        const drawinglayer::primitive2d::Primitive2DReference aReference(
            new drawinglayer::primitive2d::PolyPolygonHairlinePrimitive2D(
                maPolyPolygon,
                getBaseColor().getBColor()));

        if(mbVisible)
        {
            // visible, just return as sequence
            aRetval = drawinglayer::primitive2d::Primitive2DSequence(&aReference, 1);
        }
        else
        {
            // embed in HiddenGeometryPrimitive2D to support HitTest of this invisible
            // overlay object
            const drawinglayer::primitive2d::Primitive2DSequence aSequence(&aReference, 1);
            const drawinglayer::primitive2d::Primitive2DReference aNewReference(
                new drawinglayer::primitive2d::HiddenGeometryPrimitive2D(aSequence));
            aRetval = drawinglayer::primitive2d::Primitive2DSequence(&aNewReference, 1);
        }
    }

    return aRetval;
}

TableBorderHdl::TableBorderHdl(
    const Rectangle& rRect,
    bool bAnimate)
:   SdrHdl(rRect.TopLeft(), HDL_MOVE),
    maRectangle(rRect),
    mbAnimate(bAnimate)
{
}

Pointer TableBorderHdl::GetPointer() const
{
    return POINTER_MOVE;
}

// create marker for this kind
void TableBorderHdl::CreateB2dIAObject()
{
    GetRidOfIAObject();

    if (pHdlList && pHdlList->GetView() && !pHdlList->GetView()->areMarkHandlesHidden())
    {
        SdrMarkView* pView = pHdlList->GetView();
        SdrPageView* pPageView = pView->GetSdrPageView();

        if (!pPageView)
            return;

        for(sal_uInt32 nWindow = 0; nWindow < pPageView->PageWindowCount(); nWindow++)
        {
            const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(nWindow);

            if (rPageWindow.GetPaintWindow().OutputToWindow())
            {
                rtl::Reference<sdr::overlay::OverlayManager> xManager = rPageWindow.GetOverlayManager();

                if (xManager.is())
                {
                    const basegfx::B2DRange aRange(vcl::unotools::b2DRectangleFromRectangle(maRectangle));
                    const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer;
                    const Color aHilightColor(aSvtOptionsDrawinglayer.getHilightColor());
                    const double fTransparence(aSvtOptionsDrawinglayer.GetTransparentSelectionPercent() * 0.01);
                    // make animation dependent from text edit active, because for tables
                    // this handle is also used when text edit *is* active for it. This
                    // interferes too much concerning repaint stuff (at least as long as
                    // text edit is not yet on the overlay)
                    const bool bAnimate = getAnimate();

                    sdr::overlay::OverlayObject* pOverlayObject =
                        new sdr::overlay::OverlayRectangle(aRange.getMinimum(), aRange.getMaximum(),
                                                           aHilightColor, fTransparence,
                                                           6.0, 0.0, 0.0, 500, bAnimate);
                    xManager->add(*pOverlayObject);
                    maOverlayGroup.append(*pOverlayObject);
                }
            }
        }
    }
}

} // end of namespace table
} // end of namespace sdr

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>#pragma once

#include <phosphor-logging/lg2/concepts.hpp>
#include <string_view>

namespace lg2::details
{

/** A type to handle compile-time validation of header strings. */
struct header_str
{
    // Hold the header string value.
    std::string_view value;

    /** Constructor which performs validation. */
    template <typename T>
    consteval header_str(const T& s) : value(s)
    {
        if (value.size() == 0)
        {
            report_error(
                "journald requires headers must have non-zero length.");
        }
        if (value[0] == '_')
        {
            report_error("journald requires header do not start with "
                         "underscore (_)");
        }

        if (value.find_first_not_of("ABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789") !=
            std::string_view::npos)
        {
            report_error(
                "journald requires header may only contain underscore, "
                "uppercase letters, or numbers ([_A-Z0-9]).");
        }
    }

    /** Cast conversion back to (const char*). */
    operator const char*() const
    {
        return value.data();
    }

    const char* data() const
    {
        return value.data();
    }

  private:
    // This does nothing, but is useful for creating nice compile errors in
    // a constexpr context.
    static void report_error(const char*);
};

/** A helper type for constexpr conversion into header_str, if
 *  'maybe_constexpr_string'.  For non-constexpr string, this does nothing.
 */
template <typename T>
struct header_str_conversion
{
    using type = T;
};

/** Specialization for maybe_constexpr_string. */
template <maybe_constexpr_string T>
struct header_str_conversion<T>
{
    using type = const header_str&;
};

/** std-style _t alias for header_str_conversion. */
template <typename T>
using header_str_conversion_t = typename header_str_conversion<T>::type;

} // namespace lg2::details
<commit_msg>lg2: compile time checking for reserved header names<commit_after>#pragma once

#include <array>
#include <phosphor-logging/lg2/concepts.hpp>
#include <string_view>

namespace lg2::details
{

/** A type to handle compile-time validation of header strings. */
struct header_str
{
    // Hold the header string value.
    std::string_view value;

    /** Constructor which performs validation. */
    template <typename T>
    consteval header_str(const T& s) : value(s)
    {
        if (value.size() == 0)
        {
            report_error(
                "journald requires headers must have non-zero length.");
        }
        if (value[0] == '_')
        {
            report_error("journald requires header do not start with "
                         "underscore (_)");
        }

        if (value.find_first_not_of("ABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789") !=
            std::string_view::npos)
        {
            report_error(
                "journald requires header may only contain underscore, "
                "uppercase letters, or numbers ([_A-Z0-9]).");
        }

        constexpr std::array reserved{
            "CODE_FILE",   "CODE_FUNC", "CODE_LINE",
            "LOG2_FMTMSG", "MESSAGE",   "PRIORITY",
        };
        if (std::ranges::find(reserved, value) != std::end(reserved))
        {
            report_error("Header name is reserved.");
        }
    }

    /** Cast conversion back to (const char*). */
    operator const char*() const
    {
        return value.data();
    }

    const char* data() const
    {
        return value.data();
    }

  private:
    // This does nothing, but is useful for creating nice compile errors in
    // a constexpr context.
    static void report_error(const char*);
};

/** A helper type for constexpr conversion into header_str, if
 *  'maybe_constexpr_string'.  For non-constexpr string, this does nothing.
 */
template <typename T>
struct header_str_conversion
{
    using type = T;
};

/** Specialization for maybe_constexpr_string. */
template <maybe_constexpr_string T>
struct header_str_conversion<T>
{
    using type = const header_str&;
};

/** std-style _t alias for header_str_conversion. */
template <typename T>
using header_str_conversion_t = typename header_str_conversion<T>::type;

} // namespace lg2::details
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: stmenu.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: hr $ $Date: 2007-01-02 16:54:04 $
 *
 *  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
 *
 *    Initial Contributer was Fabalabs Software GmbH, Jakob Lechner
 *
 *    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
 *
 ************************************************************************/

// SMARTTAGS

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sw.hxx"

#ifndef _HINTIDS_HXX
#include <hintids.hxx>
#endif
#ifndef _HELPID_H
#include <helpid.h>
#endif
#ifndef _SWTYPES_HXX
#include <swtypes.hxx>
#endif

#ifndef _STMENU_HXX
#include <stmenu.hxx>
#endif
#ifndef _STMENU_HRC
#include <stmenu.hrc>
#endif
#ifndef _VIEW_HXX
#include <view.hxx>
#endif

#ifndef _COM_SUN_STAR_TEXT_XTEXTDOCUMENT_HPP_
#include <com/sun/star/text/XTextDocument.hpp>
#endif
#ifndef _COM_SUN_STAR_FRAME_XMODEL_HPP_
#include "com/sun/star/frame/XModel.hpp"
#endif
#ifndef _SWDOCSH_HXX //autogen
#include <docsh.hxx>
#endif

#define C2U(cChar) OUString::createFromAscii(cChar)

using namespace ::com::sun::star::frame;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::text;

SwSmartTagPopup::SwSmartTagPopup( SwView* _pSwView, std::vector <ActionReference> _aActionRefs, Reference<XTextRange> _xTextRange ) :
   PopupMenu(SW_RES(MN_SMARTTAG_POPUP)),
   pSwView ( _pSwView ),
   aActionRefs(_aActionRefs), xTextRange (_xTextRange)
{
    CreateAutoMnemonics();

    PopupMenu *pMenu = GetPopupMenu(MN_SMARTTAG);
   if (!pMenu) {
       return;
   }

   pMenu->SetMenuFlags(MENU_FLAG_NOAUTOMNEMONICS);
   sal_Bool bEnable = sal_True;

   Reference <XController> xController = pSwView->GetController();

   nMaxVerbCount=0;
   for (int i=0; i<aActionRefs.size(); i++) {
       Reference<XSmartTagAction> aSmartTagAction = aActionRefs[i].aSmartTagAction;
       sal_Int32 nSmartTagIndex = aActionRefs[i].nSmartTagIndex;
       if (aSmartTagAction->getActionCount(nSmartTagIndex, xController)>nMaxVerbCount)
           nMaxVerbCount = aSmartTagAction->getActionCount(nSmartTagIndex, xController);
   }

   // add menuitem for every smarttag
   for (sal_uInt16 i=0; i<aActionRefs.size(); i++) {
       Reference<XSmartTagAction> aSmartTagAction = aActionRefs[i].aSmartTagAction;
       sal_Int32 nSmartTagIndex = aActionRefs[i].nSmartTagIndex;

       InsertItem(i+1, aSmartTagAction->getSmartTagCaption(nSmartTagIndex, xController));
       PopupMenu* pSubMenu = new PopupMenu;
       SetPopupMenu(i+1, pSubMenu);

       // add subitem for every action of current smarttag
       for (int j=0; j<aSmartTagAction->getActionCount(nSmartTagIndex, xController); j++) {
           // compute the unique id that comprises the information in which
           // smarttag library the action can be found and which action is actually meant
           // This id is needed later in the execute method to invoke the correct
           // action in the smarttag object
           sal_uInt16 nId = (i*nMaxVerbCount + j) + MN_ST_INSERT_START;
           pSubMenu->InsertItem(nId, aSmartTagAction->getActionCaption(nSmartTagIndex, j, xController));
       }
   }
   EnableItem( MN_SMARTTAG, bEnable );

   RemoveDisabledEntries( TRUE, TRUE );
}

/** Function: Execute

   executes actions by calling the invoke function of the appropriate
   smarttag library.

*/
sal_uInt16  SwSmartTagPopup::Execute( Window* pWin, const Rectangle& rWordPos )
{
  SetMenuFlags(MENU_FLAG_NOAUTOMNEMONICS);
  sal_uInt16 nRet = PopupMenu::Execute(pWin, pWin->LogicToPixel(rWordPos));

  if (nRet < MN_ST_INSERT_START) return nRet;

  // compute smarttag lib index and action index
  nRet -= MN_ST_INSERT_START;
  sal_Int32 nRefIndex  = nRet / nMaxVerbCount;
  sal_Int32 nActionIndex =  nRet % nMaxVerbCount;

  Reference<XSmartTagAction> aSmartTagAction = aActionRefs[nRefIndex].aSmartTagAction;
  sal_Int32 nSmartTagIndex = aActionRefs[nRefIndex].nSmartTagIndex;

  Reference <XController> xController = pSwView->GetController();

  // execute action
  aSmartTagAction->invokeAction(nSmartTagIndex, nActionIndex, xTextRange, xController);

  return nRet;
}

<commit_msg>INTEGRATION: CWS smarttags3 (1.2.70); FILE MERGED 2007/06/05 08:17:34 fme 1.2.70.9: #i76130# New Smart Tag API - Controller parameter added to a couple of functions 2007/05/23 14:26:51 fme 1.2.70.8: #i75130# New smart tag API - resync 2007/05/14 12:19:14 fme 1.2.70.7: #i75130# New smart tag API 2007/05/12 06:31:52 fme 1.2.70.6: #i75130# New smart tag API 2007/05/02 08:25:49 fme 1.2.70.5: #i75130# New smart tag API 2007/05/02 07:55:26 fme 1.2.70.4: #i75130# New smart tag API 2007/04/26 13:16:21 fme 1.2.70.3: #i75130# New Smarttag API 2007/04/16 12:13:23 fme 1.2.70.2: #i75130# New Smart Tag API 2007/03/05 13:55:26 fme 1.2.70.1: #i75130# New API and implementation of smart tags<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: stmenu.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: hr $ $Date: 2007-06-27 13:26:22 $
 *
 *  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
 *
 *    Initial Contributer was Fabalabs Software GmbH, Jakob Lechner
 *
 *    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
 *
 ************************************************************************/

// SMARTTAGS

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sw.hxx"

#ifndef _STMENU_HXX
#include <stmenu.hxx>
#endif

#ifndef _COM_SUN_STAR_UNO_SEQUENCE_HXX_
#include <com/sun/star/uno/Sequence.hxx>
#endif
#ifndef _SFXENUMITEM_HXX //autogen
#include <svtools/eitem.hxx>
#endif
#ifndef _SFXDISPATCH_HXX //autogen
#include <sfx2/dispatch.hxx>
#endif

#include <SwSmartTagMgr.hxx>

#ifndef _STMENU_HRC
#include <stmenu.hrc>
#endif
#ifndef _VIEW_HXX
#include <view.hxx>
#endif
#ifndef _BREAKIT_HXX
#include <breakit.hxx>
#endif

#define C2U(cChar) rtl::OUString::createFromAscii(cChar)

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;

SwSmartTagPopup::SwSmartTagPopup( SwView* pSwView,
                                  Sequence< rtl::OUString >& rSmartTagTypes,
                                  Sequence< Reference< container::XStringKeyMap > >& rStringKeyMaps,
                                  Reference< text::XTextRange > xTextRange ) :
    PopupMenu( SW_RES(MN_SMARTTAG_POPUP) ),
    mpSwView ( pSwView ),
    mxTextRange( xTextRange )
{
    //CreateAutoMnemonics();

    Reference <frame::XController> xController = mpSwView->GetController();
    const lang::Locale aLocale( SW_BREAKITER()->GetLocale( (LanguageType)GetAppLanguage() ) );

    USHORT nMenuPos = 0;
    USHORT nSubMenuPos = 0;
    USHORT nMenuId = 1;
    USHORT nSubMenuId = MN_ST_INSERT_START;

    const rtl::OUString aRangeText = mxTextRange->getString();

    SmartTagMgr& rSmartTagMgr = SwSmartTagMgr::Get();
    const rtl::OUString aApplicationName( rSmartTagMgr.GetApplicationName() );

    Sequence < Sequence< Reference< smarttags::XSmartTagAction > > > aActionComponentsSequence;
    Sequence < Sequence< sal_Int32 > > aActionIndicesSequence;

    rSmartTagMgr.GetActionSequences( rSmartTagTypes,
                                     aActionComponentsSequence,
                                     aActionIndicesSequence );

    InsertSeparator(0);

    for ( USHORT j = 0; j < aActionComponentsSequence.getLength(); ++j )
    {
        Reference< container::XStringKeyMap > xSmartTagProperties = rStringKeyMaps[j];

        // Get all actions references associated with the current smart tag type:
        const Sequence< Reference< smarttags::XSmartTagAction > >& rActionComponents = aActionComponentsSequence[j];
        const Sequence< sal_Int32 >& rActionIndices = aActionIndicesSequence[j];

        if ( 0 == rActionComponents.getLength() || 0 == rActionIndices.getLength() )
            continue;

        // Ask first entry for the smart tag type caption:
        Reference< smarttags::XSmartTagAction > xAction = rActionComponents[0];

        if ( !xAction.is() )
            continue;

        const sal_Int32 nSmartTagIndex = rActionIndices[0];
        const rtl::OUString aSmartTagType = xAction->getSmartTagName( nSmartTagIndex );
        const rtl::OUString aSmartTagCaption = xAction->getSmartTagCaption( nSmartTagIndex, aLocale );

        // no sub-menues if there's only one smart tag type listed:
        PopupMenu* pSbMenu = this;
        if ( 1 < aActionComponentsSequence.getLength() )
        {
            InsertItem( nMenuId, aSmartTagCaption, 0, nMenuPos++);
            pSbMenu = new PopupMenu;
            SetPopupMenu( nMenuId++, pSbMenu );
        }

        // sub-menu starts with smart tag caption and separator
        const rtl::OUString aSmartTagCaption2 = aSmartTagCaption + C2U(": ") + aRangeText;
        nSubMenuPos = 0;
        pSbMenu->InsertItem( nMenuId++, aSmartTagCaption2, MIB_NOSELECT, nSubMenuPos++ );
        pSbMenu->InsertSeparator( nSubMenuPos++ );

        // Add subitem for every action reference for the current smart tag type:
        for ( USHORT i = 0; i < rActionComponents.getLength(); ++i )
        {
            xAction = rActionComponents[i];

            for ( sal_Int32 k = 0; k < xAction->getActionCount( aSmartTagType, xController ); ++k )
            {
                const sal_uInt32 nActionID = xAction->getActionID( aSmartTagType, k, xController  );
                rtl::OUString aActionCaption = xAction->getActionCaptionFromID( nActionID,
                                                                                aApplicationName,
                                                                                aLocale,
                                                                                xSmartTagProperties,
                                                                                aRangeText,
                                                                                rtl::OUString(),
                                                                                xController,
                                                                                mxTextRange );

                pSbMenu->InsertItem( nSubMenuId++, aActionCaption, 0, nSubMenuPos++ );
                InvokeAction aEntry( xAction, xSmartTagProperties, nActionID );
                maInvokeActions.push_back( aEntry );
            }
        }
    }
}

/** Function: Execute

   executes actions by calling the invoke function of the appropriate
   smarttag library.

*/
sal_uInt16 SwSmartTagPopup::Execute( Window* pWin, const Rectangle& rWordPos )
{
    sal_uInt16 nId = PopupMenu::Execute(pWin, pWin->LogicToPixel(rWordPos));

    if ( nId == MN_SMARTTAG_OPTIONS )
    {
        SfxBoolItem aBool(SID_OPEN_SMARTTAGOPTIONS, TRUE);
        mpSwView->GetViewFrame()->GetDispatcher()->Execute( SID_AUTO_CORRECT_DLG, SFX_CALLMODE_ASYNCHRON, &aBool, 0L );
    }

    if ( nId < MN_ST_INSERT_START) return nId;
    nId -= MN_ST_INSERT_START;

    // compute smarttag lib index and action index
    if ( nId < maInvokeActions.size() )
    {
        Reference< smarttags::XSmartTagAction > xSmartTagAction = maInvokeActions[ nId ].mxAction;

        // execute action
        if ( xSmartTagAction.is() )
        {
            SmartTagMgr& rSmartTagMgr = SwSmartTagMgr::Get();

            xSmartTagAction->invokeAction( maInvokeActions[ nId ].mnActionID,
                                           rSmartTagMgr.GetApplicationName(),
                                           mpSwView->GetController(),
                                           mxTextRange,
                                           maInvokeActions[ nId ].mxSmartTagProperties,
                                           mxTextRange->getString(),
                                           rtl::OUString(),
                                           SW_BREAKITER()->GetLocale( (LanguageType)GetAppLanguage() )  );
        }
    }

    return nId;
}
<|endoftext|>


<commit_before>/*
** Copyright 2011 Merethis
** This file is part of Centreon Broker.
**
** Centreon Broker is free software: you can redistribute it and/or
** modify it under the terms of the GNU General Public License version 2
** as published by the Free Software Foundation.
**
** Centreon Broker 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
** General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Centreon Broker. If not, see
** <http://www.gnu.org/licenses/>.
*/

#include <assert.h>
#include <stdlib.h>
#include "config/applier/endpoint.hh"
#include "exceptions/basic.hh"
#include "io/protocols.hh"

using namespace com::centreon::broker;
using namespace com::centreon::broker::config::applier;

/**************************************
*                                     *
*           Private Methods           *
*                                     *
**************************************/

/**
 *  Default constructor.
 */
endpoint::endpoint() : QObject() {}

/**
 *  @brief Copy constructor.
 *
 *  Any call to this constructor will result in a call to abort().
 *
 *  @param[in] e Object to copy.
 */
endpoint::endpoint(endpoint const& e) : QObject() {
  (void)e;
  assert(false);
  abort();
}

/**
 *  @brief Assignment operator.
 *
 *  Any call to this method will result in a call to abort().
 *
 *  @param[in] e Object to copy.
 *
 *  @return This object.
 */
endpoint& endpoint::operator=(endpoint const& e) {
  (void)e;
  assert(false);
  abort();
  return (*this);
}

/**
 *  Create and register an endpoint according to configuration.
 *
 *  @param[in] cfg       Endpoint configuration.
 *  @param[in] is_output true if the endpoint will act as output.
 */
void endpoint::_create_endpoint(config::endpoint const& cfg, bool is_output) {
  // Create endpoint object.
  QSharedPointer<io::endpoint> endp;
  int level(1);
  for (QMap<QString, io::protocols::protocol>::const_iterator it = io::protocols::instance().begin(),
         end = io::protocols::instance().end();
       it != end;
       ++it) {
    if ((it.value().osi_from == level)
        && it.value().endpntfactry->had_endpoint()) {
      endp = QSharedPointer<io::endpoint>(it.value().endpntfactry->new_endpoint());
      break ;
    }
  }
  if (endp.isNull())
    throw (exceptions::basic() << "no matching protocol found for endpoint '"
             << cfg.name.toStdString().c_str() << "'");
  // XXX : remaining objects.

  // Create thread.
  QScopedPointer<processing::failover> fo(new processing::failover);
  fo->set_endpoint(endp,
    (is_output
       ? processing::failover::output
       : processing::failover::input));

  // Connect thread.
  connect(fo.data(), SIGNAL(finished()), fo.data(), SLOT(deleteLater));
  if (!is_output) {
    connect(fo.data(), SIGNAL(finished()), this, SLOT(terminated_input()));
    _inputs[cfg] = fo.data();
  }
  else {
    connect(fo.data(), SIGNAL(finished()), this, SLOT(terminated_output()));
    _outputs[cfg] = fo.data();
  }

  // Run thread.
  fo.take()->start();

  return ;
}

/**
 *  Diff the current configuration with the new configuration.
 *
 *  @param[in]  current       Current endpoints.
 *  @param[in]  new_endpoints New endpoints configuration.
 *  @param[out] to_create     Endpoints that should be created.
 */
void endpoint::_diff_endpoints(QMap<config::endpoint, processing::failover*> & current,
                               QList<config::endpoint> const& new_endpoints,
                               QList<config::endpoint>& to_create) {
  // Find which endpoints will be kept, created and deleted.
  QMap<config::endpoint, processing::failover*> to_delete(current);
  for (QList<config::endpoint>::const_iterator it = new_endpoints.begin(),
         end = new_endpoints.end();
       it != end;
       ++it) {
    QMap<config::endpoint, processing::failover*>::iterator endp(to_delete.find(*it));
    if (endp != to_delete.end())
      to_delete.erase(endp);
    else
      to_create.push_back(*it);
  }

  // Remove old endpoints.
  for (QMap<config::endpoint, processing::failover*>::iterator it = to_delete.begin(),
         end = to_delete.end();
       it != end;
       ++it) {
    // XXX : send only termination request, object will
    //       be destroyed by event loop on termination.
    //       But wait for threads, because
  }

  return ;
}

/**************************************
*                                     *
*           Public Methods            *
*                                     *
**************************************/

/**
 *  Destructor.
 */
endpoint::~endpoint() {}

/**
 *  Apply the endpoint configuration.
 *
 *  @param[in] inputs  Inputs configuration.
 *  @param[in] outputs Outputs configuration.
 */
void endpoint::apply(QList<config::endpoint> const& inputs,
                     QList<config::endpoint> const& outputs) {
  // Remove old inputs and generate inputs to create.
  QList<config::endpoint> in_to_create;
  _diff_endpoints(_inputs, inputs, in_to_create);

  // Remove old outputs and generate outputs to create.
  QList<config::endpoint> out_to_create;
  _diff_endpoints(_outputs, outputs, out_to_create);

  // Create new outputs.
  for (QList<config::endpoint>::iterator it = out_to_create.begin(),
         end = out_to_create.end();
       it != end;
       ++it)
    _create_endpoint(*it, true);

  // Create new inputs.
  for (QList<config::endpoint>::iterator it = in_to_create.begin(),
         end = in_to_create.end();
       it != end;
       ++it)
    _create_endpoint(*it, false);

  return ;
}

/**
 *  Get the class instance.
 *
 *  @return Class instance.
 */
endpoint& endpoint::instance() {
  static endpoint gl_endpoint;
  return (gl_endpoint);
}

/**
 *  An input thread finished executing.
 */
void endpoint::terminated_input() {
  // XXX
}

/**
 *  An output thread finished executing.
 */
void endpoint::terminated_output() {
  // XXX
}
<commit_msg>Implementation of endpoint configuration applier is finished.<commit_after>/*
** Copyright 2011 Merethis
** This file is part of Centreon Broker.
**
** Centreon Broker is free software: you can redistribute it and/or
** modify it under the terms of the GNU General Public License version 2
** as published by the Free Software Foundation.
**
** Centreon Broker 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
** General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Centreon Broker. If not, see
** <http://www.gnu.org/licenses/>.
*/

#include <assert.h>
#include <stdlib.h>
#include "config/applier/endpoint.hh"
#include "exceptions/basic.hh"
#include "io/acceptor.hh"
#include "io/connector.hh"
#include "io/protocols.hh"

using namespace com::centreon::broker;
using namespace com::centreon::broker::config::applier;

/**************************************
*                                     *
*           Private Methods           *
*                                     *
**************************************/

/**
 *  Default constructor.
 */
endpoint::endpoint() : QObject() {}

/**
 *  @brief Copy constructor.
 *
 *  Any call to this constructor will result in a call to abort().
 *
 *  @param[in] e Object to copy.
 */
endpoint::endpoint(endpoint const& e) : QObject() {
  (void)e;
  assert(false);
  abort();
}

/**
 *  @brief Assignment operator.
 *
 *  Any call to this method will result in a call to abort().
 *
 *  @param[in] e Object to copy.
 *
 *  @return This object.
 */
endpoint& endpoint::operator=(endpoint const& e) {
  (void)e;
  assert(false);
  abort();
  return (*this);
}

/**
 *  Create and register an endpoint according to configuration.
 *
 *  @param[in] cfg       Endpoint configuration.
 *  @param[in] is_output true if the endpoint will act as output.
 */
void endpoint::_create_endpoint(config::endpoint const& cfg, bool is_output) {
  // Create endpoint object.
  QSharedPointer<io::endpoint> endp;
  bool is_acceptor;
  int level;
  for (QMap<QString, io::protocols::protocol>::const_iterator it = io::protocols::instance().begin(),
         end = io::protocols::instance().end();
       it != end;
       ++it) {
    if ((it.value().osi_from == 1)
        && it.value().endpntfactry->has_endpoint(cfg)) {
      endp = QSharedPointer<io::endpoint>(it.value().endpntfactry->new_endpoint(cfg, is_acceptor));
      level = it.value().osi_to + 1;
      break ;
    }
  }
  if (endp.isNull())
    throw (exceptions::basic() << "no matching protocol found for endpoint '"
             << cfg.name.toStdString().c_str() << "'");

  // Create remaining objects.
  io::endpoint* prev(endp.data());
  while (level <= 7) {
    // Browse protocol list.
    QMap<QString, io::protocols::protocol>::const_iterator it(io::protocols::instance().begin());
    QMap<QString, io::protocols::protocol>::const_iterator end(io::protocols::instance().end());
    while (it != end) {
      if ((it.value().osi_from == level)
          && (it.value().endpntfactry->has_endpoint(cfg))) {
        if (is_acceptor) {
          QSharedPointer<io::acceptor> current(static_cast<io::acceptor*>(it.value().endpntfactry->new_endpoint(cfg, is_acceptor)));
          static_cast<io::acceptor*>(prev)->on(current);
          prev = current.data();
        }
        else {
          QSharedPointer<io::connector> current(static_cast<io::connector*>(it.value().endpntfactry->new_endpoint(cfg, is_acceptor)));
          static_cast<io::connector*>(prev)->on(current);
          prev = current.data();
        }
        break ;
      }
      ++it;
    }
    if ((7 == level) && (it == end))
      throw (exceptions::basic() << "no matching protocol found for endpoint '"
               << cfg.name.toStdString().c_str() << "'");
    ++level;
  }

  // Create thread.
  QScopedPointer<processing::failover> fo(new processing::failover);
  fo->set_endpoint(endp,
    (is_output
       ? processing::failover::output
       : processing::failover::input));

  // Connect thread.
  connect(fo.data(), SIGNAL(finished()), fo.data(), SLOT(deleteLater));
  if (!is_output) {
    connect(fo.data(), SIGNAL(finished()), this, SLOT(terminated_input()));
    _inputs[cfg] = fo.data();
  }
  else {
    connect(fo.data(), SIGNAL(finished()), this, SLOT(terminated_output()));
    _outputs[cfg] = fo.data();
  }

  // Run thread.
  fo.take()->start();

  return ;
}

/**
 *  Diff the current configuration with the new configuration.
 *
 *  @param[in]  current       Current endpoints.
 *  @param[in]  new_endpoints New endpoints configuration.
 *  @param[out] to_create     Endpoints that should be created.
 */
void endpoint::_diff_endpoints(QMap<config::endpoint, processing::failover*> & current,
                               QList<config::endpoint> const& new_endpoints,
                               QList<config::endpoint>& to_create) {
  // Find which endpoints will be kept, created and deleted.
  QMap<config::endpoint, processing::failover*> to_delete(current);
  for (QList<config::endpoint>::const_iterator it = new_endpoints.begin(),
         end = new_endpoints.end();
       it != end;
       ++it) {
    QMap<config::endpoint, processing::failover*>::iterator endp(to_delete.find(*it));
    if (endp != to_delete.end())
      to_delete.erase(endp);
    else
      to_create.push_back(*it);
  }

  // Remove old endpoints.
  for (QMap<config::endpoint, processing::failover*>::iterator it = to_delete.begin(),
         end = to_delete.end();
       it != end;
       ++it) {
    // XXX : send only termination request, object will
    //       be destroyed by event loop on termination.
    //       But wait for threads, because
  }

  return ;
}

/**************************************
*                                     *
*           Public Methods            *
*                                     *
**************************************/

/**
 *  Destructor.
 */
endpoint::~endpoint() {}

/**
 *  Apply the endpoint configuration.
 *
 *  @param[in] inputs  Inputs configuration.
 *  @param[in] outputs Outputs configuration.
 */
void endpoint::apply(QList<config::endpoint> const& inputs,
                     QList<config::endpoint> const& outputs) {
  // Remove old inputs and generate inputs to create.
  QList<config::endpoint> in_to_create;
  _diff_endpoints(_inputs, inputs, in_to_create);

  // Remove old outputs and generate outputs to create.
  QList<config::endpoint> out_to_create;
  _diff_endpoints(_outputs, outputs, out_to_create);

  // Create new outputs.
  for (QList<config::endpoint>::iterator it = out_to_create.begin(),
         end = out_to_create.end();
       it != end;
       ++it)
    _create_endpoint(*it, true);

  // Create new inputs.
  for (QList<config::endpoint>::iterator it = in_to_create.begin(),
         end = in_to_create.end();
       it != end;
       ++it)
    _create_endpoint(*it, false);

  return ;
}

/**
 *  Get the class instance.
 *
 *  @return Class instance.
 */
endpoint& endpoint::instance() {
  static endpoint gl_endpoint;
  return (gl_endpoint);
}

/**
 *  An input thread finished executing.
 */
void endpoint::terminated_input() {
  // XXX
}

/**
 *  An output thread finished executing.
 */
void endpoint::terminated_output() {
  // XXX
}
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkPlotParallelCoordinates.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

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

#include "vtkPlotParallelCoordinates.h"

#include "vtkChartParallelCoordinates.h"
#include "vtkContext2D.h"
#include "vtkAxis.h"
#include "vtkPen.h"
#include "vtkFloatArray.h"
#include "vtkDoubleArray.h"
#include "vtkVector.h"
#include "vtkTransform2D.h"
#include "vtkContextDevice2D.h"
#include "vtkContextMapper2D.h"
#include "vtkPoints2D.h"
#include "vtkTable.h"
#include "vtkDataArray.h"
#include "vtkIdTypeArray.h"
#include "vtkStringArray.h"
#include "vtkTimeStamp.h"
#include "vtkInformation.h"
#include "vtkSmartPointer.h"

// Need to turn some arrays of strings into categories
#include "vtkStringToCategory.h"

#include "vtkObjectFactory.h"

#include "vtkstd/vector"
#include "vtkstd/algorithm"

class vtkPlotParallelCoordinates::Private :
    public vtkstd::vector< vtkstd::vector<float> >
{
public:
  Private()
  {
    this->SelectionInitialized = false;
  }

  vtkstd::vector<float> AxisPos;
  bool SelectionInitialized;
};

vtkCxxRevisionMacro(vtkPlotParallelCoordinates, "1.7");

//-----------------------------------------------------------------------------
vtkStandardNewMacro(vtkPlotParallelCoordinates);

//-----------------------------------------------------------------------------
vtkPlotParallelCoordinates::vtkPlotParallelCoordinates()
{
  this->Points = NULL;
  this->Storage = new vtkPlotParallelCoordinates::Private;
  this->Parent = NULL;
  this->Pen->SetColor(0, 0, 0, 25);
}

//-----------------------------------------------------------------------------
vtkPlotParallelCoordinates::~vtkPlotParallelCoordinates()
{
  if (this->Points)
    {
    this->Points->Delete();
    this->Points = NULL;
    }
  delete this->Storage;
}

//-----------------------------------------------------------------------------
void vtkPlotParallelCoordinates::Update()
{
  if (!this->Visible)
    {
    return;
    }
  // Check if we have an input
  vtkTable *table = this->Data->GetInput();
  if (!table)
    {
    vtkDebugMacro(<< "Update event called with no input table set.");
    return;
    }

  this->UpdateTableCache(table);
}

//-----------------------------------------------------------------------------
bool vtkPlotParallelCoordinates::Paint(vtkContext2D *painter)
{
  // This is where everything should be drawn, or dispatched to other methods.
  vtkDebugMacro(<< "Paint event called in vtkPlotParallelCoordinates.");

  if (!this->Visible)
    {
    return false;
    }

  // Now to plot the points
  if (this->Points)
    {
    painter->ApplyPen(this->Pen);
    painter->DrawPoly(this->Points);
    painter->GetPen()->SetLineType(vtkPen::SOLID_LINE);
    }

  painter->ApplyPen(this->Pen);

  if (this->Storage->size() == 0)
    {
    return false;
    }

  size_t cols = this->Storage->size();
  size_t rows = this->Storage->at(0).size();
  vtkVector2f* line = new vtkVector2f[cols];

  // Update the axis positions
  for (size_t i = 0; i < cols; ++i)
    {
    this->Storage->AxisPos[i] = this->Parent->GetAxis(int(i)) ?
                                this->Parent->GetAxis(int(i))->GetPoint1()[0] :
                                0;
    }

  vtkIdType selection = 0;
  vtkIdType id = 0;
  vtkIdType selectionSize = 0;
  if (this->Selection)
    {
    selectionSize = this->Selection->GetNumberOfTuples();
    if (selectionSize)
      {
      this->Selection->GetTupleValue(selection, &id);
      }
    }

  // Draw all of the lines
  painter->ApplyPen(this->Pen);
  for (size_t i = 0; i < rows; ++i)
    {
    for (size_t j = 0; j < cols; ++j)
      {
      line[j].Set(this->Storage->AxisPos[j], (*this->Storage)[j][i]);
      }
    painter->DrawPoly(line[0].GetData(), static_cast<int>(cols));
    }

  // Now draw the selected lines
  if (this->Selection)
    {
    painter->GetPen()->SetColor(255, 0, 0, 100);
    for (vtkIdType i = 0; i < this->Selection->GetNumberOfTuples(); ++i)
      {
      for (size_t j = 0; j < cols; ++j)
        {
        this->Selection->GetTupleValue(i, &id);
        line[j].Set(this->Storage->AxisPos[j], (*this->Storage)[j][id]);
        }
      painter->DrawPoly(line[0].GetData(), static_cast<int>(cols));
      }
    }

  delete[] line;

  return true;
}

//-----------------------------------------------------------------------------
bool vtkPlotParallelCoordinates::PaintLegend(vtkContext2D *painter, float rect[4])
{
  painter->ApplyPen(this->Pen);
  painter->DrawLine(rect[0], rect[1]+0.5*rect[3],
                    rect[0]+rect[2], rect[1]+0.5*rect[3]);
  return true;
}

//-----------------------------------------------------------------------------
void vtkPlotParallelCoordinates::GetBounds(double *)
{

}

//-----------------------------------------------------------------------------
bool vtkPlotParallelCoordinates::GetNearestPoint(const vtkVector2f& ,
                                  const vtkVector2f& ,
                                  vtkVector2f* )
{
  return false;
}

//-----------------------------------------------------------------------------
void vtkPlotParallelCoordinates::SetParent(vtkChartParallelCoordinates* parent)
{
  this->Parent = parent;
}

//-----------------------------------------------------------------------------
bool vtkPlotParallelCoordinates::SetSelectionRange(int axis, float low,
                                                   float high)
{
  if (!this->Selection)
    {
    return false;
    }
  if (this->Storage->SelectionInitialized)
    {
    // Further refine the selection that has already been made
    vtkIdTypeArray *array = vtkIdTypeArray::New();
    vtkstd::vector<float>& col = this->Storage->at(axis);
    for (vtkIdType i = 0; i < this->Selection->GetNumberOfTuples(); ++i)
      {
      vtkIdType id = 0;
      this->Selection->GetTupleValue(i, &id);
      if (col[id] >= low && col[id] <= high)
        {
        // Remove this point - no longer selected
        array->InsertNextValue(id);
        }
      }
    this->Selection->DeepCopy(array);
    array->Delete();
    }
  else
    {
    // First run - ensure the selection list is empty and build it up
    vtkstd::vector<float>& col = this->Storage->at(axis);
    for (size_t i = 0; i < col.size(); ++i)
      {
      if (col[i] >= low && col[i] <= high)
        {
        // Remove this point - no longer selected
        this->Selection->InsertNextValue(i);
        }
      }
    this->Storage->SelectionInitialized = true;
    }
  return true;
}

//-----------------------------------------------------------------------------
bool vtkPlotParallelCoordinates::ResetSelectionRange()
{
  this->Storage->SelectionInitialized = false;
  if (this->Selection)
    {
    this->Selection->SetNumberOfTuples(0);
    }
  return true;
}

//-----------------------------------------------------------------------------
void vtkPlotParallelCoordinates::SetInput(vtkTable* table)
{
  if (table == this->Data->GetInput())
    {
    return;
    }

  this->vtkPlot::SetInput(table);
  if (this->Parent)
    {
    // By default make the first 10 columns visible in a plot.
    for (vtkIdType i = 0; i < table->GetNumberOfColumns() && i < 10; ++i)
      {
      this->Parent->SetColumnVisibility(table->GetColumnName(i), true);
      }
    }
}

//-----------------------------------------------------------------------------
bool vtkPlotParallelCoordinates::UpdateTableCache(vtkTable *table)
{
  // Each axis is a column in our storage array, they are scaled from 0.0 to 1.0
  if (!this->Parent || !table || table->GetNumberOfColumns() == 0)
    {
    return false;
    }

  vtkStringArray* cols = this->Parent->GetVisibleColumns();
  this->Storage->resize(cols->GetNumberOfTuples());
  this->Storage->AxisPos.resize(cols->GetNumberOfTuples());
  vtkIdType rows = table->GetNumberOfRows();

  for (vtkIdType i = 0; i < cols->GetNumberOfTuples(); ++i)
    {
    vtkstd::vector<float>& col = this->Storage->at(i);
    vtkAxis* axis = this->Parent->GetAxis(i);
    col.resize(rows);
    vtkSmartPointer<vtkDataArray> data =
        vtkDataArray::SafeDownCast(table->GetColumnByName(cols->GetValue(i)));
    if (!data)
      {
      if (table->GetColumnByName(cols->GetValue(i))->IsA("vtkStringArray"))
        {
        // We have a different kind of column - attempt to make it into an enum
        vtkStringToCategory* stoc = vtkStringToCategory::New();
        stoc->SetInput(table);
        stoc->SetInputArrayToProcess(0, 0, 0,
                                     vtkDataObject::FIELD_ASSOCIATION_ROWS,
                                     cols->GetValue(i));
        stoc->SetCategoryArrayName("enumPC");
        stoc->Update();
        vtkTable* table2 = vtkTable::SafeDownCast(stoc->GetOutput());
        vtkTable* stringTable = vtkTable::SafeDownCast(stoc->GetOutput(1));
        if (table2)
          {
          data = vtkDataArray::SafeDownCast(table2->GetColumnByName("enumPC"));
          }
        if (stringTable && stringTable->GetColumnByName("Strings"))
          {
          vtkStringArray* strings =
              vtkStringArray::SafeDownCast(stringTable->GetColumnByName("Strings"));
          vtkSmartPointer<vtkDoubleArray> arr =
              vtkSmartPointer<vtkDoubleArray>::New();
          for (vtkIdType j = 0; j < strings->GetNumberOfTuples(); ++j)
            {
            arr->InsertNextValue(j);
            }
          // Now we need to set the range on the string axis
          axis->SetTickLabels(strings);
          axis->SetTickPositions(arr);
          axis->SetRange(0.0, strings->GetNumberOfTuples()-1);
          axis->Update();
          }
        stoc->Delete();
        }
      // If we still don't have a valid data array then skip this column.
      if (!data)
        {
        continue;
        }
      }

    // Also need the range from the appropriate axis, to normalize points
    float min = axis->GetMinimum();
    float max = axis->GetMaximum();
    float scale = 1.0f / (max - min);

    for (vtkIdType j = 0; j < rows; ++j)
      {
      col[j] = (data->GetTuple1(j)-min) * scale;
      }
    }

  this->BuildTime.Modified();
  return true;
}

//-----------------------------------------------------------------------------
void vtkPlotParallelCoordinates::PrintSelf(ostream &os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
}
<commit_msg>BUG: Handle the case where there is only one enum.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkPlotParallelCoordinates.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

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

#include "vtkPlotParallelCoordinates.h"

#include "vtkChartParallelCoordinates.h"
#include "vtkContext2D.h"
#include "vtkAxis.h"
#include "vtkPen.h"
#include "vtkFloatArray.h"
#include "vtkDoubleArray.h"
#include "vtkVector.h"
#include "vtkTransform2D.h"
#include "vtkContextDevice2D.h"
#include "vtkContextMapper2D.h"
#include "vtkPoints2D.h"
#include "vtkTable.h"
#include "vtkDataArray.h"
#include "vtkIdTypeArray.h"
#include "vtkStringArray.h"
#include "vtkTimeStamp.h"
#include "vtkInformation.h"
#include "vtkSmartPointer.h"

// Need to turn some arrays of strings into categories
#include "vtkStringToCategory.h"

#include "vtkObjectFactory.h"

#include "vtkstd/vector"
#include "vtkstd/algorithm"

class vtkPlotParallelCoordinates::Private :
    public vtkstd::vector< vtkstd::vector<float> >
{
public:
  Private()
  {
    this->SelectionInitialized = false;
  }

  vtkstd::vector<float> AxisPos;
  bool SelectionInitialized;
};

vtkCxxRevisionMacro(vtkPlotParallelCoordinates, "1.8");

//-----------------------------------------------------------------------------
vtkStandardNewMacro(vtkPlotParallelCoordinates);

//-----------------------------------------------------------------------------
vtkPlotParallelCoordinates::vtkPlotParallelCoordinates()
{
  this->Points = NULL;
  this->Storage = new vtkPlotParallelCoordinates::Private;
  this->Parent = NULL;
  this->Pen->SetColor(0, 0, 0, 25);
}

//-----------------------------------------------------------------------------
vtkPlotParallelCoordinates::~vtkPlotParallelCoordinates()
{
  if (this->Points)
    {
    this->Points->Delete();
    this->Points = NULL;
    }
  delete this->Storage;
}

//-----------------------------------------------------------------------------
void vtkPlotParallelCoordinates::Update()
{
  if (!this->Visible)
    {
    return;
    }
  // Check if we have an input
  vtkTable *table = this->Data->GetInput();
  if (!table)
    {
    vtkDebugMacro(<< "Update event called with no input table set.");
    return;
    }

  this->UpdateTableCache(table);
}

//-----------------------------------------------------------------------------
bool vtkPlotParallelCoordinates::Paint(vtkContext2D *painter)
{
  // This is where everything should be drawn, or dispatched to other methods.
  vtkDebugMacro(<< "Paint event called in vtkPlotParallelCoordinates.");

  if (!this->Visible)
    {
    return false;
    }

  // Now to plot the points
  if (this->Points)
    {
    painter->ApplyPen(this->Pen);
    painter->DrawPoly(this->Points);
    painter->GetPen()->SetLineType(vtkPen::SOLID_LINE);
    }

  painter->ApplyPen(this->Pen);

  if (this->Storage->size() == 0)
    {
    return false;
    }

  size_t cols = this->Storage->size();
  size_t rows = this->Storage->at(0).size();
  vtkVector2f* line = new vtkVector2f[cols];

  // Update the axis positions
  for (size_t i = 0; i < cols; ++i)
    {
    this->Storage->AxisPos[i] = this->Parent->GetAxis(int(i)) ?
                                this->Parent->GetAxis(int(i))->GetPoint1()[0] :
                                0;
    }

  vtkIdType selection = 0;
  vtkIdType id = 0;
  vtkIdType selectionSize = 0;
  if (this->Selection)
    {
    selectionSize = this->Selection->GetNumberOfTuples();
    if (selectionSize)
      {
      this->Selection->GetTupleValue(selection, &id);
      }
    }

  // Draw all of the lines
  painter->ApplyPen(this->Pen);
  for (size_t i = 0; i < rows; ++i)
    {
    for (size_t j = 0; j < cols; ++j)
      {
      line[j].Set(this->Storage->AxisPos[j], (*this->Storage)[j][i]);
      }
    painter->DrawPoly(line[0].GetData(), static_cast<int>(cols));
    }

  // Now draw the selected lines
  if (this->Selection)
    {
    painter->GetPen()->SetColor(255, 0, 0, 100);
    for (vtkIdType i = 0; i < this->Selection->GetNumberOfTuples(); ++i)
      {
      for (size_t j = 0; j < cols; ++j)
        {
        this->Selection->GetTupleValue(i, &id);
        line[j].Set(this->Storage->AxisPos[j], (*this->Storage)[j][id]);
        }
      painter->DrawPoly(line[0].GetData(), static_cast<int>(cols));
      }
    }

  delete[] line;

  return true;
}

//-----------------------------------------------------------------------------
bool vtkPlotParallelCoordinates::PaintLegend(vtkContext2D *painter, float rect[4])
{
  painter->ApplyPen(this->Pen);
  painter->DrawLine(rect[0], rect[1]+0.5*rect[3],
                    rect[0]+rect[2], rect[1]+0.5*rect[3]);
  return true;
}

//-----------------------------------------------------------------------------
void vtkPlotParallelCoordinates::GetBounds(double *)
{

}

//-----------------------------------------------------------------------------
bool vtkPlotParallelCoordinates::GetNearestPoint(const vtkVector2f& ,
                                  const vtkVector2f& ,
                                  vtkVector2f* )
{
  return false;
}

//-----------------------------------------------------------------------------
void vtkPlotParallelCoordinates::SetParent(vtkChartParallelCoordinates* parent)
{
  this->Parent = parent;
}

//-----------------------------------------------------------------------------
bool vtkPlotParallelCoordinates::SetSelectionRange(int axis, float low,
                                                   float high)
{
  if (!this->Selection)
    {
    return false;
    }
  if (this->Storage->SelectionInitialized)
    {
    // Further refine the selection that has already been made
    vtkIdTypeArray *array = vtkIdTypeArray::New();
    vtkstd::vector<float>& col = this->Storage->at(axis);
    for (vtkIdType i = 0; i < this->Selection->GetNumberOfTuples(); ++i)
      {
      vtkIdType id = 0;
      this->Selection->GetTupleValue(i, &id);
      if (col[id] >= low && col[id] <= high)
        {
        // Remove this point - no longer selected
        array->InsertNextValue(id);
        }
      }
    this->Selection->DeepCopy(array);
    array->Delete();
    }
  else
    {
    // First run - ensure the selection list is empty and build it up
    vtkstd::vector<float>& col = this->Storage->at(axis);
    for (size_t i = 0; i < col.size(); ++i)
      {
      if (col[i] >= low && col[i] <= high)
        {
        // Remove this point - no longer selected
        this->Selection->InsertNextValue(i);
        }
      }
    this->Storage->SelectionInitialized = true;
    }
  return true;
}

//-----------------------------------------------------------------------------
bool vtkPlotParallelCoordinates::ResetSelectionRange()
{
  this->Storage->SelectionInitialized = false;
  if (this->Selection)
    {
    this->Selection->SetNumberOfTuples(0);
    }
  return true;
}

//-----------------------------------------------------------------------------
void vtkPlotParallelCoordinates::SetInput(vtkTable* table)
{
  if (table == this->Data->GetInput())
    {
    return;
    }

  this->vtkPlot::SetInput(table);
  if (this->Parent)
    {
    // By default make the first 10 columns visible in a plot.
    for (vtkIdType i = 0; i < table->GetNumberOfColumns() && i < 10; ++i)
      {
      this->Parent->SetColumnVisibility(table->GetColumnName(i), true);
      }
    }
}

//-----------------------------------------------------------------------------
bool vtkPlotParallelCoordinates::UpdateTableCache(vtkTable *table)
{
  // Each axis is a column in our storage array, they are scaled from 0.0 to 1.0
  if (!this->Parent || !table || table->GetNumberOfColumns() == 0)
    {
    return false;
    }

  vtkStringArray* cols = this->Parent->GetVisibleColumns();
  this->Storage->resize(cols->GetNumberOfTuples());
  this->Storage->AxisPos.resize(cols->GetNumberOfTuples());
  vtkIdType rows = table->GetNumberOfRows();

  for (vtkIdType i = 0; i < cols->GetNumberOfTuples(); ++i)
    {
    vtkstd::vector<float>& col = this->Storage->at(i);
    vtkAxis* axis = this->Parent->GetAxis(i);
    col.resize(rows);
    vtkSmartPointer<vtkDataArray> data =
        vtkDataArray::SafeDownCast(table->GetColumnByName(cols->GetValue(i)));
    if (!data)
      {
      if (table->GetColumnByName(cols->GetValue(i))->IsA("vtkStringArray"))
        {
        // We have a different kind of column - attempt to make it into an enum
        vtkStringToCategory* stoc = vtkStringToCategory::New();
        stoc->SetInput(table);
        stoc->SetInputArrayToProcess(0, 0, 0,
                                     vtkDataObject::FIELD_ASSOCIATION_ROWS,
                                     cols->GetValue(i));
        stoc->SetCategoryArrayName("enumPC");
        stoc->Update();
        vtkTable* table2 = vtkTable::SafeDownCast(stoc->GetOutput());
        vtkTable* stringTable = vtkTable::SafeDownCast(stoc->GetOutput(1));
        if (table2)
          {
          data = vtkDataArray::SafeDownCast(table2->GetColumnByName("enumPC"));
          }
        if (stringTable && stringTable->GetColumnByName("Strings"))
          {
          vtkStringArray* strings =
              vtkStringArray::SafeDownCast(stringTable->GetColumnByName("Strings"));
          vtkSmartPointer<vtkDoubleArray> arr =
              vtkSmartPointer<vtkDoubleArray>::New();
          for (vtkIdType j = 0; j < strings->GetNumberOfTuples(); ++j)
            {
            arr->InsertNextValue(j);
            }
          // Now we need to set the range on the string axis
          axis->SetTickLabels(strings);
          axis->SetTickPositions(arr);
          if (strings->GetNumberOfTuples() > 1)
            {
            axis->SetRange(0.0, strings->GetNumberOfTuples()-1);
            }
          else
            {
            axis->SetRange(-0.1, 0.1);
            }
          axis->Update();
          }
        stoc->Delete();
        }
      // If we still don't have a valid data array then skip this column.
      if (!data)
        {
        continue;
        }
      }

    // Also need the range from the appropriate axis, to normalize points
    float min = axis->GetMinimum();
    float max = axis->GetMaximum();
    float scale = 1.0f / (max - min);

    for (vtkIdType j = 0; j < rows; ++j)
      {
      col[j] = (data->GetTuple1(j)-min) * scale;
      }
    }

  this->BuildTime.Modified();
  return true;
}

//-----------------------------------------------------------------------------
void vtkPlotParallelCoordinates::PrintSelf(ostream &os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
 */

#ifndef UAVCAN_NODE_SCHEDULER_HPP_INCLUDED
#define UAVCAN_NODE_SCHEDULER_HPP_INCLUDED

#include <uavcan/error.hpp>
#include <uavcan/util/linked_list.hpp>
#include <uavcan/transport/dispatcher.hpp>

namespace uavcan
{

class UAVCAN_EXPORT Scheduler;

class UAVCAN_EXPORT DeadlineHandler : public LinkedListNode<DeadlineHandler>, Noncopyable
{
    MonotonicTime deadline_;

protected:
    Scheduler& scheduler_;

    explicit DeadlineHandler(Scheduler& scheduler)
        : scheduler_(scheduler)
    { }

    virtual ~DeadlineHandler() { stop(); }

public:
    virtual void handleDeadline(MonotonicTime current) = 0;

    void startWithDeadline(MonotonicTime deadline);
    void startWithDelay(MonotonicDuration delay);

    void stop();

    bool isRunning() const;

    MonotonicTime getDeadline() const { return deadline_; }
    Scheduler& getScheduler() const { return scheduler_; }
};

class UAVCAN_EXPORT DeadlineScheduler : Noncopyable
{
    LinkedListRoot<DeadlineHandler> handlers_;  // Ordered by deadline, lowest first

public:
    void add(DeadlineHandler* mdh);
    void remove(DeadlineHandler* mdh);
    bool doesExist(const DeadlineHandler* mdh) const;
    unsigned getNumHandlers() const { return handlers_.getLength(); }

    MonotonicTime pollAndGetMonotonicTime(ISystemClock& sysclock);
    MonotonicTime getEarliestDeadline() const;
};

/**
 * This class distributes processing time between library components (IO handling, deadline callbacks, ...).
 */
class UAVCAN_EXPORT Scheduler : Noncopyable
{
    enum { DefaultDeadlineResolutionMs = 5 };
    enum { MinDeadlineResolutionMs = 1 };
    enum { MaxDeadlineResolutionMs = 100 };

    enum { DefaultCleanupPeriodMs = 1000 };
    enum { MinCleanupPeriodMs = 10 };
    enum { MaxCleanupPeriodMs = 10000 };

    DeadlineScheduler deadline_scheduler_;
    Dispatcher dispatcher_;
    MonotonicTime prev_cleanup_ts_;
    MonotonicDuration deadline_resolution_;
    MonotonicDuration cleanup_period_;
    bool inside_spin_;

    MonotonicTime computeDispatcherSpinDeadline(MonotonicTime spin_deadline) const;
    void pollCleanup(MonotonicTime mono_ts, uint32_t num_frames_processed_with_last_spin);

public:
    Scheduler(ICanDriver& can_driver, IPoolAllocator& allocator, ISystemClock& sysclock, IOutgoingTransferRegistry& otr)
        : dispatcher_(can_driver, allocator, sysclock, otr)
        , prev_cleanup_ts_(sysclock.getMonotonic())
        , deadline_resolution_(MonotonicDuration::fromMSec(DefaultDeadlineResolutionMs))
        , cleanup_period_(MonotonicDuration::fromMSec(DefaultCleanupPeriodMs))
        , inside_spin_(false)
    { }

    /**
     * Spin until the deadline, or until some error occurs.
     * Returns negative error code.
     */
    int spin(MonotonicTime deadline);

    DeadlineScheduler& getDeadlineScheduler() { return deadline_scheduler_; }

    Dispatcher& getDispatcher()             { return dispatcher_; }
    const Dispatcher& getDispatcher() const { return dispatcher_; }

    ISystemClock& getSystemClock()         { return dispatcher_.getSystemClock(); }
    MonotonicTime getMonotonicTime() const { return dispatcher_.getSystemClock().getMonotonic(); }
    UtcTime getUtcTime()             const { return dispatcher_.getSystemClock().getUtc(); }

    /**
     * Worst case deadline callback resolution.
     * Higher resolution increases CPU usage.
     */
    MonotonicDuration getDeadlineResolution() const { return deadline_resolution_; }
    void setDeadlineResolution(MonotonicDuration res)
    {
        res = min(res, MonotonicDuration::fromMSec(MaxDeadlineResolutionMs));
        res = max(res, MonotonicDuration::fromMSec(MinDeadlineResolutionMs));
        deadline_resolution_ = res;
    }

    /**
     * How often the scheduler will run cleanup (listeners, outgoing transfer registry, ...).
     * Cleanup execution time grows linearly with number of listeners and number of items
     * in the Outgoing Transfer ID registry.
     * Lower period increases CPU usage.
     */
    MonotonicDuration getCleanupPeriod() const { return cleanup_period_; }
    void setCleanupPeriod(MonotonicDuration period)
    {
        period = min(period, MonotonicDuration::fromMSec(MaxCleanupPeriodMs));
        period = max(period, MonotonicDuration::fromMSec(MinCleanupPeriodMs));
        cleanup_period_ = period;
    }
};

}

#endif // UAVCAN_NODE_SCHEDULER_HPP_INCLUDED
<commit_msg>Method to generate immediate deadlines in DeadlineHandler<commit_after>/*
 * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
 */

#ifndef UAVCAN_NODE_SCHEDULER_HPP_INCLUDED
#define UAVCAN_NODE_SCHEDULER_HPP_INCLUDED

#include <uavcan/error.hpp>
#include <uavcan/util/linked_list.hpp>
#include <uavcan/transport/dispatcher.hpp>

namespace uavcan
{

class UAVCAN_EXPORT Scheduler;

class UAVCAN_EXPORT DeadlineHandler : public LinkedListNode<DeadlineHandler>, Noncopyable
{
    MonotonicTime deadline_;

protected:
    Scheduler& scheduler_;

    explicit DeadlineHandler(Scheduler& scheduler)
        : scheduler_(scheduler)
    { }

    virtual ~DeadlineHandler() { stop(); }

public:
    virtual void handleDeadline(MonotonicTime current) = 0;

    void startWithDeadline(MonotonicTime deadline);
    void startWithDelay(MonotonicDuration delay);
    void generateDeadlineImmediately() { startWithDeadline(MonotonicTime::fromUSec(1)); }

    void stop();

    bool isRunning() const;

    MonotonicTime getDeadline() const { return deadline_; }
    Scheduler& getScheduler() const { return scheduler_; }
};

class UAVCAN_EXPORT DeadlineScheduler : Noncopyable
{
    LinkedListRoot<DeadlineHandler> handlers_;  // Ordered by deadline, lowest first

public:
    void add(DeadlineHandler* mdh);
    void remove(DeadlineHandler* mdh);
    bool doesExist(const DeadlineHandler* mdh) const;
    unsigned getNumHandlers() const { return handlers_.getLength(); }

    MonotonicTime pollAndGetMonotonicTime(ISystemClock& sysclock);
    MonotonicTime getEarliestDeadline() const;
};

/**
 * This class distributes processing time between library components (IO handling, deadline callbacks, ...).
 */
class UAVCAN_EXPORT Scheduler : Noncopyable
{
    enum { DefaultDeadlineResolutionMs = 5 };
    enum { MinDeadlineResolutionMs = 1 };
    enum { MaxDeadlineResolutionMs = 100 };

    enum { DefaultCleanupPeriodMs = 1000 };
    enum { MinCleanupPeriodMs = 10 };
    enum { MaxCleanupPeriodMs = 10000 };

    DeadlineScheduler deadline_scheduler_;
    Dispatcher dispatcher_;
    MonotonicTime prev_cleanup_ts_;
    MonotonicDuration deadline_resolution_;
    MonotonicDuration cleanup_period_;
    bool inside_spin_;

    MonotonicTime computeDispatcherSpinDeadline(MonotonicTime spin_deadline) const;
    void pollCleanup(MonotonicTime mono_ts, uint32_t num_frames_processed_with_last_spin);

public:
    Scheduler(ICanDriver& can_driver, IPoolAllocator& allocator, ISystemClock& sysclock, IOutgoingTransferRegistry& otr)
        : dispatcher_(can_driver, allocator, sysclock, otr)
        , prev_cleanup_ts_(sysclock.getMonotonic())
        , deadline_resolution_(MonotonicDuration::fromMSec(DefaultDeadlineResolutionMs))
        , cleanup_period_(MonotonicDuration::fromMSec(DefaultCleanupPeriodMs))
        , inside_spin_(false)
    { }

    /**
     * Spin until the deadline, or until some error occurs.
     * Returns negative error code.
     */
    int spin(MonotonicTime deadline);

    DeadlineScheduler& getDeadlineScheduler() { return deadline_scheduler_; }

    Dispatcher& getDispatcher()             { return dispatcher_; }
    const Dispatcher& getDispatcher() const { return dispatcher_; }

    ISystemClock& getSystemClock()         { return dispatcher_.getSystemClock(); }
    MonotonicTime getMonotonicTime() const { return dispatcher_.getSystemClock().getMonotonic(); }
    UtcTime getUtcTime()             const { return dispatcher_.getSystemClock().getUtc(); }

    /**
     * Worst case deadline callback resolution.
     * Higher resolution increases CPU usage.
     */
    MonotonicDuration getDeadlineResolution() const { return deadline_resolution_; }
    void setDeadlineResolution(MonotonicDuration res)
    {
        res = min(res, MonotonicDuration::fromMSec(MaxDeadlineResolutionMs));
        res = max(res, MonotonicDuration::fromMSec(MinDeadlineResolutionMs));
        deadline_resolution_ = res;
    }

    /**
     * How often the scheduler will run cleanup (listeners, outgoing transfer registry, ...).
     * Cleanup execution time grows linearly with number of listeners and number of items
     * in the Outgoing Transfer ID registry.
     * Lower period increases CPU usage.
     */
    MonotonicDuration getCleanupPeriod() const { return cleanup_period_; }
    void setCleanupPeriod(MonotonicDuration period)
    {
        period = min(period, MonotonicDuration::fromMSec(MaxCleanupPeriodMs));
        period = max(period, MonotonicDuration::fromMSec(MinCleanupPeriodMs));
        cleanup_period_ = period;
    }
};

}

#endif // UAVCAN_NODE_SCHEDULER_HPP_INCLUDED
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Monteverdi2
  Language:  C++

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See Copyright.txt for details.

  Monteverdi2 is distributed under the CeCILL licence version 2. See
  Licence_CeCILL_V2-en.txt or
  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt for more details.

  This software is distributed WITHOUT ANY WARRANTY; without even
  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  PURPOSE.  See the above copyright notices for more information.

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

#include "mvdDatabaseModel.h"

/*****************************************************************************/
/* INCLUDE SECTION                                                           */

//
// Qt includes (sorted by alphabetic order)
//// Must be included before system/custom includes.

//
// System includes (sorted by alphabetic order)

//
// ITK includes (sorted by alphabetic order)

//
// OTB includes (sorted by alphabetic order)

//
// Monteverdi includes (sorted by alphabetic order)
#include "mvdDatasetModel.h"
#include "mvdI18nApplication.h"

namespace mvd
{
/*
  TRANSLATOR mvd::DatabaseModel

  Necessary for lupdate to be aware of C++ namespaces.

  Context comment for translator.
*/

/*****************************************************************************/
/* CONSTANTS                                                                 */

/*****************************************************************************/
/* STATIC IMPLEMENTATION SECTION                                             */

/*****************************************************************************/
/* CLASS IMPLEMENTATION SECTION                                              */

/*******************************************************************************/
DatabaseModel
::DatabaseModel( QObject* parent ) :
  AbstractModel( parent ),
  m_DatasetModels(),
  m_SelectedDatasetModel( NULL )
{
}

/*******************************************************************************/
DatabaseModel
::~DatabaseModel()
{
}

/*******************************************************************************/
QStringList
DatabaseModel
::QueryDatasetModels() const
{
  QDir cacheDir( I18nApplication::ConstInstance()->GetCacheDir() );

  QStringList nameFilters;
  nameFilters << QString( "*%1" ).arg( I18nApplication::DATASET_EXT );

  /*
  cacheDir.setNameFilters( nameFilters );
  cacheDir.setFilter( QDir::Dirs | QDir::NoDotAndDotDot );
  cacheDir.setSorting( QDir::Name );
  */

  return cacheDir.entryList(
    nameFilters,
    QDir::Dirs | QDir::NoDotAndDotDot,
    QDir::Name
  );
}

/*******************************************************************************/
DatasetModel*
DatabaseModel
::SelectDatasetModel( const DatasetId& id )
{
  qDebug() << this << "::SelectDatasetModel(" << id << ")";

  // Find dataset model or interrupt by exception.
  DatasetModel* datasetModel = FindDatasetModel( id );
  assert( datasetModel!=NULL );

  try
    {
    // Load dataset sub-models.
    datasetModel->LoadImageModels( -1, -1 );

    // If dataset model has been loaded, select it.
    SetSelectedDatasetModel( datasetModel );
    }
  catch( std::exception& exc )
    {
    throw exc;
    }

  // Return loaded and selected dataset model.
  return datasetModel;
}

/*******************************************************************************/
void
DatabaseModel
::ReleaseDatasetModel( const DatasetId& id )
{
  qDebug() << this << "::ReleaseDatasetModel(" << id << ")";

  // Find (key, value) pair.
  DatasetModelMap::iterator it( DatasetModelIterator( id ) );

  delete it.value();
  it.value() = NULL;
}

/*******************************************************************************/
DatasetModel*
DatabaseModel
::NewDatasetModel( const DatasetId& id )
{
  qDebug() << this << "::NewDatasetModel(" << id << ")";

  // Find dataset model or interrupt by exception.
  DatasetModel* datasetModel = NULL;

  // Otherwise, load it from disk.
  try
    {
    // Create empty dataset model.
    datasetModel = new DatasetModel( this );

    // Build dataset model.
    assert( I18nApplication::ConstInstance() );

    DatasetModel::BuildContext context(
      I18nApplication::ConstInstance()->GetCacheDir().path(),
      id,
      false
    );

    datasetModel->BuildModel( &context );
    }

  catch( std::exception& exc )
    {
    // If loading was interrupted, delete allocated memory.
    delete datasetModel;
    datasetModel = NULL;

    // And forward interrupting exception.
    throw exc;
    }

  // Return loaded and selected dataset model.
  return datasetModel;
}

/*******************************************************************************/
void
DatabaseModel
::virtual_BuildModel( void* context )
{
  InitializeDatasetModels();
}

/**************************************************************************************************************************************************************/

/*******************************************************************************/
void
DatabaseModel
::InitializeDatasetModels()
{
  QStringList datasets( QueryDatasetModels() );

  ClearDatasetModels();

  for( QStringList::const_iterator it( datasets.begin() );
       it!=datasets.end();
       ++it )
    {
    try
      {
      DatasetModel* datasetModel = NewDatasetModel( *it );
      assert( datasetModel!=NULL );

      m_DatasetModels.insert( *it, datasetModel );
      }
    catch( std::exception& exc )
      {
      throw exc;
      }
    }
}

/*******************************************************************************/
void
DatabaseModel
::ClearDatasetModels()
{
  while( !m_DatasetModels.empty() )
    {
    DatasetModelMap::iterator it( m_DatasetModels.begin() );

    delete it.value();
    it.value() = NULL;

    it = m_DatasetModels.erase( it );
    }
}

/*******************************************************************************/
/* SLOTS                                                                       */
/*******************************************************************************/
void
DatabaseModel
::OnDatasetToDeleteSelected( const QString&  id)
{
  // TODO : pop up a Dialog widget ??

  // In DatabaseModel : delete from the map of datasets

  // In DatasetModel  : delete from disk

  // redraw the database widget

}

} // end namespace 'mvd'
<commit_msg>ENH: add verbosity<commit_after>/*=========================================================================

  Program:   Monteverdi2
  Language:  C++

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See Copyright.txt for details.

  Monteverdi2 is distributed under the CeCILL licence version 2. See
  Licence_CeCILL_V2-en.txt or
  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt for more details.

  This software is distributed WITHOUT ANY WARRANTY; without even
  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  PURPOSE.  See the above copyright notices for more information.

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

#include "mvdDatabaseModel.h"

/*****************************************************************************/
/* INCLUDE SECTION                                                           */

//
// Qt includes (sorted by alphabetic order)
//// Must be included before system/custom includes.

//
// System includes (sorted by alphabetic order)

//
// ITK includes (sorted by alphabetic order)

//
// OTB includes (sorted by alphabetic order)

//
// Monteverdi includes (sorted by alphabetic order)
#include "mvdDatasetModel.h"
#include "mvdI18nApplication.h"

namespace mvd
{
/*
  TRANSLATOR mvd::DatabaseModel

  Necessary for lupdate to be aware of C++ namespaces.

  Context comment for translator.
*/

/*****************************************************************************/
/* CONSTANTS                                                                 */

/*****************************************************************************/
/* STATIC IMPLEMENTATION SECTION                                             */

/*****************************************************************************/
/* CLASS IMPLEMENTATION SECTION                                              */

/*******************************************************************************/
DatabaseModel
::DatabaseModel( QObject* parent ) :
  AbstractModel( parent ),
  m_DatasetModels(),
  m_SelectedDatasetModel( NULL )
{
}

/*******************************************************************************/
DatabaseModel
::~DatabaseModel()
{
}

/*******************************************************************************/
QStringList
DatabaseModel
::QueryDatasetModels() const
{
  QDir cacheDir( I18nApplication::ConstInstance()->GetCacheDir() );

  QStringList nameFilters;
  nameFilters << QString( "*%1" ).arg( I18nApplication::DATASET_EXT );

  /*
  cacheDir.setNameFilters( nameFilters );
  cacheDir.setFilter( QDir::Dirs | QDir::NoDotAndDotDot );
  cacheDir.setSorting( QDir::Name );
  */

  return cacheDir.entryList(
    nameFilters,
    QDir::Dirs | QDir::NoDotAndDotDot,
    QDir::Name
  );
}

/*******************************************************************************/
DatasetModel*
DatabaseModel
::SelectDatasetModel( const DatasetId& id )
{
  qDebug() << this << "::SelectDatasetModel(" << id << ")";

  // Find dataset model or interrupt by exception.
  DatasetModel* datasetModel = FindDatasetModel( id );
  assert( datasetModel!=NULL );

  try
    {
    // Load dataset sub-models.
    datasetModel->LoadImageModels( -1, -1 );

    // If dataset model has been loaded, select it.
    SetSelectedDatasetModel( datasetModel );
    }
  catch( std::exception& exc )
    {
    throw exc;
    }

  // Return loaded and selected dataset model.
  return datasetModel;
}

/*******************************************************************************/
void
DatabaseModel
::ReleaseDatasetModel( const DatasetId& id )
{
  qDebug() << this << "::ReleaseDatasetModel(" << id << ")";

  // Find (key, value) pair.
  DatasetModelMap::iterator it( DatasetModelIterator( id ) );

  delete it.value();
  it.value() = NULL;
}

/*******************************************************************************/
DatasetModel*
DatabaseModel
::NewDatasetModel( const DatasetId& id )
{
  qDebug() << this << "::NewDatasetModel(" << id << ")";

  // Find dataset model or interrupt by exception.
  DatasetModel* datasetModel = NULL;

  // Otherwise, load it from disk.
  try
    {
    // Create empty dataset model.
    datasetModel = new DatasetModel( this );

    // Build dataset model.
    assert( I18nApplication::ConstInstance() );

    DatasetModel::BuildContext context(
      I18nApplication::ConstInstance()->GetCacheDir().path(),
      id,
      false
    );

    datasetModel->BuildModel( &context );
    }

  catch( std::exception& exc )
    {
    // If loading was interrupted, delete allocated memory.
    delete datasetModel;
    datasetModel = NULL;

    // And forward interrupting exception.
    throw exc;
    }

  // Return loaded and selected dataset model.
  return datasetModel;
}

/*******************************************************************************/
void
DatabaseModel
::virtual_BuildModel( void* context )
{
  InitializeDatasetModels();
}

/**************************************************************************************************************************************************************/

/*******************************************************************************/
void
DatabaseModel
::InitializeDatasetModels()
{
  QStringList datasets( QueryDatasetModels() );

  ClearDatasetModels();

  for( QStringList::const_iterator it( datasets.begin() );
       it!=datasets.end();
       ++it )
    {
    try
      {
      DatasetModel* datasetModel = NewDatasetModel( *it );
      assert( datasetModel!=NULL );

      m_DatasetModels.insert( *it, datasetModel );
      }
    catch( std::exception& exc )
      {
      throw exc;
      }
    }
}

/*******************************************************************************/
void
DatabaseModel
::ClearDatasetModels()
{
  while( !m_DatasetModels.empty() )
    {
    DatasetModelMap::iterator it( m_DatasetModels.begin() );

    delete it.value();
    it.value() = NULL;

    it = m_DatasetModels.erase( it );
    }
}

/*******************************************************************************/
/* SLOTS                                                                       */
/*******************************************************************************/
void
DatabaseModel
::OnDatasetToDeleteSelected( const QString&  id)
{
  qDebug() << this << " ::OnDatasetToDeleteSelected (WIP) -> Dataset to delete : "<< id;

  // TODO : pop up a Dialog widget ??

  // In DatabaseModel : delete from the map of datasets

  // In DatasetModel  : delete from disk

  // redraw the database widget

}

} // end namespace 'mvd'
<|endoftext|>