1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: viewfunc.cxx,v $
10 * $Revision: 1.46.18.4 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
36 //------------------------------------------------------------------
38 // INCLUDE ---------------------------------------------------------------
40 #include "scitems.hxx"
41 #include <svx/eeitem.hxx>
43 #include <sfx2/app.hxx>
44 #include <svx/algitem.hxx>
45 #include <svx/boxitem.hxx>
46 #include <svx/editobj.hxx>
47 #include <svx/editview.hxx>
48 #include <svx/langitem.hxx>
49 #include <svx/scripttypeitem.hxx>
50 #include <sfx2/bindings.hxx>
51 #include <svtools/zforlist.hxx>
52 #include <svtools/zformat.hxx>
53 #include <vcl/msgbox.hxx>
54 #include <vcl/sound.hxx>
55 #include <vcl/virdev.hxx>
56 #include <vcl/waitobj.hxx>
57 #include <vcl/wrkwin.hxx>
58 #include <stdlib.h> // qsort
60 #include "viewfunc.hxx"
61 #include "tabvwsh.hxx"
64 #include "patattr.hxx"
65 #include "docpool.hxx"
66 #include "uiitems.hxx"
68 #include "undocell.hxx"
69 #include "undoblk.hxx"
70 #include "undotab.hxx"
71 #include "refundo.hxx"
72 #include "dbcolect.hxx"
73 #include "olinetab.hxx"
74 #include "rangeutl.hxx"
75 #include "rangenam.hxx"
76 #include "globstr.hrc"
78 #include "stlsheet.hxx"
79 #include "editutil.hxx"
80 //CHINA001 #include "namecrea.hxx" // wegen Flags
82 #include "scresid.hxx"
83 #include "inputhdl.hxx"
85 #include "inputopt.hxx"
86 #include "compiler.hxx"
87 #include "docfunc.hxx"
88 #include "appoptio.hxx"
89 #include "dociter.hxx"
90 #include "sizedev.hxx"
91 #include "editable.hxx"
92 #include "scui_def.hxx" //CHINA001
93 #include "funcdesc.hxx"
95 #include "cellsuno.hxx"
96 //==================================================================
98 ScViewFunc::ScViewFunc( Window
* pParent
, ScDocShell
& rDocSh
, ScTabViewShell
* pViewShell
) :
99 ScTabView( pParent
, rDocSh
, pViewShell
),
100 bFormatValid( FALSE
)
104 //UNUSED2008-05 ScViewFunc::ScViewFunc( Window* pParent, const ScViewFunc& rViewFunc, ScTabViewShell* pViewShell ) :
105 //UNUSED2008-05 ScTabView( pParent, rViewFunc, pViewShell ),
106 //UNUSED2008-05 bFormatValid( FALSE )
110 ScViewFunc::~ScViewFunc()
114 //------------------------------------------------------------------------------------
116 void ScViewFunc::StartFormatArea()
118 // ueberhaupt aktiviert?
119 if ( !SC_MOD()->GetInputOptions().GetExtendFormat() )
122 // start only with single cell (marked or cursor position)
124 BOOL bOk
= (GetViewData()->GetSimpleArea( aMarkRange
) == SC_MARK_SIMPLE
);
125 if ( bOk
&& aMarkRange
.aStart
!= aMarkRange
.aEnd
)
131 aFormatSource
= aMarkRange
.aStart
;
132 aFormatArea
= ScRange( aFormatSource
);
135 bFormatValid
= FALSE
; // keinen alten Bereich behalten
138 BOOL
ScViewFunc::TestFormatArea( SCCOL nCol
, SCROW nRow
, SCTAB nTab
, BOOL bAttrChanged
)
140 // ueberhaupt aktiviert?
141 if ( !SC_MOD()->GetInputOptions().GetExtendFormat() )
144 // Test: Eingabe mit Zahlformat (bAttrChanged) immer als neue Attributierung behandeln
145 // (alte Area verwerfen). Wenn das nicht gewollt ist, den if-Teil weglassen:
152 //! Abfrage, ob Zelle leer war ???
155 ScRange aNewRange
= aFormatArea
;
156 if ( bFormatValid
&& nTab
== aFormatSource
.Tab() )
158 if ( nRow
>= aFormatArea
.aStart
.Row() && nRow
<= aFormatArea
.aEnd
.Row() )
161 if ( nCol
>= aFormatArea
.aStart
.Col() && nCol
<= aFormatArea
.aEnd
.Col() )
163 bFound
= TRUE
; // Bereich nicht aendern
166 if ( nCol
+1 == aFormatArea
.aStart
.Col() )
169 aNewRange
.aStart
.SetCol( nCol
);
172 if ( nCol
== aFormatArea
.aEnd
.Col()+1 )
175 aNewRange
.aEnd
.SetCol( nCol
);
178 if ( nCol
>= aFormatArea
.aStart
.Col() && nCol
<= aFormatArea
.aEnd
.Col() )
181 if ( nRow
+1 == aFormatArea
.aStart
.Row() )
184 aNewRange
.aStart
.SetRow( nRow
);
187 if ( nRow
== aFormatArea
.aEnd
.Row()+1 )
190 aNewRange
.aEnd
.SetRow( nRow
);
196 aFormatArea
= aNewRange
; // erweitern
199 bFormatValid
= FALSE
; // ausserhalb -> abbrechen
200 if ( bAttrChanged
) // Wert mit Zahlformat eingegeben?
201 StartFormatArea(); // dann ggf. neu starten
207 void ScViewFunc::DoAutoAttributes( SCCOL nCol
, SCROW nRow
, SCTAB nTab
,
208 BOOL bAttrChanged
, BOOL bAddUndo
)
210 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
211 ScDocument
* pDoc
= pDocSh
->GetDocument();
212 if (bAddUndo
&& !pDoc
->IsUndoEnabled())
215 const ScPatternAttr
* pSource
= pDoc
->GetPattern(
216 aFormatSource
.Col(), aFormatSource
.Row(), nTab
);
217 if ( !((const ScMergeAttr
&)pSource
->GetItem(ATTR_MERGE
)).IsMerged() )
219 const ScPatternAttr
* pDocOld
= pDoc
->GetPattern( nCol
, nRow
, nTab
);
220 // pDocOld ist nur bis zum Apply... gueltig!
222 ScPatternAttr
* pOldPattern
= NULL
;
224 pOldPattern
= new ScPatternAttr( *pDocOld
);
226 const ScStyleSheet
* pSrcStyle
= pSource
->GetStyleSheet();
227 if ( pSrcStyle
&& pSrcStyle
!= pDocOld
->GetStyleSheet() )
228 pDoc
->ApplyStyle( nCol
, nRow
, nTab
, *pSrcStyle
);
229 pDoc
->ApplyPattern( nCol
, nRow
, nTab
, *pSource
);
230 AdjustRowHeight( nRow
, nRow
, TRUE
); //! nicht doppelt ?
234 const ScPatternAttr
* pNewPattern
= pDoc
->GetPattern( nCol
, nRow
, nTab
);
236 pDocSh
->GetUndoManager()->AddUndoAction(
237 new ScUndoCursorAttr( pDocSh
, nCol
, nRow
, nTab
,
238 pOldPattern
, pNewPattern
, pSource
,
241 delete pOldPattern
; // wird im Undo kopiert (Pool)
245 if ( bAttrChanged
) // Wert mit Zahlformat eingegeben?
246 aFormatSource
.Set( nCol
, nRow
, nTab
); // dann als neue Quelle
249 //------------------------------------------------------------------------------------
253 USHORT
ScViewFunc::GetOptimalColWidth( SCCOL nCol
, SCTAB nTab
, BOOL bFormula
)
255 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
256 ScDocument
* pDoc
= pDocSh
->GetDocument();
257 ScMarkData
& rMark
= GetViewData()->GetMarkData();
259 double nPPTX
= GetViewData()->GetPPTX();
260 double nPPTY
= GetViewData()->GetPPTY();
261 Fraction aZoomX
= GetViewData()->GetZoomX();
262 Fraction aZoomY
= GetViewData()->GetZoomY();
264 ScSizeDeviceProvider
aProv(pDocSh
);
265 if (aProv
.IsPrinter())
267 nPPTX
= aProv
.GetPPTX();
268 nPPTY
= aProv
.GetPPTY();
269 aZoomX
= aZoomY
= Fraction( 1, 1 );
272 USHORT nTwips
= pDoc
->GetOptimalColWidth( nCol
, nTab
, aProv
.GetDevice(),
273 nPPTX
, nPPTY
, aZoomX
, aZoomY
, bFormula
, &rMark
);
277 BOOL
ScViewFunc::SelectionEditable( BOOL
* pOnlyNotBecauseOfMatrix
/* = NULL */ )
280 ScDocument
* pDoc
= GetViewData()->GetDocument();
281 ScMarkData
& rMark
= GetViewData()->GetMarkData();
282 if (rMark
.IsMarked() || rMark
.IsMultiMarked())
283 bRet
= pDoc
->IsSelectionEditable( rMark
, pOnlyNotBecauseOfMatrix
);
286 SCCOL nCol
= GetViewData()->GetCurX();
287 SCROW nRow
= GetViewData()->GetCurY();
288 SCTAB nTab
= GetViewData()->GetTabNo();
289 bRet
= pDoc
->IsBlockEditable( nTab
, nCol
, nRow
, nCol
, nRow
,
290 pOnlyNotBecauseOfMatrix
);
299 BOOL
lcl_FunctionKnown( USHORT nOpCode
)
301 const ScFunctionList
* pFuncList
= ScGlobal::GetStarCalcFunctionList();
304 ULONG nCount
= pFuncList
->GetCount();
305 for (ULONG i
=0; i
<nCount
; i
++)
306 if ( pFuncList
->GetFunction(i
)->nFIndex
== nOpCode
)
312 BOOL
lcl_AddFunction( ScAppOptions
& rAppOpt
, USHORT nOpCode
)
314 USHORT nOldCount
= rAppOpt
.GetLRUFuncListCount();
315 USHORT
* pOldList
= rAppOpt
.GetLRUFuncList();
317 for (nPos
=0; nPos
<nOldCount
; nPos
++)
318 if (pOldList
[nPos
] == nOpCode
) // is the function already in the list?
321 return FALSE
; // already at the top -> no change
323 // count doesn't change, so the original array is modified
325 for (USHORT nCopy
=nPos
; nCopy
>0; nCopy
--)
326 pOldList
[nCopy
] = pOldList
[nCopy
-1];
327 pOldList
[0] = nOpCode
;
329 return TRUE
; // list has changed
332 if ( !lcl_FunctionKnown( nOpCode
) )
333 return FALSE
; // not in function list -> no change
335 USHORT nNewCount
= Min( (USHORT
)(nOldCount
+ 1), (USHORT
)LRU_MAX
);
336 USHORT nNewList
[LRU_MAX
];
337 nNewList
[0] = nOpCode
;
338 for (nPos
=1; nPos
<nNewCount
; nPos
++)
339 nNewList
[nPos
] = pOldList
[nPos
-1];
340 rAppOpt
.SetLRUFuncList( nNewList
, nNewCount
);
342 return TRUE
; // list has changed
345 // eigentliche Funktionen
349 void ScViewFunc::EnterData( SCCOL nCol
, SCROW nRow
, SCTAB nTab
, const String
& rString
,
350 BOOL bRecord
, const EditTextObject
* pData
)
352 ScDocument
* pDoc
= GetViewData()->GetDocument();
353 ScMarkData
& rMark
= GetViewData()->GetMarkData();
354 SCTAB nTabCount
= pDoc
->GetTableCount();
355 SCTAB nSelCount
= rMark
.GetSelectCount();
357 if (bRecord
&& !pDoc
->IsUndoEnabled())
360 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
361 ScDocShellModificator
aModificator( *pDocSh
);
363 ScEditableTester
aTester( pDoc
, nCol
,nRow
, nCol
,nRow
, rMark
);
364 if (aTester
.IsEditable())
366 BOOL bEditDeleted
= FALSE
;
369 ScBaseCell
** ppOldCells
= NULL
;
370 BOOL
* pHasFormat
= NULL
;
371 ULONG
* pOldFormats
= NULL
;
374 EditTextObject
* pUndoData
= NULL
;
377 ppOldCells
= new ScBaseCell
*[nSelCount
];
378 pHasFormat
= new BOOL
[nSelCount
];
379 pOldFormats
= new ULONG
[nSelCount
];
380 pTabs
= new SCTAB
[nSelCount
];
383 for (i
=0; i
<nTabCount
; i
++)
384 if (rMark
.GetTableSelect(i
))
387 ScBaseCell
* pDocCell
;
388 pDoc
->GetCell( nCol
, nRow
, i
, pDocCell
);
391 ppOldCells
[nUndoPos
] = pDocCell
->CloneWithoutNote( *pDoc
);
392 if ( pDocCell
->GetCellType() == CELLTYPE_EDIT
)
395 BYTE nDocScript
= pDoc
->GetScriptType( nCol
, nRow
, i
, pDocCell
);
396 if ( nOldScript
== 0 )
397 nOldScript
= nDocScript
;
398 else if ( nDocScript
!= nOldScript
)
403 ppOldCells
[nUndoPos
] = NULL
;
406 const SfxPoolItem
* pItem
;
407 const ScPatternAttr
* pPattern
= pDoc
->GetPattern(nCol
, nRow
, i
);
408 if ( SFX_ITEM_SET
== pPattern
->GetItemSet().GetItemState(
409 ATTR_VALUE_FORMAT
,FALSE
,&pItem
) )
411 pHasFormat
[nUndoPos
] = TRUE
;
412 pOldFormats
[nUndoPos
] = ((const SfxUInt32Item
*)pItem
)->GetValue();
415 pHasFormat
[nUndoPos
] = FALSE
;
420 DBG_ASSERT( nUndoPos
==nSelCount
, "nUndoPos!=nSelCount" );
422 pUndoData
= ( pData
? pData
->Clone() : NULL
);
425 bool bFormula
= false;
427 // a single '=' character is handled as string (needed for special filters)
428 if ( rString
.Len() > 1 )
430 if ( rString
.GetChar(0) == '=' )
435 else if ( rString
.GetChar(0) == '+' || rString
.GetChar(0) == '-' )
437 // if there is more than one leading '+' or '-' character, remove the additional ones
438 String
aString( rString
);
439 xub_StrLen nIndex
= 1;
440 xub_StrLen nLen
= aString
.Len();
441 while ( nIndex
< nLen
&& ( aString
.GetChar( nIndex
) == '+' || aString
.GetChar( nIndex
) == '-' ) )
445 aString
.Erase( 1, nIndex
- 1 );
447 // if the remaining part without the leading '+' or '-' character
448 // is non-empty and not a number, handle as formula
449 if ( aString
.Len() > 1 )
451 sal_uInt32 nFormat
= 0;
452 pDoc
->GetNumberFormat( nCol
, nRow
, nTab
, nFormat
);
453 SvNumberFormatter
* pFormatter
= pDoc
->GetFormatTable();
455 if ( !pFormatter
->IsNumberFormat( aString
, nFormat
, fNumber
) )
463 BOOL bNumFmtChanged
= FALSE
;
465 { // Formel, compile mit AutoCorrection
466 for (i
=0; i
<nTabCount
; i
++)
467 if (rMark
.GetTableSelect(i
))
469 ScAddress
aPos( nCol
, nRow
, i
);
470 ScCompiler
aComp( pDoc
, aPos
);
471 aComp
.SetGrammar(pDoc
->GetGrammar());
472 //2do: AutoCorrection via CalcOptions abschaltbar machen
473 aComp
.SetAutoCorrection( TRUE
);
474 if ( rString
.GetChar(0) == '+' || rString
.GetChar(0) == '-' )
476 aComp
.SetExtendedErrorDetection( true );
478 String
aFormula( rString
);
484 BOOL bAddEqual
= FALSE
;
485 ScTokenArray
* pArrFirst
= pArr
= aComp
.CompileString( aFormula
);
486 BOOL bCorrected
= aComp
.IsCorrected();
488 { // probieren, mit erster Parser-Korrektur neu zu parsen
489 pArr
= aComp
.CompileString( aComp
.GetCorrectedFormula() );
491 if ( !pArr
->GetCodeError() )
494 aComp
.CompileTokenArray();
495 bCorrected
|= aComp
.IsCorrected();
499 String aCorrectedFormula
;
502 aCorrectedFormula
= '=';
503 aCorrectedFormula
+= aComp
.GetCorrectedFormula();
506 aCorrectedFormula
= aComp
.GetCorrectedFormula();
508 if ( aCorrectedFormula
.Len() == 1 )
509 nResult
= RET_NO
; // leere Formel, nur '='
512 String
aMessage( ScResId( SCSTR_FORMULA_AUTOCORRECTION
) );
513 aMessage
+= aCorrectedFormula
;
514 nResult
= QueryBox( GetViewData()->GetDialogParent(),
515 WinBits(WB_YES_NO
| WB_DEF_YES
),
516 aMessage
).Execute();
518 if ( nResult
== RET_YES
)
520 aFormula
= aCorrectedFormula
;
521 if ( pArr
!= pArrFirst
)
527 if ( pArr
!= pArrFirst
)
535 // um in mehreren Tabellen eingesetzt zu werden, muss die Formel
536 // via ScFormulaCell copy-ctor evtl. wegen RangeNames neu kompiliert
537 // werden, gleiches Code-Array fuer alle Zellen geht nicht.
538 // Wenn das Array einen Fehler enthaelt, muss in den neu erzeugten
539 // Zellen RPN geloescht und der Fehler explizit gesetzt werden, da
540 // via FormulaCell copy-ctor und Interpreter das, wenn moeglich,
541 // wieder glattgebuegelt wird, zu intelligent.. z.B.: =1))
542 USHORT nError
= pArr
->GetCodeError();
545 // #68693# update list of recent functions with all functions that
546 // are not within parentheses
548 ScModule
* pScMod
= SC_MOD();
549 ScAppOptions aAppOpt
= pScMod
->GetAppOptions();
550 BOOL bOptChanged
= FALSE
;
552 formula::FormulaToken
** ppToken
= pArr
->GetArray();
553 USHORT nTokens
= pArr
->GetLen();
555 for (USHORT nTP
=0; nTP
<nTokens
; nTP
++)
557 formula::FormulaToken
* pTok
= ppToken
[nTP
];
558 OpCode eOp
= pTok
->GetOpCode();
561 else if ( eOp
== ocClose
&& nLevel
)
563 if ( nLevel
== 0 && pTok
->IsFunction() &&
564 lcl_AddFunction( aAppOpt
, sal::static_int_cast
<USHORT
>( eOp
) ) )
570 pScMod
->SetAppOptions(aAppOpt
);
571 pScMod
->RecentFunctionsChanged();
575 ScFormulaCell
aCell( pDoc
, aPos
, pArr
,formula::FormulaGrammar::GRAM_DEFAULT
, MM_NONE
);
577 BOOL bAutoCalc
= pDoc
->GetAutoCalc();
578 SvNumberFormatter
* pFormatter
= pDoc
->GetFormatTable();
579 for ( ; i
<nTabCount
; i
++)
581 if (rMark
.GetTableSelect(i
))
584 ULONG nIndex
= (ULONG
) ((SfxUInt32Item
*) pDoc
->GetAttr(
585 nCol
, nRow
, i
, ATTR_VALUE_FORMAT
))->GetValue();
586 if ( pFormatter
->GetType( nIndex
) == NUMBERFORMAT_TEXT
||
587 ( ( rString
.GetChar(0) == '+' || rString
.GetChar(0) == '-' ) && nError
&& rString
.Equals( aFormula
) ) )
591 ScEditCell
* pCell
= new ScEditCell( pData
, pDoc
, NULL
);
592 pDoc
->PutCell( aPos
, pCell
);
596 ScStringCell
* pCell
= new ScStringCell( aFormula
);
597 pDoc
->PutCell( aPos
, pCell
);
602 ScFormulaCell
* pCell
= new ScFormulaCell( aCell
, *pDoc
, aPos
);
605 pCell
->GetCode()->DelRPN();
606 pCell
->SetErrCode( nError
);
607 if(pCell
->GetCode()->IsHyperLink())
608 pCell
->GetCode()->SetHyperLink(FALSE
);
610 pDoc
->PutCell( aPos
, pCell
);
612 { // einmal nur die Zelle berechnen und wieder dirty setzen
614 pCell
->SetDirtyVar();
615 pDoc
->PutInFormulaTree( pCell
);
624 for (i
=0; i
<nTabCount
; i
++)
625 if (rMark
.GetTableSelect(i
))
626 if (pDoc
->SetString( nCol
, nRow
, i
, rString
))
627 bNumFmtChanged
= TRUE
;
630 // row height must be changed if new text has a different script type
631 for (i
=0; i
<nTabCount
&& !bEditDeleted
; i
++)
632 if (rMark
.GetTableSelect(i
))
633 if ( pDoc
->GetScriptType( nCol
, nRow
, i
) != nOldScript
)
638 if (bEditDeleted
|| pDoc
->HasAttrib( nCol
, nRow
, nTab
, nCol
, nRow
, nTab
, HASATTR_NEEDHEIGHT
))
639 AdjustRowHeight(nRow
,nRow
);
641 BOOL bAutoFormat
= TestFormatArea(nCol
, nRow
, nTab
, bNumFmtChanged
);
643 DoAutoAttributes(nCol
, nRow
, nTab
, bNumFmtChanged
, bRecord
);
646 { // wg. ChangeTrack erst jetzt
647 pDocSh
->GetUndoManager()->AddUndoAction(
648 new ScUndoEnterData( pDocSh
, nCol
, nRow
, nTab
, nUndoPos
, pTabs
,
649 ppOldCells
, pHasFormat
, pOldFormats
,
650 rString
, pUndoData
) );
653 for (i
=0; i
<nTabCount
; i
++)
654 if (rMark
.GetTableSelect(i
))
655 pDocSh
->PostPaintCell( nCol
, nRow
, i
);
659 pDocSh
->UpdateOle(GetViewData());
661 // #i97876# Spreadsheet data changes are not notified
662 ScModelObj
* pModelObj
= ScModelObj::getImplementation( pDocSh
->GetModel() );
663 if ( pModelObj
&& pModelObj
->HasChangesListeners() )
665 ScRangeList aChangeRanges
;
666 for ( i
= 0; i
< nTabCount
; ++i
)
668 if ( rMark
.GetTableSelect( i
) )
670 aChangeRanges
.Append( ScRange( nCol
, nRow
, i
) );
673 pModelObj
->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "cell-change" ) ), aChangeRanges
);
676 aModificator
.SetDocumentModified();
680 ErrorMessage(aTester
.GetMessageId());
681 PaintArea( nCol
, nRow
, nCol
, nRow
); // da steht evtl. noch die Edit-Engine
685 // Wert in einzele Zelle eintragen (nur auf nTab)
687 void ScViewFunc::EnterValue( SCCOL nCol
, SCROW nRow
, SCTAB nTab
, const double& rValue
)
689 ScDocument
* pDoc
= GetViewData()->GetDocument();
690 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
691 BOOL
bUndo (pDoc
->IsUndoEnabled());
693 if ( pDoc
&& pDocSh
)
695 ScDocShellModificator
aModificator( *pDocSh
);
697 ScEditableTester
aTester( pDoc
, nTab
, nCol
,nRow
, nCol
,nRow
);
698 if (aTester
.IsEditable())
700 ScAddress
aPos( nCol
, nRow
, nTab
);
701 ScBaseCell
* pOldCell
= pDoc
->GetCell( aPos
);
702 BOOL bNeedHeight
= ( pOldCell
&& pOldCell
->GetCellType() == CELLTYPE_EDIT
)
704 nCol
,nRow
,nTab
, nCol
,nRow
,nTab
, HASATTR_NEEDHEIGHT
);
707 ScBaseCell
* pUndoCell
= (bUndo
&& pOldCell
) ? pOldCell
->CloneWithoutNote( *pDoc
) : 0;
709 pDoc
->SetValue( nCol
, nRow
, nTab
, rValue
);
711 // wg. ChangeTrack nach Aenderung im Dokument
714 pDocSh
->GetUndoManager()->AddUndoAction(
715 new ScUndoEnterValue( pDocSh
, aPos
, pUndoCell
, rValue
, bNeedHeight
) );
718 /*! Zeilenhoehe anpassen? Dann auch bei Undo...
720 AdjustRowHeight(nRow,nRow);
723 pDocSh
->PostPaintCell( aPos
);
724 pDocSh
->UpdateOle(GetViewData());
725 aModificator
.SetDocumentModified();
728 ErrorMessage(aTester
.GetMessageId());
732 void ScViewFunc::EnterData( SCCOL nCol
, SCROW nRow
, SCTAB nTab
, const EditTextObject
* pData
,
733 BOOL bRecord
, BOOL bTestSimple
)
735 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
736 ScMarkData
& rMark
= GetViewData()->GetMarkData();
737 ScDocument
* pDoc
= pDocSh
->GetDocument();
738 if (bRecord
&& !pDoc
->IsUndoEnabled())
741 ScDocShellModificator
aModificator( *pDocSh
);
743 ScEditableTester
aTester( pDoc
, nTab
, nCol
,nRow
, nCol
,nRow
);
744 if (aTester
.IsEditable())
747 // Test auf Attribute
749 BOOL bSimple
= FALSE
;
750 BOOL bCommon
= FALSE
;
751 ScPatternAttr
* pCellAttrs
= NULL
;
752 EditTextObject
* pNewData
= NULL
;
754 if (bTestSimple
) // Testen, ob einfacher String ohne Attribute
756 const ScPatternAttr
* pOldPattern
= pDoc
->GetPattern( nCol
, nRow
, nTab
);
757 ScTabEditEngine
aEngine( *pOldPattern
, pDoc
->GetEnginePool() );
758 aEngine
.SetText(*pData
);
760 ScEditAttrTester
aAttrTester( &aEngine
);
761 bSimple
= !aAttrTester
.NeedsObject();
762 bCommon
= aAttrTester
.NeedsCellAttr();
764 // formulas have to be recognized even if they're formatted
765 // (but commmon attributes are still collected)
767 if ( !bSimple
&& aEngine
.GetParagraphCount() == 1 )
769 String aParStr
= aEngine
.GetText( (USHORT
) 0 );
770 if ( aParStr
.GetChar(0) == '=' )
774 if (bCommon
) // Attribute fuer Tabelle
776 pCellAttrs
= new ScPatternAttr( *pOldPattern
);
777 pCellAttrs
->GetFromEditItemSet( &aAttrTester
.GetAttribs() );
778 //! remove common attributes from EditEngine?
782 aString
= aEngine
.GetText();
789 SCTAB nTabCount
= pDoc
->GetTableCount();
790 SCTAB nSelCount
= rMark
.GetSelectCount();
792 ScBaseCell
** ppOldCells
= NULL
;
795 EditTextObject
* pUndoData
= NULL
;
796 if (bRecord
&& !bSimple
)
798 ppOldCells
= new ScBaseCell
*[nSelCount
];
799 pTabs
= new SCTAB
[nSelCount
];
802 for (i
=0; i
<nTabCount
; i
++)
803 if (rMark
.GetTableSelect(i
))
806 ScBaseCell
* pDocCell
;
807 pDoc
->GetCell( nCol
, nRow
, i
, pDocCell
);
808 ppOldCells
[nPos
] = pDocCell
? pDocCell
->CloneWithoutNote( *pDoc
) : 0;
812 DBG_ASSERT( nPos
==nSelCount
, "nPos!=nSelCount" );
814 pUndoData
= pData
->Clone();
822 pDoc
->ApplyPattern(nCol
,nRow
,nTab
,*pCellAttrs
); //! Undo
827 AdjustRowHeight(nRow
,nRow
);
829 EnterData(nCol
,nRow
,nTab
,aString
,bRecord
);
833 for (i
=0; i
<nTabCount
; i
++)
834 if (rMark
.GetTableSelect(i
))
835 pDoc
->PutCell( nCol
, nRow
, i
, new ScEditCell( pData
, pDoc
, NULL
) );
838 { // wg. ChangeTrack erst jetzt
839 pDocSh
->GetUndoManager()->AddUndoAction(
840 new ScUndoEnterData( pDocSh
, nCol
, nRow
, nTab
, nPos
, pTabs
,
841 ppOldCells
, NULL
, NULL
, String(),
847 AdjustRowHeight(nRow
,nRow
);
849 for (i
=0; i
<nTabCount
; i
++)
850 if (rMark
.GetTableSelect(i
))
851 pDocSh
->PostPaintCell( nCol
, nRow
, i
);
855 pDocSh
->UpdateOle(GetViewData());
857 // #i97876# Spreadsheet data changes are not notified
858 ScModelObj
* pModelObj
= ScModelObj::getImplementation( pDocSh
->GetModel() );
859 if ( pModelObj
&& pModelObj
->HasChangesListeners() )
861 ScRangeList aChangeRanges
;
862 for ( i
= 0; i
< nTabCount
; ++i
)
864 if ( rMark
.GetTableSelect( i
) )
866 aChangeRanges
.Append( ScRange( nCol
, nRow
, i
) );
869 pModelObj
->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "cell-change" ) ), aChangeRanges
);
872 aModificator
.SetDocumentModified();
880 ErrorMessage(aTester
.GetMessageId());
881 PaintArea( nCol
, nRow
, nCol
, nRow
); // da steht evtl. noch die Edit-Engine
885 void ScViewFunc::EnterDataAtCursor( const String
& rString
)
887 SCCOL nPosX
= GetViewData()->GetCurX();
888 SCROW nPosY
= GetViewData()->GetCurY();
889 SCTAB nTab
= GetViewData()->GetTabNo();
891 EnterData( nPosX
, nPosY
, nTab
, rString
);
894 void ScViewFunc::EnterMatrix( const String
& rString
)
896 ScViewData
* pData
= GetViewData();
897 const ScMarkData
& rMark
= pData
->GetMarkData();
898 if ( !rMark
.IsMarked() && !rMark
.IsMultiMarked() )
900 // nichts markiert -> automatisch Block mit Groesse des Ergebnisses
901 // Formel temporaer berechnen, um an die Groesse heranzukommen
903 ScDocument
* pDoc
= pData
->GetDocument();
904 SCCOL nCol
= pData
->GetCurX();
905 SCROW nRow
= pData
->GetCurY();
906 SCTAB nTab
= pData
->GetTabNo();
907 ScFormulaCell
aFormCell( pDoc
, ScAddress(nCol
,nRow
,nTab
), rString
,formula::FormulaGrammar::GRAM_DEFAULT
, MM_FORMULA
);
911 aFormCell
.GetResultDimensions( nSizeX
, nSizeY
);
912 if ( nSizeX
!= 0 && nSizeY
!= 0 &&
913 nCol
+nSizeX
-1 <= sal::static_int_cast
<SCSIZE
>(MAXCOL
) &&
914 nRow
+nSizeY
-1 <= sal::static_int_cast
<SCSIZE
>(MAXROW
) )
916 ScRange
aResult( nCol
, nRow
, nTab
,
917 sal::static_int_cast
<SCCOL
>(nCol
+nSizeX
-1),
918 sal::static_int_cast
<SCROW
>(nRow
+nSizeY
-1), nTab
);
919 MarkRange( aResult
, FALSE
);
924 if (pData
->GetSimpleArea(aRange
) == SC_MARK_SIMPLE
)
926 ScDocShell
* pDocSh
= pData
->GetDocShell();
927 BOOL bSuccess
= pDocSh
->GetDocFunc().EnterMatrix( aRange
, &rMark
, NULL
, rString
, FALSE
, FALSE
,formula::FormulaGrammar::GRAM_DEFAULT
);
929 pDocSh
->UpdateOle(GetViewData());
932 ErrorMessage(STR_NOMULTISELECT
);
935 BYTE
ScViewFunc::GetSelectionScriptType()
939 ScDocument
* pDoc
= GetViewData()->GetDocument();
940 const ScMarkData
& rMark
= GetViewData()->GetMarkData();
941 if ( !rMark
.IsMarked() && !rMark
.IsMultiMarked() )
943 // no selection -> cursor
945 nScript
= pDoc
->GetScriptType( GetViewData()->GetCurX(),
946 GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
951 rMark
.FillRangeListWithMarks( &aRanges
, FALSE
);
952 ULONG nCount
= aRanges
.Count();
953 for (ULONG i
=0; i
<nCount
; i
++)
955 ScRange aRange
= *aRanges
.GetObject(i
);
956 ScCellIterator
aIter( pDoc
, aRange
);
957 ScBaseCell
* pCell
= aIter
.GetFirst();
960 nScript
|= pDoc
->GetScriptType( aIter
.GetCol(), aIter
.GetRow(), aIter
.GetTab(), pCell
);
961 pCell
= aIter
.GetNext();
967 nScript
= ScGlobal::GetDefaultScriptType();
972 const ScPatternAttr
* ScViewFunc::GetSelectionPattern()
974 // Don't use UnmarkFiltered in slot state functions, for performance reasons.
975 // The displayed state is always that of the whole selection including filtered rows.
977 const ScMarkData
& rMark
= GetViewData()->GetMarkData();
978 ScDocument
* pDoc
= GetViewData()->GetDocument();
979 if ( rMark
.IsMarked() || rMark
.IsMultiMarked() )
981 // MarkToMulti is no longer necessary for pDoc->GetSelectionPattern
982 const ScPatternAttr
* pAttr
= pDoc
->GetSelectionPattern( rMark
);
987 SCCOL nCol
= GetViewData()->GetCurX();
988 SCROW nRow
= GetViewData()->GetCurY();
989 SCTAB nTab
= GetViewData()->GetTabNo();
991 ScMarkData
aTempMark( rMark
); // copy sheet selection
992 aTempMark
.SetMarkArea( ScRange( nCol
, nRow
, nTab
) );
993 const ScPatternAttr
* pAttr
= pDoc
->GetSelectionPattern( aTempMark
);
998 void ScViewFunc::GetSelectionFrame( SvxBoxItem
& rLineOuter
,
999 SvxBoxInfoItem
& rLineInner
)
1001 ScDocument
* pDoc
= GetViewData()->GetDocument();
1002 const ScMarkData
& rMark
= GetViewData()->GetMarkData();
1004 if ( rMark
.IsMarked() || rMark
.IsMultiMarked() )
1006 if ( rMark
.IsMultiMarked() )
1008 ScMarkData
aNewMark( rMark
); // use local copy for MarkToSimple
1009 aNewMark
.MarkToSimple(); // simple block is needed for GetSelectionFrame
1010 pDoc
->GetSelectionFrame( aNewMark
, rLineOuter
, rLineInner
);
1013 pDoc
->GetSelectionFrame( rMark
, rLineOuter
, rLineInner
);
1017 const ScPatternAttr
* pAttrs
=
1018 pDoc
->GetPattern( GetViewData()->GetCurX(),
1019 GetViewData()->GetCurY(),
1020 GetViewData()->GetTabNo() );
1022 rLineOuter
= (const SvxBoxItem
&) (pAttrs
->GetItem( ATTR_BORDER
));
1023 rLineInner
= (const SvxBoxInfoItem
&)(pAttrs
->GetItem( ATTR_BORDER_INNER
));
1024 rLineInner
.SetTable(FALSE
);
1025 rLineInner
.SetDist(TRUE
);
1026 rLineInner
.SetMinDist(FALSE
);
1031 // Attribute anwenden - Undo OK
1033 // kompletter Set ( ATTR_STARTINDEX, ATTR_ENDINDEX )
1036 void ScViewFunc::ApplyAttributes( const SfxItemSet
* pDialogSet
,
1037 const SfxItemSet
* pOldSet
,
1040 // nur wegen Matrix nicht editierbar? Attribute trotzdem ok
1041 BOOL bOnlyNotBecauseOfMatrix
;
1042 if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix
) && !bOnlyNotBecauseOfMatrix
)
1044 ErrorMessage(STR_PROTECTIONERR
);
1048 ScPatternAttr
aOldAttrs( new SfxItemSet(*pOldSet
) );
1049 ScPatternAttr
aNewAttrs( new SfxItemSet(*pDialogSet
) );
1050 aNewAttrs
.DeleteUnchanged( &aOldAttrs
);
1052 if ( pDialogSet
->GetItemState( ATTR_VALUE_FORMAT
) == SFX_ITEM_SET
)
1053 { // #82521# don't reset to default SYSTEM GENERAL if not intended
1054 sal_uInt32 nOldFormat
=
1055 ((const SfxUInt32Item
&)pOldSet
->Get( ATTR_VALUE_FORMAT
)).GetValue();
1056 sal_uInt32 nNewFormat
=
1057 ((const SfxUInt32Item
&)pDialogSet
->Get( ATTR_VALUE_FORMAT
)).GetValue();
1058 if ( nNewFormat
!= nOldFormat
)
1060 SvNumberFormatter
* pFormatter
=
1061 GetViewData()->GetDocument()->GetFormatTable();
1062 const SvNumberformat
* pOldEntry
= pFormatter
->GetEntry( nOldFormat
);
1063 LanguageType eOldLang
=
1064 pOldEntry
? pOldEntry
->GetLanguage() : LANGUAGE_DONTKNOW
;
1065 const SvNumberformat
* pNewEntry
= pFormatter
->GetEntry( nNewFormat
);
1066 LanguageType eNewLang
=
1067 pNewEntry
? pNewEntry
->GetLanguage() : LANGUAGE_DONTKNOW
;
1068 if ( eNewLang
!= eOldLang
)
1070 aNewAttrs
.GetItemSet().Put(
1071 SvxLanguageItem( eNewLang
, ATTR_LANGUAGE_FORMAT
) );
1073 // #40606# nur die Sprache geaendert -> Zahlformat-Attribut nicht anfassen
1074 sal_uInt32 nNewMod
= nNewFormat
% SV_COUNTRY_LANGUAGE_OFFSET
;
1075 if ( nNewMod
== ( nOldFormat
% SV_COUNTRY_LANGUAGE_OFFSET
) &&
1076 nNewMod
<= SV_MAX_ANZ_STANDARD_FORMATE
)
1077 aNewAttrs
.GetItemSet().ClearItem( ATTR_VALUE_FORMAT
);
1082 const SvxBoxItem
* pOldOuter
= (const SvxBoxItem
*) &pOldSet
->Get( ATTR_BORDER
);
1083 const SvxBoxItem
* pNewOuter
= (const SvxBoxItem
*) &pDialogSet
->Get( ATTR_BORDER
);
1084 const SvxBoxInfoItem
* pOldInner
= (const SvxBoxInfoItem
*) &pOldSet
->Get( ATTR_BORDER_INNER
);
1085 const SvxBoxInfoItem
* pNewInner
= (const SvxBoxInfoItem
*) &pDialogSet
->Get( ATTR_BORDER_INNER
);
1086 SfxItemSet
& rNewSet
= aNewAttrs
.GetItemSet();
1087 SfxItemPool
* pNewPool
= rNewSet
.GetPool();
1089 pNewPool
->Put( *pNewOuter
); // noch nicht loeschen
1090 pNewPool
->Put( *pNewInner
);
1091 rNewSet
.ClearItem( ATTR_BORDER
);
1092 rNewSet
.ClearItem( ATTR_BORDER_INNER
);
1095 * Feststellen, ob Rahmenattribute zu setzen sind:
1097 * 2. Ist eine der Linien nicht-DontCare (seit 238.f: IsxxValid())
1101 BOOL bFrame
= (pDialogSet
->GetItemState( ATTR_BORDER
) != SFX_ITEM_DEFAULT
)
1102 || (pDialogSet
->GetItemState( ATTR_BORDER_INNER
) != SFX_ITEM_DEFAULT
);
1104 if ( pNewOuter
==pOldOuter
&& pNewInner
==pOldInner
)
1107 // das sollte doch der Pool abfangen: ?!??!??
1109 if ( bFrame
&& pNewOuter
&& pNewInner
)
1110 if ( *pNewOuter
== *pOldOuter
&& *pNewInner
== *pOldInner
)
1116 && ( pNewInner
->IsValid(VALID_LEFT
)
1117 || pNewInner
->IsValid(VALID_RIGHT
)
1118 || pNewInner
->IsValid(VALID_TOP
)
1119 || pNewInner
->IsValid(VALID_BOTTOM
)
1120 || pNewInner
->IsValid(VALID_HORI
)
1121 || pNewInner
->IsValid(VALID_VERT
) );
1127 ApplySelectionPattern( aNewAttrs
, bRecord
); // nur normale
1130 // wenn neue Items Default-Items sind, so muessen die
1131 // alten Items geputtet werden:
1133 BOOL bDefNewOuter
= ( SFX_ITEMS_STATICDEFAULT
== pNewOuter
->GetKind() );
1134 BOOL bDefNewInner
= ( SFX_ITEMS_STATICDEFAULT
== pNewInner
->GetKind() );
1136 ApplyPatternLines( aNewAttrs
,
1137 bDefNewOuter
? pOldOuter
: pNewOuter
,
1138 bDefNewInner
? pOldInner
: pNewInner
,
1142 pNewPool
->Remove( *pNewOuter
); // freigeben
1143 pNewPool
->Remove( *pNewInner
);
1146 AdjustBlockHeight();
1148 // CellContentChanged wird von ApplySelectionPattern / ApplyPatternLines gerufen
1151 void ScViewFunc::ApplyAttr( const SfxPoolItem
& rAttrItem
)
1153 // nur wegen Matrix nicht editierbar? Attribute trotzdem ok
1154 BOOL bOnlyNotBecauseOfMatrix
;
1155 if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix
) && !bOnlyNotBecauseOfMatrix
)
1157 ErrorMessage(STR_PROTECTIONERR
);
1161 ScPatternAttr
aNewAttrs( new SfxItemSet( *GetViewData()->GetDocument()->GetPool(),
1162 ATTR_PATTERN_START
, ATTR_PATTERN_END
) );
1164 aNewAttrs
.GetItemSet().Put( rAttrItem
);
1165 // Wenn Ausrichtung eingestellt wird (ueber Buttons), immer Einzug 0
1166 if ( rAttrItem
.Which() == ATTR_HOR_JUSTIFY
)
1167 aNewAttrs
.GetItemSet().Put( SfxUInt16Item( ATTR_INDENT
, 0 ) );
1168 ApplySelectionPattern( aNewAttrs
);
1170 AdjustBlockHeight();
1172 // CellContentChanged wird von ApplySelectionPattern gerufen
1176 // Pattern und Rahmen
1178 void ScViewFunc::ApplyPatternLines( const ScPatternAttr
& rAttr
, const SvxBoxItem
* pNewOuter
,
1179 const SvxBoxInfoItem
* pNewInner
, BOOL bRecord
)
1181 ScDocument
* pDoc
= GetViewData()->GetDocument();
1182 ScMarkData
& rMark
= GetViewData()->GetMarkData();
1183 if (bRecord
&& !pDoc
->IsUndoEnabled())
1193 ScMarkType eMarkType
= GetViewData()->GetSimpleArea( nStartCol
, nStartRow
,
1194 nStartTab
, nEndCol
, nEndRow
, nEndTab
);
1195 if (eMarkType
== SC_MARK_SIMPLE
|| eMarkType
== SC_MARK_SIMPLE_FILTERED
)
1197 bool bChangeSelection
= false;
1198 ScRange
aMarkRange( nStartCol
, nStartRow
, nStartTab
, nEndCol
, nEndRow
, nEndTab
);
1199 if ( eMarkType
== SC_MARK_SIMPLE_FILTERED
)
1201 ScMarkData
aVisibleMark( rMark
);
1202 ScViewUtil::UnmarkFiltered( aVisibleMark
, pDoc
);
1203 ScRangeList aRangeList
;
1204 aVisibleMark
.FillRangeListWithMarks( &aRangeList
, FALSE
);
1205 if ( aRangeList
.Count() > 0 )
1207 // use the first range of visible cells
1208 // (might also show an error message instead, or, later, allow multiple ranges)
1210 aMarkRange
= *aRangeList
.GetObject(0);
1212 else // all hidden -> cursor position
1214 aMarkRange
.aStart
.SetCol(GetViewData()->GetCurX());
1215 aMarkRange
.aStart
.SetRow(GetViewData()->GetCurY());
1216 aMarkRange
.aStart
.SetTab(GetViewData()->GetTabNo());
1217 aMarkRange
.aEnd
= aMarkRange
.aStart
;
1219 aMarkRange
.GetVars( nStartCol
, nStartRow
, nStartTab
, nEndCol
, nEndRow
, nEndTab
);
1220 bChangeSelection
= true; // change the selection to only the affected cells
1223 rMark
.MarkToSimple(); // not done by GetSimpleArea anymore
1225 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
1227 ScDocShellModificator
aModificator( *pDocSh
);
1229 if (!rMark
.IsMarked() || bChangeSelection
)
1233 rMark
.SetMarkArea( ScRange( nStartCol
, nStartRow
, nStartTab
, nEndCol
, nEndRow
, nEndTab
) );
1239 SCTAB nTabCount
= pDoc
->GetTableCount();
1240 ScDocument
* pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
1241 pUndoDoc
->InitUndo( pDoc
, nStartTab
, nStartTab
);
1242 for (SCTAB i
=0; i
<nTabCount
; i
++)
1243 if (i
!= nStartTab
&& rMark
.GetTableSelect(i
))
1244 pUndoDoc
->AddUndoTab( i
, i
);
1245 pDoc
->CopyToDocument( nStartCol
, nStartRow
, 0, nEndCol
, nEndRow
, nTabCount
-1,
1246 IDF_ATTRIB
, FALSE
, pUndoDoc
);
1248 pDocSh
->GetUndoManager()->AddUndoAction(
1249 new ScUndoSelectionAttr( pDocSh
, rMark
,
1250 nStartCol
, nStartRow
, nStartTab
,
1251 nEndCol
, nEndRow
, nEndTab
,
1252 pUndoDoc
, FALSE
, &rAttr
, pNewOuter
, pNewInner
) );
1255 USHORT nExt
= SC_PF_TESTMERGE
;
1256 pDocSh
->UpdatePaintExt( nExt
, nStartCol
, nStartRow
, nStartTab
,
1257 nEndCol
, nEndRow
, nEndTab
); // content before the change
1259 pDoc
->ApplySelectionFrame( rMark
, pNewOuter
, pNewInner
);
1261 pDocSh
->UpdatePaintExt( nExt
, nStartCol
, nStartRow
, nStartTab
,
1262 nEndCol
, nEndRow
, nEndTab
); // content after the change
1264 rMark
.MarkToMulti();
1265 pDoc
->ApplySelectionPattern( rAttr
, rMark
);
1267 pDocSh
->PostPaint( nStartCol
, nStartRow
, nStartTab
,
1268 nEndCol
, nEndRow
, nEndTab
,
1270 pDocSh
->UpdateOle(GetViewData());
1271 aModificator
.SetDocumentModified();
1272 CellContentChanged();
1273 rMark
.MarkToSimple();
1276 { // "Rahmen nicht auf Mehrfachselektion"
1277 ErrorMessage(STR_MSSG_APPLYPATTLINES_0
);
1285 void ScViewFunc::ApplySelectionPattern( const ScPatternAttr
& rAttr
,
1286 BOOL bRecord
, BOOL bCursorOnly
)
1288 ScViewData
* pViewData
= GetViewData();
1289 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
1290 ScDocument
* pDoc
= pDocSh
->GetDocument();
1291 ScMarkData
aFuncMark( pViewData
->GetMarkData() ); // local copy for UnmarkFiltered
1292 ScViewUtil::UnmarkFiltered( aFuncMark
, pDoc
);
1294 if (bRecord
&& !pDoc
->IsUndoEnabled())
1297 // State from old ItemSet doesn't matter for paint flags, as any change will be
1298 // from SFX_ITEM_SET in the new ItemSet (default is ignored in ApplyPattern).
1299 // New alignment is checked (check in PostPaint isn't enough) in case a right
1300 // alignment is changed to left.
1301 const SfxItemSet
& rNewSet
= rAttr
.GetItemSet();
1302 BOOL bSetLines
= rNewSet
.GetItemState( ATTR_BORDER
, TRUE
) == SFX_ITEM_SET
||
1303 rNewSet
.GetItemState( ATTR_SHADOW
, TRUE
) == SFX_ITEM_SET
;
1304 BOOL bSetAlign
= rNewSet
.GetItemState( ATTR_HOR_JUSTIFY
, TRUE
) == SFX_ITEM_SET
;
1306 USHORT nExtFlags
= 0;
1308 nExtFlags
|= SC_PF_LINES
;
1310 nExtFlags
|= SC_PF_WHOLEROWS
;
1312 ScDocShellModificator
aModificator( *pDocSh
);
1314 BOOL bMulti
= aFuncMark
.IsMultiMarked();
1315 aFuncMark
.MarkToMulti();
1316 BOOL bOnlyTab
= (!aFuncMark
.IsMultiMarked() && !bCursorOnly
&& aFuncMark
.GetSelectCount() > 1);
1319 SCCOL nCol
= pViewData
->GetCurX();
1320 SCROW nRow
= pViewData
->GetCurY();
1321 SCTAB nTab
= pViewData
->GetTabNo();
1322 aFuncMark
.SetMarkArea(ScRange(nCol
,nRow
,nTab
));
1323 aFuncMark
.MarkToMulti();
1326 ScRangeList aChangeRanges
;
1328 if (aFuncMark
.IsMultiMarked() && !bCursorOnly
)
1331 aFuncMark
.GetMultiMarkArea( aMarkRange
);
1332 SCTAB nTabCount
= pDoc
->GetTableCount();
1333 for ( SCTAB i
= 0; i
< nTabCount
; ++i
)
1335 if ( aFuncMark
.GetTableSelect( i
) )
1337 ScRange
aChangeRange( aMarkRange
);
1338 aChangeRange
.aStart
.SetTab( i
);
1339 aChangeRange
.aEnd
.SetTab( i
);
1340 aChangeRanges
.Append( aChangeRange
);
1344 SCCOL nStartCol
= aMarkRange
.aStart
.Col();
1345 SCROW nStartRow
= aMarkRange
.aStart
.Row();
1346 SCTAB nStartTab
= aMarkRange
.aStart
.Tab();
1347 SCCOL nEndCol
= aMarkRange
.aEnd
.Col();
1348 SCROW nEndRow
= aMarkRange
.aEnd
.Row();
1349 SCTAB nEndTab
= aMarkRange
.aEnd
.Tab();
1351 ScUndoSelectionAttr
* pUndoAttr
= NULL
;
1352 ScEditDataArray
* pEditDataArray
= NULL
;
1355 ScRange aCopyRange
= aMarkRange
;
1356 aCopyRange
.aStart
.SetTab(0);
1357 aCopyRange
.aEnd
.SetTab(nTabCount
-1);
1359 ScDocument
* pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
1360 pUndoDoc
->InitUndo( pDoc
, nStartTab
, nStartTab
);
1361 for (SCTAB i
=0; i
<nTabCount
; i
++)
1362 if (i
!= nStartTab
&& aFuncMark
.GetTableSelect(i
))
1363 pUndoDoc
->AddUndoTab( i
, i
);
1364 pDoc
->CopyToDocument( aCopyRange
, IDF_ATTRIB
, bMulti
, pUndoDoc
, &aFuncMark
);
1366 aFuncMark
.MarkToMulti();
1368 pUndoAttr
= new ScUndoSelectionAttr(
1369 pDocSh
, aFuncMark
, nStartCol
, nStartRow
, nStartTab
,
1370 nEndCol
, nEndRow
, nEndTab
, pUndoDoc
, bMulti
, &rAttr
);
1371 pDocSh
->GetUndoManager()->AddUndoAction(pUndoAttr
);
1372 pEditDataArray
= pUndoAttr
->GetDataArray();
1375 pDoc
->ApplySelectionPattern( rAttr
, aFuncMark
, pEditDataArray
);
1377 pDocSh
->PostPaint( nStartCol
, nStartRow
, nStartTab
,
1378 nEndCol
, nEndRow
, nEndTab
,
1379 PAINT_GRID
, nExtFlags
| SC_PF_TESTMERGE
);
1380 pDocSh
->UpdateOle(GetViewData());
1381 aModificator
.SetDocumentModified();
1382 CellContentChanged();
1384 else // einzelne Zelle - Undo einfacher
1386 SCCOL nCol
= pViewData
->GetCurX();
1387 SCROW nRow
= pViewData
->GetCurY();
1388 SCTAB nTab
= pViewData
->GetTabNo();
1391 pDoc
->GetCell(nCol
, nRow
, nTab
, pCell
);
1392 EditTextObject
* pOldEditData
= NULL
;
1393 EditTextObject
* pNewEditData
= NULL
;
1394 if (pCell
&& pCell
->GetCellType() == CELLTYPE_EDIT
)
1396 ScEditCell
* pEditCell
= static_cast<ScEditCell
*>(pCell
);
1397 pOldEditData
= pEditCell
->GetData()->Clone();
1398 pEditCell
->RemoveCharAttribs(rAttr
);
1399 pNewEditData
= pEditCell
->GetData()->Clone();
1402 aChangeRanges
.Append( ScRange( nCol
, nRow
, nTab
) );
1403 ScPatternAttr
* pOldPat
= new ScPatternAttr(*pDoc
->GetPattern( nCol
, nRow
, nTab
));
1405 pDoc
->ApplyPattern( nCol
, nRow
, nTab
, rAttr
);
1407 const ScPatternAttr
* pNewPat
= pDoc
->GetPattern( nCol
, nRow
, nTab
);
1411 ScUndoCursorAttr
* pUndo
= new ScUndoCursorAttr(
1412 pDocSh
, nCol
, nRow
, nTab
, pOldPat
, pNewPat
, &rAttr
, false );
1413 pUndo
->SetEditData(pOldEditData
, pNewEditData
);
1414 pDocSh
->GetUndoManager()->AddUndoAction(pUndo
);
1416 delete pOldPat
; // wird im Undo kopiert (Pool)
1418 pDocSh
->PostPaint( nCol
,nRow
,nTab
, nCol
,nRow
,nTab
, PAINT_GRID
, nExtFlags
| SC_PF_TESTMERGE
);
1419 pDocSh
->UpdateOle(GetViewData());
1420 aModificator
.SetDocumentModified();
1421 CellContentChanged();
1424 // #i97876# Spreadsheet data changes are not notified
1425 ScModelObj
* pModelObj
= ScModelObj::getImplementation( pDocSh
->GetModel() );
1426 if ( pModelObj
&& pModelObj
->HasChangesListeners() )
1428 ::com::sun::star::uno::Sequence
< ::com::sun::star::beans::PropertyValue
> aProperties
;
1429 sal_Int32 nCount
= 0;
1430 for ( USHORT nWhich
= ATTR_PATTERN_START
; nWhich
<= ATTR_PATTERN_END
; ++nWhich
)
1432 const SfxPoolItem
* pItem
= 0;
1433 if ( rNewSet
.GetItemState( nWhich
, TRUE
, &pItem
) == SFX_ITEM_SET
&& pItem
)
1435 const SfxItemPropertyMap
* pMap
= ScCellObj::GetCellPropertyMap();
1436 while ( pMap
->pName
)
1438 if ( pMap
->nWID
== nWhich
)
1440 ::com::sun::star::uno::Any aVal
;
1441 pItem
->QueryValue( aVal
, pMap
->nMemberId
);
1442 aProperties
.realloc( nCount
+ 1 );
1443 aProperties
[ nCount
].Name
= ::rtl::OUString::createFromAscii( pMap
->pName
);
1444 aProperties
[ nCount
].Value
<<= aVal
;
1451 pModelObj
->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "attribute" ) ), aChangeRanges
, aProperties
);
1457 void ScViewFunc::ApplyUserItemSet( const SfxItemSet
& rItemSet
)
1459 // ItemSet from UI, may have different pool
1461 BOOL bOnlyNotBecauseOfMatrix
;
1462 if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix
) && !bOnlyNotBecauseOfMatrix
)
1464 ErrorMessage(STR_PROTECTIONERR
);
1468 ScPatternAttr
aNewAttrs( GetViewData()->GetDocument()->GetPool() );
1469 SfxItemSet
& rNewSet
= aNewAttrs
.GetItemSet();
1470 rNewSet
.Put( rItemSet
, FALSE
);
1471 ApplySelectionPattern( aNewAttrs
);
1473 AdjustBlockHeight();
1476 const SfxStyleSheet
* ScViewFunc::GetStyleSheetFromMarked()
1478 // Don't use UnmarkFiltered in slot state functions, for performance reasons.
1479 // The displayed state is always that of the whole selection including filtered rows.
1481 const ScStyleSheet
* pSheet
= NULL
;
1482 ScViewData
* pViewData
= GetViewData();
1483 ScDocument
* pDoc
= pViewData
->GetDocument();
1484 ScMarkData
& rMark
= pViewData
->GetMarkData();
1486 if ( rMark
.IsMarked() || rMark
.IsMultiMarked() )
1487 pSheet
= pDoc
->GetSelectionStyle( rMark
); // MarkToMulti isn't necessary
1489 pSheet
= pDoc
->GetStyle( pViewData
->GetCurX(),
1490 pViewData
->GetCurY(),
1491 pViewData
->GetTabNo() );
1496 void ScViewFunc::SetStyleSheetToMarked( SfxStyleSheet
* pStyleSheet
, BOOL bRecord
)
1498 // nur wegen Matrix nicht editierbar? Attribute trotzdem ok
1499 BOOL bOnlyNotBecauseOfMatrix
;
1500 if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix
) && !bOnlyNotBecauseOfMatrix
)
1502 ErrorMessage(STR_PROTECTIONERR
);
1506 if ( !pStyleSheet
) return;
1507 // -------------------------------------------------------------------
1509 ScViewData
* pViewData
= GetViewData();
1510 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
1511 ScDocument
* pDoc
= pDocSh
->GetDocument();
1512 ScMarkData
aFuncMark( pViewData
->GetMarkData() ); // local copy for UnmarkFiltered
1513 ScViewUtil::UnmarkFiltered( aFuncMark
, pDoc
);
1514 SCTAB nTabCount
= pDoc
->GetTableCount();
1515 if (bRecord
&& !pDoc
->IsUndoEnabled())
1518 ScDocShellModificator
aModificator( *pDocSh
);
1520 if ( aFuncMark
.IsMarked() || aFuncMark
.IsMultiMarked() )
1523 aFuncMark
.MarkToMulti();
1524 aFuncMark
.GetMultiMarkArea( aMarkRange
);
1528 SCTAB nTab
= pViewData
->GetTabNo();
1529 ScDocument
* pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
1530 pUndoDoc
->InitUndo( pDoc
, nTab
, nTab
);
1531 for (SCTAB i
=0; i
<nTabCount
; i
++)
1532 if (i
!= nTab
&& aFuncMark
.GetTableSelect(i
))
1533 pUndoDoc
->AddUndoTab( i
, i
);
1535 ScRange aCopyRange
= aMarkRange
;
1536 aCopyRange
.aStart
.SetTab(0);
1537 aCopyRange
.aEnd
.SetTab(nTabCount
-1);
1538 pDoc
->CopyToDocument( aCopyRange
, IDF_ATTRIB
, TRUE
, pUndoDoc
, &aFuncMark
);
1539 aFuncMark
.MarkToMulti();
1541 String aName
= pStyleSheet
->GetName();
1542 pDocSh
->GetUndoManager()->AddUndoAction(
1543 new ScUndoSelectionStyle( pDocSh
, aFuncMark
, aMarkRange
, aName
, pUndoDoc
) );
1546 pDoc
->ApplySelectionStyle( (ScStyleSheet
&)*pStyleSheet
, aFuncMark
);
1548 if (!AdjustBlockHeight())
1549 pViewData
->GetDocShell()->PostPaint( aMarkRange
, PAINT_GRID
);
1551 aFuncMark
.MarkToSimple();
1555 SCCOL nCol
= pViewData
->GetCurX();
1556 SCROW nRow
= pViewData
->GetCurY();
1557 SCTAB nTab
= pViewData
->GetTabNo();
1561 ScDocument
* pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
1562 pUndoDoc
->InitUndo( pDoc
, nTab
, nTab
);
1563 for (SCTAB i
=0; i
<nTabCount
; i
++)
1564 if (i
!= nTab
&& aFuncMark
.GetTableSelect(i
))
1565 pUndoDoc
->AddUndoTab( i
, i
);
1567 ScRange
aCopyRange( nCol
, nRow
, 0, nCol
, nRow
, nTabCount
-1 );
1568 pDoc
->CopyToDocument( aCopyRange
, IDF_ATTRIB
, FALSE
, pUndoDoc
);
1570 ScRange
aMarkRange ( nCol
, nRow
, nTab
);
1571 ScMarkData aUndoMark
= aFuncMark
;
1572 aUndoMark
.SetMultiMarkArea( aMarkRange
);
1574 String aName
= pStyleSheet
->GetName();
1575 pDocSh
->GetUndoManager()->AddUndoAction(
1576 new ScUndoSelectionStyle( pDocSh
, aUndoMark
, aMarkRange
, aName
, pUndoDoc
) );
1579 for (SCTAB i
=0; i
<nTabCount
; i
++)
1580 if (aFuncMark
.GetTableSelect(i
))
1581 pDoc
->ApplyStyle( nCol
, nRow
, i
, (ScStyleSheet
&)*pStyleSheet
);
1583 if (!AdjustBlockHeight())
1584 pViewData
->GetDocShell()->PostPaintCell( nCol
, nRow
, nTab
);
1588 aModificator
.SetDocumentModified();
1594 void ScViewFunc::RemoveStyleSheetInUse( SfxStyleSheet
* pStyleSheet
)
1596 if ( !pStyleSheet
) return;
1597 // -------------------------------------------------------------------
1599 ScViewData
* pViewData
= GetViewData();
1600 ScDocument
* pDoc
= pViewData
->GetDocument();
1601 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
1603 ScDocShellModificator
aModificator( *pDocSh
);
1605 VirtualDevice aVirtDev
;
1606 aVirtDev
.SetMapMode(MAP_PIXEL
);
1607 pDoc
->StyleSheetChanged( pStyleSheet
, TRUE
, &aVirtDev
,
1608 pViewData
->GetPPTX(),
1609 pViewData
->GetPPTY(),
1610 pViewData
->GetZoomX(),
1611 pViewData
->GetZoomY() );
1613 pDocSh
->PostPaint( 0,0,0, MAXCOL
,MAXROW
,MAXTAB
, PAINT_GRID
|PAINT_LEFT
);
1614 aModificator
.SetDocumentModified();
1616 ScInputHandler
* pHdl
= SC_MOD()->GetInputHdl();
1618 pHdl
->ForgetLastPattern();
1621 void ScViewFunc::UpdateStyleSheetInUse( SfxStyleSheet
* pStyleSheet
)
1623 if ( !pStyleSheet
) return;
1624 // -------------------------------------------------------------------
1626 ScViewData
* pViewData
= GetViewData();
1627 ScDocument
* pDoc
= pViewData
->GetDocument();
1628 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
1630 ScDocShellModificator
aModificator( *pDocSh
);
1632 VirtualDevice aVirtDev
;
1633 aVirtDev
.SetMapMode(MAP_PIXEL
);
1634 pDoc
->StyleSheetChanged( pStyleSheet
, FALSE
, &aVirtDev
,
1635 pViewData
->GetPPTX(),
1636 pViewData
->GetPPTY(),
1637 pViewData
->GetZoomX(),
1638 pViewData
->GetZoomY() );
1640 pDocSh
->PostPaint( 0,0,0, MAXCOL
,MAXROW
,MAXTAB
, PAINT_GRID
|PAINT_LEFT
);
1641 aModificator
.SetDocumentModified();
1643 ScInputHandler
* pHdl
= SC_MOD()->GetInputHdl();
1645 pHdl
->ForgetLastPattern();
1648 // Zellen einfuegen - Undo OK
1650 BOOL
ScViewFunc::InsertCells( InsCellCmd eCmd
, BOOL bRecord
, BOOL bPartOfPaste
)
1653 if (GetViewData()->GetSimpleArea(aRange
) == SC_MARK_SIMPLE
)
1655 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
1656 const ScMarkData
& rMark
= GetViewData()->GetMarkData();
1657 BOOL bSuccess
= pDocSh
->GetDocFunc().InsertCells( aRange
, &rMark
, eCmd
, bRecord
, FALSE
, bPartOfPaste
);
1660 pDocSh
->UpdateOle(GetViewData());
1661 CellContentChanged();
1663 // #i97876# Spreadsheet data changes are not notified
1664 ScModelObj
* pModelObj
= ScModelObj::getImplementation( pDocSh
->GetModel() );
1665 if ( pModelObj
&& pModelObj
->HasChangesListeners() )
1667 if ( eCmd
== INS_INSROWS
|| eCmd
== INS_INSCOLS
)
1669 ScRangeList aChangeRanges
;
1670 aChangeRanges
.Append( aRange
);
1671 ::rtl::OUString aOperation
= ( eCmd
== INS_INSROWS
?
1672 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "insert-rows" ) ) :
1673 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "insert-columns" ) ) );
1674 pModelObj
->NotifyChanges( aOperation
, aChangeRanges
);
1682 ErrorMessage(STR_NOMULTISELECT
);
1687 // Zellen loeschen - Undo OK
1689 void ScViewFunc::DeleteCells( DelCellCmd eCmd
, BOOL bRecord
)
1692 if ( GetViewData()->GetSimpleArea( aRange
) == SC_MARK_SIMPLE
)
1694 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
1695 const ScMarkData
& rMark
= GetViewData()->GetMarkData();
1697 // #i94841# [Collaboration] When deleting rows is rejected, the content is sometimes wrong
1698 if ( pDocSh
->IsDocShared() && ( eCmd
== DEL_DELROWS
|| eCmd
== DEL_DELCOLS
) )
1700 ScRange
aDelRange( aRange
.aStart
);
1701 SCCOLROW nCount
= 0;
1702 if ( eCmd
== DEL_DELROWS
)
1704 nCount
= sal::static_int_cast
< SCCOLROW
>( aRange
.aEnd
.Row() - aRange
.aStart
.Row() + 1 );
1708 nCount
= sal::static_int_cast
< SCCOLROW
>( aRange
.aEnd
.Col() - aRange
.aStart
.Col() + 1 );
1710 while ( nCount
> 0 )
1712 pDocSh
->GetDocFunc().DeleteCells( aDelRange
, &rMark
, eCmd
, bRecord
, FALSE
);
1718 pDocSh
->GetDocFunc().DeleteCells( aRange
, &rMark
, eCmd
, bRecord
, FALSE
);
1721 pDocSh
->UpdateOle(GetViewData());
1722 CellContentChanged();
1724 // #i97876# Spreadsheet data changes are not notified
1725 ScModelObj
* pModelObj
= ScModelObj::getImplementation( pDocSh
->GetModel() );
1726 if ( pModelObj
&& pModelObj
->HasChangesListeners() )
1728 if ( eCmd
== DEL_DELROWS
|| eCmd
== DEL_DELCOLS
)
1730 ScRangeList aChangeRanges
;
1731 aChangeRanges
.Append( aRange
);
1732 ::rtl::OUString aOperation
= ( eCmd
== DEL_DELROWS
?
1733 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "delete-rows" ) ) :
1734 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "delete-columns" ) ) );
1735 pModelObj
->NotifyChanges( aOperation
, aChangeRanges
);
1739 // #58106# Cursor direkt hinter den geloeschten Bereich setzen
1740 SCCOL nCurX
= GetViewData()->GetCurX();
1741 SCROW nCurY
= GetViewData()->GetCurY();
1742 if ( eCmd
==DEL_CELLSLEFT
|| eCmd
==DEL_DELCOLS
)
1743 nCurX
= aRange
.aStart
.Col();
1745 nCurY
= aRange
.aStart
.Row();
1746 SetCursor( nCurX
, nCurY
);
1750 if (eCmd
== DEL_DELCOLS
)
1751 DeleteMulti( FALSE
, bRecord
);
1752 else if (eCmd
== DEL_DELROWS
)
1753 DeleteMulti( TRUE
, bRecord
);
1755 ErrorMessage(STR_NOMULTISELECT
);
1761 void ScViewFunc::DeleteMulti( BOOL bRows
, BOOL bRecord
)
1763 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
1764 ScDocShellModificator
aModificator( *pDocSh
);
1765 SCTAB nTab
= GetViewData()->GetTabNo();
1766 ScDocument
* pDoc
= pDocSh
->GetDocument();
1767 ScMarkData
aFuncMark( GetViewData()->GetMarkData() ); // local copy for UnmarkFiltered
1768 ScViewUtil::UnmarkFiltered( aFuncMark
, pDoc
);
1770 if (bRecord
&& !pDoc
->IsUndoEnabled())
1772 SCCOLROW
* pRanges
= new SCCOLROW
[MAXCOLROWCOUNT
];
1773 SCCOLROW nRangeCnt
= bRows
? aFuncMark
.GetMarkRowRanges( pRanges
) :
1774 aFuncMark
.GetMarkColumnRanges( pRanges
);
1777 pRanges
[0] = pRanges
[1] = bRows
? static_cast<SCCOLROW
>(GetViewData()->GetCurY()) : static_cast<SCCOLROW
>(GetViewData()->GetCurX());
1783 SCCOLROW
* pOneRange
= pRanges
;
1784 USHORT nErrorId
= 0;
1785 BOOL bNeedRefresh
= FALSE
;
1787 for (nRangeNo
=0; nRangeNo
<nRangeCnt
&& !nErrorId
; nRangeNo
++)
1789 SCCOLROW nStart
= *(pOneRange
++);
1790 SCCOLROW nEnd
= *(pOneRange
++);
1792 SCCOL nStartCol
, nEndCol
;
1793 SCROW nStartRow
, nEndRow
;
1798 nStartRow
= static_cast<SCROW
>(nStart
);
1799 nEndRow
= static_cast<SCROW
>(nEnd
);
1803 nStartCol
= static_cast<SCCOL
>(nStart
);
1804 nEndCol
= static_cast<SCCOL
>(nEnd
);
1809 // cell protection (only needed for first range, as all following cells are moved)
1810 if ( nRangeNo
== 0 )
1812 // test to the end of the sheet
1813 ScEditableTester
aTester( pDoc
, nTab
, nStartCol
, nStartRow
, MAXCOL
, MAXROW
);
1814 if (!aTester
.IsEditable())
1815 nErrorId
= aTester
.GetMessageId();
1819 SCCOL nMergeStartX
= nStartCol
;
1820 SCROW nMergeStartY
= nStartRow
;
1821 SCCOL nMergeEndX
= nEndCol
;
1822 SCROW nMergeEndY
= nEndRow
;
1823 pDoc
->ExtendMerge( nMergeStartX
, nMergeStartY
, nMergeEndX
, nMergeEndY
, nTab
);
1824 pDoc
->ExtendOverlapped( nMergeStartX
, nMergeStartY
, nMergeEndX
, nMergeEndY
, nTab
);
1826 if ( nMergeStartX
!= nStartCol
|| nMergeStartY
!= nStartRow
)
1828 // Disallow deleting parts of a merged cell.
1829 // Deleting the start is allowed (merge is removed), so the end doesn't have to be checked.
1831 nErrorId
= STR_MSSG_DELETECELLS_0
;
1833 if ( nMergeEndX
!= nEndCol
|| nMergeEndY
!= nEndRow
)
1835 // detect if the start of a merged cell is deleted, so the merge flags can be refreshed
1837 bNeedRefresh
= TRUE
;
1843 ErrorMessage( nErrorId
);
1850 WaitObject
aWait( GetFrameWin() ); // wichtig wegen TrackFormulas bei UpdateReference
1852 ScDocument
* pUndoDoc
= NULL
;
1853 ScRefUndoData
* pUndoData
= NULL
;
1856 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
1857 pUndoDoc
->InitUndo( pDoc
, nTab
, nTab
, !bRows
, bRows
); // Zeilenhoehen
1859 pOneRange
= pRanges
;
1860 for (nRangeNo
=0; nRangeNo
<nRangeCnt
; nRangeNo
++)
1862 SCCOLROW nStart
= *(pOneRange
++);
1863 SCCOLROW nEnd
= *(pOneRange
++);
1865 pDoc
->CopyToDocument( 0,nStart
,nTab
, MAXCOL
,nEnd
,nTab
, IDF_ALL
,FALSE
,pUndoDoc
);
1867 pDoc
->CopyToDocument( static_cast<SCCOL
>(nStart
),0,nTab
,
1868 static_cast<SCCOL
>(nEnd
),MAXROW
,nTab
,
1869 IDF_ALL
,FALSE
,pUndoDoc
);
1872 // alle Formeln wegen Referenzen
1873 SCTAB nTabCount
= pDoc
->GetTableCount();
1874 pUndoDoc
->AddUndoTab( 0, nTabCount
-1, FALSE
, FALSE
);
1875 pDoc
->CopyToDocument( 0,0,0, MAXCOL
,MAXROW
,MAXTAB
, IDF_FORMULA
,FALSE
,pUndoDoc
);
1877 pUndoData
= new ScRefUndoData( pDoc
);
1879 pDoc
->BeginDrawUndo();
1882 pOneRange
= &pRanges
[2*nRangeCnt
]; // rueckwaerts
1883 for (nRangeNo
=0; nRangeNo
<nRangeCnt
; nRangeNo
++)
1885 SCCOLROW nEnd
= *(--pOneRange
);
1886 SCCOLROW nStart
= *(--pOneRange
);
1889 pDoc
->DeleteRow( 0,nTab
, MAXCOL
,nTab
, nStart
, static_cast<SCSIZE
>(nEnd
-nStart
+1) );
1891 pDoc
->DeleteCol( 0,nTab
, MAXROW
,nTab
, static_cast<SCCOL
>(nStart
), static_cast<SCSIZE
>(nEnd
-nStart
+1) );
1896 SCCOLROW nFirstStart
= pRanges
[0];
1897 SCCOL nStartCol
= bRows
? 0 : static_cast<SCCOL
>(nFirstStart
);
1898 SCROW nStartRow
= bRows
? static_cast<SCROW
>(nFirstStart
) : 0;
1899 SCCOL nEndCol
= MAXCOL
;
1900 SCROW nEndRow
= MAXROW
;
1902 pDoc
->RemoveFlagsTab( nStartCol
, nStartRow
, nEndCol
, nEndRow
, nTab
, SC_MF_HOR
| SC_MF_VER
);
1903 pDoc
->ExtendMerge( nStartCol
, nStartRow
, nEndCol
, nEndRow
, nTab
, TRUE
);
1908 pDocSh
->GetUndoManager()->AddUndoAction(
1909 new ScUndoDeleteMulti( pDocSh
, bRows
, bNeedRefresh
, nTab
, pRanges
, nRangeCnt
,
1910 pUndoDoc
, pUndoData
) );
1913 if (!AdjustRowHeight(0, MAXROW
))
1916 pDocSh
->PostPaint( 0,pRanges
[0],nTab
, MAXCOL
,MAXROW
,nTab
, PAINT_GRID
| PAINT_LEFT
);
1918 pDocSh
->PostPaint( static_cast<SCCOL
>(pRanges
[0]),0,nTab
,
1919 MAXCOL
,MAXROW
,nTab
, PAINT_GRID
| PAINT_TOP
);
1921 aModificator
.SetDocumentModified();
1923 CellContentChanged();
1925 // #58106# Cursor direkt hinter den ersten geloeschten Bereich setzen
1926 SCCOL nCurX
= GetViewData()->GetCurX();
1927 SCROW nCurY
= GetViewData()->GetCurY();
1931 nCurX
= static_cast<SCCOL
>(pRanges
[0]);
1932 SetCursor( nCurX
, nCurY
);
1936 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED
) );
1941 void ScViewFunc::DeleteContents( USHORT nFlags
, BOOL bRecord
)
1943 GetViewData()->SetPasteMode( SC_PASTE_NONE
);
1944 // nur wegen Matrix nicht editierbar? Attribute trotzdem ok
1945 BOOL bOnlyNotBecauseOfMatrix
;
1946 BOOL bEditable
= SelectionEditable( &bOnlyNotBecauseOfMatrix
);
1949 if ( !(bOnlyNotBecauseOfMatrix
&&
1950 ((nFlags
& (IDF_ATTRIB
| IDF_EDITATTR
)) == nFlags
)) )
1952 ErrorMessage(bOnlyNotBecauseOfMatrix
? STR_MATRIXFRAGMENTERR
: STR_PROTECTIONERR
);
1958 BOOL bSimple
= FALSE
;
1960 ScDocument
* pDoc
= GetViewData()->GetDocument();
1961 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
1962 ScMarkData
aFuncMark( GetViewData()->GetMarkData() ); // local copy for UnmarkFiltered
1963 ScViewUtil::UnmarkFiltered( aFuncMark
, pDoc
);
1965 if (bRecord
&& !pDoc
->IsUndoEnabled())
1968 ScDocShellModificator
aModificator( *pDocSh
);
1970 if ( !aFuncMark
.IsMarked() && !aFuncMark
.IsMultiMarked() )
1972 aMarkRange
.aStart
.SetCol(GetViewData()->GetCurX());
1973 aMarkRange
.aStart
.SetRow(GetViewData()->GetCurY());
1974 aMarkRange
.aStart
.SetTab(GetViewData()->GetTabNo());
1975 aMarkRange
.aEnd
= aMarkRange
.aStart
;
1976 if ( pDoc
->HasAttrib( aMarkRange
, HASATTR_MERGED
) )
1978 // InitOwnBlockMode();
1979 aFuncMark
.SetMarkArea( aMarkRange
);
1985 aFuncMark
.SetMarking(FALSE
); // for MarkToMulti
1986 aFuncMark
.MarkToSimple(); // before bMulti test below
1988 DBG_ASSERT( aFuncMark
.IsMarked() || aFuncMark
.IsMultiMarked() || bSimple
, "delete what?" );
1990 ScDocument
* pUndoDoc
= NULL
;
1991 BOOL bMulti
= !bSimple
&& aFuncMark
.IsMultiMarked();
1994 aFuncMark
.MarkToMulti();
1995 aFuncMark
.GetMultiMarkArea( aMarkRange
);
1997 ScRange
aExtendedRange(aMarkRange
);
2000 if ( pDoc
->ExtendMerge( aExtendedRange
, TRUE
) )
2004 // keine Objekte auf geschuetzten Tabellen
2005 BOOL bObjects
= FALSE
;
2006 if ( nFlags
& IDF_OBJECTS
)
2009 SCTAB nTabCount
= pDoc
->GetTableCount();
2010 for (SCTAB nTab
=0; nTab
<nTabCount
; nTab
++)
2011 if (aFuncMark
.GetTableSelect(nTab
) && pDoc
->IsTabProtected(nTab
))
2015 USHORT nExtFlags
= 0; // extra flags are needed only if attributes are deleted
2016 if ( nFlags
& IDF_ATTRIB
)
2017 pDocSh
->UpdatePaintExt( nExtFlags
, aMarkRange
);
2021 // 2) Objekte loeschen (DrawUndo wird gefuellt)
2022 // 3) Inhalte fuer Undo kopieren
2023 // 4) Inhalte loeschen
2024 // 5) Undo-Aktion anlegen
2026 BOOL bDrawUndo
= bObjects
|| ( nFlags
& IDF_NOTE
); // needed for shown notes
2027 if ( bDrawUndo
&& bRecord
)
2028 pDoc
->BeginDrawUndo();
2033 pDoc
->DeleteObjectsInSelection( aFuncMark
);
2035 pDoc
->DeleteObjectsInArea( aMarkRange
.aStart
.Col(), aMarkRange
.aStart
.Row(),
2036 /*!*/ aMarkRange
.aEnd
.Col(), aMarkRange
.aEnd
.Row(),
2042 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
2043 SCTAB nTab
= aMarkRange
.aStart
.Tab();
2044 pUndoDoc
->InitUndo( pDoc
, nTab
, nTab
);
2045 SCTAB nTabCount
= pDoc
->GetTableCount();
2046 for (SCTAB i
=0; i
<nTabCount
; i
++)
2047 if (i
!= nTab
&& aFuncMark
.GetTableSelect(i
))
2048 pUndoDoc
->AddUndoTab( i
, i
);
2049 ScRange aCopyRange
= aExtendedRange
;
2050 aCopyRange
.aStart
.SetTab(0);
2051 aCopyRange
.aEnd
.SetTab(nTabCount
-1);
2053 // bei "Format/Standard" alle Attribute kopieren, weil CopyToDocument
2054 // nur mit IDF_HARDATTR zu langsam ist:
2055 USHORT nUndoDocFlags
= nFlags
;
2056 if (nFlags
& IDF_ATTRIB
)
2057 nUndoDocFlags
|= IDF_ATTRIB
;
2058 if (nFlags
& IDF_EDITATTR
) // Edit-Engine-Attribute
2059 nUndoDocFlags
|= IDF_STRING
; // -> Zellen werden geaendert
2060 if (nFlags
& IDF_NOTE
)
2061 nUndoDocFlags
|= IDF_CONTENTS
; // #68795# copy all cells with their notes
2062 // do not copy note captions to undo document
2063 nUndoDocFlags
|= IDF_NOCAPTIONS
;
2064 pDoc
->CopyToDocument( aCopyRange
, nUndoDocFlags
, bMulti
, pUndoDoc
, &aFuncMark
);
2067 HideAllCursors(); // falls Zusammenfassung aufgehoben wird
2069 pDoc
->DeleteArea( aMarkRange
.aStart
.Col(), aMarkRange
.aStart
.Row(),
2070 aMarkRange
.aEnd
.Col(), aMarkRange
.aEnd
.Row(),
2071 aFuncMark
, nFlags
);
2074 pDoc
->DeleteSelection( nFlags
, aFuncMark
);
2075 // aFuncMark.MarkToSimple();
2080 pDocSh
->GetUndoManager()->AddUndoAction(
2081 new ScUndoDeleteContents( pDocSh
, aFuncMark
, aExtendedRange
,
2082 pUndoDoc
, bMulti
, nFlags
, bDrawUndo
) );
2085 if (!AdjustRowHeight( aExtendedRange
.aStart
.Row(), aExtendedRange
.aEnd
.Row() ))
2086 pDocSh
->PostPaint( aExtendedRange
, PAINT_GRID
, nExtFlags
);
2088 pDocSh
->UpdateOle(GetViewData());
2090 // #i97876# Spreadsheet data changes are not notified
2091 ScModelObj
* pModelObj
= ScModelObj::getImplementation( pDocSh
->GetModel() );
2092 if ( pModelObj
&& pModelObj
->HasChangesListeners() )
2094 ScRangeList aChangeRanges
;
2097 aChangeRanges
.Append( aMarkRange
);
2101 aFuncMark
.FillRangeListWithMarks( &aChangeRanges
, FALSE
);
2103 pModelObj
->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "cell-change" ) ), aChangeRanges
);
2106 aModificator
.SetDocumentModified();
2107 CellContentChanged();
2110 if ( nFlags
& IDF_ATTRIB
)
2112 if ( nFlags
& IDF_CONTENTS
)
2115 StartFormatArea(); // Attribute loeschen ist auch Attributierung
2119 // Spaltenbreiten/Zeilenhoehen (ueber Header) - Undo OK
2121 void ScViewFunc::SetWidthOrHeight( BOOL bWidth
, SCCOLROW nRangeCnt
, SCCOLROW
* pRanges
,
2122 ScSizeMode eMode
, USHORT nSizeTwips
,
2123 BOOL bRecord
, BOOL bPaint
, ScMarkData
* pMarkData
)
2128 // use view's mark if none specified
2130 pMarkData
= &GetViewData()->GetMarkData();
2132 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
2133 ScDocument
* pDoc
= pDocSh
->GetDocument();
2134 SCTAB nTabCount
= pDoc
->GetTableCount();
2135 SCTAB nFirstTab
= pMarkData
->GetFirstSelected();
2136 SCTAB nCurTab
= GetViewData()->GetTabNo();
2138 if (bRecord
&& !pDoc
->IsUndoEnabled())
2141 ScDocShellModificator
aModificator( *pDocSh
);
2143 BOOL bAllowed
= TRUE
;
2144 for (nTab
=0; nTab
<nTabCount
&& bAllowed
; nTab
++)
2145 if (pMarkData
->GetTableSelect(nTab
))
2147 for ( SCCOLROW i
=0; i
<nRangeCnt
&& bAllowed
; i
++ )
2151 bAllowed
= pDoc
->IsBlockEditable( nTab
,
2152 static_cast<SCCOL
>(pRanges
[2*i
]),0,
2153 static_cast<SCCOL
>(pRanges
[2*i
+1]),MAXROW
,
2154 &bOnlyMatrix
) || bOnlyMatrix
;
2156 bAllowed
= pDoc
->IsBlockEditable( nTab
, 0,pRanges
[2*i
],
2157 MAXCOL
,pRanges
[2*i
+1], &bOnlyMatrix
) ||
2162 // Allow users to resize cols/rows in readonly docs despite the r/o state.
2163 // It is frustrating to be unable to see content in mis-sized cells.
2164 if( !bAllowed
&& !pDocSh
->IsReadOnly() )
2166 ErrorMessage(STR_PROTECTIONERR
);
2170 SCCOLROW nStart
= pRanges
[0];
2171 SCCOLROW nEnd
= pRanges
[2*nRangeCnt
-1];
2173 BOOL bFormula
= FALSE
;
2174 if ( eMode
== SC_SIZE_OPTIMAL
)
2176 const ScViewOptions
& rOpts
= GetViewData()->GetOptions();
2177 bFormula
= rOpts
.GetOption( VOPT_FORMULAS
);
2180 ScDocument
* pUndoDoc
= NULL
;
2181 ScOutlineTable
* pUndoTab
= NULL
;
2182 SCCOLROW
* pUndoRanges
= NULL
;
2186 pDoc
->BeginDrawUndo(); // Drawing Updates
2188 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
2189 for (nTab
=0; nTab
<nTabCount
; nTab
++)
2190 if (pMarkData
->GetTableSelect(nTab
))
2194 if ( nTab
== nFirstTab
)
2195 pUndoDoc
->InitUndo( pDoc
, nTab
, nTab
, TRUE
, FALSE
);
2197 pUndoDoc
->AddUndoTab( nTab
, nTab
, TRUE
, FALSE
);
2198 pDoc
->CopyToDocument( static_cast<SCCOL
>(nStart
), 0, nTab
,
2199 static_cast<SCCOL
>(nEnd
), MAXROW
, nTab
, IDF_NONE
,
2204 if ( nTab
== nFirstTab
)
2205 pUndoDoc
->InitUndo( pDoc
, nTab
, nTab
, FALSE
, TRUE
);
2207 pUndoDoc
->AddUndoTab( nTab
, nTab
, FALSE
, TRUE
);
2208 pDoc
->CopyToDocument( 0, nStart
, nTab
, MAXCOL
, nEnd
, nTab
, IDF_NONE
, FALSE
, pUndoDoc
);
2212 pUndoRanges
= new SCCOLROW
[ 2*nRangeCnt
];
2213 memmove( pUndoRanges
, pRanges
, 2*nRangeCnt
*sizeof(SCCOLROW
) );
2215 //! outlines from all tables?
2216 ScOutlineTable
* pTable
= pDoc
->GetOutlineTable( nCurTab
);
2218 pUndoTab
= new ScOutlineTable( *pTable
);
2221 if ( eMode
==SC_SIZE_OPTIMAL
|| eMode
==SC_SIZE_VISOPT
)
2222 pMarkData
->MarkToMulti();
2224 BOOL bShow
= nSizeTwips
> 0 || eMode
!= SC_SIZE_DIRECT
;
2225 BOOL bOutline
= FALSE
;
2227 for (nTab
=0; nTab
<nTabCount
; nTab
++)
2228 if (pMarkData
->GetTableSelect(nTab
))
2230 const SCCOLROW
* pTabRanges
= pRanges
;
2232 pDoc
->IncSizeRecalcLevel( nTab
); // nicht fuer jede Spalte einzeln
2233 for (SCCOLROW nRangeNo
=0; nRangeNo
<nRangeCnt
; nRangeNo
++)
2235 SCCOLROW nStartNo
= *(pTabRanges
++);
2236 SCCOLROW nEndNo
= *(pTabRanges
++);
2238 if ( !bWidth
) // Hoehen immer blockweise
2240 if ( eMode
==SC_SIZE_OPTIMAL
|| eMode
==SC_SIZE_VISOPT
)
2242 BOOL bAll
= ( eMode
==SC_SIZE_OPTIMAL
);
2245 // fuer alle eingeblendeten CR_MANUALSIZE loeschen,
2246 // dann SetOptimalHeight mit bShrink = FALSE
2247 for (SCROW nRow
= nStartNo
; nRow
<= nEndNo
; ++nRow
)
2249 SCROW nLastRow
= nRow
;
2250 if (pDoc
->RowHidden(nRow
, nTab
, NULL
, &nLastRow
))
2256 BYTE nOld
= pDoc
->GetRowFlags(nRow
, nTab
);
2257 if (nOld
& CR_MANUALSIZE
)
2258 pDoc
->SetRowFlags(nRow
, nTab
, nOld
& ~CR_MANUALSIZE
);
2262 double nPPTX
= GetViewData()->GetPPTX();
2263 double nPPTY
= GetViewData()->GetPPTY();
2264 Fraction aZoomX
= GetViewData()->GetZoomX();
2265 Fraction aZoomY
= GetViewData()->GetZoomY();
2267 ScSizeDeviceProvider
aProv(pDocSh
);
2268 if (aProv
.IsPrinter())
2270 nPPTX
= aProv
.GetPPTX();
2271 nPPTY
= aProv
.GetPPTY();
2272 aZoomX
= aZoomY
= Fraction( 1, 1 );
2275 pDoc
->SetOptimalHeight( nStartNo
, nEndNo
, nTab
, nSizeTwips
, aProv
.GetDevice(),
2276 nPPTX
, nPPTY
, aZoomX
, aZoomY
, bAll
);
2278 pDoc
->ShowRows( nStartNo
, nEndNo
, nTab
, TRUE
);
2280 // Manual-Flag wird bei bAll=TRUE schon in SetOptimalHeight gesetzt
2281 // (an bei Extra-Height, sonst aus).
2283 else if ( eMode
==SC_SIZE_DIRECT
)
2287 pDoc
->SetRowHeightRange( nStartNo
, nEndNo
, nTab
, nSizeTwips
);
2288 pDoc
->SetManualHeight( nStartNo
, nEndNo
, nTab
, TRUE
); // height was set manually
2290 pDoc
->ShowRows( nStartNo
, nEndNo
, nTab
, nSizeTwips
!= 0 );
2292 else if ( eMode
==SC_SIZE_SHOW
)
2294 pDoc
->ShowRows( nStartNo
, nEndNo
, nTab
, TRUE
);
2297 else // Spaltenbreiten
2299 for (SCCOL nCol
=static_cast<SCCOL
>(nStartNo
); nCol
<=static_cast<SCCOL
>(nEndNo
); nCol
++)
2301 if ( eMode
!= SC_SIZE_VISOPT
|| !pDoc
->ColHidden(nCol
, nTab
) )
2303 USHORT nThisSize
= nSizeTwips
;
2305 if ( eMode
==SC_SIZE_OPTIMAL
|| eMode
==SC_SIZE_VISOPT
)
2306 nThisSize
= nSizeTwips
+ GetOptimalColWidth( nCol
, nTab
, bFormula
);
2308 pDoc
->SetColWidth( nCol
, nTab
, nThisSize
);
2310 pDoc
->ShowCol( nCol
, nTab
, bShow
);
2319 if ( pDoc
->UpdateOutlineCol( static_cast<SCCOL
>(nStartNo
),
2320 static_cast<SCCOL
>(nEndNo
), nTab
, bShow
) )
2325 if ( pDoc
->UpdateOutlineRow( nStartNo
, nEndNo
, nTab
, bShow
) )
2329 pDoc
->DecSizeRecalcLevel( nTab
); // nicht fuer jede Spalte einzeln
2338 pDocSh
->GetUndoManager()->AddUndoAction(
2339 new ScUndoWidthOrHeight( pDocSh
, *pMarkData
,
2340 nStart
, nCurTab
, nEnd
, nCurTab
,
2341 pUndoDoc
, nRangeCnt
, pUndoRanges
,
2342 pUndoTab
, eMode
, nSizeTwips
, bWidth
) );
2345 for (nTab
=0; nTab
<nTabCount
; nTab
++)
2346 if (pMarkData
->GetTableSelect(nTab
))
2347 pDoc
->UpdatePageBreaks( nTab
);
2349 GetViewData()->GetView()->UpdateScrollBars();
2355 for (nTab
=0; nTab
<nTabCount
; nTab
++)
2356 if (pMarkData
->GetTableSelect(nTab
))
2360 if (pDoc
->HasAttrib( static_cast<SCCOL
>(nStart
),0,nTab
,
2361 static_cast<SCCOL
>(nEnd
),MAXROW
,nTab
,
2362 HASATTR_MERGED
| HASATTR_OVERLAPPED
))
2364 if (nStart
> 0) // weiter oben anfangen wegen Linien und Cursor
2366 pDocSh
->PostPaint( static_cast<SCCOL
>(nStart
), 0, nTab
,
2367 MAXCOL
, MAXROW
, nTab
, PAINT_GRID
| PAINT_TOP
);
2371 if (pDoc
->HasAttrib( 0,nStart
,nTab
, MAXCOL
,nEnd
,nTab
, HASATTR_MERGED
| HASATTR_OVERLAPPED
))
2375 pDocSh
->PostPaint( 0, nStart
, nTab
, MAXCOL
, MAXROW
, nTab
, PAINT_GRID
| PAINT_LEFT
);
2379 pDocSh
->UpdateOle(GetViewData());
2380 if( !pDocSh
->IsReadOnly() )
2381 aModificator
.SetDocumentModified();
2386 // #i97876# Spreadsheet data changes are not notified
2389 ScModelObj
* pModelObj
= ScModelObj::getImplementation( pDocSh
->GetModel() );
2390 if ( pModelObj
&& pModelObj
->HasChangesListeners() )
2392 ScRangeList aChangeRanges
;
2393 for ( nTab
= 0; nTab
< nTabCount
; ++nTab
)
2395 if ( pMarkData
->GetTableSelect( nTab
) )
2397 const SCCOLROW
* pTabRanges
= pRanges
;
2398 for ( SCCOLROW nRange
= 0; nRange
< nRangeCnt
; ++nRange
)
2400 SCCOL nStartCol
= static_cast< SCCOL
>( *(pTabRanges
++) );
2401 SCCOL nEndCol
= static_cast< SCCOL
>( *(pTabRanges
++) );
2402 for ( SCCOL nCol
= nStartCol
; nCol
<= nEndCol
; ++nCol
)
2404 aChangeRanges
.Append( ScRange( nCol
, 0, nTab
) );
2409 pModelObj
->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "column-resize" ) ), aChangeRanges
);
2414 // Spaltenbreiten/Zeilenhoehen (ueber Blockmarken)
2416 void ScViewFunc::SetMarkedWidthOrHeight( BOOL bWidth
, ScSizeMode eMode
, USHORT nSizeTwips
,
2417 BOOL bRecord
, BOOL bPaint
)
2419 ScMarkData
& rMark
= GetViewData()->GetMarkData();
2421 rMark
.MarkToMulti();
2422 if (!rMark
.IsMultiMarked())
2424 SCCOL nCol
= GetViewData()->GetCurX();
2425 SCROW nRow
= GetViewData()->GetCurY();
2426 SCTAB nTab
= GetViewData()->GetTabNo();
2429 rMark
.SetMultiMarkArea( ScRange( nCol
,nRow
,nTab
), TRUE
);
2433 SCCOLROW
* pRanges
= new SCCOLROW
[MAXCOLROWCOUNT
];
2434 SCCOLROW nRangeCnt
= 0;
2437 nRangeCnt
= rMark
.GetMarkColumnRanges( pRanges
);
2439 nRangeCnt
= rMark
.GetMarkRowRanges( pRanges
);
2441 SetWidthOrHeight( bWidth
, nRangeCnt
, pRanges
, eMode
, nSizeTwips
, bRecord
, bPaint
);
2444 rMark
.MarkToSimple();
2447 void ScViewFunc::ModifyCellSize( ScDirection eDir
, BOOL bOptimal
)
2449 //! Schrittweiten einstellbar
2450 // Schrittweite ist auch Minimum
2451 USHORT nStepX
= STD_COL_WIDTH
/ 5;
2452 USHORT nStepY
= ScGlobal::nStdRowHeight
;
2454 ScModule
* pScMod
= SC_MOD();
2455 BOOL bAnyEdit
= pScMod
->IsInputMode();
2456 SCCOL nCol
= GetViewData()->GetCurX();
2457 SCROW nRow
= GetViewData()->GetCurY();
2458 SCTAB nTab
= GetViewData()->GetTabNo();
2459 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
2460 ScDocument
* pDoc
= pDocSh
->GetDocument();
2462 BOOL bAllowed
, bOnlyMatrix
;
2463 if ( eDir
== DIR_LEFT
|| eDir
== DIR_RIGHT
)
2464 bAllowed
= pDoc
->IsBlockEditable( nTab
, nCol
,0, nCol
,MAXROW
, &bOnlyMatrix
);
2466 bAllowed
= pDoc
->IsBlockEditable( nTab
, 0,nRow
, MAXCOL
,nRow
, &bOnlyMatrix
);
2467 if ( !bAllowed
&& !bOnlyMatrix
)
2469 ErrorMessage(STR_PROTECTIONERR
);
2475 USHORT nWidth
= pDoc
->GetColWidth( nCol
, nTab
);
2476 USHORT nHeight
= pDoc
->GetRowHeight( nRow
, nTab
);
2478 if ( eDir
== DIR_LEFT
|| eDir
== DIR_RIGHT
)
2480 if (bOptimal
) // Breite dieser einen Zelle
2484 // beim Editieren die aktuelle Breite der Eingabe
2485 ScInputHandler
* pHdl
= pScMod
->GetInputHdl( GetViewData()->GetViewShell() );
2488 long nEdit
= pHdl
->GetTextSize().Width(); // in 1/100mm
2490 const ScPatternAttr
* pPattern
= pDoc
->GetPattern( nCol
, nRow
, nTab
);
2491 const SvxMarginItem
& rMItem
=
2492 (const SvxMarginItem
&)pPattern
->GetItem(ATTR_MARGIN
);
2493 USHORT nMargin
= rMItem
.GetLeftMargin() + rMItem
.GetRightMargin();
2494 if ( ((const SvxHorJustifyItem
&) pPattern
->
2495 GetItem( ATTR_HOR_JUSTIFY
)).GetValue() == SVX_HOR_JUSTIFY_LEFT
)
2496 nMargin
= sal::static_int_cast
<USHORT
>(
2497 nMargin
+ ((const SfxUInt16Item
&)pPattern
->GetItem(ATTR_INDENT
)).GetValue() );
2499 nWidth
= (USHORT
)(nEdit
* pDocSh
->GetOutputFactor() / HMM_PER_TWIPS
)
2500 + nMargin
+ STD_EXTRA_WIDTH
;
2505 double nPPTX
= GetViewData()->GetPPTX();
2506 double nPPTY
= GetViewData()->GetPPTY();
2507 Fraction aZoomX
= GetViewData()->GetZoomX();
2508 Fraction aZoomY
= GetViewData()->GetZoomY();
2510 ScSizeDeviceProvider
aProv(pDocSh
);
2511 if (aProv
.IsPrinter())
2513 nPPTX
= aProv
.GetPPTX();
2514 nPPTY
= aProv
.GetPPTY();
2515 aZoomX
= aZoomY
= Fraction( 1, 1 );
2518 long nPixel
= pDoc
->GetNeededSize( nCol
, nRow
, nTab
, aProv
.GetDevice(),
2519 nPPTX
, nPPTY
, aZoomX
, aZoomY
, TRUE
);
2520 USHORT nTwips
= (USHORT
)( nPixel
/ nPPTX
);
2522 nWidth
= nTwips
+ STD_EXTRA_WIDTH
;
2524 nWidth
= STD_COL_WIDTH
;
2527 else // vergroessern / verkleinern
2529 if ( eDir
== DIR_RIGHT
)
2530 nWidth
= sal::static_int_cast
<USHORT
>( nWidth
+ nStepX
);
2531 else if ( nWidth
> nStepX
)
2532 nWidth
= sal::static_int_cast
<USHORT
>( nWidth
- nStepX
);
2533 if ( nWidth
< nStepX
) nWidth
= nStepX
;
2534 if ( nWidth
> MAX_COL_WIDTH
) nWidth
= MAX_COL_WIDTH
;
2536 nRange
[0] = nRange
[1] = nCol
;
2537 SetWidthOrHeight( TRUE
, 1, nRange
, SC_SIZE_DIRECT
, nWidth
);
2539 // hier bei Breite auch Hoehe anpassen (nur die eine Zeile)
2543 const ScPatternAttr
* pPattern
= pDoc
->GetPattern( nCol
, nRow
, nTab
);
2545 ((const SfxBoolItem
&)pPattern
->GetItem( ATTR_LINEBREAK
)).GetValue() ||
2546 ((const SvxHorJustifyItem
&)pPattern
->
2547 GetItem( ATTR_HOR_JUSTIFY
)).GetValue() == SVX_HOR_JUSTIFY_BLOCK
;
2549 AdjustRowHeight( nRow
, nRow
);
2557 eMode
= SC_SIZE_OPTIMAL
;
2562 eMode
= SC_SIZE_DIRECT
;
2563 if ( eDir
== DIR_BOTTOM
)
2564 nHeight
= sal::static_int_cast
<USHORT
>( nHeight
+ nStepY
);
2565 else if ( nHeight
> nStepY
)
2566 nHeight
= sal::static_int_cast
<USHORT
>( nHeight
- nStepY
);
2567 if ( nHeight
< nStepY
) nHeight
= nStepY
;
2568 if ( nHeight
> MAX_COL_HEIGHT
) nHeight
= MAX_COL_HEIGHT
;
2569 //! MAX_COL_HEIGHT umbenennen in MAX_ROW_HEIGHT in global.hxx !!!!!!
2571 nRange
[0] = nRange
[1] = nRow
;
2572 SetWidthOrHeight( FALSE
, 1, nRange
, eMode
, nHeight
);
2578 if ( pDoc
->HasAttrib( nCol
, nRow
, nTab
, nCol
, nRow
, nTab
, HASATTR_NEEDHEIGHT
) )
2580 ScInputHandler
* pHdl
= pScMod
->GetInputHdl( GetViewData()->GetViewShell() );
2582 pHdl
->SetModified(); // damit bei Enter die Hoehe angepasst wird
2589 void ScViewFunc::ProtectSheet( SCTAB nTab
, const ScTableProtection
& rProtect
)
2591 if (nTab
== TABLEID_DOC
)
2594 ScMarkData
& rMark
= GetViewData()->GetMarkData();
2595 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
2596 ScDocument
* pDoc
= pDocSh
->GetDocument();
2597 ScDocFunc
aFunc(*pDocSh
);
2598 bool bUndo(pDoc
->IsUndoEnabled());
2600 // modifying several tables is handled here
2604 String aUndo
= ScGlobal::GetRscString( STR_UNDO_PROTECT_TAB
);
2605 pDocSh
->GetUndoManager()->EnterListAction( aUndo
, aUndo
);
2608 SCTAB nCount
= pDocSh
->GetDocument()->GetTableCount();
2609 for ( SCTAB i
=0; i
<nCount
; i
++ )
2610 if ( rMark
.GetTableSelect(i
) )
2611 aFunc
.ProtectSheet(i
, rProtect
);
2614 pDocSh
->GetUndoManager()->LeaveListAction();
2616 UpdateLayerLocks(); //! broadcast to all views
2619 void ScViewFunc::Protect( SCTAB nTab
, const String
& rPassword
)
2621 ScMarkData
& rMark
= GetViewData()->GetMarkData();
2622 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
2623 ScDocument
* pDoc
= pDocSh
->GetDocument();
2624 ScDocFunc
aFunc(*pDocSh
);
2625 BOOL
bUndo(pDoc
->IsUndoEnabled());
2627 if ( nTab
== TABLEID_DOC
|| rMark
.GetSelectCount() <= 1 )
2628 aFunc
.Protect( nTab
, rPassword
, FALSE
);
2631 // modifying several tables is handled here
2635 String aUndo
= ScGlobal::GetRscString( STR_UNDO_PROTECT_TAB
);
2636 pDocSh
->GetUndoManager()->EnterListAction( aUndo
, aUndo
);
2639 SCTAB nCount
= pDocSh
->GetDocument()->GetTableCount();
2640 for ( SCTAB i
=0; i
<nCount
; i
++ )
2641 if ( rMark
.GetTableSelect(i
) )
2642 aFunc
.Protect( i
, rPassword
, FALSE
);
2645 pDocSh
->GetUndoManager()->LeaveListAction();
2648 UpdateLayerLocks(); //! broadcast to all views
2651 BOOL
ScViewFunc::Unprotect( SCTAB nTab
, const String
& rPassword
)
2653 ScMarkData
& rMark
= GetViewData()->GetMarkData();
2654 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
2655 ScDocument
* pDoc
= pDocSh
->GetDocument();
2656 ScDocFunc
aFunc(*pDocSh
);
2657 BOOL bChanged
= FALSE
;
2658 BOOL
bUndo (pDoc
->IsUndoEnabled());
2660 if ( nTab
== TABLEID_DOC
|| rMark
.GetSelectCount() <= 1 )
2661 bChanged
= aFunc
.Unprotect( nTab
, rPassword
, FALSE
);
2664 // modifying several tables is handled here
2668 String aUndo
= ScGlobal::GetRscString( STR_UNDO_UNPROTECT_TAB
);
2669 pDocSh
->GetUndoManager()->EnterListAction( aUndo
, aUndo
);
2672 SCTAB nCount
= pDocSh
->GetDocument()->GetTableCount();
2673 for ( SCTAB i
=0; i
<nCount
; i
++ )
2674 if ( rMark
.GetTableSelect(i
) )
2675 if ( aFunc
.Unprotect( i
, rPassword
, FALSE
) )
2679 pDocSh
->GetUndoManager()->LeaveListAction();
2683 UpdateLayerLocks(); //! broadcast to all views
2688 void ScViewFunc::SetNoteText( const ScAddress
& rPos
, const String
& rNoteText
)
2690 GetViewData()->GetDocShell()->GetDocFunc().SetNoteText( rPos
, rNoteText
, FALSE
);
2693 void ScViewFunc::ReplaceNote( const ScAddress
& rPos
, const String
& rNoteText
, const String
* pAuthor
, const String
* pDate
)
2695 GetViewData()->GetDocShell()->GetDocFunc().ReplaceNote( rPos
, rNoteText
, pAuthor
, pDate
, FALSE
);
2698 void ScViewFunc::SetNumberFormat( short nFormatType
, ULONG nAdd
)
2700 // nur wegen Matrix nicht editierbar? Attribute trotzdem ok
2701 BOOL bOnlyNotBecauseOfMatrix
;
2702 if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix
) && !bOnlyNotBecauseOfMatrix
)
2704 ErrorMessage(STR_PROTECTIONERR
);
2708 sal_uInt32 nNumberFormat
= 0;
2709 ScViewData
* pViewData
= GetViewData();
2710 ScDocument
* pDoc
= pViewData
->GetDocument();
2711 SvNumberFormatter
* pNumberFormatter
= pDoc
->GetFormatTable();
2712 LanguageType eLanguage
= ScGlobal::eLnge
;
2713 ScPatternAttr
aNewAttrs( pDoc
->GetPool() );
2715 // #67936# always take language from cursor position, even if there is a selection
2717 sal_uInt32 nCurrentNumberFormat
;
2718 pDoc
->GetNumberFormat( pViewData
->GetCurX(),
2719 pViewData
->GetCurY(),
2720 pViewData
->GetTabNo(),
2721 nCurrentNumberFormat
);
2722 const SvNumberformat
* pEntry
= pNumberFormatter
->GetEntry( nCurrentNumberFormat
);
2724 eLanguage
= pEntry
->GetLanguage(); // sonst ScGlobal::eLnge behalten
2726 nNumberFormat
= pNumberFormatter
->GetStandardFormat( nFormatType
, eLanguage
) + nAdd
;
2728 SfxItemSet
& rSet
= aNewAttrs
.GetItemSet();
2729 rSet
.Put( SfxUInt32Item( ATTR_VALUE_FORMAT
, nNumberFormat
) );
2730 // ATTR_LANGUAGE_FORMAT nicht
2731 ApplySelectionPattern( aNewAttrs
, TRUE
);
2734 void ScViewFunc::SetNumFmtByStr( const String
& rCode
)
2736 // nur wegen Matrix nicht editierbar? Attribute trotzdem ok
2737 BOOL bOnlyNotBecauseOfMatrix
;
2738 if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix
) && !bOnlyNotBecauseOfMatrix
)
2740 ErrorMessage(STR_PROTECTIONERR
);
2744 ScViewData
* pViewData
= GetViewData();
2745 ScDocument
* pDoc
= pViewData
->GetDocument();
2746 SvNumberFormatter
* pFormatter
= pDoc
->GetFormatTable();
2748 // Sprache immer von Cursorposition
2750 sal_uInt32 nCurrentNumberFormat
;
2751 pDoc
->GetNumberFormat( pViewData
->GetCurX(), pViewData
->GetCurY(),
2752 pViewData
->GetTabNo(), nCurrentNumberFormat
);
2753 const SvNumberformat
* pEntry
= pFormatter
->GetEntry( nCurrentNumberFormat
);
2754 LanguageType eLanguage
= pEntry
? pEntry
->GetLanguage() : ScGlobal::eLnge
;
2756 // Index fuer String bestimmen
2759 sal_uInt32 nNumberFormat
= pFormatter
->GetEntryKey( rCode
, eLanguage
);
2760 if ( nNumberFormat
== NUMBERFORMAT_ENTRY_NOT_FOUND
)
2764 String aFormat
= rCode
; // wird veraendert
2765 xub_StrLen nErrPos
= 0;
2766 short nType
= 0; //! ???
2767 bOk
= pFormatter
->PutEntry( aFormat
, nErrPos
, nType
, nNumberFormat
, eLanguage
);
2770 if ( bOk
) // gueltiges Format?
2772 ScPatternAttr
aNewAttrs( pDoc
->GetPool() );
2773 SfxItemSet
& rSet
= aNewAttrs
.GetItemSet();
2774 rSet
.Put( SfxUInt32Item( ATTR_VALUE_FORMAT
, nNumberFormat
) );
2775 rSet
.Put( SvxLanguageItem( eLanguage
, ATTR_LANGUAGE_FORMAT
) );
2776 ApplySelectionPattern( aNewAttrs
, TRUE
);
2779 //! sonst Fehler zuerueckgeben / Meldung ausgeben ???
2782 void ScViewFunc::ChangeNumFmtDecimals( BOOL bIncrement
)
2784 // nur wegen Matrix nicht editierbar? Attribute trotzdem ok
2785 BOOL bOnlyNotBecauseOfMatrix
;
2786 if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix
) && !bOnlyNotBecauseOfMatrix
)
2788 ErrorMessage(STR_PROTECTIONERR
);
2792 ScDocument
* pDoc
= GetViewData()->GetDocument();
2793 SvNumberFormatter
* pFormatter
= pDoc
->GetFormatTable();
2795 SCCOL nCol
= GetViewData()->GetCurX();
2796 SCROW nRow
= GetViewData()->GetCurY();
2797 SCTAB nTab
= GetViewData()->GetTabNo();
2799 sal_uInt32 nOldFormat
;
2800 pDoc
->GetNumberFormat( nCol
, nRow
, nTab
, nOldFormat
);
2801 const SvNumberformat
* pOldEntry
= pFormatter
->GetEntry( nOldFormat
);
2804 DBG_ERROR("Zahlformat nicht gefunden !!!");
2808 // was haben wir denn da?
2810 sal_uInt32 nNewFormat
= nOldFormat
;
2811 BOOL bError
= FALSE
;
2813 LanguageType eLanguage
= pOldEntry
->GetLanguage();
2814 BOOL bThousand
, bNegRed
;
2815 USHORT nPrecision
, nLeading
;
2816 pOldEntry
->GetFormatSpecialInfo( bThousand
, bNegRed
, nPrecision
, nLeading
);
2818 short nOldType
= pOldEntry
->GetType();
2819 if ( 0 == ( nOldType
& (
2820 NUMBERFORMAT_NUMBER
| NUMBERFORMAT_CURRENCY
| NUMBERFORMAT_PERCENT
) ) )
2822 // Datum, Zeit, Bruch, logisch, Text kann nicht angepasst werden
2823 //! bei Wisssenschaftlich kann es der Numberformatter auch nicht
2827 //! Das SvNumberformat hat einen Member bStandard, verraet ihn aber nicht
2828 BOOL bWasStandard
= ( nOldFormat
== pFormatter
->GetStandardIndex( eLanguage
) );
2831 // bei "Standard" die Nachkommastellen abhaengig vom Zellinhalt
2832 // 0 bei leer oder Text -> keine Nachkommastellen
2833 double nVal
= pDoc
->GetValue( ScAddress( nCol
, nRow
, nTab
) );
2835 // Die Wege des Numberformatters sind unergruendlich, darum ausprobieren:
2838 ((SvNumberformat
*)pOldEntry
)->GetOutputString( nVal
, aOut
, &pCol
);
2841 // 'E' fuer Exponential ist fest im Numberformatter
2842 if ( aOut
.Search('E') != STRING_NOTFOUND
)
2843 bError
= TRUE
; // Exponential nicht veraendern
2846 String
aDecSep( pFormatter
->GetFormatDecimalSep( nOldFormat
) );
2847 xub_StrLen nPos
= aOut
.Search( aDecSep
);
2848 if ( nPos
!= STRING_NOTFOUND
)
2849 nPrecision
= aOut
.Len() - nPos
- aDecSep
.Len();
2859 ++nPrecision
; // erhoehen
2861 bError
= TRUE
; // 20 ist Maximum
2866 --nPrecision
; // vermindern
2868 bError
= TRUE
; // weniger als 0 geht nicht
2875 pFormatter
->GenerateFormat( aNewPicture
, nOldFormat
, eLanguage
,
2876 bThousand
, bNegRed
, nPrecision
, nLeading
);
2878 nNewFormat
= pFormatter
->GetEntryKey( aNewPicture
, eLanguage
);
2879 if ( nNewFormat
== NUMBERFORMAT_ENTRY_NOT_FOUND
)
2881 xub_StrLen nErrPos
= 0;
2883 BOOL bOk
= pFormatter
->PutEntry( aNewPicture
, nErrPos
,
2884 nNewType
, nNewFormat
, eLanguage
);
2885 DBG_ASSERT( bOk
, "falsches Zahlformat generiert" );
2893 ScPatternAttr
aNewAttrs( pDoc
->GetPool() );
2894 SfxItemSet
& rSet
= aNewAttrs
.GetItemSet();
2895 rSet
.Put( SfxUInt32Item( ATTR_VALUE_FORMAT
, nNewFormat
) );
2896 // ATTR_LANGUAGE_FORMAT nicht
2897 ApplySelectionPattern( aNewAttrs
, TRUE
);
2900 Sound::Beep(); // war nix
2903 void ScViewFunc::ChangeIndent( BOOL bIncrement
)
2905 ScViewData
* pViewData
= GetViewData();
2906 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
2907 ScMarkData
& rMark
= pViewData
->GetMarkData();
2909 ScMarkData aWorkMark
= rMark
;
2910 ScViewUtil::UnmarkFiltered( aWorkMark
, pDocSh
->GetDocument() );
2911 aWorkMark
.MarkToMulti();
2912 if (!aWorkMark
.IsMultiMarked())
2914 SCCOL nCol
= pViewData
->GetCurX();
2915 SCROW nRow
= pViewData
->GetCurY();
2916 SCTAB nTab
= pViewData
->GetTabNo();
2917 aWorkMark
.SetMultiMarkArea( ScRange(nCol
,nRow
,nTab
) );
2920 BOOL bSuccess
= pDocSh
->GetDocFunc().ChangeIndent( aWorkMark
, bIncrement
, FALSE
);
2923 pDocSh
->UpdateOle(pViewData
);
2928 BOOL
ScViewFunc::InsertName( const String
& rName
, const String
& rSymbol
,
2929 const String
& rType
)
2931 // Type = P,R,C,F (und Kombinationen)
2935 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
2936 ScDocument
* pDoc
= pDocSh
->GetDocument();
2937 SCTAB nTab
= GetViewData()->GetTabNo();
2938 ScRangeName
* pList
= pDoc
->GetRangeName();
2940 RangeType nType
= RT_NAME
;
2941 ScRangeData
* pNewEntry
= new ScRangeData( pDoc
, rName
, rSymbol
,
2942 ScAddress( GetViewData()->GetCurX(), GetViewData()->GetCurY(),
2944 String aUpType
= rType
;
2945 aUpType
.ToUpperAscii();
2946 if ( aUpType
.Search( 'P' ) != STRING_NOTFOUND
)
2947 nType
|= RT_PRINTAREA
;
2948 if ( aUpType
.Search( 'R' ) != STRING_NOTFOUND
)
2949 nType
|= RT_ROWHEADER
;
2950 if ( aUpType
.Search( 'C' ) != STRING_NOTFOUND
)
2951 nType
|= RT_COLHEADER
;
2952 if ( aUpType
.Search( 'F' ) != STRING_NOTFOUND
)
2953 nType
|= RT_CRITERIA
;
2954 pNewEntry
->AddType(nType
);
2956 if ( !pNewEntry
->GetErrCode() ) // Text gueltig?
2958 ScDocShellModificator
aModificator( *pDocSh
);
2960 pDoc
->CompileNameFormula( TRUE
); // CreateFormulaString
2962 // Eintrag bereits vorhanden? Dann vorher entfernen (=Aendern)
2964 if ( pList
->SearchName( rName
, nFoundAt
) )
2965 { // alten Index uebernehmen
2966 pNewEntry
->SetIndex( ((ScRangeData
*)pList
->At(nFoundAt
))->GetIndex() );
2967 pList
->AtFree( nFoundAt
);
2970 if ( pList
->Insert( pNewEntry
) )
2972 pNewEntry
= NULL
; // nicht loeschen
2976 pDoc
->CompileNameFormula( FALSE
); // CompileFormulaString
2977 aModificator
.SetDocumentModified();
2978 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREAS_CHANGED
) );
2981 delete pNewEntry
; // wenn er nicht eingefuegt wurde
2985 void ScViewFunc::CreateNames( USHORT nFlags
)
2989 if ( GetViewData()->GetSimpleArea(aRange
) == SC_MARK_SIMPLE
)
2990 bDone
= GetViewData()->GetDocShell()->GetDocFunc().CreateNames( aRange
, nFlags
, FALSE
);
2993 ErrorMessage(STR_CREATENAME_MARKERR
);
2996 USHORT
ScViewFunc::GetCreateNameFlags()
3000 SCCOL nStartCol
, nEndCol
;
3001 SCROW nStartRow
, nEndRow
;
3003 if (GetViewData()->GetSimpleArea(nStartCol
,nStartRow
,nDummy
,nEndCol
,nEndRow
,nDummy
) == SC_MARK_SIMPLE
)
3005 ScDocument
* pDoc
= GetViewData()->GetDocument();
3006 SCTAB nTab
= GetViewData()->GetTabNo();
3012 SCCOL nFirstCol
= nStartCol
;
3013 SCCOL nLastCol
= nEndCol
;
3014 if (nStartCol
+1 < nEndCol
) { ++nFirstCol
; --nLastCol
; }
3015 for (i
=nFirstCol
; i
<=nLastCol
&& bOk
; i
++)
3016 if (!pDoc
->HasStringData( i
,nStartRow
,nTab
))
3020 else // Bottom nur wenn nicht Top
3023 for (i
=nFirstCol
; i
<=nLastCol
&& bOk
; i
++)
3024 if (!pDoc
->HasStringData( i
,nEndRow
,nTab
))
3027 nFlags
|= NAME_BOTTOM
;
3031 SCROW nFirstRow
= nStartRow
;
3032 SCROW nLastRow
= nEndRow
;
3033 if (nStartRow
+1 < nEndRow
) { ++nFirstRow
; --nLastRow
; }
3034 for (j
=nFirstRow
; j
<=nLastRow
&& bOk
; j
++)
3035 if (!pDoc
->HasStringData( nStartCol
,j
,nTab
))
3038 nFlags
|= NAME_LEFT
;
3039 else // Right nur wenn nicht Left
3042 for (j
=nFirstRow
; j
<=nLastRow
&& bOk
; j
++)
3043 if (!pDoc
->HasStringData( nEndCol
,j
,nTab
))
3046 nFlags
|= NAME_RIGHT
;
3050 if (nStartCol
== nEndCol
)
3051 nFlags
&= ~( NAME_LEFT
| NAME_RIGHT
);
3052 if (nStartRow
== nEndRow
)
3053 nFlags
&= ~( NAME_TOP
| NAME_BOTTOM
);
3058 void ScViewFunc::InsertNameList()
3060 ScAddress
aPos( GetViewData()->GetCurX(), GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
3061 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
3062 if ( pDocSh
->GetDocFunc().InsertNameList( aPos
, FALSE
) )
3063 pDocSh
->UpdateOle(GetViewData());