1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <unotools/transliterationwrapper.hxx>
23 #include "globalnames.hxx"
24 #include "refupdat.hxx"
25 #include "rechead.hxx"
26 #include "document.hxx"
27 #include "queryparam.hxx"
28 #include "queryentry.hxx"
29 #include "globstr.hrc"
30 #include "subtotalparam.hxx"
31 #include "sortparam.hxx"
35 using ::std::auto_ptr
;
36 using ::std::unary_function
;
37 using ::std::for_each
;
39 using ::std::remove_if
;
42 bool ScDBData::less::operator() (const ScDBData
& left
, const ScDBData
& right
) const
44 return ScGlobal::GetpTransliteration()->compareString(left
.GetUpperName(), right
.GetUpperName()) < 0;
47 ScDBData::ScDBData( const OUString
& rName
,
49 SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
,
50 bool bByR
, bool bHasH
) :
51 mpSortParam(new ScSortParam
),
52 mpQueryParam(new ScQueryParam
),
53 mpSubTotal(new ScSubTotalParam
),
54 mpImportParam(new ScImportParam
),
73 aUpper
= ScGlobal::pCharClass
->uppercase(aUpper
);
76 ScDBData::ScDBData( const ScDBData
& rData
) :
77 ScRefreshTimer ( rData
),
78 mpSortParam(new ScSortParam(*rData
.mpSortParam
)),
79 mpQueryParam(new ScQueryParam(*rData
.mpQueryParam
)),
80 mpSubTotal(new ScSubTotalParam(*rData
.mpSubTotal
)),
81 mpImportParam(new ScImportParam(*rData
.mpImportParam
)),
83 aUpper (rData
.aUpper
),
84 nTable (rData
.nTable
),
85 nStartCol (rData
.nStartCol
),
86 nStartRow (rData
.nStartRow
),
87 nEndCol (rData
.nEndCol
),
88 nEndRow (rData
.nEndRow
),
89 bByRow (rData
.bByRow
),
90 bHasHeader (rData
.bHasHeader
),
91 bDoSize (rData
.bDoSize
),
92 bKeepFmt (rData
.bKeepFmt
),
93 bStripData (rData
.bStripData
),
94 bIsAdvanced (rData
.bIsAdvanced
),
95 aAdvSource (rData
.aAdvSource
),
96 bDBSelection (rData
.bDBSelection
),
97 nIndex (rData
.nIndex
),
98 bAutoFilter (rData
.bAutoFilter
),
99 bModified (rData
.bModified
)
103 ScDBData::ScDBData( const OUString
& rName
, const ScDBData
& rData
) :
104 ScRefreshTimer ( rData
),
105 mpSortParam(new ScSortParam(*rData
.mpSortParam
)),
106 mpQueryParam(new ScQueryParam(*rData
.mpQueryParam
)),
107 mpSubTotal(new ScSubTotalParam(*rData
.mpSubTotal
)),
108 mpImportParam(new ScImportParam(*rData
.mpImportParam
)),
111 nTable (rData
.nTable
),
112 nStartCol (rData
.nStartCol
),
113 nStartRow (rData
.nStartRow
),
114 nEndCol (rData
.nEndCol
),
115 nEndRow (rData
.nEndRow
),
116 bByRow (rData
.bByRow
),
117 bHasHeader (rData
.bHasHeader
),
118 bDoSize (rData
.bDoSize
),
119 bKeepFmt (rData
.bKeepFmt
),
120 bStripData (rData
.bStripData
),
121 bIsAdvanced (rData
.bIsAdvanced
),
122 aAdvSource (rData
.aAdvSource
),
123 bDBSelection (rData
.bDBSelection
),
124 nIndex (rData
.nIndex
),
125 bAutoFilter (rData
.bAutoFilter
),
126 bModified (rData
.bModified
)
128 aUpper
= ScGlobal::pCharClass
->uppercase(aUpper
);
131 ScDBData
& ScDBData::operator= (const ScDBData
& rData
)
133 // Don't modify the name. The name is not mutable as it is used as a key
134 // in the container to keep the db ranges sorted by the name.
135 ScRefreshTimer::operator=( rData
);
136 mpSortParam
.reset(new ScSortParam(*rData
.mpSortParam
));
137 mpQueryParam
.reset(new ScQueryParam(*rData
.mpQueryParam
));
138 mpSubTotal
.reset(new ScSubTotalParam(*rData
.mpSubTotal
));
139 mpImportParam
.reset(new ScImportParam(*rData
.mpImportParam
));
140 nTable
= rData
.nTable
;
141 nStartCol
= rData
.nStartCol
;
142 nStartRow
= rData
.nStartRow
;
143 nEndCol
= rData
.nEndCol
;
144 nEndRow
= rData
.nEndRow
;
145 bByRow
= rData
.bByRow
;
146 bHasHeader
= rData
.bHasHeader
;
147 bDoSize
= rData
.bDoSize
;
148 bKeepFmt
= rData
.bKeepFmt
;
149 bStripData
= rData
.bStripData
;
150 bIsAdvanced
= rData
.bIsAdvanced
;
151 aAdvSource
= rData
.aAdvSource
;
152 bDBSelection
= rData
.bDBSelection
;
153 nIndex
= rData
.nIndex
;
154 bAutoFilter
= rData
.bAutoFilter
;
159 bool ScDBData::operator== (const ScDBData
& rData
) const
161 // Daten, die nicht in den Params sind
163 if ( nTable
!= rData
.nTable
||
164 bDoSize
!= rData
.bDoSize
||
165 bKeepFmt
!= rData
.bKeepFmt
||
166 bIsAdvanced
!= rData
.bIsAdvanced
||
167 bStripData
!= rData
.bStripData
||
168 // SAB: I think this should be here, but I don't want to break something
169 // bAutoFilter!= rData.bAutoFilter||
170 ScRefreshTimer::operator!=( rData
)
174 if ( bIsAdvanced
&& aAdvSource
!= rData
.aAdvSource
)
177 ScSortParam aSort1
, aSort2
;
178 GetSortParam(aSort1
);
179 rData
.GetSortParam(aSort2
);
180 if (!(aSort1
== aSort2
))
183 ScQueryParam aQuery1
, aQuery2
;
184 GetQueryParam(aQuery1
);
185 rData
.GetQueryParam(aQuery2
);
186 if (!(aQuery1
== aQuery2
))
189 ScSubTotalParam aSubTotal1
, aSubTotal2
;
190 GetSubTotalParam(aSubTotal1
);
191 rData
.GetSubTotalParam(aSubTotal2
);
192 if (!(aSubTotal1
== aSubTotal2
))
195 ScImportParam aImport1
, aImport2
;
196 GetImportParam(aImport1
);
197 rData
.GetImportParam(aImport2
);
198 if (!(aImport1
== aImport2
))
204 ScDBData::~ScDBData()
209 OUString
ScDBData::GetSourceString() const
212 if (mpImportParam
->bImport
)
214 aBuf
.append(mpImportParam
->aDBName
);
216 aBuf
.append(mpImportParam
->aStatement
);
218 return aBuf
.makeStringAndClear();
221 OUString
ScDBData::GetOperations() const
224 if (mpQueryParam
->GetEntryCount())
226 const ScQueryEntry
& rEntry
= mpQueryParam
->GetEntry(0);
228 aBuf
.append(ScGlobal::GetRscString(STR_OPERATION_FILTER
));
231 if (mpSortParam
->maKeyState
[0].bDoSort
)
235 aBuf
.append(ScGlobal::GetRscString(STR_OPERATION_SORT
));
238 if (mpSubTotal
->bGroupActive
[0] && !mpSubTotal
->bRemoveOnly
)
242 aBuf
.append(ScGlobal::GetRscString(STR_OPERATION_SUBTOTAL
));
246 aBuf
.append(ScGlobal::GetRscString(STR_OPERATION_NONE
));
248 return aBuf
.makeStringAndClear();
251 void ScDBData::GetArea(SCTAB
& rTab
, SCCOL
& rCol1
, SCROW
& rRow1
, SCCOL
& rCol2
, SCROW
& rRow2
) const
260 void ScDBData::GetArea(ScRange
& rRange
) const
262 SCROW nNewEndRow
= nEndRow
;
263 rRange
= ScRange( nStartCol
, nStartRow
, nTable
, nEndCol
, nNewEndRow
, nTable
);
266 void ScDBData::SetArea(SCTAB nTab
, SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
)
275 void ScDBData::MoveTo(SCTAB nTab
, SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
)
278 long nDifX
= ((long) nCol1
) - ((long) nStartCol
);
279 long nDifY
= ((long) nRow1
) - ((long) nStartRow
);
281 long nSortDif
= bByRow
? nDifX
: nDifY
;
282 long nSortEnd
= bByRow
? static_cast<long>(nCol2
) : static_cast<long>(nRow2
);
284 for (i
=0; i
<mpSortParam
->GetSortKeyCount(); i
++)
286 mpSortParam
->maKeyState
[i
].nField
+= nSortDif
;
287 if (mpSortParam
->maKeyState
[i
].nField
> nSortEnd
)
289 mpSortParam
->maKeyState
[i
].nField
= 0;
290 mpSortParam
->maKeyState
[i
].bDoSort
= false;
294 SCSIZE nCount
= mpQueryParam
->GetEntryCount();
295 for (i
= 0; i
< nCount
; ++i
)
297 ScQueryEntry
& rEntry
= mpQueryParam
->GetEntry(i
);
298 rEntry
.nField
+= nDifX
;
299 if (rEntry
.nField
> nCol2
)
302 rEntry
.bDoQuery
= false;
305 for (i
=0; i
<MAXSUBTOTAL
; i
++)
307 mpSubTotal
->nField
[i
] = sal::static_int_cast
<SCCOL
>( mpSubTotal
->nField
[i
] + nDifX
);
308 if (mpSubTotal
->nField
[i
] > nCol2
)
310 mpSubTotal
->nField
[i
] = 0;
311 mpSubTotal
->bGroupActive
[i
] = false;
315 SetArea( nTab
, nCol1
, nRow1
, nCol2
, nRow2
);
318 void ScDBData::GetSortParam( ScSortParam
& rSortParam
) const
320 rSortParam
= *mpSortParam
;
321 rSortParam
.nCol1
= nStartCol
;
322 rSortParam
.nRow1
= nStartRow
;
323 rSortParam
.nCol2
= nEndCol
;
324 rSortParam
.nRow2
= nEndRow
;
325 rSortParam
.bByRow
= bByRow
;
326 rSortParam
.bHasHeader
= bHasHeader
;
329 void ScDBData::SetSortParam( const ScSortParam
& rSortParam
)
331 mpSortParam
.reset(new ScSortParam(rSortParam
));
332 bByRow
= rSortParam
.bByRow
;
335 void ScDBData::GetQueryParam( ScQueryParam
& rQueryParam
) const
337 rQueryParam
= *mpQueryParam
;
338 rQueryParam
.nCol1
= nStartCol
;
339 rQueryParam
.nRow1
= nStartRow
;
340 rQueryParam
.nCol2
= nEndCol
;
341 rQueryParam
.nRow2
= nEndRow
;
342 rQueryParam
.nTab
= nTable
;
343 rQueryParam
.bByRow
= bByRow
;
344 rQueryParam
.bHasHeader
= bHasHeader
;
347 void ScDBData::SetQueryParam(const ScQueryParam
& rQueryParam
)
349 mpQueryParam
.reset(new ScQueryParam(rQueryParam
));
351 // set bIsAdvanced to false for everything that is not from the
352 // advanced filter dialog
356 void ScDBData::SetAdvancedQuerySource(const ScRange
* pSource
)
360 aAdvSource
= *pSource
;
367 bool ScDBData::GetAdvancedQuerySource(ScRange
& rSource
) const
369 rSource
= aAdvSource
;
373 void ScDBData::GetSubTotalParam(ScSubTotalParam
& rSubTotalParam
) const
375 rSubTotalParam
= *mpSubTotal
;
377 // Share the data range with the parent db data. The range in the subtotal
378 // param struct is not used.
379 rSubTotalParam
.nCol1
= nStartCol
;
380 rSubTotalParam
.nRow1
= nStartRow
;
381 rSubTotalParam
.nCol2
= nEndCol
;
382 rSubTotalParam
.nRow2
= nEndRow
;
385 void ScDBData::SetSubTotalParam(const ScSubTotalParam
& rSubTotalParam
)
387 mpSubTotal
.reset(new ScSubTotalParam(rSubTotalParam
));
390 void ScDBData::GetImportParam(ScImportParam
& rImportParam
) const
392 rImportParam
= *mpImportParam
;
394 rImportParam
.nCol1
= nStartCol
;
395 rImportParam
.nRow1
= nStartRow
;
396 rImportParam
.nCol2
= nEndCol
;
397 rImportParam
.nRow2
= nEndRow
;
400 void ScDBData::SetImportParam(const ScImportParam
& rImportParam
)
402 // the range is ignored.
403 mpImportParam
.reset(new ScImportParam(rImportParam
));
406 bool ScDBData::IsDBAtCursor(SCCOL nCol
, SCROW nRow
, SCTAB nTab
, bool bStartOnly
) const
411 return ( nCol
== nStartCol
&& nRow
== nStartRow
);
413 return ( nCol
>= nStartCol
&& nCol
<= nEndCol
&&
414 nRow
>= nStartRow
&& nRow
<= nEndRow
);
420 bool ScDBData::IsDBAtArea(SCTAB nTab
, SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
) const
422 return (bool)((nTab
== nTable
)
423 && (nCol1
== nStartCol
) && (nRow1
== nStartRow
)
424 && (nCol2
== nEndCol
) && (nRow2
== nEndRow
));
427 bool ScDBData::HasImportParam() const
429 return mpImportParam
&& mpImportParam
->bImport
;
432 bool ScDBData::HasQueryParam() const
437 if (!mpQueryParam
->GetEntryCount())
440 return mpQueryParam
->GetEntry(0).bDoQuery
;
443 bool ScDBData::HasSortParam() const
445 return mpSortParam
&&
446 !mpSortParam
->maKeyState
.empty() &&
447 mpSortParam
->maKeyState
[0].bDoSort
;
450 bool ScDBData::HasSubTotalParam() const
452 return mpSubTotal
&& mpSubTotal
->bGroupActive
[0];
455 void ScDBData::UpdateMoveTab(SCTAB nOldPos
, SCTAB nNewPos
)
459 SCTAB nTab
= aRange
.aStart
.Tab(); // hat nur eine Tabelle
461 // anpassen wie die aktuelle Tabelle bei ScTablesHint (tabvwsh5.cxx)
463 if ( nTab
== nOldPos
) // verschobene Tabelle
465 else if ( nOldPos
< nNewPos
) // nach hinten verschoben
467 if ( nTab
> nOldPos
&& nTab
<= nNewPos
) // nachrueckender Bereich
470 else // nach vorne verschoben
472 if ( nTab
>= nNewPos
&& nTab
< nOldPos
) // nachrueckender Bereich
476 bool bChanged
= ( nTab
!= aRange
.aStart
.Tab() );
478 SetArea( nTab
, aRange
.aStart
.Col(), aRange
.aStart
.Row(),
479 aRange
.aEnd
.Col(),aRange
.aEnd
.Row() );
481 // MoveTo ist nicht noetig, wenn nur die Tabelle geaendert ist
483 SetModified(bChanged
);
487 void ScDBData::UpdateReference(ScDocument
* pDoc
, UpdateRefMode eUpdateRefMode
,
488 SCCOL nCol1
, SCROW nRow1
, SCTAB nTab1
,
489 SCCOL nCol2
, SCROW nRow2
, SCTAB nTab2
,
490 SCsCOL nDx
, SCsROW nDy
, SCsTAB nDz
)
498 GetArea( theTab1
, theCol1
, theRow1
, theCol2
, theRow2
);
501 bool bDoUpdate
= ScRefUpdate::Update( pDoc
, eUpdateRefMode
,
502 nCol1
,nRow1
,nTab1
, nCol2
,nRow2
,nTab2
, nDx
,nDy
,nDz
,
503 theCol1
,theRow1
,theTab1
, theCol2
,theRow2
,theTab2
) != UR_NOTHING
;
505 MoveTo( theTab1
, theCol1
, theRow1
, theCol2
, theRow2
);
507 ScRange aRangeAdvSource
;
508 if ( GetAdvancedQuerySource(aRangeAdvSource
) )
510 aRangeAdvSource
.GetVars( theCol1
,theRow1
,theTab1
, theCol2
,theRow2
,theTab2
);
511 if ( ScRefUpdate::Update( pDoc
, eUpdateRefMode
,
512 nCol1
,nRow1
,nTab1
, nCol2
,nRow2
,nTab2
, nDx
,nDy
,nDz
,
513 theCol1
,theRow1
,theTab1
, theCol2
,theRow2
,theTab2
) )
515 aRangeAdvSource
.aStart
.Set( theCol1
,theRow1
,theTab1
);
516 aRangeAdvSource
.aEnd
.Set( theCol2
,theRow2
,theTab2
);
517 SetAdvancedQuerySource( &aRangeAdvSource
);
519 bDoUpdate
= true; // DBData is modified
523 SetModified(bDoUpdate
);
525 //! Testen, ob mitten aus dem Bereich geloescht/eingefuegt wurde !!!
528 void ScDBData::ExtendDataArea(ScDocument
* pDoc
)
530 // Extend the DB area to include data rows immediately below.
531 // or shrink it if all cells are empty
532 pDoc
->GetDataArea(nTable
, nStartCol
, nStartRow
, nEndCol
, nEndRow
, false, true);
537 class FindByTable
: public unary_function
<ScDBData
, bool>
541 FindByTable(SCTAB nTab
) : mnTab(nTab
) {}
543 bool operator() (const ScDBData
& r
) const
547 return aRange
.aStart
.Tab() == mnTab
;
551 class UpdateRefFunc
: public unary_function
<ScDBData
, void>
554 UpdateRefMode meMode
;
566 UpdateRefFunc(ScDocument
* pDoc
, UpdateRefMode eMode
,
567 SCCOL nCol1
, SCROW nRow1
, SCTAB nTab1
,
568 SCCOL nCol2
, SCROW nRow2
, SCTAB nTab2
,
569 SCsCOL nDx
, SCsROW nDy
, SCsTAB nDz
) :
570 mpDoc(pDoc
), meMode(eMode
),
571 mnCol1(nCol1
), mnRow1(nRow1
), mnTab1(nTab1
),
572 mnCol2(nCol2
), mnRow2(nRow2
), mnTab2(nTab2
),
573 mnDx(nDx
), mnDy(nDy
), mnDz(nDz
) {}
575 void operator() (ScDBData
& r
)
577 r
.UpdateReference(mpDoc
, meMode
, mnCol1
, mnRow1
, mnTab1
, mnCol2
, mnRow2
, mnTab2
, mnDx
, mnDy
, mnDz
);
581 class UpdateMoveTabFunc
: public unary_function
<ScDBData
, void>
586 UpdateMoveTabFunc(SCTAB nOld
, SCTAB nNew
) : mnOldTab(nOld
), mnNewTab(nNew
) {}
587 void operator() (ScDBData
& r
)
589 r
.UpdateMoveTab(mnOldTab
, mnNewTab
);
593 class FindByCursor
: public unary_function
<ScDBData
, bool>
600 FindByCursor(SCCOL nCol
, SCROW nRow
, SCTAB nTab
, bool bStartOnly
) :
601 mnCol(nCol
), mnRow(nRow
), mnTab(nTab
), mbStartOnly(bStartOnly
) {}
603 bool operator() (const ScDBData
& r
)
605 return r
.IsDBAtCursor(mnCol
, mnRow
, mnTab
, mbStartOnly
);
609 class FindByRange
: public unary_function
<ScDBData
, bool>
611 const ScRange
& mrRange
;
613 FindByRange(const ScRange
& rRange
) : mrRange(rRange
) {}
615 bool operator() (const ScDBData
& r
)
618 mrRange
.aStart
.Tab(), mrRange
.aStart
.Col(), mrRange
.aStart
.Row(), mrRange
.aEnd
.Col(), mrRange
.aEnd
.Row());
622 class FindByIndex
: public unary_function
<ScDBData
, bool>
626 FindByIndex(sal_uInt16 nIndex
) : mnIndex(nIndex
) {}
627 bool operator() (const ScDBData
& r
) const
629 return r
.GetIndex() == mnIndex
;
633 class FindByUpperName
: public unary_function
<ScDBData
, bool>
635 const OUString
& mrName
;
637 FindByUpperName(const OUString
& rName
) : mrName(rName
) {}
638 bool operator() (const ScDBData
& r
) const
640 return r
.GetUpperName() == mrName
;
646 ScDBCollection::NamedDBs::NamedDBs(ScDBCollection
& rParent
, ScDocument
& rDoc
) :
647 mrParent(rParent
), mrDoc(rDoc
) {}
649 ScDBCollection::NamedDBs::NamedDBs(const NamedDBs
& r
) :
650 maDBs(r
.maDBs
), mrParent(r
.mrParent
), mrDoc(r
.mrDoc
) {}
652 ScDBCollection::NamedDBs::iterator
ScDBCollection::NamedDBs::begin()
654 return maDBs
.begin();
657 ScDBCollection::NamedDBs::iterator
ScDBCollection::NamedDBs::end()
662 ScDBCollection::NamedDBs::const_iterator
ScDBCollection::NamedDBs::begin() const
664 return maDBs
.begin();
667 ScDBCollection::NamedDBs::const_iterator
ScDBCollection::NamedDBs::end() const
672 ScDBData
* ScDBCollection::NamedDBs::findByIndex(sal_uInt16 nIndex
)
674 DBsType::iterator itr
= find_if(
675 maDBs
.begin(), maDBs
.end(), FindByIndex(nIndex
));
676 return itr
== maDBs
.end() ? NULL
: &(*itr
);
679 ScDBData
* ScDBCollection::NamedDBs::findByUpperName(const OUString
& rName
)
681 DBsType::iterator itr
= find_if(
682 maDBs
.begin(), maDBs
.end(), FindByUpperName(rName
));
683 return itr
== maDBs
.end() ? NULL
: &(*itr
);
686 bool ScDBCollection::NamedDBs::insert(ScDBData
* p
)
688 SAL_WNODEPRECATED_DECLARATIONS_PUSH
689 auto_ptr
<ScDBData
> pData(p
);
690 SAL_WNODEPRECATED_DECLARATIONS_POP
691 if (!pData
->GetIndex())
692 pData
->SetIndex(mrParent
.nEntryIndex
++);
694 pair
<DBsType::iterator
, bool> r
= maDBs
.insert(pData
);
696 if (r
.second
&& p
->HasImportParam() && !p
->HasImportSelection())
698 p
->SetRefreshHandler(mrParent
.GetRefreshHandler());
699 p
->SetRefreshControl(mrDoc
.GetRefreshTimerControlAddress());
704 void ScDBCollection::NamedDBs::erase(iterator itr
)
709 void ScDBCollection::NamedDBs::erase(const ScDBData
& r
)
714 bool ScDBCollection::NamedDBs::empty() const
716 return maDBs
.empty();
719 size_t ScDBCollection::NamedDBs::size() const
724 bool ScDBCollection::NamedDBs::operator== (const NamedDBs
& r
) const
726 return maDBs
== r
.maDBs
;
729 ScDBCollection::AnonDBs::iterator
ScDBCollection::AnonDBs::begin()
731 return maDBs
.begin();
734 ScDBCollection::AnonDBs::iterator
ScDBCollection::AnonDBs::end()
739 ScDBCollection::AnonDBs::const_iterator
ScDBCollection::AnonDBs::begin() const
741 return maDBs
.begin();
744 ScDBCollection::AnonDBs::const_iterator
ScDBCollection::AnonDBs::end() const
749 const ScDBData
* ScDBCollection::AnonDBs::findAtCursor(SCCOL nCol
, SCROW nRow
, SCTAB nTab
, bool bStartOnly
) const
751 DBsType::const_iterator itr
= find_if(
752 maDBs
.begin(), maDBs
.end(), FindByCursor(nCol
, nRow
, nTab
, bStartOnly
));
753 return itr
== maDBs
.end() ? NULL
: &(*itr
);
756 const ScDBData
* ScDBCollection::AnonDBs::findByRange(const ScRange
& rRange
) const
758 DBsType::const_iterator itr
= find_if(
759 maDBs
.begin(), maDBs
.end(), FindByRange(rRange
));
760 return itr
== maDBs
.end() ? NULL
: &(*itr
);
763 ScDBData
* ScDBCollection::AnonDBs::getByRange(const ScRange
& rRange
)
765 const ScDBData
* pData
= findByRange(rRange
);
768 // Insert a new db data. They all have identical names.
769 OUString
aName(STR_DB_GLOBAL_NONAME
);
770 SAL_WNODEPRECATED_DECLARATIONS_PUSH
771 ::std::auto_ptr
<ScDBData
> pNew(new ScDBData(
772 aName
, rRange
.aStart
.Tab(), rRange
.aStart
.Col(), rRange
.aStart
.Row(),
773 rRange
.aEnd
.Col(), rRange
.aEnd
.Row(), true, false));
774 SAL_WNODEPRECATED_DECLARATIONS_POP
776 maDBs
.push_back(pNew
);
778 return const_cast<ScDBData
*>(pData
);
781 void ScDBCollection::AnonDBs::insert(ScDBData
* p
)
783 SAL_WNODEPRECATED_DECLARATIONS_PUSH
784 ::std::auto_ptr
<ScDBData
> pNew(p
);
785 SAL_WNODEPRECATED_DECLARATIONS_POP
786 maDBs
.push_back(pNew
);
789 bool ScDBCollection::AnonDBs::empty() const
791 return maDBs
.empty();
794 bool ScDBCollection::AnonDBs::operator== (const AnonDBs
& r
) const
796 return maDBs
== r
.maDBs
;
799 ScDBCollection::ScDBCollection(ScDocument
* pDocument
) :
800 pDoc(pDocument
), nEntryIndex(SC_START_INDEX_DB_COLL
), maNamedDBs(*this, *pDocument
) {}
802 ScDBCollection::ScDBCollection(const ScDBCollection
& r
) :
803 pDoc(r
.pDoc
), nEntryIndex(r
.nEntryIndex
), maNamedDBs(r
.maNamedDBs
), maAnonDBs(r
.maAnonDBs
) {}
805 ScDBCollection::NamedDBs
& ScDBCollection::getNamedDBs()
810 const ScDBCollection::NamedDBs
& ScDBCollection::getNamedDBs() const
815 ScDBCollection::AnonDBs
& ScDBCollection::getAnonDBs()
820 const ScDBCollection::AnonDBs
& ScDBCollection::getAnonDBs() const
825 const ScDBData
* ScDBCollection::GetDBAtCursor(SCCOL nCol
, SCROW nRow
, SCTAB nTab
, sal_Bool bStartOnly
) const
827 // First, search the global named db ranges.
828 NamedDBs::DBsType::const_iterator itr
= find_if(
829 maNamedDBs
.begin(), maNamedDBs
.end(), FindByCursor(nCol
, nRow
, nTab
, bStartOnly
));
830 if (itr
!= maNamedDBs
.end())
833 // Check for the sheet-local anonymous db range.
834 const ScDBData
* pNoNameData
= pDoc
->GetAnonymousDBData(nTab
);
836 if (pNoNameData
->IsDBAtCursor(nCol
,nRow
,nTab
,bStartOnly
))
839 // Check the global anonymous db ranges.
840 const ScDBData
* pData
= getAnonDBs().findAtCursor(nCol
, nRow
, nTab
, bStartOnly
);
847 ScDBData
* ScDBCollection::GetDBAtCursor(SCCOL nCol
, SCROW nRow
, SCTAB nTab
, sal_Bool bStartOnly
)
849 // First, search the global named db ranges.
850 NamedDBs::DBsType::iterator itr
= find_if(
851 maNamedDBs
.begin(), maNamedDBs
.end(), FindByCursor(nCol
, nRow
, nTab
, bStartOnly
));
852 if (itr
!= maNamedDBs
.end())
855 // Check for the sheet-local anonymous db range.
856 ScDBData
* pNoNameData
= pDoc
->GetAnonymousDBData(nTab
);
858 if (pNoNameData
->IsDBAtCursor(nCol
,nRow
,nTab
,bStartOnly
))
861 // Check the global anonymous db ranges.
862 const ScDBData
* pData
= getAnonDBs().findAtCursor(nCol
, nRow
, nTab
, bStartOnly
);
864 return const_cast<ScDBData
*>(pData
);
869 const ScDBData
* ScDBCollection::GetDBAtArea(SCTAB nTab
, SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
) const
871 // First, search the global named db ranges.
872 ScRange
aRange(nCol1
, nRow1
, nTab
, nCol2
, nRow2
, nTab
);
873 NamedDBs::DBsType::const_iterator itr
= find_if(
874 maNamedDBs
.begin(), maNamedDBs
.end(), FindByRange(aRange
));
875 if (itr
!= maNamedDBs
.end())
878 // Check for the sheet-local anonymous db range.
879 ScDBData
* pNoNameData
= pDoc
->GetAnonymousDBData(nTab
);
881 if (pNoNameData
->IsDBAtArea(nTab
, nCol1
, nRow1
, nCol2
, nRow2
))
884 // Lastly, check the global anonymous db ranges.
885 return maAnonDBs
.findByRange(aRange
);
888 ScDBData
* ScDBCollection::GetDBAtArea(SCTAB nTab
, SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
)
890 // First, search the global named db ranges.
891 ScRange
aRange(nCol1
, nRow1
, nTab
, nCol2
, nRow2
, nTab
);
892 NamedDBs::DBsType::iterator itr
= find_if(
893 maNamedDBs
.begin(), maNamedDBs
.end(), FindByRange(aRange
));
894 if (itr
!= maNamedDBs
.end())
897 // Check for the sheet-local anonymous db range.
898 ScDBData
* pNoNameData
= pDoc
->GetAnonymousDBData(nTab
);
900 if (pNoNameData
->IsDBAtArea(nTab
, nCol1
, nRow1
, nCol2
, nRow2
))
903 // Lastly, check the global anonymous db ranges.
904 const ScDBData
* pData
= getAnonDBs().findByRange(aRange
);
906 return const_cast<ScDBData
*>(pData
);
911 void ScDBCollection::DeleteOnTab( SCTAB nTab
)
913 FindByTable
func(nTab
);
914 // First, collect the positions of all items that need to be deleted.
915 ::std::vector
<NamedDBs::DBsType::iterator
> v
;
917 NamedDBs::DBsType::iterator itr
= maNamedDBs
.begin(), itrEnd
= maNamedDBs
.end();
918 for (; itr
!= itrEnd
; ++itr
)
926 ::std::vector
<NamedDBs::DBsType::iterator
>::iterator itr
= v
.begin(), itrEnd
= v
.end();
927 for (; itr
!= itrEnd
; ++itr
)
928 maNamedDBs
.erase(*itr
);
930 remove_if(maAnonDBs
.begin(), maAnonDBs
.end(), func
);
933 void ScDBCollection::UpdateReference(UpdateRefMode eUpdateRefMode
,
934 SCCOL nCol1
, SCROW nRow1
, SCTAB nTab1
,
935 SCCOL nCol2
, SCROW nRow2
, SCTAB nTab2
,
936 SCsCOL nDx
, SCsROW nDy
, SCsTAB nDz
)
938 ScDBData
* pData
= pDoc
->GetAnonymousDBData(nTab1
);
941 if (nTab1
== nTab2
&& nDz
== 0)
943 pData
->UpdateReference(
944 pDoc
, eUpdateRefMode
,
945 nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
, nDx
, nDy
, nDz
);
949 //this will perhabs break undo
953 UpdateRefFunc
func(pDoc
, eUpdateRefMode
, nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
, nDx
, nDy
, nDz
);
954 for_each(maNamedDBs
.begin(), maNamedDBs
.end(), func
);
955 for_each(maAnonDBs
.begin(), maAnonDBs
.end(), func
);
958 void ScDBCollection::UpdateMoveTab( SCTAB nOldPos
, SCTAB nNewPos
)
960 UpdateMoveTabFunc
func(nOldPos
, nNewPos
);
961 for_each(maNamedDBs
.begin(), maNamedDBs
.end(), func
);
962 for_each(maAnonDBs
.begin(), maAnonDBs
.end(), func
);
965 ScDBData
* ScDBCollection::GetDBNearCursor(SCCOL nCol
, SCROW nRow
, SCTAB nTab
)
967 ScDBData
* pNearData
= NULL
;
968 NamedDBs::DBsType::iterator itr
= maNamedDBs
.begin(), itrEnd
= maNamedDBs
.end();
969 for (; itr
!= itrEnd
; ++itr
)
972 SCCOL nStartCol
, nEndCol
;
973 SCROW nStartRow
, nEndRow
;
974 itr
->GetArea( nAreaTab
, nStartCol
, nStartRow
, nEndCol
, nEndRow
);
975 if ( nTab
== nAreaTab
&& nCol
+1 >= nStartCol
&& nCol
<= nEndCol
+1 &&
976 nRow
+1 >= nStartRow
&& nRow
<= nEndRow
+1 )
978 if ( nCol
< nStartCol
|| nCol
> nEndCol
|| nRow
< nStartRow
|| nRow
> nEndRow
)
981 pNearData
= &(*itr
); // ersten angrenzenden Bereich merken
984 return &(*itr
); // nicht "unbenannt" und Cursor steht wirklich drin
988 return pNearData
; // angrenzender, wenn nichts direkt getroffen
989 return pDoc
->GetAnonymousDBData(nTab
); // "unbenannt" nur zurueck, wenn sonst nichts gefunden
992 bool ScDBCollection::empty() const
994 return maNamedDBs
.empty() && maAnonDBs
.empty();
997 bool ScDBCollection::operator== (const ScDBCollection
& r
) const
999 return maNamedDBs
== r
.maNamedDBs
&& maAnonDBs
== r
.maAnonDBs
&&
1000 nEntryIndex
== r
.nEntryIndex
&& pDoc
== r
.pDoc
&& aRefreshHandler
== r
.aRefreshHandler
;
1003 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */