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

#include <hintids.hxx>

#include <com/sun/star/i18n/ScriptType.hpp>
#include <fmtcntnt.hxx>
#include <txatbase.hxx>
#include <frmatr.hxx>
#include <viscrs.hxx>
#include <callnk.hxx>
#include <crsrsh.hxx>
#include <doc.hxx>
#include <frmfmt.hxx>
#include <txtfrm.hxx>
#include <tabfrm.hxx>
#include <rowfrm.hxx>
#include <fmtfsize.hxx>
#include <ndtxt.hxx>
#include <flyfrm.hxx>
#include <breakit.hxx>

#include<vcl/window.hxx>

SwCallLink::SwCallLink( SwCrsrShell & rSh, sal_uLong nAktNode, xub_StrLen nAktCntnt,
                        sal_uInt8 nAktNdTyp, long nLRPos, bool bAktSelection )
    : rShell( rSh ), nNode( nAktNode ), nCntnt( nAktCntnt ),
      nNdTyp( nAktNdTyp ), nLeftFrmPos( nLRPos ),
      bHasSelection( bAktSelection )
{
}

SwCallLink::SwCallLink( SwCrsrShell & rSh )
    : rShell( rSh )
{
    // remember SPoint-values of current cursor
    SwPaM* pCrsr = rShell.IsTableMode() ? rShell.GetTblCrs() : rShell.GetCrsr();
    SwNode& rNd = pCrsr->GetPoint()->nNode.GetNode();
    nNode = rNd.GetIndex();
    nCntnt = pCrsr->GetPoint()->nContent.GetIndex();
    nNdTyp = rNd.GetNodeType();
    bHasSelection = ( *pCrsr->GetPoint() != *pCrsr->GetMark() );

    if( rNd.IsTxtNode() )
        nLeftFrmPos = SwCallLink::getLayoutFrm( rShell.GetLayout(), (SwTxtNode&)rNd, nCntnt,
                                            !rShell.ActionPend() );
    else
    {
        nLeftFrmPos = 0;

        // A special treatment for SwFeShell:
        // When deleting the header/footer, footnotes SwFeShell sets the
        // Cursor to NULL (Node + Content).
        // If the Cursor is not on a CntntNode (ContentNode) this fact gets
        // saved in NdType.
        if( ND_CONTENTNODE & nNdTyp )
            nNdTyp = 0;
    }
}

static void lcl_notifyRow(const SwCntntNode* pNode, SwCrsrShell& rShell)
{
    if ( pNode != NULL )
    {
        SwFrm *myFrm = pNode->getLayoutFrm( rShell.GetLayout() );
        if (myFrm!=NULL)
        {
            // We need to emulated a change of the row height in order
            // to have the complete row redrawn
            SwRowFrm* pRow = myFrm->FindRowFrm();
            if ( pRow )
            {
                const SwTableLine* pLine = pRow->GetTabLine( );
                // Avoid redrawing the complete row if there are no nested tables
                bool bHasTable = false;
                SwFrm *pCell = pRow->GetLower();
                for (; pCell && !bHasTable; pCell = pCell->GetNext())
                {
                    SwFrm *pContent = pCell->GetLower();
                    for (; pContent && !bHasTable; pContent = pContent->GetNext())
                        if (pContent->GetType() == FRM_TAB)
                            bHasTable = true;
                }
                if (bHasTable)
                {
                    SwFmtFrmSize pSize = pLine->GetFrmFmt()->GetFrmSize();
                    pRow->ModifyNotification(NULL, &pSize);
                }
            }
        }
    }
}

SwCallLink::~SwCallLink()
{
    if( !nNdTyp || !rShell.m_bCallChgLnk ) // see ctor
        return ;

    // If travelling over Nodes check formats and register them anew at the
    // new Node.
    SwPaM* pCurCrsr = rShell.IsTableMode() ? rShell.GetTblCrs() : rShell.GetCrsr();
    SwCntntNode * pCNd = pCurCrsr->GetCntntNode();
    if( !pCNd )
        return;

    lcl_notifyRow(pCNd, rShell);

    const SwDoc *pDoc=rShell.GetDoc();
    const SwCntntNode *pNode = NULL;
    if ( ( pDoc != NULL && nNode < pDoc->GetNodes( ).Count( ) ) )
    {
        pNode = pDoc->GetNodes()[nNode]->GetCntntNode();
    }
    lcl_notifyRow(pNode, rShell);

    xub_StrLen nCmp, nAktCntnt = pCurCrsr->GetPoint()->nContent.GetIndex();
    sal_uInt16 nNdWhich = pCNd->GetNodeType();
    sal_uLong nAktNode = pCurCrsr->GetPoint()->nNode.GetIndex();

    // Register the Shell as dependent at the current Node. By doing this all
    // attribute changes can be signaled over the link.
    pCNd->Add( &rShell );

    if( nNdTyp != nNdWhich || nNode != nAktNode )
    {
        // Every time a switch between nodes occurs, there is a chance that
        // new attributes do apply - meaning text-attributes.
        // So the currently applying attributes would have to be determined.
        // That can be done in one go by the handler.
        rShell.CallChgLnk();
    }
    else if( !bHasSelection != !(*pCurCrsr->GetPoint() != *pCurCrsr->GetMark()) )
    {
        // always call change link when selection changes
        rShell.CallChgLnk();
    }
    else if( rShell.m_aChgLnk.IsSet() && ND_TEXTNODE == nNdWhich &&
             nCntnt != nAktCntnt )
    {
        // If travelling with left/right only and the frame is
        // unchanged (columns!) then check text hints.
        if( nLeftFrmPos == SwCallLink::getLayoutFrm( rShell.GetLayout(), (SwTxtNode&)*pCNd, nAktCntnt,
                                                    !rShell.ActionPend() ) &&
            (( nCmp = nCntnt ) + 1 == nAktCntnt ||          // Right
            nCntnt -1 == ( nCmp = nAktCntnt )) )            // Left
        {
            if( nCmp == nAktCntnt && pCurCrsr->HasMark() ) // left & select
                ++nCmp;
            if ( ((SwTxtNode*)pCNd)->HasHints() )
            {

                const SwpHints &rHts = ((SwTxtNode*)pCNd)->GetSwpHints();
                sal_uInt16 n;
                xub_StrLen nStart;
                const xub_StrLen *pEnd;

                for( n = 0; n < rHts.Count(); n++ )
                {
                    const SwTxtAttr* pHt = rHts[ n ];
                    pEnd = pHt->GetEnd();
                    nStart = *pHt->GetStart();

                    // If "only start" or "start and end equal" then call on
                    // every overflow of start.
                    if( ( !pEnd || ( nStart == *pEnd ) ) &&
                        ( nStart == nCntnt || nStart == nAktCntnt) )
                    {
                        rShell.CallChgLnk();
                        return;
                    }

                    // If the attribute has an area and that area is not empty ...
                    else if( pEnd && nStart < *pEnd &&
                        // ... then test if travelling occurred via start/end.
                        ( nStart == nCmp ||
                            ( pHt->DontExpand() ? nCmp == *pEnd-1
                                                : nCmp == *pEnd ) ))
                    {
                        rShell.CallChgLnk();
                        return;
                    }
                    nStart = 0;
                }
            }

            if( g_pBreakIt->GetBreakIter().is() )
            {
                const String& rTxt = ((SwTxtNode*)pCNd)->GetTxt();
                if( !nCmp ||
                    g_pBreakIt->GetBreakIter()->getScriptType( rTxt, nCmp )
                     != g_pBreakIt->GetBreakIter()->getScriptType( rTxt, nCmp - 1 ))
                {
                    rShell.CallChgLnk();
                    return;
                }
            }
        }
        else
            // If travelling more than one character with home/end/.. then
            // always call ChgLnk, because it can not be determined here what
            // has changed. Something may have changed.
            rShell.CallChgLnk();
    }

    const SwFrm* pFrm;
    const SwFlyFrm *pFlyFrm;
    if( !rShell.ActionPend() && 0 != ( pFrm = pCNd->getLayoutFrm(rShell.GetLayout(),0,0,sal_False) ) &&
        0 != ( pFlyFrm = pFrm->FindFlyFrm() ) && !rShell.IsTableMode() )
    {
        const SwNodeIndex* pIndex = pFlyFrm->GetFmt()->GetCntnt().GetCntntIdx();
        OSL_ENSURE( pIndex, "Fly without Cntnt" );

        if (!pIndex)
            return;

        const SwNode& rStNd = pIndex->GetNode();

        if( rStNd.EndOfSectionNode()->StartOfSectionIndex() > nNode ||
            nNode > rStNd.EndOfSectionIndex() )
            rShell.GetFlyMacroLnk().Call( (void*)pFlyFrm->GetFmt() );
    }
}

long SwCallLink::getLayoutFrm( const SwRootFrm* pRoot, SwTxtNode& rNd, xub_StrLen nCntPos, sal_Bool bCalcFrm )
{
    SwTxtFrm* pFrm = (SwTxtFrm*)rNd.getLayoutFrm(pRoot,0,0,bCalcFrm), *pNext = pFrm;
    if ( pFrm && !pFrm->IsHiddenNow() )
    {
        if( pFrm->HasFollow() )
            while( 0 != ( pNext = (SwTxtFrm*)pFrm->GetFollow() ) &&
                    nCntPos >= pNext->GetOfst() )
                pFrm = pNext;

        return pFrm->Frm().Left();
    }
    return 0;
}

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

#include <hintids.hxx>

#include <com/sun/star/i18n/ScriptType.hpp>
#include <fmtcntnt.hxx>
#include <txatbase.hxx>
#include <frmatr.hxx>
#include <viscrs.hxx>
#include <callnk.hxx>
#include <crsrsh.hxx>
#include <doc.hxx>
#include <frmfmt.hxx>
#include <txtfrm.hxx>
#include <tabfrm.hxx>
#include <rowfrm.hxx>
#include <fmtfsize.hxx>
#include <ndtxt.hxx>
#include <flyfrm.hxx>
#include <breakit.hxx>

#include<vcl/window.hxx>

SwCallLink::SwCallLink( SwCrsrShell & rSh, sal_uLong nAktNode, xub_StrLen nAktCntnt,
                        sal_uInt8 nAktNdTyp, long nLRPos, bool bAktSelection )
    : rShell( rSh ), nNode( nAktNode ), nCntnt( nAktCntnt ),
      nNdTyp( nAktNdTyp ), nLeftFrmPos( nLRPos ),
      bHasSelection( bAktSelection )
{
}

SwCallLink::SwCallLink( SwCrsrShell & rSh )
    : rShell( rSh )
{
    // remember SPoint-values of current cursor
    SwPaM* pCrsr = rShell.IsTableMode() ? rShell.GetTblCrs() : rShell.GetCrsr();
    SwNode& rNd = pCrsr->GetPoint()->nNode.GetNode();
    nNode = rNd.GetIndex();
    nCntnt = pCrsr->GetPoint()->nContent.GetIndex();
    nNdTyp = rNd.GetNodeType();
    bHasSelection = ( *pCrsr->GetPoint() != *pCrsr->GetMark() );

    if( rNd.IsTxtNode() )
        nLeftFrmPos = SwCallLink::getLayoutFrm( rShell.GetLayout(), (SwTxtNode&)rNd, nCntnt,
                                            !rShell.ActionPend() );
    else
    {
        nLeftFrmPos = 0;

        // A special treatment for SwFeShell:
        // When deleting the header/footer, footnotes SwFeShell sets the
        // Cursor to NULL (Node + Content).
        // If the Cursor is not on a CntntNode (ContentNode) this fact gets
        // saved in NdType.
        if( ND_CONTENTNODE & nNdTyp )
            nNdTyp = 0;
    }
}

static void lcl_notifyRow(const SwCntntNode* pNode, SwCrsrShell& rShell)
{
    if ( pNode != NULL )
    {
        SwFrm *myFrm = pNode->getLayoutFrm( rShell.GetLayout() );
        if (myFrm!=NULL)
        {
            // We need to emulated a change of the row height in order
            // to have the complete row redrawn
            SwRowFrm* pRow = myFrm->FindRowFrm();
            if ( pRow )
            {
                const SwTableLine* pLine = pRow->GetTabLine( );
                // Avoid redrawing the complete row if there are no nested tables
                bool bHasTable = false;
                SwFrm *pCell = pRow->GetLower();
                for (; pCell && !bHasTable; pCell = pCell->GetNext())
                {
                    SwFrm *pContent = pCell->GetLower();
                    for (; pContent && !bHasTable; pContent = pContent->GetNext())
                        if (pContent->GetType() == FRM_TAB)
                            bHasTable = true;
                }
                if (bHasTable)
                {
                    SwFmtFrmSize pSize = pLine->GetFrmFmt()->GetFrmSize();
                    pRow->ModifyNotification(NULL, &pSize);
                }
            }
        }
    }
}

SwCallLink::~SwCallLink()
{
    if( !nNdTyp || !rShell.m_bCallChgLnk ) // see ctor
        return ;

    // If travelling over Nodes check formats and register them anew at the
    // new Node.
    SwPaM* pCurCrsr = rShell.IsTableMode() ? rShell.GetTblCrs() : rShell.GetCrsr();
    SwCntntNode * pCNd = pCurCrsr->GetCntntNode();
    if( !pCNd )
        return;

    lcl_notifyRow(pCNd, rShell);

    const SwDoc *pDoc=rShell.GetDoc();
    const SwCntntNode *pNode = NULL;
    if ( ( pDoc != NULL && nNode < pDoc->GetNodes( ).Count( ) ) )
    {
        pNode = pDoc->GetNodes()[nNode]->GetCntntNode();
    }
    lcl_notifyRow(pNode, rShell);

    xub_StrLen nCmp, nAktCntnt = pCurCrsr->GetPoint()->nContent.GetIndex();
    sal_uInt16 nNdWhich = pCNd->GetNodeType();
    sal_uLong nAktNode = pCurCrsr->GetPoint()->nNode.GetIndex();

    // Register the Shell as dependent at the current Node. By doing this all
    // attribute changes can be signaled over the link.
    pCNd->Add( &rShell );

    if( nNdTyp != nNdWhich || nNode != nAktNode )
    {
        // Every time a switch between nodes occurs, there is a chance that
        // new attributes do apply - meaning text-attributes.
        // So the currently applying attributes would have to be determined.
        // That can be done in one go by the handler.
        rShell.CallChgLnk();
    }
    else if( !bHasSelection != !(*pCurCrsr->GetPoint() != *pCurCrsr->GetMark()) )
    {
        // always call change link when selection changes
        rShell.CallChgLnk();
    }
    else if( rShell.m_aChgLnk.IsSet() && ND_TEXTNODE == nNdWhich &&
             nCntnt != nAktCntnt )
    {
        // If travelling with left/right only and the frame is
        // unchanged (columns!) then check text hints.
        if( nLeftFrmPos == SwCallLink::getLayoutFrm( rShell.GetLayout(), (SwTxtNode&)*pCNd, nAktCntnt,
                                                    !rShell.ActionPend() ) &&
            (( nCmp = nCntnt ) + 1 == nAktCntnt ||          // Right
            nCntnt -1 == ( nCmp = nAktCntnt )) )            // Left
        {
            if( nCmp == nAktCntnt && pCurCrsr->HasMark() ) // left & select
                ++nCmp;
            if ( ((SwTxtNode*)pCNd)->HasHints() )
            {

                const SwpHints &rHts = ((SwTxtNode*)pCNd)->GetSwpHints();
                sal_uInt16 n;
                xub_StrLen nStart;
                const xub_StrLen *pEnd;

                for( n = 0; n < rHts.Count(); n++ )
                {
                    const SwTxtAttr* pHt = rHts[ n ];
                    pEnd = pHt->GetEnd();
                    nStart = *pHt->GetStart();

                    // If "only start" or "start and end equal" then call on
                    // every overflow of start.
                    if( ( !pEnd || ( nStart == *pEnd ) ) &&
                        ( nStart == nCntnt || nStart == nAktCntnt) )
                    {
                        rShell.CallChgLnk();
                        return;
                    }

                    // If the attribute has an area and that area is not empty ...
                    else if( pEnd && nStart < *pEnd &&
                        // ... then test if travelling occurred via start/end.
                        ( nStart == nCmp ||
                            ( pHt->DontExpand() ? nCmp == *pEnd-1
                                                : nCmp == *pEnd ) ))
                    {
                        rShell.CallChgLnk();
                        return;
                    }
                    nStart = 0;
                }
            }

            if( g_pBreakIt->GetBreakIter().is() )
            {
                const OUString rTxt = ((SwTxtNode*)pCNd)->GetTxt();
                if( !nCmp ||
                    g_pBreakIt->GetBreakIter()->getScriptType( rTxt, nCmp )
                     != g_pBreakIt->GetBreakIter()->getScriptType( rTxt, nCmp - 1 ))
                {
                    rShell.CallChgLnk();
                    return;
                }
            }
        }
        else
            // If travelling more than one character with home/end/.. then
            // always call ChgLnk, because it can not be determined here what
            // has changed. Something may have changed.
            rShell.CallChgLnk();
    }

    const SwFrm* pFrm;
    const SwFlyFrm *pFlyFrm;
    if( !rShell.ActionPend() && 0 != ( pFrm = pCNd->getLayoutFrm(rShell.GetLayout(),0,0,sal_False) ) &&
        0 != ( pFlyFrm = pFrm->FindFlyFrm() ) && !rShell.IsTableMode() )
    {
        const SwNodeIndex* pIndex = pFlyFrm->GetFmt()->GetCntnt().GetCntntIdx();
        OSL_ENSURE( pIndex, "Fly without Cntnt" );

        if (!pIndex)
            return;

        const SwNode& rStNd = pIndex->GetNode();

        if( rStNd.EndOfSectionNode()->StartOfSectionIndex() > nNode ||
            nNode > rStNd.EndOfSectionIndex() )
            rShell.GetFlyMacroLnk().Call( (void*)pFlyFrm->GetFmt() );
    }
}

long SwCallLink::getLayoutFrm( const SwRootFrm* pRoot, SwTxtNode& rNd, xub_StrLen nCntPos, sal_Bool bCalcFrm )
{
    SwTxtFrm* pFrm = (SwTxtFrm*)rNd.getLayoutFrm(pRoot,0,0,bCalcFrm), *pNext = pFrm;
    if ( pFrm && !pFrm->IsHiddenNow() )
    {
        if( pFrm->HasFollow() )
            while( 0 != ( pNext = (SwTxtFrm*)pFrm->GetFollow() ) &&
                    nCntPos >= pNext->GetOfst() )
                pFrm = pNext;

        return pFrm->Frm().Left();
    }
    return 0;
}

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


<commit_before>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: viewcontactoftableobj.hxx,v $
 * $Revision: 1.3 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef _SDR_CONTACT_VIEWCONTACTOFTABLEOBJ_HXX
#define _SDR_CONTACT_VIEWCONTACTOFTABLEOBJ_HXX

#include <svx/sdr/contact/viewcontactofsdrobj.hxx>

//////////////////////////////////////////////////////////////////////////////
// predeclarations

//////////////////////////////////////////////////////////////////////////////

namespace sdr
{
    namespace table
    {
        class SdrTableObj;
    }

    namespace contact
    {
        class ViewContactOfTableObj : public ViewContactOfSdrObj
        {
        protected:
            // internal access to SdrTextObj
            ::sdr::table::SdrTableObj& GetTextObj() const
            {
                return (::sdr::table::SdrTableObj&)GetSdrObject();
            }

        public:
            // basic constructor, used from SdrObject.
            ViewContactOfTableObj(::sdr::table::SdrTableObj& rTextObj);

            // The destructor. When PrepareDelete() was not called before (see there)
            // warnings will be generated in debug version if there are still contacts
            // existing.
            virtual ~ViewContactOfTableObj();
        };
    } // end of namespace contact
} // end of namespace sdr

//////////////////////////////////////////////////////////////////////////////

#endif

// eof
<commit_msg>INTEGRATION: CWS aw033 (1.2.4); FILE MERGED 2008/07/10 13:00:59 aw 1.2.4.3: #i39532# XOutputDevice removed, PrepareDelete removed 2008/05/14 14:01:46 aw 1.2.4.2: RESYNC: (1.2-1.3); FILE MERGED 2008/03/31 05:53:01 aw 1.2.4.1: in-between ersion of the primitive transition<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: viewcontactoftableobj.hxx,v $
 * $Revision: 1.4 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef _SDR_CONTACT_VIEWCONTACTOFTABLEOBJ_HXX
#define _SDR_CONTACT_VIEWCONTACTOFTABLEOBJ_HXX

#include <svx/sdr/contact/viewcontactofsdrobj.hxx>

//////////////////////////////////////////////////////////////////////////////
// predeclarations

//////////////////////////////////////////////////////////////////////////////

namespace sdr
{
    namespace table
    {
        class SdrTableObj;
    }

    namespace contact
    {
        class ViewContactOfTableObj : public ViewContactOfSdrObj
        {
        protected:
            // internal access to SdrTextObj
            ::sdr::table::SdrTableObj& GetTableObj() const
            {
                return (::sdr::table::SdrTableObj&)GetSdrObject();
            }

            // This method is responsible for creating the graphical visualisation data derived ONLY from
            // the model data
            virtual drawinglayer::primitive2d::Primitive2DSequence createViewIndependentPrimitive2DSequence() const;

        public:
            // basic constructor, used from SdrObject.
            ViewContactOfTableObj(::sdr::table::SdrTableObj& rTextObj);
            virtual ~ViewContactOfTableObj();
        };
    } // end of namespace contact
} // end of namespace sdr

//////////////////////////////////////////////////////////////////////////////

#endif

// eof
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: callnk.hxx,v $
 *
 *  $Revision: 1.1.1.1 $
 *
 *  last change: $Author: hr $ $Date: 2000-09-19 00:08:17 $
 *
 *  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 _CALLNK_HXX
#define _CALLNK_HXX

#include <tools/solar.h>

class SwCrsrShell;
class SwTxtNode;

class SwCallLink
{
public:
    SwCrsrShell & rShell;
    ULONG nNode;
    xub_StrLen nCntnt;
    BYTE nNdTyp;
    long nLeftFrmPos;

    SwCallLink( SwCrsrShell & rSh );
    SwCallLink( SwCrsrShell & rSh, ULONG nAktNode, xub_StrLen nAktCntnt,
                                    BYTE nAktNdTyp, long nLRPos );
    ~SwCallLink();

    static long GetFrm( SwTxtNode& rNd, xub_StrLen nCntPos, BOOL bCalcFrm );
};

#endif  // _CALLNK_HXX
<commit_msg>INTEGRATION: CWS sw011 (1.1.1.1.190); FILE MERGED 2003/04/11 10:03:50 dvo 1.1.1.1.190.1: #108801# always update toolbar (etc.) when whether we have a text selection          changes<commit_after>/*************************************************************************
 *
 *  $RCSfile: callnk.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: vg $ $Date: 2003-04-17 16:03:53 $
 *
 *  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 _CALLNK_HXX
#define _CALLNK_HXX

#include <tools/solar.h>

class SwCrsrShell;
class SwTxtNode;

class SwCallLink
{
public:
    SwCrsrShell & rShell;
    ULONG nNode;
    xub_StrLen nCntnt;
    BYTE nNdTyp;
    long nLeftFrmPos;
    bool bHasSelection;

    SwCallLink( SwCrsrShell & rSh );
    SwCallLink( SwCrsrShell & rSh, ULONG nAktNode, xub_StrLen nAktCntnt,
                                    BYTE nAktNdTyp, long nLRPos,
                                    bool bAktSelection );
    ~SwCallLink();

    static long GetFrm( SwTxtNode& rNd, xub_StrLen nCntPos, BOOL bCalcFrm );
};

#endif  // _CALLNK_HXX
<|endoftext|>


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

#include "AntennaRepair.h"

#include <cmath>
#include <cstring>
#include <iostream>
#include <map>
#include <set>
#include <string>
#include <utility>
#include <vector>

#include "Net.h"
#include "Pin.h"
#include "grt/GlobalRouter.h"
#include "utl/Logger.h"

namespace grt {

using utl::GRT;

AntennaRepair::AntennaRepair(GlobalRouter* grouter,
                             ant::AntennaChecker* arc,
                             dpl::Opendp* opendp,
                             odb::dbDatabase* db,
                             utl::Logger* logger)
    : _grouter(grouter), _arc(arc), _opendp(opendp), _db(db), _logger(logger)
{
  _block = _db->getChip()->getBlock();
}

int AntennaRepair::checkAntennaViolations(NetRouteMap& routing,
                                          int maxRoutingLayer,
                                          odb::dbMTerm* diodeMTerm)
{
  odb::dbTech* tech = _db->getTech();

  _arc->load_antenna_rules();

  std::map<int, odb::dbTechVia*> defaultVias
      = _grouter->getDefaultVias(maxRoutingLayer);

  for (auto net_route : routing) {
    odb::dbNet* db_net = net_route.first;
    GRoute& route = net_route.second;
    odb::dbWire* wire = odb::dbWire::create(db_net);
    if (wire != nullptr) {
      odb::dbWireEncoder wireEncoder;
      wireEncoder.begin(wire);
      odb::dbWireType wireType = odb::dbWireType::ROUTED;

      for (GSegment& seg : route) {
        if (std::abs(seg.initLayer - seg.finalLayer) > 1) {
          _logger->error(GRT, 68, "Global route segment not valid.");
        }
        int x1 = seg.initX;
        int y1 = seg.initY;
        int x2 = seg.finalX;
        int y2 = seg.finalY;
        int l1 = seg.initLayer;
        int l2 = seg.finalLayer;

        odb::dbTechLayer* currLayer = tech->findRoutingLayer(l1);

        if (l1 == l2) {  // Add wire
          if (x1 == x2 && y1 == y2)
            continue;
          wireEncoder.newPath(currLayer, wireType);
          wireEncoder.addPoint(x1, y1);
          wireEncoder.addPoint(x2, y2);
        } else {  // Add via
          int bottomLayer = (l1 < l2) ? l1 : l2;
          wireEncoder.newPath(currLayer, wireType);
          wireEncoder.addPoint(x1, y1);
          wireEncoder.addTechVia(defaultVias[bottomLayer]);
        }
      }
      wireEncoder.end();

      odb::orderWires(db_net, false, false);

      std::vector<ant::VINFO> netViol = _arc->get_net_antenna_violations(
          db_net,
          diodeMTerm->getMaster()->getConstName(),
          diodeMTerm->getConstName());
      if (!netViol.empty()) {
        _antennaViolations[db_net] = netViol;
        _grouter->addDirtyNet(db_net);
      }

      odb::dbWire::destroy(wire);
    } else {
      _logger->error(GRT, 221, "Cannot create wire for net {}.", db_net->getConstName());
    }
  }

  _logger->info(GRT, 12, "Antenna violations: {}", _antennaViolations.size());
  return _antennaViolations.size();
}

void AntennaRepair::fixAntennas(odb::dbMTerm* diodeMTerm)
{
  int siteWidth = -1;
  int cnt = 0;
  r_tree fixedInsts;

  auto rows = _block->getRows();
  for (odb::dbRow* db_row : rows) {
    odb::dbSite* site = db_row->getSite();
    int site_width = site->getWidth();
    if (siteWidth == -1) {
      siteWidth = site_width;
    }

    if (siteWidth != site_width) {
      _logger->warn(GRT, 27, "Design has rows with different site widths.");
    }
  }

  deleteFillerCells();

  setInstsPlacementStatus(odb::dbPlacementStatus::FIRM);
  getFixedInstances(fixedInsts);

  for (auto const& violation : _antennaViolations) {
    odb::dbNet* net = violation.first;
    for (int i = 0; i < violation.second.size(); i++) {
      for (odb::dbITerm* sinkITerm : violation.second[i].iterms) {
        odb::dbInst* sinkInst = sinkITerm->getInst();
        for (int j = 0; j < violation.second[i].antenna_cell_nums; j++) {
          std::string antennaInstName = "ANTENNA_" + std::to_string(cnt);
          insertDiode(net,
                      diodeMTerm,
                      sinkInst,
                      sinkITerm,
                      antennaInstName,
                      siteWidth,
                      fixedInsts);
          cnt++;
        }
      }
    }
  }
}

void AntennaRepair::legalizePlacedCells()
{
  AntennaCbk* cbk = new AntennaCbk(_grouter);
  cbk->addOwner(_block);

  _opendp->detailedPlacement(0);
  _opendp->checkPlacement(false);

  cbk->removeOwner();

  // After legalize placement, diodes and violated insts don't need to be FIRM
  setInstsPlacementStatus(odb::dbPlacementStatus::PLACED);
}

void AntennaRepair::deleteFillerCells()
{
  int fillerCnt = 0;
  for (odb::dbInst* inst : _block->getInsts()) {
    if (inst->getMaster()->getType() == odb::dbMasterType::CORE_SPACER) {
      fillerCnt++;
      odb::dbInst::destroy(inst);
    }
  }

  if (fillerCnt > 0) {
    _logger->info(GRT, 11, "Deleted {} filler cells.", fillerCnt);
  }
}

void AntennaRepair::insertDiode(odb::dbNet* net,
                                odb::dbMTerm* diodeMTerm,
                                odb::dbInst* sinkInst,
                                odb::dbITerm* sinkITerm,
                                std::string antennaInstName,
                                int siteWidth,
                                r_tree& fixedInsts)
{
  bool legallyPlaced = false;
  bool placeAtLeft = true;
  int leftOffset = 0;
  int rightOffset = 0;
  int offset;

  std::string netName = net->getConstName();

  odb::dbMaster* antennaMaster = diodeMTerm->getMaster();

  int instLocX, instLocY, instWidth;
  odb::dbBox* sinkBBox = sinkInst->getBBox();
  instLocX = sinkBBox->xMin();
  instLocY = sinkBBox->yMin();
  instWidth = sinkBBox->xMax() - sinkBBox->xMin();
  odb::dbOrientType instOrient = sinkInst->getOrient();

  odb::dbInst* antennaInst
      = odb::dbInst::create(_block, antennaMaster, antennaInstName.c_str());
  odb::dbITerm* antennaITerm
      = antennaInst->findITerm(diodeMTerm->getConstName());
  odb::dbBox* antennaBBox = antennaInst->getBBox();
  int antennaWidth = antennaBBox->xMax() - antennaBBox->xMin();

  // Use R-tree to check if diode will not overlap or cause 1-site spacing with
  // other cells
  int leftPad = _opendp->padGlobalLeft();
  int rightPad = _opendp->padGlobalRight();
  std::vector<value> overlapInsts;
  while (!legallyPlaced) {
    if (placeAtLeft) {
      offset = -(antennaWidth + leftOffset * siteWidth);
      leftOffset++;
      placeAtLeft = false;
    } else {
      offset = instWidth + rightOffset * siteWidth;
      rightOffset++;
      placeAtLeft = true;
    }

    antennaInst->setOrient(instOrient);
    antennaInst->setLocation(instLocX + offset, instLocY);

    odb::dbBox* instBox = antennaInst->getBBox();
    box box(point(instBox->xMin() - ((leftPad + rightPad) * siteWidth) + 1,
                  instBox->yMin() + 1),
            point(instBox->xMax() + ((leftPad + rightPad) * siteWidth) - 1,
                  instBox->yMax() - 1));
    fixedInsts.query(bgi::intersects(box), std::back_inserter(overlapInsts));

    odb::Rect coreArea;
    _block->getCoreArea(coreArea);

    if (overlapInsts.empty() && instBox->xMin() >= coreArea.xMin()
        && instBox->xMax() <= coreArea.xMax()) {
      legallyPlaced = true;
    }
    overlapInsts.clear();
  }

  antennaInst->setPlacementStatus(odb::dbPlacementStatus::FIRM);
  odb::dbITerm::connect(antennaITerm, net);
  _diodeInsts.push_back(antennaInst);

  // Add diode to the R-tree of fixed instances
  int fixedInstId = fixedInsts.size();
  odb::dbBox* instBox = antennaInst->getBBox();
  box b(point(instBox->xMin(), instBox->yMin()),
        point(instBox->xMax(), instBox->yMax()));
  value v(b, fixedInstId);
  fixedInsts.insert(v);
  fixedInstId++;
}

void AntennaRepair::getFixedInstances(r_tree& fixedInsts)
{
  int fixedInstId = 0;
  for (odb::dbInst* inst : _block->getInsts()) {
    if (inst->getPlacementStatus() == odb::dbPlacementStatus::FIRM) {
      odb::dbBox* instBox = inst->getBBox();
      box b(point(instBox->xMin(), instBox->yMin()),
            point(instBox->xMax(), instBox->yMax()));
      value v(b, fixedInstId);
      fixedInsts.insert(v);
      fixedInstId++;
    }
  }
}

void AntennaRepair::setInstsPlacementStatus(
    odb::dbPlacementStatus placementStatus)
{
  for (auto const& violation : _antennaViolations) {
    for (int i = 0; i < violation.second.size(); i++) {
      for (odb::dbITerm* sinkITerm : violation.second[i].iterms) {
        sinkITerm->getInst()->setPlacementStatus(placementStatus);
      }
    }
  }

  for (odb::dbInst* diodeInst : _diodeInsts) {
    diodeInst->setPlacementStatus(placementStatus);
  }
}

AntennaCbk::AntennaCbk(GlobalRouter* grouter) : _grouter(grouter)
{
}

void AntennaCbk::inDbPostMoveInst(odb::dbInst* inst)
{
  for (odb::dbITerm* iterm : inst->getITerms()) {
    if (iterm->getNet() != nullptr && !iterm->getNet()->isSpecial())
      _grouter->addDirtyNet(iterm->getNet());
  }
}

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

#include "AntennaRepair.h"

#include <cmath>
#include <cstring>
#include <iostream>
#include <map>
#include <set>
#include <string>
#include <utility>
#include <vector>

#include "Net.h"
#include "Pin.h"
#include "grt/GlobalRouter.h"
#include "utl/Logger.h"

namespace grt {

using utl::GRT;

AntennaRepair::AntennaRepair(GlobalRouter* grouter,
                             ant::AntennaChecker* arc,
                             dpl::Opendp* opendp,
                             odb::dbDatabase* db,
                             utl::Logger* logger)
    : _grouter(grouter), _arc(arc), _opendp(opendp), _db(db), _logger(logger)
{
  _block = _db->getChip()->getBlock();
}

int AntennaRepair::checkAntennaViolations(NetRouteMap& routing,
                                          int maxRoutingLayer,
                                          odb::dbMTerm* diodeMTerm)
{
  odb::dbTech* tech = _db->getTech();

  _arc->load_antenna_rules();

  std::map<int, odb::dbTechVia*> defaultVias
      = _grouter->getDefaultVias(maxRoutingLayer);

  for (auto net_route : routing) {
    odb::dbNet* db_net = net_route.first;
    GRoute& route = net_route.second;
    odb::dbWire* wire = odb::dbWire::create(db_net);
    if (wire != nullptr) {
      odb::dbWireEncoder wireEncoder;
      wireEncoder.begin(wire);
      odb::dbWireType wireType = odb::dbWireType::ROUTED;

      for (GSegment& seg : route) {
        if (std::abs(seg.initLayer - seg.finalLayer) > 1) {
          _logger->error(GRT, 68, "Global route segment not valid.");
        }
        int x1 = seg.initX;
        int y1 = seg.initY;
        int x2 = seg.finalX;
        int y2 = seg.finalY;
        int l1 = seg.initLayer;
        int l2 = seg.finalLayer;

        odb::dbTechLayer* currLayer = tech->findRoutingLayer(l1);

        if (l1 == l2) {  // Add wire
          if (x1 == x2 && y1 == y2)
            continue;
          wireEncoder.newPath(currLayer, wireType);
          wireEncoder.addPoint(x1, y1);
          wireEncoder.addPoint(x2, y2);
        } else {  // Add via
          int bottomLayer = (l1 < l2) ? l1 : l2;
          wireEncoder.newPath(currLayer, wireType);
          wireEncoder.addPoint(x1, y1);
          wireEncoder.addTechVia(defaultVias[bottomLayer]);
        }
      }
      wireEncoder.end();

      odb::orderWires(db_net, false, false);

      std::vector<ant::VINFO> netViol = _arc->get_net_antenna_violations(
          db_net,
          diodeMTerm->getMaster()->getConstName(),
          diodeMTerm->getConstName());
      if (!netViol.empty()) {
        _antennaViolations[db_net] = netViol;
        _grouter->addDirtyNet(db_net);
      }

      odb::dbWire::destroy(wire);
    } else {
      _logger->error(GRT, 221, "Cannot create wire for net {}.", db_net->getConstName());
    }
  }

  _logger->info(GRT, 12, "Antenna violations: {}", _antennaViolations.size());
  return _antennaViolations.size();
}

void AntennaRepair::fixAntennas(odb::dbMTerm* diodeMTerm)
{
  int siteWidth = -1;
  int cnt = 0;
  r_tree fixedInsts;

  auto rows = _block->getRows();
  for (odb::dbRow* db_row : rows) {
    odb::dbSite* site = db_row->getSite();
    int site_width = site->getWidth();
    if (siteWidth == -1) {
      siteWidth = site_width;
    }

    if (siteWidth != site_width) {
      _logger->warn(GRT, 27, "Design has rows with different site widths.");
    }
  }

  deleteFillerCells();

  setInstsPlacementStatus(odb::dbPlacementStatus::FIRM);
  getFixedInstances(fixedInsts);

  for (auto const& violation : _antennaViolations) {
    odb::dbNet* net = violation.first;
    for (int i = 0; i < violation.second.size(); i++) {
      for (odb::dbITerm* sinkITerm : violation.second[i].iterms) {
        odb::dbInst* sinkInst = sinkITerm->getInst();
        for (int j = 0; j < violation.second[i].antenna_cell_nums; j++) {
          std::string antennaInstName = "ANTENNA_" + std::to_string(cnt);
          insertDiode(net,
                      diodeMTerm,
                      sinkInst,
                      sinkITerm,
                      antennaInstName,
                      siteWidth,
                      fixedInsts);
          cnt++;
        }
      }
    }
  }
}

void AntennaRepair::legalizePlacedCells()
{
  AntennaCbk* cbk = new AntennaCbk(_grouter);
  cbk->addOwner(_block);

  _opendp->detailedPlacement(0);
  _opendp->checkPlacement(false);

  cbk->removeOwner();

  // After legalize placement, diodes and violated insts don't need to be FIRM
  setInstsPlacementStatus(odb::dbPlacementStatus::PLACED);
}

void AntennaRepair::deleteFillerCells()
{
  int fillerCnt = 0;
  for (odb::dbInst* inst : _block->getInsts()) {
    if (inst->getMaster()->getType() == odb::dbMasterType::CORE_SPACER) {
      fillerCnt++;
      odb::dbInst::destroy(inst);
    }
  }

  if (fillerCnt > 0) {
    _logger->info(GRT, 11, "Deleted {} filler cells.", fillerCnt);
  }
}

void AntennaRepair::insertDiode(odb::dbNet* net,
                                odb::dbMTerm* diodeMTerm,
                                odb::dbInst* sinkInst,
                                odb::dbITerm* sinkITerm,
                                std::string antennaInstName,
                                int siteWidth,
                                r_tree& fixedInsts)
{
  bool legallyPlaced = false;
  bool placeAtLeft = true;
  int leftOffset = 0;
  int rightOffset = 0;
  int offset;

  std::string netName = net->getConstName();

  odb::dbMaster* antennaMaster = diodeMTerm->getMaster();

  int instLocX, instLocY, instWidth;
  odb::dbBox* sinkBBox = sinkInst->getBBox();
  instLocX = sinkBBox->xMin();
  instLocY = sinkBBox->yMin();
  instWidth = sinkBBox->xMax() - sinkBBox->xMin();
  odb::dbOrientType instOrient = sinkInst->getOrient();

  odb::dbInst* antennaInst
      = odb::dbInst::create(_block, antennaMaster, antennaInstName.c_str());
  odb::dbITerm* antennaITerm
      = antennaInst->findITerm(diodeMTerm->getConstName());
  odb::dbBox* antennaBBox = antennaInst->getBBox();
  int antennaWidth = antennaBBox->xMax() - antennaBBox->xMin();

  // Use R-tree to check if diode will not overlap or cause 1-site spacing with
  // other cells
  int leftPad = _opendp->padGlobalLeft();
  int rightPad = _opendp->padGlobalRight();
  std::vector<value> overlapInsts;
  while (!legallyPlaced) {
    if (placeAtLeft) {
      offset = -(antennaWidth + leftOffset * siteWidth);
      leftOffset++;
      placeAtLeft = false;
    } else {
      offset = instWidth + rightOffset * siteWidth;
      rightOffset++;
      placeAtLeft = true;
    }

    antennaInst->setOrient(instOrient);
    antennaInst->setLocation(instLocX + offset, instLocY);

    odb::dbBox* instBox = antennaInst->getBBox();
    box box(point(instBox->xMin() - ((leftPad + rightPad) * siteWidth) + 1,
                  instBox->yMin() + 1),
            point(instBox->xMax() + ((leftPad + rightPad) * siteWidth) - 1,
                  instBox->yMax() - 1));
    fixedInsts.query(bgi::intersects(box), std::back_inserter(overlapInsts));

    odb::Rect coreArea;
    _block->getCoreArea(coreArea);

    if (overlapInsts.empty() && instBox->xMin() >= coreArea.xMin()
        && instBox->xMax() <= coreArea.xMax()) {
      legallyPlaced = true;
    }
    overlapInsts.clear();
  }

  antennaInst->setPlacementStatus(odb::dbPlacementStatus::FIRM);
  odb::dbITerm::connect(antennaITerm, net);
  _diodeInsts.push_back(antennaInst);

  // Add diode to the R-tree of fixed instances
  int fixedInstId = fixedInsts.size();
  odb::dbBox* instBox = antennaInst->getBBox();
  box b(point(instBox->xMin(), instBox->yMin()),
        point(instBox->xMax(), instBox->yMax()));
  value v(b, fixedInstId);
  fixedInsts.insert(v);
  fixedInstId++;
}

void AntennaRepair::getFixedInstances(r_tree& fixedInsts)
{
  int fixedInstId = 0;
  for (odb::dbInst* inst : _block->getInsts()) {
    if (inst->getPlacementStatus() == odb::dbPlacementStatus::FIRM) {
      odb::dbBox* instBox = inst->getBBox();
      box b(point(instBox->xMin(), instBox->yMin()),
            point(instBox->xMax(), instBox->yMax()));
      value v(b, fixedInstId);
      fixedInsts.insert(v);
      fixedInstId++;
    }
  }
}

void AntennaRepair::setInstsPlacementStatus(
    odb::dbPlacementStatus placementStatus)
{
  for (auto const& violation : _antennaViolations) {
    for (int i = 0; i < violation.second.size(); i++) {
      for (odb::dbITerm* sinkITerm : violation.second[i].iterms) {
        sinkITerm->getInst()->setPlacementStatus(placementStatus);
      }
    }
  }

  for (odb::dbInst* diodeInst : _diodeInsts) {
    diodeInst->setPlacementStatus(placementStatus);
  }
}

AntennaCbk::AntennaCbk(GlobalRouter* grouter) : _grouter(grouter)
{
}

void AntennaCbk::inDbPostMoveInst(odb::dbInst* inst)
{
  for (odb::dbITerm* iterm : inst->getITerms()) {
    odb::dbNet* db_net = iterm->getNet();
    if (db_net != nullptr && !db_net->isSpecial())
      _grouter->addDirtyNet(iterm->getNet());
  }
}

}  // namespace grt
<|endoftext|>


<commit_before>/* This file is part of Ingen.
 * Copyright (C) 2007-2009 David Robillard <http://drobilla.net>
 *
 * Ingen is free software; you can redistribute it and/or modify it under the
 * terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version.
 *
 * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for details.
 *
 * You should have received a copy of the GNU General Public License alongCont
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include <cmath>
#include "interface/EngineInterface.hpp"
#include "shared/LV2URIMap.hpp"
#include "client/NodeModel.hpp"
#include "App.hpp"
#include "NodeControlWindow.hpp"
#include "GladeFactory.hpp"
#include "Controls.hpp"
#include "ControlPanel.hpp"
#include "PatchWindow.hpp"

using namespace std;

namespace Ingen {
namespace GUI {

/** Create a node control window and load a new ControlPanel for it.
 */
NodeControlWindow::NodeControlWindow(SharedPtr<NodeModel> node, uint32_t poly)
	: _node(node)
	, _position_stored(false)
	, _x(0)
	, _y(0)
{
	assert(_node != NULL);

	property_resizable() = true;
	set_border_width(5);

	set_title(_node->path().chop_scheme() + " Controls - Ingen");

	Glib::RefPtr<Gnome::Glade::Xml> xml = GladeFactory::new_glade_reference("warehouse_win");
	xml->get_widget_derived("control_panel_vbox", _control_panel);

	show_all_children();

	_control_panel->reparent(*this);
	_control_panel->init(_node, poly);
	_control_panel->show();

	resize();

	_callback_enabled = true;
}

/** Create a node control window and with an existing ControlPanel.
 */
NodeControlWindow::NodeControlWindow(SharedPtr<NodeModel> node, ControlPanel* panel)
	: _node(node)
	, _control_panel(panel)
{
	assert(_node);

	property_resizable() = true;
	set_border_width(5);

	set_title(_node->path().chop_scheme() + " Controls - Ingen");

	_control_panel->reparent(*this);

	show_all_children();
	resize();

	_callback_enabled = true;
}

NodeControlWindow::~NodeControlWindow()
{
	delete _control_panel;
}

void
NodeControlWindow::resize()
{
	pair<int,int> controls_size = _control_panel->ideal_size();
	int width  = controls_size.first;
	int height = controls_size.second;

	if (height > property_screen().get_value()->get_height() - 64)
		height = property_screen().get_value()->get_height() - 64;
	if (width > property_screen().get_value()->get_width() - 64)
		width = property_screen().get_value()->get_width() - 64;

	Gtk::Window::resize(width, height);
}

void
NodeControlWindow::on_show()
{
	for (NodeModel::Ports::const_iterator i = _node->ports().begin();
			i != _node->ports().end(); ++i)
		if ((*i)->is_input() && App::instance().can_control(i->get()))
			App::instance().engine()->request_property((*i)->path(),
					App::instance().uris().ingen_value);

	if (_position_stored)
		move(_x, _y);

	Gtk::Window::on_show();
}

void
NodeControlWindow::on_hide()
{
	_position_stored = true;
	get_position(_x, _y);
	Gtk::Window::on_hide();
}

} // namespace GUI
} // namespace Ingen
<commit_msg>Show human name instead of symbol in node control window (fix ticket #637).<commit_after>/* This file is part of Ingen.
 * Copyright (C) 2007-2009 David Robillard <http://drobilla.net>
 *
 * Ingen is free software; you can redistribute it and/or modify it under the
 * terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version.
 *
 * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for details.
 *
 * You should have received a copy of the GNU General Public License alongCont
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include <cmath>
#include "interface/EngineInterface.hpp"
#include "shared/LV2URIMap.hpp"
#include "client/NodeModel.hpp"
#include "App.hpp"
#include "NodeControlWindow.hpp"
#include "GladeFactory.hpp"
#include "Controls.hpp"
#include "ControlPanel.hpp"
#include "PatchWindow.hpp"

using namespace std;

namespace Ingen {
namespace GUI {

/** Create a node control window and load a new ControlPanel for it.
 */
NodeControlWindow::NodeControlWindow(SharedPtr<NodeModel> node, uint32_t poly)
	: _node(node)
	, _position_stored(false)
	, _x(0)
	, _y(0)
{
	assert(_node != NULL);

	property_resizable() = true;
	set_border_width(5);

	set_title(_node->plugin_model()->human_name() + " - Ingen");

	Glib::RefPtr<Gnome::Glade::Xml> xml = GladeFactory::new_glade_reference("warehouse_win");
	xml->get_widget_derived("control_panel_vbox", _control_panel);

	show_all_children();

	_control_panel->reparent(*this);
	_control_panel->init(_node, poly);
	_control_panel->show();

	resize();

	_callback_enabled = true;
}

/** Create a node control window and with an existing ControlPanel.
 */
NodeControlWindow::NodeControlWindow(SharedPtr<NodeModel> node, ControlPanel* panel)
	: _node(node)
	, _control_panel(panel)
{
	assert(_node);

	property_resizable() = true;
	set_border_width(5);

	set_title(_node->path().chop_scheme() + " Controls - Ingen");

	_control_panel->reparent(*this);

	show_all_children();
	resize();

	_callback_enabled = true;
}

NodeControlWindow::~NodeControlWindow()
{
	delete _control_panel;
}

void
NodeControlWindow::resize()
{
	pair<int,int> controls_size = _control_panel->ideal_size();
	int width  = controls_size.first;
	int height = controls_size.second;

	if (height > property_screen().get_value()->get_height() - 64)
		height = property_screen().get_value()->get_height() - 64;
	if (width > property_screen().get_value()->get_width() - 64)
		width = property_screen().get_value()->get_width() - 64;

	Gtk::Window::resize(width, height);
}

void
NodeControlWindow::on_show()
{
	for (NodeModel::Ports::const_iterator i = _node->ports().begin();
			i != _node->ports().end(); ++i)
		if ((*i)->is_input() && App::instance().can_control(i->get()))
			App::instance().engine()->request_property((*i)->path(),
					App::instance().uris().ingen_value);

	if (_position_stored)
		move(_x, _y);

	Gtk::Window::on_show();
}

void
NodeControlWindow::on_hide()
{
	_position_stored = true;
	get_position(_x, _y);
	Gtk::Window::on_hide();
}

} // namespace GUI
} // namespace Ingen
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: docruby.cxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: hr $ $Date: 2006-08-14 15:59:31 $
 *
 *  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

#include <string.h>         // fuer strchr()

#ifndef _HINTIDS_HXX
#include <hintids.hxx>
#endif

#ifndef _COM_SUN_STAR_I18N_UNICODETYPE_HDL
#include <com/sun/star/i18n/UnicodeType.hdl>
#endif
#ifndef _COM_SUN_STAR_I18N_WORDTYPE_HDL
#include <com/sun/star/i18n/WordType.hdl>
#endif
#ifndef _UNOTOOLS_CHARCLASS_HXX
#include <unotools/charclass.hxx>
#endif

#ifndef _DOC_HXX
#include <doc.hxx>
#endif
#ifndef _DOCARY_HXX
#include <docary.hxx>
#endif
#ifndef _MVSAVE_HXX
#include <mvsave.hxx>       // Strukturen zum Sichern beim Move/Delete
#endif
#ifndef _NDTXT_HXX
#include <ndtxt.hxx>
#endif
#ifndef _TXATBASE_HXX
#include <txatbase.hxx>
#endif
#ifndef _RUBYLIST_HXX
#include <rubylist.hxx>
#endif
#ifndef _PAM_HXX
#include <pam.hxx>
#endif
#ifndef _SWUNDO_HXX
#include <swundo.hxx>       // fuer die UndoIds
#endif
#ifndef _UNDOBJ_HXX
#include <undobj.hxx>
#endif
#ifndef _BREAKIT_HXX
#include <breakit.hxx>
#endif
#ifndef _CRSSKIP_HXX
#include <crsskip.hxx>
#endif

SV_IMPL_PTRARR( SwRubyList, SwRubyListEntryPtr )

using namespace ::com::sun::star::i18n;

/*
 * Members in the list:
 *   - String - the orig text
 *   - SwFmtRuby - the ruby attribut
 *
 *
 */
USHORT SwDoc::FillRubyList( const SwPaM& rPam, SwRubyList& rList,
                            USHORT nMode )
{
    const SwPaM *_pStartCrsr = (SwPaM*)rPam.GetNext(),
                *__pStartCrsr = _pStartCrsr;
    BOOL bCheckEmpty = &rPam != _pStartCrsr;
    do {
        const SwPosition* pStt = _pStartCrsr->Start(),
                        * pEnd = pStt == _pStartCrsr->GetPoint()
                                                ? _pStartCrsr->GetMark()
                                                : _pStartCrsr->GetPoint();
        if( !bCheckEmpty || ( pStt != pEnd && *pStt != *pEnd ))
        {
            SwPaM aPam( *pStt );
            do {
                SwRubyListEntry* pNew = new SwRubyListEntry;
                if( pEnd != pStt )
                {
                    aPam.SetMark();
                    *aPam.GetMark() = *pEnd;
                }
                if( _SelectNextRubyChars( aPam, *pNew, nMode ))
                {
                    rList.Insert( pNew, rList.Count() );
                    aPam.DeleteMark();
                }
                else
                {
                    delete pNew;
                     if( *aPam.GetPoint() < *pEnd )
                     {
                        // goto next paragraph
                        aPam.DeleteMark();
                        aPam.Move( fnMoveForward, fnGoNode );
                     }
                     else
                        break;
                }
            } while( 30 > rList.Count() && *aPam.GetPoint() < *pEnd );
        }
    } while( 30 > rList.Count() &&
        (_pStartCrsr=(SwPaM *)_pStartCrsr->GetNext()) != __pStartCrsr );

    return rList.Count();
}

USHORT SwDoc::SetRubyList( const SwPaM& rPam, const SwRubyList& rList,
                            USHORT nMode )
{
    StartUndo( UNDO_SETRUBYATTR, NULL );
    SvUShortsSort aDelArr;
    aDelArr.Insert( RES_TXTATR_CJK_RUBY );

    USHORT nListEntry = 0;

    const SwPaM *_pStartCrsr = (SwPaM*)rPam.GetNext(),
                *__pStartCrsr = _pStartCrsr;
    BOOL bCheckEmpty = &rPam != _pStartCrsr;
    do {
        const SwPosition* pStt = _pStartCrsr->Start(),
                        * pEnd = pStt == _pStartCrsr->GetPoint()
                                                ? _pStartCrsr->GetMark()
                                                : _pStartCrsr->GetPoint();
        if( !bCheckEmpty || ( pStt != pEnd && *pStt != *pEnd ))
        {

            SwPaM aPam( *pStt );
            do {
                SwRubyListEntry aCheckEntry;
                if( pEnd != pStt )
                {
                    aPam.SetMark();
                    *aPam.GetMark() = *pEnd;
                }
                if( _SelectNextRubyChars( aPam, aCheckEntry, nMode ))
                {
                    const SwRubyListEntry* pEntry = rList[ nListEntry++ ];
                    if( aCheckEntry.GetRubyAttr() != pEntry->GetRubyAttr() )
                    {
                        // set/reset the attribut
                        if( pEntry->GetRubyAttr().GetText().Len() )
                            Insert( aPam, pEntry->GetRubyAttr(), 0 );
                        else
                            ResetAttr( aPam, TRUE, &aDelArr );
                    }

                    if( aCheckEntry.GetText() != pEntry->GetText() &&
                        pEntry->GetText().Len() )
                    {
                        // text is changed, so replace the original
                        Replace( aPam, pEntry->GetText(), FALSE );
                    }
                    aPam.DeleteMark();
                }
                else
                {
                     if( *aPam.GetPoint() < *pEnd )
                     {
                        // goto next paragraph
                        aPam.DeleteMark();
                        aPam.Move( fnMoveForward, fnGoNode );
                     }
                     else
                    {
                        const SwRubyListEntry* pEntry = rList[ nListEntry++ ];

                        // set/reset the attribut
                        if( pEntry->GetRubyAttr().GetText().Len() &&
                            pEntry->GetText().Len() )
                        {
                            Insert( aPam, pEntry->GetText(), true );
                            aPam.SetMark();
                            aPam.GetMark()->nContent -= pEntry->GetText().Len();
                            Insert( aPam, pEntry->GetRubyAttr(), SETATTR_DONTEXPAND );
                        }
                        else
                            break;
                        aPam.DeleteMark();
                    }
                }
            } while( nListEntry < rList.Count() && *aPam.GetPoint() < *pEnd );
        }
    } while( 30 > rList.Count() &&
        (_pStartCrsr=(SwPaM *)_pStartCrsr->GetNext()) != __pStartCrsr );

    EndUndo( UNDO_SETRUBYATTR, NULL );

    return nListEntry;
}

BOOL SwDoc::_SelectNextRubyChars( SwPaM& rPam, SwRubyListEntry& rEntry,
                                    USHORT nMode )
{
    // Point must be the startposition, Mark is optional the end position
    SwPosition* pPos = rPam.GetPoint();
       const SwTxtNode* pTNd = pPos->nNode.GetNode().GetTxtNode();
    const String* pTxt = &pTNd->GetTxt();
    xub_StrLen nStart = pPos->nContent.GetIndex(), nEnd = pTxt->Len();

    BOOL bHasMark = rPam.HasMark();
    if( bHasMark )
    {
        // in the same node?
        if( rPam.GetMark()->nNode == pPos->nNode )
        {
            // then use that end
            xub_StrLen nTEnd = rPam.GetMark()->nContent.GetIndex();
            if( nTEnd < nEnd )
                nEnd = nTEnd;
        }
        rPam.DeleteMark();
    }

    // ----- search the start
    // --- look where a ruby attribut starts
    USHORT nHtIdx = USHRT_MAX;
    const SwpHints* pHts = pTNd->GetpSwpHints();
    const SwTxtAttr* pAttr = 0;
    if( pHts )
    {
        const SwTxtAttr* pHt;
        for( nHtIdx = 0; nHtIdx < pHts->Count(); ++nHtIdx )
            if( RES_TXTATR_CJK_RUBY == ( pHt = (*pHts)[ nHtIdx ])->Which() &&
                *pHt->GetAnyEnd() > nStart )
            {
                if( *pHt->GetStart() < nEnd )
                {
                    pAttr = pHt;
                    if( !bHasMark && nStart > *pAttr->GetStart() )
                    {
                        nStart = *pAttr->GetStart();
                        pPos->nContent = nStart;
                    }
                }
                break;
            }
    }

    if( !bHasMark && nStart && ( !pAttr || nStart != *pAttr->GetStart()) )
    {
        // skip to the word begin!
        long nWordStt = pBreakIt->xBreak->getWordBoundary(
                            *pTxt, nStart,
                            pBreakIt->GetLocale( pTNd->GetLang( nStart )),
                            WordType::ANYWORD_IGNOREWHITESPACES,
                            TRUE ).startPos;
        if( nWordStt < nStart && -1 != nWordStt )
        {
            nStart = (xub_StrLen)nWordStt;
            pPos->nContent = nStart;
        }
    }

    BOOL bAlphaNum = FALSE;
    long nWordEnd = nEnd;
    CharClass& rCC = GetAppCharClass();
    while(  nStart < nEnd )
    {
        if( pAttr && nStart == *pAttr->GetStart() )
        {
            pPos->nContent = nStart;
            if( !rPam.HasMark() )
            {
                rPam.SetMark();
                pPos->nContent = *pAttr->GetAnyEnd();
                if( pPos->nContent.GetIndex() > nEnd )
                    pPos->nContent = nEnd;
                rEntry.SetRubyAttr( pAttr->GetRuby() );
            }
            break;
        }

        sal_Int32 nChType = rCC.getType( *pTxt, nStart );
        BOOL bIgnoreChar = FALSE, bIsAlphaNum = FALSE, bChkNxtWrd = FALSE;
        switch( nChType )
        {
        case UnicodeType::UPPERCASE_LETTER:
        case UnicodeType::LOWERCASE_LETTER:
        case UnicodeType::TITLECASE_LETTER:
        case UnicodeType::DECIMAL_DIGIT_NUMBER:
                bChkNxtWrd = bIsAlphaNum = TRUE;
                break;

        case UnicodeType::SPACE_SEPARATOR:
        case UnicodeType::CONTROL:
/*??*/  case UnicodeType::PRIVATE_USE:
        case UnicodeType::START_PUNCTUATION:
        case UnicodeType::END_PUNCTUATION:
            bIgnoreChar = TRUE;
            break;

        case UnicodeType::OTHER_LETTER:
            bChkNxtWrd = TRUE;
            // no break!
//      case UnicodeType::UNASSIGNED:
//      case UnicodeType::MODIFIER_LETTER:
//      case UnicodeType::NON_SPACING_MARK:
//      case UnicodeType::ENCLOSING_MARK:
//      case UnicodeType::COMBINING_SPACING_MARK:
//      case UnicodeType::LETTER_NUMBER:
//      case UnicodeType::OTHER_NUMBER:
//      case UnicodeType::LINE_SEPARATOR:
//      case UnicodeType::PARAGRAPH_SEPARATOR:
//      case UnicodeType::FORMAT:
//      case UnicodeType::SURROGATE:
//      case UnicodeType::DASH_PUNCTUATION:
//      case UnicodeType::CONNECTOR_PUNCTUATION:
///*?? */case UnicodeType::OTHER_PUNCTUATION:
//--> char '!' is to ignore!
//      case UnicodeType::MATH_SYMBOL:
//      case UnicodeType::CURRENCY_SYMBOL:
//      case UnicodeType::MODIFIER_SYMBOL:
//      case UnicodeType::OTHER_SYMBOL:
//      case UnicodeType::INITIAL_PUNCTUATION:
//      case UnicodeType::FINAL_PUNCTUATION:
        default:
                bIsAlphaNum = FALSE;
                break;
        }

        if( rPam.HasMark() )
        {
            if( bIgnoreChar || bIsAlphaNum != bAlphaNum || nStart >= nWordEnd )
                break;
        }
        else if( !bIgnoreChar )
        {
            rPam.SetMark();
            bAlphaNum = bIsAlphaNum;
            if( bChkNxtWrd && pBreakIt->xBreak.is() )
            {
                // search the end of this word
                nWordEnd = pBreakIt->xBreak->getWordBoundary(
                            *pTxt, nStart,
                            pBreakIt->GetLocale( pTNd->GetLang( nStart )),
                            WordType::ANYWORD_IGNOREWHITESPACES,
                            TRUE ).endPos;
                if( 0 > nWordEnd || nWordEnd > nEnd || nWordEnd == nStart )
                    nWordEnd = nEnd;
            }
        }
        pTNd->GoNext( &pPos->nContent, CRSR_SKIP_CHARS );
        nStart = pPos->nContent.GetIndex();
    }

    nStart = rPam.GetMark()->nContent.GetIndex();
    rEntry.SetText( pTxt->Copy( nStart,
                           rPam.GetPoint()->nContent.GetIndex() - nStart ));
    return rPam.HasMark();
}

SwRubyListEntry::~SwRubyListEntry()
{
}
<commit_msg>INTEGRATION: CWS pchfix02 (1.9.2); FILE MERGED 2006/09/01 17:51:26 kaib 1.9.2.1: #i68856# Added header markers and pch files<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: docruby.cxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-16 20:54: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
 *
 ************************************************************************/

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

#include <string.h>         // fuer strchr()

#ifndef _HINTIDS_HXX
#include <hintids.hxx>
#endif

#ifndef _COM_SUN_STAR_I18N_UNICODETYPE_HDL
#include <com/sun/star/i18n/UnicodeType.hdl>
#endif
#ifndef _COM_SUN_STAR_I18N_WORDTYPE_HDL
#include <com/sun/star/i18n/WordType.hdl>
#endif
#ifndef _UNOTOOLS_CHARCLASS_HXX
#include <unotools/charclass.hxx>
#endif

#ifndef _DOC_HXX
#include <doc.hxx>
#endif
#ifndef _DOCARY_HXX
#include <docary.hxx>
#endif
#ifndef _MVSAVE_HXX
#include <mvsave.hxx>       // Strukturen zum Sichern beim Move/Delete
#endif
#ifndef _NDTXT_HXX
#include <ndtxt.hxx>
#endif
#ifndef _TXATBASE_HXX
#include <txatbase.hxx>
#endif
#ifndef _RUBYLIST_HXX
#include <rubylist.hxx>
#endif
#ifndef _PAM_HXX
#include <pam.hxx>
#endif
#ifndef _SWUNDO_HXX
#include <swundo.hxx>       // fuer die UndoIds
#endif
#ifndef _UNDOBJ_HXX
#include <undobj.hxx>
#endif
#ifndef _BREAKIT_HXX
#include <breakit.hxx>
#endif
#ifndef _CRSSKIP_HXX
#include <crsskip.hxx>
#endif

SV_IMPL_PTRARR( SwRubyList, SwRubyListEntryPtr )

using namespace ::com::sun::star::i18n;

/*
 * Members in the list:
 *   - String - the orig text
 *   - SwFmtRuby - the ruby attribut
 *
 *
 */
USHORT SwDoc::FillRubyList( const SwPaM& rPam, SwRubyList& rList,
                            USHORT nMode )
{
    const SwPaM *_pStartCrsr = (SwPaM*)rPam.GetNext(),
                *__pStartCrsr = _pStartCrsr;
    BOOL bCheckEmpty = &rPam != _pStartCrsr;
    do {
        const SwPosition* pStt = _pStartCrsr->Start(),
                        * pEnd = pStt == _pStartCrsr->GetPoint()
                                                ? _pStartCrsr->GetMark()
                                                : _pStartCrsr->GetPoint();
        if( !bCheckEmpty || ( pStt != pEnd && *pStt != *pEnd ))
        {
            SwPaM aPam( *pStt );
            do {
                SwRubyListEntry* pNew = new SwRubyListEntry;
                if( pEnd != pStt )
                {
                    aPam.SetMark();
                    *aPam.GetMark() = *pEnd;
                }
                if( _SelectNextRubyChars( aPam, *pNew, nMode ))
                {
                    rList.Insert( pNew, rList.Count() );
                    aPam.DeleteMark();
                }
                else
                {
                    delete pNew;
                     if( *aPam.GetPoint() < *pEnd )
                     {
                        // goto next paragraph
                        aPam.DeleteMark();
                        aPam.Move( fnMoveForward, fnGoNode );
                     }
                     else
                        break;
                }
            } while( 30 > rList.Count() && *aPam.GetPoint() < *pEnd );
        }
    } while( 30 > rList.Count() &&
        (_pStartCrsr=(SwPaM *)_pStartCrsr->GetNext()) != __pStartCrsr );

    return rList.Count();
}

USHORT SwDoc::SetRubyList( const SwPaM& rPam, const SwRubyList& rList,
                            USHORT nMode )
{
    StartUndo( UNDO_SETRUBYATTR, NULL );
    SvUShortsSort aDelArr;
    aDelArr.Insert( RES_TXTATR_CJK_RUBY );

    USHORT nListEntry = 0;

    const SwPaM *_pStartCrsr = (SwPaM*)rPam.GetNext(),
                *__pStartCrsr = _pStartCrsr;
    BOOL bCheckEmpty = &rPam != _pStartCrsr;
    do {
        const SwPosition* pStt = _pStartCrsr->Start(),
                        * pEnd = pStt == _pStartCrsr->GetPoint()
                                                ? _pStartCrsr->GetMark()
                                                : _pStartCrsr->GetPoint();
        if( !bCheckEmpty || ( pStt != pEnd && *pStt != *pEnd ))
        {

            SwPaM aPam( *pStt );
            do {
                SwRubyListEntry aCheckEntry;
                if( pEnd != pStt )
                {
                    aPam.SetMark();
                    *aPam.GetMark() = *pEnd;
                }
                if( _SelectNextRubyChars( aPam, aCheckEntry, nMode ))
                {
                    const SwRubyListEntry* pEntry = rList[ nListEntry++ ];
                    if( aCheckEntry.GetRubyAttr() != pEntry->GetRubyAttr() )
                    {
                        // set/reset the attribut
                        if( pEntry->GetRubyAttr().GetText().Len() )
                            Insert( aPam, pEntry->GetRubyAttr(), 0 );
                        else
                            ResetAttr( aPam, TRUE, &aDelArr );
                    }

                    if( aCheckEntry.GetText() != pEntry->GetText() &&
                        pEntry->GetText().Len() )
                    {
                        // text is changed, so replace the original
                        Replace( aPam, pEntry->GetText(), FALSE );
                    }
                    aPam.DeleteMark();
                }
                else
                {
                     if( *aPam.GetPoint() < *pEnd )
                     {
                        // goto next paragraph
                        aPam.DeleteMark();
                        aPam.Move( fnMoveForward, fnGoNode );
                     }
                     else
                    {
                        const SwRubyListEntry* pEntry = rList[ nListEntry++ ];

                        // set/reset the attribut
                        if( pEntry->GetRubyAttr().GetText().Len() &&
                            pEntry->GetText().Len() )
                        {
                            Insert( aPam, pEntry->GetText(), true );
                            aPam.SetMark();
                            aPam.GetMark()->nContent -= pEntry->GetText().Len();
                            Insert( aPam, pEntry->GetRubyAttr(), SETATTR_DONTEXPAND );
                        }
                        else
                            break;
                        aPam.DeleteMark();
                    }
                }
            } while( nListEntry < rList.Count() && *aPam.GetPoint() < *pEnd );
        }
    } while( 30 > rList.Count() &&
        (_pStartCrsr=(SwPaM *)_pStartCrsr->GetNext()) != __pStartCrsr );

    EndUndo( UNDO_SETRUBYATTR, NULL );

    return nListEntry;
}

BOOL SwDoc::_SelectNextRubyChars( SwPaM& rPam, SwRubyListEntry& rEntry,
                                    USHORT nMode )
{
    // Point must be the startposition, Mark is optional the end position
    SwPosition* pPos = rPam.GetPoint();
       const SwTxtNode* pTNd = pPos->nNode.GetNode().GetTxtNode();
    const String* pTxt = &pTNd->GetTxt();
    xub_StrLen nStart = pPos->nContent.GetIndex(), nEnd = pTxt->Len();

    BOOL bHasMark = rPam.HasMark();
    if( bHasMark )
    {
        // in the same node?
        if( rPam.GetMark()->nNode == pPos->nNode )
        {
            // then use that end
            xub_StrLen nTEnd = rPam.GetMark()->nContent.GetIndex();
            if( nTEnd < nEnd )
                nEnd = nTEnd;
        }
        rPam.DeleteMark();
    }

    // ----- search the start
    // --- look where a ruby attribut starts
    USHORT nHtIdx = USHRT_MAX;
    const SwpHints* pHts = pTNd->GetpSwpHints();
    const SwTxtAttr* pAttr = 0;
    if( pHts )
    {
        const SwTxtAttr* pHt;
        for( nHtIdx = 0; nHtIdx < pHts->Count(); ++nHtIdx )
            if( RES_TXTATR_CJK_RUBY == ( pHt = (*pHts)[ nHtIdx ])->Which() &&
                *pHt->GetAnyEnd() > nStart )
            {
                if( *pHt->GetStart() < nEnd )
                {
                    pAttr = pHt;
                    if( !bHasMark && nStart > *pAttr->GetStart() )
                    {
                        nStart = *pAttr->GetStart();
                        pPos->nContent = nStart;
                    }
                }
                break;
            }
    }

    if( !bHasMark && nStart && ( !pAttr || nStart != *pAttr->GetStart()) )
    {
        // skip to the word begin!
        long nWordStt = pBreakIt->xBreak->getWordBoundary(
                            *pTxt, nStart,
                            pBreakIt->GetLocale( pTNd->GetLang( nStart )),
                            WordType::ANYWORD_IGNOREWHITESPACES,
                            TRUE ).startPos;
        if( nWordStt < nStart && -1 != nWordStt )
        {
            nStart = (xub_StrLen)nWordStt;
            pPos->nContent = nStart;
        }
    }

    BOOL bAlphaNum = FALSE;
    long nWordEnd = nEnd;
    CharClass& rCC = GetAppCharClass();
    while(  nStart < nEnd )
    {
        if( pAttr && nStart == *pAttr->GetStart() )
        {
            pPos->nContent = nStart;
            if( !rPam.HasMark() )
            {
                rPam.SetMark();
                pPos->nContent = *pAttr->GetAnyEnd();
                if( pPos->nContent.GetIndex() > nEnd )
                    pPos->nContent = nEnd;
                rEntry.SetRubyAttr( pAttr->GetRuby() );
            }
            break;
        }

        sal_Int32 nChType = rCC.getType( *pTxt, nStart );
        BOOL bIgnoreChar = FALSE, bIsAlphaNum = FALSE, bChkNxtWrd = FALSE;
        switch( nChType )
        {
        case UnicodeType::UPPERCASE_LETTER:
        case UnicodeType::LOWERCASE_LETTER:
        case UnicodeType::TITLECASE_LETTER:
        case UnicodeType::DECIMAL_DIGIT_NUMBER:
                bChkNxtWrd = bIsAlphaNum = TRUE;
                break;

        case UnicodeType::SPACE_SEPARATOR:
        case UnicodeType::CONTROL:
/*??*/  case UnicodeType::PRIVATE_USE:
        case UnicodeType::START_PUNCTUATION:
        case UnicodeType::END_PUNCTUATION:
            bIgnoreChar = TRUE;
            break;

        case UnicodeType::OTHER_LETTER:
            bChkNxtWrd = TRUE;
            // no break!
//      case UnicodeType::UNASSIGNED:
//      case UnicodeType::MODIFIER_LETTER:
//      case UnicodeType::NON_SPACING_MARK:
//      case UnicodeType::ENCLOSING_MARK:
//      case UnicodeType::COMBINING_SPACING_MARK:
//      case UnicodeType::LETTER_NUMBER:
//      case UnicodeType::OTHER_NUMBER:
//      case UnicodeType::LINE_SEPARATOR:
//      case UnicodeType::PARAGRAPH_SEPARATOR:
//      case UnicodeType::FORMAT:
//      case UnicodeType::SURROGATE:
//      case UnicodeType::DASH_PUNCTUATION:
//      case UnicodeType::CONNECTOR_PUNCTUATION:
///*?? */case UnicodeType::OTHER_PUNCTUATION:
//--> char '!' is to ignore!
//      case UnicodeType::MATH_SYMBOL:
//      case UnicodeType::CURRENCY_SYMBOL:
//      case UnicodeType::MODIFIER_SYMBOL:
//      case UnicodeType::OTHER_SYMBOL:
//      case UnicodeType::INITIAL_PUNCTUATION:
//      case UnicodeType::FINAL_PUNCTUATION:
        default:
                bIsAlphaNum = FALSE;
                break;
        }

        if( rPam.HasMark() )
        {
            if( bIgnoreChar || bIsAlphaNum != bAlphaNum || nStart >= nWordEnd )
                break;
        }
        else if( !bIgnoreChar )
        {
            rPam.SetMark();
            bAlphaNum = bIsAlphaNum;
            if( bChkNxtWrd && pBreakIt->xBreak.is() )
            {
                // search the end of this word
                nWordEnd = pBreakIt->xBreak->getWordBoundary(
                            *pTxt, nStart,
                            pBreakIt->GetLocale( pTNd->GetLang( nStart )),
                            WordType::ANYWORD_IGNOREWHITESPACES,
                            TRUE ).endPos;
                if( 0 > nWordEnd || nWordEnd > nEnd || nWordEnd == nStart )
                    nWordEnd = nEnd;
            }
        }
        pTNd->GoNext( &pPos->nContent, CRSR_SKIP_CHARS );
        nStart = pPos->nContent.GetIndex();
    }

    nStart = rPam.GetMark()->nContent.GetIndex();
    rEntry.SetText( pTxt->Copy( nStart,
                           rPam.GetPoint()->nContent.GetIndex() - nStart ));
    return rPam.HasMark();
}

SwRubyListEntry::~SwRubyListEntry()
{
}
<|endoftext|>


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

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

#pragma hdrstop

#include "swtypes.hxx"
#include "swrect.hxx"
#include "scroll.hxx"

SwScrollbar::SwScrollbar( Window *pWin, int bHoriz ) :
    ScrollBar( pWin,
    WinBits( WB_3DLOOK | WB_HIDE | ( bHoriz ? WB_HSCROLL : WB_VSCROLL)  ) ),
    bHori( bHoriz ),
    bAuto( FALSE ),
    bThumbEnabled( TRUE ),
    bVisible(FALSE),
    bSizeSet(FALSE)
{
}

 SwScrollbar::~SwScrollbar() {}

/*------------------------------------------------------------------------
 Beschreibung:  wird nach einer Aenderung der Dokumentgroesse gerufen, um den
                Range des Scrollbars neu einzustellen.
------------------------------------------------------------------------*/

void SwScrollbar::DocSzChgd( const Size &rSize )
{
    aDocSz = rSize;
    SetRange( Range( 0, bHori ? rSize.Width() : rSize.Height()) );
    const ULONG nVisSize = GetVisibleSize();
    SetLineSize( nVisSize * 10 / 100 );
    SetPageSize( nVisSize * 77 / 100 );
}

/*------------------------------------------------------------------------
 Beschreibung:  wird nach einer Veraenderung des sichtbaren Ausschnittes
                gerufen.
------------------------------------------------------------------------*/

void SwScrollbar::ViewPortChgd( const Rectangle &rRect )
{
    long nThumb, nVisible;
    if( bHori )
    {
        nThumb = rRect.Left();
        nVisible = rRect.GetWidth();
    }
    else
    {
        nThumb = rRect.Top();
        nVisible = rRect.GetHeight();
    }

    SetVisibleSize( nVisible );
    DocSzChgd(aDocSz);
    if ( bThumbEnabled )
        SetThumbPos( nThumb );
    long nVis = GetVisibleSize();
    long nLen = GetRange().Len();
    if(bAuto)
        AutoShow();
}

void SwScrollbar::EnableThumbPos( BOOL bEnable, const SwRect &rVisArea )
{
    bThumbEnabled = bEnable;
    if ( bEnable )
    {
        long nThumb = bHori ? rVisArea.Left() : rVisArea.Top();
        SetThumbPos( nThumb );
    }
}

/*-----------------10/21/97 02:48pm-----------------

--------------------------------------------------*/
void SwScrollbar::Show( BOOL bSet )
{
    bVisible = bSet;
    if( (!bSet || bSizeSet || !bAuto) && IsUpdateMode() )
        ScrollBar::Show(bSet);
}

/*-----------------10/21/97 03:23pm-----------------

--------------------------------------------------*/
void SwScrollbar::SetPosSizePixel( const Point& rNewPos, const Size& rNewSize )
{
    ScrollBar::SetPosSizePixel(rNewPos, rNewSize);
    bSizeSet = TRUE;
    if(bVisible)
        Show();

}

/*-----------------10/21/97 04:47pm-----------------

--------------------------------------------------*/
void SwScrollbar::SetUpdateMode( BOOL bUpdate )
{
    ScrollBar::SetUpdateMode( bUpdate );
    if(bUpdate &&
        bVisible != ScrollBar::IsVisible())
    {
        if(bAuto)
            AutoShow();
        else
            ScrollBar::Show(bVisible);
    }
}
/*-----------------14.04.98 11:38-------------------

--------------------------------------------------*/
void SwScrollbar::SetAuto(BOOL bSet)
{
    if(bAuto != bSet)
    {
        bAuto = bSet;

        // automatisch versteckt - dann anzeigen
        if(!bAuto && bVisible && !ScrollBar::IsVisible())
            Show(TRUE);
        else if(bAuto)
            AutoShow(); // oder automatisch verstecken
    }
}
/*-----------------14.04.98 11:43-------------------

--------------------------------------------------*/
void SwScrollbar::AutoShow()
{
    long nVis = GetVisibleSize();
    long nLen = GetRange().Len();
    {
        if( nVis >= nLen - 1)
        {
            if(ScrollBar::IsVisible())
                ScrollBar::Show(FALSE);
        }
        else if ( !ScrollBar::IsVisible() &&
                  (!bHori || nVis) )        //Optimierung fuer Browser.
                                            //Horizontaler Scrollbar per
                                            //default aus.
        {
            ScrollBar::Show(TRUE);
        }
    }
}
<commit_msg>#103358# no UI mirroring for horz scrollbars<commit_after>/*************************************************************************
 *
 *  $RCSfile: scroll.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: ssa $ $Date: 2002-09-17 09:40:27 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

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

#pragma hdrstop

#include "swtypes.hxx"
#include "swrect.hxx"
#include "scroll.hxx"

SwScrollbar::SwScrollbar( Window *pWin, int bHoriz ) :
    ScrollBar( pWin,
    WinBits( WB_3DLOOK | WB_HIDE | ( bHoriz ? WB_HSCROLL : WB_VSCROLL)  ) ),
    bHori( bHoriz ),
    bAuto( FALSE ),
    bThumbEnabled( TRUE ),
    bVisible(FALSE),
    bSizeSet(FALSE)
{
    // SSA: --- RTL --- no mirroring for horizontal scrollbars
    if( bHoriz )
        EnableRTL( FALSE );
}

 SwScrollbar::~SwScrollbar() {}

/*------------------------------------------------------------------------
 Beschreibung:  wird nach einer Aenderung der Dokumentgroesse gerufen, um den
                Range des Scrollbars neu einzustellen.
------------------------------------------------------------------------*/

void SwScrollbar::DocSzChgd( const Size &rSize )
{
    aDocSz = rSize;
    SetRange( Range( 0, bHori ? rSize.Width() : rSize.Height()) );
    const ULONG nVisSize = GetVisibleSize();
    SetLineSize( nVisSize * 10 / 100 );
    SetPageSize( nVisSize * 77 / 100 );
}

/*------------------------------------------------------------------------
 Beschreibung:  wird nach einer Veraenderung des sichtbaren Ausschnittes
                gerufen.
------------------------------------------------------------------------*/

void SwScrollbar::ViewPortChgd( const Rectangle &rRect )
{
    long nThumb, nVisible;
    if( bHori )
    {
        nThumb = rRect.Left();
        nVisible = rRect.GetWidth();
    }
    else
    {
        nThumb = rRect.Top();
        nVisible = rRect.GetHeight();
    }

    SetVisibleSize( nVisible );
    DocSzChgd(aDocSz);
    if ( bThumbEnabled )
        SetThumbPos( nThumb );
    long nVis = GetVisibleSize();
    long nLen = GetRange().Len();
    if(bAuto)
        AutoShow();
}

void SwScrollbar::EnableThumbPos( BOOL bEnable, const SwRect &rVisArea )
{
    bThumbEnabled = bEnable;
    if ( bEnable )
    {
        long nThumb = bHori ? rVisArea.Left() : rVisArea.Top();
        SetThumbPos( nThumb );
    }
}

/*-----------------10/21/97 02:48pm-----------------

--------------------------------------------------*/
void SwScrollbar::Show( BOOL bSet )
{
    bVisible = bSet;
    if( (!bSet || bSizeSet || !bAuto) && IsUpdateMode() )
        ScrollBar::Show(bSet);
}

/*-----------------10/21/97 03:23pm-----------------

--------------------------------------------------*/
void SwScrollbar::SetPosSizePixel( const Point& rNewPos, const Size& rNewSize )
{
    ScrollBar::SetPosSizePixel(rNewPos, rNewSize);
    bSizeSet = TRUE;
    if(bVisible)
        Show();

}

/*-----------------10/21/97 04:47pm-----------------

--------------------------------------------------*/
void SwScrollbar::SetUpdateMode( BOOL bUpdate )
{
    ScrollBar::SetUpdateMode( bUpdate );
    if(bUpdate &&
        bVisible != ScrollBar::IsVisible())
    {
        if(bAuto)
            AutoShow();
        else
            ScrollBar::Show(bVisible);
    }
}
/*-----------------14.04.98 11:38-------------------

--------------------------------------------------*/
void SwScrollbar::SetAuto(BOOL bSet)
{
    if(bAuto != bSet)
    {
        bAuto = bSet;

        // automatisch versteckt - dann anzeigen
        if(!bAuto && bVisible && !ScrollBar::IsVisible())
            Show(TRUE);
        else if(bAuto)
            AutoShow(); // oder automatisch verstecken
    }
}
/*-----------------14.04.98 11:43-------------------

--------------------------------------------------*/
void SwScrollbar::AutoShow()
{
    long nVis = GetVisibleSize();
    long nLen = GetRange().Len();
    {
        if( nVis >= nLen - 1)
        {
            if(ScrollBar::IsVisible())
                ScrollBar::Show(FALSE);
        }
        else if ( !ScrollBar::IsVisible() &&
                  (!bHori || nVis) )        //Optimierung fuer Browser.
                                            //Horizontaler Scrollbar per
                                            //default aus.
        {
            ScrollBar::Show(TRUE);
        }
    }
}
<|endoftext|>