Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "scitems.hxx"
21 : #include <comphelper/string.hxx>
22 : #include <editeng/eeitem.hxx>
23 :
24 : #include <sfx2/app.hxx>
25 : #include <editeng/boxitem.hxx>
26 : #include <editeng/fontitem.hxx>
27 : #include <editeng/scripttypeitem.hxx>
28 : #include <svl/srchitem.hxx>
29 : #include <sfx2/linkmgr.hxx>
30 : #include <sfx2/dispatch.hxx>
31 : #include <sfx2/docfilt.hxx>
32 : #include <sfx2/docfile.hxx>
33 : #include <sfx2/objitem.hxx>
34 : #include <sfx2/viewfrm.hxx>
35 : #include <svl/stritem.hxx>
36 : #include <svl/zforlist.hxx>
37 : #include <svx/svdview.hxx>
38 : #include <vcl/msgbox.hxx>
39 : #include <vcl/waitobj.hxx>
40 :
41 : #include <basic/sbstar.hxx>
42 : #include <com/sun/star/container/XNameContainer.hpp>
43 : #include <com/sun/star/script/XLibraryContainer.hpp>
44 :
45 : #include "viewfunc.hxx"
46 :
47 : #include "sc.hrc"
48 : #include "globstr.hrc"
49 :
50 : #include "attrib.hxx"
51 : #include "autoform.hxx"
52 : #include "formulacell.hxx" // EnterAutoSum
53 : #include "cellmergeoption.hxx"
54 : #include "compiler.hxx"
55 : #include "docfunc.hxx"
56 : #include "docpool.hxx"
57 : #include "docsh.hxx"
58 : #include "global.hxx"
59 : #include "patattr.hxx"
60 : #include "printfun.hxx"
61 : #include "rangenam.hxx"
62 : #include "rangeutl.hxx"
63 : #include "refundo.hxx"
64 : #include "table.hxx"
65 : #include "tablink.hxx"
66 : #include "tabvwsh.hxx"
67 : #include "uiitems.hxx"
68 : #include "undoblk.hxx"
69 : #include "undocell.hxx"
70 : #include "undotab.hxx"
71 : #include "sizedev.hxx"
72 : #include "editable.hxx"
73 : #include "scmod.hxx"
74 : #include "inputhdl.hxx"
75 : #include "inputwin.hxx"
76 : #include "funcdesc.hxx"
77 : #include "docuno.hxx"
78 : #include "charthelper.hxx"
79 : #include "tabbgcolor.hxx"
80 : #include "clipparam.hxx"
81 : #include "prnsave.hxx"
82 : #include "tokenarray.hxx"
83 :
84 : #include <boost/scoped_ptr.hpp>
85 : #include <vector>
86 : #include <memory>
87 :
88 : using namespace com::sun::star;
89 : using ::editeng::SvxBorderLine;
90 :
91 : using ::std::vector;
92 : using ::std::auto_ptr;
93 :
94 : // helper func defined in docfunc.cxx
95 : void VBA_DeleteModule( ScDocShell& rDocSh, const OUString& sModuleName );
96 :
97 : // STATIC DATA ---------------------------------------------------------------
98 :
99 :
100 : //----------------------------------------------------------------------------
101 :
102 167 : sal_Bool ScViewFunc::AdjustBlockHeight( sal_Bool bPaint, ScMarkData* pMarkData )
103 : {
104 167 : ScDocShell* pDocSh = GetViewData()->GetDocShell();
105 167 : if (!pMarkData)
106 16 : pMarkData = &GetViewData()->GetMarkData();
107 :
108 167 : ScDocument* pDoc = pDocSh->GetDocument();
109 167 : SCCOLROW* pRanges = new SCCOLROW[MAXCOLROWCOUNT];
110 167 : SCCOLROW nRangeCnt = pMarkData->GetMarkRowRanges( pRanges );
111 167 : if (nRangeCnt == 0)
112 : {
113 0 : pRanges[0] = pRanges[1] = GetViewData()->GetCurY();
114 0 : nRangeCnt = 1;
115 : }
116 :
117 167 : double nPPTX = GetViewData()->GetPPTX();
118 167 : double nPPTY = GetViewData()->GetPPTY();
119 167 : Fraction aZoomX = GetViewData()->GetZoomX();
120 167 : Fraction aZoomY = GetViewData()->GetZoomY();
121 :
122 167 : ScSizeDeviceProvider aProv(pDocSh);
123 167 : if (aProv.IsPrinter())
124 : {
125 24 : nPPTX = aProv.GetPPTX();
126 24 : nPPTY = aProv.GetPPTY();
127 24 : aZoomX = aZoomY = Fraction( 1, 1 );
128 : }
129 :
130 167 : sal_Bool bAnyChanged = false;
131 167 : ScMarkData::iterator itr = pMarkData->begin(), itrEnd = pMarkData->end();
132 334 : for (; itr != itrEnd; ++itr)
133 : {
134 167 : SCTAB nTab = *itr;
135 167 : SCCOLROW* pOneRange = pRanges;
136 167 : sal_Bool bChanged = false;
137 167 : SCROW nPaintY = 0;
138 334 : for (SCROW nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++)
139 : {
140 167 : SCROW nStartNo = *(pOneRange++);
141 167 : SCROW nEndNo = *(pOneRange++);
142 167 : if (pDoc->SetOptimalHeight( nStartNo, nEndNo, nTab, 0, aProv.GetDevice(),
143 167 : nPPTX, nPPTY, aZoomX, aZoomY, false ))
144 : {
145 162 : if (!bChanged)
146 162 : nPaintY = nStartNo;
147 162 : bAnyChanged = bChanged = sal_True;
148 : }
149 : }
150 167 : if ( bPaint && bChanged )
151 : pDocSh->PostPaint( 0, nPaintY, nTab, MAXCOL, MAXROW, nTab,
152 162 : PAINT_GRID | PAINT_LEFT );
153 : }
154 167 : delete[] pRanges;
155 :
156 167 : if ( bPaint && bAnyChanged )
157 162 : pDocSh->UpdateOle(GetViewData());
158 :
159 167 : return bAnyChanged;
160 : }
161 :
162 :
163 : //----------------------------------------------------------------------------
164 :
165 0 : sal_Bool ScViewFunc::AdjustRowHeight( SCROW nStartRow, SCROW nEndRow, sal_Bool bPaint )
166 : {
167 0 : ScDocShell* pDocSh = GetViewData()->GetDocShell();
168 0 : ScDocument* pDoc = pDocSh->GetDocument();
169 0 : SCTAB nTab = GetViewData()->GetTabNo();
170 0 : double nPPTX = GetViewData()->GetPPTX();
171 0 : double nPPTY = GetViewData()->GetPPTY();
172 0 : Fraction aZoomX = GetViewData()->GetZoomX();
173 0 : Fraction aZoomY = GetViewData()->GetZoomY();
174 0 : sal_uInt16 nOldPixel = 0;
175 0 : if (nStartRow == nEndRow)
176 0 : nOldPixel = (sal_uInt16) (pDoc->GetRowHeight(nStartRow,nTab) * nPPTY);
177 :
178 0 : ScSizeDeviceProvider aProv(pDocSh);
179 0 : if (aProv.IsPrinter())
180 : {
181 0 : nPPTX = aProv.GetPPTX();
182 0 : nPPTY = aProv.GetPPTY();
183 0 : aZoomX = aZoomY = Fraction( 1, 1 );
184 : }
185 : sal_Bool bChanged = pDoc->SetOptimalHeight( nStartRow, nEndRow, nTab, 0, aProv.GetDevice(),
186 0 : nPPTX, nPPTY, aZoomX, aZoomY, false );
187 :
188 0 : if (bChanged && ( nStartRow == nEndRow ))
189 : {
190 0 : sal_uInt16 nNewPixel = (sal_uInt16) (pDoc->GetRowHeight(nStartRow,nTab) * nPPTY);
191 0 : if ( nNewPixel == nOldPixel )
192 0 : bChanged = false;
193 : }
194 :
195 0 : if ( bPaint && bChanged )
196 : pDocSh->PostPaint( 0, nStartRow, nTab, MAXCOL, MAXROW, nTab,
197 0 : PAINT_GRID | PAINT_LEFT );
198 :
199 0 : return bChanged;
200 : }
201 :
202 :
203 : //----------------------------------------------------------------------------
204 :
205 : enum ScAutoSum
206 : {
207 : ScAutoSumNone = 0,
208 : ScAutoSumData,
209 : ScAutoSumSum
210 : };
211 :
212 :
213 0 : static ScAutoSum lcl_IsAutoSumData( ScDocument* pDoc, SCCOL nCol, SCROW nRow,
214 : SCTAB nTab, ScDirection eDir, SCCOLROW& nExtend )
215 : {
216 0 : ScRefCellValue aCell;
217 0 : aCell.assign(*pDoc, ScAddress(nCol, nRow, nTab));
218 0 : if (aCell.hasNumeric())
219 : {
220 0 : if (aCell.meType == CELLTYPE_FORMULA)
221 : {
222 0 : ScTokenArray* pCode = aCell.mpFormula->GetCode();
223 0 : if ( pCode && pCode->GetOuterFuncOpCode() == ocSum )
224 : {
225 0 : if ( pCode->GetAdjacentExtendOfOuterFuncRefs( nExtend,
226 0 : ScAddress( nCol, nRow, nTab ), eDir ) )
227 0 : return ScAutoSumSum;
228 : }
229 : }
230 0 : return ScAutoSumData;
231 : }
232 0 : return ScAutoSumNone;
233 : }
234 :
235 :
236 : //----------------------------------------------------------------------------
237 :
238 : #define SC_AUTOSUM_MAXCOUNT 20
239 :
240 0 : static ScAutoSum lcl_SeekAutoSumData( ScDocument* pDoc, SCCOL& nCol, SCROW& nRow,
241 : SCTAB nTab, ScDirection eDir, SCCOLROW& nExtend )
242 : {
243 0 : sal_uInt16 nCount = 0;
244 0 : while (nCount < SC_AUTOSUM_MAXCOUNT)
245 : {
246 0 : if ( eDir == DIR_TOP )
247 : {
248 0 : if (nRow > 0)
249 0 : --nRow;
250 : else
251 0 : return ScAutoSumNone;
252 : }
253 : else
254 : {
255 0 : if (nCol > 0)
256 0 : --nCol;
257 : else
258 0 : return ScAutoSumNone;
259 : }
260 : ScAutoSum eSum;
261 0 : if ( (eSum = lcl_IsAutoSumData(
262 0 : pDoc, nCol, nRow, nTab, eDir, nExtend )) != ScAutoSumNone )
263 0 : return eSum;
264 0 : ++nCount;
265 : }
266 0 : return ScAutoSumNone;
267 : }
268 :
269 : #undef SC_AUTOSUM_MAXCOUNT
270 :
271 : //----------------------------------------------------------------------------
272 :
273 0 : static bool lcl_FindNextSumEntryInColumn( ScDocument* pDoc, SCCOL nCol, SCROW& nRow,
274 : SCTAB nTab, SCCOLROW& nExtend, SCROW nMinRow )
275 : {
276 0 : const SCROW nTmp = nRow;
277 0 : ScAutoSum eSkip = ScAutoSumNone;
278 0 : while ( ( eSkip = lcl_IsAutoSumData( pDoc, nCol, nRow, nTab, DIR_TOP, nExtend ) ) == ScAutoSumData &&
279 0 : nRow > nMinRow )
280 : {
281 0 : --nRow;
282 : }
283 0 : if ( eSkip == ScAutoSumSum && nRow < nTmp )
284 : {
285 0 : return true;
286 : }
287 0 : return false;
288 : }
289 :
290 : //----------------------------------------------------------------------------
291 :
292 0 : static bool lcl_FindNextSumEntryInRow( ScDocument* pDoc, SCCOL& nCol, SCROW nRow,
293 : SCTAB nTab, SCCOLROW& nExtend, SCROW nMinCol )
294 : {
295 0 : const SCCOL nTmp = nCol;
296 0 : ScAutoSum eSkip = ScAutoSumNone;
297 0 : while ( ( eSkip = lcl_IsAutoSumData( pDoc, nCol, nRow, nTab, DIR_LEFT, nExtend ) ) == ScAutoSumData &&
298 0 : nCol > nMinCol )
299 : {
300 0 : --nCol;
301 : }
302 0 : if ( eSkip == ScAutoSumSum && nCol < nTmp )
303 : {
304 0 : return true;
305 : }
306 0 : return false;
307 : }
308 :
309 : //----------------------------------------------------------------------------
310 :
311 0 : static bool lcl_GetAutoSumForColumnRange( ScDocument* pDoc, ScRangeList& rRangeList, const ScRange& rRange )
312 : {
313 0 : const ScAddress aStart = rRange.aStart;
314 0 : const ScAddress aEnd = rRange.aEnd;
315 0 : if ( aStart.Col() != aEnd.Col() )
316 : {
317 0 : return false;
318 : }
319 :
320 0 : const SCTAB nTab = aEnd.Tab();
321 0 : const SCCOL nCol = aEnd.Col();
322 0 : SCROW nEndRow = aEnd.Row();
323 0 : SCROW nStartRow = nEndRow;
324 0 : SCCOLROW nExtend = 0;
325 0 : const ScAutoSum eSum = lcl_IsAutoSumData( pDoc, nCol, nEndRow, nTab, DIR_TOP, nExtend /*out*/ );
326 :
327 0 : if ( eSum == ScAutoSumSum )
328 : {
329 0 : bool bContinue = false;
330 0 : do
331 : {
332 0 : rRangeList.Append( ScRange( nCol, nStartRow, nTab, nCol, nEndRow, nTab ) );
333 0 : nEndRow = static_cast< SCROW >( nExtend );
334 0 : if ( ( bContinue = lcl_FindNextSumEntryInColumn( pDoc, nCol, nEndRow /*inout*/, nTab, nExtend /*out*/, aStart.Row() ) ) == true )
335 : {
336 0 : nStartRow = nEndRow;
337 : }
338 : } while ( bContinue );
339 : }
340 : else
341 : {
342 0 : while ( nStartRow > aStart.Row() &&
343 0 : lcl_IsAutoSumData( pDoc, nCol, nStartRow-1, nTab, DIR_TOP, nExtend /*out*/ ) != ScAutoSumSum )
344 : {
345 0 : --nStartRow;
346 : }
347 0 : rRangeList.Append( ScRange( nCol, nStartRow, nTab, nCol, nEndRow, nTab ) );
348 : }
349 :
350 0 : return true;
351 : }
352 :
353 : //----------------------------------------------------------------------------
354 :
355 0 : static bool lcl_GetAutoSumForRowRange( ScDocument* pDoc, ScRangeList& rRangeList, const ScRange& rRange )
356 : {
357 0 : const ScAddress aStart = rRange.aStart;
358 0 : const ScAddress aEnd = rRange.aEnd;
359 0 : if ( aStart.Row() != aEnd.Row() )
360 : {
361 0 : return false;
362 : }
363 :
364 0 : const SCTAB nTab = aEnd.Tab();
365 0 : const SCROW nRow = aEnd.Row();
366 0 : SCCOL nEndCol = aEnd.Col();
367 0 : SCCOL nStartCol = nEndCol;
368 0 : SCCOLROW nExtend = 0;
369 0 : const ScAutoSum eSum = lcl_IsAutoSumData( pDoc, nEndCol, nRow, nTab, DIR_LEFT, nExtend /*out*/ );
370 :
371 0 : if ( eSum == ScAutoSumSum )
372 : {
373 0 : bool bContinue = false;
374 0 : do
375 : {
376 0 : rRangeList.Append( ScRange( nStartCol, nRow, nTab, nEndCol, nRow, nTab ) );
377 0 : nEndCol = static_cast< SCCOL >( nExtend );
378 0 : if ( ( bContinue = lcl_FindNextSumEntryInRow( pDoc, nEndCol /*inout*/, nRow, nTab, nExtend /*out*/, aStart.Col() ) ) == true )
379 : {
380 0 : nStartCol = nEndCol;
381 : }
382 : } while ( bContinue );
383 : }
384 : else
385 : {
386 0 : while ( nStartCol > aStart.Col() &&
387 0 : lcl_IsAutoSumData( pDoc, nStartCol-1, nRow, nTab, DIR_LEFT, nExtend /*out*/ ) != ScAutoSumSum )
388 : {
389 0 : --nStartCol;
390 : }
391 0 : rRangeList.Append( ScRange( nStartCol, nRow, nTab, nEndCol, nRow, nTab ) );
392 : }
393 :
394 0 : return true;
395 : }
396 :
397 : //----------------------------------------------------------------------------
398 :
399 0 : sal_Bool ScViewFunc::GetAutoSumArea( ScRangeList& rRangeList )
400 : {
401 0 : ScDocument* pDoc = GetViewData()->GetDocument();
402 0 : SCTAB nTab = GetViewData()->GetTabNo();
403 :
404 0 : SCCOL nCol = GetViewData()->GetCurX();
405 0 : SCROW nRow = GetViewData()->GetCurY();
406 :
407 0 : SCCOL nStartCol = nCol;
408 0 : SCROW nStartRow = nRow;
409 0 : SCCOL nEndCol = nCol;
410 0 : SCROW nEndRow = nRow;
411 0 : SCCOL nSeekCol = nCol;
412 0 : SCROW nSeekRow = nRow;
413 : SCCOLROW nExtend; // will become valid via reference for ScAutoSumSum
414 :
415 0 : sal_Bool bCol = false;
416 0 : sal_Bool bRow = false;
417 :
418 : ScAutoSum eSum;
419 0 : if ( nRow != 0
420 0 : && ((eSum = lcl_IsAutoSumData( pDoc, nCol, nRow-1, nTab,
421 0 : DIR_TOP, nExtend /*out*/ )) == ScAutoSumData )
422 0 : && ((eSum = lcl_IsAutoSumData( pDoc, nCol, nRow-1, nTab,
423 0 : DIR_LEFT, nExtend /*out*/ )) == ScAutoSumData )
424 : )
425 : {
426 0 : bRow = sal_True;
427 0 : nSeekRow = nRow - 1;
428 : }
429 0 : else if ( nCol != 0 && (eSum = lcl_IsAutoSumData( pDoc, nCol-1, nRow, nTab,
430 0 : DIR_LEFT, nExtend /*out*/ )) == ScAutoSumData )
431 : {
432 0 : bCol = sal_True;
433 0 : nSeekCol = nCol - 1;
434 : }
435 0 : else if ( (eSum = lcl_SeekAutoSumData( pDoc, nCol, nSeekRow, nTab, DIR_TOP, nExtend /*out*/ )) != ScAutoSumNone )
436 0 : bRow = sal_True;
437 0 : else if (( eSum = lcl_SeekAutoSumData( pDoc, nSeekCol, nRow, nTab, DIR_LEFT, nExtend /*out*/ )) != ScAutoSumNone )
438 0 : bCol = sal_True;
439 :
440 0 : if ( bCol || bRow )
441 : {
442 0 : if ( bRow )
443 : {
444 0 : nStartRow = nSeekRow; // nSeekRow might be adjusted via reference
445 0 : if ( eSum == ScAutoSumSum )
446 0 : nEndRow = nStartRow; // only sum sums
447 : else
448 0 : nEndRow = nRow - 1; // maybe extend data area at bottom
449 : }
450 : else
451 : {
452 0 : nStartCol = nSeekCol; // nSeekCol might be adjusted vie reference
453 0 : if ( eSum == ScAutoSumSum )
454 0 : nEndCol = nStartCol; // only sum sums
455 : else
456 0 : nEndCol = nCol - 1; // maybe extend data area to the right
457 : }
458 0 : sal_Bool bContinue = false;
459 0 : do
460 : {
461 0 : if ( eSum == ScAutoSumData )
462 : {
463 0 : if ( bRow )
464 : {
465 0 : while ( nStartRow != 0 && lcl_IsAutoSumData( pDoc, nCol,
466 0 : nStartRow-1, nTab, DIR_TOP, nExtend /*out*/ ) == eSum )
467 0 : --nStartRow;
468 : }
469 : else
470 : {
471 0 : while ( nStartCol != 0 && lcl_IsAutoSumData( pDoc, nStartCol-1,
472 0 : nRow, nTab, DIR_LEFT, nExtend /*out*/ ) == eSum )
473 0 : --nStartCol;
474 : }
475 : }
476 : rRangeList.Append(
477 0 : ScRange( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab ) );
478 0 : if ( eSum == ScAutoSumSum )
479 : {
480 0 : if ( bRow )
481 : {
482 0 : nEndRow = static_cast< SCROW >( nExtend );
483 0 : if ( ( bContinue = lcl_FindNextSumEntryInColumn( pDoc, nCol, nEndRow /*inout*/, nTab, nExtend /*out*/, 0 ) ) == true )
484 : {
485 0 : nStartRow = nEndRow;
486 : }
487 : }
488 : else
489 : {
490 0 : nEndCol = static_cast< SCCOL >( nExtend );
491 0 : if ( ( bContinue = lcl_FindNextSumEntryInRow( pDoc, nEndCol /*inout*/, nRow, nTab, nExtend /*out*/, 0 ) ) == true )
492 : {
493 0 : nStartCol = nEndCol;
494 : }
495 : }
496 : }
497 : } while ( bContinue );
498 0 : return sal_True;
499 : }
500 0 : return false;
501 : }
502 :
503 : //----------------------------------------------------------------------------
504 :
505 0 : void ScViewFunc::EnterAutoSum(const ScRangeList& rRangeList, bool bSubTotal, const ScAddress& rAddr)
506 : {
507 0 : String aFormula = GetAutoSumFormula( rRangeList, bSubTotal, rAddr );
508 0 : EnterBlock( aFormula, NULL );
509 0 : }
510 :
511 : //----------------------------------------------------------------------------
512 :
513 0 : bool ScViewFunc::AutoSum( const ScRange& rRange, bool bSubTotal, bool bSetCursor, bool bContinue )
514 : {
515 0 : ScDocument* pDoc = GetViewData()->GetDocument();
516 0 : const SCTAB nTab = rRange.aStart.Tab();
517 0 : SCCOL nStartCol = rRange.aStart.Col();
518 0 : SCROW nStartRow = rRange.aStart.Row();
519 0 : const SCCOL nEndCol = rRange.aEnd.Col();
520 0 : const SCROW nEndRow = rRange.aEnd.Row();
521 0 : SCCOLROW nExtend = 0; // out parameter for lcl_IsAutoSumData
522 :
523 : // ignore rows at the top of the given range which don't contain autosum data
524 0 : bool bRowData = false;
525 0 : for ( SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow )
526 : {
527 0 : for ( SCCOL nCol = nStartCol; nCol <= nEndCol; ++nCol )
528 : {
529 0 : if ( lcl_IsAutoSumData( pDoc, nCol, nRow, nTab, DIR_TOP, nExtend ) != ScAutoSumNone )
530 : {
531 0 : bRowData = true;
532 0 : break;
533 : }
534 : }
535 0 : if ( bRowData )
536 : {
537 0 : nStartRow = nRow;
538 0 : break;
539 : }
540 : }
541 0 : if ( !bRowData )
542 : {
543 0 : return false;
544 : }
545 :
546 : // ignore columns at the left of the given range which don't contain autosum data
547 0 : bool bColData = false;
548 0 : for ( SCCOL nCol = nStartCol; nCol <= nEndCol; ++nCol )
549 : {
550 0 : for ( SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow )
551 : {
552 0 : if ( lcl_IsAutoSumData( pDoc, nCol, nRow, nTab, DIR_LEFT, nExtend ) != ScAutoSumNone )
553 : {
554 0 : bColData = true;
555 0 : break;
556 : }
557 : }
558 0 : if ( bColData )
559 : {
560 0 : nStartCol = nCol;
561 0 : break;
562 : }
563 : }
564 0 : if ( !bColData )
565 : {
566 0 : return false;
567 : }
568 :
569 0 : const bool bEndRowEmpty = pDoc->IsBlockEmpty( nTab, nStartCol, nEndRow, nEndCol, nEndRow );
570 0 : const bool bEndColEmpty = pDoc->IsBlockEmpty( nTab, nEndCol, nStartRow, nEndCol, nEndRow );
571 0 : bool bRow = ( ( nStartRow != nEndRow ) && ( bEndRowEmpty || ( !bEndRowEmpty && !bEndColEmpty ) ) );
572 0 : bool bCol = ( ( nStartCol != nEndCol ) && ( bEndColEmpty || nStartRow == nEndRow ) );
573 :
574 : // find an empty row for entering the result
575 0 : SCROW nInsRow = nEndRow;
576 0 : if ( bRow && !bEndRowEmpty )
577 : {
578 0 : if ( nInsRow < MAXROW )
579 : {
580 0 : ++nInsRow;
581 0 : while ( !pDoc->IsBlockEmpty( nTab, nStartCol, nInsRow, nEndCol, nInsRow ) )
582 : {
583 0 : if ( nInsRow < MAXROW )
584 : {
585 0 : ++nInsRow;
586 : }
587 : else
588 : {
589 0 : bRow = false;
590 0 : break;
591 : }
592 : }
593 : }
594 : else
595 : {
596 0 : bRow = false;
597 : }
598 : }
599 :
600 : // find an empty column for entering the result
601 0 : SCCOL nInsCol = nEndCol;
602 0 : if ( bCol && !bEndColEmpty )
603 : {
604 0 : if ( nInsCol < MAXCOL )
605 : {
606 0 : ++nInsCol;
607 0 : while ( !pDoc->IsBlockEmpty( nTab, nInsCol, nStartRow, nInsCol, nEndRow ) )
608 : {
609 0 : if ( nInsCol < MAXCOL )
610 : {
611 0 : ++nInsCol;
612 : }
613 : else
614 : {
615 0 : bCol = false;
616 0 : break;
617 : }
618 : }
619 : }
620 : else
621 : {
622 0 : bCol = false;
623 : }
624 : }
625 :
626 0 : if ( !bRow && !bCol )
627 : {
628 0 : return false;
629 : }
630 :
631 0 : SCCOL nMarkEndCol = nEndCol;
632 0 : SCROW nMarkEndRow = nEndRow;
633 :
634 0 : if ( bRow )
635 : {
636 : // calculate the row sums for all columns of the given range
637 :
638 0 : SCROW nSumEndRow = nEndRow;
639 :
640 0 : if ( bEndRowEmpty )
641 : {
642 : // the last row of the given range is empty;
643 : // don't take into account for calculating the autosum
644 0 : --nSumEndRow;
645 : }
646 : else
647 : {
648 : // increase mark range
649 0 : ++nMarkEndRow;
650 : }
651 :
652 0 : for ( SCCOL nCol = nStartCol; nCol <= nEndCol; ++nCol )
653 : {
654 0 : if ( !pDoc->IsBlockEmpty( nTab, nCol, nStartRow, nCol, nSumEndRow ) )
655 : {
656 0 : ScRangeList aRangeList;
657 0 : const ScRange aRange( nCol, nStartRow, nTab, nCol, nSumEndRow, nTab );
658 0 : if ( lcl_GetAutoSumForColumnRange( pDoc, aRangeList, aRange ) )
659 : {
660 : const String aFormula = GetAutoSumFormula(
661 0 : aRangeList, bSubTotal, ScAddress(nCol, nInsRow, nTab));
662 0 : EnterData( nCol, nInsRow, nTab, aFormula );
663 0 : }
664 : }
665 : }
666 : }
667 :
668 0 : if ( bCol )
669 : {
670 : // calculate the column sums for all rows of the given range
671 :
672 0 : SCCOL nSumEndCol = nEndCol;
673 :
674 0 : if ( bEndColEmpty )
675 : {
676 : // the last column of the given range is empty;
677 : // don't take into account for calculating the autosum
678 0 : --nSumEndCol;
679 : }
680 : else
681 : {
682 : // increase mark range
683 0 : ++nMarkEndCol;
684 : }
685 :
686 0 : for ( SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow )
687 : {
688 0 : if ( !pDoc->IsBlockEmpty( nTab, nStartCol, nRow, nSumEndCol, nRow ) )
689 : {
690 0 : ScRangeList aRangeList;
691 0 : const ScRange aRange( nStartCol, nRow, nTab, nSumEndCol, nRow, nTab );
692 0 : if ( lcl_GetAutoSumForRowRange( pDoc, aRangeList, aRange ) )
693 : {
694 0 : const String aFormula = GetAutoSumFormula( aRangeList, bSubTotal, ScAddress(nInsCol, nRow, nTab) );
695 0 : EnterData( nInsCol, nRow, nTab, aFormula );
696 0 : }
697 : }
698 : }
699 : }
700 :
701 : // set new mark range and cursor position
702 0 : const ScRange aMarkRange( nStartCol, nStartRow, nTab, nMarkEndCol, nMarkEndRow, nTab );
703 0 : MarkRange( aMarkRange, false, bContinue );
704 0 : if ( bSetCursor )
705 : {
706 0 : SetCursor( nMarkEndCol, nMarkEndRow );
707 : }
708 :
709 0 : return true;
710 : }
711 :
712 : //----------------------------------------------------------------------------
713 :
714 0 : String ScViewFunc::GetAutoSumFormula( const ScRangeList& rRangeList, bool bSubTotal, const ScAddress& rAddr )
715 : {
716 0 : ScViewData* pViewData = GetViewData();
717 0 : ScDocument* pDoc = pViewData->GetDocument();
718 0 : ::boost::scoped_ptr<ScTokenArray> pArray(new ScTokenArray);
719 :
720 0 : pArray->AddOpCode(bSubTotal ? ocSubTotal : ocSum);
721 0 : pArray->AddOpCode(ocOpen);
722 :
723 0 : if (bSubTotal)
724 : {
725 0 : pArray->AddDouble(9);
726 0 : pArray->AddOpCode(ocSep);
727 : }
728 :
729 0 : if(!rRangeList.empty())
730 : {
731 0 : ScRangeList aRangeList = rRangeList;
732 0 : const ScRange* pFirst = aRangeList.front();
733 0 : size_t ListSize = aRangeList.size();
734 0 : for ( size_t i = 0; i < ListSize; ++i )
735 : {
736 0 : const ScRange* p = aRangeList[i];
737 0 : if (p != pFirst)
738 0 : pArray->AddOpCode(ocSep);
739 : ScComplexRefData aRef;
740 0 : aRef.InitRangeRel(*p, rAddr);
741 0 : pArray->AddDoubleReference(aRef);
742 0 : }
743 : }
744 :
745 0 : pArray->AddOpCode(ocClose);
746 :
747 0 : ScCompiler aComp(pDoc, rAddr, *pArray);
748 0 : aComp.SetGrammar(pDoc->GetGrammar());
749 0 : OUStringBuffer aBuf;
750 0 : aComp.CreateStringFromTokenArray(aBuf);
751 0 : OUString aFormula = aBuf.makeStringAndClear();
752 0 : aBuf.append(sal_Unicode('='));
753 0 : aBuf.append(aFormula);
754 0 : return aBuf.makeStringAndClear();
755 : }
756 :
757 : //----------------------------------------------------------------------------
758 :
759 0 : void ScViewFunc::EnterBlock( const String& rString, const EditTextObject* pData )
760 : {
761 : // test for multi selection
762 :
763 0 : SCCOL nCol = GetViewData()->GetCurX();
764 0 : SCROW nRow = GetViewData()->GetCurY();
765 0 : SCTAB nTab = GetViewData()->GetTabNo();
766 0 : ScMarkData& rMark = GetViewData()->GetMarkData();
767 0 : if ( rMark.IsMultiMarked() )
768 : {
769 0 : rMark.MarkToSimple();
770 0 : if ( rMark.IsMultiMarked() )
771 : { // "Insert into multi selection not possible"
772 0 : ErrorMessage(STR_MSSG_PASTEFROMCLIP_0);
773 :
774 : // insert into single cell
775 0 : if ( pData )
776 0 : EnterData(nCol, nRow, nTab, *pData);
777 : else
778 0 : EnterData( nCol, nRow, nTab, rString );
779 0 : return;
780 : }
781 : }
782 :
783 0 : ScDocument* pDoc = GetViewData()->GetDocument();
784 0 : String aNewStr = rString;
785 0 : if ( pData )
786 : {
787 0 : const ScPatternAttr* pOldPattern = pDoc->GetPattern( nCol, nRow, nTab );
788 0 : ScTabEditEngine aEngine( *pOldPattern, pDoc->GetEnginePool() );
789 0 : aEngine.SetText(*pData);
790 :
791 0 : ScEditAttrTester aTester( &aEngine );
792 0 : if (!aTester.NeedsObject())
793 : {
794 0 : aNewStr = aEngine.GetText();
795 0 : pData = NULL;
796 0 : }
797 : }
798 :
799 : // Insert via PasteFromClip
800 :
801 0 : WaitObject aWait( GetFrameWin() );
802 :
803 0 : ScAddress aPos( nCol, nRow, nTab );
804 :
805 0 : ScDocument* pInsDoc = new ScDocument( SCDOCMODE_CLIP );
806 0 : pInsDoc->ResetClip( pDoc, nTab );
807 :
808 0 : if (aNewStr.GetChar(0) == '=') // Formula ?
809 : {
810 : // SetString not possible, because in Clipboard-Documents nothing will be compiled!
811 0 : pInsDoc->SetFormulaCell(aPos, new ScFormulaCell(pDoc, aPos, aNewStr));
812 : }
813 0 : else if ( pData )
814 : {
815 : // A copy of pData will be stored.
816 0 : pInsDoc->SetEditText(aPos, *pData, pDoc->GetEditPool());
817 : }
818 : else
819 0 : pInsDoc->SetString( nCol, nRow, nTab, aNewStr );
820 :
821 0 : pInsDoc->SetClipArea( ScRange(aPos) );
822 : // insert Block, with Undo etc.
823 0 : if ( PasteFromClip( IDF_CONTENTS, pInsDoc, PASTE_NOFUNC, false, false,
824 : false, INS_NONE, IDF_ATTRIB ) )
825 : {
826 : const SfxUInt32Item* pItem = (SfxUInt32Item*) pInsDoc->GetAttr(
827 0 : nCol, nRow, nTab, ATTR_VALUE_FORMAT );
828 0 : if ( pItem )
829 : { // set number format if incompatible
830 : // MarkData was already MarkToSimple'ed in PasteFromClip
831 0 : ScRange aRange;
832 0 : rMark.GetMarkArea( aRange );
833 0 : ScPatternAttr* pPattern = new ScPatternAttr( pDoc->GetPool() );
834 0 : pPattern->GetItemSet().Put( *pItem );
835 0 : short nNewType = pDoc->GetFormatTable()->GetType( pItem->GetValue() );
836 : pDoc->ApplyPatternIfNumberformatIncompatible( aRange, rMark,
837 0 : *pPattern, nNewType );
838 0 : delete pPattern;
839 : }
840 : }
841 :
842 0 : delete pInsDoc;
843 : }
844 :
845 :
846 : //----------------------------------------------------------------------------
847 : // manual page break
848 :
849 0 : void ScViewFunc::InsertPageBreak( sal_Bool bColumn, sal_Bool bRecord, const ScAddress* pPos,
850 : sal_Bool bSetModified )
851 : {
852 0 : SCTAB nTab = GetViewData()->GetTabNo();
853 0 : ScAddress aCursor;
854 0 : if (pPos)
855 0 : aCursor = *pPos;
856 : else
857 0 : aCursor = ScAddress( GetViewData()->GetCurX(), GetViewData()->GetCurY(), nTab );
858 :
859 0 : sal_Bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
860 0 : InsertPageBreak( bColumn, aCursor, bRecord, bSetModified, false );
861 :
862 0 : if ( bSuccess && bSetModified )
863 0 : UpdatePageBreakData( true ); // for PageBreak-Mode
864 0 : }
865 :
866 :
867 : //----------------------------------------------------------------------------
868 :
869 0 : void ScViewFunc::DeletePageBreak( sal_Bool bColumn, sal_Bool bRecord, const ScAddress* pPos,
870 : sal_Bool bSetModified )
871 : {
872 0 : SCTAB nTab = GetViewData()->GetTabNo();
873 0 : ScAddress aCursor;
874 0 : if (pPos)
875 0 : aCursor = *pPos;
876 : else
877 0 : aCursor = ScAddress( GetViewData()->GetCurX(), GetViewData()->GetCurY(), nTab );
878 :
879 0 : sal_Bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
880 0 : RemovePageBreak( bColumn, aCursor, bRecord, bSetModified, false );
881 :
882 0 : if ( bSuccess && bSetModified )
883 0 : UpdatePageBreakData( true ); // for PageBreak-Mode
884 0 : }
885 :
886 : //----------------------------------------------------------------------------
887 :
888 0 : void ScViewFunc::RemoveManualBreaks()
889 : {
890 0 : ScDocShell* pDocSh = GetViewData()->GetDocShell();
891 0 : ScDocument* pDoc = pDocSh->GetDocument();
892 0 : SCTAB nTab = GetViewData()->GetTabNo();
893 0 : sal_Bool bUndo(pDoc->IsUndoEnabled());
894 :
895 0 : if (bUndo)
896 : {
897 0 : ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
898 0 : pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_True, sal_True );
899 0 : pDoc->CopyToDocument( 0,0,nTab, MAXCOL,MAXROW,nTab, IDF_NONE, false, pUndoDoc );
900 0 : pDocSh->GetUndoManager()->AddUndoAction(
901 0 : new ScUndoRemoveBreaks( pDocSh, nTab, pUndoDoc ) );
902 : }
903 :
904 0 : pDoc->RemoveManualBreaks(nTab);
905 0 : pDoc->UpdatePageBreaks(nTab);
906 :
907 0 : UpdatePageBreakData( sal_True );
908 0 : pDocSh->SetDocumentModified();
909 0 : pDocSh->PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID );
910 0 : }
911 :
912 : //----------------------------------------------------------------------------
913 :
914 0 : void ScViewFunc::SetPrintZoom(sal_uInt16 nScale, sal_uInt16 nPages)
915 : {
916 0 : ScDocShell* pDocSh = GetViewData()->GetDocShell();
917 0 : SCTAB nTab = GetViewData()->GetTabNo();
918 0 : pDocSh->SetPrintZoom( nTab, nScale, nPages );
919 0 : }
920 :
921 0 : void ScViewFunc::AdjustPrintZoom()
922 : {
923 0 : ScRange aRange;
924 0 : if ( GetViewData()->GetSimpleArea( aRange ) != SC_MARK_SIMPLE )
925 0 : GetViewData()->GetMarkData().GetMultiMarkArea( aRange );
926 0 : GetViewData()->GetDocShell()->AdjustPrintZoom( aRange );
927 0 : }
928 :
929 : //----------------------------------------------------------------------------
930 :
931 0 : void ScViewFunc::SetPrintRanges( sal_Bool bEntireSheet, const String* pPrint,
932 : const String* pRepCol, const String* pRepRow,
933 : sal_Bool bAddPrint )
934 : {
935 : // on all selected tables
936 :
937 0 : ScDocShell* pDocSh = GetViewData()->GetDocShell();
938 0 : ScDocument* pDoc = pDocSh->GetDocument();
939 0 : ScMarkData& rMark = GetViewData()->GetMarkData();
940 : SCTAB nTab;
941 0 : sal_Bool bUndo (pDoc->IsUndoEnabled());
942 :
943 0 : ScPrintRangeSaver* pOldRanges = pDoc->CreatePrintRangeSaver();
944 :
945 0 : ScAddress::Details aDetails(pDoc->GetAddressConvention(), 0, 0);
946 :
947 0 : ScMarkData::iterator itr = rMark.begin(), itrEnd = rMark.end();
948 0 : for (; itr != itrEnd; ++itr)
949 : {
950 0 : nTab = *itr;
951 0 : ScRange aRange( 0,0,nTab );
952 :
953 : // print ranges
954 :
955 0 : if( !bAddPrint )
956 0 : pDoc->ClearPrintRanges( nTab );
957 :
958 0 : if( bEntireSheet )
959 : {
960 0 : pDoc->SetPrintEntireSheet( nTab );
961 : }
962 0 : else if ( pPrint )
963 : {
964 0 : if ( pPrint->Len() )
965 : {
966 0 : const sal_Unicode sep = ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
967 0 : sal_uInt16 nTCount = comphelper::string::getTokenCount(*pPrint, sep);
968 0 : for (sal_uInt16 i=0; i<nTCount; i++)
969 : {
970 0 : String aToken = pPrint->GetToken(i, sep);
971 0 : if ( aRange.ParseAny( aToken, pDoc, aDetails ) & SCA_VALID )
972 0 : pDoc->AddPrintRange( nTab, aRange );
973 0 : }
974 : }
975 : }
976 : else // NULL = use selection (print range is always set), use empty string to delete all ranges
977 : {
978 0 : if ( GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE )
979 : {
980 0 : pDoc->AddPrintRange( nTab, aRange );
981 : }
982 0 : else if ( rMark.IsMultiMarked() )
983 : {
984 0 : rMark.MarkToMulti();
985 0 : ScRangeListRef pList( new ScRangeList );
986 0 : rMark.FillRangeListWithMarks( pList, false );
987 0 : for (size_t i = 0, n = pList->size(); i < n; ++i)
988 : {
989 0 : ScRange* pR = (*pList)[i];
990 0 : pDoc->AddPrintRange(nTab, *pR);
991 0 : }
992 : }
993 : }
994 :
995 : // repeat columns
996 :
997 0 : if ( pRepCol )
998 : {
999 0 : if ( !pRepCol->Len() )
1000 0 : pDoc->SetRepeatColRange( nTab, NULL );
1001 : else
1002 0 : if ( aRange.ParseAny( *pRepCol, pDoc, aDetails ) & SCA_VALID )
1003 0 : pDoc->SetRepeatColRange( nTab, &aRange );
1004 : }
1005 :
1006 : // repeat rows
1007 :
1008 0 : if ( pRepRow )
1009 : {
1010 0 : if ( !pRepRow->Len() )
1011 0 : pDoc->SetRepeatRowRange( nTab, NULL );
1012 : else
1013 0 : if ( aRange.ParseAny( *pRepRow, pDoc, aDetails ) & SCA_VALID )
1014 0 : pDoc->SetRepeatRowRange( nTab, &aRange );
1015 : }
1016 : }
1017 :
1018 : // undo (for all tables)
1019 0 : if (bUndo)
1020 : {
1021 0 : SCTAB nCurTab = GetViewData()->GetTabNo();
1022 0 : ScPrintRangeSaver* pNewRanges = pDoc->CreatePrintRangeSaver();
1023 0 : pDocSh->GetUndoManager()->AddUndoAction(
1024 0 : new ScUndoPrintRange( pDocSh, nCurTab, pOldRanges, pNewRanges ) );
1025 : }
1026 : else
1027 0 : delete pOldRanges;
1028 :
1029 : // update page breaks
1030 :
1031 0 : itr = rMark.begin();
1032 0 : for (; itr != itrEnd; ++itr)
1033 0 : ScPrintFunc( pDocSh, pDocSh->GetPrinter(), *itr ).UpdatePages();
1034 :
1035 0 : SfxBindings& rBindings = GetViewData()->GetBindings();
1036 0 : rBindings.Invalidate( SID_DELETE_PRINTAREA );
1037 :
1038 0 : pDocSh->SetDocumentModified();
1039 0 : }
1040 :
1041 : //----------------------------------------------------------------------------
1042 : // Merge cells
1043 :
1044 180 : sal_Bool ScViewFunc::TestMergeCells() // pre-test (for menu)
1045 : {
1046 : // simple test: sal_True if there's a selection but no multi selection and not filtered
1047 :
1048 180 : const ScMarkData& rMark = GetViewData()->GetMarkData();
1049 180 : if ( rMark.IsMarked() || rMark.IsMultiMarked() )
1050 : {
1051 2 : ScRange aDummy;
1052 2 : return GetViewData()->GetSimpleArea( aDummy) == SC_MARK_SIMPLE;
1053 : }
1054 : else
1055 178 : return false;
1056 : }
1057 :
1058 :
1059 : //----------------------------------------------------------------------------
1060 :
1061 0 : sal_Bool ScViewFunc::MergeCells( sal_Bool bApi, sal_Bool& rDoContents, sal_Bool bRecord, sal_Bool bCenter )
1062 : {
1063 : // Editable- and Being-Nested- test must be at the beginning (in DocFunc too),
1064 : // so that the Contents-QueryBox won't appear
1065 0 : ScEditableTester aTester( this );
1066 0 : if (!aTester.IsEditable())
1067 : {
1068 0 : ErrorMessage(aTester.GetMessageId());
1069 0 : return false;
1070 : }
1071 :
1072 0 : ScMarkData& rMark = GetViewData()->GetMarkData();
1073 0 : rMark.MarkToSimple();
1074 0 : if (!rMark.IsMarked())
1075 : {
1076 0 : ErrorMessage(STR_NOMULTISELECT);
1077 0 : return false;
1078 : }
1079 :
1080 0 : ScDocShell* pDocSh = GetViewData()->GetDocShell();
1081 0 : ScDocument* pDoc = pDocSh->GetDocument();
1082 :
1083 0 : ScRange aMarkRange;
1084 0 : rMark.GetMarkArea( aMarkRange );
1085 0 : SCCOL nStartCol = aMarkRange.aStart.Col();
1086 0 : SCROW nStartRow = aMarkRange.aStart.Row();
1087 0 : SCTAB nStartTab = aMarkRange.aStart.Tab();
1088 0 : SCCOL nEndCol = aMarkRange.aEnd.Col();
1089 0 : SCROW nEndRow = aMarkRange.aEnd.Row();
1090 0 : SCTAB nEndTab = aMarkRange.aEnd.Tab();
1091 0 : if ( nStartCol == nEndCol && nStartRow == nEndRow )
1092 : {
1093 : // nothing to do
1094 0 : return true;
1095 : }
1096 :
1097 0 : if ( pDoc->HasAttrib( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab,
1098 0 : HASATTR_MERGED | HASATTR_OVERLAPPED ) )
1099 : { // "Don't nest merging !"
1100 0 : ErrorMessage(STR_MSSG_MERGECELLS_0);
1101 0 : return false;
1102 : }
1103 :
1104 : // Check for the contents of all selected tables.
1105 0 : bool bAskDialog = false;
1106 0 : ScCellMergeOption aMergeOption(nStartCol, nStartRow, nEndCol, nEndRow, bCenter);
1107 0 : ScMarkData::iterator itr = rMark.begin(), itrEnd = rMark.end();
1108 0 : for (; itr != itrEnd; ++itr)
1109 : {
1110 0 : SCTAB i = *itr;
1111 0 : aMergeOption.maTabs.insert(i);
1112 :
1113 0 : if (!pDoc->IsBlockEmpty(i, nStartCol, nStartRow+1, nStartCol, nEndRow) ||
1114 0 : !pDoc->IsBlockEmpty(i, nStartCol+1, nStartRow, nEndCol, nEndRow))
1115 0 : bAskDialog = true;
1116 : }
1117 :
1118 0 : sal_Bool bOk = true;
1119 :
1120 0 : if (bAskDialog)
1121 : {
1122 0 : if (!bApi)
1123 : {
1124 : MessBox aBox( GetViewData()->GetDialogParent(),
1125 : WinBits(WB_YES_NO_CANCEL | WB_DEF_NO),
1126 0 : ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_0 ),
1127 0 : ScGlobal::GetRscString( STR_MERGE_NOTEMPTY ) );
1128 0 : sal_uInt16 nRetVal = aBox.Execute();
1129 :
1130 0 : if ( nRetVal == RET_YES )
1131 0 : rDoContents = sal_True;
1132 0 : else if ( nRetVal == RET_CANCEL )
1133 0 : bOk = false;
1134 : }
1135 : }
1136 :
1137 0 : if (bOk)
1138 : {
1139 0 : bOk = pDocSh->GetDocFunc().MergeCells( aMergeOption, rDoContents, bRecord, bApi );
1140 :
1141 0 : if (bOk)
1142 : {
1143 0 : SetCursor( nStartCol, nStartRow );
1144 : //DoneBlockMode( sal_False);
1145 0 : Unmark();
1146 :
1147 0 : pDocSh->UpdateOle(GetViewData());
1148 0 : UpdateInputLine();
1149 : }
1150 : }
1151 :
1152 0 : return bOk;
1153 : }
1154 :
1155 :
1156 : //----------------------------------------------------------------------------
1157 :
1158 180 : sal_Bool ScViewFunc::TestRemoveMerge()
1159 : {
1160 180 : sal_Bool bMerged = false;
1161 180 : ScRange aRange;
1162 180 : if (GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE)
1163 : {
1164 180 : ScDocument* pDoc = GetViewData()->GetDocument();
1165 180 : if ( pDoc->HasAttrib( aRange, HASATTR_MERGED ) )
1166 0 : bMerged = sal_True;
1167 : }
1168 180 : return bMerged;
1169 : }
1170 :
1171 :
1172 : //----------------------------------------------------------------------------
1173 :
1174 0 : static bool lcl_extendMergeRange(ScCellMergeOption& rOption, const ScRange& rRange)
1175 : {
1176 0 : bool bExtended = false;
1177 0 : if (rOption.mnStartCol > rRange.aStart.Col())
1178 : {
1179 0 : rOption.mnStartCol = rRange.aStart.Col();
1180 0 : bExtended = true;
1181 : }
1182 0 : if (rOption.mnStartRow > rRange.aStart.Row())
1183 : {
1184 0 : rOption.mnStartRow = rRange.aStart.Row();
1185 0 : bExtended = true;
1186 : }
1187 0 : if (rOption.mnEndCol < rRange.aEnd.Col())
1188 : {
1189 0 : rOption.mnEndCol = rRange.aEnd.Col();
1190 0 : bExtended = true;
1191 : }
1192 0 : if (rOption.mnEndRow < rRange.aEnd.Row())
1193 : {
1194 0 : rOption.mnEndRow = rRange.aEnd.Row();
1195 0 : bExtended = true;
1196 : }
1197 0 : return bExtended;
1198 : }
1199 :
1200 0 : sal_Bool ScViewFunc::RemoveMerge( sal_Bool bRecord )
1201 : {
1202 0 : ScRange aRange;
1203 0 : ScEditableTester aTester( this );
1204 0 : if (!aTester.IsEditable())
1205 : {
1206 0 : ErrorMessage(aTester.GetMessageId());
1207 0 : return false;
1208 : }
1209 0 : else if (GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE)
1210 : {
1211 0 : ScDocument* pDoc = GetViewData()->GetDocument();
1212 0 : ScRange aExtended( aRange );
1213 0 : pDoc->ExtendMerge( aExtended );
1214 0 : ScDocShell* pDocSh = GetViewData()->GetDocShell();
1215 0 : const ScMarkData& rMark = GetViewData()->GetMarkData();
1216 0 : ScCellMergeOption aOption(aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(), aRange.aEnd.Row());
1217 0 : bool bExtended = false;
1218 0 : do
1219 : {
1220 0 : bExtended = false;
1221 0 : ScMarkData::const_iterator itr = rMark.begin(), itrEnd = rMark.end();
1222 0 : for (; itr != itrEnd; ++itr)
1223 : {
1224 0 : SCTAB i = *itr;
1225 0 : aOption.maTabs.insert(i);
1226 0 : aExtended.aStart.SetTab(i);
1227 0 : aExtended.aEnd.SetTab(i);
1228 0 : pDoc->ExtendMerge(aExtended);
1229 0 : pDoc->ExtendOverlapped(aExtended);
1230 :
1231 : // Expand the current range to be inclusive of all merged
1232 : // areas on all sheets.
1233 0 : bExtended = lcl_extendMergeRange(aOption, aExtended);
1234 : }
1235 : }
1236 : while (bExtended);
1237 :
1238 0 : sal_Bool bOk = pDocSh->GetDocFunc().UnmergeCells(aOption, bRecord );
1239 0 : aExtended = aOption.getFirstSingleRange();
1240 0 : MarkRange( aExtended );
1241 :
1242 0 : if (bOk)
1243 0 : pDocSh->UpdateOle(GetViewData());
1244 : }
1245 0 : return sal_True; //! bOk ??
1246 : }
1247 :
1248 : //----------------------------------------------------------------------------
1249 :
1250 0 : void ScViewFunc::FillSimple( FillDir eDir, bool bRecord )
1251 : {
1252 0 : ScRange aRange;
1253 0 : if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
1254 : {
1255 0 : ScDocShell* pDocSh = GetViewData()->GetDocShell();
1256 0 : const ScMarkData& rMark = GetViewData()->GetMarkData();
1257 0 : bool bSuccess = pDocSh->GetDocFunc().FillSimple( aRange, &rMark, eDir, bRecord, false );
1258 0 : if (bSuccess)
1259 : {
1260 0 : pDocSh->UpdateOle(GetViewData());
1261 0 : UpdateScrollBars();
1262 : }
1263 : }
1264 : else
1265 0 : ErrorMessage(STR_NOMULTISELECT);
1266 0 : }
1267 :
1268 : //----------------------------------------------------------------------------
1269 :
1270 0 : void ScViewFunc::FillSeries( FillDir eDir, FillCmd eCmd, FillDateCmd eDateCmd,
1271 : double fStart, double fStep, double fMax, sal_Bool bRecord )
1272 : {
1273 0 : ScRange aRange;
1274 0 : if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
1275 : {
1276 0 : ScDocShell* pDocSh = GetViewData()->GetDocShell();
1277 0 : const ScMarkData& rMark = GetViewData()->GetMarkData();
1278 0 : sal_Bool bSuccess = pDocSh->GetDocFunc().
1279 : FillSeries( aRange, &rMark, eDir, eCmd, eDateCmd,
1280 0 : fStart, fStep, fMax, bRecord, false );
1281 0 : if (bSuccess)
1282 : {
1283 0 : pDocSh->UpdateOle(GetViewData());
1284 0 : UpdateScrollBars();
1285 :
1286 : // #i97876# Spreadsheet data changes are not notified
1287 0 : ScModelObj* pModelObj = ScModelObj::getImplementation( pDocSh->GetModel() );
1288 0 : if ( pModelObj && pModelObj->HasChangesListeners() )
1289 : {
1290 0 : ScRangeList aChangeRanges;
1291 0 : aChangeRanges.Append( aRange );
1292 0 : pModelObj->NotifyChanges( OUString( "cell-change" ), aChangeRanges );
1293 : }
1294 : }
1295 : }
1296 : else
1297 0 : ErrorMessage(STR_NOMULTISELECT);
1298 0 : }
1299 :
1300 : //----------------------------------------------------------------------------
1301 :
1302 0 : void ScViewFunc::FillAuto( FillDir eDir, SCCOL nStartCol, SCROW nStartRow,
1303 : SCCOL nEndCol, SCROW nEndRow, sal_uLong nCount, sal_Bool bRecord )
1304 : {
1305 0 : SCTAB nTab = GetViewData()->GetTabNo();
1306 0 : ScRange aRange( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab );
1307 0 : ScRange aSourceRange( aRange );
1308 0 : ScDocShell* pDocSh = GetViewData()->GetDocShell();
1309 0 : const ScMarkData& rMark = GetViewData()->GetMarkData();
1310 0 : sal_Bool bSuccess = pDocSh->GetDocFunc().
1311 0 : FillAuto( aRange, &rMark, eDir, nCount, bRecord, false );
1312 0 : if (bSuccess)
1313 : {
1314 0 : MarkRange( aRange, false ); // aRange was modified in FillAuto
1315 0 : pDocSh->UpdateOle(GetViewData());
1316 0 : UpdateScrollBars();
1317 :
1318 : // #i97876# Spreadsheet data changes are not notified
1319 0 : ScModelObj* pModelObj = ScModelObj::getImplementation( pDocSh->GetModel() );
1320 0 : if ( pModelObj && pModelObj->HasChangesListeners() )
1321 : {
1322 0 : ScRangeList aChangeRanges;
1323 0 : ScRange aChangeRange( aRange );
1324 0 : switch ( eDir )
1325 : {
1326 : case FILL_TO_BOTTOM:
1327 : {
1328 0 : aChangeRange.aStart.SetRow( aSourceRange.aEnd.Row() + 1 );
1329 : }
1330 0 : break;
1331 : case FILL_TO_TOP:
1332 : {
1333 0 : aChangeRange.aEnd.SetRow( aSourceRange.aStart.Row() - 1 );
1334 : }
1335 0 : break;
1336 : case FILL_TO_RIGHT:
1337 : {
1338 0 : aChangeRange.aStart.SetCol( aSourceRange.aEnd.Col() + 1 );
1339 : }
1340 0 : break;
1341 : case FILL_TO_LEFT:
1342 : {
1343 0 : aChangeRange.aEnd.SetCol( aSourceRange.aStart.Col() - 1 );
1344 : }
1345 0 : break;
1346 : default:
1347 : {
1348 :
1349 : }
1350 0 : break;
1351 : }
1352 0 : aChangeRanges.Append( aChangeRange );
1353 0 : pModelObj->NotifyChanges( OUString( "cell-change" ), aChangeRanges );
1354 : }
1355 : }
1356 0 : }
1357 :
1358 : //----------------------------------------------------------------------------
1359 :
1360 0 : void ScViewFunc::FillTab( sal_uInt16 nFlags, sal_uInt16 nFunction, sal_Bool bSkipEmpty, sal_Bool bAsLink )
1361 : {
1362 : //! allow source sheet to be protected
1363 0 : ScEditableTester aTester( this );
1364 0 : if (!aTester.IsEditable())
1365 : {
1366 0 : ErrorMessage(aTester.GetMessageId());
1367 0 : return;
1368 : }
1369 :
1370 0 : ScDocShell* pDocSh = GetViewData()->GetDocShell();
1371 0 : ScDocument* pDoc = pDocSh->GetDocument();
1372 0 : ScMarkData& rMark = GetViewData()->GetMarkData();
1373 0 : SCTAB nTab = GetViewData()->GetTabNo();
1374 0 : sal_Bool bUndo(pDoc->IsUndoEnabled());
1375 :
1376 0 : ScRange aMarkRange;
1377 0 : rMark.MarkToSimple();
1378 0 : sal_Bool bMulti = rMark.IsMultiMarked();
1379 0 : if (bMulti)
1380 0 : rMark.GetMultiMarkArea( aMarkRange );
1381 0 : else if (rMark.IsMarked())
1382 0 : rMark.GetMarkArea( aMarkRange );
1383 : else
1384 0 : aMarkRange = ScRange( GetViewData()->GetCurX(), GetViewData()->GetCurY(), nTab );
1385 :
1386 0 : ScDocument* pUndoDoc = NULL;
1387 :
1388 0 : if (bUndo)
1389 : {
1390 0 : pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
1391 0 : pUndoDoc->InitUndo( pDoc, nTab, nTab );
1392 :
1393 0 : ScMarkData::iterator itr = rMark.begin(), itrEnd = rMark.end();
1394 0 : for (; itr != itrEnd; ++itr)
1395 0 : if (*itr != nTab )
1396 : {
1397 0 : SCTAB i = *itr;
1398 0 : pUndoDoc->AddUndoTab( i, i );
1399 0 : aMarkRange.aStart.SetTab( i );
1400 0 : aMarkRange.aEnd.SetTab( i );
1401 0 : pDoc->CopyToDocument( aMarkRange, IDF_ALL, bMulti, pUndoDoc );
1402 : }
1403 : }
1404 :
1405 0 : if (bMulti)
1406 0 : pDoc->FillTabMarked( nTab, rMark, nFlags, nFunction, bSkipEmpty, bAsLink );
1407 : else
1408 : {
1409 0 : aMarkRange.aStart.SetTab( nTab );
1410 0 : aMarkRange.aEnd.SetTab( nTab );
1411 0 : pDoc->FillTab( aMarkRange, rMark, nFlags, nFunction, bSkipEmpty, bAsLink );
1412 : }
1413 :
1414 0 : if (bUndo)
1415 : { //! for ChangeTrack not until the end
1416 0 : pDocSh->GetUndoManager()->AddUndoAction(
1417 : new ScUndoFillTable( pDocSh, rMark,
1418 0 : aMarkRange.aStart.Col(), aMarkRange.aStart.Row(), nTab,
1419 0 : aMarkRange.aEnd.Col(), aMarkRange.aEnd.Row(), nTab,
1420 0 : pUndoDoc, bMulti, nTab, nFlags, nFunction, bSkipEmpty, bAsLink ) );
1421 : }
1422 :
1423 0 : pDocSh->PostPaintGridAll();
1424 0 : pDocSh->PostDataChanged();
1425 : }
1426 :
1427 : //----------------------------------------------------------------------------
1428 :
1429 : /** Downward fill of selected cell(s) by double-clicking cross-hair cursor
1430 :
1431 : Extends a current selection down to the last non-empty cell of an adjacent
1432 : column when the lower-right corner of the selection is double-clicked. It
1433 : uses a left-adjoining non-empty column as a guide if such is available,
1434 : otherwise a right-adjoining non-empty column is used.
1435 :
1436 : @author Kohei Yoshida (kohei@openoffice.org)
1437 :
1438 : @return No return value
1439 :
1440 : @see #i12313#
1441 : */
1442 0 : void ScViewFunc::FillCrossDblClick()
1443 : {
1444 0 : ScRange aRange;
1445 0 : GetViewData()->GetSimpleArea( aRange );
1446 0 : aRange.Justify();
1447 :
1448 0 : SCTAB nTab = GetViewData()->GetCurPos().Tab();
1449 0 : SCCOL nStartX = aRange.aStart.Col();
1450 0 : SCROW nStartY = aRange.aStart.Row();
1451 0 : SCCOL nEndX = aRange.aEnd.Col();
1452 0 : SCROW nEndY = aRange.aEnd.Row();
1453 :
1454 0 : ScDocument* pDoc = GetViewData()->GetDocument();
1455 :
1456 : // Make sure the selection is not empty
1457 0 : if ( pDoc->IsBlockEmpty( nTab, nStartX, nStartY, nEndX, nEndY ) )
1458 0 : return;
1459 :
1460 0 : if ( nEndY < MAXROW )
1461 : {
1462 0 : if ( nStartX > 0 )
1463 : {
1464 0 : SCCOL nMovX = nStartX - 1;
1465 0 : SCROW nMovY = nStartY;
1466 :
1467 0 : if ( pDoc->HasData( nMovX, nStartY, nTab ) &&
1468 0 : pDoc->HasData( nMovX, nStartY + 1, nTab ) )
1469 : {
1470 0 : pDoc->FindAreaPos( nMovX, nMovY, nTab, SC_MOVE_DOWN );
1471 :
1472 0 : if ( nMovY > nEndY )
1473 : {
1474 : FillAuto( FILL_TO_BOTTOM, nStartX, nStartY, nEndX, nEndY,
1475 0 : nMovY - nEndY );
1476 0 : return;
1477 : }
1478 : }
1479 : }
1480 :
1481 0 : if ( nEndX < MAXCOL )
1482 : {
1483 0 : SCCOL nMovX = nEndX + 1;
1484 0 : SCROW nMovY = nStartY;
1485 :
1486 0 : if ( pDoc->HasData( nMovX, nStartY, nTab ) &&
1487 0 : pDoc->HasData( nMovX, nStartY + 1, nTab ) )
1488 : {
1489 0 : pDoc->FindAreaPos( nMovX, nMovY, nTab, SC_MOVE_DOWN );
1490 :
1491 0 : if ( nMovY > nEndY )
1492 : {
1493 : FillAuto( FILL_TO_BOTTOM, nStartX, nStartY, nEndX, nEndY,
1494 0 : nMovY - nEndY );
1495 0 : return;
1496 : }
1497 : }
1498 : }
1499 : }
1500 : }
1501 :
1502 : //----------------------------------------------------------------------------
1503 :
1504 0 : void ScViewFunc::TransliterateText( sal_Int32 nType )
1505 : {
1506 0 : ScMarkData aFuncMark = GetViewData()->GetMarkData();
1507 0 : if ( !aFuncMark.IsMarked() && !aFuncMark.IsMultiMarked() )
1508 : {
1509 : // no selection -> use cursor position
1510 :
1511 0 : ScAddress aCursor( GetViewData()->GetCurX(), GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
1512 0 : aFuncMark.SetMarkArea( ScRange( aCursor ) );
1513 : }
1514 :
1515 0 : sal_Bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
1516 0 : TransliterateText( aFuncMark, nType, sal_True, false );
1517 0 : if (bSuccess)
1518 : {
1519 0 : GetViewData()->GetViewShell()->UpdateInputHandler();
1520 0 : }
1521 0 : }
1522 :
1523 : //----------------------------------------------------------------------------
1524 : // AutoFormat
1525 :
1526 0 : ScAutoFormatData* ScViewFunc::CreateAutoFormatData()
1527 : {
1528 0 : ScAutoFormatData* pData = NULL;
1529 : SCCOL nStartCol;
1530 : SCROW nStartRow;
1531 : SCTAB nStartTab;
1532 : SCCOL nEndCol;
1533 : SCROW nEndRow;
1534 : SCTAB nEndTab;
1535 0 : if (GetViewData()->GetSimpleArea(nStartCol,nStartRow,nStartTab,nEndCol,nEndRow,nEndTab) == SC_MARK_SIMPLE)
1536 : {
1537 0 : if ( nEndCol-nStartCol >= 3 && nEndRow-nStartRow >= 3 )
1538 : {
1539 0 : ScDocument* pDoc = GetViewData()->GetDocument();
1540 0 : pData = new ScAutoFormatData;
1541 0 : pDoc->GetAutoFormatData( nStartTab, nStartCol,nStartRow,nEndCol,nEndRow, *pData );
1542 : }
1543 : }
1544 0 : return pData;
1545 : }
1546 :
1547 :
1548 : //----------------------------------------------------------------------------
1549 :
1550 0 : void ScViewFunc::AutoFormat( sal_uInt16 nFormatNo, sal_Bool bRecord )
1551 : {
1552 0 : ScRange aRange;
1553 0 : if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
1554 : {
1555 0 : ScDocShell* pDocSh = GetViewData()->GetDocShell();
1556 0 : ScMarkData& rMark = GetViewData()->GetMarkData();
1557 :
1558 0 : sal_Bool bSuccess = pDocSh->GetDocFunc().AutoFormat( aRange, &rMark, nFormatNo, bRecord, false );
1559 0 : if (bSuccess)
1560 0 : pDocSh->UpdateOle(GetViewData());
1561 : }
1562 : else
1563 0 : ErrorMessage(STR_NOMULTISELECT);
1564 0 : }
1565 :
1566 :
1567 : //----------------------------------------------------------------------------
1568 : // Suchen & Ersetzen
1569 :
1570 0 : void ScViewFunc::SearchAndReplace( const SvxSearchItem* pSearchItem,
1571 : sal_Bool bAddUndo, sal_Bool bIsApi )
1572 : {
1573 0 : ScDocShell* pDocSh = GetViewData()->GetDocShell();
1574 0 : ScDocument* pDoc = pDocSh->GetDocument();
1575 0 : ScMarkData& rMark = GetViewData()->GetMarkData();
1576 0 : if (bAddUndo && !pDoc->IsUndoEnabled())
1577 0 : bAddUndo = false;
1578 :
1579 : SCCOL nCol, nOldCol;
1580 : SCROW nRow, nOldRow;
1581 : SCTAB nTab, nOldTab;
1582 0 : nCol = nOldCol = GetViewData()->GetCurX();
1583 0 : nRow = nOldRow = GetViewData()->GetCurY();
1584 0 : nTab = nOldTab = GetViewData()->GetTabNo();
1585 :
1586 0 : sal_uInt16 nCommand = pSearchItem->GetCommand();
1587 0 : bool bAllTables = pSearchItem->IsAllTables();
1588 0 : std::set<SCTAB> aOldSelectedTables;
1589 0 : SCTAB nLastTab = pDoc->GetTableCount() - 1;
1590 : SCTAB nStartTab, nEndTab;
1591 0 : if ( bAllTables )
1592 : {
1593 0 : nStartTab = 0;
1594 0 : nEndTab = nLastTab;
1595 0 : std::set<SCTAB> aTmp(rMark.begin(), rMark.end());
1596 0 : aOldSelectedTables.swap(aTmp);
1597 : }
1598 : else
1599 : { //! at least one is always selected
1600 0 : nStartTab = rMark.GetFirstSelected();
1601 0 : nEndTab = rMark.GetLastSelected();
1602 : }
1603 :
1604 0 : if ( nCommand == SVX_SEARCHCMD_FIND
1605 0 : || nCommand == SVX_SEARCHCMD_FIND_ALL)
1606 0 : bAddUndo = false;
1607 :
1608 : //! account for bAttrib during Undo !!!
1609 :
1610 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
1611 0 : std::auto_ptr<ScDocument> pUndoDoc;
1612 0 : std::auto_ptr<ScMarkData> pUndoMark;
1613 : SAL_WNODEPRECATED_DECLARATIONS_POP
1614 0 : OUString aUndoStr;
1615 0 : if (bAddUndo)
1616 : {
1617 0 : pUndoMark.reset(new ScMarkData(rMark)); // Mark is being modified
1618 0 : if ( nCommand == SVX_SEARCHCMD_REPLACE_ALL )
1619 : {
1620 0 : pUndoDoc.reset(new ScDocument(SCDOCMODE_UNDO));
1621 0 : pUndoDoc->InitUndo( pDoc, nStartTab, nEndTab );
1622 : }
1623 : }
1624 :
1625 0 : if ( bAllTables )
1626 : { //! select all, after pUndoMark has been created
1627 0 : for ( SCTAB j = nStartTab; j <= nEndTab; j++ )
1628 : {
1629 0 : rMark.SelectTable( j, true );
1630 : }
1631 : }
1632 :
1633 0 : DoneBlockMode(true); // don't delete mark
1634 0 : InitOwnBlockMode();
1635 :
1636 : // If search starts at the beginning don't ask again whether it shall start at the beginning
1637 0 : bool bFirst = true;
1638 0 : if ( nCol == 0 && nRow == 0 && nTab == nStartTab && !pSearchItem->GetBackward() )
1639 0 : bFirst = false;
1640 :
1641 0 : bool bFound = false;
1642 : while (true)
1643 : {
1644 0 : GetFrameWin()->EnterWait();
1645 0 : ScRangeList aMatchedRanges;
1646 0 : if (pDoc->SearchAndReplace(*pSearchItem, nCol, nRow, nTab, rMark, aMatchedRanges, aUndoStr, pUndoDoc.get()))
1647 : {
1648 0 : bFound = true;
1649 0 : bFirst = true;
1650 0 : if (bAddUndo)
1651 : {
1652 0 : GetViewData()->GetDocShell()->GetUndoManager()->AddUndoAction(
1653 0 : new ScUndoReplace( GetViewData()->GetDocShell(), *pUndoMark,
1654 : nCol, nRow, nTab,
1655 0 : aUndoStr, pUndoDoc.release(), pSearchItem ) );
1656 : }
1657 :
1658 0 : if (nCommand == SVX_SEARCHCMD_FIND_ALL || nCommand == SVX_SEARCHCMD_REPLACE_ALL)
1659 : {
1660 0 : rMark.ResetMark();
1661 0 : for (size_t i = 0, n = aMatchedRanges.size(); i < n; ++i)
1662 : {
1663 0 : const ScRange& r = *aMatchedRanges[i];
1664 0 : if (r.aStart.Tab() == nTab)
1665 0 : rMark.SetMultiMarkArea(r);
1666 : }
1667 : }
1668 :
1669 0 : break; // break 'while (TRUE)'
1670 : }
1671 0 : else if ( bFirst && (nCommand == SVX_SEARCHCMD_FIND ||
1672 : nCommand == SVX_SEARCHCMD_REPLACE) )
1673 : {
1674 0 : bFirst = false;
1675 : sal_uInt16 nRetVal;
1676 0 : GetFrameWin()->LeaveWait();
1677 0 : if ( bIsApi )
1678 0 : nRetVal = RET_NO;
1679 : else
1680 : {
1681 : // search dialog as parent (if available)
1682 0 : Window* pParent = GetParentOrChild(SID_SEARCH_DLG);
1683 : sal_uInt16 nStrId;
1684 0 : if ( pSearchItem->GetBackward() )
1685 : {
1686 0 : if ( nStartTab == nEndTab )
1687 0 : nStrId = STR_MSSG_SEARCHANDREPLACE_1;
1688 : else
1689 0 : nStrId = STR_MSSG_SEARCHANDREPLACE_4;
1690 : }
1691 : else
1692 : {
1693 0 : if ( nStartTab == nEndTab )
1694 0 : nStrId = STR_MSSG_SEARCHANDREPLACE_2;
1695 : else
1696 0 : nStrId = STR_MSSG_SEARCHANDREPLACE_5;
1697 : }
1698 : MessBox aBox( pParent, WinBits(WB_YES_NO | WB_DEF_YES),
1699 0 : ScGlobal::GetRscString( STR_MSSG_SEARCHANDREPLACE_3 ),
1700 0 : ScGlobal::GetRscString( nStrId ) );
1701 0 : nRetVal = aBox.Execute();
1702 : }
1703 :
1704 0 : if ( nRetVal == RET_YES )
1705 : {
1706 0 : ScDocument::GetSearchAndReplaceStart( *pSearchItem, nCol, nRow );
1707 0 : if (pSearchItem->GetBackward())
1708 0 : nTab = nEndTab;
1709 : else
1710 0 : nTab = nStartTab;
1711 : }
1712 : else
1713 : {
1714 0 : break; // break 'while (TRUE)'
1715 0 : }
1716 : }
1717 : else // nothing found
1718 : {
1719 0 : if ( nCommand == SVX_SEARCHCMD_FIND_ALL || nCommand == SVX_SEARCHCMD_REPLACE_ALL )
1720 : {
1721 0 : pDocSh->PostPaintGridAll(); // Mark
1722 : }
1723 :
1724 0 : GetFrameWin()->LeaveWait();
1725 0 : if (!bIsApi)
1726 : {
1727 : // search dialog as parent if available
1728 0 : Window* pParent = GetParentOrChild(SID_SEARCH_DLG);
1729 : // "nothing found"
1730 0 : InfoBox aBox( pParent, ScGlobal::GetRscString( STR_MSSG_SEARCHANDREPLACE_0 ) );
1731 0 : aBox.Execute();
1732 : }
1733 :
1734 0 : break; // break 'while (TRUE)'
1735 : }
1736 0 : } // of while true
1737 :
1738 0 : if (!aOldSelectedTables.empty())
1739 : {
1740 : // restore originally selected table
1741 0 : for (SCTAB i = 0; i <= nEndTab; ++i)
1742 0 : rMark.SelectTable(i, false);
1743 :
1744 0 : std::set<SCTAB>::const_iterator itr = aOldSelectedTables.begin(), itrEnd = aOldSelectedTables.end();
1745 0 : for (; itr != itrEnd; ++itr)
1746 0 : rMark.SelectTable(*itr, true);
1747 :
1748 0 : if ( bFound )
1749 : { // if a table is selected as a "match" it remains selected.
1750 0 : rMark.SelectTable( nTab, true );
1751 : // It's a swap if only one table was selected before
1752 : //! otherwise now one table more might be selected
1753 0 : if ( aOldSelectedTables.size() == 1 && nTab != nOldTab )
1754 0 : rMark.SelectTable( nOldTab, false );
1755 : }
1756 : }
1757 :
1758 0 : MarkDataChanged();
1759 :
1760 0 : if ( bFound )
1761 : {
1762 0 : if ( nTab != GetViewData()->GetTabNo() )
1763 0 : SetTabNo( nTab );
1764 :
1765 : // if nothing is marked, DoneBlockMode, then marking can start
1766 : // directly from this place via Shift-Cursor
1767 0 : if (!rMark.IsMarked() && !rMark.IsMultiMarked())
1768 0 : DoneBlockMode(true);
1769 :
1770 0 : AlignToCursor( nCol, nRow, SC_FOLLOW_JUMP );
1771 0 : SetCursor( nCol, nRow, true );
1772 :
1773 0 : if ( nCommand == SVX_SEARCHCMD_REPLACE
1774 0 : || nCommand == SVX_SEARCHCMD_REPLACE_ALL )
1775 : {
1776 0 : if ( nCommand == SVX_SEARCHCMD_REPLACE )
1777 : {
1778 0 : pDocSh->PostPaint( nCol,nRow,nTab, nCol,nRow,nTab, PAINT_GRID );
1779 :
1780 : // jump to next cell if we replaced everything in the cell
1781 : // where the cursor was positioned (but avoid switching tabs)
1782 0 : if ( nCol == nOldCol && nRow == nOldRow && nTab == nOldTab )
1783 : {
1784 0 : SvxSearchItem aSearchItem = ScGlobal::GetSearchItem();
1785 0 : aSearchItem.SetCommand(SVX_SEARCHCMD_FIND);
1786 0 : aSearchItem.SetWhich(SID_SEARCH_ITEM);
1787 :
1788 0 : ScRangeList aMatchedRanges;
1789 0 : ScTable::UpdateSearchItemAddressForReplace( aSearchItem, nCol, nRow );
1790 0 : if ( pDoc->SearchAndReplace( aSearchItem, nCol, nRow, nTab, rMark, aMatchedRanges, aUndoStr, NULL ) &&
1791 0 : ( nTab == nOldTab ) &&
1792 0 : ( nCol != nOldCol || nRow != nOldRow ) )
1793 : {
1794 0 : SetCursor( nCol, nRow, true );
1795 0 : }
1796 : }
1797 : }
1798 : else
1799 0 : pDocSh->PostPaintGridAll();
1800 0 : pDocSh->SetDocumentModified();
1801 : }
1802 0 : else if ( nCommand == SVX_SEARCHCMD_FIND_ALL )
1803 0 : pDocSh->PostPaintGridAll(); // mark
1804 0 : GetFrameWin()->LeaveWait();
1805 0 : }
1806 0 : }
1807 :
1808 :
1809 : //----------------------------------------------------------------------------
1810 : // Zielwertsuche
1811 :
1812 0 : void ScViewFunc::Solve( const ScSolveParam& rParam )
1813 : {
1814 0 : ScDocument* pDoc = GetViewData()->GetDocument();
1815 :
1816 0 : SCCOL nDestCol = rParam.aRefVariableCell.Col();
1817 0 : SCROW nDestRow = rParam.aRefVariableCell.Row();
1818 0 : SCTAB nDestTab = rParam.aRefVariableCell.Tab();
1819 :
1820 0 : ScEditableTester aTester( pDoc, nDestTab, nDestCol,nDestRow, nDestCol,nDestRow );
1821 0 : if (!aTester.IsEditable())
1822 : {
1823 0 : ErrorMessage(aTester.GetMessageId());
1824 0 : return;
1825 : }
1826 :
1827 0 : if ( pDoc )
1828 : {
1829 0 : String aTargetValStr;
1830 0 : if ( rParam.pStrTargetVal != NULL )
1831 0 : aTargetValStr = *(rParam.pStrTargetVal);
1832 :
1833 0 : OUString aMsgStr;
1834 0 : OUString aResStr;
1835 : double nSolveResult;
1836 :
1837 0 : GetFrameWin()->EnterWait();
1838 :
1839 : sal_Bool bExact =
1840 : pDoc->Solver(
1841 0 : rParam.aRefFormulaCell.Col(),
1842 : rParam.aRefFormulaCell.Row(),
1843 0 : rParam.aRefFormulaCell.Tab(),
1844 : nDestCol, nDestRow, nDestTab,
1845 : aTargetValStr,
1846 0 : nSolveResult );
1847 :
1848 0 : GetFrameWin()->LeaveWait();
1849 :
1850 0 : SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
1851 0 : sal_uLong nFormat = 0;
1852 0 : const ScPatternAttr* pPattern = pDoc->GetPattern( nDestCol, nDestRow, nDestTab );
1853 0 : if ( pPattern )
1854 0 : nFormat = pPattern->GetNumberFormat( pFormatter );
1855 : Color* p;
1856 0 : pFormatter->GetOutputString( nSolveResult, nFormat, aResStr, &p );
1857 :
1858 0 : if ( bExact )
1859 : {
1860 0 : aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_0 );
1861 0 : aMsgStr += aResStr;
1862 0 : aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_1 );
1863 : }
1864 : else
1865 : {
1866 0 : aMsgStr = ScGlobal::GetRscString( STR_MSSG_SOLVE_2 );
1867 0 : aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_3 );
1868 0 : aMsgStr += aResStr ;
1869 0 : aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_4 );
1870 : }
1871 :
1872 : MessBox aBox( GetViewData()->GetDialogParent(),
1873 : WinBits(WB_YES_NO | WB_DEF_NO),
1874 0 : ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_0 ), aMsgStr );
1875 0 : sal_uInt16 nRetVal = aBox.Execute();
1876 :
1877 0 : if ( RET_YES == nRetVal )
1878 0 : EnterValue( nDestCol, nDestRow, nDestTab, nSolveResult );
1879 :
1880 0 : GetViewData()->GetViewShell()->UpdateInputHandler( sal_True );
1881 : }
1882 : }
1883 :
1884 :
1885 : //----------------------------------------------------------------------------
1886 : // multi operation
1887 :
1888 0 : void ScViewFunc::TabOp( const ScTabOpParam& rParam, sal_Bool bRecord )
1889 : {
1890 0 : ScRange aRange;
1891 0 : if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
1892 : {
1893 0 : ScDocShell* pDocSh = GetViewData()->GetDocShell();
1894 0 : ScMarkData& rMark = GetViewData()->GetMarkData();
1895 0 : pDocSh->GetDocFunc().TabOp( aRange, &rMark, rParam, bRecord, false );
1896 : }
1897 : else
1898 0 : ErrorMessage(STR_NOMULTISELECT);
1899 0 : }
1900 :
1901 :
1902 : //----------------------------------------------------------------------------
1903 :
1904 0 : void ScViewFunc::MakeScenario( const String& rName, const String& rComment,
1905 : const Color& rColor, sal_uInt16 nFlags )
1906 : {
1907 0 : ScDocShell* pDocSh = GetViewData()->GetDocShell();
1908 0 : ScMarkData& rMark = GetViewData()->GetMarkData();
1909 0 : SCTAB nTab = GetViewData()->GetTabNo();
1910 :
1911 0 : SCTAB nNewTab = pDocSh->MakeScenario( nTab, rName, rComment, rColor, nFlags, rMark );
1912 0 : if (nFlags & SC_SCENARIO_COPYALL)
1913 0 : SetTabNo( nNewTab, true ); // SC_SCENARIO_COPYALL -> visible
1914 : else
1915 : {
1916 0 : SfxBindings& rBindings = GetViewData()->GetBindings();
1917 0 : rBindings.Invalidate( SID_STATUS_DOCPOS ); // Statusbar
1918 0 : rBindings.Invalidate( SID_TABLES_COUNT );
1919 0 : rBindings.Invalidate( SID_SELECT_SCENARIO );
1920 0 : rBindings.Invalidate( FID_TABLE_SHOW );
1921 : }
1922 0 : }
1923 :
1924 :
1925 : //----------------------------------------------------------------------------
1926 :
1927 0 : void ScViewFunc::ExtendScenario()
1928 : {
1929 0 : ScEditableTester aTester( this );
1930 0 : if (!aTester.IsEditable())
1931 : {
1932 0 : ErrorMessage(aTester.GetMessageId());
1933 0 : return;
1934 : }
1935 :
1936 : // Undo: apply attributes
1937 :
1938 0 : ScDocument* pDoc = GetViewData()->GetDocument();
1939 0 : ScPatternAttr aPattern( pDoc->GetPool() );
1940 0 : aPattern.GetItemSet().Put( ScMergeFlagAttr( SC_MF_SCENARIO ) );
1941 0 : aPattern.GetItemSet().Put( ScProtectionAttr( sal_True ) );
1942 0 : ApplySelectionPattern(aPattern);
1943 : }
1944 :
1945 :
1946 : //----------------------------------------------------------------------------
1947 :
1948 0 : void ScViewFunc::UseScenario( const String& rName )
1949 : {
1950 0 : ScDocShell* pDocSh = GetViewData()->GetDocShell();
1951 0 : SCTAB nTab = GetViewData()->GetTabNo();
1952 :
1953 0 : DoneBlockMode();
1954 0 : InitOwnBlockMode();
1955 0 : pDocSh->UseScenario( nTab, rName );
1956 0 : }
1957 :
1958 :
1959 : //----------------------------------------------------------------------------
1960 : // Insert table
1961 :
1962 16 : sal_Bool ScViewFunc::InsertTable( const String& rName, SCTAB nTab, sal_Bool bRecord )
1963 : {
1964 : // Order Tabl/Name is inverted for DocFunc
1965 16 : sal_Bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
1966 16 : InsertTable( nTab, rName, bRecord, false );
1967 16 : if (bSuccess)
1968 16 : SetTabNo( nTab, sal_True );
1969 :
1970 16 : return bSuccess;
1971 : }
1972 :
1973 : //----------------------------------------------------------------------------
1974 : // Insert tables
1975 :
1976 0 : sal_Bool ScViewFunc::InsertTables(std::vector<OUString>& aNames, SCTAB nTab,
1977 : SCTAB nCount, sal_Bool bRecord )
1978 : {
1979 0 : ScDocShell* pDocSh = GetViewData()->GetDocShell();
1980 0 : ScDocument* pDoc = pDocSh->GetDocument();
1981 0 : if (bRecord && !pDoc->IsUndoEnabled())
1982 0 : bRecord = false;
1983 :
1984 0 : WaitObject aWait( GetFrameWin() );
1985 :
1986 0 : if (bRecord)
1987 : {
1988 0 : pDoc->BeginDrawUndo(); // InsertTab creates a SdrUndoNewPage
1989 : }
1990 :
1991 0 : bool bFlag=false;
1992 :
1993 0 : if(aNames.empty())
1994 : {
1995 0 : pDoc->CreateValidTabNames(aNames, nCount);
1996 : }
1997 0 : if (pDoc->InsertTabs(nTab, aNames, false))
1998 : {
1999 0 : pDocSh->Broadcast( ScTablesHint( SC_TABS_INSERTED, nTab, nCount ) );
2000 0 : bFlag = true;
2001 : }
2002 :
2003 0 : if (bFlag)
2004 : {
2005 0 : if (bRecord)
2006 0 : pDocSh->GetUndoManager()->AddUndoAction(
2007 0 : new ScUndoInsertTables( pDocSh, nTab, aNames));
2008 :
2009 : // Update views
2010 :
2011 0 : SetTabNo( nTab, true );
2012 0 : pDocSh->PostPaintExtras();
2013 0 : pDocSh->SetDocumentModified();
2014 0 : SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
2015 0 : return true;
2016 : }
2017 : else
2018 : {
2019 0 : return false;
2020 0 : }
2021 : }
2022 :
2023 :
2024 : //----------------------------------------------------------------------------
2025 :
2026 0 : sal_Bool ScViewFunc::AppendTable( const String& rName, sal_Bool bRecord )
2027 : {
2028 0 : ScDocShell* pDocSh = GetViewData()->GetDocShell();
2029 0 : ScDocument* pDoc = pDocSh->GetDocument();
2030 0 : if (bRecord && !pDoc->IsUndoEnabled())
2031 0 : bRecord = false;
2032 :
2033 0 : WaitObject aWait( GetFrameWin() );
2034 :
2035 0 : if (bRecord)
2036 0 : pDoc->BeginDrawUndo(); // InsertTab creates a SdrUndoNewPage
2037 :
2038 0 : if (pDoc->InsertTab( SC_TAB_APPEND, rName ))
2039 : {
2040 0 : SCTAB nTab = pDoc->GetTableCount()-1;
2041 0 : if (bRecord)
2042 0 : pDocSh->GetUndoManager()->AddUndoAction(
2043 0 : new ScUndoInsertTab( pDocSh, nTab, sal_True, rName));
2044 0 : GetViewData()->InsertTab( nTab );
2045 0 : SetTabNo( nTab, sal_True );
2046 0 : pDocSh->PostPaintExtras();
2047 0 : pDocSh->SetDocumentModified();
2048 0 : SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
2049 0 : return sal_True;
2050 : }
2051 : else
2052 : {
2053 0 : return false;
2054 0 : }
2055 : }
2056 :
2057 :
2058 : //----------------------------------------------------------------------------
2059 :
2060 0 : sal_Bool ScViewFunc::DeleteTable( SCTAB nTab, sal_Bool bRecord )
2061 : {
2062 0 : ScDocShell* pDocSh = GetViewData()->GetDocShell();
2063 0 : ScDocument* pDoc = pDocSh->GetDocument();
2064 :
2065 0 : sal_Bool bSuccess = pDocSh->GetDocFunc().DeleteTable( nTab, bRecord, false );
2066 0 : if (bSuccess)
2067 : {
2068 0 : SCTAB nNewTab = nTab;
2069 0 : if ( nNewTab >= pDoc->GetTableCount() )
2070 0 : --nNewTab;
2071 0 : SetTabNo( nNewTab, sal_True );
2072 : }
2073 0 : return bSuccess;
2074 : }
2075 :
2076 : //only use this method for undo for now, all sheets must be connected
2077 : //this method doesn't support undo for now, merge it when it with the other method later
2078 0 : bool ScViewFunc::DeleteTables( const SCTAB nTab, SCTAB nSheets )
2079 : {
2080 0 : ScDocShell* pDocSh = GetViewData()->GetDocShell();
2081 0 : ScDocument* pDoc = pDocSh->GetDocument();
2082 0 : bool bVbaEnabled = pDoc->IsInVBAMode();
2083 0 : SCTAB nNewTab = nTab;
2084 0 : WaitObject aWait( GetFrameWin() );
2085 :
2086 0 : while ( nNewTab > 0 && !pDoc->IsVisible( nNewTab ) )
2087 0 : --nNewTab;
2088 :
2089 0 : if (pDoc->DeleteTabs(nTab, nSheets, NULL))
2090 : {
2091 0 : if( bVbaEnabled )
2092 : {
2093 0 : for (SCTAB aTab = 0; aTab < nSheets; ++aTab)
2094 : {
2095 0 : OUString sCodeName;
2096 0 : bool bHasCodeName = pDoc->GetCodeName( nTab + aTab, sCodeName );
2097 0 : if ( bHasCodeName )
2098 0 : VBA_DeleteModule( *pDocSh, sCodeName );
2099 0 : }
2100 : }
2101 :
2102 0 : pDocSh->Broadcast( ScTablesHint( SC_TABS_DELETED, nTab, nSheets ) );
2103 0 : if ( nNewTab >= pDoc->GetTableCount() )
2104 0 : nNewTab = pDoc->GetTableCount() - 1;
2105 0 : SetTabNo( nNewTab, sal_True );
2106 :
2107 0 : pDocSh->PostPaintExtras();
2108 0 : pDocSh->SetDocumentModified();
2109 :
2110 0 : SfxApplication* pSfxApp = SFX_APP(); // Navigator
2111 0 : pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
2112 0 : pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_DBAREAS_CHANGED ) );
2113 0 : pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
2114 0 : return true;
2115 : }
2116 0 : return false;
2117 : }
2118 :
2119 0 : sal_Bool ScViewFunc::DeleteTables(const vector<SCTAB> &TheTabs, sal_Bool bRecord )
2120 : {
2121 0 : ScDocShell* pDocSh = GetViewData()->GetDocShell();
2122 0 : ScDocument* pDoc = pDocSh->GetDocument();
2123 0 : sal_Bool bVbaEnabled = pDoc->IsInVBAMode();
2124 0 : SCTAB nNewTab = TheTabs.front();
2125 0 : WaitObject aWait( GetFrameWin() );
2126 0 : if (bRecord && !pDoc->IsUndoEnabled())
2127 0 : bRecord = false;
2128 0 : if ( bVbaEnabled )
2129 0 : bRecord = false;
2130 :
2131 0 : while ( nNewTab > 0 && !pDoc->IsVisible( nNewTab ) )
2132 0 : --nNewTab;
2133 :
2134 0 : sal_Bool bWasLinked = false;
2135 0 : ScDocument* pUndoDoc = NULL;
2136 0 : ScRefUndoData* pUndoData = NULL;
2137 0 : if (bRecord)
2138 : {
2139 0 : pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
2140 0 : SCTAB nCount = pDoc->GetTableCount();
2141 :
2142 0 : OUString aOldName;
2143 0 : for(unsigned int i=0; i<TheTabs.size(); ++i)
2144 : {
2145 0 : SCTAB nTab = TheTabs[i];
2146 0 : if (i==0)
2147 0 : pUndoDoc->InitUndo( pDoc, nTab,nTab, true,true ); // incl. column/fow flags
2148 : else
2149 0 : pUndoDoc->AddUndoTab( nTab,nTab, true,true ); // incl. column/fow flags
2150 :
2151 0 : pDoc->CopyToDocument(0,0,nTab, MAXCOL,MAXROW,nTab, IDF_ALL,false, pUndoDoc );
2152 0 : pDoc->GetName( nTab, aOldName );
2153 0 : pUndoDoc->RenameTab( nTab, aOldName, false );
2154 0 : if (pDoc->IsLinked(nTab))
2155 : {
2156 0 : bWasLinked = sal_True;
2157 0 : pUndoDoc->SetLink( nTab, pDoc->GetLinkMode(nTab), pDoc->GetLinkDoc(nTab),
2158 : pDoc->GetLinkFlt(nTab), pDoc->GetLinkOpt(nTab),
2159 : pDoc->GetLinkTab(nTab),
2160 0 : pDoc->GetLinkRefreshDelay(nTab) );
2161 : }
2162 0 : if ( pDoc->IsScenario(nTab) )
2163 : {
2164 0 : pUndoDoc->SetScenario( nTab, sal_True );
2165 0 : OUString aComment;
2166 0 : Color aColor;
2167 : sal_uInt16 nScenFlags;
2168 0 : pDoc->GetScenarioData( nTab, aComment, aColor, nScenFlags );
2169 0 : pUndoDoc->SetScenarioData( nTab, aComment, aColor, nScenFlags );
2170 0 : sal_Bool bActive = pDoc->IsActiveScenario( nTab );
2171 0 : pUndoDoc->SetActiveScenario( nTab, bActive );
2172 : }
2173 0 : pUndoDoc->SetVisible( nTab, pDoc->IsVisible( nTab ) );
2174 0 : pUndoDoc->SetTabBgColor( nTab, pDoc->GetTabBgColor(nTab) );
2175 0 : pUndoDoc->SetSheetEvents( nTab, pDoc->GetSheetEvents( nTab ) );
2176 0 : pUndoDoc->SetLayoutRTL( nTab, pDoc->IsLayoutRTL( nTab ) );
2177 :
2178 0 : if ( pDoc->IsTabProtected( nTab ) )
2179 0 : pUndoDoc->SetTabProtection(nTab, pDoc->GetTabProtection(nTab));
2180 :
2181 : // Drawing-Layer is responsible for its Undo !!!
2182 : // pUndoDoc->TransferDrawPage(pDoc, nTab,nTab);
2183 : }
2184 :
2185 0 : pUndoDoc->AddUndoTab( 0, nCount-1 ); // all Tabs for references
2186 :
2187 0 : pDoc->BeginDrawUndo(); // DeleteTab creates a SdrUndoDelPage
2188 :
2189 0 : pUndoData = new ScRefUndoData( pDoc );
2190 : }
2191 :
2192 0 : sal_Bool bDelDone = false;
2193 :
2194 0 : for(int i=TheTabs.size()-1; i>=0; --i)
2195 : {
2196 0 : OUString sCodeName;
2197 0 : sal_Bool bHasCodeName = pDoc->GetCodeName( TheTabs[i], sCodeName );
2198 0 : if (pDoc->DeleteTab( TheTabs[i], pUndoDoc ))
2199 : {
2200 0 : bDelDone = sal_True;
2201 0 : if( bVbaEnabled )
2202 : {
2203 0 : if( bHasCodeName )
2204 : {
2205 0 : VBA_DeleteModule( *pDocSh, sCodeName );
2206 : }
2207 : }
2208 0 : pDocSh->Broadcast( ScTablesHint( SC_TAB_DELETED, TheTabs[i] ) );
2209 : }
2210 0 : }
2211 0 : if (bRecord)
2212 : {
2213 0 : pDocSh->GetUndoManager()->AddUndoAction(
2214 0 : new ScUndoDeleteTab( GetViewData()->GetDocShell(), TheTabs,
2215 0 : pUndoDoc, pUndoData ));
2216 : }
2217 :
2218 :
2219 0 : if (bDelDone)
2220 : {
2221 0 : if ( nNewTab >= pDoc->GetTableCount() )
2222 0 : nNewTab = pDoc->GetTableCount() - 1;
2223 :
2224 0 : SetTabNo( nNewTab, sal_True );
2225 :
2226 0 : if (bWasLinked)
2227 : {
2228 0 : pDocSh->UpdateLinks(); // update Link-Manager
2229 0 : GetViewData()->GetBindings().Invalidate(SID_LINKS);
2230 : }
2231 :
2232 0 : pDocSh->PostPaintExtras();
2233 0 : pDocSh->SetDocumentModified();
2234 :
2235 :
2236 0 : SfxApplication* pSfxApp = SFX_APP(); // Navigator
2237 0 : pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
2238 0 : pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_DBAREAS_CHANGED ) );
2239 0 : pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
2240 : }
2241 : else
2242 : {
2243 0 : delete pUndoDoc;
2244 0 : delete pUndoData;
2245 : }
2246 0 : return bDelDone;
2247 : }
2248 :
2249 :
2250 : //----------------------------------------------------------------------------
2251 :
2252 0 : sal_Bool ScViewFunc::RenameTable( const String& rName, SCTAB nTab )
2253 : {
2254 : // order Table/Name is inverted for DocFunc
2255 0 : sal_Bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
2256 0 : RenameTable( nTab, rName, true, false );
2257 0 : if (bSuccess)
2258 : {
2259 : // the table name might be part of a formula
2260 0 : GetViewData()->GetViewShell()->UpdateInputHandler();
2261 : }
2262 0 : return bSuccess;
2263 : }
2264 :
2265 :
2266 : //----------------------------------------------------------------------------
2267 :
2268 0 : bool ScViewFunc::SetTabBgColor( const Color& rColor, SCTAB nTab )
2269 : {
2270 0 : bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().SetTabBgColor( nTab, rColor, sal_True, false );
2271 0 : if (bSuccess)
2272 : {
2273 0 : GetViewData()->GetViewShell()->UpdateInputHandler();
2274 : }
2275 0 : return bSuccess;
2276 : }
2277 :
2278 0 : bool ScViewFunc::SetTabBgColor( ScUndoTabColorInfo::List& rUndoSetTabBgColorInfoList )
2279 : {
2280 0 : bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().SetTabBgColor( rUndoSetTabBgColorInfoList, sal_True, false );
2281 0 : if (bSuccess)
2282 : {
2283 0 : GetViewData()->GetViewShell()->UpdateInputHandler();
2284 : }
2285 0 : return bSuccess;
2286 : }
2287 :
2288 : //----------------------------------------------------------------------------
2289 :
2290 0 : void ScViewFunc::InsertAreaLink( const String& rFile,
2291 : const String& rFilter, const String& rOptions,
2292 : const String& rSource, sal_uLong nRefresh )
2293 : {
2294 0 : ScDocShell* pDocSh = GetViewData()->GetDocShell();
2295 0 : SCCOL nPosX = GetViewData()->GetCurX();
2296 0 : SCROW nPosY = GetViewData()->GetCurY();
2297 0 : SCTAB nTab = GetViewData()->GetTabNo();
2298 0 : ScAddress aPos( nPosX, nPosY, nTab );
2299 :
2300 0 : pDocSh->GetDocFunc().InsertAreaLink( rFile, rFilter, rOptions, rSource, aPos, nRefresh, false, false );
2301 0 : }
2302 :
2303 :
2304 : //----------------------------------------------------------------------------
2305 :
2306 0 : void ScViewFunc::InsertTableLink( const String& rFile,
2307 : const String& rFilter, const String& rOptions,
2308 : const String& rTabName )
2309 : {
2310 0 : OUString aFilterName = rFilter;
2311 0 : OUString aOpt = rOptions;
2312 0 : OUString aURL = rFile;
2313 0 : ScDocumentLoader aLoader( aURL, aFilterName, aOpt );
2314 0 : if (!aLoader.IsError())
2315 : {
2316 0 : ScDocShell* pSrcSh = aLoader.GetDocShell();
2317 0 : ScDocument* pSrcDoc = pSrcSh->GetDocument();
2318 0 : SCTAB nTab = MAXTAB+1;
2319 0 : if (!rTabName.Len()) // no name given -> first table
2320 0 : nTab = 0;
2321 : else
2322 : {
2323 0 : OUString aTemp;
2324 0 : SCTAB nCount = pSrcDoc->GetTableCount();
2325 0 : for (SCTAB i=0; i<nCount; i++)
2326 : {
2327 0 : pSrcDoc->GetName( i, aTemp );
2328 0 : if ( aTemp.equals(rTabName) )
2329 0 : nTab = i;
2330 0 : }
2331 : }
2332 :
2333 0 : if ( nTab <= MAXTAB )
2334 : ImportTables( pSrcSh, 1, &nTab, sal_True,
2335 0 : GetViewData()->GetTabNo() );
2336 0 : }
2337 0 : }
2338 :
2339 :
2340 : //----------------------------------------------------------------------------
2341 : // Copy/link tables from another document
2342 :
2343 0 : void ScViewFunc::ImportTables( ScDocShell* pSrcShell,
2344 : SCTAB nCount, const SCTAB* pSrcTabs, sal_Bool bLink,SCTAB nTab )
2345 : {
2346 0 : ScDocument* pSrcDoc = pSrcShell->GetDocument();
2347 :
2348 0 : ScDocShell* pDocSh = GetViewData()->GetDocShell();
2349 0 : ScDocument* pDoc = pDocSh->GetDocument();
2350 0 : sal_Bool bUndo(pDoc->IsUndoEnabled());
2351 :
2352 0 : sal_Bool bError = false;
2353 0 : sal_Bool bRefs = false;
2354 0 : sal_Bool bName = false;
2355 :
2356 0 : if (pSrcDoc->GetDrawLayer())
2357 0 : pDocSh->MakeDrawLayer();
2358 :
2359 0 : if (bUndo)
2360 0 : pDoc->BeginDrawUndo(); // drawing layer must do its own undo actions
2361 :
2362 0 : SCTAB nInsCount = 0;
2363 : SCTAB i;
2364 0 : for( i=0; i<nCount; i++ )
2365 : { // insert sheets first and update all references
2366 0 : OUString aName;
2367 0 : pSrcDoc->GetName( pSrcTabs[i], aName );
2368 0 : pDoc->CreateValidTabName( aName );
2369 0 : if ( !pDoc->InsertTab( nTab+i, aName ) )
2370 : {
2371 0 : bError = sal_True; // total error
2372 0 : break; // for
2373 : }
2374 0 : ++nInsCount;
2375 0 : }
2376 0 : for (i=0; i<nCount && !bError; i++)
2377 : {
2378 0 : SCTAB nSrcTab = pSrcTabs[i];
2379 0 : SCTAB nDestTab1=nTab+i;
2380 : sal_uLong nErrVal = pDocSh->TransferTab( *pSrcShell, nSrcTab, nDestTab1,
2381 0 : false, false ); // no insert
2382 :
2383 0 : switch (nErrVal)
2384 : {
2385 : case 0: // internal error or full of errors
2386 0 : bError = true;
2387 0 : break;
2388 : case 2:
2389 0 : bRefs = sal_True;
2390 0 : break;
2391 : case 3:
2392 0 : bName = sal_True;
2393 0 : break;
2394 : case 4:
2395 0 : bRefs = bName = sal_True;
2396 0 : break;
2397 : }
2398 :
2399 : }
2400 :
2401 0 : if (bLink)
2402 : {
2403 0 : sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
2404 :
2405 0 : SfxMedium* pMed = pSrcShell->GetMedium();
2406 0 : String aFileName = pMed->GetName();
2407 0 : String aFilterName;
2408 0 : if (pMed->GetFilter())
2409 0 : aFilterName = pMed->GetFilter()->GetFilterName();
2410 0 : String aOptions = ScDocumentLoader::GetOptions(*pMed);
2411 :
2412 0 : sal_Bool bWasThere = pDoc->HasLink( aFileName, aFilterName, aOptions );
2413 :
2414 0 : sal_uLong nRefresh = 0;
2415 0 : OUString aTabStr;
2416 0 : for (i=0; i<nInsCount; i++)
2417 : {
2418 0 : pSrcDoc->GetName( pSrcTabs[i], aTabStr );
2419 : pDoc->SetLink( nTab+i, SC_LINK_NORMAL,
2420 0 : aFileName, aFilterName, aOptions, aTabStr, nRefresh );
2421 : }
2422 :
2423 0 : if (!bWasThere) // Insert link only once per source document
2424 : {
2425 0 : ScTableLink* pLink = new ScTableLink( pDocSh, aFileName, aFilterName, aOptions, nRefresh );
2426 0 : pLink->SetInCreate( sal_True );
2427 0 : pLinkManager->InsertFileLink( *pLink, OBJECT_CLIENT_FILE, aFileName, &aFilterName );
2428 0 : pLink->Update();
2429 0 : pLink->SetInCreate( false );
2430 :
2431 0 : SfxBindings& rBindings = GetViewData()->GetBindings();
2432 0 : rBindings.Invalidate( SID_LINKS );
2433 0 : }
2434 : }
2435 :
2436 :
2437 0 : if (bUndo)
2438 : {
2439 0 : pDocSh->GetUndoManager()->AddUndoAction(
2440 0 : new ScUndoImportTab( pDocSh, nTab, nCount ) );
2441 : }
2442 :
2443 0 : for (i=0; i<nInsCount; i++)
2444 0 : GetViewData()->InsertTab(nTab);
2445 0 : SetTabNo(nTab,sal_True);
2446 : pDocSh->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB,
2447 0 : PAINT_GRID | PAINT_TOP | PAINT_LEFT | PAINT_EXTRAS );
2448 :
2449 0 : SfxApplication* pSfxApp = SFX_APP();
2450 0 : pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
2451 0 : pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_AREAS_CHANGED ) );
2452 :
2453 0 : pDocSh->PostPaintExtras();
2454 0 : pDocSh->PostPaintGridAll();
2455 0 : pDocSh->SetDocumentModified();
2456 :
2457 0 : if (bRefs)
2458 0 : ErrorMessage(STR_ABSREFLOST);
2459 0 : if (bName)
2460 0 : ErrorMessage(STR_NAMECONFLICT);
2461 0 : }
2462 :
2463 :
2464 : //----------------------------------------------------------------------------
2465 : // Move/Copy table to another document
2466 :
2467 0 : void ScViewFunc::MoveTable(
2468 : sal_uInt16 nDestDocNo, SCTAB nDestTab, bool bCopy, const OUString* pNewTabName )
2469 : {
2470 0 : ScDocument* pDoc = GetViewData()->GetDocument();
2471 0 : ScDocShell* pDocShell = GetViewData()->GetDocShell();
2472 0 : ScDocument* pDestDoc = NULL;
2473 0 : ScDocShell* pDestShell = NULL;
2474 0 : ScTabViewShell* pDestViewSh = NULL;
2475 0 : sal_Bool bUndo (pDoc->IsUndoEnabled());
2476 0 : bool bRename = pNewTabName && !pNewTabName->isEmpty();
2477 :
2478 0 : bool bNewDoc = (nDestDocNo == SC_DOC_NEW);
2479 0 : if ( bNewDoc )
2480 : {
2481 0 : nDestTab = 0; // firstly insert
2482 :
2483 : // execute without SFX_CALLMODE_RECORD, because already contained in move command
2484 :
2485 0 : String aUrl = OUString("private:factory/");
2486 0 : aUrl.AppendAscii(RTL_CONSTASCII_STRINGPARAM( STRING_SCAPP )); // "scalc"
2487 0 : SfxStringItem aItem( SID_FILE_NAME, aUrl );
2488 0 : SfxStringItem aTarget( SID_TARGETNAME, OUString("_blank") );
2489 :
2490 0 : const SfxPoolItem* pRetItem = GetViewData()->GetDispatcher().Execute(
2491 0 : SID_OPENDOC, SFX_CALLMODE_API|SFX_CALLMODE_SYNCHRON, &aItem, &aTarget, 0L );
2492 0 : if ( pRetItem )
2493 : {
2494 0 : if ( pRetItem->ISA( SfxObjectItem ) )
2495 0 : pDestShell = PTR_CAST( ScDocShell, ((const SfxObjectItem*)pRetItem)->GetShell() );
2496 0 : else if ( pRetItem->ISA( SfxViewFrameItem ) )
2497 : {
2498 0 : SfxViewFrame* pFrm = ((const SfxViewFrameItem*)pRetItem)->GetFrame();
2499 0 : if (pFrm)
2500 0 : pDestShell = PTR_CAST( ScDocShell, pFrm->GetObjectShell() );
2501 : }
2502 0 : if (pDestShell)
2503 0 : pDestViewSh = pDestShell->GetBestViewShell();
2504 0 : }
2505 : }
2506 : else
2507 0 : pDestShell = ScDocShell::GetShellByNum( nDestDocNo );
2508 :
2509 0 : if (!pDestShell)
2510 : {
2511 : OSL_FAIL("Dest-Doc nicht gefunden !!!");
2512 0 : return;
2513 : }
2514 :
2515 0 : ScMarkData& rMark = GetViewData()->GetMarkData();
2516 0 : if (bRename && rMark.GetSelectCount() != 1)
2517 : {
2518 : // Custom sheet name is provided, but more than one sheet is selected.
2519 : // We don't support this scenario at the moment.
2520 0 : return;
2521 : }
2522 :
2523 0 : pDestDoc = pDestShell->GetDocument();
2524 :
2525 0 : SCTAB nTab = GetViewData()->GetTabNo();
2526 :
2527 0 : if (pDestDoc != pDoc)
2528 : {
2529 0 : if (bNewDoc)
2530 : {
2531 0 : while (pDestDoc->GetTableCount() > 1)
2532 0 : pDestDoc->DeleteTab(0);
2533 : pDestDoc->RenameTab( 0, OUString("______42_____"),
2534 0 : false );
2535 : }
2536 :
2537 0 : SCTAB nTabCount = pDoc->GetTableCount();
2538 0 : SCTAB nTabSelCount = rMark.GetSelectCount();
2539 :
2540 0 : vector<SCTAB> TheTabs;
2541 :
2542 0 : for(SCTAB i=0; i<nTabCount; ++i)
2543 : {
2544 0 : if(rMark.GetTableSelect(i))
2545 : {
2546 0 : OUString aTabName;
2547 0 : pDoc->GetName( i, aTabName);
2548 0 : TheTabs.push_back(i);
2549 0 : for(SCTAB j=i+1;j<nTabCount;j++)
2550 : {
2551 0 : if((!pDoc->IsVisible(j))&&(pDoc->IsScenario(j)))
2552 : {
2553 0 : pDoc->GetName( j, aTabName);
2554 0 : TheTabs.push_back(j);
2555 0 : i=j;
2556 : }
2557 0 : else break;
2558 0 : }
2559 : }
2560 : }
2561 :
2562 0 : GetFrameWin()->EnterWait();
2563 :
2564 0 : if (pDoc->GetDrawLayer())
2565 0 : pDestShell->MakeDrawLayer();
2566 :
2567 0 : if (!bNewDoc && bUndo)
2568 0 : pDestDoc->BeginDrawUndo(); // drawing layer must do its own undo actions
2569 :
2570 0 : sal_uLong nErrVal =1;
2571 0 : if(nDestTab==SC_TAB_APPEND)
2572 0 : nDestTab=pDestDoc->GetTableCount();
2573 0 : SCTAB nDestTab1=nDestTab;
2574 0 : ScClipParam aParam;
2575 0 : for( sal_uInt16 j=0; j<TheTabs.size(); ++j, ++nDestTab1 )
2576 : { // insert sheets first and update all references
2577 0 : OUString aName;
2578 0 : if (bRename)
2579 0 : aName = *pNewTabName;
2580 : else
2581 0 : pDoc->GetName( TheTabs[j], aName );
2582 :
2583 0 : pDestDoc->CreateValidTabName( aName );
2584 0 : if ( !pDestDoc->InsertTab( nDestTab1, aName ) )
2585 : {
2586 0 : nErrVal = 0; // total error
2587 0 : break; // for
2588 : }
2589 0 : ScRange aRange( 0, 0, TheTabs[j], MAXCOL, MAXROW, TheTabs[j] );
2590 0 : aParam.maRanges.Append(aRange);
2591 0 : }
2592 0 : pDoc->SetClipParam(aParam);
2593 0 : if ( nErrVal > 0 )
2594 : {
2595 0 : nDestTab1 = nDestTab;
2596 0 : for(sal_uInt16 i=0; i<TheTabs.size();++i)
2597 : {
2598 0 : nErrVal = pDestShell->TransferTab( *pDocShell, TheTabs[i], static_cast<SCTAB>(nDestTab1), false, false );
2599 0 : nDestTab1++;
2600 : }
2601 : }
2602 0 : OUString sName;
2603 0 : if (!bNewDoc && bUndo)
2604 : {
2605 0 : pDestDoc->GetName(nDestTab, sName);
2606 0 : pDestShell->GetUndoManager()->AddUndoAction(
2607 : new ScUndoImportTab( pDestShell, nDestTab,
2608 0 : static_cast<SCTAB>(TheTabs.size())));
2609 :
2610 : }
2611 : else
2612 : {
2613 0 : pDestShell->GetUndoManager()->Clear();
2614 : }
2615 :
2616 0 : GetFrameWin()->LeaveWait();
2617 0 : switch (nErrVal)
2618 : {
2619 : case 0: // internal error or full of errors
2620 : {
2621 0 : ErrorMessage(STR_TABINSERT_ERROR);
2622 0 : return;
2623 : }
2624 : //break;
2625 : case 2:
2626 0 : ErrorMessage(STR_ABSREFLOST);
2627 0 : break;
2628 : case 3:
2629 0 : ErrorMessage(STR_NAMECONFLICT);
2630 0 : break;
2631 : case 4:
2632 : {
2633 0 : ErrorMessage(STR_ABSREFLOST);
2634 0 : ErrorMessage(STR_NAMECONFLICT);
2635 : }
2636 0 : break;
2637 : default:
2638 0 : break;
2639 : }
2640 :
2641 0 : if (!bCopy)
2642 : {
2643 0 : if(nTabCount!=nTabSelCount)
2644 0 : DeleteTables(TheTabs); // incl. Paint & Undo
2645 : else
2646 0 : ErrorMessage(STR_TABREMOVE_ERROR);
2647 : }
2648 :
2649 0 : if (bNewDoc)
2650 : {
2651 : // ChartListenerCollection must be updated before DeleteTab
2652 0 : if ( pDestDoc->IsChartListenerCollectionNeedsUpdate() )
2653 0 : pDestDoc->UpdateChartListenerCollection();
2654 :
2655 0 : pDestDoc->DeleteTab(static_cast<SCTAB>(TheTabs.size())); // old first table
2656 0 : if (pDestViewSh)
2657 : {
2658 : // Make sure to clear the cached page view after sheet
2659 : // deletion, which still points to the sdr page belonging to
2660 : // the deleted sheet.
2661 0 : SdrView* pSdrView = pDestViewSh->GetSdrView();
2662 0 : if (pSdrView)
2663 0 : pSdrView->ClearPageView();
2664 :
2665 0 : pDestViewSh->TabChanged(); // Pages auf dem Drawing-Layer
2666 : }
2667 : pDestShell->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB,
2668 : PAINT_GRID | PAINT_TOP | PAINT_LEFT |
2669 0 : PAINT_EXTRAS | PAINT_SIZE );
2670 : // PAINT_SIZE for outline
2671 : }
2672 : else
2673 : {
2674 0 : pDestShell->Broadcast( ScTablesHint( SC_TAB_INSERTED, nDestTab ) );
2675 0 : pDestShell->PostPaintExtras();
2676 0 : pDestShell->PostPaintGridAll();
2677 : }
2678 :
2679 0 : TheTabs.clear();
2680 :
2681 0 : pDestShell->SetDocumentModified();
2682 0 : SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
2683 : }
2684 : else
2685 : {
2686 : // Move or copy within the same document.
2687 0 : SCTAB nTabCount = pDoc->GetTableCount();
2688 :
2689 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
2690 0 : auto_ptr< vector<SCTAB> > pSrcTabs(new vector<SCTAB>);
2691 0 : auto_ptr< vector<SCTAB> > pDestTabs(new vector<SCTAB>);
2692 0 : auto_ptr< vector<OUString> > pTabNames(new vector<OUString>);
2693 0 : auto_ptr< vector<OUString> > pDestNames(NULL);
2694 : SAL_WNODEPRECATED_DECLARATIONS_POP
2695 0 : pSrcTabs->reserve(nTabCount);
2696 0 : pDestTabs->reserve(nTabCount);
2697 0 : pTabNames->reserve(nTabCount);
2698 0 : OUString aDestName;
2699 :
2700 0 : for(SCTAB i=0;i<nTabCount;i++)
2701 : {
2702 0 : if(rMark.GetTableSelect(i))
2703 : {
2704 0 : OUString aTabName;
2705 0 : pDoc->GetName( i, aTabName);
2706 0 : pTabNames->push_back(aTabName);
2707 :
2708 0 : for(SCTAB j=i+1;j<nTabCount;j++)
2709 : {
2710 0 : if((!pDoc->IsVisible(j))&&(pDoc->IsScenario(j)))
2711 : {
2712 0 : pDoc->GetName( j, aTabName);
2713 0 : pTabNames->push_back(aTabName);
2714 0 : i=j;
2715 : }
2716 0 : else break;
2717 0 : }
2718 : }
2719 : }
2720 :
2721 0 : if (bCopy && bUndo)
2722 0 : pDoc->BeginDrawUndo(); // drawing layer must do its own undo actions
2723 :
2724 0 : pDoc->GetName( nDestTab, aDestName);
2725 0 : SCTAB nDestTab1=nDestTab;
2726 0 : SCTAB nMovTab=0;
2727 0 : for (size_t j = 0, n = pTabNames->size(); j < n; ++j)
2728 : {
2729 0 : nTabCount = pDoc->GetTableCount();
2730 0 : const OUString& rStr = (*pTabNames)[j];
2731 0 : if(!pDoc->GetTable(rStr,nMovTab))
2732 : {
2733 0 : nMovTab=nTabCount;
2734 : }
2735 0 : if(!pDoc->GetTable(aDestName,nDestTab1))
2736 : {
2737 0 : nDestTab1=nTabCount;
2738 : }
2739 0 : pDocShell->MoveTable( nMovTab, nDestTab1, bCopy, false ); // Undo is here
2740 :
2741 0 : if(bCopy && pDoc->IsScenario(nMovTab))
2742 : {
2743 0 : OUString aComment;
2744 0 : Color aColor;
2745 : sal_uInt16 nFlags;
2746 :
2747 0 : pDoc->GetScenarioData(nMovTab, aComment,aColor, nFlags);
2748 0 : pDoc->SetScenario(nDestTab1,sal_True);
2749 0 : pDoc->SetScenarioData(nDestTab1,aComment,aColor,nFlags);
2750 0 : sal_Bool bActive = pDoc->IsActiveScenario(nMovTab );
2751 0 : pDoc->SetActiveScenario( nDestTab1, bActive );
2752 0 : sal_Bool bVisible=pDoc->IsVisible(nMovTab);
2753 0 : pDoc->SetVisible(nDestTab1,bVisible );
2754 : }
2755 :
2756 0 : pSrcTabs->push_back(nMovTab);
2757 :
2758 0 : if(!bCopy)
2759 : {
2760 0 : if(!pDoc->GetTable(rStr,nDestTab1))
2761 : {
2762 0 : nDestTab1=nTabCount;
2763 : }
2764 : }
2765 :
2766 0 : pDestTabs->push_back(nDestTab1);
2767 : }
2768 :
2769 : // Rename must be done after all sheets have been moved.
2770 0 : if (bRename)
2771 : {
2772 0 : pDestNames.reset(new vector<OUString>);
2773 0 : size_t n = pDestTabs->size();
2774 0 : pDestNames->reserve(n);
2775 0 : for (size_t j = 0; j < n; ++j)
2776 : {
2777 0 : SCTAB nRenameTab = (*pDestTabs)[j];
2778 0 : OUString aTabName = *pNewTabName;
2779 0 : pDoc->CreateValidTabName( aTabName );
2780 0 : pDestNames->push_back(aTabName);
2781 0 : pDoc->RenameTab(nRenameTab, aTabName);
2782 0 : }
2783 : }
2784 : else
2785 : // No need to keep this around when we are not renaming.
2786 0 : pTabNames.reset();
2787 :
2788 0 : nTab = GetViewData()->GetTabNo();
2789 :
2790 0 : if (bUndo)
2791 : {
2792 0 : if (bCopy)
2793 : {
2794 0 : pDocShell->GetUndoManager()->AddUndoAction(
2795 : new ScUndoCopyTab(
2796 0 : pDocShell, pSrcTabs.release(), pDestTabs.release(), pDestNames.release()));
2797 : }
2798 : else
2799 : {
2800 0 : pDocShell->GetUndoManager()->AddUndoAction(
2801 : new ScUndoMoveTab(
2802 0 : pDocShell, pSrcTabs.release(), pDestTabs.release(), pTabNames.release(), pDestNames.release()));
2803 : }
2804 : }
2805 :
2806 0 : SCTAB nNewTab = nDestTab;
2807 0 : if (nNewTab == SC_TAB_APPEND)
2808 0 : nNewTab = pDoc->GetTableCount()-1;
2809 0 : else if (!bCopy && nTab<nDestTab)
2810 0 : nNewTab--;
2811 :
2812 0 : SetTabNo( nNewTab, sal_True );
2813 :
2814 : //#i29848# adjust references to data on the copied sheet
2815 0 : if( bCopy )
2816 0 : ScChartHelper::AdjustRangesOfChartsOnDestinationPage( pDoc, pDestDoc, nTab, nNewTab );
2817 : }
2818 : }
2819 :
2820 :
2821 : //----------------------------------------------------------------------------
2822 :
2823 0 : void ScViewFunc::ShowTable( const std::vector<String>& rNames )
2824 : {
2825 0 : ScDocShell* pDocSh = GetViewData()->GetDocShell();
2826 0 : ScDocument* pDoc = pDocSh->GetDocument();
2827 0 : sal_Bool bUndo(pDoc->IsUndoEnabled());
2828 :
2829 0 : std::vector<SCTAB> undoTabs;
2830 0 : OUString aName;
2831 0 : SCTAB nPos = 0;
2832 :
2833 0 : bool bFound(false);
2834 :
2835 0 : for (std::vector<String>::const_iterator itr=rNames.begin(), itrEnd = rNames.end(); itr!=itrEnd; ++itr)
2836 : {
2837 0 : aName = *itr;
2838 0 : if (pDoc->GetTable(aName, nPos))
2839 : {
2840 0 : pDoc->SetVisible( nPos, sal_True );
2841 0 : SetTabNo( nPos, sal_True );
2842 0 : SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
2843 0 : if (!bFound)
2844 0 : bFound = true;
2845 0 : if (bUndo)
2846 0 : undoTabs.push_back(nPos);
2847 : }
2848 : }
2849 0 : if (bFound)
2850 : {
2851 0 : if (bUndo)
2852 : {
2853 0 : pDocSh->GetUndoManager()->AddUndoAction( new ScUndoShowHideTab( pDocSh, undoTabs, true ) );
2854 : }
2855 0 : pDocSh->PostPaint(0,0,0,MAXCOL,MAXROW,MAXTAB, PAINT_EXTRAS);
2856 0 : pDocSh->SetDocumentModified();
2857 0 : }
2858 0 : }
2859 :
2860 :
2861 : //----------------------------------------------------------------------------
2862 :
2863 0 : void ScViewFunc::HideTable( const ScMarkData& rMark )
2864 : {
2865 0 : ScDocShell* pDocSh = GetViewData()->GetDocShell();
2866 0 : ScDocument* pDoc = pDocSh->GetDocument();
2867 0 : sal_Bool bUndo(pDoc->IsUndoEnabled());
2868 0 : SCTAB nVisible = 0;
2869 0 : SCTAB nTabCount = pDoc->GetTableCount();
2870 :
2871 0 : SCTAB nTabSelCount = rMark.GetSelectCount();
2872 :
2873 : // check to make sure we won't hide all sheets. we need at least one visible at all times.
2874 0 : for ( SCTAB i=0; i < nTabCount && nVisible <= nTabSelCount ; i++ )
2875 0 : if (pDoc->IsVisible(i))
2876 0 : ++nVisible;
2877 :
2878 0 : if (nVisible > nTabSelCount)
2879 : {
2880 : SCTAB nTab;
2881 0 : ScMarkData::MarkedTabsType::const_iterator it;
2882 0 : std::vector<SCTAB> undoTabs;
2883 :
2884 0 : ScMarkData::MarkedTabsType selectedTabs = rMark.GetSelectedTabs();
2885 0 : for (it=selectedTabs.begin(); it!=selectedTabs.end(); ++it)
2886 : {
2887 0 : nTab = *it;
2888 0 : if (pDoc->IsVisible( nTab ))
2889 : {
2890 0 : pDoc->SetVisible( nTab, false );
2891 : // Update views
2892 0 : pDocSh->Broadcast( ScTablesHint( SC_TAB_HIDDEN, nTab ) );
2893 0 : SetTabNo( nTab, true );
2894 : // Store for undo
2895 0 : if (bUndo)
2896 0 : undoTabs.push_back(nTab);
2897 : }
2898 : }
2899 0 : if (bUndo)
2900 : {
2901 0 : pDocSh->GetUndoManager()->AddUndoAction( new ScUndoShowHideTab( pDocSh, undoTabs, false ) );
2902 : }
2903 :
2904 : // Update views
2905 0 : SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
2906 0 : pDocSh->PostPaint(0,0,0,MAXCOL,MAXROW,MAXTAB, PAINT_EXTRAS);
2907 0 : pDocSh->SetDocumentModified();
2908 : }
2909 0 : }
2910 :
2911 :
2912 : //----------------------------------------------------------------------------
2913 :
2914 0 : void ScViewFunc::InsertSpecialChar( const String& rStr, const Font& rFont )
2915 : {
2916 0 : ScEditableTester aTester( this );
2917 0 : if (!aTester.IsEditable())
2918 : {
2919 0 : ErrorMessage(aTester.GetMessageId());
2920 0 : return;
2921 : }
2922 :
2923 0 : const sal_Unicode* pChar = rStr.GetBuffer();
2924 0 : ScTabViewShell* pViewShell = GetViewData()->GetViewShell();
2925 : SvxFontItem aFontItem( rFont.GetFamily(),
2926 0 : rFont.GetName(),
2927 0 : rFont.GetStyleName(),
2928 : rFont.GetPitch(),
2929 0 : rFont.GetCharSet(),
2930 0 : ATTR_FONT );
2931 :
2932 : // if string contains WEAK characters, set all fonts
2933 : sal_uInt8 nScript;
2934 0 : ScDocument* pDoc = GetViewData()->GetDocument();
2935 0 : if ( pDoc->HasStringWeakCharacters( rStr ) )
2936 0 : nScript = SCRIPTTYPE_LATIN | SCRIPTTYPE_ASIAN | SCRIPTTYPE_COMPLEX;
2937 : else
2938 0 : nScript = pDoc->GetStringScriptType( rStr );
2939 :
2940 0 : SvxScriptSetItem aSetItem( SID_ATTR_CHAR_FONT, pViewShell->GetPool() );
2941 0 : aSetItem.PutItemForScriptType( nScript, aFontItem );
2942 0 : ApplyUserItemSet( aSetItem.GetItemSet() );
2943 :
2944 0 : while ( *pChar )
2945 0 : pViewShell->TabKeyInput( KeyEvent( *(pChar++), KeyCode() ) );
2946 : }
2947 :
2948 :
2949 : //----------------------------------------------------------------------------
2950 :
2951 0 : void ScViewFunc::UpdateLineAttrs( SvxBorderLine& rLine,
2952 : const SvxBorderLine* pDestLine,
2953 : const SvxBorderLine* pSrcLine,
2954 : sal_Bool bColor )
2955 : {
2956 0 : if ( pSrcLine && pDestLine )
2957 : {
2958 0 : if ( bColor )
2959 : {
2960 0 : rLine.SetColor ( pSrcLine->GetColor() );
2961 0 : rLine.SetBorderLineStyle(pDestLine->GetBorderLineStyle());
2962 0 : rLine.SetWidth ( pDestLine->GetWidth() );
2963 : }
2964 : else
2965 : {
2966 0 : rLine.SetColor ( pDestLine->GetColor() );
2967 0 : rLine.SetBorderLineStyle(pSrcLine->GetBorderLineStyle());
2968 0 : rLine.SetWidth ( pSrcLine->GetWidth() );
2969 : }
2970 : }
2971 0 : }
2972 :
2973 :
2974 : #define SET_LINE_ATTRIBUTES(LINE,BOXLINE) \
2975 : pBoxLine = aBoxItem.Get##LINE(); \
2976 : if ( pBoxLine ) \
2977 : { \
2978 : if ( pLine ) \
2979 : { \
2980 : UpdateLineAttrs( aLine, pBoxLine, pLine, bColorOnly ); \
2981 : aBoxItem.SetLine( &aLine, BOXLINE ); \
2982 : } \
2983 : else \
2984 : aBoxItem.SetLine( NULL, BOXLINE ); \
2985 : }
2986 :
2987 :
2988 : //----------------------------------------------------------------------------
2989 :
2990 0 : void ScViewFunc::SetSelectionFrameLines( const SvxBorderLine* pLine,
2991 : sal_Bool bColorOnly )
2992 : {
2993 : // Not editable only due to a matrix? Attribute is ok anyhow.
2994 : bool bOnlyNotBecauseOfMatrix;
2995 0 : if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
2996 : {
2997 0 : ErrorMessage(STR_PROTECTIONERR);
2998 0 : return;
2999 : }
3000 :
3001 0 : ScDocument* pDoc = GetViewData()->GetDocument();
3002 0 : ScMarkData aFuncMark( GetViewData()->GetMarkData() ); // local copy for UnmarkFiltered
3003 0 : ScViewUtil::UnmarkFiltered( aFuncMark, pDoc );
3004 0 : ScDocShell* pDocSh = GetViewData()->GetDocShell();
3005 0 : const ScPatternAttr* pSelAttrs = GetSelectionPattern();
3006 0 : const SfxItemSet& rSelItemSet = pSelAttrs->GetItemSet();
3007 :
3008 0 : const SfxPoolItem* pBorderAttr = NULL;
3009 0 : SfxItemState eItemState = rSelItemSet.GetItemState( ATTR_BORDER, sal_True, &pBorderAttr );
3010 :
3011 0 : const SfxPoolItem* pTLBRItem = 0;
3012 0 : SfxItemState eTLBRState = rSelItemSet.GetItemState( ATTR_BORDER_TLBR, sal_True, &pTLBRItem );
3013 :
3014 0 : const SfxPoolItem* pBLTRItem = 0;
3015 0 : SfxItemState eBLTRState = rSelItemSet.GetItemState( ATTR_BORDER_BLTR, sal_True, &pBLTRItem );
3016 :
3017 : // any of the lines visible?
3018 0 : if( (eItemState != SFX_ITEM_DEFAULT) || (eTLBRState != SFX_ITEM_DEFAULT) || (eBLTRState != SFX_ITEM_DEFAULT) )
3019 : {
3020 : // none of the lines don't care?
3021 0 : if( (eItemState != SFX_ITEM_DONTCARE) && (eTLBRState != SFX_ITEM_DONTCARE) && (eBLTRState != SFX_ITEM_DONTCARE) )
3022 : {
3023 : SfxItemSet* pOldSet = new SfxItemSet(
3024 0 : *(pDoc->GetPool()),
3025 : ATTR_PATTERN_START,
3026 0 : ATTR_PATTERN_END );
3027 : SfxItemSet* pNewSet = new SfxItemSet(
3028 0 : *(pDoc->GetPool()),
3029 : ATTR_PATTERN_START,
3030 0 : ATTR_PATTERN_END );
3031 :
3032 : //------------------------------------------------------------
3033 0 : const SvxBorderLine* pBoxLine = NULL;
3034 0 : SvxBorderLine aLine;
3035 :
3036 : // here pBoxLine is used
3037 :
3038 0 : if( pBorderAttr )
3039 : {
3040 0 : SvxBoxItem aBoxItem( *(const SvxBoxItem*)pBorderAttr );
3041 0 : SvxBoxInfoItem aBoxInfoItem( ATTR_BORDER_INNER );
3042 :
3043 0 : SET_LINE_ATTRIBUTES(Top,BOX_LINE_TOP)
3044 0 : SET_LINE_ATTRIBUTES(Bottom,BOX_LINE_BOTTOM)
3045 0 : SET_LINE_ATTRIBUTES(Left,BOX_LINE_LEFT)
3046 0 : SET_LINE_ATTRIBUTES(Right,BOX_LINE_RIGHT)
3047 :
3048 0 : aBoxInfoItem.SetLine( aBoxItem.GetTop(), BOXINFO_LINE_HORI );
3049 0 : aBoxInfoItem.SetLine( aBoxItem.GetLeft(), BOXINFO_LINE_VERT );
3050 0 : aBoxInfoItem.ResetFlags(); // set Lines to Valid
3051 :
3052 0 : pOldSet->Put( *pBorderAttr );
3053 0 : pNewSet->Put( aBoxItem );
3054 0 : pNewSet->Put( aBoxInfoItem );
3055 : }
3056 :
3057 0 : if( pTLBRItem && ((const SvxLineItem*)pTLBRItem)->GetLine() )
3058 : {
3059 0 : SvxLineItem aTLBRItem( *(const SvxLineItem*)pTLBRItem );
3060 0 : UpdateLineAttrs( aLine, aTLBRItem.GetLine(), pLine, bColorOnly );
3061 0 : aTLBRItem.SetLine( &aLine );
3062 0 : pOldSet->Put( *pTLBRItem );
3063 0 : pNewSet->Put( aTLBRItem );
3064 : }
3065 :
3066 0 : if( pBLTRItem && ((const SvxLineItem*)pBLTRItem)->GetLine() )
3067 : {
3068 0 : SvxLineItem aBLTRItem( *(const SvxLineItem*)pBLTRItem );
3069 0 : UpdateLineAttrs( aLine, aBLTRItem.GetLine(), pLine, bColorOnly );
3070 0 : aBLTRItem.SetLine( &aLine );
3071 0 : pOldSet->Put( *pBLTRItem );
3072 0 : pNewSet->Put( aBLTRItem );
3073 : }
3074 :
3075 0 : ApplyAttributes( pNewSet, pOldSet );
3076 :
3077 0 : delete pOldSet;
3078 0 : delete pNewSet;
3079 : }
3080 : else // if ( eItemState == SFX_ITEM_DONTCARE )
3081 : {
3082 0 : aFuncMark.MarkToMulti();
3083 0 : pDoc->ApplySelectionLineStyle( aFuncMark, pLine, bColorOnly );
3084 : }
3085 :
3086 0 : ScRange aMarkRange;
3087 0 : aFuncMark.GetMultiMarkArea( aMarkRange );
3088 0 : SCCOL nStartCol = aMarkRange.aStart.Col();
3089 0 : SCROW nStartRow = aMarkRange.aStart.Row();
3090 0 : SCTAB nStartTab = aMarkRange.aStart.Tab();
3091 0 : SCCOL nEndCol = aMarkRange.aEnd.Col();
3092 0 : SCROW nEndRow = aMarkRange.aEnd.Row();
3093 0 : SCTAB nEndTab = aMarkRange.aEnd.Tab();
3094 : pDocSh->PostPaint( nStartCol, nStartRow, nStartTab,
3095 : nEndCol, nEndRow, nEndTab,
3096 0 : PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
3097 :
3098 0 : pDocSh->UpdateOle( GetViewData() );
3099 0 : pDocSh->SetDocumentModified();
3100 0 : }
3101 : }
3102 :
3103 : #undef SET_LINE_ATTRIBUTES
3104 :
3105 : //----------------------------------------------------------------------------
3106 :
3107 0 : void ScViewFunc::SetValidation( const ScValidationData& rNew )
3108 : {
3109 0 : ScDocument* pDoc = GetViewData()->GetDocument();
3110 0 : sal_uLong nIndex = pDoc->AddValidationEntry(rNew); // for it there is no Undo
3111 0 : SfxUInt32Item aItem( ATTR_VALIDDATA, nIndex );
3112 :
3113 0 : ApplyAttr( aItem ); // with Paint and Undo...
3114 93 : }
3115 :
3116 :
3117 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|