xref: /aoo41x/main/sc/source/core/data/markdata.cxx (revision b3f79822)
1*b3f79822SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*b3f79822SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*b3f79822SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*b3f79822SAndrew Rist  * distributed with this work for additional information
6*b3f79822SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*b3f79822SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*b3f79822SAndrew Rist  * "License"); you may not use this file except in compliance
9*b3f79822SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*b3f79822SAndrew Rist  *
11*b3f79822SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*b3f79822SAndrew Rist  *
13*b3f79822SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*b3f79822SAndrew Rist  * software distributed under the License is distributed on an
15*b3f79822SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b3f79822SAndrew Rist  * KIND, either express or implied.  See the License for the
17*b3f79822SAndrew Rist  * specific language governing permissions and limitations
18*b3f79822SAndrew Rist  * under the License.
19*b3f79822SAndrew Rist  *
20*b3f79822SAndrew Rist  *************************************************************/
21*b3f79822SAndrew Rist 
22*b3f79822SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sc.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir 
28cdf0e10cSrcweir 
29cdf0e10cSrcweir // INCLUDE ---------------------------------------------------------------
30cdf0e10cSrcweir 
31cdf0e10cSrcweir #include <tools/debug.hxx>
32cdf0e10cSrcweir 
33cdf0e10cSrcweir #include "markdata.hxx"
34cdf0e10cSrcweir #include "markarr.hxx"
35cdf0e10cSrcweir #include "rangelst.hxx"
36cdf0e10cSrcweir 
37cdf0e10cSrcweir // STATIC DATA -----------------------------------------------------------
38cdf0e10cSrcweir 
39cdf0e10cSrcweir //------------------------------------------------------------------------
40cdf0e10cSrcweir 
ScMarkData()41cdf0e10cSrcweir ScMarkData::ScMarkData() :
42cdf0e10cSrcweir 	pMultiSel( NULL )
43cdf0e10cSrcweir {
44cdf0e10cSrcweir 	for (SCTAB i=0; i<=MAXTAB; i++)
45cdf0e10cSrcweir 		bTabMarked[i] = sal_False;
46cdf0e10cSrcweir 
47cdf0e10cSrcweir 	ResetMark();
48cdf0e10cSrcweir }
49cdf0e10cSrcweir 
ScMarkData(const ScMarkData & rData)50cdf0e10cSrcweir ScMarkData::ScMarkData(const ScMarkData& rData) :
51cdf0e10cSrcweir 	aMarkRange( rData.aMarkRange ),
52cdf0e10cSrcweir 	aMultiRange( rData.aMultiRange ),
53cdf0e10cSrcweir 	pMultiSel( NULL )
54cdf0e10cSrcweir {
55cdf0e10cSrcweir 	bMarked		 = rData.bMarked;
56cdf0e10cSrcweir 	bMultiMarked = rData.bMultiMarked;
57cdf0e10cSrcweir 	bMarking	 = rData.bMarking;
58cdf0e10cSrcweir 	bMarkIsNeg	 = rData.bMarkIsNeg;
59cdf0e10cSrcweir 
60cdf0e10cSrcweir 	for (SCTAB i=0; i<=MAXTAB; i++)
61cdf0e10cSrcweir 		bTabMarked[i] = rData.bTabMarked[i];
62cdf0e10cSrcweir 
63cdf0e10cSrcweir 	if (rData.pMultiSel)
64cdf0e10cSrcweir 	{
65cdf0e10cSrcweir 		pMultiSel = new ScMarkArray[MAXCOLCOUNT];
66cdf0e10cSrcweir 		for (SCCOL j=0; j<MAXCOLCOUNT; j++)
67cdf0e10cSrcweir 			rData.pMultiSel[j].CopyMarksTo( pMultiSel[j] );
68cdf0e10cSrcweir 	}
69cdf0e10cSrcweir }
70cdf0e10cSrcweir 
operator =(const ScMarkData & rData)71cdf0e10cSrcweir ScMarkData&	ScMarkData::operator=(const ScMarkData& rData)
72cdf0e10cSrcweir {
73cdf0e10cSrcweir 	if ( &rData == this )
74cdf0e10cSrcweir 		return *this;
75cdf0e10cSrcweir 
76cdf0e10cSrcweir 	delete[] pMultiSel;
77cdf0e10cSrcweir 	pMultiSel = NULL;
78cdf0e10cSrcweir 
79cdf0e10cSrcweir 	aMarkRange	 = rData.aMarkRange;
80cdf0e10cSrcweir 	aMultiRange  = rData.aMultiRange;
81cdf0e10cSrcweir 	bMarked		 = rData.bMarked;
82cdf0e10cSrcweir 	bMultiMarked = rData.bMultiMarked;
83cdf0e10cSrcweir 	bMarking	 = rData.bMarking;
84cdf0e10cSrcweir 	bMarkIsNeg	 = rData.bMarkIsNeg;
85cdf0e10cSrcweir 
86cdf0e10cSrcweir 	for (SCTAB i=0; i<=MAXTAB; i++)
87cdf0e10cSrcweir 		bTabMarked[i] = rData.bTabMarked[i];
88cdf0e10cSrcweir 
89cdf0e10cSrcweir 	if (rData.pMultiSel)
90cdf0e10cSrcweir 	{
91cdf0e10cSrcweir 		pMultiSel = new ScMarkArray[MAXCOLCOUNT];
92cdf0e10cSrcweir 		for (SCCOL j=0; j<MAXCOLCOUNT; j++)
93cdf0e10cSrcweir 			rData.pMultiSel[j].CopyMarksTo( pMultiSel[j] );
94cdf0e10cSrcweir 	}
95cdf0e10cSrcweir 
96cdf0e10cSrcweir 	return *this;
97cdf0e10cSrcweir }
98cdf0e10cSrcweir 
~ScMarkData()99cdf0e10cSrcweir ScMarkData::~ScMarkData()
100cdf0e10cSrcweir {
101cdf0e10cSrcweir 	delete[] pMultiSel;
102cdf0e10cSrcweir }
103cdf0e10cSrcweir 
ResetMark()104cdf0e10cSrcweir void ScMarkData::ResetMark()
105cdf0e10cSrcweir {
106cdf0e10cSrcweir 	delete[] pMultiSel;
107cdf0e10cSrcweir 	pMultiSel = NULL;
108cdf0e10cSrcweir 
109cdf0e10cSrcweir 	bMarked = bMultiMarked = sal_False;
110cdf0e10cSrcweir 	bMarking = bMarkIsNeg = sal_False;
111cdf0e10cSrcweir }
112cdf0e10cSrcweir 
SetMarkArea(const ScRange & rRange)113cdf0e10cSrcweir void ScMarkData::SetMarkArea( const ScRange& rRange )
114cdf0e10cSrcweir {
115cdf0e10cSrcweir 	aMarkRange = rRange;
116cdf0e10cSrcweir 	aMarkRange.Justify();
117cdf0e10cSrcweir 	if ( !bMarked )
118cdf0e10cSrcweir 	{
119cdf0e10cSrcweir 		// #77987# Upon creation of a document ScFormatShell GetTextAttrState
120cdf0e10cSrcweir 		// may query (default) attributes although no sheet is marked yet.
121cdf0e10cSrcweir 		// => mark that one.
122cdf0e10cSrcweir 		if ( !GetSelectCount() )
123cdf0e10cSrcweir 			bTabMarked[ aMarkRange.aStart.Tab() ] = sal_True;
124cdf0e10cSrcweir 		bMarked = sal_True;
125cdf0e10cSrcweir 	}
126cdf0e10cSrcweir }
127cdf0e10cSrcweir 
GetMarkArea(ScRange & rRange) const128cdf0e10cSrcweir void ScMarkData::GetMarkArea( ScRange& rRange ) const
129cdf0e10cSrcweir {
130cdf0e10cSrcweir 	rRange = aMarkRange;		//! inline ?
131cdf0e10cSrcweir }
132cdf0e10cSrcweir 
GetMultiMarkArea(ScRange & rRange) const133cdf0e10cSrcweir void ScMarkData::GetMultiMarkArea( ScRange& rRange ) const
134cdf0e10cSrcweir {
135cdf0e10cSrcweir 	rRange = aMultiRange;
136cdf0e10cSrcweir }
137cdf0e10cSrcweir 
SetMultiMarkArea(const ScRange & rRange,sal_Bool bMark)138cdf0e10cSrcweir void ScMarkData::SetMultiMarkArea( const ScRange& rRange, sal_Bool bMark )
139cdf0e10cSrcweir {
140cdf0e10cSrcweir 	if (!pMultiSel)
141cdf0e10cSrcweir 	{
142cdf0e10cSrcweir 		pMultiSel = new ScMarkArray[MAXCOL+1];
143cdf0e10cSrcweir 
144cdf0e10cSrcweir 		// if simple mark range is set, copy to multi marks
145cdf0e10cSrcweir 		if ( bMarked && !bMarkIsNeg )
146cdf0e10cSrcweir 		{
147cdf0e10cSrcweir 			bMarked = sal_False;
148cdf0e10cSrcweir 			SetMultiMarkArea( aMarkRange, sal_True );
149cdf0e10cSrcweir 		}
150cdf0e10cSrcweir 	}
151cdf0e10cSrcweir 
152cdf0e10cSrcweir 	SCCOL nStartCol = rRange.aStart.Col();
153cdf0e10cSrcweir 	SCROW nStartRow = rRange.aStart.Row();
154cdf0e10cSrcweir 	SCCOL nEndCol = rRange.aEnd.Col();
155cdf0e10cSrcweir 	SCROW nEndRow = rRange.aEnd.Row();
156cdf0e10cSrcweir 	PutInOrder( nStartRow, nEndRow );
157cdf0e10cSrcweir 	PutInOrder( nStartCol, nEndCol );
158cdf0e10cSrcweir 
159cdf0e10cSrcweir 	SCCOL nCol;
160cdf0e10cSrcweir 	for (nCol=nStartCol; nCol<=nEndCol; nCol++)
161cdf0e10cSrcweir 		pMultiSel[nCol].SetMarkArea( nStartRow, nEndRow, bMark );
162cdf0e10cSrcweir 
163cdf0e10cSrcweir 	if ( bMultiMarked )					// aMultiRange updaten
164cdf0e10cSrcweir 	{
165cdf0e10cSrcweir 		if ( nStartCol < aMultiRange.aStart.Col() )
166cdf0e10cSrcweir 			aMultiRange.aStart.SetCol( nStartCol );
167cdf0e10cSrcweir 		if ( nStartRow < aMultiRange.aStart.Row() )
168cdf0e10cSrcweir 			aMultiRange.aStart.SetRow( nStartRow );
169cdf0e10cSrcweir 		if ( nEndCol > aMultiRange.aEnd.Col() )
170cdf0e10cSrcweir 			aMultiRange.aEnd.SetCol( nEndCol );
171cdf0e10cSrcweir 		if ( nEndRow > aMultiRange.aEnd.Row() )
172cdf0e10cSrcweir 			aMultiRange.aEnd.SetRow( nEndRow );
173cdf0e10cSrcweir 	}
174cdf0e10cSrcweir 	else
175cdf0e10cSrcweir 	{
176cdf0e10cSrcweir 		aMultiRange = rRange;			// neu
177cdf0e10cSrcweir 		bMultiMarked = sal_True;
178cdf0e10cSrcweir 	}
179cdf0e10cSrcweir }
180cdf0e10cSrcweir 
SetAreaTab(SCTAB nTab)181cdf0e10cSrcweir void ScMarkData::SetAreaTab( SCTAB nTab )
182cdf0e10cSrcweir {
183cdf0e10cSrcweir 	aMarkRange.aStart.SetTab(nTab);
184cdf0e10cSrcweir 	aMarkRange.aEnd.SetTab(nTab);
185cdf0e10cSrcweir 	aMultiRange.aStart.SetTab(nTab);
186cdf0e10cSrcweir 	aMultiRange.aEnd.SetTab(nTab);
187cdf0e10cSrcweir }
188cdf0e10cSrcweir 
SelectOneTable(SCTAB nTab)189cdf0e10cSrcweir void ScMarkData::SelectOneTable( SCTAB nTab )
190cdf0e10cSrcweir {
191cdf0e10cSrcweir 	for (SCTAB i=0; i<=MAXTAB; i++)
192cdf0e10cSrcweir 		bTabMarked[i] = ( nTab == i );
193cdf0e10cSrcweir }
194cdf0e10cSrcweir 
GetSelectCount() const195cdf0e10cSrcweir SCTAB ScMarkData::GetSelectCount() const
196cdf0e10cSrcweir {
197cdf0e10cSrcweir 	SCTAB nCount = 0;
198cdf0e10cSrcweir 	for (SCTAB i=0; i<=MAXTAB; i++)
199cdf0e10cSrcweir 		if (bTabMarked[i])
200cdf0e10cSrcweir 			++nCount;
201cdf0e10cSrcweir 
202cdf0e10cSrcweir 	return nCount;
203cdf0e10cSrcweir }
204cdf0e10cSrcweir 
GetFirstSelected() const205cdf0e10cSrcweir SCTAB ScMarkData::GetFirstSelected() const
206cdf0e10cSrcweir {
207cdf0e10cSrcweir 	for (SCTAB i=0; i<=MAXTAB; i++)
208cdf0e10cSrcweir 		if (bTabMarked[i])
209cdf0e10cSrcweir 			return i;
210cdf0e10cSrcweir 
211cdf0e10cSrcweir 	DBG_ERROR("GetFirstSelected: keine markiert");
212cdf0e10cSrcweir 	return 0;
213cdf0e10cSrcweir }
214cdf0e10cSrcweir 
MarkToMulti()215cdf0e10cSrcweir void ScMarkData::MarkToMulti()
216cdf0e10cSrcweir {
217cdf0e10cSrcweir 	if ( bMarked && !bMarking )
218cdf0e10cSrcweir 	{
219cdf0e10cSrcweir 		SetMultiMarkArea( aMarkRange, !bMarkIsNeg );
220cdf0e10cSrcweir 		bMarked = sal_False;
221cdf0e10cSrcweir 
222cdf0e10cSrcweir 		//	check if all multi mark ranges have been removed
223cdf0e10cSrcweir 		if ( bMarkIsNeg && !HasAnyMultiMarks() )
224cdf0e10cSrcweir 			ResetMark();
225cdf0e10cSrcweir 	}
226cdf0e10cSrcweir }
227cdf0e10cSrcweir 
MarkToSimple()228cdf0e10cSrcweir void ScMarkData::MarkToSimple()
229cdf0e10cSrcweir {
230cdf0e10cSrcweir 	if ( bMarking )
231cdf0e10cSrcweir 		return;
232cdf0e10cSrcweir 
233cdf0e10cSrcweir 	if ( bMultiMarked && bMarked )
234cdf0e10cSrcweir 		MarkToMulti();					// may result in bMarked and bMultiMarked reset
235cdf0e10cSrcweir 
236cdf0e10cSrcweir 	if ( bMultiMarked )
237cdf0e10cSrcweir 	{
238cdf0e10cSrcweir 		DBG_ASSERT(pMultiSel, "bMultiMarked, aber pMultiSel == 0");
239cdf0e10cSrcweir 
240cdf0e10cSrcweir 		ScRange aNew = aMultiRange;
241cdf0e10cSrcweir 
242cdf0e10cSrcweir 		sal_Bool bOk = sal_False;
243cdf0e10cSrcweir 		SCCOL nStartCol = aNew.aStart.Col();
244cdf0e10cSrcweir 		SCCOL nEndCol   = aNew.aEnd.Col();
245cdf0e10cSrcweir 
246cdf0e10cSrcweir 		while ( nStartCol < nEndCol && !pMultiSel[nStartCol].HasMarks() )
247cdf0e10cSrcweir 			++nStartCol;
248cdf0e10cSrcweir 		while ( nStartCol < nEndCol && !pMultiSel[nEndCol].HasMarks() )
249cdf0e10cSrcweir 			--nEndCol;
250cdf0e10cSrcweir 
251cdf0e10cSrcweir 		//	Zeilen werden nur aus MarkArray genommen
252cdf0e10cSrcweir 		SCROW nStartRow, nEndRow;
253cdf0e10cSrcweir 		if ( pMultiSel[nStartCol].HasOneMark( nStartRow, nEndRow ) )
254cdf0e10cSrcweir 		{
255cdf0e10cSrcweir 			bOk = sal_True;
256cdf0e10cSrcweir 			SCROW nCmpStart, nCmpEnd;
257cdf0e10cSrcweir 			for (SCCOL nCol=nStartCol+1; nCol<=nEndCol && bOk; nCol++)
258cdf0e10cSrcweir 				if ( !pMultiSel[nCol].HasOneMark( nCmpStart, nCmpEnd )
259cdf0e10cSrcweir 						|| nCmpStart != nStartRow || nCmpEnd != nEndRow )
260cdf0e10cSrcweir 					bOk = sal_False;
261cdf0e10cSrcweir 		}
262cdf0e10cSrcweir 
263cdf0e10cSrcweir 		if (bOk)
264cdf0e10cSrcweir 		{
265cdf0e10cSrcweir 			aNew.aStart.SetCol(nStartCol);
266cdf0e10cSrcweir 			aNew.aStart.SetRow(nStartRow);
267cdf0e10cSrcweir 			aNew.aEnd.SetCol(nEndCol);
268cdf0e10cSrcweir 			aNew.aEnd.SetRow(nEndRow);
269cdf0e10cSrcweir 
270cdf0e10cSrcweir 			ResetMark();
271cdf0e10cSrcweir 			aMarkRange = aNew;
272cdf0e10cSrcweir 			bMarked = sal_True;
273cdf0e10cSrcweir 			bMarkIsNeg = sal_False;
274cdf0e10cSrcweir 		}
275cdf0e10cSrcweir 	}
276cdf0e10cSrcweir }
277cdf0e10cSrcweir 
IsCellMarked(SCCOL nCol,SCROW nRow,sal_Bool bNoSimple) const278cdf0e10cSrcweir sal_Bool ScMarkData::IsCellMarked( SCCOL nCol, SCROW nRow, sal_Bool bNoSimple ) const
279cdf0e10cSrcweir {
280cdf0e10cSrcweir 	if ( bMarked && !bNoSimple && !bMarkIsNeg )
281cdf0e10cSrcweir 		if ( aMarkRange.aStart.Col() <= nCol && aMarkRange.aEnd.Col() >= nCol &&
282cdf0e10cSrcweir 			 aMarkRange.aStart.Row() <= nRow && aMarkRange.aEnd.Row() >= nRow )
283cdf0e10cSrcweir 			return sal_True;
284cdf0e10cSrcweir 
285cdf0e10cSrcweir 	if (bMultiMarked)
286cdf0e10cSrcweir 	{
287cdf0e10cSrcweir 		//!	hier auf negative Markierung testen ?
288cdf0e10cSrcweir 
289cdf0e10cSrcweir 		DBG_ASSERT(pMultiSel, "bMultiMarked, aber pMultiSel == 0");
290cdf0e10cSrcweir 		return pMultiSel[nCol].GetMark( nRow );
291cdf0e10cSrcweir 	}
292cdf0e10cSrcweir 
293cdf0e10cSrcweir 	return sal_False;
294cdf0e10cSrcweir }
295cdf0e10cSrcweir 
IsColumnMarked(SCCOL nCol) const296cdf0e10cSrcweir sal_Bool ScMarkData::IsColumnMarked( SCCOL nCol ) const
297cdf0e10cSrcweir {
298cdf0e10cSrcweir 	//	bMarkIsNeg inzwischen auch fuer Spaltenkoepfe
299cdf0e10cSrcweir 	//!	GetMarkColumnRanges fuer komplett markierte Spalten
300cdf0e10cSrcweir 
301cdf0e10cSrcweir 	if ( bMarked && !bMarkIsNeg &&
302cdf0e10cSrcweir 					aMarkRange.aStart.Col() <= nCol && aMarkRange.aEnd.Col() >= nCol &&
303cdf0e10cSrcweir 					aMarkRange.aStart.Row() == 0	&& aMarkRange.aEnd.Row() == MAXROW )
304cdf0e10cSrcweir 		return sal_True;
305cdf0e10cSrcweir 
306cdf0e10cSrcweir 	if ( bMultiMarked && pMultiSel[nCol].IsAllMarked(0,MAXROW) )
307cdf0e10cSrcweir 		return sal_True;
308cdf0e10cSrcweir 
309cdf0e10cSrcweir 	return sal_False;
310cdf0e10cSrcweir }
311cdf0e10cSrcweir 
IsRowMarked(SCROW nRow) const312cdf0e10cSrcweir sal_Bool ScMarkData::IsRowMarked( SCROW nRow ) const
313cdf0e10cSrcweir {
314cdf0e10cSrcweir 	//	bMarkIsNeg inzwischen auch fuer Zeilenkoepfe
315cdf0e10cSrcweir 	//!	GetMarkRowRanges fuer komplett markierte Zeilen
316cdf0e10cSrcweir 
317cdf0e10cSrcweir 	if ( bMarked && !bMarkIsNeg &&
318cdf0e10cSrcweir 					aMarkRange.aStart.Col() == 0	&& aMarkRange.aEnd.Col() == MAXCOL &&
319cdf0e10cSrcweir 					aMarkRange.aStart.Row() <= nRow && aMarkRange.aEnd.Row() >= nRow )
320cdf0e10cSrcweir 		return sal_True;
321cdf0e10cSrcweir 
322cdf0e10cSrcweir 	if ( bMultiMarked )
323cdf0e10cSrcweir 	{
324cdf0e10cSrcweir 		DBG_ASSERT(pMultiSel, "bMultiMarked, aber pMultiSel == 0");
325cdf0e10cSrcweir 		for (SCCOL nCol=0; nCol<=MAXCOL; nCol++)
326cdf0e10cSrcweir 			if (!pMultiSel[nCol].GetMark(nRow))
327cdf0e10cSrcweir 				return sal_False;
328cdf0e10cSrcweir 		return sal_True;
329cdf0e10cSrcweir 	}
330cdf0e10cSrcweir 
331cdf0e10cSrcweir 	return sal_False;
332cdf0e10cSrcweir }
333cdf0e10cSrcweir 
MarkFromRangeList(const ScRangeList & rList,sal_Bool bReset)334cdf0e10cSrcweir void ScMarkData::MarkFromRangeList( const ScRangeList& rList, sal_Bool bReset )
335cdf0e10cSrcweir {
336cdf0e10cSrcweir 	if (bReset)
337cdf0e10cSrcweir 	{
338cdf0e10cSrcweir 		for (SCTAB i=0; i<=MAXTAB; i++)
339cdf0e10cSrcweir 			bTabMarked[i] = sal_False;				// Tabellen sind nicht in ResetMark
340cdf0e10cSrcweir 		ResetMark();
341cdf0e10cSrcweir 	}
342cdf0e10cSrcweir 
343cdf0e10cSrcweir 	sal_uLong nCount = rList.Count();
344cdf0e10cSrcweir 	if ( nCount == 1 && !bMarked && !bMultiMarked )
345cdf0e10cSrcweir 	{
346cdf0e10cSrcweir 		ScRange aRange = *rList.GetObject(0);
347cdf0e10cSrcweir 		SetMarkArea( aRange );
348cdf0e10cSrcweir 		SelectTable( aRange.aStart.Tab(), sal_True );
349cdf0e10cSrcweir 	}
350cdf0e10cSrcweir 	else
351cdf0e10cSrcweir 	{
352cdf0e10cSrcweir 		for (sal_uLong i=0; i<nCount; i++)
353cdf0e10cSrcweir 		{
354cdf0e10cSrcweir 			ScRange aRange = *rList.GetObject(i);
355cdf0e10cSrcweir 			SetMultiMarkArea( aRange, sal_True );
356cdf0e10cSrcweir 			SelectTable( aRange.aStart.Tab(), sal_True );
357cdf0e10cSrcweir 		}
358cdf0e10cSrcweir 	}
359cdf0e10cSrcweir }
360cdf0e10cSrcweir 
FillRangeListWithMarks(ScRangeList * pList,sal_Bool bClear) const361cdf0e10cSrcweir void ScMarkData::FillRangeListWithMarks( ScRangeList* pList, sal_Bool bClear ) const
362cdf0e10cSrcweir {
363cdf0e10cSrcweir 	if (!pList)
364cdf0e10cSrcweir 		return;
365cdf0e10cSrcweir 
366cdf0e10cSrcweir 	if (bClear)
367cdf0e10cSrcweir 		pList->RemoveAll();
368cdf0e10cSrcweir 
369cdf0e10cSrcweir 	//!		bei mehreren selektierten Tabellen mehrere Ranges eintragen !!!
370cdf0e10cSrcweir 
371cdf0e10cSrcweir 	if ( bMultiMarked )
372cdf0e10cSrcweir 	{
373cdf0e10cSrcweir 		DBG_ASSERT(pMultiSel, "bMultiMarked, aber pMultiSel == 0");
374cdf0e10cSrcweir 
375cdf0e10cSrcweir 		SCTAB nTab = aMultiRange.aStart.Tab();
376cdf0e10cSrcweir 
377cdf0e10cSrcweir 		SCCOL nStartCol = aMultiRange.aStart.Col();
378cdf0e10cSrcweir 		SCCOL nEndCol = aMultiRange.aEnd.Col();
379cdf0e10cSrcweir 		for (SCCOL nCol=nStartCol; nCol<=nEndCol; nCol++)
380cdf0e10cSrcweir 			if (pMultiSel[nCol].HasMarks())
381cdf0e10cSrcweir 			{
382cdf0e10cSrcweir 				SCROW nTop, nBottom;
383cdf0e10cSrcweir 				ScRange aRange( nCol, 0, nTab );
384cdf0e10cSrcweir 				ScMarkArrayIter aMarkIter( &pMultiSel[nCol] );
385cdf0e10cSrcweir 				while ( aMarkIter.Next( nTop, nBottom ) )
386cdf0e10cSrcweir 				{
387cdf0e10cSrcweir 					aRange.aStart.SetRow( nTop );
388cdf0e10cSrcweir 					aRange.aEnd.SetRow( nBottom );
389cdf0e10cSrcweir 					pList->Join( aRange );
390cdf0e10cSrcweir 				}
391cdf0e10cSrcweir 			}
392cdf0e10cSrcweir 	}
393cdf0e10cSrcweir 
394cdf0e10cSrcweir 	if ( bMarked )
395cdf0e10cSrcweir 		pList->Append( aMarkRange );
396cdf0e10cSrcweir }
397cdf0e10cSrcweir 
ExtendRangeListTables(ScRangeList * pList) const398cdf0e10cSrcweir void ScMarkData::ExtendRangeListTables( ScRangeList* pList ) const
399cdf0e10cSrcweir {
400cdf0e10cSrcweir 	if (!pList)
401cdf0e10cSrcweir 		return;
402cdf0e10cSrcweir 
403cdf0e10cSrcweir 	ScRangeList aOldList(*pList);
404cdf0e10cSrcweir 	pList->RemoveAll();					//!	oder die vorhandenen unten weglassen
405cdf0e10cSrcweir 
406cdf0e10cSrcweir 	for (SCTAB nTab=0; nTab<=MAXTAB; nTab++)
407cdf0e10cSrcweir 		if (bTabMarked[nTab])
408cdf0e10cSrcweir 		{
409cdf0e10cSrcweir 			sal_uLong nCount = aOldList.Count();
410cdf0e10cSrcweir 			for (sal_uLong i=0; i<nCount; i++)
411cdf0e10cSrcweir 			{
412cdf0e10cSrcweir 				ScRange aRange = *aOldList.GetObject(i);
413cdf0e10cSrcweir 				aRange.aStart.SetTab(nTab);
414cdf0e10cSrcweir 				aRange.aEnd.SetTab(nTab);
415cdf0e10cSrcweir 				pList->Append( aRange );
416cdf0e10cSrcweir 			}
417cdf0e10cSrcweir 		}
418cdf0e10cSrcweir }
419cdf0e10cSrcweir 
GetMarkColumnRanges(SCCOLROW * pRanges)420cdf0e10cSrcweir SCCOLROW ScMarkData::GetMarkColumnRanges( SCCOLROW* pRanges )
421cdf0e10cSrcweir {
422cdf0e10cSrcweir 	if (bMarked)
423cdf0e10cSrcweir 		MarkToMulti();
424cdf0e10cSrcweir 
425cdf0e10cSrcweir 	if (!bMultiMarked)
426cdf0e10cSrcweir 		return 0;
427cdf0e10cSrcweir 
428cdf0e10cSrcweir 	DBG_ASSERT(pMultiSel, "bMultiMarked, but pMultiSel == 0");
429cdf0e10cSrcweir 
430cdf0e10cSrcweir     const SCCOLROW nMultiStart = aMultiRange.aStart.Col();
431cdf0e10cSrcweir     const SCCOLROW nMultiEnd = aMultiRange.aEnd.Col();
432cdf0e10cSrcweir     if (nMultiStart == 0 && nMultiEnd == MAXCOL)
433cdf0e10cSrcweir     {
434cdf0e10cSrcweir         // One or more entire rows.
435cdf0e10cSrcweir         pRanges[0] = 0;
436cdf0e10cSrcweir         pRanges[1] = MAXCOL;
437cdf0e10cSrcweir         return 1;
438cdf0e10cSrcweir     }
439cdf0e10cSrcweir 
440cdf0e10cSrcweir 	SCCOLROW nRangeCnt = 0;
441cdf0e10cSrcweir 	SCCOLROW nStart = nMultiStart;
442cdf0e10cSrcweir 	while (nStart <= nMultiEnd)
443cdf0e10cSrcweir 	{
444cdf0e10cSrcweir 		while (nStart < nMultiEnd && !pMultiSel[nStart].HasMarks())
445cdf0e10cSrcweir 			++nStart;
446cdf0e10cSrcweir 		if (pMultiSel[nStart].HasMarks())
447cdf0e10cSrcweir 		{
448cdf0e10cSrcweir 			SCCOLROW nEnd = nStart;
449cdf0e10cSrcweir 			while (nEnd < nMultiEnd && pMultiSel[nEnd].HasMarks())
450cdf0e10cSrcweir 				++nEnd;
451cdf0e10cSrcweir 			if (!pMultiSel[nEnd].HasMarks())
452cdf0e10cSrcweir 				--nEnd;
453cdf0e10cSrcweir 			pRanges[2*nRangeCnt  ] = nStart;
454cdf0e10cSrcweir 			pRanges[2*nRangeCnt+1] = nEnd;
455cdf0e10cSrcweir 			++nRangeCnt;
456cdf0e10cSrcweir 			nStart = nEnd+1;
457cdf0e10cSrcweir 		}
458cdf0e10cSrcweir 		else
459cdf0e10cSrcweir 			nStart = nMultiEnd+1;
460cdf0e10cSrcweir 	}
461cdf0e10cSrcweir 
462cdf0e10cSrcweir 	return nRangeCnt;
463cdf0e10cSrcweir }
464cdf0e10cSrcweir 
GetMarkRowRanges(SCCOLROW * pRanges)465cdf0e10cSrcweir SCCOLROW ScMarkData::GetMarkRowRanges( SCCOLROW* pRanges )
466cdf0e10cSrcweir {
467cdf0e10cSrcweir 	if (bMarked)
468cdf0e10cSrcweir 		MarkToMulti();
469cdf0e10cSrcweir 
470cdf0e10cSrcweir 	if (!bMultiMarked)
471cdf0e10cSrcweir 		return 0;
472cdf0e10cSrcweir 
473cdf0e10cSrcweir 	DBG_ASSERT(pMultiSel, "bMultiMarked, but pMultiSel == 0");
474cdf0e10cSrcweir 
475cdf0e10cSrcweir     // Which rows are marked?
476cdf0e10cSrcweir 
477cdf0e10cSrcweir     // Optimized to not loop over MAXCOL*MAXROW as worst case, i.e. Ctrl+A
478cdf0e10cSrcweir 
479cdf0e10cSrcweir     const SCCOLROW nMultiStart = aMultiRange.aStart.Row();
480cdf0e10cSrcweir     const SCCOLROW nMultiEnd = aMultiRange.aEnd.Row();
481cdf0e10cSrcweir 
482cdf0e10cSrcweir     sal_Bool*   bRowMarked = new sal_Bool[MAXROWCOUNT];
483cdf0e10cSrcweir     memset( bRowMarked, 0, sizeof(sal_Bool) * MAXROWCOUNT);
484cdf0e10cSrcweir 	SCROW  nRow;
485cdf0e10cSrcweir 	SCCOL  nCol;
486cdf0e10cSrcweir 
487cdf0e10cSrcweir     SCROW nTop = -1, nBottom = -1;
488cdf0e10cSrcweir     for (nCol = aMultiRange.aStart.Col(); nCol <= aMultiRange.aEnd.Col(); ++nCol)
489cdf0e10cSrcweir     {
490cdf0e10cSrcweir         ScMarkArrayIter aMarkIter( &pMultiSel[nCol] );
491cdf0e10cSrcweir         while (aMarkIter.Next( nTop, nBottom ))
492cdf0e10cSrcweir             for (nRow=nTop; nRow<=nBottom; nRow++)
493cdf0e10cSrcweir                 bRowMarked[nRow] = sal_True;
494cdf0e10cSrcweir         if (nTop == nMultiStart && nBottom == nMultiEnd)
495cdf0e10cSrcweir             break;  // for, all relevant rows marked
496cdf0e10cSrcweir     }
497cdf0e10cSrcweir 
498cdf0e10cSrcweir     if (nTop == nMultiStart && nBottom == nMultiEnd)
499cdf0e10cSrcweir     {
500cdf0e10cSrcweir         pRanges[0] = nTop;
501cdf0e10cSrcweir         pRanges[1] = nBottom;
502cdf0e10cSrcweir         delete[] bRowMarked;
503cdf0e10cSrcweir         return 1;
504cdf0e10cSrcweir     }
505cdf0e10cSrcweir 
506cdf0e10cSrcweir     // Combine to ranges of rows.
507cdf0e10cSrcweir 
508cdf0e10cSrcweir     SCCOLROW nRangeCnt = 0;
509cdf0e10cSrcweir     SCCOLROW nStart = nMultiStart;
510cdf0e10cSrcweir     while (nStart <= nMultiEnd)
511cdf0e10cSrcweir     {
512cdf0e10cSrcweir         while (nStart < nMultiEnd && !bRowMarked[nStart])
513cdf0e10cSrcweir             ++nStart;
514cdf0e10cSrcweir         if (bRowMarked[nStart])
515cdf0e10cSrcweir         {
516cdf0e10cSrcweir             SCCOLROW nEnd = nStart;
517cdf0e10cSrcweir             while (nEnd < nMultiEnd && bRowMarked[nEnd])
518cdf0e10cSrcweir                 ++nEnd;
519cdf0e10cSrcweir             if (!bRowMarked[nEnd])
520cdf0e10cSrcweir                 --nEnd;
521cdf0e10cSrcweir             pRanges[2*nRangeCnt  ] = nStart;
522cdf0e10cSrcweir             pRanges[2*nRangeCnt+1] = nEnd;
523cdf0e10cSrcweir             ++nRangeCnt;
524cdf0e10cSrcweir             nStart = nEnd+1;
525cdf0e10cSrcweir         }
526cdf0e10cSrcweir         else
527cdf0e10cSrcweir             nStart = nMultiEnd+1;
528cdf0e10cSrcweir     }
529cdf0e10cSrcweir 
530cdf0e10cSrcweir 	delete[] bRowMarked;
531cdf0e10cSrcweir 	return nRangeCnt;
532cdf0e10cSrcweir }
533cdf0e10cSrcweir 
IsAllMarked(const ScRange & rRange) const534cdf0e10cSrcweir sal_Bool ScMarkData::IsAllMarked( const ScRange& rRange ) const
535cdf0e10cSrcweir {
536cdf0e10cSrcweir 	if ( !bMultiMarked )
537cdf0e10cSrcweir 		return sal_False;
538cdf0e10cSrcweir 
539cdf0e10cSrcweir 	DBG_ASSERT(pMultiSel, "bMultiMarked, aber pMultiSel == 0");
540cdf0e10cSrcweir 
541cdf0e10cSrcweir 	SCCOL nStartCol = rRange.aStart.Col();
542cdf0e10cSrcweir 	SCROW nStartRow = rRange.aStart.Row();
543cdf0e10cSrcweir 	SCCOL nEndCol = rRange.aEnd.Col();
544cdf0e10cSrcweir 	SCROW nEndRow = rRange.aEnd.Row();
545cdf0e10cSrcweir 	sal_Bool bOk = sal_True;
546cdf0e10cSrcweir 	for (SCCOL nCol=nStartCol; nCol<=nEndCol && bOk; nCol++)
547cdf0e10cSrcweir 		if ( !pMultiSel[nCol].IsAllMarked( nStartRow, nEndRow ) )
548cdf0e10cSrcweir 			bOk = sal_False;
549cdf0e10cSrcweir 
550cdf0e10cSrcweir 	return bOk;
551cdf0e10cSrcweir }
552cdf0e10cSrcweir 
GetNextMarked(SCCOL nCol,SCsROW nRow,sal_Bool bUp) const553cdf0e10cSrcweir SCsROW ScMarkData::GetNextMarked( SCCOL nCol, SCsROW nRow, sal_Bool bUp ) const
554cdf0e10cSrcweir {
555cdf0e10cSrcweir 	if ( !bMultiMarked )
556cdf0e10cSrcweir 		return nRow;
557cdf0e10cSrcweir 
558cdf0e10cSrcweir 	DBG_ASSERT(pMultiSel, "bMultiMarked, aber pMultiSel == 0");
559cdf0e10cSrcweir 
560cdf0e10cSrcweir 	return pMultiSel[nCol].GetNextMarked( nRow, bUp );
561cdf0e10cSrcweir }
562cdf0e10cSrcweir 
HasMultiMarks(SCCOL nCol) const563cdf0e10cSrcweir sal_Bool ScMarkData::HasMultiMarks( SCCOL nCol ) const
564cdf0e10cSrcweir {
565cdf0e10cSrcweir 	if ( !bMultiMarked )
566cdf0e10cSrcweir 		return sal_False;
567cdf0e10cSrcweir 
568cdf0e10cSrcweir 	DBG_ASSERT(pMultiSel, "bMultiMarked, aber pMultiSel == 0");
569cdf0e10cSrcweir 
570cdf0e10cSrcweir 	return pMultiSel[nCol].HasMarks();
571cdf0e10cSrcweir }
572cdf0e10cSrcweir 
HasAnyMultiMarks() const573cdf0e10cSrcweir sal_Bool ScMarkData::HasAnyMultiMarks() const
574cdf0e10cSrcweir {
575cdf0e10cSrcweir 	if ( !bMultiMarked )
576cdf0e10cSrcweir 		return sal_False;
577cdf0e10cSrcweir 
578cdf0e10cSrcweir 	DBG_ASSERT(pMultiSel, "bMultiMarked, aber pMultiSel == 0");
579cdf0e10cSrcweir 
580cdf0e10cSrcweir 	for (SCCOL nCol=0; nCol<=MAXCOL; nCol++)
581cdf0e10cSrcweir 		if ( pMultiSel[nCol].HasMarks() )
582cdf0e10cSrcweir 			return sal_True;
583cdf0e10cSrcweir 
584cdf0e10cSrcweir 	return sal_False;		// nix
585cdf0e10cSrcweir }
586cdf0e10cSrcweir 
InsertTab(SCTAB nTab)587cdf0e10cSrcweir void ScMarkData::InsertTab( SCTAB nTab )
588cdf0e10cSrcweir {
589cdf0e10cSrcweir 	for (SCTAB i=MAXTAB; i>nTab; i--)
590cdf0e10cSrcweir 		bTabMarked[i] = bTabMarked[i-1];
591cdf0e10cSrcweir 	bTabMarked[nTab] = sal_False;
592cdf0e10cSrcweir }
593cdf0e10cSrcweir 
DeleteTab(SCTAB nTab)594cdf0e10cSrcweir void ScMarkData::DeleteTab( SCTAB nTab )
595cdf0e10cSrcweir {
596cdf0e10cSrcweir 	for (SCTAB i=nTab; i<MAXTAB; i++)
597cdf0e10cSrcweir 		bTabMarked[i] = bTabMarked[i+1];
598cdf0e10cSrcweir 	bTabMarked[MAXTAB] = sal_False;
599cdf0e10cSrcweir }
600cdf0e10cSrcweir 
601cdf0e10cSrcweir 
602cdf0e10cSrcweir 
603cdf0e10cSrcweir 
604cdf0e10cSrcweir 
605