LibreOffice Module sc (master)  1
documen6.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <scitems.hxx>
21 
22 #include <com/sun/star/i18n/BreakIterator.hpp>
23 #include <com/sun/star/i18n/ScriptType.hpp>
25 
26 #include <document.hxx>
27 #include <cellform.hxx>
28 #include <patattr.hxx>
29 #include <scrdata.hxx>
30 #include <poolhelp.hxx>
31 #include <attrib.hxx>
32 #include <columnspanset.hxx>
33 #include <table.hxx>
34 
35 using namespace com::sun::star;
36 
37 // this file is compiled with exceptions enabled
38 // put functions here that need exceptions!
39 
40 const uno::Reference< i18n::XBreakIterator >& ScDocument::GetBreakIterator()
41 {
42  if ( !pScriptTypeData )
43  pScriptTypeData.reset( new ScScriptTypeData );
44  if ( !pScriptTypeData->xBreakIter.is() )
45  {
46  pScriptTypeData->xBreakIter = i18n::BreakIterator::create( comphelper::getProcessComponentContext() );
47  }
48  return pScriptTypeData->xBreakIter;
49 }
50 
51 bool ScDocument::HasStringWeakCharacters( const OUString& rString )
52 {
53  if (!rString.isEmpty())
54  {
55  uno::Reference<i18n::XBreakIterator> xBreakIter = GetBreakIterator();
56  if ( xBreakIter.is() )
57  {
58  sal_Int32 nLen = rString.getLength();
59 
60  sal_Int32 nPos = 0;
61  do
62  {
63  sal_Int16 nType = xBreakIter->getScriptType( rString, nPos );
64  if ( nType == i18n::ScriptType::WEAK )
65  return true; // found
66 
67  nPos = xBreakIter->endOfScript( rString, nPos, nType );
68  }
69  while ( nPos >= 0 && nPos < nLen );
70  }
71  }
72 
73  return false; // none found
74 }
75 
77 {
78  SvtScriptType nRet = SvtScriptType::NONE;
79  if (!rString.isEmpty())
80  {
81  uno::Reference<i18n::XBreakIterator> xBreakIter = GetBreakIterator();
82  if ( xBreakIter.is() )
83  {
84  sal_Int32 nLen = rString.getLength();
85 
86  sal_Int32 nPos = 0;
87  do
88  {
89  sal_Int16 nType = xBreakIter->getScriptType( rString, nPos );
90  switch ( nType )
91  {
92  case i18n::ScriptType::LATIN:
93  nRet |= SvtScriptType::LATIN;
94  break;
95  case i18n::ScriptType::ASIAN:
96  nRet |= SvtScriptType::ASIAN;
97  break;
98  case i18n::ScriptType::COMPLEX:
99  nRet |= SvtScriptType::COMPLEX;
100  break;
101  // WEAK is ignored
102  }
103  nPos = xBreakIter->endOfScript( rString, nPos, nType );
104  }
105  while ( nPos >= 0 && nPos < nLen );
106  }
107  }
108  return nRet;
109 }
110 
111 SvtScriptType ScDocument::GetCellScriptType( const ScAddress& rPos, sal_uInt32 nNumberFormat,
112  const ScRefCellValue* pCell )
113 {
114  SvtScriptType nStored = GetScriptType(rPos);
115  if ( nStored != SvtScriptType::UNKNOWN ) // stored value valid?
116  return nStored; // use stored value
117 
118  Color* pColor;
119  OUString aStr;
120  if( pCell )
121  ScCellFormat::GetString(*pCell, nNumberFormat, aStr, &pColor, *mxPoolHelper->GetFormTable(), this);
122  else
123  aStr = ScCellFormat::GetString(*this, rPos, nNumberFormat, &pColor, *mxPoolHelper->GetFormTable());
124 
125  SvtScriptType nRet = GetStringScriptType( aStr );
126 
127  SetScriptType(rPos, nRet); // store for later calls
128 
129  return nRet;
130 }
131 
133 {
134  // if script type is set, don't have to get number formats
135 
136  ScAddress aPos(nCol, nRow, nTab);
137  SvtScriptType nStored = GetScriptType(aPos);
138  if ( nStored != SvtScriptType::UNKNOWN ) // stored value valid?
139  return nStored; // use stored value
140 
141  // include number formats from conditional formatting
142 
143  const ScPatternAttr* pPattern = GetPattern( nCol, nRow, nTab );
144  if (!pPattern) return SvtScriptType::NONE;
145  const SfxItemSet* pCondSet = nullptr;
146  if ( !pPattern->GetItem(ATTR_CONDITIONAL).GetCondFormatData().empty() )
147  pCondSet = GetCondResult( nCol, nRow, nTab );
148 
149  sal_uInt32 nFormat = pPattern->GetNumberFormat( mxPoolHelper->GetFormTable(), pCondSet );
150 
151  return GetCellScriptType(aPos, nFormat, pCell);
152 }
153 
154 namespace {
155 
156 class ScriptTypeAggregator : public sc::ColumnSpanSet::Action
157 {
158  ScDocument& mrDoc;
159  sc::ColumnBlockPosition maBlockPos;
160  SvtScriptType mnScriptType;
161 
162 public:
163  explicit ScriptTypeAggregator(ScDocument& rDoc) : mrDoc(rDoc), mnScriptType(SvtScriptType::NONE) {}
164 
165  virtual void startColumn(SCTAB nTab, SCCOL nCol) override
166  {
167  mrDoc.InitColumnBlockPosition(maBlockPos, nTab, nCol);
168  }
169 
170  virtual void execute(const ScAddress& rPos, SCROW nLength, bool bVal) override
171  {
172  if (!bVal)
173  return;
174 
175  mnScriptType |= mrDoc.GetRangeScriptType(maBlockPos, rPos, nLength);
176  };
177 
178  SvtScriptType getScriptType() const { return mnScriptType; }
179 };
180 
181 }
182 
184  sc::ColumnBlockPosition& rBlockPos, const ScAddress& rPos, SCROW nLength )
185 {
186  if (!TableExists(rPos.Tab()))
187  return SvtScriptType::NONE;
188 
189  return maTabs[rPos.Tab()]->GetRangeScriptType(rBlockPos, rPos.Col(), rPos.Row(), rPos.Row()+nLength-1);
190 }
191 
193 {
194  sc::ColumnSpanSet aSet;
195  for (size_t i = 0, n = rRanges.size(); i < n; ++i)
196  {
197  const ScRange& rRange = rRanges[i];
198  SCTAB nTab = rRange.aStart.Tab();
199  SCROW nRow1 = rRange.aStart.Row();
200  SCROW nRow2 = rRange.aEnd.Row();
201  for (SCCOL nCol = rRange.aStart.Col(); nCol <= rRange.aEnd.Col(); ++nCol)
202  aSet.set(*this, nTab, nCol, nRow1, nRow2, true);
203  }
204 
205  ScriptTypeAggregator aAction(*this);
206  aSet.executeAction(aAction);
207  return aAction.getScriptType();
208 }
209 
210 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SC_DLLPUBLIC const css::uno::Reference< css::i18n::XBreakIterator > & GetBreakIterator()
Definition: documen6.cxx:40
ScAddress aStart
Definition: address.hxx:500
SCROW Row() const
Definition: address.hxx:262
static void GetString(const ScRefCellValue &rCell, sal_uInt32 nFormat, OUString &rString, Color **ppColor, SvNumberFormatter &rFormatter, const ScDocument *pDoc, bool bNullVals=true, bool bFormula=false, bool bUseStarFormat=false)
Definition: cellform.cxx:33
SC_DLLPUBLIC bool InitColumnBlockPosition(sc::ColumnBlockPosition &rBlockPos, SCTAB nTab, SCCOL nCol)
Definition: document.cxx:2613
sal_Int64 n
Store position data for column array storage.
ScAddress aEnd
Definition: address.hxx:501
This is very similar to ScCellValue, except that it references the original value instead of copying ...
Definition: cellvalue.hxx:104
bool HasStringWeakCharacters(const OUString &rString)
Definition: documen6.cxx:51
SC_DLLPUBLIC SvtScriptType GetStringScriptType(const OUString &rString)
Definition: documen6.cxx:76
NONE
SvtScriptType GetRangeScriptType(sc::ColumnBlockPosition &rBlockPos, const ScAddress &rPos, SCROW nLength)
Definition: documen6.cxx:183
void set(const ScDocument &rDoc, SCTAB nTab, SCCOL nCol, SCROW nRow, bool bVal)
SCTAB Tab() const
Definition: address.hxx:271
const SfxPoolItem & GetItem(sal_uInt16 nWhichP) const
Definition: patattr.hxx:70
SvtScriptType
int i
sal_Int16 SCCOL
Definition: types.hxx:22
size_t size() const
Definition: rangelst.hxx:90
Structure that stores segments of boolean flags per column, and perform custom action on those segmen...
sal_uInt32 GetNumberFormat(SvNumberFormatter *) const
Definition: patattr.cxx:1256
SCCOL Col() const
Definition: address.hxx:267
sal_Int32 SCROW
Definition: types.hxx:18
SC_DLLPUBLIC SvtScriptType GetScriptType(SCCOL nCol, SCROW nRow, SCTAB nTab, const ScRefCellValue *pCell=nullptr)
Definition: documen6.cxx:132
constexpr TypedWhichId< ScCondFormatItem > ATTR_CONDITIONAL(154)
Reference< XComponentContext > getProcessComponentContext()
QPRO_FUNC_TYPE nType
Definition: qproform.cxx:401
SC_DLLPUBLIC SvtScriptType GetCellScriptType(const ScAddress &rPos, sal_uInt32 nNumberFormat, const ScRefCellValue *pCell=nullptr)
Definition: documen6.cxx:111
aStr
void executeAction(Action &ac) const
sal_uInt16 nPos
sal_Int16 SCTAB
Definition: types.hxx:23