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

//_________________________________________________________________________________________________________________
//  my own includes
//_________________________________________________________________________________________________________________

#ifndef __FRAMEWORK_PATTERN_WINDOW_HXX_
#include <pattern/window.hxx>
#endif

#ifndef __FRAMEWORK_HELPER_PERSISTENTWINDOWSTATE_HXX_
#include <helper/persistentwindowstate.hxx>
#endif

#ifndef __FRAMEWORK_THREADHELP_WRITEGUARD_HXX_
#include <threadhelp/writeguard.hxx>
#endif

#ifndef __FRAMEWORK_THREADHELP_READGUARD_HXX_
#include <threadhelp/readguard.hxx>
#endif

#ifndef __FRAMEWORK_MACROS_GENERIC_HXX_
#include <macros/generic.hxx>
#endif

#ifndef __FRAMEWORK_SERVICES_H_
#include <services.h>
#endif

//_________________________________________________________________________________________________________________
//  interface includes
//_________________________________________________________________________________________________________________

#ifndef _COM_SUN_STAR_AWT_XWINDOW_HPP_
#include <com/sun/star/awt/XWindow.hpp>
#endif

#ifndef _COM_SUN_STAR_LANG_XSERVICXEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif

#ifndef _COM_SUN_STAR_LANG_ILLEGALARGUMENTEXCEPTION_HPP_
#include <com/sun/star/lang/IllegalArgumentException.hpp>
#endif

#ifndef _DRAFTS_COM_SUN_STAR_FRAME_XMODULEMANAGER_HPP_
#include <drafts/com/sun/star/frame/XModuleManager.hpp>
#endif

//_________________________________________________________________________________________________________________
//  other includes
//_________________________________________________________________________________________________________________

#ifndef _COMPHELPER_CONFIGURATIONHELPER_HXX_
#include <comphelper/configurationhelper.hxx>
#endif

#ifndef _SV_WINDOW_HXX
#include <vcl/window.hxx>
#endif

#ifndef _SV_SYSWIN_HXX
#include <vcl/syswin.hxx>
#endif

#ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
#include <toolkit/unohlp.hxx>
#endif

#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif

#ifndef _SV_WRKWIN_HXX
#include <vcl/wrkwin.hxx>
#endif

//_________________________________________________________________________________________________________________
//  namespace

namespace framework{

namespace fpw = ::framework::pattern::window;

//_________________________________________________________________________________________________________________
//  definitions

//*****************************************************************************************************************
//  XInterface, XTypeProvider

DEFINE_XINTERFACE_4(PersistentWindowState                                                       ,
                    OWeakObject                                                                 ,
                    DIRECT_INTERFACE (css::lang::XTypeProvider                                  ),
                    DIRECT_INTERFACE (css::lang::XInitialization                                ),
                    DIRECT_INTERFACE (css::frame::XFrameActionListener                          ),
                    DERIVED_INTERFACE(css::lang::XEventListener,css::frame::XFrameActionListener))

DEFINE_XTYPEPROVIDER_4(PersistentWindowState           ,
                       css::lang::XTypeProvider        ,
                       css::lang::XInitialization      ,
                       css::frame::XFrameActionListener,
                       css::lang::XEventListener       )

//*****************************************************************************************************************
PersistentWindowState::PersistentWindowState(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
    : ThreadHelpBase(&Application::GetSolarMutex())
    , m_xSMGR       (xSMGR                        )
{
}

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

//*****************************************************************************************************************
void SAL_CALL PersistentWindowState::initialize(const css::uno::Sequence< css::uno::Any >& lArguments)
    throw(css::uno::Exception       ,
          css::uno::RuntimeException)
{
    // check arguments
    css::uno::Reference< css::frame::XFrame > xFrame;
    if (lArguments.getLength() < 1)
        throw css::lang::IllegalArgumentException(
                DECLARE_ASCII("Empty argument list!"),
                static_cast< ::cppu::OWeakObject* >(this),
                1);

    lArguments[0] >>= xFrame;
    if (!xFrame.is())
        throw css::lang::IllegalArgumentException(
                DECLARE_ASCII("No valid frame specified!"),
                static_cast< ::cppu::OWeakObject* >(this),
                1);

    // SAFE -> ----------------------------------
    WriteGuard aWriteLock(m_aLock);
    // hold the frame as weak reference(!) so it can die everytimes :-)
    m_xFrame = xFrame;
    aWriteLock.unlock();
    // <- SAFE ----------------------------------

    // start listening
    xFrame->addFrameActionListener(this);
}

//*****************************************************************************************************************
void SAL_CALL PersistentWindowState::frameAction(const css::frame::FrameActionEvent& aEvent)
    throw(css::uno::RuntimeException)
{
    // SAFE -> ----------------------------------
    ReadGuard aReadLock(m_aLock);
    css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR ;
    css::uno::Reference< css::frame::XFrame >              xFrame(m_xFrame.get(), css::uno::UNO_QUERY);
    aReadLock.unlock();
    // <- SAFE ----------------------------------

    // frame already gone ? We hold it weak only ...
    if (!xFrame.is())
        return;

    // no window -> no position and size available
    css::uno::Reference< css::awt::XWindow > xWindow = xFrame->getContainerWindow();
    if (!xWindow.is())
        return;

    // unknown module -> no configuration available!
    ::rtl::OUString sModuleName = PersistentWindowState::implst_identifyModule(xSMGR, xFrame);
    if (!sModuleName.getLength())
        return;

    switch(aEvent.Action)
    {
        case css::frame::FrameAction_COMPONENT_ATTACHED :
            {
                ::rtl::OUString sWindowState = PersistentWindowState::implst_getWindowStateFromConfig(xSMGR, sModuleName);
                PersistentWindowState::implst_setWindowStateOnWindow(xWindow,sWindowState);
            }
            break;

        case css::frame::FrameAction_COMPONENT_REATTACHED :
            {
                // nothing todo here, because its not allowed to change position and size
                // of an alredy existing frame!
            }
            break;

        case css::frame::FrameAction_COMPONENT_DETACHING :
            {
                ::rtl::OUString sWindowState = PersistentWindowState::implst_getWindowStateFromWindow(xWindow);
                PersistentWindowState::implst_setWindowStateOnConfig(xSMGR, sModuleName, sWindowState);
            }
            break;
    }
}

//*****************************************************************************************************************
void SAL_CALL PersistentWindowState::disposing(const css::lang::EventObject& aEvent)
    throw(css::uno::RuntimeException)
{
    // nothing todo here - because we hold the frame as weak reference only
}

//*****************************************************************************************************************
::rtl::OUString PersistentWindowState::implst_identifyModule(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
                                                             const css::uno::Reference< css::frame::XFrame >&              xFrame)
{
    ::rtl::OUString sModuleName;

    css::uno::Reference< dcss::frame::XModuleManager > xModuleManager(
        xSMGR->createInstance(SERVICENAME_MODULEMANAGER),
        css::uno::UNO_QUERY_THROW);

    try
    {
        sModuleName = xModuleManager->identify(xFrame);
    }
    catch(const css::uno::RuntimeException& exRun)
        { throw exRun; }
    catch(const css::uno::Exception&)
        { sModuleName = ::rtl::OUString(); }

    return sModuleName;
}

//*****************************************************************************************************************
::rtl::OUString PersistentWindowState::implst_getWindowStateFromConfig(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR      ,
                                                                       const ::rtl::OUString&                                        sModuleName)
{
    ::rtl::OUString sWindowState;

    ::rtl::OUStringBuffer sRelPathBuf(256);
    sRelPathBuf.appendAscii("Office/Factories/*[\"");
    sRelPathBuf.append     (sModuleName            );
    sRelPathBuf.appendAscii("\"]"                  );

    ::rtl::OUString sPackage = ::rtl::OUString::createFromAscii("org.openoffice.Setup/");
    ::rtl::OUString sRelPath = sRelPathBuf.makeStringAndClear();
    ::rtl::OUString sKey     = ::rtl::OUString::createFromAscii("ooSetupFactoryWindowAttributes");

    try
    {
        css::uno::Any aWindowState = ::comphelper::ConfigurationHelper::readDirectKey(xSMGR,
                                                                                sPackage,
                                                                                sRelPath,
                                                                                sKey,
                                                                                ::comphelper::ConfigurationHelper::E_READONLY);
        aWindowState >>= sWindowState;
    }
    catch(const css::uno::RuntimeException& exRun)
        { throw exRun; }
    catch(const css::uno::Exception&)
        { sWindowState = ::rtl::OUString(); }

    return sWindowState;
}

//*****************************************************************************************************************
void PersistentWindowState::implst_setWindowStateOnConfig(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR       ,
                                                          const ::rtl::OUString&                                        sModuleName ,
                                                          const ::rtl::OUString&                                        sWindowState)
{
    ::rtl::OUStringBuffer sRelPathBuf(256);
    sRelPathBuf.appendAscii("Office/Factories/*[\"");
    sRelPathBuf.append     (sModuleName            );
    sRelPathBuf.appendAscii("\"]"                  );

    ::rtl::OUString sPackage = ::rtl::OUString::createFromAscii("org.openoffice.Setup/");
    ::rtl::OUString sRelPath = sRelPathBuf.makeStringAndClear();
    ::rtl::OUString sKey     = ::rtl::OUString::createFromAscii("ooSetupFactoryWindowAttributes");

    try
    {
        ::comphelper::ConfigurationHelper::writeDirectKey(xSMGR,
                                                          sPackage,
                                                          sRelPath,
                                                          sKey,
                                                          css::uno::makeAny(sWindowState),
                                                          ::comphelper::ConfigurationHelper::E_STANDARD);
    }
    catch(const css::uno::RuntimeException& exRun)
        { throw exRun; }
    catch(const css::uno::Exception&)
        {}
}

//*****************************************************************************************************************
::rtl::OUString PersistentWindowState::implst_getWindowStateFromWindow(const css::uno::Reference< css::awt::XWindow >& xWindow)
{
    ::rtl::OUString sWindowState;

    if (xWindow.is())
    {
        // SOLAR SAFE -> ------------------------
        ::vos::OClearableGuard aSolarLock(Application::GetSolarMutex());

        Window* pWindow = VCLUnoHelper::GetWindow(xWindow);
        // check for system window is neccessary to guarantee correct pointer cast!
        if (
            (pWindow                  ) &&
            (pWindow->IsSystemWindow())
           )
        {
            ULONG nMask  =   WINDOWSTATE_MASK_ALL;
                  nMask &= ~(WINDOWSTATE_MASK_MINIMIZED);
            sWindowState = B2U_ENC(
                            ((SystemWindow*)pWindow)->GetWindowState(nMask),
                            RTL_TEXTENCODING_UTF8);
        }

        aSolarLock.clear();
        // <- SOLAR SAFE ------------------------
    }

    return sWindowState;
}

//*********************************************************************************************************
void PersistentWindowState::implst_setWindowStateOnWindow(const css::uno::Reference< css::awt::XWindow >& xWindow     ,
                                                          const ::rtl::OUString&                          sWindowState)
{
    if (
        (!xWindow.is()                ) ||
        ( sWindowState.getLength() < 1)
       )
        return;

    // SOLAR SAFE -> ------------------------
    ::vos::OClearableGuard aSolarLock(Application::GetSolarMutex());

    Window* pWindow = VCLUnoHelper::GetWindow(xWindow);
    if (!pWindow)
        return;

    // check for system and work window - its neccessary to guarantee correct pointer cast!
    sal_Bool bSystemWindow = pWindow->IsSystemWindow();
    sal_Bool bWorkWindow   = (pWindow->GetType() == WINDOW_WORKWINDOW);

    if (!bSystemWindow && !bWorkWindow)
        return;

    SystemWindow* pSystemWindow = (SystemWindow*)pWindow;
    WorkWindow*   pWorkWindow   = (WorkWindow*  )pWindow;

    // dont save this special state!
    if (pWorkWindow->IsMinimized())
        return;

    pSystemWindow->SetWindowState(U2B_ENC(sWindowState,RTL_TEXTENCODING_UTF8));

    aSolarLock.clear();
    // <- SOLAR SAFE ------------------------
}

} // namespace framework
<commit_msg>INTEGRATION: CWS fwkbeta01 (1.5.6); FILE MERGED 2004/12/01 12:07:22 as 1.5.6.1: #i38089# restore view data one times only for the same frame<commit_after>/*************************************************************************
 *
 *  $RCSfile: persistentwindowstate.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: kz $ $Date: 2004-12-03 14:04:39 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

//_________________________________________________________________________________________________________________
//  my own includes
//_________________________________________________________________________________________________________________

#ifndef __FRAMEWORK_PATTERN_WINDOW_HXX_
#include <pattern/window.hxx>
#endif

#ifndef __FRAMEWORK_HELPER_PERSISTENTWINDOWSTATE_HXX_
#include <helper/persistentwindowstate.hxx>
#endif

#ifndef __FRAMEWORK_THREADHELP_WRITEGUARD_HXX_
#include <threadhelp/writeguard.hxx>
#endif

#ifndef __FRAMEWORK_THREADHELP_READGUARD_HXX_
#include <threadhelp/readguard.hxx>
#endif

#ifndef __FRAMEWORK_MACROS_GENERIC_HXX_
#include <macros/generic.hxx>
#endif

#ifndef __FRAMEWORK_SERVICES_H_
#include <services.h>
#endif

//_________________________________________________________________________________________________________________
//  interface includes
//_________________________________________________________________________________________________________________

#ifndef _COM_SUN_STAR_AWT_XWINDOW_HPP_
#include <com/sun/star/awt/XWindow.hpp>
#endif

#ifndef _COM_SUN_STAR_LANG_XSERVICXEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif

#ifndef _COM_SUN_STAR_LANG_ILLEGALARGUMENTEXCEPTION_HPP_
#include <com/sun/star/lang/IllegalArgumentException.hpp>
#endif

#ifndef _DRAFTS_COM_SUN_STAR_FRAME_XMODULEMANAGER_HPP_
#include <drafts/com/sun/star/frame/XModuleManager.hpp>
#endif

//_________________________________________________________________________________________________________________
//  other includes
//_________________________________________________________________________________________________________________

#ifndef _COMPHELPER_CONFIGURATIONHELPER_HXX_
#include <comphelper/configurationhelper.hxx>
#endif

#ifndef _SV_WINDOW_HXX
#include <vcl/window.hxx>
#endif

#ifndef _SV_SYSWIN_HXX
#include <vcl/syswin.hxx>
#endif

#ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
#include <toolkit/unohlp.hxx>
#endif

#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif

#ifndef _SV_WRKWIN_HXX
#include <vcl/wrkwin.hxx>
#endif

//_________________________________________________________________________________________________________________
//  namespace

namespace framework{

namespace fpw = ::framework::pattern::window;

//_________________________________________________________________________________________________________________
//  definitions

//*****************************************************************************************************************
//  XInterface, XTypeProvider

DEFINE_XINTERFACE_4(PersistentWindowState                                                       ,
                    OWeakObject                                                                 ,
                    DIRECT_INTERFACE (css::lang::XTypeProvider                                  ),
                    DIRECT_INTERFACE (css::lang::XInitialization                                ),
                    DIRECT_INTERFACE (css::frame::XFrameActionListener                          ),
                    DERIVED_INTERFACE(css::lang::XEventListener,css::frame::XFrameActionListener))

DEFINE_XTYPEPROVIDER_4(PersistentWindowState           ,
                       css::lang::XTypeProvider        ,
                       css::lang::XInitialization      ,
                       css::frame::XFrameActionListener,
                       css::lang::XEventListener       )

//*****************************************************************************************************************
PersistentWindowState::PersistentWindowState(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
    : ThreadHelpBase          (&Application::GetSolarMutex())
    , m_xSMGR                 (xSMGR                        )
    , m_bWindowStateAlreadySet(sal_False                    )
{
}

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

//*****************************************************************************************************************
void SAL_CALL PersistentWindowState::initialize(const css::uno::Sequence< css::uno::Any >& lArguments)
    throw(css::uno::Exception       ,
          css::uno::RuntimeException)
{
    // check arguments
    css::uno::Reference< css::frame::XFrame > xFrame;
    if (lArguments.getLength() < 1)
        throw css::lang::IllegalArgumentException(
                DECLARE_ASCII("Empty argument list!"),
                static_cast< ::cppu::OWeakObject* >(this),
                1);

    lArguments[0] >>= xFrame;
    if (!xFrame.is())
        throw css::lang::IllegalArgumentException(
                DECLARE_ASCII("No valid frame specified!"),
                static_cast< ::cppu::OWeakObject* >(this),
                1);

    // SAFE -> ----------------------------------
    WriteGuard aWriteLock(m_aLock);
    // hold the frame as weak reference(!) so it can die everytimes :-)
    m_xFrame = xFrame;
    aWriteLock.unlock();
    // <- SAFE ----------------------------------

    // start listening
    xFrame->addFrameActionListener(this);
}

//*****************************************************************************************************************
void SAL_CALL PersistentWindowState::frameAction(const css::frame::FrameActionEvent& aEvent)
    throw(css::uno::RuntimeException)
{
    // SAFE -> ----------------------------------
    ReadGuard aReadLock(m_aLock);
    css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR ;
    css::uno::Reference< css::frame::XFrame >              xFrame(m_xFrame.get(), css::uno::UNO_QUERY);
    sal_Bool                                               bRestoreWindowState = !m_bWindowStateAlreadySet;
    aReadLock.unlock();
    // <- SAFE ----------------------------------

    // frame already gone ? We hold it weak only ...
    if (!xFrame.is())
        return;

    // no window -> no position and size available
    css::uno::Reference< css::awt::XWindow > xWindow = xFrame->getContainerWindow();
    if (!xWindow.is())
        return;

    // unknown module -> no configuration available!
    ::rtl::OUString sModuleName = PersistentWindowState::implst_identifyModule(xSMGR, xFrame);
    if (!sModuleName.getLength())
        return;

    switch(aEvent.Action)
    {
        case css::frame::FrameAction_COMPONENT_ATTACHED :
            {
                if (bRestoreWindowState)
                {
                    ::rtl::OUString sWindowState = PersistentWindowState::implst_getWindowStateFromConfig(xSMGR, sModuleName);
                    PersistentWindowState::implst_setWindowStateOnWindow(xWindow,sWindowState);
                    // SAFE -> ----------------------------------
                    WriteGuard aWriteLock(m_aLock);
                    m_bWindowStateAlreadySet = sal_True;
                    aWriteLock.unlock();
                    // <- SAFE ----------------------------------
                }
            }
            break;

        case css::frame::FrameAction_COMPONENT_REATTACHED :
            {
                // nothing todo here, because its not allowed to change position and size
                // of an alredy existing frame!
            }
            break;

        case css::frame::FrameAction_COMPONENT_DETACHING :
            {
                ::rtl::OUString sWindowState = PersistentWindowState::implst_getWindowStateFromWindow(xWindow);
                PersistentWindowState::implst_setWindowStateOnConfig(xSMGR, sModuleName, sWindowState);
            }
            break;
    }
}

//*****************************************************************************************************************
void SAL_CALL PersistentWindowState::disposing(const css::lang::EventObject& aEvent)
    throw(css::uno::RuntimeException)
{
    // nothing todo here - because we hold the frame as weak reference only
}

//*****************************************************************************************************************
::rtl::OUString PersistentWindowState::implst_identifyModule(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
                                                             const css::uno::Reference< css::frame::XFrame >&              xFrame)
{
    ::rtl::OUString sModuleName;

    css::uno::Reference< dcss::frame::XModuleManager > xModuleManager(
        xSMGR->createInstance(SERVICENAME_MODULEMANAGER),
        css::uno::UNO_QUERY_THROW);

    try
    {
        sModuleName = xModuleManager->identify(xFrame);
    }
    catch(const css::uno::RuntimeException& exRun)
        { throw exRun; }
    catch(const css::uno::Exception&)
        { sModuleName = ::rtl::OUString(); }

    return sModuleName;
}

//*****************************************************************************************************************
::rtl::OUString PersistentWindowState::implst_getWindowStateFromConfig(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR      ,
                                                                       const ::rtl::OUString&                                        sModuleName)
{
    ::rtl::OUString sWindowState;

    ::rtl::OUStringBuffer sRelPathBuf(256);
    sRelPathBuf.appendAscii("Office/Factories/*[\"");
    sRelPathBuf.append     (sModuleName            );
    sRelPathBuf.appendAscii("\"]"                  );

    ::rtl::OUString sPackage = ::rtl::OUString::createFromAscii("org.openoffice.Setup/");
    ::rtl::OUString sRelPath = sRelPathBuf.makeStringAndClear();
    ::rtl::OUString sKey     = ::rtl::OUString::createFromAscii("ooSetupFactoryWindowAttributes");

    try
    {
        css::uno::Any aWindowState = ::comphelper::ConfigurationHelper::readDirectKey(xSMGR,
                                                                                sPackage,
                                                                                sRelPath,
                                                                                sKey,
                                                                                ::comphelper::ConfigurationHelper::E_READONLY);
        aWindowState >>= sWindowState;
    }
    catch(const css::uno::RuntimeException& exRun)
        { throw exRun; }
    catch(const css::uno::Exception&)
        { sWindowState = ::rtl::OUString(); }

    return sWindowState;
}

//*****************************************************************************************************************
void PersistentWindowState::implst_setWindowStateOnConfig(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR       ,
                                                          const ::rtl::OUString&                                        sModuleName ,
                                                          const ::rtl::OUString&                                        sWindowState)
{
    ::rtl::OUStringBuffer sRelPathBuf(256);
    sRelPathBuf.appendAscii("Office/Factories/*[\"");
    sRelPathBuf.append     (sModuleName            );
    sRelPathBuf.appendAscii("\"]"                  );

    ::rtl::OUString sPackage = ::rtl::OUString::createFromAscii("org.openoffice.Setup/");
    ::rtl::OUString sRelPath = sRelPathBuf.makeStringAndClear();
    ::rtl::OUString sKey     = ::rtl::OUString::createFromAscii("ooSetupFactoryWindowAttributes");

    try
    {
        ::comphelper::ConfigurationHelper::writeDirectKey(xSMGR,
                                                          sPackage,
                                                          sRelPath,
                                                          sKey,
                                                          css::uno::makeAny(sWindowState),
                                                          ::comphelper::ConfigurationHelper::E_STANDARD);
    }
    catch(const css::uno::RuntimeException& exRun)
        { throw exRun; }
    catch(const css::uno::Exception&)
        {}
}

//*****************************************************************************************************************
::rtl::OUString PersistentWindowState::implst_getWindowStateFromWindow(const css::uno::Reference< css::awt::XWindow >& xWindow)
{
    ::rtl::OUString sWindowState;

    if (xWindow.is())
    {
        // SOLAR SAFE -> ------------------------
        ::vos::OClearableGuard aSolarLock(Application::GetSolarMutex());

        Window* pWindow = VCLUnoHelper::GetWindow(xWindow);
        // check for system window is neccessary to guarantee correct pointer cast!
        if (
            (pWindow                  ) &&
            (pWindow->IsSystemWindow())
           )
        {
            ULONG nMask  =   WINDOWSTATE_MASK_ALL;
                  nMask &= ~(WINDOWSTATE_MASK_MINIMIZED);
            sWindowState = B2U_ENC(
                            ((SystemWindow*)pWindow)->GetWindowState(nMask),
                            RTL_TEXTENCODING_UTF8);
        }

        aSolarLock.clear();
        // <- SOLAR SAFE ------------------------
    }

    return sWindowState;
}

//*********************************************************************************************************
void PersistentWindowState::implst_setWindowStateOnWindow(const css::uno::Reference< css::awt::XWindow >& xWindow     ,
                                                          const ::rtl::OUString&                          sWindowState)
{
    if (
        (!xWindow.is()                ) ||
        ( sWindowState.getLength() < 1)
       )
        return;

    // SOLAR SAFE -> ------------------------
    ::vos::OClearableGuard aSolarLock(Application::GetSolarMutex());

    Window* pWindow = VCLUnoHelper::GetWindow(xWindow);
    if (!pWindow)
        return;

    // check for system and work window - its neccessary to guarantee correct pointer cast!
    sal_Bool bSystemWindow = pWindow->IsSystemWindow();
    sal_Bool bWorkWindow   = (pWindow->GetType() == WINDOW_WORKWINDOW);

    if (!bSystemWindow && !bWorkWindow)
        return;

    SystemWindow* pSystemWindow = (SystemWindow*)pWindow;
    WorkWindow*   pWorkWindow   = (WorkWindow*  )pWindow;

    // dont save this special state!
    if (pWorkWindow->IsMinimized())
        return;

    pSystemWindow->SetWindowState(U2B_ENC(sWindowState,RTL_TEXTENCODING_UTF8));

    aSolarLock.clear();
    // <- SOLAR SAFE ------------------------
}

} // namespace framework
<|endoftext|>


<commit_before>//
//  boost_console.cpp
//  TameParse
//
//  Created by Andrew Hunter on 24/09/2011.
//  Copyright 2011-2012 Andrew Hunter. All rights reserved.
//

#include <string>
#include <vector>

#include "TameParse/version.h"

#include "boost_console.h"
#include "boost/program_options.hpp"
#include "boost/filesystem.hpp"
#include "boost/filesystem/fstream.hpp"

using namespace std;
using namespace compiler;
using namespace tameparse;

namespace po = boost::program_options;
namespace fs = boost::filesystem;

 // \brief Copies this console
boost_console::boost_console(const boost_console& bc)
: std_console(L"")
, m_VarMap(bc.m_VarMap) {
}

/// \brief Constructor
boost_console::boost_console(int argc, const char** argv)
: std_console(L"") {
	// Declare the options supported by the tameparse utility
	po::options_description inputOptions("Input options");

	inputOptions.add_options()
		("input-file,i",		po::value<string>(),			"specifies the name of the input file.")
		("include-path,I",		po::value< vector<string> >(),	"sets the path to search for included files.");

	po::options_description outputOptions("Output options");

	outputOptions.add_options()
		("output-file,o",		po::value<string>(),			"specifies the base name for the output file. For languages that need to generate multiple files (for example, C++), the appropriate extensions will be added to this filename. If this is not specified, the output filenames will be derived from the input file.")
		("output-language,T",	po::value<string>(),			"specifies the output language the parser will be generated in.")
		("start-symbol,S",		po::value< vector<string> >(),	"specifies the name of the start symbol (overriding anything defined in the parser block of the input file)")
		("compile-language,L",	po::value<string>(),			"specifies the name of the language block to compile (overriding anything defined in the parser block of the input file)")
		("class-name,C",		po::value<string>(),			"specifies the name of the class to generate (overriding anything defined in the parser block of the input file)")
		("namespace-name,N",	po::value<string>(),			"specifies the namespace to put the target class into.")
		("run-tests",											"if the language contains any tests, then run them")
		("test",												"specifies that no output should be generated. This tool will instead try to read from stdin and indicate whether or not it can be accepted.")
        ("show-parser",                                         "writes the generated parser to standard out");

	po::options_description infoOptions("Information");

    infoOptions.add_options()
        ("help,h", 												"display help message.")
        ("verbose,v",											"display verbose messages.")
        ("silent",												"suppress informational messages.")
        ("version",												"display version information.")
        ("warranty",											"display warranty information.")
        ("license",												"display license information.");

    po::options_description errorOptions("Error reporting");

    errorOptions.add_options()
        ("suppress-warnings",                                   "do not display any warning messages.")
        ("show-error-codes",                                    "display error codes alongside the error messages.")
        ("show-conflict-details",                               "show details about the context that conflicts occur in.")
        ("allow-reduce-conflicts",                              "reduce/reduce conflicts will produce a warning instead of an error.")
        ("no-conflicts",                                        "all parser conflicts count as an error and not a warning.");

    po::options_description hiddenOptions;

    hiddenOptions.add_options()
    	("show-parser-closure", 								"display the closure of all states when showing the parser with --show-parser.")
    	("show-propagation",									"display the lookahead propagation tables")
    	("disable-compact-dfa",									"do not compact the DFA")
    	("disable-merged-dfa",									"do not attempt to merge symbol sets in the DFA");

	// Positional options
	po::positional_options_description positional;

	positional.add("input-file", 1);
	positional.add("output-file", 1);

    // Command line options
    po::options_description cmdLine;
    po::options_description help;
    cmdLine.add(inputOptions).add(outputOptions).add(infoOptions).add(errorOptions).add(hiddenOptions);
    help.add(inputOptions).add(outputOptions).add(infoOptions).add(errorOptions);

	// Store the options
    try {
        po::store(po::command_line_parser(argc, argv).options(cmdLine).positional(positional).run(), m_VarMap);
        po::notify(m_VarMap);
    } catch (po::error e) {
        cerr << e.what() << endl << endl;
		cout << help << endl;
        ::exit(1);
    }

	// Display help if needed
    bool doneSomething = false;

    if (m_VarMap.count("version") || m_VarMap.count("warranty") || m_VarMap.count("license") || m_VarMap.count("help")) {
        cout << "TameParse version " << version::version_string;
        if (m_VarMap.count("license") == 0) {
            cout << endl << version::copyright_string << " " << version::contact_string;
        }
        cout << endl << endl;
        doneSomething = true;
    }

    if (m_VarMap.count("warranty")) {
        cout << version::warranty_string << endl << endl;
        doneSomething = true;
    }

    if (m_VarMap.count("license")) {
        cout << version::license_string << endl << endl;
        doneSomething = true;
    }

	if (m_VarMap.count("help")) {
		cout << help << endl;
	    doneSomething = true;
	}

	// Also display help if no input file is displayed
	if (!doneSomething && m_VarMap.count("input-file") == 0) {
		cerr << argv[0] << ": no input files" << endl << endl;
		cout << help << endl;
	}

    // Set the value of the input file string
    m_InputFile = get_option(L"input-file");
}

/// \brief Returns true if the options are valid and the parser can start
bool boost_console::can_start() const {
	// Nothing to do if no input file is specified
	if (m_VarMap.count("input-file") == 0) {
		return false;
	}

	// Everything looks to be in order
    return true;
}

/// \brief Clones the console
console* boost_console::clone() const {
	return new boost_console(*this);
}

/// \brief Reports an error to the console
void boost_console::report_error(const compiler::error& error) {
	// Pass to the standard console
	std_console::report_error(error);
}

/// \brief Simple conversion from a string to wstring
static wstring convert(string asciiValue) {
	// Convert to a wstring by assuming that the string is latin-1
	// TODO: could take account of the locale here, somehow
	wstring value;
	for (size_t x = 0; x < asciiValue.size(); ++x) {
		value += (wchar_t) asciiValue[x];
	}

	return value;
}

/// \brief Retrieves the value of the option with the specified name.
///
/// If the option is not set, then this should return an empty string
std::wstring boost_console::get_option(const std::wstring& name) const {
	// Convert to a standard string
	string asciiName;

	for (size_t x=0; x<name.size(); ++x) {
		asciiName += (char) name[x];
	}

	// Return the empty string if the option is not present
	if (m_VarMap.count(asciiName) == 0) {
		return L"";
	}

	// Try to get the value as a string
	try {
		// Convert to a wstring
		wstring value = convert(m_VarMap[asciiName].as<string>());

        // Value is '1' if the value is empty but the option is present
        if (value.empty()) {
            value += L'1';
        }

		return value;
	} catch (boost::bad_any_cast) {
		// The option is present but doesn't have a string value
		// Assume it's a boolean on/off option and return the name
		return name;
	}
}

/// \brief Returns a list of values for a particular option
///
/// For some options it is possible to specify more than one value: in this
/// case, this will return all of the possible values. This can also be used
/// to retrieve the values of options that can have an empty value.
std::vector<std::wstring> boost_console::get_option_list(const std::wstring& name) {
	// Convert to a standard string
	string asciiName;

	for (size_t x=0; x<name.size(); ++x) {
		asciiName += (char) name[x];
	}

	// Return the empty string if the option is not present
	if (m_VarMap.count(asciiName) == 0) {
		return vector<wstring>();
	}

	// Try to get the value as a string
	try {
		// Get as an ascii string
		vector<string> asciiValue = m_VarMap[asciiName].as< vector<string> >();

		// Convert to a wstring
		vector<wstring> value;
		for (size_t x = 0; x < asciiValue.size(); ++x) {
			value.push_back(convert(asciiValue[x]));
		}

		return value;
	} catch (boost::bad_any_cast) {
		// Option is not a vector of string: try getting as a simple value
		wstring simpleValue = get_option(name);

		// Place in the result if it's non-empty
		vector<wstring> res;
		if (!simpleValue.empty()) {
			res.push_back(simpleValue);
		}
		return res;
	}
}

/// \brief The name of the initial input file
const std::wstring& boost_console::input_file() const {
	return m_InputFile;
}

/// \brief Converts a wstring filename to whatever is the preferred format for the current system
std::string boost_console::convert_filename(const std::wstring& filename) {
	fs::wpath path(filename);
	return path.generic_string();
}

/// \brief Given a pathname, returns the 'real', absolute pathname
///
/// The default implementation just returns the current path
std::wstring boost_console::real_path(const std::wstring& pathname) {
	fs::wpath path(pathname);
	fs::wpath absolute;

    try {
        // Try to get the absolute path for this file
        absolute = fs::absolute(path);
        return absolute.generic_wstring();
    } catch (fs::filesystem_error e) {
        // Report as an error
        report_error(error(error::sev_error, pathname, L"CANT_GET_ABSOLUTE_PATH", L"Unable to get absolute path for file", dfa::position(-1, -1, -1)));

        // Return the path unchanged
        return pathname;
    }
}

/// \brief Splits a path into its components
///
/// The default implementation assumes UNIX-style paths.
std::vector<std::wstring> boost_console::split_path(const std::wstring& pathname) {
	fs::wpath path(pathname);
	vector<wstring> res;

	for (fs::wpath::iterator component = path.begin(); component != path.end(); ++component) {
		res.push_back(component->generic_wstring());
	}

	return res;
}

/// \brief Opens a text file with the specified name for reading
///
/// The caller should delete the stream once it has finished with it. Streams are generally expected to contain UTF-8
/// data, so console classes should usually open streams in binary mode.
std::istream* boost_console::open_file(const std::wstring& filename) {
	// Get the path
	fs::wpath path(filename);

	// Create the stream
    fs::fstream* readFile = new fs::fstream();

    // Initially try
    readFile->open(path, fstream::in | fstream::binary);

    // Try searching various paths until we find the file
    if (readFile->fail() && !input_file().empty() && path.is_relative()) {
        // Try next to the input file
        readFile->close();

        // Generate a new path based on the input file
        fs::wpath inputPath(input_file());
        inputPath.remove_filename();
        inputPath /= filename;

        // Try to open this path
        readFile->open(inputPath, fstream::in | fstream::binary);
    }

    // Return NULL if the file failed to open
    if (readFile->fail()) {
        delete readFile;
        return NULL;
    }

    // Return the stream
    return readFile;
}

/// \brief Opens an output file with the specified name for writing binary data
///
/// The caller should delete the stream once it has finished writing to it. The parser primarily writes binary files
/// to ensure that the output is consistent between locales.
///
/// (This is an annoying compromise added to deal with C++'s completely useless support for locales and unicode)
std::ostream* boost_console::open_binary_file_for_writing(const std::wstring& filename) {
    // Get the path
	fs::wpath path(filename);

    // Create the resulting stream
    fs::fstream* result = new fs::fstream();

    result->open(path, fstream::out | fstream::binary | fstream::trunc);

    // Return as the result
    return result;
}
<commit_msg>Documentation update<commit_after>//
//  boost_console.cpp
//  TameParse
//
//  Created by Andrew Hunter on 24/09/2011.
//  Copyright 2011-2012 Andrew Hunter. All rights reserved.
//

#include <string>
#include <vector>

#include "TameParse/version.h"

#include "boost_console.h"
#include "boost/program_options.hpp"
#include "boost/filesystem.hpp"
#include "boost/filesystem/fstream.hpp"

using namespace std;
using namespace compiler;
using namespace tameparse;

namespace po = boost::program_options;
namespace fs = boost::filesystem;

 // \brief Copies this console
boost_console::boost_console(const boost_console& bc)
: std_console(L"")
, m_VarMap(bc.m_VarMap) {
}

/// \brief Constructor
boost_console::boost_console(int argc, const char** argv)
: std_console(L"") {
	// Declare the options supported by the tameparse utility
	po::options_description inputOptions("Input options");

	inputOptions.add_options()
		("input-file,i",		po::value<string>(),			"specifies the name of the input file.")
		("include-path,I",		po::value< vector<string> >(),	"sets the path to search for included files.");

	po::options_description outputOptions("Output options");

	outputOptions.add_options()
		("output-file,o",		po::value<string>(),			"specifies the base name for the output file. For languages that need to generate multiple files (for example, C++), the appropriate extensions will be added to this filename. If this is not specified, the output filenames will be derived from the input file.")
		("output-language,T",	po::value<string>(),			"specifies the output language the parser will be generated in.")
		("start-symbol,S",		po::value< vector<string> >(),	"specifies the name of the start symbol (overriding anything defined in the parser block of the input file)")
		("compile-language,L",	po::value<string>(),			"specifies the name of the language block to compile (overriding anything defined in the parser block of the input file)")
		("class-name,C",		po::value<string>(),			"specifies the name of the class to generate (overriding anything defined in the parser block of the input file)")
		("namespace-name,N",	po::value<string>(),			"specifies the namespace to put the target class into.")
		("run-tests",											"if the language contains any tests, then run them")
		("test",												"specifies that no output should be generated. This tool will instead try to read from stdin and indicate whether or not it can be accepted.")
        ("show-parser",                                         "writes the generated parser to standard out");

	po::options_description infoOptions("Information");

    infoOptions.add_options()
        ("help,h", 												"display help message.")
        ("verbose,v",											"display verbose messages.")
        ("silent",												"suppress informational messages.")
        ("version",												"display version information.")
        ("warranty",											"display warranty information.")
        ("license",												"display license information.");

    po::options_description errorOptions("Error reporting");

    errorOptions.add_options()
        ("suppress-warnings",                                   "do not display any warning messages.")
        ("show-error-codes",                                    "display error codes alongside the error messages.")
        ("show-conflict-details",                               "show details about the context that conflicts occur in.")
        ("allow-reduce-conflicts",                              "reduce/reduce conflicts will produce a warning instead of an error.")
        ("no-conflicts",                                        "all unresolved parser conflicts count as an error and not a warning.");

    po::options_description hiddenOptions;

    hiddenOptions.add_options()
    	("show-parser-closure", 								"display the closure of all states when showing the parser with --show-parser.")
    	("show-propagation",									"display the lookahead propagation tables")
    	("disable-compact-dfa",									"do not compact the DFA")
    	("disable-merged-dfa",									"do not attempt to merge symbol sets in the DFA");

	// Positional options
	po::positional_options_description positional;

	positional.add("input-file", 1);
	positional.add("output-file", 1);

    // Command line options
    po::options_description cmdLine;
    po::options_description help;
    cmdLine.add(inputOptions).add(outputOptions).add(infoOptions).add(errorOptions).add(hiddenOptions);
    help.add(inputOptions).add(outputOptions).add(infoOptions).add(errorOptions);

	// Store the options
    try {
        po::store(po::command_line_parser(argc, argv).options(cmdLine).positional(positional).run(), m_VarMap);
        po::notify(m_VarMap);
    } catch (po::error e) {
        cerr << e.what() << endl << endl;
		cout << help << endl;
        ::exit(1);
    }

	// Display help if needed
    bool doneSomething = false;

    if (m_VarMap.count("version") || m_VarMap.count("warranty") || m_VarMap.count("license") || m_VarMap.count("help")) {
        cout << "TameParse version " << version::version_string;
        if (m_VarMap.count("license") == 0) {
            cout << endl << version::copyright_string << " " << version::contact_string;
        }
        cout << endl << endl;
        doneSomething = true;
    }

    if (m_VarMap.count("warranty")) {
        cout << version::warranty_string << endl << endl;
        doneSomething = true;
    }

    if (m_VarMap.count("license")) {
        cout << version::license_string << endl << endl;
        doneSomething = true;
    }

	if (m_VarMap.count("help")) {
		cout << help << endl;
	    doneSomething = true;
	}

	// Also display help if no input file is displayed
	if (!doneSomething && m_VarMap.count("input-file") == 0) {
		cerr << argv[0] << ": no input files" << endl << endl;
		cout << help << endl;
	}

    // Set the value of the input file string
    m_InputFile = get_option(L"input-file");
}

/// \brief Returns true if the options are valid and the parser can start
bool boost_console::can_start() const {
	// Nothing to do if no input file is specified
	if (m_VarMap.count("input-file") == 0) {
		return false;
	}

	// Everything looks to be in order
    return true;
}

/// \brief Clones the console
console* boost_console::clone() const {
	return new boost_console(*this);
}

/// \brief Reports an error to the console
void boost_console::report_error(const compiler::error& error) {
	// Pass to the standard console
	std_console::report_error(error);
}

/// \brief Simple conversion from a string to wstring
static wstring convert(string asciiValue) {
	// Convert to a wstring by assuming that the string is latin-1
	// TODO: could take account of the locale here, somehow
	wstring value;
	for (size_t x = 0; x < asciiValue.size(); ++x) {
		value += (wchar_t) asciiValue[x];
	}

	return value;
}

/// \brief Retrieves the value of the option with the specified name.
///
/// If the option is not set, then this should return an empty string
std::wstring boost_console::get_option(const std::wstring& name) const {
	// Convert to a standard string
	string asciiName;

	for (size_t x=0; x<name.size(); ++x) {
		asciiName += (char) name[x];
	}

	// Return the empty string if the option is not present
	if (m_VarMap.count(asciiName) == 0) {
		return L"";
	}

	// Try to get the value as a string
	try {
		// Convert to a wstring
		wstring value = convert(m_VarMap[asciiName].as<string>());

        // Value is '1' if the value is empty but the option is present
        if (value.empty()) {
            value += L'1';
        }

		return value;
	} catch (boost::bad_any_cast) {
		// The option is present but doesn't have a string value
		// Assume it's a boolean on/off option and return the name
		return name;
	}
}

/// \brief Returns a list of values for a particular option
///
/// For some options it is possible to specify more than one value: in this
/// case, this will return all of the possible values. This can also be used
/// to retrieve the values of options that can have an empty value.
std::vector<std::wstring> boost_console::get_option_list(const std::wstring& name) {
	// Convert to a standard string
	string asciiName;

	for (size_t x=0; x<name.size(); ++x) {
		asciiName += (char) name[x];
	}

	// Return the empty string if the option is not present
	if (m_VarMap.count(asciiName) == 0) {
		return vector<wstring>();
	}

	// Try to get the value as a string
	try {
		// Get as an ascii string
		vector<string> asciiValue = m_VarMap[asciiName].as< vector<string> >();

		// Convert to a wstring
		vector<wstring> value;
		for (size_t x = 0; x < asciiValue.size(); ++x) {
			value.push_back(convert(asciiValue[x]));
		}

		return value;
	} catch (boost::bad_any_cast) {
		// Option is not a vector of string: try getting as a simple value
		wstring simpleValue = get_option(name);

		// Place in the result if it's non-empty
		vector<wstring> res;
		if (!simpleValue.empty()) {
			res.push_back(simpleValue);
		}
		return res;
	}
}

/// \brief The name of the initial input file
const std::wstring& boost_console::input_file() const {
	return m_InputFile;
}

/// \brief Converts a wstring filename to whatever is the preferred format for the current system
std::string boost_console::convert_filename(const std::wstring& filename) {
	fs::wpath path(filename);
	return path.generic_string();
}

/// \brief Given a pathname, returns the 'real', absolute pathname
///
/// The default implementation just returns the current path
std::wstring boost_console::real_path(const std::wstring& pathname) {
	fs::wpath path(pathname);
	fs::wpath absolute;

    try {
        // Try to get the absolute path for this file
        absolute = fs::absolute(path);
        return absolute.generic_wstring();
    } catch (fs::filesystem_error e) {
        // Report as an error
        report_error(error(error::sev_error, pathname, L"CANT_GET_ABSOLUTE_PATH", L"Unable to get absolute path for file", dfa::position(-1, -1, -1)));

        // Return the path unchanged
        return pathname;
    }
}

/// \brief Splits a path into its components
///
/// The default implementation assumes UNIX-style paths.
std::vector<std::wstring> boost_console::split_path(const std::wstring& pathname) {
	fs::wpath path(pathname);
	vector<wstring> res;

	for (fs::wpath::iterator component = path.begin(); component != path.end(); ++component) {
		res.push_back(component->generic_wstring());
	}

	return res;
}

/// \brief Opens a text file with the specified name for reading
///
/// The caller should delete the stream once it has finished with it. Streams are generally expected to contain UTF-8
/// data, so console classes should usually open streams in binary mode.
std::istream* boost_console::open_file(const std::wstring& filename) {
	// Get the path
	fs::wpath path(filename);

	// Create the stream
    fs::fstream* readFile = new fs::fstream();

    // Initially try
    readFile->open(path, fstream::in | fstream::binary);

    // Try searching various paths until we find the file
    if (readFile->fail() && !input_file().empty() && path.is_relative()) {
        // Try next to the input file
        readFile->close();

        // Generate a new path based on the input file
        fs::wpath inputPath(input_file());
        inputPath.remove_filename();
        inputPath /= filename;

        // Try to open this path
        readFile->open(inputPath, fstream::in | fstream::binary);
    }

    // Return NULL if the file failed to open
    if (readFile->fail()) {
        delete readFile;
        return NULL;
    }

    // Return the stream
    return readFile;
}

/// \brief Opens an output file with the specified name for writing binary data
///
/// The caller should delete the stream once it has finished writing to it. The parser primarily writes binary files
/// to ensure that the output is consistent between locales.
///
/// (This is an annoying compromise added to deal with C++'s completely useless support for locales and unicode)
std::ostream* boost_console::open_binary_file_for_writing(const std::wstring& filename) {
    // Get the path
	fs::wpath path(filename);

    // Create the resulting stream
    fs::fstream* result = new fs::fstream();

    result->open(path, fstream::out | fstream::binary | fstream::trunc);

    // Return as the result
    return result;
}
<|endoftext|>


<commit_before>// This file is part of OpenMVG, an Open Multiple View Geometry C++ library.

// Copyright (c) 2017 <Zillow Inc.> Pierre Moulon

// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include "mainframe.h"
#include "pairgraphicsitem.h"
#include "matchingpairgraphicsview.h"

#ifndef QT_NO_OPENGL
#include <QtOpenGL>
#else
#include <QtWidgets>
#endif
#include <QSvgWidget>

QGraphicsView *MainFrame::view() const
{
  return static_cast<QGraphicsView *>(matching_pair_view);
}

MainFrame::MainFrame(const QString &name, const Document & doc, QWidget *parent)
  : QFrame(parent), doc(doc)
{
  setFrameStyle(Sunken | StyledPanel);
  matching_pair_view = new MatchingPairGraphicsView(this, doc);
  matching_pair_view->setRenderHint(QPainter::Antialiasing, false);
  matching_pair_view->setDragMode(QGraphicsView::RubberBandDrag);
  matching_pair_view->setOptimizationFlags(QGraphicsView::DontSavePainterState);
  matching_pair_view->setViewportUpdateMode(QGraphicsView::SmartViewportUpdate);
  matching_pair_view->setTransformationAnchor(QGraphicsView::AnchorUnderMouse);

  // configure the icon size
  const int size = style()->pixelMetric(QStyle::PM_ToolBarIconSize);
  const QSize iconSize(size, size);

  QToolButton *zoom_in_icon = new QToolButton;
  zoom_in_icon->setText(tr("-"));
  zoom_in_icon->setIconSize(iconSize);
  QToolButton *zoom_out_icon = new QToolButton;
  zoom_out_icon->setText(tr("+"));
  zoom_out_icon->setIconSize(iconSize);
  zoom_slider = new QSlider;
  zoom_slider->setMinimum(-500);
  zoom_slider->setMaximum(500);
  zoom_slider->setValue(0);
  zoom_slider->setTickPosition(QSlider::TicksRight);

  // Zoom slider layout
  QVBoxLayout *zoom_slider_layout = new QVBoxLayout;
  zoom_slider_layout->addWidget(zoom_in_icon);
  zoom_slider_layout->addWidget(zoom_slider);
  zoom_slider_layout->addWidget(zoom_out_icon);

  reset_button = new QToolButton;
  reset_button->setText(tr("0"));
  reset_button->setEnabled(false);

  // Label layout
  QHBoxLayout *label_layout = new QHBoxLayout;
  QLabel *label = new QLabel(name);
  QLabel *label2 = new QLabel(tr("Pointer Mode"));
  QToolButton *select_mode_button = new QToolButton;
  select_mode_button->setText(tr("Select"));
  select_mode_button->setCheckable(true);
  select_mode_button->setChecked(true);
  QToolButton *drag_mode_button = new QToolButton;
  drag_mode_button->setText(tr("Drag"));
  drag_mode_button->setCheckable(true);
  drag_mode_button->setChecked(false);
  QToolButton * antialias_button = new QToolButton;
  antialias_button->setText(tr("Antialiasing"));
  antialias_button->setCheckable(true);
  antialias_button->setChecked(false);
  opengl_button = new QToolButton;
  opengl_button->setText(tr("OpenGL"));
  opengl_button->setCheckable(true);
#ifndef QT_NO_OPENGL
  opengl_button->setEnabled(QGLFormat::hasOpenGL());
#else
  opengl_button->setEnabled(false);
#endif

  //
  // Build the window layout
  //

  QButtonGroup *pointer_mode_group = new QButtonGroup(this);
  pointer_mode_group->setExclusive(true);
  pointer_mode_group->addButton(select_mode_button);
  pointer_mode_group->addButton(drag_mode_button);

  label_layout->addWidget(label);
  label_layout->addStretch();
  label_layout->addWidget(label2);
  label_layout->addWidget(select_mode_button);
  label_layout->addWidget(drag_mode_button);
  label_layout->addStretch();
  label_layout->addWidget(antialias_button);
  label_layout->addWidget(opengl_button);

  QGridLayout *top_layout = new QGridLayout;
  top_layout->addLayout(label_layout, 0, 0);
  top_layout->addWidget(matching_pair_view, 1, 0);
  top_layout->addLayout(zoom_slider_layout, 1, 1);
  top_layout->addWidget(reset_button, 2, 1);
  setLayout(top_layout);

  //
  // Confiugre connection between SIGNALs and SLOTs
  //

  connect(reset_button, SIGNAL(clicked()), this, SLOT(resetView()));
  connect(zoom_slider, SIGNAL(valueChanged(int)), this, SLOT(setupMatrix()));
  connect(matching_pair_view->verticalScrollBar(), SIGNAL(valueChanged(int)),
          this, SLOT(setResetButtonEnabled()));
  connect(matching_pair_view->horizontalScrollBar(), SIGNAL(valueChanged(int)),
          this, SLOT(setResetButtonEnabled()));
  connect(select_mode_button, SIGNAL(toggled(bool)), this, SLOT(togglePointerMode()));
  connect(drag_mode_button, SIGNAL(toggled(bool)), this, SLOT(togglePointerMode()));
  connect(antialias_button, SIGNAL(toggled(bool)), this, SLOT(toggleAntialiasing()));
  connect(opengl_button, SIGNAL(toggled(bool)), this, SLOT(toggleOpenGL()));
  connect(zoom_in_icon, SIGNAL(clicked()), this, SLOT(zoomIn()));
  connect(zoom_out_icon, SIGNAL(clicked()), this, SLOT(zoomOut()));

  setupMatrix();
}

void MainFrame::resetView()
{
  zoom_slider->setValue(0);
  matching_pair_view->ensureVisible(QRectF(0, 0, 0, 0));

  matching_pair_view->fitInView(
    matching_pair_view->scene()->itemsBoundingRect(),
    Qt::KeepAspectRatio);

  reset_button->setEnabled(false);
}

void MainFrame::setResetButtonEnabled()
{
  reset_button->setEnabled(true);
}

void MainFrame::setupMatrix()
{
  const qreal scale = qPow(qreal(2), (zoom_slider->value() - 250) / qreal(50));

  QMatrix matrix;
  matrix.scale(scale, scale);

  matching_pair_view->setMatrix(matrix);
  setResetButtonEnabled();
}

void MainFrame::togglePointerMode()
{
  matching_pair_view->setDragMode(select_mode_button->isChecked()
                                  ? QGraphicsView::RubberBandDrag
                                  : QGraphicsView::ScrollHandDrag);
  matching_pair_view->setInteractive(select_mode_button->isChecked());
}

void MainFrame::toggleOpenGL()
{
#ifndef QT_NO_OPENGL
  matching_pair_view->setViewport(
    opengl_button->isChecked() ?
      new QGLWidget(QGLFormat(QGL::SampleBuffers)) :
      new QWidget);
#endif
}

void MainFrame::toggleAntialiasing()
{
  matching_pair_view->setRenderHint(QPainter::Antialiasing, antialias_button->isChecked());
}

void MainFrame::zoomIn(int level)
{
  zoom_slider->setValue(zoom_slider->value() + level);
}

void MainFrame::zoomOut(int level)
{
  zoom_slider->setValue(zoom_slider->value() - level);
}
<commit_msg>Fix segfault in adjacency-matrix-viewer.<commit_after>// This file is part of OpenMVG, an Open Multiple View Geometry C++ library.

// Copyright (c) 2017 <Zillow Inc.> Pierre Moulon

// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include "mainframe.h"
#include "pairgraphicsitem.h"
#include "matchingpairgraphicsview.h"

#ifndef QT_NO_OPENGL
#include <QtOpenGL>
#else
#include <QtWidgets>
#endif
#include <QSvgWidget>

QGraphicsView *MainFrame::view() const
{
  return static_cast<QGraphicsView *>(matching_pair_view);
}

MainFrame::MainFrame(const QString &name, const Document & doc, QWidget *parent)
  : QFrame(parent), doc(doc)
{
  setFrameStyle(Sunken | StyledPanel);
  matching_pair_view = new MatchingPairGraphicsView(this, doc);
  matching_pair_view->setRenderHint(QPainter::Antialiasing, false);
  matching_pair_view->setDragMode(QGraphicsView::RubberBandDrag);
  matching_pair_view->setOptimizationFlags(QGraphicsView::DontSavePainterState);
  matching_pair_view->setViewportUpdateMode(QGraphicsView::SmartViewportUpdate);
  matching_pair_view->setTransformationAnchor(QGraphicsView::AnchorUnderMouse);

  // configure the icon size
  const int size = style()->pixelMetric(QStyle::PM_ToolBarIconSize);
  const QSize iconSize(size, size);

  QToolButton *zoom_in_icon = new QToolButton;
  zoom_in_icon->setText(tr("-"));
  zoom_in_icon->setIconSize(iconSize);
  QToolButton *zoom_out_icon = new QToolButton;
  zoom_out_icon->setText(tr("+"));
  zoom_out_icon->setIconSize(iconSize);
  zoom_slider = new QSlider;
  zoom_slider->setMinimum(-500);
  zoom_slider->setMaximum(500);
  zoom_slider->setValue(0);
  zoom_slider->setTickPosition(QSlider::TicksRight);

  // Zoom slider layout
  QVBoxLayout *zoom_slider_layout = new QVBoxLayout;
  zoom_slider_layout->addWidget(zoom_in_icon);
  zoom_slider_layout->addWidget(zoom_slider);
  zoom_slider_layout->addWidget(zoom_out_icon);

  reset_button = new QToolButton;
  reset_button->setText(tr("0"));
  reset_button->setEnabled(false);

  // Label layout
  QHBoxLayout *label_layout = new QHBoxLayout;
  QLabel *label = new QLabel(name);
  QLabel *label2 = new QLabel(tr("Pointer Mode"));
  select_mode_button = new QToolButton;
  select_mode_button->setText(tr("Select"));
  select_mode_button->setCheckable(true);
  select_mode_button->setChecked(true);
  QToolButton *drag_mode_button = new QToolButton;
  drag_mode_button->setText(tr("Drag"));
  drag_mode_button->setCheckable(true);
  drag_mode_button->setChecked(false);
  antialias_button = new QToolButton;
  antialias_button->setText(tr("Antialiasing"));
  antialias_button->setCheckable(true);
  antialias_button->setChecked(false);
  opengl_button = new QToolButton;
  opengl_button->setText(tr("OpenGL"));
  opengl_button->setCheckable(true);
#ifndef QT_NO_OPENGL
  opengl_button->setEnabled(QGLFormat::hasOpenGL());
#else
  opengl_button->setEnabled(false);
#endif

  //
  // Build the window layout
  //

  QButtonGroup *pointer_mode_group = new QButtonGroup(this);
  pointer_mode_group->setExclusive(true);
  pointer_mode_group->addButton(select_mode_button);
  pointer_mode_group->addButton(drag_mode_button);

  label_layout->addWidget(label);
  label_layout->addStretch();
  label_layout->addWidget(label2);
  label_layout->addWidget(select_mode_button);
  label_layout->addWidget(drag_mode_button);
  label_layout->addStretch();
  label_layout->addWidget(antialias_button);
  label_layout->addWidget(opengl_button);

  QGridLayout *top_layout = new QGridLayout;
  top_layout->addLayout(label_layout, 0, 0);
  top_layout->addWidget(matching_pair_view, 1, 0);
  top_layout->addLayout(zoom_slider_layout, 1, 1);
  top_layout->addWidget(reset_button, 2, 1);
  setLayout(top_layout);

  //
  // Confiugre connection between SIGNALs and SLOTs
  //

  connect(reset_button, SIGNAL(clicked()), this, SLOT(resetView()));
  connect(zoom_slider, SIGNAL(valueChanged(int)), this, SLOT(setupMatrix()));
  connect(matching_pair_view->verticalScrollBar(), SIGNAL(valueChanged(int)),
          this, SLOT(setResetButtonEnabled()));
  connect(matching_pair_view->horizontalScrollBar(), SIGNAL(valueChanged(int)),
          this, SLOT(setResetButtonEnabled()));
  connect(select_mode_button, SIGNAL(toggled(bool)), this, SLOT(togglePointerMode()));
  connect(drag_mode_button, SIGNAL(toggled(bool)), this, SLOT(togglePointerMode()));
  connect(antialias_button, SIGNAL(toggled(bool)), this, SLOT(toggleAntialiasing()));
  connect(opengl_button, SIGNAL(toggled(bool)), this, SLOT(toggleOpenGL()));
  connect(zoom_in_icon, SIGNAL(clicked()), this, SLOT(zoomIn()));
  connect(zoom_out_icon, SIGNAL(clicked()), this, SLOT(zoomOut()));

  setupMatrix();
}

void MainFrame::resetView()
{
  zoom_slider->setValue(0);
  matching_pair_view->ensureVisible(QRectF(0, 0, 0, 0));

  matching_pair_view->fitInView(
    matching_pair_view->scene()->itemsBoundingRect(),
    Qt::KeepAspectRatio);

  reset_button->setEnabled(false);
}

void MainFrame::setResetButtonEnabled()
{
  reset_button->setEnabled(true);
}

void MainFrame::setupMatrix()
{
  const qreal scale = qPow(qreal(2), (zoom_slider->value() - 250) / qreal(50));

  QMatrix matrix;
  matrix.scale(scale, scale);

  matching_pair_view->setMatrix(matrix);
  setResetButtonEnabled();
}

void MainFrame::togglePointerMode()
{
  matching_pair_view->setDragMode(select_mode_button->isChecked()
                                  ? QGraphicsView::RubberBandDrag
                                  : QGraphicsView::ScrollHandDrag);
  matching_pair_view->setInteractive(select_mode_button->isChecked());
}

void MainFrame::toggleOpenGL()
{
#ifndef QT_NO_OPENGL
  matching_pair_view->setViewport(
    opengl_button->isChecked() ?
      new QGLWidget(QGLFormat(QGL::SampleBuffers)) :
      new QWidget);
#endif
}

void MainFrame::toggleAntialiasing()
{
  matching_pair_view->setRenderHint(QPainter::Antialiasing, antialias_button->isChecked());
}

void MainFrame::zoomIn(int level)
{
  zoom_slider->setValue(zoom_slider->value() + level);
}

void MainFrame::zoomOut(int level)
{
  zoom_slider->setValue(zoom_slider->value() - level);
}
<|endoftext|>


<commit_before>// The libMesh Finite Element Library.
// Copyright (C) 2002-2016 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner

// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.

// This 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

#include "libmesh/boundary_volume_solution_transfer.h"
#include "libmesh/elem.h"
#include "libmesh/numeric_vector.h"
#include "libmesh/dof_map.h"

namespace libMesh {

void BoundaryVolumeSolutionTransfer::transfer(const Variable & from_var,
                                              const Variable & to_var)
{
  // Determine which direction the tranfer is in
  System * from_sys = from_var.system();
  System * to_sys = to_var.system();

  unsigned int
    from_dimension = from_sys->get_mesh().mesh_dimension(),
    to_dimension = to_sys->get_mesh().mesh_dimension();

  // Sanity check
  if (from_dimension == to_dimension)
    libmesh_error_msg("Error: Transfer must be from volume mesh to its boundary or vice-versa!");

  if (from_dimension > to_dimension)
    this->transfer_volume_boundary(from_var, to_var);
  else
    this->transfer_boundary_volume(from_var, to_var);
}

void BoundaryVolumeSolutionTransfer::
transfer_volume_boundary(const Variable & from_var, const Variable & to_var)
{
  // Get references to the Systems from the Variables
  System * from_sys = from_var.system(); // volume system
  System * to_sys = to_var.system();     // boundary system

  // Get reference to the BoundaryMesh.  Note: we always loop over the
  // BoundaryMesh since, by definition, it has fewer dofs than the
  // volume mesh.
  const MeshBase & to_mesh = to_sys->get_mesh();

  // Get system number and variable numbers
  const unsigned short int from_sys_number = from_sys->number();
  const unsigned short int from_var_number = from_var.number();

  const unsigned short int to_sys_number = to_sys->number();
  const unsigned short int to_var_number = to_var.number();

  // Get a constant reference to variables, get their number of components
  const unsigned short int from_n_comp = from_var.n_components();
  const unsigned short int to_n_comp = to_var.n_components();

  // Sanity check that the variables have the same number of components
  libmesh_assert_equal_to(from_n_comp, to_n_comp);

  // Iterator for BoundaryMesh.
  MeshBase::const_element_iterator       el     = to_mesh.active_local_elements_begin();
  const MeshBase::const_element_iterator end_el = to_mesh.active_local_elements_end();

  // Construct map from "from" dofs to "to" dofs.
  typedef std::map<numeric_index_type, numeric_index_type> DofMapping;
  DofMapping dof_mapping;

  // Loop through all boundary elements.
  for ( ; el != end_el; ++el)
    {
      const Elem * to_elem = *el;
      const Elem * from_elem = to_elem->interior_parent();

      if (!from_elem)
        libmesh_error_msg("Error, transfer must be between a Mesh and its associated BoundaryMesh.");

      // loop through all nodes in each boundary element.
      for (unsigned int node=0; node < to_elem->n_nodes(); node++)
        {
          // Node in boundary element.
          const Node * to_node = to_elem->node_ptr(node);

          for (unsigned int node_id=0; node_id < from_elem->n_nodes(); node_id++)
            {
              // Nodes in interior_parent element.
              const Node * from_node = from_elem->node_ptr(node_id);

              const dof_id_type from_dof = from_node->dof_number(from_sys_number,
                                                                 from_var_number,
                                                                 from_n_comp - 1);

              // See if we've already encountered this DOF in the loop
              // over boundary elements.
              DofMapping::iterator it = dof_mapping.find(from_dof);

              // If we've already mapped this dof, we don't need to map
              // it again or do floating point comparisons.
              if (it == dof_mapping.end() &&
                  from_node->absolute_fuzzy_equals(*to_node, TOLERANCE))
                {
                  // Global dof_index for node in BoundaryMesh.
                  const dof_id_type to_dof = to_node->dof_number(to_sys_number,
                                                                 to_var_number,
                                                                 to_n_comp - 1);

                  // Keep track of the volume system dof index which is needed.
                  dof_mapping[from_dof] = to_dof;
                }
            }
        }
    }

  // Construct a vector of the indices needed from the Volume system's
  // global solution vector on this processor.
  std::vector<numeric_index_type> needed_indices;
  needed_indices.reserve(dof_mapping.size());
  {
    DofMapping::iterator
      it = dof_mapping.begin(),
      end = dof_mapping.end();

    for (; it!=end; ++it)
      needed_indices.push_back(it->first);
  }

  // Communicate just the required values without making a copy of the
  // global solution vector.
  std::vector<Number> needed_values;
  from_sys->solution->localize(needed_values, needed_indices);

  // Loop over DofMapping again, assigning values in the
  // Boundary System solution vector.
  {
    DofMapping::iterator
      it = dof_mapping.begin(),
      end = dof_mapping.end();

    for (unsigned idx=0; it!=end; ++it, ++idx)
      to_sys->solution->set(it->second, needed_values[idx]);
  }
}

void BoundaryVolumeSolutionTransfer::
transfer_boundary_volume(const Variable & from_var, const Variable & to_var)
{
  // Get references to the Systems from the Variables
  System * from_sys = from_var.system(); // boundary system
  System * to_sys = to_var.system();     // volume system

  // Get reference to BoundaryMesh.
  const MeshBase & from_mesh = from_sys->get_mesh();

  // DofMap for BoundaryMesh
  const DofMap & dof_map = from_sys->get_dof_map();

  // Get system number and variable numbers
  const unsigned short int to_sys_number = to_sys->number();
  const unsigned short int to_var_number = to_var.number();
  const unsigned short int from_var_number = from_var.number();
  const unsigned short int to_n_comp = to_var.n_components();

  // Iterator for BoundaryMesh.
  MeshBase::const_element_iterator       el     = from_mesh.active_local_elements_begin();
  const MeshBase::const_element_iterator end_el = from_mesh.active_local_elements_end();

  // In order to get solution vectors from BoundaryMesh
  std::vector<dof_id_type> from_dof_indices;
  std::vector<Real> value;

  // Loop through all boundary elements.
  for (; el != end_el; ++el)
    {
      const Elem * from_elem = *el;
      const Elem * to_elem = from_elem->interior_parent();

      if (!to_elem)
        libmesh_error_msg("Error, transfer must be between a Mesh and its associated BoundaryMesh.");

      // Get dof indices for phi2 for all nodes on this boundary element
      dof_map.dof_indices(from_elem, from_dof_indices, from_var_number);

      // Get values from BoundaryMesh for this element
      from_sys->current_local_solution->get(from_dof_indices, value);

      // loop through all nodes in each boundary element.
      for (unsigned int node=0; node < from_elem->n_nodes(); node++)
        {
          // Node in boundary element.
          const Node * from_node = from_elem->node_ptr(node);

          for (unsigned int node_id=0; node_id < to_elem->n_nodes(); node_id++)
            {
              // Nodes in interior_parent element.
              const Node * to_node = to_elem->node_ptr(node_id);

              // Match BoundaryNode & VolumeNode.
              if (to_node->absolute_fuzzy_equals(*from_node, TOLERANCE))
                {
                  // Global dof_index for node in VolumeMesh.
                  const dof_id_type to_dof = to_node->dof_number(to_sys_number,
                                                                 to_var_number,
                                                                 to_n_comp - 1);

                  // Assign values to boundary in VolumeMesh.
                  to_sys->solution->set(to_dof, value[node]);
                }
            }
        }
    }
}

} // namespace libMesh
<commit_msg>Bugfix for --enable-complex<commit_after>// The libMesh Finite Element Library.
// Copyright (C) 2002-2016 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner

// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.

// This 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

#include "libmesh/boundary_volume_solution_transfer.h"
#include "libmesh/elem.h"
#include "libmesh/numeric_vector.h"
#include "libmesh/dof_map.h"

namespace libMesh {

void BoundaryVolumeSolutionTransfer::transfer(const Variable & from_var,
                                              const Variable & to_var)
{
  // Determine which direction the tranfer is in
  System * from_sys = from_var.system();
  System * to_sys = to_var.system();

  unsigned int
    from_dimension = from_sys->get_mesh().mesh_dimension(),
    to_dimension = to_sys->get_mesh().mesh_dimension();

  // Sanity check
  if (from_dimension == to_dimension)
    libmesh_error_msg("Error: Transfer must be from volume mesh to its boundary or vice-versa!");

  if (from_dimension > to_dimension)
    this->transfer_volume_boundary(from_var, to_var);
  else
    this->transfer_boundary_volume(from_var, to_var);
}

void BoundaryVolumeSolutionTransfer::
transfer_volume_boundary(const Variable & from_var, const Variable & to_var)
{
  // Get references to the Systems from the Variables
  System * from_sys = from_var.system(); // volume system
  System * to_sys = to_var.system();     // boundary system

  // Get reference to the BoundaryMesh.  Note: we always loop over the
  // BoundaryMesh since, by definition, it has fewer dofs than the
  // volume mesh.
  const MeshBase & to_mesh = to_sys->get_mesh();

  // Get system number and variable numbers
  const unsigned short int from_sys_number = from_sys->number();
  const unsigned short int from_var_number = from_var.number();

  const unsigned short int to_sys_number = to_sys->number();
  const unsigned short int to_var_number = to_var.number();

  // Get a constant reference to variables, get their number of components
  const unsigned short int from_n_comp = from_var.n_components();
  const unsigned short int to_n_comp = to_var.n_components();

  // Sanity check that the variables have the same number of components
  libmesh_assert_equal_to(from_n_comp, to_n_comp);

  // Iterator for BoundaryMesh.
  MeshBase::const_element_iterator       el     = to_mesh.active_local_elements_begin();
  const MeshBase::const_element_iterator end_el = to_mesh.active_local_elements_end();

  // Construct map from "from" dofs to "to" dofs.
  typedef std::map<numeric_index_type, numeric_index_type> DofMapping;
  DofMapping dof_mapping;

  // Loop through all boundary elements.
  for ( ; el != end_el; ++el)
    {
      const Elem * to_elem = *el;
      const Elem * from_elem = to_elem->interior_parent();

      if (!from_elem)
        libmesh_error_msg("Error, transfer must be between a Mesh and its associated BoundaryMesh.");

      // loop through all nodes in each boundary element.
      for (unsigned int node=0; node < to_elem->n_nodes(); node++)
        {
          // Node in boundary element.
          const Node * to_node = to_elem->node_ptr(node);

          for (unsigned int node_id=0; node_id < from_elem->n_nodes(); node_id++)
            {
              // Nodes in interior_parent element.
              const Node * from_node = from_elem->node_ptr(node_id);

              const dof_id_type from_dof = from_node->dof_number(from_sys_number,
                                                                 from_var_number,
                                                                 from_n_comp - 1);

              // See if we've already encountered this DOF in the loop
              // over boundary elements.
              DofMapping::iterator it = dof_mapping.find(from_dof);

              // If we've already mapped this dof, we don't need to map
              // it again or do floating point comparisons.
              if (it == dof_mapping.end() &&
                  from_node->absolute_fuzzy_equals(*to_node, TOLERANCE))
                {
                  // Global dof_index for node in BoundaryMesh.
                  const dof_id_type to_dof = to_node->dof_number(to_sys_number,
                                                                 to_var_number,
                                                                 to_n_comp - 1);

                  // Keep track of the volume system dof index which is needed.
                  dof_mapping[from_dof] = to_dof;
                }
            }
        }
    }

  // Construct a vector of the indices needed from the Volume system's
  // global solution vector on this processor.
  std::vector<numeric_index_type> needed_indices;
  needed_indices.reserve(dof_mapping.size());
  {
    DofMapping::iterator
      it = dof_mapping.begin(),
      end = dof_mapping.end();

    for (; it!=end; ++it)
      needed_indices.push_back(it->first);
  }

  // Communicate just the required values without making a copy of the
  // global solution vector.
  std::vector<Number> needed_values;
  from_sys->solution->localize(needed_values, needed_indices);

  // Loop over DofMapping again, assigning values in the
  // Boundary System solution vector.
  {
    DofMapping::iterator
      it = dof_mapping.begin(),
      end = dof_mapping.end();

    for (unsigned idx=0; it!=end; ++it, ++idx)
      to_sys->solution->set(it->second, needed_values[idx]);
  }
}

void BoundaryVolumeSolutionTransfer::
transfer_boundary_volume(const Variable & from_var, const Variable & to_var)
{
  // Get references to the Systems from the Variables
  System * from_sys = from_var.system(); // boundary system
  System * to_sys = to_var.system();     // volume system

  // Get reference to BoundaryMesh.
  const MeshBase & from_mesh = from_sys->get_mesh();

  // DofMap for BoundaryMesh
  const DofMap & dof_map = from_sys->get_dof_map();

  // Get system number and variable numbers
  const unsigned short int to_sys_number = to_sys->number();
  const unsigned short int to_var_number = to_var.number();
  const unsigned short int from_var_number = from_var.number();
  const unsigned short int to_n_comp = to_var.n_components();

  // Iterator for BoundaryMesh.
  MeshBase::const_element_iterator       el     = from_mesh.active_local_elements_begin();
  const MeshBase::const_element_iterator end_el = from_mesh.active_local_elements_end();

  // In order to get solution vectors from BoundaryMesh
  std::vector<dof_id_type> from_dof_indices;
  std::vector<Number> value;

  // Loop through all boundary elements.
  for (; el != end_el; ++el)
    {
      const Elem * from_elem = *el;
      const Elem * to_elem = from_elem->interior_parent();

      if (!to_elem)
        libmesh_error_msg("Error, transfer must be between a Mesh and its associated BoundaryMesh.");

      // Get dof indices for phi2 for all nodes on this boundary element
      dof_map.dof_indices(from_elem, from_dof_indices, from_var_number);

      // Get values from BoundaryMesh for this element
      from_sys->current_local_solution->get(from_dof_indices, value);

      // loop through all nodes in each boundary element.
      for (unsigned int node=0; node < from_elem->n_nodes(); node++)
        {
          // Node in boundary element.
          const Node * from_node = from_elem->node_ptr(node);

          for (unsigned int node_id=0; node_id < to_elem->n_nodes(); node_id++)
            {
              // Nodes in interior_parent element.
              const Node * to_node = to_elem->node_ptr(node_id);

              // Match BoundaryNode & VolumeNode.
              if (to_node->absolute_fuzzy_equals(*from_node, TOLERANCE))
                {
                  // Global dof_index for node in VolumeMesh.
                  const dof_id_type to_dof = to_node->dof_number(to_sys_number,
                                                                 to_var_number,
                                                                 to_n_comp - 1);

                  // Assign values to boundary in VolumeMesh.
                  to_sys->solution->set(to_dof, value[node]);
                }
            }
        }
    }
}

} // namespace libMesh
<|endoftext|>