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