<commit_before>/*************************************************************************
 *
 *  $RCSfile: wview.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: os $ $Date: 2002-12-05 12:59:37 $
 *
 *  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): _______________________________________
 *
 *
 ************************************************************************/

#ifdef PRECOMPILED
#include "ui_pch.hxx"
#endif

#pragma hdrstop

#include "itemdef.hxx"

#ifndef _SVX_SRCHITEM_HXX
#include <svx/srchitem.hxx>
#endif
#ifndef _SFXDISPATCH_HXX //autogen
#include <sfx2/dispatch.hxx>
#endif
#ifndef _SFX_TEMPLDLG_HXX //autogen
#include <sfx2/templdlg.hxx>
#endif
#ifndef _SVX_SRCHDLG_HXX //autogen
#include <svx/srchdlg.hxx>
#endif
#ifndef _SBX_SBXOBJECT_HXX //autogen
#include <svtools/sbxobj.hxx>
#endif
#ifndef _UIVWIMP_HXX
#include <uivwimp.hxx>
#endif
#ifndef _SVX_FMSHELL_HXX //autogen
#include <svx/fmshell.hxx>
#endif
#ifndef _SFXENUMITEM_HXX //autogen
#include <svtools/eitem.hxx>
#endif

#ifndef _SWMODULE_HXX //autogen
#include <swmodule.hxx>
#endif
#ifndef _UNOTXVW_HXX //autogen
#include <unotxvw.hxx>
#endif
#include "swtypes.hxx"
#include "cmdid.h"
#include "globals.hrc"
#include "wrtsh.hxx"
#include "edtwin.hxx"
#include "wgrfsh.hxx"
#include "wfrmsh.hxx"
#include "wolesh.hxx"
#include "wtabsh.hxx"
#include "wlistsh.hxx"
#include "wformsh.hxx"
#include "wtextsh.hxx"
#include "barcfg.hxx"
#include "doc.hxx"

// EIGENTLICH nicht moeglich !!
#include "beziersh.hxx"
#include "drawsh.hxx"
#include "drwtxtsh.hxx"

#include "wview.hxx"
#include "wdocsh.hxx"
#include "web.hrc"
#include "shells.hrc"

#define SwWebView
#define SearchAttributes
#define ReplaceAttributes
#define SearchSettings
#define _ExecSearch ExecSearch
#define _StateSearch StateSearch
#define Frames
#define Graphics
#define OLEObjects
#define Controls
#define Text
#define Frame
#define Graphic
#define Object
#define Draw
#define DrawText
#define TextInTable
#define ListInText
#define ListInTable
#define Page
#include <svx/svxslots.hxx>
#include "swslots.hxx"

SFX_IMPL_VIEWFACTORY(SwWebView, SW_RES(STR_NONAME))
{
    SFX_VIEW_REGISTRATION(SwWebDocShell);
}

SFX_IMPL_INTERFACE( SwWebView, SwView, SW_RES(RID_WEBTOOLS_TOOLBOX) )
{
    SFX_CHILDWINDOW_REGISTRATION(SfxTemplateDialogWrapper::GetChildWindowId());
    SFX_CHILDWINDOW_REGISTRATION(SvxSearchDialogWrapper::GetChildWindowId());
    SFX_OBJECTBAR_REGISTRATION( SFX_OBJECTBAR_TOOLS|
                                SFX_VISIBILITY_STANDARD|SFX_VISIBILITY_SERVER,
                                SW_RES(RID_WEBTOOLS_TOOLBOX) );
}

TYPEINIT1(SwWebView,SwView)

/*-----------------22.01.97 14.27-------------------

--------------------------------------------------*/

SwWebView::SwWebView(SfxViewFrame* pFrame, SfxViewShell* pShell) :
    SwView(pFrame, pShell)
{
}

/*-----------------22.01.97 14.27-------------------

--------------------------------------------------*/

SwWebView::~SwWebView()
{
}

/*-----------------23.01.97 09.01-------------------

--------------------------------------------------*/

void SwWebView::SelectShell()
{
    // Entscheidung, ob UpdateTable gerufen werden muss
    BOOL bUpdateTable = FALSE;
    const SwFrmFmt* pCurTableFmt = GetWrtShell().GetTableFmt();
    if(pCurTableFmt && pCurTableFmt != GetLastTblFrmFmt())
    {
        bUpdateTable = TRUE; // kann erst spaeter ausgefuehrt werden
    }
    SetLastTblFrmFmt(pCurTableFmt);
    //SEL_TBL und SEL_TBL_CELLS koennen verodert sein!
    int nNewSelectionType = (GetWrtShell().GetSelectionType()
                                & ~SwWrtShell::SEL_TBL_CELLS);

    int nSelectionType = GetSelectionType();
    if ( nNewSelectionType == nSelectionType )
    {
        GetViewFrame()->GetBindings().InvalidateAll( FALSE );
        if ( nSelectionType & SwWrtShell::SEL_OLE ||
             nSelectionType & SwWrtShell::SEL_GRF )
            //Fuer Grafiken und OLE kann sich natuerlich das Verb aendern!
            ImpSetVerb( nNewSelectionType );
    }
    else
    {

    //  DELETEZ(pxSelectionObj); //Selektionsobjekt loeschen
        SfxDispatcher &rDispatcher = *GetViewFrame()->GetDispatcher();
        SwToolbarConfigItem *pBarCfg = SW_MOD()->GetWebToolbarConfig();

        if( GetCurShell() )
        {
            rDispatcher.Flush();        // alle gecachten Shells wirklich loeschen

            //Zur alten Selektion merken welche Toolbar sichtbar war
            USHORT nId = rDispatcher.GetObjectBarId( SFX_OBJECTBAR_OBJECT );
            if ( nId )
                pBarCfg->SetTopToolbar( nSelectionType, nId );

            SfxShell *pSfxShell;
            USHORT i;
            for ( i = 0; TRUE; ++i )
            {
                pSfxShell = rDispatcher.GetShell( i );
                if ( !(pSfxShell->ISA( SwBaseShell ) ||
                    pSfxShell->ISA( SwDrawTextShell )) )
                    break;
            }
            pSfxShell = rDispatcher.GetShell( --i );
            ASSERT( pSfxShell, "My Shell ist lost in space" );
            rDispatcher.Pop( *pSfxShell, SFX_SHELL_POP_UNTIL | SFX_SHELL_POP_DELETE);
        }

        FASTBOOL bInitFormShell = FALSE;
        if( !GetFormShell() )
        {
            bInitFormShell = TRUE;
            SetFormShell( new FmFormShell( this ) );
            rDispatcher.Push( *GetFormShell() );
        }

        FASTBOOL bSetExtInpCntxt = FALSE;
        nSelectionType = nNewSelectionType;
        SetSelectionType( nSelectionType );
        ShellModes eShellMode;

        if ( nSelectionType & SwWrtShell::SEL_OLE )
        {
            eShellMode = SEL_OBJECT;
            SetShell( new SwWebOleShell( *this ));
            rDispatcher.Push( *GetCurShell() );
        }
        else if ( nSelectionType & SwWrtShell::SEL_FRM
            || nSelectionType & SwWrtShell::SEL_GRF)
        {
            eShellMode = SEL_FRAME;
            SetShell( new SwWebFrameShell( *this ));
            rDispatcher.Push( *GetCurShell() );
            if(nSelectionType & SwWrtShell::SEL_GRF )
            {
                eShellMode = SEL_GRAPHIC;
                SetShell( new SwWebGrfShell( *this ));
                rDispatcher.Push( *GetCurShell() );
            }
        }
        else if ( nSelectionType & SwWrtShell::SEL_FRM )
        {
            eShellMode = SEL_FRAME;
            SetShell( new SwWebFrameShell( *this ));
            rDispatcher.Push( *GetCurShell() );
        }
        else if ( nSelectionType & SwWrtShell::SEL_DRW )
        {
            eShellMode = SEL_DRAW;
            SetShell( new SwDrawShell( *this ));
            rDispatcher.Push( *GetCurShell() );
            if ( nSelectionType & SwWrtShell::SEL_BEZ )
            {
                eShellMode = SEL_BEZIER;
                SetShell( new SwBezierShell( *this ));
                rDispatcher.Push( *GetCurShell() );
            }

        }
        else if ( nSelectionType & SwWrtShell::SEL_DRW_FORM )
        {
            eShellMode = SEL_DRAW_FORM;
            SetShell( new SwWebDrawFormShell( *this ));

            rDispatcher.Push( *GetCurShell() );
        }
        else if ( nSelectionType & SwWrtShell::SEL_DRW_TXT )
        {
            eShellMode = SEL_DRAWTEXT;
            rDispatcher.Push( *(new SwBaseShell( *this )) );
            SetShell( new SwDrawTextShell( *this ));
            rDispatcher.Push( *GetCurShell() );
        }
        else
        {
            bSetExtInpCntxt = TRUE;
            eShellMode = SEL_TEXT;
            if ( nSelectionType & SwWrtShell::SEL_NUM )
            {
                eShellMode = SEL_LIST_TEXT;
                SetShell( new SwWebListShell( *this ));
                rDispatcher.Push( *GetCurShell() );
            }
            SetShell( new SwWebTextShell(*this));
            rDispatcher.Push( *GetCurShell() );
            if ( nSelectionType & SwWrtShell::SEL_TBL )
            {
                eShellMode = eShellMode == SEL_LIST_TEXT ? SEL_TABLE_LIST_TEXT
                                                        : SEL_TABLE_TEXT;
                SetShell( new SwWebTableShell( *this ));
                rDispatcher.Push( *GetCurShell() );
            }
        }
        ImpSetVerb( nSelectionType );
        GetViewImpl()->SetShellMode(eShellMode);

        if( !GetDocShell()->IsReadOnly() )
        {
            if( bSetExtInpCntxt && GetWrtShell().HasReadonlySel() )
                bSetExtInpCntxt = FALSE;

            InputContext aCntxt( GetEditWin().GetInputContext() );
            aCntxt.SetOptions( bSetExtInpCntxt
                                ? (aCntxt.GetOptions() |
                                        ( INPUTCONTEXT_TEXT |
                                            INPUTCONTEXT_EXTTEXTINPUT ))
                                : (aCntxt.GetOptions() & ~
                                        ( INPUTCONTEXT_TEXT |
                                            INPUTCONTEXT_EXTTEXTINPUT )) );
            GetEditWin().SetInputContext( aCntxt );
        }

        //Zur neuen Selektion die Toolbar aktivieren, die auch beim letzten Mal
        //aktiviert war
        //Vorher muss ein Flush() sein, betrifft aber lt. MBA nicht das UI und ist
        //kein Performance-Problem
        rDispatcher.Flush();
        USHORT nId = pBarCfg->GetTopToolbar( nSelectionType );
        if ( USHRT_MAX != nId )
            rDispatcher.ShowObjectBar( nId );

        Point aPnt = GetEditWin().GetPointerPosPixel();
        aPnt = GetEditWin().PixelToLogic(aPnt);
        GetEditWin().UpdatePointer(aPnt);

        if ( bInitFormShell && GetWrtShell().GetDrawView() )
            GetFormShell()->SetView( PTR_CAST( FmFormView,
                                                GetWrtShell().GetDrawView()));

    }
    GetViewImpl()->GetUNOObject_Impl()->NotifySelChanged();

    //Guenstiger Zeitpunkt fuer die Kommunikation mit OLE-Objekten?
    if ( GetDocShell()->GetDoc()->IsOLEPrtNotifyPending() )
        GetDocShell()->GetDoc()->PrtOLENotify( FALSE );

    //jetzt das Tabellen-Update
    if(bUpdateTable)
        GetWrtShell().UpdateTable();
}

<commit_msg>INTEGRATION: CWS os8 (1.4.138); FILE MERGED 2003/04/03 07:16:00 os 1.4.138.1: #108583# precompiled headers removed<commit_after>/*************************************************************************
 *
 *  $RCSfile: wview.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: vg $ $Date: 2003-04-17 15:59:32 $
 *
 *  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): _______________________________________
 *
 *
 ************************************************************************/

#pragma hdrstop

#include "itemdef.hxx"

#ifndef _SVX_SRCHITEM_HXX
#include <svx/srchitem.hxx>
#endif
#ifndef _SFXDISPATCH_HXX //autogen
#include <sfx2/dispatch.hxx>
#endif
#ifndef _SFX_TEMPLDLG_HXX //autogen
#include <sfx2/templdlg.hxx>
#endif
#ifndef _SVX_SRCHDLG_HXX //autogen
#include <svx/srchdlg.hxx>
#endif
#ifndef _SBX_SBXOBJECT_HXX //autogen
#include <svtools/sbxobj.hxx>
#endif
#ifndef _UIVWIMP_HXX
#include <uivwimp.hxx>
#endif
#ifndef _SVX_FMSHELL_HXX //autogen
#include <svx/fmshell.hxx>
#endif
#ifndef _SFXENUMITEM_HXX //autogen
#include <svtools/eitem.hxx>
#endif

#ifndef _SWMODULE_HXX //autogen
#include <swmodule.hxx>
#endif
#ifndef _UNOTXVW_HXX //autogen
#include <unotxvw.hxx>
#endif
#include "swtypes.hxx"
#include "cmdid.h"
#include "globals.hrc"
#include "wrtsh.hxx"
#include "edtwin.hxx"
#include "wgrfsh.hxx"
#include "wfrmsh.hxx"
#include "wolesh.hxx"
#include "wtabsh.hxx"
#include "wlistsh.hxx"
#include "wformsh.hxx"
#include "wtextsh.hxx"
#include "barcfg.hxx"
#include "doc.hxx"

// EIGENTLICH nicht moeglich !!
#include "beziersh.hxx"
#include "drawsh.hxx"
#include "drwtxtsh.hxx"

#include "wview.hxx"
#include "wdocsh.hxx"
#include "web.hrc"
#include "shells.hrc"

#define SwWebView
#define SearchAttributes
#define ReplaceAttributes
#define SearchSettings
#define _ExecSearch ExecSearch
#define _StateSearch StateSearch
#define Frames
#define Graphics
#define OLEObjects
#define Controls
#define Text
#define Frame
#define Graphic
#define Object
#define Draw
#define DrawText
#define TextInTable
#define ListInText
#define ListInTable
#define Page
#include <svx/svxslots.hxx>
#include "swslots.hxx"

SFX_IMPL_VIEWFACTORY(SwWebView, SW_RES(STR_NONAME))
{
    SFX_VIEW_REGISTRATION(SwWebDocShell);
}

SFX_IMPL_INTERFACE( SwWebView, SwView, SW_RES(RID_WEBTOOLS_TOOLBOX) )
{
    SFX_CHILDWINDOW_REGISTRATION(SfxTemplateDialogWrapper::GetChildWindowId());
    SFX_CHILDWINDOW_REGISTRATION(SvxSearchDialogWrapper::GetChildWindowId());
    SFX_OBJECTBAR_REGISTRATION( SFX_OBJECTBAR_TOOLS|
                                SFX_VISIBILITY_STANDARD|SFX_VISIBILITY_SERVER,
                                SW_RES(RID_WEBTOOLS_TOOLBOX) );
}

TYPEINIT1(SwWebView,SwView)

/*-----------------22.01.97 14.27-------------------

--------------------------------------------------*/

SwWebView::SwWebView(SfxViewFrame* pFrame, SfxViewShell* pShell) :
    SwView(pFrame, pShell)
{
}

/*-----------------22.01.97 14.27-------------------

--------------------------------------------------*/

SwWebView::~SwWebView()
{
}

/*-----------------23.01.97 09.01-------------------

--------------------------------------------------*/

void SwWebView::SelectShell()
{
    // Entscheidung, ob UpdateTable gerufen werden muss
    BOOL bUpdateTable = FALSE;
    const SwFrmFmt* pCurTableFmt = GetWrtShell().GetTableFmt();
    if(pCurTableFmt && pCurTableFmt != GetLastTblFrmFmt())
    {
        bUpdateTable = TRUE; // kann erst spaeter ausgefuehrt werden
    }
    SetLastTblFrmFmt(pCurTableFmt);
    //SEL_TBL und SEL_TBL_CELLS koennen verodert sein!
    int nNewSelectionType = (GetWrtShell().GetSelectionType()
                                & ~SwWrtShell::SEL_TBL_CELLS);

    int nSelectionType = GetSelectionType();
    if ( nNewSelectionType == nSelectionType )
    {
        GetViewFrame()->GetBindings().InvalidateAll( FALSE );
        if ( nSelectionType & SwWrtShell::SEL_OLE ||
             nSelectionType & SwWrtShell::SEL_GRF )
            //Fuer Grafiken und OLE kann sich natuerlich das Verb aendern!
            ImpSetVerb( nNewSelectionType );
    }
    else
    {

    //  DELETEZ(pxSelectionObj); //Selektionsobjekt loeschen
        SfxDispatcher &rDispatcher = *GetViewFrame()->GetDispatcher();
        SwToolbarConfigItem *pBarCfg = SW_MOD()->GetWebToolbarConfig();

        if( GetCurShell() )
        {
            rDispatcher.Flush();        // alle gecachten Shells wirklich loeschen

            //Zur alten Selektion merken welche Toolbar sichtbar war
            USHORT nId = rDispatcher.GetObjectBarId( SFX_OBJECTBAR_OBJECT );
            if ( nId )
                pBarCfg->SetTopToolbar( nSelectionType, nId );

            SfxShell *pSfxShell;
            USHORT i;
            for ( i = 0; TRUE; ++i )
            {
                pSfxShell = rDispatcher.GetShell( i );
                if ( !(pSfxShell->ISA( SwBaseShell ) ||
                    pSfxShell->ISA( SwDrawTextShell )) )
                    break;
            }
            pSfxShell = rDispatcher.GetShell( --i );
            ASSERT( pSfxShell, "My Shell ist lost in space" );
            rDispatcher.Pop( *pSfxShell, SFX_SHELL_POP_UNTIL | SFX_SHELL_POP_DELETE);
        }

        FASTBOOL bInitFormShell = FALSE;
        if( !GetFormShell() )
        {
            bInitFormShell = TRUE;
            SetFormShell( new FmFormShell( this ) );
            rDispatcher.Push( *GetFormShell() );
        }

        FASTBOOL bSetExtInpCntxt = FALSE;
        nSelectionType = nNewSelectionType;
        SetSelectionType( nSelectionType );
        ShellModes eShellMode;

        if ( nSelectionType & SwWrtShell::SEL_OLE )
        {
            eShellMode = SEL_OBJECT;
            SetShell( new SwWebOleShell( *this ));
            rDispatcher.Push( *GetCurShell() );
        }
        else if ( nSelectionType & SwWrtShell::SEL_FRM
            || nSelectionType & SwWrtShell::SEL_GRF)
        {
            eShellMode = SEL_FRAME;
            SetShell( new SwWebFrameShell( *this ));
            rDispatcher.Push( *GetCurShell() );
            if(nSelectionType & SwWrtShell::SEL_GRF )
            {
                eShellMode = SEL_GRAPHIC;
                SetShell( new SwWebGrfShell( *this ));
                rDispatcher.Push( *GetCurShell() );
            }
        }
        else if ( nSelectionType & SwWrtShell::SEL_FRM )
        {
            eShellMode = SEL_FRAME;
            SetShell( new SwWebFrameShell( *this ));
            rDispatcher.Push( *GetCurShell() );
        }
        else if ( nSelectionType & SwWrtShell::SEL_DRW )
        {
            eShellMode = SEL_DRAW;
            SetShell( new SwDrawShell( *this ));
            rDispatcher.Push( *GetCurShell() );
            if ( nSelectionType & SwWrtShell::SEL_BEZ )
            {
                eShellMode = SEL_BEZIER;
                SetShell( new SwBezierShell( *this ));
                rDispatcher.Push( *GetCurShell() );
            }

        }
        else if ( nSelectionType & SwWrtShell::SEL_DRW_FORM )
        {
            eShellMode = SEL_DRAW_FORM;
            SetShell( new SwWebDrawFormShell( *this ));

            rDispatcher.Push( *GetCurShell() );
        }
        else if ( nSelectionType & SwWrtShell::SEL_DRW_TXT )
        {
            eShellMode = SEL_DRAWTEXT;
            rDispatcher.Push( *(new SwBaseShell( *this )) );
            SetShell( new SwDrawTextShell( *this ));
            rDispatcher.Push( *GetCurShell() );
        }
        else
        {
            bSetExtInpCntxt = TRUE;
            eShellMode = SEL_TEXT;
            if ( nSelectionType & SwWrtShell::SEL_NUM )
            {
                eShellMode = SEL_LIST_TEXT;
                SetShell( new SwWebListShell( *this ));
                rDispatcher.Push( *GetCurShell() );
            }
            SetShell( new SwWebTextShell(*this));
            rDispatcher.Push( *GetCurShell() );
            if ( nSelectionType & SwWrtShell::SEL_TBL )
            {
                eShellMode = eShellMode == SEL_LIST_TEXT ? SEL_TABLE_LIST_TEXT
                                                        : SEL_TABLE_TEXT;
                SetShell( new SwWebTableShell( *this ));
                rDispatcher.Push( *GetCurShell() );
            }
        }
        ImpSetVerb( nSelectionType );
        GetViewImpl()->SetShellMode(eShellMode);

        if( !GetDocShell()->IsReadOnly() )
        {
            if( bSetExtInpCntxt && GetWrtShell().HasReadonlySel() )
                bSetExtInpCntxt = FALSE;

            InputContext aCntxt( GetEditWin().GetInputContext() );
            aCntxt.SetOptions( bSetExtInpCntxt
                                ? (aCntxt.GetOptions() |
                                        ( INPUTCONTEXT_TEXT |
                                            INPUTCONTEXT_EXTTEXTINPUT ))
                                : (aCntxt.GetOptions() & ~
                                        ( INPUTCONTEXT_TEXT |
                                            INPUTCONTEXT_EXTTEXTINPUT )) );
            GetEditWin().SetInputContext( aCntxt );
        }

        //Zur neuen Selektion die Toolbar aktivieren, die auch beim letzten Mal
        //aktiviert war
        //Vorher muss ein Flush() sein, betrifft aber lt. MBA nicht das UI und ist
        //kein Performance-Problem
        rDispatcher.Flush();
        USHORT nId = pBarCfg->GetTopToolbar( nSelectionType );
        if ( USHRT_MAX != nId )
            rDispatcher.ShowObjectBar( nId );

        Point aPnt = GetEditWin().GetPointerPosPixel();
        aPnt = GetEditWin().PixelToLogic(aPnt);
        GetEditWin().UpdatePointer(aPnt);

        if ( bInitFormShell && GetWrtShell().GetDrawView() )
            GetFormShell()->SetView( PTR_CAST( FmFormView,
                                                GetWrtShell().GetDrawView()));

    }
    GetViewImpl()->GetUNOObject_Impl()->NotifySelChanged();

    //Guenstiger Zeitpunkt fuer die Kommunikation mit OLE-Objekten?
    if ( GetDocShell()->GetDoc()->IsOLEPrtNotifyPending() )
        GetDocShell()->GetDoc()->PrtOLENotify( FALSE );

    //jetzt das Tabellen-Update
    if(bUpdateTable)
        GetWrtShell().UpdateTable();
}

<|endoftext|>


<commit_before>#include "../Include/CTransitionVisitor.h"
#include "../Include/CSceneNode.h"
#include "../Include/CSequenceNode.h"
#include "../Include/CKernel.h"

#include "../../Modules/Util/Include/CStats.h"

#include "cocos2d.h"

using namespace cocos2d;

namespace LM
{

CTransitionVisitor::CTransitionVisitor(CKernel* a_pKernel, bool a_bTransitionNext) :
	m_bTransitionNext(a_bTransitionNext),
	m_pKernel(a_pKernel)
{
}

Result CTransitionVisitor::ProcessNodeTopDown(CNode* a_pNode)
{
  // pSequence is the father node of all the scenes.
  // transition will be done on the between the current scene in the node
  // (CSequenceNode::m_iCurrentNode) and the next node
  CSequenceNode* pSequence = dynamic_cast<CSequenceNode*>(a_pNode);
  CSceneNode* pScene = nullptr;
  if (pSequence)
  {
	  pScene = dynamic_cast<CSceneNode*>(pSequence->GetCurrentNode());
  }
  if (pScene)
  {
	  GotoScene(pSequence);
  }
  return RESULT_PRUNE;
}

void CTransitionVisitor::GotoScene(CSequenceNode* a_pSequence)
{
	if (m_pKernel->m_pCurrentScene->m_bDashboardTrigger && m_bTransitionNext)
	{
		// init dashboard
		InitScene(m_pKernel->m_pDashboard);
		return;
	}
	bool bSceneExists = false;
	if (m_bTransitionNext)
	{
		// if TransitioNext offset of 1 scene
		bSceneExists = a_pSequence->OffsetCurrentNode(1);
	}
	else
	{
		// else return to previous scene
		bSceneExists = a_pSequence->OffsetCurrentNode(-1);
	}
	if (!bSceneExists)
	{
		return;
	}
	CSceneNode* pNewSceneNode = dynamic_cast<CSceneNode*>(a_pSequence->GetCurrentNode());
	if (!m_pKernel->PlayerHasScene(pNewSceneNode->GetSceneID()))
	{ // if the player does not have this scene in his list, skip it and go to the next one
		GotoScene(a_pSequence);
		return;
	}
	else if (pNewSceneNode)
	{
		InitScene(pNewSceneNode);
	}

}

void CTransitionVisitor::InitScene(CSceneNode* a_pSceneNode)
{
	Scene* pNewScene = a_pSceneNode->CreateScene();
	a_pSceneNode->init();

	if (m_bTransitionNext)
	{
		Director::getInstance()->replaceScene(TransitionSlideInR::create(0.5f, pNewScene));
	}
	else
	{
		Director::getInstance()->replaceScene(TransitionSlideInL::create(0.5f, pNewScene));
	}
	CSceneNode* pOldScene = m_pKernel->m_pCurrentScene;
	m_pKernel->m_pCurrentScene = a_pSceneNode;
	pOldScene->UnInit();

	M_STATS->StartStats();
}

} // namespace LM
<commit_msg>[DEL] removed a regression that was causing incomplete transitions<commit_after>#include "../Include/CTransitionVisitor.h"
#include "../Include/CSceneNode.h"
#include "../Include/CSequenceNode.h"
#include "../Include/CKernel.h"

#include "../../Modules/Util/Include/CStats.h"

#include "cocos2d.h"

using namespace cocos2d;

namespace LM
{

CTransitionVisitor::CTransitionVisitor(CKernel* a_pKernel, bool a_bTransitionNext) :
	m_bTransitionNext(a_bTransitionNext),
	m_pKernel(a_pKernel)
{
}

Result CTransitionVisitor::ProcessNodeTopDown(CNode* a_pNode)
{
  // pSequence is the father node of all the scenes.
  // transition will be done on the between the current scene in the node
  // (CSequenceNode::m_iCurrentNode) and the next node
  CSequenceNode* pSequence = dynamic_cast<CSequenceNode*>(a_pNode);
  CSceneNode* pScene = nullptr;
  if (pSequence)
  {
	  pScene = dynamic_cast<CSceneNode*>(pSequence->GetCurrentNode());
  }
  if (pScene)
  {
	  GotoScene(pSequence);
  }
  return RESULT_PRUNE;
}

void CTransitionVisitor::GotoScene(CSequenceNode* a_pSequence)
{
	if (m_pKernel->m_pCurrentScene->m_bDashboardTrigger && m_bTransitionNext)
	{
		// init dashboard
		InitScene(m_pKernel->m_pDashboard);
		return;
	}
	bool bSceneExists = false;
	if (m_bTransitionNext)
	{
		// if TransitioNext offset of 1 scene
		bSceneExists = a_pSequence->OffsetCurrentNode(1);
	}
	else
	{
		// else return to previous scene
		bSceneExists = a_pSequence->OffsetCurrentNode(-1);
	}
	if (!bSceneExists)
	{
		return;
	}
	CSceneNode* pNewSceneNode = dynamic_cast<CSceneNode*>(a_pSequence->GetCurrentNode());
	if (!m_pKernel->PlayerHasScene(pNewSceneNode->GetSceneID()))
	{ // if the player does not have this scene in his list, skip it and go to the next one
		GotoScene(a_pSequence);
		return;
	}
	else if (pNewSceneNode)
	{
		InitScene(pNewSceneNode);
	}

}

void CTransitionVisitor::InitScene(CSceneNode* a_pSceneNode)
{
	Scene* pNewScene = a_pSceneNode->CreateScene();
	a_pSceneNode->init();

	if (m_bTransitionNext)
	{
		Director::getInstance()->replaceScene(TransitionSlideInR::create(0.5f, pNewScene));
	}
	else
	{
		Director::getInstance()->replaceScene(TransitionSlideInL::create(0.5f, pNewScene));
	}
	//CSceneNode* pOldScene = m_pKernel->m_pCurrentScene;
	m_pKernel->m_pCurrentScene = a_pSceneNode;
	//pOldScene->UnInit();

	M_STATS->StartStats();
}

} // namespace LM
<|endoftext|>


<commit_before>#include <StdAfx.h>
#include <UI/ViewPane/TreePane.h>
#include <UI/UIFunctions.h>
#include <utility>

namespace viewpane
{
	static std::wstring CLASS = L"TreePane";

	TreePane* TreePane::Create(int paneID, UINT uidLabel, bool bReadOnly)
	{
		auto pane = new (std::nothrow) TreePane();
		if (pane)
		{
			pane->SetLabel(uidLabel);
			pane->SetReadOnly(bReadOnly);
			pane->m_paneID = paneID;
		}

		return pane;
	}

	bool TreePane::IsDirty() { return m_bDirty; }

	void TreePane::Initialize(_In_ CWnd* pParent, _In_ HDC /*hdc*/)
	{
		ViewPane::Initialize(pParent, nullptr);
		m_Tree.Create(pParent, 0);

		// TODO: Don't leave this here
		TVINSERTSTRUCTW tvInsert = {nullptr};
		auto szName = std::wstring(L"TEST");
		tvInsert.hParent = nullptr;
		tvInsert.hInsertAfter = TVI_SORT;
		tvInsert.item.mask = TVIF_CHILDREN | TVIF_TEXT;
		tvInsert.item.cChildren = I_CHILDRENCALLBACK;
		tvInsert.item.pszText = const_cast<LPWSTR>(szName.c_str());
		::SendMessage(m_Tree.GetSafeHwnd(), TVM_INSERTITEMW, 0, reinterpret_cast<LPARAM>(&tvInsert));

		m_bInitialized = true;
	}

	int TreePane::GetMinWidth(_In_ HDC /*hdc*/)
	{
		return 100;
		//return max(
		//	ViewPane::GetMinWidth(hdc), (int) (NUMLISTBUTTONS * m_iButtonWidth + m_iMargin * (NUMLISTBUTTONS - 1)));
	}

	int TreePane::GetFixedHeight()
	{
		auto iHeight = 0;
		if (0 != m_paneID) iHeight += m_iSmallHeightMargin; // Top margin

		if (m_bCollapsible)
		{
			// Our expand/collapse button
			iHeight += m_iButtonHeight;
		}
		else if (!m_szLabel.empty())
		{
			iHeight += m_iLabelHeight;
		}

		if (!m_bCollapsed)
		{
			iHeight += m_iSmallHeightMargin;

			if (!m_bReadOnly)
			{
				iHeight += m_iLargeHeightMargin + m_iButtonHeight;
			}
		}

		return iHeight;
	}

	int TreePane::GetLines()
	{
		if (m_bCollapsed)
		{
			return 0;
		}

		return 4;
	}

	ULONG TreePane::HandleChange(UINT nID)
	{
		//switch (nID)
		//{
		//}

		return ViewPane::HandleChange(nID);
	}

	void TreePane::DeferWindowPos(_In_ HDWP hWinPosInfo, _In_ int x, _In_ int y, _In_ int width, _In_ int height)
	{
		output::DebugPrint(DBGDraw, L"TreePane::DeferWindowPos x:%d y:%d width:%d height:%d \n", x, y, width, height);

		auto iVariableHeight = height - GetFixedHeight();
		if (0 != m_paneID)
		{
			y += m_iSmallHeightMargin;
			height -= m_iSmallHeightMargin;
		}

		EC_B_S(m_Tree.ShowWindow(m_bCollapsed ? SW_HIDE : SW_SHOW));
		ViewPane::DeferWindowPos(hWinPosInfo, x, y, width, height);

		if (m_bCollapsible)
		{
			y += m_iLabelHeight + m_iSmallHeightMargin;
		}
		else
		{
			if (!m_szLabel.empty())
			{
				y += m_iLabelHeight;
				height -= m_iLabelHeight;
			}

			height -= m_iSmallHeightMargin; // This is the bottom margin
		}

		EC_B_S(::DeferWindowPos(
			hWinPosInfo,
			m_Tree.GetSafeHwnd(),
			nullptr,
			x,
			y,
			width,
			m_bCollapsible ? iVariableHeight : height,
			SWP_NOZORDER));
	}

	void TreePane::CommitUIValues() {}
} // namespace viewpane<commit_msg>Enable label drawing, collapse button, fix heights<commit_after>#include <StdAfx.h>
#include <UI/ViewPane/TreePane.h>
#include <UI/UIFunctions.h>
#include <utility>

namespace viewpane
{
	static std::wstring CLASS = L"TreePane";

	TreePane* TreePane::Create(int paneID, UINT uidLabel, bool bReadOnly)
	{
		auto pane = new (std::nothrow) TreePane();
		if (pane)
		{
			if (uidLabel)
			{
				pane->SetLabel(uidLabel);
				pane->m_bCollapsible = true;
			}

			pane->SetReadOnly(bReadOnly);
			pane->m_paneID = paneID;
		}

		return pane;
	}

	bool TreePane::IsDirty() { return m_bDirty; }

	void TreePane::Initialize(_In_ CWnd* pParent, _In_ HDC hdc)
	{
		ViewPane::Initialize(pParent, hdc);
		m_Tree.Create(pParent, 0);

		// TODO: Don't leave this here
		TVINSERTSTRUCTW tvInsert = {nullptr};
		auto szName = std::wstring(L"TEST");
		tvInsert.hParent = nullptr;
		tvInsert.hInsertAfter = TVI_SORT;
		tvInsert.item.mask = TVIF_CHILDREN | TVIF_TEXT;
		tvInsert.item.cChildren = I_CHILDRENCALLBACK;
		tvInsert.item.pszText = const_cast<LPWSTR>(szName.c_str());
		::SendMessage(m_Tree.GetSafeHwnd(), TVM_INSERTITEMW, 0, reinterpret_cast<LPARAM>(&tvInsert));

		m_bInitialized = true;
	}

	int TreePane::GetMinWidth(_In_ HDC /*hdc*/)
	{
		return 100;
		//return max(
		//	ViewPane::GetMinWidth(hdc), (int) (NUMLISTBUTTONS * m_iButtonWidth + m_iMargin * (NUMLISTBUTTONS - 1)));
	}

	int TreePane::GetFixedHeight()
	{
		auto iHeight = 0;
		if (0 != m_paneID) iHeight += m_iSmallHeightMargin; // Top margin

		const auto labelHeight = GetLabelHeight();

		if (labelHeight)
		{
			iHeight += labelHeight;
		}

		if (m_bCollapsible && !m_bCollapsed)
		{
			iHeight += m_iSmallHeightMargin;
		}

		iHeight += m_iSmallHeightMargin;

		return iHeight;
	}

	int TreePane::GetLines()
	{
		if (m_bCollapsed)
		{
			return 0;
		}

		return 4;
	}

	ULONG TreePane::HandleChange(UINT nID)
	{
		//switch (nID)
		//{
		//}

		return ViewPane::HandleChange(nID);
	}

	void TreePane::DeferWindowPos(
		_In_ HDWP hWinPosInfo,
		_In_ const int x,
		_In_ const int y,
		_In_ const int width,
		_In_ const int height)
	{
		output::DebugPrint(DBGDraw, L"TreePane::DeferWindowPos x:%d y:%d width:%d height:%d \n", x, y, width, height);

		auto curY = y;
		const auto labelHeight = GetLabelHeight();
		if (0 != m_paneID)
		{
			curY += m_iSmallHeightMargin;
		}

		EC_B_S(m_Tree.ShowWindow(m_bCollapsed ? SW_HIDE : SW_SHOW));
		// Layout our label
		ViewPane::DeferWindowPos(hWinPosInfo, x, curY, width, height - (curY - y));

		if (labelHeight)
		{
			curY += labelHeight + m_iSmallHeightMargin;
		}

		auto treeHeight = height - (curY - y) - m_iSmallHeightMargin;

		EC_B_S(::DeferWindowPos(hWinPosInfo, m_Tree.GetSafeHwnd(), nullptr, x, curY, width, treeHeight, SWP_NOZORDER));
	}

	void TreePane::CommitUIValues() {}
} // namespace viewpane<|endoftext|>


<commit_before>//
//  RenderCapabilities.cpp
//  Chilli Source
//  Created by Ian Copland on 27/01/2014.
//
//  The MIT License (MIT)
//
//  Copyright (c) 2014 Tag Games Limited
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//

#include <ChilliSource/Rendering/Base/RenderCapabilities.h>

#import <ChilliSource/Core/Base/RenderInfo.h>

namespace ChilliSource
{
    CS_DEFINE_NAMEDTYPE(RenderCapabilities);

    //-------------------------------------------------------
    RenderCapabilitiesUPtr RenderCapabilities::Create(const RenderInfo& renderInfo) noexcept
    {
        return RenderCapabilitiesUPtr(new RenderCapabilities(renderInfo.IsShadowMappingSupported(), renderInfo.IsDepthTextureSupported(), renderInfo.IsMapBufferSupported(),
                                                             renderInfo.GetMaxTextureSize(), renderInfo.GetNumTextureUnits()));
    }

    //-------------------------------------------------------
    RenderCapabilities::RenderCapabilities(bool areShadowMapsSupported, bool areDepthTexturesSupported, bool areMapBuffersSupported, u32 maxTextureSize, u32 numTextureUnits)
    : m_areShadowMapsSupported(areShadowMapsSupported), m_areDepthTexturesSupported(areDepthTexturesSupported), m_areMapBuffersSupported(areMapBuffersSupported), m_maxTextureSize(maxTextureSize), m_maxTextureUnits(numTextureUnits)
    {
    }

    //-------------------------------------------------------
    bool RenderCapabilities::IsA(ChilliSource::InterfaceIDType interfaceId) const
    {
        return (RenderCapabilities::InterfaceID == interfaceId);
    }

    //-------------------------------------------------------
    bool RenderCapabilities::IsShadowMappingSupported() const noexcept
    {
        return m_areShadowMapsSupported;
    }

    //-------------------------------------------------------
    bool RenderCapabilities::IsDepthTextureSupported() const noexcept
    {
        return m_areDepthTexturesSupported;
    }

    //-------------------------------------------------------
    bool RenderCapabilities::IsMapBufferSupported() const noexcept
    {
        return m_areMapBuffersSupported;
    }

    //-------------------------------------------------------
    u32 RenderCapabilities::GetMaxTextureSize() const noexcept
    {
        return m_maxTextureSize;
    }

    //-------------------------------------------------------
    u32 RenderCapabilities::GetNumTextureUnits() const noexcept
    {
        return m_maxTextureUnits;
    }
}
<commit_msg>Include fix<commit_after>//
//  RenderCapabilities.cpp
//  Chilli Source
//  Created by Ian Copland on 27/01/2014.
//
//  The MIT License (MIT)
//
//  Copyright (c) 2014 Tag Games Limited
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//

#include <ChilliSource/Rendering/Base/RenderCapabilities.h>

#include <ChilliSource/Core/Base/RenderInfo.h>

namespace ChilliSource
{
    CS_DEFINE_NAMEDTYPE(RenderCapabilities);

    //-------------------------------------------------------
    RenderCapabilitiesUPtr RenderCapabilities::Create(const RenderInfo& renderInfo) noexcept
    {
        return RenderCapabilitiesUPtr(new RenderCapabilities(renderInfo.IsShadowMappingSupported(), renderInfo.IsDepthTextureSupported(), renderInfo.IsMapBufferSupported(),
                                                             renderInfo.GetMaxTextureSize(), renderInfo.GetNumTextureUnits()));
    }

    //-------------------------------------------------------
    RenderCapabilities::RenderCapabilities(bool areShadowMapsSupported, bool areDepthTexturesSupported, bool areMapBuffersSupported, u32 maxTextureSize, u32 numTextureUnits)
    : m_areShadowMapsSupported(areShadowMapsSupported), m_areDepthTexturesSupported(areDepthTexturesSupported), m_areMapBuffersSupported(areMapBuffersSupported), m_maxTextureSize(maxTextureSize), m_maxTextureUnits(numTextureUnits)
    {
    }

    //-------------------------------------------------------
    bool RenderCapabilities::IsA(ChilliSource::InterfaceIDType interfaceId) const
    {
        return (RenderCapabilities::InterfaceID == interfaceId);
    }

    //-------------------------------------------------------
    bool RenderCapabilities::IsShadowMappingSupported() const noexcept
    {
        return m_areShadowMapsSupported;
    }

    //-------------------------------------------------------
    bool RenderCapabilities::IsDepthTextureSupported() const noexcept
    {
        return m_areDepthTexturesSupported;
    }

    //-------------------------------------------------------
    bool RenderCapabilities::IsMapBufferSupported() const noexcept
    {
        return m_areMapBuffersSupported;
    }

    //-------------------------------------------------------
    u32 RenderCapabilities::GetMaxTextureSize() const noexcept
    {
        return m_maxTextureSize;
    }

    //-------------------------------------------------------
    u32 RenderCapabilities::GetNumTextureUnits() const noexcept
    {
        return m_maxTextureUnits;
    }
}
<|endoftext|>


<commit_before>// C++ source file - (C) 2003 Robert Osfield, released under the OSGPL.
//
// Simple example of use of Producer::RenderSurface + KeyboardMouseCallback + SimpleViewer

#include <Producer/RenderSurface>
#include <Producer/KeyboardMouse>
#include <Producer/Trackball>

#include <osgDB/ReadFile>

#include <osgGA/SimpleViewer>
#include <osgGA/TrackballManipulator>
#include <osgGA/StateSetManipulator>

// ----------- Begining of glue classes to adapter Producer's keyboard mouse events to osgGA's abstraction events.
class MyKeyboardMouseCallback : public Producer::KeyboardMouseCallback
{
public:

    MyKeyboardMouseCallback(osgGA::EventQueue* eventQueue) :
        _done(false),
        _eventQueue(eventQueue)
    {
    }

    virtual void shutdown()
    {
        _done = true;
    }

    virtual void specialKeyPress( Producer::KeyCharacter key )
    {
        if (key==Producer::KeyChar_Escape)
                    shutdown();

        _eventQueue->keyPress( (osgGA::GUIEventAdapter::KeySymbol) key );
    }

    virtual void specialKeyRelease( Producer::KeyCharacter key )
    {
        _eventQueue->keyRelease( (osgGA::GUIEventAdapter::KeySymbol) key );
    }

    virtual void keyPress( Producer::KeyCharacter key)
    {
        _eventQueue->keyPress( (osgGA::GUIEventAdapter::KeySymbol) key );
    }

    virtual void keyRelease( Producer::KeyCharacter key)
    {
        _eventQueue->keyRelease( (osgGA::GUIEventAdapter::KeySymbol) key );
    }

    virtual void mouseMotion( float mx, float my )
    {
        _eventQueue->mouseMotion( mx, my );
    }

    virtual void buttonPress( float mx, float my, unsigned int mbutton )
    {
        _eventQueue->mouseButtonPress(mx, my, mbutton);
    }

    virtual void buttonRelease( float mx, float my, unsigned int mbutton )
    {
        _eventQueue->mouseButtonRelease(mx, my, mbutton);
    }

    bool done() { return _done; }

private:

    bool                                _done;
    osg::ref_ptr<osgGA::EventQueue>     _eventQueue;
};

int main( int argc, char **argv )
{
    if (argc<2)
    {
        std::cout << argv[0] <<": requires filename argument." << std::endl;
        return 1;
    }

    // load the scene.
    osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFile(argv[1]);
    if (!loadedModel)
    {
        std::cout << argv[0] <<": No data loaded." << std::endl;
        return 1;
    }

    // create the window to draw to.
    osg::ref_ptr<Producer::RenderSurface> renderSurface = new Producer::RenderSurface;
    renderSurface->setWindowName("osgkeyboardmouse");
    renderSurface->setWindowRectangle(100,100,800,600);
    renderSurface->useBorder(true);
    renderSurface->realize();

    // create the view of the scene.
    osgGA::SimpleViewer viewer;
    viewer.setSceneData(loadedModel.get());

    // set up a KeyboardMouse to manage the events comming in from the RenderSurface
    osg::ref_ptr<Producer::KeyboardMouse>  kbm = new Producer::KeyboardMouse(renderSurface.get());

    // create a KeyboardMouseCallback to handle the mouse events within this applications
    osg::ref_ptr<MyKeyboardMouseCallback> kbmcb = new MyKeyboardMouseCallback(viewer.getEventQueue());

    // create a tracball manipulator to move the camera around in response to keyboard/mouse events
    viewer.setCameraManipulator( new osgGA::TrackballManipulator );

    // set the window dimensions
    viewer.getEventQueue()->getCurrentEventState()->setWindowRectangle(100,100,800,600);

    // set the mouse input range.
    // Producer defaults to using non-dimensional units, so we pass this onto osgGA, most windowing toolkits use pixel coords so use the window size instead.
    viewer.getEventQueue()->getCurrentEventState()->setInputRange(-1.0, -1.0, 1.0, 1.0);

    // Producer has the y axis increase upwards, like OpenGL, and contary to most Windowing toolkits.
    // we need to construct the event queue so that it knows about this convention.
    viewer.getEventQueue()->getCurrentEventState()->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS);

    // main loop (note, window toolkits which take control over the main loop will require a window redraw callback containing the code below.)
    while( renderSurface->isRealized() && !kbmcb->done())
    {
        // update the window dimensions, in case the window has been resized.
         viewer.getEventQueue()->windowResize(0,0,renderSurface->getWindowWidth(),renderSurface->getWindowHeight(), false);

        // pass any keyboard mouse events onto the local keyboard mouse callback.
        kbm->update( *kbmcb );

        viewer.frame();

        // Swap Buffers
        renderSurface->swapBuffers();
    }

    return 0;
}

<commit_msg>Added a path with an experiemental GraphicsContexProducer implementation, and a test of mulitple inheritance.<commit_after>// C++ source file - (C) 2003 Robert Osfield, released under the OSGPL.
//
// Simple example of use of Producer::RenderSurface + KeyboardMouseCallback + SimpleViewer

#include <Producer/RenderSurface>
#include <Producer/KeyboardMouse>
#include <Producer/Trackball>

#include <osgDB/ReadFile>

#include <osgGA/SimpleViewer>
#include <osgGA/TrackballManipulator>
#include <osgGA/StateSetManipulator>

// ----------- Begining of glue classes to adapter Producer's keyboard mouse events to osgGA's abstraction events.
class MyKeyboardMouseCallback : public Producer::KeyboardMouseCallback
{
public:

    MyKeyboardMouseCallback(osgGA::EventQueue* eventQueue) :
        _done(false),
        _eventQueue(eventQueue)
    {
    }

    virtual void shutdown()
    {
        _done = true;
    }

    virtual void specialKeyPress( Producer::KeyCharacter key )
    {
        if (key==Producer::KeyChar_Escape)
                    shutdown();

        _eventQueue->keyPress( (osgGA::GUIEventAdapter::KeySymbol) key );
    }

    virtual void specialKeyRelease( Producer::KeyCharacter key )
    {
        _eventQueue->keyRelease( (osgGA::GUIEventAdapter::KeySymbol) key );
    }

    virtual void keyPress( Producer::KeyCharacter key)
    {
        _eventQueue->keyPress( (osgGA::GUIEventAdapter::KeySymbol) key );
    }

    virtual void keyRelease( Producer::KeyCharacter key)
    {
        _eventQueue->keyRelease( (osgGA::GUIEventAdapter::KeySymbol) key );
    }

    virtual void mouseMotion( float mx, float my )
    {
        _eventQueue->mouseMotion( mx, my );
    }

    virtual void buttonPress( float mx, float my, unsigned int mbutton )
    {
        _eventQueue->mouseButtonPress(mx, my, mbutton);
    }

    virtual void buttonRelease( float mx, float my, unsigned int mbutton )
    {
        _eventQueue->mouseButtonRelease(mx, my, mbutton);
    }

    bool done() { return _done; }

private:

    bool                                _done;
    osg::ref_ptr<osgGA::EventQueue>     _eventQueue;
};

#if 1

// first approach uses a custom GraphicsWindow
// then uses multiple inheritance to create a SimpleViewerWindowProducer

class GraphicsWindowProducer : public virtual osgGA::GraphicsWindow, public Producer::RenderSurface
{
    public:

        GraphicsWindowProducer()
        {
            // create a KeyboardMouseCallback to handle the mouse events within this applications
            _kbmcb = new MyKeyboardMouseCallback(getEventQueue());

            // set up a KeyboardMouse to manage the events comming in from the RenderSurface
            _kbm = new Producer::KeyboardMouse(this);
            _kbm->setCallback(_kbmcb.get());

            // set the mouse input range.
            // Producer defaults to using non-dimensional units, so we pass this onto osgGA, most windowing toolkits use pixel coords so use the window size instead.
            getEventQueue()->getCurrentEventState()->setInputRange(-1.0, -1.0, 1.0, 1.0);

            // Producer has the y axis increase upwards, like OpenGL, and contary to most Windowing toolkits.
            // we need to construct the event queue so that it knows about this convention.
            getEventQueue()->getCurrentEventState()->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS);

        }

        void setWindowRectangle(int x, int y, unsigned int width, unsigned int height, bool resize = true)
        {
            Producer::RenderSurface::setWindowRectangle(x, y, width, height, resize);
            getEventQueue()->windowResize(x,y,width,height, false);
        }

        void realize() { Producer::RenderSurface::realize(); _kbm->startThread(); }
        bool isRealized() const { return Producer::RenderSurface::isRealized(); }
        void swapBuffers() { return Producer::RenderSurface::swapBuffers(); }

    protected:

        osg::ref_ptr<Producer::KeyboardMouse>  _kbm;
        osg::ref_ptr<MyKeyboardMouseCallback> _kbmcb;
};

class SimplerViewerWindowProducer : public osgGA::SimpleViewer, public GraphicsWindowProducer
{
    public:
        SimplerViewerProducer() {}
};

int main( int argc, char **argv )
{
    if (argc<2)
    {
        std::cout << argv[0] <<": requires filename argument." << std::endl;
        return 1;
    }

    // load the scene.
    osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFile(argv[1]);
    if (!loadedModel)
    {
        std::cout << argv[0] <<": No data loaded." << std::endl;
        return 1;
    }

    // create the window to draw to.
    SimplerViewerWindowProducer viewer;
    viewer.setWindowName("osgkeyboardmouse");
    viewer.setWindowRectangle(100,100,800,600);
    viewer.useBorder(true);
    viewer.realize();

    // create the view of the scene.
    viewer.setSceneData(loadedModel.get());

    // create a tracball manipulator to move the camera around in response to keyboard/mouse events
    viewer.setCameraManipulator( new osgGA::TrackballManipulator );

    // main loop (note, window toolkits which take control over the main loop will require a window redraw callback containing the code below.)
    while( viewer.isRealized() )
    {
        // update the window dimensions, in case the window has been resized.
        viewer.getEventQueue()->windowResize(0,0,viewer.getWindowWidth(),viewer.getWindowHeight(), false);

        viewer.frame();

        // Swap Buffers
        viewer.swapBuffers();
    }

    return 0;
}

#else

// Second approach is to leave Producer and SimpleViewer decoupled, with the integration done mannually in the main loop
int main( int argc, char **argv )
{
    if (argc<2)
    {
        std::cout << argv[0] <<": requires filename argument." << std::endl;
        return 1;
    }

    // load the scene.
    osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFile(argv[1]);
    if (!loadedModel)
    {
        std::cout << argv[0] <<": No data loaded." << std::endl;
        return 1;
    }

    // create the window to draw to.
    osg::ref_ptr<Producer::RenderSurface> renderSurface = new Producer::RenderSurface;
    renderSurface->setWindowName("osgkeyboardmouse");
    renderSurface->setWindowRectangle(100,100,800,600);
    renderSurface->useBorder(true);
    renderSurface->realize();

    // create the view of the scene.
    osgGA::SimpleViewer viewer;
    viewer.setSceneData(loadedModel.get());

    // set up a KeyboardMouse to manage the events comming in from the RenderSurface
    osg::ref_ptr<Producer::KeyboardMouse>  kbm = new Producer::KeyboardMouse(renderSurface.get());

    // create a KeyboardMouseCallback to handle the mouse events within this applications
    osg::ref_ptr<MyKeyboardMouseCallback> kbmcb = new MyKeyboardMouseCallback(viewer.getEventQueue());

    // create a tracball manipulator to move the camera around in response to keyboard/mouse events
    viewer.setCameraManipulator( new osgGA::TrackballManipulator );

    // set the window dimensions
    viewer.getEventQueue()->getCurrentEventState()->setWindowRectangle(100,100,800,600);

    // set the mouse input range.
    // Producer defaults to using non-dimensional units, so we pass this onto osgGA, most windowing toolkits use pixel coords so use the window size instead.
    viewer.getEventQueue()->getCurrentEventState()->setInputRange(-1.0, -1.0, 1.0, 1.0);

    // Producer has the y axis increase upwards, like OpenGL, and contary to most Windowing toolkits.
    // we need to construct the event queue so that it knows about this convention.
    viewer.getEventQueue()->getCurrentEventState()->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS);

    // main loop (note, window toolkits which take control over the main loop will require a window redraw callback containing the code below.)
    while( renderSurface->isRealized() && !kbmcb->done())
    {
        // update the window dimensions, in case the window has been resized.
         viewer.getEventQueue()->windowResize(0,0,renderSurface->getWindowWidth(),renderSurface->getWindowHeight(), false);

        // pass any keyboard mouse events onto the local keyboard mouse callback.
        kbm->update( *kbmcb );

        viewer.frame();

        // Swap Buffers
        renderSurface->swapBuffers();
    }

    return 0;
}
#endif
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) Qxt Foundation. Some rights reserved.
**
** This file is part of the QxtGui module of the Qxt library.
**
** This library is free software; you can redistribute it and/or modify it
** under the terms of the Common Public License, version 1.0, as published by
** IBM.
**
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
** FITNESS FOR A PARTICULAR PURPOSE.
**
** You should have received a copy of the CPL along with this file.
** See the LICENSE file and the cpl1.0.txt file included with the source
** distribution for more information. If you did not receive a copy of the
** license, contact the Qxt Foundation.
**
** <http://libqxt.org>  <foundation@libqxt.org>
**
****************************************************************************/
#include "qxtitemdelegate.h"
#include "qxtitemdelegate_p.h"
#include <QApplication>
#include <QTreeView>
#include <QPainter>
#include <QTimer>

static const int TOP_LEVEL_EXTENT = 2;

QxtItemDelegatePrivate::QxtItemDelegatePrivate() :
        textVisible(true),
        progressFormat("%1%"),
        elide(Qt::ElideMiddle),
        style(Qxt::NoDecoration)
{
}

void QxtItemDelegatePrivate::paintButton(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index, const QTreeView* view) const
{
    // draw the button
    QStyleOptionButton buttonOption;
    buttonOption.state = option.state;
#ifdef Q_WS_MAC
    buttonOption.state |= QStyle::State_Raised;
#endif
    buttonOption.state &= ~QStyle::State_HasFocus;
    if (view->isExpanded(index))
        buttonOption.state |= QStyle::State_Sunken;
    buttonOption.rect = option.rect;
    buttonOption.palette = option.palette;
    buttonOption.features = QStyleOptionButton::None;
    view->style()->drawControl(QStyle::CE_PushButton, &buttonOption, painter, view);

    // draw the branch indicator
    static const int i = 9;
    const QRect& r = option.rect;
    if (index.model()->hasChildren(index))
    {
        QStyleOption branchOption;
        branchOption.initFrom(view);
        if (branchOption.direction == Qt::LeftToRight)
            branchOption.rect = QRect(r.left() + i / 2, r.top() + (r.height() - i) / 2, i, i);
        else
            branchOption.rect = QRect(r.right() - i / 2 - i, r.top() + (r.height() - i) / 2, i, i);
        branchOption.palette = option.palette;
        branchOption.state = QStyle::State_Children;
        if (view->isExpanded(index))
            branchOption.state |= QStyle::State_Open;
        view->style()->drawPrimitive(QStyle::PE_IndicatorBranch, &branchOption, painter, view);
    }

    // draw the text
    QRect textrect = QRect(r.left() + i * 2, r.top(), r.width() - ((5 * i) / 2), r.height());
#if QT_VERSION < 0x040200
    QString text = QItemDelegate::elidedText(option.fontMetrics, textrect.width(), elide, index.data().toString());
#else // QT_VERSION >= 0x040200
    QString text = option.fontMetrics.elidedText(index.data().toString(), elide, textrect.width());
#endif // QT_VERSION
    view->style()->drawItemText(painter, textrect, Qt::AlignCenter, option.palette, view->isEnabled(), text);
}

void QxtItemDelegatePrivate::paintMenu(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index, const QTreeView* view) const
{
    // draw the menu bar item
    QStyleOptionMenuItem menuOption;
    menuOption.palette = view->palette();
    menuOption.fontMetrics = view->fontMetrics();
    menuOption.state = QStyle::State_None;
    // QModelIndex::flags() was introduced in 4.2
    // => therefore "index.model()->flags(index)"
    if (view->isEnabled() && index.model()->flags(index) & Qt::ItemIsEnabled)
        menuOption.state |= QStyle::State_Enabled;
    else
        menuOption.palette.setCurrentColorGroup(QPalette::Disabled);
    menuOption.state |= QStyle::State_Selected;
    menuOption.state |= QStyle::State_Sunken;
    menuOption.state |= QStyle::State_HasFocus;
    menuOption.rect = option.rect;
    menuOption.text = index.data().toString();
    menuOption.icon = QIcon(index.data(Qt::DecorationRole).value<QPixmap>());
    view->style()->drawControl(QStyle::CE_MenuBarItem, &menuOption, painter, view);

    // draw the an arrow as a branch indicator
    if (index.model()->hasChildren(index))
    {
        QStyle::PrimitiveElement arrow;
        if (view->isExpanded(index))
            arrow = QStyle::PE_IndicatorArrowUp;
        else
            arrow = QStyle::PE_IndicatorArrowDown;
        static const int i = 9;
        const QRect& r = option.rect;
        menuOption.rect = QRect(r.left() + i / 2, r.top() + (r.height() - i) / 2, i, i);
        view->style()->drawPrimitive(arrow, &menuOption, painter, view);
    }
}

void QxtItemDelegatePrivate::paintProgress(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
    QVariant min = index.data(QxtItemDelegate::ProgressMinimumRole);
    QVariant max = index.data(QxtItemDelegate::ProgressMaximumRole);

    QStyleOptionProgressBar opt;
    opt.minimum = (min.isValid() && min.canConvert(QVariant::Int)) ? min.toInt() : 0;
    opt.maximum = (max.isValid() && max.canConvert(QVariant::Int)) ? max.toInt() : 100;
    opt.progress = index.data(QxtItemDelegate::ProgressValueRole).toInt();
    opt.rect = option.rect;
    opt.textVisible = textVisible;
    opt.text = progressFormat.arg(opt.progress);
    QApplication::style()->drawControl(QStyle::CE_ProgressBar, &opt, painter, 0);

    QWidget* viewport = dynamic_cast<QWidget*>(painter->device());
    if (viewport)
    {
        if (opt.minimum == 0 && opt.maximum == 0)
        {
            if (!updatedItems.contains(viewport))
                connect(viewport, SIGNAL(destroyed()), this, SLOT(viewDestroyed()));
            updatedItems.replace(viewport, index);
        }
        else
        {
            updatedItems.remove(viewport, index);
            if (!updatedItems.contains(viewport))
                disconnect(viewport, SIGNAL(destroyed()), this, SLOT(viewDestroyed()));
        }
    }

    if (updatedItems.isEmpty())
    {
        if (updateTimer.isActive())
            updateTimer.stop();
    }
    else
    {
        if (!updateTimer.isActive())
            updateTimer.start(1000 / 25, const_cast<QxtItemDelegatePrivate*>(this));
    }
}

void QxtItemDelegatePrivate::setCurrentEditor(QWidget* editor, const QModelIndex& index) const
{
    currentEditor = editor;
    currentEdited = index;
}

void QxtItemDelegatePrivate::timerEvent(QTimerEvent* event)
{
    if (event->timerId() == updateTimer.timerId())
    {
        QMutableHashIterator<QWidget*, QPersistentModelIndex> it(updatedItems);
        while (it.hasNext())
        {
            it.next();
            if (!it.key())
            {
                it.remove();
                continue;
            }

            // try to update the specific view item instead of the whole view if possible
            if (QAbstractItemView* view = qobject_cast<QAbstractItemView*>(it.key()->parentWidget()))
                view->update(it.value());
            else
                it.key()->update();
        }
    }
}

void QxtItemDelegatePrivate::viewDestroyed()
{
    QWidget* viewport = qobject_cast<QWidget*>(sender());
    if (viewport)
    {
        updatedItems.remove(viewport);
    }
}

void QxtItemDelegatePrivate::closeEditor(QWidget* editor)
{
    if (currentEdited.isValid() && editor == currentEditor)
    {
        setCurrentEditor(0, QModelIndex());
        emit qxt_p().editingFinished(currentEdited);
    }
}

/*!
    \class QxtItemDelegate QxtItemDelegate
    \ingroup QxtGui
    \brief An extended QItemDelegate with additional signals and optional decoration.

    QxtItemDelegate provides signals for starting and finishing of editing
    and an optional decoration for top level indices in a QTreeView.
    QxtItemDelegate can also draw a progress bar for indices providing
    appropriate progress data.
 */

/*!
    \fn QxtItemDelegate::editingStarted(const QModelIndex& index)

    This signal is emitted after the editing of \a index has been started.

    \sa editingFinished()
 */

/*!
    \fn QxtItemDelegate::editingFinished(const QModelIndex& index)

    This signal is emitted after the editing of \a index has been finished.

    \sa editingStarted()
 */

/*!
    Constructs a new QxtItemDelegate with \a parent.
 */
QxtItemDelegate::QxtItemDelegate(QObject* parent) : QItemDelegate(parent)
{
    QXT_INIT_PRIVATE(QxtItemDelegate);
    connect(this, SIGNAL(closeEditor(QWidget*)), &qxt_d(), SLOT(closeEditor(QWidget*)));
}

/*!
    Destructs the item delegate.
 */
QxtItemDelegate::~QxtItemDelegate()
{}

/*!
    \property QxtItemDelegate::decorationStyle
    \brief This property holds the top level index decoration style

    Top level indices are decorated according to this property.
    The default value is \b Qxt::NoDecoration.

    \note The property has effect only in case the delegate is installed
    on a QTreeView. The view must be the parent of the delegate.

    \note Set \b QTreeView::rootIsDecorated to \b false to avoid
    multiple branch indicators.

    \sa Qxt::DecorationStyle, QTreeView::rootIsDecorated
 */
Qxt::DecorationStyle QxtItemDelegate::decorationStyle() const
{
    return qxt_d().style;
}

void QxtItemDelegate::setDecorationStyle(Qxt::DecorationStyle style)
{
    qxt_d().style = style;
}

/*!
    \property QxtItemDelegate::elideMode
    \brief This property holds the text elide mode

    The text of a decorated top level index is elided according to this property.
    The default value is \b Qt::ElideMiddle.

    \note The property has effect only for decorated top level indices.

    \sa decorationStyle, Qt::TextElideMode
 */
Qt::TextElideMode QxtItemDelegate::elideMode() const
{
    return qxt_d().elide;
}

void QxtItemDelegate::setElideMode(Qt::TextElideMode mode)
{
    qxt_d().elide = mode;
}

/*!
    \property QxtItemDelegate::progressTextFormat
    \brief This property holds the format of optional progress text

    The progress text is formatted according to this property.
    The default value is \b "%1%".

    \note Progress bar is rendered for indices providing valid
    numerical data for \b ProgressValueRole.

 \note \b \%1 is replaced by the progress percent.

    \sa progressTextVisible, Role
 */
QString QxtItemDelegate::progressTextFormat() const
{
    return qxt_d().progressFormat;
}

void QxtItemDelegate::setProgressTextFormat(const QString& format)
{
    qxt_d().progressFormat = format;
}

/*!
    \property QxtItemDelegate::progressTextVisible
    \brief This property holds whether progress text is visible

    The default value is \b true.

    \note Progress bar is rendered for indices providing valid
    numerical data for \b ProgressValueRole.

    \sa progressTextFormat, QxtItemDelegate::Role
 */
bool QxtItemDelegate::isProgressTextVisible() const
{
    return qxt_d().textVisible;
}

void QxtItemDelegate::setProgressTextVisible(bool visible)
{
    qxt_d().textVisible = visible;
}

/*!
    \reimp
 */
QWidget* QxtItemDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
    QWidget* editor = QItemDelegate::createEditor(parent, option, index);
    qxt_d().setCurrentEditor(editor, index);
    emit const_cast<QxtItemDelegate*>(this)->editingStarted(index);
    return editor;
}

/*!
    \reimp
 */
void QxtItemDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const
{
    QItemDelegate::setModelData(editor, model, index);
    qxt_d().setCurrentEditor(0, QModelIndex());
    emit const_cast<QxtItemDelegate*>(this)->editingFinished(index);
}

/*!
    \reimp
 */
void QxtItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
    const QAbstractItemModel* model = index.model();
    const QTreeView* tree = qobject_cast<QTreeView*>(parent());
    const bool topLevel = !index.parent().isValid();

    if (tree && model && topLevel && qxt_d().style != Qxt::NoDecoration)
    {
        QStyleOptionViewItem opt;
        opt.QStyleOption::operator=(option);
        opt.showDecorationSelected = false;

        QModelIndex valid = model->index(index.row(), 0);
        QModelIndex sibling = valid;
        while (sibling.isValid())
        {
            opt.rect |= tree->visualRect(sibling);
            sibling = sibling.sibling(sibling.row(), sibling.column() + 1);
        }

        switch (qxt_d().style)
        {
        case Qxt::Buttonlike:
            qxt_d().paintButton(painter, opt, valid, tree);
            break;
        case Qxt::Menulike:
            qxt_d().paintMenu(painter, opt, valid, tree);
            break;
        default:
            qWarning("QxtItemDelegate::paint() unknown decoration style");
            QItemDelegate::paint(painter, opt, valid);
            break;
        }
    }
    else
    {
        QItemDelegate::paint(painter, option, index);

        const QVariant data = index.data(ProgressValueRole);
        if (data.isValid() && data.canConvert(QVariant::Int))
            qxt_d().paintProgress(painter, option, index);
    }
}

/*!
    \reimp
 */
QSize QxtItemDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const
{
    // something slightly bigger for top level indices
    QSize size = QItemDelegate::sizeHint(option, index);
    if (!index.parent().isValid())
        size += QSize(TOP_LEVEL_EXTENT, TOP_LEVEL_EXTENT);
    return  size;
}
<commit_msg>Improved QxtItemDelegate docs.<commit_after>/****************************************************************************
**
** Copyright (C) Qxt Foundation. Some rights reserved.
**
** This file is part of the QxtGui module of the Qxt library.
**
** This library is free software; you can redistribute it and/or modify it
** under the terms of the Common Public License, version 1.0, as published by
** IBM.
**
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
** FITNESS FOR A PARTICULAR PURPOSE.
**
** You should have received a copy of the CPL along with this file.
** See the LICENSE file and the cpl1.0.txt file included with the source
** distribution for more information. If you did not receive a copy of the
** license, contact the Qxt Foundation.
**
** <http://libqxt.org>  <foundation@libqxt.org>
**
****************************************************************************/
#include "qxtitemdelegate.h"
#include "qxtitemdelegate_p.h"
#include <QApplication>
#include <QTreeView>
#include <QPainter>
#include <QTimer>

static const int TOP_LEVEL_EXTENT = 2;

QxtItemDelegatePrivate::QxtItemDelegatePrivate() :
        textVisible(true),
        progressFormat("%1%"),
        elide(Qt::ElideMiddle),
        style(Qxt::NoDecoration)
{
}

void QxtItemDelegatePrivate::paintButton(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index, const QTreeView* view) const
{
    // draw the button
    QStyleOptionButton buttonOption;
    buttonOption.state = option.state;
#ifdef Q_WS_MAC
    buttonOption.state |= QStyle::State_Raised;
#endif
    buttonOption.state &= ~QStyle::State_HasFocus;
    if (view->isExpanded(index))
        buttonOption.state |= QStyle::State_Sunken;
    buttonOption.rect = option.rect;
    buttonOption.palette = option.palette;
    buttonOption.features = QStyleOptionButton::None;
    view->style()->drawControl(QStyle::CE_PushButton, &buttonOption, painter, view);

    // draw the branch indicator
    static const int i = 9;
    const QRect& r = option.rect;
    if (index.model()->hasChildren(index))
    {
        QStyleOption branchOption;
        branchOption.initFrom(view);
        if (branchOption.direction == Qt::LeftToRight)
            branchOption.rect = QRect(r.left() + i / 2, r.top() + (r.height() - i) / 2, i, i);
        else
            branchOption.rect = QRect(r.right() - i / 2 - i, r.top() + (r.height() - i) / 2, i, i);
        branchOption.palette = option.palette;
        branchOption.state = QStyle::State_Children;
        if (view->isExpanded(index))
            branchOption.state |= QStyle::State_Open;
        view->style()->drawPrimitive(QStyle::PE_IndicatorBranch, &branchOption, painter, view);
    }

    // draw the text
    QRect textrect = QRect(r.left() + i * 2, r.top(), r.width() - ((5 * i) / 2), r.height());
#if QT_VERSION < 0x040200
    QString text = QItemDelegate::elidedText(option.fontMetrics, textrect.width(), elide, index.data().toString());
#else // QT_VERSION >= 0x040200
    QString text = option.fontMetrics.elidedText(index.data().toString(), elide, textrect.width());
#endif // QT_VERSION
    view->style()->drawItemText(painter, textrect, Qt::AlignCenter, option.palette, view->isEnabled(), text);
}

void QxtItemDelegatePrivate::paintMenu(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index, const QTreeView* view) const
{
    // draw the menu bar item
    QStyleOptionMenuItem menuOption;
    menuOption.palette = view->palette();
    menuOption.fontMetrics = view->fontMetrics();
    menuOption.state = QStyle::State_None;
    // QModelIndex::flags() was introduced in 4.2
    // => therefore "index.model()->flags(index)"
    if (view->isEnabled() && index.model()->flags(index) & Qt::ItemIsEnabled)
        menuOption.state |= QStyle::State_Enabled;
    else
        menuOption.palette.setCurrentColorGroup(QPalette::Disabled);
    menuOption.state |= QStyle::State_Selected;
    menuOption.state |= QStyle::State_Sunken;
    menuOption.state |= QStyle::State_HasFocus;
    menuOption.rect = option.rect;
    menuOption.text = index.data().toString();
    menuOption.icon = QIcon(index.data(Qt::DecorationRole).value<QPixmap>());
    view->style()->drawControl(QStyle::CE_MenuBarItem, &menuOption, painter, view);

    // draw the an arrow as a branch indicator
    if (index.model()->hasChildren(index))
    {
        QStyle::PrimitiveElement arrow;
        if (view->isExpanded(index))
            arrow = QStyle::PE_IndicatorArrowUp;
        else
            arrow = QStyle::PE_IndicatorArrowDown;
        static const int i = 9;
        const QRect& r = option.rect;
        menuOption.rect = QRect(r.left() + i / 2, r.top() + (r.height() - i) / 2, i, i);
        view->style()->drawPrimitive(arrow, &menuOption, painter, view);
    }
}

void QxtItemDelegatePrivate::paintProgress(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
    QVariant min = index.data(QxtItemDelegate::ProgressMinimumRole);
    QVariant max = index.data(QxtItemDelegate::ProgressMaximumRole);

    QStyleOptionProgressBar opt;
    opt.minimum = (min.isValid() && min.canConvert(QVariant::Int)) ? min.toInt() : 0;
    opt.maximum = (max.isValid() && max.canConvert(QVariant::Int)) ? max.toInt() : 100;
    opt.progress = index.data(QxtItemDelegate::ProgressValueRole).toInt();
    opt.rect = option.rect;
    opt.textVisible = textVisible;
    opt.text = progressFormat.arg(opt.progress);
    QApplication::style()->drawControl(QStyle::CE_ProgressBar, &opt, painter, 0);

    QWidget* viewport = dynamic_cast<QWidget*>(painter->device());
    if (viewport)
    {
        if (opt.minimum == 0 && opt.maximum == 0)
        {
            if (!updatedItems.contains(viewport))
                connect(viewport, SIGNAL(destroyed()), this, SLOT(viewDestroyed()));
            updatedItems.replace(viewport, index);
        }
        else
        {
            updatedItems.remove(viewport, index);
            if (!updatedItems.contains(viewport))
                disconnect(viewport, SIGNAL(destroyed()), this, SLOT(viewDestroyed()));
        }
    }

    if (updatedItems.isEmpty())
    {
        if (updateTimer.isActive())
            updateTimer.stop();
    }
    else
    {
        if (!updateTimer.isActive())
            updateTimer.start(1000 / 25, const_cast<QxtItemDelegatePrivate*>(this));
    }
}

void QxtItemDelegatePrivate::setCurrentEditor(QWidget* editor, const QModelIndex& index) const
{
    currentEditor = editor;
    currentEdited = index;
}

void QxtItemDelegatePrivate::timerEvent(QTimerEvent* event)
{
    if (event->timerId() == updateTimer.timerId())
    {
        QMutableHashIterator<QWidget*, QPersistentModelIndex> it(updatedItems);
        while (it.hasNext())
        {
            it.next();
            if (!it.key())
            {
                it.remove();
                continue;
            }

            // try to update the specific view item instead of the whole view if possible
            if (QAbstractItemView* view = qobject_cast<QAbstractItemView*>(it.key()->parentWidget()))
                view->update(it.value());
            else
                it.key()->update();
        }
    }
}

void QxtItemDelegatePrivate::viewDestroyed()
{
    QWidget* viewport = qobject_cast<QWidget*>(sender());
    if (viewport)
    {
        updatedItems.remove(viewport);
    }
}

void QxtItemDelegatePrivate::closeEditor(QWidget* editor)
{
    if (currentEdited.isValid() && editor == currentEditor)
    {
        setCurrentEditor(0, QModelIndex());
        emit qxt_p().editingFinished(currentEdited);
    }
}

/*!
    \class QxtItemDelegate QxtItemDelegate
    \ingroup QxtGui
    \brief An extended QItemDelegate with additional signals and optional decoration.

    QxtItemDelegate provides signals for starting and finishing of editing
    and an optional decoration for top level indices in a QTreeView.

    QxtItemDelegate can also draw a progress bar for indices providing
    appropriate progress data. Just like QProgressBar, QxtItemDelegate
    can show a busy indicator. If minimum and maximum both are set to
    \b 0, a busy indicator is shown instead of a percentage of steps.
 */

/*!
    \fn QxtItemDelegate::editingStarted(const QModelIndex& index)

    This signal is emitted after the editing of \a index has been started.

    \sa editingFinished()
 */

/*!
    \fn QxtItemDelegate::editingFinished(const QModelIndex& index)

    This signal is emitted after the editing of \a index has been finished.

    \sa editingStarted()
 */

/*!
    \enum QxtItemDelegate::Role

    This enum defines custom roles used by QxtItemDelegate.
 */

/*!
    \var QxtItemDelegate::Role QxtItemDelegate::ProgressValueRole

    The progress value.
 */

/*!
    \var QxtItemDelegate::Role QxtItemDelegate::ProgressMinimumRole

    The minimum progress value. The default value \b 0 is used
    if no value is provided for ProgressMinimumRole.
 */

/*!
    \var QxtItemDelegate::Role QxtItemDelegate::ProgressMaximumRole

    The maximum progress value. The default value \b 100 is used
    if no value is provided for ProgressMaximumRole.
 */

/*!
    Constructs a new QxtItemDelegate with \a parent.
 */
QxtItemDelegate::QxtItemDelegate(QObject* parent) : QItemDelegate(parent)
{
    QXT_INIT_PRIVATE(QxtItemDelegate);
    connect(this, SIGNAL(closeEditor(QWidget*)), &qxt_d(), SLOT(closeEditor(QWidget*)));
}

/*!
    Destructs the item delegate.
 */
QxtItemDelegate::~QxtItemDelegate()
{}

/*!
    \property QxtItemDelegate::decorationStyle
    \brief This property holds the top level index decoration style

    Top level indices are decorated according to this property.
    The default value is \b Qxt::NoDecoration.

    \note The property has effect only in case the delegate is installed
    on a QTreeView. The view must be the parent of the delegate.

    \note Set \b QTreeView::rootIsDecorated to \b false to avoid
    multiple branch indicators.

    \sa Qxt::DecorationStyle, QTreeView::rootIsDecorated
 */
Qxt::DecorationStyle QxtItemDelegate::decorationStyle() const
{
    return qxt_d().style;
}

void QxtItemDelegate::setDecorationStyle(Qxt::DecorationStyle style)
{
    qxt_d().style = style;
}

/*!
    \property QxtItemDelegate::elideMode
    \brief This property holds the text elide mode

    The text of a decorated top level index is elided according to this property.
    The default value is \b Qt::ElideMiddle.

    \note The property has effect only for decorated top level indices.

    \sa decorationStyle, Qt::TextElideMode
 */
Qt::TextElideMode QxtItemDelegate::elideMode() const
{
    return qxt_d().elide;
}

void QxtItemDelegate::setElideMode(Qt::TextElideMode mode)
{
    qxt_d().elide = mode;
}

/*!
    \property QxtItemDelegate::progressTextFormat
    \brief This property holds the format of optional progress text

    The progress text is formatted according to this property.
    The default value is \b "%1%".

    \note Progress bar is rendered for indices providing valid
    numerical data for \b ProgressValueRole.

 \note \b \%1 is replaced by the progress percent.

    \sa progressTextVisible, Role
 */
QString QxtItemDelegate::progressTextFormat() const
{
    return qxt_d().progressFormat;
}

void QxtItemDelegate::setProgressTextFormat(const QString& format)
{
    qxt_d().progressFormat = format;
}

/*!
    \property QxtItemDelegate::progressTextVisible
    \brief This property holds whether progress text is visible

    The default value is \b true.

    \note Progress bar is rendered for indices providing valid
    numerical data for \b ProgressValueRole.

    \sa progressTextFormat, QxtItemDelegate::Role
 */
bool QxtItemDelegate::isProgressTextVisible() const
{
    return qxt_d().textVisible;
}

void QxtItemDelegate::setProgressTextVisible(bool visible)
{
    qxt_d().textVisible = visible;
}

/*!
    \reimp
 */
QWidget* QxtItemDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
    QWidget* editor = QItemDelegate::createEditor(parent, option, index);
    qxt_d().setCurrentEditor(editor, index);
    emit const_cast<QxtItemDelegate*>(this)->editingStarted(index);
    return editor;
}

/*!
    \reimp
 */
void QxtItemDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const
{
    QItemDelegate::setModelData(editor, model, index);
    qxt_d().setCurrentEditor(0, QModelIndex());
    emit const_cast<QxtItemDelegate*>(this)->editingFinished(index);
}

/*!
    \reimp
 */
void QxtItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
    const QAbstractItemModel* model = index.model();
    const QTreeView* tree = qobject_cast<QTreeView*>(parent());
    const bool topLevel = !index.parent().isValid();

    if (tree && model && topLevel && qxt_d().style != Qxt::NoDecoration)
    {
        QStyleOptionViewItem opt;
        opt.QStyleOption::operator=(option);
        opt.showDecorationSelected = false;

        QModelIndex valid = model->index(index.row(), 0);
        QModelIndex sibling = valid;
        while (sibling.isValid())
        {
            opt.rect |= tree->visualRect(sibling);
            sibling = sibling.sibling(sibling.row(), sibling.column() + 1);
        }

        switch (qxt_d().style)
        {
        case Qxt::Buttonlike:
            qxt_d().paintButton(painter, opt, valid, tree);
            break;
        case Qxt::Menulike:
            qxt_d().paintMenu(painter, opt, valid, tree);
            break;
        default:
            qWarning("QxtItemDelegate::paint() unknown decoration style");
            QItemDelegate::paint(painter, opt, valid);
            break;
        }
    }
    else
    {
        QItemDelegate::paint(painter, option, index);

        const QVariant data = index.data(ProgressValueRole);
        if (data.isValid() && data.canConvert(QVariant::Int))
            qxt_d().paintProgress(painter, option, index);
    }
}

/*!
    \reimp
 */
QSize QxtItemDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const
{
    // something slightly bigger for top level indices
    QSize size = QItemDelegate::sizeHint(option, index);
    if (!index.parent().isValid())
        size += QSize(TOP_LEVEL_EXTENT, TOP_LEVEL_EXTENT);
    return  size;
}
<|endoftext|>


<commit_before>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2007-2009, Image Engine Design Inc. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
//     * Neither the name of Image Engine Design nor the names of any
//       other contributors to this software may be used to endorse or
//       promote products derived from this software without specific prior
//       written permission.
//
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
//  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
//  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
//  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
//  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
//  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
//  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
//  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
//  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
//  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////

#include "IECore/CompoundData.h"
#include "IECore/TypedData.inl"

#include <iostream>
using namespace std;
using namespace IECore;

namespace IECore
{

IECORE_RUNTIMETYPED_DEFINETEMPLATESPECIALISATION( CompoundData, CompoundDataTypeId, Data );

template<>
void CompoundData::memoryUsage( Object::MemoryAccumulator &accumulator ) const
{
	Data::memoryUsage( accumulator );
	const CompoundDataMap &data = readable();
	CompoundDataMap::const_iterator iter = data.begin();
	while (iter != data.end())
	{
		accumulator.accumulate( iter->second );
		iter++;
	}
}

template<>
void CompoundData::copyFrom( ConstObjectPtr other, CopyContext *context )
{
	Data::copyFrom( other, context );
	const CompoundData *tOther = static_cast<const CompoundData *>( other.get() );
	CompoundDataMap &data = writable();
	data.clear();
	const CompoundDataMap &otherData = tOther->readable();
	for( CompoundDataMap::const_iterator it = otherData.begin(); it!=otherData.end(); it++ )
	{
		data[it->first] = context->copy<Data>( it->second );
	}
}

template<>
bool CompoundData::isEqualTo( ConstObjectPtr other ) const
{
	if( !Data::isEqualTo( other ) )
	{
		return false;
	}
	ConstCompoundDataPtr tOther = boost::static_pointer_cast<const CompoundData>( other );
	const CompoundDataMap &m1 = readable();
	const CompoundDataMap &m2 = tOther->readable();
	if( m1.size()!=m2.size() )
	{
		return false;
	}
	CompoundDataMap::const_iterator it1 = m1.begin();
	CompoundDataMap::const_iterator it2 = m2.begin();
	while( it1!=m1.end() )
	{
		if( it1->first!=it2->first )
		{
			return false;
		}
		if( ! it1->second->isEqualTo( it2->second ) )
		{
			return false;
		}
		it1++;
		it2++;
	}
	return true;
}

template<>
void CompoundData::save( SaveContext *context ) const
{
	Data::save( context );
	IndexedIOInterfacePtr container = context->container( staticTypeName(), 0 );
	container->mkdir( "members" );
	container->chdir( "members" );
		const CompoundDataMap &m = readable();
		CompoundDataMap::const_iterator it;
		for( it=m.begin(); it!=m.end(); it++ )
		{
			context->save( it->second, container, it->first );
		}
	container->chdir( ".." );
}

template<>
void CompoundData::load( LoadContextPtr context )
{
	Data::load( context );
	unsigned int v = 0;
	IndexedIOInterfacePtr container = context->container( staticTypeName(), v );
	CompoundDataMap &m = writable();
	m.clear();
	container->chdir( "members" );
		IndexedIO::EntryList members = container->ls();
		IndexedIO::EntryList::const_iterator it;
		for( it=members.begin(); it!=members.end(); it++ )
		{
			m[it->id()] = context->load<Data>( container, it->id() );
		}
	container->chdir( ".." );
}

IE_CORE_DEFINETYPEDDATANOBASESIZE( CompoundData )

}

// Instantiate that bad boy.
template class TypedData<CompoundDataMap>;
<commit_msg>Added todo<commit_after>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2007-2009, Image Engine Design Inc. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
//     * Neither the name of Image Engine Design nor the names of any
//       other contributors to this software may be used to endorse or
//       promote products derived from this software without specific prior
//       written permission.
//
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
//  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
//  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
//  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
//  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
//  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
//  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
//  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
//  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
//  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////

#include "IECore/CompoundData.h"
#include "IECore/TypedData.inl"

#include <iostream>
using namespace std;
using namespace IECore;

namespace IECore
{

IECORE_RUNTIMETYPED_DEFINETEMPLATESPECIALISATION( CompoundData, CompoundDataTypeId, Data );

template<>
void CompoundData::memoryUsage( Object::MemoryAccumulator &accumulator ) const
{
	Data::memoryUsage( accumulator );
	const CompoundDataMap &data = readable();
	CompoundDataMap::const_iterator iter = data.begin();
	while (iter != data.end())
	{
		/// \todo Accumulate size of keys, too (iter->first), as this
		/// can be significant
		accumulator.accumulate( iter->second );
		iter++;
	}
}

template<>
void CompoundData::copyFrom( ConstObjectPtr other, CopyContext *context )
{
	Data::copyFrom( other, context );
	const CompoundData *tOther = static_cast<const CompoundData *>( other.get() );
	CompoundDataMap &data = writable();
	data.clear();
	const CompoundDataMap &otherData = tOther->readable();
	for( CompoundDataMap::const_iterator it = otherData.begin(); it!=otherData.end(); it++ )
	{
		data[it->first] = context->copy<Data>( it->second );
	}
}

template<>
bool CompoundData::isEqualTo( ConstObjectPtr other ) const
{
	if( !Data::isEqualTo( other ) )
	{
		return false;
	}
	ConstCompoundDataPtr tOther = boost::static_pointer_cast<const CompoundData>( other );
	const CompoundDataMap &m1 = readable();
	const CompoundDataMap &m2 = tOther->readable();
	if( m1.size()!=m2.size() )
	{
		return false;
	}
	CompoundDataMap::const_iterator it1 = m1.begin();
	CompoundDataMap::const_iterator it2 = m2.begin();
	while( it1!=m1.end() )
	{
		if( it1->first!=it2->first )
		{
			return false;
		}
		if( ! it1->second->isEqualTo( it2->second ) )
		{
			return false;
		}
		it1++;
		it2++;
	}
	return true;
}

template<>
void CompoundData::save( SaveContext *context ) const
{
	Data::save( context );
	IndexedIOInterfacePtr container = context->container( staticTypeName(), 0 );
	container->mkdir( "members" );
	container->chdir( "members" );
		const CompoundDataMap &m = readable();
		CompoundDataMap::const_iterator it;
		for( it=m.begin(); it!=m.end(); it++ )
		{
			context->save( it->second, container, it->first );
		}
	container->chdir( ".." );
}

template<>
void CompoundData::load( LoadContextPtr context )
{
	Data::load( context );
	unsigned int v = 0;
	IndexedIOInterfacePtr container = context->container( staticTypeName(), v );
	CompoundDataMap &m = writable();
	m.clear();
	container->chdir( "members" );
		IndexedIO::EntryList members = container->ls();
		IndexedIO::EntryList::const_iterator it;
		for( it=members.begin(); it!=members.end(); it++ )
		{
			m[it->id()] = context->load<Data>( container, it->id() );
		}
	container->chdir( ".." );
}

IE_CORE_DEFINETYPEDDATANOBASESIZE( CompoundData )

}

// Instantiate that bad boy.
template class TypedData<CompoundDataMap>;
<|endoftext|>