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

// ============================================================================

#ifndef SC_XLROOT_HXX
#include "xlroot.hxx"
#endif

#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif
#ifndef _SFX_OBJSH_HXX
#include <sfx2/objsh.hxx>
#endif
#ifndef _SFX_PRINTER_HXX
#include <sfx2/printer.hxx>
#endif
#ifndef _SV_FONT_HXX
#include <vcl/font.hxx>
#endif
#ifndef _EDITSTAT_HXX
#include <svx/editstat.hxx>
#endif

#ifndef _COM_SUN_STAR_UNO_REFERENCE_HXX_
#include <com/sun/star/uno/Reference.hxx>
#endif

#ifndef SC_ITEMS_HXX
#include "scitems.hxx"
#endif
#ifndef _EEITEM_HXX
#include <svx/eeitem.hxx>
#endif

#ifndef SC_DOCUMENT_HXX
#include "document.hxx"
#endif
#ifndef SC_SCDOCPOL_HXX
#include "docpool.hxx"
#endif
#ifndef SC_DOCUNO_HXX
#include "docuno.hxx"
#endif
#ifndef SC_EDITUTIL_HXX
#include "editutil.hxx"
#endif
#ifndef SC_DRWLAYER_HXX
#include "drwlayer.hxx"
#endif
#ifndef SC_SCPATATR_HXX
#include "patattr.hxx"
#endif

#ifndef SC_XLSTYLE_HXX
#include "xlstyle.hxx"
#endif
#ifndef SC_XLTRACER_HXX
#include "xltracer.hxx"
#endif

#include "root.hxx"

namespace com { namespace sun { namespace star { namespace frame { class XModel; } } } }

using ::com::sun::star::uno::Reference;
using ::com::sun::star::frame::XModel;

// Global data ================================================================

XclRootData::XclRootData( XclBiff eBiff, ScDocument& rDocument, const String& rDocUrl, CharSet eCharSet ) :
    meBiff( eBiff ),
    mrDoc( rDocument ),
    maDocUrl( rDocUrl ),
    maBasePath( rDocUrl, 0, rDocUrl.SearchBackward( '/' ) + 1 ),
    meCharSet( eCharSet ),
    meSysLang( Application::GetSettings().GetLanguage() ),
    meDocLang( Application::GetSettings().GetLanguage() ),
    meUILang( Application::GetSettings().GetUILanguage() ),
    maScMaxPos( MAXCOL, MAXROW, MAXTAB ),
    maXclMaxPos( EXC_MAXCOL_BIFF2, EXC_MAXROW_BIFF2, EXC_MAXTAB_BIFF2 ),
    mnCharWidth( 110 ),
    mnScTab( 0 ),
    mbTruncated( false ),
    mpRDP( new RootData )//!
{
#ifdef DBG_UTIL
    mnObjCnt = 0;
#endif
}

XclRootData::~XclRootData()
{
#ifdef DBG_UTIL
    DBG_ASSERT( mnObjCnt == 0, "XclRootData::~XclRootData - wrong object count" );
#endif
}

// ----------------------------------------------------------------------------

XclRoot::XclRoot( XclRootData& rRootData ) :
    mrData( rRootData ),
    mpRD( rRootData.mpRDP.get() )//!
{
#ifdef DBG_UTIL
    ++mrData.mnObjCnt;
#endif
    if( GetBiff() != xlBiffUnknown )
        SetMaxPos();
}

XclRoot::XclRoot( const XclRoot& rRoot ) :
    mrData( rRoot.mrData ),
    mpRD( rRoot.mpRD )//!
{
#ifdef DBG_UTIL
    ++mrData.mnObjCnt;
#endif
}

XclRoot::~XclRoot()
{
#ifdef DBG_UTIL
    --mrData.mnObjCnt;
#endif
}

XclRoot& XclRoot::operator=( const XclRoot& rRoot )
{
    // allowed for assignment in derived classes - but test if the same root data is used
    DBG_ASSERT( &mrData == &rRoot.mrData, "XclRoot::operator= - incompatible root data" );
    return *this;
}

void XclRoot::SetBiff( XclBiff eBiff )
{
    mrData.meBiff = eBiff;
    if( eBiff != xlBiffUnknown )
        SetMaxPos();
}

void XclRoot::SetCharWidth( const XclFontData& rFontData )
{
    if( SfxPrinter* pPrinter = GetPrinter() )
    {
        Font aFont( rFontData.maName, Size( 0, rFontData.mnHeight ) );
        aFont.SetFamily( rFontData.GetScFamily( GetCharSet() ) );
        aFont.SetCharSet( rFontData.GetScCharSet() );
        aFont.SetWeight( rFontData.GetScWeight() );
        pPrinter->SetFont( aFont );
        mrData.mnCharWidth = pPrinter->GetTextWidth( String( '0' ) );
    }
    else
        mrData.mnCharWidth = 11 * rFontData.mnHeight / 20;
}

void XclRoot::SetMaxPos()
{
    switch( GetBiff() )
    {
        case xlBiff2:
        case xlBiff3:   mrData.maXclMaxPos.Set( EXC_MAXCOL_BIFF2, EXC_MAXROW_BIFF2, EXC_MAXTAB_BIFF2 );    break;
        case xlBiff4:
        case xlBiff5:
        case xlBiff7:   mrData.maXclMaxPos.Set( EXC_MAXCOL_BIFF4, EXC_MAXROW_BIFF4, EXC_MAXTAB_BIFF4 );    break;
        case xlBiff8:   mrData.maXclMaxPos.Set( EXC_MAXCOL_BIFF8, EXC_MAXROW_BIFF8, EXC_MAXTAB_BIFF8 );    break;
        default:        DBG_ERROR_BIFF();
    }
}

SfxObjectShell* XclRoot::GetDocShell() const
{
    return GetDoc().GetDocumentShell();
}

ScModelObj* XclRoot::GetDocModelObj() const
{
    SfxObjectShell* pDocShell = GetDocShell();
    return pDocShell ? ScModelObj::getImplementation( Reference< XModel >( pDocShell->GetModel() ) ) : NULL;
}

SfxPrinter* XclRoot::GetPrinter() const
{
    return GetDoc().GetPrinter();
}

SvNumberFormatter& XclRoot::GetFormatter() const
{
    return *GetDoc().GetFormatTable();
}

ScStyleSheetPool& XclRoot::GetStyleSheetPool() const
{
    return *GetDoc().GetStyleSheetPool();
}

ScRangeName& XclRoot::GetNamedRanges() const
{
    return *GetDoc().GetRangeName();
}

SvStorage* XclRoot::GetRootStorage() const
{
    return mpRD->pRootStorage;
}

ScEditEngineDefaulter& XclRoot::GetEditEngine() const
{
    if( !mrData.mpEditEngine.get() )
    {
        mrData.mpEditEngine.reset( new ScEditEngineDefaulter( GetDoc().GetEnginePool() ) );
        ScEditEngineDefaulter& rEE = *mrData.mpEditEngine;
        rEE.SetRefMapMode( MAP_100TH_MM );
        rEE.SetEditTextObjectPool( GetDoc().GetEditPool() );
        rEE.SetUpdateMode( FALSE );
        rEE.EnableUndo( FALSE );
        rEE.SetControlWord( rEE.GetControlWord() & ~EE_CNTRL_ALLOWBIGOBJS );
    }
    return *mrData.mpEditEngine;
}

ScHeaderEditEngine& XclRoot::GetHFEditEngine() const
{
    if( !mrData.mpHFEditEngine.get() )
    {
        mrData.mpHFEditEngine.reset( new ScHeaderEditEngine( EditEngine::CreatePool(), TRUE ) );
        ScHeaderEditEngine& rEE = *mrData.mpHFEditEngine;
        rEE.SetRefMapMode( MAP_TWIP );  // headers/footers use twips as default metric
        rEE.SetUpdateMode( FALSE );
        rEE.EnableUndo( FALSE );
        rEE.SetControlWord( rEE.GetControlWord() & ~EE_CNTRL_ALLOWBIGOBJS );

        // set Calc header/footer defaults
        SfxItemSet* pEditSet = new SfxItemSet( rEE.GetEmptyItemSet() );
        SfxItemSet aItemSet( *GetDoc().GetPool(), ATTR_PATTERN_START, ATTR_PATTERN_END );
        ScPatternAttr::FillToEditItemSet( *pEditSet, aItemSet );
        // FillToEditItemSet() adjusts font height to 1/100th mm, we need twips
        pEditSet->Put( aItemSet.Get( ATTR_FONT_HEIGHT ), EE_CHAR_FONTHEIGHT );
        pEditSet->Put( aItemSet.Get( ATTR_CJK_FONT_HEIGHT ), EE_CHAR_FONTHEIGHT_CJK );
        pEditSet->Put( aItemSet.Get( ATTR_CTL_FONT_HEIGHT ), EE_CHAR_FONTHEIGHT_CTL );
        rEE.SetDefaults( pEditSet );    // takes ownership
   }
    return *mrData.mpHFEditEngine;
}

EditEngine& XclRoot::GetDrawEditEngine() const
{
    if( !mrData.mpDrawEditEng.get() )
    {
        mrData.mpDrawEditEng.reset( new EditEngine( &GetDoc().GetDrawLayer()->GetItemPool() ) );
        EditEngine& rEE = *mrData.mpDrawEditEng;
        rEE.SetRefMapMode( MAP_100TH_MM );
        rEE.SetUpdateMode( FALSE );
        rEE.EnableUndo( FALSE );
        rEE.SetControlWord( rEE.GetControlWord() & ~EE_CNTRL_ALLOWBIGOBJS );
    }
    return *mrData.mpDrawEditEng;
}

XclTracer& XclRoot::GetTracer() const
{
    return *mrData.mpTracer;
}

bool XclRoot::CheckCellAddress( const ScAddress& rPos, const ScAddress& rMaxPos ) const
{
    bool bValid = (rPos.Col() <= rMaxPos.Col()) && (rPos.Row() <= rMaxPos.Row()) && (rPos.Tab() <= rMaxPos.Tab());
    if( !bValid )
    {
        mrData.mbTruncated = true;
        GetTracer().TraceInvalidAddress(rPos, rMaxPos);
    }
    return bValid;
}

bool XclRoot::CheckCellRange( ScRange& rRange, const ScAddress& rMaxPos ) const
{
    rRange.Justify();

    // check start position
    bool bValidStart = CheckCellAddress( rRange.aStart, rMaxPos );

    // check & correct end position
    if( bValidStart )
    {
        CheckCellAddress( rRange.aEnd, rMaxPos );

        if( rRange.aEnd.Col() > rMaxPos.Col() )
            rRange.aEnd.SetCol( rMaxPos.Col() );
        if( rRange.aEnd.Row() > rMaxPos.Row() )
            rRange.aEnd.SetRow( rMaxPos.Row() );
        if( rRange.aEnd.Tab() > rMaxPos.Tab() )
            rRange.aEnd.SetTab( rMaxPos.Tab() );
    }

    return bValidStart;
}

void XclRoot::CheckCellRangeList( ScRangeList& rRanges, const ScAddress& rMaxPos ) const
{
    sal_uInt32 nIndex = rRanges.Count();
    while( nIndex )
    {
        --nIndex;   // backwards to keep nIndex valid
        ScRange* pRange = rRanges.GetObject( nIndex );
        if( pRange && !CheckCellRange( *pRange, rMaxPos ) )
            delete rRanges.Remove( nIndex );
    }
}

// ============================================================================

<commit_msg>INTEGRATION: CWS calcrtl (1.7.56); FILE MERGED 2003/11/27 11:30:54 nn 1.7.56.3: RESYNC: (1.8-1.9); FILE MERGED 2003/11/04 16:25:09 nn 1.7.56.2: RESYNC: (1.7-1.8); FILE MERGED 2003/10/10 15:33:29 dr 1.7.56.1: #i1967# first preparations for >32000 rows<commit_after>/*************************************************************************
 *
 *  $RCSfile: xlroot.cxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: hr $ $Date: 2004-02-03 12:24:45 $
 *
 *  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 SC_XLROOT_HXX
#include "xlroot.hxx"
#endif

#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif
#ifndef _SFX_OBJSH_HXX
#include <sfx2/objsh.hxx>
#endif
#ifndef _SFX_PRINTER_HXX
#include <sfx2/printer.hxx>
#endif
#ifndef _SV_FONT_HXX
#include <vcl/font.hxx>
#endif
#ifndef _EDITSTAT_HXX
#include <svx/editstat.hxx>
#endif

#ifndef _COM_SUN_STAR_UNO_REFERENCE_HXX_
#include <com/sun/star/uno/Reference.hxx>
#endif

#ifndef SC_ITEMS_HXX
#include "scitems.hxx"
#endif
#ifndef _EEITEM_HXX
#include <svx/eeitem.hxx>
#endif

#ifndef SC_DOCUMENT_HXX
#include "document.hxx"
#endif
#ifndef SC_SCDOCPOL_HXX
#include "docpool.hxx"
#endif
#ifndef SC_DOCUNO_HXX
#include "docuno.hxx"
#endif
#ifndef SC_EDITUTIL_HXX
#include "editutil.hxx"
#endif
#ifndef SC_DRWLAYER_HXX
#include "drwlayer.hxx"
#endif
#ifndef SC_SCPATATR_HXX
#include "patattr.hxx"
#endif

#ifndef SC_XLSTYLE_HXX
#include "xlstyle.hxx"
#endif
#ifndef SC_XLTRACER_HXX
#include "xltracer.hxx"
#endif

#include "root.hxx"

namespace com { namespace sun { namespace star { namespace frame { class XModel; } } } }

using ::com::sun::star::uno::Reference;
using ::com::sun::star::frame::XModel;

// Global data ================================================================

XclRootData::XclRootData( XclBiff eBiff, ScDocument& rDocument, const String& rDocUrl, CharSet eCharSet ) :
    meBiff( eBiff ),
    mrDoc( rDocument ),
    maDocUrl( rDocUrl ),
    maBasePath( rDocUrl, 0, rDocUrl.SearchBackward( '/' ) + 1 ),
    meCharSet( eCharSet ),
    meSysLang( Application::GetSettings().GetLanguage() ),
    meDocLang( Application::GetSettings().GetLanguage() ),
    meUILang( Application::GetSettings().GetUILanguage() ),
    maScMaxPos( SCMAXCOL, SCMAXROW, SCMAXTAB ),
    maXclMaxPos( EXC_MAXCOL2, EXC_MAXROW2, EXC_MAXTAB2 ),
    mnCharWidth( 110 ),
    mnScTab( 0 ),
    mbTruncated( false ),
    mpRDP( new RootData )//!
{
#ifdef DBG_UTIL
    mnObjCnt = 0;
#endif
}

XclRootData::~XclRootData()
{
#ifdef DBG_UTIL
    DBG_ASSERT( mnObjCnt == 0, "XclRootData::~XclRootData - wrong object count" );
#endif
}

// ----------------------------------------------------------------------------

XclRoot::XclRoot( XclRootData& rRootData ) :
    mrData( rRootData ),
    mpRD( rRootData.mpRDP.get() )//!
{
#ifdef DBG_UTIL
    ++mrData.mnObjCnt;
#endif
    if( GetBiff() != xlBiffUnknown )
        SetMaxPos();
}

XclRoot::XclRoot( const XclRoot& rRoot ) :
    mrData( rRoot.mrData ),
    mpRD( rRoot.mpRD )//!
{
#ifdef DBG_UTIL
    ++mrData.mnObjCnt;
#endif
}

XclRoot::~XclRoot()
{
#ifdef DBG_UTIL
    --mrData.mnObjCnt;
#endif
}

XclRoot& XclRoot::operator=( const XclRoot& rRoot )
{
    // allowed for assignment in derived classes - but test if the same root data is used
    DBG_ASSERT( &mrData == &rRoot.mrData, "XclRoot::operator= - incompatible root data" );
    return *this;
}

void XclRoot::SetBiff( XclBiff eBiff )
{
    mrData.meBiff = eBiff;
    if( eBiff != xlBiffUnknown )
        SetMaxPos();
}

void XclRoot::SetCharWidth( const XclFontData& rFontData )
{
    if( SfxPrinter* pPrinter = GetPrinter() )
    {
        Font aFont( rFontData.maName, Size( 0, rFontData.mnHeight ) );
        aFont.SetFamily( rFontData.GetScFamily( GetCharSet() ) );
        aFont.SetCharSet( rFontData.GetScCharSet() );
        aFont.SetWeight( rFontData.GetScWeight() );
        pPrinter->SetFont( aFont );
        mrData.mnCharWidth = pPrinter->GetTextWidth( String( '0' ) );
    }
    else
        mrData.mnCharWidth = 11 * rFontData.mnHeight / 20;
}

void XclRoot::SetMaxPos()
{
    switch( GetBiff() )
    {
        case xlBiff2:   mrData.maXclMaxPos.Set( EXC_MAXCOL2, EXC_MAXROW2, EXC_MAXTAB2 );    break;
        case xlBiff3:   mrData.maXclMaxPos.Set( EXC_MAXCOL3, EXC_MAXROW3, EXC_MAXTAB3 );    break;
        case xlBiff4:   mrData.maXclMaxPos.Set( EXC_MAXCOL4, EXC_MAXROW4, EXC_MAXTAB4 );    break;
        case xlBiff5:
        case xlBiff7:   mrData.maXclMaxPos.Set( EXC_MAXCOL5, EXC_MAXROW5, EXC_MAXTAB5 );    break;
        case xlBiff8:   mrData.maXclMaxPos.Set( EXC_MAXCOL8, EXC_MAXROW8, EXC_MAXTAB8 );    break;
        default:        DBG_ERROR_BIFF();
    }
}

SfxObjectShell* XclRoot::GetDocShell() const
{
    return GetDoc().GetDocumentShell();
}

ScModelObj* XclRoot::GetDocModelObj() const
{
    SfxObjectShell* pDocShell = GetDocShell();
    return pDocShell ? ScModelObj::getImplementation( Reference< XModel >( pDocShell->GetModel() ) ) : NULL;
}

SfxPrinter* XclRoot::GetPrinter() const
{
    return GetDoc().GetPrinter();
}

SvNumberFormatter& XclRoot::GetFormatter() const
{
    return *GetDoc().GetFormatTable();
}

ScStyleSheetPool& XclRoot::GetStyleSheetPool() const
{
    return *GetDoc().GetStyleSheetPool();
}

ScRangeName& XclRoot::GetNamedRanges() const
{
    return *GetDoc().GetRangeName();
}

SvStorage* XclRoot::GetRootStorage() const
{
    return mpRD->pRootStorage;
}

ScEditEngineDefaulter& XclRoot::GetEditEngine() const
{
    if( !mrData.mpEditEngine.get() )
    {
        mrData.mpEditEngine.reset( new ScEditEngineDefaulter( GetDoc().GetEnginePool() ) );
        ScEditEngineDefaulter& rEE = *mrData.mpEditEngine;
        rEE.SetRefMapMode( MAP_100TH_MM );
        rEE.SetEditTextObjectPool( GetDoc().GetEditPool() );
        rEE.SetUpdateMode( FALSE );
        rEE.EnableUndo( FALSE );
        rEE.SetControlWord( rEE.GetControlWord() & ~EE_CNTRL_ALLOWBIGOBJS );
    }
    return *mrData.mpEditEngine;
}

ScHeaderEditEngine& XclRoot::GetHFEditEngine() const
{
    if( !mrData.mpHFEditEngine.get() )
    {
        mrData.mpHFEditEngine.reset( new ScHeaderEditEngine( EditEngine::CreatePool(), TRUE ) );
        ScHeaderEditEngine& rEE = *mrData.mpHFEditEngine;
        rEE.SetRefMapMode( MAP_TWIP );  // headers/footers use twips as default metric
        rEE.SetUpdateMode( FALSE );
        rEE.EnableUndo( FALSE );
        rEE.SetControlWord( rEE.GetControlWord() & ~EE_CNTRL_ALLOWBIGOBJS );

        // set Calc header/footer defaults
        SfxItemSet* pEditSet = new SfxItemSet( rEE.GetEmptyItemSet() );
        SfxItemSet aItemSet( *GetDoc().GetPool(), ATTR_PATTERN_START, ATTR_PATTERN_END );
        ScPatternAttr::FillToEditItemSet( *pEditSet, aItemSet );
        // FillToEditItemSet() adjusts font height to 1/100th mm, we need twips
        pEditSet->Put( aItemSet.Get( ATTR_FONT_HEIGHT ), EE_CHAR_FONTHEIGHT );
        pEditSet->Put( aItemSet.Get( ATTR_CJK_FONT_HEIGHT ), EE_CHAR_FONTHEIGHT_CJK );
        pEditSet->Put( aItemSet.Get( ATTR_CTL_FONT_HEIGHT ), EE_CHAR_FONTHEIGHT_CTL );
        rEE.SetDefaults( pEditSet );    // takes ownership
   }
    return *mrData.mpHFEditEngine;
}

EditEngine& XclRoot::GetDrawEditEngine() const
{
    if( !mrData.mpDrawEditEng.get() )
    {
        mrData.mpDrawEditEng.reset( new EditEngine( &GetDoc().GetDrawLayer()->GetItemPool() ) );
        EditEngine& rEE = *mrData.mpDrawEditEng;
        rEE.SetRefMapMode( MAP_100TH_MM );
        rEE.SetUpdateMode( FALSE );
        rEE.EnableUndo( FALSE );
        rEE.SetControlWord( rEE.GetControlWord() & ~EE_CNTRL_ALLOWBIGOBJS );
    }
    return *mrData.mpDrawEditEng;
}

XclTracer& XclRoot::GetTracer() const
{
    return *mrData.mpTracer;
}

bool XclRoot::CheckCellAddress( const ScAddress& rPos, const ScAddress& rMaxPos ) const
{
    bool bValid = (rPos.Col() <= rMaxPos.Col()) && (rPos.Row() <= rMaxPos.Row()) && (rPos.Tab() <= rMaxPos.Tab());
    if( !bValid )
    {
        mrData.mbTruncated = true;
        GetTracer().TraceInvalidAddress(rPos, rMaxPos);
    }
    return bValid;
}

bool XclRoot::CheckCellRange( ScRange& rRange, const ScAddress& rMaxPos ) const
{
    rRange.Justify();

    // check start position
    bool bValidStart = CheckCellAddress( rRange.aStart, rMaxPos );

    // check & correct end position
    if( bValidStart )
    {
        CheckCellAddress( rRange.aEnd, rMaxPos );

        if( rRange.aEnd.Col() > rMaxPos.Col() )
            rRange.aEnd.SetCol( rMaxPos.Col() );
        if( rRange.aEnd.Row() > rMaxPos.Row() )
            rRange.aEnd.SetRow( rMaxPos.Row() );
        if( rRange.aEnd.Tab() > rMaxPos.Tab() )
            rRange.aEnd.SetTab( rMaxPos.Tab() );
    }

    return bValidStart;
}

void XclRoot::CheckCellRangeList( ScRangeList& rRanges, const ScAddress& rMaxPos ) const
{
    sal_uInt32 nIndex = rRanges.Count();
    while( nIndex )
    {
        --nIndex;   // backwards to keep nIndex valid
        ScRange* pRange = rRanges.GetObject( nIndex );
        if( pRange && !CheckCellRange( *pRange, rMaxPos ) )
            delete rRanges.Remove( nIndex );
    }
}

// ============================================================================

<|endoftext|>


<commit_before>#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;

int main()
{
	int i = 0, n = 0, j = 0, k = 0, tmp = 0;
	char ch;
	srand(time(NULL)); // initalizes seed value
	cout<<"How many numbers would you like to have on your list?"<<endl;
	cin>>n;
	int *list = new int [n];
	cout<<"Please enter the integers."<<endl;
	for(i = 0; i < n; i++)
	{
		cin>>list[i];
 	}
	cout<<"The list you have entered is ";
	for(i = 0; i < n; i++)
	{
		cout<<list[i]<<" ";
 	}
	cout<<".\n";
	cout<<"Enter s to shuffle the list."<<endl;
	while(1)
	{
		cin>>ch;
		if(ch != 's') // shuffles the list every time the user enters s
			break;
		for(k = 0; k < n; k++) // shuffles the list n times
		{
			i = rand() % n; // selects two random positions
			j = rand() % n;
			tmp = list[i];
			list[i] = list[j];
			list[j] = tmp;
		}
		cout<<"The shuffled list is ";
		for(i = 0; i < n; i++)
		{
			cout<<list[i]<<" ";
		}
		cout<<".\n";
		cout<<"Enter s to shuffle again. Enter q to quit."<<endl;
	}
	cout<<"Thank you."<<endl;
	return 0;
} // end<commit_msg>Update<commit_after>#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;

int main()
{
	int i = 0, n = 0, j = 0, k = 0, tmp = 0;
	char ch;
	srand(time(NULL)); // initalizes seed value
	cout<<"How many numbers would you like to have on your list?"<<endl;
	cin>>n;
	int *list = new int [n];
	cout<<"Please enter the integers."<<endl;
	for(i = 0; i < n; i++)
	{
		cin>>list[i];
 	}
	cout<<"The list you have entered is ";
	for(i = 0; i < n; i++)
	{
		cout<<list[i]<<" ";
 	}
	cout<<".\n";
	cout<<"Enter s to shuffle the list."<<endl;
	while(1)
	{
		cin>>ch;
		if(ch != 's') // shuffles the list every time the user enters s
			break;
		for(k = 0; k < n; k++) // shuffles the list n times
		{
			i = rand() % n; // selects two random positions
			j = rand() % n;
			tmp = list[i];
			list[i] = list[j];
			list[j] = tmp;
		}
		cout<<"The shuffled list is ";
		for(i = 0; i < n; i++)
		{
			cout<<list[i]<<" ";
		}
		cout<<".\n";
		cout<<"Enter s to shuffle again. Enter q to quit."<<endl;
	}
	cout<<"Thank you."<<endl;
	delete list;
	return 0;
} // end<|endoftext|>


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

#ifdef PCH
#include "ui_pch.hxx"
#endif
#pragma hdrstop

// ============================================================================

#ifndef _SC_CSVCONTROL_HXX
#include "csvcontrol.hxx"
#endif

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

#ifndef _SC_ACCESSIBLECSVCONTROL_HXX
#include "AccessibleCsvControl.hxx"
#endif

// ============================================================================

ScCsvLayoutData::ScCsvLayoutData() :
    mnPosCount( 1 ),
    mnPosOffset( 0 ),
    mnWinWidth( 1 ),
    mnHdrWidth( 0 ),
    mnCharWidth( 1 ),
    mnLineCount( 1 ),
    mnLineOffset( 0 ),
    mnWinHeight( 1 ),
    mnHdrHeight( 0 ),
    mnLineHeight( 1 ),
    mnPosCursor( CSV_POS_INVALID ),
    mnColCursor( 0 ),
    mnNoRepaint( 0 ),
    mbAppRTL( !!Application::GetSettings().GetLayoutRTL() )
{
}

ScCsvDiff ScCsvLayoutData::GetDiff( const ScCsvLayoutData& rData ) const
{
    ScCsvDiff nRet = CSV_DIFF_EQUAL;
    if( mnPosCount != rData.mnPosCount )        nRet |= CSV_DIFF_POSCOUNT;
    if( mnPosOffset != rData.mnPosOffset )      nRet |= CSV_DIFF_POSOFFSET;
    if( mnHdrWidth != rData.mnHdrWidth )        nRet |= CSV_DIFF_HDRWIDTH;
    if( mnCharWidth != rData.mnCharWidth )      nRet |= CSV_DIFF_CHARWIDTH;
    if( mnLineCount != rData.mnLineCount )      nRet |= CSV_DIFF_LINECOUNT;
    if( mnLineOffset != rData.mnLineOffset )    nRet |= CSV_DIFF_LINEOFFSET;
    if( mnHdrHeight != rData.mnHdrHeight )      nRet |= CSV_DIFF_HDRHEIGHT;
    if( mnLineHeight != rData.mnLineHeight )    nRet |= CSV_DIFF_LINEHEIGHT;
    if( mnPosCursor != rData.mnPosCursor )      nRet |= CSV_DIFF_RULERCURSOR;
    if( mnColCursor != rData.mnColCursor )      nRet |= CSV_DIFF_GRIDCURSOR;
    return nRet;
}

// ============================================================================

ScCsvControl::ScCsvControl( ScCsvControl& rParent ) :
    Control( &rParent, WB_TABSTOP | WB_NODIALOGCONTROL ),
    mrData( rParent.GetLayoutData() ),
    mpAccessible( NULL ),
    mbValidGfx( false )
{
}

ScCsvControl::ScCsvControl( Window* pParent, const ScCsvLayoutData& rData, WinBits nStyle ) :
    Control( pParent, nStyle ),
    mrData( rData ),
    mpAccessible( NULL ),
    mbValidGfx( false )
{
}

ScCsvControl::ScCsvControl( Window* pParent, const ScCsvLayoutData& rData, const ResId& rResId ) :
    Control( pParent, rResId ),
    mrData( rData ),
    mpAccessible( NULL ),
    mbValidGfx( false )
{
}

ScCsvControl::~ScCsvControl()
{
    if( mpAccessible )
        mpAccessible->dispose();
}

// event handling -------------------------------------------------------------

void ScCsvControl::GetFocus()
{
    Control::GetFocus();
    AccSendFocusEvent( true );
}

void ScCsvControl::LoseFocus()
{
    Control::LoseFocus();
    AccSendFocusEvent( false );
}

void ScCsvControl::AccSendFocusEvent( bool bFocused )
{
    if( mpAccessible )
        mpAccessible->SendFocusEvent( bFocused );
}

void ScCsvControl::AccSendCaretEvent()
{
    if( mpAccessible )
        mpAccessible->SendCaretEvent();
}

void ScCsvControl::AccSendVisibleEvent()
{
    if( mpAccessible )
        mpAccessible->SendVisibleEvent();
}

void ScCsvControl::AccSendSelectionEvent()
{
    if( mpAccessible )
        mpAccessible->SendSelectionEvent();
}

void ScCsvControl::AccSendTableUpdateEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn, bool bAllRows )
{
    if( mpAccessible )
        mpAccessible->SendTableUpdateEvent( nFirstColumn, nLastColumn, bAllRows );
}

void ScCsvControl::AccSendInsertColumnEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn )
{
    if( mpAccessible )
        mpAccessible->SendInsertColumnEvent( nFirstColumn, nLastColumn );
}

void ScCsvControl::AccSendRemoveColumnEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn )
{
    if( mpAccessible )
        mpAccessible->SendRemoveColumnEvent( nFirstColumn, nLastColumn );
}

// repaint helpers ------------------------------------------------------------

void ScCsvControl::Repaint( bool bInvalidate )
{
    if( bInvalidate )
        InvalidateGfx();
    if( !IsNoRepaint() )
        Execute( CSVCMD_REPAINT );
}

void ScCsvControl::DisableRepaint()
{
    ++mrData.mnNoRepaint;
}

void ScCsvControl::EnableRepaint( bool bInvalidate )
{
    DBG_ASSERT( IsNoRepaint(), "ScCsvControl::EnableRepaint - invalid call" );
    --mrData.mnNoRepaint;
    Repaint( bInvalidate );
}

// command handling -----------------------------------------------------------

void ScCsvControl::Execute( ScCsvCmdType eType, sal_Int32 nParam1, sal_Int32 nParam2 )
{
    maCmd.Set( eType, nParam1, nParam2 );
    maCmdHdl.Call( this );
}

// layout helpers -------------------------------------------------------------

sal_Int32 ScCsvControl::GetVisPosCount() const
{
    return (mrData.mnWinWidth - GetHdrWidth()) / GetCharWidth();
}

sal_Int32 ScCsvControl::GetMaxPosOffset() const
{
    return Max( GetPosCount() - GetVisPosCount() + 2L, 0L );
}

bool ScCsvControl::IsValidSplitPos( sal_Int32 nPos ) const
{
    return (0 < nPos) && (nPos < GetPosCount() );
}

bool ScCsvControl::IsVisibleSplitPos( sal_Int32 nPos ) const
{
    return IsValidSplitPos( nPos ) && (GetFirstVisPos() <= nPos) && (nPos <= GetLastVisPos());
}

sal_Int32 ScCsvControl::GetHdrX() const
{
    return IsRTL() ? (mrData.mnWinWidth - GetHdrWidth()) : 0;
}

sal_Int32 ScCsvControl::GetFirstX() const
{
    return IsRTL() ? 0 : GetHdrWidth();
}

sal_Int32 ScCsvControl::GetLastX() const
{
    return mrData.mnWinWidth - (IsRTL() ? GetHdrWidth() : 0) - 1;
}

sal_Int32 ScCsvControl::GetX( sal_Int32 nPos ) const
{
    return GetFirstX() + (nPos - GetFirstVisPos()) * GetCharWidth();
}

sal_Int32 ScCsvControl::GetPosFromX( sal_Int32 nX ) const
{
    return (nX - GetFirstX() + GetCharWidth() / 2) / GetCharWidth() + GetFirstVisPos();
}

sal_Int32 ScCsvControl::GetVisLineCount() const
{
    return (mrData.mnWinHeight - GetHdrHeight() - 2) / GetLineHeight() + 1;
}

sal_Int32 ScCsvControl::GetLastVisLine() const
{
    return Min( GetFirstVisLine() + GetVisLineCount(), GetLineCount() ) - 1;
}

sal_Int32 ScCsvControl::GetMaxLineOffset() const
{
    return Max( GetLineCount() - GetVisLineCount() + 1L, 0L );
}

bool ScCsvControl::IsValidLine( sal_Int32 nLine ) const
{
    return (0 <= nLine) && (nLine < GetLineCount());
}

bool ScCsvControl::IsVisibleLine( sal_Int32 nLine ) const
{
    return IsValidLine( nLine ) && (GetFirstVisLine() <= nLine) && (nLine <= GetLastVisLine());
}

sal_Int32 ScCsvControl::GetY( sal_Int32 nLine ) const
{
    return GetHdrHeight() + (nLine - GetFirstVisLine()) * GetLineHeight();
}

sal_Int32 ScCsvControl::GetLineFromY( sal_Int32 nY ) const
{
    return (nY - GetHdrHeight()) / GetLineHeight() + GetFirstVisLine();
}

// static helpers -------------------------------------------------------------

void ScCsvControl::ImplInvertRect( OutputDevice& rOutDev, const Rectangle& rRect )
{
    rOutDev.Push( PUSH_LINECOLOR | PUSH_FILLCOLOR | PUSH_RASTEROP );
    rOutDev.SetLineColor( Color( COL_BLACK ) );
    rOutDev.SetFillColor( Color( COL_BLACK ) );
    rOutDev.SetRasterOp( ROP_INVERT );
    rOutDev.DrawRect( rRect );
    rOutDev.Pop();
}

ScMoveMode ScCsvControl::GetHorzDirection( sal_uInt16 nCode, bool bHomeEnd )
{
    switch( nCode )
    {
        case KEY_LEFT:  return MOVE_PREV;
        case KEY_RIGHT: return MOVE_NEXT;
    }
    if( bHomeEnd ) switch( nCode )
    {
        case KEY_HOME:  return MOVE_FIRST;
        case KEY_END:   return MOVE_LAST;
    }
    return MOVE_NONE;
}

ScMoveMode ScCsvControl::GetVertDirection( sal_uInt16 nCode, bool bHomeEnd )
{
    switch( nCode )
    {
        case KEY_UP:        return MOVE_PREV;
        case KEY_DOWN:      return MOVE_NEXT;
        case KEY_PAGEUP:    return MOVE_PREVPAGE;
        case KEY_PAGEDOWN:  return MOVE_NEXTPAGE;
    }
    if( bHomeEnd ) switch( nCode )
    {
        case KEY_HOME:      return MOVE_FIRST;
        case KEY_END:       return MOVE_LAST;
    }
    return MOVE_NONE;
}

// accessibility --------------------------------------------------------------

ScCsvControl::XAccessibleRef ScCsvControl::CreateAccessible()
{
    mpAccessible = ImplCreateAccessible();
    mxAccessible = mpAccessible;
    return mxAccessible;
}

// ============================================================================

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

#ifdef PCH
#include "ui_pch.hxx"
#endif
#pragma hdrstop

// ============================================================================

#ifndef _SC_CSVCONTROL_HXX
#include "csvcontrol.hxx"
#endif

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

#ifndef _SC_ACCESSIBLECSVCONTROL_HXX
#include "AccessibleCsvControl.hxx"
#endif

// ============================================================================

ScCsvLayoutData::ScCsvLayoutData() :
    mnPosCount( 1 ),
    mnPosOffset( 0 ),
    mnWinWidth( 1 ),
    mnHdrWidth( 0 ),
    mnCharWidth( 1 ),
    mnLineCount( 1 ),
    mnLineOffset( 0 ),
    mnWinHeight( 1 ),
    mnHdrHeight( 0 ),
    mnLineHeight( 1 ),
    mnPosCursor( CSV_POS_INVALID ),
    mnColCursor( 0 ),
    mnNoRepaint( 0 ),
    mbAppRTL( !!Application::GetSettings().GetLayoutRTL() )
{
}

ScCsvDiff ScCsvLayoutData::GetDiff( const ScCsvLayoutData& rData ) const
{
    ScCsvDiff nRet = CSV_DIFF_EQUAL;
    if( mnPosCount != rData.mnPosCount )        nRet |= CSV_DIFF_POSCOUNT;
    if( mnPosOffset != rData.mnPosOffset )      nRet |= CSV_DIFF_POSOFFSET;
    if( mnHdrWidth != rData.mnHdrWidth )        nRet |= CSV_DIFF_HDRWIDTH;
    if( mnCharWidth != rData.mnCharWidth )      nRet |= CSV_DIFF_CHARWIDTH;
    if( mnLineCount != rData.mnLineCount )      nRet |= CSV_DIFF_LINECOUNT;
    if( mnLineOffset != rData.mnLineOffset )    nRet |= CSV_DIFF_LINEOFFSET;
    if( mnHdrHeight != rData.mnHdrHeight )      nRet |= CSV_DIFF_HDRHEIGHT;
    if( mnLineHeight != rData.mnLineHeight )    nRet |= CSV_DIFF_LINEHEIGHT;
    if( mnPosCursor != rData.mnPosCursor )      nRet |= CSV_DIFF_RULERCURSOR;
    if( mnColCursor != rData.mnColCursor )      nRet |= CSV_DIFF_GRIDCURSOR;
    return nRet;
}

// ============================================================================

ScCsvControl::ScCsvControl( ScCsvControl& rParent ) :
    Control( &rParent, WB_TABSTOP | WB_NODIALOGCONTROL ),
    mrData( rParent.GetLayoutData() ),
    mpAccessible( NULL ),
    mbValidGfx( false )
{
}

ScCsvControl::ScCsvControl( Window* pParent, const ScCsvLayoutData& rData, WinBits nStyle ) :
    Control( pParent, nStyle ),
    mrData( rData ),
    mpAccessible( NULL ),
    mbValidGfx( false )
{
}

ScCsvControl::ScCsvControl( Window* pParent, const ScCsvLayoutData& rData, const ResId& rResId ) :
    Control( pParent, rResId ),
    mrData( rData ),
    mpAccessible( NULL ),
    mbValidGfx( false )
{
}

ScCsvControl::~ScCsvControl()
{
    if( mpAccessible )
        mpAccessible->dispose();
}

// event handling -------------------------------------------------------------

void ScCsvControl::GetFocus()
{
    Control::GetFocus();
    AccSendFocusEvent( true );
}

void ScCsvControl::LoseFocus()
{
    Control::LoseFocus();
    AccSendFocusEvent( false );
}

void ScCsvControl::AccSendFocusEvent( bool bFocused )
{
    if( mpAccessible )
        mpAccessible->SendFocusEvent( bFocused );
}

void ScCsvControl::AccSendCaretEvent()
{
    if( mpAccessible )
        mpAccessible->SendCaretEvent();
}

void ScCsvControl::AccSendVisibleEvent()
{
    if( mpAccessible )
        mpAccessible->SendVisibleEvent();
}

void ScCsvControl::AccSendSelectionEvent()
{
    if( mpAccessible )
        mpAccessible->SendSelectionEvent();
}

void ScCsvControl::AccSendTableUpdateEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn, bool bAllRows )
{
    if( mpAccessible )
        mpAccessible->SendTableUpdateEvent( nFirstColumn, nLastColumn, bAllRows );
}

void ScCsvControl::AccSendInsertColumnEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn )
{
    if( mpAccessible )
        mpAccessible->SendInsertColumnEvent( nFirstColumn, nLastColumn );
}

void ScCsvControl::AccSendRemoveColumnEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn )
{
    if( mpAccessible )
        mpAccessible->SendRemoveColumnEvent( nFirstColumn, nLastColumn );
}

// repaint helpers ------------------------------------------------------------

void ScCsvControl::Repaint( bool bInvalidate )
{
    if( bInvalidate )
        InvalidateGfx();
    if( !IsNoRepaint() )
        Execute( CSVCMD_REPAINT );
}

void ScCsvControl::DisableRepaint()
{
    ++mrData.mnNoRepaint;
}

void ScCsvControl::EnableRepaint( bool bInvalidate )
{
    DBG_ASSERT( IsNoRepaint(), "ScCsvControl::EnableRepaint - invalid call" );
    --mrData.mnNoRepaint;
    Repaint( bInvalidate );
}

// command handling -----------------------------------------------------------

void ScCsvControl::Execute( ScCsvCmdType eType, sal_Int32 nParam1, sal_Int32 nParam2 )
{
    maCmd.Set( eType, nParam1, nParam2 );
    maCmdHdl.Call( this );
}

// layout helpers -------------------------------------------------------------

sal_Int32 ScCsvControl::GetVisPosCount() const
{
    return (mrData.mnWinWidth - GetHdrWidth()) / GetCharWidth();
}

sal_Int32 ScCsvControl::GetMaxPosOffset() const
{
    return Max( GetPosCount() - GetVisPosCount() + 2L, 0L );
}

bool ScCsvControl::IsValidSplitPos( sal_Int32 nPos ) const
{
    return (0 < nPos) && (nPos < GetPosCount() );
}

bool ScCsvControl::IsVisibleSplitPos( sal_Int32 nPos ) const
{
    return IsValidSplitPos( nPos ) && (GetFirstVisPos() <= nPos) && (nPos <= GetLastVisPos());
}

sal_Int32 ScCsvControl::GetHdrX() const
{
    return IsRTL() ? (mrData.mnWinWidth - GetHdrWidth()) : 0;
}

sal_Int32 ScCsvControl::GetFirstX() const
{
    return IsRTL() ? 0 : GetHdrWidth();
}

sal_Int32 ScCsvControl::GetLastX() const
{
    return mrData.mnWinWidth - (IsRTL() ? GetHdrWidth() : 0) - 1;
}

sal_Int32 ScCsvControl::GetX( sal_Int32 nPos ) const
{
    return GetFirstX() + (nPos - GetFirstVisPos()) * GetCharWidth();
}

sal_Int32 ScCsvControl::GetPosFromX( sal_Int32 nX ) const
{
    return (nX - GetFirstX() + GetCharWidth() / 2) / GetCharWidth() + GetFirstVisPos();
}

sal_Int32 ScCsvControl::GetVisLineCount() const
{
    return (mrData.mnWinHeight - GetHdrHeight() - 2) / GetLineHeight() + 1;
}

sal_Int32 ScCsvControl::GetLastVisLine() const
{
    return Min( GetFirstVisLine() + GetVisLineCount(), GetLineCount() ) - 1;
}

sal_Int32 ScCsvControl::GetMaxLineOffset() const
{
    return Max( GetLineCount() - GetVisLineCount() + 1L, 0L );
}

bool ScCsvControl::IsValidLine( sal_Int32 nLine ) const
{
    return (0 <= nLine) && (nLine < GetLineCount());
}

bool ScCsvControl::IsVisibleLine( sal_Int32 nLine ) const
{
    return IsValidLine( nLine ) && (GetFirstVisLine() <= nLine) && (nLine <= GetLastVisLine());
}

sal_Int32 ScCsvControl::GetY( sal_Int32 nLine ) const
{
    return GetHdrHeight() + (nLine - GetFirstVisLine()) * GetLineHeight();
}

sal_Int32 ScCsvControl::GetLineFromY( sal_Int32 nY ) const
{
    return (nY - GetHdrHeight()) / GetLineHeight() + GetFirstVisLine();
}

// static helpers -------------------------------------------------------------

void ScCsvControl::ImplInvertRect( OutputDevice& rOutDev, const Rectangle& rRect )
{
    rOutDev.Push( PUSH_LINECOLOR | PUSH_FILLCOLOR | PUSH_RASTEROP );
    rOutDev.SetLineColor( Color( COL_BLACK ) );
    rOutDev.SetFillColor( Color( COL_BLACK ) );
    rOutDev.SetRasterOp( ROP_INVERT );
    rOutDev.DrawRect( rRect );
    rOutDev.Pop();
}

ScMoveMode ScCsvControl::GetHorzDirection( sal_uInt16 nCode, bool bHomeEnd )
{
    switch( nCode )
    {
        case KEY_LEFT:  return MOVE_PREV;
        case KEY_RIGHT: return MOVE_NEXT;
    }
    if( bHomeEnd ) switch( nCode )
    {
        case KEY_HOME:  return MOVE_FIRST;
        case KEY_END:   return MOVE_LAST;
    }
    return MOVE_NONE;
}

ScMoveMode ScCsvControl::GetVertDirection( sal_uInt16 nCode, bool bHomeEnd )
{
    switch( nCode )
    {
        case KEY_UP:        return MOVE_PREV;
        case KEY_DOWN:      return MOVE_NEXT;
        case KEY_PAGEUP:    return MOVE_PREVPAGE;
        case KEY_PAGEDOWN:  return MOVE_NEXTPAGE;
    }
    if( bHomeEnd ) switch( nCode )
    {
        case KEY_HOME:      return MOVE_FIRST;
        case KEY_END:       return MOVE_LAST;
    }
    return MOVE_NONE;
}

// accessibility --------------------------------------------------------------

ScCsvControl::XAccessibleRef ScCsvControl::CreateAccessible()
{
    mpAccessible = ImplCreateAccessible();
    mxAccessible = mpAccessible;
    return mxAccessible;
}

// ============================================================================

<|endoftext|>


<commit_before>
//@HEADER
// ************************************************************************
//
//               HPCG: Simple Conjugate Gradient Benchmark Code
// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
//
// ************************************************************************
//@HEADER

// Changelog
//
// Version 0.3
// - Added timing of setup time for sparse MV
// - Corrected percentages reported for sparse MV with overhead
//
/////////////////////////////////////////////////////////////////////////

// Main routine of a program that calls the HPCG conjugate gradient
// solver to solve the problem, and then prints results.

#include <fstream>
#include <iostream>
#ifdef DEBUG
using std::cin;
#endif
using std::endl;

#include <cstdlib>
#include <vector>

#include "hpcg.hpp"

#ifndef HPCG_NOMPI
#include <mpi.h> // If this routine is not compiled with HPCG_NOMPI
#endif

#ifndef HPCG_NOOPENMP
#include <omp.h> // If this routine is not compiled with HPCG_NOOPENMP
#endif

#include "GenerateGeometry.hpp"
#include "GenerateProblem.hpp"
#include "SetupHalo.hpp"
#include "ExchangeHalo.hpp"
#include "OptimizeProblem.hpp"
#include "WriteProblem.hpp"
#include "ReportResults.hpp"
#include "mytimer.hpp"
#include "spmvref.hpp"
#include "symgsref.hpp"
#include "ComputeResidual.hpp"
#include "CG.hpp"
#include "CGref.hpp"
#include "Geometry.hpp"
#include "SparseMatrix.hpp"
#include "CGData.hpp"

int main(int argc, char *argv[]) {

#ifndef HPCG_NOMPI

    MPI_Init(&argc, &argv);

    int size, rank; // Number of MPI processes, My process ID
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
#else

    int size = 1; // Serial case (not using MPI)
    int rank = 0;

#endif

  HPCG_Params params;

  HPCG_Init(&argc, &argv, &params);

  int numThreads = 1;

#ifndef HPCG_NOOPENMP
#pragma omp parallel
  numThreads = omp_get_num_threads();
#endif

#ifdef DEBUG
    if (size < 100) HPCG_fout << "Process "<<rank<<" of "<<size<<" is alive with " << numThreads << " threads." <<endl;
#endif

#ifdef DEBUG
    if (rank==0)
    {
        int junk = 0;
        HPCG_fout << "Press enter to continue"<< endl;
        cin >> junk;
    }
#ifndef HPCG_NOMPI
    MPI_Barrier(MPI_COMM_WORLD);
#endif
#endif

#ifdef NO_PRECONDITIONER
    bool doPreconditioning = false;
#else
    bool doPreconditioning = true;
#endif

    local_int_t nx,ny,nz;
    nx = (local_int_t)params.nx;
    ny = (local_int_t)params.ny;
    nz = (local_int_t)params.nz;

#ifdef HPCG_DEBUG
    double t1 = mytimer();
#endif

    Geometry geom;
    GenerateGeometry(size, rank, numThreads, nx, ny, nz, geom);

    SparseMatrix A;
    CGData data;
    double *x, *b, *xexact;
    GenerateProblem(geom, A, &x, &b, &xexact);
    SetupHalo(geom, A);
    initializeCGData(A, data);

#ifdef HPCG_DEBUG
    if (rank==0) HPCG_fout << "Total setup time (sec) = " << mytimer() - t1 << endl;
#endif

    //if (geom.size==1) WriteProblem(A, x, b, xexact);

    // Use this array for collecting timing information
    std::vector< double > times(9,0.0);

    // Call user-tunable set up function.
    double t7 = mytimer(); OptimizeProblem(geom, A, data, x, b, xexact); t7 = mytimer() - t7;
    times[7] = t7;

    // Call Reference SPMV and SYMGS. Compute Optimization time as ratio of times in these routines

    local_int_t nrow = A.localNumberOfRows;
	local_int_t ncol = A.localNumberOfColumns;

	double * x_overlap = new double [ncol]; // Overlapped copy of x vector
	double * b_computed = new double [nrow]; // Computed RHS vector

	// Test symmetry of matrix

	// First load vector with random values
	for (int i=0; i<nrow; ++i) {
		x_overlap[i] = ((double) rand() / (RAND_MAX)) + 1;
	}

	int ierr = 0;
	int numberOfCalls = 10;
	double t_begin = mytimer();
	for (int i=0; i< numberOfCalls; ++i) {
#ifndef HPCG_NOMPI
		ExchangeHalo(A,x_overlap);
#endif
		ierr = spmvref(A, x_overlap, b_computed); // b_computed = A*x_overlap
		if (ierr) HPCG_fout << "Error in call to spmv: " << ierr << ".\n" << endl;
		ierr = symgsref(A, x_overlap, b_computed); // b_computed = Minv*y_overlap
		if (ierr) HPCG_fout << "Error in call to symgs: " << ierr << ".\n" << endl;
	}
    times[8] = (mytimer() - t_begin)/((double) numberOfCalls);  // Total time divided by number of calls.

    int global_failure = 0; // assume all is well: no failures

    int niters = 0;
    int totalNiters = 0;
    double normr = 0.0;
    double normr0 = 0.0;
    int maxIters = 50;

    /* Compute the residual reduction for the natural ordering and reference kernels. */
    std::vector< double > ref_times(9,0.0);
    double tolerance = 0.0; // Set tolerance to zero to make all runs do max_iter iterations
    int err_count = 0;
    for (int i=0; i< numberOfCalls; ++i) {
    	for (int j=0; j< A.localNumberOfRows; ++j) x[j] = 0.0; // start x at all zeros
    	ierr = CGref( geom, A, data, b, x, maxIters, tolerance, niters, normr, normr0, &ref_times[0], true);
    	if (ierr) ++err_count; // count the number of errors in CG
	totalNiters += niters;
    }
    if (rank == 0 && err_count) HPCG_fout << err_count << " error(s) in call(s) to reference CG." << endl;
    double ref_tolerance = normr / normr0;
    int ref_iters = niters;

    totalNiters = 0;
    niters = 0;
    normr = 0.0;
    normr0 = 0.0;
    err_count = 0;
    int tolerance_failures = 0;

    int opt_maxIters = 10*maxIters;
    int opt_iters = 0;
    double opt_worst_time = 0.0;
    /* Compute the residual reduction and residual count for the user ordering and optimized kernels. */
    for (int i=0; i< numberOfCalls; ++i) {
    	for (int j=0; j< A.localNumberOfRows; ++j) x[j] = 0.0; // start x at all zeros
    	ierr = CG( geom, A, data, b, x, opt_maxIters, ref_tolerance, niters, normr, normr0, &times[0], true);
    	if (ierr) ++err_count; // count the number of errors in CG
        if (normr / normr0 > ref_tolerance) ++tolerance_failures; // the number of failures to reduce residual

        // pick the largest number of iterations to guarantee convergence
        if (niters > opt_iters) opt_iters = niters;

        if (times[0] > opt_worst_time) opt_worst_time = times[0];

	totalNiters += niters;
    }
    if (rank == 0 && err_count) HPCG_fout << err_count << " error(s) in call(s) to optimized CG." << endl;
    if (tolerance_failures) {
      global_failure = 1;
      if (rank == 0)
        HPCG_fout << "Failed to reduce the residual " << tolerance_failures << " times." << endl;
    }

    double total_runtime = 60; // run for at least one minute
    numberOfCalls = int(total_runtime / opt_worst_time);
    if (numberOfCalls < 1) numberOfCalls = 1; // run CG at least once

    for (int i=0; i< numberOfCalls; ++i) {
    	for (int j=0; j< A.localNumberOfRows; ++j) x[j] = 0.0; // Zero out x
    	ierr = CG( geom, A, data, b, x, maxIters, tolerance, niters, normr, normr0, &times[0], doPreconditioning);
    	if (ierr) HPCG_fout << "Error in call to CG: " << ierr << ".\n" << endl;
    	if (rank==0) HPCG_fout << "Call [" << i << "] Scaled Residual [" << normr/normr0 << "]" << endl;
	totalNiters += niters;
    }

    // Compute difference between known exact solution and computed solution
    // All processors are needed here.
#ifdef DEBUG
    double residual = 0;
    ierr = ComputeResidual(A.localNumberOfRows, x, xexact, &residual);
    if (ierr) HPCG_fout << "Error in call to compute_residual: " << ierr << ".\n" << endl;
    if (rank==0)
    HPCG_fout << "Difference between computed and exact  = " << residual << ".\n" << endl;
#endif

    // Report results to YAML file
    ReportResults(geom, A, totalNiters, normr/normr0, &times[0]);

    // Clean up
    destroyMatrix(A);
    destroyCGData(data);
    delete [] x;
    delete [] b;
    delete [] xexact;

    HPCG_Finalize();

    // Finish up
#ifndef HPCG_NOMPI
    MPI_Finalize();
#endif
    return 0 ;
}
<commit_msg>Fixed a bug: I should have not been using cumulative time.<commit_after>
//@HEADER
// ************************************************************************
//
//               HPCG: Simple Conjugate Gradient Benchmark Code
// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
//
// ************************************************************************
//@HEADER

// Changelog
//
// Version 0.3
// - Added timing of setup time for sparse MV
// - Corrected percentages reported for sparse MV with overhead
//
/////////////////////////////////////////////////////////////////////////

// Main routine of a program that calls the HPCG conjugate gradient
// solver to solve the problem, and then prints results.

#include <fstream>
#include <iostream>
#ifdef DEBUG
using std::cin;
#endif
using std::endl;

#include <cstdlib>
#include <vector>

#include "hpcg.hpp"

#ifndef HPCG_NOMPI
#include <mpi.h> // If this routine is not compiled with HPCG_NOMPI
#endif

#ifndef HPCG_NOOPENMP
#include <omp.h> // If this routine is not compiled with HPCG_NOOPENMP
#endif

#include "GenerateGeometry.hpp"
#include "GenerateProblem.hpp"
#include "SetupHalo.hpp"
#include "ExchangeHalo.hpp"
#include "OptimizeProblem.hpp"
#include "WriteProblem.hpp"
#include "ReportResults.hpp"
#include "mytimer.hpp"
#include "spmvref.hpp"
#include "symgsref.hpp"
#include "ComputeResidual.hpp"
#include "CG.hpp"
#include "CGref.hpp"
#include "Geometry.hpp"
#include "SparseMatrix.hpp"
#include "CGData.hpp"

int main(int argc, char *argv[]) {

#ifndef HPCG_NOMPI

    MPI_Init(&argc, &argv);

    int size, rank; // Number of MPI processes, My process ID
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
#else

    int size = 1; // Serial case (not using MPI)
    int rank = 0;

#endif

  HPCG_Params params;

  HPCG_Init(&argc, &argv, &params);

  int numThreads = 1;

#ifndef HPCG_NOOPENMP
#pragma omp parallel
  numThreads = omp_get_num_threads();
#endif

#ifdef DEBUG
    if (size < 100) HPCG_fout << "Process "<<rank<<" of "<<size<<" is alive with " << numThreads << " threads." <<endl;
#endif

#ifdef DEBUG
    if (rank==0)
    {
        int junk = 0;
        HPCG_fout << "Press enter to continue"<< endl;
        cin >> junk;
    }
#ifndef HPCG_NOMPI
    MPI_Barrier(MPI_COMM_WORLD);
#endif
#endif

#ifdef NO_PRECONDITIONER
    bool doPreconditioning = false;
#else
    bool doPreconditioning = true;
#endif

    local_int_t nx,ny,nz;
    nx = (local_int_t)params.nx;
    ny = (local_int_t)params.ny;
    nz = (local_int_t)params.nz;

#ifdef HPCG_DEBUG
    double t1 = mytimer();
#endif

    Geometry geom;
    GenerateGeometry(size, rank, numThreads, nx, ny, nz, geom);

    SparseMatrix A;
    CGData data;
    double *x, *b, *xexact;
    GenerateProblem(geom, A, &x, &b, &xexact);
    SetupHalo(geom, A);
    initializeCGData(A, data);

#ifdef HPCG_DEBUG
    if (rank==0) HPCG_fout << "Total setup time (sec) = " << mytimer() - t1 << endl;
#endif

    //if (geom.size==1) WriteProblem(A, x, b, xexact);

    // Use this array for collecting timing information
    std::vector< double > times(9,0.0);

    // Call user-tunable set up function.
    double t7 = mytimer(); OptimizeProblem(geom, A, data, x, b, xexact); t7 = mytimer() - t7;
    times[7] = t7;

    // Call Reference SPMV and SYMGS. Compute Optimization time as ratio of times in these routines

    local_int_t nrow = A.localNumberOfRows;
	local_int_t ncol = A.localNumberOfColumns;

	double * x_overlap = new double [ncol]; // Overlapped copy of x vector
	double * b_computed = new double [nrow]; // Computed RHS vector

	// Test symmetry of matrix

	// First load vector with random values
	for (int i=0; i<nrow; ++i) {
		x_overlap[i] = ((double) rand() / (RAND_MAX)) + 1;
	}

	int ierr = 0;
	int numberOfCalls = 10;
	double t_begin = mytimer();
	for (int i=0; i< numberOfCalls; ++i) {
#ifndef HPCG_NOMPI
		ExchangeHalo(A,x_overlap);
#endif
		ierr = spmvref(A, x_overlap, b_computed); // b_computed = A*x_overlap
		if (ierr) HPCG_fout << "Error in call to spmv: " << ierr << ".\n" << endl;
		ierr = symgsref(A, x_overlap, b_computed); // b_computed = Minv*y_overlap
		if (ierr) HPCG_fout << "Error in call to symgs: " << ierr << ".\n" << endl;
	}
    times[8] = (mytimer() - t_begin)/((double) numberOfCalls);  // Total time divided by number of calls.

    int global_failure = 0; // assume all is well: no failures

    int niters = 0;
    int totalNiters = 0;
    double normr = 0.0;
    double normr0 = 0.0;
    int maxIters = 50;

    /* Compute the residual reduction for the natural ordering and reference kernels. */
    std::vector< double > ref_times(9,0.0);
    double tolerance = 0.0; // Set tolerance to zero to make all runs do max_iter iterations
    int err_count = 0;
    for (int i=0; i< numberOfCalls; ++i) {
    	for (int j=0; j< A.localNumberOfRows; ++j) x[j] = 0.0; // start x at all zeros
    	ierr = CGref( geom, A, data, b, x, maxIters, tolerance, niters, normr, normr0, &ref_times[0], true);
    	if (ierr) ++err_count; // count the number of errors in CG
	totalNiters += niters;
    }
    if (rank == 0 && err_count) HPCG_fout << err_count << " error(s) in call(s) to reference CG." << endl;
    double ref_tolerance = normr / normr0;
    int ref_iters = niters;

    totalNiters = 0;
    niters = 0;
    normr = 0.0;
    normr0 = 0.0;
    err_count = 0;
    int tolerance_failures = 0;

    int opt_maxIters = 10*maxIters;
    int opt_iters = 0;
    double opt_worst_time = 0.0;

    /* Compute the residual reduction and residual count for the user ordering and optimized kernels. */
    for (int i=0; i< numberOfCalls; ++i) {
    	for (int j=0; j< A.localNumberOfRows; ++j) x[j] = 0.0; // start x at all zeros
        double last_cummulative_time = times[0];
    	ierr = CG( geom, A, data, b, x, opt_maxIters, ref_tolerance, niters, normr, normr0, &times[0], true);
    	if (ierr) ++err_count; // count the number of errors in CG
        if (normr / normr0 > ref_tolerance) ++tolerance_failures; // the number of failures to reduce residual

        // pick the largest number of iterations to guarantee convergence
        if (niters > opt_iters) opt_iters = niters;

        double current_time = times[0] - last_cummulative_time;
        if (current_time > opt_worst_time) opt_worst_time = current_time;

	totalNiters += niters;
    }
    if (rank == 0 && err_count) HPCG_fout << err_count << " error(s) in call(s) to optimized CG." << endl;
    if (tolerance_failures) {
      global_failure = 1;
      if (rank == 0)
        HPCG_fout << "Failed to reduce the residual " << tolerance_failures << " times." << endl;
    }

    double total_runtime = 60; // run for at least one minute
    numberOfCalls = int(total_runtime / opt_worst_time);
    if (numberOfCalls < 1) numberOfCalls = 1; // run CG at least once

    for (int i=0; i< numberOfCalls; ++i) {
    	for (int j=0; j< A.localNumberOfRows; ++j) x[j] = 0.0; // Zero out x
    	ierr = CG( geom, A, data, b, x, maxIters, tolerance, niters, normr, normr0, &times[0], doPreconditioning);
    	if (ierr) HPCG_fout << "Error in call to CG: " << ierr << ".\n" << endl;
    	if (rank==0) HPCG_fout << "Call [" << i << "] Scaled Residual [" << normr/normr0 << "]" << endl;
	totalNiters += niters;
    }

    // Compute difference between known exact solution and computed solution
    // All processors are needed here.
#ifdef DEBUG
    double residual = 0;
    ierr = ComputeResidual(A.localNumberOfRows, x, xexact, &residual);
    if (ierr) HPCG_fout << "Error in call to compute_residual: " << ierr << ".\n" << endl;
    if (rank==0)
    HPCG_fout << "Difference between computed and exact  = " << residual << ".\n" << endl;
#endif

    // Report results to YAML file
    ReportResults(geom, A, totalNiters, normr/normr0, &times[0]);

    // Clean up
    destroyMatrix(A);
    destroyCGData(data);
    delete [] x;
    delete [] b;
    delete [] xexact;

    HPCG_Finalize();

    // Finish up
#ifndef HPCG_NOMPI
    MPI_Finalize();
#endif
    return 0 ;
}
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/i2c/exp_i2c.H $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2018,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed 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                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///
/// @file exp_i2c.H
/// @brief explorer I2C utility function declarations
///
// *HWP HWP Owner: Andre A. Marin <aamarin@us.ibm.com>
// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 2
// *HWP Consumed by: HB:FSP

#ifndef _MSS_EXP_I2C_H_
#define _MSS_EXP_I2C_H_

#include <fapi2.H>
#include <i2c_access.H>

#include <vector>
#include <lib/i2c/exp_i2c_fields.H>

namespace mss
{
namespace exp
{
namespace i2c
{
namespace check
{

///
/// @brief Checks the I2c explorer status codes
/// @param[in] i_target the OCMB target
/// @param[in] i_cmd_id the command ID
/// @param[in] i_data data to check from EXP_FW_STATUS
///
inline fapi2::ReturnCode status_code( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
                                      const uint8_t i_cmd_id,
                                      const std::vector<uint8_t>& i_data )
{
    // Set to a high number to make sure check for SUCCESS (== 0) isn't a fluke
    uint8_t l_status = ~(0);
    FAPI_TRY( status::get_status_code(i_target, i_data, l_status) );

    // Technically many cmds have their own status code decoding..but SUCCESS is always 0.
    // If it's anything else we can just look up the status code
    FAPI_ASSERT( l_status == status_codes::SUCCESS,
                 fapi2::MSS_EXP_STATUS_CODE_UNSUCCESSFUL().
                 set_TARGET(i_target).
                 set_STATUS_CODE(l_status).
                 set_CMD_ID(i_cmd_id),
                 "Status code did not return SUCCESS (%d), received (%d) for %s",
                 status_codes::SUCCESS, l_status, mss::c_str(i_target) );

    return fapi2::FAPI2_RC_SUCCESS;

fapi_try_exit:
    return fapi2::current_err;
}

}// check

///
/// @brief EXP_FW_STATUS setup helper function - useful for testing
/// @param[out] o_size the size of data
/// @param[out] o_cmd_id the explorer command ID
///
inline void fw_status_setup(size_t& o_size,
                            std::vector<uint8_t>& o_cmd_id)
{
    o_size = FW_STATUS_BYTE_LEN;
    o_cmd_id.clear();
    o_cmd_id.push_back(FW_STATUS);
}

///
/// @brief EXP_FW_STATUS
/// @param[in] i_target the OCMB target
/// @return FAPI2_RC_SUCCESS iff okay
///
inline fapi2::ReturnCode fw_status(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target)
{
    // Retrieve setup data
    size_t l_size = 0;
    std::vector<uint8_t> l_cmd_id;
    fw_status_setup(l_size, l_cmd_id);

    // Get data and check for errors
    {
        std::vector<uint8_t> l_data;
        FAPI_TRY(fapi2::getI2c(i_target, l_size, l_cmd_id, l_data));
        FAPI_TRY( check::status_code(i_target, l_cmd_id[0], l_data) );
    }

fapi_try_exit:
    return fapi2::current_err;
}

///
/// @brief EXP_FW_BOOT_CONFIG setup
/// @param[in,out] io_data the data to go to boot config
///
inline void boot_config_setup(std::vector<uint8_t>& io_data)

{
    // Need data length as well - boot config can only ever be written
    io_data.push_back(FW_BOOT_CONFIG_BYTE_LEN);

    // Then add the command
    io_data.push_back(FW_BOOT_CONFIG);

    // Written commands need to be in the form of (MSB first)
    // CMD
    // DATA LEN
    // DATA
}

///
/// @brief EXP_FW_BOOT_CONFIG
/// @param[in] i_target the OCMB target
/// @param[in] i_data the data to write
/// @return FAPI2_RC_SUCCESS iff okay
///
inline fapi2::ReturnCode boot_config(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
                                     const std::vector<uint8_t>& i_data)
{
    // Retrieve setup data
    std::vector<uint8_t> l_configured_data(i_data);
    boot_config_setup(l_configured_data);

    // Get data and check for errors
    FAPI_TRY(fapi2::putI2c(i_target, l_configured_data));
    FAPI_TRY(fw_status(i_target));

fapi_try_exit:
    return fapi2::current_err;
}

///
/// @brief Checks if the I2C interface returns an ACK
/// @param[in] i_target the OCMB target
/// @return FAPI2_RC_SUCCESS iff okay
///
inline fapi2::ReturnCode is_ready(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target)
{
    // We send a simple but valid command to poll the I2C
    // Arbitrarily send an EXP_FW_STATUS command id
    size_t l_size = 0;
    std::vector<uint8_t> l_cmd_id;
    fw_status_setup(l_size, l_cmd_id);

    // We just ignore the data.  We'll see FAPI2_RC_SUCCESS if
    // the I2C returns an ACK.
    std::vector<uint8_t> l_data;
    return fapi2::getI2c(i_target, l_size, l_cmd_id, l_data);
}

}// i2c
}// exp
}// mss

#endif
<commit_msg>Add exp_i2c_scom driver that will be consumed by HB/SBE platforms<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/i2c/exp_i2c.H $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2018,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed 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                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///
/// @file exp_i2c.H
/// @brief explorer I2C utility function declarations
///
// *HWP HWP Owner: Andre A. Marin <aamarin@us.ibm.com>
// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 2
// *HWP Consumed by: HB:FSP

#ifndef _MSS_EXP_I2C_H_
#define _MSS_EXP_I2C_H_

#include <fapi2.H>
#include <i2c_access.H>

#include <vector>
#include <lib/i2c/exp_i2c_fields.H>
#include <generic/memory/lib/utils/pos.H>
#include <generic/memory/lib/utils/endian_utils.H>

namespace mss
{
namespace exp
{
namespace i2c
{
namespace check
{

///
/// @brief Checks the I2c explorer status codes
/// @param[in] i_target the OCMB target
/// @param[in] i_cmd_id the command ID
/// @param[in] i_data data to check from EXP_FW_STATUS
///
inline fapi2::ReturnCode status_code( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
                                      const uint8_t i_cmd_id,
                                      const std::vector<uint8_t>& i_data )
{
    // Set to a high number to make sure check for SUCCESS (== 0) isn't a fluke
    uint8_t l_status = ~(0);
    FAPI_TRY( status::get_status_code(i_target, i_data, l_status) );

    // Technically many cmds have their own status code decoding..but SUCCESS is always 0.
    // If it's anything else we can just look up the status code
    FAPI_ASSERT( l_status == status_codes::SUCCESS,
                 fapi2::MSS_EXP_STATUS_CODE_UNSUCCESSFUL().
                 set_TARGET(i_target).
                 set_STATUS_CODE(l_status).
                 set_CMD_ID(i_cmd_id),
                 "Status code did not return SUCCESS (%d), received (%d) for %s",
                 status_codes::SUCCESS, l_status, mss::c_str(i_target) );

    return fapi2::FAPI2_RC_SUCCESS;

fapi_try_exit:
    return fapi2::current_err;
}

}// check

///
/// @brief EXP_FW_STATUS setup helper function - useful for testing
/// @param[out] o_size the size of data
/// @param[out] o_cmd_id the explorer command ID
///
inline void fw_status_setup(size_t& o_size,
                            std::vector<uint8_t>& o_cmd_id)
{
    o_size = FW_STATUS_BYTE_LEN;
    o_cmd_id.clear();
    o_cmd_id.push_back(FW_STATUS);
}

///
/// @brief EXP_FW_STATUS
/// @param[in] i_target the OCMB target
/// @return FAPI2_RC_SUCCESS iff okay
///
inline fapi2::ReturnCode fw_status(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target)
{
    // Retrieve setup data
    size_t l_size = 0;
    std::vector<uint8_t> l_cmd_id;
    fw_status_setup(l_size, l_cmd_id);

    // Get data and check for errors
    {
        std::vector<uint8_t> l_data;
        FAPI_TRY(fapi2::getI2c(i_target, l_size, l_cmd_id, l_data));
        FAPI_TRY( check::status_code(i_target, l_cmd_id[0], l_data) );
    }

fapi_try_exit:
    return fapi2::current_err;
}

///
/// @brief EXP_FW_BOOT_CONFIG setup
/// @param[in,out] io_data the data to go to boot config
///
inline void boot_config_setup(std::vector<uint8_t>& io_data)

{
    // Need data length as well - boot config can only ever be written
    io_data.push_back(FW_BOOT_CONFIG_BYTE_LEN);

    // Then add the command
    io_data.push_back(FW_BOOT_CONFIG);

    // Written commands need to be in the form of (MSB first)
    // CMD
    // DATA LEN
    // DATA
}

///
/// @brief EXP_FW_BOOT_CONFIG
/// @param[in] i_target the OCMB target
/// @param[in] i_data the data to write
/// @return FAPI2_RC_SUCCESS iff okay
///
inline fapi2::ReturnCode boot_config(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
                                     const std::vector<uint8_t>& i_data)
{
    // Retrieve setup data
    std::vector<uint8_t> l_configured_data(i_data);
    boot_config_setup(l_configured_data);

    // Get data and check for errors
    FAPI_TRY(fapi2::putI2c(i_target, l_configured_data));
    FAPI_TRY(fw_status(i_target));

fapi_try_exit:
    return fapi2::current_err;
}

///
/// @brief Checks if the I2C interface returns an ACK
/// @param[in] i_target the OCMB target
/// @return FAPI2_RC_SUCCESS iff okay
///
inline fapi2::ReturnCode is_ready(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target)
{
    // We send a simple but valid command to poll the I2C
    // Arbitrarily send an EXP_FW_STATUS command id
    size_t l_size = 0;
    std::vector<uint8_t> l_cmd_id;
    fw_status_setup(l_size, l_cmd_id);

    // We just ignore the data.  We'll see FAPI2_RC_SUCCESS if
    // the I2C returns an ACK.
    std::vector<uint8_t> l_data;
    return fapi2::getI2c(i_target, l_size, l_cmd_id, l_data);
}

///
/// @brief Perform a register write operation on the given OCMB chip
/// @param[in] i_target the OCMB target
/// @param[in] i_addr   The translated address on the OCMB chip
/// @param[in] i_data_buffer buffer of data we want to write to the register
/// @return FAPI2_RC_SUCCESS iff okay
///
inline  fapi2::ReturnCode fw_reg_write(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
                                       const uint32_t i_addr,
                                       const fapi2::buffer<uint32_t>& i_data_buffer)
{
    // create byte vector that will hold command bytes in sequence that will do the scom
    std::vector<uint8_t> l_cmd_vector;
    std::vector<uint8_t> l_le_addr_vector;
    std::vector<uint8_t> l_le_data_vector;
    uint32_t l_input_data = static_cast<uint32_t>(i_data_buffer);

    forceLE(i_addr, l_le_addr_vector);
    forceLE(l_input_data, l_le_data_vector);

    // Start building the cmd vector for the write operation
    l_cmd_vector.push_back(FW_REG_WRITE);              // Byte 0 = 0x05 (FW_REG_WRITE)
    l_cmd_vector.push_back(FW_WRITE_REG_DATA_SIZE);    // Byte 1 = 0x08 (FW_SCOM_DATA_SIZE)

    // i_addr and i_data_buffer were converted to LE above so we can
    // write them directly to the cmd_vector in the same order they
    // currently are
    // Byte 2:5 = Address
    l_cmd_vector.insert(l_cmd_vector.end(), l_le_addr_vector.begin(), l_le_addr_vector.end());
    // Byte 6:9 = Data
    l_cmd_vector.insert(l_cmd_vector.end(), l_le_data_vector.begin(), l_le_data_vector.end());

    // Use fapi2 putI2c interface to execute command
    FAPI_TRY(fapi2::putI2c(i_target, l_cmd_vector),
             "I2C FW_REG_WRITE op failed to write to 0x%.8X on OCMB w/ fapiPos = 0x%.8X",
             i_addr, mss::fapi_pos(i_target));

    // Check status of operation
    FAPI_TRY(fw_status(i_target),
             "Invalid Status after FW_REG_WRITE operation to 0x%.8X on OCMB w/ fapiPos = 0x%.8X",
             i_addr, mss::fapi_pos(i_target));

fapi_try_exit:
    return fapi2::current_err;
}

///
/// @brief Perform a register write operation on the given OCMB chip
/// @param[in] i_target the OCMB target
/// @param[in] i_addr   The translated address on the OCMB chip
/// @param[in] o_data_buffer buffer of data we will write the contents of the register to
/// @return FAPI2_RC_SUCCESS iff okay
///
inline fapi2::ReturnCode fw_reg_read(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
                                     const uint32_t i_addr,
                                     fapi2::buffer<uint32_t>& o_data_buffer)
{
    // create byte vector that will hold command bytes in sequence that will do the scom
    std::vector<uint8_t> l_cmd_vector;
    std::vector<uint8_t> l_read_data;
    std::vector<uint8_t> l_le_addr_vector;
    uint32_t l_index = 0;
    uint32_t l_read_value = 0;

    forceLE(i_addr, l_le_addr_vector);

    // Build the cmd vector for the Read
    l_cmd_vector.push_back(FW_REG_ADDR_LATCH);         // Byte 0 = 0x03 (FW_REG_ADDR_LATCH)
    l_cmd_vector.push_back(FW_REG_ADDR_LATCH_SIZE);    // Byte 1 = 0x04 (FW_REG_ADDR_LATCH_SIZE)

    // i_addr was converted to LE above so we can write it
    // directly to the cmd_vector in the same order it
    // currently is in
    // Byte 2:5 = Address
    l_cmd_vector.insert(l_cmd_vector.end(), l_le_addr_vector.begin(), l_le_addr_vector.end());

    // Use fapi2 putI2c interface to execute command
    FAPI_TRY(fapi2::putI2c(i_target, l_cmd_vector),
             "putI2c returned error for FW_REG_ADDR_LATCH operation to 0x%.8X on OCMB w/ fapiPos = 0x%.8X",
             i_addr, mss::fapi_pos(i_target));

    // Check i2c status after operation
    FAPI_TRY(fw_status(i_target),
             "Invalid Status after FW_REG_ADDR_LATCH operation to 0x%.8X on OCMB w/ fapiPos = 0x%.8X",
             i_addr, mss::fapi_pos(i_target));

    // Clear out cmd vector as i2c op is complete and we must prepare for next
    l_cmd_vector.clear();

    // Cmd vector is a single byte with FW_REG_READ code
    l_cmd_vector.push_back(FW_REG_READ); // Byte 0 = 0x04 (FW_REG_READ)

    // Use fapi2 getI2c interface to execute command
    FAPI_TRY(fapi2::getI2c(i_target, FW_I2C_SCOM_READ_SIZE,  l_cmd_vector, l_read_data),
             "getI2c returned error for FW_REG_READ operation to 0x%.8X on OCMB w/ fapiPos = 0x%.8X",
             i_addr, mss::fapi_pos(i_target));

    // The first byte returned should be the size of the remaining data
    // We requested FW_REG_ADDR_LATCH_SIZE bytes so that is what we
    // expect to see as the first byte.
    FAPI_ASSERT(  (l_read_data.front() == FW_REG_ADDR_LATCH_SIZE),
                  fapi2::I2C_GET_SCOM_INVALID_READ_SIZE()
                  .set_TARGET(i_target)
                  .set_ADDRESS(i_addr)
                  .set_SIZE_RETURNED(l_read_data[0])
                  .set_SIZE_REQUESTED(FW_REG_ADDR_LATCH_SIZE),
                  "First byte of read data was expected to be 0x%lx but byte read = 0x%x",
                  FW_REG_ADDR_LATCH_SIZE, l_read_data[0] );

    // Check i2c status after operation
    FAPI_TRY(fw_status(i_target),
             "Invalid Status after FW_REG_READ operation to 0x%.8X on OCMB w/ fapiPos = 0x%.8X",
             i_addr, mss::fapi_pos(i_target));

    // The OCMB is a 32-bit little endian engine so
    // we must convert the buffer that we read into native
    // incase native endian is different than LE
    readLE(l_read_data, l_index, l_read_value);
    o_data_buffer = l_read_value;

fapi_try_exit:
    return fapi2::current_err;
}

///
/// @brief Perform a register write operation on the given OCMB chip
/// @param[in] i_addr   The raw address that needs to be translated to IBM scom addr
/// @param[in] i_side   LHS or RHS of the IBM i2c scom. IBM addresses expect 64 bits of
///                     data returned from them so we must have a LHS and a RHS which is offset
///                     by 4 bytes. This is because the OCMB is a 32 bit architecture
/// @return uint32 of translated address
///
inline uint32_t trans_ibm_i2c_scom_addr(const uint32_t i_addr,
                                        const addrSide i_side)
{
    return (i_side == LHS) ?
           ((LAST_THREE_BYTES_MASK & i_addr) << OCMB_ADDR_SHIFT) | IBM_SCOM_OFFSET_LHS | OCMB_UNCACHED_OFFSET :
           ((LAST_THREE_BYTES_MASK & i_addr) << OCMB_ADDR_SHIFT) | IBM_SCOM_OFFSET_RHS | OCMB_UNCACHED_OFFSET ;
}

///
/// @brief Perform a register write operation on the given OCMB chip
/// @param[in] i_addr   The raw address that needs to be translated to Microchip scom addr
/// @return uint32 of translated address
///
inline uint32_t trans_micro_i2c_scom_addr(const uint32_t i_addr)
{
    return (i_addr | OCMB_UNCACHED_OFFSET) ;
}

}// i2c
}// exp
}// mss

#endif
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * Version: MPL 1.1 / GPLv3+ / LGPLv3+
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License or as specified alternatively below. You may obtain a copy of
 * the License at http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * Major Contributor(s):
 *   Copyright (C) 2012 Kohei Yoshida <kohei.yoshida@suse.com>
 *
 * All Rights Reserved.
 *
 * For minor contributions see the git repository.
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
 * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
 * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
 * instead of those above.
 */

#include "dpitemdata.hxx"

#include "document.hxx"
#include "dpobject.hxx"
#include "cell.hxx"
#include "globstr.hrc"
#include "dptabdat.hxx"
#include "rtl/math.hxx"

const sal_Int32 ScDPItemData::DateFirst = -1;
const sal_Int32 ScDPItemData::DateLast  = 10000;

sal_Int32 ScDPItemData::Compare(const ScDPItemData& rA, const ScDPItemData& rB)
{
    if (rA.meType != rB.meType)
    {
        // group value, value and string in this order.
        return rA.meType < rB.meType ? -1 : 1;
    }

    switch (rA.meType)
    {
        case GroupValue:
        {
            if (rA.maGroupValue.mnGroupType == rB.maGroupValue.mnGroupType)
            {
                if (rA.maGroupValue.mnValue == rB.maGroupValue.mnValue)
                    return 0;

                return rA.maGroupValue.mnValue < rB.maGroupValue.mnValue ? -1 : 1;
            }

            return rA.maGroupValue.mnGroupType < rB.maGroupValue.mnGroupType ? -1 : 1;
        }
        case Value:
        case RangeStart:
        {
            if (rA.mfValue == rB.mfValue)
                return 0;

            return rA.mfValue < rB.mfValue ? -1 : 1;
        }
        case String:
        case Error:
            return ScGlobal::GetCollator()->compareString(rA.GetString(), rB.GetString());
        default:
            ;
    }
    return 0;
}

ScDPItemData::ScDPItemData() :
    mfValue(0.0), meType(Empty) {}

ScDPItemData::ScDPItemData(const ScDPItemData& r) :
    meType(r.meType)
{
    switch (r.meType)
    {
        case String:
        case Error:
            mpString = new rtl::OUString(*r.mpString);
        break;
        case Value:
        case RangeStart:
            mfValue = r.mfValue;
        break;
        case GroupValue:
            maGroupValue.mnGroupType = r.maGroupValue.mnGroupType;
            maGroupValue.mnValue = r.maGroupValue.mnValue;
        break;
        case Empty:
        default:
            mfValue = 0.0;
    }
}

void ScDPItemData::DisposeString()
{
    if (meType == String || meType == Error)
        delete mpString;
}

ScDPItemData::ScDPItemData(const rtl::OUString& rStr) :
    mpString(new rtl::OUString(rStr)), meType(String) {}

ScDPItemData::ScDPItemData(sal_Int32 nGroupType, sal_Int32 nValue) :
    meType(GroupValue)
{
    maGroupValue.mnGroupType = nGroupType;
    maGroupValue.mnValue = nValue;
}

ScDPItemData::~ScDPItemData()
{
    DisposeString();
}

ScDPItemData::Type ScDPItemData::GetType() const
{
    return meType;
}

void ScDPItemData::SetString(const rtl::OUString& rS)
{
    DisposeString();
    mpString = new rtl::OUString(rS);
    meType = String;
}

void ScDPItemData::SetValue(double fVal)
{
    DisposeString();
    mfValue = fVal;
    meType = Value;
}

void ScDPItemData::SetRangeStart(double fVal)
{
    DisposeString();
    mfValue = fVal;
    meType = RangeStart;
}

void ScDPItemData::SetRangeFirst()
{
    DisposeString();
    rtl::math::setInf(&mfValue, true);
    meType = RangeStart;
}

void ScDPItemData::SetRangeLast()
{
    DisposeString();
    rtl::math::setInf(&mfValue, false);
    meType = RangeStart;
}

void ScDPItemData::SetErrorString(const rtl::OUString& rS)
{
    SetString(rS);
    meType = Error;
}

bool ScDPItemData::IsCaseInsEqual(const ScDPItemData& r) const
{
    if (meType != r.meType)
        return false;

    switch (meType)
    {
        case Value:
        case RangeStart:
            return rtl::math::approxEqual(mfValue, r.mfValue);
        case GroupValue:
            return maGroupValue.mnGroupType == r.maGroupValue.mnGroupType &&
                maGroupValue.mnValue == r.maGroupValue.mnValue;
        default:
            ;
    }

    return ScGlobal::GetpTransliteration()->isEqual(GetString(), r.GetString());
}

bool ScDPItemData::operator== (const ScDPItemData& r) const
{
    if (meType != r.meType)
        return false;

    switch (meType)
    {
        case Value:
        case RangeStart:
            return rtl::math::approxEqual(mfValue, r.mfValue);
        case GroupValue:
            return maGroupValue.mnGroupType == r.maGroupValue.mnGroupType &&
                maGroupValue.mnValue == r.maGroupValue.mnValue;
        default:
            ;
    }

    // need exact equality until we have a safe case insensitive string hash
    return GetString() == r.GetString();
}

bool ScDPItemData::operator!= (const ScDPItemData& r) const
{
    return !operator== (r);
}

bool ScDPItemData::operator< (const ScDPItemData& r) const
{
    return Compare(*this, r) == -1;
}

ScDPItemData& ScDPItemData::operator= (const ScDPItemData& r)
{
    meType = r.meType;
    switch (r.meType)
    {
        case String:
        case Error:
            mpString = new rtl::OUString(*r.mpString);
        break;
        case Value:
        case RangeStart:
            mfValue = r.mfValue;
        break;
        case GroupValue:
            maGroupValue.mnGroupType = r.maGroupValue.mnGroupType;
            maGroupValue.mnValue = r.maGroupValue.mnValue;
        break;
        case Empty:
        default:
            mfValue = 0.0;
    }
    return *this;
}

sal_uInt8 ScDPItemData::GetCellType() const
{
    switch (meType)
    {
        case Error:
            return SC_VALTYPE_ERROR;
        case Empty:
            return SC_VALTYPE_EMPTY;
        case Value:
            return SC_VALTYPE_VALUE;
        default:
            ;
    }

    return SC_VALTYPE_STRING;
}

#if DEBUG_DP_ITEM_DATA
void ScDPItemData::Dump(const char* msg) const
{
    printf("--- (%s)\n", msg);
    switch (meType)
    {
        case Empty:
            printf("empty\n");
        break;
        case Error:
            printf("error: %s\n",
                   rtl::OUStringToOString(*mpString, RTL_TEXTENCODING_UTF8).getStr());
        break;
        case GroupValue:
            printf("group value: group type = %d  value = %d\n",
                   maGroupValue.mnGroupType, maGroupValue.mnValue);
        break;
        case String:
            printf("string: %s\n",
                   rtl::OUStringToOString(*mpString, RTL_TEXTENCODING_UTF8).getStr());
        break;
        case Value:
            printf("value: %g\n", mfValue);
        break;
        case RangeStart:
            printf("range start: %g\n", mfValue);
        break;
        default:
            printf("unknown type\n");
    }
    printf("---\n");
}
#endif

bool ScDPItemData::IsEmpty() const
{
    return meType == Empty;
}

bool ScDPItemData::IsValue() const
{
    return meType == Value;
}

rtl::OUString ScDPItemData::GetString() const
{
    switch (meType)
    {
        case String:
        case Error:
            return *mpString;
        case Value:
            return rtl::OUString::valueOf(mfValue);
        case GroupValue:
        case RangeStart:
            return rtl::OUString::createFromAscii("fail");
        case Empty:
        default:
            ;
    }

    return rtl::OUString();
}

double ScDPItemData::GetValue() const
{
    if (meType == Value || meType == RangeStart)
        return mfValue;

    return 0.0;
}

ScDPItemData::GroupValueAttr ScDPItemData::GetGroupValue() const
{
    if (meType == GroupValue)
        return maGroupValue;

    GroupValueAttr aGV;
    aGV.mnGroupType = -1;
    aGV.mnValue = -1;
    return aGV;
}

bool ScDPItemData::HasStringData() const
{
    return meType == String || meType == Error;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>Fixed memory leak.<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * Version: MPL 1.1 / GPLv3+ / LGPLv3+
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License or as specified alternatively below. You may obtain a copy of
 * the License at http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * Major Contributor(s):
 *   Copyright (C) 2012 Kohei Yoshida <kohei.yoshida@suse.com>
 *
 * All Rights Reserved.
 *
 * For minor contributions see the git repository.
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
 * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
 * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
 * instead of those above.
 */

#include "dpitemdata.hxx"

#include "document.hxx"
#include "dpobject.hxx"
#include "cell.hxx"
#include "globstr.hrc"
#include "dptabdat.hxx"
#include "rtl/math.hxx"

const sal_Int32 ScDPItemData::DateFirst = -1;
const sal_Int32 ScDPItemData::DateLast  = 10000;

sal_Int32 ScDPItemData::Compare(const ScDPItemData& rA, const ScDPItemData& rB)
{
    if (rA.meType != rB.meType)
    {
        // group value, value and string in this order.
        return rA.meType < rB.meType ? -1 : 1;
    }

    switch (rA.meType)
    {
        case GroupValue:
        {
            if (rA.maGroupValue.mnGroupType == rB.maGroupValue.mnGroupType)
            {
                if (rA.maGroupValue.mnValue == rB.maGroupValue.mnValue)
                    return 0;

                return rA.maGroupValue.mnValue < rB.maGroupValue.mnValue ? -1 : 1;
            }

            return rA.maGroupValue.mnGroupType < rB.maGroupValue.mnGroupType ? -1 : 1;
        }
        case Value:
        case RangeStart:
        {
            if (rA.mfValue == rB.mfValue)
                return 0;

            return rA.mfValue < rB.mfValue ? -1 : 1;
        }
        case String:
        case Error:
            return ScGlobal::GetCollator()->compareString(rA.GetString(), rB.GetString());
        default:
            ;
    }
    return 0;
}

ScDPItemData::ScDPItemData() :
    mfValue(0.0), meType(Empty) {}

ScDPItemData::ScDPItemData(const ScDPItemData& r) :
    meType(r.meType)
{
    switch (r.meType)
    {
        case String:
        case Error:
            mpString = new rtl::OUString(*r.mpString);
        break;
        case Value:
        case RangeStart:
            mfValue = r.mfValue;
        break;
        case GroupValue:
            maGroupValue.mnGroupType = r.maGroupValue.mnGroupType;
            maGroupValue.mnValue = r.maGroupValue.mnValue;
        break;
        case Empty:
        default:
            mfValue = 0.0;
    }
}

void ScDPItemData::DisposeString()
{
    if (meType == String || meType == Error)
        delete mpString;
}

ScDPItemData::ScDPItemData(const rtl::OUString& rStr) :
    mpString(new rtl::OUString(rStr)), meType(String) {}

ScDPItemData::ScDPItemData(sal_Int32 nGroupType, sal_Int32 nValue) :
    meType(GroupValue)
{
    maGroupValue.mnGroupType = nGroupType;
    maGroupValue.mnValue = nValue;
}

ScDPItemData::~ScDPItemData()
{
    DisposeString();
}

ScDPItemData::Type ScDPItemData::GetType() const
{
    return meType;
}

void ScDPItemData::SetString(const rtl::OUString& rS)
{
    DisposeString();
    mpString = new rtl::OUString(rS);
    meType = String;
}

void ScDPItemData::SetValue(double fVal)
{
    DisposeString();
    mfValue = fVal;
    meType = Value;
}

void ScDPItemData::SetRangeStart(double fVal)
{
    DisposeString();
    mfValue = fVal;
    meType = RangeStart;
}

void ScDPItemData::SetRangeFirst()
{
    DisposeString();
    rtl::math::setInf(&mfValue, true);
    meType = RangeStart;
}

void ScDPItemData::SetRangeLast()
{
    DisposeString();
    rtl::math::setInf(&mfValue, false);
    meType = RangeStart;
}

void ScDPItemData::SetErrorString(const rtl::OUString& rS)
{
    SetString(rS);
    meType = Error;
}

bool ScDPItemData::IsCaseInsEqual(const ScDPItemData& r) const
{
    if (meType != r.meType)
        return false;

    switch (meType)
    {
        case Value:
        case RangeStart:
            return rtl::math::approxEqual(mfValue, r.mfValue);
        case GroupValue:
            return maGroupValue.mnGroupType == r.maGroupValue.mnGroupType &&
                maGroupValue.mnValue == r.maGroupValue.mnValue;
        default:
            ;
    }

    return ScGlobal::GetpTransliteration()->isEqual(GetString(), r.GetString());
}

bool ScDPItemData::operator== (const ScDPItemData& r) const
{
    if (meType != r.meType)
        return false;

    switch (meType)
    {
        case Value:
        case RangeStart:
            return rtl::math::approxEqual(mfValue, r.mfValue);
        case GroupValue:
            return maGroupValue.mnGroupType == r.maGroupValue.mnGroupType &&
                maGroupValue.mnValue == r.maGroupValue.mnValue;
        default:
            ;
    }

    // need exact equality until we have a safe case insensitive string hash
    return GetString() == r.GetString();
}

bool ScDPItemData::operator!= (const ScDPItemData& r) const
{
    return !operator== (r);
}

bool ScDPItemData::operator< (const ScDPItemData& r) const
{
    return Compare(*this, r) == -1;
}

ScDPItemData& ScDPItemData::operator= (const ScDPItemData& r)
{
    DisposeString();
    meType = r.meType;
    switch (r.meType)
    {
        case String:
        case Error:
            mpString = new rtl::OUString(*r.mpString);
        break;
        case Value:
        case RangeStart:
            mfValue = r.mfValue;
        break;
        case GroupValue:
            maGroupValue.mnGroupType = r.maGroupValue.mnGroupType;
            maGroupValue.mnValue = r.maGroupValue.mnValue;
        break;
        case Empty:
        default:
            mfValue = 0.0;
    }
    return *this;
}

sal_uInt8 ScDPItemData::GetCellType() const
{
    switch (meType)
    {
        case Error:
            return SC_VALTYPE_ERROR;
        case Empty:
            return SC_VALTYPE_EMPTY;
        case Value:
            return SC_VALTYPE_VALUE;
        default:
            ;
    }

    return SC_VALTYPE_STRING;
}

#if DEBUG_DP_ITEM_DATA
void ScDPItemData::Dump(const char* msg) const
{
    printf("--- (%s)\n", msg);
    switch (meType)
    {
        case Empty:
            printf("empty\n");
        break;
        case Error:
            printf("error: %s\n",
                   rtl::OUStringToOString(*mpString, RTL_TEXTENCODING_UTF8).getStr());
        break;
        case GroupValue:
            printf("group value: group type = %d  value = %d\n",
                   maGroupValue.mnGroupType, maGroupValue.mnValue);
        break;
        case String:
            printf("string: %s\n",
                   rtl::OUStringToOString(*mpString, RTL_TEXTENCODING_UTF8).getStr());
        break;
        case Value:
            printf("value: %g\n", mfValue);
        break;
        case RangeStart:
            printf("range start: %g\n", mfValue);
        break;
        default:
            printf("unknown type\n");
    }
    printf("---\n");
}
#endif

bool ScDPItemData::IsEmpty() const
{
    return meType == Empty;
}

bool ScDPItemData::IsValue() const
{
    return meType == Value;
}

rtl::OUString ScDPItemData::GetString() const
{
    switch (meType)
    {
        case String:
        case Error:
            return *mpString;
        case Value:
            return rtl::OUString::valueOf(mfValue);
        case GroupValue:
        case RangeStart:
            return rtl::OUString::createFromAscii("fail");
        case Empty:
        default:
            ;
    }

    return rtl::OUString();
}

double ScDPItemData::GetValue() const
{
    if (meType == Value || meType == RangeStart)
        return mfValue;

    return 0.0;
}

ScDPItemData::GroupValueAttr ScDPItemData::GetGroupValue() const
{
    if (meType == GroupValue)
        return maGroupValue;

    GroupValueAttr aGV;
    aGV.mnGroupType = -1;
    aGV.mnValue = -1;
    return aGV;
}

bool ScDPItemData::HasStringData() const
{
    return meType == String || meType == Error;
}

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