fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / sc / source / core / data / document10.cxx
blob977a0dba5be0c1fa876e44164951fad6b4083513
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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 */
10 #include <document.hxx>
11 #include <clipcontext.hxx>
12 #include <formulacell.hxx>
13 #include <clipparam.hxx>
14 #include <table.hxx>
15 #include <tokenarray.hxx>
16 #include <editutil.hxx>
17 #include <listenercontext.hxx>
18 #include <tokenstringcontext.hxx>
19 #include <poolhelp.hxx>
20 #include <bcaslot.hxx>
21 #include <cellvalues.hxx>
22 #include <docpool.hxx>
24 #include "dociter.hxx"
25 #include "patattr.hxx"
26 #include <svl/whiter.hxx>
27 #include <editeng/colritem.hxx>
28 #include "scitems.hxx"
30 // Add totally brand-new methods to this source file.
32 bool ScDocument::IsMerged( const ScAddress& rPos ) const
34 const ScTable* pTab = FetchTable(rPos.Tab());
35 if (!pTab)
36 return false;
38 return pTab->IsMerged(rPos.Col(), rPos.Row());
41 void ScDocument::DeleteBeforeCopyFromClip(
42 sc::CopyFromClipContext& rCxt, const ScMarkData& rMark, sc::ColumnSpanSet& rBroadcastSpans )
44 SCTAB nClipTab = 0;
45 const TableContainer& rClipTabs = rCxt.getClipDoc()->maTabs;
46 SCTAB nClipTabCount = rClipTabs.size();
48 for (SCTAB nTab = rCxt.getTabStart(); nTab <= rCxt.getTabEnd(); ++nTab)
50 ScTable* pTab = FetchTable(nTab);
51 if (!pTab)
52 continue;
54 if (!rMark.GetTableSelect(nTab))
55 continue;
57 while (!rClipTabs[nClipTab])
58 nClipTab = (nClipTab+1) % nClipTabCount;
60 pTab->DeleteBeforeCopyFromClip(rCxt, *rClipTabs[nClipTab], rBroadcastSpans);
62 nClipTab = (nClipTab+1) % nClipTabCount;
66 bool ScDocument::CopyOneCellFromClip(
67 sc::CopyFromClipContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
69 ScDocument* pClipDoc = rCxt.getClipDoc();
70 if (pClipDoc->GetClipParam().mbCutMode)
71 // We don't handle cut and paste or moving of cells here.
72 return false;
74 ScRange aClipRange = pClipDoc->GetClipParam().getWholeRange();
75 if (aClipRange.aStart.Row() != aClipRange.aEnd.Row())
76 // The source is not really a single row. Bail out.
77 return false;
79 SCCOL nSrcColSize = aClipRange.aEnd.Col() - aClipRange.aStart.Col() + 1;
80 SCCOL nDestColSize = nCol2 - nCol1 + 1;
81 if (nDestColSize < nSrcColSize)
82 return false;
84 ScAddress aSrcPos = aClipRange.aStart;
86 for (SCCOL nCol = aClipRange.aStart.Col(); nCol <= aClipRange.aEnd.Col(); ++nCol)
88 ScAddress aTestPos = aSrcPos;
89 aTestPos.SetCol(nCol);
90 if (pClipDoc->IsMerged(aTestPos))
91 // We don't handle merged source cell for this.
92 return false;
95 ScTable* pSrcTab = pClipDoc->FetchTable(aSrcPos.Tab());
96 if (!pSrcTab)
97 return false;
99 rCxt.setSingleCellColumnSize(nSrcColSize);
101 for (SCCOL nColOffset = 0; nColOffset < nSrcColSize; ++nColOffset, aSrcPos.IncCol())
103 const ScPatternAttr* pAttr = pClipDoc->GetPattern(aSrcPos);
104 rCxt.setSingleCellPattern(nColOffset, pAttr);
106 if ((rCxt.getInsertFlag() & (IDF_NOTE | IDF_ADDNOTES)) != IDF_NONE)
107 rCxt.setSingleCellNote(nColOffset, pClipDoc->GetNote(aSrcPos));
109 ScColumn& rSrcCol = pSrcTab->aCol[aSrcPos.Col()];
110 // Determine the script type of the copied single cell.
111 rSrcCol.UpdateScriptTypes(aSrcPos.Row(), aSrcPos.Row());
112 rCxt.setSingleCell(aSrcPos, rSrcCol);
115 // All good. Proceed with the pasting.
117 SCTAB nTabEnd = rCxt.getTabEnd();
118 for (SCTAB i = rCxt.getTabStart(); i <= nTabEnd && i < static_cast<SCTAB>(maTabs.size()); ++i)
120 maTabs[i]->CopyOneCellFromClip(rCxt, nCol1, nRow1, nCol2, nRow2);
121 if (rCxt.getInsertFlag() & IDF_ATTRIB)
122 for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow)
124 maTabs[i]->CopyConditionalFormat(nCol1, nRow, nCol2, nRow, nCol1 - aClipRange.aStart.Col(),
125 nRow - aClipRange.aStart.Row(), pSrcTab);
129 return true;
132 void ScDocument::SetValues( const ScAddress& rPos, const std::vector<double>& rVals )
134 ScTable* pTab = FetchTable(rPos.Tab());
135 if (!pTab)
136 return;
138 pTab->SetValues(rPos.Col(), rPos.Row(), rVals);
141 void ScDocument::TransferCellValuesTo( const ScAddress& rTopPos, size_t nLen, sc::CellValues& rDest )
143 ScTable* pTab = FetchTable(rTopPos.Tab());
144 if (!pTab)
145 return;
147 pTab->TransferCellValuesTo(rTopPos.Col(), rTopPos.Row(), nLen, rDest);
150 void ScDocument::CopyCellValuesFrom( const ScAddress& rTopPos, const sc::CellValues& rSrc )
152 ScTable* pTab = FetchTable(rTopPos.Tab());
153 if (!pTab)
154 return;
156 pTab->CopyCellValuesFrom(rTopPos.Col(), rTopPos.Row(), rSrc);
159 std::set<Color> ScDocument::GetDocColors()
161 std::set<Color> aDocColors;
162 ScDocumentPool *pPool = GetPool();
163 const sal_uInt16 pAttribs[] = {ATTR_BACKGROUND, ATTR_FONT_COLOR};
164 for (size_t i=0; i<SAL_N_ELEMENTS( pAttribs ); i++)
166 const sal_uInt16 nAttrib = pAttribs[i];
167 const sal_uInt32 nCount = pPool->GetItemCount2(nAttrib);
168 for (sal_uInt32 j=0; j<nCount; j++)
170 const SvxColorItem *pItem = static_cast<const SvxColorItem*>(pPool->GetItem2(nAttrib, j));
171 if (pItem == 0)
172 continue;
173 Color aColor( pItem->GetValue() );
174 if (COL_AUTO != aColor.GetColor())
175 aDocColors.insert(aColor);
178 return aDocColors;
181 void ScDocument::SetCalcConfig( const ScCalcConfig& rConfig )
183 maCalcConfig = rConfig;
186 void ScDocument::ConvertFormulaToValue( const ScRange& rRange, sc::TableValues* pUndo )
188 sc::EndListeningContext aCxt(*this);
190 for (SCTAB nTab = rRange.aStart.Tab(); nTab <= rRange.aEnd.Tab(); ++nTab)
192 ScTable* pTab = FetchTable(nTab);
193 if (!pTab)
194 continue;
196 pTab->ConvertFormulaToValue(
197 aCxt, rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row(),
198 pUndo);
201 aCxt.purgeEmptyBroadcasters();
204 void ScDocument::SwapNonEmpty( sc::TableValues& rValues )
206 const ScRange& rRange = rValues.getRange();
207 if (!rRange.IsValid())
208 return;
210 boost::shared_ptr<sc::ColumnBlockPositionSet> pPosSet(new sc::ColumnBlockPositionSet(*this));
211 sc::StartListeningContext aStartCxt(*this, pPosSet);
212 sc::EndListeningContext aEndCxt(*this, pPosSet);
214 for (SCTAB nTab = rRange.aStart.Tab(); nTab <= rRange.aEnd.Tab(); ++nTab)
216 ScTable* pTab = FetchTable(nTab);
217 if (!pTab)
218 continue;
220 pTab->SwapNonEmpty(rValues, aStartCxt, aEndCxt);
223 aEndCxt.purgeEmptyBroadcasters();
226 void ScDocument::PreprocessRangeNameUpdate()
228 sc::EndListeningContext aEndListenCxt(*this);
229 sc::CompileFormulaContext aCompileCxt(this);
231 TableContainer::iterator it = maTabs.begin(), itEnd = maTabs.end();
232 for (; it != itEnd; ++it)
234 ScTable* p = *it;
235 p->PreprocessRangeNameUpdate(aEndListenCxt, aCompileCxt);
239 void ScDocument::PreprocessDBDataUpdate()
241 sc::EndListeningContext aEndListenCxt(*this);
242 sc::CompileFormulaContext aCompileCxt(this);
244 TableContainer::iterator it = maTabs.begin(), itEnd = maTabs.end();
245 for (; it != itEnd; ++it)
247 ScTable* p = *it;
248 p->PreprocessDBDataUpdate(aEndListenCxt, aCompileCxt);
252 void ScDocument::CompileHybridFormula()
254 sc::StartListeningContext aStartListenCxt(*this);
255 sc::CompileFormulaContext aCompileCxt(this);
256 TableContainer::iterator it = maTabs.begin(), itEnd = maTabs.end();
257 for (; it != itEnd; ++it)
259 ScTable* p = *it;
260 p->CompileHybridFormula(aStartListenCxt, aCompileCxt);
264 void ScDocument::SharePooledResources( ScDocument* pSrcDoc )
266 xPoolHelper = pSrcDoc->xPoolHelper;
267 mpCellStringPool = pSrcDoc->mpCellStringPool;
270 void ScDocument::UpdateScriptTypes( const ScAddress& rPos, SCCOL nColSize, SCROW nRowSize )
272 ScTable* pTab = FetchTable(rPos.Tab());
273 if (!pTab)
274 return;
276 pTab->UpdateScriptTypes(rPos.Col(), rPos.Row(), rPos.Col()+nColSize-1, rPos.Row()+nRowSize-1);
279 bool ScDocument::HasUniformRowHeight( SCTAB nTab, SCROW nRow1, SCROW nRow2 ) const
281 const ScTable* pTab = FetchTable(nTab);
282 if (!pTab)
283 return false;
285 return pTab->HasUniformRowHeight(nRow1, nRow2);
288 void ScDocument::UnshareFormulaCells( SCTAB nTab, SCCOL nCol, std::vector<SCROW>& rRows )
290 ScTable* pTab = FetchTable(nTab);
291 if (!pTab)
292 return;
294 pTab->UnshareFormulaCells(nCol, rRows);
297 void ScDocument::RegroupFormulaCells( SCTAB nTab, SCCOL nCol )
299 ScTable* pTab = FetchTable(nTab);
300 if (!pTab)
301 return;
303 pTab->RegroupFormulaCells(nCol);
306 void ScDocument::CollectAllAreaListeners(
307 std::vector<SvtListener*>& rListener, const ScRange& rRange, sc::AreaOverlapType eType )
309 if (!pBASM)
310 return;
312 std::vector<sc::AreaListener> aAL = pBASM->GetAllListeners(rRange, eType);
313 std::vector<sc::AreaListener>::iterator it = aAL.begin(), itEnd = aAL.end();
314 for (; it != itEnd; ++it)
315 rListener.push_back(it->mpListener);
318 bool ScDocument::HasFormulaCell( const ScRange& rRange ) const
320 if (!rRange.IsValid())
321 return false;
323 for (SCTAB nTab = rRange.aStart.Tab(); nTab <= rRange.aEnd.Tab(); ++nTab)
325 const ScTable* pTab = FetchTable(nTab);
326 if (!pTab)
327 continue;
329 if (pTab->HasFormulaCell(rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row()))
330 return true;
333 return false;
336 void ScDocument::EndListeningIntersectedGroup(
337 sc::EndListeningContext& rCxt, const ScAddress& rPos, std::vector<ScAddress>* pGroupPos )
339 ScTable* pTab = FetchTable(rPos.Tab());
340 if (!pTab)
341 return;
343 pTab->EndListeningIntersectedGroup(rCxt, rPos.Col(), rPos.Row(), pGroupPos);
346 void ScDocument::EndListeningIntersectedGroups(
347 sc::EndListeningContext& rCxt, const ScRange& rRange, std::vector<ScAddress>* pGroupPos )
349 for (SCTAB nTab = rRange.aStart.Tab(); nTab <= rRange.aEnd.Tab(); ++nTab)
351 ScTable* pTab = FetchTable(nTab);
352 if (!pTab)
353 continue;
355 pTab->EndListeningIntersectedGroups(
356 rCxt, rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row(),
357 pGroupPos);
361 void ScDocument::EndListeningGroups( const std::vector<ScAddress>& rPosArray )
363 sc::EndListeningContext aCxt(*this);
364 std::vector<ScAddress>::const_iterator it = rPosArray.begin(), itEnd = rPosArray.end();
365 for (; it != itEnd; ++it)
367 const ScAddress& rPos = *it;
368 ScTable* pTab = FetchTable(rPos.Tab());
369 if (!pTab)
370 return;
372 pTab->EndListeningGroup(aCxt, rPos.Col(), rPos.Row());
375 aCxt.purgeEmptyBroadcasters();
378 void ScDocument::SetNeedsListeningGroups( const std::vector<ScAddress>& rPosArray )
380 std::vector<ScAddress>::const_iterator it = rPosArray.begin(), itEnd = rPosArray.end();
381 for (; it != itEnd; ++it)
383 const ScAddress& rPos = *it;
384 ScTable* pTab = FetchTable(rPos.Tab());
385 if (!pTab)
386 return;
388 pTab->SetNeedsListeningGroup(rPos.Col(), rPos.Row());
392 namespace {
394 class StartNeededListenersHandler : std::unary_function<ScTable*, void>
396 boost::shared_ptr<sc::StartListeningContext> mpCxt;
397 public:
398 StartNeededListenersHandler( ScDocument& rDoc ) : mpCxt(new sc::StartListeningContext(rDoc)) {}
400 void operator() (ScTable* p)
402 if (p)
403 p->StartListeners(*mpCxt, false);
409 void ScDocument::StartNeededListeners()
411 std::for_each(maTabs.begin(), maTabs.end(), StartNeededListenersHandler(*this));
414 void ScDocument::StartAllListeners( const ScRange& rRange )
416 boost::shared_ptr<sc::ColumnBlockPositionSet> pPosSet(new sc::ColumnBlockPositionSet(*this));
417 sc::StartListeningContext aStartCxt(*this, pPosSet);
418 sc::EndListeningContext aEndCxt(*this, pPosSet);
420 for (SCTAB nTab = rRange.aStart.Tab(); nTab <= rRange.aEnd.Tab(); ++nTab)
422 ScTable* pTab = FetchTable(nTab);
423 if (!pTab)
424 continue;
426 pTab->StartListeningFormulaCells(
427 aStartCxt, aEndCxt,
428 rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row());
432 void ScDocument::EndAllListeners( const ScRange& rRange )
434 sc::EndListeningContext aEndCxt(*this);
436 for (SCTAB nTab = rRange.aStart.Tab(); nTab <= rRange.aEnd.Tab(); ++nTab)
438 ScTable* pTab = FetchTable(nTab);
439 if (!pTab)
440 continue;
442 pTab->EndListeningFormulaCells(
443 aEndCxt,
444 rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row());
448 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */