Stop leaking all ScPostIt instances.
[LibreOffice.git] / sc / source / ui / unoobj / cursuno.cxx
blob691ee3ea8657dbcd7d784d4b5b89fecd4bf83c16
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/.
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 "scitems.hxx"
21 #include <svl/intitem.hxx>
22 #include <svl/zforlist.hxx>
23 #include <vcl/svapp.hxx>
24 #include <comphelper/servicehelper.hxx>
26 #include "cursuno.hxx"
27 #include "cellsuno.hxx"
28 #include "docsh.hxx"
29 #include "hints.hxx"
30 #include "markdata.hxx"
31 #include "dociter.hxx"
32 #include "miscuno.hxx"
34 using namespace com::sun::star;
36 //------------------------------------------------------------------------
38 #define SCSHEETCELLCURSOR_SERVICE "com.sun.star.sheet.SheetCellCursor"
39 #define SCCELLCURSOR_SERVICE "com.sun.star.table.CellCursor"
41 //------------------------------------------------------------------------
43 ScCellCursorObj::ScCellCursorObj(ScDocShell* pDocSh, const ScRange& rR) :
44 ScCellRangeObj( pDocSh, rR )
48 ScCellCursorObj::~ScCellCursorObj()
52 uno::Any SAL_CALL ScCellCursorObj::queryInterface( const uno::Type& rType ) throw(uno::RuntimeException)
54 SC_QUERYINTERFACE( sheet::XSheetCellCursor )
55 SC_QUERYINTERFACE( sheet::XUsedAreaCursor )
56 SC_QUERYINTERFACE( table::XCellCursor )
58 return ScCellRangeObj::queryInterface( rType );
61 void SAL_CALL ScCellCursorObj::acquire() throw()
63 ScCellRangeObj::acquire();
66 void SAL_CALL ScCellCursorObj::release() throw()
68 ScCellRangeObj::release();
71 uno::Sequence<uno::Type> SAL_CALL ScCellCursorObj::getTypes() throw(uno::RuntimeException)
73 static uno::Sequence<uno::Type> aTypes;
74 if ( aTypes.getLength() == 0 )
76 uno::Sequence<uno::Type> aParentTypes(ScCellRangeObj::getTypes());
77 long nParentLen = aParentTypes.getLength();
78 const uno::Type* pParentPtr = aParentTypes.getConstArray();
80 aTypes.realloc( nParentLen + 3 );
81 uno::Type* pPtr = aTypes.getArray();
82 pPtr[nParentLen + 0] = getCppuType((const uno::Reference<sheet::XSheetCellCursor>*)0);
83 pPtr[nParentLen + 1] = getCppuType((const uno::Reference<sheet::XUsedAreaCursor>*)0);
84 pPtr[nParentLen + 2] = getCppuType((const uno::Reference<table::XCellCursor>*)0);
86 for (long i=0; i<nParentLen; i++)
87 pPtr[i] = pParentPtr[i]; // parent types first
89 return aTypes;
92 namespace
94 class theScCellCursorObjImplementationId : public rtl::Static< UnoTunnelIdInit, theScCellCursorObjImplementationId > {};
97 uno::Sequence<sal_Int8> SAL_CALL ScCellCursorObj::getImplementationId() throw(uno::RuntimeException)
99 return theScCellCursorObjImplementationId::get().getSeq();
102 // XSheetCellCursor
104 void SAL_CALL ScCellCursorObj::collapseToCurrentRegion() throw(uno::RuntimeException)
106 SolarMutexGuard aGuard;
107 const ScRangeList& rRanges = GetRangeList();
108 OSL_ENSURE( rRanges.size() == 1, "Range? Ranges?" );
109 ScRange aOneRange( *rRanges[ 0 ] );
111 aOneRange.Justify();
112 ScDocShell* pDocSh = GetDocShell();
113 if ( pDocSh )
115 SCCOL nStartCol = aOneRange.aStart.Col();
116 SCROW nStartRow = aOneRange.aStart.Row();
117 SCCOL nEndCol = aOneRange.aEnd.Col();
118 SCROW nEndRow = aOneRange.aEnd.Row();
119 SCTAB nTab = aOneRange.aStart.Tab();
121 pDocSh->GetDocument()->GetDataArea(
122 nTab, nStartCol, nStartRow, nEndCol, nEndRow, true, false );
124 ScRange aNew( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab );
125 SetNewRange( aNew );
129 void SAL_CALL ScCellCursorObj::collapseToCurrentArray() throw(uno::RuntimeException)
131 SolarMutexGuard aGuard;
132 const ScRangeList& rRanges = GetRangeList();
133 OSL_ENSURE( rRanges.size() == 1, "Range? Ranges?" );
134 ScRange aOneRange( *rRanges[ 0 ] );
136 aOneRange.Justify();
137 ScAddress aCursor(aOneRange.aStart); // use the start address of the range
139 ScDocShell* pDocSh = GetDocShell();
140 if ( pDocSh )
142 ScDocument* pDoc = pDocSh->GetDocument();
143 ScRange aMatrix;
145 // finding the matrix range is now in GetMatrixFormulaRange in the document
146 if ( pDoc->GetMatrixFormulaRange( aCursor, aMatrix ) )
148 SetNewRange( aMatrix );
151 // thats a Bug, that this assertion comes; the API Reference says, that
152 // if there is no Matrix, the Range is left unchanged; they says nothing
153 // about a exception
154 /*if (!bFound)
156 OSL_FAIL("keine Matrix");
157 //! Exception, oder was?
161 void SAL_CALL ScCellCursorObj::collapseToMergedArea() throw(uno::RuntimeException)
163 SolarMutexGuard aGuard;
164 ScDocShell* pDocSh = GetDocShell();
165 if ( pDocSh )
167 const ScRangeList& rRanges = GetRangeList();
168 OSL_ENSURE( rRanges.size() == 1, "Range? Ranges?" );
169 ScRange aNewRange( *rRanges[ 0 ] );
171 ScDocument* pDoc = pDocSh->GetDocument();
172 pDoc->ExtendOverlapped( aNewRange );
173 pDoc->ExtendMerge( aNewRange ); // after ExtendOverlapped!
175 SetNewRange( aNewRange );
179 void SAL_CALL ScCellCursorObj::expandToEntireColumns() throw(uno::RuntimeException)
181 SolarMutexGuard aGuard;
182 const ScRangeList& rRanges = GetRangeList();
183 OSL_ENSURE( rRanges.size() == 1, "Range? Ranges?" );
184 ScRange aNewRange( *rRanges[ 0 ] );
186 aNewRange.aStart.SetRow( 0 );
187 aNewRange.aEnd.SetRow( MAXROW );
189 SetNewRange( aNewRange );
192 void SAL_CALL ScCellCursorObj::expandToEntireRows() throw(uno::RuntimeException)
194 SolarMutexGuard aGuard;
195 const ScRangeList& rRanges = GetRangeList();
196 OSL_ENSURE( rRanges.size() == 1, "Range? Ranges?" );
197 ScRange aNewRange( *rRanges[ 0 ] );
199 aNewRange.aStart.SetCol( 0 );
200 aNewRange.aEnd.SetCol( MAXCOL );
202 SetNewRange( aNewRange );
205 void SAL_CALL ScCellCursorObj::collapseToSize( sal_Int32 nColumns, sal_Int32 nRows )
206 throw(uno::RuntimeException)
208 SolarMutexGuard aGuard;
209 if ( nColumns <= 0 || nRows <= 0 )
211 OSL_FAIL("leerer Range geht nicht");
212 //! und dann?
214 else
216 const ScRangeList& rRanges = GetRangeList();
217 OSL_ENSURE( rRanges.size() == 1, "Range? Ranges?" );
218 ScRange aNewRange( *rRanges[ 0 ] );
220 aNewRange.Justify(); //! wirklich?
222 long nEndX = aNewRange.aStart.Col() + nColumns - 1;
223 long nEndY = aNewRange.aStart.Row() + nRows - 1;
224 if ( nEndX < 0 ) nEndX = 0;
225 if ( nEndX > MAXCOL ) nEndX = MAXCOL;
226 if ( nEndY < 0 ) nEndY = 0;
227 if ( nEndY > MAXROW ) nEndY = MAXROW;
228 //! Fehler/Exception oder so, wenn zu gross/zu klein?
230 aNewRange.aEnd.SetCol((SCCOL)nEndX);
231 aNewRange.aEnd.SetRow((SCROW)nEndY);
233 aNewRange.Justify(); //! wirklich?
235 SetNewRange( aNewRange );
239 // XUsedAreaCursor
241 void SAL_CALL ScCellCursorObj::gotoStartOfUsedArea( sal_Bool bExpand )
242 throw(uno::RuntimeException)
244 SolarMutexGuard aGuard;
245 ScDocShell* pDocSh = GetDocShell();
246 if ( pDocSh )
248 const ScRangeList& rRanges = GetRangeList();
249 OSL_ENSURE( rRanges.size() == 1, "Range? Ranges?" );
250 ScRange aNewRange( *rRanges[0] );
251 SCTAB nTab = aNewRange.aStart.Tab();
253 SCCOL nUsedX = 0; // Anfang holen
254 SCROW nUsedY = 0;
255 if (!pDocSh->GetDocument()->GetDataStart( nTab, nUsedX, nUsedY ))
257 nUsedX = 0;
258 nUsedY = 0;
261 aNewRange.aStart.SetCol( nUsedX );
262 aNewRange.aStart.SetRow( nUsedY );
263 if (!bExpand)
264 aNewRange.aEnd = aNewRange.aStart;
265 SetNewRange( aNewRange );
269 void SAL_CALL ScCellCursorObj::gotoEndOfUsedArea( sal_Bool bExpand )
270 throw(uno::RuntimeException)
272 SolarMutexGuard aGuard;
273 ScDocShell* pDocSh = GetDocShell();
274 if ( pDocSh )
276 const ScRangeList& rRanges = GetRangeList();
277 OSL_ENSURE( rRanges.size() == 1, "Range? Ranges?" );
278 ScRange aNewRange( *rRanges[ 0 ]);
279 SCTAB nTab = aNewRange.aStart.Tab();
281 SCCOL nUsedX = 0; // Ende holen
282 SCROW nUsedY = 0;
283 if (!pDocSh->GetDocument()->GetTableArea( nTab, nUsedX, nUsedY ))
285 nUsedX = 0;
286 nUsedY = 0;
289 aNewRange.aEnd.SetCol( nUsedX );
290 aNewRange.aEnd.SetRow( nUsedY );
291 if (!bExpand)
292 aNewRange.aStart = aNewRange.aEnd;
293 SetNewRange( aNewRange );
297 // XCellCursor
299 void SAL_CALL ScCellCursorObj::gotoStart() throw(uno::RuntimeException)
301 // this is similar to collapseToCurrentRegion
302 //! something like gotoEdge with 4 possible directions is needed
304 SolarMutexGuard aGuard;
305 const ScRangeList& rRanges = GetRangeList();
306 OSL_ENSURE( rRanges.size() == 1, "Range? Ranges?" );
307 ScRange aOneRange( *rRanges[ 0 ]);
309 aOneRange.Justify();
310 ScDocShell* pDocSh = GetDocShell();
311 if ( pDocSh )
313 SCCOL nStartCol = aOneRange.aStart.Col();
314 SCROW nStartRow = aOneRange.aStart.Row();
315 SCCOL nEndCol = aOneRange.aEnd.Col();
316 SCROW nEndRow = aOneRange.aEnd.Row();
317 SCTAB nTab = aOneRange.aStart.Tab();
319 pDocSh->GetDocument()->GetDataArea(
320 nTab, nStartCol, nStartRow, nEndCol, nEndRow, false, false );
322 ScRange aNew( nStartCol, nStartRow, nTab );
323 SetNewRange( aNew );
327 void SAL_CALL ScCellCursorObj::gotoEnd() throw(uno::RuntimeException)
329 // this is similar to collapseToCurrentRegion
330 //! something like gotoEdge with 4 possible directions is needed
332 SolarMutexGuard aGuard;
333 const ScRangeList& rRanges = GetRangeList();
334 OSL_ENSURE( rRanges.size() == 1, "Range? Ranges?" );
335 ScRange aOneRange( *rRanges[ 0 ] );
337 aOneRange.Justify();
338 ScDocShell* pDocSh = GetDocShell();
339 if ( pDocSh )
341 SCCOL nStartCol = aOneRange.aStart.Col();
342 SCROW nStartRow = aOneRange.aStart.Row();
343 SCCOL nEndCol = aOneRange.aEnd.Col();
344 SCROW nEndRow = aOneRange.aEnd.Row();
345 SCTAB nTab = aOneRange.aStart.Tab();
347 pDocSh->GetDocument()->GetDataArea(
348 nTab, nStartCol, nStartRow, nEndCol, nEndRow, false, false );
350 ScRange aNew( nEndCol, nEndRow, nTab );
351 SetNewRange( aNew );
355 void SAL_CALL ScCellCursorObj::gotoNext() throw(uno::RuntimeException)
357 SolarMutexGuard aGuard;
358 const ScRangeList& rRanges = GetRangeList();
359 OSL_ENSURE( rRanges.size() == 1, "Range? Ranges?" );
360 ScRange aOneRange( *rRanges[ 0 ] );
362 aOneRange.Justify();
363 ScAddress aCursor(aOneRange.aStart); // bei Block immer den Start nehmen
365 ScMarkData aMark; // not used with bMarked=FALSE
366 SCCOL nNewX = aCursor.Col();
367 SCROW nNewY = aCursor.Row();
368 SCTAB nTab = aCursor.Tab();
369 ScDocShell* pDocSh = GetDocShell();
370 if ( pDocSh )
371 pDocSh->GetDocument()->GetNextPos( nNewX,nNewY, nTab, 1,0, false,sal_True, aMark );
372 //! sonst Exception oder so
374 SetNewRange( ScRange( nNewX, nNewY, nTab ) );
377 void SAL_CALL ScCellCursorObj::gotoPrevious() throw(uno::RuntimeException)
379 SolarMutexGuard aGuard;
380 const ScRangeList& rRanges = GetRangeList();
381 OSL_ENSURE( rRanges.size() == 1, "Range? Ranges?" );
382 ScRange aOneRange( *rRanges[ 0 ] );
384 aOneRange.Justify();
385 ScAddress aCursor(aOneRange.aStart); // bei Block immer den Start nehmen
387 ScMarkData aMark; // not used with bMarked=FALSE
388 SCCOL nNewX = aCursor.Col();
389 SCROW nNewY = aCursor.Row();
390 SCTAB nTab = aCursor.Tab();
391 ScDocShell* pDocSh = GetDocShell();
392 if ( pDocSh )
393 pDocSh->GetDocument()->GetNextPos( nNewX,nNewY, nTab, -1,0, false,sal_True, aMark );
394 //! sonst Exception oder so
396 SetNewRange( ScRange( nNewX, nNewY, nTab ) );
399 void SAL_CALL ScCellCursorObj::gotoOffset( sal_Int32 nColumnOffset, sal_Int32 nRowOffset )
400 throw(uno::RuntimeException)
402 SolarMutexGuard aGuard;
403 const ScRangeList& rRanges = GetRangeList();
404 OSL_ENSURE( rRanges.size() == 1, "Range? Ranges?" );
405 ScRange aOneRange( *rRanges[ 0 ] );
406 aOneRange.Justify();
408 if ( aOneRange.aStart.Col() + nColumnOffset >= 0 &&
409 aOneRange.aEnd.Col() + nColumnOffset <= MAXCOL &&
410 aOneRange.aStart.Row() + nRowOffset >= 0 &&
411 aOneRange.aEnd.Row() + nRowOffset <= MAXROW )
413 ScRange aNew( (SCCOL)(aOneRange.aStart.Col() + nColumnOffset),
414 (SCROW)(aOneRange.aStart.Row() + nRowOffset),
415 aOneRange.aStart.Tab(),
416 (SCCOL)(aOneRange.aEnd.Col() + nColumnOffset),
417 (SCROW)(aOneRange.aEnd.Row() + nRowOffset),
418 aOneRange.aEnd.Tab() );
419 SetNewRange( aNew );
423 // XSheetCellRange
425 uno::Reference<sheet::XSpreadsheet> SAL_CALL ScCellCursorObj::getSpreadsheet()
426 throw(uno::RuntimeException)
428 SolarMutexGuard aGuard;
429 return ScCellRangeObj::getSpreadsheet();
432 // XCellRange
434 uno::Reference<table::XCell> SAL_CALL ScCellCursorObj::getCellByPosition(
435 sal_Int32 nColumn, sal_Int32 nRow )
436 throw(lang::IndexOutOfBoundsException, uno::RuntimeException)
438 SolarMutexGuard aGuard;
439 return ScCellRangeObj::getCellByPosition(nColumn,nRow);
442 uno::Reference<table::XCellRange> SAL_CALL ScCellCursorObj::getCellRangeByPosition(
443 sal_Int32 nLeft, sal_Int32 nTop, sal_Int32 nRight, sal_Int32 nBottom )
444 throw(lang::IndexOutOfBoundsException, uno::RuntimeException)
446 SolarMutexGuard aGuard;
447 return ScCellRangeObj::getCellRangeByPosition(nLeft,nTop,nRight,nBottom);
450 uno::Reference<table::XCellRange> SAL_CALL ScCellCursorObj::getCellRangeByName(
451 const OUString& rRange ) throw(uno::RuntimeException)
453 SolarMutexGuard aGuard;
454 return ScCellRangeObj::getCellRangeByName(rRange);
457 // XServiceInfo
459 OUString SAL_CALL ScCellCursorObj::getImplementationName() throw(uno::RuntimeException)
461 return OUString( "ScCellCursorObj" );
464 sal_Bool SAL_CALL ScCellCursorObj::supportsService( const OUString& rServiceName )
465 throw(uno::RuntimeException)
467 return rServiceName.equalsAscii( SCSHEETCELLCURSOR_SERVICE ) ||
468 rServiceName.equalsAscii( SCCELLCURSOR_SERVICE ) ||
469 ScCellRangeObj::supportsService(rServiceName);
472 uno::Sequence<OUString> SAL_CALL ScCellCursorObj::getSupportedServiceNames()
473 throw(uno::RuntimeException)
475 // get all service names from cell range
476 uno::Sequence<OUString> aParentSeq(ScCellRangeObj::getSupportedServiceNames());
477 sal_Int32 nParentLen = aParentSeq.getLength();
478 const OUString* pParentArr = aParentSeq.getConstArray();
480 // SheetCellCursor should be first (?)
481 uno::Sequence<OUString> aTotalSeq( nParentLen + 2 );
482 OUString* pTotalArr = aTotalSeq.getArray();
483 pTotalArr[0] = OUString( SCSHEETCELLCURSOR_SERVICE );
484 pTotalArr[1] = OUString( SCCELLCURSOR_SERVICE );
486 // append cell range services
487 for (long i=0; i<nParentLen; i++)
488 pTotalArr[i+2] = pParentArr[i];
490 return aTotalSeq;
496 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */