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