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