Kaydet (Commit) 2bf0fd73 authored tarafından Kohei Yoshida's avatar Kohei Yoshida

Moved ScDPItemData into own files.

üst dc261fc0
......@@ -107,6 +107,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\
sc/source/core/data/dpdimsave \
sc/source/core/data/dpglobal \
sc/source/core/data/dpgroup \
sc/source/core/data/dpitemdata \
sc/source/core/data/dpobject \
sc/source/core/data/dpoutput \
sc/source/core/data/dpoutputgeometry \
......
......@@ -32,7 +32,6 @@
#include <algorithm>
#include <list>
#include <vector>
#include <tools/gen.hxx>
#include <global.hxx>
......@@ -71,83 +70,6 @@
#define PIVOT_FUNC_STD_VARP 0x0400
#define PIVOT_FUNC_AUTO 0x1000
class SC_DLLPUBLIC ScDPItemData
{
public:
enum {
MK_VAL = 0x01,
MK_DATA = 0x02,
MK_ERR = 0x04,
MK_DATE = 0x08,
MK_DATEPART = 0x10
};
static bool isDate( sal_uLong nNumType );
private:
union
{
sal_uLong mnNumFormat;
sal_Int32 mnDatePart;
};
String maString;
double mfValue;
sal_uInt8 mbFlag;
friend class ScDPCache;
public:
ScDPItemData();
ScDPItemData(sal_uLong nNF, const String & rS, double fV, sal_uInt8 bF);
ScDPItemData(const String& rS, double fV = 0.0, bool bHV = false, const sal_uLong nNumFormat = 0 , bool bData = true);
ScDPItemData(ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nDocTab, bool bLabel);
void SetString( const String& rS );
bool IsCaseInsEqual(const ScDPItemData& r) const;
size_t Hash() const;
// exact equality
bool operator==( const ScDPItemData& r ) const;
// case insensitive equality
static sal_Int32 Compare( const ScDPItemData& rA, const ScDPItemData& rB );
public:
bool IsHasData() const ;
bool IsHasErr() const ;
bool IsValue() const;
String GetString() const ;
double GetValue() const ;
bool HasStringData() const ;
bool IsDate() const;
bool HasDatePart() const;
void SetDate( bool b ) ;
sal_uInt8 GetType() const;
};
class SC_DLLPUBLIC ScDPItemDataPool
{
public:
ScDPItemDataPool();
ScDPItemDataPool(const ScDPItemDataPool& r);
virtual ~ScDPItemDataPool();
virtual const ScDPItemData* getData( sal_Int32 nId );
virtual sal_Int32 getDataId( const ScDPItemData& aData );
virtual sal_Int32 insertData( const ScDPItemData& aData );
protected:
struct DataHashFunc : public std::unary_function< const ScDPItemData &, size_t >
{
size_t operator() (const ScDPItemData &rData) const { return rData.Hash(); }
};
typedef ::boost::unordered_multimap< ScDPItemData, sal_Int32, DataHashFunc > DataHash;
::std::vector< ScDPItemData > maItems;
DataHash maItemIds;
};
namespace ScDPGlobal
{
// common operation
......
/* -*- 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.
*/
#ifndef __SC_DPITEMDATA_HXX__
#define __SC_DPITEMDATA_HXX__
#include "scdllapi.h"
#include "sal/types.h"
#include "tools/solar.h"
#include "tools/string.hxx"
#include "address.hxx"
#include <vector>
#include <boost/unordered_map.hpp>
class ScDocument;
class SC_DLLPUBLIC ScDPItemData
{
public:
enum {
MK_VAL = 0x01,
MK_DATA = 0x02,
MK_ERR = 0x04,
MK_DATE = 0x08,
MK_DATEPART = 0x10
};
static bool isDate( sal_uLong nNumType );
private:
union
{
sal_uLong mnNumFormat;
sal_Int32 mnDatePart;
};
String maString;
double mfValue;
sal_uInt8 mbFlag;
friend class ScDPCache;
public:
ScDPItemData();
ScDPItemData(sal_uLong nNF, const String & rS, double fV, sal_uInt8 bF);
ScDPItemData(const String& rS, double fV = 0.0, bool bHV = false, const sal_uLong nNumFormat = 0 , bool bData = true);
ScDPItemData(ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nDocTab, bool bLabel);
void SetString( const String& rS );
bool IsCaseInsEqual(const ScDPItemData& r) const;
size_t Hash() const;
// exact equality
bool operator==( const ScDPItemData& r ) const;
// case insensitive equality
static sal_Int32 Compare( const ScDPItemData& rA, const ScDPItemData& rB );
public:
bool IsHasData() const ;
bool IsHasErr() const ;
bool IsValue() const;
String GetString() const ;
double GetValue() const ;
bool HasStringData() const ;
bool IsDate() const;
bool HasDatePart() const;
void SetDate( bool b ) ;
sal_uInt8 GetType() const;
};
class SC_DLLPUBLIC ScDPItemDataPool
{
public:
ScDPItemDataPool();
ScDPItemDataPool(const ScDPItemDataPool& r);
virtual ~ScDPItemDataPool();
virtual const ScDPItemData* getData( sal_Int32 nId );
virtual sal_Int32 getDataId( const ScDPItemData& aData );
virtual sal_Int32 insertData( const ScDPItemData& aData );
protected:
struct DataHashFunc : public std::unary_function< const ScDPItemData &, size_t >
{
size_t operator() (const ScDPItemData &rData) const { return rData.Hash(); }
};
typedef ::boost::unordered_multimap< ScDPItemData, sal_Int32, DataHashFunc > DataHash;
::std::vector< ScDPItemData > maItems;
DataHash maItemIds;
};
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
......@@ -32,6 +32,7 @@
#include "global.hxx"
#include <svl/zforlist.hxx>
#include "dpglobal.hxx"
#include "dpitemdata.hxx"
#include <com/sun/star/sdbc/DataType.hpp>
#include <com/sun/star/sdbc/XRow.hpp>
......
......@@ -29,209 +29,6 @@
#include "dpglobal.hxx"
#include "document.hxx"
#include "dpobject.hxx"
#include "cell.hxx"
#include "globstr.hrc"
#include "dptabdat.hxx"
bool ScDPItemData::isDate( sal_uLong nNumType )
{
return ((nNumType & NUMBERFORMAT_DATE) != 0) ? 1 : 0;
}
ScDPItemData::ScDPItemData() :
mnNumFormat( 0 ), mfValue(0.0), mbFlag(0) {}
ScDPItemData::ScDPItemData(sal_uLong nNF, const String & rS, double fV, sal_uInt8 bF) :
mnNumFormat(nNF), maString(rS), mfValue(fV), mbFlag(bF) {}
ScDPItemData::ScDPItemData(const String& rS, double fV, bool bHV, const sal_uLong nNumFormatP, bool bData) :
mnNumFormat( nNumFormatP ), maString(rS), mfValue(fV),
mbFlag( (MK_VAL*!!bHV) | (MK_DATA*!!bData) | (MK_ERR*!!false) | (MK_DATE*!!isDate( mnNumFormat ) ) )
{
}
ScDPItemData::ScDPItemData(ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nDocTab, bool bLabel) :
mnNumFormat( 0 ), mfValue(0.0), mbFlag( 0 )
{
String aDocStr;
pDoc->GetString( nCol, nRow, nDocTab, aDocStr );
SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
ScAddress aPos( nCol, nRow, nDocTab );
ScBaseCell* pCell = pDoc->GetCell( aPos );
if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA && ((ScFormulaCell*)pCell)->GetErrCode() )
{
SetString ( aDocStr );
mbFlag |= MK_ERR;
}
else if ( pDoc->HasValueData( nCol, nRow, nDocTab ) )
{
double fVal = pDoc->GetValue(ScAddress(nCol, nRow, nDocTab));
sal_uLong nFormat = NUMBERFORMAT_NUMBER;
if ( pFormatter )
nFormat = pFormatter->GetType( pDoc->GetNumberFormat( ScAddress( nCol, nRow, nDocTab ) ) );
maString = aDocStr;
mfValue = fVal;
mbFlag |= MK_VAL|MK_DATA;
mnNumFormat = pDoc->GetNumberFormat( ScAddress( nCol, nRow, nDocTab ) );
isDate( nFormat ) ? ( mbFlag |= MK_DATE ) : (mbFlag &= ~MK_DATE);
}
else if (bLabel || pDoc->HasData(nCol, nRow, nDocTab))
{
if (bLabel && !aDocStr.Len())
{
// Replace an empty label string with column name.
rtl::OUStringBuffer aBuf;
aBuf.append(ScGlobal::GetRscString(STR_COLUMN));
aBuf.append(sal_Unicode(' '));
ScAddress aColAddr(nCol, 0, 0);
rtl::OUString aColStr;
aColAddr.Format(aColStr, SCA_VALID_COL, NULL);
aBuf.append(aColStr);
aDocStr = aBuf.makeStringAndClear();
}
SetString(aDocStr);
}
}
void ScDPItemData::SetString( const String& rS )
{
maString = rS;
mbFlag &= ~(MK_VAL|MK_DATE);
mnNumFormat = 0;
mbFlag |= MK_DATA;
}
bool ScDPItemData::IsCaseInsEqual( const ScDPItemData& r ) const
{
//! pass Transliteration?
//! inline?
return IsValue() ? ( r.IsValue() && rtl::math::approxEqual( mfValue, r.mfValue ) ) :
( !r.IsValue() &&
ScGlobal::GetpTransliteration()->isEqual( maString, r.maString ) );
}
size_t ScDPItemData::Hash() const
{
if ( IsValue() )
return (size_t) rtl::math::approxFloor( mfValue );
else
// If we do unicode safe case insensitive hash we can drop
// ScDPItemData::operator== and use ::IsCasInsEqual
return rtl_ustr_hashCode_WithLength( maString.GetBuffer(), maString.Len() );
}
bool ScDPItemData::operator==( const ScDPItemData& r ) const
{
if ( IsValue() )
{
if( (HasDatePart() != r.HasDatePart()) || (HasDatePart() && mnDatePart != r.mnDatePart) )
return false;
if ( IsDate() != r.IsDate() )
return false;
else if ( r.IsValue() )
return rtl::math::approxEqual( mfValue, r.mfValue );
else
return false;
}
else if ( r.IsValue() )
return false;
else
// need exact equality until we have a safe case insensitive string hash
return maString == r.maString;
}
sal_Int32 ScDPItemData::Compare( const ScDPItemData& rA,
const ScDPItemData& rB )
{
if ( rA.IsValue() )
{
if ( rB.IsValue() )
{
if ( rtl::math::approxEqual( rA.mfValue, rB.mfValue ) )
{
if ( rA.IsDate() == rB.IsDate() )
return 0;
else
return rA.IsDate() ? 1: -1;
}
else if ( rA.mfValue < rB.mfValue )
return -1;
else
return 1;
}
else
return -1; // values first
}
else if ( rB.IsValue() )
return 1; // values first
else
return ScGlobal::GetCollator()->compareString( rA.maString, rB.maString );
}
sal_uInt8 ScDPItemData::GetType() const
{
if ( IsHasErr() )
return SC_VALTYPE_ERROR;
else if ( !IsHasData() )
return SC_VALTYPE_EMPTY;
else if ( IsValue())
return SC_VALTYPE_VALUE;
else
return SC_VALTYPE_STRING;
}
bool ScDPItemData::IsHasData() const
{
return !!(mbFlag&MK_DATA);
}
bool ScDPItemData::IsHasErr() const
{
return !!(mbFlag&MK_ERR);
}
bool ScDPItemData::IsValue() const
{
return !!(mbFlag&MK_VAL);
}
String ScDPItemData::GetString() const
{
return maString;
}
double ScDPItemData::GetValue() const
{
return mfValue;
}
bool ScDPItemData::HasStringData() const
{
return IsHasData()&&!IsHasErr()&&!IsValue();
}
bool ScDPItemData::IsDate() const
{
return !!(mbFlag&MK_DATE);
}
bool ScDPItemData::HasDatePart() const
{
return !!(mbFlag&MK_DATEPART);
}
void ScDPItemData::SetDate( bool b )
{
b ? ( mbFlag |= MK_DATE ) : ( mbFlag &= ~MK_DATE );
}
namespace ScDPGlobal
{
......@@ -245,54 +42,4 @@ namespace ScDPGlobal
}
ScDPItemDataPool::ScDPItemDataPool()
{
}
ScDPItemDataPool::ScDPItemDataPool(const ScDPItemDataPool& r):
maItems(r.maItems),
maItemIds(r.maItemIds)
{
}
ScDPItemDataPool::~ScDPItemDataPool()
{
}
const ScDPItemData* ScDPItemDataPool::getData( sal_Int32 nId )
{
if ( nId >= static_cast<sal_Int32>(maItems.size()) )
return NULL;
else
return &(maItems[nId]);
}
sal_Int32 ScDPItemDataPool::getDataId( const ScDPItemData& aData )
{
DataHash::const_iterator itr = maItemIds.find( aData),
itrEnd = maItemIds.end();
if ( itr == itrEnd )
// not exist
return -1;
else //exist
return itr->second;
}
sal_Int32 ScDPItemDataPool::insertData( const ScDPItemData& aData )
{
sal_Int32 nResult = getDataId( aData );
if( nResult < 0 )
{
maItemIds.insert( DataHash::value_type( aData, nResult = maItems.size() ) );
maItems.push_back( aData );
}
return nResult;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
/* -*- 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"
bool ScDPItemData::isDate( sal_uLong nNumType )
{
return ((nNumType & NUMBERFORMAT_DATE) != 0) ? 1 : 0;
}
ScDPItemData::ScDPItemData() :
mnNumFormat( 0 ), mfValue(0.0), mbFlag(0) {}
ScDPItemData::ScDPItemData(sal_uLong nNF, const String & rS, double fV, sal_uInt8 bF) :
mnNumFormat(nNF), maString(rS), mfValue(fV), mbFlag(bF) {}
ScDPItemData::ScDPItemData(const String& rS, double fV, bool bHV, const sal_uLong nNumFormatP, bool bData) :
mnNumFormat( nNumFormatP ), maString(rS), mfValue(fV),
mbFlag( (MK_VAL*!!bHV) | (MK_DATA*!!bData) | (MK_ERR*!!false) | (MK_DATE*!!isDate( mnNumFormat ) ) )
{
}
ScDPItemData::ScDPItemData(ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nDocTab, bool bLabel) :
mnNumFormat( 0 ), mfValue(0.0), mbFlag( 0 )
{
String aDocStr;
pDoc->GetString( nCol, nRow, nDocTab, aDocStr );
SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
ScAddress aPos( nCol, nRow, nDocTab );
ScBaseCell* pCell = pDoc->GetCell( aPos );
if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA && ((ScFormulaCell*)pCell)->GetErrCode() )
{
SetString ( aDocStr );
mbFlag |= MK_ERR;
}
else if ( pDoc->HasValueData( nCol, nRow, nDocTab ) )
{
double fVal = pDoc->GetValue(ScAddress(nCol, nRow, nDocTab));
sal_uLong nFormat = NUMBERFORMAT_NUMBER;
if ( pFormatter )
nFormat = pFormatter->GetType( pDoc->GetNumberFormat( ScAddress( nCol, nRow, nDocTab ) ) );
maString = aDocStr;
mfValue = fVal;
mbFlag |= MK_VAL|MK_DATA;
mnNumFormat = pDoc->GetNumberFormat( ScAddress( nCol, nRow, nDocTab ) );
isDate( nFormat ) ? ( mbFlag |= MK_DATE ) : (mbFlag &= ~MK_DATE);
}
else if (bLabel || pDoc->HasData(nCol, nRow, nDocTab))
{
if (bLabel && !aDocStr.Len())
{
// Replace an empty label string with column name.
rtl::OUStringBuffer aBuf;
aBuf.append(ScGlobal::GetRscString(STR_COLUMN));
aBuf.append(sal_Unicode(' '));
ScAddress aColAddr(nCol, 0, 0);
rtl::OUString aColStr;
aColAddr.Format(aColStr, SCA_VALID_COL, NULL);
aBuf.append(aColStr);
aDocStr = aBuf.makeStringAndClear();
}
SetString(aDocStr);
}
}
void ScDPItemData::SetString( const String& rS )
{
maString = rS;
mbFlag &= ~(MK_VAL|MK_DATE);
mnNumFormat = 0;
mbFlag |= MK_DATA;
}
bool ScDPItemData::IsCaseInsEqual( const ScDPItemData& r ) const
{
//! pass Transliteration?
//! inline?
return IsValue() ? ( r.IsValue() && rtl::math::approxEqual( mfValue, r.mfValue ) ) :
( !r.IsValue() &&
ScGlobal::GetpTransliteration()->isEqual( maString, r.maString ) );
}
size_t ScDPItemData::Hash() const
{
if ( IsValue() )
return (size_t) rtl::math::approxFloor( mfValue );
else
// If we do unicode safe case insensitive hash we can drop
// ScDPItemData::operator== and use ::IsCasInsEqual
return rtl_ustr_hashCode_WithLength( maString.GetBuffer(), maString.Len() );
}
bool ScDPItemData::operator==( const ScDPItemData& r ) const
{
if ( IsValue() )
{
if( (HasDatePart() != r.HasDatePart()) || (HasDatePart() && mnDatePart != r.mnDatePart) )
return false;
if ( IsDate() != r.IsDate() )
return false;
else if ( r.IsValue() )
return rtl::math::approxEqual( mfValue, r.mfValue );
else
return false;
}
else if ( r.IsValue() )
return false;
else
// need exact equality until we have a safe case insensitive string hash
return maString == r.maString;
}
sal_Int32 ScDPItemData::Compare( const ScDPItemData& rA,
const ScDPItemData& rB )
{
if ( rA.IsValue() )
{
if ( rB.IsValue() )
{
if ( rtl::math::approxEqual( rA.mfValue, rB.mfValue ) )
{
if ( rA.IsDate() == rB.IsDate() )
return 0;
else
return rA.IsDate() ? 1: -1;
}
else if ( rA.mfValue < rB.mfValue )
return -1;
else
return 1;
}
else
return -1; // values first
}
else if ( rB.IsValue() )
return 1; // values first
else
return ScGlobal::GetCollator()->compareString( rA.maString, rB.maString );
}
sal_uInt8 ScDPItemData::GetType() const
{
if ( IsHasErr() )
return SC_VALTYPE_ERROR;
else if ( !IsHasData() )
return SC_VALTYPE_EMPTY;
else if ( IsValue())
return SC_VALTYPE_VALUE;
else
return SC_VALTYPE_STRING;
}
bool ScDPItemData::IsHasData() const
{
return !!(mbFlag&MK_DATA);
}
bool ScDPItemData::IsHasErr() const
{
return !!(mbFlag&MK_ERR);
}
bool ScDPItemData::IsValue() const
{
return !!(mbFlag&MK_VAL);
}
String ScDPItemData::GetString() const
{
return maString;
}
double ScDPItemData::GetValue() const
{
return mfValue;
}
bool ScDPItemData::HasStringData() const
{
return IsHasData()&&!IsHasErr()&&!IsValue();
}
bool ScDPItemData::IsDate() const
{
return !!(mbFlag&MK_DATE);
}
bool ScDPItemData::HasDatePart() const
{
return !!(mbFlag&MK_DATEPART);
}
void ScDPItemData::SetDate( bool b )
{
b ? ( mbFlag |= MK_DATE ) : ( mbFlag &= ~MK_DATE );
}
ScDPItemDataPool::ScDPItemDataPool()
{
}
ScDPItemDataPool::ScDPItemDataPool(const ScDPItemDataPool& r):
maItems(r.maItems),
maItemIds(r.maItemIds)
{
}
ScDPItemDataPool::~ScDPItemDataPool()
{
}
const ScDPItemData* ScDPItemDataPool::getData( sal_Int32 nId )
{
if ( nId >= static_cast<sal_Int32>(maItems.size()) )
return NULL;
else
return &(maItems[nId]);
}
sal_Int32 ScDPItemDataPool::getDataId( const ScDPItemData& aData )
{
DataHash::const_iterator itr = maItemIds.find( aData),
itrEnd = maItemIds.end();
if ( itr == itrEnd )
// not exist
return -1;
else //exist
return itr->second;
}
sal_Int32 ScDPItemDataPool::insertData( const ScDPItemData& aData )
{
sal_Int32 nResult = getDataId( aData );
if( nResult < 0 )
{
maItemIds.insert( DataHash::value_type( aData, nResult = maItems.size() ) );
maItems.push_back( aData );
}
return nResult;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment