<commit_before>#include "ZoomViewOP.h"

#include "view/Camera.h"
#include "common/Settings.h"

namespace d2d
{

ZoomViewOP::ZoomViewOP(EditPanel* editPanel, bool bMouseMoveFocus,
					   bool bOpenRightTap, bool bOpenLeftTap)
	: AbstractEditOP(editPanel)
	, m_bMouseMoveFocus(bMouseMoveFocus)
	, m_openRightTap(bOpenRightTap)
	, m_openLeftTap(bOpenLeftTap)
	, m_onRightBtnPan(false)
{
	m_lastPos.setInvalid();
}

bool ZoomViewOP::onKeyDown(int keyCode)
{
	if (m_openLeftTap && keyCode == WXK_SPACE)
		m_editPanel->SetCursor(wxCURSOR_HAND);
	return false;
}

bool ZoomViewOP::onKeyUp(int keyCode)
{
	if (m_openLeftTap && keyCode == WXK_SPACE)
		m_editPanel->SetCursor(wxCURSOR_ARROW);
	return false;
}

bool ZoomViewOP::onMouseLeftDown(int x, int y)
{
	if (m_openLeftTap)
		m_lastPos.setInvalid();

	if (m_openLeftTap && wxGetKeyState(WXK_SPACE))
	{
		m_lastPos.set(x, y);
		return true;
	}
	else
	{
		return false;
	}
}

bool ZoomViewOP::onMouseLeftUp(int x, int y)
{
	if (m_openLeftTap && wxGetKeyState(WXK_SPACE))
	{
		m_lastPos.setInvalid();
		return true;
	}
	else
	{
		return false;
	}
}

bool ZoomViewOP::onMouseRightDown(int x, int y)
{
	if (m_openRightTap)
	{
		m_onRightBtnPan = true;
		m_lastPos.set(x, y);
		return true;
	}
	else
	{
		return false;
	}
}

bool ZoomViewOP::onMouseRightUp(int x, int y)
{
	if (m_openRightTap)
	{
		m_onRightBtnPan = false;
		m_lastPos.setInvalid();
		return true;
	}
	else
	{
		return false;
	}
}

bool ZoomViewOP::onMouseMove(int x, int y)
{
	if (m_bMouseMoveFocus)
		m_editPanel->SetFocus();

	return false;
}

bool ZoomViewOP::onMouseDrag(int x, int y)
{
	if (!m_openLeftTap) return false;

	if (wxGetKeyState(WXK_SPACE) || m_onRightBtnPan)
	{
		if (!m_lastPos.isValid())
			m_lastPos.set(x, y);
		else
		{
			Vector currPos(x, y);

			Vector cameraPos = m_editPanel->getCamera()->getCenter();
			Vector offset = m_lastPos - currPos;
			offset *= m_editPanel->getCamera()->getScale();
			offset.y = -offset.y;
			m_editPanel->getCamera()->setCenter(cameraPos + offset);

			m_lastPos = currPos;

			m_editPanel->Refresh();
		}
		return true;
	}
	else
	{
		m_lastPos.setInvalid();
		return false;
	}
}

bool ZoomViewOP::onMouseWheelRotation(int x, int y, int direction)
{
//	if (Settings::bZoomOnlyUseMouseWheel)
		m_editPanel->onMouseWheelRotation(x, y, direction);
// 	else
// 		m_editPanel->onMouseWheelRotation(m_editPanel->GetSize().GetWidth() * 0.5f, m_editPanel->GetSize().GetHeight() * 0.5f, direction);

	return false;
}

void ZoomViewOP::enableRightTap(bool enable)
{
	if (m_openRightTap == enable)
		return;

	m_openRightTap = enable;
	if (enable)
	{
		m_onRightBtnPan = true;
	}
	else
	{
		m_onRightBtnPan = false;
		m_lastPos.setInvalid();
	}
}

} // d2d<commit_msg>[ADDED] esc键重置摄像机<commit_after>#include "ZoomViewOP.h"

#include "view/Camera.h"
#include "common/Settings.h"

namespace d2d
{

ZoomViewOP::ZoomViewOP(EditPanel* editPanel, bool bMouseMoveFocus,
					   bool bOpenRightTap, bool bOpenLeftTap)
	: AbstractEditOP(editPanel)
	, m_bMouseMoveFocus(bMouseMoveFocus)
	, m_openRightTap(bOpenRightTap)
	, m_openLeftTap(bOpenLeftTap)
	, m_onRightBtnPan(false)
{
	m_lastPos.setInvalid();
}

bool ZoomViewOP::onKeyDown(int keyCode)
{
	if (m_openLeftTap && keyCode == WXK_SPACE) {
		m_editPanel->SetCursor(wxCURSOR_HAND);
	} else if (keyCode == WXK_ESCAPE) {
		Camera* cam = m_editPanel->getCamera();
		cam->setCenter(Vector(0, 0));
		cam->setScale(1.0f);
	}

	return false;
}

bool ZoomViewOP::onKeyUp(int keyCode)
{
	if (m_openLeftTap && keyCode == WXK_SPACE)
		m_editPanel->SetCursor(wxCURSOR_ARROW);
	return false;
}

bool ZoomViewOP::onMouseLeftDown(int x, int y)
{
	if (m_openLeftTap)
		m_lastPos.setInvalid();

	if (m_openLeftTap && wxGetKeyState(WXK_SPACE))
	{
		m_lastPos.set(x, y);
		return true;
	}
	else
	{
		return false;
	}
}

bool ZoomViewOP::onMouseLeftUp(int x, int y)
{
	if (m_openLeftTap && wxGetKeyState(WXK_SPACE))
	{
		m_lastPos.setInvalid();
		return true;
	}
	else
	{
		return false;
	}
}

bool ZoomViewOP::onMouseRightDown(int x, int y)
{
	if (m_openRightTap)
	{
		m_onRightBtnPan = true;
		m_lastPos.set(x, y);
		return true;
	}
	else
	{
		return false;
	}
}

bool ZoomViewOP::onMouseRightUp(int x, int y)
{
	if (m_openRightTap)
	{
		m_onRightBtnPan = false;
		m_lastPos.setInvalid();
		return true;
	}
	else
	{
		return false;
	}
}

bool ZoomViewOP::onMouseMove(int x, int y)
{
	if (m_bMouseMoveFocus)
		m_editPanel->SetFocus();

	return false;
}

bool ZoomViewOP::onMouseDrag(int x, int y)
{
	if (!m_openLeftTap) return false;

	if (wxGetKeyState(WXK_SPACE) || m_onRightBtnPan)
	{
		if (!m_lastPos.isValid())
			m_lastPos.set(x, y);
		else
		{
			Vector currPos(x, y);

			Vector cameraPos = m_editPanel->getCamera()->getCenter();
			Vector offset = m_lastPos - currPos;
			offset *= m_editPanel->getCamera()->getScale();
			offset.y = -offset.y;
			m_editPanel->getCamera()->setCenter(cameraPos + offset);

			m_lastPos = currPos;

			m_editPanel->Refresh();
		}
		return true;
	}
	else
	{
		m_lastPos.setInvalid();
		return false;
	}
}

bool ZoomViewOP::onMouseWheelRotation(int x, int y, int direction)
{
//	if (Settings::bZoomOnlyUseMouseWheel)
		m_editPanel->onMouseWheelRotation(x, y, direction);
// 	else
// 		m_editPanel->onMouseWheelRotation(m_editPanel->GetSize().GetWidth() * 0.5f, m_editPanel->GetSize().GetHeight() * 0.5f, direction);

	return false;
}

void ZoomViewOP::enableRightTap(bool enable)
{
	if (m_openRightTap == enable)
		return;

	m_openRightTap = enable;
	if (enable)
	{
		m_onRightBtnPan = true;
	}
	else
	{
		m_onRightBtnPan = false;
		m_lastPos.setInvalid();
	}
}

} // d2d<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef _FRM_GROUPMANAGER_HXX_
#define _FRM_GROUPMANAGER_HXX_

#include <com/sun/star/sdbc/XRowSet.hpp>
#include <com/sun/star/awt/XControlModel.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/beans/XPropertyChangeListener.hpp>
#include <com/sun/star/container/XContainerListener.hpp>
#include <com/sun/star/container/XContainer.hpp>
#include <comphelper/stl_types.hxx>
#include <cppuhelper/implbase2.hxx>
#include <comphelper/stl_types.hxx>
#include <comphelper/types.hxx>
using namespace comphelper;

/*========================================================================
Funktionsweise GroupManager:

Der GroupManager horcht an der starform, ob FormComponents eingefuegt oder entfernt
werden. Zusaetzlich horcht er bei den FormComponents an den Properties
"Name" und "TabIndex". Mit diesen Infos aktualisiert er seine Gruppen.

Der GroupManager verwaltet eine Gruppe, in der alle Controls nach TabIndex
geordnet sind, und ein Array von Gruppen, in dem jede FormComponent noch
einmal einer Gruppe dem Namen nach zugeordnet wird.
Die einzelnen Gruppen werden ueber eine Map aktiviert, wenn sie mehr als
ein Element besitzen.

Die Gruppen verwalten intern die FormComponents in zwei Arrays. In dem
GroupCompArray werden die Components nach TabIndex und Einfuegepostion
sortiert. Da auf dieses Array ueber die FormComponent zugegriffen
wird, gibt es noch das GroupCompAccessArray, in dem die FormComponents
nach ihrer Speicheradresse sortiert sind. Jedes Element des
GroupCompAccessArrays ist mit einem Element des GroupCompArrays verpointert.

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

//.........................................................................
namespace frm
{
//.........................................................................

//========================================================================
    template <class ELEMENT, class LESS_COMPARE>
    sal_Int32 insert_sorted(::std::vector<ELEMENT>& _rArray, const ELEMENT& _rNewElement, const LESS_COMPARE& _rCompareOp)
    {
        typename ::std::vector<ELEMENT>::iterator aInsertPos = ::std::lower_bound(
            _rArray.begin(),
            _rArray.end(),
            _rNewElement,
            _rCompareOp
        );
        aInsertPos = _rArray.insert(aInsertPos, _rNewElement);
        return aInsertPos - _rArray.begin();
    }

    template <class ELEMENT, class LESS_COMPARE>
    sal_Bool seek_entry(const ::std::vector<ELEMENT>& _rArray, const ELEMENT& _rNewElement, sal_Int32& nPos, const LESS_COMPARE& _rCompareOp)
    {
        typename ::std::vector<ELEMENT>::const_iterator aExistentPos = ::std::lower_bound(
            _rArray.begin(),
            _rArray.end(),
            _rNewElement,
            _rCompareOp
        );
        if ((aExistentPos != _rArray.end()) && (*aExistentPos == _rNewElement))
        {   // we have a valid "lower or equal" element and it's really "equal"
            nPos = aExistentPos - _rArray.begin();
            return sal_True;
        }
        nPos = -1;
        return sal_False;
    }

//========================================================================
class OGroupComp
{
    ::rtl::OUString m_aName;
    ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>    m_xComponent;
    ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel>     m_xControlModel;
    sal_Int32   m_nPos;
    sal_Int16   m_nTabIndex;

    friend class OGroupCompLess;

public:
    OGroupComp(const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& rxElement, sal_Int32 nInsertPos );
    OGroupComp(const OGroupComp& _rSource);
    OGroupComp();

    sal_Bool operator==( const OGroupComp& rComp ) const;

    inline const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& GetComponent() const { return m_xComponent; }
    inline const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel>&   GetControlModel() const { return m_xControlModel; }

    sal_Int32   GetPos() const { return m_nPos; }
    sal_Int16   GetTabIndex() const { return m_nTabIndex; }
    ::rtl::OUString GetName() const { return m_aName; }
};

DECLARE_STL_VECTOR(OGroupComp, OGroupCompArr);

//========================================================================
class OGroupComp;
class OGroupCompAcc
{
    ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>    m_xComponent;

    OGroupComp                                      m_aGroupComp;

    friend class OGroupCompAccLess;

public:
    OGroupCompAcc(const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& rxElement, const OGroupComp& _rGroupComp );

    sal_Bool operator==( const OGroupCompAcc& rCompAcc ) const;

    inline const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>&  GetComponent() const { return m_xComponent; }
    const OGroupComp&   GetGroupComponent() const { return m_aGroupComp; }
};

DECLARE_STL_VECTOR(OGroupCompAcc, OGroupCompAccArr);

//========================================================================
class OGroup
{
    OGroupCompArr       m_aCompArray;
    OGroupCompAccArr    m_aCompAccArray;

    ::rtl::OUString m_aGroupName;
    sal_uInt16  m_nInsertPos;               // Die Einfugeposition der GroupComps wird von der Gruppe bestimmt.

    friend class OGroupLess;

public:
    OGroup( const ::rtl::OUString& rGroupName );
#ifdef DBG_UTIL
    OGroup( const OGroup& _rSource );   // just to ensure the DBG_CTOR call
#endif
    virtual ~OGroup();

    sal_Bool operator==( const OGroup& rGroup ) const;

    ::rtl::OUString GetGroupName() const { return m_aGroupName; }
    ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel>  > GetControlModels() const;

    void InsertComponent( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& rxElement );
    void RemoveComponent( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& rxElement );
    sal_uInt16 Count() const { return sal::static_int_cast< sal_uInt16 >(m_aCompArray.size()); }
    const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& GetObject( sal_uInt16 nP ) const
        { return m_aCompArray[nP].GetComponent(); }
};

DECLARE_STL_USTRINGACCESS_MAP(OGroup, OGroupArr);
DECLARE_STL_VECTOR(OGroupArr::iterator, OActiveGroups);

//========================================================================
class OGroupManager : public ::cppu::WeakImplHelper2< ::com::sun::star::beans::XPropertyChangeListener, ::com::sun::star::container::XContainerListener>
{
    OGroup*         m_pCompGroup;           // Alle Components nach TabIndizes sortiert
    OGroupArr       m_aGroupArr;            // Alle Components nach Gruppen sortiert
    OActiveGroups   m_aActiveGroupMap;      // In dieser Map werden die Indizes aller Gruppen gehalten,
                                        // die mehr als 1 Element haben

    ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainer >
                    m_xContainer;

    // Helper functions
    void InsertElement( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& rxElement );
    void RemoveElement( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& rxElement );
    void removeFromGroupMap(const ::rtl::OUString& _sGroupName,const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& _xSet);

public:
    OGroupManager(const ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainer >& _rxContainer);
    virtual ~OGroupManager();

// ::com::sun::star::lang::XEventListener
    virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& _rSource) throw(::com::sun::star::uno::RuntimeException);

// ::com::sun::star::beans::XPropertyChangeListener
    virtual void SAL_CALL propertyChange(const ::com::sun::star::beans::PropertyChangeEvent& evt) throw ( ::com::sun::star::uno::RuntimeException);

// ::com::sun::star::container::XContainerListener
    virtual void SAL_CALL elementInserted(const ::com::sun::star::container::ContainerEvent& _rEvent) throw ( ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL elementRemoved(const ::com::sun::star::container::ContainerEvent& _rEvent) throw ( ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL elementReplaced(const ::com::sun::star::container::ContainerEvent& _rEvent) throw ( ::com::sun::star::uno::RuntimeException);

// Other functions
    sal_Int32 getGroupCount();
    void getGroup(sal_Int32 nGroup, ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel> >& _rGroup, ::rtl::OUString& Name);
    void getGroupByName(const ::rtl::OUString& Name, ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel> >& _rGroup);
    ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel> > getControlModels();

    static ::rtl::OUString GetGroupName( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet> xComponent );
};

//.........................................................................
}   // namespace frm
//.........................................................................

#endif // _FRM_GROUPMANAGER_HXX_

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>include algorithm for std::lower_bound<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef _FRM_GROUPMANAGER_HXX_
#define _FRM_GROUPMANAGER_HXX_

#include <com/sun/star/sdbc/XRowSet.hpp>
#include <com/sun/star/awt/XControlModel.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/beans/XPropertyChangeListener.hpp>
#include <com/sun/star/container/XContainerListener.hpp>
#include <com/sun/star/container/XContainer.hpp>
#include <comphelper/stl_types.hxx>
#include <cppuhelper/implbase2.hxx>
#include <comphelper/stl_types.hxx>
#include <comphelper/types.hxx>

#include <algorithm>

using namespace comphelper;

/*========================================================================
Funktionsweise GroupManager:

Der GroupManager horcht an der starform, ob FormComponents eingefuegt oder entfernt
werden. Zusaetzlich horcht er bei den FormComponents an den Properties
"Name" und "TabIndex". Mit diesen Infos aktualisiert er seine Gruppen.

Der GroupManager verwaltet eine Gruppe, in der alle Controls nach TabIndex
geordnet sind, und ein Array von Gruppen, in dem jede FormComponent noch
einmal einer Gruppe dem Namen nach zugeordnet wird.
Die einzelnen Gruppen werden ueber eine Map aktiviert, wenn sie mehr als
ein Element besitzen.

Die Gruppen verwalten intern die FormComponents in zwei Arrays. In dem
GroupCompArray werden die Components nach TabIndex und Einfuegepostion
sortiert. Da auf dieses Array ueber die FormComponent zugegriffen
wird, gibt es noch das GroupCompAccessArray, in dem die FormComponents
nach ihrer Speicheradresse sortiert sind. Jedes Element des
GroupCompAccessArrays ist mit einem Element des GroupCompArrays verpointert.

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

//.........................................................................
namespace frm
{
//.........................................................................

//========================================================================
    template <class ELEMENT, class LESS_COMPARE>
    sal_Int32 insert_sorted(::std::vector<ELEMENT>& _rArray, const ELEMENT& _rNewElement, const LESS_COMPARE& _rCompareOp)
    {
        typename ::std::vector<ELEMENT>::iterator aInsertPos = ::std::lower_bound(
            _rArray.begin(),
            _rArray.end(),
            _rNewElement,
            _rCompareOp
        );
        aInsertPos = _rArray.insert(aInsertPos, _rNewElement);
        return aInsertPos - _rArray.begin();
    }

    template <class ELEMENT, class LESS_COMPARE>
    sal_Bool seek_entry(const ::std::vector<ELEMENT>& _rArray, const ELEMENT& _rNewElement, sal_Int32& nPos, const LESS_COMPARE& _rCompareOp)
    {
        typename ::std::vector<ELEMENT>::const_iterator aExistentPos = ::std::lower_bound(
            _rArray.begin(),
            _rArray.end(),
            _rNewElement,
            _rCompareOp
        );
        if ((aExistentPos != _rArray.end()) && (*aExistentPos == _rNewElement))
        {   // we have a valid "lower or equal" element and it's really "equal"
            nPos = aExistentPos - _rArray.begin();
            return sal_True;
        }
        nPos = -1;
        return sal_False;
    }

//========================================================================
class OGroupComp
{
    ::rtl::OUString m_aName;
    ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>    m_xComponent;
    ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel>     m_xControlModel;
    sal_Int32   m_nPos;
    sal_Int16   m_nTabIndex;

    friend class OGroupCompLess;

public:
    OGroupComp(const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& rxElement, sal_Int32 nInsertPos );
    OGroupComp(const OGroupComp& _rSource);
    OGroupComp();

    sal_Bool operator==( const OGroupComp& rComp ) const;

    inline const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& GetComponent() const { return m_xComponent; }
    inline const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel>&   GetControlModel() const { return m_xControlModel; }

    sal_Int32   GetPos() const { return m_nPos; }
    sal_Int16   GetTabIndex() const { return m_nTabIndex; }
    ::rtl::OUString GetName() const { return m_aName; }
};

DECLARE_STL_VECTOR(OGroupComp, OGroupCompArr);

//========================================================================
class OGroupComp;
class OGroupCompAcc
{
    ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>    m_xComponent;

    OGroupComp                                      m_aGroupComp;

    friend class OGroupCompAccLess;

public:
    OGroupCompAcc(const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& rxElement, const OGroupComp& _rGroupComp );

    sal_Bool operator==( const OGroupCompAcc& rCompAcc ) const;

    inline const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>&  GetComponent() const { return m_xComponent; }
    const OGroupComp&   GetGroupComponent() const { return m_aGroupComp; }
};

DECLARE_STL_VECTOR(OGroupCompAcc, OGroupCompAccArr);

//========================================================================
class OGroup
{
    OGroupCompArr       m_aCompArray;
    OGroupCompAccArr    m_aCompAccArray;

    ::rtl::OUString m_aGroupName;
    sal_uInt16  m_nInsertPos;               // Die Einfugeposition der GroupComps wird von der Gruppe bestimmt.

    friend class OGroupLess;

public:
    OGroup( const ::rtl::OUString& rGroupName );
#ifdef DBG_UTIL
    OGroup( const OGroup& _rSource );   // just to ensure the DBG_CTOR call
#endif
    virtual ~OGroup();

    sal_Bool operator==( const OGroup& rGroup ) const;

    ::rtl::OUString GetGroupName() const { return m_aGroupName; }
    ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel>  > GetControlModels() const;

    void InsertComponent( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& rxElement );
    void RemoveComponent( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& rxElement );
    sal_uInt16 Count() const { return sal::static_int_cast< sal_uInt16 >(m_aCompArray.size()); }
    const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& GetObject( sal_uInt16 nP ) const
        { return m_aCompArray[nP].GetComponent(); }
};

DECLARE_STL_USTRINGACCESS_MAP(OGroup, OGroupArr);
DECLARE_STL_VECTOR(OGroupArr::iterator, OActiveGroups);

//========================================================================
class OGroupManager : public ::cppu::WeakImplHelper2< ::com::sun::star::beans::XPropertyChangeListener, ::com::sun::star::container::XContainerListener>
{
    OGroup*         m_pCompGroup;           // Alle Components nach TabIndizes sortiert
    OGroupArr       m_aGroupArr;            // Alle Components nach Gruppen sortiert
    OActiveGroups   m_aActiveGroupMap;      // In dieser Map werden die Indizes aller Gruppen gehalten,
                                        // die mehr als 1 Element haben

    ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainer >
                    m_xContainer;

    // Helper functions
    void InsertElement( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& rxElement );
    void RemoveElement( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& rxElement );
    void removeFromGroupMap(const ::rtl::OUString& _sGroupName,const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& _xSet);

public:
    OGroupManager(const ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainer >& _rxContainer);
    virtual ~OGroupManager();

// ::com::sun::star::lang::XEventListener
    virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& _rSource) throw(::com::sun::star::uno::RuntimeException);

// ::com::sun::star::beans::XPropertyChangeListener
    virtual void SAL_CALL propertyChange(const ::com::sun::star::beans::PropertyChangeEvent& evt) throw ( ::com::sun::star::uno::RuntimeException);

// ::com::sun::star::container::XContainerListener
    virtual void SAL_CALL elementInserted(const ::com::sun::star::container::ContainerEvent& _rEvent) throw ( ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL elementRemoved(const ::com::sun::star::container::ContainerEvent& _rEvent) throw ( ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL elementReplaced(const ::com::sun::star::container::ContainerEvent& _rEvent) throw ( ::com::sun::star::uno::RuntimeException);

// Other functions
    sal_Int32 getGroupCount();
    void getGroup(sal_Int32 nGroup, ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel> >& _rGroup, ::rtl::OUString& Name);
    void getGroupByName(const ::rtl::OUString& Name, ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel> >& _rGroup);
    ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel> > getControlModels();

    static ::rtl::OUString GetGroupName( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet> xComponent );
};

//.........................................................................
}   // namespace frm
//.........................................................................

#endif // _FRM_GROUPMANAGER_HXX_

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


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: SchXMLExportHelper.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: ihi $ $Date: 2007-11-23 11:33:58 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _XMLOFF_SCH_XMLEXPORTHELPER_HXX_
#define _XMLOFF_SCH_XMLEXPORTHELPER_HXX_

#ifndef _SAL_CONFIG_H_
#include "sal/config.h"
#endif

#ifndef INCLUDED_XMLOFF_DLLAPI_H
#include "xmloff/dllapi.h"
#endif

#ifndef _SAL_TYPES_H_
#include "sal/types.h"
#endif
#ifndef _UNIVERSALL_REFERENCE_HXX
#include <xmloff/uniref.hxx>
#endif
#ifndef _RTL_USTRBUF_HXX_
#include <rtl/ustrbuf.hxx>
#endif
#ifndef _COM_SUN_STAR_UTIL_XSTRINGMAPPING_HPP_
#include <com/sun/star/util/XStringMapping.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_SIZE_HPP_
#include <com/sun/star/awt/Size.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_POINT_HPP_
#include <com/sun/star/awt/Point.hpp>
#endif

#ifndef _XMLOFF_PROPERTYSETMAPPER_HXX
#include <xmloff/xmlprmap.hxx>
#endif

#include <queue>
#include <vector>

namespace com { namespace sun { namespace star {
    namespace chart {
        class XDiagram;
        class XChartDocument;
        class XChartDataArray;
        struct ChartSeriesAddress;
    }
    namespace chart2 {
        class XDiagram;
        class XChartDocument;
        class XDataSeries;
        namespace data
        {
            class XDataProvider;
            class XDataSequence;
        }
    }
    namespace drawing {
        class XShape;
        class XShapes;
    }
    namespace task {
        class XStatusIndicator;
    }
    namespace frame {
        class XModel;
    }
    namespace xml {
        namespace sax {
            class XAttributeList;
}}}}}

class SvXMLAutoStylePoolP;
class XMLChartExportPropertyMapper;
class SvXMLExport;
class XMLPropertyHandlerFactory;

/** With this class you can export a <chart:chart> element containing
    its data as <table:table> element or without internal table. In
    the latter case you have to provide a table address mapper if the
    cell addressing set at the document is not in XML format.
 */
class XMLOFF_DLLPUBLIC SchXMLExportHelper : public UniRefBase
{
public:
    // first: data sequence for label, second: data sequence for values.
    typedef ::std::pair< ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XDataSequence >,
            ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XDataSequence > > tLabelValuesDataPair;
    typedef ::std::vector< tLabelValuesDataPair > tDataSequenceCont;

private:
    SvXMLExport& mrExport;
    SvXMLAutoStylePoolP& mrAutoStylePool;
    UniReference< XMLPropertyHandlerFactory > mxPropertyHandlerFactory;
    UniReference< XMLPropertySetMapper > mxPropertySetMapper;
    UniReference< XMLChartExportPropertyMapper > mxExpPropMapper;

    rtl::OUString msTableName;
    rtl::OUStringBuffer msStringBuffer;
    rtl::OUString msString;

    // members filled by InitRangeSegmentationProperties (retrieved from DataProvider)
    sal_Bool mbHasSeriesLabels;
    sal_Bool mbHasCategoryLabels; //if the categories are only automatically generated this will be false
    sal_Bool mbRowSourceColumns;
    rtl::OUString msChartAddress;
    rtl::OUString msTableNumberList;
    ::com::sun::star::uno::Sequence< sal_Int32 > maSequenceMapping;

    rtl::OUString msCLSID;

    ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes > mxAdditionalShapes;

    tDataSequenceCont m_aDataSequencesToExport;

    /** first parseDocument: collect autostyles and store names in this queue
        second parseDocument: export content and use names from this queue
     */
    ::std::queue< ::rtl::OUString > maAutoStyleNameQueue;
    SAL_DLLPRIVATE void CollectAutoStyle(
        const std::vector< XMLPropertyState >& aStates );
    SAL_DLLPRIVATE void AddAutoStyleAttribute(
        const std::vector< XMLPropertyState >& aStates );

    SAL_DLLPRIVATE SvXMLAutoStylePoolP& GetAutoStylePoolP()
    { return mrAutoStylePool; }

    /// if bExportContent is false the auto-styles are collected
    SAL_DLLPRIVATE void parseDocument( com::sun::star::uno::Reference<
                            com::sun::star::chart::XChartDocument >& rChartDoc,
                        sal_Bool bExportContent,
                        sal_Bool bIncludeTable = sal_False );
    SAL_DLLPRIVATE void exportTable();
    SAL_DLLPRIVATE void exportPlotArea(
        com::sun::star::uno::Reference< com::sun::star::chart::XDiagram > xDiagram,
        com::sun::star::uno::Reference< com::sun::star::chart2::XDiagram > xNewDiagram,
        const ::com::sun::star::awt::Size & rPageSize,
        sal_Bool bExportContent,
        sal_Bool bIncludeTable );
    SAL_DLLPRIVATE void exportAxes( const com::sun::star::uno::Reference< com::sun::star::chart::XDiagram > & xDiagram,
                                    const com::sun::star::uno::Reference< com::sun::star::chart2::XDiagram > & xNewDiagram,
                                    sal_Bool bExportContent );

    SAL_DLLPRIVATE void exportSeries(
        const com::sun::star::uno::Reference< com::sun::star::chart2::XDiagram > & xNewDiagram,
        const ::com::sun::star::awt::Size & rPageSize,
        sal_Bool bExportContent,
        sal_Bool bHasTwoYAxes );
    SAL_DLLPRIVATE void exportCandleStickSeries(
        const ::com::sun::star::uno::Sequence<
            ::com::sun::star::uno::Reference<
                ::com::sun::star::chart2::XDataSeries > > & aSeriesSeq,
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::chart2::XDiagram > & xDiagram,
        sal_Bool bJapaneseCandleSticks,
        sal_Bool bExportContent );
    SAL_DLLPRIVATE void exportDataPoints(
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::beans::XPropertySet > & xSeriesProperties,
        sal_Int32 nSeriesLength,
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::chart2::XDiagram > & xDiagram,
        sal_Bool bExportContent );
    SAL_DLLPRIVATE void exportRegressionCurve(
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::chart2::XDataSeries > & xSeries,
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::beans::XPropertySet > & xSeriesProp,
        const ::com::sun::star::awt::Size & rPageSize,
        sal_Bool bExportContent );

    /// add svg position as attribute for current element
    SAL_DLLPRIVATE void addPosition( const ::com::sun::star::awt::Point & rPosition );
    SAL_DLLPRIVATE void addPosition( com::sun::star::uno::Reference< com::sun::star::drawing::XShape > xShape );
    /// add svg size as attribute for current element
    SAL_DLLPRIVATE void addSize( const ::com::sun::star::awt::Size & rSize );
    SAL_DLLPRIVATE void addSize( com::sun::star::uno::Reference< com::sun::star::drawing::XShape > xShape );
    /// fills the member msString with the appropriate String (i.e. "A3")
    SAL_DLLPRIVATE void getCellAddress( sal_Int32 nCol, sal_Int32 nRow );
    /// interchanges rows and columns of the sequence given
    SAL_DLLPRIVATE void swapDataArray( com::sun::star::uno::Sequence< com::sun::star::uno::Sequence< double > >& rSequence );
    /// exports a string as a paragraph element
    SAL_DLLPRIVATE void exportText( const ::rtl::OUString& rText, bool bConvertTabsLFs = false );

    SAL_DLLPRIVATE SchXMLExportHelper(SchXMLExportHelper &); // not defined
    SAL_DLLPRIVATE void operator =(SchXMLExportHelper &); // not defined

public:
    SchXMLExportHelper( SvXMLExport& rExport,
                        SvXMLAutoStylePoolP& rASPool );

    virtual ~SchXMLExportHelper();

    // auto-styles
    /// parse chart and collect all auto-styles used in current pool
    void collectAutoStyles( com::sun::star::uno::Reference<
                            com::sun::star::chart::XChartDocument > rChartDoc );
    /// write the styles collected into the current pool as <style:style> elements
    void exportAutoStyles();

    /** export the <chart:chart> element corresponding to rChartDoc
        if bIncludeTable is true, the chart data is exported as <table:table>
        element (inside the chart element).

        Otherwise the external references stored in the chart document are used
        for writing the corresponding attributes at series

        All attributes contained in xAttrList are written at the chart element,
        which ist the outer element of a chart. So these attributes can easily
        be parsed again by the container
     */
    void exportChart( com::sun::star::uno::Reference<
                          com::sun::star::chart::XChartDocument > rChartDoc,
                      sal_Bool bIncludeTable );

    /// returns the string corresponding to the current FileFormat CLSID for Chart
    const rtl::OUString& getChartCLSID();

    UniReference< XMLPropertySetMapper > GetPropertySetMapper() const { return mxPropertySetMapper; }

    void SetChartRangeAddress( const ::rtl::OUString& rAddress )
        { msChartAddress = rAddress; }
    void SetTableNumberList( const ::rtl::OUString& rList )
        { msTableNumberList = rList; }

    void InitRangeSegmentationProperties(
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::chart2::XChartDocument > & xChartDoc );

    // if no data provider exists by, now the model (as XChild) is asked for its
    // parent which creates the data provider that is finally set at the chart
    // document
    static ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XDataProvider >
        GetDataProvider( const ::com::sun::star::uno::Reference<
                             ::com::sun::star::chart2::XChartDocument > & xChartDoc );

    ::com::sun::star::awt::Size getPageSize(
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::chart2::XChartDocument > & xChartDoc ) const;
};

#endif  // _XMLOFF_SCH_XMLEXPORTHELPER_HXX_
<commit_msg>INTEGRATION: CWS chart20_DEV300 (1.4.74); FILE MERGED 2008/02/21 15:59:48 bm 1.4.74.1: #i366# error bars from cell ranges<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: SchXMLExportHelper.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: kz $ $Date: 2008-03-06 15:39:53 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _XMLOFF_SCH_XMLEXPORTHELPER_HXX_
#define _XMLOFF_SCH_XMLEXPORTHELPER_HXX_

#ifndef _SAL_CONFIG_H_
#include "sal/config.h"
#endif

#ifndef INCLUDED_XMLOFF_DLLAPI_H
#include "xmloff/dllapi.h"
#endif

#ifndef _SAL_TYPES_H_
#include "sal/types.h"
#endif
#ifndef _UNIVERSALL_REFERENCE_HXX
#include <xmloff/uniref.hxx>
#endif
#ifndef _RTL_USTRBUF_HXX_
#include <rtl/ustrbuf.hxx>
#endif
#ifndef _COM_SUN_STAR_UTIL_XSTRINGMAPPING_HPP_
#include <com/sun/star/util/XStringMapping.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_SIZE_HPP_
#include <com/sun/star/awt/Size.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_POINT_HPP_
#include <com/sun/star/awt/Point.hpp>
#endif

#ifndef _XMLOFF_PROPERTYSETMAPPER_HXX
#include <xmloff/xmlprmap.hxx>
#endif

#include <queue>
#include <vector>

namespace com { namespace sun { namespace star {
    namespace chart {
        class XDiagram;
        class XChartDocument;
        class XChartDataArray;
        struct ChartSeriesAddress;
    }
    namespace chart2 {
        class XDiagram;
        class XChartDocument;
        class XDataSeries;
        namespace data
        {
            class XDataProvider;
            class XDataSequence;
        }
    }
    namespace drawing {
        class XShape;
        class XShapes;
    }
    namespace task {
        class XStatusIndicator;
    }
    namespace frame {
        class XModel;
    }
    namespace xml {
        namespace sax {
            class XAttributeList;
}}}}}

class SvXMLAutoStylePoolP;
class XMLChartExportPropertyMapper;
class SvXMLExport;
class XMLPropertyHandlerFactory;

/** With this class you can export a <chart:chart> element containing
    its data as <table:table> element or without internal table. In
    the latter case you have to provide a table address mapper if the
    cell addressing set at the document is not in XML format.
 */
class XMLOFF_DLLPUBLIC SchXMLExportHelper : public UniRefBase
{
public:
    // first: data sequence for label, second: data sequence for values.
    typedef ::std::pair< ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XDataSequence >,
            ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XDataSequence > > tLabelValuesDataPair;
    typedef ::std::vector< tLabelValuesDataPair > tDataSequenceCont;

private:
    SvXMLExport& mrExport;
    SvXMLAutoStylePoolP& mrAutoStylePool;
    UniReference< XMLPropertyHandlerFactory > mxPropertyHandlerFactory;
    UniReference< XMLPropertySetMapper > mxPropertySetMapper;
    UniReference< XMLChartExportPropertyMapper > mxExpPropMapper;

    rtl::OUString msTableName;
    rtl::OUStringBuffer msStringBuffer;
    rtl::OUString msString;

    // members filled by InitRangeSegmentationProperties (retrieved from DataProvider)
    sal_Bool mbHasSeriesLabels;
    sal_Bool mbHasCategoryLabels; //if the categories are only automatically generated this will be false
    sal_Bool mbRowSourceColumns;
    rtl::OUString msChartAddress;
    rtl::OUString msTableNumberList;
    ::com::sun::star::uno::Sequence< sal_Int32 > maSequenceMapping;

    rtl::OUString msCLSID;

    ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes > mxAdditionalShapes;

    tDataSequenceCont m_aDataSequencesToExport;

    /** first parseDocument: collect autostyles and store names in this queue
        second parseDocument: export content and use names from this queue
     */
    ::std::queue< ::rtl::OUString > maAutoStyleNameQueue;
    SAL_DLLPRIVATE void CollectAutoStyle(
        const std::vector< XMLPropertyState >& aStates );
    SAL_DLLPRIVATE void AddAutoStyleAttribute(
        const std::vector< XMLPropertyState >& aStates );

    SAL_DLLPRIVATE SvXMLAutoStylePoolP& GetAutoStylePoolP()
    { return mrAutoStylePool; }

    /// if bExportContent is false the auto-styles are collected
    SAL_DLLPRIVATE void parseDocument( com::sun::star::uno::Reference<
                            com::sun::star::chart::XChartDocument >& rChartDoc,
                        sal_Bool bExportContent,
                        sal_Bool bIncludeTable = sal_False );
    SAL_DLLPRIVATE void exportTable();
    SAL_DLLPRIVATE void exportPlotArea(
        com::sun::star::uno::Reference< com::sun::star::chart::XDiagram > xDiagram,
        com::sun::star::uno::Reference< com::sun::star::chart2::XDiagram > xNewDiagram,
        const ::com::sun::star::awt::Size & rPageSize,
        sal_Bool bExportContent,
        sal_Bool bIncludeTable );
    SAL_DLLPRIVATE void exportAxes( const com::sun::star::uno::Reference< com::sun::star::chart::XDiagram > & xDiagram,
                                    const com::sun::star::uno::Reference< com::sun::star::chart2::XDiagram > & xNewDiagram,
                                    sal_Bool bExportContent );

    SAL_DLLPRIVATE void exportSeries(
        const com::sun::star::uno::Reference< com::sun::star::chart2::XDiagram > & xNewDiagram,
        const ::com::sun::star::awt::Size & rPageSize,
        sal_Bool bExportContent,
        sal_Bool bHasTwoYAxes );
    SAL_DLLPRIVATE void exportCandleStickSeries(
        const ::com::sun::star::uno::Sequence<
            ::com::sun::star::uno::Reference<
                ::com::sun::star::chart2::XDataSeries > > & aSeriesSeq,
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::chart2::XDiagram > & xDiagram,
        sal_Bool bJapaneseCandleSticks,
        sal_Bool bExportContent );
    SAL_DLLPRIVATE void exportDataPoints(
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::beans::XPropertySet > & xSeriesProperties,
        sal_Int32 nSeriesLength,
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::chart2::XDiagram > & xDiagram,
        sal_Bool bExportContent );
    SAL_DLLPRIVATE void exportRegressionCurve(
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::chart2::XDataSeries > & xSeries,
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::beans::XPropertySet > & xSeriesProp,
        const ::com::sun::star::awt::Size & rPageSize,
        sal_Bool bExportContent );

    /// add svg position as attribute for current element
    SAL_DLLPRIVATE void addPosition( const ::com::sun::star::awt::Point & rPosition );
    SAL_DLLPRIVATE void addPosition( com::sun::star::uno::Reference< com::sun::star::drawing::XShape > xShape );
    /// add svg size as attribute for current element
    SAL_DLLPRIVATE void addSize( const ::com::sun::star::awt::Size & rSize );
    SAL_DLLPRIVATE void addSize( com::sun::star::uno::Reference< com::sun::star::drawing::XShape > xShape );
    /// fills the member msString with the appropriate String (i.e. "A3")
    SAL_DLLPRIVATE void getCellAddress( sal_Int32 nCol, sal_Int32 nRow );
    /// interchanges rows and columns of the sequence given
    SAL_DLLPRIVATE void swapDataArray( com::sun::star::uno::Sequence< com::sun::star::uno::Sequence< double > >& rSequence );
    /// exports a string as a paragraph element
    SAL_DLLPRIVATE void exportText( const ::rtl::OUString& rText, bool bConvertTabsLFs = false );
    SAL_DLLPRIVATE void exportErrorBarRanges();

    SAL_DLLPRIVATE SchXMLExportHelper(SchXMLExportHelper &); // not defined
    SAL_DLLPRIVATE void operator =(SchXMLExportHelper &); // not defined

public:
    SchXMLExportHelper( SvXMLExport& rExport,
                        SvXMLAutoStylePoolP& rASPool );

    virtual ~SchXMLExportHelper();

    // auto-styles
    /// parse chart and collect all auto-styles used in current pool
    void collectAutoStyles( com::sun::star::uno::Reference<
                            com::sun::star::chart::XChartDocument > rChartDoc );
    /// write the styles collected into the current pool as <style:style> elements
    void exportAutoStyles();

    /** export the <chart:chart> element corresponding to rChartDoc
        if bIncludeTable is true, the chart data is exported as <table:table>
        element (inside the chart element).

        Otherwise the external references stored in the chart document are used
        for writing the corresponding attributes at series

        All attributes contained in xAttrList are written at the chart element,
        which ist the outer element of a chart. So these attributes can easily
        be parsed again by the container
     */
    void exportChart( com::sun::star::uno::Reference<
                          com::sun::star::chart::XChartDocument > rChartDoc,
                      sal_Bool bIncludeTable );

    /// returns the string corresponding to the current FileFormat CLSID for Chart
    const rtl::OUString& getChartCLSID();

    UniReference< XMLPropertySetMapper > GetPropertySetMapper() const { return mxPropertySetMapper; }

    void SetChartRangeAddress( const ::rtl::OUString& rAddress )
        { msChartAddress = rAddress; }
    void SetTableNumberList( const ::rtl::OUString& rList )
        { msTableNumberList = rList; }

    void InitRangeSegmentationProperties(
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::chart2::XChartDocument > & xChartDoc );

    // if no data provider exists by, now the model (as XChild) is asked for its
    // parent which creates the data provider that is finally set at the chart
    // document
    static ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XDataProvider >
        GetDataProvider( const ::com::sun::star::uno::Reference<
                             ::com::sun::star::chart2::XChartDocument > & xChartDoc );

    ::com::sun::star::awt::Size getPageSize(
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::chart2::XChartDocument > & xChartDoc ) const;
};

#endif  // _XMLOFF_SCH_XMLEXPORTHELPER_HXX_
<|endoftext|>


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

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

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

#include "mitkCommon.h"
#include "mitkTestingMacros.h"
#include <mitkLog.h>
#include <itksys/SystemTools.hxx>
#include <mitkStandardFileLocations.h>

#include <string>

#include <QtConcurrentRun>

void LogMessages(unsigned int threadID, unsigned int numberOfTimes = 5000)
{
  unsigned int times = 0;

  while(times < numberOfTimes)
  {
    MITK_INFO << "Test info stream in thread" << threadID << "\n even with newlines";
    MITK_WARN << "Test warning stream in thread " << threadID <<". "
      << "Even with a very long text, even without meaning or implied meaning or content, just a long sentence to see whether something has problems with long sentences or output in files or into windows or commandlines or whatever.";
    MITK_DEBUG << "Test debugging stream in thread " << threadID;
    MITK_ERROR << "Test error stream in thread " << threadID;
    MITK_FATAL << "Test fatal stream in thread " << threadID;

    times= 5;
  }
}

/**
  \brief Test logging from Qt threads
*/
static void TestThreadSaveLog(bool toFile)
{
  bool testSucceded = true;

  try
  {
    if (toFile)
    {
      std::string filename = mitk::StandardFileLocations::GetInstance()->GetOptionDirectory() + "/qtestthreadlog.log";
      mitk::LoggingBackend::SetLogFile(filename.c_str());
    }

    unsigned int numberOfThreads = 20;
    unsigned int threadRuntimeInMilliseconds = 4000;
    QVector< QFuture<void> > threads;

    // Spawn some threads
    for (unsigned int threadIdx = 0; threadIdx < numberOfThreads;+threadIdx)
    {
      threads.push_back( QtConcurrent::run( LogMessages, threadIdx, 1000 ) );
      std::cout << "Created " << threadIdx << ". thread." << std::endl;
    }

    //wait for some time (milliseconds)
    itksys::SystemTools::Delay( threadRuntimeInMilliseconds );

    // Wait for all to finish
    for (unsigned int threadIdx = 0; threadIdx < numberOfThreads;+threadIdx)
    {
      threads[threadIdx].waitForFinished();
      std::cout << threadIdx << ". thread has finished" << std::endl;
    }
  }
  catch(std::exception e)
  {
    MITK_ERROR << "exception during 'TestThreadSaveLog': "<<e.what();
    testSucceded = false;
  }
  catch(...)
  {
    MITK_ERROR << "unknown exception during 'TestThreadSaveLog'";
    testSucceded = false;
  }

  //if no error occured until now, everything is ok
  MITK_TEST_CONDITION_REQUIRED(testSucceded,"Test logging in different threads.");
}

int QmitkThreadedLogTest(int /* argc */, char* /*argv*/[])
{
  // always start with this!
  MITK_TEST_BEGIN("QmitkThreadedLogTest")

  MITK_TEST_OUTPUT(<<"TESTING ALL LOGGING OUTPUTS, ERROR MESSAGES ARE ALSO TESTED AND NOT MEANING AN ERROR OCCURED!")

  TestThreadSaveLog( false ); // false = to console
  TestThreadSaveLog( true );  // true = to file

  MITK_TEST_OUTPUT(<<"Number of threads in QThreadPool: " << QThreadPool::globalInstance()->maxThreadCount() )

  // always end with this!
  MITK_TEST_END()
}
<commit_msg>Fix stupid logic errors<commit_after>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

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

#include "mitkCommon.h"
#include "mitkTestingMacros.h"
#include <mitkLog.h>
#include <itksys/SystemTools.hxx>
#include <mitkStandardFileLocations.h>

#include <string>

#include <QtConcurrentRun>

void LogMessages(unsigned int threadID, unsigned int numberOfTimes)
{
  unsigned int times = 0;

  while(times < numberOfTimes)
  {
    MITK_INFO << "Test info stream in thread" << threadID << "\n even with newlines";
    MITK_WARN << "Test warning stream in thread " << threadID <<". "
      << "Even with a very long text, even without meaning or implied meaning or content, just a long sentence to see whether something has problems with long sentences or output in files or into windows or commandlines or whatever.";
    MITK_DEBUG << "Test debugging stream in thread " << threadID;
    MITK_ERROR << "Test error stream in thread " << threadID;
    MITK_FATAL << "Test fatal stream in thread " << threadID;

    times += 5;
  }
}

/**
  \brief Test logging from Qt threads
*/
static void TestThreadSaveLog(bool toFile)
{
  bool testSucceded = true;

  try
  {
    if (toFile)
    {
      std::string filename = mitk::StandardFileLocations::GetInstance()->GetOptionDirectory() + "/qtestthreadlog.log";
      mitk::LoggingBackend::SetLogFile(filename.c_str());
    }

    unsigned int numberOfThreads = 20;
    unsigned int threadRuntimeInMilliseconds = 4000;
    QVector< QFuture<void> > threads;

    // Spawn some threads
    for (unsigned int threadIdx = 0; threadIdx < numberOfThreads;++threadIdx)
    {
      threads.push_back( QtConcurrent::run( LogMessages, threadIdx, 100 ) );
      std::cout << "Created " << threadIdx << ". thread." << std::endl;
    }

    //wait for some time (milliseconds)
    itksys::SystemTools::Delay( threadRuntimeInMilliseconds );

    // Wait for all to finish
    for (unsigned int threadIdx = 0; threadIdx < numberOfThreads;++threadIdx)
    {
      threads[threadIdx].waitForFinished();
      std::cout << threadIdx << ". thread has finished" << std::endl;
    }
  }
  catch(std::exception e)
  {
    MITK_ERROR << "exception during 'TestThreadSaveLog': "<<e.what();
    testSucceded = false;
  }
  catch(...)
  {
    MITK_ERROR << "unknown exception during 'TestThreadSaveLog'";
    testSucceded = false;
  }

  //if no error occured until now, everything is ok
  MITK_TEST_CONDITION_REQUIRED(testSucceded,"Test logging in different threads.");
}

int QmitkThreadedLogTest(int /* argc */, char* /*argv*/[])
{
  // always start with this!
  MITK_TEST_BEGIN("QmitkThreadedLogTest")

  MITK_TEST_OUTPUT(<<"TESTING ALL LOGGING OUTPUTS, ERROR MESSAGES ARE ALSO TESTED AND NOT MEANING AN ERROR OCCURED!")

  TestThreadSaveLog( false ); // false = to console
  TestThreadSaveLog( true );  // true = to file

  MITK_TEST_OUTPUT(<<"Number of threads in QThreadPool: " << QThreadPool::globalInstance()->maxThreadCount() )

  // always end with this!
  MITK_TEST_END()
}
<|endoftext|>


<commit_before>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 RC 1        *
*                (c) 2006-2011 INRIA, USTL, UJF, CNRS, MGH                    *
*                                                                             *
* This program is free software; you can redistribute it and/or modify it     *
* under the terms of the GNU General Public License as published by the Free  *
* Software Foundation; either version 2 of the License, or (at your option)   *
* any later version.                                                          *
*                                                                             *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for    *
* more details.                                                               *
*                                                                             *
* You should have received a copy of the GNU General Public License along     *
* with this program; if not, write to the Free Software Foundation, Inc., 51  *
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.                   *
*******************************************************************************
*                            SOFA :: Applications                             *
*                                                                             *
* Authors: The SOFA Team and external contributors (see Authors.txt)          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
#include "GenerateRigid.h"

#include <stdlib.h>
#include <math.h>
#include <sofa/helper/vector.h>
#include <sofa/helper/decompose.h>
#include <sofa/defaulttype/Quat.h>

namespace sofa
{

namespace helper
{

using namespace sofa::defaulttype;

void generateRigid(Rigid3Mass& mass, Vector3& center, const sofa::helper::io::Mesh* mesh)
{
    using namespace sofa::helper;
    // Geometric Tools, Inc.
    // http://www.geometrictools.com
    // Copyright (c) 1998-2006.	All Rights Reserved
    //
    // The Wild Magic Library (WM3) source code is supplied under the terms of
    // the license agreement
    //     http://www.geometrictools.com/License/WildMagic3License.pdf
    // and may not be copied or disclosed except in accordance with the terms
    // of that agreement.

    // order:	1, x, y, z, x^2, y^2, z^2, xy, yz, zx
    SReal afIntegral[10] = { (SReal)0.0, (SReal)0.0, (SReal)0.0, (SReal)0.0,
            (SReal)0.0, (SReal)0.0, (SReal)0.0, (SReal)0.0, (SReal)0.0, (SReal)0.0
                            };

    const vector<Vector3>& points = mesh->getVertices();
    const vector< vector< vector<int> > >& facets = mesh->getFacets();
    for (unsigned int i = 0; i < facets.size(); i++)
    {
        const vector<int>& v = facets[i][0];
        for (unsigned int j = 2; j < v.size(); j++)
        {
            // get vertices of current triangle
            const Vector3 kV0 = points[v[0  ]];
            const Vector3 kV1 = points[v[j-1]];
            const Vector3 kV2 = points[v[j  ]];

            // get cross product of edges
            Vector3 kV1mV0 = kV1 - kV0;
            Vector3 kV2mV0 = kV2 - kV0;
            Vector3 kN = cross(kV1mV0,kV2mV0);

            // compute integral terms
            SReal fTmp0, fTmp1, fTmp2;
            SReal fF1x, fF2x, fF3x, fG0x, fG1x, fG2x;
            fTmp0 = kV0[0] + kV1[0];
            fF1x = fTmp0 + kV2[0];
            fTmp1 = kV0[0]*kV0[0];
            fTmp2 = fTmp1 + kV1[0]*fTmp0;
            fF2x = fTmp2 + kV2[0]*fF1x;
            fF3x = kV0[0]*fTmp1 + kV1[0]*fTmp2 + kV2[0]*fF2x;
            fG0x = fF2x + kV0[0]*(fF1x + kV0[0]);
            fG1x = fF2x + kV1[0]*(fF1x + kV1[0]);
            fG2x = fF2x + kV2[0]*(fF1x + kV2[0]);

            SReal fF1y, fF2y, fF3y, fG0y, fG1y, fG2y;
            fTmp0 = kV0[1] + kV1[1];
            fF1y = fTmp0 + kV2[1];
            fTmp1 = kV0[1]*kV0[1];
            fTmp2 = fTmp1 + kV1[1]*fTmp0;
            fF2y = fTmp2 + kV2[1]*fF1y;
            fF3y = kV0[1]*fTmp1 + kV1[1]*fTmp2 + kV2[1]*fF2y;
            fG0y = fF2y + kV0[1]*(fF1y + kV0[1]);
            fG1y = fF2y + kV1[1]*(fF1y + kV1[1]);
            fG2y = fF2y + kV2[1]*(fF1y + kV2[1]);

            SReal fF1z, fF2z, fF3z, fG0z, fG1z, fG2z;
            fTmp0 = kV0[2] + kV1[2];
            fF1z = fTmp0 + kV2[2];
            fTmp1 = kV0[2]*kV0[2];
            fTmp2 = fTmp1 + kV1[2]*fTmp0;
            fF2z = fTmp2 + kV2[2]*fF1z;
            fF3z = kV0[2]*fTmp1 + kV1[2]*fTmp2 + kV2[2]*fF2z;
            fG0z = fF2z + kV0[2]*(fF1z + kV0[2]);
            fG1z = fF2z + kV1[2]*(fF1z + kV1[2]);
            fG2z = fF2z + kV2[2]*(fF1z + kV2[2]);

            // update integrals
            afIntegral[0] += kN[0]*fF1x;
            afIntegral[1] += kN[0]*fF2x;
            afIntegral[2] += kN[1]*fF2y;
            afIntegral[3] += kN[2]*fF2z;
            afIntegral[4] += kN[0]*fF3x;
            afIntegral[5] += kN[1]*fF3y;
            afIntegral[6] += kN[2]*fF3z;
            afIntegral[7] += kN[0]*(kV0[1]*fG0x + kV1[1]*fG1x + kV2[1]*fG2x);
            afIntegral[8] += kN[1]*(kV0[2]*fG0y + kV1[2]*fG1y + kV2[2]*fG2y);
            afIntegral[9] += kN[2]*(kV0[0]*fG0z + kV1[0]*fG1z + kV2[0]*fG2z);
        }
    }

    afIntegral[0] /= (SReal)6.0;
    afIntegral[1] /= (SReal)24.0;
    afIntegral[2] /= (SReal)24.0;
    afIntegral[3] /= (SReal)24.0;
    afIntegral[4] /= (SReal)60.0;
    afIntegral[5] /= (SReal)60.0;
    afIntegral[6] /= (SReal)60.0;
    afIntegral[7] /= (SReal)120.0;
    afIntegral[8] /= (SReal)120.0;
    afIntegral[9] /= (SReal)120.0;

    // mass
    mass.volume = afIntegral[0];
    mass.mass = mass.volume;

    // center of mass
    center = Vector3(afIntegral[1]/afIntegral[0],afIntegral[2]/afIntegral[0],afIntegral[3]/afIntegral[0]);

    // inertia relative to world origin
    mass.inertiaMatrix[0][0] = afIntegral[5] + afIntegral[6];
    mass.inertiaMatrix[0][1] = -afIntegral[7];
    mass.inertiaMatrix[0][2] = -afIntegral[9];
    mass.inertiaMatrix[1][0] = mass.inertiaMatrix[0][1];
    mass.inertiaMatrix[1][1] = afIntegral[4] + afIntegral[6];
    mass.inertiaMatrix[1][2] = -afIntegral[8];
    mass.inertiaMatrix[2][0] = mass.inertiaMatrix[0][2];
    mass.inertiaMatrix[2][1] = mass.inertiaMatrix[1][2];
    mass.inertiaMatrix[2][2] = afIntegral[4] + afIntegral[5];

    // inertia relative to center of mass
    mass.inertiaMatrix[0][0] -= mass.mass*(center[1]*center[1] + center[2]*center[2]);
    mass.inertiaMatrix[0][1] += mass.mass*center[0]*center[1];
    mass.inertiaMatrix[0][2] += mass.mass*center[2]*center[0];
    mass.inertiaMatrix[1][0] = mass.inertiaMatrix[0][1];
    mass.inertiaMatrix[1][1] -= mass.mass*(center[2]*center[2] + center[0]*center[0]);
    mass.inertiaMatrix[1][2] += mass.mass*center[1]*center[2];
    mass.inertiaMatrix[2][0] = mass.inertiaMatrix[0][2];
    mass.inertiaMatrix[2][1] = mass.inertiaMatrix[1][2];
    mass.inertiaMatrix[2][2] -= mass.mass*(center[0]*center[0] + center[1]*center[1]);

    mass.inertiaMatrix /= mass.mass;
}

bool generateRigid(Rigid3Mass& mass, Vector3& center, const std::string& meshFilename
                   , SReal density
                   , const Vector3& scale
                   , const Vector3& rotation /*Euler angles*/
                  )
{
    sofa::helper::io::Mesh* mesh = sofa::helper::io::Mesh::Create( meshFilename );
    if (mesh == NULL)
    {
        std::cerr << "ERROR loading mesh "<<meshFilename<<std::endl;
        return false;
    }

    if( scale != Vector3(1, 1, 1) ) {
        for(unsigned i = 0, n = mesh->getVertices().size(); i < n; ++i) {
            mesh->getVertices()[i] = mesh->getVertices()[i].linearProduct(scale);
        }
    }

    if( rotation != Vector3(0,0,0) ) {

        Quaternion q = sofa::helper::Quater<SReal>::createQuaterFromEuler( rotation*M_PI/180.0 );

        for(unsigned i = 0, n = mesh->getVertices().size(); i < n; ++i) {
            mesh->getVertices()[i] = q.rotate( mesh->getVertices()[i] );
        }
    }

    generateRigid( mass, center, mesh );

    mass.recalc();

    mass.mass *= density;

    return true;
}

bool SOFA_HELPER_API generateRigid( GenerateRigidInfo& res
                                  , const std::string& meshFilename
                                  , SReal density
                                  , const defaulttype::Vector3& scale
                                  )
{
    Rigid3Mass rigidMass;

    if( !generateRigid( rigidMass, res.com, meshFilename, density, scale ) )
        return false;

    res.mass = rigidMass.mass;
    res.inertia = res.mass * rigidMass.inertiaMatrix;

    // a threshol to test if inertia is diagonal in function of diagonal values
    SReal threshold = defaulttype::trace( res.inertia ) * 1e-6;

    // if not diagonal, extracting principal axes basis to get the corresponding rotation with a diagonal inertia
    if( res.inertia[0][1]>threshold || res.inertia[0][2]>threshold || res.inertia[1][2]>threshold )
    {
        defaulttype::Matrix3 U;
        Decompose<SReal>::eigenDecomposition_iterative( res.inertia, U, res.inertia_diagonal );

        // det should be 1->rotation or -1->reflexion
        if( determinant( U ) < 0 ) // reflexion
        {
            // made it a rotation by negating a column
            U[0][0] = -U[0][0];
            U[1][0] = -U[1][0];
            U[2][0] = -U[2][0];
        }
        res.inertia_rotation.fromMatrix( U );
    }
    else
    {
        res.inertia_diagonal[0] = res.inertia[0][0];
        res.inertia_diagonal[1] = res.inertia[1][1];
        res.inertia_diagonal[2] = res.inertia[2][2];
        res.inertia_rotation.clear();
    }

    return true;
}

}

}
<commit_msg>GenerateRigid: when normals are inverted, get the opposite of the mass/inertia.<commit_after>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 RC 1        *
*                (c) 2006-2011 INRIA, USTL, UJF, CNRS, MGH                    *
*                                                                             *
* This program is free software; you can redistribute it and/or modify it     *
* under the terms of the GNU General Public License as published by the Free  *
* Software Foundation; either version 2 of the License, or (at your option)   *
* any later version.                                                          *
*                                                                             *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for    *
* more details.                                                               *
*                                                                             *
* You should have received a copy of the GNU General Public License along     *
* with this program; if not, write to the Free Software Foundation, Inc., 51  *
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.                   *
*******************************************************************************
*                            SOFA :: Applications                             *
*                                                                             *
* Authors: The SOFA Team and external contributors (see Authors.txt)          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
#include "GenerateRigid.h"

#include <stdlib.h>
#include <math.h>
#include <sofa/helper/vector.h>
#include <sofa/helper/decompose.h>
#include <sofa/defaulttype/Quat.h>

namespace sofa
{

namespace helper
{

using namespace sofa::defaulttype;

void generateRigid(Rigid3Mass& mass, Vector3& center, const sofa::helper::io::Mesh* mesh)
{
    using namespace sofa::helper;
    // Geometric Tools, Inc.
    // http://www.geometrictools.com
    // Copyright (c) 1998-2006.	All Rights Reserved
    //
    // The Wild Magic Library (WM3) source code is supplied under the terms of
    // the license agreement
    //     http://www.geometrictools.com/License/WildMagic3License.pdf
    // and may not be copied or disclosed except in accordance with the terms
    // of that agreement.

    // order:	1, x, y, z, x^2, y^2, z^2, xy, yz, zx
    SReal afIntegral[10] = { (SReal)0.0, (SReal)0.0, (SReal)0.0, (SReal)0.0,
            (SReal)0.0, (SReal)0.0, (SReal)0.0, (SReal)0.0, (SReal)0.0, (SReal)0.0
                            };

    const vector<Vector3>& points = mesh->getVertices();
    const vector< vector< vector<int> > >& facets = mesh->getFacets();
    for (unsigned int i = 0; i < facets.size(); i++)
    {
        const vector<int>& v = facets[i][0];
        for (unsigned int j = 2; j < v.size(); j++)
        {
            // get vertices of current triangle
            const Vector3 kV0 = points[v[0  ]];
            const Vector3 kV1 = points[v[j-1]];
            const Vector3 kV2 = points[v[j  ]];

            // get cross product of edges
            Vector3 kV1mV0 = kV1 - kV0;
            Vector3 kV2mV0 = kV2 - kV0;
            Vector3 kN = cross(kV1mV0,kV2mV0);

            // compute integral terms
            SReal fTmp0, fTmp1, fTmp2;
            SReal fF1x, fF2x, fF3x, fG0x, fG1x, fG2x;
            fTmp0 = kV0[0] + kV1[0];
            fF1x = fTmp0 + kV2[0];
            fTmp1 = kV0[0]*kV0[0];
            fTmp2 = fTmp1 + kV1[0]*fTmp0;
            fF2x = fTmp2 + kV2[0]*fF1x;
            fF3x = kV0[0]*fTmp1 + kV1[0]*fTmp2 + kV2[0]*fF2x;
            fG0x = fF2x + kV0[0]*(fF1x + kV0[0]);
            fG1x = fF2x + kV1[0]*(fF1x + kV1[0]);
            fG2x = fF2x + kV2[0]*(fF1x + kV2[0]);

            SReal fF1y, fF2y, fF3y, fG0y, fG1y, fG2y;
            fTmp0 = kV0[1] + kV1[1];
            fF1y = fTmp0 + kV2[1];
            fTmp1 = kV0[1]*kV0[1];
            fTmp2 = fTmp1 + kV1[1]*fTmp0;
            fF2y = fTmp2 + kV2[1]*fF1y;
            fF3y = kV0[1]*fTmp1 + kV1[1]*fTmp2 + kV2[1]*fF2y;
            fG0y = fF2y + kV0[1]*(fF1y + kV0[1]);
            fG1y = fF2y + kV1[1]*(fF1y + kV1[1]);
            fG2y = fF2y + kV2[1]*(fF1y + kV2[1]);

            SReal fF1z, fF2z, fF3z, fG0z, fG1z, fG2z;
            fTmp0 = kV0[2] + kV1[2];
            fF1z = fTmp0 + kV2[2];
            fTmp1 = kV0[2]*kV0[2];
            fTmp2 = fTmp1 + kV1[2]*fTmp0;
            fF2z = fTmp2 + kV2[2]*fF1z;
            fF3z = kV0[2]*fTmp1 + kV1[2]*fTmp2 + kV2[2]*fF2z;
            fG0z = fF2z + kV0[2]*(fF1z + kV0[2]);
            fG1z = fF2z + kV1[2]*(fF1z + kV1[2]);
            fG2z = fF2z + kV2[2]*(fF1z + kV2[2]);

            // update integrals
            afIntegral[0] += kN[0]*fF1x;
            afIntegral[1] += kN[0]*fF2x;
            afIntegral[2] += kN[1]*fF2y;
            afIntegral[3] += kN[2]*fF2z;
            afIntegral[4] += kN[0]*fF3x;
            afIntegral[5] += kN[1]*fF3y;
            afIntegral[6] += kN[2]*fF3z;
            afIntegral[7] += kN[0]*(kV0[1]*fG0x + kV1[1]*fG1x + kV2[1]*fG2x);
            afIntegral[8] += kN[1]*(kV0[2]*fG0y + kV1[2]*fG1y + kV2[2]*fG2y);
            afIntegral[9] += kN[2]*(kV0[0]*fG0z + kV1[0]*fG1z + kV2[0]*fG2z);
        }
    }

    afIntegral[0] /= (SReal)6.0;
    afIntegral[1] /= (SReal)24.0;
    afIntegral[2] /= (SReal)24.0;
    afIntegral[3] /= (SReal)24.0;
    afIntegral[4] /= (SReal)60.0;
    afIntegral[5] /= (SReal)60.0;
    afIntegral[6] /= (SReal)60.0;
    afIntegral[7] /= (SReal)120.0;
    afIntegral[8] /= (SReal)120.0;
    afIntegral[9] /= (SReal)120.0;

    // mass
    mass.volume = afIntegral[0];
    mass.mass = mass.volume;

    // center of mass
    center = Vector3(afIntegral[1]/afIntegral[0],afIntegral[2]/afIntegral[0],afIntegral[3]/afIntegral[0]);

    // inertia relative to world origin
    mass.inertiaMatrix[0][0] = afIntegral[5] + afIntegral[6];
    mass.inertiaMatrix[0][1] = -afIntegral[7];
    mass.inertiaMatrix[0][2] = -afIntegral[9];
    mass.inertiaMatrix[1][0] = mass.inertiaMatrix[0][1];
    mass.inertiaMatrix[1][1] = afIntegral[4] + afIntegral[6];
    mass.inertiaMatrix[1][2] = -afIntegral[8];
    mass.inertiaMatrix[2][0] = mass.inertiaMatrix[0][2];
    mass.inertiaMatrix[2][1] = mass.inertiaMatrix[1][2];
    mass.inertiaMatrix[2][2] = afIntegral[4] + afIntegral[5];

    // inertia relative to center of mass
    mass.inertiaMatrix[0][0] -= mass.mass*(center[1]*center[1] + center[2]*center[2]);
    mass.inertiaMatrix[0][1] += mass.mass*center[0]*center[1];
    mass.inertiaMatrix[0][2] += mass.mass*center[2]*center[0];
    mass.inertiaMatrix[1][0] = mass.inertiaMatrix[0][1];
    mass.inertiaMatrix[1][1] -= mass.mass*(center[2]*center[2] + center[0]*center[0]);
    mass.inertiaMatrix[1][2] += mass.mass*center[1]*center[2];
    mass.inertiaMatrix[2][0] = mass.inertiaMatrix[0][2];
    mass.inertiaMatrix[2][1] = mass.inertiaMatrix[1][2];
    mass.inertiaMatrix[2][2] -= mass.mass*(center[0]*center[0] + center[1]*center[1]);

    mass.inertiaMatrix /= mass.mass;
}

bool generateRigid(Rigid3Mass& mass, Vector3& center, const std::string& meshFilename
                   , SReal density
                   , const Vector3& scale
                   , const Vector3& rotation /*Euler angles*/
                  )
{
    sofa::helper::io::Mesh* mesh = sofa::helper::io::Mesh::Create( meshFilename );
    if (mesh == NULL)
    {
        std::cerr << "ERROR loading mesh "<<meshFilename<<std::endl;
        return false;
    }

    if( scale != Vector3(1, 1, 1) ) {
        for(unsigned i = 0, n = mesh->getVertices().size(); i < n; ++i) {
            mesh->getVertices()[i] = mesh->getVertices()[i].linearProduct(scale);
        }
    }

    if( rotation != Vector3(0,0,0) ) {

        Quaternion q = sofa::helper::Quater<SReal>::createQuaterFromEuler( rotation*M_PI/180.0 );

        for(unsigned i = 0, n = mesh->getVertices().size(); i < n; ++i) {
            mesh->getVertices()[i] = q.rotate( mesh->getVertices()[i] );
        }
    }

    generateRigid( mass, center, mesh );

    mass.recalc();

    mass.mass *= density;

    return true;
}

bool SOFA_HELPER_API generateRigid( GenerateRigidInfo& res
                                  , const std::string& meshFilename
                                  , SReal density
                                  , const defaulttype::Vector3& scale
                                  )
{
    Rigid3Mass rigidMass;

    if( !generateRigid( rigidMass, res.com, meshFilename, density, scale ) )
        return false;

    if( rigidMass.mass < 0 )
    {
        std::cerr<<"WARNING: generateRigid: are normals inverted? "<<meshFilename<<std::endl;
        rigidMass.mass = -rigidMass.mass;
        rigidMass.inertiaMatrix = -rigidMass.inertiaMatrix;
    }

    res.mass = rigidMass.mass;
    res.inertia = res.mass * rigidMass.inertiaMatrix;

    // a threshol to test if inertia is diagonal in function of diagonal values
    SReal threshold = defaulttype::trace( res.inertia ) * 1e-6;

    // if not diagonal, extracting principal axes basis to get the corresponding rotation with a diagonal inertia
    if( res.inertia[0][1]>threshold || res.inertia[0][2]>threshold || res.inertia[1][2]>threshold )
    {
        defaulttype::Matrix3 U;
        Decompose<SReal>::eigenDecomposition_iterative( res.inertia, U, res.inertia_diagonal );

        // det should be 1->rotation or -1->reflexion
        if( determinant( U ) < 0 ) // reflexion
        {
            // made it a rotation by negating a column
            U[0][0] = -U[0][0];
            U[1][0] = -U[1][0];
            U[2][0] = -U[2][0];
        }
        res.inertia_rotation.fromMatrix( U );
    }
    else
    {
        res.inertia_diagonal[0] = res.inertia[0][0];
        res.inertia_diagonal[1] = res.inertia[1][1];
        res.inertia_diagonal[2] = res.inertia[2][2];
        res.inertia_rotation.clear();
    }

    return true;
}

}

}
<|endoftext|>


<commit_before>#include <iostream>
#include <unistd.h>
#include <chrono>
#include <thread>

#include "Hardware.h"
#include "Fido/Fido.h"
#include "../../Connection.h"

void lSleep(double seconds) {
    usleep(seconds*1000000.0);
}

void goStraight() {
	double maxRotate = 100;
	double exploration = 0.2;

	Connection connection;
    int receiverNum;
    do {
        receiverNum = atoi(connection.getString().c_str());
    } while(receiverNum != 5 && receiverNum != 6);

    Hardware hardware;

	rl::WireFitQLearn learner = rl::WireFitQLearn(1, 1, 1, 3, 4, {-1}, {1}, 11, new rl::LSInterpolator(), net::Backpropagation(0.01, 0.9, 0.1, 35000), 0.95, 0.4);
	learner.reset();

    std::cout << "Done with initialization\n";
	while(true) {
		rl::Action action = learner.chooseBoltzmanAction({1}, exploration);
        std::cout << "Action: " << action[0] << "\n";

		hardware.goHolonomic(0, 50, action[0]*maxRotate);
		std::this_thread::sleep_for(std::chrono::milliseconds(500));
		hardware.goHolonomic(0, 0, 0);

        double reward = connection.getReward();
        if(fabs(reward - (-2)) < 0.001) break;
		learner.applyReinforcementToLastAction(reward, {1});
	}

    while(true) {
        rl::Action action = learner.chooseBoltzmanAction({1}, 0.001);
        hardware.goHolonomic(0, 50, action[0]*maxRotate);
        std::this_thread::sleep_for(std::chrono::milliseconds(50));
        std::cout << "Action: " << action[0] << "\n";
    }
}

void goStraightKiwi() {
    double maxMove = 100;
    double exploration = 0.2;

    Connection connection;
    int receiverNum;
    do {
        receiverNum = atoi(connection.getString().c_str());
    } while(receiverNum != 5 && receiverNum != 6);

    Hardware hardware;

    rl::WireFitQLearn learner = rl::WireFitQLearn(1, 3, 1, 8, 4, {-1, -1, -1}, {1, 1, 1}, 3, new rl::LSInterpolator(), net::Backpropagation(0.01, 0.9, 0.1, 35000), 0.95, 0.4);
    learner.reset();

    std::cout << "Done with initialization\n";
    while(true) {
        rl::Action action = learner.chooseBoltzmanAction({1}, exploration);
        std::cout << "Action: " << action[0] << "\n";

        hardware.setMotos(action[0]*maxMove, action[1]*maxMove, action[2]*maxMove);
        std::this_thread::sleep_for(std::chrono::milliseconds(500));
        hardware.setMotors(0, 0, 0);

        double reward = connection.getReward();
        if(fabs(reward - (-2)) < 0.001) break;
        learner.applyReinforcementToLastAction(reward, {1});
    }

    while(true) {
        rl::Action action = learner.chooseBoltzmanAction({1}, 0.001);
        hardware.goHolonomic(0, 50, action[0]*maxRotate);
        std::this_thread::sleep_for(std::chrono::milliseconds(50));
        std::cout << "Action: " << action[0] << "\n";
    }
}

int main() {
    goStraightKiwi();

    return 0;
}
<commit_msg>Take out unneeded sleep function<commit_after>#include <iostream>
#include <unistd.h>
#include <chrono>
#include <thread>

#include "Hardware.h"
#include "Fido/Fido.h"
#include "../../Connection.h"

void goStraight() {
	double maxRotate = 100;
	double exploration = 0.2;

	Connection connection;
    int receiverNum;
    do {
        receiverNum = atoi(connection.getString().c_str());
    } while(receiverNum != 5 && receiverNum != 6);

    Hardware hardware;

	rl::WireFitQLearn learner = rl::WireFitQLearn(1, 1, 1, 3, 4, {-1}, {1}, 11, new rl::LSInterpolator(), net::Backpropagation(0.01, 0.9, 0.1, 35000), 0.95, 0.4);
	learner.reset();

    std::cout << "Done with initialization\n";
	while(true) {
		rl::Action action = learner.chooseBoltzmanAction({1}, exploration);
        std::cout << "Action: " << action[0] << "\n";

		hardware.goHolonomic(0, 50, action[0]*maxRotate);
		std::this_thread::sleep_for(std::chrono::milliseconds(500));
		hardware.goHolonomic(0, 0, 0);

        double reward = connection.getReward();
        if(fabs(reward - (-2)) < 0.001) break;
		learner.applyReinforcementToLastAction(reward, {1});
	}

    while(true) {
        rl::Action action = learner.chooseBoltzmanAction({1}, 0.001);
        hardware.goHolonomic(0, 50, action[0]*maxRotate);
        std::this_thread::sleep_for(std::chrono::milliseconds(50));
        std::cout << "Action: " << action[0] << "\n";
    }
}

void goStraightKiwi() {
    double maxMove = 100;
    double exploration = 0.2;

    Connection connection;
    int receiverNum;
    do {
        receiverNum = atoi(connection.getString().c_str());
    } while(receiverNum != 5 && receiverNum != 6);

    Hardware hardware;

    rl::WireFitQLearn learner = rl::WireFitQLearn(1, 3, 1, 8, 4, {-1, -1, -1}, {1, 1, 1}, 3, new rl::LSInterpolator(), net::Backpropagation(0.01, 0.9, 0.1, 35000), 0.95, 0.4);
    learner.reset();

    std::cout << "Done with initialization\n";
    while(true) {
        rl::Action action = learner.chooseBoltzmanAction({1}, exploration);
        std::cout << "Action: " << action[0] << "\n";

        hardware.setMotos(action[0]*maxMove, action[1]*maxMove, action[2]*maxMove);
        std::this_thread::sleep_for(std::chrono::milliseconds(500));
        hardware.setMotors(0, 0, 0);

        double reward = connection.getReward();
        if(fabs(reward - (-2)) < 0.001) break;
        learner.applyReinforcementToLastAction(reward, {1});
    }

    while(true) {
        rl::Action action = learner.chooseBoltzmanAction({1}, 0.001);
        hardware.goHolonomic(0, 50, action[0]*maxRotate);
        std::this_thread::sleep_for(std::chrono::milliseconds(50));
        std::cout << "Action: " << action[0] << "\n";
    }
}

int main() {
    goStraightKiwi();

    return 0;
}
<|endoftext|>


<commit_before>

#include "config.h"
#include "storage/StorageImpl.h"
#include "storage/DevicegraphImpl.h"
#include "storage/Devices/DiskImpl.h"
#include "storage/Devices/FilesystemImpl.h"
#include "storage/SystemInfo/SystemInfo.h"
#include "storage/Actiongraph.h"
#include "storage/Utils/AppUtil.h"
#include "storage/Utils/Mockup.h"

namespace storage
{

    Storage::Impl::Impl(const Storage& storage, const Environment& environment)
	: storage(storage), environment(environment), arch(false)
    {
	y2mil("constructed Storage with " << environment);
	y2mil("libstorage version " VERSION);

	Devicegraph* probed = create_devicegraph("probed");

	switch (environment.get_probe_mode())
	{
	    case ProbeMode::STANDARD: {
		probe(probed);
	    } break;

	    case ProbeMode::STANDARD_WRITE_DEVICEGRAPH: {
		probe(probed);
		probed->save(environment.get_devicegraph_filename());
	    } break;

	    case ProbeMode::STANDARD_WRITE_MOCKUP: {
		Mockup::set_mode(Mockup::Mode::RECORD);
		probe(probed);
		Mockup::save(environment.get_mockup_filename());
	    } break;

	    case ProbeMode::NONE: {
	    } break;

	    case ProbeMode::READ_DEVICEGRAPH: {
		probed->load(environment.get_devicegraph_filename());
	    } break;

	    case ProbeMode::READ_MOCKUP: {
		Mockup::set_mode(Mockup::Mode::PLAYBACK);
		Mockup::load(environment.get_mockup_filename());
		probe(probed);
	    } break;
	}

	y2mil("probed devicegraph begin");
	y2mil(*probed);
	y2mil("probed devicegraph end");

	copy_devicegraph("probed", "staging");
    }

    Storage::Impl::~Impl()
    {
	y2mil("destructed Storage");
    }

    void
    Storage::Impl::probe(Devicegraph* probed)
    {
	SystemInfo systeminfo;

	arch = systeminfo.getArch();

	EtcFstab fstab("/etc");

	// TODO

	for (const string& name : Disk::Impl::probe_disks(systeminfo))
	{
	    Disk* disk = Disk::create(probed, name);
	    disk->get_impl().probe(systeminfo);
	}

	for (Devicegraph::Impl::vertex_descriptor vertex : probed->get_impl().vertices())
	{
	    BlkDevice* blkdevice = dynamic_cast<BlkDevice*>(probed->get_impl()[vertex]);
	    if (!blkdevice)
		continue;

	    if (blkdevice->num_children() != 0)
		continue;

	    Blkid::Entry entry;
	    if (systeminfo.getBlkid().getEntry(blkdevice->get_name(), entry))
	    {
		if (entry.is_fs)
		{
		    // TODO temporary until all fs are implemented
		    if (entry.fs_type != EXT4 && entry.fs_type != BTRFS && entry.fs_type != XFS &&
			entry.fs_type != SWAP)
			continue;

		    Filesystem* filesystem = blkdevice->create_filesystem(entry.fs_type);
		    filesystem->get_impl().probe(systeminfo, fstab);
		}
	    }
	}
    }

    Devicegraph*
    Storage::Impl::get_devicegraph(const string& name)
    {
	if (name == "probed")
	    throw runtime_error("invalid name");

	map<string, Devicegraph>::iterator it = devicegraphs.find(name);
	if (it == devicegraphs.end())
	    throw runtime_error("device graph not found");

	return &it->second;
    }

    const Devicegraph*
    Storage::Impl::get_devicegraph(const string& name) const
    {
	map<string, Devicegraph>::const_iterator it = devicegraphs.find(name);
	if (it == devicegraphs.end())
	    throw runtime_error("device graph not found");

	return &it->second;
    }

    Devicegraph*
    Storage::Impl::get_staging()
    {
	return get_devicegraph("staging");
    }

    const Devicegraph*
    Storage::Impl::get_staging() const
    {
	return get_devicegraph("staging");
    }

    const Devicegraph*
    Storage::Impl::get_probed() const
    {
	return get_devicegraph("probed");
    }

    vector<string>
    Storage::Impl::get_devicegraph_names() const
    {
	vector<string> ret;

	for (const map<string, Devicegraph>::value_type& it : devicegraphs)
	    ret.push_back(it.first);

	return ret;
    }

    Devicegraph*
    Storage::Impl::create_devicegraph(const string& name)
    {
	pair<map<string, Devicegraph>::iterator, bool> tmp =
	    devicegraphs.emplace(piecewise_construct, forward_as_tuple(name),
				 forward_as_tuple(&storage));
	if (!tmp.second)
	    throw logic_error("device graph already exists");

	map<string, Devicegraph>::iterator it = tmp.first;

	return &it->second;
    }

    Devicegraph*
    Storage::Impl::copy_devicegraph(const string& source_name, const string& dest_name)
    {
	const Devicegraph* tmp1 = static_cast<const Impl*>(this)->get_devicegraph(source_name);

	Devicegraph* tmp2 = create_devicegraph(dest_name);

	tmp1->copy(*tmp2);

	return tmp2;
    }

    void
    Storage::Impl::remove_devicegraph(const string& name)
    {
	map<string, Devicegraph>::const_iterator it1 = devicegraphs.find(name);
	if (it1 == devicegraphs.end())
	    throw runtime_error("device graph not found");

	devicegraphs.erase(it1);
    }

    void
    Storage::Impl::restore_devicegraph(const string& name)
    {
	map<string, Devicegraph>::iterator it1 = devicegraphs.find(name);
	if (it1 == devicegraphs.end())
	    throw runtime_error("device graph not found");

	map<string, Devicegraph>::iterator it2 = devicegraphs.find("staging");
	if (it2 == devicegraphs.end())
	    throw runtime_error("device graph not found");

	it1->second.get_impl().swap(it2->second.get_impl());
	devicegraphs.erase(it1);
    }

    bool
    Storage::Impl::exist_devicegraph(const string& name) const
    {
	return devicegraphs.find(name) != devicegraphs.end();
    }

    bool
    Storage::Impl::equal_devicegraph(const string& lhs, const string& rhs) const
    {
	return *get_devicegraph(lhs) == *get_devicegraph(rhs);
    }

    void
    Storage::Impl::check() const
    {
	for (const map<string, Devicegraph>::value_type& key_value : devicegraphs)
	{
	    key_value.second.check();
	}

	// TODO check that a object has the same type in every devicegraph
    }

    string
    Storage::Impl::prepend_rootprefix(const string& mountpoint) const
    {
	if (mountpoint == "swap" || rootprefix.empty())
	    return mountpoint;

	if (mountpoint == "/")
	    return rootprefix;
	else
	    return rootprefix + mountpoint;
    }

    const Actiongraph*
    Storage::Impl::calculate_actiongraph()
    {
	actiongraph.reset(new Actiongraph(storage, get_probed(), get_staging()));

	return actiongraph.get();
    }

    void
    Storage::Impl::commit(const CommitCallbacks* commit_callbacks)
    {
	ST_CHECK_PTR(actiongraph.get());

	actiongraph->get_impl().commit(commit_callbacks);

	// TODO somehow update probed
    }

}
<commit_msg>Prevent crash upon shutdown (object destruction sequence)<commit_after>

#include "config.h"
#include "storage/StorageImpl.h"
#include "storage/DevicegraphImpl.h"
#include "storage/Devices/DiskImpl.h"
#include "storage/Devices/FilesystemImpl.h"
#include "storage/SystemInfo/SystemInfo.h"
#include "storage/Actiongraph.h"
#include "storage/Utils/AppUtil.h"
#include "storage/Utils/Mockup.h"

namespace storage
{

    Storage::Impl::Impl(const Storage& storage, const Environment& environment)
	: storage(storage), environment(environment), arch(false)
    {
	y2mil("constructed Storage with " << environment);
	y2mil("libstorage version " VERSION);

	Devicegraph* probed = create_devicegraph("probed");

	switch (environment.get_probe_mode())
	{
	    case ProbeMode::STANDARD: {
		probe(probed);
	    } break;

	    case ProbeMode::STANDARD_WRITE_DEVICEGRAPH: {
		probe(probed);
		probed->save(environment.get_devicegraph_filename());
	    } break;

	    case ProbeMode::STANDARD_WRITE_MOCKUP: {
		Mockup::set_mode(Mockup::Mode::RECORD);
		probe(probed);
		Mockup::save(environment.get_mockup_filename());
	    } break;

	    case ProbeMode::NONE: {
	    } break;

	    case ProbeMode::READ_DEVICEGRAPH: {
		probed->load(environment.get_devicegraph_filename());
	    } break;

	    case ProbeMode::READ_MOCKUP: {
		Mockup::set_mode(Mockup::Mode::PLAYBACK);
		Mockup::load(environment.get_mockup_filename());
		probe(probed);
	    } break;
	}

	y2mil("probed devicegraph begin");
	y2mil(*probed);
	y2mil("probed devicegraph end");

	copy_devicegraph("probed", "staging");
    }

    Storage::Impl::~Impl()
    {
    }

    void
    Storage::Impl::probe(Devicegraph* probed)
    {
	SystemInfo systeminfo;

	arch = systeminfo.getArch();

	EtcFstab fstab("/etc");

	// TODO

	for (const string& name : Disk::Impl::probe_disks(systeminfo))
	{
	    Disk* disk = Disk::create(probed, name);
	    disk->get_impl().probe(systeminfo);
	}

	for (Devicegraph::Impl::vertex_descriptor vertex : probed->get_impl().vertices())
	{
	    BlkDevice* blkdevice = dynamic_cast<BlkDevice*>(probed->get_impl()[vertex]);
	    if (!blkdevice)
		continue;

	    if (blkdevice->num_children() != 0)
		continue;

	    Blkid::Entry entry;
	    if (systeminfo.getBlkid().getEntry(blkdevice->get_name(), entry))
	    {
		if (entry.is_fs)
		{
		    // TODO temporary until all fs are implemented
		    if (entry.fs_type != EXT4 && entry.fs_type != BTRFS && entry.fs_type != XFS &&
			entry.fs_type != SWAP)
			continue;

		    Filesystem* filesystem = blkdevice->create_filesystem(entry.fs_type);
		    filesystem->get_impl().probe(systeminfo, fstab);
		}
	    }
	}
    }

    Devicegraph*
    Storage::Impl::get_devicegraph(const string& name)
    {
	if (name == "probed")
	    throw runtime_error("invalid name");

	map<string, Devicegraph>::iterator it = devicegraphs.find(name);
	if (it == devicegraphs.end())
	    throw runtime_error("device graph not found");

	return &it->second;
    }

    const Devicegraph*
    Storage::Impl::get_devicegraph(const string& name) const
    {
	map<string, Devicegraph>::const_iterator it = devicegraphs.find(name);
	if (it == devicegraphs.end())
	    throw runtime_error("device graph not found");

	return &it->second;
    }

    Devicegraph*
    Storage::Impl::get_staging()
    {
	return get_devicegraph("staging");
    }

    const Devicegraph*
    Storage::Impl::get_staging() const
    {
	return get_devicegraph("staging");
    }

    const Devicegraph*
    Storage::Impl::get_probed() const
    {
	return get_devicegraph("probed");
    }

    vector<string>
    Storage::Impl::get_devicegraph_names() const
    {
	vector<string> ret;

	for (const map<string, Devicegraph>::value_type& it : devicegraphs)
	    ret.push_back(it.first);

	return ret;
    }

    Devicegraph*
    Storage::Impl::create_devicegraph(const string& name)
    {
	pair<map<string, Devicegraph>::iterator, bool> tmp =
	    devicegraphs.emplace(piecewise_construct, forward_as_tuple(name),
				 forward_as_tuple(&storage));
	if (!tmp.second)
	    throw logic_error("device graph already exists");

	map<string, Devicegraph>::iterator it = tmp.first;

	return &it->second;
    }

    Devicegraph*
    Storage::Impl::copy_devicegraph(const string& source_name, const string& dest_name)
    {
	const Devicegraph* tmp1 = static_cast<const Impl*>(this)->get_devicegraph(source_name);

	Devicegraph* tmp2 = create_devicegraph(dest_name);

	tmp1->copy(*tmp2);

	return tmp2;
    }

    void
    Storage::Impl::remove_devicegraph(const string& name)
    {
	map<string, Devicegraph>::const_iterator it1 = devicegraphs.find(name);
	if (it1 == devicegraphs.end())
	    throw runtime_error("device graph not found");

	devicegraphs.erase(it1);
    }

    void
    Storage::Impl::restore_devicegraph(const string& name)
    {
	map<string, Devicegraph>::iterator it1 = devicegraphs.find(name);
	if (it1 == devicegraphs.end())
	    throw runtime_error("device graph not found");

	map<string, Devicegraph>::iterator it2 = devicegraphs.find("staging");
	if (it2 == devicegraphs.end())
	    throw runtime_error("device graph not found");

	it1->second.get_impl().swap(it2->second.get_impl());
	devicegraphs.erase(it1);
    }

    bool
    Storage::Impl::exist_devicegraph(const string& name) const
    {
	return devicegraphs.find(name) != devicegraphs.end();
    }

    bool
    Storage::Impl::equal_devicegraph(const string& lhs, const string& rhs) const
    {
	return *get_devicegraph(lhs) == *get_devicegraph(rhs);
    }

    void
    Storage::Impl::check() const
    {
	for (const map<string, Devicegraph>::value_type& key_value : devicegraphs)
	{
	    key_value.second.check();
	}

	// TODO check that a object has the same type in every devicegraph
    }

    string
    Storage::Impl::prepend_rootprefix(const string& mountpoint) const
    {
	if (mountpoint == "swap" || rootprefix.empty())
	    return mountpoint;

	if (mountpoint == "/")
	    return rootprefix;
	else
	    return rootprefix + mountpoint;
    }

    const Actiongraph*
    Storage::Impl::calculate_actiongraph()
    {
	actiongraph.reset(new Actiongraph(storage, get_probed(), get_staging()));

	return actiongraph.get();
    }

    void
    Storage::Impl::commit(const CommitCallbacks* commit_callbacks)
    {
	ST_CHECK_PTR(actiongraph.get());

	actiongraph->get_impl().commit(commit_callbacks);

	// TODO somehow update probed
    }

}
<|endoftext|>