sync master with lastest vba changes
[ooovba.git] / sc / source / ui / unoobj / cursuno.cxx
blobb50df5940879b4775e174fa86d52e86f1eda7093
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: cursuno.cxx,v $
10 * $Revision: 1.11 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
36 #include "scitems.hxx"
37 #include <svtools/intitem.hxx>
38 #include <svtools/zforlist.hxx>
39 #include <rtl/uuid.h>
41 #include "cursuno.hxx"
42 #include "cellsuno.hxx"
43 #include "docsh.hxx"
44 #include "hints.hxx"
45 #include "markdata.hxx"
46 #include "dociter.hxx"
47 #include "unoguard.hxx"
48 #include "miscuno.hxx"
50 using namespace com::sun::star;
52 //------------------------------------------------------------------------
54 #define SCSHEETCELLCURSOR_SERVICE "com.sun.star.sheet.SheetCellCursor"
55 #define SCCELLCURSOR_SERVICE "com.sun.star.table.CellCursor"
57 //------------------------------------------------------------------------
59 ScCellCursorObj::ScCellCursorObj(ScDocShell* pDocSh, const ScRange& rR) :
60 ScCellRangeObj( pDocSh, rR )
64 ScCellCursorObj::~ScCellCursorObj()
68 uno::Any SAL_CALL ScCellCursorObj::queryInterface( const uno::Type& rType ) throw(uno::RuntimeException)
70 SC_QUERYINTERFACE( sheet::XSheetCellCursor )
71 SC_QUERYINTERFACE( sheet::XUsedAreaCursor )
72 SC_QUERYINTERFACE( table::XCellCursor )
74 return ScCellRangeObj::queryInterface( rType );
77 void SAL_CALL ScCellCursorObj::acquire() throw()
79 ScCellRangeObj::acquire();
82 void SAL_CALL ScCellCursorObj::release() throw()
84 ScCellRangeObj::release();
87 uno::Sequence<uno::Type> SAL_CALL ScCellCursorObj::getTypes() throw(uno::RuntimeException)
89 static uno::Sequence<uno::Type> aTypes;
90 if ( aTypes.getLength() == 0 )
92 uno::Sequence<uno::Type> aParentTypes(ScCellRangeObj::getTypes());
93 long nParentLen = aParentTypes.getLength();
94 const uno::Type* pParentPtr = aParentTypes.getConstArray();
96 aTypes.realloc( nParentLen + 3 );
97 uno::Type* pPtr = aTypes.getArray();
98 pPtr[nParentLen + 0] = getCppuType((const uno::Reference<sheet::XSheetCellCursor>*)0);
99 pPtr[nParentLen + 1] = getCppuType((const uno::Reference<sheet::XUsedAreaCursor>*)0);
100 pPtr[nParentLen + 2] = getCppuType((const uno::Reference<table::XCellCursor>*)0);
102 for (long i=0; i<nParentLen; i++)
103 pPtr[i] = pParentPtr[i]; // parent types first
105 return aTypes;
108 uno::Sequence<sal_Int8> SAL_CALL ScCellCursorObj::getImplementationId() throw(uno::RuntimeException)
110 static uno::Sequence< sal_Int8 > aId;
111 if( aId.getLength() == 0 )
113 aId.realloc( 16 );
114 rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
116 return aId;
119 // XSheetCellCursor
121 void SAL_CALL ScCellCursorObj::collapseToCurrentRegion() throw(uno::RuntimeException)
123 ScUnoGuard aGuard;
124 const ScRangeList& rRanges = GetRangeList();
125 DBG_ASSERT( rRanges.Count() == 1, "Range? Ranges?" );
126 ScRange aOneRange(*rRanges.GetObject(0));
128 aOneRange.Justify();
129 ScDocShell* pDocSh = GetDocShell();
130 if ( pDocSh )
132 SCCOL nStartCol = aOneRange.aStart.Col();
133 SCROW nStartRow = aOneRange.aStart.Row();
134 SCCOL nEndCol = aOneRange.aEnd.Col();
135 SCROW nEndRow = aOneRange.aEnd.Row();
136 SCTAB nTab = aOneRange.aStart.Tab();
138 pDocSh->GetDocument()->GetDataArea(
139 nTab, nStartCol, nStartRow, nEndCol, nEndRow, TRUE );
141 ScRange aNew( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab );
142 SetNewRange( aNew );
146 void SAL_CALL ScCellCursorObj::collapseToCurrentArray() throw(uno::RuntimeException)
148 ScUnoGuard aGuard;
149 const ScRangeList& rRanges = GetRangeList();
150 DBG_ASSERT( rRanges.Count() == 1, "Range? Ranges?" );
151 ScRange aOneRange(*rRanges.GetObject(0));
153 aOneRange.Justify();
154 ScAddress aCursor(aOneRange.aStart); // use the start address of the range
156 ScDocShell* pDocSh = GetDocShell();
157 if ( pDocSh )
159 ScDocument* pDoc = pDocSh->GetDocument();
160 ScRange aMatrix;
162 // finding the matrix range is now in GetMatrixFormulaRange in the document
163 if ( pDoc->GetMatrixFormulaRange( aCursor, aMatrix ) )
165 SetNewRange( aMatrix );
168 // thats a Bug, that this assertion comes; the API Reference says, that
169 // if there is no Matrix, the Range is left unchanged; they says nothing
170 // about a exception
171 /*if (!bFound)
173 DBG_ERROR("keine Matrix");
174 //! Exception, oder was?
178 void SAL_CALL ScCellCursorObj::collapseToMergedArea() throw(uno::RuntimeException)
180 ScUnoGuard aGuard;
181 ScDocShell* pDocSh = GetDocShell();
182 if ( pDocSh )
184 const ScRangeList& rRanges = GetRangeList();
185 DBG_ASSERT( rRanges.Count() == 1, "Range? Ranges?" );
186 ScRange aNewRange(*rRanges.GetObject(0));
188 ScDocument* pDoc = pDocSh->GetDocument();
189 pDoc->ExtendOverlapped( aNewRange );
190 pDoc->ExtendMerge( aNewRange ); // after ExtendOverlapped!
192 SetNewRange( aNewRange );
196 void SAL_CALL ScCellCursorObj::expandToEntireColumns() throw(uno::RuntimeException)
198 ScUnoGuard aGuard;
199 const ScRangeList& rRanges = GetRangeList();
200 DBG_ASSERT( rRanges.Count() == 1, "Range? Ranges?" );
201 ScRange aNewRange(*rRanges.GetObject(0));
203 aNewRange.aStart.SetRow( 0 );
204 aNewRange.aEnd.SetRow( MAXROW );
206 SetNewRange( aNewRange );
209 void SAL_CALL ScCellCursorObj::expandToEntireRows() throw(uno::RuntimeException)
211 ScUnoGuard aGuard;
212 const ScRangeList& rRanges = GetRangeList();
213 DBG_ASSERT( rRanges.Count() == 1, "Range? Ranges?" );
214 ScRange aNewRange(*rRanges.GetObject(0));
216 aNewRange.aStart.SetCol( 0 );
217 aNewRange.aEnd.SetCol( MAXCOL );
219 SetNewRange( aNewRange );
222 void SAL_CALL ScCellCursorObj::collapseToSize( sal_Int32 nColumns, sal_Int32 nRows )
223 throw(uno::RuntimeException)
225 ScUnoGuard aGuard;
226 if ( nColumns <= 0 || nRows <= 0 )
228 DBG_ERROR("leerer Range geht nicht");
229 //! und dann?
231 else
233 const ScRangeList& rRanges = GetRangeList();
234 DBG_ASSERT( rRanges.Count() == 1, "Range? Ranges?" );
235 ScRange aNewRange(*rRanges.GetObject(0));
237 aNewRange.Justify(); //! wirklich?
239 long nEndX = aNewRange.aStart.Col() + nColumns - 1;
240 long nEndY = aNewRange.aStart.Row() + nRows - 1;
241 if ( nEndX < 0 ) nEndX = 0;
242 if ( nEndX > MAXCOL ) nEndX = MAXCOL;
243 if ( nEndY < 0 ) nEndY = 0;
244 if ( nEndY > MAXROW ) nEndY = MAXROW;
245 //! Fehler/Exception oder so, wenn zu gross/zu klein?
247 aNewRange.aEnd.SetCol((SCCOL)nEndX);
248 aNewRange.aEnd.SetRow((SCROW)nEndY);
250 aNewRange.Justify(); //! wirklich?
252 SetNewRange( aNewRange );
256 // XUsedAreaCursor
258 void SAL_CALL ScCellCursorObj::gotoStartOfUsedArea( sal_Bool bExpand )
259 throw(uno::RuntimeException)
261 ScUnoGuard aGuard;
262 ScDocShell* pDocSh = GetDocShell();
263 if ( pDocSh )
265 const ScRangeList& rRanges = GetRangeList();
266 DBG_ASSERT( rRanges.Count() == 1, "Range? Ranges?" );
267 ScRange aNewRange(*rRanges.GetObject(0));
268 SCTAB nTab = aNewRange.aStart.Tab();
270 SCCOL nUsedX = 0; // Anfang holen
271 SCROW nUsedY = 0;
272 if (!pDocSh->GetDocument()->GetDataStart( nTab, nUsedX, nUsedY ))
274 nUsedX = 0;
275 nUsedY = 0;
278 aNewRange.aStart.SetCol( nUsedX );
279 aNewRange.aStart.SetRow( nUsedY );
280 if (!bExpand)
281 aNewRange.aEnd = aNewRange.aStart;
282 SetNewRange( aNewRange );
286 void SAL_CALL ScCellCursorObj::gotoEndOfUsedArea( sal_Bool bExpand )
287 throw(uno::RuntimeException)
289 ScUnoGuard aGuard;
290 ScDocShell* pDocSh = GetDocShell();
291 if ( pDocSh )
293 const ScRangeList& rRanges = GetRangeList();
294 DBG_ASSERT( rRanges.Count() == 1, "Range? Ranges?" );
295 ScRange aNewRange(*rRanges.GetObject(0));
296 SCTAB nTab = aNewRange.aStart.Tab();
298 SCCOL nUsedX = 0; // Ende holen
299 SCROW nUsedY = 0;
300 if (!pDocSh->GetDocument()->GetTableArea( nTab, nUsedX, nUsedY ))
302 nUsedX = 0;
303 nUsedY = 0;
306 aNewRange.aEnd.SetCol( nUsedX );
307 aNewRange.aEnd.SetRow( nUsedY );
308 if (!bExpand)
309 aNewRange.aStart = aNewRange.aEnd;
310 SetNewRange( aNewRange );
314 // XCellCursor
316 void SAL_CALL ScCellCursorObj::gotoStart() throw(uno::RuntimeException)
318 // this is similar to collapseToCurrentRegion
319 //! something like gotoEdge with 4 possible directions is needed
321 ScUnoGuard aGuard;
322 const ScRangeList& rRanges = GetRangeList();
323 DBG_ASSERT( rRanges.Count() == 1, "Range? Ranges?" );
324 ScRange aOneRange(*rRanges.GetObject(0));
326 aOneRange.Justify();
327 ScDocShell* pDocSh = GetDocShell();
328 if ( pDocSh )
330 SCCOL nStartCol = aOneRange.aStart.Col();
331 SCROW nStartRow = aOneRange.aStart.Row();
332 SCCOL nEndCol = aOneRange.aEnd.Col();
333 SCROW nEndRow = aOneRange.aEnd.Row();
334 SCTAB nTab = aOneRange.aStart.Tab();
336 pDocSh->GetDocument()->GetDataArea(
337 nTab, nStartCol, nStartRow, nEndCol, nEndRow, FALSE );
339 ScRange aNew( nStartCol, nStartRow, nTab );
340 SetNewRange( aNew );
344 void SAL_CALL ScCellCursorObj::gotoEnd() throw(uno::RuntimeException)
346 // this is similar to collapseToCurrentRegion
347 //! something like gotoEdge with 4 possible directions is needed
349 ScUnoGuard aGuard;
350 const ScRangeList& rRanges = GetRangeList();
351 DBG_ASSERT( rRanges.Count() == 1, "Range? Ranges?" );
352 ScRange aOneRange(*rRanges.GetObject(0));
354 aOneRange.Justify();
355 ScDocShell* pDocSh = GetDocShell();
356 if ( pDocSh )
358 SCCOL nStartCol = aOneRange.aStart.Col();
359 SCROW nStartRow = aOneRange.aStart.Row();
360 SCCOL nEndCol = aOneRange.aEnd.Col();
361 SCROW nEndRow = aOneRange.aEnd.Row();
362 SCTAB nTab = aOneRange.aStart.Tab();
364 pDocSh->GetDocument()->GetDataArea(
365 nTab, nStartCol, nStartRow, nEndCol, nEndRow, FALSE );
367 ScRange aNew( nEndCol, nEndRow, nTab );
368 SetNewRange( aNew );
372 void SAL_CALL ScCellCursorObj::gotoNext() throw(uno::RuntimeException)
374 ScUnoGuard aGuard;
375 const ScRangeList& rRanges = GetRangeList();
376 DBG_ASSERT( rRanges.Count() == 1, "Range? Ranges?" );
377 ScRange aOneRange(*rRanges.GetObject(0));
379 aOneRange.Justify();
380 ScAddress aCursor(aOneRange.aStart); // bei Block immer den Start nehmen
382 ScMarkData aMark; // not used with bMarked=FALSE
383 SCCOL nNewX = aCursor.Col();
384 SCROW nNewY = aCursor.Row();
385 SCTAB nTab = aCursor.Tab();
386 ScDocShell* pDocSh = GetDocShell();
387 if ( pDocSh )
388 pDocSh->GetDocument()->GetNextPos( nNewX,nNewY, nTab, 1,0, FALSE,TRUE, aMark );
389 //! sonst Exception oder so
391 SetNewRange( ScRange( nNewX, nNewY, nTab ) );
394 void SAL_CALL ScCellCursorObj::gotoPrevious() throw(uno::RuntimeException)
396 ScUnoGuard aGuard;
397 const ScRangeList& rRanges = GetRangeList();
398 DBG_ASSERT( rRanges.Count() == 1, "Range? Ranges?" );
399 ScRange aOneRange(*rRanges.GetObject(0));
401 aOneRange.Justify();
402 ScAddress aCursor(aOneRange.aStart); // bei Block immer den Start nehmen
404 ScMarkData aMark; // not used with bMarked=FALSE
405 SCCOL nNewX = aCursor.Col();
406 SCROW nNewY = aCursor.Row();
407 SCTAB nTab = aCursor.Tab();
408 ScDocShell* pDocSh = GetDocShell();
409 if ( pDocSh )
410 pDocSh->GetDocument()->GetNextPos( nNewX,nNewY, nTab, -1,0, FALSE,TRUE, aMark );
411 //! sonst Exception oder so
413 SetNewRange( ScRange( nNewX, nNewY, nTab ) );
416 void SAL_CALL ScCellCursorObj::gotoOffset( sal_Int32 nColumnOffset, sal_Int32 nRowOffset )
417 throw(uno::RuntimeException)
419 ScUnoGuard aGuard;
420 const ScRangeList& rRanges = GetRangeList();
421 DBG_ASSERT( rRanges.Count() == 1, "Range? Ranges?" );
422 ScRange aOneRange(*rRanges.GetObject(0));
423 aOneRange.Justify();
425 if ( aOneRange.aStart.Col() + nColumnOffset >= 0 &&
426 aOneRange.aEnd.Col() + nColumnOffset <= MAXCOL &&
427 aOneRange.aStart.Row() + nRowOffset >= 0 &&
428 aOneRange.aEnd.Row() + nRowOffset <= MAXROW )
430 ScRange aNew( (SCCOL)(aOneRange.aStart.Col() + nColumnOffset),
431 (SCROW)(aOneRange.aStart.Row() + nRowOffset),
432 aOneRange.aStart.Tab(),
433 (SCCOL)(aOneRange.aEnd.Col() + nColumnOffset),
434 (SCROW)(aOneRange.aEnd.Row() + nRowOffset),
435 aOneRange.aEnd.Tab() );
436 SetNewRange( aNew );
440 // XSheetCellRange
442 uno::Reference<sheet::XSpreadsheet> SAL_CALL ScCellCursorObj::getSpreadsheet()
443 throw(uno::RuntimeException)
445 ScUnoGuard aGuard;
446 return ScCellRangeObj::getSpreadsheet();
449 // XCellRange
451 uno::Reference<table::XCell> SAL_CALL ScCellCursorObj::getCellByPosition(
452 sal_Int32 nColumn, sal_Int32 nRow )
453 throw(lang::IndexOutOfBoundsException, uno::RuntimeException)
455 ScUnoGuard aGuard;
456 return ScCellRangeObj::getCellByPosition(nColumn,nRow);
459 uno::Reference<table::XCellRange> SAL_CALL ScCellCursorObj::getCellRangeByPosition(
460 sal_Int32 nLeft, sal_Int32 nTop, sal_Int32 nRight, sal_Int32 nBottom )
461 throw(lang::IndexOutOfBoundsException, uno::RuntimeException)
463 ScUnoGuard aGuard;
464 return ScCellRangeObj::getCellRangeByPosition(nLeft,nTop,nRight,nBottom);
467 uno::Reference<table::XCellRange> SAL_CALL ScCellCursorObj::getCellRangeByName(
468 const rtl::OUString& rRange ) throw(uno::RuntimeException)
470 ScUnoGuard aGuard;
471 return ScCellRangeObj::getCellRangeByName(rRange);
474 // XServiceInfo
476 rtl::OUString SAL_CALL ScCellCursorObj::getImplementationName() throw(uno::RuntimeException)
478 return rtl::OUString::createFromAscii( "ScCellCursorObj" );
481 sal_Bool SAL_CALL ScCellCursorObj::supportsService( const rtl::OUString& rServiceName )
482 throw(uno::RuntimeException)
484 String aServiceStr( rServiceName );
485 return aServiceStr.EqualsAscii( SCSHEETCELLCURSOR_SERVICE ) ||
486 aServiceStr.EqualsAscii( SCCELLCURSOR_SERVICE ) ||
487 ScCellRangeObj::supportsService(rServiceName);
490 uno::Sequence<rtl::OUString> SAL_CALL ScCellCursorObj::getSupportedServiceNames()
491 throw(uno::RuntimeException)
493 // get all service names from cell range
494 uno::Sequence<rtl::OUString> aParentSeq(ScCellRangeObj::getSupportedServiceNames());
495 sal_Int32 nParentLen = aParentSeq.getLength();
496 const rtl::OUString* pParentArr = aParentSeq.getConstArray();
498 // SheetCellCursor should be first (?)
499 uno::Sequence<rtl::OUString> aTotalSeq( nParentLen + 2 );
500 rtl::OUString* pTotalArr = aTotalSeq.getArray();
501 pTotalArr[0] = rtl::OUString::createFromAscii( SCSHEETCELLCURSOR_SERVICE );
502 pTotalArr[1] = rtl::OUString::createFromAscii( SCCELLCURSOR_SERVICE );
504 // append cell range services
505 for (long i=0; i<nParentLen; i++)
506 pTotalArr[i+2] = pParentArr[i];
508 return aTotalSeq;