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