update dev300-m58
[ooovba.git] / sc / source / ui / view / viewfun2.cxx
bloba3b828a241a75bba601e7dcf76bfcf68d6f3aaaf
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: viewfun2.cxx,v $
10 * $Revision: 1.41.100.2 $
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 ---------------------------------------------------------------
38 #include "scitems.hxx"
39 #include <svx/eeitem.hxx>
41 #include <sfx2/app.hxx>
42 #define _SVSTDARR_STRINGS
43 #include <svx/boxitem.hxx>
44 #include <svx/fontitem.hxx>
45 #include <svx/scripttypeitem.hxx>
46 #include <svx/srchitem.hxx>
47 #include <svx/linkmgr.hxx>
48 #include <sfx2/dispatch.hxx>
49 #include <sfx2/docfilt.hxx>
50 #include <sfx2/docfile.hxx>
51 #include <sfx2/objitem.hxx>
52 #include <sfx2/viewfrm.hxx>
53 #include <svtools/stritem.hxx>
54 #include <svtools/zforlist.hxx>
55 #include <svtools/svstdarr.hxx>
56 #include <vcl/msgbox.hxx>
57 #include <vcl/sound.hxx>
58 #include <vcl/waitobj.hxx>
60 #include <basic/sbstar.hxx>
61 #include <com/sun/star/container/XNameContainer.hpp>
62 #include <com/sun/star/script/XLibraryContainer.hpp>
63 using namespace com::sun::star;
65 #include "viewfunc.hxx"
67 #include "sc.hrc"
68 #include "globstr.hrc"
70 #include "attrib.hxx"
71 #include "autoform.hxx"
72 #include "cell.hxx" // EnterAutoSum
73 #include "cellmergeoption.hxx"
74 #include "compiler.hxx"
75 #include "docfunc.hxx"
76 #include "docpool.hxx"
77 #include "docsh.hxx"
78 #include "global.hxx"
79 #include "patattr.hxx"
80 #include "printfun.hxx"
81 #include "rangenam.hxx"
82 #include "rangeutl.hxx"
83 #include "refundo.hxx"
84 #include "tablink.hxx"
85 #include "tabvwsh.hxx"
86 #include "uiitems.hxx"
87 #include "undoblk.hxx"
88 #include "undocell.hxx"
89 #include "undotab.hxx"
90 #include "sizedev.hxx"
91 #include "editable.hxx"
92 #include "scmod.hxx"
93 #include "inputhdl.hxx"
94 #include "inputwin.hxx"
95 #include "funcdesc.hxx"
96 #include "docuno.hxx"
98 #include "tabbgcolor.hxx" //DBW
100 // STATIC DATA ---------------------------------------------------------------
103 //----------------------------------------------------------------------------
105 BOOL ScViewFunc::AdjustBlockHeight( BOOL bPaint, ScMarkData* pMarkData )
107 ScDocShell* pDocSh = GetViewData()->GetDocShell();
108 if (!pMarkData)
109 pMarkData = &GetViewData()->GetMarkData();
111 ScDocument* pDoc = pDocSh->GetDocument();
112 SCCOLROW* pRanges = new SCCOLROW[MAXCOLROWCOUNT];
113 SCCOLROW nRangeCnt = pMarkData->GetMarkRowRanges( pRanges );
114 if (nRangeCnt == 0)
116 pRanges[0] = pRanges[1] = GetViewData()->GetCurY();
117 nRangeCnt = 1;
120 double nPPTX = GetViewData()->GetPPTX();
121 double nPPTY = GetViewData()->GetPPTY();
122 Fraction aZoomX = GetViewData()->GetZoomX();
123 Fraction aZoomY = GetViewData()->GetZoomY();
125 ScSizeDeviceProvider aProv(pDocSh);
126 if (aProv.IsPrinter())
128 nPPTX = aProv.GetPPTX();
129 nPPTY = aProv.GetPPTY();
130 aZoomX = aZoomY = Fraction( 1, 1 );
133 BOOL bAnyChanged = FALSE;
134 SCTAB nTabCount = pDoc->GetTableCount();
135 for (SCTAB nTab=0; nTab<nTabCount; nTab++)
137 if (pMarkData->GetTableSelect(nTab))
139 SCCOLROW* pOneRange = pRanges;
140 BOOL bChanged = FALSE;
141 SCROW nPaintY = 0;
142 for (SCROW nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++)
144 SCROW nStartNo = *(pOneRange++);
145 SCROW nEndNo = *(pOneRange++);
146 if (pDoc->SetOptimalHeight( nStartNo, nEndNo, nTab, 0, aProv.GetDevice(),
147 nPPTX, nPPTY, aZoomX, aZoomY, FALSE ))
149 if (!bChanged)
150 nPaintY = nStartNo;
151 bAnyChanged = bChanged = TRUE;
154 if ( bPaint && bChanged )
155 pDocSh->PostPaint( 0, nPaintY, nTab, MAXCOL, MAXROW, nTab,
156 PAINT_GRID | PAINT_LEFT );
159 delete[] pRanges;
161 if ( bPaint && bAnyChanged )
162 pDocSh->UpdateOle(GetViewData());
164 return bAnyChanged;
168 //----------------------------------------------------------------------------
170 BOOL ScViewFunc::AdjustRowHeight( SCROW nStartRow, SCROW nEndRow, BOOL bPaint )
172 ScDocShell* pDocSh = GetViewData()->GetDocShell();
173 ScDocument* pDoc = pDocSh->GetDocument();
174 SCTAB nTab = GetViewData()->GetTabNo();
175 double nPPTX = GetViewData()->GetPPTX();
176 double nPPTY = GetViewData()->GetPPTY();
177 Fraction aZoomX = GetViewData()->GetZoomX();
178 Fraction aZoomY = GetViewData()->GetZoomY();
179 USHORT nOldPixel = 0;
180 if (nStartRow == nEndRow)
181 nOldPixel = (USHORT) (pDoc->GetRowHeight(nStartRow,nTab) * nPPTY);
183 ScSizeDeviceProvider aProv(pDocSh);
184 if (aProv.IsPrinter())
186 nPPTX = aProv.GetPPTX();
187 nPPTY = aProv.GetPPTY();
188 aZoomX = aZoomY = Fraction( 1, 1 );
190 BOOL bChanged = pDoc->SetOptimalHeight( nStartRow, nEndRow, nTab, 0, aProv.GetDevice(),
191 nPPTX, nPPTY, aZoomX, aZoomY, FALSE );
193 if (bChanged && ( nStartRow == nEndRow ))
195 USHORT nNewPixel = (USHORT) (pDoc->GetRowHeight(nStartRow,nTab) * nPPTY);
196 if ( nNewPixel == nOldPixel )
197 bChanged = FALSE;
200 if ( bPaint && bChanged )
201 pDocSh->PostPaint( 0, nStartRow, nTab, MAXCOL, MAXROW, nTab,
202 PAINT_GRID | PAINT_LEFT );
204 return bChanged;
208 //----------------------------------------------------------------------------
210 enum ScAutoSum
212 ScAutoSumNone = 0,
213 ScAutoSumData,
214 ScAutoSumSum
218 ScAutoSum lcl_IsAutoSumData( ScDocument* pDoc, SCCOL nCol, SCROW nRow,
219 SCTAB nTab, ScDirection eDir, SCCOLROW& nExtend )
221 ScBaseCell* pCell;
222 pDoc->GetCell( nCol, nRow, nTab, pCell );
223 if ( pCell && pCell->HasValueData() )
225 if ( pCell->GetCellType() == CELLTYPE_FORMULA )
227 ScTokenArray* pCode = ((ScFormulaCell*)pCell)->GetCode();
228 if ( pCode && pCode->GetOuterFuncOpCode() == ocSum )
230 if ( pCode->GetAdjacentExtendOfOuterFuncRefs( nExtend,
231 ScAddress( nCol, nRow, nTab ), eDir ) )
232 return ScAutoSumSum;
235 return ScAutoSumData;
237 return ScAutoSumNone;
241 //----------------------------------------------------------------------------
243 #define SC_AUTOSUM_MAXCOUNT 20
245 ScAutoSum lcl_SeekAutoSumData( ScDocument* pDoc, SCCOL& nCol, SCROW& nRow,
246 SCTAB nTab, ScDirection eDir, SCCOLROW& nExtend )
248 USHORT nCount = 0;
249 while (nCount < SC_AUTOSUM_MAXCOUNT)
251 if ( eDir == DIR_TOP )
253 if (nRow > 0)
254 --nRow;
255 else
256 return ScAutoSumNone;
258 else
260 if (nCol > 0)
261 --nCol;
262 else
263 return ScAutoSumNone;
265 ScAutoSum eSum;
266 if ( (eSum = lcl_IsAutoSumData(
267 pDoc, nCol, nRow, nTab, eDir, nExtend )) != ScAutoSumNone )
268 return eSum;
269 ++nCount;
271 return ScAutoSumNone;
274 #undef SC_AUTOSUM_MAXCOUNT
276 //----------------------------------------------------------------------------
278 bool lcl_FindNextSumEntryInColumn( ScDocument* pDoc, SCCOL nCol, SCROW& nRow,
279 SCTAB nTab, SCCOLROW& nExtend, SCROW nMinRow )
281 const SCROW nTmp = nRow;
282 ScAutoSum eSkip = ScAutoSumNone;
283 while ( ( eSkip = lcl_IsAutoSumData( pDoc, nCol, nRow, nTab, DIR_TOP, nExtend ) ) == ScAutoSumData &&
284 nRow > nMinRow )
286 --nRow;
288 if ( eSkip == ScAutoSumSum && nRow < nTmp )
290 return true;
292 return false;
295 //----------------------------------------------------------------------------
297 bool lcl_FindNextSumEntryInRow( ScDocument* pDoc, SCCOL& nCol, SCROW nRow,
298 SCTAB nTab, SCCOLROW& nExtend, SCROW nMinCol )
300 const SCCOL nTmp = nCol;
301 ScAutoSum eSkip = ScAutoSumNone;
302 while ( ( eSkip = lcl_IsAutoSumData( pDoc, nCol, nRow, nTab, DIR_LEFT, nExtend ) ) == ScAutoSumData &&
303 nCol > nMinCol )
305 --nCol;
307 if ( eSkip == ScAutoSumSum && nCol < nTmp )
309 return true;
311 return false;
314 //----------------------------------------------------------------------------
316 bool lcl_GetAutoSumForColumnRange( ScDocument* pDoc, ScRangeList& rRangeList, const ScRange& rRange )
318 const ScAddress aStart = rRange.aStart;
319 const ScAddress aEnd = rRange.aEnd;
320 if ( aStart.Col() != aEnd.Col() )
322 return false;
325 const SCTAB nTab = aEnd.Tab();
326 const SCCOL nCol = aEnd.Col();
327 SCROW nEndRow = aEnd.Row();
328 SCROW nStartRow = nEndRow;
329 SCCOLROW nExtend = 0;
330 const ScAutoSum eSum = lcl_IsAutoSumData( pDoc, nCol, nEndRow, nTab, DIR_TOP, nExtend /*out*/ );
332 if ( eSum == ScAutoSumSum )
334 bool bContinue = false;
337 rRangeList.Append( ScRange( nCol, nStartRow, nTab, nCol, nEndRow, nTab ) );
338 nEndRow = static_cast< SCROW >( nExtend );
339 if ( ( bContinue = lcl_FindNextSumEntryInColumn( pDoc, nCol, nEndRow /*inout*/, nTab, nExtend /*out*/, aStart.Row() ) ) == true )
341 nStartRow = nEndRow;
343 } while ( bContinue );
345 else
347 while ( nStartRow > aStart.Row() &&
348 lcl_IsAutoSumData( pDoc, nCol, nStartRow-1, nTab, DIR_TOP, nExtend /*out*/ ) != ScAutoSumSum )
350 --nStartRow;
352 rRangeList.Append( ScRange( nCol, nStartRow, nTab, nCol, nEndRow, nTab ) );
355 return true;
358 //----------------------------------------------------------------------------
360 bool lcl_GetAutoSumForRowRange( ScDocument* pDoc, ScRangeList& rRangeList, const ScRange& rRange )
362 const ScAddress aStart = rRange.aStart;
363 const ScAddress aEnd = rRange.aEnd;
364 if ( aStart.Row() != aEnd.Row() )
366 return false;
369 const SCTAB nTab = aEnd.Tab();
370 const SCROW nRow = aEnd.Row();
371 SCCOL nEndCol = aEnd.Col();
372 SCCOL nStartCol = nEndCol;
373 SCCOLROW nExtend = 0;
374 const ScAutoSum eSum = lcl_IsAutoSumData( pDoc, nEndCol, nRow, nTab, DIR_LEFT, nExtend /*out*/ );
376 if ( eSum == ScAutoSumSum )
378 bool bContinue = false;
381 rRangeList.Append( ScRange( nStartCol, nRow, nTab, nEndCol, nRow, nTab ) );
382 nEndCol = static_cast< SCCOL >( nExtend );
383 if ( ( bContinue = lcl_FindNextSumEntryInRow( pDoc, nEndCol /*inout*/, nRow, nTab, nExtend /*out*/, aStart.Col() ) ) == true )
385 nStartCol = nEndCol;
387 } while ( bContinue );
389 else
391 while ( nStartCol > aStart.Col() &&
392 lcl_IsAutoSumData( pDoc, nStartCol-1, nRow, nTab, DIR_LEFT, nExtend /*out*/ ) != ScAutoSumSum )
394 --nStartCol;
396 rRangeList.Append( ScRange( nStartCol, nRow, nTab, nEndCol, nRow, nTab ) );
399 return true;
402 //----------------------------------------------------------------------------
404 BOOL ScViewFunc::GetAutoSumArea( ScRangeList& rRangeList )
406 ScDocument* pDoc = GetViewData()->GetDocument();
407 SCTAB nTab = GetViewData()->GetTabNo();
409 SCCOL nCol = GetViewData()->GetCurX();
410 SCROW nRow = GetViewData()->GetCurY();
412 SCCOL nStartCol = nCol;
413 SCROW nStartRow = nRow;
414 SCCOL nEndCol = nCol;
415 SCROW nEndRow = nRow;
416 SCCOL nSeekCol = nCol;
417 SCROW nSeekRow = nRow;
418 SCCOLROW nExtend; // wird per Reference gueltig bei ScAutoSumSum
420 BOOL bCol = FALSE;
421 BOOL bRow = FALSE;
423 ScAutoSum eSum;
424 if ( nRow != 0
425 && ((eSum = lcl_IsAutoSumData( pDoc, nCol, nRow-1, nTab,
426 DIR_TOP, nExtend /*out*/ )) == ScAutoSumData )
427 && ((eSum = lcl_IsAutoSumData( pDoc, nCol, nRow-1, nTab,
428 DIR_LEFT, nExtend /*out*/ )) == ScAutoSumData )
431 bRow = TRUE;
432 nSeekRow = nRow - 1;
434 else if ( nCol != 0 && (eSum = lcl_IsAutoSumData( pDoc, nCol-1, nRow, nTab,
435 DIR_LEFT, nExtend /*out*/ )) == ScAutoSumData )
437 bCol = TRUE;
438 nSeekCol = nCol - 1;
440 else if ( (eSum = lcl_SeekAutoSumData( pDoc, nCol, nSeekRow, nTab, DIR_TOP, nExtend /*out*/ )) != ScAutoSumNone )
441 bRow = TRUE;
442 else if (( eSum = lcl_SeekAutoSumData( pDoc, nSeekCol, nRow, nTab, DIR_LEFT, nExtend /*out*/ )) != ScAutoSumNone )
443 bCol = TRUE;
445 if ( bCol || bRow )
447 if ( bRow )
449 nStartRow = nSeekRow; // nSeekRow evtl. per Reference angepasst
450 if ( eSum == ScAutoSumSum )
451 nEndRow = nStartRow; // nur Summen summieren
452 else
453 nEndRow = nRow - 1; // Datenbereich evtl. nach unten erweitern
455 else
457 nStartCol = nSeekCol; // nSeekCol evtl. per Reference angepasst
458 if ( eSum == ScAutoSumSum )
459 nEndCol = nStartCol; // nur Summen summieren
460 else
461 nEndCol = nCol - 1; // Datenbereich evtl. nach rechts erweitern
463 BOOL bContinue = FALSE;
466 if ( eSum == ScAutoSumData )
468 if ( bRow )
470 while ( nStartRow != 0 && lcl_IsAutoSumData( pDoc, nCol,
471 nStartRow-1, nTab, DIR_TOP, nExtend /*out*/ ) == eSum )
472 --nStartRow;
474 else
476 while ( nStartCol != 0 && lcl_IsAutoSumData( pDoc, nStartCol-1,
477 nRow, nTab, DIR_LEFT, nExtend /*out*/ ) == eSum )
478 --nStartCol;
481 rRangeList.Append(
482 ScRange( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab ) );
483 if ( eSum == ScAutoSumSum )
485 if ( bRow )
487 nEndRow = static_cast< SCROW >( nExtend );
488 if ( ( bContinue = lcl_FindNextSumEntryInColumn( pDoc, nCol, nEndRow /*inout*/, nTab, nExtend /*out*/, 0 ) ) == true )
490 nStartRow = nEndRow;
493 else
495 nEndCol = static_cast< SCCOL >( nExtend );
496 if ( ( bContinue = lcl_FindNextSumEntryInRow( pDoc, nEndCol /*inout*/, nRow, nTab, nExtend /*out*/, 0 ) ) == true )
498 nStartCol = nEndCol;
502 } while ( bContinue );
503 return TRUE;
505 return FALSE;
508 //----------------------------------------------------------------------------
510 void ScViewFunc::EnterAutoSum(const ScRangeList& rRangeList, sal_Bool bSubTotal) // Block mit Summen fuellen
512 String aFormula = GetAutoSumFormula( rRangeList, bSubTotal );
513 EnterBlock( aFormula, NULL );
516 //----------------------------------------------------------------------------
518 bool ScViewFunc::AutoSum( const ScRange& rRange, bool bSubTotal, bool bSetCursor, bool bContinue )
520 ScDocument* pDoc = GetViewData()->GetDocument();
521 const SCTAB nTab = rRange.aStart.Tab();
522 SCCOL nStartCol = rRange.aStart.Col();
523 SCROW nStartRow = rRange.aStart.Row();
524 const SCCOL nEndCol = rRange.aEnd.Col();
525 const SCROW nEndRow = rRange.aEnd.Row();
526 SCCOLROW nExtend = 0; // out parameter for lcl_IsAutoSumData
528 // ignore rows at the top of the given range which don't contain autosum data
529 bool bRowData = false;
530 for ( SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow )
532 for ( SCCOL nCol = nStartCol; nCol <= nEndCol; ++nCol )
534 if ( lcl_IsAutoSumData( pDoc, nCol, nRow, nTab, DIR_TOP, nExtend ) != ScAutoSumNone )
536 bRowData = true;
537 break;
540 if ( bRowData )
542 nStartRow = nRow;
543 break;
546 if ( !bRowData )
548 return false;
551 // ignore columns at the left of the given range which don't contain autosum data
552 bool bColData = false;
553 for ( SCCOL nCol = nStartCol; nCol <= nEndCol; ++nCol )
555 for ( SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow )
557 if ( lcl_IsAutoSumData( pDoc, nCol, nRow, nTab, DIR_LEFT, nExtend ) != ScAutoSumNone )
559 bColData = true;
560 break;
563 if ( bColData )
565 nStartCol = nCol;
566 break;
569 if ( !bColData )
571 return false;
574 const bool bEndRowEmpty = pDoc->IsBlockEmpty( nTab, nStartCol, nEndRow, nEndCol, nEndRow );
575 const bool bEndColEmpty = pDoc->IsBlockEmpty( nTab, nEndCol, nStartRow, nEndCol, nEndRow );
576 bool bRow = ( ( nStartRow != nEndRow ) && ( bEndRowEmpty || ( !bEndRowEmpty && !bEndColEmpty ) ) );
577 bool bCol = ( ( nStartCol != nEndCol ) && ( bEndColEmpty || nStartRow == nEndRow ) );
579 // find an empty row for entering the result
580 SCROW nInsRow = nEndRow;
581 if ( bRow && !bEndRowEmpty )
583 if ( nInsRow < MAXROW )
585 ++nInsRow;
586 while ( !pDoc->IsBlockEmpty( nTab, nStartCol, nInsRow, nEndCol, nInsRow ) )
588 if ( nInsRow < MAXROW )
590 ++nInsRow;
592 else
594 bRow = false;
595 break;
599 else
601 bRow = false;
605 // find an empty column for entering the result
606 SCCOL nInsCol = nEndCol;
607 if ( bCol && !bEndColEmpty )
609 if ( nInsCol < MAXCOL )
611 ++nInsCol;
612 while ( !pDoc->IsBlockEmpty( nTab, nInsCol, nStartRow, nInsCol, nEndRow ) )
614 if ( nInsCol < MAXCOL )
616 ++nInsCol;
618 else
620 bCol = false;
621 break;
625 else
627 bCol = false;
631 if ( !bRow && !bCol )
633 return false;
636 SCCOL nMarkEndCol = nEndCol;
637 SCROW nMarkEndRow = nEndRow;
639 if ( bRow )
641 // calculate the row sums for all columns of the given range
643 SCROW nSumEndRow = nEndRow;
645 if ( bEndRowEmpty )
647 // the last row of the given range is empty;
648 // don't take into account for calculating the autosum
649 --nSumEndRow;
651 else
653 // increase mark range
654 ++nMarkEndRow;
657 for ( SCCOL nCol = nStartCol; nCol <= nEndCol; ++nCol )
659 if ( !pDoc->IsBlockEmpty( nTab, nCol, nStartRow, nCol, nSumEndRow ) )
661 ScRangeList aRangeList;
662 const ScRange aRange( nCol, nStartRow, nTab, nCol, nSumEndRow, nTab );
663 if ( lcl_GetAutoSumForColumnRange( pDoc, aRangeList, aRange ) )
665 const String aFormula = GetAutoSumFormula( aRangeList, bSubTotal );
666 EnterData( nCol, nInsRow, nTab, aFormula );
672 if ( bCol )
674 // calculate the column sums for all rows of the given range
676 SCCOL nSumEndCol = nEndCol;
678 if ( bEndColEmpty )
680 // the last column of the given range is empty;
681 // don't take into account for calculating the autosum
682 --nSumEndCol;
684 else
686 // increase mark range
687 ++nMarkEndCol;
690 for ( SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow )
692 if ( !pDoc->IsBlockEmpty( nTab, nStartCol, nRow, nSumEndCol, nRow ) )
694 ScRangeList aRangeList;
695 const ScRange aRange( nStartCol, nRow, nTab, nSumEndCol, nRow, nTab );
696 if ( lcl_GetAutoSumForRowRange( pDoc, aRangeList, aRange ) )
698 const String aFormula = GetAutoSumFormula( aRangeList, bSubTotal );
699 EnterData( nInsCol, nRow, nTab, aFormula );
705 // set new mark range and cursor position
706 const ScRange aMarkRange( nStartCol, nStartRow, nTab, nMarkEndCol, nMarkEndRow, nTab );
707 MarkRange( aMarkRange, FALSE, bContinue );
708 if ( bSetCursor )
710 SetCursor( nMarkEndCol, nMarkEndRow );
713 return true;
716 //----------------------------------------------------------------------------
718 String ScViewFunc::GetAutoSumFormula( const ScRangeList& rRangeList, bool bSubTotal )
720 String aFormula = '=';
721 ScFunctionMgr* pFuncMgr = ScGlobal::GetStarCalcFunctionMgr();
722 const ScFuncDesc* pDesc = NULL;
723 if ( bSubTotal )
725 pDesc = pFuncMgr->Get( SC_OPCODE_SUB_TOTAL );
727 else
729 pDesc = pFuncMgr->Get( SC_OPCODE_SUM );
731 if ( pDesc && pDesc->pFuncName )
733 aFormula += *pDesc->pFuncName;
734 if ( bSubTotal )
736 aFormula.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "(9;" ) );
738 else
740 aFormula += '(';
742 ScDocument* pDoc = GetViewData()->GetDocument();
743 String aRef;
744 rRangeList.Format( aRef, SCA_VALID, pDoc );
745 aFormula += aRef;
746 aFormula += ')';
748 return aFormula;
751 //----------------------------------------------------------------------------
753 void ScViewFunc::EnterBlock( const String& rString, const EditTextObject* pData )
755 // Mehrfachselektion vorher abfragen...
757 SCCOL nCol = GetViewData()->GetCurX();
758 SCROW nRow = GetViewData()->GetCurY();
759 SCTAB nTab = GetViewData()->GetTabNo();
760 ScMarkData& rMark = GetViewData()->GetMarkData();
761 if ( rMark.IsMultiMarked() )
763 rMark.MarkToSimple();
764 if ( rMark.IsMultiMarked() )
765 { // "Einfuegen auf Mehrfachselektion nicht moeglich"
766 ErrorMessage(STR_MSSG_PASTEFROMCLIP_0);
768 // insert into single cell
769 if ( pData )
770 EnterData( nCol, nRow, nTab, pData );
771 else
772 EnterData( nCol, nRow, nTab, rString );
773 return;
777 ScDocument* pDoc = GetViewData()->GetDocument();
778 String aNewStr = rString;
779 if ( pData )
781 const ScPatternAttr* pOldPattern = pDoc->GetPattern( nCol, nRow, nTab );
782 ScTabEditEngine aEngine( *pOldPattern, pDoc->GetEnginePool() );
783 aEngine.SetText(*pData);
785 ScEditAttrTester aTester( &aEngine );
786 if (!aTester.NeedsObject())
788 aNewStr = aEngine.GetText();
789 pData = NULL;
793 // Einfuegen per PasteFromClip
795 WaitObject aWait( GetFrameWin() );
797 ScAddress aPos( nCol, nRow, nTab );
799 ScDocument* pInsDoc = new ScDocument( SCDOCMODE_CLIP );
800 pInsDoc->ResetClip( pDoc, nTab );
802 if (aNewStr.GetChar(0) == '=') // Formel ?
804 // SetString geht nicht, weil in Clipboard-Dokumenten nicht kompiliert wird!
805 ScFormulaCell* pFCell = new ScFormulaCell( pDoc, aPos, aNewStr );
806 pInsDoc->PutCell( nCol, nRow, nTab, pFCell );
808 else if ( pData )
809 pInsDoc->PutCell( nCol, nRow, nTab, new ScEditCell( pData, pDoc, NULL ) );
810 else
811 pInsDoc->SetString( nCol, nRow, nTab, aNewStr );
813 pInsDoc->SetClipArea( ScRange(aPos) );
814 // auf Block einfuegen, mit Undo etc.
815 if ( PasteFromClip( IDF_CONTENTS, pInsDoc, PASTE_NOFUNC, FALSE, FALSE,
816 FALSE, INS_NONE, IDF_ATTRIB ) )
818 const SfxUInt32Item* pItem = (SfxUInt32Item*) pInsDoc->GetAttr(
819 nCol, nRow, nTab, ATTR_VALUE_FORMAT );
820 if ( pItem )
821 { // Numberformat setzen wenn inkompatibel
822 // MarkData wurde bereits in PasteFromClip MarkToSimple'ed
823 ScRange aRange;
824 rMark.GetMarkArea( aRange );
825 ScPatternAttr* pPattern = new ScPatternAttr( pDoc->GetPool() );
826 pPattern->GetItemSet().Put( *pItem );
827 short nNewType = pDoc->GetFormatTable()->GetType( pItem->GetValue() );
828 pDoc->ApplyPatternIfNumberformatIncompatible( aRange, rMark,
829 *pPattern, nNewType );
830 delete pPattern;
834 delete pInsDoc;
838 //----------------------------------------------------------------------------
840 //UNUSED2008-05 void ScViewFunc::PaintWidthHeight( BOOL bColumns, SCCOLROW nStart, SCCOLROW nEnd )
841 //UNUSED2008-05 {
842 //UNUSED2008-05 SCTAB nTab = GetViewData()->GetTabNo();
843 //UNUSED2008-05 ScDocument* pDoc = GetViewData()->GetDocument();
844 //UNUSED2008-05
845 //UNUSED2008-05 USHORT nParts = PAINT_GRID;
846 //UNUSED2008-05 SCCOL nStartCol = 0;
847 //UNUSED2008-05 SCROW nStartRow = 0;
848 //UNUSED2008-05 SCCOL nEndCol = MAXCOL; // fuer Test auf Merge
849 //UNUSED2008-05 SCROW nEndRow = MAXROW;
850 //UNUSED2008-05 if ( bColumns )
851 //UNUSED2008-05 {
852 //UNUSED2008-05 nParts |= PAINT_TOP;
853 //UNUSED2008-05 nStartCol = static_cast<SCCOL>(nStart);
854 //UNUSED2008-05 nEndCol = static_cast<SCCOL>(nEnd);
855 //UNUSED2008-05 }
856 //UNUSED2008-05 else
857 //UNUSED2008-05 {
858 //UNUSED2008-05 nParts |= PAINT_LEFT;
859 //UNUSED2008-05 nStartRow = nStart;
860 //UNUSED2008-05 nEndRow = nEnd;
861 //UNUSED2008-05 }
862 //UNUSED2008-05 if (pDoc->HasAttrib( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab,
863 //UNUSED2008-05 HASATTR_MERGED | HASATTR_OVERLAPPED ))
864 //UNUSED2008-05 {
865 //UNUSED2008-05 nStartCol = 0;
866 //UNUSED2008-05 nStartRow = 0;
867 //UNUSED2008-05 }
868 //UNUSED2008-05 GetViewData()->GetDocShell()->PostPaint( nStartCol,nStartRow,nTab, MAXCOL,MAXROW,nTab, nParts );
869 //UNUSED2008-05 }
872 //----------------------------------------------------------------------------
873 // manueller Seitenumbruch
875 void ScViewFunc::InsertPageBreak( BOOL bColumn, BOOL bRecord, const ScAddress* pPos,
876 BOOL bSetModified )
878 SCTAB nTab = GetViewData()->GetTabNo();
879 ScAddress aCursor;
880 if (pPos)
881 aCursor = *pPos;
882 else
883 aCursor = ScAddress( GetViewData()->GetCurX(), GetViewData()->GetCurY(), nTab );
885 BOOL bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
886 InsertPageBreak( bColumn, aCursor, bRecord, bSetModified, FALSE );
888 if ( bSuccess && bSetModified )
889 UpdatePageBreakData( TRUE ); // fuer PageBreak-Modus
893 //----------------------------------------------------------------------------
895 void ScViewFunc::DeletePageBreak( BOOL bColumn, BOOL bRecord, const ScAddress* pPos,
896 BOOL bSetModified )
898 SCTAB nTab = GetViewData()->GetTabNo();
899 ScAddress aCursor;
900 if (pPos)
901 aCursor = *pPos;
902 else
903 aCursor = ScAddress( GetViewData()->GetCurX(), GetViewData()->GetCurY(), nTab );
905 BOOL bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
906 RemovePageBreak( bColumn, aCursor, bRecord, bSetModified, FALSE );
908 if ( bSuccess && bSetModified )
909 UpdatePageBreakData( TRUE ); // fuer PageBreak-Modus
912 //----------------------------------------------------------------------------
914 void ScViewFunc::RemoveManualBreaks()
916 ScDocShell* pDocSh = GetViewData()->GetDocShell();
917 ScDocument* pDoc = pDocSh->GetDocument();
918 SCTAB nTab = GetViewData()->GetTabNo();
919 BOOL bUndo(pDoc->IsUndoEnabled());
921 if (bUndo)
923 ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
924 pUndoDoc->InitUndo( pDoc, nTab, nTab, TRUE, TRUE );
925 pDoc->CopyToDocument( 0,0,nTab, MAXCOL,MAXROW,nTab, IDF_NONE, FALSE, pUndoDoc );
926 pDocSh->GetUndoManager()->AddUndoAction(
927 new ScUndoRemoveBreaks( pDocSh, nTab, pUndoDoc ) );
930 pDoc->RemoveManualBreaks(nTab);
931 pDoc->UpdatePageBreaks(nTab);
933 UpdatePageBreakData( TRUE );
934 pDocSh->SetDocumentModified();
935 pDocSh->PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID );
938 //----------------------------------------------------------------------------
940 void ScViewFunc::SetPrintZoom(USHORT nScale, USHORT nPages)
942 ScDocShell* pDocSh = GetViewData()->GetDocShell();
943 SCTAB nTab = GetViewData()->GetTabNo();
944 pDocSh->SetPrintZoom( nTab, nScale, nPages );
947 void ScViewFunc::AdjustPrintZoom()
949 ScRange aRange;
950 if ( GetViewData()->GetSimpleArea( aRange ) != SC_MARK_SIMPLE )
951 GetViewData()->GetMarkData().GetMultiMarkArea( aRange );
952 GetViewData()->GetDocShell()->AdjustPrintZoom( aRange );
955 //----------------------------------------------------------------------------
957 void ScViewFunc::SetPrintRanges( BOOL bEntireSheet, const String* pPrint,
958 const String* pRepCol, const String* pRepRow,
959 BOOL bAddPrint )
961 // on all selected tables
963 ScDocShell* pDocSh = GetViewData()->GetDocShell();
964 ScDocument* pDoc = pDocSh->GetDocument();
965 SCTAB nTabCount = pDoc->GetTableCount();
966 ScMarkData& rMark = GetViewData()->GetMarkData();
967 SCTAB nTab;
968 BOOL bUndo (pDoc->IsUndoEnabled());
970 ScPrintRangeSaver* pOldRanges = pDoc->CreatePrintRangeSaver();
972 ScAddress::Details aDetails(pDoc->GetAddressConvention(), 0, 0);
974 for (nTab=0; nTab<nTabCount; nTab++)
975 if (rMark.GetTableSelect(nTab))
977 ScRange aRange( 0,0,nTab );
979 // print ranges
981 if( !bAddPrint )
982 pDoc->ClearPrintRanges( nTab );
984 if( bEntireSheet )
986 pDoc->SetPrintEntireSheet( nTab );
988 else if ( pPrint )
990 if ( pPrint->Len() )
992 const sal_Unicode sep = ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
993 USHORT nTCount = pPrint->GetTokenCount(sep);
994 for (USHORT i=0; i<nTCount; i++)
996 String aToken = pPrint->GetToken(i, sep);
997 if ( aRange.ParseAny( aToken, pDoc, aDetails ) & SCA_VALID )
998 pDoc->AddPrintRange( nTab, aRange );
1002 else // NULL = use selection (print range is always set), use empty string to delete all ranges
1004 if ( GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE )
1006 pDoc->AddPrintRange( nTab, aRange );
1008 else if ( rMark.IsMultiMarked() )
1010 rMark.MarkToMulti();
1011 ScRangeListRef aList( new ScRangeList );
1012 rMark.FillRangeListWithMarks( aList, FALSE );
1013 USHORT nCnt = (USHORT) aList->Count();
1014 if ( nCnt )
1016 ScRangePtr pR;
1017 USHORT i;
1018 for ( pR = aList->First(), i=0; i < nCnt;
1019 pR = aList->Next(), i++ )
1021 pDoc->AddPrintRange( nTab, *pR );
1027 // repeat columns
1029 if ( pRepCol )
1031 if ( !pRepCol->Len() )
1032 pDoc->SetRepeatColRange( nTab, NULL );
1033 else
1034 if ( aRange.ParseAny( *pRepCol, pDoc, aDetails ) & SCA_VALID )
1035 pDoc->SetRepeatColRange( nTab, &aRange );
1038 // repeat rows
1040 if ( pRepRow )
1042 if ( !pRepRow->Len() )
1043 pDoc->SetRepeatRowRange( nTab, NULL );
1044 else
1045 if ( aRange.ParseAny( *pRepRow, pDoc, aDetails ) & SCA_VALID )
1046 pDoc->SetRepeatRowRange( nTab, &aRange );
1050 // undo (for all tables)
1051 if (bUndo)
1053 SCTAB nCurTab = GetViewData()->GetTabNo();
1054 ScPrintRangeSaver* pNewRanges = pDoc->CreatePrintRangeSaver();
1055 pDocSh->GetUndoManager()->AddUndoAction(
1056 new ScUndoPrintRange( pDocSh, nCurTab, pOldRanges, pNewRanges ) );
1059 // update page breaks
1061 for (nTab=0; nTab<nTabCount; nTab++)
1062 if (rMark.GetTableSelect(nTab))
1063 ScPrintFunc( pDocSh, pDocSh->GetPrinter(), nTab ).UpdatePages();
1065 SfxBindings& rBindings = GetViewData()->GetBindings();
1066 rBindings.Invalidate( SID_DELETE_PRINTAREA );
1068 pDocSh->SetDocumentModified();
1071 //----------------------------------------------------------------------------
1072 // Zellen zusammenfassen
1074 BOOL ScViewFunc::TestMergeCells() // Vorab-Test (fuer Menue)
1076 // simple test: TRUE if there's a selection but no multi selection and not filtered
1078 const ScMarkData& rMark = GetViewData()->GetMarkData();
1079 if ( rMark.IsMarked() || rMark.IsMultiMarked() )
1081 ScRange aDummy;
1082 return GetViewData()->GetSimpleArea( aDummy) == SC_MARK_SIMPLE;
1084 else
1085 return FALSE;
1089 //----------------------------------------------------------------------------
1091 BOOL ScViewFunc::MergeCells( BOOL bApi, BOOL& rDoContents, BOOL bRecord, BOOL bCenter )
1093 // Editable- und Verschachtelungs-Abfrage muss vorneweg sein (auch in DocFunc),
1094 // damit dann nicht die Inhalte-QueryBox kommt
1095 ScEditableTester aTester( this );
1096 if (!aTester.IsEditable())
1098 ErrorMessage(aTester.GetMessageId());
1099 return FALSE;
1102 ScMarkData& rMark = GetViewData()->GetMarkData();
1103 rMark.MarkToSimple();
1104 if (!rMark.IsMarked())
1106 ErrorMessage(STR_NOMULTISELECT);
1107 return FALSE;
1110 ScDocShell* pDocSh = GetViewData()->GetDocShell();
1111 ScDocument* pDoc = pDocSh->GetDocument();
1113 ScRange aMarkRange;
1114 rMark.GetMarkArea( aMarkRange );
1115 SCCOL nStartCol = aMarkRange.aStart.Col();
1116 SCROW nStartRow = aMarkRange.aStart.Row();
1117 SCTAB nStartTab = aMarkRange.aStart.Tab();
1118 SCCOL nEndCol = aMarkRange.aEnd.Col();
1119 SCROW nEndRow = aMarkRange.aEnd.Row();
1120 SCTAB nEndTab = aMarkRange.aEnd.Tab();
1121 if ( nStartCol == nEndCol && nStartRow == nEndRow )
1123 // nichts zu tun
1124 return TRUE;
1127 if ( pDoc->HasAttrib( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab,
1128 HASATTR_MERGED | HASATTR_OVERLAPPED ) )
1129 { // "Zusammenfassen nicht verschachteln !"
1130 ErrorMessage(STR_MSSG_MERGECELLS_0);
1131 return FALSE;
1134 // Check for the contents of all selected tables.
1135 bool bAskDialog = false;
1136 SCTAB nTabCount = pDoc->GetTableCount();
1137 ScCellMergeOption aMergeOption(nStartCol, nStartRow, nEndCol, nEndRow, bCenter);
1138 for (SCTAB i = 0; i < nTabCount; ++i)
1140 if (!rMark.GetTableSelect(i))
1141 // this table is not selected.
1142 continue;
1144 aMergeOption.maTabs.insert(i);
1146 if (!pDoc->IsBlockEmpty(i, nStartCol, nStartRow+1, nStartCol, nEndRow) ||
1147 !pDoc->IsBlockEmpty(i, nStartCol+1, nStartRow, nEndCol, nEndRow))
1148 bAskDialog = true;
1151 BOOL bOk = TRUE;
1153 if (bAskDialog)
1155 if (!bApi)
1157 MessBox aBox( GetViewData()->GetDialogParent(),
1158 WinBits(WB_YES_NO_CANCEL | WB_DEF_NO),
1159 ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_0 ),
1160 ScGlobal::GetRscString( STR_MERGE_NOTEMPTY ) );
1161 USHORT nRetVal = aBox.Execute();
1163 if ( nRetVal == RET_YES )
1164 rDoContents = TRUE;
1165 else if ( nRetVal == RET_CANCEL )
1166 bOk = FALSE;
1170 if (bOk)
1172 HideCursor();
1173 bOk = pDocSh->GetDocFunc().MergeCells( aMergeOption, rDoContents, bRecord, bApi );
1174 ShowCursor();
1176 if (bOk)
1178 SetCursor( nStartCol, nStartRow );
1179 //DoneBlockMode( FALSE);
1180 Unmark();
1182 pDocSh->UpdateOle(GetViewData());
1183 UpdateInputLine();
1187 return bOk;
1191 //----------------------------------------------------------------------------
1193 BOOL ScViewFunc::TestRemoveMerge()
1195 BOOL bMerged = FALSE;
1196 ScRange aRange;
1197 if (GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE)
1199 ScDocument* pDoc = GetViewData()->GetDocument();
1200 if ( pDoc->HasAttrib( aRange, HASATTR_MERGED ) )
1201 bMerged = TRUE;
1203 return bMerged;
1207 //----------------------------------------------------------------------------
1209 static bool lcl_extendMergeRange(ScCellMergeOption& rOption, const ScRange& rRange)
1211 bool bExtended = false;
1212 if (rOption.mnStartCol > rRange.aStart.Col())
1214 rOption.mnStartCol = rRange.aStart.Col();
1215 bExtended = true;
1217 if (rOption.mnStartRow > rRange.aStart.Row())
1219 rOption.mnStartRow = rRange.aStart.Row();
1220 bExtended = true;
1222 if (rOption.mnEndCol < rRange.aEnd.Col())
1224 rOption.mnEndCol = rRange.aEnd.Col();
1225 bExtended = true;
1227 if (rOption.mnEndRow < rRange.aEnd.Row())
1229 rOption.mnEndRow = rRange.aEnd.Row();
1230 bExtended = true;
1232 return bExtended;
1235 BOOL ScViewFunc::RemoveMerge( BOOL bRecord )
1237 ScRange aRange;
1238 ScEditableTester aTester( this );
1239 if (!aTester.IsEditable())
1241 ErrorMessage(aTester.GetMessageId());
1242 return FALSE;
1244 else if (GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE)
1246 ScDocument* pDoc = GetViewData()->GetDocument();
1247 ScRange aExtended( aRange );
1248 pDoc->ExtendMerge( aExtended );
1249 ScDocShell* pDocSh = GetViewData()->GetDocShell();
1250 const ScMarkData& rMark = GetViewData()->GetMarkData();
1251 SCTAB nTabCount = pDoc->GetTableCount();
1252 ScCellMergeOption aOption(aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(), aRange.aEnd.Row());
1253 bool bExtended = false;
1256 bExtended = false;
1257 for (SCTAB i = 0; i < nTabCount; ++i)
1259 if (!rMark.GetTableSelect(i))
1260 // This table is not selected.
1261 continue;
1263 aOption.maTabs.insert(i);
1264 aExtended.aStart.SetTab(i);
1265 aExtended.aEnd.SetTab(i);
1266 pDoc->ExtendMerge(aExtended);
1267 pDoc->ExtendOverlapped(aExtended);
1269 // Expand the current range to be inclusive of all merged
1270 // areas on all sheets.
1271 bExtended = lcl_extendMergeRange(aOption, aExtended);
1274 while (bExtended);
1276 HideCursor();
1277 BOOL bOk = pDocSh->GetDocFunc().UnmergeCells(aOption, bRecord, FALSE );
1278 aExtended = aOption.getFirstSingleRange();
1279 MarkRange( aExtended );
1280 ShowCursor();
1282 if (bOk)
1283 pDocSh->UpdateOle(GetViewData());
1285 return TRUE; //! bOk ??
1288 //----------------------------------------------------------------------------
1290 void ScViewFunc::FillSimple( FillDir eDir, BOOL bRecord )
1292 ScRange aRange;
1293 if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
1295 ScDocShell* pDocSh = GetViewData()->GetDocShell();
1296 const ScMarkData& rMark = GetViewData()->GetMarkData();
1297 BOOL bSuccess = pDocSh->GetDocFunc().FillSimple( aRange, &rMark, eDir, bRecord, FALSE );
1298 if (bSuccess)
1300 pDocSh->UpdateOle(GetViewData());
1301 UpdateScrollBars();
1304 else
1305 ErrorMessage(STR_NOMULTISELECT);
1308 //----------------------------------------------------------------------------
1310 void ScViewFunc::FillSeries( FillDir eDir, FillCmd eCmd, FillDateCmd eDateCmd,
1311 double fStart, double fStep, double fMax, BOOL bRecord )
1313 ScRange aRange;
1314 if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
1316 ScDocShell* pDocSh = GetViewData()->GetDocShell();
1317 const ScMarkData& rMark = GetViewData()->GetMarkData();
1318 BOOL bSuccess = pDocSh->GetDocFunc().
1319 FillSeries( aRange, &rMark, eDir, eCmd, eDateCmd,
1320 fStart, fStep, fMax, bRecord, FALSE );
1321 if (bSuccess)
1323 pDocSh->UpdateOle(GetViewData());
1324 UpdateScrollBars();
1326 // #i97876# Spreadsheet data changes are not notified
1327 ScModelObj* pModelObj = ScModelObj::getImplementation( pDocSh->GetModel() );
1328 if ( pModelObj && pModelObj->HasChangesListeners() )
1330 ScRangeList aChangeRanges;
1331 aChangeRanges.Append( aRange );
1332 pModelObj->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "cell-change" ) ), aChangeRanges );
1336 else
1337 ErrorMessage(STR_NOMULTISELECT);
1340 //----------------------------------------------------------------------------
1342 void ScViewFunc::FillAuto( FillDir eDir, SCCOL nStartCol, SCROW nStartRow,
1343 SCCOL nEndCol, SCROW nEndRow, ULONG nCount, BOOL bRecord )
1345 SCTAB nTab = GetViewData()->GetTabNo();
1346 ScRange aRange( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab );
1347 ScRange aSourceRange( aRange );
1348 ScDocShell* pDocSh = GetViewData()->GetDocShell();
1349 const ScMarkData& rMark = GetViewData()->GetMarkData();
1350 BOOL bSuccess = pDocSh->GetDocFunc().
1351 FillAuto( aRange, &rMark, eDir, nCount, bRecord, FALSE );
1352 if (bSuccess)
1354 MarkRange( aRange, FALSE ); // aRange ist in FillAuto veraendert worden
1355 pDocSh->UpdateOle(GetViewData());
1356 UpdateScrollBars();
1358 // #i97876# Spreadsheet data changes are not notified
1359 ScModelObj* pModelObj = ScModelObj::getImplementation( pDocSh->GetModel() );
1360 if ( pModelObj && pModelObj->HasChangesListeners() )
1362 ScRangeList aChangeRanges;
1363 ScRange aChangeRange( aRange );
1364 switch ( eDir )
1366 case FILL_TO_BOTTOM:
1368 aChangeRange.aStart.SetRow( aSourceRange.aEnd.Row() + 1 );
1370 break;
1371 case FILL_TO_TOP:
1373 aChangeRange.aEnd.SetRow( aSourceRange.aStart.Row() - 1 );
1375 break;
1376 case FILL_TO_RIGHT:
1378 aChangeRange.aStart.SetCol( aSourceRange.aEnd.Col() + 1 );
1380 break;
1381 case FILL_TO_LEFT:
1383 aChangeRange.aEnd.SetCol( aSourceRange.aStart.Col() - 1 );
1385 break;
1386 default:
1390 break;
1392 aChangeRanges.Append( aChangeRange );
1393 pModelObj->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "cell-change" ) ), aChangeRanges );
1398 //----------------------------------------------------------------------------
1400 void ScViewFunc::FillTab( USHORT nFlags, USHORT nFunction, BOOL bSkipEmpty, BOOL bAsLink )
1402 //! allow source sheet to be protected
1403 ScEditableTester aTester( this );
1404 if (!aTester.IsEditable())
1406 ErrorMessage(aTester.GetMessageId());
1407 return;
1410 ScDocShell* pDocSh = GetViewData()->GetDocShell();
1411 ScDocument* pDoc = pDocSh->GetDocument();
1412 ScMarkData& rMark = GetViewData()->GetMarkData();
1413 SCTAB nTab = GetViewData()->GetTabNo();
1414 BOOL bUndo(pDoc->IsUndoEnabled());
1416 ScRange aMarkRange;
1417 rMark.MarkToSimple();
1418 BOOL bMulti = rMark.IsMultiMarked();
1419 if (bMulti)
1420 rMark.GetMultiMarkArea( aMarkRange );
1421 else if (rMark.IsMarked())
1422 rMark.GetMarkArea( aMarkRange );
1423 else
1424 aMarkRange = ScRange( GetViewData()->GetCurX(), GetViewData()->GetCurY(), nTab );
1426 ScDocument* pUndoDoc = NULL;
1427 // if ( bRecord )
1428 if (bUndo)
1430 pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
1431 pUndoDoc->InitUndo( pDoc, nTab, nTab );
1432 // pUndoDoc->SelectTable( nTab, TRUE ); // nur fuer Markierung
1434 SCTAB nTabCount = pDoc->GetTableCount();
1435 for (SCTAB i=0; i<nTabCount; i++)
1436 if (i != nTab && rMark.GetTableSelect(i))
1438 pUndoDoc->AddUndoTab( i, i );
1439 aMarkRange.aStart.SetTab( i );
1440 aMarkRange.aEnd.SetTab( i );
1441 pDoc->CopyToDocument( aMarkRange, IDF_ALL, bMulti, pUndoDoc );
1442 // pUndoDoc->SelectTable( i, TRUE );
1446 if (bMulti)
1447 pDoc->FillTabMarked( nTab, rMark, nFlags, nFunction, bSkipEmpty, bAsLink );
1448 else
1450 aMarkRange.aStart.SetTab( nTab );
1451 aMarkRange.aEnd.SetTab( nTab );
1452 pDoc->FillTab( aMarkRange, rMark, nFlags, nFunction, bSkipEmpty, bAsLink );
1455 // if ( bRecord )
1456 if (bUndo)
1457 { //! fuer ChangeTrack erst zum Schluss
1458 pDocSh->GetUndoManager()->AddUndoAction(
1459 new ScUndoFillTable( pDocSh, rMark,
1460 aMarkRange.aStart.Col(), aMarkRange.aStart.Row(), nTab,
1461 aMarkRange.aEnd.Col(), aMarkRange.aEnd.Row(), nTab,
1462 pUndoDoc, bMulti, nTab, nFlags, nFunction, bSkipEmpty, bAsLink ) );
1465 pDocSh->PostPaintGridAll();
1466 pDocSh->PostDataChanged();
1469 //----------------------------------------------------------------------------
1471 /** Downward fill of selected cell(s) by double-clicking cross-hair cursor
1473 Extends a current selection down to the last non-empty cell of an adjacent
1474 column when the lower-right corner of the selection is double-clicked. It
1475 uses a left-adjoining non-empty column as a guide if such is available,
1476 otherwise a right-adjoining non-empty column is used.
1478 @author Kohei Yoshida (kohei@openoffice.org)
1480 @return No return value
1482 @see #i12313#
1484 void ScViewFunc::FillCrossDblClick()
1486 ScRange aRange;
1487 GetViewData()->GetSimpleArea( aRange );
1488 aRange.Justify();
1490 SCTAB nTab = GetViewData()->GetCurPos().Tab();
1491 SCCOL nStartX = aRange.aStart.Col();
1492 SCROW nStartY = aRange.aStart.Row();
1493 SCCOL nEndX = aRange.aEnd.Col();
1494 SCROW nEndY = aRange.aEnd.Row();
1496 ScDocument* pDoc = GetViewData()->GetDocument();
1498 // Make sure the selection is not empty
1499 if ( pDoc->IsBlockEmpty( nTab, nStartX, nStartY, nEndX, nEndY ) )
1500 return;
1502 if ( nEndY < MAXROW )
1504 if ( nStartX > 0 )
1506 SCCOL nMovX = nStartX - 1;
1507 SCROW nMovY = nStartY;
1509 if ( pDoc->HasData( nMovX, nStartY, nTab ) &&
1510 pDoc->HasData( nMovX, nStartY + 1, nTab ) )
1512 pDoc->FindAreaPos( nMovX, nMovY, nTab, 0, 1 );
1514 if ( nMovY > nEndY )
1516 FillAuto( FILL_TO_BOTTOM, nStartX, nStartY, nEndX, nEndY,
1517 nMovY - nEndY );
1518 return;
1523 if ( nEndX < MAXCOL )
1525 SCCOL nMovX = nEndX + 1;
1526 SCROW nMovY = nStartY;
1528 if ( pDoc->HasData( nMovX, nStartY, nTab ) &&
1529 pDoc->HasData( nMovX, nStartY + 1, nTab ) )
1531 pDoc->FindAreaPos( nMovX, nMovY, nTab, 0, 1 );
1533 if ( nMovY > nEndY )
1535 FillAuto( FILL_TO_BOTTOM, nStartX, nStartY, nEndX, nEndY,
1536 nMovY - nEndY );
1537 return;
1544 //----------------------------------------------------------------------------
1546 void ScViewFunc::TransliterateText( sal_Int32 nType )
1548 ScMarkData aFuncMark = GetViewData()->GetMarkData();
1549 if ( !aFuncMark.IsMarked() && !aFuncMark.IsMultiMarked() )
1551 // no selection -> use cursor position
1553 ScAddress aCursor( GetViewData()->GetCurX(), GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
1554 aFuncMark.SetMarkArea( ScRange( aCursor ) );
1557 BOOL bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
1558 TransliterateText( aFuncMark, nType, TRUE, FALSE );
1559 if (bSuccess)
1561 GetViewData()->GetViewShell()->UpdateInputHandler();
1565 //----------------------------------------------------------------------------
1566 // AutoFormat
1568 ScAutoFormatData* ScViewFunc::CreateAutoFormatData()
1570 ScAutoFormatData* pData = NULL;
1571 SCCOL nStartCol;
1572 SCROW nStartRow;
1573 SCTAB nStartTab;
1574 SCCOL nEndCol;
1575 SCROW nEndRow;
1576 SCTAB nEndTab;
1577 if (GetViewData()->GetSimpleArea(nStartCol,nStartRow,nStartTab,nEndCol,nEndRow,nEndTab) == SC_MARK_SIMPLE)
1579 if ( nEndCol-nStartCol >= 3 && nEndRow-nStartRow >= 3 )
1581 ScDocument* pDoc = GetViewData()->GetDocument();
1582 pData = new ScAutoFormatData;
1583 pDoc->GetAutoFormatData( nStartTab, nStartCol,nStartRow,nEndCol,nEndRow, *pData );
1586 return pData;
1590 //----------------------------------------------------------------------------
1592 void ScViewFunc::AutoFormat( USHORT nFormatNo, BOOL bRecord )
1594 #if 1
1596 ScRange aRange;
1597 if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
1599 ScDocShell* pDocSh = GetViewData()->GetDocShell();
1600 ScMarkData& rMark = GetViewData()->GetMarkData();
1602 BOOL bSuccess = pDocSh->GetDocFunc().AutoFormat( aRange, &rMark, nFormatNo, bRecord, FALSE );
1603 if (bSuccess)
1604 pDocSh->UpdateOle(GetViewData());
1606 else
1607 ErrorMessage(STR_NOMULTISELECT);
1609 #else
1611 // nur wegen Matrix nicht editierbar? Attribute trotzdem ok
1612 BOOL bOnlyNotBecauseOfMatrix;
1613 if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
1615 ErrorMessage(STR_PROTECTIONERR);
1616 return;
1619 SCCOL nStartCol;
1620 SCROW nStartRow;
1621 SCTAB nStartTab;
1622 SCCOL nEndCol;
1623 SCROW nEndRow;
1624 SCTAB nEndTab;
1626 if (GetViewData()->GetSimpleArea(nStartCol,nStartRow,nStartTab,nEndCol,nEndRow,nEndTab) == SC_MARK_SIMPLE)
1628 ScDocShell* pDocSh = GetViewData()->GetDocShell();
1629 ScDocument* pDoc = pDocSh->GetDocument();
1630 ScMarkData& rMark = GetViewData()->GetMarkData();
1631 BOOL bSize = (*ScGlobal::GetAutoFormat())[nFormatNo]->GetIncludeWidthHeight();
1632 if (bRecord && !pDoc->IsUndoEnabled())
1633 bRecord = FALSE;
1635 ScDocument* pUndoDoc = NULL;
1636 if ( bRecord )
1638 pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
1639 pUndoDoc->InitUndo( pDoc, nStartTab, nEndTab, bSize, bSize );
1640 pDoc->CopyToDocument( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab,
1641 IDF_ATTRIB, FALSE, pUndoDoc );
1642 if (bSize)
1644 pDoc->CopyToDocument( nStartCol,0,nStartTab, nEndCol,MAXROW,nEndTab,
1645 IDF_NONE, FALSE, pUndoDoc );
1646 pDoc->CopyToDocument( 0,nStartRow,nStartTab, MAXCOL,nEndRow,nEndTab,
1647 IDF_NONE, FALSE, pUndoDoc );
1649 pDoc->BeginDrawUndo();
1652 GetFrameWin()->EnterWait();
1653 pDoc->AutoFormat( nStartCol, nStartRow, nEndCol, nEndRow, nFormatNo, rMark );
1654 GetFrameWin()->LeaveWait();
1656 if (bSize)
1658 SetMarkedWidthOrHeight( TRUE, SC_SIZE_VISOPT, STD_EXTRA_WIDTH, FALSE, FALSE );
1659 SetMarkedWidthOrHeight( FALSE, SC_SIZE_VISOPT, 0, FALSE, FALSE );
1660 pDocSh->PostPaint( 0,0,nStartTab, MAXCOL,MAXROW,nStartTab,
1661 PAINT_GRID | PAINT_LEFT | PAINT_TOP );
1663 else
1665 BOOL bAdj = AdjustBlockHeight( FALSE );
1666 if (bAdj)
1667 pDocSh->PostPaint( 0,nStartRow,nStartTab, MAXCOL,MAXROW,nStartTab,
1668 PAINT_GRID | PAINT_LEFT );
1669 else
1670 pDocSh->PostPaint( nStartCol, nStartRow, nStartTab,
1671 nEndCol, nEndRow, nEndTab, PAINT_GRID );
1674 if ( bRecord ) // Draw-Undo erst jetzt verfuegbar
1676 pDocSh->GetUndoManager()->AddUndoAction(
1677 new ScUndoAutoFormat( pDocSh,
1678 ScRange(nStartCol,nStartRow,nStartTab, nEndCol,nEndRow,nEndTab),
1679 pUndoDoc, rMark, bSize, nFormatNo ) );
1682 pDocSh->UpdateOle(GetViewData());
1683 pDocSh->SetDocumentModified();
1685 else
1686 ErrorMessage(STR_NOMULTISELECT);
1688 #endif
1692 //----------------------------------------------------------------------------
1693 // Suchen & Ersetzen
1695 void ScViewFunc::SearchAndReplace( const SvxSearchItem* pSearchItem,
1696 BOOL bAddUndo, BOOL bIsApi )
1698 ScDocShell* pDocSh = GetViewData()->GetDocShell();
1699 ScDocument* pDoc = pDocSh->GetDocument();
1700 ScMarkData& rMark = GetViewData()->GetMarkData();
1701 if (bAddUndo && !pDoc->IsUndoEnabled())
1702 bAddUndo = FALSE;
1704 SCCOL nCol = GetViewData()->GetCurX();
1705 SCROW nRow = GetViewData()->GetCurY();
1706 SCTAB nTab = GetViewData()->GetTabNo();
1707 // BOOL bAttrib = pSearchItem->GetPattern();
1708 USHORT nCommand = pSearchItem->GetCommand();
1709 BOOL bAllTables = pSearchItem->IsAllTables();
1710 BOOL* pOldSelectedTables = NULL;
1711 USHORT nOldSelectedCount = 0;
1712 SCTAB nOldTab = nTab;
1713 SCTAB nLastTab = pDoc->GetTableCount() - 1;
1714 SCTAB nStartTab, nEndTab;
1715 if ( bAllTables )
1717 nStartTab = 0;
1718 nEndTab = nLastTab;
1719 pOldSelectedTables = new BOOL [ nEndTab + 1 ];
1720 for ( SCTAB j = 0; j <= nEndTab; j++ )
1722 pOldSelectedTables[j] = rMark.GetTableSelect( j );
1723 if ( pOldSelectedTables[j] )
1724 ++nOldSelectedCount;
1727 else
1728 { //! mindestens eine ist immer selektiert
1729 nStartTab = nEndTab = rMark.GetFirstSelected();
1730 for ( SCTAB j = nStartTab + 1; j <= nLastTab; j++ )
1732 if ( rMark.GetTableSelect( j ) )
1733 nEndTab = j;
1737 if ( nCommand == SVX_SEARCHCMD_REPLACE
1738 || nCommand == SVX_SEARCHCMD_REPLACE_ALL )
1740 for ( SCTAB j = nStartTab; j <= nEndTab; j++ )
1742 if ( (bAllTables || rMark.GetTableSelect( j )) &&
1743 pDoc->IsTabProtected( j ) )
1745 if ( pOldSelectedTables )
1746 delete [] pOldSelectedTables;
1747 ErrorMessage(STR_PROTECTIONERR);
1748 return;
1753 if ( nCommand == SVX_SEARCHCMD_FIND
1754 || nCommand == SVX_SEARCHCMD_FIND_ALL)
1755 bAddUndo = FALSE;
1757 //! bAttrib bei Undo beruecksichtigen !!!
1759 ScDocument* pUndoDoc = NULL;
1760 ScMarkData* pUndoMark = NULL;
1761 String aUndoStr;
1762 if (bAddUndo)
1764 pUndoMark = new ScMarkData( rMark ); // Markierung wird veraendert
1765 if ( nCommand == SVX_SEARCHCMD_REPLACE_ALL )
1767 pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
1768 pUndoDoc->InitUndo( pDoc, nStartTab, nEndTab );
1772 if ( bAllTables )
1773 { //! alles selektieren, erst nachdem pUndoMark erzeugt wurde
1774 for ( SCTAB j = nStartTab; j <= nEndTab; j++ )
1776 rMark.SelectTable( j, TRUE );
1780 DoneBlockMode(TRUE); // Markierung nicht loeschen!
1781 InitOwnBlockMode();
1783 // wenn vom Anfang an gesucht wird, nicht nochmal fragen ob vom Anfang gesucht werden soll
1784 BOOL bFirst = TRUE;
1785 if ( nCol == 0 && nRow == 0 && nTab == nStartTab && !pSearchItem->GetBackward() )
1786 bFirst = FALSE;
1788 BOOL bFound = FALSE;
1789 while (TRUE)
1791 GetFrameWin()->EnterWait();
1792 if (pDoc->SearchAndReplace( *pSearchItem, nCol, nRow, nTab, rMark, aUndoStr, pUndoDoc ) )
1794 bFound = TRUE;
1795 bFirst = TRUE;
1796 if (bAddUndo)
1798 GetViewData()->GetDocShell()->GetUndoManager()->AddUndoAction(
1799 new ScUndoReplace( GetViewData()->GetDocShell(), *pUndoMark,
1800 nCol, nRow, nTab,
1801 aUndoStr, pUndoDoc, pSearchItem ) );
1802 pUndoDoc = NULL;
1805 break; // Abbruch while True
1807 else if ( bFirst && (nCommand == SVX_SEARCHCMD_FIND ||
1808 nCommand == SVX_SEARCHCMD_REPLACE) )
1810 bFirst = FALSE;
1811 USHORT nRetVal;
1812 GetFrameWin()->LeaveWait();
1813 if ( bIsApi )
1814 nRetVal = RET_NO;
1815 else
1817 // Suchen-Dialog als Parent, wenn vorhanden
1818 Window* pParent = GetParentOrChild(SID_SEARCH_DLG);
1819 USHORT nStrId;
1820 if ( pSearchItem->GetBackward() )
1822 if ( nStartTab == nEndTab )
1823 nStrId = STR_MSSG_SEARCHANDREPLACE_1;
1824 else
1825 nStrId = STR_MSSG_SEARCHANDREPLACE_4;
1827 else
1829 if ( nStartTab == nEndTab )
1830 nStrId = STR_MSSG_SEARCHANDREPLACE_2;
1831 else
1832 nStrId = STR_MSSG_SEARCHANDREPLACE_5;
1834 MessBox aBox( pParent, WinBits(WB_YES_NO | WB_DEF_YES),
1835 ScGlobal::GetRscString( STR_MSSG_SEARCHANDREPLACE_3 ),
1836 ScGlobal::GetRscString( nStrId ) );
1837 nRetVal = aBox.Execute();
1840 if ( nRetVal == RET_YES )
1842 ScDocument::GetSearchAndReplaceStart( *pSearchItem, nCol, nRow );
1843 if (pSearchItem->GetBackward())
1844 nTab = nEndTab;
1845 else
1846 nTab = nStartTab;
1848 else
1850 break; // Abbruch while True
1853 else // nichts gefunden
1855 if ( nCommand == SVX_SEARCHCMD_FIND_ALL || nCommand == SVX_SEARCHCMD_REPLACE_ALL )
1857 pDocSh->PostPaintGridAll(); // Markierung
1860 GetFrameWin()->LeaveWait();
1861 if (!bIsApi)
1863 // Suchen-Dialog als Parent, wenn vorhanden
1864 Window* pParent = GetParentOrChild(SID_SEARCH_DLG);
1865 // "nichts gefunden"
1866 InfoBox aBox( pParent, ScGlobal::GetRscString( STR_MSSG_SEARCHANDREPLACE_0 ) );
1867 aBox.Execute();
1870 break; // Abbruch while True
1872 } // of while TRUE
1874 if ( pOldSelectedTables )
1875 { // urspruenglich selektierte Tabellen wiederherstellen
1876 for ( SCTAB j = nStartTab; j <= nEndTab; j++ )
1878 rMark.SelectTable( j, pOldSelectedTables[j] );
1880 if ( bFound )
1881 { // durch Fundstelle neu selektierte Tabelle bleibt
1882 rMark.SelectTable( nTab, TRUE );
1883 // wenn vorher nur eine selektiert war, ist es ein Tausch
1884 //! wenn nicht, ist jetzt evtl. eine mehr selektiert
1885 if ( nOldSelectedCount == 1 && nTab != nOldTab )
1886 rMark.SelectTable( nOldTab, FALSE );
1888 delete [] pOldSelectedTables;
1891 MarkDataChanged();
1893 if ( bFound )
1895 if ( nTab != GetViewData()->GetTabNo() )
1896 SetTabNo( nTab );
1898 // wenn nichts markiert ist, DoneBlockMode, damit von hier aus
1899 // direkt per Shift-Cursor markiert werden kann:
1900 if (!rMark.IsMarked() && !rMark.IsMultiMarked())
1901 DoneBlockMode(TRUE);
1903 AlignToCursor( nCol, nRow, SC_FOLLOW_JUMP );
1904 SetCursor( nCol, nRow, TRUE );
1906 if ( nCommand == SVX_SEARCHCMD_REPLACE
1907 || nCommand == SVX_SEARCHCMD_REPLACE_ALL )
1909 if ( nCommand == SVX_SEARCHCMD_REPLACE )
1910 pDocSh->PostPaint( nCol,nRow,nTab, nCol,nRow,nTab, PAINT_GRID );
1911 else
1912 pDocSh->PostPaintGridAll();
1913 pDocSh->SetDocumentModified();
1915 else if ( nCommand == SVX_SEARCHCMD_FIND_ALL )
1916 pDocSh->PostPaintGridAll(); // Markierung
1917 GetFrameWin()->LeaveWait();
1920 delete pUndoDoc; // loeschen wenn nicht benutzt
1921 delete pUndoMark; // kann immer geloescht werden
1925 //----------------------------------------------------------------------------
1926 // Zielwertsuche
1928 void ScViewFunc::Solve( const ScSolveParam& rParam )
1930 ScDocument* pDoc = GetViewData()->GetDocument();
1932 SCCOL nDestCol = rParam.aRefVariableCell.Col();
1933 SCROW nDestRow = rParam.aRefVariableCell.Row();
1934 SCTAB nDestTab = rParam.aRefVariableCell.Tab();
1936 ScEditableTester aTester( pDoc, nDestTab, nDestCol,nDestRow, nDestCol,nDestRow );
1937 if (!aTester.IsEditable())
1939 ErrorMessage(aTester.GetMessageId());
1940 return;
1943 if ( pDoc )
1945 String aTargetValStr;
1946 if ( rParam.pStrTargetVal != NULL )
1947 aTargetValStr = *(rParam.pStrTargetVal);
1949 String aMsgStr;
1950 String aResStr;
1951 double nSolveResult;
1953 GetFrameWin()->EnterWait();
1955 BOOL bExact =
1956 pDoc->Solver(
1957 rParam.aRefFormulaCell.Col(),
1958 rParam.aRefFormulaCell.Row(),
1959 rParam.aRefFormulaCell.Tab(),
1960 nDestCol, nDestRow, nDestTab,
1961 aTargetValStr,
1962 nSolveResult );
1964 GetFrameWin()->LeaveWait();
1966 SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
1967 ULONG nFormat = 0;
1968 const ScPatternAttr* pPattern = pDoc->GetPattern( nDestCol, nDestRow, nDestTab );
1969 if ( pPattern )
1970 nFormat = pPattern->GetNumberFormat( pFormatter );
1971 Color* p;
1972 pFormatter->GetOutputString( nSolveResult, nFormat, aResStr, &p );
1974 if ( bExact )
1976 aMsgStr = ScGlobal::GetRscString( STR_MSSG_SOLVE_0 );
1977 aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_1 );
1978 aMsgStr += String( aResStr );
1979 aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_2 );
1981 else
1983 aMsgStr = ScGlobal::GetRscString( STR_MSSG_SOLVE_3 );
1984 aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_4 );
1985 aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_5 );
1986 aMsgStr += String( aResStr );
1987 aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_6 );
1990 MessBox aBox( GetViewData()->GetDialogParent(),
1991 WinBits(WB_YES_NO | WB_DEF_NO),
1992 ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_0 ), aMsgStr );
1993 USHORT nRetVal = aBox.Execute();
1995 if ( RET_YES == nRetVal )
1996 EnterValue( nDestCol, nDestRow, nDestTab, nSolveResult );
1998 GetViewData()->GetViewShell()->UpdateInputHandler( TRUE );
2003 //----------------------------------------------------------------------------
2004 // Mehrfachoperation
2006 void ScViewFunc::TabOp( const ScTabOpParam& rParam, BOOL bRecord )
2008 ScRange aRange;
2009 if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
2011 ScDocShell* pDocSh = GetViewData()->GetDocShell();
2012 ScMarkData& rMark = GetViewData()->GetMarkData();
2013 pDocSh->GetDocFunc().TabOp( aRange, &rMark, rParam, bRecord, FALSE );
2015 else
2016 ErrorMessage(STR_NOMULTISELECT);
2020 //----------------------------------------------------------------------------
2022 void ScViewFunc::MakeScenario( const String& rName, const String& rComment,
2023 const Color& rColor, USHORT nFlags )
2025 ScDocShell* pDocSh = GetViewData()->GetDocShell();
2026 ScMarkData& rMark = GetViewData()->GetMarkData();
2027 SCTAB nTab = GetViewData()->GetTabNo();
2029 SCTAB nNewTab = pDocSh->MakeScenario( nTab, rName, rComment, rColor, nFlags, rMark );
2030 if (nFlags & SC_SCENARIO_COPYALL)
2031 SetTabNo( nNewTab, TRUE ); // SC_SCENARIO_COPYALL -> sichtbar
2032 else
2034 SfxBindings& rBindings = GetViewData()->GetBindings();
2035 rBindings.Invalidate( SID_STATUS_DOCPOS ); // Statusbar
2036 rBindings.Invalidate( SID_TABLES_COUNT );
2037 rBindings.Invalidate( SID_SELECT_SCENARIO );
2038 rBindings.Invalidate( FID_TABLE_SHOW );
2043 //----------------------------------------------------------------------------
2045 void ScViewFunc::ExtendScenario()
2047 ScEditableTester aTester( this );
2048 if (!aTester.IsEditable())
2050 ErrorMessage(aTester.GetMessageId());
2051 return;
2054 // Undo: Attribute anwenden
2056 ScDocument* pDoc = GetViewData()->GetDocument();
2057 ScPatternAttr aPattern( pDoc->GetPool() );
2058 aPattern.GetItemSet().Put( ScMergeFlagAttr( SC_MF_SCENARIO ) );
2059 aPattern.GetItemSet().Put( ScProtectionAttr( TRUE ) );
2060 ApplySelectionPattern(aPattern);
2064 //----------------------------------------------------------------------------
2066 void ScViewFunc::UseScenario( const String& rName )
2068 ScDocShell* pDocSh = GetViewData()->GetDocShell();
2069 SCTAB nTab = GetViewData()->GetTabNo();
2071 DoneBlockMode();
2072 InitOwnBlockMode();
2073 pDocSh->UseScenario( nTab, rName );
2077 //----------------------------------------------------------------------------
2078 // Tabelle einfuegen
2080 BOOL ScViewFunc::InsertTable( const String& rName, SCTAB nTab, BOOL bRecord )
2082 // Reihenfolge Tabelle/Name ist bei DocFunc umgekehrt
2083 BOOL bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
2084 InsertTable( nTab, rName, bRecord, FALSE );
2085 if (bSuccess)
2086 SetTabNo( nTab, TRUE );
2088 return bSuccess;
2091 //----------------------------------------------------------------------------
2092 // Tabellen einfuegen
2094 BOOL ScViewFunc::InsertTables(SvStrings *pNames, SCTAB nTab,
2095 SCTAB nCount, BOOL bRecord )
2097 ScDocShell* pDocSh = GetViewData()->GetDocShell();
2098 ScDocument* pDoc = pDocSh->GetDocument();
2099 if (bRecord && !pDoc->IsUndoEnabled())
2100 bRecord = FALSE;
2102 SvStrings *pNameList= NULL;
2104 WaitObject aWait( GetFrameWin() );
2106 if (bRecord)
2108 pNameList= new SvStrings;
2109 pDoc->BeginDrawUndo(); // InsertTab erzeugt ein SdrUndoNewPage
2112 BOOL bFlag=FALSE;
2114 String aValTabName;
2115 String *pStr;
2117 for(SCTAB i=0;i<nCount;i++)
2119 if(pNames!=NULL)
2121 pStr=pNames->GetObject(static_cast<USHORT>(i));
2123 else
2125 aValTabName.Erase();
2126 pDoc->CreateValidTabName( aValTabName);
2127 pStr=&aValTabName;
2130 if(pDoc->InsertTab( nTab+i,*pStr))
2132 bFlag=TRUE;
2133 pDocSh->Broadcast( ScTablesHint( SC_TAB_INSERTED, nTab+i ) );
2135 else
2137 break;
2140 if(pNameList!=NULL)
2141 pNameList->Insert(new String(*pStr),pNameList->Count());
2145 if (bFlag)
2147 if (bRecord)
2148 pDocSh->GetUndoManager()->AddUndoAction(
2149 new ScUndoInsertTables( pDocSh, nTab, FALSE, pNameList));
2151 // Views updaten:
2153 SetTabNo( nTab, TRUE );
2154 pDocSh->PostPaintExtras();
2155 pDocSh->SetDocumentModified();
2156 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
2157 return TRUE;
2159 else
2161 return FALSE;
2166 //----------------------------------------------------------------------------
2168 BOOL ScViewFunc::AppendTable( const String& rName, BOOL bRecord )
2170 ScDocShell* pDocSh = GetViewData()->GetDocShell();
2171 ScDocument* pDoc = pDocSh->GetDocument();
2172 if (bRecord && !pDoc->IsUndoEnabled())
2173 bRecord = FALSE;
2175 WaitObject aWait( GetFrameWin() );
2177 if (bRecord)
2178 pDoc->BeginDrawUndo(); // InsertTab erzeugt ein SdrUndoNewPage
2180 if (pDoc->InsertTab( SC_TAB_APPEND, rName ))
2182 SCTAB nTab = pDoc->GetTableCount()-1;
2183 if (bRecord)
2184 pDocSh->GetUndoManager()->AddUndoAction(
2185 new ScUndoInsertTab( pDocSh, nTab, TRUE, rName));
2186 GetViewData()->InsertTab( nTab );
2187 SetTabNo( nTab, TRUE );
2188 pDocSh->PostPaintExtras();
2189 pDocSh->SetDocumentModified();
2190 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
2191 return TRUE;
2193 else
2195 return FALSE;
2200 //----------------------------------------------------------------------------
2202 BOOL ScViewFunc::DeleteTable( SCTAB nTab, BOOL bRecord )
2204 ScDocShell* pDocSh = GetViewData()->GetDocShell();
2205 ScDocument* pDoc = pDocSh->GetDocument();
2207 BOOL bSuccess = pDocSh->GetDocFunc().DeleteTable( nTab, bRecord, FALSE );
2208 if (bSuccess)
2210 SCTAB nNewTab = nTab;
2211 if ( nNewTab >= pDoc->GetTableCount() )
2212 --nNewTab;
2213 SetTabNo( nNewTab, TRUE );
2215 return bSuccess;
2218 void lcl_DeleteModule( ScDocShell* rDocSh, String& sModuleName )
2220 SFX_APP()->EnterBasicCall();
2221 uno::Reference< script::XLibraryContainer > xLibContainer = rDocSh->GetBasicContainer();
2222 DBG_ASSERT( xLibContainer.is(), "No BasicContainer!" );
2224 uno::Reference< container::XNameContainer > xLib;
2225 if( xLibContainer.is() )
2227 String aLibName( RTL_CONSTASCII_USTRINGPARAM( "Standard" ) );
2228 uno::Any aLibAny = xLibContainer->getByName( aLibName );
2229 aLibAny >>= xLib;
2231 if( xLib.is() )
2233 if( xLib->hasByName( sModuleName ) )
2235 xLib->removeByName( sModuleName );
2238 SFX_APP()->LeaveBasicCall();
2241 BOOL ScViewFunc::DeleteTables(const SvShorts &TheTabs, BOOL bRecord )
2243 ScDocShell* pDocSh = GetViewData()->GetDocShell();
2244 ScDocument* pDoc = pDocSh->GetDocument();
2245 StarBASIC* pStarBASIC = pDocSh->GetBasic();
2246 BOOL bVbaEnabled = pStarBASIC->isVBAEnabled();
2247 SCTAB nNewTab = TheTabs[0];
2248 int i;
2249 WaitObject aWait( GetFrameWin() );
2250 if (bRecord && !pDoc->IsUndoEnabled())
2251 bRecord = FALSE;
2252 if ( bVbaEnabled )
2253 bRecord = FALSE;
2255 while ( nNewTab > 0 && !pDoc->IsVisible( nNewTab ) )
2256 --nNewTab;
2258 BOOL bWasLinked = FALSE;
2259 ScDocument* pUndoDoc = NULL;
2260 ScRefUndoData* pUndoData = NULL;
2261 if (bRecord)
2263 pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
2264 // pUndoDoc->InitDrawLayer( pDocSh );
2265 SCTAB nCount = pDoc->GetTableCount();
2267 // pUndoDoc->InitUndo( pDoc, 0, nCount-1 ); // incl. Ref.
2269 String aOldName;
2270 for(i=0;i<TheTabs.Count();i++)
2272 SCTAB nTab = TheTabs[sal::static_int_cast<USHORT>(i)];
2273 if (i==0)
2274 pUndoDoc->InitUndo( pDoc, nTab,nTab, TRUE,TRUE ); // incl. Spalten/Zeilenflags
2275 else
2276 pUndoDoc->AddUndoTab( nTab,nTab, TRUE,TRUE ); // incl. Spalten/Zeilenflags
2278 pDoc->CopyToDocument(0,0,nTab, MAXCOL,MAXROW,nTab, IDF_ALL,FALSE, pUndoDoc );
2279 pDoc->GetName( nTab, aOldName );
2280 pUndoDoc->RenameTab( nTab, aOldName, FALSE );
2281 if (pDoc->IsLinked(nTab))
2283 bWasLinked = TRUE;
2284 pUndoDoc->SetLink( nTab, pDoc->GetLinkMode(nTab), pDoc->GetLinkDoc(nTab),
2285 pDoc->GetLinkFlt(nTab), pDoc->GetLinkOpt(nTab),
2286 pDoc->GetLinkTab(nTab),
2287 pDoc->GetLinkRefreshDelay(nTab) );
2289 if ( pDoc->IsScenario(nTab) )
2291 pUndoDoc->SetScenario( nTab, TRUE );
2292 String aComment;
2293 Color aColor;
2294 USHORT nScenFlags;
2295 pDoc->GetScenarioData( nTab, aComment, aColor, nScenFlags );
2296 pUndoDoc->SetScenarioData( nTab, aComment, aColor, nScenFlags );
2297 BOOL bActive = pDoc->IsActiveScenario( nTab );
2298 pUndoDoc->SetActiveScenario( nTab, bActive );
2300 pUndoDoc->SetVisible( nTab, pDoc->IsVisible( nTab ) );
2302 if ( pDoc->IsTabProtected( nTab ) )
2303 pUndoDoc->SetTabProtection(nTab, pDoc->GetTabProtection(nTab));
2305 // Drawing-Layer muss sein Undo selbst in der Hand behalten !!!
2306 // pUndoDoc->TransferDrawPage(pDoc, nTab,nTab);
2309 pUndoDoc->AddUndoTab( 0, nCount-1 ); // alle Tabs fuer Referenzen
2311 pDoc->BeginDrawUndo(); // DeleteTab erzeugt ein SdrUndoDelPage
2313 pUndoData = new ScRefUndoData( pDoc );
2316 BOOL bDelDone = FALSE;
2318 for(i=TheTabs.Count()-1;i>=0;i--)
2320 String sCodeName;
2321 BOOL bHasCodeName = pDoc->GetCodeName( TheTabs[sal::static_int_cast<USHORT>(i)], sCodeName );
2322 if (pDoc->DeleteTab( TheTabs[sal::static_int_cast<USHORT>(i)], pUndoDoc ))
2324 bDelDone = TRUE;
2325 if( bVbaEnabled )
2327 if( bHasCodeName )
2329 lcl_DeleteModule( pDocSh, sCodeName );
2332 pDocSh->Broadcast( ScTablesHint( SC_TAB_DELETED, TheTabs[sal::static_int_cast<USHORT>(i)] ) );
2335 if (bRecord)
2337 pDocSh->GetUndoManager()->AddUndoAction(
2338 new ScUndoDeleteTab( GetViewData()->GetDocShell(), TheTabs,
2339 pUndoDoc, pUndoData ));
2343 if (bDelDone)
2345 if ( nNewTab >= pDoc->GetTableCount() )
2346 nNewTab = pDoc->GetTableCount() - 1;
2348 SetTabNo( nNewTab, TRUE );
2350 if (bWasLinked)
2352 pDocSh->UpdateLinks(); // Link-Manager updaten
2353 GetViewData()->GetBindings().Invalidate(SID_LINKS);
2356 pDocSh->PostPaintExtras();
2357 pDocSh->SetDocumentModified();
2360 SfxApplication* pSfxApp = SFX_APP(); // Navigator
2361 pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
2362 pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_DBAREAS_CHANGED ) );
2363 pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
2365 else
2367 delete pUndoDoc;
2368 delete pUndoData;
2370 return bDelDone;
2374 //----------------------------------------------------------------------------
2376 BOOL ScViewFunc::RenameTable( const String& rName, SCTAB nTab )
2378 // Reihenfolge Tabelle/Name ist bei DocFunc umgekehrt
2379 BOOL bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
2380 RenameTable( nTab, rName, TRUE, FALSE );
2381 if (bSuccess)
2383 // Der Tabellenname koennte in einer Formel vorkommen...
2384 GetViewData()->GetViewShell()->UpdateInputHandler();
2386 return bSuccess;
2390 //----------------------------------------------------------------------------
2392 BOOL ScViewFunc::SetTabBgColor( const Color& rColor, SCTAB nTab )
2394 BOOL bSuccess = GetViewData()->GetDocShell()->GetDocFunc().SetTabBgColor( nTab, rColor, TRUE, FALSE );
2395 if (bSuccess)
2397 GetViewData()->GetViewShell()->UpdateInputHandler();
2399 return bSuccess;
2402 BOOL ScViewFunc::SetTabBgColor( ScUndoSetTabBgColorInfoList* rUndoSetTabBgColorInfoList )
2404 BOOL bSuccess = GetViewData()->GetDocShell()->GetDocFunc().SetTabBgColor( rUndoSetTabBgColorInfoList, TRUE, FALSE );
2405 if (bSuccess)
2407 GetViewData()->GetViewShell()->UpdateInputHandler();
2409 return bSuccess;
2412 //----------------------------------------------------------------------------
2414 void ScViewFunc::InsertAreaLink( const String& rFile,
2415 const String& rFilter, const String& rOptions,
2416 const String& rSource, ULONG nRefresh )
2418 ScDocShell* pDocSh = GetViewData()->GetDocShell();
2419 SCCOL nPosX = GetViewData()->GetCurX();
2420 SCROW nPosY = GetViewData()->GetCurY();
2421 SCTAB nTab = GetViewData()->GetTabNo();
2422 ScAddress aPos( nPosX, nPosY, nTab );
2424 pDocSh->GetDocFunc().InsertAreaLink( rFile, rFilter, rOptions, rSource, aPos, nRefresh, FALSE, FALSE );
2428 //----------------------------------------------------------------------------
2430 void ScViewFunc::InsertTableLink( const String& rFile,
2431 const String& rFilter, const String& rOptions,
2432 const String& rTabName )
2434 String aFilterName = rFilter;
2435 String aOpt = rOptions;
2436 ScDocumentLoader aLoader( rFile, aFilterName, aOpt );
2437 if (!aLoader.IsError())
2439 ScDocShell* pSrcSh = aLoader.GetDocShell();
2440 ScDocument* pSrcDoc = pSrcSh->GetDocument();
2441 SCTAB nTab = MAXTAB+1;
2442 if (!rTabName.Len()) // kein Name angegeben -> erste Tabelle
2443 nTab = 0;
2444 else
2446 String aTemp;
2447 SCTAB nCount = pSrcDoc->GetTableCount();
2448 for (SCTAB i=0; i<nCount; i++)
2450 pSrcDoc->GetName( i, aTemp );
2451 if ( aTemp == rTabName )
2452 nTab = i;
2456 if ( nTab <= MAXTAB )
2457 ImportTables( pSrcSh, 1, &nTab, TRUE,
2458 GetViewData()->GetTabNo() );
2463 //----------------------------------------------------------------------------
2464 // Tabellen aus anderem Dokument kopieren / linken
2466 void ScViewFunc::ImportTables( ScDocShell* pSrcShell,
2467 SCTAB nCount, const SCTAB* pSrcTabs, BOOL bLink,SCTAB nTab )
2469 ScDocument* pSrcDoc = pSrcShell->GetDocument();
2471 ScDocShell* pDocSh = GetViewData()->GetDocShell();
2472 ScDocument* pDoc = pDocSh->GetDocument();
2473 BOOL bUndo(pDoc->IsUndoEnabled());
2474 //SCTAB nTab = GetViewData()->GetTabNo();
2476 BOOL bError = FALSE;
2477 BOOL bRefs = FALSE;
2478 BOOL bName = FALSE;
2480 if (pSrcDoc->GetDrawLayer())
2481 pDocSh->MakeDrawLayer();
2483 if (bUndo)
2484 pDoc->BeginDrawUndo(); // drawing layer must do its own undo actions
2486 SCTAB nInsCount = 0;
2487 SCTAB i;
2488 for( i=0; i<nCount; i++ )
2489 { // #63304# insert sheets first and update all references
2490 String aName;
2491 pSrcDoc->GetName( pSrcTabs[i], aName );
2492 pDoc->CreateValidTabName( aName );
2493 if ( !pDoc->InsertTab( nTab+i, aName ) )
2495 bError = TRUE; // total error
2496 break; // for
2498 ++nInsCount;
2500 for (i=0; i<nCount && !bError; i++)
2502 SCTAB nSrcTab = pSrcTabs[i];
2503 SCTAB nDestTab1=nTab+i;
2504 ULONG nErrVal = pDoc->TransferTab( pSrcDoc, nSrcTab, nDestTab1,
2505 FALSE ); // no insert
2507 switch (nErrVal)
2509 case 0: // interner Fehler oder voll Fehler
2510 bError = TRUE;
2511 break;
2512 case 2:
2513 bRefs = TRUE;
2514 break;
2515 case 3:
2516 bName = TRUE;
2517 break;
2518 case 4:
2519 bRefs = bName = TRUE;
2520 break;
2523 // TransferTab doesn't copy drawing objects with bInsertNew=FALSE
2524 if ( !bError )
2525 pDoc->TransferDrawPage( pSrcDoc, nSrcTab, nDestTab1 );
2527 if(!bError &&pSrcDoc->IsScenario(nSrcTab))
2529 String aComment;
2530 Color aColor;
2531 USHORT nFlags;
2533 pSrcDoc->GetScenarioData(nSrcTab, aComment,aColor, nFlags);
2534 pDoc->SetScenario( nDestTab1,TRUE);
2535 pDoc->SetScenarioData( nTab+i,aComment,aColor,nFlags);
2536 BOOL bActive = pSrcDoc->IsActiveScenario(nSrcTab );
2537 pDoc->SetActiveScenario( nDestTab1, bActive );
2538 BOOL bVisible=pSrcDoc->IsVisible(nSrcTab);
2539 pDoc->SetVisible(nDestTab1,bVisible );
2544 if (bLink)
2546 SvxLinkManager* pLinkManager = pDoc->GetLinkManager();
2548 SfxMedium* pMed = pSrcShell->GetMedium();
2549 String aFileName = pMed->GetName();
2550 String aFilterName;
2551 if (pMed->GetFilter())
2552 aFilterName = pMed->GetFilter()->GetFilterName();
2553 String aOptions = ScDocumentLoader::GetOptions(*pMed);
2555 BOOL bWasThere = pDoc->HasLink( aFileName, aFilterName, aOptions );
2557 ULONG nRefresh = 0;
2558 String aTabStr;
2559 for (i=0; i<nInsCount; i++)
2561 pSrcDoc->GetName( pSrcTabs[i], aTabStr );
2562 pDoc->SetLink( nTab+i, SC_LINK_NORMAL,
2563 aFileName, aFilterName, aOptions, aTabStr, nRefresh );
2566 if (!bWasThere) // Link pro Quelldokument nur einmal eintragen
2568 ScTableLink* pLink = new ScTableLink( pDocSh, aFileName, aFilterName, aOptions, nRefresh );
2569 pLink->SetInCreate( TRUE );
2570 pLinkManager->InsertFileLink( *pLink, OBJECT_CLIENT_FILE, aFileName, &aFilterName );
2571 pLink->Update();
2572 pLink->SetInCreate( FALSE );
2574 SfxBindings& rBindings = GetViewData()->GetBindings();
2575 rBindings.Invalidate( SID_LINKS );
2580 if (bUndo)
2582 pDocSh->GetUndoManager()->AddUndoAction(
2583 new ScUndoImportTab( pDocSh, nTab, nCount, bLink ) );
2586 for (i=0; i<nInsCount; i++)
2587 GetViewData()->InsertTab(nTab);
2588 SetTabNo(nTab,TRUE);
2589 pDocSh->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB,
2590 PAINT_GRID | PAINT_TOP | PAINT_LEFT | PAINT_EXTRAS );
2592 SfxApplication* pSfxApp = SFX_APP();
2593 pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
2594 pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_AREAS_CHANGED ) );
2596 pDocSh->PostPaintExtras();
2597 pDocSh->PostPaintGridAll();
2598 pDocSh->SetDocumentModified();
2600 if (bRefs)
2601 ErrorMessage(STR_ABSREFLOST);
2602 if (bName)
2603 ErrorMessage(STR_NAMECONFLICT);
2607 //----------------------------------------------------------------------------
2608 // Tabelle in anderes Dokument verschieben / kopieren
2610 void ScViewFunc::MoveTable( USHORT nDestDocNo, SCTAB nDestTab, BOOL bCopy )
2612 ScDocument* pDoc = GetViewData()->GetDocument();
2613 ScDocShell* pDocShell = GetViewData()->GetDocShell();
2614 ScDocument* pDestDoc = NULL;
2615 ScDocShell* pDestShell = NULL;
2616 ScTabViewShell* pDestViewSh = NULL;
2617 BOOL bUndo (pDoc->IsUndoEnabled());
2619 BOOL bNewDoc = ( nDestDocNo == SC_DOC_NEW );
2620 if ( bNewDoc )
2622 nDestTab = 0; // als erstes einfuegen
2624 // ohne SFX_CALLMODE_RECORD ausfuehren, weil schon im Move-Befehl enthalten:
2626 String aUrl = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("private:factory/"));
2627 aUrl.AppendAscii(RTL_CONSTASCII_STRINGPARAM( STRING_SCAPP )); // "scalc"
2628 SfxStringItem aItem( SID_FILE_NAME, aUrl );
2629 SfxStringItem aTarget( SID_TARGETNAME, String::CreateFromAscii("_blank") );
2631 const SfxPoolItem* pRetItem = GetViewData()->GetDispatcher().Execute(
2632 SID_OPENDOC, SFX_CALLMODE_API|SFX_CALLMODE_SYNCHRON, &aItem, &aTarget, 0L );
2633 if ( pRetItem )
2635 if ( pRetItem->ISA( SfxObjectItem ) )
2636 pDestShell = PTR_CAST( ScDocShell, ((const SfxObjectItem*)pRetItem)->GetShell() );
2637 else if ( pRetItem->ISA( SfxViewFrameItem ) )
2639 SfxViewFrame* pFrm = ((const SfxViewFrameItem*)pRetItem)->GetFrame();
2640 if (pFrm)
2641 pDestShell = PTR_CAST( ScDocShell, pFrm->GetObjectShell() );
2643 if (pDestShell)
2644 pDestViewSh = pDestShell->GetBestViewShell();
2647 else
2648 pDestShell = ScDocShell::GetShellByNum( nDestDocNo );
2650 if (!pDestShell)
2652 DBG_ERROR("Dest-Doc nicht gefunden !!!");
2653 return;
2656 pDestDoc = pDestShell->GetDocument();
2658 SCTAB nTab = GetViewData()->GetTabNo();
2660 if (pDestDoc != pDoc)
2662 if (bNewDoc)
2664 while (pDestDoc->GetTableCount() > 1)
2665 pDestDoc->DeleteTab(0);
2666 pDestDoc->RenameTab( 0,
2667 String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("______42_____")),
2668 FALSE );
2671 ScMarkData& rMark = GetViewData()->GetMarkData();
2672 SCTAB nTabCount = pDoc->GetTableCount();
2673 SCTAB nTabSelCount = rMark.GetSelectCount();
2675 SvShorts TheTabs;
2677 for(SCTAB i=0;i<nTabCount;i++)
2679 if(rMark.GetTableSelect(i))
2681 String aTabName;
2682 pDoc->GetName( i, aTabName);
2683 TheTabs.Insert(i,TheTabs.Count());
2684 for(SCTAB j=i+1;j<nTabCount;j++)
2686 if((!pDoc->IsVisible(j))&&(pDoc->IsScenario(j)))
2688 pDoc->GetName( j, aTabName);
2689 TheTabs.Insert(j,TheTabs.Count());
2690 i=j;
2692 else break;
2697 GetFrameWin()->EnterWait();
2699 if (pDoc->GetDrawLayer())
2700 pDestShell->MakeDrawLayer();
2702 if (!bNewDoc && bUndo)
2703 pDestDoc->BeginDrawUndo(); // drawing layer must do its own undo actions
2705 ULONG nErrVal =1;
2706 if(nDestTab==SC_TAB_APPEND)
2707 nDestTab=pDestDoc->GetTableCount();
2708 SCTAB nDestTab1=nDestTab;
2709 for( USHORT j=0; j<TheTabs.Count(); j++, nDestTab1++ )
2710 { // #63304# insert sheets first and update all references
2711 String aName;
2712 pDoc->GetName( TheTabs[j], aName );
2713 pDestDoc->CreateValidTabName( aName );
2714 if ( !pDestDoc->InsertTab( nDestTab1, aName ) )
2716 nErrVal = 0; // total error
2717 break; // for
2720 if ( nErrVal > 0 )
2722 nDestTab1 = nDestTab;
2723 for(USHORT i=0;i<TheTabs.Count();i++)
2725 nErrVal = pDestDoc->TransferTab( pDoc, TheTabs[i], nDestTab1,
2726 FALSE ); // no insert
2728 // TransferTab doesn't copy drawing objects with bInsertNew=FALSE
2729 if ( nErrVal > 0 )
2730 pDestDoc->TransferDrawPage( pDoc, TheTabs[i], nDestTab1 );
2732 if(nErrVal>0 && pDoc->IsScenario(TheTabs[i]))
2734 String aComment;
2735 Color aColor;
2736 USHORT nFlags;
2738 pDoc->GetScenarioData(TheTabs[i], aComment,aColor, nFlags);
2739 pDestDoc->SetScenario(nDestTab1,TRUE);
2740 pDestDoc->SetScenarioData(nDestTab1,aComment,aColor,nFlags);
2741 BOOL bActive = pDoc->IsActiveScenario(TheTabs[i]);
2742 pDestDoc->SetActiveScenario(nDestTab1, bActive );
2744 BOOL bVisible=pDoc->IsVisible(TheTabs[i]);
2745 pDestDoc->SetVisible(nDestTab1,bVisible );
2749 if ( nErrVal > 0 && pDoc->IsTabProtected( TheTabs[i] ) )
2750 pDestDoc->SetTabProtection(nDestTab1, pDoc->GetTabProtection(TheTabs[i]));
2752 nDestTab1++;
2755 String sName;
2756 if (!bNewDoc && bUndo)
2758 pDestDoc->GetName(nDestTab, sName);
2759 pDestShell->GetUndoManager()->AddUndoAction(
2760 new ScUndoImportTab( pDestShell, nDestTab,
2761 static_cast<SCTAB>(TheTabs.Count()), FALSE));
2764 else
2766 pDestShell->GetUndoManager()->Clear();
2769 GetFrameWin()->LeaveWait();
2770 switch (nErrVal)
2772 case 0: // interner Fehler oder voll Fehler
2774 ErrorMessage(STR_TABINSERT_ERROR);
2775 return;
2777 //break;
2778 case 2:
2779 ErrorMessage(STR_ABSREFLOST);
2780 break;
2781 case 3:
2782 ErrorMessage(STR_NAMECONFLICT);
2783 break;
2784 case 4:
2786 ErrorMessage(STR_ABSREFLOST);
2787 ErrorMessage(STR_NAMECONFLICT);
2789 break;
2790 default:
2791 break;
2793 //pDestShell->GetUndoManager()->Clear(); //! Undo implementieren !!!
2795 String sName;
2796 pDestDoc->GetName(nDestTab, sName);
2797 pDestShell->GetUndoManager()->AddUndoAction(
2798 new ScUndoInsertTab( pDestShell, nDestTab, TRUE, sName ) );
2800 if (!bCopy)
2802 if(nTabCount!=nTabSelCount)
2803 DeleteTables(TheTabs);// incl. Paint & Undo
2804 else
2805 ErrorMessage(STR_TABREMOVE_ERROR);
2808 if (bNewDoc)
2810 // ChartListenerCollection must be updated before DeleteTab
2811 if ( pDestDoc->IsChartListenerCollectionNeedsUpdate() )
2812 pDestDoc->UpdateChartListenerCollection();
2814 pDestDoc->DeleteTab(static_cast<SCTAB>(TheTabs.Count())); // alte erste Tabelle
2815 //? pDestDoc->SelectTable(0, TRUE); // neue erste Tabelle selektieren
2816 if (pDestViewSh)
2817 pDestViewSh->TabChanged(); // Pages auf dem Drawing-Layer
2818 pDestShell->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB,
2819 PAINT_GRID | PAINT_TOP | PAINT_LEFT |
2820 PAINT_EXTRAS | PAINT_SIZE );
2821 // PAINT_SIZE fuer Gliederung
2823 else
2825 pDestShell->Broadcast( ScTablesHint( SC_TAB_INSERTED, nDestTab ) );
2826 pDestShell->PostPaintExtras();
2827 pDestShell->PostPaintGridAll();
2830 TheTabs.Remove(0,TheTabs.Count());
2832 pDestShell->SetDocumentModified();
2833 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
2835 else // innerhalb des Dokuments
2838 ScMarkData& rMark = GetViewData()->GetMarkData();
2839 SCTAB nTabCount = pDoc->GetTableCount();
2841 SvShorts TheTabs;
2842 SvShorts TheDestTabs;
2843 SvStrings TheTabNames;
2844 String aDestName;
2845 String *pString;
2847 for(SCTAB i=0;i<nTabCount;i++)
2849 if(rMark.GetTableSelect(i))
2851 String aTabName;
2852 pDoc->GetName( i, aTabName);
2853 TheTabNames.Insert(new String(aTabName),TheTabNames.Count());
2855 for(SCTAB j=i+1;j<nTabCount;j++)
2857 if((!pDoc->IsVisible(j))&&(pDoc->IsScenario(j)))
2859 pDoc->GetName( j, aTabName);
2860 TheTabNames.Insert(new String(aTabName),TheTabNames.Count());
2861 i=j;
2863 else break;
2869 if (bCopy && bUndo)
2870 pDoc->BeginDrawUndo(); // drawing layer must do its own undo actions
2872 pDoc->GetName( nDestTab, aDestName);
2873 SCTAB nDestTab1=nDestTab;
2874 SCTAB nMovTab=0;
2875 for(int j=0;j<TheTabNames.Count();j++)
2877 nTabCount = pDoc->GetTableCount();
2878 pString=TheTabNames[sal::static_int_cast<USHORT>(j)];
2879 if(!pDoc->GetTable(*pString,nMovTab))
2881 nMovTab=nTabCount;
2883 if(!pDoc->GetTable(aDestName,nDestTab1))
2885 nDestTab1=nTabCount;
2887 pDocShell->MoveTable( nMovTab, nDestTab1, bCopy, FALSE ); // Undo ist hier
2889 if(bCopy && pDoc->IsScenario(nMovTab))
2891 String aComment;
2892 Color aColor;
2893 USHORT nFlags;
2895 pDoc->GetScenarioData(nMovTab, aComment,aColor, nFlags);
2896 pDoc->SetScenario(nDestTab1,TRUE);
2897 pDoc->SetScenarioData(nDestTab1,aComment,aColor,nFlags);
2898 BOOL bActive = pDoc->IsActiveScenario(nMovTab );
2899 pDoc->SetActiveScenario( nDestTab1, bActive );
2900 BOOL bVisible=pDoc->IsVisible(nMovTab);
2901 pDoc->SetVisible(nDestTab1,bVisible );
2904 TheTabs.Insert(nMovTab,TheTabs.Count());
2906 if(!bCopy)
2908 if(!pDoc->GetTable(*pString,nDestTab1))
2910 nDestTab1=nTabCount;
2914 TheDestTabs.Insert(nDestTab1,TheDestTabs.Count());
2915 delete pString;
2918 nTab = GetViewData()->GetTabNo();
2920 if (bUndo)
2922 if (bCopy)
2924 pDocShell->GetUndoManager()->AddUndoAction(
2925 new ScUndoCopyTab( pDocShell, TheTabs, TheDestTabs));
2927 else
2929 pDocShell->GetUndoManager()->AddUndoAction(
2930 new ScUndoMoveTab( pDocShell, TheTabs, TheDestTabs));
2934 SCTAB nNewTab = nDestTab;
2935 if (nNewTab == SC_TAB_APPEND)
2936 nNewTab = pDoc->GetTableCount()-1;
2937 else if (!bCopy && nTab<nDestTab)
2938 nNewTab--;
2940 SetTabNo( nNewTab, TRUE );
2945 //----------------------------------------------------------------------------
2947 void ScViewFunc::ShowTable( const String& rName )
2949 ScDocShell* pDocSh = GetViewData()->GetDocShell();
2950 ScDocument* pDoc = pDocSh->GetDocument();
2951 BOOL bUndo(pDoc->IsUndoEnabled());
2952 BOOL bFound = FALSE;
2953 SCTAB nPos = 0;
2954 String aTabName;
2955 SCTAB nCount = pDoc->GetTableCount();
2956 for (SCTAB i=0; i<nCount; i++)
2958 pDoc->GetName( i, aTabName );
2959 if ( aTabName == rName )
2961 nPos = i;
2962 bFound = TRUE;
2966 if (bFound)
2968 pDoc->SetVisible( nPos, TRUE );
2969 if (bUndo)
2971 pDocSh->GetUndoManager()->AddUndoAction( new ScUndoShowHideTab( pDocSh, nPos, TRUE ) );
2973 SetTabNo( nPos, TRUE );
2974 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
2975 pDocSh->PostPaint(0,0,0,MAXCOL,MAXROW,MAXTAB, PAINT_EXTRAS);
2976 pDocSh->SetDocumentModified();
2978 else
2979 Sound::Beep();
2983 //----------------------------------------------------------------------------
2985 void ScViewFunc::HideTable( SCTAB nTab )
2987 ScDocShell* pDocSh = GetViewData()->GetDocShell();
2988 ScDocument* pDoc = pDocSh->GetDocument();
2989 BOOL bUndo(pDoc->IsUndoEnabled());
2990 SCTAB nVisible = 0;
2991 SCTAB nCount = pDoc->GetTableCount();
2992 for (SCTAB i=0; i<nCount; i++)
2994 if (pDoc->IsVisible(i))
2995 ++nVisible;
2998 if (nVisible > 1)
3000 pDoc->SetVisible( nTab, FALSE );
3001 if (bUndo)
3003 pDocSh->GetUndoManager()->AddUndoAction( new ScUndoShowHideTab( pDocSh, nTab, FALSE ) );
3006 // Views updaten:
3007 pDocSh->Broadcast( ScTablesHint( SC_TAB_HIDDEN, nTab ) );
3009 SetTabNo( nTab, TRUE );
3010 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
3011 pDocSh->PostPaint(0,0,0,MAXCOL,MAXROW,MAXTAB, PAINT_EXTRAS);
3012 pDocSh->SetDocumentModified();
3014 else
3015 Sound::Beep();
3019 //----------------------------------------------------------------------------
3021 void ScViewFunc::InsertSpecialChar( const String& rStr, const Font& rFont )
3023 ScEditableTester aTester( this );
3024 if (!aTester.IsEditable())
3026 ErrorMessage(aTester.GetMessageId());
3027 return;
3030 const sal_Unicode* pChar = rStr.GetBuffer();
3031 ScTabViewShell* pViewShell = GetViewData()->GetViewShell();
3032 SvxFontItem aFontItem( rFont.GetFamily(),
3033 rFont.GetName(),
3034 rFont.GetStyleName(),
3035 rFont.GetPitch(),
3036 rFont.GetCharSet(),
3037 ATTR_FONT );
3039 // if string contains WEAK characters, set all fonts
3040 BYTE nScript;
3041 ScDocument* pDoc = GetViewData()->GetDocument();
3042 if ( pDoc->HasStringWeakCharacters( rStr ) )
3043 nScript = SCRIPTTYPE_LATIN | SCRIPTTYPE_ASIAN | SCRIPTTYPE_COMPLEX;
3044 else
3045 nScript = pDoc->GetStringScriptType( rStr );
3047 SvxScriptSetItem aSetItem( SID_ATTR_CHAR_FONT, pViewShell->GetPool() );
3048 aSetItem.PutItemForScriptType( nScript, aFontItem );
3049 ApplyUserItemSet( aSetItem.GetItemSet() );
3051 while ( *pChar )
3052 pViewShell->TabKeyInput( KeyEvent( *(pChar++), KeyCode() ) );
3056 //----------------------------------------------------------------------------
3058 void ScViewFunc::UpdateLineAttrs( SvxBorderLine& rLine,
3059 const SvxBorderLine* pDestLine,
3060 const SvxBorderLine* pSrcLine,
3061 BOOL bColor )
3063 if ( pSrcLine && pDestLine )
3065 if ( bColor )
3067 rLine.SetColor ( pSrcLine->GetColor() );
3068 rLine.SetOutWidth ( pDestLine->GetOutWidth() );
3069 rLine.SetInWidth ( pDestLine->GetInWidth() );
3070 rLine.SetDistance ( pDestLine->GetDistance() );
3072 else
3074 rLine.SetColor ( pDestLine->GetColor() );
3075 rLine.SetOutWidth ( pSrcLine->GetOutWidth() );
3076 rLine.SetInWidth ( pSrcLine->GetInWidth() );
3077 rLine.SetDistance ( pSrcLine->GetDistance() );
3083 #define SET_LINE_ATTRIBUTES(LINE,BOXLINE) \
3084 pBoxLine = aBoxItem.Get##LINE(); \
3085 if ( pBoxLine ) \
3087 if ( pLine ) \
3089 UpdateLineAttrs( aLine, pBoxLine, pLine, bColorOnly ); \
3090 aBoxItem.SetLine( &aLine, BOXLINE ); \
3092 else \
3093 aBoxItem.SetLine( NULL, BOXLINE ); \
3097 //----------------------------------------------------------------------------
3099 void ScViewFunc::SetSelectionFrameLines( const SvxBorderLine* pLine,
3100 BOOL bColorOnly )
3102 // nur wegen Matrix nicht editierbar? Attribute trotzdem ok
3103 BOOL bOnlyNotBecauseOfMatrix;
3104 if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
3106 ErrorMessage(STR_PROTECTIONERR);
3107 return;
3110 ScDocument* pDoc = GetViewData()->GetDocument();
3111 ScMarkData aFuncMark( GetViewData()->GetMarkData() ); // local copy for UnmarkFiltered
3112 ScViewUtil::UnmarkFiltered( aFuncMark, pDoc );
3113 ScDocShell* pDocSh = GetViewData()->GetDocShell();
3114 const ScPatternAttr* pSelAttrs = GetSelectionPattern();
3115 const SfxItemSet& rSelItemSet = pSelAttrs->GetItemSet();
3117 const SfxPoolItem* pBorderAttr = NULL;
3118 SfxItemState eItemState = rSelItemSet.GetItemState( ATTR_BORDER, TRUE, &pBorderAttr );
3120 const SfxPoolItem* pTLBRItem = 0;
3121 SfxItemState eTLBRState = rSelItemSet.GetItemState( ATTR_BORDER_TLBR, TRUE, &pTLBRItem );
3123 const SfxPoolItem* pBLTRItem = 0;
3124 SfxItemState eBLTRState = rSelItemSet.GetItemState( ATTR_BORDER_BLTR, TRUE, &pBLTRItem );
3126 // any of the lines visible?
3127 if( (eItemState != SFX_ITEM_DEFAULT) || (eTLBRState != SFX_ITEM_DEFAULT) || (eBLTRState != SFX_ITEM_DEFAULT) )
3129 // none of the lines don't care?
3130 if( (eItemState != SFX_ITEM_DONTCARE) && (eTLBRState != SFX_ITEM_DONTCARE) && (eBLTRState != SFX_ITEM_DONTCARE) )
3132 SfxItemSet* pOldSet = new SfxItemSet(
3133 *(pDoc->GetPool()),
3134 ATTR_PATTERN_START,
3135 ATTR_PATTERN_END );
3136 SfxItemSet* pNewSet = new SfxItemSet(
3137 *(pDoc->GetPool()),
3138 ATTR_PATTERN_START,
3139 ATTR_PATTERN_END );
3141 //------------------------------------------------------------
3142 const SvxBorderLine* pBoxLine = NULL;
3143 SvxBorderLine aLine;
3145 // hier wird die pBoxLine benutzt:
3147 if( pBorderAttr )
3149 SvxBoxItem aBoxItem( *(const SvxBoxItem*)pBorderAttr );
3150 SvxBoxInfoItem aBoxInfoItem( ATTR_BORDER_INNER );
3152 SET_LINE_ATTRIBUTES(Top,BOX_LINE_TOP)
3153 SET_LINE_ATTRIBUTES(Bottom,BOX_LINE_BOTTOM)
3154 SET_LINE_ATTRIBUTES(Left,BOX_LINE_LEFT)
3155 SET_LINE_ATTRIBUTES(Right,BOX_LINE_RIGHT)
3157 aBoxInfoItem.SetLine( aBoxItem.GetTop(), BOXINFO_LINE_HORI );
3158 aBoxInfoItem.SetLine( aBoxItem.GetLeft(), BOXINFO_LINE_VERT );
3159 aBoxInfoItem.ResetFlags(); // Lines auf Valid setzen
3161 pOldSet->Put( *pBorderAttr );
3162 pNewSet->Put( aBoxItem );
3163 pNewSet->Put( aBoxInfoItem );
3166 if( pTLBRItem && ((const SvxLineItem*)pTLBRItem)->GetLine() )
3168 SvxLineItem aTLBRItem( *(const SvxLineItem*)pTLBRItem );
3169 UpdateLineAttrs( aLine, aTLBRItem.GetLine(), pLine, bColorOnly );
3170 aTLBRItem.SetLine( &aLine );
3171 pOldSet->Put( *pTLBRItem );
3172 pNewSet->Put( aTLBRItem );
3175 if( pBLTRItem && ((const SvxLineItem*)pBLTRItem)->GetLine() )
3177 SvxLineItem aBLTRItem( *(const SvxLineItem*)pBLTRItem );
3178 UpdateLineAttrs( aLine, aBLTRItem.GetLine(), pLine, bColorOnly );
3179 aBLTRItem.SetLine( &aLine );
3180 pOldSet->Put( *pBLTRItem );
3181 pNewSet->Put( aBLTRItem );
3184 ApplyAttributes( pNewSet, pOldSet );
3186 delete pOldSet;
3187 delete pNewSet;
3189 else // if ( eItemState == SFX_ITEM_DONTCARE )
3191 aFuncMark.MarkToMulti();
3192 pDoc->ApplySelectionLineStyle( aFuncMark, pLine, bColorOnly );
3195 ScRange aMarkRange;
3196 aFuncMark.GetMultiMarkArea( aMarkRange );
3197 SCCOL nStartCol = aMarkRange.aStart.Col();
3198 SCROW nStartRow = aMarkRange.aStart.Row();
3199 SCTAB nStartTab = aMarkRange.aStart.Tab();
3200 SCCOL nEndCol = aMarkRange.aEnd.Col();
3201 SCROW nEndRow = aMarkRange.aEnd.Row();
3202 SCTAB nEndTab = aMarkRange.aEnd.Tab();
3203 pDocSh->PostPaint( nStartCol, nStartRow, nStartTab,
3204 nEndCol, nEndRow, nEndTab,
3205 PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
3207 pDocSh->UpdateOle( GetViewData() );
3208 pDocSh->SetDocumentModified();
3212 #undef SET_LINE_ATTRIBUTES
3215 //----------------------------------------------------------------------------
3217 void ScViewFunc::SetConditionalFormat( const ScConditionalFormat& rNew )
3219 ScDocument* pDoc = GetViewData()->GetDocument();
3220 ULONG nIndex = pDoc->AddCondFormat(rNew); // dafuer gibt's kein Undo
3221 SfxUInt32Item aItem( ATTR_CONDITIONAL, nIndex );
3223 ApplyAttr( aItem ); // mit Paint und Undo...
3227 //----------------------------------------------------------------------------
3229 void ScViewFunc::SetValidation( const ScValidationData& rNew )
3231 ScDocument* pDoc = GetViewData()->GetDocument();
3232 ULONG nIndex = pDoc->AddValidationEntry(rNew); // dafuer gibt's kein Undo
3233 SfxUInt32Item aItem( ATTR_VALIDDATA, nIndex );
3235 ApplyAttr( aItem ); // mit Paint und Undo...