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 "scitems.hxx"
21 #include <editeng/eeitem.hxx>
23 #include <sot/exchange.hxx>
24 #include <editeng/autokernitem.hxx>
25 #include <editeng/fontitem.hxx>
26 #include <editeng/forbiddencharacterstable.hxx>
27 #include <editeng/langitem.hxx>
28 #include <osl/thread.h>
29 #include <svx/svdetc.hxx>
30 #include <svx/svditer.hxx>
31 #include <svx/svdocapt.hxx>
32 #include <svx/svdograf.hxx>
33 #include <svx/svdoole2.hxx>
34 #include <svx/svdouno.hxx>
35 #include <svx/svdpage.hxx>
36 #include <svx/svdundo.hxx>
37 #include <svx/xtable.hxx>
38 #include <sfx2/objsh.hxx>
39 #include <sfx2/printer.hxx>
40 #include <unotools/saveopt.hxx>
41 #include <unotools/pathoptions.hxx>
43 #include "document.hxx"
44 #include "docoptio.hxx"
46 #include "drwlayer.hxx"
47 #include "markdata.hxx"
48 #include "patattr.hxx"
49 #include "rechead.hxx"
50 #include "poolhelp.hxx"
51 #include "docpool.hxx"
52 #include "detfunc.hxx"
53 #include "editutil.hxx"
55 #include "charthelper.hxx"
56 #include "interpre.hxx"
57 #include <documentlinkmgr.hxx>
59 using namespace ::com::sun::star
;
62 SfxBroadcaster
* ScDocument::GetDrawBroadcaster()
67 void ScDocument::BeginDrawUndo()
70 pDrawLayer
->BeginCalcUndo(false);
73 rtl::Reference
<XColorList
> ScDocument::GetColorList()
76 return pDrawLayer
->GetColorList();
80 pColorList
= XColorList::CreateStdColorList();
85 void ScDocument::TransferDrawPage(ScDocument
* pSrcDoc
, SCTAB nSrcPos
, SCTAB nDestPos
)
87 if (pDrawLayer
&& pSrcDoc
->pDrawLayer
)
89 SdrPage
* pOldPage
= pSrcDoc
->pDrawLayer
->GetPage(static_cast<sal_uInt16
>(nSrcPos
));
90 SdrPage
* pNewPage
= pDrawLayer
->GetPage(static_cast<sal_uInt16
>(nDestPos
));
92 if (pOldPage
&& pNewPage
)
94 SdrObjListIter
aIter( *pOldPage
, IM_FLAT
);
95 SdrObject
* pOldObject
= aIter
.Next();
99 SdrObject
* pNewObject
= pOldObject
->Clone();
100 // SdrObject* pNewObject = pOldObject->Clone( pNewPage, pDrawLayer );
101 pNewObject
->SetModel(pDrawLayer
);
102 pNewObject
->SetPage(pNewPage
);
104 pNewObject
->NbcMove(Size(0,0));
105 pNewPage
->InsertObject( pNewObject
);
107 if (pDrawLayer
->IsRecording())
108 pDrawLayer
->AddCalcUndo( new SdrUndoInsertObj( *pNewObject
) );
110 pOldObject
= aIter
.Next();
115 // make sure the data references of charts are adapted
116 // (this must be after InsertObject!)
117 ScChartHelper::AdjustRangesOfChartsOnDestinationPage( pSrcDoc
, this, nSrcPos
, nDestPos
);
118 ScChartHelper::UpdateChartsOnDestinationPage(this, nDestPos
);
121 void ScDocument::InitDrawLayer( SfxObjectShell
* pDocShell
)
123 if (pDocShell
&& !pShell
)
129 if ( pShell
&& !pShell
->IsLoading() ) // don't call GetTitle while loading
130 aName
= pShell
->GetTitle();
131 pDrawLayer
= new ScDrawLayer( this, aName
);
133 sfx2::LinkManager
* pMgr
= GetDocLinkManager().getLinkManager(bAutoCalc
);
135 pDrawLayer
->SetLinkManager(pMgr
);
137 //UUUU set DrawingLayer's SfxItemPool at Calc's SfxItemPool as
138 // secondary pool to support DrawingLayer FillStyle ranges (and similar)
139 // in SfxItemSets using the Calc SfxItemPool. This is e.g. needed when
140 // the PageStyle using SvxBrushItem is visualized and will be potentially
141 // used more intense in the future
142 if (xPoolHelper
.is() && !IsClipOrUndo()) //Using IsClipOrUndo as a proxy for SharePooledResources called
144 ScDocumentPool
* pLocalPool
= xPoolHelper
->GetDocPool();
148 OSL_ENSURE(!pLocalPool
->GetSecondaryPool(), "OOps, already a secondary pool set where the DrawingLayer ItemPool is to be placed (!)");
149 pLocalPool
->SetSecondaryPool(&pDrawLayer
->GetItemPool());
153 // Drawing pages are accessed by table number, so they must also be present
154 // for preceding table numbers, even if the tables aren't allocated
155 // (important for clipboard documents).
157 SCTAB nDrawPages
= 0;
159 for (nTab
=0; nTab
< static_cast<SCTAB
>(maTabs
.size()); nTab
++)
161 nDrawPages
= nTab
+ 1; // needed number of pages
163 for (nTab
=0; nTab
<nDrawPages
&& nTab
< static_cast<SCTAB
>(maTabs
.size()); nTab
++)
165 pDrawLayer
->ScAddPage( nTab
); // always add page, with or without the table
169 maTabs
[nTab
]->GetName(aTabName
);
170 pDrawLayer
->ScRenamePage( nTab
, aTabName
);
172 maTabs
[nTab
]->SetDrawPageSize(false,false); // set the right size immediately
176 pDrawLayer
->SetDefaultTabulator( GetDocOptions().GetTabDistance() );
180 // set draw defaults directly
181 SfxItemPool
& rDrawPool
= pDrawLayer
->GetItemPool();
182 rDrawPool
.SetPoolDefaultItem( SvxAutoKernItem( true, EE_CHAR_PAIRKERNING
) );
184 UpdateDrawLanguages();
186 pDrawLayer
->EnableAdjust(false);
188 pDrawLayer
->SetForbiddenCharsTable( xForbiddenCharacters
);
189 pDrawLayer
->SetCharCompressType( GetAsianCompression() );
190 pDrawLayer
->SetKernAsianPunctuation( GetAsianKerning() );
194 void ScDocument::UpdateDrawLanguages()
198 SfxItemPool
& rDrawPool
= pDrawLayer
->GetItemPool();
199 rDrawPool
.SetPoolDefaultItem( SvxLanguageItem( eLanguage
, EE_CHAR_LANGUAGE
) );
200 rDrawPool
.SetPoolDefaultItem( SvxLanguageItem( eCjkLanguage
, EE_CHAR_LANGUAGE_CJK
) );
201 rDrawPool
.SetPoolDefaultItem( SvxLanguageItem( eCtlLanguage
, EE_CHAR_LANGUAGE_CTL
) );
205 void ScDocument::UpdateDrawPrinter()
209 // use the printer even if IsValid is false
210 // Application::GetDefaultDevice causes trouble with changing MapModes
211 pDrawLayer
->SetRefDevice(GetRefDevice());
215 void ScDocument::SetDrawPageSize(SCTAB nTab
)
217 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
])
220 maTabs
[nTab
]->SetDrawPageSize();
223 bool ScDocument::IsChart( const SdrObject
* pObject
)
226 // IsChart() implementation moved to svx drawinglayer
227 if(pObject
&& OBJ_OLE2
== pObject
->GetObjIdentifier())
229 return static_cast<const SdrOle2Obj
*>(pObject
)->IsChart();
235 IMPL_LINK( ScDocument
, GetUserDefinedColor
, sal_uInt16
*, pColorIndex
)
237 return reinterpret_cast<sal_IntPtr
>( &((GetColorList()->GetColor(*pColorIndex
))->GetColor()) );
240 void ScDocument::DeleteDrawLayer()
242 //UUUU remove DrawingLayer's SfxItemPool from Calc's SfxItemPool where
243 // it is registered as secondary pool
244 if (xPoolHelper
.is() && !IsClipOrUndo()) //Using IsClipOrUndo as a proxy for SharePooledResources called
246 ScDocumentPool
* pLocalPool
= xPoolHelper
->GetDocPool();
248 if(pLocalPool
&& pLocalPool
->GetSecondaryPool())
250 pLocalPool
->SetSecondaryPool(0);
257 bool ScDocument::DrawGetPrintArea( ScRange
& rRange
, bool bSetHor
, bool bSetVer
) const
259 return pDrawLayer
->GetPrintArea( rRange
, bSetHor
, bSetVer
);
262 void ScDocument::DrawMovePage( sal_uInt16 nOldPos
, sal_uInt16 nNewPos
)
264 pDrawLayer
->ScMovePage(nOldPos
,nNewPos
);
267 void ScDocument::DrawCopyPage( sal_uInt16 nOldPos
, sal_uInt16 nNewPos
)
269 // angelegt wird die Page schon im ScTable ctor
270 pDrawLayer
->ScCopyPage( nOldPos
, nNewPos
);
273 void ScDocument::DeleteObjectsInArea( SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
,
274 const ScMarkData
& rMark
)
279 SCTAB nTabCount
= GetTableCount();
280 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
281 for (; itr
!= itrEnd
&& *itr
< nTabCount
; ++itr
)
283 pDrawLayer
->DeleteObjectsInArea( *itr
, nCol1
, nRow1
, nCol2
, nRow2
);
286 void ScDocument::DeleteObjectsInSelection( const ScMarkData
& rMark
)
291 pDrawLayer
->DeleteObjectsInSelection( rMark
);
294 bool ScDocument::HasOLEObjectsInArea( const ScRange
& rRange
, const ScMarkData
* pTabMark
)
296 // pTabMark is used only for selected tables. If pTabMark is 0, all tables of rRange are used.
302 SCTAB nEndTab
= static_cast<SCTAB
>(maTabs
.size());
305 nStartTab
= rRange
.aStart
.Tab();
306 nEndTab
= rRange
.aEnd
.Tab();
309 for (SCTAB nTab
= nStartTab
; nTab
<= nEndTab
; nTab
++)
311 if ( !pTabMark
|| pTabMark
->GetTableSelect(nTab
) )
313 Rectangle aMMRect
= GetMMRect( rRange
.aStart
.Col(), rRange
.aStart
.Row(),
314 rRange
.aEnd
.Col(), rRange
.aEnd
.Row(), nTab
);
316 SdrPage
* pPage
= pDrawLayer
->GetPage(static_cast<sal_uInt16
>(nTab
));
317 OSL_ENSURE(pPage
,"Page ?");
320 SdrObjListIter
aIter( *pPage
, IM_FLAT
);
321 SdrObject
* pObject
= aIter
.Next();
324 if ( pObject
->GetObjIdentifier() == OBJ_OLE2
&&
325 aMMRect
.IsInside( pObject
->GetCurrentBoundRect() ) )
328 pObject
= aIter
.Next();
337 void ScDocument::StartAnimations( SCTAB nTab
, vcl::Window
* pWin
)
341 SdrPage
* pPage
= pDrawLayer
->GetPage(static_cast<sal_uInt16
>(nTab
));
342 OSL_ENSURE(pPage
,"Page ?");
346 SdrObjListIter
aIter( *pPage
, IM_FLAT
);
347 SdrObject
* pObject
= aIter
.Next();
350 if (pObject
->ISA(SdrGrafObj
))
352 SdrGrafObj
* pGrafObj
= static_cast<SdrGrafObj
*>(pObject
);
353 if ( pGrafObj
->IsAnimated() )
355 const Rectangle
& rRect
= pGrafObj
->GetCurrentBoundRect();
356 pGrafObj
->StartAnimation( pWin
, rRect
.TopLeft(), rRect
.GetSize() );
359 pObject
= aIter
.Next();
363 bool ScDocument::HasBackgroundDraw( SCTAB nTab
, const Rectangle
& rMMRect
) const
365 // Are there objects in the background layer who are (partly) affected by rMMRect
366 // (for Drawing optimization, no deletion in front of the background
369 SdrPage
* pPage
= pDrawLayer
->GetPage(static_cast<sal_uInt16
>(nTab
));
370 OSL_ENSURE(pPage
,"Page ?");
376 SdrObjListIter
aIter( *pPage
, IM_FLAT
);
377 SdrObject
* pObject
= aIter
.Next();
378 while (pObject
&& !bFound
)
380 if ( pObject
->GetLayer() == SC_LAYER_BACK
&& pObject
->GetCurrentBoundRect().IsOver( rMMRect
) )
382 pObject
= aIter
.Next();
388 bool ScDocument::HasAnyDraw( SCTAB nTab
, const Rectangle
& rMMRect
) const
390 // Are there any objects at all who are (partly) affected by rMMRect?
391 // (To detect blank pages when printing)
394 SdrPage
* pPage
= pDrawLayer
->GetPage(static_cast<sal_uInt16
>(nTab
));
395 OSL_ENSURE(pPage
,"Page ?");
401 SdrObjListIter
aIter( *pPage
, IM_FLAT
);
402 SdrObject
* pObject
= aIter
.Next();
403 while (pObject
&& !bFound
)
405 if ( pObject
->GetCurrentBoundRect().IsOver( rMMRect
) )
407 pObject
= aIter
.Next();
413 void ScDocument::EnsureGraphicNames()
416 pDrawLayer
->EnsureGraphicNames();
419 SdrObject
* ScDocument::GetObjectAtPoint( SCTAB nTab
, const Point
& rPos
)
421 // for Drag&Drop on draw object
422 SdrObject
* pFound
= NULL
;
423 if (pDrawLayer
&& nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
425 SdrPage
* pPage
= pDrawLayer
->GetPage(static_cast<sal_uInt16
>(nTab
));
426 OSL_ENSURE(pPage
,"Page ?");
429 SdrObjListIter
aIter( *pPage
, IM_FLAT
);
430 SdrObject
* pObject
= aIter
.Next();
433 if ( pObject
->GetCurrentBoundRect().IsInside(rPos
) )
435 // Intern is of no interest
436 // Only object form background layer, when no object form another layer is found
437 SdrLayerID nLayer
= pObject
->GetLayer();
438 if ( (nLayer
!= SC_LAYER_INTERN
) && (nLayer
!= SC_LAYER_HIDDEN
) )
440 if ( nLayer
!= SC_LAYER_BACK
||
441 !pFound
|| pFound
->GetLayer() == SC_LAYER_BACK
)
447 // Continue search -> take last (on top) found object
448 pObject
= aIter
.Next();
455 bool ScDocument::IsPrintEmpty( SCTAB nTab
, SCCOL nStartCol
, SCROW nStartRow
,
456 SCCOL nEndCol
, SCROW nEndRow
, bool bLeftIsEmpty
,
457 ScRange
* pLastRange
, Rectangle
* pLastMM
) const
459 if (!IsBlockEmpty( nTab
, nStartCol
, nStartRow
, nEndCol
, nEndRow
))
462 if (HasAttrib(ScRange(nStartCol
, nStartRow
, nTab
, nEndCol
, nEndRow
, nTab
), HASATTR_LINES
))
463 // We want to print sheets with borders even if there is no cell content.
467 if ( pLastRange
&& pLastMM
&& nTab
== pLastRange
->aStart
.Tab() &&
468 nStartRow
== pLastRange
->aStart
.Row() && nEndRow
== pLastRange
->aEnd
.Row() )
470 // keep vertical part of aMMRect, only update horizontal position
475 for (i
=0; i
<nStartCol
; i
++)
476 nLeft
+= GetColWidth(i
,nTab
);
478 for (i
=nStartCol
; i
<=nEndCol
; i
++)
479 nRight
+= GetColWidth(i
,nTab
);
481 aMMRect
.Left() = (long)(nLeft
* HMM_PER_TWIPS
);
482 aMMRect
.Right() = (long)(nRight
* HMM_PER_TWIPS
);
485 aMMRect
= GetMMRect( nStartCol
, nStartRow
, nEndCol
, nEndRow
, nTab
);
487 if ( pLastRange
&& pLastMM
)
489 *pLastRange
= ScRange( nStartCol
, nStartRow
, nTab
, nEndCol
, nEndRow
, nTab
);
493 if ( HasAnyDraw( nTab
, aMMRect
))
496 if ( nStartCol
> 0 && !bLeftIsEmpty
)
498 // similar to in ScPrintFunc::AdjustPrintArea
499 // ExtendPrintArea starting only from the start column of the print area
501 SCCOL nExtendCol
= nStartCol
- 1;
502 SCROW nTmpRow
= nEndRow
;
504 // ExtendMerge() is non-const, but called without refresh. GetPrinter()
505 // might create and assign a printer.
506 ScDocument
* pThis
= const_cast<ScDocument
*>(this);
508 pThis
->ExtendMerge( 0,nStartRow
, nExtendCol
,nTmpRow
, nTab
,
509 false ); // no Refresh, incl. Attrs
511 OutputDevice
* pDev
= pThis
->GetPrinter();
512 pDev
->SetMapMode( MAP_PIXEL
); // Important for GetNeededSize
513 ExtendPrintArea( pDev
, nTab
, 0, nStartRow
, nExtendCol
, nEndRow
);
514 if ( nExtendCol
>= nStartCol
)
521 void ScDocument::Clear( bool bFromDestructor
)
523 TableContainer::iterator it
= maTabs
.begin();
524 for (;it
!= maTabs
.end(); ++it
)
527 delete pSelectionAttr
;
528 pSelectionAttr
= NULL
;
532 pDrawLayer
->ClearModel( bFromDestructor
);
536 bool ScDocument::HasDetectiveObjects(SCTAB nTab
) const
538 // looks for detective objects, annotations don't count
539 // (used to adjust scale so detective objects hit their cells better)
545 SdrPage
* pPage
= pDrawLayer
->GetPage(static_cast<sal_uInt16
>(nTab
));
546 OSL_ENSURE(pPage
,"Page ?");
549 SdrObjListIter
aIter( *pPage
, IM_DEEPNOGROUPS
);
550 SdrObject
* pObject
= aIter
.Next();
551 while (pObject
&& !bFound
)
553 // anything on the internal layer except captions (annotations)
554 if ( (pObject
->GetLayer() == SC_LAYER_INTERN
) && !ScDrawLayer::IsNoteCaption( pObject
) )
557 pObject
= aIter
.Next();
565 void ScDocument::UpdateFontCharSet()
567 // In old versions (until 4.0 without SP), when switching between systems,
568 // the Font attribute was not adjusted.
569 // This has to be redone for Documents until SP2:
570 // Everything that is not SYMBOL is set to system CharSet.
571 // CharSet should be correct for new documents (version SC_FONTCHARSET)
573 bool bUpdateOld
= ( nSrcVer
< SC_FONTCHARSET
);
575 rtl_TextEncoding eSysSet
= osl_getThreadTextEncoding();
576 if ( eSrcSet
!= eSysSet
|| bUpdateOld
)
581 ScDocumentPool
* pPool
= xPoolHelper
->GetDocPool();
582 nCount
= pPool
->GetItemCount2(ATTR_FONT
);
583 for (i
=0; i
<nCount
; i
++)
585 pItem
= const_cast<SvxFontItem
*>(static_cast<const SvxFontItem
*>(pPool
->GetItem2(ATTR_FONT
, i
)));
586 if ( pItem
&& ( pItem
->GetCharSet() == eSrcSet
||
587 ( bUpdateOld
&& pItem
->GetCharSet() != RTL_TEXTENCODING_SYMBOL
) ) )
588 pItem
->SetCharSet(eSysSet
);
593 SfxItemPool
& rDrawPool
= pDrawLayer
->GetItemPool();
594 nCount
= rDrawPool
.GetItemCount2(EE_CHAR_FONTINFO
);
595 for (i
=0; i
<nCount
; i
++)
597 pItem
= const_cast<SvxFontItem
*>(static_cast<const SvxFontItem
*>(rDrawPool
.GetItem2(EE_CHAR_FONTINFO
, i
)));
598 if ( pItem
&& ( pItem
->GetCharSet() == eSrcSet
||
599 ( bUpdateOld
&& pItem
->GetCharSet() != RTL_TEXTENCODING_SYMBOL
) ) )
600 pItem
->SetCharSet( eSysSet
);
606 void ScDocument::SetLoadingMedium( bool bVal
)
608 bLoadingMedium
= bVal
;
609 TableContainer::iterator it
= maTabs
.begin();
610 for (; it
!= maTabs
.end(); ++it
)
615 (*it
)->SetLoadingMedium(bVal
);
619 void ScDocument::SetImportingXML( bool bVal
)
621 bImportingXML
= bVal
;
623 pDrawLayer
->EnableAdjust(!bImportingXML
);
627 // #i57869# after loading, do the real RTL mirroring for the sheets that have the LoadingRTL flag set
629 for ( SCTAB nTab
=0; nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
]; nTab
++ )
630 if ( maTabs
[nTab
]->IsLoadingRTL() )
632 maTabs
[nTab
]->SetLoadingRTL( false );
633 SetLayoutRTL( nTab
, true ); // includes mirroring; bImportingXML must be cleared first
637 SetLoadingMedium(bVal
);
640 rtl::Reference
<SvxForbiddenCharactersTable
> ScDocument::GetForbiddenCharacters()
642 return xForbiddenCharacters
;
645 void ScDocument::SetForbiddenCharacters(const rtl::Reference
<SvxForbiddenCharactersTable
>& rNew
)
647 xForbiddenCharacters
= rNew
;
649 EditEngine::SetForbiddenCharsTable( xForbiddenCharacters
);
651 pDrawLayer
->SetForbiddenCharsTable( xForbiddenCharacters
);
654 bool ScDocument::IsValidAsianCompression() const
656 return ( nAsianCompression
!= SC_ASIANCOMPRESSION_INVALID
);
659 sal_uInt8
ScDocument::GetAsianCompression() const
661 if ( nAsianCompression
== SC_ASIANCOMPRESSION_INVALID
)
664 return nAsianCompression
;
667 void ScDocument::SetAsianCompression(sal_uInt8 nNew
)
669 nAsianCompression
= nNew
;
671 pEditEngine
->SetAsianCompressionMode( nAsianCompression
);
673 pDrawLayer
->SetCharCompressType( nAsianCompression
);
676 bool ScDocument::IsValidAsianKerning() const
678 return ( nAsianKerning
!= SC_ASIANKERNING_INVALID
);
681 bool ScDocument::GetAsianKerning() const
683 if ( nAsianKerning
== SC_ASIANKERNING_INVALID
)
686 return static_cast<bool>(nAsianKerning
);
689 void ScDocument::SetAsianKerning(bool bNew
)
691 nAsianKerning
= (sal_uInt8
)bNew
;
693 pEditEngine
->SetKernAsianPunctuation( static_cast<bool>( nAsianKerning
) );
695 pDrawLayer
->SetKernAsianPunctuation( static_cast<bool>( nAsianKerning
) );
698 void ScDocument::ApplyAsianEditSettings( ScEditEngineDefaulter
& rEngine
)
700 EditEngine::SetForbiddenCharsTable( xForbiddenCharacters
);
701 rEngine
.SetAsianCompressionMode( GetAsianCompression() );
702 rEngine
.SetKernAsianPunctuation( GetAsianKerning() );
705 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */