summaryrefslogtreecommitdiff
path: root/svx/source/svdraw/svdetc.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'svx/source/svdraw/svdetc.cxx')
-rw-r--r--svx/source/svdraw/svdetc.cxx1118
1 files changed, 1118 insertions, 0 deletions
diff --git a/svx/source/svdraw/svdetc.cxx b/svx/source/svdraw/svdetc.cxx
new file mode 100644
index 000000000000..8a4245919821
--- /dev/null
+++ b/svx/source/svdraw/svdetc.cxx
@@ -0,0 +1,1118 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+#include "editeng/forbiddencharacterstable.hxx"
+#include <com/sun/star/embed/XEmbeddedObject.hpp>
+#include <com/sun/star/embed/EmbedStates.hpp>
+#include <svx/svdetc.hxx>
+#include "svditext.hxx"
+#include <svx/svdmodel.hxx>
+#include <svx/svdtrans.hxx>
+#include "svdglob.hxx"
+#include "svdstr.hrc"
+#include "svdviter.hxx"
+#include <svx/svdview.hxx>
+#include <svx/svdoutl.hxx>
+#include <vcl/bmpacc.hxx>
+#include <editeng/eeitem.hxx>
+#include <svl/itemset.hxx>
+#include <tools/config.hxx>
+#include <unotools/cacheoptions.hxx>
+#include <svl/whiter.hxx>
+#include <tools/bigint.hxx>
+#include "editeng/fontitem.hxx"
+#include <editeng/colritem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <svx/xgrad.hxx>
+#include <svx/xfillit0.hxx>
+#include <svx/xflclit.hxx>
+#include <svx/xflhtit.hxx>
+#include <svx/xbtmpit.hxx>
+#include <svx/xflgrit.hxx>
+#include <svx/svdoole2.hxx>
+#include <svl/itempool.hxx>
+#include <unotools/localedatawrapper.hxx>
+#include <com/sun/star/lang/Locale.hpp>
+#include <comphelper/processfactory.hxx>
+#include <i18npool/lang.h>
+#include <unotools/charclass.hxx>
+#include <unotools/syslocale.hxx>
+#include <svx/xflbckit.hxx>
+#include <svx/extrusionbar.hxx>
+#include <svx/fontworkbar.hxx>
+#include <vcl/svapp.hxx> //add CHINA001
+#include <svx/sdr/contact/viewcontact.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdotable.hxx>
+#include <svx/sdrhittesthelper.hxx>
+
+using namespace ::com::sun::star;
+
+/******************************************************************************
+* Globale Daten der DrawingEngine
+******************************************************************************/
+
+SdrGlobalData::SdrGlobalData() :
+ pSysLocale(NULL),
+ pCharClass(NULL),
+ pLocaleData(NULL),
+ pOutliner(NULL),
+ pDefaults(NULL),
+ pResMgr(NULL),
+ nExchangeFormat(0)
+{
+ //pSysLocale = new SvtSysLocale;
+ //pCharClass = pSysLocale->GetCharClassPtr();
+ //pLocaleData = pSysLocale->GetLocaleDataPtr();
+
+ svx::ExtrusionBar::RegisterInterface();
+ svx::FontworkBar::RegisterInterface();
+}
+
+SdrGlobalData::~SdrGlobalData()
+{
+ delete pOutliner;
+ delete pDefaults;
+ delete pResMgr;
+ //! do NOT delete pCharClass and pLocaleData
+ delete pSysLocale;
+}
+const SvtSysLocale* SdrGlobalData::GetSysLocale()
+{
+ if ( !pSysLocale )
+ pSysLocale = new SvtSysLocale;
+ return pSysLocale;
+}
+const CharClass* SdrGlobalData::GetCharClass()
+{
+ if ( !pCharClass )
+ pCharClass = GetSysLocale()->GetCharClassPtr();
+ return pCharClass;
+}
+const LocaleDataWrapper* SdrGlobalData::GetLocaleData()
+{
+ if ( !pLocaleData )
+ pLocaleData = GetSysLocale()->GetLocaleDataPtr();
+ return pLocaleData;
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+OLEObjCache::OLEObjCache()
+: Container( 0 )
+{
+ SvtCacheOptions aCacheOptions;
+
+ nSize = aCacheOptions.GetDrawingEngineOLE_Objects();
+ pTimer = new AutoTimer();
+ Link aLink = LINK(this, OLEObjCache, UnloadCheckHdl);
+
+ pTimer->SetTimeoutHdl(aLink);
+ pTimer->SetTimeout(20000);
+ pTimer->Start();
+
+ aLink.Call(pTimer);
+}
+
+OLEObjCache::~OLEObjCache()
+{
+ pTimer->Stop();
+ delete pTimer;
+}
+
+void OLEObjCache::UnloadOnDemand()
+{
+ if ( nSize < Count() )
+ {
+ // more objects than configured cache size try to remove objects
+ // of course not the freshly inserted one at nIndex=0
+ ULONG nCount2 = Count();
+ ULONG nIndex = nCount2-1;
+ while( nIndex && nCount2 > nSize )
+ {
+ SdrOle2Obj* pUnloadObj = (SdrOle2Obj*) GetObject(nIndex--);
+ if ( pUnloadObj )
+ {
+ try
+ {
+ // it is important to get object without reinitialization to avoid reentrance
+ uno::Reference< embed::XEmbeddedObject > xUnloadObj = pUnloadObj->GetObjRef_NoInit();
+
+ sal_Bool bUnload = SdrOle2Obj::CanUnloadRunningObj( xUnloadObj, pUnloadObj->GetAspect() );
+
+ // check whether the object can be unloaded before looking for the parent objects
+ if ( xUnloadObj.is() && bUnload )
+ {
+ uno::Reference< frame::XModel > xUnloadModel( xUnloadObj->getComponent(), uno::UNO_QUERY );
+ if ( xUnloadModel.is() )
+ {
+ for ( ULONG nCheckInd = 0; nCheckInd < Count(); nCheckInd++ )
+ {
+ SdrOle2Obj* pCacheObj = (SdrOle2Obj*) GetObject(nCheckInd);
+ if ( pCacheObj && pCacheObj != pUnloadObj )
+ {
+ uno::Reference< frame::XModel > xParentModel = pCacheObj->GetParentXModel();
+ if ( xUnloadModel == xParentModel )
+ bUnload = sal_False; // the object has running embedded objects
+ }
+ }
+ }
+ }
+
+ if ( bUnload && UnloadObj(pUnloadObj) )
+ // object was successfully unloaded
+ nCount2--;
+ }
+ catch( uno::Exception& )
+ {}
+ }
+ }
+ }
+}
+
+void OLEObjCache::SetSize(ULONG nNewSize)
+{
+ nSize = nNewSize;
+}
+
+void OLEObjCache::InsertObj(SdrOle2Obj* pObj)
+{
+ if ( Count() )
+ {
+ SdrOle2Obj* pExistingObj = (SdrOle2Obj*)GetObject( 0 );
+ if ( pObj == pExistingObj )
+ // the object is already on the top, nothing has to be changed
+ return;
+ }
+
+ // get the old position of the object to know whether it is already in container
+ ULONG nOldPos = GetPos( pObj );
+
+ // insert object into first position
+ Remove( nOldPos );
+ Insert(pObj, (ULONG) 0L);
+
+ if ( nOldPos == CONTAINER_ENTRY_NOTFOUND )
+ {
+ // a new object was inserted, recalculate the cache
+ UnloadOnDemand();
+ }
+}
+
+void OLEObjCache::RemoveObj(SdrOle2Obj* pObj)
+{
+ Remove(pObj);
+}
+
+BOOL OLEObjCache::UnloadObj(SdrOle2Obj* pObj)
+{
+ BOOL bUnloaded = FALSE;
+ if (pObj)
+ {
+ //#i80528# The old mechanism is completely useless, only taking into account if
+ // in all views the GrafDraft feature is used. This will nearly never have been the
+ // case since no one ever used this option.
+ //
+ // A much better (and working) criteria would be the VOC contact count.
+ // The quesion is what will happen whe i make it work now suddenly? I
+ // will try it for 2.4.
+ const sdr::contact::ViewContact& rViewContact = pObj->GetViewContact();
+ const bool bVisible(rViewContact.HasViewObjectContacts(true));
+
+ if(!bVisible)
+ {
+ bUnloaded = pObj->Unload();
+ }
+ }
+
+ return bUnloaded;
+}
+
+IMPL_LINK(OLEObjCache, UnloadCheckHdl, AutoTimer*, /*pTim*/)
+{
+ UnloadOnDemand();
+ return 0;
+}
+
+void ContainerSorter::DoSort(ULONG a, ULONG b) const
+{
+ ULONG nAnz=rCont.Count();
+ if (b>nAnz) b=nAnz;
+ if (b>0) b--;
+ if (a<b) ImpSubSort(a,b);
+}
+
+void ContainerSorter::Is1stLessThan2nd(const void* /*pElem1*/, const void* /*pElem2*/) const
+{
+}
+
+void ContainerSorter::ImpSubSort(long nL, long nR) const
+{
+ long i,j;
+ const void* pX;
+ void* pI;
+ void* pJ;
+ i=nL;
+ j=nR;
+ pX=rCont.GetObject((nL+nR)/2);
+ do {
+ pI=rCont.Seek(i);
+ while (pI!=pX && Compare(pI,pX)<0) { i++; pI=rCont.Next(); }
+ pJ=rCont.Seek(j);
+ while (pJ!=pX && Compare(pX,pJ)<0) { j--; pJ=rCont.Prev(); }
+ if (i<=j) {
+ rCont.Replace(pJ,i);
+ rCont.Replace(pI,j);
+ i++;
+ j--;
+ }
+ } while (i<=j);
+ if (nL<j) ImpSubSort(nL,j);
+ if (i<nR) ImpSubSort(i,nR);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+class ImpUShortContainerSorter: public ContainerSorter {
+public:
+ ImpUShortContainerSorter(Container& rNewCont): ContainerSorter(rNewCont) {}
+ virtual int Compare(const void* pElem1, const void* pElem2) const;
+};
+
+int ImpUShortContainerSorter::Compare(const void* pElem1, const void* pElem2) const
+{
+ USHORT n1=USHORT(ULONG(pElem1));
+ USHORT n2=USHORT(ULONG(pElem2));
+ return n1<n2 ? -1 : n1>n2 ? 1 : 0;
+}
+
+void UShortCont::Sort()
+{
+ ImpUShortContainerSorter aSorter(aArr);
+ aSorter.DoSort();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+class ImpClipMerk {
+ Region aClip;
+ FASTBOOL bClip;
+public:
+ ImpClipMerk(const OutputDevice& rOut): aClip(rOut.GetClipRegion()),bClip(rOut.IsClipRegion()) {}
+ void Restore(OutputDevice& rOut)
+ {
+ // Kein Clipping in die Metafileaufzeichnung
+ GDIMetaFile* pMtf=rOut.GetConnectMetaFile();
+ if (pMtf!=NULL && (!pMtf->IsRecord() || pMtf->IsPause())) pMtf=NULL;
+ if (pMtf!=NULL) pMtf->Pause(TRUE);
+ if (bClip) rOut.SetClipRegion(aClip);
+ else rOut.SetClipRegion();
+ if (pMtf!=NULL) pMtf->Pause(FALSE);
+ }
+};
+
+class ImpColorMerk {
+ Color aLineColor;
+ Color aFillColor;
+ Color aBckgrdColor;
+ Font aFont;
+public:
+ ImpColorMerk(const OutputDevice& rOut):
+ aLineColor( rOut.GetLineColor() ),
+ aFillColor( rOut.GetFillColor() ),
+ aBckgrdColor( rOut.GetBackground().GetColor() ),
+ aFont (rOut.GetFont()) {}
+
+ ImpColorMerk(const OutputDevice& rOut, USHORT nMode)
+ {
+ if ( (nMode & SDRHDC_SAVEPEN) == SDRHDC_SAVEPEN )
+ aLineColor = rOut.GetLineColor();
+
+ if ( (nMode & SDRHDC_SAVEBRUSH) == SDRHDC_SAVEBRUSH)
+ {
+ aFillColor = rOut.GetFillColor();
+ aBckgrdColor = rOut.GetBackground().GetColor();
+ }
+
+ if ( (nMode & SDRHDC_SAVEFONT) == SDRHDC_SAVEFONT)
+ aFont=rOut.GetFont();
+ }
+
+ void Restore(OutputDevice& rOut, USHORT nMode=SDRHDC_SAVEPENANDBRUSHANDFONT)
+ {
+ if ( (nMode & SDRHDC_SAVEPEN) == SDRHDC_SAVEPEN)
+ rOut.SetLineColor( aLineColor );
+
+ if ( (nMode & SDRHDC_SAVEBRUSH) == SDRHDC_SAVEBRUSH)
+ {
+ rOut.SetFillColor( aFillColor );
+ rOut.SetBackground( Wallpaper( aBckgrdColor ) );
+ }
+ if ((nMode & SDRHDC_SAVEFONT) ==SDRHDC_SAVEFONT)
+ {
+ if (!rOut.GetFont().IsSameInstance(aFont))
+ {
+ rOut.SetFont(aFont);
+ }
+ }
+ }
+
+ const Color& GetLineColor() const { return aLineColor; }
+};
+
+ImpSdrHdcMerk::ImpSdrHdcMerk(const OutputDevice& rOut, USHORT nNewMode, FASTBOOL bAutoMerk):
+ pFarbMerk(NULL),
+ pClipMerk(NULL),
+ pLineColorMerk(NULL),
+ nMode(nNewMode)
+{
+ if (bAutoMerk) Save(rOut);
+}
+
+ImpSdrHdcMerk::~ImpSdrHdcMerk()
+{
+ if (pFarbMerk!=NULL) delete pFarbMerk;
+ if (pClipMerk!=NULL) delete pClipMerk;
+ if (pLineColorMerk !=NULL) delete pLineColorMerk;
+}
+
+void ImpSdrHdcMerk::Save(const OutputDevice& rOut)
+{
+ if (pFarbMerk!=NULL)
+ {
+ delete pFarbMerk;
+ pFarbMerk=NULL;
+ }
+ if (pClipMerk!=NULL)
+ {
+ delete pClipMerk;
+ pClipMerk=NULL;
+ }
+ if (pLineColorMerk !=NULL)
+ {
+ delete pLineColorMerk ;
+ pLineColorMerk =NULL;
+ }
+ if ((nMode & SDRHDC_SAVECLIPPING) ==SDRHDC_SAVECLIPPING)
+ pClipMerk=new ImpClipMerk(rOut);
+
+ USHORT nCol=nMode & SDRHDC_SAVEPENANDBRUSHANDFONT;
+
+ if (nCol==SDRHDC_SAVEPEN)
+ pLineColorMerk=new Color( rOut.GetLineColor() );
+ else if (nCol==SDRHDC_SAVEPENANDBRUSHANDFONT)
+ pFarbMerk=new ImpColorMerk(rOut);
+ else if (nCol!=0)
+ pFarbMerk=new ImpColorMerk(rOut,nCol);
+}
+
+void ImpSdrHdcMerk::Restore(OutputDevice& rOut, USHORT nMask) const
+{
+ nMask&=nMode; // nur restaurieren, was auch gesichert wurde
+
+ if ((nMask & SDRHDC_SAVECLIPPING) ==SDRHDC_SAVECLIPPING && pClipMerk!=NULL)
+ pClipMerk->Restore(rOut);
+
+ USHORT nCol=nMask & SDRHDC_SAVEPENANDBRUSHANDFONT;
+
+ if (nCol==SDRHDC_SAVEPEN)
+ {
+ if (pLineColorMerk!=NULL)
+ rOut.SetLineColor(*pLineColorMerk);
+ else if (pFarbMerk!=NULL)
+ rOut.SetLineColor( pFarbMerk->GetLineColor() );
+ } else if (nCol!=0 && pFarbMerk!=NULL)
+ pFarbMerk->Restore(rOut,nCol);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrLinkList::Clear()
+{
+ unsigned nAnz=GetLinkCount();
+ for (unsigned i=0; i<nAnz; i++) {
+ delete (Link*)aList.GetObject(i);
+ }
+ aList.Clear();
+}
+
+unsigned SdrLinkList::FindEntry(const Link& rLink) const
+{
+ unsigned nAnz=GetLinkCount();
+ for (unsigned i=0; i<nAnz; i++) {
+ if (GetLink(i)==rLink) return i;
+ }
+ return 0xFFFF;
+}
+
+void SdrLinkList::InsertLink(const Link& rLink, unsigned nPos)
+{
+ unsigned nFnd=FindEntry(rLink);
+ if (nFnd==0xFFFF) {
+ if (rLink.IsSet()) {
+ aList.Insert(new Link(rLink),nPos);
+ } else {
+ DBG_ERROR("SdrLinkList::InsertLink(): Versuch, einen nicht gesetzten Link einzufuegen");
+ }
+ } else {
+ DBG_ERROR("SdrLinkList::InsertLink(): Link schon vorhanden");
+ }
+}
+
+void SdrLinkList::RemoveLink(const Link& rLink)
+{
+ unsigned nFnd=FindEntry(rLink);
+ if (nFnd!=0xFFFF) {
+ Link* pLink=(Link*)aList.Remove(nFnd);
+ delete pLink;
+ } else {
+ DBG_ERROR("SdrLinkList::RemoveLink(): Link nicht gefunden");
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// #98988# Re-implement GetDraftFillColor(...)
+
+FASTBOOL GetDraftFillColor(const SfxItemSet& rSet, Color& rCol)
+{
+ XFillStyle eFill=((XFillStyleItem&)rSet.Get(XATTR_FILLSTYLE)).GetValue();
+ FASTBOOL bRetval(FALSE);
+
+ switch(eFill)
+ {
+ case XFILL_SOLID:
+ {
+ rCol = ((XFillColorItem&)rSet.Get(XATTR_FILLCOLOR)).GetColorValue();
+ bRetval = TRUE;
+
+ break;
+ }
+ case XFILL_HATCH:
+ {
+ Color aCol1(((XFillHatchItem&)rSet.Get(XATTR_FILLHATCH)).GetHatchValue().GetColor());
+ Color aCol2(COL_WHITE);
+
+ // #97870# when hatch background is activated, use object fill color as hatch color
+ sal_Bool bFillHatchBackground = ((const XFillBackgroundItem&)(rSet.Get(XATTR_FILLBACKGROUND))).GetValue();
+ if(bFillHatchBackground)
+ {
+ aCol2 = ((const XFillColorItem&)(rSet.Get(XATTR_FILLCOLOR))).GetColorValue();
+ }
+
+ const basegfx::BColor aAverageColor(basegfx::average(aCol1.getBColor(), aCol2.getBColor()));
+ rCol = Color(aAverageColor);
+ bRetval = TRUE;
+
+ break;
+ }
+ case XFILL_GRADIENT: {
+ const XGradient& rGrad=((XFillGradientItem&)rSet.Get(XATTR_FILLGRADIENT)).GetGradientValue();
+ Color aCol1(rGrad.GetStartColor());
+ Color aCol2(rGrad.GetEndColor());
+ const basegfx::BColor aAverageColor(basegfx::average(aCol1.getBColor(), aCol2.getBColor()));
+ rCol = Color(aAverageColor);
+ bRetval = TRUE;
+
+ break;
+ }
+ case XFILL_BITMAP:
+ {
+ const Bitmap& rBitmap = ((XFillBitmapItem&)rSet.Get(XATTR_FILLBITMAP)).GetBitmapValue().GetBitmap();
+ const Size aSize(rBitmap.GetSizePixel());
+ const sal_uInt32 nWidth = aSize.Width();
+ const sal_uInt32 nHeight = aSize.Height();
+ Bitmap aBitmap(rBitmap);
+ BitmapReadAccess* pAccess = aBitmap.AcquireReadAccess();
+
+ if(pAccess && nWidth > 0 && nHeight > 0)
+ {
+ sal_uInt32 nRt(0L);
+ sal_uInt32 nGn(0L);
+ sal_uInt32 nBl(0L);
+ const sal_uInt32 nMaxSteps(8L);
+ const sal_uInt32 nXStep((nWidth > nMaxSteps) ? nWidth / nMaxSteps : 1L);
+ const sal_uInt32 nYStep((nHeight > nMaxSteps) ? nHeight / nMaxSteps : 1L);
+ sal_uInt32 nAnz(0L);
+
+ for(sal_uInt32 nY(0L); nY < nHeight; nY += nYStep)
+ {
+ for(sal_uInt32 nX(0L); nX < nWidth; nX += nXStep)
+ {
+ const BitmapColor& rCol2 = (pAccess->HasPalette())
+ ? pAccess->GetPaletteColor((BYTE)pAccess->GetPixel(nY, nX))
+ : pAccess->GetPixel(nY, nX);
+
+ nRt += rCol2.GetRed();
+ nGn += rCol2.GetGreen();
+ nBl += rCol2.GetBlue();
+ nAnz++;
+ }
+ }
+
+ nRt /= nAnz;
+ nGn /= nAnz;
+ nBl /= nAnz;
+
+ rCol = Color(UINT8(nRt), UINT8(nGn), UINT8(nBl));
+
+ bRetval = TRUE;
+ }
+
+ if(pAccess)
+ {
+ aBitmap.ReleaseAccess(pAccess);
+ }
+
+ break;
+ }
+ default: break;
+ }
+
+ return bRetval;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrEngineDefaults::SdrEngineDefaults():
+ aFontName( OutputDevice::GetDefaultFont( DEFAULTFONT_SERIF, LANGUAGE_SYSTEM, DEFAULTFONT_FLAGS_ONLYONE ).GetName() ),
+ eFontFamily(FAMILY_ROMAN),
+ aFontColor(COL_AUTO),
+ nFontHeight(847), // 847/100mm = ca. 24 Point
+ eMapUnit(MAP_100TH_MM),
+ aMapFraction(1,1)
+{
+}
+
+SdrEngineDefaults& SdrEngineDefaults::GetDefaults()
+{
+ SdrGlobalData& rGlobalData=GetSdrGlobalData();
+ if (rGlobalData.pDefaults==NULL) {
+ rGlobalData.pDefaults=new SdrEngineDefaults;
+ }
+ return *rGlobalData.pDefaults;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrEngineDefaults::LanguageHasChanged()
+{
+ SdrGlobalData& rGlobalData=GetSdrGlobalData();
+ if (rGlobalData.pResMgr!=NULL) {
+ delete rGlobalData.pResMgr;
+ rGlobalData.pResMgr=NULL;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrOutliner* SdrMakeOutliner( USHORT nOutlinerMode, SdrModel* pModel )
+{
+ //SdrEngineDefaults& rDefaults = SdrEngineDefaults::GetDefaults();
+
+ SfxItemPool* pPool = &pModel->GetItemPool();
+ SdrOutliner* pOutl = new SdrOutliner( pPool, nOutlinerMode );
+ pOutl->SetEditTextObjectPool( pPool );
+ pOutl->SetStyleSheetPool( (SfxStyleSheetPool*) pModel->GetStyleSheetPool() );
+ pOutl->SetDefTab( pModel->GetDefaultTabulator() );
+ pOutl->SetForbiddenCharsTable( pModel->GetForbiddenCharsTable() );
+ pOutl->SetAsianCompressionMode( pModel->GetCharCompressType() );
+ pOutl->SetKernAsianPunctuation( pModel->IsKernAsianPunctuation() );
+ pOutl->SetAddExtLeading( pModel->IsAddExtLeading() );
+
+ return pOutl;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+SdrLinkList& ImpGetUserMakeObjHdl()
+{
+ SdrGlobalData& rGlobalData=GetSdrGlobalData();
+ return rGlobalData.aUserMakeObjHdl;
+}
+
+SdrLinkList& ImpGetUserMakeObjUserDataHdl()
+{
+ SdrGlobalData& rGlobalData=GetSdrGlobalData();
+ return rGlobalData.aUserMakeObjUserDataHdl;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ResMgr* ImpGetResMgr()
+{
+ SdrGlobalData& rGlobalData = GetSdrGlobalData();
+
+ if(!rGlobalData.pResMgr)
+ {
+ ByteString aName("svx");
+ rGlobalData.pResMgr =
+ ResMgr::CreateResMgr( aName.GetBuffer(), Application::GetSettings().GetUILocale() );
+ }
+
+ return rGlobalData.pResMgr;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+String ImpGetResStr(sal_uInt16 nResID)
+{
+ return String(ResId(nResID, *ImpGetResMgr()));
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace sdr
+{
+String GetResourceString(sal_uInt16 nResID)
+{
+ return ImpGetResStr( nResID );
+}
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+BOOL SearchOutlinerItems(const SfxItemSet& rSet, BOOL bInklDefaults, BOOL* pbOnlyEE)
+{
+ BOOL bHas=FALSE;
+ BOOL bOnly=TRUE;
+ BOOL bLookOnly=pbOnlyEE!=NULL;
+ SfxWhichIter aIter(rSet);
+ USHORT nWhich=aIter.FirstWhich();
+ while (((bLookOnly && bOnly) || !bHas) && nWhich!=0) {
+ // bei bInklDefaults ist der gesamte Which-Range
+ // ausschlaggebend, ansonsten nur die gesetzten Items
+ // Disabled und DontCare wird als Loch im Which-Range betrachtet
+ SfxItemState eState=rSet.GetItemState(nWhich);
+ if ((eState==SFX_ITEM_DEFAULT && bInklDefaults) || eState==SFX_ITEM_SET) {
+ if (nWhich<EE_ITEMS_START || nWhich>EE_ITEMS_END) bOnly=FALSE;
+ else bHas=TRUE;
+ }
+ nWhich=aIter.NextWhich();
+ }
+ if (!bHas) bOnly=FALSE;
+ if (pbOnlyEE!=NULL) *pbOnlyEE=bOnly;
+ return bHas;
+}
+
+USHORT* RemoveWhichRange(const USHORT* pOldWhichTable, USHORT nRangeBeg, USHORT nRangeEnd)
+{
+ // insgesamt sind 6 Faelle moeglich (je Range):
+ // [Beg..End] zu entfernender Range
+ // [b..e] [b..e] [b..e] Fall 1,3,2: egal, ganz weg, egal + Ranges
+ // [b........e] [b........e] Fall 4,5 : Bereich verkleinern | in
+ // [b......................e] Fall 6 : Splitting + pOldWhichTable
+ USHORT nAnz=0;
+ while (pOldWhichTable[nAnz]!=0) nAnz++;
+ nAnz++; // nAnz muesste nun in jedem Fall eine ungerade Zahl sein (0 am Ende des Arrays)
+ DBG_ASSERT((nAnz&1)==1,"Joe: RemoveWhichRange: WhichTable hat keine ungerade Anzahl von Eintraegen");
+ USHORT nAlloc=nAnz;
+ // benoetigte Groesse des neuen Arrays ermitteln
+ USHORT nNum=nAnz-1;
+ while (nNum!=0) {
+ nNum-=2;
+ USHORT nBeg=pOldWhichTable[nNum];
+ USHORT nEnd=pOldWhichTable[nNum+1];
+ if (nEnd<nRangeBeg) /*nCase=1*/ ;
+ else if (nBeg>nRangeEnd) /* nCase=2 */ ;
+ else if (nBeg>=nRangeBeg && nEnd<=nRangeEnd) /* nCase=3 */ nAlloc-=2;
+ else if (nEnd<=nRangeEnd) /* nCase=4 */;
+ else if (nBeg>=nRangeBeg) /* nCase=5*/ ;
+ else /* nCase=6 */ nAlloc+=2;
+ }
+
+ USHORT* pNewWhichTable=new USHORT[nAlloc];
+ memcpy(pNewWhichTable,pOldWhichTable,nAlloc*sizeof(USHORT));
+ pNewWhichTable[nAlloc-1]=0; // im Falle 3 fehlt die 0 am Ende
+ // nun die unerwuenschten Ranges entfernen
+ nNum=nAlloc-1;
+ while (nNum!=0) {
+ nNum-=2;
+ USHORT nBeg=pNewWhichTable[nNum];
+ USHORT nEnd=pNewWhichTable[nNum+1];
+ unsigned nCase=0;
+ if (nEnd<nRangeBeg) nCase=1;
+ else if (nBeg>nRangeEnd) nCase=2;
+ else if (nBeg>=nRangeBeg && nEnd<=nRangeEnd) nCase=3;
+ else if (nEnd<=nRangeEnd) nCase=4;
+ else if (nBeg>=nRangeBeg) nCase=5;
+ else nCase=6;
+ switch (nCase) {
+ case 3: {
+ unsigned nTailBytes=(nAnz-(nNum+2))*sizeof(USHORT);
+ memcpy(&pNewWhichTable[nNum],&pNewWhichTable[nNum+2],nTailBytes);
+ nAnz-=2; // Merken: Array hat sich verkleinert
+ } break;
+ case 4: pNewWhichTable[nNum+1]=nRangeBeg-1; break;
+ case 5: pNewWhichTable[nNum]=nRangeEnd+1; break;
+ case 6: {
+ unsigned nTailBytes=(nAnz-(nNum+2))*sizeof(USHORT);
+ memcpy(&pNewWhichTable[nNum+4],&pNewWhichTable[nNum+2],nTailBytes);
+ nAnz+=2; // Merken: Array hat sich vergroessert
+ pNewWhichTable[nNum+2]=nRangeEnd+1;
+ pNewWhichTable[nNum+3]=pNewWhichTable[nNum+1];
+ pNewWhichTable[nNum+1]=nRangeBeg-1;
+ } break;
+ } // switch
+ }
+ return pNewWhichTable;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SvdProgressInfo::SvdProgressInfo( Link *_pLink )
+{
+ DBG_ASSERT(_pLink!=NULL,"SvdProgressInfo(): Kein Link angegeben!!");
+
+ pLink = _pLink;
+ nSumActionCount = 0;
+ nSumCurAction = 0;
+
+ nObjCount = 0;
+ nCurObj = 0;
+
+ nActionCount = 0;
+ nCurAction = 0;
+
+ nInsertCount = 0;
+ nCurInsert = 0;
+}
+
+void SvdProgressInfo::Init( ULONG _nSumActionCount, ULONG _nObjCount )
+{
+ nSumActionCount = _nSumActionCount;
+ nObjCount = _nObjCount;
+}
+
+BOOL SvdProgressInfo::ReportActions( ULONG nAnzActions )
+{
+ nSumCurAction += nAnzActions;
+ nCurAction += nAnzActions;
+ if(nCurAction > nActionCount)
+ nCurAction = nActionCount;
+
+ return pLink->Call(NULL) == 1L;
+}
+
+BOOL SvdProgressInfo::ReportInserts( ULONG nAnzInserts )
+{
+ nSumCurAction += nAnzInserts;
+ nCurInsert += nAnzInserts;
+
+ return pLink->Call(NULL) == 1L;
+}
+
+BOOL SvdProgressInfo::ReportRescales( ULONG nAnzRescales )
+{
+ nSumCurAction += nAnzRescales;
+ return pLink->Call(NULL) == 1L;
+}
+
+void SvdProgressInfo::SetActionCount( ULONG _nActionCount )
+{
+ nActionCount = _nActionCount;
+}
+
+void SvdProgressInfo::SetInsertCount( ULONG _nInsertCount )
+{
+ nInsertCount = _nInsertCount;
+}
+
+BOOL SvdProgressInfo::SetNextObject()
+{
+ nActionCount = 0;
+ nCurAction = 0;
+
+ nInsertCount = 0;
+ nCurInsert = 0;
+
+ nCurObj++;
+ return ReportActions(0);
+}
+
+void SvdProgressInfo::ReportError()
+{
+ pLink->Call((void *)1L);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// #i101872# isolate GetTextEditBackgroundColor to tooling; it woll anyways only be used as long
+// as text edit is not running on overlay
+
+namespace
+{
+ bool impGetSdrObjListFillColor(
+ const SdrObjList& rList,
+ const Point& rPnt,
+ const SdrPageView& rTextEditPV,
+ const SetOfByte& rVisLayers,
+ Color& rCol)
+ {
+ if(!rList.GetModel())
+ return false;
+
+ bool bRet(false);
+ bool bMaster(rList.GetPage() ? rList.GetPage()->IsMasterPage() : false);
+
+ for(ULONG no(rList.GetObjCount()); !bRet && no > 0; )
+ {
+ no--;
+ SdrObject* pObj = rList.GetObj(no);
+ SdrObjList* pOL = pObj->GetSubList();
+
+ if(pOL)
+ {
+ // group object
+ bRet = impGetSdrObjListFillColor(*pOL, rPnt, rTextEditPV, rVisLayers, rCol);
+ }
+ else
+ {
+ SdrTextObj* pText = dynamic_cast< SdrTextObj * >(pObj);
+
+ // #108867# Exclude zero master page object (i.e. background shape) from color query
+ if(pText
+ && pObj->IsClosedObj()
+ && (!bMaster || (!pObj->IsNotVisibleAsMaster() && 0 != no))
+ && pObj->GetCurrentBoundRect().IsInside(rPnt)
+ && !pText->IsHideContour()
+ && SdrObjectPrimitiveHit(*pObj, rPnt, 0, rTextEditPV, &rVisLayers, false))
+ {
+ bRet = GetDraftFillColor(pObj->GetMergedItemSet(), rCol);
+ }
+ }
+ }
+
+ return bRet;
+ }
+
+ bool impGetSdrPageFillColor(
+ const SdrPage& rPage,
+ const Point& rPnt,
+ const SdrPageView& rTextEditPV,
+ const SetOfByte& rVisLayers,
+ Color& rCol,
+ bool bSkipBackgroundShape)
+ {
+ if(!rPage.GetModel())
+ return false;
+
+ bool bRet(impGetSdrObjListFillColor(rPage, rPnt, rTextEditPV, rVisLayers, rCol));
+
+ if(!bRet && !rPage.IsMasterPage())
+ {
+ if(rPage.TRG_HasMasterPage())
+ {
+ SetOfByte aSet(rVisLayers);
+ aSet &= rPage.TRG_GetMasterPageVisibleLayers();
+ SdrPage& rMasterPage = rPage.TRG_GetMasterPage();
+
+ // #108867# Don't fall back to background shape on
+ // master pages. This is later handled by
+ // GetBackgroundColor, and is necessary to cater for
+ // the silly ordering: 1. shapes, 2. master page
+ // shapes, 3. page background, 4. master page
+ // background.
+ bRet = impGetSdrPageFillColor(rMasterPage, rPnt, rTextEditPV, aSet, rCol, true);
+ }
+ }
+
+ // #108867# Only now determine background color from background shapes
+ if(!bRet && !bSkipBackgroundShape)
+ {
+ rCol = rPage.GetPageBackgroundColor();
+ return true;
+ }
+
+ return bRet;
+ }
+
+ Color impCalcBackgroundColor(
+ const Rectangle& rArea,
+ const SdrPageView& rTextEditPV,
+ const SdrPage& rPage)
+ {
+ svtools::ColorConfig aColorConfig;
+ Color aBackground(aColorConfig.GetColorValue(svtools::DOCCOLOR).nColor);
+ const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+
+ if(!rStyleSettings.GetHighContrastMode())
+ {
+ // search in page
+ const USHORT SPOTCOUNT(5);
+ Point aSpotPos[SPOTCOUNT];
+ Color aSpotColor[SPOTCOUNT];
+ ULONG nHeight( rArea.GetSize().Height() );
+ ULONG nWidth( rArea.GetSize().Width() );
+ ULONG nWidth14 = nWidth / 4;
+ ULONG nHeight14 = nHeight / 4;
+ ULONG nWidth34 = ( 3 * nWidth ) / 4;
+ ULONG nHeight34 = ( 3 * nHeight ) / 4;
+
+ USHORT i;
+ for ( i = 0; i < SPOTCOUNT; i++ )
+ {
+ // five spots are used
+ switch ( i )
+ {
+ case 0 :
+ {
+ // Center-Spot
+ aSpotPos[i] = rArea.Center();
+ }
+ break;
+
+ case 1 :
+ {
+ // TopLeft-Spot
+ aSpotPos[i] = rArea.TopLeft();
+ aSpotPos[i].X() += nWidth14;
+ aSpotPos[i].Y() += nHeight14;
+ }
+ break;
+
+ case 2 :
+ {
+ // TopRight-Spot
+ aSpotPos[i] = rArea.TopLeft();
+ aSpotPos[i].X() += nWidth34;
+ aSpotPos[i].Y() += nHeight14;
+ }
+ break;
+
+ case 3 :
+ {
+ // BottomLeft-Spot
+ aSpotPos[i] = rArea.TopLeft();
+ aSpotPos[i].X() += nWidth14;
+ aSpotPos[i].Y() += nHeight34;
+ }
+ break;
+
+ case 4 :
+ {
+ // BottomRight-Spot
+ aSpotPos[i] = rArea.TopLeft();
+ aSpotPos[i].X() += nWidth34;
+ aSpotPos[i].Y() += nHeight34;
+ }
+ break;
+
+ }
+
+ aSpotColor[i] = Color( COL_WHITE );
+ impGetSdrPageFillColor(rPage, aSpotPos[i], rTextEditPV, rTextEditPV.GetVisibleLayers(), aSpotColor[i], false);
+ }
+
+ USHORT aMatch[SPOTCOUNT];
+
+ for ( i = 0; i < SPOTCOUNT; i++ )
+ {
+ // were same spot colors found?
+ aMatch[i] = 0;
+
+ for ( USHORT j = 0; j < SPOTCOUNT; j++ )
+ {
+ if( j != i )
+ {
+ if( aSpotColor[i] == aSpotColor[j] )
+ {
+ aMatch[i]++;
+ }
+ }
+ }
+ }
+
+ // highest weight to center spot
+ aBackground = aSpotColor[0];
+
+ for ( USHORT nMatchCount = SPOTCOUNT - 1; nMatchCount > 1; nMatchCount-- )
+ {
+ // which spot color was found most?
+ for ( i = 0; i < SPOTCOUNT; i++ )
+ {
+ if( aMatch[i] == nMatchCount )
+ {
+ aBackground = aSpotColor[i];
+ nMatchCount = 1; // break outer for-loop
+ break;
+ }
+ }
+ }
+ }
+
+ return aBackground;
+ }
+} // end of anonymous namespace
+
+Color GetTextEditBackgroundColor(const SdrObjEditView& rView)
+{
+ svtools::ColorConfig aColorConfig;
+ Color aBackground(aColorConfig.GetColorValue(svtools::DOCCOLOR).nColor);
+ const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+
+ if(!rStyleSettings.GetHighContrastMode())
+ {
+ bool bFound(false);
+ SdrTextObj* pText = dynamic_cast< SdrTextObj * >(rView.GetTextEditObject());
+
+ if(pText && pText->IsClosedObj())
+ {
+ ::sdr::table::SdrTableObj* pTable = dynamic_cast< ::sdr::table::SdrTableObj * >( pText );
+
+ if( pTable )
+ bFound = GetDraftFillColor(pTable->GetActiveCellItemSet(), aBackground );
+
+ if( !bFound )
+ bFound=GetDraftFillColor(pText->GetMergedItemSet(), aBackground);
+ }
+
+ if(!bFound && pText)
+ {
+ SdrPageView* pTextEditPV = rView.GetTextEditPageView();
+
+ if(pTextEditPV)
+ {
+ Point aPvOfs(pText->GetTextEditOffset());
+ const SdrPage* pPg = pTextEditPV->GetPage();
+
+ if(pPg)
+ {
+ Rectangle aSnapRect( pText->GetSnapRect() );
+ aSnapRect.Move(aPvOfs.X(), aPvOfs.Y());
+
+ return impCalcBackgroundColor(aSnapRect, *pTextEditPV, *pPg);
+ }
+ }
+ }
+ }
+
+ return aBackground;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// eof