<commit_before>/*************************************************************************
 *
 *  $RCSfile: unmove.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005-03-29 11:49:03 $
 *
 *  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

#ifndef _DOC_HXX
#include <doc.hxx>
#endif
#ifndef _PAM_HXX
#include <pam.hxx>
#endif
#ifndef _SWUNDO_HXX
#include <swundo.hxx>           // fuer die UndoIds
#endif
#ifndef _NDTXT_HXX
#include <ndtxt.hxx>
#endif
#ifndef _UNDOBJ_HXX
#include <undobj.hxx>
#endif
#ifndef _ROLBCK_HXX
#include <rolbck.hxx>
#endif

inline SwDoc& SwUndoIter::GetDoc() const { return *pAktPam->GetDoc(); }

// MOVE

SwUndoMove::SwUndoMove( const SwPaM& rRange, const SwPosition& rMvPos )
    : SwUndo( UNDO_MOVE ), SwUndRng( rRange ),
    nMvDestNode( rMvPos.nNode.GetIndex() ),
    nMvDestCntnt( rMvPos.nContent.GetIndex() ),
    bMoveRedlines( false )
{
    bMoveRange = bJoinNext = bJoinPrev = FALSE;

    // StartNode vorm loeschen von Fussnoten besorgen!
    SwDoc* pDoc = rRange.GetDoc();
    SwTxtNode* pTxtNd = pDoc->GetNodes()[ nSttNode ]->GetTxtNode();
    SwTxtNode* pEndTxtNd = pDoc->GetNodes()[ nEndNode ]->GetTxtNode();

    pHistory = new SwHistory;

    if( pTxtNd )
    {
        pHistory->Add( pTxtNd->GetTxtColl(), nSttNode, ND_TEXTNODE );
        if( pTxtNd->GetpSwpHints() )
            pHistory->CopyAttr( pTxtNd->GetpSwpHints(), nSttNode,
                                0, pTxtNd->GetTxt().Len(), FALSE );
        if( pTxtNd->GetpSwAttrSet() )
            pHistory->CopyFmtAttr( *pTxtNd->GetpSwAttrSet(), nSttNode );
    }
    if( pEndTxtNd && pEndTxtNd != pTxtNd )
    {
        pHistory->Add( pEndTxtNd->GetTxtColl(), nEndNode, ND_TEXTNODE );
        if( pEndTxtNd->GetpSwpHints() )
            pHistory->CopyAttr( pEndTxtNd->GetpSwpHints(), nEndNode,
                                0, pEndTxtNd->GetTxt().Len(), FALSE );
        if( pEndTxtNd->GetpSwAttrSet() )
            pHistory->CopyFmtAttr( *pEndTxtNd->GetpSwAttrSet(), nEndNode );
    }

    if( 0 != (pTxtNd = rRange.GetDoc()->GetNodes()[ rMvPos.nNode ]->GetTxtNode() ))
    {
        pHistory->Add( pTxtNd->GetTxtColl(), nMvDestNode, ND_TEXTNODE );
        if( pTxtNd->GetpSwpHints() )
            pHistory->CopyAttr( pTxtNd->GetpSwpHints(), nMvDestNode,
                                0, pTxtNd->GetTxt().Len(), FALSE );
        if( pTxtNd->GetpSwAttrSet() )
            pHistory->CopyFmtAttr( *pTxtNd->GetpSwAttrSet(), nMvDestNode );
    }

    nFtnStt = pHistory->Count();
    DelFtn( rRange );

    if( pHistory && !pHistory->Count() )
        DELETEZ( pHistory );
}

SwUndoMove::SwUndoMove( SwDoc* pDoc, const SwNodeRange& rRg,
                        const SwNodeIndex& rMvPos )
    : SwUndo( UNDO_MOVE ),
    nMvDestNode( rMvPos.GetIndex() ),
    bMoveRedlines( false )
{
    bMoveRange = TRUE;
    bJoinNext = bJoinPrev = FALSE;

    nSttCntnt = nEndCntnt = nMvDestCntnt = STRING_MAXLEN;

    nSttNode = rRg.aStart.GetIndex();
    nEndNode = rRg.aEnd.GetIndex();

//  DelFtn( rRange );

    // wird aus dem CntntBereich in den Sonderbereich verschoben ?
    ULONG nCntntStt = pDoc->GetNodes().GetEndOfAutotext().GetIndex();
    if( nMvDestNode < nCntntStt && rRg.aStart.GetIndex() > nCntntStt )
    {
        // loesche alle Fussnoten. Diese sind dort nicht erwuenscht.
        SwPosition aPtPos( rRg.aEnd );
        SwCntntNode* pCNd = rRg.aEnd.GetNode().GetCntntNode();
        if( pCNd )
            aPtPos.nContent.Assign( pCNd, pCNd->Len() );
        SwPosition aMkPos( rRg.aStart );
        if( 0 != ( pCNd = aMkPos.nNode.GetNode().GetCntntNode() ))
            aMkPos.nContent.Assign( pCNd, 0 );

        DelCntntIndex( aMkPos, aPtPos, SwUndoSaveCntnt::DELCNT_FTN );

        if( pHistory && !pHistory->Count() )
            DELETEZ( pHistory );
    }

    nFtnStt = 0;
}

void SwUndoMove::SetDestRange( const SwPaM& rRange,
                                const SwPosition& rInsPos,
                                BOOL bJoin, BOOL bCorrPam )
{
    const SwPosition *pStt = rRange.Start(),
                    *pEnd = rRange.GetPoint() == pStt
                        ? rRange.GetMark()
                        : rRange.GetPoint();

    nDestSttNode    = pStt->nNode.GetIndex();
    nDestSttCntnt   = pStt->nContent.GetIndex();
    nDestEndNode    = pEnd->nNode.GetIndex();
    nDestEndCntnt   = pEnd->nContent.GetIndex();

    nInsPosNode     = rInsPos.nNode.GetIndex();
    nInsPosCntnt    = rInsPos.nContent.GetIndex();

    if( bCorrPam )
    {
        nDestSttNode--;
        nDestEndNode--;
    }

    bJoinNext = nDestSttNode != nDestEndNode &&
                pStt->nNode.GetNode().GetTxtNode() &&
                pEnd->nNode.GetNode().GetTxtNode();
    bJoinPrev = bJoin;
}

void SwUndoMove::SetDestRange( const SwNodeIndex& rStt,
                                const SwNodeIndex& rEnd,
                                const SwNodeIndex& rInsPos )
{
    nDestSttNode = rStt.GetIndex();
    nDestEndNode = rEnd.GetIndex();
    if( nDestSttNode > nDestEndNode )
    {
        nDestSttNode = nDestEndNode;
        nDestEndNode = rStt.GetIndex();
    }
    nInsPosNode  = rInsPos.GetIndex();

    nDestSttCntnt = nDestEndCntnt = nInsPosCntnt = STRING_MAXLEN;
}

void SwUndoMove::Undo( SwUndoIter& rUndoIter )
{
    SwDoc* pDoc = &rUndoIter.GetDoc();
    BOOL bUndo = pDoc->DoesUndo();
    pDoc->DoUndo( FALSE );

    // Block, damit aus diesem gesprungen werden kann
    do {
        // erzeuge aus den Werten die Insert-Position und den Bereich
        SwNodeIndex aIdx( pDoc->GetNodes(), nDestSttNode );

        if( bMoveRange )
        {
            // nur ein Move mit SwRange
            SwNodeRange aRg( aIdx, aIdx );
            aRg.aEnd = nDestEndNode;
            aIdx = nInsPosNode;
            if( !pDoc->Move( aRg, aIdx ) )
                break;
        }
        else
        {
            SwPaM aPam( aIdx.GetNode(), nDestSttCntnt,
                        *pDoc->GetNodes()[ nDestEndNode ], nDestEndCntnt );

            // #i17764# if redlines are to be moved, we may not remove them before
            //          pDoc->Move gets a chance to handle them
            if( ! bMoveRedlines )
                RemoveIdxFromRange( aPam, FALSE );

            SwPosition aPos( *pDoc->GetNodes()[ nInsPosNode] );
            SwCntntNode* pCNd = aPos.nNode.GetNode().GetCntntNode();
            aPos.nContent.Assign( pCNd, nInsPosCntnt );

            if( pCNd->GetpSwAttrSet() )
                pCNd->ResetAllAttr();

            if( pCNd->IsTxtNode() && ((SwTxtNode*)pCNd)->GetpSwpHints() )
                ((SwTxtNode*)pCNd)->ClearSwpHintsArr( FALSE, FALSE );

            // an der InsertPos erstmal alle Attribute entfernen,
            if( !pDoc->Move( aPam, aPos, ( bMoveRedlines ? DOC_MOVEREDLINES : DOC_MOVEDEFAULT ) ) )
                break;

            aPam.Exchange();
            aPam.DeleteMark();
//          pDoc->ResetAttr( aPam, FALSE );
            if( aPam.GetNode()->IsCntntNode() )
                aPam.GetNode()->GetCntntNode()->ResetAllAttr();
            // der Pam wird jetzt aufgegeben.
        }

        SwTxtNode* pTxtNd = aIdx.GetNode().GetTxtNode();
        if( bJoinNext )
        {
            {
                RemoveIdxRel( aIdx.GetIndex() + 1, SwPosition( aIdx,
                        SwIndex( pTxtNd, pTxtNd->GetTxt().Len() ) ) );
            }
            // sind keine Pams mehr im naechsten TextNode
            pTxtNd->JoinNext();
        }

        if( bJoinPrev && pTxtNd->CanJoinPrev( &aIdx ) )
        {
            // ?? sind keine Pams mehr im naechsten TextNode ??
            pTxtNd = aIdx.GetNode().GetTxtNode();
            {
                RemoveIdxRel( aIdx.GetIndex() + 1, SwPosition( aIdx,
                        SwIndex( pTxtNd, pTxtNd->GetTxt().Len() ) ) );
            }
            pTxtNd->JoinNext();
        }

    } while( FALSE );

    if( pHistory )
    {
        if( nFtnStt != pHistory->Count() )
            pHistory->Rollback( pDoc, nFtnStt );
        pHistory->TmpRollback( pDoc, 0 );
        pHistory->SetTmpEnd( pHistory->Count() );
    }

    pDoc->DoUndo( bUndo );

    // setze noch den Cursor auf den Undo-Bereich
    if( !bMoveRange )
        SetPaM( rUndoIter );
}

void SwUndoMove::Redo( SwUndoIter& rUndoIter )
{
    SwPaM* pPam = rUndoIter.pAktPam;
    SwDoc& rDoc = *pPam->GetDoc();

    SwNodes& rNds = rDoc.GetNodes();
    SwNodeIndex aIdx( rNds, nMvDestNode );

    if( bMoveRange )
    {
        // nur ein Move mit SwRange
        SwNodeRange aRg( rNds, nSttNode, rNds, nEndNode );
        rDoc.Move( aRg, aIdx, ( bMoveRedlines ? DOC_MOVEREDLINES : DOC_MOVEDEFAULT ) );
    }
    else
    {
        SwPaM aPam( *pPam->GetPoint() );
        SetPaM( aPam );
        SwPosition aMvPos( aIdx, SwIndex( aIdx.GetNode().GetCntntNode(),
                                        nMvDestCntnt ));

        DelFtn( aPam );
        RemoveIdxFromRange( aPam, FALSE );

        aIdx = aPam.Start()->nNode;
        BOOL bJoinTxt = aIdx.GetNode().IsTxtNode();

        aIdx--;
        rDoc.Move( aPam, aMvPos );

        if( nSttNode != nEndNode && bJoinTxt )
        {
            aIdx++;
            SwTxtNode * pTxtNd = aIdx.GetNode().GetTxtNode();
            if( pTxtNd && pTxtNd->CanJoinNext() )
            {
                {
                    RemoveIdxRel( aIdx.GetIndex() + 1, SwPosition( aIdx,
                            SwIndex( pTxtNd, pTxtNd->GetTxt().Len() ) ) );
                }
                pTxtNd->JoinNext();
            }
        }
        *pPam->GetPoint() = *aPam.GetPoint();
        pPam->SetMark();
        *pPam->GetMark() = *aPam.GetMark();
    }
}

void SwUndoMove::DelFtn( const SwPaM& rRange )
{
    // wird aus dem CntntBereich in den Sonderbereich verschoben ?
    SwDoc* pDoc = rRange.GetDoc();
    ULONG nCntntStt = pDoc->GetNodes().GetEndOfAutotext().GetIndex();
    if( nMvDestNode < nCntntStt &&
        rRange.GetPoint()->nNode.GetIndex() >= nCntntStt )
    {
        // loesche alle Fussnoten. Diese sind dort nicht erwuenscht.
        DelCntntIndex( *rRange.GetMark(), *rRange.GetPoint(),
                            SwUndoSaveCntnt::DELCNT_FTN );

        if( pHistory && !pHistory->Count() )
            delete pHistory, pHistory = 0;
    }
}

void SwUndoMove::AddTblMrgFlyHstry( SwHistory& rHstr )
{
    if( !pHistory )
        pHistory = new SwHistory;

    USHORT nInsPos = nFtnStt;
    nFtnStt += rHstr.Count();
    pHistory->Move( nInsPos, &rHstr );
}

<commit_msg>INTEGRATION: CWS ooo19126 (1.4.226); FILE MERGED 2005/09/05 13:41:29 rt 1.4.226.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: unmove.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 05:20:43 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#pragma hdrstop

#ifndef _DOC_HXX
#include <doc.hxx>
#endif
#ifndef _PAM_HXX
#include <pam.hxx>
#endif
#ifndef _SWUNDO_HXX
#include <swundo.hxx>           // fuer die UndoIds
#endif
#ifndef _NDTXT_HXX
#include <ndtxt.hxx>
#endif
#ifndef _UNDOBJ_HXX
#include <undobj.hxx>
#endif
#ifndef _ROLBCK_HXX
#include <rolbck.hxx>
#endif

inline SwDoc& SwUndoIter::GetDoc() const { return *pAktPam->GetDoc(); }

// MOVE

SwUndoMove::SwUndoMove( const SwPaM& rRange, const SwPosition& rMvPos )
    : SwUndo( UNDO_MOVE ), SwUndRng( rRange ),
    nMvDestNode( rMvPos.nNode.GetIndex() ),
    nMvDestCntnt( rMvPos.nContent.GetIndex() ),
    bMoveRedlines( false )
{
    bMoveRange = bJoinNext = bJoinPrev = FALSE;

    // StartNode vorm loeschen von Fussnoten besorgen!
    SwDoc* pDoc = rRange.GetDoc();
    SwTxtNode* pTxtNd = pDoc->GetNodes()[ nSttNode ]->GetTxtNode();
    SwTxtNode* pEndTxtNd = pDoc->GetNodes()[ nEndNode ]->GetTxtNode();

    pHistory = new SwHistory;

    if( pTxtNd )
    {
        pHistory->Add( pTxtNd->GetTxtColl(), nSttNode, ND_TEXTNODE );
        if( pTxtNd->GetpSwpHints() )
            pHistory->CopyAttr( pTxtNd->GetpSwpHints(), nSttNode,
                                0, pTxtNd->GetTxt().Len(), FALSE );
        if( pTxtNd->GetpSwAttrSet() )
            pHistory->CopyFmtAttr( *pTxtNd->GetpSwAttrSet(), nSttNode );
    }
    if( pEndTxtNd && pEndTxtNd != pTxtNd )
    {
        pHistory->Add( pEndTxtNd->GetTxtColl(), nEndNode, ND_TEXTNODE );
        if( pEndTxtNd->GetpSwpHints() )
            pHistory->CopyAttr( pEndTxtNd->GetpSwpHints(), nEndNode,
                                0, pEndTxtNd->GetTxt().Len(), FALSE );
        if( pEndTxtNd->GetpSwAttrSet() )
            pHistory->CopyFmtAttr( *pEndTxtNd->GetpSwAttrSet(), nEndNode );
    }

    if( 0 != (pTxtNd = rRange.GetDoc()->GetNodes()[ rMvPos.nNode ]->GetTxtNode() ))
    {
        pHistory->Add( pTxtNd->GetTxtColl(), nMvDestNode, ND_TEXTNODE );
        if( pTxtNd->GetpSwpHints() )
            pHistory->CopyAttr( pTxtNd->GetpSwpHints(), nMvDestNode,
                                0, pTxtNd->GetTxt().Len(), FALSE );
        if( pTxtNd->GetpSwAttrSet() )
            pHistory->CopyFmtAttr( *pTxtNd->GetpSwAttrSet(), nMvDestNode );
    }

    nFtnStt = pHistory->Count();
    DelFtn( rRange );

    if( pHistory && !pHistory->Count() )
        DELETEZ( pHistory );
}

SwUndoMove::SwUndoMove( SwDoc* pDoc, const SwNodeRange& rRg,
                        const SwNodeIndex& rMvPos )
    : SwUndo( UNDO_MOVE ),
    nMvDestNode( rMvPos.GetIndex() ),
    bMoveRedlines( false )
{
    bMoveRange = TRUE;
    bJoinNext = bJoinPrev = FALSE;

    nSttCntnt = nEndCntnt = nMvDestCntnt = STRING_MAXLEN;

    nSttNode = rRg.aStart.GetIndex();
    nEndNode = rRg.aEnd.GetIndex();

//  DelFtn( rRange );

    // wird aus dem CntntBereich in den Sonderbereich verschoben ?
    ULONG nCntntStt = pDoc->GetNodes().GetEndOfAutotext().GetIndex();
    if( nMvDestNode < nCntntStt && rRg.aStart.GetIndex() > nCntntStt )
    {
        // loesche alle Fussnoten. Diese sind dort nicht erwuenscht.
        SwPosition aPtPos( rRg.aEnd );
        SwCntntNode* pCNd = rRg.aEnd.GetNode().GetCntntNode();
        if( pCNd )
            aPtPos.nContent.Assign( pCNd, pCNd->Len() );
        SwPosition aMkPos( rRg.aStart );
        if( 0 != ( pCNd = aMkPos.nNode.GetNode().GetCntntNode() ))
            aMkPos.nContent.Assign( pCNd, 0 );

        DelCntntIndex( aMkPos, aPtPos, SwUndoSaveCntnt::DELCNT_FTN );

        if( pHistory && !pHistory->Count() )
            DELETEZ( pHistory );
    }

    nFtnStt = 0;
}

void SwUndoMove::SetDestRange( const SwPaM& rRange,
                                const SwPosition& rInsPos,
                                BOOL bJoin, BOOL bCorrPam )
{
    const SwPosition *pStt = rRange.Start(),
                    *pEnd = rRange.GetPoint() == pStt
                        ? rRange.GetMark()
                        : rRange.GetPoint();

    nDestSttNode    = pStt->nNode.GetIndex();
    nDestSttCntnt   = pStt->nContent.GetIndex();
    nDestEndNode    = pEnd->nNode.GetIndex();
    nDestEndCntnt   = pEnd->nContent.GetIndex();

    nInsPosNode     = rInsPos.nNode.GetIndex();
    nInsPosCntnt    = rInsPos.nContent.GetIndex();

    if( bCorrPam )
    {
        nDestSttNode--;
        nDestEndNode--;
    }

    bJoinNext = nDestSttNode != nDestEndNode &&
                pStt->nNode.GetNode().GetTxtNode() &&
                pEnd->nNode.GetNode().GetTxtNode();
    bJoinPrev = bJoin;
}

void SwUndoMove::SetDestRange( const SwNodeIndex& rStt,
                                const SwNodeIndex& rEnd,
                                const SwNodeIndex& rInsPos )
{
    nDestSttNode = rStt.GetIndex();
    nDestEndNode = rEnd.GetIndex();
    if( nDestSttNode > nDestEndNode )
    {
        nDestSttNode = nDestEndNode;
        nDestEndNode = rStt.GetIndex();
    }
    nInsPosNode  = rInsPos.GetIndex();

    nDestSttCntnt = nDestEndCntnt = nInsPosCntnt = STRING_MAXLEN;
}

void SwUndoMove::Undo( SwUndoIter& rUndoIter )
{
    SwDoc* pDoc = &rUndoIter.GetDoc();
    BOOL bUndo = pDoc->DoesUndo();
    pDoc->DoUndo( FALSE );

    // Block, damit aus diesem gesprungen werden kann
    do {
        // erzeuge aus den Werten die Insert-Position und den Bereich
        SwNodeIndex aIdx( pDoc->GetNodes(), nDestSttNode );

        if( bMoveRange )
        {
            // nur ein Move mit SwRange
            SwNodeRange aRg( aIdx, aIdx );
            aRg.aEnd = nDestEndNode;
            aIdx = nInsPosNode;
            if( !pDoc->Move( aRg, aIdx ) )
                break;
        }
        else
        {
            SwPaM aPam( aIdx.GetNode(), nDestSttCntnt,
                        *pDoc->GetNodes()[ nDestEndNode ], nDestEndCntnt );

            // #i17764# if redlines are to be moved, we may not remove them before
            //          pDoc->Move gets a chance to handle them
            if( ! bMoveRedlines )
                RemoveIdxFromRange( aPam, FALSE );

            SwPosition aPos( *pDoc->GetNodes()[ nInsPosNode] );
            SwCntntNode* pCNd = aPos.nNode.GetNode().GetCntntNode();
            aPos.nContent.Assign( pCNd, nInsPosCntnt );

            if( pCNd->GetpSwAttrSet() )
                pCNd->ResetAllAttr();

            if( pCNd->IsTxtNode() && ((SwTxtNode*)pCNd)->GetpSwpHints() )
                ((SwTxtNode*)pCNd)->ClearSwpHintsArr( FALSE, FALSE );

            // an der InsertPos erstmal alle Attribute entfernen,
            if( !pDoc->Move( aPam, aPos, ( bMoveRedlines ? DOC_MOVEREDLINES : DOC_MOVEDEFAULT ) ) )
                break;

            aPam.Exchange();
            aPam.DeleteMark();
//          pDoc->ResetAttr( aPam, FALSE );
            if( aPam.GetNode()->IsCntntNode() )
                aPam.GetNode()->GetCntntNode()->ResetAllAttr();
            // der Pam wird jetzt aufgegeben.
        }

        SwTxtNode* pTxtNd = aIdx.GetNode().GetTxtNode();
        if( bJoinNext )
        {
            {
                RemoveIdxRel( aIdx.GetIndex() + 1, SwPosition( aIdx,
                        SwIndex( pTxtNd, pTxtNd->GetTxt().Len() ) ) );
            }
            // sind keine Pams mehr im naechsten TextNode
            pTxtNd->JoinNext();
        }

        if( bJoinPrev && pTxtNd->CanJoinPrev( &aIdx ) )
        {
            // ?? sind keine Pams mehr im naechsten TextNode ??
            pTxtNd = aIdx.GetNode().GetTxtNode();
            {
                RemoveIdxRel( aIdx.GetIndex() + 1, SwPosition( aIdx,
                        SwIndex( pTxtNd, pTxtNd->GetTxt().Len() ) ) );
            }
            pTxtNd->JoinNext();
        }

    } while( FALSE );

    if( pHistory )
    {
        if( nFtnStt != pHistory->Count() )
            pHistory->Rollback( pDoc, nFtnStt );
        pHistory->TmpRollback( pDoc, 0 );
        pHistory->SetTmpEnd( pHistory->Count() );
    }

    pDoc->DoUndo( bUndo );

    // setze noch den Cursor auf den Undo-Bereich
    if( !bMoveRange )
        SetPaM( rUndoIter );
}

void SwUndoMove::Redo( SwUndoIter& rUndoIter )
{
    SwPaM* pPam = rUndoIter.pAktPam;
    SwDoc& rDoc = *pPam->GetDoc();

    SwNodes& rNds = rDoc.GetNodes();
    SwNodeIndex aIdx( rNds, nMvDestNode );

    if( bMoveRange )
    {
        // nur ein Move mit SwRange
        SwNodeRange aRg( rNds, nSttNode, rNds, nEndNode );
        rDoc.Move( aRg, aIdx, ( bMoveRedlines ? DOC_MOVEREDLINES : DOC_MOVEDEFAULT ) );
    }
    else
    {
        SwPaM aPam( *pPam->GetPoint() );
        SetPaM( aPam );
        SwPosition aMvPos( aIdx, SwIndex( aIdx.GetNode().GetCntntNode(),
                                        nMvDestCntnt ));

        DelFtn( aPam );
        RemoveIdxFromRange( aPam, FALSE );

        aIdx = aPam.Start()->nNode;
        BOOL bJoinTxt = aIdx.GetNode().IsTxtNode();

        aIdx--;
        rDoc.Move( aPam, aMvPos );

        if( nSttNode != nEndNode && bJoinTxt )
        {
            aIdx++;
            SwTxtNode * pTxtNd = aIdx.GetNode().GetTxtNode();
            if( pTxtNd && pTxtNd->CanJoinNext() )
            {
                {
                    RemoveIdxRel( aIdx.GetIndex() + 1, SwPosition( aIdx,
                            SwIndex( pTxtNd, pTxtNd->GetTxt().Len() ) ) );
                }
                pTxtNd->JoinNext();
            }
        }
        *pPam->GetPoint() = *aPam.GetPoint();
        pPam->SetMark();
        *pPam->GetMark() = *aPam.GetMark();
    }
}

void SwUndoMove::DelFtn( const SwPaM& rRange )
{
    // wird aus dem CntntBereich in den Sonderbereich verschoben ?
    SwDoc* pDoc = rRange.GetDoc();
    ULONG nCntntStt = pDoc->GetNodes().GetEndOfAutotext().GetIndex();
    if( nMvDestNode < nCntntStt &&
        rRange.GetPoint()->nNode.GetIndex() >= nCntntStt )
    {
        // loesche alle Fussnoten. Diese sind dort nicht erwuenscht.
        DelCntntIndex( *rRange.GetMark(), *rRange.GetPoint(),
                            SwUndoSaveCntnt::DELCNT_FTN );

        if( pHistory && !pHistory->Count() )
            delete pHistory, pHistory = 0;
    }
}

void SwUndoMove::AddTblMrgFlyHstry( SwHistory& rHstr )
{
    if( !pHistory )
        pHistory = new SwHistory;

    USHORT nInsPos = nFtnStt;
    nFtnStt += rHstr.Count();
    pHistory->Move( nInsPos, &rHstr );
}

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: multmrk.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: rt $ $Date: 2004-08-23 09:05:25 $
 *
 *  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 SW_DLLIMPLEMENTATION
#undef SW_DLLIMPLEMENTATION
#endif

#pragma hdrstop

#include "swtypes.hxx"

#include "multmrk.hxx"
#include "toxmgr.hxx"

#include "index.hrc"
#include "multmrk.hrc"

SwMultiTOXMarkDlg::SwMultiTOXMarkDlg( Window* pParent, SwTOXMgr& rTOXMgr ) :

    SvxStandardDialog(pParent, SW_RES(DLG_MULTMRK)),

    aEntryFT(this,  SW_RES(FT_ENTRY)),
    aTextFT(this,   SW_RES(FT_TEXT)),
    aTOXFT(this,    SW_RES(FT_TOX)),
    aOkBT(this,     SW_RES(OK_BT)),
    aCancelBT(this, SW_RES(CANCEL_BT)),
    aTOXLB(this,    SW_RES(LB_TOX)),
    aTOXFL(this,    SW_RES(FL_TOX)),
    rMgr( rTOXMgr ),
    nPos(0)
{
    aTOXLB.SetSelectHdl(LINK(this, SwMultiTOXMarkDlg, SelectHdl));

    USHORT nSize = rMgr.GetTOXMarkCount();
    for(USHORT i=0; i < nSize; ++i)
        aTOXLB.InsertEntry(rMgr.GetTOXMark(i)->GetText());

    aTOXLB.SelectEntryPos(0);
    aTextFT.SetText(rMgr.GetTOXMark(0)->GetTOXType()->GetTypeName());

    FreeResource();
}

IMPL_LINK_INLINE_START( SwMultiTOXMarkDlg, SelectHdl, ListBox *, pBox )
{
    if(pBox->GetSelectEntryPos() != LISTBOX_ENTRY_NOTFOUND)
    {   SwTOXMark* pMark = rMgr.GetTOXMark(pBox->GetSelectEntryPos());
        aTextFT.SetText(pMark->GetTOXType()->GetTypeName());
        nPos = pBox->GetSelectEntryPos();
    }
    return 0;
}
IMPL_LINK_INLINE_END( SwMultiTOXMarkDlg, SelectHdl, ListBox *, pBox )

void SwMultiTOXMarkDlg::Apply()
{
    rMgr.SetCurTOXMark(nPos);
}

/*-----------------25.02.94 22:06-------------------
 dtor ueberladen
--------------------------------------------------*/

SwMultiTOXMarkDlg::~SwMultiTOXMarkDlg() {}

<commit_msg>INTEGRATION: CWS ooo19126 (1.5.596); FILE MERGED 2005/09/05 13:46:26 rt 1.5.596.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: multmrk.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 10:23:30 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifdef SW_DLLIMPLEMENTATION
#undef SW_DLLIMPLEMENTATION
#endif

#pragma hdrstop

#include "swtypes.hxx"

#include "multmrk.hxx"
#include "toxmgr.hxx"

#include "index.hrc"
#include "multmrk.hrc"

SwMultiTOXMarkDlg::SwMultiTOXMarkDlg( Window* pParent, SwTOXMgr& rTOXMgr ) :

    SvxStandardDialog(pParent, SW_RES(DLG_MULTMRK)),

    aEntryFT(this,  SW_RES(FT_ENTRY)),
    aTextFT(this,   SW_RES(FT_TEXT)),
    aTOXFT(this,    SW_RES(FT_TOX)),
    aOkBT(this,     SW_RES(OK_BT)),
    aCancelBT(this, SW_RES(CANCEL_BT)),
    aTOXLB(this,    SW_RES(LB_TOX)),
    aTOXFL(this,    SW_RES(FL_TOX)),
    rMgr( rTOXMgr ),
    nPos(0)
{
    aTOXLB.SetSelectHdl(LINK(this, SwMultiTOXMarkDlg, SelectHdl));

    USHORT nSize = rMgr.GetTOXMarkCount();
    for(USHORT i=0; i < nSize; ++i)
        aTOXLB.InsertEntry(rMgr.GetTOXMark(i)->GetText());

    aTOXLB.SelectEntryPos(0);
    aTextFT.SetText(rMgr.GetTOXMark(0)->GetTOXType()->GetTypeName());

    FreeResource();
}

IMPL_LINK_INLINE_START( SwMultiTOXMarkDlg, SelectHdl, ListBox *, pBox )
{
    if(pBox->GetSelectEntryPos() != LISTBOX_ENTRY_NOTFOUND)
    {   SwTOXMark* pMark = rMgr.GetTOXMark(pBox->GetSelectEntryPos());
        aTextFT.SetText(pMark->GetTOXType()->GetTypeName());
        nPos = pBox->GetSelectEntryPos();
    }
    return 0;
}
IMPL_LINK_INLINE_END( SwMultiTOXMarkDlg, SelectHdl, ListBox *, pBox )

void SwMultiTOXMarkDlg::Apply()
{
    rMgr.SetCurTOXMark(nPos);
}

/*-----------------25.02.94 22:06-------------------
 dtor ueberladen
--------------------------------------------------*/

SwMultiTOXMarkDlg::~SwMultiTOXMarkDlg() {}

<|endoftext|>


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

#ifndef _SFXTABDLG_HXX //autogen
#include <sfx2/tabdlg.hxx>
#endif
#ifndef _FIXED_HXX //autogen
#include <vcl/fixed.hxx>
#endif
#ifndef _IMAGEBTN_HXX //autogen
#include <vcl/imagebtn.hxx>
#endif
#ifndef _LSTBOX_HXX //autogen
#include <vcl/lstbox.hxx>
#endif

#ifndef _ACTCTRL_HXX
#include <actctrl.hxx>
#endif
#include "prcntfld.hxx"
#include "swtypes.hxx"

class SwTabCols;
class SwWrtShell;
class SwTableRep;

struct TColumn
{
    SwTwips nWidth;
    BOOL    bVisible;
};

class SwFormatTablePage : public SfxTabPage
{
    FixedLine        aOptionsFL;
    FixedText       aNameFT;
    TableNameEdit   aNameED;
    FixedText       aWidthFT;
    PercentField    aWidthMF;
    CheckBox        aRelWidthCB;

    FixedLine        aPosFL;
    RadioButton     aFullBtn;
    RadioButton     aLeftBtn;
    RadioButton     aFromLeftBtn;
    RadioButton     aRightBtn;
    RadioButton     aCenterBtn;
    RadioButton     aFreeBtn;

    FixedLine       aDistFL;
    FixedText       aLeftFT;
    PercentField    aLeftMF;
    FixedText       aRightFT;
    PercentField    aRightMF;
    FixedText       aTopFT;
    MetricField     aTopMF;
    FixedText       aBottomFT;
    MetricField     aBottomMF;

    FixedLine       aPropertiesFL;
    FixedText       aTextDirectionFT;
    ListBox         aTextDirectionLB;

    SwTableRep*     pTblData;
    SwTwips         nSaveWidth;
    SwTwips         nMinTableWidth;
    USHORT          nOldAlign;
    BOOL            bModified;
    BOOL            bFull:1;
    BOOL            bHtmlMode : 1;

    void        Init();
    void        ModifyHdl( Edit* pEdit );

    DECL_LINK( AutoClickHdl, CheckBox * );
    DECL_LINK( RelWidthClickHdl, CheckBox * );
    DECL_LINK( RightModifyHdl, MetricField * );
    DECL_LINK( UpDownLoseFocusHdl, MetricField * );

public:
    SwFormatTablePage( Window* pParent, const SfxItemSet& rSet );

    static SfxTabPage*  Create( Window* pParent, const SfxItemSet& rAttrSet);
    virtual BOOL        FillItemSet( SfxItemSet& rSet );
    virtual void        Reset( const SfxItemSet& rSet );
    virtual void        ActivatePage( const SfxItemSet& rSet );
    virtual int         DeactivatePage( SfxItemSet* pSet = 0 );
};

/*-------------------------------------------------------
 TabPage Format/Tabelle/Spalten
--------------------------------------------------------- */
#define MET_FIELDS 6 //Anzahl der verwendeten MetricFields

class SwTableColumnPage : public SfxTabPage
{
    CheckBox        aModifyTableCB;
    CheckBox        aProportionalCB;
    FixedText       aSpaceFT;
    MetricField     aSpaceED;

    ImageButton     aUpBtn;
    FixedText       aFT1;
    PercentField    aMF1;
    FixedText       aFT2;
    PercentField    aMF2;
    FixedText       aFT3;
    PercentField    aMF3;
    FixedText       aFT4;
    PercentField    aMF4;
    FixedText       aFT5;
    PercentField    aMF5;
    FixedText       aFT6;
    PercentField    aMF6;
    ImageButton     aDownBtn;
    FixedLine        aColFL;

    SwTableRep*     pTblData;
    PercentField*   pFieldArr[MET_FIELDS];
    FixedText*      pTextArr[MET_FIELDS];
    SwTwips         nTableWidth;
    SwTwips         nMinWidth;
    USHORT          nNoOfCols;
    USHORT          nNoOfVisibleCols;
    //Breite merken, wenn auf autom. Ausrichtung gestellt wird
    USHORT          aValueTbl[MET_FIELDS];//primaere Zuordnung der MetricFields
    BOOL            bModified:1;
    BOOL            bModifyTbl:1;
    BOOL            bPercentMode:1;

    void        Init(BOOL bWeb);
    DECL_LINK( AutoClickHdl, CheckBox * );
    void        ModifyHdl( PercentField* pEdit );
    DECL_LINK( UpHdl, PercentField * );
    DECL_LINK( DownHdl, PercentField * );
    DECL_LINK( LoseFocusHdl, PercentField * );
    DECL_LINK( ModeHdl, CheckBox * );
    void        UpdateCols( USHORT nAktPos );
    SwTwips     GetVisibleWidth(USHORT nPos);
    void        SetVisibleWidth(USHORT nPos, SwTwips nNewWidth);
public:
    SwTableColumnPage( Window* pParent, const SfxItemSet& rSet );
    ~SwTableColumnPage();

    static SfxTabPage*  Create( Window* pParent, const SfxItemSet& rAttrSet);
    virtual BOOL        FillItemSet( SfxItemSet& rSet );
    virtual void        Reset( const SfxItemSet& rSet );
    virtual void        ActivatePage( const SfxItemSet& rSet );
    virtual int         DeactivatePage( SfxItemSet* pSet = 0 );

};

/*-----------------12.12.96 11.48-------------------
        Textflu
--------------------------------------------------*/
class SwTextFlowPage : public SfxTabPage
{
    FixedLine        aFlowFL;
    CheckBox        aPgBrkCB;
    RadioButton     aPgBrkRB;
    RadioButton     aColBrkRB;
    RadioButton     aPgBrkBeforeRB;
    RadioButton     aPgBrkAfterRB;
    CheckBox        aPageCollCB;
    ListBox         aPageCollLB;
    FixedText       aPageNoFT;
    NumericField    aPageNoNF;
    CheckBox        aSplitCB;
    CheckBox        aKeepCB;
    CheckBox        aHeadLineCB;

    FixedLine        aVertOrientFL;
    RadioButton     aTopRB;
    RadioButton     aCenterRB;
    RadioButton     aBottomRB;

    SwWrtShell*     pShell;

    BOOL            bPageBreak;
    BOOL            bHtmlMode;

    DECL_LINK( PageBreakHdl_Impl, CheckBox* );
    DECL_LINK( ApplyCollClickHdl_Impl, CheckBox* );
    DECL_LINK( PageBreakPosHdl_Impl, RadioButton* );
    DECL_LINK( PageBreakTypeHdl_Impl, RadioButton* );

    SwTextFlowPage( Window* pParent, const SfxItemSet& rSet );
    ~SwTextFlowPage();

public:
    static SfxTabPage*  Create( Window* pParent, const SfxItemSet& rAttrSet);
    virtual BOOL        FillItemSet( SfxItemSet& rSet );
    virtual void        Reset( const SfxItemSet& rSet );

    void                SetShell(SwWrtShell* pSh);

    void                DisablePageBreak();
};

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

#ifndef _SFXTABDLG_HXX //autogen
#include <sfx2/tabdlg.hxx>
#endif
#ifndef _FIXED_HXX //autogen
#include <vcl/fixed.hxx>
#endif
#ifndef _IMAGEBTN_HXX //autogen
#include <vcl/imagebtn.hxx>
#endif
#ifndef _LSTBOX_HXX //autogen
#include <vcl/lstbox.hxx>
#endif

#ifndef _ACTCTRL_HXX
#include <actctrl.hxx>
#endif
#include "prcntfld.hxx"
#include "swtypes.hxx"

class SwTabCols;
class SwWrtShell;
class SwTableRep;

struct TColumn
{
    SwTwips nWidth;
    BOOL    bVisible;
};

class SwFormatTablePage : public SfxTabPage
{
    FixedLine        aOptionsFL;
    FixedText       aNameFT;
    TableNameEdit   aNameED;
    FixedText       aWidthFT;
    PercentField    aWidthMF;
    CheckBox        aRelWidthCB;

    FixedLine        aPosFL;
    RadioButton     aFullBtn;
    RadioButton     aLeftBtn;
    RadioButton     aFromLeftBtn;
    RadioButton     aRightBtn;
    RadioButton     aCenterBtn;
    RadioButton     aFreeBtn;

    FixedLine       aDistFL;
    FixedText       aLeftFT;
    PercentField    aLeftMF;
    FixedText       aRightFT;
    PercentField    aRightMF;
    FixedText       aTopFT;
    MetricField     aTopMF;
    FixedText       aBottomFT;
    MetricField     aBottomMF;

    FixedLine       aPropertiesFL;
    FixedText       aTextDirectionFT;
    ListBox         aTextDirectionLB;

    SwTableRep*     pTblData;
    SwTwips         nSaveWidth;
    SwTwips         nMinTableWidth;
    USHORT          nOldAlign;
    BOOL            bModified;
    BOOL            bFull:1;
    BOOL            bHtmlMode : 1;

    void        Init();
    void        ModifyHdl( Edit* pEdit );

    DECL_LINK( AutoClickHdl, CheckBox * );
    DECL_LINK( RelWidthClickHdl, CheckBox * );
    DECL_LINK( RightModifyHdl, MetricField * );
    DECL_LINK( UpDownLoseFocusHdl, MetricField * );

public:
    SwFormatTablePage( Window* pParent, const SfxItemSet& rSet );

    static SfxTabPage*  Create( Window* pParent, const SfxItemSet& rAttrSet);
    virtual BOOL        FillItemSet( SfxItemSet& rSet );
    virtual void        Reset( const SfxItemSet& rSet );
    virtual void        ActivatePage( const SfxItemSet& rSet );
    virtual int         DeactivatePage( SfxItemSet* pSet = 0 );
};

/*-------------------------------------------------------
 TabPage Format/Tabelle/Spalten
--------------------------------------------------------- */
#define MET_FIELDS 6 //Anzahl der verwendeten MetricFields

class SwTableColumnPage : public SfxTabPage
{
    CheckBox        aModifyTableCB;
    CheckBox        aProportionalCB;
    FixedText       aSpaceFT;
    MetricField     aSpaceED;

    ImageButton     aUpBtn;
    FixedText       aFT1;
    PercentField    aMF1;
    FixedText       aFT2;
    PercentField    aMF2;
    FixedText       aFT3;
    PercentField    aMF3;
    FixedText       aFT4;
    PercentField    aMF4;
    FixedText       aFT5;
    PercentField    aMF5;
    FixedText       aFT6;
    PercentField    aMF6;
    ImageButton     aDownBtn;
    FixedLine        aColFL;

    SwTableRep*     pTblData;
    PercentField*   pFieldArr[MET_FIELDS];
    FixedText*      pTextArr[MET_FIELDS];
    SwTwips         nTableWidth;
    SwTwips         nMinWidth;
    USHORT          nNoOfCols;
    USHORT          nNoOfVisibleCols;
    //Breite merken, wenn auf autom. Ausrichtung gestellt wird
    USHORT          aValueTbl[MET_FIELDS];//primaere Zuordnung der MetricFields
    BOOL            bModified:1;
    BOOL            bModifyTbl:1;
    BOOL            bPercentMode:1;

    void        Init(BOOL bWeb);
    DECL_LINK( AutoClickHdl, CheckBox * );
    void        ModifyHdl( PercentField* pEdit );
    DECL_LINK( UpHdl, PercentField * );
    DECL_LINK( DownHdl, PercentField * );
    DECL_LINK( LoseFocusHdl, PercentField * );
    DECL_LINK( ModeHdl, CheckBox * );
    void        UpdateCols( USHORT nAktPos );
    SwTwips     GetVisibleWidth(USHORT nPos);
    void        SetVisibleWidth(USHORT nPos, SwTwips nNewWidth);
public:
    SwTableColumnPage( Window* pParent, const SfxItemSet& rSet );
    ~SwTableColumnPage();

    static SfxTabPage*  Create( Window* pParent, const SfxItemSet& rAttrSet);
    virtual BOOL        FillItemSet( SfxItemSet& rSet );
    virtual void        Reset( const SfxItemSet& rSet );
    virtual void        ActivatePage( const SfxItemSet& rSet );
    virtual int         DeactivatePage( SfxItemSet* pSet = 0 );

};

/*-----------------12.12.96 11.48-------------------
        Textflu
--------------------------------------------------*/
class SwTextFlowPage : public SfxTabPage
{
    FixedLine        aFlowFL;
    CheckBox        aPgBrkCB;
    RadioButton     aPgBrkRB;
    RadioButton     aColBrkRB;
    RadioButton     aPgBrkBeforeRB;
    RadioButton     aPgBrkAfterRB;
    CheckBox        aPageCollCB;
    ListBox         aPageCollLB;
    FixedText       aPageNoFT;
    NumericField    aPageNoNF;
    CheckBox        aSplitCB;
    TriStateBox     aSplitRowCB;
    CheckBox        aKeepCB;
    CheckBox        aHeadLineCB;

    FixedLine        aVertOrientFL;
    RadioButton     aTopRB;
    RadioButton     aCenterRB;
    RadioButton     aBottomRB;

    SwWrtShell*     pShell;

    BOOL            bPageBreak;
    BOOL            bHtmlMode;

    DECL_LINK( PageBreakHdl_Impl, CheckBox* );
    DECL_LINK( ApplyCollClickHdl_Impl, CheckBox* );
    DECL_LINK( PageBreakPosHdl_Impl, RadioButton* );
    DECL_LINK( PageBreakTypeHdl_Impl, RadioButton* );
    DECL_LINK( SplitHdl_Impl, CheckBox* );
    DECL_LINK( SplitRowHdl_Impl, TriStateBox* );

    SwTextFlowPage( Window* pParent, const SfxItemSet& rSet );
    ~SwTextFlowPage();

public:
    static SfxTabPage*  Create( Window* pParent, const SfxItemSet& rAttrSet);
    virtual BOOL        FillItemSet( SfxItemSet& rSet );
    virtual void        Reset( const SfxItemSet& rSet );

    void                SetShell(SwWrtShell* pSh);

    void                DisablePageBreak();
};

#endif
<|endoftext|>


<commit_before>#include "Makefile.hpp"

#include <configure/BuildGraph.hpp>
#include <configure/Build.hpp>
#include <configure/Command.hpp>
#include <configure/Filesystem.hpp>
#include <configure/Graph.hpp>
#include <configure/quote.hpp>
#include <configure/utils/path.hpp>
#include <configure/PropertyMap.hpp>
#include <configure/log.hpp>
#include <configure/Rule.hpp>
#include <configure/ShellCommand.hpp>
#include <configure/error.hpp>

#include <boost/algorithm/string/join.hpp>
#include <boost/filesystem.hpp>

#include <fstream>
#include <unordered_set>

namespace configure { namespace generators {

	Makefile::Makefile(Build& build,
	                   path_t project_directory,
	                   path_t configure_exe,
	                   char const* name)
		: Generator(
			build,
			std::move(project_directory),
			std::move(configure_exe),
			(name == nullptr ? Makefile::name() : name)
		)
	{}

	static std::string relative_node_path(Build& b, Node& n)
	{ return n.relative_path(b.directory()).string(); }

	static std::string absolute_node_path(Build&, Node& n)
	{ return n.path().string(); }

	void Makefile::prepare()
	{
		BuildGraph const& bg = _build.build_graph();
		Graph const& g = bg.graph();

		{
			Rule regen;
			regen.add_target(_build.target_node("Makefile"));
			for (auto& project_dir: _build.project_stack())
			{
				auto p = Build::find_project_file(project_dir);
				auto& n = _build.source_node(p);
				regen.add_source(n);
			}
			ShellCommand regen_cmd;
			regen_cmd.append(
				_build.target_node(_configure_exe),
				"--project", _build.project_stack().at(0),
				_build.directory()
			);
			regen.add_shell_command(std::move(regen_cmd));
			//ShellCommand make_cmd;
			//make_cmd.extend(this->build_command("all"));
			//regen.add_shell_command(std::move(make_cmd));
			_build.add_rule(std::move(regen));
		}

		for (auto vertex_range = boost::vertices(g);
		     vertex_range.first != vertex_range.second;
		     ++vertex_range.first)
		{
			auto vertex = *vertex_range.first;
			auto& node = bg.node(vertex);

			if (node->is_virtual())
			{
				if (node->name().empty())
					continue;
				_virtual_nodes.push_back(node);
			}
			else
			{
				// Check for nodes that are not generated by us (no inputs).
				// (this does not apply to virtual nodes, that always
				// considered as targets).
				auto in_edge_range = boost::in_edges(vertex, g);
				if (in_edge_range.first == in_edge_range.second)
				{
					_sources.push_back(node);
					continue;
				}
			}

			// At this point we know that the node is a target.
			_targets.push_back(node);

			auto out_edge_range = boost::out_edges(vertex, g);
			if (out_edge_range.first == out_edge_range.second)
			{
				// Nothing depends on this node, this target is final.
				if (!node->is_virtual())
					_final_targets.push_back(node);
			}
			else
			{
				// Something depends on this Node, it is a also a source.
				if (!node->is_virtual())
					_sources.push_back(node);

				// The node is still considered final if the root node depends
				// on it.
				if (bg.has_link(*_build.root_node(), *node))
					_final_targets.push_back(node);
			}
		}

		for (auto& node: _sources)
		{
			if (!node->is_file() || !node->has_property("language"))
				continue;

			auto& lang = node->property<std::string>("language");
			if (lang == "c" || lang == "c++")
			{
				auto include_directories = node->property<std::vector<boost::filesystem::path>>("include_directories");
				NodePtr first_target;
				for (auto out_edge_range = boost::out_edges(node->index, g);
					 out_edge_range.first != out_edge_range.second;
					 ++out_edge_range.first)
				{
					first_target = bg.node(boost::target(*out_edge_range.first, g));
					break;
				}
				if (first_target == nullptr)
				{
					log::warning("Ignore implicit dependencies for",
					             node->string(), ", no target node found...");
					continue;
				}

				auto& target = _build.target_node(
					first_target->relative_path(_build.directory()).string() + ".mk"
				);
				_includes.push_back(target);
				ShellCommand cmd;
				cmd.append(
					_configure_exe, "-E" , "c-header-dependencies",
					target, node
				);
				for (auto out_edge_range = boost::out_edges(node->index, g);
					 out_edge_range.first != out_edge_range.second;
					 ++out_edge_range.first)
					cmd.append(bg.node(boost::target(*out_edge_range.first, g)));
				cmd.append("--");
				for (auto& dir: include_directories)
				{
					if (utils::starts_with(dir, _project_directory))
						cmd.append(_build.directory_node(dir));
				}
				_build.add_rule(
					Rule()
						.add_source(node)
						.add_target(target)
						.add_shell_command(std::move(cmd))
				);
			}
		}

		// We still need to add dependencies to the final targets
		for (auto& node: _includes)
			_targets.push_back(node);
	}

	namespace {

		struct RelativePathShellFormatter
			: public ShellFormatter
		{
			boost::filesystem::path const& _build_dir;
			boost::filesystem::path const& _project_dir;

			RelativePathShellFormatter(Build& build,
			                           boost::filesystem::path const& project_dir)
				: ShellFormatter(build)
				, _build_dir(build.directory())
				, _project_dir(project_dir)
			{}

			std::string
			operator()(ShellCommand const& command,
				       boost::filesystem::path const& value) const override
			{
				if (command.has_working_directory() &&
				    utils::starts_with(value, _project_dir))
					return utils::relative_path(
					  value, command.working_directory()).string();
				if (utils::starts_with(value, _project_dir))
					return utils::relative_path(value, _build_dir).string();
				return value.string();
			}
		};

	}

	void Makefile::generate() const
	{
		bool use_relpath = _build.option<bool>(
		    "GENERATOR_" + std::string(_name) + "_USE_RELATIVE_PATH",
		    std::string(_name) + " generator uses relative path",
		    this->use_relative_path()
		);
		std::unique_ptr<ShellFormatter> formatter;
		if (use_relpath)
			formatter = std::unique_ptr<ShellFormatter>(
				new RelativePathShellFormatter(_build, _project_directory)
			);
		else
			formatter = std::unique_ptr<ShellFormatter>(new ShellFormatter(_build));

		std::string (*node_path)(Build&, Node&);
		if (use_relpath)
			node_path = &relative_node_path;
		else
			node_path = &absolute_node_path;

		auto& makefile_node = _build.target_node("Makefile");
		std::ofstream out(makefile_node->path().string());
		out << "# Generated " << _name << std::endl;
		if (_name == "Makefile")
		{
			// This speed up the makefile
			out << "MAKEFLAGS += --no-builtin-rules" << std::endl;
			out << ".SUFFIXES:" << std::endl;
		}
		BuildGraph const& bg = _build.build_graph();
		Graph const& g = bg.graph();

		// Fill the "all" and ".PHONY" rules
		out << ".PHONY:" << std::endl;
		out << ".PHONY: all";
		for (auto node: _virtual_nodes)
			out << ' ' << node->name();
		out << "\n\n";

		if (!_final_targets.empty())
		{
			out << "all:";
			for (auto& node: _final_targets)
			{
				if (node->is_file())
					out << ' ' << node_path(_build, *node);
				else if (node->is_virtual() && !node->name().empty())
					out << ' ' << node->name();
			}
			out << "\n\n";

			out << "clean:\n";
			for (auto& node: _targets)
				if (node->is_file())
					out << '\t' << "rm -f " << node_path(_build, *node) << '\n';
			out << "\n";
		}

		auto generated_commands_property_name =
			std::string(this->name()) + "_GENERATED_COMMANDS";
		std::unordered_set<Node const*> to_delete;
		for (auto& node: _targets)
		{
			if (node->is_virtual())
				out << node->name() << ':';
			else
				out << node_path(_build, *node) << ':';

			auto in_edge_range = boost::in_edges(node->index, g);
			for (GraphTraits::in_edge_iterator i = in_edge_range.first;
			     i != in_edge_range.second; ++i)
			{
				auto node = bg.node(boost::source(*i, g)).get();
				if (node->is_file())
					out << ' ' << node_path(_build, *node);
				else if (node->is_virtual())
					out << ' ' << node->name();
			}
			out << std::endl;

			std::vector<std::string> command_strings;
			std::unordered_set<Command const*> seen_commands;
			for (; in_edge_range.first != in_edge_range.second;
			     ++in_edge_range.first)
			{
				auto& link = bg.link(*in_edge_range.first);
				Command const* cmd_ptr = &link.command();
				if (seen_commands.insert(cmd_ptr).second == false)
					continue;
				for (auto const& shell_command: cmd_ptr->shell_commands())
				{
					std::string wd;
					if (shell_command.has_working_directory())
					{
						ShellCommand chdir;
						chdir.append("cd", shell_command.working_directory());
						wd = this->dump_command(chdir.string(_build, link, *formatter)) + " && ";
					}
					std::string env;
					if (shell_command.has_env())
					{
						for (auto&& pair: shell_command.env())
							env += pair.first + "=" + pair.second + " ";
					}
					command_strings.push_back(
						wd + env + this->dump_command(
							shell_command.string(_build, link, *formatter)
						)
					);
					out << '\t' << command_strings.back() << std::endl;
				}
			}
			out << std::endl;
			if (node->is_file())
			{
				bool had_commands_property = node->has_property(
					generated_commands_property_name
				);
				node->set_property<std::string>(
					generated_commands_property_name,
					boost::join(command_strings, "\n")
				);
				if (had_commands_property &&
				    node != makefile_node &&
				    node->properties().dirty())
					to_delete.insert(node.get());
			}
		}

		for (auto node: to_delete)
		{
			log::verbose("Deleting node", node->string(), "(command line changed)");
			try {
				boost::filesystem::remove(node->path());
			} catch (...) {
				log::warning("Couldn't remove", node->string(), ":", error_string());
			}
		}
		this->include_dependencies(out, use_relpath);
	}

	void Makefile::include_dependencies(std::ostream& out, bool relative) const
	{
		if (relative)
			for (auto& node: _includes)
				out << "-include " << relative_node_path(_build, *node) << std::endl;
		else
			for (auto& node: _includes)
				out << "-include " << absolute_node_path(_build, *node) << std::endl;
	}

	std::string Makefile::dump_command(std::vector<std::string> const& cmd) const
	{
#ifdef _WIN32
		if (cmd.size() == 1)
		{
			// Workaroung a bug in GNU Make, when commands contain a double quote
			// they are spawned through CreateProcess() as 'sh -c \"COMMAND HERE\"'
			// when the argument does have any special character other than slash
			// and there is only one argument, quotes are left ...
			auto res = quote<CommandParser::make>(cmd);
			if (res[0] == '"' && res.back() == '"' )
			{
				res = res.substr(1, res.size() - 2);
			}
			return res;
		}
#endif
		return quote<CommandParser::make>(cmd);
	}

	bool Makefile::is_available(Build& build)
	{ return build.fs().which("make") != boost::none; }

	std::vector<std::string>
	Makefile::build_command(std::string const& target) const
	{
		return {
			"make", "-C", _build.directory().string(),
			target.empty() ? "all" : target
		};
	}

	bool Makefile::use_relative_path() const { return true; }
}}

<commit_msg>Fix build files removal condition (check only for command lines change.<commit_after>#include "Makefile.hpp"

#include <configure/BuildGraph.hpp>
#include <configure/Build.hpp>
#include <configure/Command.hpp>
#include <configure/Filesystem.hpp>
#include <configure/Graph.hpp>
#include <configure/quote.hpp>
#include <configure/utils/path.hpp>
#include <configure/PropertyMap.hpp>
#include <configure/log.hpp>
#include <configure/Rule.hpp>
#include <configure/ShellCommand.hpp>
#include <configure/error.hpp>

#include <boost/algorithm/string/join.hpp>
#include <boost/filesystem.hpp>

#include <fstream>
#include <unordered_set>

namespace configure { namespace generators {

	Makefile::Makefile(Build& build,
	                   path_t project_directory,
	                   path_t configure_exe,
	                   char const* name)
		: Generator(
			build,
			std::move(project_directory),
			std::move(configure_exe),
			(name == nullptr ? Makefile::name() : name)
		)
	{}

	static std::string relative_node_path(Build& b, Node& n)
	{ return n.relative_path(b.directory()).string(); }

	static std::string absolute_node_path(Build&, Node& n)
	{ return n.path().string(); }

	void Makefile::prepare()
	{
		BuildGraph const& bg = _build.build_graph();
		Graph const& g = bg.graph();

		{
			Rule regen;
			regen.add_target(_build.target_node("Makefile"));
			for (auto& project_dir: _build.project_stack())
			{
				auto p = Build::find_project_file(project_dir);
				auto& n = _build.source_node(p);
				regen.add_source(n);
			}
			ShellCommand regen_cmd;
			regen_cmd.append(
				_build.target_node(_configure_exe),
				"--project", _build.project_stack().at(0),
				_build.directory()
			);
			regen.add_shell_command(std::move(regen_cmd));
			//ShellCommand make_cmd;
			//make_cmd.extend(this->build_command("all"));
			//regen.add_shell_command(std::move(make_cmd));
			_build.add_rule(std::move(regen));
		}

		for (auto vertex_range = boost::vertices(g);
		     vertex_range.first != vertex_range.second;
		     ++vertex_range.first)
		{
			auto vertex = *vertex_range.first;
			auto& node = bg.node(vertex);

			if (node->is_virtual())
			{
				if (node->name().empty())
					continue;
				_virtual_nodes.push_back(node);
			}
			else
			{
				// Check for nodes that are not generated by us (no inputs).
				// (this does not apply to virtual nodes, that always
				// considered as targets).
				auto in_edge_range = boost::in_edges(vertex, g);
				if (in_edge_range.first == in_edge_range.second)
				{
					_sources.push_back(node);
					continue;
				}
			}

			// At this point we know that the node is a target.
			_targets.push_back(node);

			auto out_edge_range = boost::out_edges(vertex, g);
			if (out_edge_range.first == out_edge_range.second)
			{
				// Nothing depends on this node, this target is final.
				if (!node->is_virtual())
					_final_targets.push_back(node);
			}
			else
			{
				// Something depends on this Node, it is a also a source.
				if (!node->is_virtual())
					_sources.push_back(node);

				// The node is still considered final if the root node depends
				// on it.
				if (bg.has_link(*_build.root_node(), *node))
					_final_targets.push_back(node);
			}
		}

		for (auto& node: _sources)
		{
			if (!node->is_file() || !node->has_property("language"))
				continue;

			auto& lang = node->property<std::string>("language");
			if (lang == "c" || lang == "c++")
			{
				auto include_directories = node->property<std::vector<boost::filesystem::path>>("include_directories");
				NodePtr first_target;
				for (auto out_edge_range = boost::out_edges(node->index, g);
					 out_edge_range.first != out_edge_range.second;
					 ++out_edge_range.first)
				{
					first_target = bg.node(boost::target(*out_edge_range.first, g));
					break;
				}
				if (first_target == nullptr)
				{
					log::warning("Ignore implicit dependencies for",
					             node->string(), ", no target node found...");
					continue;
				}

				auto& target = _build.target_node(
					first_target->relative_path(_build.directory()).string() + ".mk"
				);
				_includes.push_back(target);
				ShellCommand cmd;
				cmd.append(
					_configure_exe, "-E" , "c-header-dependencies",
					target, node
				);
				for (auto out_edge_range = boost::out_edges(node->index, g);
					 out_edge_range.first != out_edge_range.second;
					 ++out_edge_range.first)
					cmd.append(bg.node(boost::target(*out_edge_range.first, g)));
				cmd.append("--");
				for (auto& dir: include_directories)
				{
					if (utils::starts_with(dir, _project_directory))
						cmd.append(_build.directory_node(dir));
				}
				_build.add_rule(
					Rule()
						.add_source(node)
						.add_target(target)
						.add_shell_command(std::move(cmd))
				);
			}
		}

		// We still need to add dependencies to the final targets
		for (auto& node: _includes)
			_targets.push_back(node);
	}

	namespace {

		struct RelativePathShellFormatter
			: public ShellFormatter
		{
			boost::filesystem::path const& _build_dir;
			boost::filesystem::path const& _project_dir;

			RelativePathShellFormatter(Build& build,
			                           boost::filesystem::path const& project_dir)
				: ShellFormatter(build)
				, _build_dir(build.directory())
				, _project_dir(project_dir)
			{}

			std::string
			operator()(ShellCommand const& command,
				       boost::filesystem::path const& value) const override
			{
				if (command.has_working_directory() &&
				    utils::starts_with(value, _project_dir))
					return utils::relative_path(
					  value, command.working_directory()).string();
				if (utils::starts_with(value, _project_dir))
					return utils::relative_path(value, _build_dir).string();
				return value.string();
			}
		};

	}

	void Makefile::generate() const
	{
		bool use_relpath = _build.option<bool>(
		    "GENERATOR_" + std::string(_name) + "_USE_RELATIVE_PATH",
		    std::string(_name) + " generator uses relative path",
		    this->use_relative_path()
		);
		std::unique_ptr<ShellFormatter> formatter;
		if (use_relpath)
			formatter = std::unique_ptr<ShellFormatter>(
				new RelativePathShellFormatter(_build, _project_directory)
			);
		else
			formatter = std::unique_ptr<ShellFormatter>(new ShellFormatter(_build));

		std::string (*node_path)(Build&, Node&);
		if (use_relpath)
			node_path = &relative_node_path;
		else
			node_path = &absolute_node_path;

		auto& makefile_node = _build.target_node("Makefile");
		std::ofstream out(makefile_node->path().string());
		out << "# Generated " << _name << std::endl;
		if (_name == "Makefile")
		{
			// This speed up the makefile
			out << "MAKEFLAGS += --no-builtin-rules" << std::endl;
			out << ".SUFFIXES:" << std::endl;
		}
		BuildGraph const& bg = _build.build_graph();
		Graph const& g = bg.graph();

		// Fill the "all" and ".PHONY" rules
		out << ".PHONY:" << std::endl;
		out << ".PHONY: all";
		for (auto node: _virtual_nodes)
			out << ' ' << node->name();
		out << "\n\n";

		if (!_final_targets.empty())
		{
			out << "all:";
			for (auto& node: _final_targets)
			{
				if (node->is_file())
					out << ' ' << node_path(_build, *node);
				else if (node->is_virtual() && !node->name().empty())
					out << ' ' << node->name();
			}
			out << "\n\n";

			out << "clean:\n";
			for (auto& node: _targets)
				if (node->is_file())
					out << '\t' << "rm -f " << node_path(_build, *node) << '\n';
			out << "\n";
		}

		auto generated_commands_property_name =
			std::string(this->name()) + "_GENERATED_COMMANDS";
		std::unordered_set<Node const*> to_delete;
		for (auto& node: _targets)
		{
			if (node->is_virtual())
				out << node->name() << ':';
			else
				out << node_path(_build, *node) << ':';

			auto in_edge_range = boost::in_edges(node->index, g);
			for (GraphTraits::in_edge_iterator i = in_edge_range.first;
			     i != in_edge_range.second; ++i)
			{
				auto node = bg.node(boost::source(*i, g)).get();
				if (node->is_file())
					out << ' ' << node_path(_build, *node);
				else if (node->is_virtual())
					out << ' ' << node->name();
			}
			out << std::endl;

			std::vector<std::string> command_strings;
			std::unordered_set<Command const*> seen_commands;
			for (; in_edge_range.first != in_edge_range.second;
			     ++in_edge_range.first)
			{
				auto& link = bg.link(*in_edge_range.first);
				Command const* cmd_ptr = &link.command();
				if (seen_commands.insert(cmd_ptr).second == false)
					continue;
				for (auto const& shell_command: cmd_ptr->shell_commands())
				{
					std::string wd;
					if (shell_command.has_working_directory())
					{
						ShellCommand chdir;
						chdir.append("cd", shell_command.working_directory());
						wd = this->dump_command(chdir.string(_build, link, *formatter)) + " && ";
					}
					std::string env;
					if (shell_command.has_env())
					{
						for (auto&& pair: shell_command.env())
							env += pair.first + "=" + pair.second + " ";
					}
					command_strings.push_back(
						wd + env + this->dump_command(
							shell_command.string(_build, link, *formatter)
						)
					);
					out << '\t' << command_strings.back() << std::endl;
				}
			}
			out << std::endl;
			if (node->is_file())
			{
				bool had_commands_property = node->has_property(
					generated_commands_property_name
				);
				auto new_command = boost::join(command_strings, "\n");
				if (had_commands_property && node != makefile_node)
				{
					auto& old_command = node->property<std::string>(generated_commands_property_name);
				    if (old_command != new_command)
					{
						log::verbose("Deleting node", node->string(),
						             "(command line changed: ", old_command,
						             "->", new_command, ")");
						to_delete.insert(node.get());
					}
				}
				node->set_property<std::string>(
					generated_commands_property_name,
					new_command
				);
			}
		}

		for (auto node: to_delete)
		{
			try {
				boost::filesystem::remove(node->path());
			} catch (...) {
				log::warning("Couldn't remove", node->string(), ":", error_string());
			}
		}
		this->include_dependencies(out, use_relpath);
	}

	void Makefile::include_dependencies(std::ostream& out, bool relative) const
	{
		if (relative)
			for (auto& node: _includes)
				out << "-include " << relative_node_path(_build, *node) << std::endl;
		else
			for (auto& node: _includes)
				out << "-include " << absolute_node_path(_build, *node) << std::endl;
	}

	std::string Makefile::dump_command(std::vector<std::string> const& cmd) const
	{
#ifdef _WIN32
		if (cmd.size() == 1)
		{
			// Workaroung a bug in GNU Make, when commands contain a double quote
			// they are spawned through CreateProcess() as 'sh -c \"COMMAND HERE\"'
			// when the argument does have any special character other than slash
			// and there is only one argument, quotes are left ...
			auto res = quote<CommandParser::make>(cmd);
			if (res[0] == '"' && res.back() == '"' )
			{
				res = res.substr(1, res.size() - 2);
			}
			return res;
		}
#endif
		return quote<CommandParser::make>(cmd);
	}

	bool Makefile::is_available(Build& build)
	{ return build.fs().which("make") != boost::none; }

	std::vector<std::string>
	Makefile::build_command(std::string const& target) const
	{
		return {
			"make", "-C", _build.directory().string(),
			target.empty() ? "all" : target
		};
	}

	bool Makefile::use_relative_path() const { return true; }
}}

<|endoftext|>


<commit_before>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Albrecht
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_GDT_SPACE_INTERFACE_HH
#define DUNE_GDT_SPACE_INTERFACE_HH

#include <memory>

#include <dune/common/dynvector.hh>

#include <dune/grid/io/file/vtk/vtkwriter.hh>

#include <dune/stuff/la/container/pattern.hh>

#include "constraints.hh"
#include "../discretefunction/visualize.hh"

// needs to be here, since one of the above includes the config.h
#include <dune/common/bartonnackmanifcheck.hh>

namespace Dune {
namespace GDT {

template <class Traits>
class SpaceInterface
{
public:
  typedef typename Traits::derived_type derived_type;

  typedef typename Traits::GridPartType GridPartType;
  static const int polOrder = Traits::polOrder;
  typedef typename GridPartType::ctype DomainFieldType;
  static const unsigned int dimDomain = GridPartType::dimension;
  typedef typename Traits::RangeFieldType RangeFieldType;
  static const unsigned int dimRange     = Traits::dimRange;
  static const unsigned int dimRangeCols = Traits::dimRangeCols;

  typedef typename Traits::BackendType BackendType;
  typedef typename Traits::MapperType MapperType;
  typedef typename Traits::BaseFunctionSetType BaseFunctionSetType;
  typedef typename Traits::EntityType EntityType;

  typedef Dune::Stuff::LA::SparsityPatternDefault PatternType;

  const std::shared_ptr<const GridPartType>& gridPart() const
  {
    CHECK_INTERFACE_IMPLEMENTATION(asImp().gridPart());
    return asImp().gridPart();
  }

  const BackendType& backend() const
  {
    CHECK_INTERFACE_IMPLEMENTATION(asImp().backend());
    return asImp().backend();
  }

  bool continuous() const
  {
    CHECK_INTERFACE_IMPLEMENTATION(asImp().continuous());
    return asImp().continuous();
  }

  const MapperType& mapper() const
  {
    CHECK_INTERFACE_IMPLEMENTATION(asImp().mapper());
    return asImp().mapper();
  }

  BaseFunctionSetType baseFunctionSet(const EntityType& entity) const
  {
    CHECK_INTERFACE_IMPLEMENTATION(asImp().baseFunctionSet(entity));
    return asImp().baseFunctionSet(entity);
  }

  template <class ConstraintsType>
  void localConstraints(const EntityType& entity, ConstraintsType& ret) const
  {
    CHECK_AND_CALL_INTERFACE_IMPLEMENTATION(asImp().localConstraints(entity, ret));
    asImp().localConstraints(entity, ret);
  }

  PatternType* computePattern() const
  {
    return computePattern(*this);
  }

  template <class OtherSpaceType>
  PatternType* computePattern(const OtherSpaceType& other) const
  {
    return computePattern(*(gridPart()), other);
  }

  template <class LocalGridPartType, class OtherSpaceType>
  PatternType* computePattern(const LocalGridPartType& localGridPart, const OtherSpaceType& otherSpace) const
  {
    CHECK_INTERFACE_IMPLEMENTATION(asImp().computePattern(localGridPart, otherSpace));
    return asImp().computePattern(localGridPart, otherSpace);
  }

  template <class VectorType>
  void visualize(const VectorType& vector, const std::string filename, const std::string name = "vector") const
  {
    typedef DiscreteFunction::VisualizationAdapter<derived_type, VectorType> DiscreteFunctionType;
    const auto function = std::make_shared<const DiscreteFunctionType>(asImp(), vector, name);
    typedef typename Dune::VTKWriter<typename GridPartType::GridViewType> VTKWriterType;
    VTKWriterType vtk_writer(gridPart().gridView(), Dune::VTK::nonconforming);
    vtk_writer.addVertexData(function);
    vtk_writer.write(filename);
  }

  void visualize(const std::string filename_prefix = "") const
  {
    std::string filename = filename_prefix;
    if (filename_prefix.empty()) {
      filename = "raviartthomasspace.femlocalfunctions";
      //                 + Stuff::Common::toString(dimDomain) + "_to_" + Stuff::Common::toString(dimRange);
      if (dimRangeCols > 1)
        filename += "x" + Stuff::Common::toString(dimRangeCols);
    }
    typedef typename Dune::VTKWriter<typename GridPartType::GridViewType> VTKWriterType;
    VTKWriterType vtk_writer(gridPart().gridView(), Dune::VTK::nonconforming);
    for (size_t ii = 0; ii < mapper().maxNumDofs(); ++ii) {
      typedef DiscreteFunction::BasisVisualization<typename Traits::derived_type> BasisFunctionType;
      const auto iith_baseFunction =
          std::make_shared<BasisFunctionType>(asImp(), ii, Stuff::Common::toString(ii) + "th basis");
      vtk_writer.addVertexData(iith_baseFunction);
    }
    vtk_writer.write(filename);
  }

  derived_type& asImp()
  {
    return static_cast<derived_type&>(*this);
  }

  const derived_type& asImp() const
  {
    return static_cast<const derived_type&>(*this);
  }

protected:
  /**
   *  \brief  computes a sparsity pattern, where this space is the test space (rows/outer) and the other space is the
   *          ansatz space (cols/inner)
   */
  template <class LocalGridPartType, class O>
  PatternType* computeVolumePattern(const LocalGridPartType& localGridPart, const SpaceInterface<O>& otherSpace) const
  {
    PatternType* ret     = new PatternType(mapper().size());
    PatternType& pattern = *ret;
    // walk the grid part
    for (typename LocalGridPartType::template Codim<0>::IteratorType entityIt = localGridPart.template begin<0>();
         entityIt != localGridPart.template end<0>();
         ++entityIt) {
      const typename LocalGridPartType::template Codim<0>::EntityType& entity = *entityIt;
      // get basefunctionsets
      const auto testBase   = baseFunctionSet(entity);
      const auto ansatzBase = otherSpace.baseFunctionSet(entity);
      Dune::DynamicVector<size_t> globalRows(testBase.size(), 0);
      mapper().globalIndices(entity, globalRows);
      Dune::DynamicVector<size_t> globalCols(ansatzBase.size(), 0);
      otherSpace.mapper().globalIndices(entity, globalCols);
      for (size_t ii = 0; ii < testBase.size(); ++ii) {
        auto& columns = pattern.inner(globalRows[ii]);
        for (size_t jj = 0; jj < ansatzBase.size(); ++jj) {
          columns.insert(globalCols[jj]);
        }
      }
    } // walk the grid part
    return ret;
  } // ... computeVolumePattern(...)

  /**
   *  \brief  computes a DG sparsity pattern, where this space is the test space (rows/outer) and the other space is the
   *          ansatz space (cols/inner)
   */
  template <class LocalGridPartType, class O>
  PatternType* computeVolumeAndCouplingPattern(const LocalGridPartType& local_grid_part,
                                               const SpaceInterface<O>& other_space) const
  {
    // prepare
    PatternType* ret     = new PatternType(mapper().size());
    PatternType& pattern = *ret;
    Dune::DynamicVector<size_t> global_rows(mapper().maxNumDofs(), 0);
    Dune::DynamicVector<size_t> global_cols(other_space.mapper().maxNumDofs(), 0);
    // walk the grid part
    const auto entity_it_end = local_grid_part.template end<0>();
    for (auto entity_it = local_grid_part.template begin<0>(); entity_it != entity_it_end; ++entity_it) {
      const auto& entity = *entity_it;
      // get basefunctionsets
      const auto test_base_entity   = baseFunctionSet(entity);
      const auto ansatz_base_entity = other_space.baseFunctionSet(entity);
      mapper().globalIndices(entity, global_rows);
      other_space.mapper().globalIndices(entity, global_cols);
      // compute entity/entity
      for (size_t ii = 0; ii < test_base_entity.size(); ++ii) {
        auto& columns = pattern.inner(global_rows[ii]);
        for (size_t jj = 0; jj < ansatz_base_entity.size(); ++jj) {
          columns.insert(global_cols[jj]);
        }
      }
      // walk the intersections
      const auto intersection_it_end = local_grid_part.iend(entity);
      for (auto intersection_it = local_grid_part.ibegin(entity); intersection_it != intersection_it_end;
           ++intersection_it) {
        const auto& intersection = *intersection_it;
        // get the neighbour
        if (intersection.neighbor() && !intersection.boundary()) {
          const auto neighbour_ptr = intersection.outside();
          const auto& neighbour    = *neighbour_ptr;
          // get the basis
          const auto ansatz_base_neighbour = other_space.baseFunctionSet(neighbour);
          other_space.mapper().globalIndices(neighbour, global_cols);
          // compute entity/neighbour
          for (size_t ii = 0; ii < test_base_entity.size(); ++ii) {
            auto& columns = pattern.inner(global_rows[ii]);
            for (size_t jj = 0; jj < ansatz_base_neighbour.size(); ++jj) {
              columns.insert(global_cols[jj]);
            }
          }
        } // get the neighbour
      } // walk the intersections
    } // walk the grid part
    return ret;
  } // ... computeVolumeAndCouplingPattern(...)

public:
  template <class LocalGridPartType, class O>
  PatternType* computeCodim0Pattern(const LocalGridPartType& local_grid_part,
                                    const SpaceInterface<O>& other_space) const
  {
    return computeVolumePattern(local_grid_part, other_space);
  }

  template <class LocalGridPartType, class O>
  PatternType* computeCodim1Pattern(const LocalGridPartType& local_grid_part,
                                    const SpaceInterface<O>& other_space) const
  {
    // prepare
    PatternType* ret     = new PatternType(mapper().size());
    PatternType& pattern = *ret;
    Dune::DynamicVector<size_t> global_rows(mapper().maxNumDofs(), 0);
    Dune::DynamicVector<size_t> global_cols(other_space.mapper().maxNumDofs(), 0);
    // walk the grid part
    const auto entity_it_end = local_grid_part.template end<0>();
    for (auto entity_it = local_grid_part.template begin<0>(); entity_it != entity_it_end; ++entity_it) {
      const auto& entity = *entity_it;
      // get basefunctionsets
      const auto test_base_entity = baseFunctionSet(entity);
      mapper().globalIndices(entity, global_rows);
      // walk the intersections
      const auto intersection_it_end = local_grid_part.iend(entity);
      for (auto intersection_it = local_grid_part.ibegin(entity); intersection_it != intersection_it_end;
           ++intersection_it) {
        const auto& intersection = *intersection_it;
        // get the neighbour
        if (intersection.neighbor() && !intersection.boundary()) {
          const auto neighbour_ptr = intersection.outside();
          const auto& neighbour    = *neighbour_ptr;
          // get the basis
          const auto ansatz_base_neighbour = other_space.baseFunctionSet(neighbour);
          other_space.mapper().globalIndices(neighbour, global_cols);
          // compute entity/neighbour
          for (size_t ii = 0; ii < test_base_entity.size(); ++ii) {
            auto& columns = pattern.inner(global_rows[ii]);
            for (size_t jj = 0; jj < ansatz_base_neighbour.size(); ++jj) {
              columns.insert(global_cols[jj]);
            }
          }
        } // get the neighbour
      } // walk the intersections
    } // walk the grid part
    return ret;
  } // ... computeCodim1Pattern(...)
}; // class SpaceInterface

} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_SPACE_INTERFACE_HH
<commit_msg>[space.interface] renamed internale pattern computations<commit_after>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Albrecht
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_GDT_SPACE_INTERFACE_HH
#define DUNE_GDT_SPACE_INTERFACE_HH

#include <memory>

#include <dune/common/dynvector.hh>

#include <dune/grid/io/file/vtk/vtkwriter.hh>

#include <dune/stuff/la/container/pattern.hh>

#include "constraints.hh"
#include "../discretefunction/visualize.hh"

// needs to be here, since one of the above includes the config.h
#include <dune/common/bartonnackmanifcheck.hh>

namespace Dune {
namespace GDT {

template <class Traits>
class SpaceInterface
{
public:
  typedef typename Traits::derived_type derived_type;

  typedef typename Traits::GridPartType GridPartType;
  static const int polOrder = Traits::polOrder;
  typedef typename GridPartType::ctype DomainFieldType;
  static const unsigned int dimDomain = GridPartType::dimension;
  typedef typename Traits::RangeFieldType RangeFieldType;
  static const unsigned int dimRange     = Traits::dimRange;
  static const unsigned int dimRangeCols = Traits::dimRangeCols;

  typedef typename Traits::BackendType BackendType;
  typedef typename Traits::MapperType MapperType;
  typedef typename Traits::BaseFunctionSetType BaseFunctionSetType;
  typedef typename Traits::EntityType EntityType;

  typedef Dune::Stuff::LA::SparsityPatternDefault PatternType;

  const std::shared_ptr<const GridPartType>& gridPart() const
  {
    CHECK_INTERFACE_IMPLEMENTATION(asImp().gridPart());
    return asImp().gridPart();
  }

  const BackendType& backend() const
  {
    CHECK_INTERFACE_IMPLEMENTATION(asImp().backend());
    return asImp().backend();
  }

  bool continuous() const
  {
    CHECK_INTERFACE_IMPLEMENTATION(asImp().continuous());
    return asImp().continuous();
  }

  const MapperType& mapper() const
  {
    CHECK_INTERFACE_IMPLEMENTATION(asImp().mapper());
    return asImp().mapper();
  }

  BaseFunctionSetType baseFunctionSet(const EntityType& entity) const
  {
    CHECK_INTERFACE_IMPLEMENTATION(asImp().baseFunctionSet(entity));
    return asImp().baseFunctionSet(entity);
  }

  template <class ConstraintsType>
  void localConstraints(const EntityType& entity, ConstraintsType& ret) const
  {
    CHECK_AND_CALL_INTERFACE_IMPLEMENTATION(asImp().localConstraints(entity, ret));
    asImp().localConstraints(entity, ret);
  }

  PatternType* computePattern() const
  {
    return computePattern(*this);
  }

  template <class OtherSpaceType>
  PatternType* computePattern(const OtherSpaceType& other) const
  {
    return computePattern(*(gridPart()), other);
  }

  template <class LocalGridPartType, class OtherSpaceType>
  PatternType* computePattern(const LocalGridPartType& localGridPart, const OtherSpaceType& otherSpace) const
  {
    CHECK_INTERFACE_IMPLEMENTATION(asImp().computePattern(localGridPart, otherSpace));
    return asImp().computePattern(localGridPart, otherSpace);
  }

  template <class VectorType>
  void visualize(const VectorType& vector, const std::string filename, const std::string name = "vector") const
  {
    typedef DiscreteFunction::VisualizationAdapter<derived_type, VectorType> DiscreteFunctionType;
    const auto function = std::make_shared<const DiscreteFunctionType>(asImp(), vector, name);
    typedef typename Dune::VTKWriter<typename GridPartType::GridViewType> VTKWriterType;
    VTKWriterType vtk_writer(gridPart().gridView(), Dune::VTK::nonconforming);
    vtk_writer.addVertexData(function);
    vtk_writer.write(filename);
  }

  void visualize(const std::string filename_prefix = "") const
  {
    std::string filename = filename_prefix;
    if (filename_prefix.empty()) {
      filename = "raviartthomasspace.femlocalfunctions";
      //                 + Stuff::Common::toString(dimDomain) + "_to_" + Stuff::Common::toString(dimRange);
      if (dimRangeCols > 1)
        filename += "x" + Stuff::Common::toString(dimRangeCols);
    }
    typedef typename Dune::VTKWriter<typename GridPartType::GridViewType> VTKWriterType;
    VTKWriterType vtk_writer(gridPart().gridView(), Dune::VTK::nonconforming);
    for (size_t ii = 0; ii < mapper().maxNumDofs(); ++ii) {
      typedef DiscreteFunction::BasisVisualization<typename Traits::derived_type> BasisFunctionType;
      const auto iith_baseFunction =
          std::make_shared<BasisFunctionType>(asImp(), ii, Stuff::Common::toString(ii) + "th basis");
      vtk_writer.addVertexData(iith_baseFunction);
    }
    vtk_writer.write(filename);
  }

  derived_type& asImp()
  {
    return static_cast<derived_type&>(*this);
  }

  const derived_type& asImp() const
  {
    return static_cast<const derived_type&>(*this);
  }

protected:
  /**
   *  \brief  computes a sparsity pattern, where this space is the test space (rows/outer) and the other space is the
   *          ansatz space (cols/inner)
   */
  template <class LocalGridPartType, class O>
  PatternType* computeCodim0Pattern(const LocalGridPartType& localGridPart, const SpaceInterface<O>& otherSpace) const
  {
    PatternType* ret     = new PatternType(mapper().size());
    PatternType& pattern = *ret;
    // walk the grid part
    for (typename LocalGridPartType::template Codim<0>::IteratorType entityIt = localGridPart.template begin<0>();
         entityIt != localGridPart.template end<0>();
         ++entityIt) {
      const typename LocalGridPartType::template Codim<0>::EntityType& entity = *entityIt;
      // get basefunctionsets
      const auto testBase   = baseFunctionSet(entity);
      const auto ansatzBase = otherSpace.baseFunctionSet(entity);
      Dune::DynamicVector<size_t> globalRows(testBase.size(), 0);
      mapper().globalIndices(entity, globalRows);
      Dune::DynamicVector<size_t> globalCols(ansatzBase.size(), 0);
      otherSpace.mapper().globalIndices(entity, globalCols);
      for (size_t ii = 0; ii < testBase.size(); ++ii) {
        auto& columns = pattern.inner(globalRows[ii]);
        for (size_t jj = 0; jj < ansatzBase.size(); ++jj) {
          columns.insert(globalCols[jj]);
        }
      }
    } // walk the grid part
    return ret;
  } // ... computeVolumePattern(...)

  /**
   *  \brief  computes a DG sparsity pattern, where this space is the test space (rows/outer) and the other space is the
   *          ansatz space (cols/inner)
   */
  template <class LocalGridPartType, class O>
  PatternType* computeCodim0AndCodim1Pattern(const LocalGridPartType& local_grid_part,
                                             const SpaceInterface<O>& other_space) const
  {
    // prepare
    PatternType* ret     = new PatternType(mapper().size());
    PatternType& pattern = *ret;
    Dune::DynamicVector<size_t> global_rows(mapper().maxNumDofs(), 0);
    Dune::DynamicVector<size_t> global_cols(other_space.mapper().maxNumDofs(), 0);
    // walk the grid part
    const auto entity_it_end = local_grid_part.template end<0>();
    for (auto entity_it = local_grid_part.template begin<0>(); entity_it != entity_it_end; ++entity_it) {
      const auto& entity = *entity_it;
      // get basefunctionsets
      const auto test_base_entity   = baseFunctionSet(entity);
      const auto ansatz_base_entity = other_space.baseFunctionSet(entity);
      mapper().globalIndices(entity, global_rows);
      other_space.mapper().globalIndices(entity, global_cols);
      // compute entity/entity
      for (size_t ii = 0; ii < test_base_entity.size(); ++ii) {
        auto& columns = pattern.inner(global_rows[ii]);
        for (size_t jj = 0; jj < ansatz_base_entity.size(); ++jj) {
          columns.insert(global_cols[jj]);
        }
      }
      // walk the intersections
      const auto intersection_it_end = local_grid_part.iend(entity);
      for (auto intersection_it = local_grid_part.ibegin(entity); intersection_it != intersection_it_end;
           ++intersection_it) {
        const auto& intersection = *intersection_it;
        // get the neighbour
        if (intersection.neighbor() && !intersection.boundary()) {
          const auto neighbour_ptr = intersection.outside();
          const auto& neighbour    = *neighbour_ptr;
          // get the basis
          const auto ansatz_base_neighbour = other_space.baseFunctionSet(neighbour);
          other_space.mapper().globalIndices(neighbour, global_cols);
          // compute entity/neighbour
          for (size_t ii = 0; ii < test_base_entity.size(); ++ii) {
            auto& columns = pattern.inner(global_rows[ii]);
            for (size_t jj = 0; jj < ansatz_base_neighbour.size(); ++jj) {
              columns.insert(global_cols[jj]);
            }
          }
        } // get the neighbour
      } // walk the intersections
    } // walk the grid part
    return ret;
  } // ... computeVolumeAndCouplingPattern(...)

  template <class LocalGridPartType, class O>
  PatternType* computeCodim1Pattern(const LocalGridPartType& local_grid_part,
                                    const SpaceInterface<O>& other_space) const
  {
    // prepare
    PatternType* ret     = new PatternType(mapper().size());
    PatternType& pattern = *ret;
    Dune::DynamicVector<size_t> global_rows(mapper().maxNumDofs(), 0);
    Dune::DynamicVector<size_t> global_cols(other_space.mapper().maxNumDofs(), 0);
    // walk the grid part
    const auto entity_it_end = local_grid_part.template end<0>();
    for (auto entity_it = local_grid_part.template begin<0>(); entity_it != entity_it_end; ++entity_it) {
      const auto& entity = *entity_it;
      // get basefunctionsets
      const auto test_base_entity = baseFunctionSet(entity);
      mapper().globalIndices(entity, global_rows);
      // walk the intersections
      const auto intersection_it_end = local_grid_part.iend(entity);
      for (auto intersection_it = local_grid_part.ibegin(entity); intersection_it != intersection_it_end;
           ++intersection_it) {
        const auto& intersection = *intersection_it;
        // get the neighbour
        if (intersection.neighbor() && !intersection.boundary()) {
          const auto neighbour_ptr = intersection.outside();
          const auto& neighbour    = *neighbour_ptr;
          // get the basis
          const auto ansatz_base_neighbour = other_space.baseFunctionSet(neighbour);
          other_space.mapper().globalIndices(neighbour, global_cols);
          // compute entity/neighbour
          for (size_t ii = 0; ii < test_base_entity.size(); ++ii) {
            auto& columns = pattern.inner(global_rows[ii]);
            for (size_t jj = 0; jj < ansatz_base_neighbour.size(); ++jj) {
              columns.insert(global_cols[jj]);
            }
          }
        } // get the neighbour
      } // walk the intersections
    } // walk the grid part
    return ret;
  } // ... computeCodim1Pattern(...)
}; // class SpaceInterface

} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_SPACE_INTERFACE_HH
<|endoftext|>


<commit_before>// This file is part of the dune-gdt project:
//   https://github.com/dune-community/dune-gdt
// Copyright 2010-2017 dune-gdt developers and contributors. All rights reserved.
// License: Dual licensed as BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)
//      or  GPL-2.0+ (http://opensource.org/licenses/gpl-license)
//          with "runtime exception" (http://www.dune-project.org/license.html)
// Authors:
//   Felix Schindler (2015 - 2017)
//   Rene Milk       (2014, 2016)
//   Tobias Leibner  (2014, 2016)

#ifndef DUNE_GDT_SPACES_PARALLEL_HH
#define DUNE_GDT_SPACES_PARALLEL_HH

#include <dune/common/parallel/communicator.hh>

#include <dune/istl/owneroverlapcopy.hh>

#if HAVE_DUNE_PDELAB
#include <dune/pdelab/backend/istl.hh>
#endif

#include <dune/xt/la/container/istl.hh>
#include <dune/xt/common/parallel/helper.hh>

namespace Dune {
namespace GDT {

template <class ViewImp,
          bool is_parallel = Dune::XT::UseParallelCommunication<typename ViewImp::Grid::CollectiveCommunication>::value>
struct CommunicationChooser
{
  typedef Dune::XT::SequentialCommunication Type;

  static Type* create(const ViewImp& /*gridView*/)
  {
    return new Type;
  }

  template <class SpaceBackend>
  static bool prepare(const SpaceBackend& /*space_backend*/, Type& /*communicator*/)
  {
    return false;
  }
}; // struct CommunicationChooser

#if HAVE_MPI

template <class ViewImp>
struct CommunicationChooser<ViewImp, true>
{
  typedef OwnerOverlapCopyCommunication<bigunsignedint<96>, int> Type;

  static Type* create(const ViewImp& gridView)
  {
    return new Type(gridView.comm());
  }

  template <class Space>
  static bool prepare(const Space&
#if HAVE_DUNE_PDELAB
                          space,
                      Type& communicator)
#else
                      /*space*/,
                      Type& communicator)
#endif
  {
#if HAVE_DUNE_PDELAB
    XT::LA::IstlRowMajorSparseMatrix<typename Space::RangeFieldType> matrix;
    PDELab::istl::ParallelHelper<typename Space::BackendType>(space.backend(), 0)
        .createIndexSetAndProjectForAMG(matrix.backend(), communicator);
#endif // HAVE_DUNE_PDELAB
    return true;
  } // ... prepare(...)
}; // struct CommunicationChooser< ..., true >

#endif // HAVE_MPI

} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_SPACES_PARALLEL_HH
<commit_msg>[spaces.parallel] add prepare overloads for diff backends<commit_after>// This file is part of the dune-gdt project:
//   https://github.com/dune-community/dune-gdt
// Copyright 2010-2017 dune-gdt developers and contributors. All rights reserved.
// License: Dual licensed as BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)
//      or  GPL-2.0+ (http://opensource.org/licenses/gpl-license)
//          with "runtime exception" (http://www.dune-project.org/license.html)
// Authors:
//   Felix Schindler (2015 - 2017)
//   Rene Milk       (2014, 2016)
//   Tobias Leibner  (2014, 2016)

#ifndef DUNE_GDT_SPACES_PARALLEL_HH
#define DUNE_GDT_SPACES_PARALLEL_HH

#include <dune/common/parallel/communicator.hh>

#include <dune/istl/owneroverlapcopy.hh>

#if HAVE_DUNE_PDELAB
#include <dune/pdelab/backend/istl.hh>
#endif

#include <dune/xt/la/container/istl.hh>
#include <dune/xt/common/parallel/helper.hh>

#include <dune/gdt/spaces/interface.hh>

namespace Dune {
namespace GDT {

template <class ViewImp,
          bool is_parallel = Dune::XT::UseParallelCommunication<typename ViewImp::Grid::CollectiveCommunication>::value>
struct CommunicationChooser
{
  typedef Dune::XT::SequentialCommunication Type;

  static Type* create(const ViewImp& /*gridView*/)
  {
    return new Type;
  }

  template <class SpaceBackend>
  static bool prepare(const SpaceBackend& /*space_backend*/, Type& /*communicator*/)
  {
    return false;
  }
}; // struct CommunicationChooser

#if HAVE_MPI

template <class ViewImp>
struct CommunicationChooser<ViewImp, true>
{
  typedef OwnerOverlapCopyCommunication<bigunsignedint<96>, int> Type;

  static Type* create(const ViewImp& gridView)
  {
    return new Type(gridView.comm());
  }

  template <class Space>
  static typename std::enable_if<Space::backend_type == Dune::GDT::ChooseSpaceBackend::pdelab, bool>::type
  prepare(const Space& space, Type& communicator)
  {
#if HAVE_DUNE_PDELAB
    XT::LA::IstlRowMajorSparseMatrix<typename Space::RangeFieldType> matrix;
    PDELab::istl::ParallelHelper<typename Space::BackendType>(space.backend(), 0)
        .createIndexSetAndProjectForAMG(matrix.backend(), communicator);
#endif // HAVE_DUNE_PDELAB
    return true;
  } // ... prepare(...)

  template <class Space>
  static typename std::enable_if<Space::backend_type == Dune::GDT::ChooseSpaceBackend::gdt, bool>::type
  prepare(const Space& /*space*/, Type& communicator)
  {
    communicator.remoteIndices().template rebuild<true>();
    return true;
  } // ... prepare(...)

  template <class Space>
  static typename std::enable_if<Space::backend_type == Dune::GDT::ChooseSpaceBackend::fem, bool>::type
  prepare(const Space& /*space*/, Type& communicator)
  {
    communicator.remoteIndices().template rebuild<true>();
    return true;
  } // ... prepare(...)

}; // struct CommunicationChooser< ..., true >

#endif // HAVE_MPI

} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_SPACES_PARALLEL_HH
<|endoftext|>