1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <config_features.h>
22 #include "scitems.hxx"
23 #include <editeng/eeitem.hxx>
25 #include <sfx2/app.hxx>
26 #include <svx/algitem.hxx>
27 #include <editeng/boxitem.hxx>
28 #include <editeng/editobj.hxx>
29 #include <editeng/editview.hxx>
30 #include <editeng/langitem.hxx>
31 #include <editeng/scripttypeitem.hxx>
32 #include <editeng/justifyitem.hxx>
33 #include <sfx2/bindings.hxx>
34 #include <svl/zforlist.hxx>
35 #include <svl/zformat.hxx>
36 #include <vcl/msgbox.hxx>
37 #include <vcl/virdev.hxx>
38 #include <vcl/waitobj.hxx>
39 #include <vcl/wrkwin.hxx>
42 #include "viewfunc.hxx"
43 #include "tabvwsh.hxx"
46 #include "patattr.hxx"
47 #include "docpool.hxx"
48 #include "uiitems.hxx"
50 #include "undocell.hxx"
51 #include "undoblk.hxx"
52 #include "undotab.hxx"
53 #include "refundo.hxx"
55 #include "olinetab.hxx"
56 #include "rangeutl.hxx"
57 #include "rangenam.hxx"
58 #include "globstr.hrc"
60 #include "stlsheet.hxx"
61 #include "editutil.hxx"
62 #include "formulacell.hxx"
63 #include "scresid.hxx"
64 #include "inputhdl.hxx"
66 #include "inputopt.hxx"
67 #include "compiler.hxx"
68 #include "docfunc.hxx"
69 #include "appoptio.hxx"
70 #include "dociter.hxx"
71 #include "sizedev.hxx"
72 #include "editable.hxx"
73 #include "scui_def.hxx"
74 #include "funcdesc.hxx"
76 #include "cellsuno.hxx"
77 #include "tokenarray.hxx"
78 #include <rowheightcontext.hxx>
79 #include <docfuncutil.hxx>
81 #include <boost/scoped_ptr.hpp>
83 static void lcl_PostRepaintCondFormat( const ScConditionalFormat
*pCondFmt
, ScDocShell
*pDocSh
)
87 const ScRangeList
& rRanges
= pCondFmt
->GetRange();
89 pDocSh
->PostPaint( rRanges
, PAINT_ALL
);
93 ScViewFunc::ScViewFunc( vcl::Window
* pParent
, ScDocShell
& rDocSh
, ScTabViewShell
* pViewShell
) :
94 ScTabView( pParent
, rDocSh
, pViewShell
),
99 ScViewFunc::~ScViewFunc()
103 void ScViewFunc::StartFormatArea()
106 if ( !SC_MOD()->GetInputOptions().GetExtendFormat() )
109 // start only with single cell (marked or cursor position)
111 bool bOk
= (GetViewData().GetSimpleArea( aMarkRange
) == SC_MARK_SIMPLE
);
112 if ( bOk
&& aMarkRange
.aStart
!= aMarkRange
.aEnd
)
118 aFormatSource
= aMarkRange
.aStart
;
119 aFormatArea
= ScRange( aFormatSource
);
122 bFormatValid
= false; // discard old range
125 bool ScViewFunc::TestFormatArea( SCCOL nCol
, SCROW nRow
, SCTAB nTab
, bool bAttrChanged
)
128 if ( !SC_MOD()->GetInputOptions().GetExtendFormat() )
131 // Test: treat input with numberformat (bAttrChanged) always as new Attribute
132 // (discard old Area ). If not wanted, discard if-statement
139 //! Test if cell empty ???
142 ScRange aNewRange
= aFormatArea
;
143 if ( bFormatValid
&& nTab
== aFormatSource
.Tab() )
145 if ( nRow
>= aFormatArea
.aStart
.Row() && nRow
<= aFormatArea
.aEnd
.Row() )
148 if ( nCol
>= aFormatArea
.aStart
.Col() && nCol
<= aFormatArea
.aEnd
.Col() )
150 bFound
= true; // do not change range
153 if ( nCol
+1 == aFormatArea
.aStart
.Col() )
156 aNewRange
.aStart
.SetCol( nCol
);
159 if ( nCol
== aFormatArea
.aEnd
.Col()+1 )
162 aNewRange
.aEnd
.SetCol( nCol
);
165 if ( nCol
>= aFormatArea
.aStart
.Col() && nCol
<= aFormatArea
.aEnd
.Col() )
168 if ( nRow
+1 == aFormatArea
.aStart
.Row() )
171 aNewRange
.aStart
.SetRow( nRow
);
174 if ( nRow
== aFormatArea
.aEnd
.Row()+1 )
177 aNewRange
.aEnd
.SetRow( nRow
);
183 aFormatArea
= aNewRange
; // extend
185 bFormatValid
= false; // outside of range -> break
190 void ScViewFunc::DoAutoAttributes( SCCOL nCol
, SCROW nRow
, SCTAB nTab
,
191 bool bAttrChanged
, bool bAddUndo
)
193 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
194 ScDocument
& rDoc
= pDocSh
->GetDocument();
195 if (bAddUndo
&& !rDoc
.IsUndoEnabled())
198 const ScPatternAttr
* pSource
= rDoc
.GetPattern(
199 aFormatSource
.Col(), aFormatSource
.Row(), nTab
);
200 if ( !static_cast<const ScMergeAttr
&>(pSource
->GetItem(ATTR_MERGE
)).IsMerged() )
202 ScRange
aRange( nCol
, nRow
, nTab
, nCol
, nRow
, nTab
);
204 aMark
.SetMarkArea( aRange
);
206 ScDocFunc
&rFunc
= GetViewData().GetDocFunc();
208 // pOldPattern is only valid until call to ApplyAttributes!
209 const ScPatternAttr
* pOldPattern
= rDoc
.GetPattern( nCol
, nRow
, nTab
);
210 const ScStyleSheet
* pSrcStyle
= pSource
->GetStyleSheet();
211 if ( pSrcStyle
&& pSrcStyle
!= pOldPattern
->GetStyleSheet() )
212 rFunc
.ApplyStyle( aMark
, pSrcStyle
->GetName(), true, false );
214 rFunc
.ApplyAttributes( aMark
, *pSource
, true, false );
217 if ( bAttrChanged
) // value entered with number format?
218 aFormatSource
.Set( nCol
, nRow
, nTab
); // then set a new source
221 // additional routines
223 sal_uInt16
ScViewFunc::GetOptimalColWidth( SCCOL nCol
, SCTAB nTab
, bool bFormula
)
225 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
226 ScDocument
& rDoc
= pDocSh
->GetDocument();
227 ScMarkData
& rMark
= GetViewData().GetMarkData();
229 double nPPTX
= GetViewData().GetPPTX();
230 double nPPTY
= GetViewData().GetPPTY();
231 Fraction aZoomX
= GetViewData().GetZoomX();
232 Fraction aZoomY
= GetViewData().GetZoomY();
234 ScSizeDeviceProvider
aProv(pDocSh
);
235 if (aProv
.IsPrinter())
237 nPPTX
= aProv
.GetPPTX();
238 nPPTY
= aProv
.GetPPTY();
239 aZoomX
= aZoomY
= Fraction( 1, 1 );
242 sal_uInt16 nTwips
= rDoc
.GetOptimalColWidth( nCol
, nTab
, aProv
.GetDevice(),
243 nPPTX
, nPPTY
, aZoomX
, aZoomY
, bFormula
, &rMark
);
247 bool ScViewFunc::SelectionEditable( bool* pOnlyNotBecauseOfMatrix
/* = NULL */ )
250 ScDocument
* pDoc
= GetViewData().GetDocument();
251 ScMarkData
& rMark
= GetViewData().GetMarkData();
252 if (rMark
.IsMarked() || rMark
.IsMultiMarked())
253 bRet
= pDoc
->IsSelectionEditable( rMark
, pOnlyNotBecauseOfMatrix
);
256 SCCOL nCol
= GetViewData().GetCurX();
257 SCROW nRow
= GetViewData().GetCurY();
258 SCTAB nTab
= GetViewData().GetTabNo();
259 bRet
= pDoc
->IsBlockEditable( nTab
, nCol
, nRow
, nCol
, nRow
,
260 pOnlyNotBecauseOfMatrix
);
269 static bool lcl_FunctionKnown( sal_uInt16 nOpCode
)
271 const ScFunctionList
* pFuncList
= ScGlobal::GetStarCalcFunctionList();
274 sal_uLong nCount
= pFuncList
->GetCount();
275 for (sal_uLong i
=0; i
<nCount
; i
++)
276 if ( pFuncList
->GetFunction(i
)->nFIndex
== nOpCode
)
282 static bool lcl_AddFunction( ScAppOptions
& rAppOpt
, sal_uInt16 nOpCode
)
284 sal_uInt16 nOldCount
= rAppOpt
.GetLRUFuncListCount();
285 sal_uInt16
* pOldList
= rAppOpt
.GetLRUFuncList();
287 for (nPos
=0; nPos
<nOldCount
; nPos
++)
288 if (pOldList
[nPos
] == nOpCode
) // is the function already in the list?
291 return false; // already at the top -> no change
293 // count doesn't change, so the original array is modified
295 for (sal_uInt16 nCopy
=nPos
; nCopy
>0; nCopy
--)
296 pOldList
[nCopy
] = pOldList
[nCopy
-1];
297 pOldList
[0] = nOpCode
;
299 return true; // list has changed
302 if ( !lcl_FunctionKnown( nOpCode
) )
303 return false; // not in function list -> no change
305 sal_uInt16 nNewCount
= std::min( (sal_uInt16
)(nOldCount
+ 1), (sal_uInt16
)LRU_MAX
);
306 sal_uInt16 nNewList
[LRU_MAX
];
307 nNewList
[0] = nOpCode
;
308 for (nPos
=1; nPos
<nNewCount
; nPos
++)
309 nNewList
[nPos
] = pOldList
[nPos
-1];
310 rAppOpt
.SetLRUFuncList( nNewList
, nNewCount
);
312 return true; // list has changed
315 namespace HelperNotifyChanges
317 void NotifyIfChangesListeners(ScDocShell
&rDocShell
, ScMarkData
& rMark
, SCCOL nCol
, SCROW nRow
,
318 const OUString
&rType
= OUString("cell-change"))
320 if (ScModelObj
*pModelObj
= getMustPropagateChangesModel(rDocShell
))
322 ScRangeList aChangeRanges
;
323 ScMarkData::iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
324 for (; itr
!= itrEnd
; ++itr
)
325 aChangeRanges
.Append( ScRange( nCol
, nRow
, *itr
) );
327 HelperNotifyChanges::Notify(*pModelObj
, aChangeRanges
, rType
);
335 void ScViewFunc::EnterData( SCCOL nCol
, SCROW nRow
, SCTAB nTab
,
336 const OUString
& rString
,
337 const EditTextObject
* pData
)
339 ScDocument
* pDoc
= GetViewData().GetDocument();
340 ScMarkData
rMark(GetViewData().GetMarkData());
341 bool bRecord
= pDoc
->IsUndoEnabled();
344 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
345 ScDocFunc
&rFunc
= GetViewData().GetDocFunc();
346 ScDocShellModificator
aModificator( *pDocSh
);
348 ScEditableTester
aTester( pDoc
, nCol
,nRow
, nCol
,nRow
, rMark
);
349 if (!aTester
.IsEditable())
351 ErrorMessage(aTester
.GetMessageId());
352 PaintArea(nCol
, nRow
, nCol
, nRow
); // possibly the edit-engine is still painted there
357 rFunc
.EnterListAction( STR_UNDO_ENTERDATA
);
359 bool bFormula
= false;
361 // a single '=' character is handled as string (needed for special filters)
362 if ( rString
.getLength() > 1 )
364 if ( rString
[0] == '=' )
369 else if ( rString
[0] == '+' || rString
[0] == '-' )
371 // if there is more than one leading '+' or '-' character, remove the additional ones
372 sal_Int32 nIndex
= 1;
373 sal_Int32 nLen
= rString
.getLength();
374 while ( nIndex
< nLen
&& ( rString
[ nIndex
] == '+' || rString
[ nIndex
] == '-' ) )
378 OUString aString
= rString
.replaceAt( 1, nIndex
- 1, "" );
380 // if the remaining part without the leading '+' or '-' character
381 // is non-empty and not a number, handle as formula
382 if ( aString
.getLength() > 1 )
384 sal_uInt32 nFormat
= 0;
385 pDoc
->GetNumberFormat( nCol
, nRow
, nTab
, nFormat
);
386 SvNumberFormatter
* pFormatter
= pDoc
->GetFormatTable();
388 if ( !pFormatter
->IsNumberFormat( aString
, nFormat
, fNumber
) )
396 bool bNumFmtChanged
= false;
398 { // formula, compile with autoCorrection
399 i
= rMark
.GetFirstSelected();
400 ScAddress
aPos( nCol
, nRow
, i
);
401 ScCompiler
aComp( pDoc
, aPos
);
402 aComp
.SetGrammar(pDoc
->GetGrammar());
403 //2do: enable/disable autoCorrection via calcoptions
404 aComp
.SetAutoCorrection( true );
405 if ( rString
[0] == '+' || rString
[0] == '-' )
407 aComp
.SetExtendedErrorDetection( ScCompiler::EXTENDED_ERROR_DETECTION_NAME_BREAK
);
409 OUString
aFormula( rString
);
415 bool bAddEqual
= false;
416 ScTokenArray
* pArrFirst
= pArr
= aComp
.CompileString( aFormula
);
417 bool bCorrected
= aComp
.IsCorrected();
419 { // try to parse with first parser-correction
420 pArr
= aComp
.CompileString( aComp
.GetCorrectedFormula() );
422 if ( !pArr
->GetCodeError() )
425 aComp
.CompileTokenArray();
426 bCorrected
|= aComp
.IsCorrected();
430 OUString aCorrectedFormula
;
433 aCorrectedFormula
= "=" + aComp
.GetCorrectedFormula();
436 aCorrectedFormula
= aComp
.GetCorrectedFormula();
438 if ( aCorrectedFormula
.getLength() == 1 )
439 nResult
= RET_NO
; // empty formula, just '='
442 OUString
aMessage( ScResId( SCSTR_FORMULA_AUTOCORRECTION
) );
443 aMessage
+= aCorrectedFormula
;
444 nResult
= ScopedVclPtr
<QueryBox
>::Create( GetViewData().GetDialogParent(),
445 WinBits(WB_YES_NO
| WB_DEF_YES
),
446 aMessage
)->Execute();
448 if ( nResult
== RET_YES
)
450 aFormula
= aCorrectedFormula
;
451 if ( pArr
!= pArrFirst
)
457 if ( pArr
!= pArrFirst
)
465 // to be used in multiple tabs, the formula must be compiled anew
466 // via ScFormulaCell copy-ctor because of RangeNames,
467 // the same code-array for all cells is not possible.
468 // If the array has an error, (it) must be RPN-erased in the newly generated
469 // cellst and the error be set explicitly, so that
470 // via FormulaCell copy-ctor and Interpreter it will be, when possible,
471 // ironed out again, too intelligent.. e.g.: =1))
472 sal_uInt16 nError
= pArr
->GetCodeError();
475 // update list of recent functions with all functions that
476 // are not within parentheses
478 ScModule
* pScMod
= SC_MOD();
479 ScAppOptions aAppOpt
= pScMod
->GetAppOptions();
480 bool bOptChanged
= false;
482 formula::FormulaToken
** ppToken
= pArr
->GetArray();
483 sal_uInt16 nTokens
= pArr
->GetLen();
484 sal_uInt16 nLevel
= 0;
485 for (sal_uInt16 nTP
=0; nTP
<nTokens
; nTP
++)
487 formula::FormulaToken
* pTok
= ppToken
[nTP
];
488 OpCode eOp
= pTok
->GetOpCode();
491 else if ( eOp
== ocClose
&& nLevel
)
493 if ( nLevel
== 0 && pTok
->IsFunction() &&
494 lcl_AddFunction( aAppOpt
, sal::static_int_cast
<sal_uInt16
>( eOp
) ) )
500 pScMod
->SetAppOptions(aAppOpt
);
501 ScModule::RecentFunctionsChanged();
505 ScFormulaCell
aCell(pDoc
, aPos
, *pArr
, formula::FormulaGrammar::GRAM_DEFAULT
, MM_NONE
);
508 SvNumberFormatter
* pFormatter
= pDoc
->GetFormatTable();
509 ScMarkData::iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
510 for (; itr
!= itrEnd
; ++itr
)
514 sal_uLong nIndex
= (sal_uLong
) static_cast<const SfxUInt32Item
*>( pDoc
->GetAttr(
515 nCol
, nRow
, i
, ATTR_VALUE_FORMAT
))->GetValue();
516 if ( pFormatter
->GetType( nIndex
) == css::util::NumberFormat::TEXT
||
517 ( ( rString
[0] == '+' || rString
[0] == '-' ) && nError
&& rString
== aFormula
) )
521 // A clone of pData will be stored in the cell.
522 rFunc
.SetEditCell(aPos
, *pData
, true);
525 rFunc
.SetStringCell(aPos
, aFormula
, true);
529 ScFormulaCell
* pCell
= new ScFormulaCell( aCell
, *pDoc
, aPos
);
532 pCell
->GetCode()->DelRPN();
533 pCell
->SetErrCode( nError
);
534 if(pCell
->GetCode()->IsHyperLink())
535 pCell
->GetCode()->SetHyperLink(false);
537 rFunc
.SetFormulaCell(aPos
, pCell
, true);
543 ScMarkData::iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
544 for ( ; itr
!= itrEnd
; ++itr
)
546 bool bNumFmtSet
= false;
547 rFunc
.SetNormalString( bNumFmtSet
, ScAddress( nCol
, nRow
, *itr
), rString
, false );
550 /* FIXME: if set on any sheet results in changed only on
551 * sheet nTab for TestFormatArea() and DoAutoAttributes() */
552 bNumFmtChanged
= true;
557 bool bAutoFormat
= TestFormatArea(nCol
, nRow
, nTab
, bNumFmtChanged
);
560 DoAutoAttributes(nCol
, nRow
, nTab
, bNumFmtChanged
, bRecord
);
562 pDocSh
->UpdateOle(&GetViewData());
564 HelperNotifyChanges::NotifyIfChangesListeners(*pDocSh
, rMark
, nCol
, nRow
);
567 rFunc
.EndListAction();
569 aModificator
.SetDocumentModified();
570 lcl_PostRepaintCondFormat( pDoc
->GetCondFormat( nCol
, nRow
, nTab
), pDocSh
);
573 // enter value in single cell (on nTab only)
575 void ScViewFunc::EnterValue( SCCOL nCol
, SCROW nRow
, SCTAB nTab
, const double& rValue
)
577 ScDocument
* pDoc
= GetViewData().GetDocument();
578 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
580 if ( pDoc
&& pDocSh
)
582 bool bUndo(pDoc
->IsUndoEnabled());
583 ScDocShellModificator
aModificator( *pDocSh
);
585 ScEditableTester
aTester( pDoc
, nTab
, nCol
,nRow
, nCol
,nRow
);
586 if (aTester
.IsEditable())
588 ScAddress
aPos( nCol
, nRow
, nTab
);
589 ScCellValue aUndoCell
;
591 aUndoCell
.assign(*pDoc
, aPos
);
593 pDoc
->SetValue( nCol
, nRow
, nTab
, rValue
);
595 // because of ChangeTrack after change in document
598 pDocSh
->GetUndoManager()->AddUndoAction(
599 new ScUndoEnterValue(pDocSh
, aPos
, aUndoCell
, rValue
));
602 pDocSh
->PostPaintCell( aPos
);
603 pDocSh
->UpdateOle(&GetViewData());
604 aModificator
.SetDocumentModified();
607 ErrorMessage(aTester
.GetMessageId());
611 void ScViewFunc::EnterData( SCCOL nCol
, SCROW nRow
, SCTAB nTab
,
612 const EditTextObject
& rData
, bool bTestSimple
)
614 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
615 ScMarkData
& rMark
= GetViewData().GetMarkData();
616 ScDocument
& rDoc
= pDocSh
->GetDocument();
617 bool bRecord
= rDoc
.IsUndoEnabled();
619 ScDocShellModificator
aModificator( *pDocSh
);
621 ScEditableTester
aTester( &rDoc
, nTab
, nCol
,nRow
, nCol
,nRow
);
622 if (aTester
.IsEditable())
625 // test for attribute
627 bool bSimple
= false;
628 bool bCommon
= false;
629 boost::scoped_ptr
<ScPatternAttr
> pCellAttrs
;
632 const ScPatternAttr
* pOldPattern
= rDoc
.GetPattern( nCol
, nRow
, nTab
);
633 ScTabEditEngine
aEngine( *pOldPattern
, rDoc
.GetEnginePool() );
634 aEngine
.SetText(rData
);
636 if (bTestSimple
) // test, if simple string without attribute
638 ScEditAttrTester
aAttrTester( &aEngine
);
639 bSimple
= !aAttrTester
.NeedsObject();
640 bCommon
= aAttrTester
.NeedsCellAttr();
642 // formulas have to be recognized even if they're formatted
643 // (but commmon attributes are still collected)
645 if ( !bSimple
&& aEngine
.GetParagraphCount() == 1 )
647 OUString
aParStr(aEngine
.GetText( 0 ));
648 if ( aParStr
[0] == '=' )
652 if (bCommon
) // attribute for tab
654 pCellAttrs
.reset(new ScPatternAttr( *pOldPattern
));
655 pCellAttrs
->GetFromEditItemSet( &aAttrTester
.GetAttribs() );
656 //! remove common attributes from EditEngine?
660 // #i97726# always get text for "repeat" of undo action
661 aString
= ScEditUtil::GetSpaceDelimitedString(aEngine
);
665 EditTextObject
* pUndoData
= NULL
;
666 ScUndoEnterData::ValuesType aOldValues
;
668 if (bRecord
&& !bSimple
)
670 ScMarkData::iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
671 for (; itr
!= itrEnd
; ++itr
)
673 ScUndoEnterData::Value aOldValue
;
674 aOldValue
.mnTab
= *itr
;
675 aOldValue
.maCell
.assign(rDoc
, ScAddress(nCol
, nRow
, *itr
));
676 aOldValues
.push_back(aOldValue
);
679 pUndoData
= rData
.Clone();
685 rDoc
.ApplyPattern(nCol
,nRow
,nTab
,*pCellAttrs
); //! undo
690 AdjustRowHeight(nRow
,nRow
);
692 EnterData(nCol
,nRow
,nTab
,aString
);
696 ScMarkData::iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
697 for (; itr
!= itrEnd
; ++itr
)
699 ScAddress
aPos(nCol
, nRow
, *itr
);
700 rDoc
.SetEditText(aPos
, rData
, rDoc
.GetEditPool());
704 { // because of ChangeTrack current first
705 pDocSh
->GetUndoManager()->AddUndoAction(
706 new ScUndoEnterData(pDocSh
, ScAddress(nCol
,nRow
,nTab
), aOldValues
, aString
, pUndoData
));
711 AdjustRowHeight(nRow
,nRow
);
714 for (; itr
!= itrEnd
; ++itr
)
715 pDocSh
->PostPaintCell( nCol
, nRow
, *itr
);
719 pDocSh
->UpdateOle(&GetViewData());
721 HelperNotifyChanges::NotifyIfChangesListeners(*pDocSh
, rMark
, nCol
, nRow
);
723 aModificator
.SetDocumentModified();
725 lcl_PostRepaintCondFormat( rDoc
.GetCondFormat( nCol
, nRow
, nTab
), pDocSh
);
729 ErrorMessage(aTester
.GetMessageId());
730 PaintArea( nCol
, nRow
, nCol
, nRow
); // possibly the edit-engine is still painted there
734 void ScViewFunc::EnterDataAtCursor( const OUString
& rString
)
736 SCCOL nPosX
= GetViewData().GetCurX();
737 SCROW nPosY
= GetViewData().GetCurY();
738 SCTAB nTab
= GetViewData().GetTabNo();
740 EnterData( nPosX
, nPosY
, nTab
, rString
);
743 void ScViewFunc::EnterMatrix( const OUString
& rString
, ::formula::FormulaGrammar::Grammar eGram
)
745 ScViewData
& rData
= GetViewData();
746 const ScMarkData
& rMark
= rData
.GetMarkData();
747 if ( !rMark
.IsMarked() && !rMark
.IsMultiMarked() )
749 // nothing marked -> temporarily calculate block
750 // with size of result formula to get the size
752 ScDocument
* pDoc
= rData
.GetDocument();
753 SCCOL nCol
= rData
.GetCurX();
754 SCROW nRow
= rData
.GetCurY();
755 SCTAB nTab
= rData
.GetTabNo();
756 ScFormulaCell
aFormCell( pDoc
, ScAddress(nCol
,nRow
,nTab
), rString
, eGram
, MM_FORMULA
);
760 aFormCell
.GetResultDimensions( nSizeX
, nSizeY
);
761 if ( nSizeX
!= 0 && nSizeY
!= 0 &&
762 nCol
+nSizeX
-1 <= sal::static_int_cast
<SCSIZE
>(MAXCOL
) &&
763 nRow
+nSizeY
-1 <= sal::static_int_cast
<SCSIZE
>(MAXROW
) )
765 ScRange
aResult( nCol
, nRow
, nTab
,
766 sal::static_int_cast
<SCCOL
>(nCol
+nSizeX
-1),
767 sal::static_int_cast
<SCROW
>(nRow
+nSizeY
-1), nTab
);
768 MarkRange( aResult
, false );
773 if (rData
.GetSimpleArea(aRange
) == SC_MARK_SIMPLE
)
775 ScDocShell
* pDocSh
= rData
.GetDocShell();
776 bool bSuccess
= pDocSh
->GetDocFunc().EnterMatrix(
777 aRange
, &rMark
, NULL
, rString
, false, false, EMPTY_OUSTRING
, eGram
);
779 pDocSh
->UpdateOle(&GetViewData());
782 ErrorMessage(STR_NOMULTISELECT
);
785 SvtScriptType
ScViewFunc::GetSelectionScriptType()
787 SvtScriptType nScript
= SvtScriptType::NONE
;
789 ScDocument
* pDoc
= GetViewData().GetDocument();
790 const ScMarkData
& rMark
= GetViewData().GetMarkData();
791 if ( !rMark
.IsMarked() && !rMark
.IsMultiMarked() )
793 // no selection -> cursor
795 nScript
= pDoc
->GetScriptType( GetViewData().GetCurX(),
796 GetViewData().GetCurY(), GetViewData().GetTabNo());
801 rMark
.FillRangeListWithMarks( &aRanges
, false );
802 nScript
= pDoc
->GetRangeScriptType(aRanges
);
805 if (nScript
== SvtScriptType::NONE
)
806 nScript
= ScGlobal::GetDefaultScriptType();
811 const ScPatternAttr
* ScViewFunc::GetSelectionPattern()
813 // Don't use UnmarkFiltered in slot state functions, for performance reasons.
814 // The displayed state is always that of the whole selection including filtered rows.
816 const ScMarkData
& rMark
= GetViewData().GetMarkData();
817 ScDocument
* pDoc
= GetViewData().GetDocument();
818 if ( rMark
.IsMarked() || rMark
.IsMultiMarked() )
820 // MarkToMulti is no longer necessary for pDoc->GetSelectionPattern
821 const ScPatternAttr
* pAttr
= pDoc
->GetSelectionPattern( rMark
);
826 SCCOL nCol
= GetViewData().GetCurX();
827 SCROW nRow
= GetViewData().GetCurY();
828 SCTAB nTab
= GetViewData().GetTabNo();
830 ScMarkData
aTempMark( rMark
); // copy sheet selection
831 aTempMark
.SetMarkArea( ScRange( nCol
, nRow
, nTab
) );
832 const ScPatternAttr
* pAttr
= pDoc
->GetSelectionPattern( aTempMark
);
837 void ScViewFunc::GetSelectionFrame( SvxBoxItem
& rLineOuter
,
838 SvxBoxInfoItem
& rLineInner
)
840 ScDocument
* pDoc
= GetViewData().GetDocument();
841 const ScMarkData
& rMark
= GetViewData().GetMarkData();
843 if ( rMark
.IsMarked() || rMark
.IsMultiMarked() )
845 if ( rMark
.IsMultiMarked() )
847 ScMarkData
aNewMark( rMark
); // use local copy for MarkToSimple
848 aNewMark
.MarkToSimple(); // simple block is needed for GetSelectionFrame
849 pDoc
->GetSelectionFrame( aNewMark
, rLineOuter
, rLineInner
);
852 pDoc
->GetSelectionFrame( rMark
, rLineOuter
, rLineInner
);
856 const ScPatternAttr
* pAttrs
=
857 pDoc
->GetPattern( GetViewData().GetCurX(),
858 GetViewData().GetCurY(),
859 GetViewData().GetTabNo() );
861 rLineOuter
= static_cast<const SvxBoxItem
&> (pAttrs
->GetItem( ATTR_BORDER
));
862 rLineInner
= static_cast<const SvxBoxInfoItem
&>(pAttrs
->GetItem( ATTR_BORDER_INNER
));
863 rLineInner
.SetTable(false);
864 rLineInner
.SetDist(true);
865 rLineInner
.SetMinDist(false);
869 // apply attribute - undo OK
871 // complete set ( ATTR_STARTINDEX, ATTR_ENDINDEX )
873 void ScViewFunc::ApplyAttributes( const SfxItemSet
* pDialogSet
,
874 const SfxItemSet
* pOldSet
,
877 // not editable because of matrix only? attribute OK nonetheless
878 bool bOnlyNotBecauseOfMatrix
;
879 if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix
) && !bOnlyNotBecauseOfMatrix
)
881 ErrorMessage(STR_PROTECTIONERR
);
885 ScPatternAttr
aOldAttrs( new SfxItemSet(*pOldSet
) );
886 ScPatternAttr
aNewAttrs( new SfxItemSet(*pDialogSet
) );
887 aNewAttrs
.DeleteUnchanged( &aOldAttrs
);
889 if ( pDialogSet
->GetItemState( ATTR_VALUE_FORMAT
) == SfxItemState::SET
)
890 { // don't reset to default SYSTEM GENERAL if not intended
891 sal_uInt32 nOldFormat
=
892 static_cast<const SfxUInt32Item
&>(pOldSet
->Get( ATTR_VALUE_FORMAT
)).GetValue();
893 sal_uInt32 nNewFormat
=
894 static_cast<const SfxUInt32Item
&>(pDialogSet
->Get( ATTR_VALUE_FORMAT
)).GetValue();
895 if ( nNewFormat
!= nOldFormat
)
897 SvNumberFormatter
* pFormatter
=
898 GetViewData().GetDocument()->GetFormatTable();
899 const SvNumberformat
* pOldEntry
= pFormatter
->GetEntry( nOldFormat
);
900 LanguageType eOldLang
=
901 pOldEntry
? pOldEntry
->GetLanguage() : LANGUAGE_DONTKNOW
;
902 const SvNumberformat
* pNewEntry
= pFormatter
->GetEntry( nNewFormat
);
903 LanguageType eNewLang
=
904 pNewEntry
? pNewEntry
->GetLanguage() : LANGUAGE_DONTKNOW
;
905 if ( eNewLang
!= eOldLang
)
907 aNewAttrs
.GetItemSet().Put(
908 SvxLanguageItem( eNewLang
, ATTR_LANGUAGE_FORMAT
) );
910 // only the language has changed -> do not touch numberformat-attribute
911 sal_uInt32 nNewMod
= nNewFormat
% SV_COUNTRY_LANGUAGE_OFFSET
;
912 if ( nNewMod
== ( nOldFormat
% SV_COUNTRY_LANGUAGE_OFFSET
) &&
913 nNewMod
<= SV_MAX_ANZ_STANDARD_FORMATE
)
914 aNewAttrs
.GetItemSet().ClearItem( ATTR_VALUE_FORMAT
);
919 const SvxBoxItem
* pOldOuter
= static_cast<const SvxBoxItem
*> (&pOldSet
->Get( ATTR_BORDER
));
920 const SvxBoxItem
* pNewOuter
= static_cast<const SvxBoxItem
*> (&pDialogSet
->Get( ATTR_BORDER
));
921 const SvxBoxInfoItem
* pOldInner
= static_cast<const SvxBoxInfoItem
*> (&pOldSet
->Get( ATTR_BORDER_INNER
));
922 const SvxBoxInfoItem
* pNewInner
= static_cast<const SvxBoxInfoItem
*> (&pDialogSet
->Get( ATTR_BORDER_INNER
));
923 SfxItemSet
& rNewSet
= aNewAttrs
.GetItemSet();
924 SfxItemPool
* pNewPool
= rNewSet
.GetPool();
926 pNewPool
->Put( *pNewOuter
); // don't delete yet
927 pNewPool
->Put( *pNewInner
);
928 rNewSet
.ClearItem( ATTR_BORDER
);
929 rNewSet
.ClearItem( ATTR_BORDER_INNER
);
932 * establish whether border attribute is to be set:
934 * 2. is one of the borders not-DontCare (since 238.f: IsxxValid())
938 bool bFrame
= (pDialogSet
->GetItemState( ATTR_BORDER
) != SfxItemState::DEFAULT
)
939 || (pDialogSet
->GetItemState( ATTR_BORDER_INNER
) != SfxItemState::DEFAULT
);
941 if ( pNewOuter
==pOldOuter
&& pNewInner
==pOldInner
)
944 // this should be intercepted by the pool: ?!??!??
946 if ( bFrame
&& pNewOuter
&& pNewInner
)
947 if ( *pNewOuter
== *pOldOuter
&& *pNewInner
== *pOldInner
)
953 && ( pNewInner
->IsValid(SvxBoxInfoItemValidFlags::LEFT
)
954 || pNewInner
->IsValid(SvxBoxInfoItemValidFlags::RIGHT
)
955 || pNewInner
->IsValid(SvxBoxInfoItemValidFlags::TOP
)
956 || pNewInner
->IsValid(SvxBoxInfoItemValidFlags::BOTTOM
)
957 || pNewInner
->IsValid(SvxBoxInfoItemValidFlags::HORI
)
958 || pNewInner
->IsValid(SvxBoxInfoItemValidFlags::VERT
) );
964 ApplySelectionPattern( aNewAttrs
, bRecord
); // standard only
967 // if new items are default-items, overwrite the old items:
969 bool bDefNewOuter
= ( SFX_ITEMS_STATICDEFAULT
== pNewOuter
->GetKind() );
970 bool bDefNewInner
= ( SFX_ITEMS_STATICDEFAULT
== pNewInner
->GetKind() );
972 ApplyPatternLines( aNewAttrs
,
973 bDefNewOuter
? pOldOuter
: pNewOuter
,
974 bDefNewInner
? pOldInner
: pNewInner
,
978 pNewPool
->Remove( *pNewOuter
); // release
979 pNewPool
->Remove( *pNewInner
);
984 // CellContentChanged is called in ApplySelectionPattern / ApplyPatternLines
987 void ScViewFunc::ApplyAttr( const SfxPoolItem
& rAttrItem
)
989 // not editable because of matrix only? attribute OK nonetheless
990 bool bOnlyNotBecauseOfMatrix
;
991 if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix
) && !bOnlyNotBecauseOfMatrix
)
993 ErrorMessage(STR_PROTECTIONERR
);
997 ScPatternAttr
aNewAttrs( new SfxItemSet( *GetViewData().GetDocument()->GetPool(),
998 ATTR_PATTERN_START
, ATTR_PATTERN_END
) );
1000 aNewAttrs
.GetItemSet().Put( rAttrItem
);
1001 // if justify is set (with Buttons), always indentation 0
1002 if ( rAttrItem
.Which() == ATTR_HOR_JUSTIFY
)
1003 aNewAttrs
.GetItemSet().Put( SfxUInt16Item( ATTR_INDENT
, 0 ) );
1004 ApplySelectionPattern( aNewAttrs
);
1006 AdjustBlockHeight();
1008 // CellContentChanged is called in ApplySelectionPattern
1011 // patterns and borders
1013 void ScViewFunc::ApplyPatternLines( const ScPatternAttr
& rAttr
, const SvxBoxItem
* pNewOuter
,
1014 const SvxBoxInfoItem
* pNewInner
, bool bRecord
)
1016 ScDocument
* pDoc
= GetViewData().GetDocument();
1017 ScMarkData
aFuncMark( GetViewData().GetMarkData() ); // local copy for UnmarkFiltered
1018 ScViewUtil::UnmarkFiltered( aFuncMark
, pDoc
);
1019 if (bRecord
&& !pDoc
->IsUndoEnabled())
1023 aFuncMark
.MarkToSimple();
1024 bool bMulti
= aFuncMark
.IsMultiMarked();
1026 aFuncMark
.GetMultiMarkArea( aMarkRange
);
1027 else if (aFuncMark
.IsMarked())
1028 aFuncMark
.GetMarkArea( aMarkRange
);
1031 aMarkRange
= ScRange( GetViewData().GetCurX(),
1032 GetViewData().GetCurY(), GetViewData().GetTabNo() );
1035 aFuncMark
.SetMarkArea(aMarkRange
);
1039 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
1041 ScDocShellModificator
aModificator( *pDocSh
);
1045 ScDocument
* pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
1046 SCTAB nStartTab
= aMarkRange
.aStart
.Tab();
1047 SCTAB nTabCount
= pDoc
->GetTableCount();
1048 pUndoDoc
->InitUndo( pDoc
, nStartTab
, nStartTab
);
1049 ScMarkData::iterator itr
= aFuncMark
.begin(), itrEnd
= aFuncMark
.end();
1050 for (; itr
!= itrEnd
; ++itr
)
1051 if (*itr
!= nStartTab
)
1052 pUndoDoc
->AddUndoTab( *itr
, *itr
);
1054 ScRange aCopyRange
= aMarkRange
;
1055 aCopyRange
.aStart
.SetTab(0);
1056 aCopyRange
.aEnd
.SetTab(nTabCount
-1);
1057 pDoc
->CopyToDocument( aCopyRange
, IDF_ATTRIB
, bMulti
, pUndoDoc
, &aFuncMark
);
1059 pDocSh
->GetUndoManager()->AddUndoAction(
1060 new ScUndoSelectionAttr(
1062 aMarkRange
.aStart
.Col(), aMarkRange
.aStart
.Row(), aMarkRange
.aStart
.Tab(),
1063 aMarkRange
.aEnd
.Col(), aMarkRange
.aEnd
.Row(), aMarkRange
.aEnd
.Tab(),
1064 pUndoDoc
, bMulti
, &rAttr
, pNewOuter
, pNewInner
) );
1067 sal_uInt16 nExt
= SC_PF_TESTMERGE
;
1068 pDocSh
->UpdatePaintExt( nExt
, aMarkRange
); // content before the change
1070 pDoc
->ApplySelectionFrame( aFuncMark
, pNewOuter
, pNewInner
);
1072 pDocSh
->UpdatePaintExt( nExt
, aMarkRange
); // content after the change
1074 aFuncMark
.MarkToMulti();
1075 pDoc
->ApplySelectionPattern( rAttr
, aFuncMark
);
1077 pDocSh
->PostPaint( aMarkRange
, PAINT_GRID
, nExt
);
1078 pDocSh
->UpdateOle(&GetViewData());
1079 aModificator
.SetDocumentModified();
1080 CellContentChanged();
1087 void ScViewFunc::ApplySelectionPattern( const ScPatternAttr
& rAttr
,
1088 bool bRecord
, bool bCursorOnly
)
1090 ScViewData
& rViewData
= GetViewData();
1091 ScDocShell
* pDocSh
= rViewData
.GetDocShell();
1092 ScDocument
& rDoc
= pDocSh
->GetDocument();
1093 ScMarkData
aFuncMark( rViewData
.GetMarkData() ); // local copy for UnmarkFiltered
1094 ScViewUtil::UnmarkFiltered( aFuncMark
, &rDoc
);
1096 if (bRecord
&& !rDoc
.IsUndoEnabled())
1099 // State from old ItemSet doesn't matter for paint flags, as any change will be
1100 // from SfxItemState::SET in the new ItemSet (default is ignored in ApplyPattern).
1101 // New alignment is checked (check in PostPaint isn't enough) in case a right
1102 // alignment is changed to left.
1103 const SfxItemSet
& rNewSet
= rAttr
.GetItemSet();
1104 bool bSetLines
= rNewSet
.GetItemState( ATTR_BORDER
, true ) == SfxItemState::SET
||
1105 rNewSet
.GetItemState( ATTR_SHADOW
, true ) == SfxItemState::SET
;
1106 bool bSetAlign
= rNewSet
.GetItemState( ATTR_HOR_JUSTIFY
, true ) == SfxItemState::SET
;
1108 sal_uInt16 nExtFlags
= 0;
1110 nExtFlags
|= SC_PF_LINES
;
1112 nExtFlags
|= SC_PF_WHOLEROWS
;
1114 ScDocShellModificator
aModificator( *pDocSh
);
1116 bool bMulti
= aFuncMark
.IsMultiMarked();
1117 aFuncMark
.MarkToMulti();
1118 bool bOnlyTab
= (!aFuncMark
.IsMultiMarked() && !bCursorOnly
&& aFuncMark
.GetSelectCount() > 1);
1121 SCCOL nCol
= rViewData
.GetCurX();
1122 SCROW nRow
= rViewData
.GetCurY();
1123 SCTAB nTab
= rViewData
.GetTabNo();
1124 aFuncMark
.SetMarkArea(ScRange(nCol
,nRow
,nTab
));
1125 aFuncMark
.MarkToMulti();
1128 ScRangeList aChangeRanges
;
1130 if (aFuncMark
.IsMultiMarked() && !bCursorOnly
)
1133 aFuncMark
.GetMultiMarkArea( aMarkRange
);
1134 SCTAB nTabCount
= rDoc
.GetTableCount();
1135 ScMarkData::iterator itr
= aFuncMark
.begin(), itrEnd
= aFuncMark
.end();
1136 for (; itr
!= itrEnd
; ++itr
)
1138 ScRange
aChangeRange( aMarkRange
);
1139 aChangeRange
.aStart
.SetTab( *itr
);
1140 aChangeRange
.aEnd
.SetTab( *itr
);
1141 aChangeRanges
.Append( aChangeRange
);
1144 SCCOL nStartCol
= aMarkRange
.aStart
.Col();
1145 SCROW nStartRow
= aMarkRange
.aStart
.Row();
1146 SCTAB nStartTab
= aMarkRange
.aStart
.Tab();
1147 SCCOL nEndCol
= aMarkRange
.aEnd
.Col();
1148 SCROW nEndRow
= aMarkRange
.aEnd
.Row();
1149 SCTAB nEndTab
= aMarkRange
.aEnd
.Tab();
1151 ScUndoSelectionAttr
* pUndoAttr
= NULL
;
1152 ScEditDataArray
* pEditDataArray
= NULL
;
1155 ScRange aCopyRange
= aMarkRange
;
1156 aCopyRange
.aStart
.SetTab(0);
1157 aCopyRange
.aEnd
.SetTab(nTabCount
-1);
1159 ScDocument
* pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
1160 pUndoDoc
->InitUndo( &rDoc
, nStartTab
, nStartTab
);
1161 itr
= aFuncMark
.begin();
1162 for (; itr
!= itrEnd
; ++itr
)
1163 if (*itr
!= nStartTab
)
1164 pUndoDoc
->AddUndoTab( *itr
, *itr
);
1165 rDoc
.CopyToDocument( aCopyRange
, IDF_ATTRIB
, bMulti
, pUndoDoc
, &aFuncMark
);
1167 aFuncMark
.MarkToMulti();
1169 pUndoAttr
= new ScUndoSelectionAttr(
1170 pDocSh
, aFuncMark
, nStartCol
, nStartRow
, nStartTab
,
1171 nEndCol
, nEndRow
, nEndTab
, pUndoDoc
, bMulti
, &rAttr
);
1172 pDocSh
->GetUndoManager()->AddUndoAction(pUndoAttr
);
1173 pEditDataArray
= pUndoAttr
->GetDataArray();
1176 rDoc
.ApplySelectionPattern( rAttr
, aFuncMark
, pEditDataArray
);
1178 pDocSh
->PostPaint( nStartCol
, nStartRow
, nStartTab
,
1179 nEndCol
, nEndRow
, nEndTab
,
1180 PAINT_GRID
, nExtFlags
| SC_PF_TESTMERGE
);
1181 pDocSh
->UpdateOle(&GetViewData());
1182 aModificator
.SetDocumentModified();
1183 CellContentChanged();
1185 else // single cell - simpler undo
1187 SCCOL nCol
= rViewData
.GetCurX();
1188 SCROW nRow
= rViewData
.GetCurY();
1189 SCTAB nTab
= rViewData
.GetTabNo();
1191 EditTextObject
* pOldEditData
= NULL
;
1192 EditTextObject
* pNewEditData
= NULL
;
1193 ScAddress
aPos(nCol
, nRow
, nTab
);
1194 if (rDoc
.GetCellType(aPos
) == CELLTYPE_EDIT
)
1196 const EditTextObject
* pEditObj
= rDoc
.GetEditText(aPos
);
1197 pOldEditData
= pEditObj
? pEditObj
->Clone() : NULL
;
1198 rDoc
.RemoveEditTextCharAttribs(aPos
, rAttr
);
1199 pEditObj
= rDoc
.GetEditText(aPos
);
1200 pNewEditData
= pEditObj
? pEditObj
->Clone() : NULL
;
1203 aChangeRanges
.Append(aPos
);
1204 boost::scoped_ptr
<ScPatternAttr
> pOldPat(new ScPatternAttr(*rDoc
.GetPattern( nCol
, nRow
, nTab
)));
1206 rDoc
.ApplyPattern( nCol
, nRow
, nTab
, rAttr
);
1208 const ScPatternAttr
* pNewPat
= rDoc
.GetPattern( nCol
, nRow
, nTab
);
1212 ScUndoCursorAttr
* pUndo
= new ScUndoCursorAttr(
1213 pDocSh
, nCol
, nRow
, nTab
, pOldPat
.get(), pNewPat
, &rAttr
, false );
1214 pUndo
->SetEditData(pOldEditData
, pNewEditData
);
1215 pDocSh
->GetUndoManager()->AddUndoAction(pUndo
);
1217 pOldPat
.reset(); // is copied in undo (Pool)
1219 pDocSh
->PostPaint( nCol
,nRow
,nTab
, nCol
,nRow
,nTab
, PAINT_GRID
, nExtFlags
| SC_PF_TESTMERGE
);
1220 pDocSh
->UpdateOle(&GetViewData());
1221 aModificator
.SetDocumentModified();
1222 CellContentChanged();
1225 ScModelObj
* pModelObj
= HelperNotifyChanges::getMustPropagateChangesModel(*pDocSh
);
1228 ::com::sun::star::uno::Sequence
< ::com::sun::star::beans::PropertyValue
> aProperties
;
1229 sal_Int32 nCount
= 0;
1230 const SfxItemPropertyMap
& rMap
= ScCellObj::GetCellPropertyMap();
1231 PropertyEntryVector_t aPropVector
= rMap
.getPropertyEntries();
1232 for ( sal_uInt16 nWhich
= ATTR_PATTERN_START
; nWhich
<= ATTR_PATTERN_END
; ++nWhich
)
1234 const SfxPoolItem
* pItem
= 0;
1235 if ( rNewSet
.GetItemState( nWhich
, true, &pItem
) == SfxItemState::SET
&& pItem
)
1237 PropertyEntryVector_t::const_iterator aIt
= aPropVector
.begin();
1238 while ( aIt
!= aPropVector
.end())
1240 if ( aIt
->nWID
== nWhich
)
1242 ::com::sun::star::uno::Any aVal
;
1243 pItem
->QueryValue( aVal
, aIt
->nMemberId
);
1244 aProperties
.realloc( nCount
+ 1 );
1245 aProperties
[ nCount
].Name
= aIt
->sName
;
1246 aProperties
[ nCount
].Value
<<= aVal
;
1253 HelperNotifyChanges::Notify(*pModelObj
, aChangeRanges
, "attribute", aProperties
);
1259 void ScViewFunc::ApplyUserItemSet( const SfxItemSet
& rItemSet
)
1261 // ItemSet from UI, may have different pool
1263 bool bOnlyNotBecauseOfMatrix
;
1264 if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix
) && !bOnlyNotBecauseOfMatrix
)
1266 ErrorMessage(STR_PROTECTIONERR
);
1270 ScPatternAttr
aNewAttrs( GetViewData().GetDocument()->GetPool() );
1271 SfxItemSet
& rNewSet
= aNewAttrs
.GetItemSet();
1272 rNewSet
.Put( rItemSet
, false );
1273 ApplySelectionPattern( aNewAttrs
);
1275 AdjustBlockHeight();
1278 const SfxStyleSheet
* ScViewFunc::GetStyleSheetFromMarked()
1280 // Don't use UnmarkFiltered in slot state functions, for performance reasons.
1281 // The displayed state is always that of the whole selection including filtered rows.
1283 const ScStyleSheet
* pSheet
= NULL
;
1284 ScViewData
& rViewData
= GetViewData();
1285 ScDocument
* pDoc
= rViewData
.GetDocument();
1286 ScMarkData
& rMark
= rViewData
.GetMarkData();
1288 if ( rMark
.IsMarked() || rMark
.IsMultiMarked() )
1289 pSheet
= pDoc
->GetSelectionStyle( rMark
); // MarkToMulti isn't necessary
1291 pSheet
= pDoc
->GetStyle( rViewData
.GetCurX(),
1292 rViewData
.GetCurY(),
1293 rViewData
.GetTabNo() );
1298 void ScViewFunc::SetStyleSheetToMarked( SfxStyleSheet
* pStyleSheet
, bool bRecord
)
1300 // not editable because of matrix only? attribute OK nonetheless
1301 bool bOnlyNotBecauseOfMatrix
;
1302 if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix
) && !bOnlyNotBecauseOfMatrix
)
1304 ErrorMessage(STR_PROTECTIONERR
);
1308 if ( !pStyleSheet
) return;
1310 ScViewData
& rViewData
= GetViewData();
1311 ScDocShell
* pDocSh
= rViewData
.GetDocShell();
1312 ScDocument
& rDoc
= pDocSh
->GetDocument();
1313 ScMarkData
aFuncMark( rViewData
.GetMarkData() ); // local copy for UnmarkFiltered
1314 ScViewUtil::UnmarkFiltered( aFuncMark
, &rDoc
);
1315 SCTAB nTabCount
= rDoc
.GetTableCount();
1316 if (bRecord
&& !rDoc
.IsUndoEnabled())
1319 ScDocShellModificator
aModificator( *pDocSh
);
1321 if ( aFuncMark
.IsMarked() || aFuncMark
.IsMultiMarked() )
1324 aFuncMark
.MarkToMulti();
1325 aFuncMark
.GetMultiMarkArea( aMarkRange
);
1329 SCTAB nTab
= rViewData
.GetTabNo();
1330 ScDocument
* pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
1331 pUndoDoc
->InitUndo( &rDoc
, nTab
, nTab
);
1332 ScMarkData::iterator itr
= aFuncMark
.begin(), itrEnd
= aFuncMark
.end();
1333 for (; itr
!= itrEnd
; ++itr
)
1335 pUndoDoc
->AddUndoTab( *itr
, *itr
);
1337 ScRange aCopyRange
= aMarkRange
;
1338 aCopyRange
.aStart
.SetTab(0);
1339 aCopyRange
.aEnd
.SetTab(nTabCount
-1);
1340 rDoc
.CopyToDocument( aCopyRange
, IDF_ATTRIB
, true, pUndoDoc
, &aFuncMark
);
1341 aFuncMark
.MarkToMulti();
1343 OUString aName
= pStyleSheet
->GetName();
1344 pDocSh
->GetUndoManager()->AddUndoAction(
1345 new ScUndoSelectionStyle( pDocSh
, aFuncMark
, aMarkRange
, aName
, pUndoDoc
) );
1348 rDoc
.ApplySelectionStyle( static_cast<ScStyleSheet
&>(*pStyleSheet
), aFuncMark
);
1350 if (!AdjustBlockHeight())
1351 rViewData
.GetDocShell()->PostPaint( aMarkRange
, PAINT_GRID
);
1353 aFuncMark
.MarkToSimple();
1357 SCCOL nCol
= rViewData
.GetCurX();
1358 SCROW nRow
= rViewData
.GetCurY();
1359 SCTAB nTab
= rViewData
.GetTabNo();
1363 ScDocument
* pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
1364 pUndoDoc
->InitUndo( &rDoc
, nTab
, nTab
);
1365 ScMarkData::iterator itr
= aFuncMark
.begin(), itrEnd
= aFuncMark
.end();
1366 for (; itr
!= itrEnd
; ++itr
)
1368 pUndoDoc
->AddUndoTab( *itr
, *itr
);
1370 ScRange
aCopyRange( nCol
, nRow
, 0, nCol
, nRow
, nTabCount
-1 );
1371 rDoc
.CopyToDocument( aCopyRange
, IDF_ATTRIB
, false, pUndoDoc
);
1373 ScRange
aMarkRange ( nCol
, nRow
, nTab
);
1374 ScMarkData aUndoMark
= aFuncMark
;
1375 aUndoMark
.SetMultiMarkArea( aMarkRange
);
1377 OUString aName
= pStyleSheet
->GetName();
1378 pDocSh
->GetUndoManager()->AddUndoAction(
1379 new ScUndoSelectionStyle( pDocSh
, aUndoMark
, aMarkRange
, aName
, pUndoDoc
) );
1382 ScMarkData::iterator itr
= aFuncMark
.begin(), itrEnd
= aFuncMark
.end();
1383 for (; itr
!= itrEnd
; ++itr
)
1384 rDoc
.ApplyStyle( nCol
, nRow
, *itr
, static_cast<ScStyleSheet
&>(*pStyleSheet
) );
1386 if (!AdjustBlockHeight())
1387 rViewData
.GetDocShell()->PostPaintCell( nCol
, nRow
, nTab
);
1391 aModificator
.SetDocumentModified();
1396 void ScViewFunc::RemoveStyleSheetInUse( const SfxStyleSheetBase
* pStyleSheet
)
1398 if ( !pStyleSheet
) return;
1400 ScViewData
& rViewData
= GetViewData();
1401 ScDocument
* pDoc
= rViewData
.GetDocument();
1402 ScDocShell
* pDocSh
= rViewData
.GetDocShell();
1404 ScDocShellModificator
aModificator( *pDocSh
);
1406 ScopedVclPtrInstance
< VirtualDevice
> pVirtDev
;
1407 pVirtDev
->SetMapMode(MAP_PIXEL
);
1408 pDoc
->StyleSheetChanged( pStyleSheet
, true, pVirtDev
,
1409 rViewData
.GetPPTX(),
1410 rViewData
.GetPPTY(),
1411 rViewData
.GetZoomX(),
1412 rViewData
.GetZoomY() );
1414 pDocSh
->PostPaint( 0,0,0, MAXCOL
,MAXROW
,MAXTAB
, PAINT_GRID
|PAINT_LEFT
);
1415 aModificator
.SetDocumentModified();
1417 ScInputHandler
* pHdl
= SC_MOD()->GetInputHdl();
1419 pHdl
->ForgetLastPattern();
1422 void ScViewFunc::UpdateStyleSheetInUse( const SfxStyleSheetBase
* pStyleSheet
)
1424 if ( !pStyleSheet
) return;
1426 ScViewData
& rViewData
= GetViewData();
1427 ScDocument
* pDoc
= rViewData
.GetDocument();
1428 ScDocShell
* pDocSh
= rViewData
.GetDocShell();
1430 ScDocShellModificator
aModificator( *pDocSh
);
1432 ScopedVclPtrInstance
< VirtualDevice
> pVirtDev
;
1433 pVirtDev
->SetMapMode(MAP_PIXEL
);
1434 pDoc
->StyleSheetChanged( pStyleSheet
, false, pVirtDev
,
1435 rViewData
.GetPPTX(),
1436 rViewData
.GetPPTY(),
1437 rViewData
.GetZoomX(),
1438 rViewData
.GetZoomY() );
1440 pDocSh
->PostPaint( 0,0,0, MAXCOL
,MAXROW
,MAXTAB
, PAINT_GRID
|PAINT_LEFT
);
1441 aModificator
.SetDocumentModified();
1443 ScInputHandler
* pHdl
= SC_MOD()->GetInputHdl();
1445 pHdl
->ForgetLastPattern();
1448 // insert cells - undo OK
1450 bool ScViewFunc::InsertCells( InsCellCmd eCmd
, bool bRecord
, bool bPartOfPaste
)
1453 if (GetViewData().GetSimpleArea(aRange
) == SC_MARK_SIMPLE
)
1455 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
1456 const ScMarkData
& rMark
= GetViewData().GetMarkData();
1457 bool bSuccess
= pDocSh
->GetDocFunc().InsertCells( aRange
, &rMark
, eCmd
, bRecord
, false, bPartOfPaste
);
1460 pDocSh
->UpdateOle(&GetViewData());
1461 CellContentChanged();
1464 if ( eCmd
== INS_INSROWS
|| eCmd
== INS_INSCOLS
)
1466 OUString aOperation
= ( eCmd
== INS_INSROWS
) ?
1467 OUString("insert-rows"):
1468 OUString("insert-columns");
1469 HelperNotifyChanges::NotifyIfChangesListeners(*pDocSh
, aRange
, aOperation
);
1476 ErrorMessage(STR_NOMULTISELECT
);
1481 // delete cells - undo OK
1483 void ScViewFunc::DeleteCells( DelCellCmd eCmd
, bool bRecord
)
1486 if ( GetViewData().GetSimpleArea( aRange
) == SC_MARK_SIMPLE
)
1488 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
1489 const ScMarkData
& rMark
= GetViewData().GetMarkData();
1491 #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
1492 // #i94841# [Collaboration] if deleting rows is rejected, the content is sometimes wrong
1493 if ( pDocSh
->IsDocShared() && ( eCmd
== DEL_DELROWS
|| eCmd
== DEL_DELCOLS
) )
1495 ScRange
aDelRange( aRange
.aStart
);
1496 SCCOLROW nCount
= 0;
1497 if ( eCmd
== DEL_DELROWS
)
1499 nCount
= sal::static_int_cast
< SCCOLROW
>( aRange
.aEnd
.Row() - aRange
.aStart
.Row() + 1 );
1503 nCount
= sal::static_int_cast
< SCCOLROW
>( aRange
.aEnd
.Col() - aRange
.aStart
.Col() + 1 );
1505 while ( nCount
> 0 )
1507 pDocSh
->GetDocFunc().DeleteCells( aDelRange
, &rMark
, eCmd
, bRecord
, false );
1514 pDocSh
->GetDocFunc().DeleteCells( aRange
, &rMark
, eCmd
, bRecord
, false );
1517 pDocSh
->UpdateOle(&GetViewData());
1518 CellContentChanged();
1521 if ( eCmd
== DEL_DELROWS
|| eCmd
== DEL_DELCOLS
)
1523 OUString aOperation
= ( eCmd
== DEL_DELROWS
) ?
1524 OUString("delete-rows"):
1525 OUString("delete-columns");
1526 HelperNotifyChanges::NotifyIfChangesListeners(*pDocSh
, aRange
, aOperation
);
1529 // put cursor directly behind deleted range
1530 SCCOL nCurX
= GetViewData().GetCurX();
1531 SCROW nCurY
= GetViewData().GetCurY();
1532 if ( eCmd
==DEL_CELLSLEFT
|| eCmd
==DEL_DELCOLS
)
1533 nCurX
= aRange
.aStart
.Col();
1535 nCurY
= aRange
.aStart
.Row();
1536 SetCursor( nCurX
, nCurY
);
1540 if (eCmd
== DEL_DELCOLS
)
1541 DeleteMulti( false, bRecord
);
1542 else if (eCmd
== DEL_DELROWS
)
1543 DeleteMulti( true, bRecord
);
1545 ErrorMessage(STR_NOMULTISELECT
);
1551 void ScViewFunc::DeleteMulti( bool bRows
, bool bRecord
)
1553 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
1554 ScDocShellModificator
aModificator( *pDocSh
);
1555 SCTAB nTab
= GetViewData().GetTabNo();
1556 ScDocument
& rDoc
= pDocSh
->GetDocument();
1557 ScMarkData
aFuncMark( GetViewData().GetMarkData() ); // local copy for UnmarkFiltered
1558 ScViewUtil::UnmarkFiltered( aFuncMark
, &rDoc
);
1560 if (!rDoc
.IsUndoEnabled())
1563 std::vector
<sc::ColRowSpan
> aSpans
;
1565 aSpans
= aFuncMark
.GetMarkedRowSpans();
1567 aSpans
= aFuncMark
.GetMarkedColSpans();
1571 SCCOLROW nCurPos
= bRows
? GetViewData().GetCurY() : GetViewData().GetCurX();
1572 aSpans
.push_back(sc::ColRowSpan(nCurPos
, nCurPos
));
1577 sal_uInt16 nErrorId
= 0;
1578 bool bNeedRefresh
= false;
1579 for (size_t i
= 0, n
= aSpans
.size(); i
< n
&& !nErrorId
; ++i
)
1581 SCCOLROW nStart
= aSpans
[i
].mnStart
;
1582 SCCOLROW nEnd
= aSpans
[i
].mnEnd
;
1584 SCCOL nStartCol
, nEndCol
;
1585 SCROW nStartRow
, nEndRow
;
1590 nStartRow
= static_cast<SCROW
>(nStart
);
1591 nEndRow
= static_cast<SCROW
>(nEnd
);
1595 nStartCol
= static_cast<SCCOL
>(nStart
);
1596 nEndCol
= static_cast<SCCOL
>(nEnd
);
1601 // cell protection (only needed for first range, as all following cells are moved)
1604 // test to the end of the sheet
1605 ScEditableTester
aTester( &rDoc
, nTab
, nStartCol
, nStartRow
, MAXCOL
, MAXROW
);
1606 if (!aTester
.IsEditable())
1607 nErrorId
= aTester
.GetMessageId();
1611 SCCOL nMergeStartX
= nStartCol
;
1612 SCROW nMergeStartY
= nStartRow
;
1613 SCCOL nMergeEndX
= nEndCol
;
1614 SCROW nMergeEndY
= nEndRow
;
1615 rDoc
.ExtendMerge( nMergeStartX
, nMergeStartY
, nMergeEndX
, nMergeEndY
, nTab
);
1616 rDoc
.ExtendOverlapped( nMergeStartX
, nMergeStartY
, nMergeEndX
, nMergeEndY
, nTab
);
1618 if ( nMergeStartX
!= nStartCol
|| nMergeStartY
!= nStartRow
)
1620 // Disallow deleting parts of a merged cell.
1621 // Deleting the start is allowed (merge is removed), so the end doesn't have to be checked.
1623 nErrorId
= STR_MSSG_DELETECELLS_0
;
1625 if ( nMergeEndX
!= nEndCol
|| nMergeEndY
!= nEndRow
)
1627 // detect if the start of a merged cell is deleted, so the merge flags can be refreshed
1629 bNeedRefresh
= true;
1635 ErrorMessage( nErrorId
);
1641 WaitObject
aWait( GetFrameWin() ); // important for TrackFormulas in UpdateReference
1643 ScDocument
* pUndoDoc
= NULL
;
1644 ScRefUndoData
* pUndoData
= NULL
;
1647 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
1648 pUndoDoc
->InitUndo( &rDoc
, nTab
, nTab
, !bRows
, bRows
); // row height
1650 for (size_t i
= 0, n
= aSpans
.size(); i
< n
; ++i
)
1652 SCCOLROW nStart
= aSpans
[i
].mnStart
;
1653 SCCOLROW nEnd
= aSpans
[i
].mnEnd
;
1655 rDoc
.CopyToDocument( 0,nStart
,nTab
, MAXCOL
,nEnd
,nTab
, IDF_ALL
,false,pUndoDoc
);
1657 rDoc
.CopyToDocument( static_cast<SCCOL
>(nStart
),0,nTab
,
1658 static_cast<SCCOL
>(nEnd
),MAXROW
,nTab
,
1659 IDF_ALL
,false,pUndoDoc
);
1662 // all Formulas because of references
1663 SCTAB nTabCount
= rDoc
.GetTableCount();
1664 pUndoDoc
->AddUndoTab( 0, nTabCount
-1, false, false );
1665 rDoc
.CopyToDocument( 0,0,0, MAXCOL
,MAXROW
,MAXTAB
, IDF_FORMULA
,false,pUndoDoc
);
1667 pUndoData
= new ScRefUndoData( &rDoc
);
1669 rDoc
.BeginDrawUndo();
1672 std::vector
<sc::ColRowSpan
>::const_reverse_iterator ri
= aSpans
.rbegin(), riEnd
= aSpans
.rend();
1673 for (; ri
!= riEnd
; ++ri
)
1675 SCCOLROW nEnd
= ri
->mnEnd
;
1676 SCCOLROW nStart
= ri
->mnStart
;
1679 rDoc
.DeleteRow( 0,nTab
, MAXCOL
,nTab
, nStart
, static_cast<SCSIZE
>(nEnd
-nStart
+1) );
1681 rDoc
.DeleteCol( 0,nTab
, MAXROW
,nTab
, static_cast<SCCOL
>(nStart
), static_cast<SCSIZE
>(nEnd
-nStart
+1) );
1686 SCCOLROW nFirstStart
= aSpans
[0].mnStart
;
1687 SCCOL nStartCol
= bRows
? 0 : static_cast<SCCOL
>(nFirstStart
);
1688 SCROW nStartRow
= bRows
? static_cast<SCROW
>(nFirstStart
) : 0;
1689 SCCOL nEndCol
= MAXCOL
;
1690 SCROW nEndRow
= MAXROW
;
1692 rDoc
.RemoveFlagsTab( nStartCol
, nStartRow
, nEndCol
, nEndRow
, nTab
, SC_MF_HOR
| SC_MF_VER
);
1693 rDoc
.ExtendMerge( nStartCol
, nStartRow
, nEndCol
, nEndRow
, nTab
, true );
1698 pDocSh
->GetUndoManager()->AddUndoAction(
1699 new ScUndoDeleteMulti(
1700 pDocSh
, bRows
, bNeedRefresh
, nTab
, aSpans
, pUndoDoc
, pUndoData
));
1703 if (!AdjustRowHeight(0, MAXROW
))
1708 0, aSpans
[0].mnStart
, nTab
,
1709 MAXCOL
, MAXROW
, nTab
, (PAINT_GRID
| PAINT_LEFT
));
1714 static_cast<SCCOL
>(aSpans
[0].mnStart
), 0, nTab
,
1715 MAXCOL
, MAXROW
, nTab
, (PAINT_GRID
| PAINT_TOP
));
1720 aModificator
.SetDocumentModified();
1722 CellContentChanged();
1724 // put cursor directly behind the first deleted range
1725 SCCOL nCurX
= GetViewData().GetCurX();
1726 SCROW nCurY
= GetViewData().GetCurY();
1728 nCurY
= aSpans
[0].mnStart
;
1730 nCurX
= static_cast<SCCOL
>(aSpans
[0].mnStart
);
1731 SetCursor( nCurX
, nCurY
);
1733 SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED
) );
1738 void ScViewFunc::DeleteContents( InsertDeleteFlags nFlags
, bool bRecord
)
1740 ScViewData
& rViewData
= GetViewData();
1741 rViewData
.SetPasteMode( SC_PASTE_NONE
);
1742 rViewData
.GetViewShell()->UpdateCopySourceOverlay();
1744 // not editable because of matrix only? attribute OK nonetheless
1745 bool bOnlyNotBecauseOfMatrix
;
1746 bool bEditable
= SelectionEditable( &bOnlyNotBecauseOfMatrix
);
1749 if ( !(bOnlyNotBecauseOfMatrix
&&
1750 ((nFlags
& (IDF_ATTRIB
| IDF_EDITATTR
)) == nFlags
)) )
1752 ErrorMessage(bOnlyNotBecauseOfMatrix
? STR_MATRIXFRAGMENTERR
: STR_PROTECTIONERR
);
1758 bool bSimple
= false;
1760 ScDocument
* pDoc
= GetViewData().GetDocument();
1761 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
1762 ScMarkData
aFuncMark( GetViewData().GetMarkData() ); // local copy for UnmarkFiltered
1763 ScViewUtil::UnmarkFiltered( aFuncMark
, pDoc
);
1765 if (bRecord
&& !pDoc
->IsUndoEnabled())
1768 if ( !aFuncMark
.IsMarked() && !aFuncMark
.IsMultiMarked() )
1770 aMarkRange
.aStart
.SetCol(GetViewData().GetCurX());
1771 aMarkRange
.aStart
.SetRow(GetViewData().GetCurY());
1772 aMarkRange
.aStart
.SetTab(GetViewData().GetTabNo());
1773 aMarkRange
.aEnd
= aMarkRange
.aStart
;
1774 if ( pDoc
->HasAttrib( aMarkRange
, HASATTR_MERGED
) )
1776 aFuncMark
.SetMarkArea( aMarkRange
);
1782 HideAllCursors(); // for if summary is cancelled
1784 ScDocFunc
& rDocFunc
= pDocSh
->GetDocFunc();
1786 rDocFunc
.DeleteCell(aMarkRange
.aStart
, aFuncMark
, nFlags
, bRecord
, false);
1788 rDocFunc
.DeleteContents(aFuncMark
, nFlags
, bRecord
, false);
1790 pDocSh
->UpdateOle(&GetViewData());
1792 if (ScModelObj
*pModelObj
= HelperNotifyChanges::getMustPropagateChangesModel(*pDocSh
))
1794 ScRangeList aChangeRanges
;
1797 aChangeRanges
.Append( aMarkRange
);
1801 aFuncMark
.FillRangeListWithMarks( &aChangeRanges
, false );
1803 HelperNotifyChanges::Notify(*pModelObj
, aChangeRanges
);
1806 CellContentChanged();
1809 if ( nFlags
& IDF_ATTRIB
)
1811 if ( nFlags
& IDF_CONTENTS
)
1814 StartFormatArea(); // delete attribute is also attribute-change
1818 // column width/row height (via header) - undo OK
1820 void ScViewFunc::SetWidthOrHeight(
1821 bool bWidth
, const std::vector
<sc::ColRowSpan
>& rRanges
, ScSizeMode eMode
,
1822 sal_uInt16 nSizeTwips
, bool bRecord
, bool bPaint
, ScMarkData
* pMarkData
)
1824 if (rRanges
.empty())
1827 // Use view's mark if none specified, but do not modify the original data,
1828 // i.e. no MarkToMulti() on that.
1829 ScMarkData
aMarkData( pMarkData
? *pMarkData
: GetViewData().GetMarkData());
1831 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
1832 ScDocument
& rDoc
= pDocSh
->GetDocument();
1833 SCTAB nFirstTab
= aMarkData
.GetFirstSelected();
1834 SCTAB nCurTab
= GetViewData().GetTabNo();
1836 if (bRecord
&& !rDoc
.IsUndoEnabled())
1839 ScDocShellModificator
aModificator( *pDocSh
);
1841 bool bAllowed
= true;
1842 ScMarkData::iterator itr
= aMarkData
.begin(), itrEnd
= aMarkData
.end();
1843 for (; itr
!= itrEnd
&& bAllowed
; ++itr
)
1845 for (size_t i
= 0, n
= rRanges
.size(); i
< n
&& bAllowed
; ++i
)
1850 bAllowed
= rDoc
.IsBlockEditable(
1851 *itr
, rRanges
[i
].mnStart
, 0, rRanges
[i
].mnEnd
, MAXROW
,
1852 &bOnlyMatrix
) || bOnlyMatrix
;
1856 bAllowed
= rDoc
.IsBlockEditable(
1857 *itr
, 0, rRanges
[i
].mnStart
, MAXCOL
,rRanges
[i
].mnEnd
, &bOnlyMatrix
) || bOnlyMatrix
;
1862 // Allow users to resize cols/rows in readonly docs despite the r/o state.
1863 // It is frustrating to be unable to see content in mis-sized cells.
1864 if( !bAllowed
&& !pDocSh
->IsReadOnly() )
1866 ErrorMessage(STR_PROTECTIONERR
);
1870 SCCOLROW nStart
= rRanges
[0].mnStart
;
1871 SCCOLROW nEnd
= rRanges
[0].mnEnd
;
1873 bool bFormula
= false;
1874 if ( eMode
== SC_SIZE_OPTIMAL
)
1876 const ScViewOptions
& rOpts
= GetViewData().GetOptions();
1877 bFormula
= rOpts
.GetOption( VOPT_FORMULAS
);
1880 ScDocument
* pUndoDoc
= NULL
;
1881 ScOutlineTable
* pUndoTab
= NULL
;
1882 std::vector
<sc::ColRowSpan
> aUndoRanges
;
1886 rDoc
.BeginDrawUndo(); // Drawing Updates
1888 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
1889 itr
= aMarkData
.begin();
1890 for (; itr
!= itrEnd
; ++itr
)
1894 if ( *itr
== nFirstTab
)
1895 pUndoDoc
->InitUndo( &rDoc
, *itr
, *itr
, true, false );
1897 pUndoDoc
->AddUndoTab( *itr
, *itr
, true, false );
1898 rDoc
.CopyToDocument( static_cast<SCCOL
>(nStart
), 0, *itr
,
1899 static_cast<SCCOL
>(nEnd
), MAXROW
, *itr
, IDF_NONE
,
1904 if ( *itr
== nFirstTab
)
1905 pUndoDoc
->InitUndo( &rDoc
, *itr
, *itr
, false, true );
1907 pUndoDoc
->AddUndoTab( *itr
, *itr
, false, true );
1908 rDoc
.CopyToDocument( 0, nStart
, *itr
, MAXCOL
, nEnd
, *itr
, IDF_NONE
, false, pUndoDoc
);
1912 aUndoRanges
= rRanges
;
1914 //! outlines from all tab?
1915 ScOutlineTable
* pTable
= rDoc
.GetOutlineTable( nCurTab
);
1917 pUndoTab
= new ScOutlineTable( *pTable
);
1920 if ( eMode
==SC_SIZE_OPTIMAL
|| eMode
==SC_SIZE_VISOPT
)
1921 aMarkData
.MarkToMulti();
1923 bool bShow
= nSizeTwips
> 0 || eMode
!= SC_SIZE_DIRECT
;
1924 bool bOutline
= false;
1926 itr
= aMarkData
.begin();
1927 for (; itr
!= itrEnd
; ++itr
)
1931 for (size_t i
= 0, n
= rRanges
.size(); i
< n
; ++i
)
1933 SCCOLROW nStartNo
= rRanges
[i
].mnStart
;
1934 SCCOLROW nEndNo
= rRanges
[i
].mnEnd
;
1936 if ( !bWidth
) // height always blockwise
1938 if ( eMode
==SC_SIZE_OPTIMAL
|| eMode
==SC_SIZE_VISOPT
)
1940 bool bAll
= ( eMode
==SC_SIZE_OPTIMAL
);
1943 // delete CR_MANUALSIZE for all in range,
1944 // then SetOptimalHeight with bShrink = FALSE
1945 for (SCROW nRow
= nStartNo
; nRow
<= nEndNo
; ++nRow
)
1947 SCROW nLastRow
= nRow
;
1948 if (rDoc
.RowHidden(nRow
, nTab
, NULL
, &nLastRow
))
1954 sal_uInt8 nOld
= rDoc
.GetRowFlags(nRow
, nTab
);
1955 if (nOld
& CR_MANUALSIZE
)
1956 rDoc
.SetRowFlags(nRow
, nTab
, nOld
& ~CR_MANUALSIZE
);
1960 double nPPTX
= GetViewData().GetPPTX();
1961 double nPPTY
= GetViewData().GetPPTY();
1962 Fraction aZoomX
= GetViewData().GetZoomX();
1963 Fraction aZoomY
= GetViewData().GetZoomY();
1965 ScSizeDeviceProvider
aProv(pDocSh
);
1966 if (aProv
.IsPrinter())
1968 nPPTX
= aProv
.GetPPTX();
1969 nPPTY
= aProv
.GetPPTY();
1970 aZoomX
= aZoomY
= Fraction( 1, 1 );
1973 sc::RowHeightContext
aCxt(nPPTX
, nPPTY
, aZoomX
, aZoomY
, aProv
.GetDevice());
1974 aCxt
.setForceAutoSize(bAll
);
1975 aCxt
.setExtraHeight(nSizeTwips
);
1976 rDoc
.SetOptimalHeight(aCxt
, nStartNo
, nEndNo
, nTab
);
1978 rDoc
.ShowRows( nStartNo
, nEndNo
, nTab
, true );
1980 // Manual-Flag already (re)set in SetOptimalHeight in case of bAll=sal_True
1981 // (set for Extra-Height, else reset).
1983 else if ( eMode
==SC_SIZE_DIRECT
)
1987 rDoc
.SetRowHeightRange( nStartNo
, nEndNo
, nTab
, nSizeTwips
);
1988 rDoc
.SetManualHeight( nStartNo
, nEndNo
, nTab
, true ); // height was set manually
1990 rDoc
.ShowRows( nStartNo
, nEndNo
, nTab
, nSizeTwips
!= 0 );
1992 else if ( eMode
==SC_SIZE_SHOW
)
1994 rDoc
.ShowRows( nStartNo
, nEndNo
, nTab
, true );
1997 else // column width
1999 for (SCCOL nCol
=static_cast<SCCOL
>(nStartNo
); nCol
<=static_cast<SCCOL
>(nEndNo
); nCol
++)
2001 if ( eMode
!= SC_SIZE_VISOPT
|| !rDoc
.ColHidden(nCol
, nTab
) )
2003 sal_uInt16 nThisSize
= nSizeTwips
;
2005 if ( eMode
==SC_SIZE_OPTIMAL
|| eMode
==SC_SIZE_VISOPT
)
2006 nThisSize
= nSizeTwips
+ GetOptimalColWidth( nCol
, nTab
, bFormula
);
2008 rDoc
.SetColWidth( nCol
, nTab
, nThisSize
);
2010 rDoc
.ShowCol( nCol
, nTab
, bShow
);
2019 if ( rDoc
.UpdateOutlineCol( static_cast<SCCOL
>(nStartNo
),
2020 static_cast<SCCOL
>(nEndNo
), nTab
, bShow
) )
2025 if ( rDoc
.UpdateOutlineRow( nStartNo
, nEndNo
, nTab
, bShow
) )
2029 rDoc
.SetDrawPageSize(nTab
);
2037 pDocSh
->GetUndoManager()->AddUndoAction(
2038 new ScUndoWidthOrHeight(
2039 pDocSh
, aMarkData
, nStart
, nCurTab
, nEnd
, nCurTab
,
2040 pUndoDoc
, aUndoRanges
, pUndoTab
, eMode
, nSizeTwips
, bWidth
));
2043 // fdo#36247 Ensure that the drawing layer's map mode scaling factors match
2044 // the new heights and widths.
2045 GetViewData().GetView()->RefreshZoom();
2047 itr
= aMarkData
.begin();
2048 for (; itr
!= itrEnd
; ++itr
)
2049 rDoc
.UpdatePageBreaks( *itr
);
2051 GetViewData().GetView()->UpdateScrollBars();
2055 itr
= aMarkData
.begin();
2056 for (; itr
!= itrEnd
; ++itr
)
2061 if (rDoc
.HasAttrib( static_cast<SCCOL
>(nStart
),0,nTab
,
2062 static_cast<SCCOL
>(nEnd
),MAXROW
,nTab
,
2063 HASATTR_MERGED
| HASATTR_OVERLAPPED
))
2065 if (nStart
> 0) // go upwards because of Lines and cursor
2067 pDocSh
->PostPaint( static_cast<SCCOL
>(nStart
), 0, nTab
,
2068 MAXCOL
, MAXROW
, nTab
, PAINT_GRID
| PAINT_TOP
);
2072 if (rDoc
.HasAttrib( 0,nStart
,nTab
, MAXCOL
,nEnd
,nTab
, HASATTR_MERGED
| HASATTR_OVERLAPPED
))
2076 pDocSh
->PostPaint( 0, nStart
, nTab
, MAXCOL
, MAXROW
, nTab
, PAINT_GRID
| PAINT_LEFT
);
2080 pDocSh
->UpdateOle(&GetViewData());
2081 if( !pDocSh
->IsReadOnly() )
2082 aModificator
.SetDocumentModified();
2087 if (ScModelObj
* pModelObj
= HelperNotifyChanges::getMustPropagateChangesModel(*pDocSh
))
2089 ScRangeList aChangeRanges
;
2090 itr
= aMarkData
.begin();
2091 for (; itr
!= itrEnd
; ++itr
)
2094 for (size_t i
= 0, n
= rRanges
.size(); i
< n
; ++i
)
2096 SCCOL nStartCol
= rRanges
[i
].mnStart
;
2097 SCCOL nEndCol
= rRanges
[i
].mnEnd
;
2098 for ( SCCOL nCol
= nStartCol
; nCol
<= nEndCol
; ++nCol
)
2100 aChangeRanges
.Append( ScRange( nCol
, 0, nTab
) );
2104 HelperNotifyChanges::Notify(*pModelObj
, aChangeRanges
, "column-resize");
2109 // column width/row height (via marked range)
2111 void ScViewFunc::SetMarkedWidthOrHeight( bool bWidth
, ScSizeMode eMode
, sal_uInt16 nSizeTwips
,
2112 bool bRecord
, bool bPaint
)
2114 ScMarkData
& rMark
= GetViewData().GetMarkData();
2116 rMark
.MarkToMulti();
2117 if (!rMark
.IsMultiMarked())
2119 SCCOL nCol
= GetViewData().GetCurX();
2120 SCROW nRow
= GetViewData().GetCurY();
2121 SCTAB nTab
= GetViewData().GetTabNo();
2124 rMark
.SetMultiMarkArea( ScRange( nCol
,nRow
,nTab
), true );
2128 std::vector
<sc::ColRowSpan
> aRanges
=
2129 bWidth
? rMark
.GetMarkedColSpans() : rMark
.GetMarkedRowSpans();
2131 SetWidthOrHeight(bWidth
, aRanges
, eMode
, nSizeTwips
, bRecord
, bPaint
);
2133 rMark
.MarkToSimple();
2136 void ScViewFunc::ModifyCellSize( ScDirection eDir
, bool bOptimal
)
2138 //! step size adjustable
2139 // step size is also minimum
2140 sal_uInt16 nStepX
= STD_COL_WIDTH
/ 5;
2141 sal_uInt16 nStepY
= ScGlobal::nStdRowHeight
;
2143 ScModule
* pScMod
= SC_MOD();
2144 bool bAnyEdit
= pScMod
->IsInputMode();
2145 SCCOL nCol
= GetViewData().GetCurX();
2146 SCROW nRow
= GetViewData().GetCurY();
2147 SCTAB nTab
= GetViewData().GetTabNo();
2148 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
2149 ScDocument
& rDoc
= pDocSh
->GetDocument();
2151 bool bAllowed
, bOnlyMatrix
;
2152 if ( eDir
== DIR_LEFT
|| eDir
== DIR_RIGHT
)
2153 bAllowed
= rDoc
.IsBlockEditable( nTab
, nCol
,0, nCol
,MAXROW
, &bOnlyMatrix
);
2155 bAllowed
= rDoc
.IsBlockEditable( nTab
, 0,nRow
, MAXCOL
,nRow
, &bOnlyMatrix
);
2156 if ( !bAllowed
&& !bOnlyMatrix
)
2158 ErrorMessage(STR_PROTECTIONERR
);
2164 sal_uInt16 nWidth
= rDoc
.GetColWidth( nCol
, nTab
);
2165 sal_uInt16 nHeight
= rDoc
.GetRowHeight( nRow
, nTab
);
2166 std::vector
<sc::ColRowSpan
> aRange(1, sc::ColRowSpan(0,0));
2167 if ( eDir
== DIR_LEFT
|| eDir
== DIR_RIGHT
)
2169 if (bOptimal
) // width of this single cell
2173 // when editing the actual entered width
2174 ScInputHandler
* pHdl
= pScMod
->GetInputHdl( GetViewData().GetViewShell() );
2177 long nEdit
= pHdl
->GetTextSize().Width(); // in 0.01 mm
2179 const ScPatternAttr
* pPattern
= rDoc
.GetPattern( nCol
, nRow
, nTab
);
2180 const SvxMarginItem
& rMItem
=
2181 static_cast<const SvxMarginItem
&>(pPattern
->GetItem(ATTR_MARGIN
));
2182 sal_uInt16 nMargin
= rMItem
.GetLeftMargin() + rMItem
.GetRightMargin();
2183 if ( static_cast<const SvxHorJustifyItem
&>( pPattern
->
2184 GetItem( ATTR_HOR_JUSTIFY
)).GetValue() == SVX_HOR_JUSTIFY_LEFT
)
2185 nMargin
= sal::static_int_cast
<sal_uInt16
>(
2186 nMargin
+ static_cast<const SfxUInt16Item
&>(pPattern
->GetItem(ATTR_INDENT
)).GetValue() );
2188 nWidth
= (sal_uInt16
)(nEdit
* pDocSh
->GetOutputFactor() / HMM_PER_TWIPS
)
2189 + nMargin
+ STD_EXTRA_WIDTH
;
2194 double nPPTX
= GetViewData().GetPPTX();
2195 double nPPTY
= GetViewData().GetPPTY();
2196 Fraction aZoomX
= GetViewData().GetZoomX();
2197 Fraction aZoomY
= GetViewData().GetZoomY();
2199 ScSizeDeviceProvider
aProv(pDocSh
);
2200 if (aProv
.IsPrinter())
2202 nPPTX
= aProv
.GetPPTX();
2203 nPPTY
= aProv
.GetPPTY();
2204 aZoomX
= aZoomY
= Fraction( 1, 1 );
2207 long nPixel
= rDoc
.GetNeededSize( nCol
, nRow
, nTab
, aProv
.GetDevice(),
2208 nPPTX
, nPPTY
, aZoomX
, aZoomY
, true );
2209 sal_uInt16 nTwips
= (sal_uInt16
)( nPixel
/ nPPTX
);
2211 nWidth
= nTwips
+ STD_EXTRA_WIDTH
;
2213 nWidth
= STD_COL_WIDTH
;
2216 else // increment / decrement
2218 if ( eDir
== DIR_RIGHT
)
2219 nWidth
= sal::static_int_cast
<sal_uInt16
>( nWidth
+ nStepX
);
2220 else if ( nWidth
> nStepX
)
2221 nWidth
= sal::static_int_cast
<sal_uInt16
>( nWidth
- nStepX
);
2222 if ( nWidth
< nStepX
) nWidth
= nStepX
;
2223 if ( nWidth
> MAX_COL_WIDTH
) nWidth
= MAX_COL_WIDTH
;
2225 aRange
[0].mnStart
= nCol
;
2226 aRange
[0].mnEnd
= nCol
;
2227 SetWidthOrHeight(true, aRange
, SC_SIZE_DIRECT
, nWidth
);
2229 // adjust height of this row if width demands/allows this
2233 const ScPatternAttr
* pPattern
= rDoc
.GetPattern( nCol
, nRow
, nTab
);
2235 static_cast<const SfxBoolItem
&>(pPattern
->GetItem( ATTR_LINEBREAK
)).GetValue() ||
2236 static_cast<const SvxHorJustifyItem
&>(pPattern
->
2237 GetItem( ATTR_HOR_JUSTIFY
)).GetValue() == SVX_HOR_JUSTIFY_BLOCK
;
2239 AdjustRowHeight( nRow
, nRow
);
2247 eMode
= SC_SIZE_OPTIMAL
;
2252 eMode
= SC_SIZE_DIRECT
;
2253 if ( eDir
== DIR_BOTTOM
)
2254 nHeight
= sal::static_int_cast
<sal_uInt16
>( nHeight
+ nStepY
);
2255 else if ( nHeight
> nStepY
)
2256 nHeight
= sal::static_int_cast
<sal_uInt16
>( nHeight
- nStepY
);
2257 if ( nHeight
< nStepY
) nHeight
= nStepY
;
2258 if ( nHeight
> MAX_ROW_HEIGHT
) nHeight
= MAX_ROW_HEIGHT
;
2260 aRange
[0].mnStart
= nRow
;
2261 aRange
[0].mnEnd
= nRow
;
2262 SetWidthOrHeight(false, aRange
, eMode
, nHeight
);
2268 if ( rDoc
.HasAttrib( nCol
, nRow
, nTab
, nCol
, nRow
, nTab
, HASATTR_NEEDHEIGHT
) )
2270 ScInputHandler
* pHdl
= pScMod
->GetInputHdl( GetViewData().GetViewShell() );
2272 pHdl
->SetModified(); // so that the height is adjusted with Enter
2279 void ScViewFunc::ProtectSheet( SCTAB nTab
, const ScTableProtection
& rProtect
)
2281 if (nTab
== TABLEID_DOC
)
2284 ScMarkData
& rMark
= GetViewData().GetMarkData();
2285 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
2286 ScDocument
& rDoc
= pDocSh
->GetDocument();
2287 ScDocFunc
&rFunc
= pDocSh
->GetDocFunc();
2288 bool bUndo(rDoc
.IsUndoEnabled());
2290 // modifying several tabs is handled here
2294 OUString aUndo
= ScGlobal::GetRscString( STR_UNDO_PROTECT_TAB
);
2295 pDocSh
->GetUndoManager()->EnterListAction( aUndo
, aUndo
);
2298 ScMarkData::iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
2299 for (; itr
!= itrEnd
; ++itr
)
2300 rFunc
.ProtectSheet(*itr
, rProtect
);
2303 pDocSh
->GetUndoManager()->LeaveListAction();
2305 UpdateLayerLocks(); //! broadcast to all views
2308 void ScViewFunc::Protect( SCTAB nTab
, const OUString
& rPassword
)
2310 ScMarkData
& rMark
= GetViewData().GetMarkData();
2311 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
2312 ScDocument
& rDoc
= pDocSh
->GetDocument();
2313 ScDocFunc
&rFunc
= pDocSh
->GetDocFunc();
2314 bool bUndo(rDoc
.IsUndoEnabled());
2316 if ( nTab
== TABLEID_DOC
|| rMark
.GetSelectCount() <= 1 )
2317 rFunc
.Protect( nTab
, rPassword
, false );
2320 // modifying several tabs is handled here
2324 OUString aUndo
= ScGlobal::GetRscString( STR_UNDO_PROTECT_TAB
);
2325 pDocSh
->GetUndoManager()->EnterListAction( aUndo
, aUndo
);
2328 ScMarkData::iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
2329 for (; itr
!= itrEnd
; ++itr
)
2330 rFunc
.Protect( *itr
, rPassword
, false );
2333 pDocSh
->GetUndoManager()->LeaveListAction();
2336 UpdateLayerLocks(); //! broadcast to all views
2339 bool ScViewFunc::Unprotect( SCTAB nTab
, const OUString
& rPassword
)
2341 ScMarkData
& rMark
= GetViewData().GetMarkData();
2342 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
2343 ScDocument
& rDoc
= pDocSh
->GetDocument();
2344 ScDocFunc
&rFunc
= pDocSh
->GetDocFunc();
2345 bool bChanged
= false;
2346 bool bUndo (rDoc
.IsUndoEnabled());
2348 if ( nTab
== TABLEID_DOC
|| rMark
.GetSelectCount() <= 1 )
2349 bChanged
= rFunc
.Unprotect( nTab
, rPassword
, false );
2352 // modifying several tabs is handled here
2356 OUString aUndo
= ScGlobal::GetRscString( STR_UNDO_UNPROTECT_TAB
);
2357 pDocSh
->GetUndoManager()->EnterListAction( aUndo
, aUndo
);
2360 ScMarkData::iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
2361 for (; itr
!= itrEnd
; ++itr
)
2362 if ( rFunc
.Unprotect( *itr
, rPassword
, false ) )
2366 pDocSh
->GetUndoManager()->LeaveListAction();
2370 UpdateLayerLocks(); //! broadcast to all views
2375 void ScViewFunc::SetNoteText( const ScAddress
& rPos
, const OUString
& rNoteText
)
2377 GetViewData().GetDocShell()->GetDocFunc().SetNoteText( rPos
, rNoteText
, false );
2380 void ScViewFunc::ReplaceNote( const ScAddress
& rPos
, const OUString
& rNoteText
, const OUString
* pAuthor
, const OUString
* pDate
)
2382 GetViewData().GetDocShell()->GetDocFunc().ReplaceNote( rPos
, rNoteText
, pAuthor
, pDate
, false );
2385 void ScViewFunc::SetNumberFormat( short nFormatType
, sal_uLong nAdd
)
2387 // not editable because of matrix only? attribute OK nonetheless
2388 bool bOnlyNotBecauseOfMatrix
;
2389 if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix
) && !bOnlyNotBecauseOfMatrix
)
2391 ErrorMessage(STR_PROTECTIONERR
);
2395 sal_uInt32 nNumberFormat
= 0;
2396 ScViewData
& rViewData
= GetViewData();
2397 ScDocument
* pDoc
= rViewData
.GetDocument();
2398 SvNumberFormatter
* pNumberFormatter
= pDoc
->GetFormatTable();
2399 LanguageType eLanguage
= ScGlobal::eLnge
;
2400 ScPatternAttr
aNewAttrs( pDoc
->GetPool() );
2402 // always take language from cursor position, even if there is a selection
2404 sal_uInt32 nCurrentNumberFormat
;
2405 pDoc
->GetNumberFormat( rViewData
.GetCurX(),
2406 rViewData
.GetCurY(),
2407 rViewData
.GetTabNo(),
2408 nCurrentNumberFormat
);
2409 const SvNumberformat
* pEntry
= pNumberFormatter
->GetEntry( nCurrentNumberFormat
);
2411 eLanguage
= pEntry
->GetLanguage(); // else keep ScGlobal::eLnge
2413 nNumberFormat
= pNumberFormatter
->GetStandardFormat( nFormatType
, eLanguage
) + nAdd
;
2415 SfxItemSet
& rSet
= aNewAttrs
.GetItemSet();
2416 rSet
.Put( SfxUInt32Item( ATTR_VALUE_FORMAT
, nNumberFormat
) );
2417 // ATTR_LANGUAGE_FORMAT not
2418 ApplySelectionPattern( aNewAttrs
, true );
2421 void ScViewFunc::SetNumFmtByStr( const OUString
& rCode
)
2423 // not editable because of matrix only? attribute OK nonetheless
2424 bool bOnlyNotBecauseOfMatrix
;
2425 if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix
) && !bOnlyNotBecauseOfMatrix
)
2427 ErrorMessage(STR_PROTECTIONERR
);
2431 ScViewData
& rViewData
= GetViewData();
2432 ScDocument
* pDoc
= rViewData
.GetDocument();
2433 SvNumberFormatter
* pFormatter
= pDoc
->GetFormatTable();
2435 // language always from cursor position
2437 sal_uInt32 nCurrentNumberFormat
;
2438 pDoc
->GetNumberFormat( rViewData
.GetCurX(), rViewData
.GetCurY(),
2439 rViewData
.GetTabNo(), nCurrentNumberFormat
);
2440 const SvNumberformat
* pEntry
= pFormatter
->GetEntry( nCurrentNumberFormat
);
2441 LanguageType eLanguage
= pEntry
? pEntry
->GetLanguage() : ScGlobal::eLnge
;
2443 // determine index for String
2446 sal_uInt32 nNumberFormat
= pFormatter
->GetEntryKey( rCode
, eLanguage
);
2447 if ( nNumberFormat
== NUMBERFORMAT_ENTRY_NOT_FOUND
)
2451 OUString aFormat
= rCode
; // will be changed
2452 sal_Int32 nErrPos
= 0;
2453 short nType
= 0; //! ???
2454 bOk
= pFormatter
->PutEntry( aFormat
, nErrPos
, nType
, nNumberFormat
, eLanguage
);
2457 if ( bOk
) // valid format?
2459 ScPatternAttr
aNewAttrs( pDoc
->GetPool() );
2460 SfxItemSet
& rSet
= aNewAttrs
.GetItemSet();
2461 rSet
.Put( SfxUInt32Item( ATTR_VALUE_FORMAT
, nNumberFormat
) );
2462 rSet
.Put( SvxLanguageItem( eLanguage
, ATTR_LANGUAGE_FORMAT
) );
2463 ApplySelectionPattern( aNewAttrs
, true );
2466 //! else return error / issue warning ???
2469 void ScViewFunc::ChangeNumFmtDecimals( bool bIncrement
)
2471 // not editable because of matrix only? attribute OK nonetheless
2472 bool bOnlyNotBecauseOfMatrix
;
2473 if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix
) && !bOnlyNotBecauseOfMatrix
)
2475 ErrorMessage(STR_PROTECTIONERR
);
2479 ScDocument
* pDoc
= GetViewData().GetDocument();
2480 SvNumberFormatter
* pFormatter
= pDoc
->GetFormatTable();
2482 SCCOL nCol
= GetViewData().GetCurX();
2483 SCROW nRow
= GetViewData().GetCurY();
2484 SCTAB nTab
= GetViewData().GetTabNo();
2486 sal_uInt32 nOldFormat
;
2487 pDoc
->GetNumberFormat( nCol
, nRow
, nTab
, nOldFormat
);
2488 const SvNumberformat
* pOldEntry
= pFormatter
->GetEntry( nOldFormat
);
2491 OSL_FAIL("numberformat not found !!!");
2495 // what have we got here?
2497 sal_uInt32 nNewFormat
= nOldFormat
;
2498 bool bError
= false;
2500 LanguageType eLanguage
= pOldEntry
->GetLanguage();
2501 bool bThousand
, bNegRed
;
2502 sal_uInt16 nPrecision
, nLeading
;
2503 pOldEntry
->GetFormatSpecialInfo( bThousand
, bNegRed
, nPrecision
, nLeading
);
2505 short nOldType
= pOldEntry
->GetType();
2506 if ( 0 == ( nOldType
& (
2507 css::util::NumberFormat::NUMBER
| css::util::NumberFormat::CURRENCY
| css::util::NumberFormat::PERCENT
| css::util::NumberFormat::SCIENTIFIC
) ) )
2509 // date, time, fraction, logical, text can not be changed
2513 //! SvNumberformat has a Member bStandard, but doesn't disclose it
2514 bool bWasStandard
= ( nOldFormat
== pFormatter
->GetStandardIndex( eLanguage
) );
2515 OUString sExponentialStandardFormat
= "";
2518 // with "Standard" the decimal places depend on cell content
2519 // 0 if empty or text -> no decimal places
2520 double nVal
= pDoc
->GetValue( ScAddress( nCol
, nRow
, nTab
) );
2522 // the ways of the Numberformatters are unfathomable, so try:
2525 const_cast<SvNumberformat
*>(pOldEntry
)->GetOutputString( nVal
, aOut
, &pCol
);
2528 // 'E' for exponential is fixed in Numberformatter
2529 sal_Int32 nIndexE
= aOut
.indexOf((sal_Unicode
)'E');
2532 sExponentialStandardFormat
= aOut
.copy( nIndexE
).replace( '-', '+' );
2533 for ( sal_Int32 i
=1 ; i
<sExponentialStandardFormat
.getLength() ; i
++ )
2535 if ( sExponentialStandardFormat
[i
] >= '1' && sExponentialStandardFormat
[i
] <= '9' )
2536 sExponentialStandardFormat
= sExponentialStandardFormat
.replaceAt( i
, 1, OUString( "0" ) );
2538 aOut
= aOut
.copy( 0, nIndexE
); // remove exponential part
2540 OUString
aDecSep( pFormatter
->GetFormatDecimalSep( nOldFormat
) );
2541 sal_Int32 nPos
= aOut
.indexOf( aDecSep
);
2543 nPrecision
= aOut
.getLength() - nPos
- aDecSep
.getLength();
2548 if ( (nOldType
& css::util::NumberFormat::SCIENTIFIC
) && !bThousand
&&
2549 (pOldEntry
->GetFormatIntegerDigits()%3 == 0) && pOldEntry
->GetFormatIntegerDigits() > 0 )
2558 ++nPrecision
; // increment
2560 bError
= true; // 20 is maximum
2565 --nPrecision
; // decrement
2567 bError
= true; // 0 is minimum
2573 OUString aNewPicture
= pFormatter
->GenerateFormat(nOldFormat
, eLanguage
,
2575 nPrecision
, nLeading
)
2576 + sExponentialStandardFormat
;
2578 nNewFormat
= pFormatter
->GetEntryKey( aNewPicture
, eLanguage
);
2579 if ( nNewFormat
== NUMBERFORMAT_ENTRY_NOT_FOUND
)
2581 sal_Int32 nErrPos
= 0;
2583 bool bOk
= pFormatter
->PutEntry( aNewPicture
, nErrPos
,
2584 nNewType
, nNewFormat
, eLanguage
);
2585 OSL_ENSURE( bOk
, "incorrect numberformat generated" );
2593 ScPatternAttr
aNewAttrs( pDoc
->GetPool() );
2594 SfxItemSet
& rSet
= aNewAttrs
.GetItemSet();
2595 rSet
.Put( SfxUInt32Item( ATTR_VALUE_FORMAT
, nNewFormat
) );
2596 // ATTR_LANGUAGE_FORMAT not
2597 ApplySelectionPattern( aNewAttrs
, true );
2601 void ScViewFunc::ChangeIndent( bool bIncrement
)
2603 ScViewData
& rViewData
= GetViewData();
2604 ScDocShell
* pDocSh
= rViewData
.GetDocShell();
2605 ScMarkData
& rMark
= rViewData
.GetMarkData();
2607 ScMarkData aWorkMark
= rMark
;
2608 ScViewUtil::UnmarkFiltered( aWorkMark
, &pDocSh
->GetDocument() );
2609 aWorkMark
.MarkToMulti();
2610 if (!aWorkMark
.IsMultiMarked())
2612 SCCOL nCol
= rViewData
.GetCurX();
2613 SCROW nRow
= rViewData
.GetCurY();
2614 SCTAB nTab
= rViewData
.GetTabNo();
2615 aWorkMark
.SetMultiMarkArea( ScRange(nCol
,nRow
,nTab
) );
2618 bool bSuccess
= pDocSh
->GetDocFunc().ChangeIndent( aWorkMark
, bIncrement
, false );
2621 pDocSh
->UpdateOle(&rViewData
);
2624 // stuff for sidebar panels
2625 SfxBindings
& rBindings
= GetViewData().GetBindings();
2626 rBindings
.Invalidate( SID_H_ALIGNCELL
);
2627 rBindings
.Invalidate( SID_ATTR_ALIGN_INDENT
);
2631 bool ScViewFunc::InsertName( const OUString
& rName
, const OUString
& rSymbol
,
2632 const OUString
& rType
)
2634 // Type = P,R,C,F (and combinations)
2638 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
2639 ScDocument
& rDoc
= pDocSh
->GetDocument();
2640 SCTAB nTab
= GetViewData().GetTabNo();
2641 ScRangeName
* pList
= rDoc
.GetRangeName();
2643 RangeType nType
= RT_NAME
;
2644 ScRangeData
* pNewEntry
= new ScRangeData( &rDoc
, rName
, rSymbol
,
2645 ScAddress( GetViewData().GetCurX(), GetViewData().GetCurY(),
2647 OUString aUpType
= rType
.toAsciiUpperCase();
2648 if ( aUpType
.indexOf( 'P' ) != -1 )
2649 nType
|= RT_PRINTAREA
;
2650 if ( aUpType
.indexOf( 'R' ) != -1 )
2651 nType
|= RT_ROWHEADER
;
2652 if ( aUpType
.indexOf( 'C' ) != -1 )
2653 nType
|= RT_COLHEADER
;
2654 if ( aUpType
.indexOf( 'F' ) != -1 )
2655 nType
|= RT_CRITERIA
;
2656 pNewEntry
->AddType(nType
);
2658 if ( !pNewEntry
->GetErrCode() ) // text valid?
2660 ScDocShellModificator
aModificator( *pDocSh
);
2662 rDoc
.PreprocessRangeNameUpdate();
2664 // input available yet? Then remove beforehand (=change)
2665 ScRangeData
* pData
= pList
->findByUpperName(ScGlobal::pCharClass
->uppercase(rName
));
2668 pNewEntry
->SetIndex(pData
->GetIndex());
2669 pList
->erase(*pData
);
2672 if ( pList
->insert( pNewEntry
) )
2674 pNewEntry
= NULL
; // never delete, insert took ownership
2676 rDoc
.CompileHybridFormula();
2678 aModificator
.SetDocumentModified();
2679 SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_AREAS_CHANGED
) );
2682 delete pNewEntry
; // if it wasn't inserted
2686 void ScViewFunc::CreateNames( sal_uInt16 nFlags
)
2690 if ( GetViewData().GetSimpleArea(aRange
) == SC_MARK_SIMPLE
)
2691 bDone
= GetViewData().GetDocShell()->GetDocFunc().CreateNames( aRange
, nFlags
, false );
2694 ErrorMessage(STR_CREATENAME_MARKERR
);
2697 sal_uInt16
ScViewFunc::GetCreateNameFlags()
2699 sal_uInt16 nFlags
= 0;
2701 SCCOL nStartCol
, nEndCol
;
2702 SCROW nStartRow
, nEndRow
;
2704 if (GetViewData().GetSimpleArea(nStartCol
,nStartRow
,nDummy
,nEndCol
,nEndRow
,nDummy
) == SC_MARK_SIMPLE
)
2706 ScDocument
* pDoc
= GetViewData().GetDocument();
2707 SCTAB nTab
= GetViewData().GetTabNo();
2713 SCCOL nFirstCol
= nStartCol
;
2714 SCCOL nLastCol
= nEndCol
;
2715 if (nStartCol
+1 < nEndCol
) { ++nFirstCol
; --nLastCol
; }
2716 for (i
=nFirstCol
; i
<=nLastCol
&& bOk
; i
++)
2717 if (!pDoc
->HasStringData( i
,nStartRow
,nTab
))
2721 else // Bottom only if not Top
2724 for (i
=nFirstCol
; i
<=nLastCol
&& bOk
; i
++)
2725 if (!pDoc
->HasStringData( i
,nEndRow
,nTab
))
2728 nFlags
|= NAME_BOTTOM
;
2732 SCROW nFirstRow
= nStartRow
;
2733 SCROW nLastRow
= nEndRow
;
2734 if (nStartRow
+1 < nEndRow
) { ++nFirstRow
; --nLastRow
; }
2735 for (j
=nFirstRow
; j
<=nLastRow
&& bOk
; j
++)
2736 if (!pDoc
->HasStringData( nStartCol
,j
,nTab
))
2739 nFlags
|= NAME_LEFT
;
2740 else // Right only if not Left
2743 for (j
=nFirstRow
; j
<=nLastRow
&& bOk
; j
++)
2744 if (!pDoc
->HasStringData( nEndCol
,j
,nTab
))
2747 nFlags
|= NAME_RIGHT
;
2751 if (nStartCol
== nEndCol
)
2752 nFlags
&= ~( NAME_LEFT
| NAME_RIGHT
);
2753 if (nStartRow
== nEndRow
)
2754 nFlags
&= ~( NAME_TOP
| NAME_BOTTOM
);
2759 void ScViewFunc::InsertNameList()
2761 ScAddress
aPos( GetViewData().GetCurX(), GetViewData().GetCurY(), GetViewData().GetTabNo() );
2762 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
2763 if ( pDocSh
->GetDocFunc().InsertNameList( aPos
, false ) )
2764 pDocSh
->UpdateOle(&GetViewData());
2767 void ScViewFunc::UpdateSelectionArea( const ScMarkData
& rSel
, ScPatternAttr
* pAttr
)
2769 ScDocShell
* pDocShell
= GetViewData().GetDocShell();
2771 if (rSel
.IsMultiMarked() )
2772 rSel
.GetMultiMarkArea( aMarkRange
);
2774 rSel
.GetMarkArea( aMarkRange
);
2776 bool bSetLines
= false;
2777 bool bSetAlign
= false;
2780 const SfxItemSet
& rNewSet
= pAttr
->GetItemSet();
2781 bSetLines
= rNewSet
.GetItemState( ATTR_BORDER
, true ) == SfxItemState::SET
||
2782 rNewSet
.GetItemState( ATTR_SHADOW
, true ) == SfxItemState::SET
;
2783 bSetAlign
= rNewSet
.GetItemState( ATTR_HOR_JUSTIFY
, true ) == SfxItemState::SET
;
2786 sal_uInt16 nExtFlags
= 0;
2788 nExtFlags
|= SC_PF_LINES
;
2790 nExtFlags
|= SC_PF_WHOLEROWS
;
2792 SCCOL nStartCol
= aMarkRange
.aStart
.Col();
2793 SCROW nStartRow
= aMarkRange
.aStart
.Row();
2794 SCTAB nStartTab
= aMarkRange
.aStart
.Tab();
2795 SCCOL nEndCol
= aMarkRange
.aEnd
.Col();
2796 SCROW nEndRow
= aMarkRange
.aEnd
.Row();
2797 SCTAB nEndTab
= aMarkRange
.aEnd
.Tab();
2798 pDocShell
->PostPaint( nStartCol
, nStartRow
, nStartTab
,
2799 nEndCol
, nEndRow
, nEndTab
,
2800 PAINT_GRID
, nExtFlags
| SC_PF_TESTMERGE
);
2801 ScTabViewShell
* pTabViewShell
= GetViewData().GetViewShell();
2802 pTabViewShell
->AdjustBlockHeight(false, const_cast<ScMarkData
*>(&rSel
));
2805 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */