diff options
Diffstat (limited to 'sc/source/ui/app')
-rw-r--r-- | sc/source/ui/app/client.cxx | 256 | ||||
-rw-r--r-- | sc/source/ui/app/drwtrans.cxx | 804 | ||||
-rw-r--r-- | sc/source/ui/app/inputhdl.cxx | 3793 | ||||
-rw-r--r-- | sc/source/ui/app/inputwin.cxx | 1818 | ||||
-rw-r--r-- | sc/source/ui/app/lnktrans.cxx | 97 | ||||
-rw-r--r-- | sc/source/ui/app/makefile.mk | 73 | ||||
-rw-r--r-- | sc/source/ui/app/msgpool.cxx | 123 | ||||
-rw-r--r-- | sc/source/ui/app/rfindlst.cxx | 67 | ||||
-rw-r--r-- | sc/source/ui/app/scdll.cxx | 422 | ||||
-rw-r--r-- | sc/source/ui/app/scmod.cxx | 2297 | ||||
-rw-r--r-- | sc/source/ui/app/scmod2.cxx | 107 | ||||
-rw-r--r-- | sc/source/ui/app/seltrans.cxx | 449 | ||||
-rw-r--r-- | sc/source/ui/app/template.cxx | 79 | ||||
-rw-r--r-- | sc/source/ui/app/transobj.cxx | 869 | ||||
-rw-r--r-- | sc/source/ui/app/typemap.cxx | 135 | ||||
-rw-r--r-- | sc/source/ui/app/uiitems.cxx | 737 | ||||
-rw-r--r-- | sc/source/ui/app/wtcdummy.cxx | 65 |
17 files changed, 12191 insertions, 0 deletions
diff --git a/sc/source/ui/app/client.cxx b/sc/source/ui/app/client.cxx new file mode 100644 index 000000000000..b1cb325ceb69 --- /dev/null +++ b/sc/source/ui/app/client.cxx @@ -0,0 +1,256 @@ +/************************************************************************* + * + * 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_sc.hxx" + +// INCLUDE --------------------------------------------------------------- + + +#include <com/sun/star/embed/XEmbeddedObject.hpp> +#include <com/sun/star/embed/NoVisualAreaSizeException.hpp> + +#include <toolkit/helper/vclunohelper.hxx> +#include <sfx2/objsh.hxx> +#include <sfx2/viewfrm.hxx> +#include <sot/sotref.hxx> +#include <svx/svditer.hxx> +#include <svx/svdobj.hxx> +#include <svx/svdmodel.hxx> +#include <svx/svdpage.hxx> +#include <svx/svdoole2.hxx> +#include <svx/svdview.hxx> +#include <svx/svdograf.hxx> +#include <svtools/embedhlp.hxx> + +#include "client.hxx" +#include "tabvwsh.hxx" +#include "docsh.hxx" + +using namespace com::sun::star; + +//------------------------------------------------------------------------ + +ScClient::ScClient( ScTabViewShell* pViewShell, Window* pDraw, SdrModel* pSdrModel, SdrOle2Obj* pObj ) : + SfxInPlaceClient( pViewShell, pDraw, pObj->GetAspect() ), + pModel( pSdrModel ), + pGrafEdit( 0 ) +{ + SetObject( pObj->GetObjRef() ); +} + +__EXPORT ScClient::~ScClient() +{ +} + +SdrOle2Obj* ScClient::GetDrawObj() +{ + uno::Reference < embed::XEmbeddedObject > xObj = GetObject(); + SdrOle2Obj* pOle2Obj = NULL; + String aName = GetViewShell()->GetObjectShell()->GetEmbeddedObjectContainer().GetEmbeddedObjectName( xObj ); + + USHORT nPages = pModel->GetPageCount(); + for (USHORT nPNr=0; nPNr<nPages && !pOle2Obj; nPNr++) + { + SdrPage* pPage = pModel->GetPage(nPNr); + SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS ); + SdrObject* pObject = aIter.Next(); + while (pObject && !pOle2Obj) + { + if ( pObject->GetObjIdentifier() == OBJ_OLE2 ) + { + // name from InfoObject is PersistName + if ( ((SdrOle2Obj*)pObject)->GetPersistName() == aName ) + pOle2Obj = (SdrOle2Obj*)pObject; + } + pObject = aIter.Next(); + } + } + return pOle2Obj; +} + +void __EXPORT ScClient::RequestNewObjectArea( Rectangle& aLogicRect ) +{ + SfxViewShell* pSfxViewSh = GetViewShell(); + ScTabViewShell* pViewSh = PTR_CAST( ScTabViewShell, pSfxViewSh ); + if (!pViewSh) + { + DBG_ERROR("Wrong ViewShell"); + return; + } + + Rectangle aOldRect = GetObjArea(); + SdrOle2Obj* pDrawObj = GetDrawObj(); + if ( pDrawObj ) + { + if ( pDrawObj->IsResizeProtect() ) + aLogicRect.SetSize( aOldRect.GetSize() ); + + if ( pDrawObj->IsMoveProtect() ) + aLogicRect.SetPos( aOldRect.TopLeft() ); + } + + USHORT nTab = pViewSh->GetViewData()->GetTabNo(); + SdrPage* pPage = pModel->GetPage(static_cast<sal_uInt16>(static_cast<sal_Int16>(nTab))); + if ( pPage && aLogicRect != aOldRect ) + { + Point aPos; + Size aSize = pPage->GetSize(); + if ( aSize.Width() < 0 ) + { + aPos.X() = aSize.Width() + 1; // negative + aSize.Width() = -aSize.Width(); // positive + } + Rectangle aPageRect( aPos, aSize ); + + if (aLogicRect.Right() > aPageRect.Right()) + { + long nDiff = aLogicRect.Right() - aPageRect.Right(); + aLogicRect.Left() -= nDiff; + aLogicRect.Right() -= nDiff; + } + if (aLogicRect.Bottom() > aPageRect.Bottom()) + { + long nDiff = aLogicRect.Bottom() - aPageRect.Bottom(); + aLogicRect.Top() -= nDiff; + aLogicRect.Bottom() -= nDiff; + } + + if (aLogicRect.Left() < aPageRect.Left()) + { + long nDiff = aLogicRect.Left() - aPageRect.Left(); + aLogicRect.Right() -= nDiff; + aLogicRect.Left() -= nDiff; + } + if (aLogicRect.Top() < aPageRect.Top()) + { + long nDiff = aLogicRect.Top() - aPageRect.Top(); + aLogicRect.Bottom() -= nDiff; + aLogicRect.Top() -= nDiff; + } + } +} + +void __EXPORT ScClient::ObjectAreaChanged() +{ + SfxViewShell* pSfxViewSh = GetViewShell(); + ScTabViewShell* pViewSh = PTR_CAST( ScTabViewShell, pSfxViewSh ); + if (!pViewSh) + { + DBG_ERROR("Wrong ViewShell"); + return; + } + + // Position und Groesse ins Dokument uebernehmen + SdrOle2Obj* pDrawObj = GetDrawObj(); + if (pDrawObj) + { + pDrawObj->SetLogicRect( GetScaledObjArea() ); + + // set document modified (SdrModel::SetChanged is not used) + // TODO/LATER: is there a reason that this code is not executed in Draw? +// SfxViewShell* pSfxViewSh = GetViewShell(); +// ScTabViewShell* pViewSh = PTR_CAST( ScTabViewShell, pSfxViewSh ); + if (pViewSh) + pViewSh->GetViewData()->GetDocShell()->SetDrawModified(); + } + + if (pDrawObj) + pViewSh->ScrollToObject( pDrawObj ); +} + +void __EXPORT ScClient::ViewChanged() +{ + if ( GetAspect() == embed::Aspects::MSOLE_ICON ) + { + // the iconified object seems not to need such a scaling handling + // since the replacement image and the size a completely controlled by the container + // TODO/LATER: when the icon exchange is implemented the scaling handling might be required again here + + return; + } + + uno::Reference < embed::XEmbeddedObject > xObj = GetObject(); + + // TODO/LEAN: working with Visual Area can switch object to running state + awt::Size aSz; + try { + aSz = xObj->getVisualAreaSize( GetAspect() ); + } catch ( embed::NoVisualAreaSizeException& ) + { + DBG_ERROR("The visual area size must be available!\n"); + } + + MapUnit aMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( GetAspect() ) ); + Size aVisSize = OutputDevice::LogicToLogic( Size( aSz.Width, aSz.Height ), aMapUnit, MAP_100TH_MM ); + + // Groesse ins Dokument uebernehmen + SdrOle2Obj* pDrawObj = GetDrawObj(); + if (pDrawObj) + { + Rectangle aLogicRect = pDrawObj->GetLogicRect(); + Fraction aFractX = GetScaleWidth(); + Fraction aFractY = GetScaleHeight(); + aFractX *= aVisSize.Width(); + aFractY *= aVisSize.Height(); + aVisSize = Size( (long) aFractX, (long) aFractY ); // skaliert fuer Draw-Model + + // pClientData->SetObjArea vor pDrawObj->SetLogicRect, damit keine + // falschen Skalierungen ausgerechnet werden: + //Rectangle aObjArea = aLogicRect; + //aObjArea.SetSize( aVisSize ); // Dokument-Groesse vom Server + //SetObjArea( aObjArea ); + + SfxViewShell* pSfxViewSh = GetViewShell(); + ScTabViewShell* pViewSh = PTR_CAST( ScTabViewShell, pSfxViewSh ); + if ( pViewSh ) + { + Window* pWin = pViewSh->GetActiveWin(); + if ( pWin->LogicToPixel( aVisSize ) != pWin->LogicToPixel( aLogicRect.GetSize() ) ) + { + aLogicRect.SetSize( aVisSize ); + pDrawObj->SetLogicRect( aLogicRect ); + + // set document modified (SdrModel::SetChanged is not used) + pViewSh->GetViewData()->GetDocShell()->SetDrawModified(); + } + } + } +} + +void __EXPORT ScClient::MakeVisible() +{ + SdrOle2Obj* pDrawObj = GetDrawObj(); + if (pDrawObj) + { + SfxViewShell* pSfxViewSh = GetViewShell(); + ScTabViewShell* pViewSh = PTR_CAST( ScTabViewShell, pSfxViewSh ); + if (pViewSh) + pViewSh->ScrollToObject( pDrawObj ); + } +} + diff --git a/sc/source/ui/app/drwtrans.cxx b/sc/source/ui/app/drwtrans.cxx new file mode 100644 index 000000000000..b256233d7394 --- /dev/null +++ b/sc/source/ui/app/drwtrans.cxx @@ -0,0 +1,804 @@ +/************************************************************************* + * + * 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_sc.hxx" + +// INCLUDE --------------------------------------------------------------- + + +#include <com/sun/star/embed/XTransactedObject.hpp> +#include <com/sun/star/embed/XEmbedPersist.hpp> +#include <com/sun/star/uno/Exception.hpp> + +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/beans/XPropertySetInfo.hpp> +#include <com/sun/star/form/FormButtonType.hpp> +#include <toolkit/helper/vclunohelper.hxx> +#include <unotools/streamwrap.hxx> + +#include <svx/unomodel.hxx> +#include <unotools/tempfile.hxx> +#include <unotools/ucbstreamhelper.hxx> +#include <comphelper/storagehelper.hxx> + +#include <svtools/embedtransfer.hxx> +#include <sot/storage.hxx> +#include <vcl/virdev.hxx> +#include <svx/fmglob.hxx> +#include <svx/svditer.hxx> +#include <svx/svdograf.hxx> +#include <svx/svdoole2.hxx> +#include <svx/svdouno.hxx> +#include <svx/svdpage.hxx> +#include <svx/svdxcgv.hxx> +#include <sfx2/docfile.hxx> +#include <svl/itempool.hxx> +#include <svl/urlbmk.hxx> +#include <tools/urlobj.hxx> +#include <vos/mutex.hxx> + +#include "drwtrans.hxx" +#include "docsh.hxx" +#include "drwlayer.hxx" +#include "drawview.hxx" +#include "viewdata.hxx" +#include "scmod.hxx" + +// #108584# +#include "scitems.hxx" + +// #108584# +#include <editeng/eeitem.hxx> + +// #108584# +#include <editeng/fhgtitem.hxx> +#include <vcl/svapp.hxx> + +using namespace com::sun::star; + +// ----------------------------------------------------------------------- + +#define SCDRAWTRANS_TYPE_EMBOBJ 1 +#define SCDRAWTRANS_TYPE_DRAWMODEL 2 +#define SCDRAWTRANS_TYPE_DOCUMENT 3 + +// ----------------------------------------------------------------------- + +// ----------------------------------------------------------------------- + +ScDrawTransferObj::ScDrawTransferObj( SdrModel* pClipModel, ScDocShell* pContainerShell, + const TransferableObjectDescriptor& rDesc ) : + pModel( pClipModel ), + aObjDesc( rDesc ), + pBookmark( NULL ), + bGraphic( FALSE ), + bGrIsBit( FALSE ), + bOleObj( FALSE ), + pDragSourceView( NULL ), + nDragSourceFlags( 0 ), + bDragWasInternal( FALSE ), + nSourceDocID( 0 ) +{ + // + // check what kind of objects are contained + // + + SdrPage* pPage = pModel->GetPage(0); + if (pPage) + { + SdrObjListIter aIter( *pPage, IM_FLAT ); + SdrObject* pObject = aIter.Next(); + if (pObject && !aIter.Next()) // exactly one object? + { + // + // OLE object + // + + UINT16 nSdrObjKind = pObject->GetObjIdentifier(); + if (nSdrObjKind == OBJ_OLE2) + { + // if object has no persistence it must be copied as a part of document + try + { + uno::Reference< embed::XEmbedPersist > xPersObj( ((SdrOle2Obj*)pObject)->GetObjRef(), uno::UNO_QUERY ); + if ( xPersObj.is() && xPersObj->hasEntry() ) + bOleObj = TRUE; + } + catch( uno::Exception& ) + {} + // aOleData is initialized later + } + + // + // Graphic object + // + + if (nSdrObjKind == OBJ_GRAF) + { + bGraphic = TRUE; + if ( ((SdrGrafObj*)pObject)->GetGraphic().GetType() == GRAPHIC_BITMAP ) + bGrIsBit = TRUE; + } + + // + // URL button + // + + SdrUnoObj* pUnoCtrl = PTR_CAST(SdrUnoObj, pObject); + if (pUnoCtrl && FmFormInventor == pUnoCtrl->GetObjInventor()) + { + uno::Reference<awt::XControlModel> xControlModel = pUnoCtrl->GetUnoControlModel(); + DBG_ASSERT( xControlModel.is(), "uno control without model" ); + if ( xControlModel.is() ) + { + uno::Reference< beans::XPropertySet > xPropSet( xControlModel, uno::UNO_QUERY ); + uno::Reference< beans::XPropertySetInfo > xInfo = xPropSet->getPropertySetInfo(); + + rtl::OUString sPropButtonType = rtl::OUString::createFromAscii( "ButtonType" ); + rtl::OUString sPropTargetURL = rtl::OUString::createFromAscii( "TargetURL" ); + rtl::OUString sPropLabel = rtl::OUString::createFromAscii( "Label" ); + + if(xInfo->hasPropertyByName( sPropButtonType )) + { + uno::Any aAny = xPropSet->getPropertyValue( sPropButtonType ); + form::FormButtonType eTmp; + if ( (aAny >>= eTmp) && eTmp == form::FormButtonType_URL ) + { + // URL + if(xInfo->hasPropertyByName( sPropTargetURL )) + { + aAny = xPropSet->getPropertyValue( sPropTargetURL ); + rtl::OUString sTmp; + if ( (aAny >>= sTmp) && sTmp.getLength() ) + { + String aUrl = sTmp; + String aAbs; + const SfxMedium* pMedium; + if (pContainerShell && (pMedium = pContainerShell->GetMedium()) != NULL) + { + bool bWasAbs = true; + aAbs = pMedium->GetURLObject().smartRel2Abs( aUrl, bWasAbs ). + GetMainURL(INetURLObject::NO_DECODE); + // full path as stored INetBookmark must be encoded + } + else + aAbs = aUrl; + + // Label + String aLabel; + if(xInfo->hasPropertyByName( sPropLabel )) + { + aAny = xPropSet->getPropertyValue( sPropLabel ); + if ( (aAny >>= sTmp) && sTmp.getLength() ) + { + aLabel = String(sTmp); + } + } + pBookmark = new INetBookmark( aAbs, aLabel ); + } + } + } + } + } + } + } + } + + // + // get size for object descriptor + // + + // #i71538# use complete SdrViews + // SdrExchangeView aView(pModel); + SdrView aView(pModel); + SdrPageView* pPv = aView.ShowSdrPage(aView.GetModel()->GetPage(0)); + aView.MarkAllObj(pPv); + aSrcSize = aView.GetAllMarkedRect().GetSize(); + + if ( bOleObj ) // single OLE object + { + SdrOle2Obj* pObj = GetSingleObject(); + if ( pObj && pObj->GetObjRef().is() ) + SvEmbedTransferHelper::FillTransferableObjectDescriptor( aObjDesc, pObj->GetObjRef(), pObj->GetGraphic(), pObj->GetAspect() ); + } + + aObjDesc.maSize = aSrcSize; + PrepareOLE( aObjDesc ); + + // + // remember a unique ID of the source document + // + if ( pContainerShell ) + { + const ScDocument* pDoc = pContainerShell->GetDocument(); + if ( pDoc ) + nSourceDocID = pDoc->GetDocumentID(); + } +} + +ScDrawTransferObj::~ScDrawTransferObj() +{ + Application::GetSolarMutex().acquire(); //! ??? + + ScModule* pScMod = SC_MOD(); + if ( pScMod->GetClipData().pDrawClipboard == this ) + { + DBG_ERROR("ScDrawTransferObj wasn't released"); + pScMod->SetClipObject( NULL, NULL ); + } + if ( pScMod->GetDragData().pDrawTransfer == this ) + { + DBG_ERROR("ScDrawTransferObj wasn't released"); + pScMod->ResetDragObject(); + } + + aOleData = TransferableDataHelper(); // clear before releasing the mutex + aDocShellRef.Clear(); + + delete pModel; + aDrawPersistRef.Clear(); // after the model + + delete pBookmark; + delete pDragSourceView; + + Application::GetSolarMutex().release(); //! ??? +} + +// static +ScDrawTransferObj* ScDrawTransferObj::GetOwnClipboard( Window* ) +{ + ScDrawTransferObj* pObj = SC_MOD()->GetClipData().pDrawClipboard; + return pObj; +} + +BOOL lcl_HasOnlyControls( SdrModel* pModel ) +{ + BOOL bOnlyControls = FALSE; // default if there are no objects + + if ( pModel ) + { + SdrPage* pPage = pModel->GetPage(0); + if (pPage) + { + SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS ); + SdrObject* pObj = aIter.Next(); + if ( pObj ) + { + bOnlyControls = TRUE; // only set if there are any objects at all + while ( pObj ) + { + if (!pObj->ISA(SdrUnoObj)) + { + bOnlyControls = FALSE; + break; + } + pObj = aIter.Next(); + } + } + } + } + + return bOnlyControls; +} + +void ScDrawTransferObj::AddSupportedFormats() +{ + if ( bGrIsBit ) // single bitmap graphic + { + AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ); + AddFormat( SOT_FORMATSTR_ID_SVXB ); + AddFormat( SOT_FORMAT_BITMAP ); + AddFormat( SOT_FORMAT_GDIMETAFILE ); + } + else if ( bGraphic ) // other graphic + { + // #i25616# + AddFormat( SOT_FORMATSTR_ID_DRAWING ); + + AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ); + AddFormat( SOT_FORMATSTR_ID_SVXB ); + AddFormat( SOT_FORMAT_GDIMETAFILE ); + AddFormat( SOT_FORMAT_BITMAP ); + } + else if ( pBookmark ) // url button + { +// AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ); + AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ); + AddFormat( SOT_FORMATSTR_ID_SOLK ); + AddFormat( SOT_FORMAT_STRING ); + AddFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ); + AddFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ); + AddFormat( SOT_FORMATSTR_ID_DRAWING ); + } + else if ( bOleObj ) // single OLE object + { + AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ); + AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ); + AddFormat( SOT_FORMAT_GDIMETAFILE ); + + if ( !aOleData.GetTransferable().is() ) + { + SdrOle2Obj* pObj = GetSingleObject(); + if ( pObj && pObj->GetObjRef().is() ) + aOleData = TransferableDataHelper( new SvEmbedTransferHelper( pObj->GetObjRef(), pObj->GetGraphic(), pObj->GetAspect() ) ) ; + } + if ( aOleData.GetTransferable().is() ) + { + // get format list from object snapshot + // (this must be after inserting the default formats!) + + DataFlavorExVector aVector( aOleData.GetDataFlavorExVector() ); + DataFlavorExVector::iterator aIter( aVector.begin() ), aEnd( aVector.end() ); + + while( aIter != aEnd ) + AddFormat( *aIter++ ); + } + } + else // any drawing objects + { + AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ); + AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ); + AddFormat( SOT_FORMATSTR_ID_DRAWING ); + + // #103556# leave out bitmap and metafile if there are only controls + if ( !lcl_HasOnlyControls( pModel ) ) + { + AddFormat( SOT_FORMAT_BITMAP ); + AddFormat( SOT_FORMAT_GDIMETAFILE ); + } + } + +// if( pImageMap ) +// AddFormat( SOT_FORMATSTR_ID_SVIM ); +} + +sal_Bool ScDrawTransferObj::GetData( const ::com::sun::star::datatransfer::DataFlavor& rFlavor ) +{ + sal_Bool bOK = sal_False; + sal_uInt32 nFormat = SotExchange::GetFormat( rFlavor ); + + if ( bOleObj && nFormat != SOT_FORMAT_GDIMETAFILE ) + { + if ( !aOleData.GetTransferable().is() ) + { + SdrOle2Obj* pObj = GetSingleObject(); + if ( pObj && pObj->GetObjRef().is() ) + aOleData = TransferableDataHelper( new SvEmbedTransferHelper( pObj->GetObjRef(), pObj->GetGraphic(), pObj->GetAspect() ) ) ; + } + + if( aOleData.GetTransferable().is() && aOleData.HasFormat( rFlavor ) ) + { + ULONG nOldSwapMode = 0; + + if( pModel ) + { + nOldSwapMode = pModel->GetSwapGraphicsMode(); + pModel->SetSwapGraphicsMode( SDR_SWAPGRAPHICSMODE_PURGE ); + } + + bOK = SetAny( aOleData.GetAny( rFlavor ), rFlavor ); + + if( pModel ) + pModel->SetSwapGraphicsMode( nOldSwapMode ); + + return bOK; + } + } + + if( HasFormat( nFormat ) ) + { + if ( nFormat == SOT_FORMATSTR_ID_LINKSRCDESCRIPTOR || nFormat == SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ) + { + bOK = SetTransferableObjectDescriptor( aObjDesc, rFlavor ); + } + else if ( nFormat == SOT_FORMATSTR_ID_DRAWING ) + { + bOK = SetObject( pModel, SCDRAWTRANS_TYPE_DRAWMODEL, rFlavor ); + } + else if ( nFormat == SOT_FORMAT_BITMAP || nFormat == SOT_FORMAT_GDIMETAFILE ) + { + // #i71538# use complete SdrViews + // SdrExchangeView aView( pModel ); + SdrView aView( pModel ); + SdrPageView* pPv = aView.ShowSdrPage(aView.GetModel()->GetPage(0)); + DBG_ASSERT( pPv, "pPv not there..." ); + aView.MarkAllObj( pPv ); + if ( nFormat == SOT_FORMAT_GDIMETAFILE ) + bOK = SetGDIMetaFile( aView.GetAllMarkedMetaFile( TRUE ), rFlavor ); + else + bOK = SetBitmap( aView.GetAllMarkedBitmap( TRUE ), rFlavor ); + } + else if ( nFormat == SOT_FORMATSTR_ID_SVXB ) + { + // only enabled for single graphics object + + SdrPage* pPage = pModel->GetPage(0); + if (pPage) + { + SdrObjListIter aIter( *pPage, IM_FLAT ); + SdrObject* pObject = aIter.Next(); + if (pObject && pObject->GetObjIdentifier() == OBJ_GRAF) + { + SdrGrafObj* pGraphObj = (SdrGrafObj*) pObject; + bOK = SetGraphic( pGraphObj->GetGraphic(), rFlavor ); + } + } + } + else if ( nFormat == SOT_FORMATSTR_ID_EMBED_SOURCE ) + { + if ( bOleObj ) // single OLE object + { + SdrOle2Obj* pObj = GetSingleObject(); + if ( pObj && pObj->GetObjRef().is() ) + { + bOK = SetObject( pObj->GetObjRef().get(), SCDRAWTRANS_TYPE_EMBOBJ, rFlavor ); + } + } + else // create object from contents + { + //TODO/LATER: needs new Format, because now single OLE and "this" are different + InitDocShell(); // set aDocShellRef + + SfxObjectShell* pEmbObj = aDocShellRef; + bOK = SetObject( pEmbObj, SCDRAWTRANS_TYPE_DOCUMENT, rFlavor ); + } + } + else if( pBookmark ) + { + bOK = SetINetBookmark( *pBookmark, rFlavor ); + } + } + return bOK; +} + +sal_Bool ScDrawTransferObj::WriteObject( SotStorageStreamRef& rxOStm, void* pUserObject, sal_uInt32 nUserObjectId, + const ::com::sun::star::datatransfer::DataFlavor& /* rFlavor */ ) +{ + // called from SetObject, put data into stream + + sal_Bool bRet = sal_False; + switch (nUserObjectId) + { + case SCDRAWTRANS_TYPE_DRAWMODEL: + { + SdrModel* pDrawModel = (SdrModel*)pUserObject; + rxOStm->SetBufferSize( 0xff00 ); + + // #108584# + // for the changed pool defaults from drawing layer pool set those + // attributes as hard attributes to preserve them for saving + const SfxItemPool& rItemPool = pModel->GetItemPool(); + const SvxFontHeightItem& rDefaultFontHeight = (const SvxFontHeightItem&)rItemPool.GetDefaultItem(EE_CHAR_FONTHEIGHT); + + // SW should have no MasterPages + DBG_ASSERT(0L == pModel->GetMasterPageCount(), "SW with MasterPages (!)"); + + for(sal_uInt16 a(0); a < pModel->GetPageCount(); a++) + { + const SdrPage* pPage = pModel->GetPage(a); + SdrObjListIter aIter(*pPage, IM_DEEPNOGROUPS); + + while(aIter.IsMore()) + { + SdrObject* pObj = aIter.Next(); + const SvxFontHeightItem& rItem = (const SvxFontHeightItem&)pObj->GetMergedItem(EE_CHAR_FONTHEIGHT); + + if(rItem.GetHeight() == rDefaultFontHeight.GetHeight()) + { + pObj->SetMergedItem(rDefaultFontHeight); + } + } + } + + { + com::sun::star::uno::Reference<com::sun::star::io::XOutputStream> xDocOut( new utl::OOutputStreamWrapper( *rxOStm ) ); + if( SvxDrawingLayerExport( pDrawModel, xDocOut ) ) + rxOStm->Commit(); + } + + bRet = ( rxOStm->GetError() == ERRCODE_NONE ); + } + break; + + case SCDRAWTRANS_TYPE_EMBOBJ: + { + // impl. for "single OLE" + embed::XEmbeddedObject* pEmbObj = (embed::XEmbeddedObject*) pUserObject; + + ::utl::TempFile aTempFile; + aTempFile.EnableKillingFile(); + uno::Reference< embed::XStorage > xWorkStore = + ::comphelper::OStorageHelper::GetStorageFromURL( aTempFile.GetURL(), embed::ElementModes::READWRITE ); + + uno::Reference < embed::XEmbedPersist > xPers( (embed::XVisualObject*)pEmbObj, uno::UNO_QUERY ); + if ( xPers.is() ) + { + try + { + uno::Sequence < beans::PropertyValue > aSeq; + ::rtl::OUString aDummyName = ::rtl::OUString::createFromAscii("Dummy"); + xPers->storeToEntry( xWorkStore, aDummyName, aSeq, aSeq ); + if ( xWorkStore->isStreamElement( aDummyName ) ) + { + uno::Reference < io::XOutputStream > xDocOut( new utl::OOutputStreamWrapper( *rxOStm ) ); + uno::Reference < io::XStream > xNewStream = xWorkStore->openStreamElement( aDummyName, embed::ElementModes::READ ); + ::comphelper::OStorageHelper::CopyInputToOutput( xNewStream->getInputStream(), xDocOut ); + } + else + { + uno::Reference < io::XStream > xDocStr( new utl::OStreamWrapper( *rxOStm ) ); + uno::Reference< embed::XStorage > xDocStg = ::comphelper::OStorageHelper::GetStorageFromStream( xDocStr ); + uno::Reference < embed::XStorage > xNewStg = xWorkStore->openStorageElement( aDummyName, embed::ElementModes::READ ); + xNewStg->copyToStorage( xDocStg ); + uno::Reference < embed::XTransactedObject > xTrans( xDocStg, uno::UNO_QUERY ); + if ( xTrans.is() ) + xTrans->commit(); + } + + rxOStm->Commit(); + } + catch ( uno::Exception& ) + { + } + } + + break; + } + case SCDRAWTRANS_TYPE_DOCUMENT: + { + // impl. for "DocShell" + SfxObjectShell* pEmbObj = (SfxObjectShell*) pUserObject; + + try + { + ::utl::TempFile aTempFile; + aTempFile.EnableKillingFile(); + uno::Reference< embed::XStorage > xWorkStore = + ::comphelper::OStorageHelper::GetStorageFromURL( aTempFile.GetURL(), embed::ElementModes::READWRITE ); + + // write document storage + pEmbObj->SetupStorage( xWorkStore, SOFFICE_FILEFORMAT_CURRENT, sal_False ); + + // mba: no relative ULRs for clipboard! + SfxMedium aMedium( xWorkStore, String() ); + bRet = pEmbObj->DoSaveObjectAs( aMedium, FALSE ); + pEmbObj->DoSaveCompleted(); + + uno::Reference< embed::XTransactedObject > xTransact( xWorkStore, uno::UNO_QUERY ); + if ( xTransact.is() ) + xTransact->commit(); + + SvStream* pSrcStm = ::utl::UcbStreamHelper::CreateStream( aTempFile.GetURL(), STREAM_READ ); + if( pSrcStm ) + { + rxOStm->SetBufferSize( 0xff00 ); + *rxOStm << *pSrcStm; + delete pSrcStm; + } + + bRet = TRUE; + + xWorkStore->dispose(); + xWorkStore = uno::Reference < embed::XStorage >(); + rxOStm->Commit(); + } + catch ( uno::Exception& ) + {} + + bRet = ( rxOStm->GetError() == ERRCODE_NONE ); + } + break; + + default: + DBG_ERROR("unknown object id"); + } + return bRet; +} + +void ScDrawTransferObj::ObjectReleased() +{ + ScModule* pScMod = SC_MOD(); + if ( pScMod->GetClipData().pDrawClipboard == this ) + pScMod->SetClipObject( NULL, NULL ); + + TransferableHelper::ObjectReleased(); +} + +void ScDrawTransferObj::DragFinished( sal_Int8 nDropAction ) +{ + if ( nDropAction == DND_ACTION_MOVE && !bDragWasInternal && !(nDragSourceFlags & SC_DROP_NAVIGATOR) ) + { + // move: delete source objects + + if ( pDragSourceView ) + pDragSourceView->DeleteMarked(); + } + + ScModule* pScMod = SC_MOD(); + if ( pScMod->GetDragData().pDrawTransfer == this ) + pScMod->ResetDragObject(); + + DELETEZ( pDragSourceView ); + + TransferableHelper::DragFinished( nDropAction ); +} + +void ScDrawTransferObj::SetDrawPersist( const SfxObjectShellRef& rRef ) +{ + aDrawPersistRef = rRef; +} + +void lcl_InitMarks( SdrMarkView& rDest, const SdrMarkView& rSource, SCTAB nTab ) +{ + rDest.ShowSdrPage(rDest.GetModel()->GetPage(nTab)); + SdrPageView* pDestPV = rDest.GetSdrPageView(); + DBG_ASSERT(pDestPV,"PageView ?"); + + const SdrMarkList& rMarkList = rSource.GetMarkedObjectList(); + ULONG nCount = rMarkList.GetMarkCount(); + for (ULONG i=0; i<nCount; i++) + { + SdrMark* pMark = rMarkList.GetMark(i); + SdrObject* pObj = pMark->GetMarkedSdrObj(); + + rDest.MarkObj(pObj, pDestPV); + } +} + +void ScDrawTransferObj::SetDragSource( ScDrawView* pView ) +{ + DELETEZ( pDragSourceView ); + pDragSourceView = new SdrView( pView->GetModel() ); + lcl_InitMarks( *pDragSourceView, *pView, pView->GetTab() ); + + //! add as listener with document, delete pDragSourceView if document gone +} + +void ScDrawTransferObj::SetDragSourceObj( SdrObject* pObj, SCTAB nTab ) +{ + DELETEZ( pDragSourceView ); + pDragSourceView = new SdrView( pObj->GetModel() ); + pDragSourceView->ShowSdrPage(pDragSourceView->GetModel()->GetPage(nTab)); + SdrPageView* pPV = pDragSourceView->GetSdrPageView(); + pDragSourceView->MarkObj(pObj, pPV); + + //! add as listener with document, delete pDragSourceView if document gone +} + +void ScDrawTransferObj::SetDragSourceFlags( USHORT nFlags ) +{ + nDragSourceFlags = nFlags; +} + +void ScDrawTransferObj::SetDragWasInternal() +{ + bDragWasInternal = TRUE; +} + +SdrOle2Obj* ScDrawTransferObj::GetSingleObject() +{ + // if single OLE object was copied, get its object + + SdrPage* pPage = pModel->GetPage(0); + if (pPage) + { + SdrObjListIter aIter( *pPage, IM_FLAT ); + SdrObject* pObject = aIter.Next(); + if (pObject && pObject->GetObjIdentifier() == OBJ_OLE2) + { + return (SdrOle2Obj*) pObject; + } + } + + return NULL; +} + +// +// initialize aDocShellRef with a live document from the ClipDoc +// + +void ScDrawTransferObj::InitDocShell() +{ + if ( !aDocShellRef.Is() ) + { + ScDocShell* pDocSh = new ScDocShell; + aDocShellRef = pDocSh; // ref must be there before InitNew + + pDocSh->DoInitNew(NULL); + + ScDocument* pDestDoc = pDocSh->GetDocument(); + pDestDoc->InitDrawLayer( pDocSh ); + + SdrModel* pDestModel = pDestDoc->GetDrawLayer(); + // #i71538# use complete SdrViews + // SdrExchangeView aDestView( pDestModel ); + SdrView aDestView( pDestModel ); + aDestView.ShowSdrPage(aDestView.GetModel()->GetPage(0)); + aDestView.Paste( *pModel, Point( aSrcSize.Width()/2, aSrcSize.Height()/2 ) ); + + // put objects to right layer (see ScViewFunc::PasteDataFormat for SOT_FORMATSTR_ID_DRAWING) + + SdrPage* pPage = pDestModel->GetPage(0); + if (pPage) + { + SdrObjListIter aIter( *pPage, IM_DEEPWITHGROUPS ); + SdrObject* pObject = aIter.Next(); + while (pObject) + { + if ( pObject->ISA(SdrUnoObj) ) + pObject->NbcSetLayer(SC_LAYER_CONTROLS); + else + pObject->NbcSetLayer(SC_LAYER_FRONT); + pObject = aIter.Next(); + } + } + + Point aTmpPoint; + Rectangle aDestArea( aTmpPoint, aSrcSize ); + pDocSh->SetVisArea( aDestArea ); + + ScViewOptions aViewOpt( pDestDoc->GetViewOptions() ); + aViewOpt.SetOption( VOPT_GRID, FALSE ); + pDestDoc->SetViewOptions( aViewOpt ); + + ScViewData aViewData( pDocSh, NULL ); + aViewData.SetTabNo( 0 ); + aViewData.SetScreen( aDestArea ); + aViewData.SetCurX( 0 ); + aViewData.SetCurY( 0 ); + pDocSh->UpdateOle(&aViewData, TRUE); + } +} + +const com::sun::star::uno::Sequence< sal_Int8 >& ScDrawTransferObj::getUnoTunnelId() +{ + static com::sun::star::uno::Sequence< sal_Int8 > aSeq; + if( !aSeq.getLength() ) + { + static osl::Mutex aCreateMutex; + osl::Guard< osl::Mutex > aGuard( aCreateMutex ); + aSeq.realloc( 16 ); + rtl_createUuid( reinterpret_cast< sal_uInt8* >( aSeq.getArray() ), 0, sal_True ); + } + return aSeq; +} + +sal_Int64 SAL_CALL ScDrawTransferObj::getSomething( const com::sun::star::uno::Sequence< sal_Int8 >& rId ) throw( com::sun::star::uno::RuntimeException ) +{ + sal_Int64 nRet; + if( ( rId.getLength() == 16 ) && + ( 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), rId.getConstArray(), 16 ) ) ) + { + nRet = reinterpret_cast< sal_Int64 >( this ); + } + else + nRet = TransferableHelper::getSomething(rId); + return nRet; +} + + diff --git a/sc/source/ui/app/inputhdl.cxx b/sc/source/ui/app/inputhdl.cxx new file mode 100644 index 000000000000..485ea4b88589 --- /dev/null +++ b/sc/source/ui/app/inputhdl.cxx @@ -0,0 +1,3793 @@ +/************************************************************************* + * + * 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_sc.hxx" + +//------------------------------------------------------------------ + +#include "scitems.hxx" +#include <editeng/eeitem.hxx> + +#include <sfx2/app.hxx> +#include <editeng/acorrcfg.hxx> +#include <svx/algitem.hxx> +#include <editeng/adjitem.hxx> +#include <editeng/brshitem.hxx> +#include <svtools/colorcfg.hxx> +#include <editeng/colritem.hxx> +#include <editeng/editobj.hxx> +#include <editeng/editstat.hxx> +#include <editeng/editview.hxx> +#include <editeng/escpitem.hxx> +#include <editeng/forbiddencharacterstable.hxx> +#include <editeng/langitem.hxx> +#include <editeng/svxacorr.hxx> +#include <editeng/unolingu.hxx> +#include <editeng/wghtitem.hxx> +#include <sfx2/bindings.hxx> +#include <sfx2/viewfrm.hxx> +#include <sfx2/dispatch.hxx> +#include <sfx2/docfile.hxx> +#include <sfx2/printer.hxx> +#include <svl/zforlist.hxx> +#include <vcl/sound.hxx> +#include <unotools/localedatawrapper.hxx> +#include <vcl/help.hxx> +#include <vcl/cursor.hxx> +#include <tools/urlobj.hxx> +#include <formula/formulahelper.hxx> + +#include "inputwin.hxx" +#include "tabvwsh.hxx" +#include "docsh.hxx" +#include "scmod.hxx" +#include "uiitems.hxx" +#include "global.hxx" +#include "sc.hrc" +#include "globstr.hrc" +#include "patattr.hxx" +#include "viewdata.hxx" +#include "document.hxx" +#include "docpool.hxx" +#include "editutil.hxx" +#include "collect.hxx" +#include "appoptio.hxx" +#include "docoptio.hxx" +#include "validat.hxx" +#include "userlist.hxx" +#include "rfindlst.hxx" +#include "inputopt.hxx" +#include "cell.hxx" // fuer Formel-Preview +#include "compiler.hxx" // fuer Formel-Preview +#include "editable.hxx" +#include "funcdesc.hxx" + +#define _INPUTHDL_CXX +#include "inputhdl.hxx" + +// max. Ranges im RangeFinder +#define RANGEFIND_MAX 32 + +using namespace formula; + +// STATIC DATA ----------------------------------------------------------- + +BOOL ScInputHandler::bOptLoaded = FALSE; // App-Optionen ausgewertet +BOOL ScInputHandler::bAutoComplete = FALSE; // wird in KeyInput gesetzt + +// delimiters (in addition to ScEditUtil) needed for range finder: +// only characters that are allowed in formulas next to references +// and the quotation mark (so string constants can be skipped) + +static const sal_Char __FAR_DATA pMinDelimiters[] = " !\""; + +extern USHORT nEditAdjust; //! Member an ViewData + +//================================================================== + +static sal_Unicode lcl_getSheetSeparator(ScDocument* pDoc) +{ + ScCompiler aComp(pDoc, ScAddress()); + aComp.SetGrammar(pDoc->GetGrammar()); + return aComp.GetNativeAddressSymbol(ScCompiler::Convention::SHEET_SEPARATOR); +} + +void ScInputHandler::InitRangeFinder( const String& rFormula ) +{ + DeleteRangeFinder(); + ScDocShell* pDocSh = pActiveViewSh->GetViewData()->GetDocShell(); + ScDocument* pDoc = pDocSh->GetDocument(); + const sal_Unicode cSheetSep = lcl_getSheetSeparator(pDoc); + + if ( !pActiveViewSh || !SC_MOD()->GetInputOptions().GetRangeFinder() ) + return; + +// String aDelimiters = pEngine->GetWordDelimiters(); + String aDelimiters = ScEditUtil::ModifyDelimiters( + String::CreateFromAscii( pMinDelimiters ) ); + + xub_StrLen nColon = aDelimiters.Search(':'); + if ( nColon != STRING_NOTFOUND ) + aDelimiters.Erase( nColon, 1 ); // Delimiter ohne Doppelpunkt + xub_StrLen nDot = aDelimiters.Search(cSheetSep); + if ( nDot != STRING_NOTFOUND ) + aDelimiters.Erase( nDot, 1 ); // Delimiter ohne Punkt + + const sal_Unicode* pChar = rFormula.GetBuffer(); + xub_StrLen nLen = rFormula.Len(); + xub_StrLen nPos = 0; + xub_StrLen nStart = 0; + USHORT nCount = 0; + ScRange aRange; + while ( nPos < nLen && nCount < RANGEFIND_MAX ) + { + // Trenner ueberlesen + while ( nPos<nLen && ScGlobal::UnicodeStrChr( aDelimiters.GetBuffer(), pChar[nPos] ) ) + { + if ( pChar[nPos] == '"' ) // String + { + ++nPos; + while (nPos<nLen && pChar[nPos] != '"') // bis zum Ende ueberlesen + ++nPos; + } + ++nPos; // Trennzeichen oder schliessender Quote + } + + // Text zwischen Trennern + nStart = nPos; +handle_r1c1: + while ( nPos<nLen && !ScGlobal::UnicodeStrChr( aDelimiters.GetBuffer(), pChar[nPos] ) ) + ++nPos; + + // for R1C1 '-' in R[-]... or C[-]... are not delimiters + // Nothing heroic here to ensure that there are '[]' around a negative + // integer. we need to clean up this code. + if( nPos < nLen && nPos > 0 && + '-' == pChar[nPos] && '[' == pChar[nPos-1] && + NULL != pDoc && + formula::FormulaGrammar::CONV_XL_R1C1 == pDoc->GetAddressConvention() ) + { + nPos++; + goto handle_r1c1; + } + + if ( nPos > nStart ) + { + String aTest = rFormula.Copy( nStart, nPos-nStart ); + const ScAddress::Details aAddrDetails( pDoc, aCursorPos ); + USHORT nFlags = aRange.ParseAny( aTest, pDoc, aAddrDetails ); + if ( nFlags & SCA_VALID ) + { + // Tabelle setzen, wenn nicht angegeben + if ( (nFlags & SCA_TAB_3D) == 0 ) + aRange.aStart.SetTab( pActiveViewSh->GetViewData()->GetTabNo() ); + if ( (nFlags & SCA_TAB2_3D) == 0 ) + aRange.aEnd.SetTab( aRange.aStart.Tab() ); + + if (!nCount) + { + pEngine->SetUpdateMode( FALSE ); + pRangeFindList = new ScRangeFindList( pDocSh->GetTitle() ); + } + + ScRangeFindData* pNew = new ScRangeFindData( aRange, nFlags, nStart, nPos ); + pRangeFindList->Insert( pNew ); + + ESelection aSel( 0, nStart, 0, nPos ); + SfxItemSet aSet( pEngine->GetEmptyItemSet() ); + aSet.Put( SvxColorItem( Color( ScRangeFindList::GetColorName( nCount ) ), + EE_CHAR_COLOR ) ); + pEngine->QuickSetAttribs( aSet, aSel ); + ++nCount; + } + } + + // letzten Trenner nicht ueberlesen, koennte ja ein Quote sein (?) + } + + if (nCount) + { + pEngine->SetUpdateMode( TRUE ); + + pDocSh->Broadcast( SfxSimpleHint( SC_HINT_SHOWRANGEFINDER ) ); + } +} + +void lcl_Replace( EditView* pView, const String& rNewStr, const ESelection& rOldSel ) +{ + if ( pView ) + { + ESelection aOldSel = pView->GetSelection(); + if (aOldSel.HasRange()) + pView->SetSelection( ESelection( aOldSel.nEndPara, aOldSel.nEndPos, + aOldSel.nEndPara, aOldSel.nEndPos ) ); + + EditEngine* pEngine = pView->GetEditEngine(); + pEngine->QuickInsertText( rNewStr, rOldSel ); + + // Dummy-InsertText fuer Update und Paint + // dafuer muss oben die Selektion aufgehoben werden (vor QuickInsertText) + pView->InsertText( EMPTY_STRING, FALSE ); + + xub_StrLen nLen = pEngine->GetTextLen(0); + ESelection aSel( 0, nLen, 0, nLen ); + pView->SetSelection( aSel ); // Cursor ans Ende + } +} + +void ScInputHandler::UpdateRange( USHORT nIndex, const ScRange& rNew ) +{ + ScTabViewShell* pDocView = pRefViewSh ? pRefViewSh : pActiveViewSh; + if ( pDocView && pRangeFindList && nIndex < pRangeFindList->Count() ) + { + ScRangeFindData* pData = pRangeFindList->GetObject( nIndex ); + xub_StrLen nOldStart = pData->nSelStart; + xub_StrLen nOldEnd = pData->nSelEnd; + + ScRange aJustified = rNew; + aJustified.Justify(); // Ref in der Formel immer richtigherum anzeigen + String aNewStr; + ScDocument* pDoc = pDocView->GetViewData()->GetDocument(); + const ScAddress::Details aAddrDetails( pDoc, aCursorPos ); + aJustified.Format( aNewStr, pData->nFlags, pDoc, aAddrDetails ); + ESelection aOldSel( 0, nOldStart, 0, nOldEnd ); + + DataChanging(); + + lcl_Replace( pTopView, aNewStr, aOldSel ); + lcl_Replace( pTableView, aNewStr, aOldSel ); + + bInRangeUpdate = TRUE; + DataChanged(); + bInRangeUpdate = FALSE; + + long nDiff = aNewStr.Len() - (long)(nOldEnd-nOldStart); + + pData->aRef = rNew; + pData->nSelEnd = (xub_StrLen)(pData->nSelEnd + nDiff); + + USHORT nCount = (USHORT) pRangeFindList->Count(); + for (USHORT i=nIndex+1; i<nCount; i++) + { + ScRangeFindData* pNext = pRangeFindList->GetObject( i ); + pNext->nSelStart = (xub_StrLen)(pNext->nSelStart + nDiff); + pNext->nSelEnd = (xub_StrLen)(pNext->nSelEnd + nDiff); + } + } + else + { + DBG_ERROR("UpdateRange: da fehlt was"); + } +} + +void ScInputHandler::DeleteRangeFinder() +{ + ScTabViewShell* pPaintView = pRefViewSh ? pRefViewSh : pActiveViewSh; + if ( pRangeFindList && pPaintView ) + { + ScDocShell* pDocSh = pActiveViewSh->GetViewData()->GetDocShell(); + pRangeFindList->SetHidden(TRUE); + pDocSh->Broadcast( SfxSimpleHint( SC_HINT_SHOWRANGEFINDER ) ); // wegnehmen + DELETEZ(pRangeFindList); + } +} + +//================================================================== + +inline String GetEditText(EditEngine* pEng) +{ + return ScEditUtil::GetSpaceDelimitedString(*pEng); +} + +void lcl_RemoveTabs(String& rStr) +{ + xub_StrLen nPos; + while ( (nPos=rStr.Search('\t')) != STRING_NOTFOUND ) + rStr.SetChar( nPos, ' ' ); +} + +void lcl_RemoveLineEnd(String& rStr) +{ + rStr.ConvertLineEnd(LINEEND_LF); + xub_StrLen nPos; + while ( (nPos=rStr.Search('\n')) != STRING_NOTFOUND ) + rStr.SetChar( nPos, ' ' ); +} + +xub_StrLen lcl_MatchParenthesis( const String& rStr, xub_StrLen nPos ) +{ + int nDir; + sal_Unicode c1, c2 = 0; + c1 = rStr.GetChar( nPos ); + switch ( c1 ) + { + case '(' : + c2 = ')'; + nDir = 1; + break; + case ')' : + c2 = '('; + nDir = -1; + break; + case '<' : + c2 = '>'; + nDir = 1; + break; + case '>' : + c2 = '<'; + nDir = -1; + break; + case '{' : + c2 = '}'; + nDir = 1; + break; + case '}' : + c2 = '{'; + nDir = -1; + break; + case '[' : + c2 = ']'; + nDir = 1; + break; + case ']' : + c2 = '['; + nDir = -1; + break; + default: + nDir = 0; + } + if ( !nDir ) + return STRING_NOTFOUND; + xub_StrLen nLen = rStr.Len(); + const sal_Unicode* p0 = rStr.GetBuffer(); + register const sal_Unicode* p; + const sal_Unicode* p1; + USHORT nQuotes = 0; + if ( nPos < nLen / 2 ) + { + p = p0; + p1 = p0 + nPos; + } + else + { + p = p0 + nPos; + p1 = p0 + nLen; + } + while ( p < p1 ) + { + if ( *p++ == '\"' ) + nQuotes++; + } + // Odd number of quotes that we find ourselves in a string + BOOL bLookInString = ((nQuotes % 2) != 0); + BOOL bInString = bLookInString; + p = p0 + nPos; + p1 = (nDir < 0 ? p0 : p0 + nLen) ; + USHORT nLevel = 1; + while ( p != p1 && nLevel ) + { + p += nDir; + if ( *p == '\"' ) + { + bInString = !bInString; + if ( bLookInString && !bInString ) + p = p1; //That's it then + } + else if ( bInString == bLookInString ) + { + if ( *p == c1 ) + nLevel++; + else if ( *p == c2 ) + nLevel--; + } + } + if ( nLevel ) + return STRING_NOTFOUND; + return (xub_StrLen) (p - p0); +} + +//================================================================== + +ScInputHandler::ScInputHandler() + : pInputWin( NULL ), + pEngine( NULL ), + pTableView( NULL ), + pTopView( NULL ), + pColumnData( NULL ), + pFormulaData( NULL ), + pFormulaDataPara( NULL ), + nTipVisible( 0 ), + nTipVisibleSec( 0 ), + nAutoPos( SCPOS_INVALID ), + bUseTab( FALSE ), + bTextValid( TRUE ), + nFormSelStart( 0 ), + nFormSelEnd( 0 ), + nAutoPar( 0 ), + eMode( SC_INPUT_NONE ), + bModified( FALSE ), + bSelIsRef( FALSE ), + bFormulaMode( FALSE ), + bInRangeUpdate( FALSE ), + bParenthesisShown( FALSE ), + bCreatingFuncView( FALSE ), + bInEnterHandler( FALSE ), + bCommandErrorShown( FALSE ), + bInOwnChange( FALSE ), + bProtected( FALSE ), + bCellHasPercentFormat( FALSE ), + nValidation( 0 ), + eAttrAdjust( SVX_HOR_JUSTIFY_STANDARD ), + aScaleX( 1,1 ), + aScaleY( 1,1 ), + pRefViewSh( NULL ), + pLastPattern( NULL ), + pEditDefaults( NULL ), + bLastIsSymbol( FALSE ), + pLastState( NULL ), + pDelayTimer( NULL ), + pRangeFindList( NULL ) +{ + // The InputHandler is constructed with the view, so SfxViewShell::Current + // doesn't have the right view yet. pActiveViewSh is updated in NotifyChange. + pActiveViewSh = NULL; + + // Bindings (nur noch fuer Invalidate benutzt) werden bei Bedarf aktuell geholt +} + +__EXPORT ScInputHandler::~ScInputHandler() +{ + // Wenn dies der Applikations-InputHandler ist, wird der dtor erst nach SfxApplication::Main + // gerufen, darf sich also auf keine Sfx-Funktionen mehr verlassen + + if ( !SFX_APP()->IsDowning() ) // inplace + EnterHandler(); // Eingabe noch abschliessen + + if (SC_MOD()->GetRefInputHdl()==this) + SC_MOD()->SetRefInputHdl(NULL); + + if ( pInputWin && pInputWin->GetInputHandler() == this ) + pInputWin->SetInputHandler( NULL ); + + delete pRangeFindList; + delete pEditDefaults; + delete pEngine; + delete pLastState; + delete pDelayTimer; + delete pColumnData; + delete pFormulaData; + delete pFormulaDataPara; +} + +void ScInputHandler::SetRefScale( const Fraction& rX, const Fraction& rY ) +{ + if ( rX != aScaleX || rY != aScaleY ) + { + aScaleX = rX; + aScaleY = rY; + if (pEngine) + { + MapMode aMode( MAP_100TH_MM, Point(), aScaleX, aScaleY ); + pEngine->SetRefMapMode( aMode ); + } + } +} + +void ScInputHandler::UpdateRefDevice() +{ + if (!pEngine) + return; + + BOOL bTextWysiwyg = SC_MOD()->GetInputOptions().GetTextWysiwyg(); + if ( bTextWysiwyg && pActiveViewSh ) + pEngine->SetRefDevice( pActiveViewSh->GetViewData()->GetDocument()->GetPrinter() ); + else + pEngine->SetRefDevice( NULL ); + + MapMode aMode( MAP_100TH_MM, Point(), aScaleX, aScaleY ); + pEngine->SetRefMapMode( aMode ); + + // SetRefDevice(NULL) uses VirtualDevice, SetRefMapMode forces creation of a local VDev, + // so the DigitLanguage can be safely modified (might use an own VDev instead of NULL). + if ( !( bTextWysiwyg && pActiveViewSh ) ) + { + pEngine->GetRefDevice()->SetDigitLanguage( SC_MOD()->GetOptDigitLanguage() ); + } +} + +void ScInputHandler::ImplCreateEditEngine() +{ + if ( !pEngine ) + { + if ( pActiveViewSh ) + { + const ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocShell()->GetDocument(); + pEngine = new ScFieldEditEngine( pDoc->GetEnginePool(), pDoc->GetEditPool() ); + } + else + pEngine = new ScFieldEditEngine( EditEngine::CreatePool(), NULL, TRUE ); + pEngine->SetWordDelimiters( ScEditUtil::ModifyDelimiters( pEngine->GetWordDelimiters() ) ); + UpdateRefDevice(); // also sets MapMode + pEngine->SetPaperSize( Size( 1000000, 1000000 ) ); + pEditDefaults = new SfxItemSet( pEngine->GetEmptyItemSet() ); + + pEngine->SetControlWord( pEngine->GetControlWord() | EE_CNTRL_AUTOCORRECT ); + pEngine->SetModifyHdl( LINK( this, ScInputHandler, ModifyHdl ) ); + } +} + +void ScInputHandler::UpdateAutoCorrFlag() +{ + ULONG nCntrl = pEngine->GetControlWord(); + ULONG nOld = nCntrl; + + // don't use pLastPattern here (may be invalid because of AutoStyle) + + BOOL bDisable = bLastIsSymbol || bFormulaMode; + if ( bDisable ) + nCntrl &= ~EE_CNTRL_AUTOCORRECT; + else + nCntrl |= EE_CNTRL_AUTOCORRECT; + + if ( nCntrl != nOld ) + pEngine->SetControlWord(nCntrl); +} + +void ScInputHandler::UpdateSpellSettings( BOOL bFromStartTab ) +{ + if ( pActiveViewSh ) + { + ScViewData* pViewData = pActiveViewSh->GetViewData(); + BOOL bOnlineSpell = pViewData->GetDocument()->GetDocOptions().IsAutoSpell(); + + // SetDefaultLanguage is independent of the language attributes, + // ScGlobal::GetEditDefaultLanguage is always used. + // It must be set every time in case the office language was changed. + + pEngine->SetDefaultLanguage( ScGlobal::GetEditDefaultLanguage() ); + + // if called for changed options, update flags only if already editing + // if called from StartTable, always update flags + + if ( bFromStartTab || eMode != SC_INPUT_NONE ) + { + ULONG nCntrl = pEngine->GetControlWord(); + ULONG nOld = nCntrl; + if( bOnlineSpell ) + nCntrl |= EE_CNTRL_ONLINESPELLING; + else + nCntrl &= ~EE_CNTRL_ONLINESPELLING; + // kein AutoCorrect auf Symbol-Font (EditEngine wertet Default nicht aus) + if ( pLastPattern && pLastPattern->IsSymbolFont() ) + nCntrl &= ~EE_CNTRL_AUTOCORRECT; + else + nCntrl |= EE_CNTRL_AUTOCORRECT; + if ( nCntrl != nOld ) + pEngine->SetControlWord(nCntrl); + + ScDocument* pDoc = pViewData->GetDocument(); + pEngine->SetForbiddenCharsTable( pDoc->GetForbiddenCharacters() ); + pEngine->SetAsianCompressionMode( pDoc->GetAsianCompression() ); + pEngine->SetKernAsianPunctuation( pDoc->GetAsianKerning() ); + pEngine->SetDefaultHorizontalTextDirection( + (EEHorizontalTextDirection)pDoc->GetEditTextDirection( pViewData->GetTabNo() ) ); + pEngine->SetFirstWordCapitalization( FALSE ); + } + + // language is set separately, so the speller is needed only if online + // spelling is active + + if ( bOnlineSpell ) { + com::sun::star::uno::Reference<com::sun::star::linguistic2::XSpellChecker1> xXSpellChecker1( LinguMgr::GetSpellChecker() ); + pEngine->SetSpeller( xXSpellChecker1 ); + } + + BOOL bHyphen = pLastPattern && ((const SfxBoolItem&)pLastPattern->GetItem(ATTR_HYPHENATE)).GetValue(); + if ( bHyphen ) { + com::sun::star::uno::Reference<com::sun::star::linguistic2::XHyphenator> xXHyphenator( LinguMgr::GetHyphenator() ); + pEngine->SetHyphenator( xXHyphenator ); + } + } +} + +// +// Funktionen/Bereichsnamen etc. als Tip-Hilfe +// + +#define SC_STRTYPE_FUNCTIONS 1 +// die anderen Typen sind in ScDocument::GetFormulaEntries festgelegt + +void ScInputHandler::GetFormulaData() +{ + if ( pActiveViewSh ) + { + ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocShell()->GetDocument(); + + if ( pFormulaData ) + pFormulaData->FreeAll(); + else + pFormulaData = new TypedScStrCollection; + + if( pFormulaDataPara ) + pFormulaDataPara->FreeAll(); + else + pFormulaDataPara = new TypedScStrCollection; + + // MRU-Funktionen aus dem Funktions-Autopiloten + // wie in ScPosWnd::FillFunctions (inputwin.cxx) + + const ScAppOptions& rOpt = SC_MOD()->GetAppOptions(); + USHORT nMRUCount = rOpt.GetLRUFuncListCount(); + const USHORT* pMRUList = rOpt.GetLRUFuncList(); + const ScFunctionList* pFuncList = ScGlobal::GetStarCalcFunctionList(); + ULONG nListCount = pFuncList->GetCount(); + if (pMRUList) + { + for (USHORT i=0; i<nMRUCount; i++) + { + USHORT nId = pMRUList[i]; + for (ULONG j=0; j<nListCount; j++) + { + const ScFuncDesc* pDesc = pFuncList->GetFunction( j ); + if ( pDesc->nFIndex == nId && pDesc->pFuncName ) + { + String aEntry = *pDesc->pFuncName; + aEntry.AppendAscii(RTL_CONSTASCII_STRINGPARAM( "()" )); + TypedStrData* pData = new TypedStrData( aEntry, 0.0, SC_STRTYPE_FUNCTIONS ); + if (!pFormulaData->Insert(pData)) + delete pData; + break; // nicht weitersuchen + } + } + } + } + for(ULONG i=0;i<nListCount;i++) + { + const ScFuncDesc* pDesc = pFuncList->GetFunction( i ); + if ( pDesc->pFuncName ) + { + pDesc->initArgumentInfo(); + String aEntry = pDesc->GetSignature(); + TypedStrData* pData = new TypedStrData( aEntry, 0.0, SC_STRTYPE_FUNCTIONS ); + if (!pFormulaDataPara->Insert(pData)) + delete pData; + } + } + pDoc->GetFormulaEntries( *pFormulaData ); + pDoc->GetFormulaEntries( *pFormulaDataPara ); + } +} + +void ScInputHandler::HideTip() +{ + if ( nTipVisible ) + { + Help::HideTip( nTipVisible ); + nTipVisible = 0; + } + aManualTip.Erase(); +} +void ScInputHandler::HideTipBelow() +{ + if ( nTipVisibleSec ) + { + Help::HideTip( nTipVisibleSec ); + nTipVisibleSec = 0; + } + aManualTip.Erase(); +} + +void ScInputHandler::ShowTipCursor() +{ + HideTip(); + HideTipBelow(); + EditView* pActiveView = pTopView ? pTopView : pTableView; + ScDocShell* pDocSh = pActiveViewSh->GetViewData()->GetDocShell(); + const sal_Unicode cSep = ScCompiler::GetNativeSymbol(ocSep).GetChar(0); + const sal_Unicode cSheetSep = lcl_getSheetSeparator(pDocSh->GetDocument()); + + if ( bFormulaMode && pActiveView && pFormulaDataPara && pEngine->GetParagraphCount() == 1 ) + { + String aFormula = pEngine->GetText( (USHORT) 0 ); + ESelection aSel = pActiveView->GetSelection(); + aSel.Adjust(); + xub_StrLen nLeftParentPos = 0; + if( aSel.nEndPos ) + { + if ( aFormula.Len() < aSel.nEndPos ) + return; + xub_StrLen nPos = aSel.nEndPos; + String aSelText = aFormula.Copy( 0, nPos ); + xub_StrLen nNextFStart = 0; + xub_StrLen nNextFEnd = 0; + xub_StrLen nArgPos = 0; + const IFunctionDescription* ppFDesc; + ::std::vector< ::rtl::OUString> aArgs; + USHORT nArgs; + BOOL bFound = FALSE; + FormulaHelper aHelper(ScGlobal::GetStarCalcFunctionMgr()); + + while( !bFound ) + { + aSelText.AppendAscii( RTL_CONSTASCII_STRINGPARAM( ")" ) ); + nLeftParentPos = lcl_MatchParenthesis( aSelText, aSelText.Len()-1 ); + if( nLeftParentPos != STRING_NOTFOUND ) + { + sal_Unicode c = ( nLeftParentPos > 0 ) ? aSelText.GetChar( nLeftParentPos-1 ) : 0; + if( !((c >= 'A' && c<= 'Z') || (c>= 'a' && c<= 'z' )) ) + continue; + nNextFStart = aHelper.GetFunctionStart( aSelText, nLeftParentPos, TRUE); + if( aHelper.GetNextFunc( aSelText, FALSE, nNextFStart, &nNextFEnd, &ppFDesc, &aArgs ) ) + { + if( ppFDesc->getFunctionName().getLength() ) + { + nArgPos = aHelper.GetArgStart( aSelText, nNextFStart, 0 ); + nArgs = static_cast<USHORT>(ppFDesc->getParameterCount()); + + USHORT nActive = 0; + USHORT nCount = 0; + USHORT nCountSemicolon = 0; + USHORT nCountDot = 0; + USHORT nStartPosition = 0; + USHORT nEndPosition = 0; + BOOL bFlag = FALSE; + String aNew; + USHORT nParAutoPos = SCPOS_INVALID; + if( pFormulaDataPara->FindText( ppFDesc->getFunctionName(), aNew, nParAutoPos, FALSE ) ) + { + for( USHORT i=0; i < nArgs; i++ ) + { + xub_StrLen nLength = static_cast<xub_StrLen>(aArgs[i].getLength()); + if( nArgPos <= aSelText.Len()-1 ) + { + nActive = i+1; + bFlag = TRUE; + } + nArgPos+=nLength+1; + } + if( bFlag ) + { + nCountSemicolon = aNew.GetTokenCount(cSep)-1; + nCountDot = aNew.GetTokenCount(cSheetSep)-1; + + if( !nCountSemicolon ) + { + for( USHORT i = 0; i < aNew.Len(); i++ ) + { + sal_Unicode cNext = aNew.GetChar( i ); + if( cNext == '(' ) + { + nStartPosition = i+1; + } + } + } + else if( !nCountDot ) + { + for( USHORT i = 0; i < aNew.Len(); i++ ) + { + sal_Unicode cNext = aNew.GetChar( i ); + if( cNext == '(' ) + { + nStartPosition = i+1; + } + else if( cNext == cSep ) + { + nCount ++; + nEndPosition = i; + if( nCount == nActive ) + { + break; + } + nStartPosition = nEndPosition+1; + } + } + } + else + { + for( USHORT i = 0; i < aNew.Len(); i++ ) + { + sal_Unicode cNext = aNew.GetChar( i ); + if( cNext == '(' ) + { + nStartPosition = i+1; + } + else if( cNext == cSep ) + { + nCount ++; + nEndPosition = i; + if( nCount == nActive ) + { + break; + } + nStartPosition = nEndPosition+1; + } + else if( cNext == cSheetSep ) + { + continue; + } + } + } + + if( nStartPosition ) + { + aNew.Insert( 0x25BA, nStartPosition ); + ShowTipBelow( aNew ); + bFound = TRUE; + } + } + else + { + ShowTipBelow( aNew ); + bFound = TRUE; + } + } + } + } + } + else + { + USHORT nPosition = 0; + String aText = pEngine->GetWord( 0, aSel.nEndPos-1 ); + if( aText.GetChar( aSel.nEndPos-1 ) == '=' ) + { + break; + } + String aNew; + USHORT nParAutoPos = SCPOS_INVALID; + nPosition = aText.Len()+1; + if( pFormulaDataPara->FindText( aText, aNew, nParAutoPos, FALSE ) ) + { + if( aFormula.GetChar( nPosition ) =='(' ) + { + ShowTipBelow( aNew ); + bFound = TRUE; + } + else + break; + } + else + { + break; + } + } + } + } + } +} + +void ScInputHandler::ShowTip( const String& rText ) +{ + // aManualTip muss hinterher von aussen gesetzt werden + HideTip(); + + EditView* pActiveView = pTopView ? pTopView : pTableView; + if (pActiveView) + { + Point aPos; + Window* pWin = pActiveView->GetWindow(); + Cursor* pCur = pActiveView->GetCursor(); + if (pCur) + aPos = pWin->LogicToPixel( pCur->GetPos() ); + aPos = pWin->OutputToScreenPixel( aPos ); + Rectangle aRect( aPos, aPos ); + + USHORT nAlign = QUICKHELP_LEFT|QUICKHELP_BOTTOM; + nTipVisible = Help::ShowTip(pWin, aRect, rText, nAlign); + } +} + +void ScInputHandler::ShowTipBelow( const String& rText ) +{ + HideTipBelow(); + + EditView* pActiveView = pTopView ? pTopView : pTableView; + if ( pActiveView ) + { + Point aPos; + Window* pWin = pActiveView->GetWindow(); + Cursor* pCur = pActiveView->GetCursor(); + if ( pCur ) + { + Point aLogicPos = pCur->GetPos(); + aLogicPos.Y() += pCur->GetHeight(); + aPos = pWin->LogicToPixel( aLogicPos ); + } + aPos = pWin->OutputToScreenPixel( aPos ); + Rectangle aRect( aPos, aPos ); + USHORT nAlign = QUICKHELP_LEFT | QUICKHELP_TOP; + nTipVisibleSec = Help::ShowTip(pWin, aRect, rText, nAlign); + } +} + +void ScInputHandler::UseFormulaData() +{ + EditView* pActiveView = pTopView ? pTopView : pTableView; + ScDocShell* pDocSh = pActiveViewSh->GetViewData()->GetDocShell(); + const sal_Unicode cSep = ScCompiler::GetNativeSymbol(ocSep).GetChar(0); + const sal_Unicode cSheetSep = lcl_getSheetSeparator(pDocSh->GetDocument()); + + // Formeln duerfen nur 1 Absatz haben + if ( pActiveView && pFormulaData && pEngine->GetParagraphCount() == 1 ) + { + String aTotal = pEngine->GetText( (USHORT) 0 ); + ESelection aSel = pActiveView->GetSelection(); + aSel.Adjust(); + + // #59348# Durch Differenzen zwischen Tabelle und Eingabezeile + // (z.B. Clipboard mit Zeilenumbruechen) kann es sein, dass die Selektion + // nicht mehr zur EditEngine passt. Dann halt kommentarlos abbrechen: + + if ( aSel.nEndPos > aTotal.Len() ) + return; + + // steht der Cursor am Ende eines Wortes? + + if ( aSel.nEndPos > 0 ) + { + xub_StrLen nPos = aSel.nEndPos; + String aFormula = aTotal.Copy( 0, nPos );; + xub_StrLen nLeftParentPos = 0; + xub_StrLen nNextFStart = 0; + xub_StrLen nNextFEnd = 0; + xub_StrLen nArgPos = 0; + const IFunctionDescription* ppFDesc; + ::std::vector< ::rtl::OUString> aArgs; + USHORT nArgs; + BOOL bFound = FALSE; + + String aText = pEngine->GetWord( 0, aSel.nEndPos-1 ); + if ( aText.Len() ) + { + String aNew; + nAutoPos = SCPOS_INVALID; + if ( pFormulaData->FindText( aText, aNew, nAutoPos, FALSE ) ) + { + ShowTip( aNew ); + aAutoSearch = aText; + } + } + FormulaHelper aHelper(ScGlobal::GetStarCalcFunctionMgr()); + + while( !bFound ) + { + aFormula.AppendAscii( RTL_CONSTASCII_STRINGPARAM( ")" ) ); + nLeftParentPos = lcl_MatchParenthesis( aFormula, aFormula.Len()-1 ); + if( nLeftParentPos == STRING_NOTFOUND ) + break; + + // #160063# nLeftParentPos can be 0 if a parenthesis is inserted before the formula + sal_Unicode c = ( nLeftParentPos > 0 ) ? aFormula.GetChar( nLeftParentPos-1 ) : 0; + if( !((c >= 'A' && c<= 'Z') || (c>= 'a' && c<= 'z') ) ) + continue; + nNextFStart = aHelper.GetFunctionStart( aFormula, nLeftParentPos, TRUE); + if( aHelper.GetNextFunc( aFormula, FALSE, nNextFStart, &nNextFEnd, &ppFDesc, &aArgs ) ) + { + if( ppFDesc->getFunctionName().getLength() ) + { + nArgPos = aHelper.GetArgStart( aFormula, nNextFStart, 0 ); + nArgs = static_cast<USHORT>(ppFDesc->getParameterCount()); + + USHORT nActive = 0; + USHORT nCount = 0; + USHORT nCountSemicolon = 0; + USHORT nCountDot = 0; + USHORT nStartPosition = 0; + USHORT nEndPosition = 0; + BOOL bFlag = FALSE; + String aNew; + USHORT nParAutoPos = SCPOS_INVALID; + if( pFormulaDataPara->FindText( ppFDesc->getFunctionName(), aNew, nParAutoPos, FALSE ) ) + { + for( USHORT i=0; i < nArgs; i++ ) + { + xub_StrLen nLength = static_cast<xub_StrLen>(aArgs[i].getLength()); + if( nArgPos <= aFormula.Len()-1 ) + { + nActive = i+1; + bFlag = TRUE; + } + nArgPos+=nLength+1; + } + if( bFlag ) + { + nCountSemicolon = aNew.GetTokenCount(cSep)-1; + nCountDot = aNew.GetTokenCount(cSheetSep)-1; + + if( !nCountSemicolon ) + { + for( USHORT i = 0; i < aNew.Len(); i++ ) + { + sal_Unicode cNext = aNew.GetChar( i ); + if( cNext == '(' ) + { + nStartPosition = i+1; + } + } + } + else if( !nCountDot ) + { + for( USHORT i = 0; i < aNew.Len(); i++ ) + { + sal_Unicode cNext = aNew.GetChar( i ); + if( cNext == '(' ) + { + nStartPosition = i+1; + } + else if( cNext == cSep ) + { + nCount ++; + nEndPosition = i; + if( nCount == nActive ) + { + break; + } + nStartPosition = nEndPosition+1; + } + } + } + else + { + for( USHORT i = 0; i < aNew.Len(); i++ ) + { + sal_Unicode cNext = aNew.GetChar( i ); + if( cNext == '(' ) + { + nStartPosition = i+1; + } + else if( cNext == cSep ) + { + nCount ++; + nEndPosition = i; + if( nCount == nActive ) + { + break; + } + nStartPosition = nEndPosition+1; + } + else if( cNext == cSheetSep ) + { + continue; + } + } + } + + if( nStartPosition ) + { + aNew.Insert( 0x25BA, nStartPosition ); + ShowTipBelow( aNew ); + bFound = TRUE; + } + } + else + { + ShowTipBelow( aNew ); + bFound = TRUE; + } + } + } + } + } + } + } +} + +void ScInputHandler::NextFormulaEntry( BOOL bBack ) +{ + EditView* pActiveView = pTopView ? pTopView : pTableView; + if ( pActiveView && pFormulaData ) + { + String aNew; + if ( pFormulaData->FindText( aAutoSearch, aNew, nAutoPos, bBack ) ) + ShowTip( aNew ); // als QuickHelp anzeigen + } + + // bei Tab wird vorher immer HideCursor gerufen + + if (pActiveView) + pActiveView->ShowCursor(); +} + +void lcl_CompleteFunction( EditView* pView, const String& rInsert, BOOL& rParInserted ) +{ + if (pView) + { + ESelection aSel = pView->GetSelection(); + --aSel.nStartPos; + --aSel.nEndPos; + pView->SetSelection(aSel); + pView->SelectCurrentWord(); + + String aInsStr = rInsert; + xub_StrLen nInsLen = aInsStr.Len(); + BOOL bDoParen = ( nInsLen > 1 && aInsStr.GetChar(nInsLen-2) == '(' + && aInsStr.GetChar(nInsLen-1) == ')' ); + if ( bDoParen ) + { + // Klammern hinter Funktionsnamen nicht einfuegen, wenn direkt dahinter + // schon eine Klammer steht (z.B. wenn der Funktionsname geaendert wurde, + // #39393#). + + ESelection aWordSel = pView->GetSelection(); + String aOld = pView->GetEditEngine()->GetText((USHORT)0); + sal_Unicode cNext = aOld.GetChar(aWordSel.nEndPos); + if ( cNext == '(' ) + { + bDoParen = FALSE; + aInsStr.Erase( nInsLen - 2 ); // Klammern weglassen + } + } + + pView->InsertText( aInsStr, FALSE ); + + if ( bDoParen ) // Cursor zwischen die Klammern setzen + { + aSel = pView->GetSelection(); + --aSel.nStartPos; + --aSel.nEndPos; + pView->SetSelection(aSel); + + rParInserted = TRUE; + } + } +} + +void ScInputHandler::PasteFunctionData() +{ + if ( pFormulaData && nAutoPos != SCPOS_INVALID ) + { + TypedStrData* pData = (*pFormulaData)[nAutoPos]; + if (pData) + { + String aInsert = pData->GetString(); + BOOL bParInserted = FALSE; + + DataChanging(); // kann nicht neu sein + lcl_CompleteFunction( pTopView, aInsert, bParInserted ); + lcl_CompleteFunction( pTableView, aInsert, bParInserted ); + DataChanged(); + ShowTipCursor(); + + if (bParInserted) + AutoParAdded(); + } + } + + HideTip(); + + EditView* pActiveView = pTopView ? pTopView : pTableView; + if (pActiveView) + pActiveView->ShowCursor(); +} + +// +// Selektion berechnen und als Tip-Hilfe anzeigen +// + +String lcl_Calculate( const String& rFormula, ScDocument* pDoc, const ScAddress &rPos ) +{ + //! mit ScFormulaDlg::CalcValue zusammenfassen und ans Dokument verschieben !!!! + //! (Anfuehrungszeichen bei Strings werden nur hier eingefuegt) + + String aValue; + + if (rFormula.Len()) + { + ScFormulaCell* pCell = new ScFormulaCell( pDoc, rPos, rFormula ); + + // #35521# HACK! um bei ColRowNames kein #REF! zu bekommen, + // wenn ein Name eigentlich als Bereich in die Gesamt-Formel + // eingefuegt wird, bei der Einzeldarstellung aber als + // single-Zellbezug interpretiert wird + BOOL bColRowName = pCell->HasColRowName(); + if ( bColRowName ) + { + // ColRowName im RPN-Code? + if ( pCell->GetCode()->GetCodeLen() <= 1 ) + { // ==1: einzelner ist als Parameter immer Bereich + // ==0: es waere vielleicht einer, wenn.. + String aBraced( '(' ); + aBraced += rFormula; + aBraced += ')'; + delete pCell; + pCell = new ScFormulaCell( pDoc, rPos, aBraced ); + } + else + bColRowName = FALSE; + } + + USHORT nErrCode = pCell->GetErrCode(); + if ( nErrCode == 0 ) + { + SvNumberFormatter& aFormatter = *(pDoc->GetFormatTable()); + Color* pColor; + if ( pCell->IsValue() ) + { + double n = pCell->GetValue(); + ULONG nFormat = aFormatter.GetStandardFormat( n, 0, + pCell->GetFormatType(), ScGlobal::eLnge ); + aFormatter.GetInputLineString( n, nFormat, aValue ); + //! display OutputString but insert InputLineString + } + else + { + String aStr; + + pCell->GetString( aStr ); + ULONG nFormat = aFormatter.GetStandardFormat( + pCell->GetFormatType(), ScGlobal::eLnge); + aFormatter.GetOutputString( aStr, nFormat, + aValue, &pColor ); + + aValue.Insert('"',0); // in Anfuehrungszeichen + aValue+='"'; + //! Anfuehrungszeichen im String escapen ???? + } + + ScRange aTestRange; + if ( bColRowName || (aTestRange.Parse(rFormula) & SCA_VALID) ) + aValue.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " ..." )); // Bereich + } + else + aValue = ScGlobal::GetErrorString(nErrCode); + delete pCell; + } + + return aValue; +} + +void ScInputHandler::FormulaPreview() +{ + String aValue; + EditView* pActiveView = pTopView ? pTopView : pTableView; + if ( pActiveView && pActiveViewSh ) + { + String aPart = pActiveView->GetSelected(); + if (!aPart.Len()) + aPart = pEngine->GetText((USHORT)0); + ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocShell()->GetDocument(); + aValue = lcl_Calculate( aPart, pDoc, aCursorPos ); + } + + if (aValue.Len()) + { + ShowTip( aValue ); // als QuickHelp anzeigen + aManualTip = aValue; // nach ShowTip setzen + nAutoPos = SCPOS_INVALID; // Formel-Autocomplete aufheben + } +} + +void ScInputHandler::PasteManualTip() +{ + // drei Punkte am Ende -> Bereichsreferenz -> nicht einfuegen + // (wenn wir mal Matrix-Konstanten haben, kann das geaendert werden) + + xub_StrLen nTipLen = aManualTip.Len(); + if ( nTipLen && ( nTipLen < 3 || !aManualTip.Copy( nTipLen-3 ).EqualsAscii("...") ) ) + { + DataChanging(); // kann nicht neu sein + + String aInsert = aManualTip; + EditView* pActiveView = pTopView ? pTopView : pTableView; + if (!pActiveView->HasSelection()) + { + // nichts selektiert -> alles selektieren + xub_StrLen nOldLen = pEngine->GetTextLen(0); + ESelection aAllSel( 0, 0, 0, nOldLen ); + if ( pTopView ) + pTopView->SetSelection( aAllSel ); + if ( pTableView ) + pTableView->SetSelection( aAllSel ); + } + + ESelection aSel = pActiveView->GetSelection(); + aSel.Adjust(); + DBG_ASSERT( !aSel.nStartPara && !aSel.nEndPara, "Zuviele Absaetze in Formel" ); + if ( !aSel.nStartPos ) // Selektion ab Anfang? + { + if ( aSel.nEndPos == pEngine->GetTextLen(0) ) + { + // alles selektiert -> Anfuehrungszeichen weglassen + if ( aInsert.GetChar(0) == '"' ) + aInsert.Erase(0,1); + xub_StrLen nInsLen = aInsert.Len(); + if ( nInsLen && aInsert.GetChar(nInsLen-1) == '"' ) + aInsert.Erase( nInsLen-1 ); + } + else if ( aSel.nEndPos ) + { + // nicht alles selektiert -> Gleichheitszeichen nicht ueberschreiben + //! doppelte Gleichheitszeichen auch ??? + + aSel.nStartPos = 1; + if ( pTopView ) + pTopView->SetSelection( aSel ); + if ( pTableView ) + pTableView->SetSelection( aSel ); + } + } + if ( pTopView ) + pTopView->InsertText( aInsert, TRUE ); + if ( pTableView ) + pTableView->InsertText( aInsert, TRUE ); + + DataChanged(); + } + + HideTip(); +} + +void ScInputHandler::ResetAutoPar() +{ + nAutoPar = 0; +} + +void ScInputHandler::AutoParAdded() +{ + ++nAutoPar; // closing parenthesis can be overwritten +} + +BOOL ScInputHandler::CursorAtClosingPar() +{ + // test if the cursor is before a closing parenthesis + + // selection from SetReference has been removed before + EditView* pActiveView = pTopView ? pTopView : pTableView; + if ( pActiveView && !pActiveView->HasSelection() && bFormulaMode ) + { + ESelection aSel = pActiveView->GetSelection(); + xub_StrLen nPos = aSel.nStartPos; + String aFormula = pEngine->GetText((USHORT)0); + if ( nPos < aFormula.Len() && aFormula.GetChar(nPos) == ')' ) + return TRUE; + } + return FALSE; +} + +void ScInputHandler::SkipClosingPar() +{ + // this is called when a ')' is typed and the cursor is before a ')' + // that can be overwritten -> just set the cursor behind the ')' + + EditView* pActiveView = pTopView ? pTopView : pTableView; + if (pActiveView) + { + ESelection aSel = pActiveView->GetSelection(); + ++aSel.nStartPos; + ++aSel.nEndPos; + + // this is in a formula (only one paragraph), so the selection + // can be used directly for the TopView + + if ( pTopView ) + pTopView->SetSelection( aSel ); + if ( pTableView ) + pTableView->SetSelection( aSel ); + } + + DBG_ASSERT(nAutoPar, "SkipClosingPar: count is wrong"); + --nAutoPar; +} + +// +// Auto-Eingabe +// + +void ScInputHandler::GetColData() +{ + if ( pActiveViewSh ) + { + ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocShell()->GetDocument(); + + if ( pColumnData ) + pColumnData->FreeAll(); + else + { + pColumnData = new TypedScStrCollection; + pColumnData->SetCaseSensitive( TRUE ); // equal strings are handled in FindText + } + + pDoc->GetDataEntries( aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab(), + *pColumnData, TRUE ); + } +} + +void ScInputHandler::UseColData() // beim Tippen +{ + EditView* pActiveView = pTopView ? pTopView : pTableView; + if ( pActiveView && pColumnData ) + { + // nur anpassen, wenn Cursor am Ende steht + + ESelection aSel = pActiveView->GetSelection(); + aSel.Adjust(); + + USHORT nParCnt = pEngine->GetParagraphCount(); + if ( aSel.nEndPara+1 == nParCnt ) + { + xub_StrLen nParLen = pEngine->GetTextLen( aSel.nEndPara ); + if ( aSel.nEndPos == nParLen ) + { + String aText = GetEditText(pEngine); + if (aText.Len()) + { + String aNew; + nAutoPos = SCPOS_INVALID; // nix + if ( pColumnData->FindText( aText, aNew, nAutoPos, FALSE ) ) + { + // #45434# durch dBase Import etc. koennen Umbrueche im String sein, + // das wuerde hier mehrere Absaetze ergeben -> nicht gut + //! GetExactMatch funktioniert dann auch nicht + lcl_RemoveLineEnd( aNew ); + + // Absaetze beibehalten, nur den Rest anfuegen + //! genaue Ersetzung im EnterHandler !!! + + // ein Space zwischen Absaetzen: + ULONG nEdLen = pEngine->GetTextLen() + nParCnt - 1; + String aIns = aNew.Copy( (xub_StrLen)nEdLen ); + + // selection must be "backwards", so the cursor stays behind the last + // typed character + ESelection aSelection( aSel.nEndPara, aSel.nEndPos + aIns.Len(), + aSel.nEndPara, aSel.nEndPos ); + + // when editing in input line, apply to both edit views + if ( pTableView ) + { + pTableView->InsertText( aIns, FALSE ); + pTableView->SetSelection( aSelection ); + } + if ( pTopView ) + { + pTopView->InsertText( aIns, FALSE ); + pTopView->SetSelection( aSelection ); + } + + aAutoSearch = aText; // zum Weitersuchen - nAutoPos ist gesetzt + + if ( aText.Len() == aNew.Len() ) + { + // Wenn der eingegebene Text gefunden wurde, TAB nur dann + // verschlucken, wenn noch etwas kommt + + String aDummy; + USHORT nNextPos = nAutoPos; + bUseTab = pColumnData->FindText( aText, aDummy, nNextPos, FALSE ); + } + else + bUseTab = TRUE; + } + } + } + } + } +} + +void ScInputHandler::NextAutoEntry( BOOL bBack ) +{ + EditView* pActiveView = pTopView ? pTopView : pTableView; + if ( pActiveView && pColumnData ) + { + if ( nAutoPos != SCPOS_INVALID && aAutoSearch.Len() ) + { + // stimmt die Selektion noch? (kann per Maus geaendert sein) + + ESelection aSel = pActiveView->GetSelection(); + aSel.Adjust(); + USHORT nParCnt = pEngine->GetParagraphCount(); + if ( aSel.nEndPara+1 == nParCnt && aSel.nStartPara == aSel.nEndPara ) + { + String aText = GetEditText(pEngine); + xub_StrLen nSelLen = aSel.nEndPos - aSel.nStartPos; + xub_StrLen nParLen = pEngine->GetTextLen( aSel.nEndPara ); + if ( aSel.nEndPos == nParLen && aText.Len() == aAutoSearch.Len() + nSelLen ) + { + String aNew; + if ( pColumnData->FindText( aAutoSearch, aNew, nAutoPos, bBack ) ) + { + bInOwnChange = TRUE; // disable ModifyHdl (reset below) + + lcl_RemoveLineEnd( aNew ); + String aIns = aNew.Copy( aAutoSearch.Len() ); + + // when editing in input line, apply to both edit views + if ( pTableView ) + { + pTableView->DeleteSelected(); + pTableView->InsertText( aIns, FALSE ); + pTableView->SetSelection( ESelection( + aSel.nEndPara, aSel.nStartPos + aIns.Len(), + aSel.nEndPara, aSel.nStartPos ) ); + } + if ( pTopView ) + { + pTopView->DeleteSelected(); + pTopView->InsertText( aIns, FALSE ); + pTopView->SetSelection( ESelection( + aSel.nEndPara, aSel.nStartPos + aIns.Len(), + aSel.nEndPara, aSel.nStartPos ) ); + } + + bInOwnChange = FALSE; + } + else + { + // mehr gibts nicht + + Sound::Beep(); + } + } + } + } + } + + // bei Tab wird vorher immer HideCursor gerufen + + if (pActiveView) + pActiveView->ShowCursor(); +} + +// +// Klammern hervorheben +// + +void ScInputHandler::UpdateParenthesis() +{ + // Klammern suchen + + //! Klammer-Hervorhebung einzeln abschaltbar ???? + + BOOL bFound = FALSE; + if ( bFormulaMode && eMode != SC_INPUT_TOP ) + { + if ( pTableView && !pTableView->HasSelection() ) // Selektion ist immer unten + { + ESelection aSel = pTableView->GetSelection(); + if (aSel.nStartPos) + { + // Das Zeichen links vom Cursor wird angeschaut + + xub_StrLen nPos = aSel.nStartPos - 1; + String aFormula = pEngine->GetText((USHORT)0); + sal_Unicode c = aFormula.GetChar(nPos); + if ( c == '(' || c == ')' ) + { + xub_StrLen nOther = lcl_MatchParenthesis( aFormula, nPos ); + if ( nOther != STRING_NOTFOUND ) + { + SfxItemSet aSet( pEngine->GetEmptyItemSet() ); + aSet.Put( SvxWeightItem( WEIGHT_BOLD, EE_CHAR_WEIGHT ) ); + //! Unterscheidung, wenn die Zelle schon fett ist !!!! + + if (bParenthesisShown) + { + // alte Hervorhebung wegnehmen + USHORT nCount = pEngine->GetParagraphCount(); + for (USHORT i=0; i<nCount; i++) + pEngine->QuickRemoveCharAttribs( i, EE_CHAR_WEIGHT ); + } + + ESelection aSelThis( 0,nPos, 0,nPos+1 ); + pEngine->QuickSetAttribs( aSet, aSelThis ); + ESelection aSelOther( 0,nOther, 0,nOther+1 ); + pEngine->QuickSetAttribs( aSet, aSelOther ); + + // Dummy-InsertText fuer Update und Paint (Selektion ist leer) + pTableView->InsertText( EMPTY_STRING, FALSE ); + + bFound = TRUE; + } + } + } + + // mark parenthesis right of cursor if it will be overwritten (nAutoPar) + // with different color (COL_LIGHTBLUE) ?? + } + } + + // alte Hervorhebung wegnehmen, wenn keine neue gesetzt + + if ( bParenthesisShown && !bFound && pTableView ) + { + USHORT nCount = pEngine->GetParagraphCount(); + for (USHORT i=0; i<nCount; i++) + pTableView->RemoveCharAttribs( i, EE_CHAR_WEIGHT ); + } + + bParenthesisShown = bFound; +} + +void ScInputHandler::ViewShellGone(ScTabViewShell* pViewSh) // wird synchron aufgerufen! +{ + if ( pViewSh == pActiveViewSh ) + { + delete pLastState; + pLastState = NULL; + pLastPattern = NULL; + } + + if ( pViewSh == pRefViewSh ) + { + //! Die Eingabe kommt aus dem EnterHandler nicht mehr an + // Trotzdem wird immerhin der Editmodus beendet + + EnterHandler(); + bFormulaMode = FALSE; + pRefViewSh = NULL; + SFX_APP()->Broadcast( SfxSimpleHint( FID_REFMODECHANGED ) ); + SC_MOD()->SetRefInputHdl(NULL); + if (pInputWin) + pInputWin->SetFormulaMode(FALSE); + UpdateAutoCorrFlag(); + } + + pActiveViewSh = PTR_CAST( ScTabViewShell, SfxViewShell::Current() ); + + if ( pActiveViewSh && pActiveViewSh == pViewSh ) + { + DBG_ERROR("pActiveViewSh weg"); + pActiveViewSh = NULL; + } + + if ( SC_MOD()->GetInputOptions().GetTextWysiwyg() ) + UpdateRefDevice(); // don't keep old document's printer as RefDevice +} + +void ScInputHandler::UpdateActiveView() +{ + ImplCreateEditEngine(); + + // #i20588# Don't rely on focus to find the active edit view. Instead, the + // active pane at the start of editing is now stored (GetEditActivePart). + // GetActiveWin (the currently active pane) fails for ref input across the + // panes of a split view. + + Window* pShellWin = pActiveViewSh ? + pActiveViewSh->GetWindowByPos( pActiveViewSh->GetViewData()->GetEditActivePart() ) : + NULL; + + USHORT nCount = pEngine->GetViewCount(); + if (nCount > 0) + { + pTableView = pEngine->GetView(0); + for (USHORT i=1; i<nCount; i++) + { + EditView* pThis = pEngine->GetView(i); + Window* pWin = pThis->GetWindow(); + if ( pWin==pShellWin ) + pTableView = pThis; + } + } + else + pTableView = NULL; + + if (pInputWin) + pTopView = pInputWin->GetEditView(); + else + pTopView = NULL; +} + +void ScInputHandler::StopInputWinEngine( BOOL bAll ) +{ + if (pInputWin) + pInputWin->StopEditEngine( bAll ); + + pTopView = NULL; // invalid now +} + +EditView* ScInputHandler::GetActiveView() +{ + UpdateActiveView(); + return pTopView ? pTopView : pTableView; +} + +void ScInputHandler::ForgetLastPattern() +{ + pLastPattern = NULL; + if ( !pLastState && pActiveViewSh ) + pActiveViewSh->UpdateInputHandler( TRUE ); // Status neu holen + else + NotifyChange( pLastState, TRUE ); +} + +void ScInputHandler::UpdateAdjust( sal_Unicode cTyped ) +{ + SvxAdjust eSvxAdjust; + switch (eAttrAdjust) + { + case SVX_HOR_JUSTIFY_STANDARD: + { + BOOL bNumber = FALSE; + if (cTyped) // neu angefangen + bNumber = (cTyped>='0' && cTyped<='9'); // nur Ziffern sind Zahlen + else if ( pActiveViewSh ) + { + ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocShell()->GetDocument(); + bNumber = ( pDoc->GetCellType( aCursorPos ) == CELLTYPE_VALUE ); + } + eSvxAdjust = bNumber ? SVX_ADJUST_RIGHT : SVX_ADJUST_LEFT; + } + break; + case SVX_HOR_JUSTIFY_BLOCK: + eSvxAdjust = SVX_ADJUST_BLOCK; + break; + case SVX_HOR_JUSTIFY_CENTER: + eSvxAdjust = SVX_ADJUST_CENTER; + break; + case SVX_HOR_JUSTIFY_RIGHT: + eSvxAdjust = SVX_ADJUST_RIGHT; + break; + default: // SVX_HOR_JUSTIFY_LEFT + eSvxAdjust = SVX_ADJUST_LEFT; + break; + } + + BOOL bAsianVertical = pLastPattern && + ((const SfxBoolItem&)pLastPattern->GetItem( ATTR_STACKED )).GetValue() && + ((const SfxBoolItem&)pLastPattern->GetItem( ATTR_VERTICAL_ASIAN )).GetValue(); + if ( bAsianVertical ) + { + // always edit at top of cell -> LEFT when editing vertically + eSvxAdjust = SVX_ADJUST_LEFT; + } + + pEditDefaults->Put( SvxAdjustItem( eSvxAdjust, EE_PARA_JUST ) ); + pEngine->SetDefaults( *pEditDefaults ); + + nEditAdjust = sal::static_int_cast<USHORT>(eSvxAdjust); //! set at ViewData or with PostEditView + + pEngine->SetVertical( bAsianVertical ); +} + +void ScInputHandler::RemoveAdjust() +{ + // harte Ausrichtungs-Attribute loeschen + + BOOL bUndo = pEngine->IsUndoEnabled(); + if ( bUndo ) + pEngine->EnableUndo( FALSE ); + + // RemoveParaAttribs removes all paragraph attributes, including EE_PARA_JUST +#if 0 + BOOL bChange = FALSE; + USHORT nCount = pEngine->GetParagraphCount(); + for (USHORT i=0; i<nCount; i++) + { + const SfxItemSet& rOld = pEngine->GetParaAttribs( i ); + if ( rOld.GetItemState( EE_PARA_JUST ) == SFX_ITEM_SET ) + { + SfxItemSet aNew( rOld ); + aNew.ClearItem( EE_PARA_JUST ); + pEngine->SetParaAttribs( i, aNew ); + bChange = TRUE; + } + } +#endif + + // #89403# non-default paragraph attributes (e.g. from clipboard) + // must be turned into character attributes + pEngine->RemoveParaAttribs(); + + if ( bUndo ) + pEngine->EnableUndo( TRUE ); + + // ER 31.08.00 Only called in EnterHandler, don't change view anymore. +#if 0 + if (bChange) + { + EditView* pActiveView = pTopView ? pTopView : pTableView; + pActiveView->ShowCursor( FALSE, TRUE ); + } +#endif +} + +void ScInputHandler::RemoveRangeFinder() +{ + // pRangeFindList und Farben loeschen + + pEngine->SetUpdateMode(FALSE); + USHORT nCount = pEngine->GetParagraphCount(); // koennte gerade neu eingefuegt worden sein + for (USHORT i=0; i<nCount; i++) + pEngine->QuickRemoveCharAttribs( i, EE_CHAR_COLOR ); + pEngine->SetUpdateMode(TRUE); + + EditView* pActiveView = pTopView ? pTopView : pTableView; + pActiveView->ShowCursor( FALSE, TRUE ); + + DeleteRangeFinder(); // loescht die Liste und die Markierungen auf der Tabelle +} + +BOOL ScInputHandler::StartTable( sal_Unicode cTyped, BOOL bFromCommand ) +{ + // returns TRUE if a new edit mode was started + + BOOL bNewTable = FALSE; + + if (!bModified && ValidCol(aCursorPos.Col())) + { + if (pActiveViewSh) + { + ImplCreateEditEngine(); + UpdateActiveView(); + SyncViews(); + + ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocShell()->GetDocument(); + + const ScMarkData& rMark = pActiveViewSh->GetViewData()->GetMarkData(); + ScEditableTester aTester; + if ( rMark.IsMarked() || rMark.IsMultiMarked() ) + aTester.TestSelection( pDoc, rMark ); + else + aTester.TestSelectedBlock( pDoc, aCursorPos.Col(),aCursorPos.Row(), + aCursorPos.Col(),aCursorPos.Row(), rMark ); + if ( aTester.IsEditable() ) + { + // UpdateMode is enabled again in ScViewData::SetEditEngine (and not needed otherwise) + pEngine->SetUpdateMode( FALSE ); + + // Attribute in EditEngine uebernehmen + + const ScPatternAttr* pPattern = pDoc->GetPattern( aCursorPos.Col(), + aCursorPos.Row(), + aCursorPos.Tab() ); + if (pPattern != pLastPattern) + { + // Prozent-Format? + + const SfxItemSet& rAttrSet = pPattern->GetItemSet(); + const SfxPoolItem* pItem; + + if ( SFX_ITEM_SET == rAttrSet.GetItemState( ATTR_VALUE_FORMAT, TRUE, &pItem ) ) + { + ULONG nFormat = ((const SfxUInt32Item*)pItem)->GetValue(); + bCellHasPercentFormat = ( NUMBERFORMAT_PERCENT == + pDoc->GetFormatTable()->GetType( nFormat ) ); + } + else + bCellHasPercentFormat = FALSE; // Default: kein Prozent + + // Gueltigkeit angegeben? + + if ( SFX_ITEM_SET == rAttrSet.GetItemState( ATTR_VALIDDATA, TRUE, &pItem ) ) + nValidation = ((const SfxUInt32Item*)pItem)->GetValue(); + else + nValidation = 0; + + // EditEngine Defaults + + // Hier auf keinen Fall SetParaAttribs, weil die EditEngine evtl. + // schon gefuellt ist (bei Edit-Zellen). + // SetParaAttribs wuerde dann den Inhalt aendern + + //! ER 30.08.00 The SetDefaults is now (since MUST/src602 + //! EditEngine changes) implemented as a SetParaAttribs. + //! Any problems? + + pPattern->FillEditItemSet( pEditDefaults ); + pEngine->SetDefaults( *pEditDefaults ); + pLastPattern = pPattern; + bLastIsSymbol = pPattern->IsSymbolFont(); + + // Background color must be known for automatic font color. + // For transparent cell background, the document background color must be used. + + Color aBackCol = ((const SvxBrushItem&) + pPattern->GetItem( ATTR_BACKGROUND )).GetColor(); + ScModule* pScMod = SC_MOD(); + // #105733# SvtAccessibilityOptions::GetIsForBorders is no longer used (always assumed TRUE) + if ( aBackCol.GetTransparency() > 0 || + Application::GetSettings().GetStyleSettings().GetHighContrastMode() ) + aBackCol.SetColor( pScMod->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor ); + pEngine->SetBackgroundColor( aBackCol ); + + // Ausrichtung + + eAttrAdjust = (SvxCellHorJustify)((const SvxHorJustifyItem&)pPattern-> + GetItem(ATTR_HOR_JUSTIFY)).GetValue(); + if ( eAttrAdjust == SVX_HOR_JUSTIFY_REPEAT && + static_cast<const SfxBoolItem&>(pPattern->GetItem(ATTR_LINEBREAK)).GetValue() ) + { + // #i31843# "repeat" with "line breaks" is treated as default alignment + eAttrAdjust = SVX_HOR_JUSTIFY_STANDARD; + } + } + + // UpdateSpellSettings enables online spelling if needed + // -> also call if attributes are unchanged + + UpdateSpellSettings( TRUE ); // uses pLastPattern + + // Edit-Engine fuellen + + String aStr; + if (bTextValid) + { + pEngine->SetText(aCurrentText); + aStr = aCurrentText; + bTextValid = FALSE; + aCurrentText.Erase(); + } + else + aStr = GetEditText(pEngine); + + if (aStr.Len() > 3 && // Matrix-Formel ? + aStr.GetChar(0) == '{' && + aStr.GetChar(1) == '=' && + aStr.GetChar(aStr.Len()-1) == '}') + { + aStr.Erase(0,1); + aStr.Erase(aStr.Len()-1,1); + pEngine->SetText(aStr); + if ( pInputWin ) + pInputWin->SetTextString(aStr); + } + + UpdateAdjust( cTyped ); + + if ( bAutoComplete ) + GetColData(); + + if ( ( aStr.GetChar(0) == '=' || aStr.GetChar(0) == '+' || aStr.GetChar(0) == '-' ) && + !cTyped && !bCreatingFuncView ) + InitRangeFinder(aStr); // Formel wird editiert -> RangeFinder + + bNewTable = TRUE; // -> PostEditView-Aufruf + } + else + { + bProtected = TRUE; + eMode = SC_INPUT_NONE; + StopInputWinEngine( TRUE ); + UpdateFormulaMode(); + if ( pActiveViewSh && ( !bFromCommand || !bCommandErrorShown ) ) + { + // #97673# Prevent repeated error messages for the same cell from command events + // (for keyboard events, multiple messages are wanted). + // Set the flag before showing the error message because the command handler + // for the next IME command may be called when showing the dialog. + if ( bFromCommand ) + bCommandErrorShown = TRUE; + + pActiveViewSh->GetActiveWin()->GrabFocus(); + pActiveViewSh->ErrorMessage(aTester.GetMessageId()); + } + } + } + + if (!bProtected && pInputWin) + pInputWin->SetOkCancelMode(); + } + + return bNewTable; +} + +void lcl_SetTopSelection( EditView* pEditView, ESelection& rSel ) +{ + DBG_ASSERT( rSel.nStartPara==0 && rSel.nEndPara==0, "SetTopSelection: Para != 0" ); + + EditEngine* pEngine = pEditView->GetEditEngine(); + USHORT nCount = pEngine->GetParagraphCount(); + if (nCount > 1) + { + xub_StrLen nParLen = pEngine->GetTextLen(rSel.nStartPara); + while (rSel.nStartPos > nParLen && rSel.nStartPara+1 < nCount) + { + rSel.nStartPos -= nParLen + 1; // incl. Leerzeichen vom Umbruch + nParLen = pEngine->GetTextLen(++rSel.nStartPara); + } + + nParLen = pEngine->GetTextLen(rSel.nEndPara); + while (rSel.nEndPos > nParLen && rSel.nEndPara+1 < nCount) + { + rSel.nEndPos -= nParLen + 1; // incl. Leerzeichen vom Umbruch + nParLen = pEngine->GetTextLen(++rSel.nEndPara); + } + } + + ESelection aSel = pEditView->GetSelection(); + + if ( rSel.nStartPara != aSel.nStartPara || rSel.nEndPara != aSel.nEndPara + || rSel.nStartPos != aSel.nStartPos || rSel.nEndPos != aSel.nEndPos ) + pEditView->SetSelection( rSel ); +} + +void ScInputHandler::SyncViews( EditView* pSourceView ) +{ + ESelection aSel; + + if (pSourceView) + { + aSel = pSourceView->GetSelection(); + if (pTopView && pTopView != pSourceView) + pTopView->SetSelection( aSel ); + if (pTableView && pTableView != pSourceView) + lcl_SetTopSelection( pTableView, aSel ); + } + else if (pTopView && pTableView) + { + aSel = pTopView->GetSelection(); + lcl_SetTopSelection( pTableView, aSel ); + } +} + +IMPL_LINK( ScInputHandler, ModifyHdl, void *, EMPTYARG ) +{ + if ( !bInOwnChange && ( eMode==SC_INPUT_TYPE || eMode==SC_INPUT_TABLE ) && + pEngine && pEngine->GetUpdateMode() && pInputWin ) + { + // #102745# update input line from ModifyHdl for changes that are not + // wrapped by DataChanging/DataChanged calls (like Drag&Drop) + + String aText = GetEditText(pEngine); + lcl_RemoveTabs(aText); + pInputWin->SetTextString(aText); + } + return 0; +} + +BOOL ScInputHandler::DataChanging( sal_Unicode cTyped, BOOL bFromCommand ) // return TRUE = new view created +{ + bInOwnChange = TRUE; // disable ModifyHdl (reset in DataChanged) + + if ( eMode == SC_INPUT_NONE ) + return StartTable( cTyped, bFromCommand ); + else + return FALSE; +} + +void ScInputHandler::DataChanged( BOOL bFromTopNotify ) +{ + ImplCreateEditEngine(); + + if (eMode==SC_INPUT_NONE) + eMode = SC_INPUT_TYPE; + + if ( eMode == SC_INPUT_TOP && pTopView && !bFromTopNotify ) + { + // table EditEngine is formatted below, input line needs formatting after paste + // #i20282# not when called from the input line's modify handler + pTopView->GetEditEngine()->QuickFormatDoc( TRUE ); + + // #i23720# QuickFormatDoc hides the cursor, but can't show it again because it + // can't safely access the EditEngine's current view, so the cursor has to be + // shown again here. + pTopView->ShowCursor(); + } + + bModified = TRUE; + bSelIsRef = FALSE; + + if ( pRangeFindList && !bInRangeUpdate ) + RemoveRangeFinder(); // Attribute und Markierung loeschen + + UpdateParenthesis(); // Hervorhebung der Klammern neu + + // ER 31.08.00 New SetDefaults sets ParaAttribs, don't clear them away ... +// RemoveAdjust(); // #40255# harte Ausrichtungs-Attribute loeschen + + if (eMode==SC_INPUT_TYPE || eMode==SC_INPUT_TABLE) + { + String aText = GetEditText(pEngine); + lcl_RemoveTabs(aText); + + if ( pInputWin ) + pInputWin->SetTextString(aText); + } + + // wenn der Cursor vor dem Absatzende steht, werden Teile rechts rausgeschoben + // (unabhaengig von eMode) -> View anpassen! + // wenn der Cursor am Ende steht, reicht der Status-Handler an der ViewData + + // #93767# first make sure the status handler is called now if the cursor + // is outside the visible area + pEngine->QuickFormatDoc(); + + EditView* pActiveView = pTopView ? pTopView : pTableView; + if (pActiveView && pActiveViewSh) + { + ScViewData* pViewData = pActiveViewSh->GetViewData(); + + BOOL bNeedGrow = ( nEditAdjust != SVX_ADJUST_LEFT ); // rechtsbuendig immer + if (!bNeedGrow) + { + // Cursor vor dem Ende? + ESelection aSel = pActiveView->GetSelection(); + aSel.Adjust(); + bNeedGrow = ( aSel.nEndPos != pEngine->GetTextLen(aSel.nEndPara) ); + } + if (!bNeedGrow) + { + bNeedGrow = pViewData->GetDocument()->IsLayoutRTL( pViewData->GetTabNo() ); + } + if (bNeedGrow) + { + // adjust inplace view + pViewData->EditGrowY(); + pViewData->EditGrowX(); + } + } + + UpdateFormulaMode(); + bTextValid = FALSE; // Aenderungen sind nur in der Edit-Engine + bInOwnChange = FALSE; +} + +void ScInputHandler::UpdateFormulaMode() +{ + SfxApplication* pSfxApp = SFX_APP(); + + if ( pEngine->GetParagraphCount() == 1 && + ( pEngine->GetText((USHORT)0).GetChar(0) == '=' || + pEngine->GetText((USHORT)0).GetChar(0) == '+' || + pEngine->GetText((USHORT)0).GetChar(0) == '-' ) && + !bProtected ) + { + if (!bFormulaMode) + { + bFormulaMode = TRUE; + pRefViewSh = pActiveViewSh; + pSfxApp->Broadcast( SfxSimpleHint( FID_REFMODECHANGED ) ); + SC_MOD()->SetRefInputHdl(this); + if (pInputWin) + pInputWin->SetFormulaMode(TRUE); + + if ( bAutoComplete ) + GetFormulaData(); + + UpdateParenthesis(); + UpdateAutoCorrFlag(); + } + } + else // ausschalten + { + if (bFormulaMode) + { + ShowRefFrame(); + bFormulaMode = FALSE; + pRefViewSh = NULL; + pSfxApp->Broadcast( SfxSimpleHint( FID_REFMODECHANGED ) ); + SC_MOD()->SetRefInputHdl(NULL); + if (pInputWin) + pInputWin->SetFormulaMode(FALSE); + UpdateAutoCorrFlag(); + } + } +} + +void ScInputHandler::ShowRefFrame() +{ + // #123169# Modifying pActiveViewSh here would interfere with the bInEnterHandler / bRepeat + // checks in NotifyChange, and lead to keeping the wrong value in pActiveViewSh. + // A local variable is used instead. + ScTabViewShell* pVisibleSh = PTR_CAST( ScTabViewShell, SfxViewShell::Current() ); + if ( pRefViewSh && pRefViewSh != pVisibleSh ) + { + BOOL bFound = FALSE; + SfxViewFrame* pRefFrame = pRefViewSh->GetViewFrame(); + SfxViewFrame* pOneFrame = SfxViewFrame::GetFirst(); + while ( pOneFrame && !bFound ) + { + if ( pOneFrame == pRefFrame ) + bFound = TRUE; + pOneFrame = SfxViewFrame::GetNext( *pOneFrame ); + } + + if (bFound) + { + // Hier wird sich darauf verlassen, dass Activate synchron funktioniert + // (dabei wird pActiveViewSh umgesetzt) + + pRefViewSh->SetActive(); // Appear und SetViewFrame + + // pLastState wird im NotifyChange aus dem Activate richtig gesetzt + } + else + { + DBG_ERROR("ViewFrame fuer Referenzeingabe ist nicht mehr da"); + } + } +} + +void ScInputHandler::RemoveSelection() +{ + EditView* pActiveView = pTopView ? pTopView : pTableView; + if (!pActiveView) + return; + + ESelection aSel = pActiveView->GetSelection(); + aSel.nStartPara = aSel.nEndPara; + aSel.nStartPos = aSel.nEndPos; + if (pTableView) + pTableView->SetSelection( aSel ); + if (pTopView) + pTopView->SetSelection( aSel ); +} + +void ScInputHandler::InvalidateAttribs() +{ + SfxViewFrame* pViewFrm = SfxViewFrame::Current(); + if (pViewFrm) + { + SfxBindings& rBindings = pViewFrm->GetBindings(); + + rBindings.Invalidate( SID_ATTR_CHAR_FONT ); + rBindings.Invalidate( SID_ATTR_CHAR_FONTHEIGHT ); + rBindings.Invalidate( SID_ATTR_CHAR_COLOR ); + + rBindings.Invalidate( SID_ATTR_CHAR_WEIGHT ); + rBindings.Invalidate( SID_ATTR_CHAR_POSTURE ); + rBindings.Invalidate( SID_ATTR_CHAR_UNDERLINE ); + rBindings.Invalidate( SID_ULINE_VAL_NONE ); + rBindings.Invalidate( SID_ULINE_VAL_SINGLE ); + rBindings.Invalidate( SID_ULINE_VAL_DOUBLE ); + rBindings.Invalidate( SID_ULINE_VAL_DOTTED ); + + rBindings.Invalidate( SID_HYPERLINK_GETLINK ); + } +} + + +// +// --------------- public Methoden -------------------------------------------- +// + +void ScInputHandler::SetMode( ScInputMode eNewMode ) +{ + if ( eMode == eNewMode ) + return; + + ImplCreateEditEngine(); + + if (bProtected) + { + eMode = SC_INPUT_NONE; + StopInputWinEngine( TRUE ); + if (pActiveViewSh) + pActiveViewSh->GetActiveWin()->GrabFocus(); + return; + } + + bInOwnChange = TRUE; // disable ModifyHdl (reset below) + + ScInputMode eOldMode = eMode; + eMode = eNewMode; + if (eOldMode == SC_INPUT_TOP && eNewMode != eOldMode) + StopInputWinEngine( FALSE ); + + if (eMode==SC_INPUT_TOP || eMode==SC_INPUT_TABLE) + { + if (eOldMode == SC_INPUT_NONE) // not when switching between modes + { + if (StartTable(0, FALSE)) // 0 = look at existing document content for text or number + { + if (pActiveViewSh) + pActiveViewSh->GetViewData()->GetDocShell()->PostEditView( pEngine, aCursorPos ); + } + } + + USHORT nPara = pEngine->GetParagraphCount()-1; + xub_StrLen nLen = pEngine->GetText(nPara).Len(); + USHORT nCount = pEngine->GetViewCount(); + + for (USHORT i=0; i<nCount; i++) + { + if ( eMode == SC_INPUT_TABLE && eOldMode == SC_INPUT_TOP ) + { + // Selektion bleibt + } + else + { + pEngine->GetView(i)-> + SetSelection( ESelection( nPara, nLen, nPara, nLen ) ); + } + pEngine->GetView(i)->ShowCursor(FALSE); + } + } + + UpdateActiveView(); + if (eMode==SC_INPUT_TABLE || eMode==SC_INPUT_TYPE) + { + if (pTableView) + pTableView->SetEditEngineUpdateMode(TRUE); + } + else + { + if (pTopView) + pTopView->SetEditEngineUpdateMode(TRUE); + } + + if (eNewMode != eOldMode) + UpdateFormulaMode(); + + bInOwnChange = FALSE; +} + +//---------------------------------------------------------------------------------------- + +// lcl_IsNumber - TRUE, wenn nur Ziffern (dann keine Autokorrektur) + +BOOL lcl_IsNumber(const String& rString) +{ + xub_StrLen nLen = rString.Len(); + for (xub_StrLen i=0; i<nLen; i++) + { + sal_Unicode c = rString.GetChar(i); + if ( c < '0' || c > '9' ) + return FALSE; + } + return TRUE; +} + +void lcl_SelectionToEnd( EditView* pView ) +{ + if ( pView ) + { + EditEngine* pEngine = pView->GetEditEngine(); + USHORT nParCnt = pEngine->GetParagraphCount(); + if ( nParCnt == 0 ) + nParCnt = 1; + ESelection aSel( nParCnt-1, pEngine->GetTextLen(nParCnt-1) ); // empty selection, cursor at the end + pView->SetSelection( aSel ); + } +} + +void ScInputHandler::EnterHandler( BYTE nBlockMode ) +{ + // #62806# Bei Makro-Aufrufen fuer Gueltigkeit kann Tod und Teufel passieren, + // darum dafuer sorgen, dass EnterHandler nicht verschachtelt gerufen wird: + + if (bInEnterHandler) return; + bInEnterHandler = TRUE; + bInOwnChange = TRUE; // disable ModifyHdl (reset below) + + ImplCreateEditEngine(); + + BOOL bMatrix = ( nBlockMode == SC_ENTER_MATRIX ); + + SfxApplication* pSfxApp = SFX_APP(); + EditTextObject* pObject = NULL; + ScPatternAttr* pCellAttrs = NULL; + BOOL bAttrib = FALSE; // Formatierung vorhanden ? + BOOL bForget = FALSE; // wegen Gueltigkeit streichen ? + + String aString = GetEditText(pEngine); + EditView* pActiveView = pTopView ? pTopView : pTableView; + if (bModified && pActiveView && aString.Len() && !lcl_IsNumber(aString)) + { + if ( pColumnData && nAutoPos != SCPOS_INVALID ) + { + // #i47125# If AutoInput appended something, do the final AutoCorrect + // with the cursor at the end of the input. + + lcl_SelectionToEnd(pTopView); + lcl_SelectionToEnd(pTableView); + } + + if (pTopView) + pTopView->CompleteAutoCorrect(); // #59759# CompleteAutoCorrect fuer beide Views + if (pTableView) + pTableView->CompleteAutoCorrect(); + aString = GetEditText(pEngine); + } + lcl_RemoveTabs(aString); + + // Test, ob zulaessig (immer mit einfachem String) + + if ( bModified && nValidation && pActiveViewSh ) + { + ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocument(); + const ScValidationData* pData = pDoc->GetValidationEntry( nValidation ); + if (pData && pData->HasErrMsg()) + { + // #i67990# don't use pLastPattern in EnterHandler + const ScPatternAttr* pPattern = pDoc->GetPattern( aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab() ); + BOOL bOk = pData->IsDataValid( aString, *pPattern, aCursorPos ); + + if (!bOk) + { + if ( pActiveViewSh ) // falls aus MouseButtonDown gekommen + pActiveViewSh->StopMarking(); // (die InfoBox verschluckt das MouseButtonUp) + + //! es gibt noch Probleme, wenn die Eingabe durch Aktivieren einer + //! anderen View ausgeloest wurde + + Window* pParent = Application::GetDefDialogParent(); + if ( pData->DoError( pParent, aString, aCursorPos ) ) + bForget = TRUE; // Eingabe nicht uebernehmen + } + } + } + + // check for input into DataPilot table + + if ( bModified && pActiveViewSh && !bForget ) + { + ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocument(); + ScDPObject* pDPObj = pDoc->GetDPAtCursor( aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab() ); + if ( pDPObj ) + { + // any input within the DataPilot table is either a valid renaming + // or an invalid action - normal cell input is always aborted + + pActiveViewSh->DataPilotInput( aCursorPos, aString ); + bForget = TRUE; + } + } + + pEngine->CompleteOnlineSpelling(); + BOOL bSpellErrors = !bFormulaMode && pEngine->HasOnlineSpellErrors(); + if ( bSpellErrors ) + { + // #i3820# If the spell checker flags numerical input as error, + // it still has to be treated as number, not EditEngine object. + + if ( pActiveViewSh ) + { + ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocument(); + // #i67990# don't use pLastPattern in EnterHandler + const ScPatternAttr* pPattern = pDoc->GetPattern( aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab() ); + SvNumberFormatter* pFormatter = pDoc->GetFormatTable(); + // without conditional format, as in ScColumn::SetString + sal_uInt32 nFormat = pPattern->GetNumberFormat( pFormatter ); + double nVal; + if ( pFormatter->IsNumberFormat( aString, nFormat, nVal ) ) + { + bSpellErrors = FALSE; // ignore the spelling errors + } + } + } + + // After RemoveAdjust, the EditView must not be repainted (has wrong font size etc). + // SetUpdateMode must come after CompleteOnlineSpelling. + // The view is hidden in any case below (Broadcast). + pEngine->SetUpdateMode( FALSE ); + + if ( bModified && !bForget ) // was wird eingeben (Text/Objekt) ? + { + USHORT nParCnt = pEngine->GetParagraphCount(); + if ( nParCnt == 0 ) + nParCnt = 1; + ESelection aSel( 0, 0, nParCnt-1, pEngine->GetTextLen(nParCnt-1) ); + SfxItemSet aOldAttribs = pEngine->GetAttribs( aSel ); + const SfxPoolItem* pItem = NULL; + + // find common (cell) attributes before RemoveAdjust + + if ( pActiveViewSh ) + { + SfxItemSet* pCommonAttrs = NULL; + for (USHORT nId = EE_CHAR_START; nId <= EE_CHAR_END; nId++) + { + SfxItemState eState = aOldAttribs.GetItemState( nId, FALSE, &pItem ); + if ( eState == SFX_ITEM_SET && + nId != EE_CHAR_ESCAPEMENT && nId != EE_CHAR_PAIRKERNING && + nId != EE_CHAR_KERNING && nId != EE_CHAR_XMLATTRIBS && + *pItem != pEditDefaults->Get(nId) ) + { + if ( !pCommonAttrs ) + pCommonAttrs = new SfxItemSet( pEngine->GetEmptyItemSet() ); + pCommonAttrs->Put( *pItem ); + } + } + + if ( pCommonAttrs ) + { + ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocument(); + pCellAttrs = new ScPatternAttr( pDoc->GetPool() ); + pCellAttrs->GetFromEditItemSet( pCommonAttrs ); + delete pCommonAttrs; + } + } + + // clear ParaAttribs (including adjustment) + + RemoveAdjust(); + + // check if EditObject is needed + + if ( bSpellErrors || nParCnt > 1 ) + bAttrib = TRUE; + else + { + for (USHORT nId = EE_CHAR_START; nId <= EE_CHAR_END && !bAttrib; nId++) + { + SfxItemState eState = aOldAttribs.GetItemState( nId, FALSE, &pItem ); + if (eState == SFX_ITEM_DONTCARE) + bAttrib = TRUE; + else if (eState == SFX_ITEM_SET) + { + // keep same items in EditEngine as in ScEditAttrTester + if ( nId == EE_CHAR_ESCAPEMENT || nId == EE_CHAR_PAIRKERNING || + nId == EE_CHAR_KERNING || nId == EE_CHAR_XMLATTRIBS ) + { + if ( *pItem != pEditDefaults->Get(nId) ) + bAttrib = TRUE; + } + } + } + + // Feldbefehle enthalten? + + SfxItemState eFieldState = aOldAttribs.GetItemState( EE_FEATURE_FIELD, FALSE ); + if ( eFieldState == SFX_ITEM_DONTCARE || eFieldState == SFX_ITEM_SET ) + bAttrib = TRUE; + + // not converted characters? + + SfxItemState eConvState = aOldAttribs.GetItemState( EE_FEATURE_NOTCONV, FALSE ); + if ( eConvState == SFX_ITEM_DONTCARE || eConvState == SFX_ITEM_SET ) + bAttrib = TRUE; + + // Formeln immer als Formeln erkennen (#38309#) + // (der Test vorher ist trotzdem noetig wegen Zell-Attributen) + } + + if (bMatrix) + bAttrib = FALSE; + + if (bAttrib) + { + ULONG nCtrl = pEngine->GetControlWord(); + ULONG nWantBig = bSpellErrors ? EE_CNTRL_ALLOWBIGOBJS : 0; + if ( ( nCtrl & EE_CNTRL_ALLOWBIGOBJS ) != nWantBig ) + pEngine->SetControlWord( (nCtrl & ~EE_CNTRL_ALLOWBIGOBJS) | nWantBig ); + pObject = pEngine->CreateTextObject(); + } + else if (bAutoComplete) // Gross-/Kleinschreibung anpassen + { + if (pColumnData) + pColumnData->GetExactMatch( aString ); + + //! effizienter in der Liste suchen (ScUserList, nur einmal ToUpper) + + USHORT nIndex; + ScUserListData* pData = ScGlobal::GetUserList()->GetData(aString); + if ( pData && pData->GetSubIndex( aString, nIndex ) ) + aString = pData->GetSubStr( nIndex ); + } + } + + // don't rely on ShowRefFrame switching the active view synchronously + // execute the function directly on the correct view's bindings instead + // pRefViewSh is reset in ShowRefFrame - get pointer before ShowRefFrame call + ScTabViewShell* pExecuteSh = pRefViewSh ? pRefViewSh : pActiveViewSh; + + if (bFormulaMode) + { + ShowRefFrame(); + + if (pExecuteSh) + { + pExecuteSh->SetTabNo(aCursorPos.Tab()); + pExecuteSh->ActiveGrabFocus(); + } + + bFormulaMode = FALSE; + pSfxApp->Broadcast( SfxSimpleHint( FID_REFMODECHANGED ) ); + SC_MOD()->SetRefInputHdl(NULL); + if (pInputWin) + pInputWin->SetFormulaMode(FALSE); + UpdateAutoCorrFlag(); + } + pRefViewSh = NULL; // auch ohne FormulaMode wegen Funktions-AP + DeleteRangeFinder(); + ResetAutoPar(); + + BOOL bOldMod = bModified; + + bModified = FALSE; + bSelIsRef = FALSE; + eMode = SC_INPUT_NONE; + StopInputWinEngine( TRUE ); + + // #123344# Text input (through number formats) or ApplySelectionPattern modify + // the cell's attributes, so pLastPattern is no longer valid + pLastPattern = NULL; + + if (bOldMod && !bProtected && !bForget) + { + // keine typographische Anfuehrungszeichen in Formeln + + if ( aString.GetChar(0) == '=' ) + { + SvxAutoCorrect* pAuto = SvxAutoCorrCfg::Get()->GetAutoCorrect(); + if ( pAuto ) + { + sal_Unicode cReplace = pAuto->GetStartDoubleQuote(); + if( !cReplace ) + cReplace = ScGlobal::pLocaleData->getDoubleQuotationMarkStart().GetChar(0); + if ( cReplace != '"' ) + aString.SearchAndReplaceAll( cReplace, '"' ); + + cReplace = pAuto->GetEndDoubleQuote(); + if( !cReplace ) + cReplace = ScGlobal::pLocaleData->getDoubleQuotationMarkEnd().GetChar(0); + if ( cReplace != '"' ) + aString.SearchAndReplaceAll( cReplace, '"' ); + + cReplace = pAuto->GetStartSingleQuote(); + if( !cReplace ) + cReplace = ScGlobal::pLocaleData->getQuotationMarkStart().GetChar(0); + if ( cReplace != '\'' ) + aString.SearchAndReplaceAll( cReplace, '\'' ); + + cReplace = pAuto->GetEndSingleQuote(); + if( !cReplace ) + cReplace = ScGlobal::pLocaleData->getQuotationMarkEnd().GetChar(0); + if ( cReplace != '\'' ) + aString.SearchAndReplaceAll( cReplace, '\'' ); + } + } + + pSfxApp->Broadcast( SfxSimpleHint( FID_KILLEDITVIEW_NOPAINT ) ); + + if ( pExecuteSh ) + { + SfxBindings& rBindings = pExecuteSh->GetViewFrame()->GetBindings(); + + USHORT nId = FID_INPUTLINE_ENTER; + if ( nBlockMode == SC_ENTER_BLOCK ) + nId = FID_INPUTLINE_BLOCK; + else if ( nBlockMode == SC_ENTER_MATRIX ) + nId = FID_INPUTLINE_MATRIX; + + ScInputStatusItem aItem( FID_INPUTLINE_STATUS, + aCursorPos, aCursorPos, aCursorPos, + aString, pObject ); + const SfxPoolItem* aArgs[2]; + aArgs[0] = &aItem; + aArgs[1] = NULL; + rBindings.Execute( nId, aArgs ); + } + + delete pLastState; // pLastState enthaelt noch den alten Text + pLastState = NULL; + } + else + pSfxApp->Broadcast( SfxSimpleHint( FID_KILLEDITVIEW ) ); + + if ( bOldMod && pExecuteSh && pCellAttrs && !bForget ) + { + // mit Eingabe zusammenfassen ? + pExecuteSh->ApplySelectionPattern( *pCellAttrs, TRUE, TRUE ); + pExecuteSh->AdjustBlockHeight(); + } + + delete pCellAttrs; + delete pObject; + + HideTip(); + + nFormSelStart = nFormSelEnd = 0; + aFormText.Erase(); + + bInOwnChange = FALSE; + bInEnterHandler = FALSE; +} + +void ScInputHandler::CancelHandler() +{ + bInOwnChange = TRUE; // disable ModifyHdl (reset below) + + ImplCreateEditEngine(); + + bModified = FALSE; + + // don't rely on ShowRefFrame switching the active view synchronously + // execute the function directly on the correct view's bindings instead + // pRefViewSh is reset in ShowRefFrame - get pointer before ShowRefFrame call + ScTabViewShell* pExecuteSh = pRefViewSh ? pRefViewSh : pActiveViewSh; + + if (bFormulaMode) + { + ShowRefFrame(); + if (pExecuteSh) + { + pExecuteSh->SetTabNo(aCursorPos.Tab()); + pExecuteSh->ActiveGrabFocus(); + } + bFormulaMode = FALSE; + SFX_APP()->Broadcast( SfxSimpleHint( FID_REFMODECHANGED ) ); + SC_MOD()->SetRefInputHdl(NULL); + if (pInputWin) + pInputWin->SetFormulaMode(FALSE); + UpdateAutoCorrFlag(); + } + pRefViewSh = NULL; // auch ohne FormulaMode wegen Funktions-AP + DeleteRangeFinder(); + ResetAutoPar(); + + eMode = SC_INPUT_NONE; + StopInputWinEngine( TRUE ); + if (pExecuteSh) + pExecuteSh->StopEditShell(); + + aCursorPos.Set(MAXCOL+1,0,0); // Flag, dass ungueltig + pEngine->SetText(String()); + + if ( !pLastState && pExecuteSh ) + pExecuteSh->UpdateInputHandler( TRUE ); // Status neu holen + else + NotifyChange( pLastState, TRUE ); + + nFormSelStart = nFormSelEnd = 0; + aFormText.Erase(); + + bInOwnChange = FALSE; +} + +BOOL ScInputHandler::IsModalMode( SfxObjectShell* pDocSh ) +{ + // Referenzen auf unbenanntes Dokument gehen nicht + + return bFormulaMode && pRefViewSh + && pRefViewSh->GetViewData()->GetDocument()->GetDocumentShell() != pDocSh + && !pDocSh->HasName(); +} + +void ScInputHandler::AddRefEntry() +{ + const sal_Unicode cSep = ScCompiler::GetNativeSymbol(ocSep).GetChar(0); + UpdateActiveView(); + if (!pTableView && !pTopView) + return; // z.B. FillMode + + DataChanging(); // kann nicht neu sein + + RemoveSelection(); + if (pTableView) + pTableView->InsertText( cSep, FALSE ); + if (pTopView) + pTopView->InsertText( cSep, FALSE ); + + DataChanged(); +} + +void ScInputHandler::SetReference( const ScRange& rRef, ScDocument* pDoc ) +{ + HideTip(); + + BOOL bOtherDoc = ( pRefViewSh && + pRefViewSh->GetViewData()->GetDocument() != pDoc ); + if (bOtherDoc) + if (!pDoc->GetDocumentShell()->HasName()) + { + // Referenzen auf unbenanntes Dokument gehen nicht + // (SetReference sollte dann auch nicht gerufen werden) + + return; + } + + UpdateActiveView(); + if (!pTableView && !pTopView) + return; // z.B. FillMode + + // nie das "=" ueberschreiben! + EditView* pActiveView = pTopView ? pTopView : pTableView; + ESelection aSel = pActiveView->GetSelection(); + aSel.Adjust(); + if ( aSel.nStartPara == 0 && aSel.nStartPos == 0 ) + return; + + DataChanging(); // kann nicht neu sein + + // Selektion umdrehen, falls rueckwaerts (noetig ???) + + if (pTableView) + { + ESelection aTabSel = pTableView->GetSelection(); + if (aTabSel.nStartPos > aTabSel.nEndPos && aTabSel.nStartPara == aTabSel.nEndPara) + { + aTabSel.Adjust(); + pTableView->SetSelection(aTabSel); + } + } + if (pTopView) + { + ESelection aTopSel = pTopView->GetSelection(); + if (aTopSel.nStartPos > aTopSel.nEndPos && aTopSel.nStartPara == aTopSel.nEndPara) + { + aTopSel.Adjust(); + pTopView->SetSelection(aTopSel); + } + } + + // String aus Referenz erzeugen + + String aRefStr; + const ScAddress::Details aAddrDetails( pDoc, aCursorPos ); + if (bOtherDoc) + { + // Referenz auf anderes Dokument + + DBG_ASSERT(rRef.aStart.Tab()==rRef.aEnd.Tab(), "nStartTab!=nEndTab"); + + String aTmp; + rRef.Format( aTmp, SCA_VALID|SCA_TAB_3D, pDoc, aAddrDetails ); // immer 3d + + SfxObjectShell* pObjSh = pDoc->GetDocumentShell(); + // #i75893# convert escaped URL of the document to something user friendly +// String aFileName = pObjSh->GetMedium()->GetName(); + String aFileName = pObjSh->GetMedium()->GetURLObject().GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS ); + + aRefStr = '\''; + aRefStr += aFileName; + aRefStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( "'#" )); + aRefStr += aTmp; + } + else + { + if ( ( rRef.aStart.Tab() != aCursorPos.Tab() || + rRef.aStart.Tab() != rRef.aEnd.Tab() ) && pDoc ) + rRef.Format( aRefStr, SCA_VALID|SCA_TAB_3D, pDoc, aAddrDetails ); + else + rRef.Format( aRefStr, SCA_VALID, pDoc, aAddrDetails ); + } + + if (pTableView || pTopView) + { + if (pTableView) + pTableView->InsertText( aRefStr, TRUE ); + if (pTopView) + pTopView->InsertText( aRefStr, TRUE ); + + DataChanged(); + } + + bSelIsRef = TRUE; +} + +void ScInputHandler::InsertFunction( const String& rFuncName, BOOL bAddPar ) +{ + if ( eMode == SC_INPUT_NONE ) + { + DBG_ERROR("InsertFunction, nicht im Eingabemodus"); + return; + } + + UpdateActiveView(); + if (!pTableView && !pTopView) + return; // z.B. FillMode + + DataChanging(); // kann nicht neu sein + + String aText = rFuncName; + if (bAddPar) + aText.AppendAscii(RTL_CONSTASCII_STRINGPARAM( "()" )); + + if (pTableView) + { + pTableView->InsertText( aText, FALSE ); + if (bAddPar) + { + ESelection aSel = pTableView->GetSelection(); + --aSel.nStartPos; + --aSel.nEndPos; + pTableView->SetSelection(aSel); + } + } + if (pTopView) + { + pTopView->InsertText( aText, FALSE ); + if (bAddPar) + { + ESelection aSel = pTopView->GetSelection(); + --aSel.nStartPos; + --aSel.nEndPos; + pTopView->SetSelection(aSel); + } + } + + DataChanged(); + + if (bAddPar) + AutoParAdded(); +} + +void ScInputHandler::ClearText() +{ + if ( eMode == SC_INPUT_NONE ) + { + DBG_ERROR("ClearText, nicht im Eingabemodus"); + return; + } + + UpdateActiveView(); + if (!pTableView && !pTopView) + return; // z.B. FillMode + + DataChanging(); // darf nicht neu sein + + String aEmpty; + if (pTableView) + { + pTableView->GetEditEngine()->SetText( aEmpty ); + pTableView->SetSelection( ESelection(0,0, 0,0) ); + } + if (pTopView) + { + pTopView->GetEditEngine()->SetText( aEmpty ); + pTopView->SetSelection( ESelection(0,0, 0,0) ); + } + + DataChanged(); +} + +BOOL ScInputHandler::KeyInput( const KeyEvent& rKEvt, BOOL bStartEdit /* = FALSE */ ) +{ + if (!bOptLoaded) + { + bAutoComplete = SC_MOD()->GetAppOptions().GetAutoComplete(); + bOptLoaded = TRUE; + } + + KeyCode aCode = rKEvt.GetKeyCode(); + USHORT nModi = aCode.GetModifier(); + BOOL bShift = aCode.IsShift(); + BOOL bControl = aCode.IsMod1(); + BOOL bAlt = aCode.IsMod2(); + USHORT nCode = aCode.GetCode(); + sal_Unicode nChar = rKEvt.GetCharCode(); + + // Alt-Return is accepted, everything else with ALT, or CTRL-TAB are not: + if (( bAlt && !bControl && nCode != KEY_RETURN ) || + ( bControl && aCode.GetCode() == KEY_TAB )) + return FALSE; + + BOOL bInputLine = ( eMode==SC_INPUT_TOP ); + + BOOL bUsed = FALSE; + BOOL bSkip = FALSE; + BOOL bDoEnter = FALSE; + + switch ( nCode ) + { + case KEY_RETURN: + if (bControl && !bShift && !bInputLine) + bDoEnter = TRUE; + else if ( nModi == 0 && nTipVisible && pFormulaData && nAutoPos != SCPOS_INVALID ) + { + PasteFunctionData(); + bUsed = TRUE; + } + else if ( nModi == 0 && nTipVisible && aManualTip.Len() ) + { + PasteManualTip(); + bUsed = TRUE; + } + else + { + BYTE nMode = SC_ENTER_NORMAL; + if ( bShift && bControl ) + nMode = SC_ENTER_MATRIX; + else if ( bAlt ) + nMode = SC_ENTER_BLOCK; + EnterHandler( nMode ); + + if (pActiveViewSh) + pActiveViewSh->MoveCursorEnter( bShift && !bControl ); + + bUsed = TRUE; + } + break; + case KEY_TAB: + if (!bControl && !bAlt) + { + if ( pFormulaData && nTipVisible && nAutoPos != SCPOS_INVALID ) + { + // blaettern + + NextFormulaEntry( bShift ); + } + else if ( pColumnData && bUseTab && nAutoPos != SCPOS_INVALID ) + { + // in den Eintraegen der AutoEingabe blaettern + + NextAutoEntry( bShift ); + } + else + { + EnterHandler(); + + // TabKeyInput gibt auf manchen Rechnern unter W95 Stackueberlaeufe, + // darum direkter Aufruf: + if (pActiveViewSh) + pActiveViewSh->FindNextUnprot( bShift ); + } + bUsed = TRUE; + } + break; + case KEY_ESCAPE: + if ( nTipVisible ) + { + HideTip(); + bUsed = TRUE; + } + else if( nTipVisibleSec ) + { + HideTipBelow(); + bUsed = TRUE; + } + else if (eMode != SC_INPUT_NONE) + { + CancelHandler(); + bUsed = TRUE; + } + else + bSkip = TRUE; + break; + case KEY_F2: + if ( !bShift && !bControl && !bAlt && eMode == SC_INPUT_TABLE ) + { + eMode = SC_INPUT_TYPE; + bUsed = TRUE; + } + break; + } + + // Cursortasten nur ausfuehren, wenn schon im Edit-Modus + // z.B. wegen Shift-Ctrl-PageDn (ist nicht als Accelerator definiert) + + BOOL bCursorKey = EditEngine::DoesKeyMoveCursor(rKEvt); + BOOL bInsKey = ( nCode == KEY_INSERT && !nModi ); // Insert wie Cursortasten behandeln + if ( !bUsed && !bSkip && ( bDoEnter || EditEngine::DoesKeyChangeText(rKEvt) || + ( eMode != SC_INPUT_NONE && ( bCursorKey || bInsKey ) ) ) ) + { + HideTip(); + HideTipBelow(); + + if (bSelIsRef) + { + RemoveSelection(); + bSelIsRef = FALSE; + } + + UpdateActiveView(); + BOOL bNewView = DataChanging( nChar ); + + if (bProtected) // Zelle geschuetzt? + bUsed = TRUE; // Key-Event nicht weiterleiten + else // Aenderungen erlaubt + { + if (bNewView ) // neu anlegen + { + if (pActiveViewSh) + pActiveViewSh->GetViewData()->GetDocShell()->PostEditView( pEngine, aCursorPos ); + UpdateActiveView(); + if (eMode==SC_INPUT_NONE) + if (pTableView || pTopView) + { + String aStrLoP; + + if ( bStartEdit && bCellHasPercentFormat && ((nChar >= '0' && nChar <= '9') || nChar == '-') ) + aStrLoP = '%'; + + if (pTableView) + { + pTableView->GetEditEngine()->SetText( aStrLoP ); + if ( aStrLoP.Len() ) + pTableView->SetSelection( ESelection(0,0, 0,0) ); // before the '%' + + // don't call SetSelection if the string is empty anyway, + // to avoid breaking the bInitial handling in ScViewData::EditGrowY + } + if (pTopView) + { + pTopView->GetEditEngine()->SetText( aStrLoP ); + if ( aStrLoP.Len() ) + pTopView->SetSelection( ESelection(0,0, 0,0) ); // before the '%' + } + } + SyncViews(); + } + + if (pTableView || pTopView) + { +// pActiveView->SetEditEngineUpdateMode(TRUE); //! gibt Muell !!!! + + if (bDoEnter) + { + if (pTableView) + if( pTableView->PostKeyEvent( KeyEvent( CHAR_CR, KeyCode(KEY_RETURN) ) ) ) + bUsed = TRUE; + if (pTopView) + if( pTopView->PostKeyEvent( KeyEvent( CHAR_CR, KeyCode(KEY_RETURN) ) ) ) + bUsed = TRUE; + } + else if ( nAutoPar && nChar == ')' && CursorAtClosingPar() ) + { + SkipClosingPar(); + bUsed = TRUE; + } + else + { + if (pTableView) + if ( pTableView->PostKeyEvent( rKEvt ) ) + bUsed = TRUE; + if (pTopView) + if ( pTopView->PostKeyEvent( rKEvt ) ) + bUsed = TRUE; + } + + // Auto-Eingabe: + + if ( bUsed && bAutoComplete ) + { + bUseTab = FALSE; + nAutoPos = SCPOS_INVALID; // do not search further + + KeyFuncType eFunc = rKEvt.GetKeyCode().GetFunction(); + if ( nChar && nChar != 8 && nChar != 127 && // no 'backspace', no 'delete' + KEYFUNC_CUT != eFunc) // and no 'CTRL-X' + { + if (bFormulaMode) + UseFormulaData(); + else + UseColData(); + } + } + + // when the selection is changed manually or an opening parenthesis + // is typed, stop overwriting parentheses + if ( bUsed && nChar == '(' ) + ResetAutoPar(); + + if ( KEY_INSERT == nCode ) + { + SfxViewFrame* pViewFrm = SfxViewFrame::Current(); + if (pViewFrm) + pViewFrm->GetBindings().Invalidate( SID_ATTR_INSERT ); + } + if( bUsed && bFormulaMode && ( bCursorKey || bInsKey || nCode == KEY_DELETE || nCode == KEY_BACKSPACE ) ) + { + ShowTipCursor(); + } + } + + DataChanged(); // ruft auch UpdateParenthesis() + InvalidateAttribs(); //! in DataChanged ? + } + } + + if (pTopView && eMode != SC_INPUT_NONE) + SyncViews(); + + return bUsed; +} + +BOOL ScInputHandler::InputCommand( const CommandEvent& rCEvt, BOOL bForce ) +{ + BOOL bUsed = FALSE; + + if ( rCEvt.GetCommand() == COMMAND_CURSORPOS ) + { + // #90346# for COMMAND_CURSORPOS, do as little as possible, because + // with remote VCL, even a ShowCursor will generate another event. + if ( eMode != SC_INPUT_NONE ) + { + UpdateActiveView(); + if (pTableView || pTopView) + { + if (pTableView) + pTableView->Command( rCEvt ); + else if (pTopView) // call only once + pTopView->Command( rCEvt ); + bUsed = TRUE; + } + } + } + else + { + if ( bForce || eMode != SC_INPUT_NONE ) + { + if (!bOptLoaded) + { + bAutoComplete = SC_MOD()->GetAppOptions().GetAutoComplete(); + bOptLoaded = TRUE; + } + + HideTip(); + HideTipBelow(); + + if ( bSelIsRef ) + { + RemoveSelection(); + bSelIsRef = FALSE; + } + + UpdateActiveView(); + BOOL bNewView = DataChanging( 0, TRUE ); + + if (bProtected) // cell protected + bUsed = TRUE; // event is used + else // changes allowed + { + if (bNewView) // create new edit view + { + if (pActiveViewSh) + pActiveViewSh->GetViewData()->GetDocShell()->PostEditView( pEngine, aCursorPos ); + UpdateActiveView(); + if (eMode==SC_INPUT_NONE) + if (pTableView || pTopView) + { + String aStrLoP; + if (pTableView) + { + pTableView->GetEditEngine()->SetText( aStrLoP ); + pTableView->SetSelection( ESelection(0,0, 0,0) ); + } + if (pTopView) + { + pTopView->GetEditEngine()->SetText( aStrLoP ); + pTopView->SetSelection( ESelection(0,0, 0,0) ); + } + } + SyncViews(); + } + + if (pTableView || pTopView) + { + if (pTableView) + pTableView->Command( rCEvt ); + if (pTopView) + pTopView->Command( rCEvt ); + + bUsed = TRUE; + + if ( rCEvt.GetCommand() == COMMAND_ENDEXTTEXTINPUT ) + { + // AutoInput after ext text input + + nAutoPos = SCPOS_INVALID; + if (bFormulaMode) + UseFormulaData(); + else + UseColData(); + } + } + + DataChanged(); // calls UpdateParenthesis() + InvalidateAttribs(); //! in DataChanged ? + } + } + + if (pTopView && eMode != SC_INPUT_NONE) + SyncViews(); + } + + return bUsed; +} + +void ScInputHandler::NotifyChange( const ScInputHdlState* pState, + BOOL bForce, ScTabViewShell* pSourceSh, + BOOL bStopEditing) +{ + // #62806# Wenn der Aufruf aus einem Makro-Aufruf im EnterHandler kommt, + // gleich abbrechen und nicht den Status durcheinander bringen + if (bInEnterHandler) + return; + + BOOL bRepeat = (pState == pLastState); + if (!bRepeat && pState && pLastState) + bRepeat = sal::static_int_cast<BOOL>(*pState == *pLastState); + if (bRepeat && !bForce) + return; + + bInOwnChange = TRUE; // disable ModifyHdl (reset below) + + if ( pState && !pLastState ) // wieder enablen + bForce = TRUE; + + BOOL bHadObject = pLastState && pLastState->GetEditData(); + + //! Before EditEngine gets eventually created (so it gets the right pools) + if ( pSourceSh ) + pActiveViewSh = pSourceSh; + else + pActiveViewSh = PTR_CAST(ScTabViewShell, SfxViewShell::Current()); + + ImplCreateEditEngine(); + + if ( pState != pLastState ) + { + delete pLastState; + pLastState = pState ? new ScInputHdlState( *pState ) : NULL; + } + + if ( pState && pActiveViewSh ) + { + ScModule* pScMod = SC_MOD(); + + if ( pState ) + { + BOOL bIgnore = FALSE; + + // hier auch fremde Referenzeingabe beruecksichtigen (z.B. Funktions-AP), + // FormEditData falls gerade von der Hilfe auf Calc umgeschaltet wird: + + if ( !bFormulaMode && !pScMod->IsFormulaMode() && !pScMod->GetFormEditData() ) + { + if ( bModified ) + { + if (pState->GetPos() != aCursorPos) + { + if (!bProtected) + EnterHandler(); + } + else + bIgnore = TRUE; + } + + if ( !bIgnore /* || bRepeat */ ) + { + const ScAddress& rSPos = pState->GetStartPos(); + const ScAddress& rEPos = pState->GetEndPos(); + const EditTextObject* pData = pState->GetEditData(); + String aString = pState->GetString(); + BOOL bTxtMod = FALSE; + ScDocShell* pDocSh = pActiveViewSh->GetViewData()->GetDocShell(); + ScDocument* pDoc = pDocSh->GetDocument(); + + aCursorPos = pState->GetPos(); + + if ( pData /* || bRepeat */ ) + bTxtMod = TRUE; + else if ( bHadObject ) + bTxtMod = TRUE; + else if ( bTextValid ) + bTxtMod = ( aString != aCurrentText ); + else + bTxtMod = ( aString != GetEditText(pEngine) ); + + if ( bTxtMod || bForce ) + { + if (pData) + { + pEngine->SetText( *pData ); + aString = GetEditText(pEngine); + lcl_RemoveTabs(aString); + bTextValid = FALSE; + aCurrentText.Erase(); + } + else + { + aCurrentText = aString; + bTextValid = TRUE; //! erst nur als String merken + } + + if ( pInputWin ) + pInputWin->SetTextString(aString); + } + + if ( pInputWin ) // Bereichsanzeige + { + String aPosStr; + const ScAddress::Details aAddrDetails( pDoc, aCursorPos ); + + // Ist der Bereich ein Name? + //! per Timer suchen ??? + + if ( pActiveViewSh ) + pActiveViewSh->GetViewData()->GetDocument()-> + GetRangeAtBlock( ScRange( rSPos, rEPos ), &aPosStr ); + + if ( !aPosStr.Len() ) // kein Name -> formatieren + { + USHORT nFlags = 0; + if( aAddrDetails.eConv == formula::FormulaGrammar::CONV_XL_R1C1 ) + nFlags |= SCA_COL_ABSOLUTE | SCA_ROW_ABSOLUTE; + if ( rSPos != rEPos ) + { + ScRange r(rSPos, rEPos); + nFlags |= (nFlags << 4); + r.Format( aPosStr, SCA_VALID | nFlags, pDoc, aAddrDetails ); + } + else + aCursorPos.Format( aPosStr, SCA_VALID | nFlags, pDoc, aAddrDetails ); + } + + pInputWin->SetPosString(aPosStr); + pInputWin->SetSumAssignMode(); + } + + if (bStopEditing) + SFX_APP()->Broadcast( SfxSimpleHint( FID_KILLEDITVIEW ) ); + + // As long as the content is not edited, turn off online spelling. + // Online spelling is turned back on in StartTable, after setting + // the right language from cell attributes. + + ULONG nCntrl = pEngine->GetControlWord(); + if ( nCntrl & EE_CNTRL_ONLINESPELLING ) + pEngine->SetControlWord( nCntrl & ~EE_CNTRL_ONLINESPELLING ); + + bModified = FALSE; + bSelIsRef = FALSE; + bProtected = FALSE; + bCommandErrorShown = FALSE; + } + } + } + +// bProtected = FALSE; + + if ( pInputWin) + { + if(!pScMod->IsFormulaMode()&& !pScMod->IsRefDialogOpen()) //BugID 54702 + { //Wenn RefDialog offen, dann nicht enablen + if ( !pInputWin->IsEnabled()) + { + pInputWin->Enable(); + if(pDelayTimer ) + { + DELETEZ( pDelayTimer ); + } + } + } + else if(pScMod->IsRefDialogOpen()) + { // Da jedes Dokument eigenes InputWin hat, sollte + if ( !pDelayTimer ) // nochmals Timer gestartet werden, da sonst Ein- + { // gabezeile evt. noch aktiv ist. + pDelayTimer = new Timer; + pDelayTimer->SetTimeout( 500 ); // 100ms Verzoegerung + pDelayTimer->SetTimeoutHdl( LINK( this, ScInputHandler, DelayTimer ) ); + pDelayTimer->Start(); + } + } + } + } + else // !pState || !pActiveViewSh + { + if ( !pDelayTimer ) + { + pDelayTimer = new Timer; + pDelayTimer->SetTimeout( 500 ); // 100ms Verzoegerung + pDelayTimer->SetTimeoutHdl( LINK( this, ScInputHandler, DelayTimer ) ); + pDelayTimer->Start(); + } + } + + HideTip(); + HideTipBelow(); + bInOwnChange = FALSE; +} + +void ScInputHandler::UpdateCellAdjust( SvxCellHorJustify eJust ) +{ + eAttrAdjust = eJust; + UpdateAdjust( 0 ); +} + +void ScInputHandler::ResetDelayTimer() +{ + if(pDelayTimer!=NULL) + { + DELETEZ( pDelayTimer ); + + if ( pInputWin) + { + pInputWin->Enable(); + } + } +} + +IMPL_LINK( ScInputHandler, DelayTimer, Timer*, pTimer ) +{ + if ( pTimer == pDelayTimer ) + { + DELETEZ( pDelayTimer ); + + if ( NULL == pLastState || SC_MOD()->IsFormulaMode() || SC_MOD()->IsRefDialogOpen()) + { + //! new method at ScModule to query if function autopilot is open + + SfxViewFrame* pViewFrm = SfxViewFrame::Current(); + if ( pViewFrm && pViewFrm->GetChildWindow( SID_OPENDLG_FUNCTION ) ) + { + if ( pInputWin) + { + pInputWin->EnableButtons( FALSE ); + pInputWin->Disable(); + } + } + else if ( !bFormulaMode ) // #39210# Formel auch z.B. bei Hilfe behalten + { + bInOwnChange = TRUE; // disable ModifyHdl (reset below) + + pActiveViewSh = NULL; + pEngine->SetText( EMPTY_STRING ); + if ( pInputWin ) + { + pInputWin->SetPosString( EMPTY_STRING ); + pInputWin->SetTextString( EMPTY_STRING ); + pInputWin->Disable(); + } + + bInOwnChange = FALSE; + } + } + } + return 0; +} + +void ScInputHandler::InputSelection( EditView* pView ) +{ + SyncViews( pView ); + ShowTipCursor(); + UpdateParenthesis(); // Selektion geaendert -> Klammer-Hervorhebung neu + + // when the selection is changed manually, stop overwriting parentheses + ResetAutoPar(); +} + +void ScInputHandler::InputChanged( EditView* pView, BOOL bFromNotify ) +{ + ESelection aSelection = pView->GetSelection(); + + UpdateActiveView(); + + // #i20282# DataChanged needs to know if this is from the input line's modify handler + BOOL bFromTopNotify = ( bFromNotify && pView == pTopView ); + + BOOL bNewView = DataChanging(); //! kann das hier ueberhaupt sein? + aCurrentText = pView->GetEditEngine()->GetText(); // auch den String merken + pEngine->SetText( aCurrentText ); + DataChanged( bFromTopNotify ); + bTextValid = TRUE; // wird in DataChanged auf FALSE gesetzt + + if ( pActiveViewSh ) + { + ScViewData* pViewData = pActiveViewSh->GetViewData(); + if ( bNewView ) + pViewData->GetDocShell()->PostEditView( pEngine, aCursorPos ); + + pViewData->EditGrowY(); + pViewData->EditGrowX(); + } + + SyncViews( pView ); +} + +const String& ScInputHandler::GetEditString() +{ + if (pEngine) + { + aCurrentText = pEngine->GetText(); // immer neu aus Engine + bTextValid = TRUE; + } + + return aCurrentText; +} + +Size ScInputHandler::GetTextSize() +{ + Size aSize; + if ( pEngine ) + aSize = Size( pEngine->CalcTextWidth(), pEngine->GetTextHeight() ); + + return aSize; +} + +BOOL ScInputHandler::GetTextAndFields( ScEditEngineDefaulter& rDestEngine ) +{ + BOOL bRet = FALSE; + if (pEngine) + { + // Feldbefehle enthalten? + + USHORT nParCnt = pEngine->GetParagraphCount(); + SfxItemSet aSet = pEngine->GetAttribs( ESelection(0,0,nParCnt,0) ); + SfxItemState eFieldState = aSet.GetItemState( EE_FEATURE_FIELD, FALSE ); + if ( eFieldState == SFX_ITEM_DONTCARE || eFieldState == SFX_ITEM_SET ) + { + // Inhalt kopieren + + EditTextObject* pObj = pEngine->CreateTextObject(); + rDestEngine.SetText(*pObj); + delete pObj; + + // Attribute loeschen + + for (USHORT i=0; i<nParCnt; i++) + rDestEngine.QuickRemoveCharAttribs( i ); + + // Absaetze zusammenfassen + + while ( nParCnt > 1 ) + { + xub_StrLen nLen = rDestEngine.GetTextLen( (USHORT)0 ); + ESelection aSel( 0,nLen, 1,0 ); + rDestEngine.QuickInsertText( ' ', aSel ); // Umbruch durch Space ersetzen + --nParCnt; + } + + bRet = TRUE; + } + } + return bRet; +} + + +//------------------------------------------------------------------------ +// Methoden fuer FunktionsAutopiloten: +// InputGetSelection, InputSetSelection, InputReplaceSelection, InputGetFormulaStr +//------------------------------------------------------------------------ + +void ScInputHandler::InputGetSelection( xub_StrLen& rStart, xub_StrLen& rEnd ) +{ + rStart = nFormSelStart; + rEnd = nFormSelEnd; +} + +//------------------------------------------------------------------------ + +EditView* ScInputHandler::GetFuncEditView() +{ + UpdateActiveView(); // wegen pTableView + + EditView* pView = NULL; + if ( pInputWin ) + { + pInputWin->MakeDialogEditView(); + pView = pInputWin->GetEditView(); + } + else + { + if ( eMode != SC_INPUT_TABLE ) + { + bCreatingFuncView = TRUE; // RangeFinder nicht anzeigen + SetMode( SC_INPUT_TABLE ); + bCreatingFuncView = FALSE; + if ( pTableView ) + pTableView->GetEditEngine()->SetText( EMPTY_STRING ); + } + pView = pTableView; + } + + return pView; +} + +//------------------------------------------------------------------------ + +void ScInputHandler::InputSetSelection( xub_StrLen nStart, xub_StrLen nEnd ) +{ + if ( nStart <= nEnd ) + { + nFormSelStart = nStart; + nFormSelEnd = nEnd; + } + else + { + nFormSelEnd = nStart; + nFormSelStart = nEnd; + } + + EditView* pView = GetFuncEditView(); + if (pView) + pView->SetSelection( ESelection(0,nStart, 0,nEnd) ); + + bModified = TRUE; +} + +//------------------------------------------------------------------------ + +void ScInputHandler::InputReplaceSelection( const String& rStr ) +{ + if (!pRefViewSh) + pRefViewSh = pActiveViewSh; + + DBG_ASSERT(nFormSelEnd>=nFormSelStart,"Selektion kaputt..."); + + xub_StrLen nOldLen = nFormSelEnd-nFormSelStart; + xub_StrLen nNewLen = rStr.Len(); + if (nOldLen) + aFormText.Erase( nFormSelStart, nOldLen ); + if (nNewLen) + aFormText.Insert( rStr, nFormSelStart ); + nFormSelEnd = nFormSelStart + nNewLen; + + EditView* pView = GetFuncEditView(); + if (pView) + { + pView->SetEditEngineUpdateMode( FALSE ); +// pView->InsertText( rStr, TRUE ); + pView->GetEditEngine()->SetText( aFormText ); + pView->SetSelection( ESelection(0,nFormSelStart, 0,nFormSelEnd) ); + pView->SetEditEngineUpdateMode( TRUE ); + } + bModified = TRUE; +} + +//------------------------------------------------------------------------ + +String ScInputHandler::InputGetFormulaStr() +{ + return aFormText; //! eigene Membervariable? +} + +//======================================================================== +// ScInputHdlState +//======================================================================== + +ScInputHdlState::ScInputHdlState( const ScAddress& rCurPos, + const ScAddress& rStartPos, + const ScAddress& rEndPos, + const String& rString, + const EditTextObject* pData ) + : aCursorPos ( rCurPos ), + aStartPos ( rStartPos ), + aEndPos ( rEndPos ), + aString ( rString ), + pEditData ( pData ? pData->Clone() : NULL ) +{ +} + +//------------------------------------------------------------------------ + +ScInputHdlState::ScInputHdlState( const ScInputHdlState& rCpy ) + : pEditData ( NULL ) +{ + *this = rCpy; +} + +//------------------------------------------------------------------------ + +ScInputHdlState::~ScInputHdlState() +{ + delete pEditData; +} + +//------------------------------------------------------------------------ + +int ScInputHdlState::operator==( const ScInputHdlState& r ) const +{ + return ( (aStartPos == r.aStartPos) + && (aEndPos == r.aEndPos) + && (aCursorPos == r.aCursorPos) + && (aString == r.aString) + && ScGlobal::EETextObjEqual( pEditData, r.pEditData ) ); +} + +//------------------------------------------------------------------------ + +ScInputHdlState& ScInputHdlState::operator=( const ScInputHdlState& r ) +{ + delete pEditData; + + aCursorPos = r.aCursorPos; + aStartPos = r.aStartPos; + aEndPos = r.aEndPos; + aString = r.aString; + pEditData = r.pEditData ? r.pEditData->Clone() : NULL; + + return *this; +} + + + + diff --git a/sc/source/ui/app/inputwin.cxx b/sc/source/ui/app/inputwin.cxx new file mode 100644 index 000000000000..5ea8c4d78e0f --- /dev/null +++ b/sc/source/ui/app/inputwin.cxx @@ -0,0 +1,1818 @@ +/************************************************************************* + * + * 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_sc.hxx" + +#include <algorithm> + +#include "scitems.hxx" +#include <editeng/eeitem.hxx> + +#include <sfx2/app.hxx> +#include <editeng/adjitem.hxx> +#include <editeng/editview.hxx> +#include <editeng/editstat.hxx> +#include <editeng/frmdiritem.hxx> +#include <editeng/lspcitem.hxx> +#include <sfx2/bindings.hxx> +#include <sfx2/viewfrm.hxx> +#include <sfx2/dispatch.hxx> +#include <sfx2/event.hxx> +#include <sfx2/imgmgr.hxx> +#include <stdlib.h> // qsort +#include <editeng/scriptspaceitem.hxx> +#include <editeng/scripttypeitem.hxx> +#include <vcl/cursor.hxx> +#include <vcl/help.hxx> +#include <svl/stritem.hxx> + +#include "inputwin.hxx" +#include "scmod.hxx" +#include "uiitems.hxx" +#include "global.hxx" +#include "scresid.hxx" +#include "sc.hrc" +#include "globstr.hrc" +#include "editutil.hxx" +#include "inputhdl.hxx" +#include "tabvwsh.hxx" +#include "document.hxx" +#include "docsh.hxx" +#include "appoptio.hxx" +#include "rangenam.hxx" +#include <formula/compiler.hrc> +#include "dbcolect.hxx" +#include "rangeutl.hxx" +#include "docfunc.hxx" +#include "funcdesc.hxx" +#include <editeng/fontitem.hxx> +#include <com/sun/star/accessibility/XAccessible.hpp> +#include "AccessibleEditObject.hxx" +#include "AccessibleText.hxx" + +#define TEXT_STARTPOS 3 +#define THESIZE 1000000 //!!! langt... :-) +#define TBX_WINDOW_HEIGHT 22 // in Pixeln - fuer alle Systeme gleich? + +enum ScNameInputType +{ + SC_NAME_INPUT_CELL, + SC_NAME_INPUT_RANGE, + SC_NAME_INPUT_NAMEDRANGE, + SC_NAME_INPUT_DATABASE, + SC_NAME_INPUT_ROW, + SC_NAME_INPUT_SHEET, + SC_NAME_INPUT_DEFINE, + SC_NAME_INPUT_BAD_NAME, + SC_NAME_INPUT_BAD_SELECTION +}; + + +//================================================================== +// class ScInputWindowWrapper +//================================================================== + +SFX_IMPL_CHILDWINDOW(ScInputWindowWrapper,FID_INPUTLINE_STATUS) + +ScInputWindowWrapper::ScInputWindowWrapper( Window* pParentP, + USHORT nId, + SfxBindings* pBindings, + SfxChildWinInfo* /* pInfo */ ) + : SfxChildWindow( pParentP, nId ) +{ + ScInputWindow* pWin=new ScInputWindow( pParentP, pBindings ); + pWindow = pWin; + + pWin->Show(); + + pWin->SetSizePixel( pWin->CalcWindowSizePixel() ); + + eChildAlignment = SFX_ALIGN_LOWESTTOP; + pBindings->Invalidate( FID_TOGGLEINPUTLINE ); +} + +// GetInfo fliegt wieder raus, wenn es ein SFX_IMPL_TOOLBOX gibt !!!! + +SfxChildWinInfo __EXPORT ScInputWindowWrapper::GetInfo() const +{ + SfxChildWinInfo aInfo = SfxChildWindow::GetInfo(); + return aInfo; +} + +//================================================================== + +#define IMAGE(id) pImgMgr->SeekImage(id, bHC) + +//================================================================== +// class ScInputWindow +//================================================================== + +ScInputWindow::ScInputWindow( Window* pParent, SfxBindings* pBind ) : +#ifdef OS2 +// #37192# ohne WB_CLIPCHILDREN wg. os/2 Paintproblem + ToolBox ( pParent, WinBits(WB_BORDER|WB_3DLOOK) ), +#else +// mit WB_CLIPCHILDREN, sonst Flicker + ToolBox ( pParent, WinBits(WB_BORDER|WB_3DLOOK|WB_CLIPCHILDREN) ), +#endif + aWndPos ( this ), + aTextWindow ( this ), + pInputHdl ( NULL ), + pBindings ( pBind ), + aTextOk ( ScResId( SCSTR_QHELP_BTNOK ) ), // nicht immer neu aus Resource + aTextCancel ( ScResId( SCSTR_QHELP_BTNCANCEL ) ), + aTextSum ( ScResId( SCSTR_QHELP_BTNSUM ) ), + aTextEqual ( ScResId( SCSTR_QHELP_BTNEQUAL ) ), + bIsOkCancelMode ( FALSE ) +{ + ScModule* pScMod = SC_MOD(); + SfxImageManager* pImgMgr = SfxImageManager::GetImageManager( pScMod ); + + // #i73615# don't rely on SfxViewShell::Current while constructing the input line + // (also for GetInputHdl below) + ScTabViewShell* pViewSh = NULL; + SfxDispatcher* pDisp = pBind->GetDispatcher(); + if ( pDisp ) + { + SfxViewFrame* pViewFrm = pDisp->GetFrame(); + if ( pViewFrm ) + pViewSh = PTR_CAST( ScTabViewShell, pViewFrm->GetViewShell() ); + } + DBG_ASSERT( pViewSh, "no view shell for input window" ); + + BOOL bHC = GetSettings().GetStyleSettings().GetHighContrastMode(); + + // Positionsfenster, 3 Buttons, Eingabefenster + InsertWindow ( 1, &aWndPos, 0, 0 ); + InsertSeparator ( 1 ); + InsertItem ( SID_INPUT_FUNCTION, IMAGE( SID_INPUT_FUNCTION ), 0, 2 ); + InsertItem ( SID_INPUT_SUM, IMAGE( SID_INPUT_SUM ), 0, 3 ); + InsertItem ( SID_INPUT_EQUAL, IMAGE( SID_INPUT_EQUAL ), 0, 4 ); + InsertSeparator ( 5 ); + InsertWindow ( 7, &aTextWindow, 0, 6 ); + + aWndPos .SetQuickHelpText( ScResId( SCSTR_QHELP_POSWND ) ); + aWndPos .SetHelpId ( HID_INSWIN_POS ); + aTextWindow.SetQuickHelpText( ScResId( SCSTR_QHELP_INPUTWND ) ); + aTextWindow.SetHelpId ( HID_INSWIN_INPUT ); + + // kein SetHelpText, die Hilfetexte kommen aus der Hilfe + + SetItemText ( SID_INPUT_FUNCTION, ScResId( SCSTR_QHELP_BTNCALC ) ); + SetHelpId ( SID_INPUT_FUNCTION, HID_INSWIN_CALC ); + + SetItemText ( SID_INPUT_SUM, aTextSum ); + SetHelpId ( SID_INPUT_SUM, HID_INSWIN_SUMME ); + + SetItemText ( SID_INPUT_EQUAL, aTextEqual ); + SetHelpId ( SID_INPUT_EQUAL, HID_INSWIN_FUNC ); + + SetHelpId( HID_SC_INPUTWIN ); // fuer die ganze Eingabezeile + + aWndPos .Show(); + aTextWindow .Show(); + + pInputHdl = SC_MOD()->GetInputHdl( pViewSh, FALSE ); // use own handler even if ref-handler is set + if (pInputHdl) + pInputHdl->SetInputWindow( this ); + + if ( pInputHdl && pInputHdl->GetFormString().Len() ) + { + // Umschalten waehrend der Funktionsautopilot aktiv ist + // -> Inhalt des Funktionsautopiloten wieder anzeigen + //! auch Selektion (am InputHdl gemerkt) wieder anzeigen + + aTextWindow.SetTextString( pInputHdl->GetFormString() ); + } + else if ( pInputHdl && pInputHdl->IsInputMode() ) + { + // wenn waehrend des Editierens die Eingabezeile weg war + // (Editieren einer Formel, dann umschalten zu fremdem Dokument/Hilfe), + // wieder den gerade editierten Text aus dem InputHandler anzeigen + + aTextWindow.SetTextString( pInputHdl->GetEditString() ); // Text anzeigen + if ( pInputHdl->IsTopMode() ) + pInputHdl->SetMode( SC_INPUT_TABLE ); // Focus kommt eh nach unten + } + else if ( pViewSh ) + pViewSh->UpdateInputHandler( TRUE ); // unbedingtes Update + + pImgMgr->RegisterToolBox( this ); +} + +__EXPORT ScInputWindow::~ScInputWindow() +{ + BOOL bDown = ( ScGlobal::pSysLocale == NULL ); // after Clear? + + // if any view's input handler has a pointer to this input window, reset it + // (may be several ones, #74522#) + // member pInputHdl is not used here + + if ( !bDown ) + { + TypeId aScType = TYPE(ScTabViewShell); + SfxViewShell* pSh = SfxViewShell::GetFirst( &aScType ); + while ( pSh ) + { + ScInputHandler* pHdl = ((ScTabViewShell*)pSh)->GetInputHandler(); + if ( pHdl && pHdl->GetInputWindow() == this ) + { + pHdl->SetInputWindow( NULL ); + pHdl->StopInputWinEngine( FALSE ); // #125841# reset pTopView pointer + } + pSh = SfxViewShell::GetNext( *pSh, &aScType ); + } + } + + SfxImageManager::GetImageManager( SC_MOD() )->ReleaseToolBox( this ); +} + +void ScInputWindow::SetInputHandler( ScInputHandler* pNew ) +{ + // wird im Activate der View gerufen... + + if ( pNew != pInputHdl ) + { + // Bei Reload (letzte Version) ist pInputHdl der Input-Handler der alten, + // geloeschten ViewShell, darum hier auf keinen Fall anfassen! + + pInputHdl = pNew; + if (pInputHdl) + pInputHdl->SetInputWindow( this ); + } +} + +sal_Bool ScInputWindow::UseSubTotal(ScRangeList* pRangeList) const +{ + sal_Bool bSubTotal(sal_False); + ScTabViewShell* pViewSh = PTR_CAST( ScTabViewShell, SfxViewShell::Current() ); + if ( pViewSh ) + { + ScDocument* pDoc = pViewSh->GetViewData()->GetDocument(); + sal_Int32 nRangeCount (pRangeList->Count()); + sal_Int32 nRangeIndex (0); + while (!bSubTotal && nRangeIndex < nRangeCount) + { + const ScRange* pRange = pRangeList->GetObject( nRangeIndex ); + if( pRange ) + { + SCTAB nTabEnd(pRange->aEnd.Tab()); + SCTAB nTab(pRange->aStart.Tab()); + while (!bSubTotal && nTab <= nTabEnd) + { + SCROW nRowEnd(pRange->aEnd.Row()); + SCROW nRow(pRange->aStart.Row()); + while (!bSubTotal && nRow <= nRowEnd) + { + if (pDoc->IsFiltered(nRow, nTab)) + bSubTotal = sal_True; + else + ++nRow; + } + ++nTab; + } + } + ++nRangeIndex; + } + + ScDBCollection* pDBCollection = pDoc->GetDBCollection(); + sal_uInt16 nDBCount (pDBCollection->GetCount()); + sal_uInt16 nDBIndex (0); + while (!bSubTotal && nDBIndex < nDBCount) + { + ScDBData* pDB = (*pDBCollection)[nDBIndex]; + if (pDB && pDB->HasAutoFilter()) + { + nRangeIndex = 0; + while (!bSubTotal && nRangeIndex < nRangeCount) + { + const ScRange* pRange = pRangeList->GetObject( nRangeIndex ); + if( pRange ) + { + ScRange aDBArea; + pDB->GetArea(aDBArea); + if (aDBArea.Intersects(*pRange)) + bSubTotal = sal_True; + } + ++nRangeIndex; + } + } + ++nDBIndex; + } + } + return bSubTotal; +} + +void __EXPORT ScInputWindow::Select() +{ + ScModule* pScMod = SC_MOD(); + ToolBox::Select(); + + switch ( GetCurItemId() ) + { + case SID_INPUT_FUNCTION: + { + //! new method at ScModule to query if function autopilot is open + SfxViewFrame* pViewFrm = SfxViewFrame::Current(); + if ( pViewFrm && !pViewFrm->GetChildWindow( SID_OPENDLG_FUNCTION ) ) + { + pViewFrm->GetDispatcher()->Execute( SID_OPENDLG_FUNCTION, + SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD ); + + // die Toolbox wird sowieso disabled, also braucht auch nicht umgeschaltet + // zu werden, egal ob's geklappt hat oder nicht +// SetOkCancelMode(); + } + } + break; + + case SID_INPUT_CANCEL: + pScMod->InputCancelHandler(); + SetSumAssignMode(); + break; + + case SID_INPUT_OK: + pScMod->InputEnterHandler(); + SetSumAssignMode(); + aTextWindow.Invalidate(); // sonst bleibt Selektion stehen + break; + + case SID_INPUT_SUM: + { + ScTabViewShell* pViewSh = PTR_CAST( ScTabViewShell, SfxViewShell::Current() ); + if ( pViewSh ) + { + const ScMarkData& rMark = pViewSh->GetViewData()->GetMarkData(); + if ( rMark.IsMarked() || rMark.IsMultiMarked() ) + { + ScRangeList aMarkRangeList; + rMark.FillRangeListWithMarks( &aMarkRangeList, FALSE ); + ScDocument* pDoc = pViewSh->GetViewData()->GetDocument(); + + // check if one of the marked ranges is empty + bool bEmpty = false; + const ULONG nCount = aMarkRangeList.Count(); + for ( ULONG i = 0; i < nCount; ++i ) + { + const ScRange aRange( *aMarkRangeList.GetObject( i ) ); + if ( pDoc->IsBlockEmpty( aRange.aStart.Tab(), + aRange.aStart.Col(), aRange.aStart.Row(), + aRange.aEnd.Col(), aRange.aEnd.Row() ) ) + { + bEmpty = true; + break; + } + } + + if ( bEmpty ) + { + ScRangeList aRangeList; + const BOOL bDataFound = pViewSh->GetAutoSumArea( aRangeList ); + if ( bDataFound ) + { + const sal_Bool bSubTotal( UseSubTotal( &aRangeList ) ); + pViewSh->EnterAutoSum( aRangeList, bSubTotal ); // Block mit Summen fuellen + } + } + else + { + const sal_Bool bSubTotal( UseSubTotal( &aMarkRangeList ) ); + for ( ULONG i = 0; i < nCount; ++i ) + { + const ScRange aRange( *aMarkRangeList.GetObject( i ) ); + const bool bSetCursor = ( i == nCount - 1 ? true : false ); + const bool bContinue = ( i != 0 ? true : false ); + if ( !pViewSh->AutoSum( aRange, bSubTotal, bSetCursor, bContinue ) ) + { + pViewSh->MarkRange( aRange, FALSE, FALSE ); + pViewSh->SetCursor( aRange.aEnd.Col(), aRange.aEnd.Row() ); + const ScRangeList aRangeList; + const String aFormula = pViewSh->GetAutoSumFormula( aRangeList, bSubTotal ); + SetFuncString( aFormula ); + break; + } + } + } + } + else // nur in Eingabezeile einfuegen + { + ScRangeList aRangeList; + const BOOL bDataFound = pViewSh->GetAutoSumArea( aRangeList ); + const sal_Bool bSubTotal( UseSubTotal( &aRangeList ) ); + const String aFormula = pViewSh->GetAutoSumFormula( aRangeList, bSubTotal ); + SetFuncString( aFormula ); + + if ( bDataFound && pScMod->IsEditMode() ) + { + ScInputHandler* pHdl = pScMod->GetInputHdl( pViewSh ); + if ( pHdl ) + { + pHdl->InitRangeFinder( aFormula ); + + //! SetSelection am InputHandler ??? + //! bSelIsRef setzen ??? + const xub_StrLen nOpen = aFormula.Search('('); + const xub_StrLen nLen = aFormula.Len(); + if ( nOpen != STRING_NOTFOUND && nLen > nOpen ) + { + sal_uInt8 nAdd(1); + if (bSubTotal) + nAdd = 3; + ESelection aSel(0,nOpen+nAdd,0,nLen-1); + EditView* pTableView = pHdl->GetTableView(); + if (pTableView) + pTableView->SetSelection(aSel); + EditView* pTopView = pHdl->GetTopView(); + if (pTopView) + pTopView->SetSelection(aSel); + } + } + } + } + } + } + break; + + case SID_INPUT_EQUAL: + { + aTextWindow.StartEditEngine(); + if ( pScMod->IsEditMode() ) // nicht, wenn z.B. geschuetzt + { + aTextWindow.GrabFocus(); + aTextWindow.SetTextString( '=' ); + + EditView* pView = aTextWindow.GetEditView(); + if (pView) + { + pView->SetSelection( ESelection(0,1, 0,1) ); + pScMod->InputChanged(pView); + SetOkCancelMode(); + pView->SetEditEngineUpdateMode(TRUE); + } + } + break; + } + } +} + +void __EXPORT ScInputWindow::Resize() +{ + ToolBox::Resize(); + + long nWidth = GetSizePixel().Width(); + long nLeft = aTextWindow.GetPosPixel().X(); + Size aSize = aTextWindow.GetSizePixel(); + + aSize.Width() = Max( ((long)(nWidth - nLeft - 5)), (long)0 ); + aTextWindow.SetSizePixel( aSize ); + aTextWindow.Invalidate(); +} + +void ScInputWindow::SetFuncString( const String& rString, BOOL bDoEdit ) +{ + //! new method at ScModule to query if function autopilot is open + SfxViewFrame* pViewFrm = SfxViewFrame::Current(); + EnableButtons( pViewFrm && !pViewFrm->GetChildWindow( SID_OPENDLG_FUNCTION ) ); + aTextWindow.StartEditEngine(); + + ScModule* pScMod = SC_MOD(); + if ( pScMod->IsEditMode() ) + { + if ( bDoEdit ) + aTextWindow.GrabFocus(); + aTextWindow.SetTextString( rString ); + EditView* pView = aTextWindow.GetEditView(); + if (pView) + { + xub_StrLen nLen = rString.Len(); + + if ( nLen > 0 ) + { + nLen--; + pView->SetSelection( ESelection( 0, nLen, 0, nLen ) ); + } + + pScMod->InputChanged(pView); + if ( bDoEdit ) + SetOkCancelMode(); // nicht, wenn gleich hinterher Enter/Cancel + + pView->SetEditEngineUpdateMode(TRUE); + } + } +} + +void ScInputWindow::SetPosString( const String& rStr ) +{ + aWndPos.SetPos( rStr ); +} + +void ScInputWindow::SetTextString( const String& rString ) +{ + if (rString.Len() <= 32767) + aTextWindow.SetTextString(rString); + else + { + String aNew = rString; + aNew.Erase(32767); + aTextWindow.SetTextString(aNew); + } +} + +void ScInputWindow::SetOkCancelMode() +{ + //! new method at ScModule to query if function autopilot is open + SfxViewFrame* pViewFrm = SfxViewFrame::Current(); + EnableButtons( pViewFrm && !pViewFrm->GetChildWindow( SID_OPENDLG_FUNCTION ) ); + + ScModule* pScMod = SC_MOD(); + SfxImageManager* pImgMgr = SfxImageManager::GetImageManager( pScMod ); + if (!bIsOkCancelMode) + { + BOOL bHC = GetSettings().GetStyleSettings().GetHighContrastMode(); + + RemoveItem( 3 ); // SID_INPUT_SUM und SID_INPUT_EQUAL entfernen + RemoveItem( 3 ); + InsertItem( SID_INPUT_CANCEL, IMAGE( SID_INPUT_CANCEL ), 0, 3 ); + InsertItem( SID_INPUT_OK, IMAGE( SID_INPUT_OK ), 0, 4 ); + SetItemText ( SID_INPUT_CANCEL, aTextCancel ); + SetHelpId ( SID_INPUT_CANCEL, HID_INSWIN_CANCEL ); + SetItemText ( SID_INPUT_OK, aTextOk ); + SetHelpId ( SID_INPUT_OK, HID_INSWIN_OK ); + bIsOkCancelMode = TRUE; + } +} + +void ScInputWindow::SetSumAssignMode() +{ + //! new method at ScModule to query if function autopilot is open + SfxViewFrame* pViewFrm = SfxViewFrame::Current(); + EnableButtons( pViewFrm && !pViewFrm->GetChildWindow( SID_OPENDLG_FUNCTION ) ); + + ScModule* pScMod = SC_MOD(); + SfxImageManager* pImgMgr = SfxImageManager::GetImageManager( pScMod ); + if (bIsOkCancelMode) + { + BOOL bHC = GetSettings().GetStyleSettings().GetHighContrastMode(); + + // SID_INPUT_CANCEL, und SID_INPUT_OK entfernen + RemoveItem( 3 ); + RemoveItem( 3 ); + InsertItem( SID_INPUT_SUM, IMAGE( SID_INPUT_SUM ), 0, 3 ); + InsertItem( SID_INPUT_EQUAL, IMAGE( SID_INPUT_EQUAL ), 0, 4 ); + SetItemText ( SID_INPUT_SUM, aTextSum ); + SetHelpId ( SID_INPUT_SUM, HID_INSWIN_SUMME ); + SetItemText ( SID_INPUT_EQUAL, aTextEqual ); + SetHelpId ( SID_INPUT_EQUAL, HID_INSWIN_FUNC ); + bIsOkCancelMode = FALSE; + + SetFormulaMode(FALSE); // kein editieren -> keine Formel + } +} + +void ScInputWindow::SetFormulaMode( BOOL bSet ) +{ + aWndPos.SetFormulaMode(bSet); + aTextWindow.SetFormulaMode(bSet); +} + +void __EXPORT ScInputWindow::SetText( const String& rString ) +{ + ToolBox::SetText(rString); +} + +String __EXPORT ScInputWindow::GetText() const +{ + return ToolBox::GetText(); +} + + +//UNUSED2008-05 EditView* ScInputWindow::ActivateEdit( const String& rText, +//UNUSED2008-05 const ESelection& rSel ) +//UNUSED2008-05 { +//UNUSED2008-05 if ( !aTextWindow.IsInputActive() ) +//UNUSED2008-05 { +//UNUSED2008-05 aTextWindow.StartEditEngine(); +//UNUSED2008-05 aTextWindow.GrabFocus(); +//UNUSED2008-05 aTextWindow.SetTextString( rText ); +//UNUSED2008-05 aTextWindow.GetEditView()->SetSelection( rSel ); +//UNUSED2008-05 } +//UNUSED2008-05 +//UNUSED2008-05 return aTextWindow.GetEditView(); +//UNUSED2008-05 } + +BOOL ScInputWindow::IsInputActive() +{ + return aTextWindow.IsInputActive(); +} + +EditView* ScInputWindow::GetEditView() +{ + return aTextWindow.GetEditView(); +} + +void ScInputWindow::MakeDialogEditView() +{ + aTextWindow.MakeDialogEditView(); +} + +void ScInputWindow::StopEditEngine( BOOL bAll ) +{ + aTextWindow.StopEditEngine( bAll ); +} + +void ScInputWindow::TextGrabFocus() +{ + aTextWindow.GrabFocus(); +} + +void ScInputWindow::TextInvalidate() +{ + aTextWindow.Invalidate(); +} + +void ScInputWindow::SwitchToTextWin() +{ + // used for shift-ctrl-F2 + + aTextWindow.StartEditEngine(); + if ( SC_MOD()->IsEditMode() ) + { + aTextWindow.GrabFocus(); + EditView* pView = aTextWindow.GetEditView(); + if (pView) + { + xub_StrLen nLen = pView->GetEditEngine()->GetTextLen(0); + ESelection aSel( 0, nLen, 0, nLen ); + pView->SetSelection( aSel ); // set cursor to end of text + } + } +} + +void ScInputWindow::PosGrabFocus() +{ + aWndPos.GrabFocus(); +} + +void ScInputWindow::EnableButtons( BOOL bEnable ) +{ + // when enabling buttons, always also enable the input window itself + if ( bEnable && !IsEnabled() ) + Enable(); + + EnableItem( SID_INPUT_FUNCTION, bEnable ); + EnableItem( bIsOkCancelMode ? SID_INPUT_CANCEL : SID_INPUT_SUM, bEnable ); + EnableItem( bIsOkCancelMode ? SID_INPUT_OK : SID_INPUT_EQUAL, bEnable ); +// Invalidate(); +} + +void ScInputWindow::StateChanged( StateChangedType nType ) +{ + ToolBox::StateChanged( nType ); + + if ( nType == STATE_CHANGE_INITSHOW ) Resize(); +} + +void ScInputWindow::DataChanged( const DataChangedEvent& rDCEvt ) +{ + if ( rDCEvt.GetType() == DATACHANGED_SETTINGS && (rDCEvt.GetFlags() & SETTINGS_STYLE) ) + { + // update item images + + ScModule* pScMod = SC_MOD(); + SfxImageManager* pImgMgr = SfxImageManager::GetImageManager( pScMod ); + BOOL bHC = GetSettings().GetStyleSettings().GetHighContrastMode(); + // IMAGE macro uses pScMod, pImgMgr, bHC + + SetItemImage( SID_INPUT_FUNCTION, IMAGE( SID_INPUT_FUNCTION ) ); + if ( bIsOkCancelMode ) + { + SetItemImage( SID_INPUT_CANCEL, IMAGE( SID_INPUT_CANCEL ) ); + SetItemImage( SID_INPUT_OK, IMAGE( SID_INPUT_OK ) ); + } + else + { + SetItemImage( SID_INPUT_SUM, IMAGE( SID_INPUT_SUM ) ); + SetItemImage( SID_INPUT_EQUAL, IMAGE( SID_INPUT_EQUAL ) ); + } + } + + ToolBox::DataChanged( rDCEvt ); +} + +//======================================================================== +// Eingabefenster +//======================================================================== + +ScTextWnd::ScTextWnd( Window* pParent ) + : Window ( pParent, WinBits(WB_HIDE | WB_BORDER) ), + DragSourceHelper( this ), + pEditEngine ( NULL ), + pEditView ( NULL ), + bIsInsertMode( TRUE ), + bFormulaMode ( FALSE ), + bInputMode ( FALSE ) +{ + EnableRTL( FALSE ); // #106269# EditEngine can't be used with VCL EnableRTL + + bIsRTL = GetSettings().GetLayoutRTL(); + + // #79096# always use application font, so a font with cjk chars can be installed + Font aAppFont = GetFont(); + aTextFont = aAppFont; + aTextFont.SetSize( PixelToLogic( aAppFont.GetSize(), MAP_TWIP ) ); // AppFont ist in Pixeln + + const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings(); + + Color aBgColor= rStyleSettings.GetWindowColor(); + Color aTxtColor= rStyleSettings.GetWindowTextColor(); + + aTextFont.SetTransparent ( TRUE ); + aTextFont.SetFillColor ( aBgColor ); + //aTextFont.SetColor ( COL_FIELDTEXT ); + aTextFont.SetColor (aTxtColor); + aTextFont.SetWeight ( WEIGHT_NORMAL ); + + SetSizePixel ( Size(1,TBX_WINDOW_HEIGHT) ); + SetBackground ( aBgColor ); + SetLineColor ( COL_BLACK ); + SetMapMode ( MAP_TWIP ); + SetPointer ( POINTER_TEXT ); +} + +__EXPORT ScTextWnd::~ScTextWnd() +{ + delete pEditView; + delete pEditEngine; + for( AccTextDataVector::reverse_iterator aIt = maAccTextDatas.rbegin(), aEnd = maAccTextDatas.rend(); aIt != aEnd; ++aIt ) + (*aIt)->Dispose(); +} + +void __EXPORT ScTextWnd::Paint( const Rectangle& rRec ) +{ + if (pEditView) + pEditView->Paint( rRec ); + else + { + SetFont( aTextFont ); + + long nDiff = GetOutputSizePixel().Height() + - LogicToPixel( Size( 0, GetTextHeight() ) ).Height(); +// if (nDiff<2) nDiff=2; // mind. 1 Pixel + + long nStartPos = TEXT_STARTPOS; + if ( bIsRTL ) + { + // right-align + nStartPos += GetOutputSizePixel().Width() - 2*TEXT_STARTPOS - + LogicToPixel( Size( GetTextWidth( aString ), 0 ) ).Width(); + + // LayoutMode isn't changed as long as ModifyRTLDefaults doesn't include SvxFrameDirectionItem + } + + DrawText( PixelToLogic( Point( nStartPos, nDiff/2 ) ), aString ); + } +} + +void __EXPORT ScTextWnd::Resize() +{ + if (pEditView) + { + Size aSize = GetOutputSizePixel(); + long nDiff = aSize.Height() + - LogicToPixel( Size( 0, GetTextHeight() ) ).Height(); + +#ifdef OS2_DOCH_NICHT + nDiff-=2; // wird durch 2 geteilt + // passt sonst nicht zur normalen Textausgabe +#endif + + aSize.Width() -= 2 * TEXT_STARTPOS - 1; + + pEditView->SetOutputArea( + PixelToLogic( Rectangle( Point( TEXT_STARTPOS, (nDiff > 0) ? nDiff/2 : 1 ), + aSize ) ) ); + } +} + +void __EXPORT ScTextWnd::MouseMove( const MouseEvent& rMEvt ) +{ + if (pEditView) + pEditView->MouseMove( rMEvt ); +} + +void __EXPORT ScTextWnd::MouseButtonDown( const MouseEvent& rMEvt ) +{ + if (!HasFocus()) + { + StartEditEngine(); + if ( SC_MOD()->IsEditMode() ) + GrabFocus(); + } + + if (pEditView) + { + pEditView->SetEditEngineUpdateMode( TRUE ); + pEditView->MouseButtonDown( rMEvt ); + } +} + +void __EXPORT ScTextWnd::MouseButtonUp( const MouseEvent& rMEvt ) +{ + if (pEditView) + if (pEditView->MouseButtonUp( rMEvt )) + { + if ( rMEvt.IsMiddle() && + GetSettings().GetMouseSettings().GetMiddleButtonAction() == MOUSE_MIDDLE_PASTESELECTION ) + { + // EditView may have pasted from selection + SC_MOD()->InputChanged( pEditView ); + } + else + SC_MOD()->InputSelection( pEditView ); + } +} + +void __EXPORT ScTextWnd::Command( const CommandEvent& rCEvt ) +{ + bInputMode = TRUE; + USHORT nCommand = rCEvt.GetCommand(); + if ( pEditView /* && ( nCommand == COMMAND_STARTDRAG || nCommand == COMMAND_VOICE ) */ ) + { + ScModule* pScMod = SC_MOD(); + ScTabViewShell* pStartViewSh = ScTabViewShell::GetActiveViewShell(); + + // #109441# don't modify the font defaults here - the right defaults are + // already set in StartEditEngine when the EditEngine is created + + // #63263# verhindern, dass die EditView beim View-Umschalten wegkommt + pScMod->SetInEditCommand( TRUE ); + pEditView->Command( rCEvt ); + pScMod->SetInEditCommand( FALSE ); + + // #48929# COMMAND_STARTDRAG heiss noch lange nicht, dass der Inhalt geaendert wurde + // darum in dem Fall kein InputChanged + //! erkennen, ob mit Move gedraggt wurde, oder Drag&Move irgendwie verbieten + + if ( nCommand == COMMAND_STARTDRAG ) + { + // ist auf eine andere View gedraggt worden? + ScTabViewShell* pEndViewSh = ScTabViewShell::GetActiveViewShell(); + if ( pEndViewSh != pStartViewSh && pStartViewSh != NULL ) + { + ScViewData* pViewData = pStartViewSh->GetViewData(); + ScInputHandler* pHdl = pScMod->GetInputHdl( pStartViewSh ); + if ( pHdl && pViewData->HasEditView( pViewData->GetActivePart() ) ) + { + pHdl->CancelHandler(); + pViewData->GetView()->ShowCursor(); // fehlt bei KillEditView, weil nicht aktiv + } + } + } + else if ( nCommand == COMMAND_CURSORPOS ) + { + // don't call InputChanged for COMMAND_CURSORPOS + } + else if ( nCommand == COMMAND_INPUTLANGUAGECHANGE ) + { + // #i55929# Font and font size state depends on input language if nothing is selected, + // so the slots have to be invalidated when the input language is changed. + + SfxViewFrame* pViewFrm = SfxViewFrame::Current(); + if (pViewFrm) + { + SfxBindings& rBindings = pViewFrm->GetBindings(); + rBindings.Invalidate( SID_ATTR_CHAR_FONT ); + rBindings.Invalidate( SID_ATTR_CHAR_FONTHEIGHT ); + } + } + else + SC_MOD()->InputChanged( pEditView ); + } + else + Window::Command(rCEvt); // sonst soll sich die Basisklasse drum kuemmern... + + bInputMode = FALSE; +} + +void ScTextWnd::StartDrag( sal_Int8 /* nAction */, const Point& rPosPixel ) +{ + if ( pEditView ) + { + CommandEvent aDragEvent( rPosPixel, COMMAND_STARTDRAG, TRUE ); + pEditView->Command( aDragEvent ); + + // handling of d&d to different view (CancelHandler) can't be done here, + // because the call returns before d&d is complete. + } +} + +void __EXPORT ScTextWnd::KeyInput(const KeyEvent& rKEvt) +{ + bInputMode = TRUE; + if (!SC_MOD()->InputKeyEvent( rKEvt )) + { + BOOL bUsed = FALSE; + ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell(); + if ( pViewSh ) + bUsed = pViewSh->SfxKeyInput(rKEvt); // nur Acceleratoren, keine Eingabe + if (!bUsed) + Window::KeyInput( rKEvt ); + } + bInputMode = FALSE; +} + +void __EXPORT ScTextWnd::GetFocus() +{ + ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell(); + if ( pViewSh ) + pViewSh->SetFormShellAtTop( FALSE ); // focus in input line -> FormShell no longer on top +} + +void __EXPORT ScTextWnd::LoseFocus() +{ +} + +String __EXPORT ScTextWnd::GetText() const +{ + // ueberladen, um per Testtool an den Text heranzukommen + + if ( pEditEngine ) + return pEditEngine->GetText(); + else + return GetTextString(); +} + +void ScTextWnd::SetFormulaMode( BOOL bSet ) +{ + if ( bSet != bFormulaMode ) + { + bFormulaMode = bSet; + UpdateAutoCorrFlag(); + } +} + +void ScTextWnd::UpdateAutoCorrFlag() +{ + if ( pEditEngine ) + { + ULONG nControl = pEditEngine->GetControlWord(); + ULONG nOld = nControl; + if ( bFormulaMode ) + nControl &= ~EE_CNTRL_AUTOCORRECT; // keine Autokorrektur in Formeln + else + nControl |= EE_CNTRL_AUTOCORRECT; // sonst schon + if ( nControl != nOld ) + pEditEngine->SetControlWord( nControl ); + } +} + +void lcl_ExtendEditFontAttribs( SfxItemSet& rSet ) +{ + const SfxPoolItem& rFontItem = rSet.Get( EE_CHAR_FONTINFO ); + rSet.Put( rFontItem, EE_CHAR_FONTINFO_CJK ); + rSet.Put( rFontItem, EE_CHAR_FONTINFO_CTL ); + const SfxPoolItem& rHeightItem = rSet.Get( EE_CHAR_FONTHEIGHT ); + rSet.Put( rHeightItem, EE_CHAR_FONTHEIGHT_CJK ); + rSet.Put( rHeightItem, EE_CHAR_FONTHEIGHT_CTL ); + const SfxPoolItem& rWeightItem = rSet.Get( EE_CHAR_WEIGHT ); + rSet.Put( rWeightItem, EE_CHAR_WEIGHT_CJK ); + rSet.Put( rWeightItem, EE_CHAR_WEIGHT_CTL ); + const SfxPoolItem& rItalicItem = rSet.Get( EE_CHAR_ITALIC ); + rSet.Put( rItalicItem, EE_CHAR_ITALIC_CJK ); + rSet.Put( rItalicItem, EE_CHAR_ITALIC_CTL ); + const SfxPoolItem& rLangItem = rSet.Get( EE_CHAR_LANGUAGE ); + rSet.Put( rLangItem, EE_CHAR_LANGUAGE_CJK ); + rSet.Put( rLangItem, EE_CHAR_LANGUAGE_CTL ); +} + +void lcl_ModifyRTLDefaults( SfxItemSet& rSet ) +{ + rSet.Put( SvxAdjustItem( SVX_ADJUST_RIGHT, EE_PARA_JUST ) ); + + // always using rtl writing direction would break formulas + //rSet.Put( SvxFrameDirectionItem( FRMDIR_HORI_RIGHT_TOP, EE_PARA_WRITINGDIR ) ); + + // PaperSize width is limited to USHRT_MAX in RTL mode (because of EditEngine's + // USHORT values in EditLine), so the text may be wrapped and line spacing must be + // increased to not see the beginning of the next line. + SvxLineSpacingItem aItem( SVX_LINESPACE_TWO_LINES, EE_PARA_SBL ); + aItem.SetPropLineSpace( 200 ); + rSet.Put( aItem ); +} + +void lcl_ModifyRTLVisArea( EditView* pEditView ) +{ + Rectangle aVisArea = pEditView->GetVisArea(); + Size aPaper = pEditView->GetEditEngine()->GetPaperSize(); + long nDiff = aPaper.Width() - aVisArea.Right(); + aVisArea.Left() += nDiff; + aVisArea.Right() += nDiff; + pEditView->SetVisArea(aVisArea); +} + +void ScTextWnd::StartEditEngine() +{ + // #31147# Bei "eigener Modalitaet" (Doc-modale Dialoge) nicht aktivieren + SfxObjectShell* pObjSh = SfxObjectShell::Current(); + if ( pObjSh && pObjSh->IsInModalMode() ) + return; + + if ( !pEditView || !pEditEngine ) + { + ScFieldEditEngine* pNew; + ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell(); + if ( pViewSh ) + { + const ScDocument* pDoc = pViewSh->GetViewData()->GetDocument(); + pNew = new ScFieldEditEngine( pDoc->GetEnginePool(), pDoc->GetEditPool() ); + } + else + pNew = new ScFieldEditEngine( EditEngine::CreatePool(), NULL, TRUE ); + pNew->SetExecuteURL( FALSE ); + pEditEngine = pNew; + + pEditEngine->SetUpdateMode( FALSE ); + pEditEngine->SetPaperSize( Size( bIsRTL ? USHRT_MAX : THESIZE, 300 ) ); + pEditEngine->SetWordDelimiters( + ScEditUtil::ModifyDelimiters( pEditEngine->GetWordDelimiters() ) ); + + UpdateAutoCorrFlag(); + + { + SfxItemSet* pSet = new SfxItemSet( pEditEngine->GetEmptyItemSet() ); + pEditEngine->SetFontInfoInItemSet( *pSet, aTextFont ); + lcl_ExtendEditFontAttribs( *pSet ); + // turn off script spacing to match DrawText output + pSet->Put( SvxScriptSpaceItem( FALSE, EE_PARA_ASIANCJKSPACING ) ); + if ( bIsRTL ) + lcl_ModifyRTLDefaults( *pSet ); + pEditEngine->SetDefaults( pSet ); + } + + // #57254# Wenn in der Zelle URL-Felder enthalten sind, muessen die auch in + // die Eingabezeile uebernommen werden, weil sonst die Positionen nicht stimmen. + + BOOL bFilled = FALSE; + ScInputHandler* pHdl = SC_MOD()->GetInputHdl(); + if ( pHdl ) //! Testen, ob's der richtige InputHdl ist? + bFilled = pHdl->GetTextAndFields( *pEditEngine ); + + pEditEngine->SetUpdateMode( TRUE ); + + // aString ist die Wahrheit... + if ( bFilled && pEditEngine->GetText() == aString ) + Invalidate(); // Repaint fuer (hinterlegte) Felder + else + pEditEngine->SetText(aString); // dann wenigstens den richtigen Text + + pEditView = new EditView( pEditEngine, this ); + pEditView->SetInsertMode(bIsInsertMode); + + // Text aus Clipboard wird als ASCII einzeilig uebernommen + ULONG n = pEditView->GetControlWord(); + pEditView->SetControlWord( n | EV_CNTRL_SINGLELINEPASTE ); + + pEditEngine->InsertView( pEditView, EE_APPEND ); + + Resize(); + + if ( bIsRTL ) + lcl_ModifyRTLVisArea( pEditView ); + + pEditEngine->SetModifyHdl(LINK(this, ScTextWnd, NotifyHdl)); + + if (!maAccTextDatas.empty()) + maAccTextDatas.back()->StartEdit(); + + // as long as EditEngine and DrawText sometimes differ for CTL text, + // repaint now to have the EditEngine's version visible +// SfxObjectShell* pObjSh = SfxObjectShell::Current(); + if ( pObjSh && pObjSh->ISA(ScDocShell) ) + { + ScDocument* pDoc = ((ScDocShell*)pObjSh)->GetDocument(); // any document + BYTE nScript = pDoc->GetStringScriptType( aString ); + if ( nScript & SCRIPTTYPE_COMPLEX ) + Invalidate(); + } + } + + SC_MOD()->SetInputMode( SC_INPUT_TOP ); + + SfxViewFrame* pViewFrm = SfxViewFrame::Current(); + if (pViewFrm) + pViewFrm->GetBindings().Invalidate( SID_ATTR_INSERT ); +} + +IMPL_LINK(ScTextWnd, NotifyHdl, EENotify*, EMPTYARG) +{ + if (pEditView && !bInputMode) + { + ScInputHandler* pHdl = SC_MOD()->GetInputHdl(); + + // #105354# Use the InputHandler's InOwnChange flag to prevent calling InputChanged + // while an InputHandler method is modifying the EditEngine content + + if ( pHdl && !pHdl->IsInOwnChange() ) + pHdl->InputChanged( pEditView, TRUE ); // #i20282# InputChanged must know if called from modify handler + } + + return 0; +} + +void ScTextWnd::StopEditEngine( BOOL bAll ) +{ + if (pEditView) + { + if (!maAccTextDatas.empty()) + maAccTextDatas.back()->EndEdit(); + + ScModule* pScMod = SC_MOD(); + + if (!bAll) + pScMod->InputSelection( pEditView ); + aString = pEditEngine->GetText(); + bIsInsertMode = pEditView->IsInsertMode(); + BOOL bSelection = pEditView->HasSelection(); + pEditEngine->SetModifyHdl(Link()); + DELETEZ(pEditView); + DELETEZ(pEditEngine); + + if ( pScMod->IsEditMode() && !bAll ) + pScMod->SetInputMode(SC_INPUT_TABLE); + + SfxViewFrame* pViewFrm = SfxViewFrame::Current(); + if (pViewFrm) + pViewFrm->GetBindings().Invalidate( SID_ATTR_INSERT ); + + if (bSelection) + Invalidate(); // damit Selektion nicht stehenbleibt + } +} + +void ScTextWnd::SetTextString( const String& rNewString ) +{ + if ( rNewString != aString ) + { + bInputMode = TRUE; + + // Position der Aenderung suchen, nur Rest painten + + long nInvPos = 0; + long nStartPos = 0; + long nTextSize = 0; + + if (!pEditEngine) + { + BOOL bPaintAll; + if ( bIsRTL ) + bPaintAll = TRUE; + else + { + // test if CTL script type is involved + BYTE nOldScript = 0; + BYTE nNewScript = 0; + SfxObjectShell* pObjSh = SfxObjectShell::Current(); + if ( pObjSh && pObjSh->ISA(ScDocShell) ) + { + // any document can be used (used only for its break iterator) + ScDocument* pDoc = ((ScDocShell*)pObjSh)->GetDocument(); + nOldScript = pDoc->GetStringScriptType( aString ); + nNewScript = pDoc->GetStringScriptType( rNewString ); + } + bPaintAll = ( nOldScript & SCRIPTTYPE_COMPLEX ) || ( nNewScript & SCRIPTTYPE_COMPLEX ); + } + + if ( bPaintAll ) + { + // if CTL is involved, the whole text has to be redrawn + Invalidate(); + } + else + { + xub_StrLen nDifPos; + if (rNewString.Len() > aString.Len()) + nDifPos = rNewString.Match(aString); + else + nDifPos = aString.Match(rNewString); + + long nSize1 = GetTextWidth(aString); + long nSize2 = GetTextWidth(rNewString); + if ( nSize1>0 && nSize2>0 ) + nTextSize = Max( nSize1, nSize2 ); + else + nTextSize = GetOutputSize().Width(); // Ueberlauf + + if (nDifPos == STRING_MATCH) + nDifPos = 0; + + // -1 wegen Rundung und "A" + Point aLogicStart = PixelToLogic(Point(TEXT_STARTPOS-1,0)); + nStartPos = aLogicStart.X(); + nInvPos = nStartPos; + if (nDifPos) + nInvPos += GetTextWidth(aString,0,nDifPos); + + USHORT nFlags = 0; + if ( nDifPos == aString.Len() ) // only new characters appended + nFlags = INVALIDATE_NOERASE; // then background is already clear + + Invalidate( Rectangle( nInvPos, 0, + nStartPos+nTextSize, GetOutputSize().Height()-1 ), + nFlags ); + } + } + else + { + pEditEngine->SetText(rNewString); + } + + aString = rNewString; + + if (!maAccTextDatas.empty()) + maAccTextDatas.back()->TextChanged(); + + bInputMode = FALSE; + } +} + +const String& ScTextWnd::GetTextString() const +{ + return aString; +} + +BOOL ScTextWnd::IsInputActive() +{ + return HasFocus(); +} + +EditView* ScTextWnd::GetEditView() +{ + return pEditView; +} + +void ScTextWnd::MakeDialogEditView() +{ + if ( pEditView ) return; + + ScFieldEditEngine* pNew; + ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell(); + if ( pViewSh ) + { + const ScDocument* pDoc = pViewSh->GetViewData()->GetDocument(); + pNew = new ScFieldEditEngine( pDoc->GetEnginePool(), pDoc->GetEditPool() ); + } + else + pNew = new ScFieldEditEngine( EditEngine::CreatePool(), NULL, TRUE ); + pNew->SetExecuteURL( FALSE ); + pEditEngine = pNew; + + pEditEngine->SetUpdateMode( FALSE ); + pEditEngine->SetWordDelimiters( pEditEngine->GetWordDelimiters() += '=' ); + pEditEngine->SetPaperSize( Size( bIsRTL ? USHRT_MAX : THESIZE, 300 ) ); + + SfxItemSet* pSet = new SfxItemSet( pEditEngine->GetEmptyItemSet() ); + pEditEngine->SetFontInfoInItemSet( *pSet, aTextFont ); + lcl_ExtendEditFontAttribs( *pSet ); + if ( bIsRTL ) + lcl_ModifyRTLDefaults( *pSet ); + pEditEngine->SetDefaults( pSet ); + pEditEngine->SetUpdateMode( TRUE ); + + pEditView = new EditView( pEditEngine, this ); + pEditEngine->InsertView( pEditView, EE_APPEND ); + + Resize(); + + if ( bIsRTL ) + lcl_ModifyRTLVisArea( pEditView ); + + if (!maAccTextDatas.empty()) + maAccTextDatas.back()->StartEdit(); +} + +void ScTextWnd::ImplInitSettings() +{ + bIsRTL = GetSettings().GetLayoutRTL(); + + const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings(); + + Color aBgColor= rStyleSettings.GetWindowColor(); + Color aTxtColor= rStyleSettings.GetWindowTextColor(); + + aTextFont.SetFillColor ( aBgColor ); + aTextFont.SetColor (aTxtColor); + SetBackground ( aBgColor ); + Invalidate(); +} + +::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > ScTextWnd::CreateAccessible() +{ + return new ScAccessibleEditObject(GetAccessibleParentWindow()->GetAccessible(), NULL, this, + rtl::OUString(String(ScResId(STR_ACC_EDITLINE_NAME))), + rtl::OUString(String(ScResId(STR_ACC_EDITLINE_DESCR))), EditLine); +} + +void ScTextWnd::InsertAccessibleTextData( ScAccessibleEditLineTextData& rTextData ) +{ + OSL_ENSURE( ::std::find( maAccTextDatas.begin(), maAccTextDatas.end(), &rTextData ) == maAccTextDatas.end(), + "ScTextWnd::InsertAccessibleTextData - passed object already registered" ); + maAccTextDatas.push_back( &rTextData ); +} + +void ScTextWnd::RemoveAccessibleTextData( ScAccessibleEditLineTextData& rTextData ) +{ + AccTextDataVector::iterator aEnd = maAccTextDatas.end(); + AccTextDataVector::iterator aIt = ::std::find( maAccTextDatas.begin(), aEnd, &rTextData ); + OSL_ENSURE( aIt != aEnd, "ScTextWnd::RemoveAccessibleTextData - passed object not registered" ); + if( aIt != aEnd ) + maAccTextDatas.erase( aIt ); +} + +// ----------------------------------------------------------------------- + +void ScTextWnd::DataChanged( const DataChangedEvent& rDCEvt ) +{ + if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && + (rDCEvt.GetFlags() & SETTINGS_STYLE) ) + { + ImplInitSettings(); + Invalidate(); + } + else + Window::DataChanged( rDCEvt ); +} + + +//======================================================================== +// Positionsfenster +//======================================================================== + +ScPosWnd::ScPosWnd( Window* pParent ) : + ComboBox ( pParent, WinBits(WB_HIDE | WB_DROPDOWN) ), + pAccel ( NULL ), + nTipVisible ( 0 ), + bFormulaMode( FALSE ) +{ + Size aSize( GetTextWidth( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("GW99999:GW99999")) ), + GetTextHeight() ); + aSize.Width() += 25; // ?? + aSize.Height() = CalcWindowSizePixel(11); // Funktionen: 10 MRU + "andere..." + SetSizePixel( aSize ); + + FillRangeNames(); + + StartListening( *SFX_APP() ); // fuer Navigator-Bereichsnamen-Updates +} + +__EXPORT ScPosWnd::~ScPosWnd() +{ + EndListening( *SFX_APP() ); + + HideTip(); + + delete pAccel; +} + +void ScPosWnd::SetFormulaMode( BOOL bSet ) +{ + if ( bSet != bFormulaMode ) + { + bFormulaMode = bSet; + + if ( bSet ) + FillFunctions(); + else + FillRangeNames(); + + HideTip(); + } +} + +void ScPosWnd::SetPos( const String& rPosStr ) +{ + if ( aPosStr != rPosStr ) + { + aPosStr = rPosStr; + SetText(aPosStr); + } +} + +void ScPosWnd::FillRangeNames() +{ + Clear(); + + SfxObjectShell* pObjSh = SfxObjectShell::Current(); + if ( pObjSh && pObjSh->ISA(ScDocShell) ) + { + ScDocument* pDoc = ((ScDocShell*)pObjSh)->GetDocument(); + + // per Hand sortieren, weil Funktionen nicht sortiert werden: + + ScRangeName* pRangeNames = pDoc->GetRangeName(); + USHORT nCount = pRangeNames->GetCount(); + if ( nCount > 0 ) + { + USHORT nValidCount = 0; + ScRange aDummy; + USHORT i; + for ( i=0; i<nCount; i++ ) + { + ScRangeData* pData = (*pRangeNames)[i]; + if (pData->IsValidReference(aDummy)) + nValidCount++; + } + if ( nValidCount ) + { + ScRangeData** ppSortArray = new ScRangeData* [ nValidCount ]; + USHORT j; + for ( i=0, j=0; i<nCount; i++ ) + { + ScRangeData* pData = (*pRangeNames)[i]; + if (pData->IsValidReference(aDummy)) + ppSortArray[j++] = pData; + } +#ifndef ICC + qsort( (void*)ppSortArray, nValidCount, sizeof(ScRangeData*), + &ScRangeData_QsortNameCompare ); +#else + qsort( (void*)ppSortArray, nValidCount, sizeof(ScRangeData*), + ICCQsortNameCompare ); +#endif + for ( j=0; j<nValidCount; j++ ) + InsertEntry( ppSortArray[j]->GetName() ); + delete [] ppSortArray; + } + } + } + SetText(aPosStr); +} + +void ScPosWnd::FillFunctions() +{ + Clear(); + + String aFirstName; + const ScAppOptions& rOpt = SC_MOD()->GetAppOptions(); + USHORT nMRUCount = rOpt.GetLRUFuncListCount(); + const USHORT* pMRUList = rOpt.GetLRUFuncList(); + if (pMRUList) + { + const ScFunctionList* pFuncList = ScGlobal::GetStarCalcFunctionList(); + ULONG nListCount = pFuncList->GetCount(); + for (USHORT i=0; i<nMRUCount; i++) + { + USHORT nId = pMRUList[i]; + for (ULONG j=0; j<nListCount; j++) + { + const ScFuncDesc* pDesc = pFuncList->GetFunction( j ); + if ( pDesc->nFIndex == nId && pDesc->pFuncName ) + { + InsertEntry( *pDesc->pFuncName ); + if (!aFirstName.Len()) + aFirstName = *pDesc->pFuncName; + break; // nicht weitersuchen + } + } + } + } + + //! Eintrag "Andere..." fuer Funktions-Autopilot wieder aufnehmen, + //! wenn der Funktions-Autopilot mit dem bisher eingegebenen Text arbeiten kann! + +// InsertEntry( ScGlobal::GetRscString(STR_FUNCTIONLIST_MORE) ); + + SetText(aFirstName); +} + +void __EXPORT ScPosWnd::Notify( SfxBroadcaster&, const SfxHint& rHint ) +{ + if ( !bFormulaMode ) + { + // muss die Liste der Bereichsnamen updgedated werden? + + if ( rHint.ISA(SfxSimpleHint) ) + { + ULONG nHintId = ((SfxSimpleHint&)rHint).GetId(); + if ( nHintId == SC_HINT_AREAS_CHANGED || nHintId == SC_HINT_NAVIGATOR_UPDATEALL) + FillRangeNames(); + } + else if ( rHint.ISA(SfxEventHint) ) + { + ULONG nEventId = ((SfxEventHint&)rHint).GetEventId(); + if ( nEventId == SFX_EVENT_ACTIVATEDOC ) + FillRangeNames(); + } + } +} + +void ScPosWnd::HideTip() +{ + if ( nTipVisible ) + { + Help::HideTip( nTipVisible ); + nTipVisible = 0; + } +} + +ScNameInputType lcl_GetInputType( const String& rText ) +{ + ScNameInputType eRet = SC_NAME_INPUT_BAD_NAME; // the more general error + + ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell(); + if ( pViewSh ) + { + ScViewData* pViewData = pViewSh->GetViewData(); + ScDocument* pDoc = pViewData->GetDocument(); + SCTAB nTab = pViewData->GetTabNo(); + formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention(); + + // test in same order as in SID_CURRENTCELL execute + + ScRange aRange; + ScAddress aAddress; + ScRangeUtil aRangeUtil; + SCTAB nNameTab; + sal_Int32 nNumeric; + + if ( aRange.Parse( rText, pDoc, eConv ) & SCA_VALID ) + eRet = SC_NAME_INPUT_NAMEDRANGE; + else if ( aAddress.Parse( rText, pDoc, eConv ) & SCA_VALID ) + eRet = SC_NAME_INPUT_CELL; + else if ( aRangeUtil.MakeRangeFromName( rText, pDoc, nTab, aRange, RUTL_NAMES, eConv ) ) + eRet = SC_NAME_INPUT_NAMEDRANGE; + else if ( aRangeUtil.MakeRangeFromName( rText, pDoc, nTab, aRange, RUTL_DBASE, eConv ) ) + eRet = SC_NAME_INPUT_DATABASE; + else if ( ByteString( rText, RTL_TEXTENCODING_ASCII_US ).IsNumericAscii() && + ( nNumeric = rText.ToInt32() ) > 0 && nNumeric <= MAXROW+1 ) + eRet = SC_NAME_INPUT_ROW; + else if ( pDoc->GetTable( rText, nNameTab ) ) + eRet = SC_NAME_INPUT_SHEET; + else if ( ScRangeData::IsNameValid( rText, pDoc ) ) // nothing found, create new range? + { + if ( pViewData->GetSimpleArea( aRange ) == SC_MARK_SIMPLE ) + eRet = SC_NAME_INPUT_DEFINE; + else + eRet = SC_NAME_INPUT_BAD_SELECTION; + } + else + eRet = SC_NAME_INPUT_BAD_NAME; + } + + return eRet; +} + +void ScPosWnd::Modify() +{ + ComboBox::Modify(); + + HideTip(); + + if ( !IsTravelSelect() && !bFormulaMode ) + { + // determine the action that would be taken for the current input + + ScNameInputType eType = lcl_GetInputType( GetText() ); // uses current view + USHORT nStrId = 0; + switch ( eType ) + { + case SC_NAME_INPUT_CELL: + nStrId = STR_NAME_INPUT_CELL; + break; + case SC_NAME_INPUT_RANGE: + case SC_NAME_INPUT_NAMEDRANGE: + nStrId = STR_NAME_INPUT_RANGE; // named range or range reference + break; + case SC_NAME_INPUT_DATABASE: + nStrId = STR_NAME_INPUT_DBRANGE; + break; + case SC_NAME_INPUT_ROW: + nStrId = STR_NAME_INPUT_ROW; + break; + case SC_NAME_INPUT_SHEET: + nStrId = STR_NAME_INPUT_SHEET; + break; + case SC_NAME_INPUT_DEFINE: + nStrId = STR_NAME_INPUT_DEFINE; + break; + default: + // other cases (error): no tip help + break; + } + + if ( nStrId ) + { + // show the help tip at the text cursor position + + Window* pWin = GetSubEdit(); + if (!pWin) + pWin = this; + Point aPos; + Cursor* pCur = pWin->GetCursor(); + if (pCur) + aPos = pWin->LogicToPixel( pCur->GetPos() ); + aPos = pWin->OutputToScreenPixel( aPos ); + Rectangle aRect( aPos, aPos ); + + String aText = ScGlobal::GetRscString( nStrId ); + USHORT nAlign = QUICKHELP_LEFT|QUICKHELP_BOTTOM; + nTipVisible = Help::ShowTip(pWin, aRect, aText, nAlign); + } + } +} + +void __EXPORT ScPosWnd::Select() +{ + ComboBox::Select(); // in VCL gibt GetText() erst danach den ausgewaehlten Eintrag + + HideTip(); + + if (!IsTravelSelect()) + DoEnter(); +} + +void ScPosWnd::DoEnter() +{ + String aText = GetText(); + if ( aText.Len() ) + { + if ( bFormulaMode ) + { + ScModule* pScMod = SC_MOD(); + if ( aText == ScGlobal::GetRscString(STR_FUNCTIONLIST_MORE) ) + { + // Funktions-Autopilot + //! mit dem bisher eingegebenen Text weiterarbeiten !!! + + //! new method at ScModule to query if function autopilot is open + SfxViewFrame* pViewFrm = SfxViewFrame::Current(); + if ( pViewFrm && !pViewFrm->GetChildWindow( SID_OPENDLG_FUNCTION ) ) + pViewFrm->GetDispatcher()->Execute( SID_OPENDLG_FUNCTION, + SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD ); + } + else + { + ScTabViewShell* pViewSh = PTR_CAST( ScTabViewShell, SfxViewShell::Current() ); + ScInputHandler* pHdl = pScMod->GetInputHdl( pViewSh ); + if (pHdl) + pHdl->InsertFunction( aText ); + } + } + else + { + // depending on the input, select something or create a new named range + + ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell(); + if ( pViewSh ) + { + ScNameInputType eType = lcl_GetInputType( aText ); + if ( eType == SC_NAME_INPUT_BAD_NAME || eType == SC_NAME_INPUT_BAD_SELECTION ) + { + USHORT nId = ( eType == SC_NAME_INPUT_BAD_NAME ) ? STR_NAME_ERROR_NAME : STR_NAME_ERROR_SELECTION; + pViewSh->ErrorMessage( nId ); + } + else if ( eType == SC_NAME_INPUT_DEFINE ) + { + ScViewData* pViewData = pViewSh->GetViewData(); + ScDocShell* pDocShell = pViewData->GetDocShell(); + ScDocument* pDoc = pDocShell->GetDocument(); + ScRangeName* pNames = pDoc->GetRangeName(); + ScRange aSelection; + USHORT nIndex = 0; + if ( pNames && !pNames->SearchName( aText, nIndex ) && + (pViewData->GetSimpleArea( aSelection ) == SC_MARK_SIMPLE) ) + { + ScRangeName aNewRanges( *pNames ); + ScAddress aCursor( pViewData->GetCurX(), pViewData->GetCurY(), pViewData->GetTabNo() ); + String aContent; + aSelection.Format( aContent, SCR_ABS_3D, pDoc, pDoc->GetAddressConvention() ); + ScRangeData* pNew = new ScRangeData( pDoc, aText, aContent, aCursor ); + if ( aNewRanges.Insert(pNew) ) + { + ScDocFunc aFunc(*pDocShell); + aFunc.ModifyRangeNames( aNewRanges, FALSE ); + pViewSh->UpdateInputHandler(TRUE); + } + else + delete pNew; // shouldn't happen + } + } + else + { + // for all selection types, excecute the SID_CURRENTCELL slot + + SfxStringItem aPosItem( SID_CURRENTCELL, aText ); + SfxBoolItem aUnmarkItem( FN_PARAM_1, TRUE ); // remove existing selection + + pViewSh->GetViewData()->GetDispatcher().Execute( SID_CURRENTCELL, + SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD, + &aPosItem, &aUnmarkItem, 0L ); + } + } + } + } + else + SetText( aPosStr ); + + ReleaseFocus_Impl(); +} + +long __EXPORT ScPosWnd::Notify( NotifyEvent& rNEvt ) +{ + long nHandled = 0; + + if ( rNEvt.GetType() == EVENT_KEYINPUT ) + { + const KeyEvent* pKEvt = rNEvt.GetKeyEvent(); + + switch ( pKEvt->GetKeyCode().GetCode() ) + { + case KEY_RETURN: + DoEnter(); + nHandled = 1; + break; + + case KEY_ESCAPE: + if (nTipVisible) + { + // escape when the tip help is shown: only hide the tip + HideTip(); + } + else + { + if (!bFormulaMode) + SetText( aPosStr ); + ReleaseFocus_Impl(); + } + nHandled = 1; + break; + } + } + + if ( !nHandled ) + nHandled = ComboBox::Notify( rNEvt ); + + if ( rNEvt.GetType() == EVENT_LOSEFOCUS ) + HideTip(); + + return nHandled; +} + +void ScPosWnd::ReleaseFocus_Impl() +{ + HideTip(); + + SfxViewShell* pCurSh = SfxViewShell::Current(); + ScInputHandler* pHdl = SC_MOD()->GetInputHdl( PTR_CAST( ScTabViewShell, pCurSh ) ); + if ( pHdl && pHdl->IsTopMode() ) + { + // Focus wieder in die Eingabezeile? + + ScInputWindow* pInputWin = pHdl->GetInputWindow(); + if (pInputWin) + { + pInputWin->TextGrabFocus(); + return; + } + } + + // Focus auf die aktive View + + if ( pCurSh ) + { + Window* pShellWnd = pCurSh->GetWindow(); + + if ( pShellWnd ) + pShellWnd->GrabFocus(); + } +} + + + + + + diff --git a/sc/source/ui/app/lnktrans.cxx b/sc/source/ui/app/lnktrans.cxx new file mode 100644 index 000000000000..2e0f5d276a97 --- /dev/null +++ b/sc/source/ui/app/lnktrans.cxx @@ -0,0 +1,97 @@ +/************************************************************************* + * + * 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_sc.hxx" + +// INCLUDE --------------------------------------------------------------- + + + +#include <svl/urlbmk.hxx> + +#include "lnktrans.hxx" +#include "scmod.hxx" + +using namespace com::sun::star; + +// ----------------------------------------------------------------------- + +ScLinkTransferObj::ScLinkTransferObj() +{ +} + +ScLinkTransferObj::~ScLinkTransferObj() +{ +} + +void ScLinkTransferObj::SetLinkURL( const String& rURL, const String& rText ) +{ + aLinkURL = rURL; + aLinkText = rText; +} + +void ScLinkTransferObj::AddSupportedFormats() +{ + if ( aLinkURL.Len() ) + { + // TransferableHelper::SetINetBookmark formats + + AddFormat( SOT_FORMATSTR_ID_SOLK ); + AddFormat( SOT_FORMAT_STRING ); + AddFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ); + AddFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ); + AddFormat( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR ); + AddFormat( SOT_FORMATSTR_ID_FILECONTENT ); + } +} + +sal_Bool ScLinkTransferObj::GetData( const ::com::sun::star::datatransfer::DataFlavor& rFlavor ) +{ + sal_Bool bOK = sal_False; + if ( aLinkURL.Len() ) + { + INetBookmark aBmk( aLinkURL, aLinkText ); + bOK = SetINetBookmark( aBmk, rFlavor ); + } + return bOK; +} + +void ScLinkTransferObj::ObjectReleased() +{ + TransferableHelper::ObjectReleased(); +} + +void ScLinkTransferObj::DragFinished( sal_Int8 nDropAction ) +{ + ScModule* pScMod = SC_MOD(); + pScMod->ResetDragObject(); + + TransferableHelper::DragFinished( nDropAction ); +} + + diff --git a/sc/source/ui/app/makefile.mk b/sc/source/ui/app/makefile.mk new file mode 100644 index 000000000000..a5e4fe8cc024 --- /dev/null +++ b/sc/source/ui/app/makefile.mk @@ -0,0 +1,73 @@ +#************************************************************************* +# +# 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. +# +#************************************************************************* + +PRJ=..$/..$/.. + +PRJNAME=sc +TARGET=app + +# --- Settings ----------------------------------------------------- + +.INCLUDE : scpre.mk +.INCLUDE : settings.mk +.INCLUDE : sc.mk +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES = \ + $(SLO)$/scmod.obj \ + $(SLO)$/scmod2.obj \ + $(SLO)$/scdll.obj \ + $(SLO)$/typemap.obj \ + $(SLO)$/transobj.obj \ + $(SLO)$/drwtrans.obj \ + $(SLO)$/lnktrans.obj \ + $(SLO)$/seltrans.obj \ + $(SLO)$/inputhdl.obj \ + $(SLO)$/inputwin.obj \ + $(SLO)$/rfindlst.obj \ + $(SLO)$/uiitems.obj \ + $(SLO)$/msgpool.obj \ + $(SLO)$/client.obj + +EXCEPTIONSFILES= \ + $(SLO)$/drwtrans.obj \ + $(SLO)$/scmod2.obj \ + $(SLO)$/scmod.obj \ + $(SLO)$/client.obj \ + $(SLO)$/inputwin.obj + +#LIB3TARGET=$(SLB)$/ysclib.lib +#LIB3OBJFILES=$(SLO)$/sclib.obj + +# --- Targets ------------------------------------------------------- + +.INCLUDE : target.mk + +$(SRS)$/app.srs: $(SOLARINCDIR)$/svx$/globlmn.hrc + diff --git a/sc/source/ui/app/msgpool.cxx b/sc/source/ui/app/msgpool.cxx new file mode 100644 index 000000000000..78cb70fa64f0 --- /dev/null +++ b/sc/source/ui/app/msgpool.cxx @@ -0,0 +1,123 @@ +/************************************************************************* + * + * 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_sc.hxx" + + + +#include "scitems.hxx" +#include <svx/dialogs.hrc> + +#include "sc.hrc" +#include "docpool.hxx" +#include "msgpool.hxx" + +//------------------------------------------------------------------------ + +static SfxItemInfo __READONLY_DATA aMsgItemInfos[] = +{ + { 0, SFX_ITEM_POOLABLE }, // SCITEM_STRING + { 0, SFX_ITEM_POOLABLE }, // SCITEM_SEARCHDATA - nicht mehr benutzt !!! + { SID_SORT, SFX_ITEM_POOLABLE }, // SCITEM_SORTDATA + { SID_QUERY, SFX_ITEM_POOLABLE }, // SCITEM_QUERYDATA + { SID_SUBTOTALS, SFX_ITEM_POOLABLE }, // SCITEM_SUBTDATA + { SID_CONSOLIDATE, SFX_ITEM_POOLABLE }, // SCITEM_CONSOLIDATEDATA + { SID_PIVOT_TABLE, SFX_ITEM_POOLABLE }, // SCITEM_PIVOTDATA + { SID_SOLVE, SFX_ITEM_POOLABLE }, // SCITEM_SOLVEDATA + { SID_SCUSERLISTS, SFX_ITEM_POOLABLE }, // SCITEM_USERLIST + { SID_PRINTER_NOTFOUND_WARN, SFX_ITEM_POOLABLE } // SCITEM_PRINTWARN +}; + +//------------------------------------------------------------------------ + +ScMessagePool::ScMessagePool() + : SfxItemPool ( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("ScMessagePool")), + MSGPOOL_START, MSGPOOL_END, + aMsgItemInfos, NULL ), + // + aGlobalStringItem ( SfxStringItem ( SCITEM_STRING, String() ) ), + aGlobalSearchItem ( SvxSearchItem ( SCITEM_SEARCHDATA ) ), + aGlobalSortItem ( ScSortItem ( SCITEM_SORTDATA, NULL ) ), + aGlobalQueryItem ( ScQueryItem ( SCITEM_QUERYDATA, NULL, NULL ) ), + aGlobalSubTotalItem ( ScSubTotalItem ( SCITEM_SUBTDATA, NULL, NULL ) ), + aGlobalConsolidateItem ( ScConsolidateItem ( SCITEM_CONSOLIDATEDATA, NULL ) ), + aGlobalPivotItem ( ScPivotItem ( SCITEM_PIVOTDATA, NULL, NULL, FALSE ) ), + aGlobalSolveItem ( ScSolveItem ( SCITEM_SOLVEDATA, NULL ) ), + aGlobalUserListItem ( ScUserListItem ( SCITEM_USERLIST ) ), + // + aPrintWarnItem ( SfxBoolItem ( SCITEM_PRINTWARN, FALSE ) ) +{ + ppPoolDefaults = new SfxPoolItem*[MSGPOOL_END - MSGPOOL_START + 1]; + + ppPoolDefaults[SCITEM_STRING - MSGPOOL_START] = &aGlobalStringItem; + ppPoolDefaults[SCITEM_SEARCHDATA - MSGPOOL_START] = &aGlobalSearchItem; + ppPoolDefaults[SCITEM_SORTDATA - MSGPOOL_START] = &aGlobalSortItem; + ppPoolDefaults[SCITEM_QUERYDATA - MSGPOOL_START] = &aGlobalQueryItem; + ppPoolDefaults[SCITEM_SUBTDATA - MSGPOOL_START] = &aGlobalSubTotalItem; + ppPoolDefaults[SCITEM_CONSOLIDATEDATA - MSGPOOL_START] = &aGlobalConsolidateItem; + ppPoolDefaults[SCITEM_PIVOTDATA - MSGPOOL_START] = &aGlobalPivotItem; + ppPoolDefaults[SCITEM_SOLVEDATA - MSGPOOL_START] = &aGlobalSolveItem; + ppPoolDefaults[SCITEM_USERLIST - MSGPOOL_START] = &aGlobalUserListItem; + ppPoolDefaults[SCITEM_PRINTWARN - MSGPOOL_START] = &aPrintWarnItem; + + SetDefaults( ppPoolDefaults ); + + pDocPool = new ScDocumentPool; + + SetSecondaryPool( pDocPool ); +} + + +__EXPORT ScMessagePool::~ScMessagePool() +{ + Delete(); + SetSecondaryPool( NULL ); // before deleting defaults (accesses defaults) + + for ( USHORT i=0; i <= MSGPOOL_END-MSGPOOL_START; i++ ) + SetRefCount( *ppPoolDefaults[i], 0 ); + + delete[] ppPoolDefaults; + + SfxItemPool::Free(pDocPool); +} + + +SfxMapUnit __EXPORT ScMessagePool::GetMetric( USHORT nWhich ) const +{ + // eigene Attribute: Twips, alles andere 1/100 mm + + if ( nWhich >= ATTR_STARTINDEX && nWhich <= ATTR_ENDINDEX ) + return SFX_MAPUNIT_TWIP; + else + return SFX_MAPUNIT_100TH_MM; +} + + + + + diff --git a/sc/source/ui/app/rfindlst.cxx b/sc/source/ui/app/rfindlst.cxx new file mode 100644 index 000000000000..3d62c0396b51 --- /dev/null +++ b/sc/source/ui/app/rfindlst.cxx @@ -0,0 +1,67 @@ +/************************************************************************* + * + * 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_sc.hxx" + + + +#include "rfindlst.hxx" + +// STATIC DATA ----------------------------------------------------------- + +#define SC_RANGECOLORS 8 + +static ColorData aColNames[SC_RANGECOLORS] = + { COL_LIGHTBLUE, COL_LIGHTRED, COL_LIGHTMAGENTA, COL_GREEN, + COL_BLUE, COL_RED, COL_MAGENTA, COL_BROWN }; + +//================================================================== + +ScRangeFindList::ScRangeFindList(const String& rName) : + aDocName( rName ), + bHidden( FALSE ) +{ +} + +ScRangeFindList::~ScRangeFindList() +{ + void* pEntry = aEntries.First(); + while ( pEntry ) + { + delete (ScRangeFindData*) aEntries.Remove( pEntry ); + pEntry = aEntries.Next(); + } +} + +ColorData ScRangeFindList::GetColorName( USHORT nIndex ) // static +{ + return aColNames[nIndex % SC_RANGECOLORS]; +} + +//================================================================== + diff --git a/sc/source/ui/app/scdll.cxx b/sc/source/ui/app/scdll.cxx new file mode 100644 index 000000000000..11e33a8892e8 --- /dev/null +++ b/sc/source/ui/app/scdll.cxx @@ -0,0 +1,422 @@ +/************************************************************************ + * + * 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_sc.hxx" + + + +#include <editeng/eeitem.hxx> + + +#ifndef _FM_FMOBJFAC_HXX +#include <svx/fmobjfac.hxx> +#endif +#include <svx/objfac3d.hxx> +#include <svx/tbxcolor.hxx> + +#include <sot/clsids.hxx> +#include <sfx2/docfilt.hxx> +#include <sfx2/fcontnr.hxx> +#include <sfx2/docfile.hxx> +#include <sfx2/app.hxx> +#include <avmedia/mediaplayer.hxx> +#include <avmedia/mediatoolbox.hxx> +#include <comphelper/types.hxx> +#include <svx/extrusioncontrols.hxx> +#include <svx/fontworkgallery.hxx> +#include <svx/tbxcustomshapes.hxx> + +#include <svtools/parhtml.hxx> +#include <sot/formats.hxx> +#define SOT_FORMATSTR_ID_STARCALC_30 SOT_FORMATSTR_ID_STARCALC + +#include "scitems.hxx" // fuer tbxctrls etc. +#include "scmod.hxx" +#include "scresid.hxx" +#include "sc.hrc" +#include "cfgids.hxx" + +//! die Registrierung wird wegen CLOOKs in ein eigenes File wandern muessen... + +// Interface-Registrierung +#include "docsh.hxx" +#include "tabvwsh.hxx" +#include "prevwsh.hxx" +#include "drawsh.hxx" +#include "drformsh.hxx" +#include "drtxtob.hxx" +#include "editsh.hxx" +#include "pivotsh.hxx" +#include "auditsh.hxx" +#include "cellsh.hxx" +#include "oleobjsh.hxx" +#include "chartsh.hxx" +#include "graphsh.hxx" +#include "mediash.hxx" +#include "pgbrksh.hxx" + +#include "docpool.hxx" +#include "appoptio.hxx" + +// Controls + +#include <svx/tbxalign.hxx> +#include <svx/tbxctl.hxx> +#include <svx/fillctrl.hxx> +#include <svx/linectrl.hxx> +#include <svx/tbcontrl.hxx> +#include <svx/selctrl.hxx> +#include <svx/insctrl.hxx> +#include <svx/zoomctrl.hxx> +#include <editeng/flditem.hxx> +#include <svx/modctrl.hxx> +#include <svx/pszctrl.hxx> +#include <svx/fntctl.hxx> +#include <svx/fntszctl.hxx> +#include <svx/grafctrl.hxx> +#include <svx/galbrws.hxx> +#include <svx/clipboardctl.hxx> +#include <svx/lboxctrl.hxx> +#include <svx/verttexttbxctrl.hxx> +#include <svx/formatpaintbrushctrl.hxx> +#include "tbinsert.hxx" +#include "tbzoomsliderctrl.hxx" +#include <svx/zoomsliderctrl.hxx> + +#include <svx/xmlsecctrl.hxx> +// Child-Windows +#include "reffact.hxx" +#include "navipi.hxx" +#include "inputwin.hxx" +#include "spelldialog.hxx" +#include <svx/fontwork.hxx> +#include <svx/srchdlg.hxx> +#include <svx/hyprlink.hxx> +#include <svx/hyperdlg.hxx> +#include <svx/imapdlg.hxx> + +#include "editutil.hxx" +#include <svx/svdfield.hxx> // SdrRegisterFieldClasses +#include <rtl/logfile.hxx> + +#include "dwfunctr.hxx" +#include "acredlin.hxx" + +//------------------------------------------------------------------ + +//UNUSED2008-05 // filter detection can't use ScFilterOptions (in sc-dll), +//UNUSED2008-05 // so access to wk3 flag must be implemented here again +//UNUSED2008-05 +//UNUSED2008-05 class ScLibOptions : public utl::ConfigItem +//UNUSED2008-05 { +//UNUSED2008-05 BOOL bWK3Flag; +//UNUSED2008-05 +//UNUSED2008-05 public: +//UNUSED2008-05 ScLibOptions(); +//UNUSED2008-05 BOOL GetWK3Flag() const { return bWK3Flag; } +//UNUSED2008-05 }; +//UNUSED2008-05 +//UNUSED2008-05 #define CFGPATH_LIBFILTER "Office.Calc/Filter/Import/Lotus123" +//UNUSED2008-05 #define ENTRYSTR_WK3 "WK3" +//UNUSED2008-05 +//UNUSED2008-05 ScLibOptions::ScLibOptions() : +//UNUSED2008-05 ConfigItem( rtl::OUString::createFromAscii( CFGPATH_LIBFILTER ) ), +//UNUSED2008-05 bWK3Flag( FALSE ) +//UNUSED2008-05 { +//UNUSED2008-05 com::sun::star::uno::Sequence<rtl::OUString> aNames(1); +//UNUSED2008-05 aNames[0] = rtl::OUString::createFromAscii( ENTRYSTR_WK3 ); +//UNUSED2008-05 com::sun::star::uno::Sequence<com::sun::star::uno::Any> aValues = GetProperties(aNames); +//UNUSED2008-05 if ( aValues.getLength() == 1 && aValues[0].hasValue() ) +//UNUSED2008-05 bWK3Flag = comphelper::getBOOL( aValues[0] ); +//UNUSED2008-05 } + +//------------------------------------------------------------------ + +ScResId::ScResId( USHORT nId ) : + ResId( nId, *SC_MOD()->GetResMgr() ) +{ +} + +//------------------------------------------------------------------ + +void ScDLL::Init() +{ + RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDLL::Init" ); + + ScModule **ppShlPtr = (ScModule**) GetAppData(SHL_CALC); + if ( *ppShlPtr ) + return; + + ScDocumentPool::InitVersionMaps(); // wird im ScModule ctor gebraucht + + ScModule* pMod = new ScModule( &ScDocShell::Factory() ); + (*ppShlPtr) = pMod; + +//REMOVE ScDocShell::RegisterFactory( SDT_SC_DOCFACTPRIO ); + + ScDocShell::Factory().SetDocumentServiceName( rtl::OUString::createFromAscii( "com.sun.star.sheet.SpreadsheetDocument" ) ); + + ScGlobal::Init(); // erst wenn der ResManager initialisiert ist + // erst nach ScGlobal::Init duerfen die App-Optionen + // initialisiert werden + + // register your view-factories here + + ScTabViewShell ::RegisterFactory(1); + ScPreviewShell ::RegisterFactory(2); + + // register your shell-interfaces here + + ScModule ::RegisterInterface(pMod); + ScDocShell ::RegisterInterface(pMod); + ScTabViewShell ::RegisterInterface(pMod); + ScPreviewShell ::RegisterInterface(pMod); + ScDrawShell ::RegisterInterface(pMod); + ScDrawFormShell ::RegisterInterface(pMod); + ScDrawTextObjectBar ::RegisterInterface(pMod); + ScEditShell ::RegisterInterface(pMod); + ScPivotShell ::RegisterInterface(pMod); + ScAuditingShell ::RegisterInterface(pMod); + ScFormatShell ::RegisterInterface(pMod); + ScCellShell ::RegisterInterface(pMod); + ScOleObjectShell ::RegisterInterface(pMod); + ScChartShell ::RegisterInterface(pMod); + ScGraphicShell ::RegisterInterface(pMod); + ScMediaShell ::RegisterInterface(pMod); + ScPageBreakShell ::RegisterInterface(pMod); + + // eigene Controller + ScTbxInsertCtrl ::RegisterControl(SID_TBXCTL_INSERT, pMod); + ScTbxInsertCtrl ::RegisterControl(SID_TBXCTL_INSCELLS, pMod); + ScTbxInsertCtrl ::RegisterControl(SID_TBXCTL_INSOBJ, pMod); + ScZoomSliderControl ::RegisterControl(SID_PREVIEW_SCALINGFACTOR, pMod); + + // Svx-Toolbox-Controller + SvxTbxCtlDraw ::RegisterControl(SID_INSERT_DRAW, pMod); + SvxTbxCtlCustomShapes ::RegisterControl(SID_DRAWTBX_CS_BASIC, pMod); + SvxTbxCtlCustomShapes ::RegisterControl(SID_DRAWTBX_CS_SYMBOL, pMod); + SvxTbxCtlCustomShapes ::RegisterControl(SID_DRAWTBX_CS_ARROW, pMod); + SvxTbxCtlCustomShapes ::RegisterControl(SID_DRAWTBX_CS_FLOWCHART, pMod); + SvxTbxCtlCustomShapes ::RegisterControl(SID_DRAWTBX_CS_CALLOUT, pMod); + SvxTbxCtlCustomShapes ::RegisterControl(SID_DRAWTBX_CS_STAR, pMod); + SvxTbxCtlAlign ::RegisterControl(SID_OBJECT_ALIGN, pMod); + SvxFillToolBoxControl ::RegisterControl(0, pMod); + SvxLineStyleToolBoxControl ::RegisterControl(0, pMod); + SvxLineWidthToolBoxControl ::RegisterControl(0, pMod); + SvxLineColorToolBoxControl ::RegisterControl(0, pMod); + SvxLineEndToolBoxControl ::RegisterControl(SID_ATTR_LINEEND_STYLE, pMod); + SvxStyleToolBoxControl ::RegisterControl(SID_STYLE_APPLY, pMod); + SvxFontNameToolBoxControl ::RegisterControl(SID_ATTR_CHAR_FONT, pMod); +// SvxFontHeightToolBoxControl ::RegisterControl(SID_ATTR_CHAR_FONTHEIGHT, pMod); + SvxFontColorToolBoxControl ::RegisterControl(SID_ATTR_CHAR_COLOR, pMod); + SvxColorToolBoxControl ::RegisterControl(SID_BACKGROUND_COLOR, pMod); + SvxFrameToolBoxControl ::RegisterControl(SID_ATTR_BORDER, pMod); + SvxFrameLineStyleToolBoxControl ::RegisterControl(SID_FRAME_LINESTYLE, pMod); + SvxFrameLineColorToolBoxControl ::RegisterControl(SID_FRAME_LINECOLOR, pMod); + SvxClipBoardControl ::RegisterControl(SID_PASTE, pMod ); + SvxUndoRedoControl ::RegisterControl(SID_UNDO, pMod ); + SvxUndoRedoControl ::RegisterControl(SID_REDO, pMod ); + svx::FormatPaintBrushToolBoxControl::RegisterControl(SID_FORMATPAINTBRUSH, pMod ); + + SvxGrafModeToolBoxControl ::RegisterControl(SID_ATTR_GRAF_MODE, pMod); + SvxGrafRedToolBoxControl ::RegisterControl(SID_ATTR_GRAF_RED, pMod); + SvxGrafGreenToolBoxControl ::RegisterControl(SID_ATTR_GRAF_GREEN, pMod); + SvxGrafBlueToolBoxControl ::RegisterControl(SID_ATTR_GRAF_BLUE, pMod); + SvxGrafLuminanceToolBoxControl ::RegisterControl(SID_ATTR_GRAF_LUMINANCE, pMod); + SvxGrafContrastToolBoxControl ::RegisterControl(SID_ATTR_GRAF_CONTRAST, pMod); + SvxGrafGammaToolBoxControl ::RegisterControl(SID_ATTR_GRAF_GAMMA, pMod); + SvxGrafTransparenceToolBoxControl::RegisterControl(SID_ATTR_GRAF_TRANSPARENCE, pMod); + SvxGrafFilterToolBoxControl ::RegisterControl(SID_GRFFILTER, pMod); + + SvxVertTextTbxCtrl::RegisterControl(SID_DRAW_CAPTION_VERTICAL, pMod); + SvxVertTextTbxCtrl::RegisterControl(SID_DRAW_TEXT_VERTICAL, pMod); + SvxVertTextTbxCtrl::RegisterControl(SID_TEXTDIRECTION_LEFT_TO_RIGHT, pMod); + SvxVertTextTbxCtrl::RegisterControl(SID_TEXTDIRECTION_TOP_TO_BOTTOM, pMod); + SvxCTLTextTbxCtrl::RegisterControl(SID_ATTR_PARA_LEFT_TO_RIGHT, pMod); + SvxCTLTextTbxCtrl::RegisterControl(SID_ATTR_PARA_RIGHT_TO_LEFT, pMod); + + //Media Controller + ::avmedia::MediaToolBoxControl::RegisterControl( SID_AVMEDIA_TOOLBOX, pMod ); + + // Svx-StatusBar-Controller + SvxInsertStatusBarControl ::RegisterControl(SID_ATTR_INSERT, pMod); + SvxSelectionModeControl ::RegisterControl(SID_STATUS_SELMODE, pMod); + SvxZoomStatusBarControl ::RegisterControl(SID_ATTR_ZOOM, pMod); + SvxZoomSliderControl ::RegisterControl(SID_ATTR_ZOOMSLIDER, pMod); + SvxModifyControl ::RegisterControl(SID_DOC_MODIFIED, pMod); + XmlSecStatusBarControl ::RegisterControl( SID_SIGNATURE, pMod ); + + SvxPosSizeStatusBarControl ::RegisterControl(SID_ATTR_SIZE, pMod); + + // Svx-Menue-Controller + SvxFontMenuControl ::RegisterControl(SID_ATTR_CHAR_FONT, pMod); + SvxFontSizeMenuControl ::RegisterControl(SID_ATTR_CHAR_FONTHEIGHT, pMod); + + // CustomShape extrusion controller + svx::ExtrusionDepthControl::RegisterControl( SID_EXTRUSION_DEPTH_FLOATER, pMod ); + svx::ExtrusionDirectionControl::RegisterControl( SID_EXTRUSION_DIRECTION_FLOATER, pMod ); + svx::ExtrusionLightingControl::RegisterControl( SID_EXTRUSION_LIGHTING_FLOATER, pMod ); + svx::ExtrusionSurfaceControl::RegisterControl( SID_EXTRUSION_SURFACE_FLOATER, pMod ); + svx::ExtrusionColorControl::RegisterControl( SID_EXTRUSION_3D_COLOR, pMod ); + + svx::FontWorkShapeTypeControl::RegisterControl( SID_FONTWORK_SHAPE_TYPE, pMod ); + svx::FontWorkAlignmentControl::RegisterControl( SID_FONTWORK_ALIGNMENT_FLOATER, pMod ); + svx::FontWorkCharacterSpacingControl::RegisterControl( SID_FONTWORK_CHARACTER_SPACING_FLOATER, pMod ); + + // Child-Windows + + // Hack: Eingabezeile mit 42 registrieren, damit sie im PlugIn immer sichtbar ist + ScInputWindowWrapper ::RegisterChildWindow(42, pMod, SFX_CHILDWIN_TASK|SFX_CHILDWIN_FORCEDOCK); + ScNavigatorDialogWrapper ::RegisterChildWindowContext( + sal::static_int_cast<sal_uInt16>(ScTabViewShell::GetInterfaceId()), pMod); + ScSolverDlgWrapper ::RegisterChildWindow(FALSE, pMod); + ScOptSolverDlgWrapper ::RegisterChildWindow(FALSE, pMod); + ScNameDlgWrapper ::RegisterChildWindow(FALSE, pMod); + ScPivotLayoutWrapper ::RegisterChildWindow(FALSE, pMod); + ScTabOpDlgWrapper ::RegisterChildWindow(FALSE, pMod); + ScFilterDlgWrapper ::RegisterChildWindow(FALSE, pMod); + ScSpecialFilterDlgWrapper ::RegisterChildWindow(FALSE, pMod); + ScDbNameDlgWrapper ::RegisterChildWindow(FALSE, pMod); + ScConsolidateDlgWrapper ::RegisterChildWindow(FALSE, pMod); + ScPrintAreasDlgWrapper ::RegisterChildWindow(FALSE, pMod); + ScCondFormatDlgWrapper ::RegisterChildWindow(FALSE, pMod); + ScColRowNameRangesDlgWrapper::RegisterChildWindow(FALSE, pMod); + ScFormulaDlgWrapper ::RegisterChildWindow(FALSE, pMod); + + // First docking Window for Calc + ScFunctionChildWindow ::RegisterChildWindow(FALSE, pMod); + + // Redlining- Window + ScAcceptChgDlgWrapper ::RegisterChildWindow(FALSE, pMod); + ScSimpleRefDlgWrapper ::RegisterChildWindow(FALSE, pMod, SFX_CHILDWIN_ALWAYSAVAILABLE|SFX_CHILDWIN_NEVERHIDE ); + ScHighlightChgDlgWrapper ::RegisterChildWindow(FALSE, pMod); + + SvxSearchDialogWrapper ::RegisterChildWindow(FALSE, pMod); + SvxHlinkDlgWrapper ::RegisterChildWindow(FALSE, pMod); + SvxFontWorkChildWindow ::RegisterChildWindow(FALSE, pMod); + SvxHyperlinkDlgWrapper ::RegisterChildWindow(FALSE, pMod, SFX_CHILDWIN_FORCEDOCK); + SvxIMapDlgChildWindow ::RegisterChildWindow(FALSE, pMod); + GalleryChildWindow ::RegisterChildWindow(FALSE, pMod); + ScSpellDialogChildWindow ::RegisterChildWindow(FALSE, pMod); + ::avmedia::MediaPlayer ::RegisterChildWindow(FALSE, pMod); + + //<!--Added by PengYunQuan for Validity Cell Range Picker + ScValidityRefChildWin::RegisterChildWindow(FALSE, pMod); + //-->Added by PengYunQuan for Validity Cell Range Picker + + // Edit-Engine-Felder, soweit nicht schon in OfficeApplication::Init + + SvClassManager& rClassManager = SvxFieldItem::GetClassManager(); +// rClassManager.SV_CLASS_REGISTER( SvxURLField ); +// rClassManager.SV_CLASS_REGISTER( SvxDateField ); +// rClassManager.SV_CLASS_REGISTER( SvxPageField ); + rClassManager.SV_CLASS_REGISTER( SvxPagesField ); +// rClassManager.SV_CLASS_REGISTER( SvxTimeField ); + rClassManager.SV_CLASS_REGISTER( SvxFileField ); +// rClassManager.SV_CLASS_REGISTER( SvxExtFileField ); + rClassManager.SV_CLASS_REGISTER( SvxTableField ); + + SdrRegisterFieldClasses(); // SvDraw-Felder registrieren + + // 3D-Objekt-Factory eintragen + E3dObjFactory(); + + // ::com::sun::star::form::component::Form-Objekt-Factory eintragen + FmFormObjFactory(); + + pMod->PutItem( SfxUInt16Item( SID_ATTR_METRIC, sal::static_int_cast<UINT16>(pMod->GetAppOptions().GetAppMetric()) ) ); + + // StarOne Services are now handled in the registry +} + +void ScDLL::Exit() +{ + // the SxxModule must be destroyed + ScModule **ppShlPtr = (ScModule**) GetAppData(SHL_CALC); + delete (*ppShlPtr); + (*ppShlPtr) = NULL; + + // ScGlobal::Clear ist schon im Module-dtor +} + +//------------------------------------------------------------------ +// Statusbar +//------------------------------------------------------------------ + +#define TEXT_WIDTH(s) rStatusBar.GetTextWidth((s)) + +//UNUSED2008-05 void ScDLL::FillStatusBar(StatusBar &rStatusBar) +//UNUSED2008-05 { +//UNUSED2008-05 // Dokumentposition (Tabelle x / y) +//UNUSED2008-05 rStatusBar.InsertItem( SID_STATUS_DOCPOS, +//UNUSED2008-05 TEXT_WIDTH( String().Fill( 10, 'X' ) ), +//UNUSED2008-05 SIB_LEFT|SIB_AUTOSIZE ); +//UNUSED2008-05 +//UNUSED2008-05 // Seitenvorlage +//UNUSED2008-05 rStatusBar.InsertItem( SID_STATUS_PAGESTYLE, +//UNUSED2008-05 TEXT_WIDTH( String().Fill( 15, 'X' ) ), +//UNUSED2008-05 SIB_LEFT|SIB_AUTOSIZE ); +//UNUSED2008-05 +//UNUSED2008-05 // Ma"sstab +//UNUSED2008-05 rStatusBar.InsertItem( SID_ATTR_ZOOM, +//UNUSED2008-05 SvxZoomStatusBarControl::GetDefItemWidth(rStatusBar), +//UNUSED2008-05 SIB_CENTER ); +//UNUSED2008-05 +//UNUSED2008-05 // Einfuege-/Ueberschreibmodus +//UNUSED2008-05 rStatusBar.InsertItem( SID_ATTR_INSERT, +//UNUSED2008-05 SvxInsertStatusBarControl::GetDefItemWidth(rStatusBar), +//UNUSED2008-05 SIB_CENTER ); +//UNUSED2008-05 +//UNUSED2008-05 // Selektionsmodus +//UNUSED2008-05 rStatusBar.InsertItem( SID_STATUS_SELMODE, +//UNUSED2008-05 SvxSelectionModeControl::GetDefItemWidth(rStatusBar), +//UNUSED2008-05 SIB_CENTER ); +//UNUSED2008-05 +//UNUSED2008-05 // Dokument geaendert +//UNUSED2008-05 rStatusBar.InsertItem( SID_DOC_MODIFIED, +//UNUSED2008-05 SvxModifyControl::GetDefItemWidth(rStatusBar)); +//UNUSED2008-05 +//UNUSED2008-05 // signatures +//UNUSED2008-05 rStatusBar.InsertItem( SID_SIGNATURE, XmlSecStatusBarControl::GetDefItemWidth( rStatusBar ), SIB_USERDRAW ); +//UNUSED2008-05 rStatusBar.SetHelpId(SID_SIGNATURE, SID_SIGNATURE); +//UNUSED2008-05 +//UNUSED2008-05 // Mail +//UNUSED2008-05 rStatusBar.InsertItem( SID_MAIL_NOTIFY, +//UNUSED2008-05 TEXT_WIDTH( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Mail")) ), +//UNUSED2008-05 SIB_CENTER ); +//UNUSED2008-05 +//UNUSED2008-05 // den aktuellen Kontext anzeigen Uhrzeit / FramePos / TabellenInfo / Errors +//UNUSED2008-05 rStatusBar.InsertItem( SID_ATTR_SIZE, +//UNUSED2008-05 SvxPosSizeStatusBarControl::GetDefItemWidth(rStatusBar), +//UNUSED2008-05 SIB_AUTOSIZE|SIB_LEFT|SIB_USERDRAW); +//UNUSED2008-05 } + +#undef TEXT_WIDTH + +// DetectFilter functionality has moved - please update your bookmarks +// see sc/source/ui/unoobj/scdetect.cxx, have a nice day. diff --git a/sc/source/ui/app/scmod.cxx b/sc/source/ui/app/scmod.cxx new file mode 100644 index 000000000000..dc5d1010dfc8 --- /dev/null +++ b/sc/source/ui/app/scmod.cxx @@ -0,0 +1,2297 @@ +/************************************************************************* + * + * 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_sc.hxx" +#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp> +#include <comphelper/processfactory.hxx> + + + + + +// INCLUDE --------------------------------------------------------------- + +#include "scitems.hxx" +#include <sfx2/app.hxx> +#include <editeng/eeitem.hxx> + +#include <editeng/flditem.hxx> +#include <editeng/outliner.hxx> +#include <basic/sbstar.hxx> + +#include <sfx2/sfxdlg.hxx> +#include <sfx2/viewfrm.hxx> +#include <sfx2/objface.hxx> + +#include <svx/hyprlink.hxx> +#include "IAnyRefDialog.hxx" + +#include <svtools/ehdl.hxx> +#include <svtools/accessibilityoptions.hxx> +#include <svl/ctloptions.hxx> +#include <unotools/useroptions.hxx> +#include <vcl/status.hxx> +#include <sfx2/bindings.hxx> +#include <sfx2/request.hxx> +#include <sfx2/macrconf.hxx> +#include <sfx2/printer.hxx> +#include <editeng/langitem.hxx> +#include <svtools/colorcfg.hxx> + +#include <svl/whiter.hxx> +#include <svx/selctrl.hxx> +#include <svx/insctrl.hxx> +#include <svx/zoomctrl.hxx> +#include <svx/modctrl.hxx> +#include <svx/pszctrl.hxx> +#include <svx/zoomsliderctrl.hxx> +#include <vcl/msgbox.hxx> +#include <svl/inethist.hxx> +#include <vcl/waitobj.hxx> +#include <svx/svxerr.hxx> + + + +#include "scmod.hxx" +#include "global.hxx" +#include "viewopti.hxx" +#include "docoptio.hxx" +#include "appoptio.hxx" +#include "inputopt.hxx" +#include "printopt.hxx" +#include "navicfg.hxx" +#include "addincfg.hxx" +#include "tabvwsh.hxx" +#include "prevwsh.hxx" +#include "docsh.hxx" +#include "drwlayer.hxx" +#include "uiitems.hxx" +#include "sc.hrc" +#include "cfgids.hxx" +#include "inputhdl.hxx" +#include "inputwin.hxx" +#include "msgpool.hxx" +#include "scresid.hxx" +#include "anyrefdg.hxx" +#include "teamdlg.hxx" +#include "dwfunctr.hxx" +#include "formdata.hxx" +//CHINA001 #include "tpview.hxx" +//CHINA001 #include "tpusrlst.hxx" +//CHINA001 #include "tpcalc.hxx" +#include "tpprint.hxx" +//CHINA001 #include "opredlin.hxx" +#include "transobj.hxx" +#include "detfunc.hxx" +#include "preview.hxx" + +#include <svx/xmlsecctrl.hxx> + + +#define ScModule +#include "scslots.hxx" + +#include "scabstdlg.hxx" //CHINA001 + +#define SC_IDLE_MIN 150 +#define SC_IDLE_MAX 3000 +#define SC_IDLE_STEP 75 +#define SC_IDLE_COUNT 50 + +static USHORT nIdleCount = 0; + +//------------------------------------------------------------------ + +SFX_IMPL_INTERFACE( ScModule, SfxShell, ScResId(RID_APPTITLE) ) +{ + SFX_OBJECTBAR_REGISTRATION( SFX_OBJECTBAR_APPLICATION | SFX_VISIBILITY_DESKTOP | SFX_VISIBILITY_STANDARD | SFX_VISIBILITY_CLIENT | SFX_VISIBILITY_VIEWER, + ScResId(RID_OBJECTBAR_APP) ); + SFX_STATUSBAR_REGISTRATION( ScResId(SCCFG_STATUSBAR) ); // nur ID wichtig + SFX_CHILDWINDOW_REGISTRATION( SvxHyperlinkDlgWrapper::GetChildWindowId() ); +} + +//------------------------------------------------------------------ + +ScModule::ScModule( SfxObjectFactory* pFact ) : + SfxModule( SfxApplication::CreateResManager( "sc" ), FALSE, pFact, NULL ), + pSelTransfer( NULL ), + pMessagePool( NULL ), + pRefInputHandler( NULL ), + pTeamDlg( NULL ), + pViewCfg( NULL ), + pDocCfg( NULL ), + pAppCfg( NULL ), + pInputCfg( NULL ), + pPrintCfg( NULL ), + pNavipiCfg( NULL ), + pAddInCfg( NULL ), + pColorConfig( NULL ), + pAccessOptions( NULL ), + pCTLOptions( NULL ), + pUserOptions( NULL ), + pErrorHdl( NULL ), + pSvxErrorHdl( NULL ), + pFormEditData( NULL ), + nCurRefDlgId( 0 ), + bIsWaterCan( FALSE ), + bIsInEditCommand( FALSE ), + bIsInExecuteDrop( FALSE ), + mbIsInSharedDocLoading( false ), + mbIsInSharedDocSaving( false ) +{ + // im ctor ist der ResManager (DLL-Daten) noch nicht initialisiert! + + SetName(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("StarCalc"))); // fuer Basic + + ResetDragObject(); + SetClipObject( NULL, NULL ); + + // InputHandler braucht nicht mehr angelegt zu werden + + // ErrorHandler anlegen - war in Init() + // zwischen OfficeApplication::Init und ScGlobal::Init + SvxErrorHandler::Get(); + pErrorHdl = new SfxErrorHandler( RID_ERRHDLSC, + ERRCODE_AREA_SC, + ERRCODE_AREA_APP2-1, + GetResMgr() ); + + aSpellTimer.SetTimeout(10); + aSpellTimer.SetTimeoutHdl( LINK( this, ScModule, SpellTimerHdl ) ); + aIdleTimer.SetTimeout(SC_IDLE_MIN); + aIdleTimer.SetTimeoutHdl( LINK( this, ScModule, IdleHandler ) ); + aIdleTimer.Start(); + + pMessagePool = new ScMessagePool; + pMessagePool->FreezeIdRanges(); + SetPool( pMessagePool ); + ScGlobal::InitTextHeight( pMessagePool ); + + StartListening( *SFX_APP() ); // for SFX_HINT_DEINITIALIZING +} + +ScModule::~ScModule() +{ + DBG_ASSERT( !pSelTransfer, "Selection Transfer object not deleted" ); + + // InputHandler braucht nicht mehr geloescht zu werden (gibt keinen an der App mehr) + + SfxItemPool::Free(pMessagePool); + + DELETEZ( pFormEditData ); + + delete pErrorHdl; +// delete pSvxErrorHdl; + + ScGlobal::Clear(); // ruft auch ScDocumentPool::DeleteVersionMaps(); + + DeleteCfg(); // wurde mal aus Exit() gerufen +} + +//------------------------------------------------------------------ +void ScModule::ConfigurationChanged( utl::ConfigurationBroadcaster* p, sal_uInt32 ) +{ + if ( p == pColorConfig || p == pAccessOptions ) + { + // Test if detective objects have to be updated with new colors + // (if the detective colors haven't been used yet, there's nothing to update) + if ( ScDetectiveFunc::IsColorsInitialized() ) + { + const svtools::ColorConfig& rColors = GetColorConfig(); + BOOL bArrows = + ( ScDetectiveFunc::GetArrowColor() != (ColorData)rColors.GetColorValue(svtools::CALCDETECTIVE).nColor || + ScDetectiveFunc::GetErrorColor() != (ColorData)rColors.GetColorValue(svtools::CALCDETECTIVEERROR).nColor ); + BOOL bComments = + ( ScDetectiveFunc::GetCommentColor() != (ColorData)rColors.GetColorValue(svtools::CALCNOTESBACKGROUND).nColor ); + if ( bArrows || bComments ) + { + ScDetectiveFunc::InitializeColors(); // get the new colors + + // update detective objects in all open documents + SfxObjectShell* pObjSh = SfxObjectShell::GetFirst(); + while ( pObjSh ) + { + if ( pObjSh->Type() == TYPE(ScDocShell) ) + { + ScDocShell* pDocSh = ((ScDocShell*)pObjSh); + if ( bArrows ) + ScDetectiveFunc( pDocSh->GetDocument(), 0 ).UpdateAllArrowColors(); + if ( bComments ) + ScDetectiveFunc::UpdateAllComments( *pDocSh->GetDocument() ); + } + pObjSh = SfxObjectShell::GetNext( *pObjSh ); + } + } + } + + // force all views to repaint, using the new options + + SfxViewShell* pViewShell = SfxViewShell::GetFirst(); + while(pViewShell) + { + if ( pViewShell->ISA(ScTabViewShell) ) + { + ScTabViewShell* pViewSh = (ScTabViewShell*)pViewShell; + pViewSh->PaintGrid(); + pViewSh->PaintTop(); + pViewSh->PaintLeft(); + pViewSh->PaintExtras(); + + ScInputHandler* pHdl = pViewSh->GetInputHandler(); + if ( pHdl ) + pHdl->ForgetLastPattern(); // EditEngine BackgroundColor may change + } + else if ( pViewShell->ISA(ScPreviewShell) ) + { + Window* pWin = pViewShell->GetWindow(); + if (pWin) + pWin->Invalidate(); + } + pViewShell = SfxViewShell::GetNext( *pViewShell ); + } + } + else if ( p == pCTLOptions ) + { + // for all documents: set digit language for printer, recalc output factor, update row heights + SfxObjectShell* pObjSh = SfxObjectShell::GetFirst(); + while ( pObjSh ) + { + if ( pObjSh->Type() == TYPE(ScDocShell) ) + { + ScDocShell* pDocSh = ((ScDocShell*)pObjSh); + OutputDevice* pPrinter = pDocSh->GetPrinter(); + if ( pPrinter ) + pPrinter->SetDigitLanguage( GetOptDigitLanguage() ); + + pDocSh->CalcOutputFactor(); + + SCTAB nTabCount = pDocSh->GetDocument()->GetTableCount(); + for (SCTAB nTab=0; nTab<nTabCount; nTab++) + pDocSh->AdjustRowHeight( 0, MAXROW, nTab ); + } + pObjSh = SfxObjectShell::GetNext( *pObjSh ); + } + + // for all views (table and preview): update digit language + SfxViewShell* pSh = SfxViewShell::GetFirst(); + while ( pSh ) + { + if ( pSh->ISA( ScTabViewShell ) ) + { + ScTabViewShell* pViewSh = (ScTabViewShell*)pSh; + + // set ref-device for EditEngine (re-evaluates digit settings) + ScInputHandler* pHdl = GetInputHdl(pViewSh); + if (pHdl) + pHdl->UpdateRefDevice(); + + pViewSh->DigitLanguageChanged(); + pViewSh->PaintGrid(); + } + else if ( pSh->ISA( ScPreviewShell ) ) + { + ScPreviewShell* pPreviewSh = (ScPreviewShell*)pSh; + ScPreview* pPreview = pPreviewSh->GetPreview(); + + pPreview->SetDigitLanguage( GetOptDigitLanguage() ); + pPreview->Invalidate(); + } + + pSh = SfxViewShell::GetNext( *pSh ); + } + } +} + +void ScModule::Notify( SfxBroadcaster&, const SfxHint& rHint ) +{ + if ( rHint.ISA(SfxSimpleHint) ) + { + ULONG nHintId = ((SfxSimpleHint&)rHint).GetId(); + if ( nHintId == SFX_HINT_DEINITIALIZING ) + { + // ConfigItems must be removed before ConfigManager + DeleteCfg(); + } + } +} + +//------------------------------------------------------------------ + +void ScModule::DeleteCfg() +{ + DELETEZ( pViewCfg ); // Speichern passiert vor Exit() automatisch + DELETEZ( pDocCfg ); + DELETEZ( pAppCfg ); + DELETEZ( pInputCfg ); + DELETEZ( pPrintCfg ); + DELETEZ( pNavipiCfg ); + DELETEZ( pAddInCfg ); + + if ( pColorConfig ) + { + pColorConfig->RemoveListener(this); + DELETEZ( pColorConfig ); + } + if ( pAccessOptions ) + { + pAccessOptions->RemoveListener(this); + DELETEZ( pAccessOptions ); + } + if ( pCTLOptions ) + { + pCTLOptions->RemoveListener(this); + DELETEZ( pCTLOptions ); + } + if( pUserOptions ) + { + DELETEZ( pUserOptions ); + } +} + +//------------------------------------------------------------------ + +#define TEXT_WIDTH(s) rStatusBar.GetTextWidth((s)) + +void ScModule::FillStatusBar(StatusBar& rStatusBar) +{ + // Dokumentposition (Tabelle x / y) + rStatusBar.InsertItem( SID_STATUS_DOCPOS, + TEXT_WIDTH( String().Fill( 10, 'X' ) ), + SIB_LEFT|SIB_AUTOSIZE ); + rStatusBar.SetHelpId( SID_STATUS_DOCPOS, SID_STATUS_DOCPOS ); + + // Seitenvorlage + rStatusBar.InsertItem( SID_STATUS_PAGESTYLE, + TEXT_WIDTH( String().Fill( 15, 'X' ) ), + SIB_LEFT|SIB_AUTOSIZE ); + rStatusBar.SetHelpId( SID_STATUS_PAGESTYLE, SID_STATUS_PAGESTYLE ); + + // Einfuege-/Ueberschreibmodus + rStatusBar.InsertItem( SID_ATTR_INSERT, + SvxInsertStatusBarControl::GetDefItemWidth(rStatusBar), + SIB_CENTER ); + rStatusBar.SetHelpId( SID_ATTR_INSERT, SID_ATTR_INSERT ); + + // Selektionsmodus + rStatusBar.InsertItem( SID_STATUS_SELMODE, + SvxSelectionModeControl::GetDefItemWidth(rStatusBar), + SIB_CENTER ); + rStatusBar.SetHelpId( SID_STATUS_SELMODE, SID_STATUS_SELMODE ); + + // Dokument geaendert + rStatusBar.InsertItem( SID_DOC_MODIFIED, + SvxModifyControl::GetDefItemWidth(rStatusBar)); + + // signatures + rStatusBar.InsertItem( SID_SIGNATURE, XmlSecStatusBarControl::GetDefItemWidth( rStatusBar ), SIB_USERDRAW ); + rStatusBar.SetHelpId(SID_SIGNATURE, SID_SIGNATURE); + + + rStatusBar.SetHelpId( SID_DOC_MODIFIED, SID_DOC_MODIFIED ); + + // den aktuellen Kontext anzeigen Uhrzeit / FramePos / TabellenInfo / Errors + rStatusBar.InsertItem( SID_ATTR_SIZE, + SvxPosSizeStatusBarControl::GetDefItemWidth(rStatusBar), + SIB_AUTOSIZE|SIB_LEFT|SIB_USERDRAW); + rStatusBar.SetHelpId( SID_ATTR_SIZE, SID_ATTR_SIZE ); + + // Ma"sstab + rStatusBar.InsertItem( SID_ATTR_ZOOM, + SvxZoomStatusBarControl::GetDefItemWidth(rStatusBar), + SIB_CENTER ); + rStatusBar.SetHelpId( SID_ATTR_ZOOM, SID_ATTR_ZOOM ); + + // ZoomSlider + rStatusBar.InsertItem( SID_ATTR_ZOOMSLIDER, + TEXT_WIDTH( String().Fill( 15, 'X' ) ), + SIB_CENTER ); + rStatusBar.SetHelpId( SID_ATTR_ZOOMSLIDER, SID_ATTR_ZOOMSLIDER ); +} + +#undef TEXT_WIDTH + +//------------------------------------------------------------------ +// +// von der Applikation verschoben: +// +//------------------------------------------------------------------ + +void ScModule::Execute( SfxRequest& rReq ) +{ + SfxViewFrame* pViewFrm = SfxViewFrame::Current(); + SfxBindings* pBindings = pViewFrm ? &pViewFrm->GetBindings() : NULL; + + const SfxItemSet* pReqArgs = rReq.GetArgs(); + USHORT nSlot = rReq.GetSlot(); + + switch ( nSlot ) + { + case SID_CHOOSE_DESIGN: + { + String aMacroName = + String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Template.Samples.ShowStyles")); + SfxApplication* pApp = SFX_APP(); + pApp->EnterBasicCall(); + pApp->GetMacroConfig()->Call( NULL, aMacroName, pApp->GetBasicManager() ); + pApp->LeaveBasicCall(); + } + break; + case SID_EURO_CONVERTER: + { + String aMacroName = + String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Euro.ConvertRun.Main")); + SfxApplication* pApp = SFX_APP(); + pApp->EnterBasicCall(); + pApp->GetMacroConfig()->Call( NULL, aMacroName, pApp->GetBasicManager() ); + pApp->LeaveBasicCall(); + } + break; + case SID_AUTOSPELL_CHECK: + { + BOOL bSet; + const SfxPoolItem* pItem; + if ( pReqArgs && SFX_ITEM_SET == pReqArgs->GetItemState( nSlot, TRUE, &pItem ) ) + bSet = ((const SfxBoolItem*)pItem)->GetValue(); + else + { // Toggle + ScDocShell* pDocSh = PTR_CAST(ScDocShell, SfxObjectShell::Current()); + if ( pDocSh ) + bSet = !pDocSh->GetDocument()->GetDocOptions().IsAutoSpell(); + else + bSet = !GetDocOptions().IsAutoSpell(); + } + + SfxItemSet aSet( GetPool(), SID_AUTOSPELL_CHECK, SID_AUTOSPELL_CHECK ); + aSet.Put( SfxBoolItem( SID_AUTOSPELL_CHECK, bSet ) ); + ModifyOptions( aSet ); + rReq.Done(); + } + break; + + case SID_ATTR_METRIC: + { + const SfxPoolItem* pItem; + if ( pReqArgs && SFX_ITEM_SET == pReqArgs->GetItemState( nSlot, TRUE, &pItem ) ) + { + FieldUnit eUnit = (FieldUnit)((const SfxUInt16Item*)pItem)->GetValue(); + switch( eUnit ) + { + case FUNIT_MM: // nur die Einheiten, die auch im Dialog stehen + case FUNIT_CM: + case FUNIT_INCH: + case FUNIT_PICA: + case FUNIT_POINT: + { + PutItem( *pItem ); + ScAppOptions aNewOpts( GetAppOptions() ); + aNewOpts.SetAppMetric( eUnit ); + SetAppOptions( aNewOpts ); + rReq.Done(); + } + break; + default: + { + // added to avoid warnings + } + } + } + } + break; + + case FID_AUTOCOMPLETE: + { + ScAppOptions aNewOpts( GetAppOptions() ); + BOOL bNew = !aNewOpts.GetAutoComplete(); + aNewOpts.SetAutoComplete( bNew ); + SetAppOptions( aNewOpts ); + ScInputHandler::SetAutoComplete( bNew ); + if (pBindings) + pBindings->Invalidate( FID_AUTOCOMPLETE ); + rReq.Done(); + } + break; + + case SID_DETECTIVE_AUTO: + { + ScAppOptions aNewOpts( GetAppOptions() ); + BOOL bNew = !aNewOpts.GetDetectiveAuto(); + SFX_REQUEST_ARG( rReq, pAuto, SfxBoolItem, SID_DETECTIVE_AUTO, sal_False ); + if ( pAuto ) + bNew = pAuto->GetValue(); + + aNewOpts.SetDetectiveAuto( bNew ); + SetAppOptions( aNewOpts ); + if (pBindings) + pBindings->Invalidate( SID_DETECTIVE_AUTO ); + rReq.AppendItem( SfxBoolItem( SID_DETECTIVE_AUTO, bNew ) ); + rReq.Done(); + } + break; + + case SID_PSZ_FUNCTION: + if (pReqArgs) + { + const SfxUInt16Item& rItem = (const SfxUInt16Item&)pReqArgs->Get(SID_PSZ_FUNCTION); + DBG_ASSERT(rItem.ISA(SfxUInt16Item),"falscher Parameter"); + + ScAppOptions aNewOpts( GetAppOptions() ); + aNewOpts.SetStatusFunc( rItem.GetValue() ); + SetAppOptions( aNewOpts ); + + if (pBindings) + { + pBindings->Invalidate( SID_TABLE_CELL ); + pBindings->Update( SID_TABLE_CELL ); // sofort + + pBindings->Invalidate( SID_PSZ_FUNCTION ); + pBindings->Update( SID_PSZ_FUNCTION ); + // falls Menue gleich wieder aufgeklappt wird + } + } + break; + + case SID_ATTR_LANGUAGE: + case SID_ATTR_CHAR_CJK_LANGUAGE: + case SID_ATTR_CHAR_CTL_LANGUAGE: + { + const SfxPoolItem* pItem; + if ( pReqArgs && SFX_ITEM_SET == pReqArgs->GetItemState( GetPool().GetWhich(nSlot), TRUE, &pItem ) ) + { + ScDocShell* pDocSh = PTR_CAST(ScDocShell, SfxObjectShell::Current()); + ScDocument* pDoc = pDocSh ? pDocSh->GetDocument() : NULL; + if ( pDoc ) + { + LanguageType eNewLang = ((SvxLanguageItem*)pItem)->GetLanguage(); + LanguageType eLatin, eCjk, eCtl; + pDoc->GetLanguage( eLatin, eCjk, eCtl ); + LanguageType eOld = ( nSlot == SID_ATTR_CHAR_CJK_LANGUAGE ) ? eCjk : + ( ( nSlot == SID_ATTR_CHAR_CTL_LANGUAGE ) ? eCtl : eLatin ); + if ( eNewLang != eOld ) + { + if ( nSlot == SID_ATTR_CHAR_CJK_LANGUAGE ) + eCjk = eNewLang; + else if ( nSlot == SID_ATTR_CHAR_CTL_LANGUAGE ) + eCtl = eNewLang; + else + eLatin = eNewLang; + + pDoc->SetLanguage( eLatin, eCjk, eCtl ); + + ScInputHandler* pInputHandler = GetInputHdl(); + if ( pInputHandler ) + pInputHandler->UpdateSpellSettings(); // EditEngine-Flags + ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell, SfxViewShell::Current()); + if ( pViewSh ) + pViewSh->UpdateDrawTextOutliner(); // EditEngine-Flags + + pDocSh->SetDocumentModified(); + } + } + } + } + break; + + case FID_FOCUS_POSWND: + { + ScInputHandler* pHdl = GetInputHdl(); + if (pHdl) + { + ScInputWindow* pWin = pHdl->GetInputWindow(); + if (pWin) + pWin->PosGrabFocus(); + } + rReq.Done(); + } + break; + + case SID_OPEN_XML_FILTERSETTINGS: + { + try + { + com::sun::star::uno::Reference < ::com::sun::star::ui::dialogs::XExecutableDialog > xDialog(::comphelper::getProcessServiceFactory()->createInstance(rtl::OUString::createFromAscii("com.sun.star.comp.ui.XSLTFilterDialog")), com::sun::star::uno::UNO_QUERY); + if( xDialog.is() ) + { + xDialog->execute(); + } + } + catch( ::com::sun::star::uno::RuntimeException& ) + { + } + } + break; + + default: + DBG_ERROR( "ScApplication: Unknown Message." ); + break; + } +} + +void ScModule::GetState( SfxItemSet& rSet ) +{ + SfxWhichIter aIter(rSet); + USHORT nWhich = aIter.FirstWhich(); + while ( nWhich ) + { + switch ( nWhich ) + { + case FID_AUTOCOMPLETE: + rSet.Put( SfxBoolItem( nWhich, GetAppOptions().GetAutoComplete() ) ); + break; + case SID_DETECTIVE_AUTO: + rSet.Put( SfxBoolItem( nWhich, GetAppOptions().GetDetectiveAuto() ) ); + break; + case SID_PSZ_FUNCTION: + rSet.Put( SfxUInt16Item( nWhich, GetAppOptions().GetStatusFunc() ) ); + break; + case SID_ATTR_METRIC: + rSet.Put( SfxUInt16Item( nWhich, sal::static_int_cast<UINT16>(GetAppOptions().GetAppMetric()) ) ); + break; + case SID_AUTOSPELL_CHECK: + { + BOOL bAuto; + ScDocShell* pDocSh = PTR_CAST(ScDocShell, SfxObjectShell::Current()); + if ( pDocSh ) + bAuto = pDocSh->GetDocument()->GetDocOptions().IsAutoSpell(); + else + { + USHORT nDummyLang, nDummyCjk, nDummyCtl; + GetSpellSettings( nDummyLang, nDummyCjk, nDummyCtl, bAuto ); + } + rSet.Put( SfxBoolItem( nWhich, bAuto ) ); + } + break; + case SID_ATTR_LANGUAGE: + case ATTR_CJK_FONT_LANGUAGE: // WID for SID_ATTR_CHAR_CJK_LANGUAGE + case ATTR_CTL_FONT_LANGUAGE: // WID for SID_ATTR_CHAR_CTL_LANGUAGE + { + ScDocShell* pDocSh = PTR_CAST(ScDocShell, SfxObjectShell::Current()); + ScDocument* pDoc = pDocSh ? pDocSh->GetDocument() : NULL; + if ( pDoc ) + { + LanguageType eLatin, eCjk, eCtl; + pDoc->GetLanguage( eLatin, eCjk, eCtl ); + LanguageType eLang = ( nWhich == ATTR_CJK_FONT_LANGUAGE ) ? eCjk : + ( ( nWhich == ATTR_CTL_FONT_LANGUAGE ) ? eCtl : eLatin ); + rSet.Put( SvxLanguageItem( eLang, nWhich ) ); + } + } + break; + + } + nWhich = aIter.NextWhich(); + } +} + + +void ScModule::HideDisabledSlots( SfxItemSet& rSet ) +{ + if( SfxViewFrame* pViewFrm = SfxViewFrame::Current() ) + { + SfxBindings& rBindings = pViewFrm->GetBindings(); + SfxWhichIter aIter( rSet ); + for( USHORT nWhich = aIter.FirstWhich(); nWhich != 0; nWhich = aIter.NextWhich() ) + { + ScViewUtil::HideDisabledSlot( rSet, rBindings, nWhich ); + // always disable the slots + rSet.DisableItem( nWhich ); + } + } +} + + +//------------------------------------------------------------------ + +void ScModule::ResetDragObject() +{ + aDragData.pCellTransfer = NULL; + aDragData.pDrawTransfer = NULL; + + aDragData.aLinkDoc.Erase(); + aDragData.aLinkTable.Erase(); + aDragData.aLinkArea.Erase(); + aDragData.pJumpLocalDoc = NULL; + aDragData.aJumpTarget.Erase(); + aDragData.aJumpText.Erase(); +} + +void ScModule::SetDragObject( ScTransferObj* pCellObj, ScDrawTransferObj* pDrawObj ) +{ + ResetDragObject(); + aDragData.pCellTransfer = pCellObj; + aDragData.pDrawTransfer = pDrawObj; +} + +void ScModule::SetDragLink( const String& rDoc, const String& rTab, const String& rArea ) +{ + ResetDragObject(); + + aDragData.aLinkDoc = rDoc; + aDragData.aLinkTable = rTab; + aDragData.aLinkArea = rArea; +} + +void ScModule::SetDragJump( ScDocument* pLocalDoc, const String& rTarget, const String& rText ) +{ + ResetDragObject(); + + aDragData.pJumpLocalDoc = pLocalDoc; + aDragData.aJumpTarget = rTarget; + aDragData.aJumpText = rText; +} + +//------------------------------------------------------------------ + +void ScModule::SetClipObject( ScTransferObj* pCellObj, ScDrawTransferObj* pDrawObj ) +{ + DBG_ASSERT( !pCellObj || !pDrawObj, "SetClipObject: not allowed to set both objects" ); + + aClipData.pCellClipboard = pCellObj; + aClipData.pDrawClipboard = pDrawObj; +} + +ScDocument* ScModule::GetClipDoc() +{ + // called from document + + ScTransferObj* pObj = ScTransferObj::GetOwnClipboard( NULL ); + if (pObj) + return pObj->GetDocument(); + + return NULL; +} + +//------------------------------------------------------------------ + +void ScModule::SetSelectionTransfer( ScSelectionTransferObj* pNew ) +{ + pSelTransfer = pNew; +} + +//------------------------------------------------------------------ + +void ScModule::InitFormEditData() +{ + pFormEditData = new ScFormEditData; +} + +void ScModule::ClearFormEditData() +{ + DELETEZ( pFormEditData ); +} + +//------------------------------------------------------------------ + +void ScModule::SetViewOptions( const ScViewOptions& rOpt ) +{ + if ( !pViewCfg ) + pViewCfg = new ScViewCfg; + + pViewCfg->SetOptions( rOpt ); +} + +const ScViewOptions& ScModule::GetViewOptions() +{ + if ( !pViewCfg ) + pViewCfg = new ScViewCfg; + + return *pViewCfg; +} + +void ScModule::SetDocOptions( const ScDocOptions& rOpt ) +{ + if ( !pDocCfg ) + pDocCfg = new ScDocCfg; + + pDocCfg->SetOptions( rOpt ); +} + +const ScDocOptions& ScModule::GetDocOptions() +{ + if ( !pDocCfg ) + pDocCfg = new ScDocCfg; + + return *pDocCfg; +} + +#ifndef LRU_MAX +#define LRU_MAX 10 +#endif + +void ScModule::InsertEntryToLRUList(USHORT nFIndex) +{ + if(nFIndex != 0) + { + const ScAppOptions& rAppOpt = GetAppOptions(); + USHORT nLRUFuncCount = Min( rAppOpt.GetLRUFuncListCount(), (USHORT)LRU_MAX ); + USHORT* pLRUListIds = rAppOpt.GetLRUFuncList(); + + USHORT aIdxList[LRU_MAX]; + USHORT n = 0; + BOOL bFound = FALSE; + + while ((n < LRU_MAX) && n<nLRUFuncCount) // alte Liste abklappern + { + if (!bFound && (pLRUListIds[n]== nFIndex)) + bFound = TRUE; // erster! Treffer + else if (bFound) + aIdxList[n ] = pLRUListIds[n]; // hinter Treffer kopieren + else if ((n+1) < LRU_MAX) + aIdxList[n+1] = pLRUListIds[n]; // vor Treffer verschieben + n++; + } + if (!bFound && (n < LRU_MAX)) // Eintrag nicht gefunden? + n++; // einen mehr + aIdxList[0] = nFIndex; // Current on Top + + ScAppOptions aNewOpts(rAppOpt); // an App melden + aNewOpts.SetLRUFuncList(aIdxList, n); + SetAppOptions(aNewOpts); + + RecentFunctionsChanged(); + } +} + +void ScModule::RecentFunctionsChanged() +{ + // update function list window + USHORT nFuncListID = ScFunctionChildWindow::GetChildWindowId(); + + //! notify all views + SfxViewFrame* pViewFrm = SfxViewFrame::Current(); + if ( pViewFrm && pViewFrm->HasChildWindow(nFuncListID) ) + { + ScFunctionChildWindow* pWnd =(ScFunctionChildWindow*)pViewFrm->GetChildWindow( nFuncListID ); + + ScFunctionDockWin* pFuncList=(ScFunctionDockWin*)pWnd->GetWindow(); + + pFuncList->InitLRUList(); + } +} + +void ScModule::SetAppOptions( const ScAppOptions& rOpt ) +{ + if ( !pAppCfg ) + pAppCfg = new ScAppCfg; + + pAppCfg->SetOptions( rOpt ); +} + +void global_InitAppOptions() +{ + SC_MOD()->GetAppOptions(); +} + +const ScAppOptions& ScModule::GetAppOptions() +{ + if ( !pAppCfg ) + pAppCfg = new ScAppCfg; + + return *pAppCfg; +} + +void ScModule::SetInputOptions( const ScInputOptions& rOpt ) +{ + if ( !pInputCfg ) + pInputCfg = new ScInputCfg; + + pInputCfg->SetOptions( rOpt ); +} + +const ScInputOptions& ScModule::GetInputOptions() +{ + if ( !pInputCfg ) + pInputCfg = new ScInputCfg; + + return *pInputCfg; +} + +void ScModule::SetPrintOptions( const ScPrintOptions& rOpt ) +{ + if ( !pPrintCfg ) + pPrintCfg = new ScPrintCfg; + + pPrintCfg->SetOptions( rOpt ); +} + +const ScPrintOptions& ScModule::GetPrintOptions() +{ + if ( !pPrintCfg ) + pPrintCfg = new ScPrintCfg; + + return *pPrintCfg; +} + +ScNavipiCfg& ScModule::GetNavipiCfg() +{ + if ( !pNavipiCfg ) + pNavipiCfg = new ScNavipiCfg; + + return *pNavipiCfg; +} + +ScAddInCfg& ScModule::GetAddInCfg() +{ + if ( !pAddInCfg ) + pAddInCfg = new ScAddInCfg; + + return *pAddInCfg; +} + +svtools::ColorConfig& ScModule::GetColorConfig() +{ + if ( !pColorConfig ) + { + pColorConfig = new svtools::ColorConfig; + pColorConfig->AddListener(this); + } + + return *pColorConfig; +} + +SvtAccessibilityOptions& ScModule::GetAccessOptions() +{ + if ( !pAccessOptions ) + { + pAccessOptions = new SvtAccessibilityOptions; + pAccessOptions->AddListener(this); + } + + return *pAccessOptions; +} + +SvtCTLOptions& ScModule::GetCTLOptions() +{ + if ( !pCTLOptions ) + { + pCTLOptions = new SvtCTLOptions; + pCTLOptions->AddListener(this); + } + + return *pCTLOptions; +} + +SvtUserOptions& ScModule::GetUserOptions() +{ + if( !pUserOptions ) + { + pUserOptions = new SvtUserOptions; + } + return *pUserOptions; +} + +USHORT ScModule::GetOptDigitLanguage() +{ + SvtCTLOptions::TextNumerals eNumerals = GetCTLOptions().GetCTLTextNumerals(); + return ( eNumerals == SvtCTLOptions::NUMERALS_ARABIC ) ? LANGUAGE_ENGLISH_US : + ( eNumerals == SvtCTLOptions::NUMERALS_HINDI) ? LANGUAGE_ARABIC_SAUDI_ARABIA : + LANGUAGE_SYSTEM; +} + +//------------------------------------------------------------------ +// +// Optionen +// +//------------------------------------------------------------------ + +// +// ModifyOptions - Items aus Calc-Options-Dialog +// und SID_AUTOSPELL_CHECK +// + +#define IS_AVAILABLE(w,item) (SFX_ITEM_SET==rOptSet.GetItemState((w),TRUE,&item)) + +void ScModule::ModifyOptions( const SfxItemSet& rOptSet ) +{ + USHORT nOldSpellLang, nOldCjkLang, nOldCtlLang; + BOOL bOldAutoSpell; + GetSpellSettings( nOldSpellLang, nOldCjkLang, nOldCtlLang, bOldAutoSpell ); + + if (!pAppCfg) + GetAppOptions(); + DBG_ASSERT( pAppCfg, "AppOptions not initialised :-(" ); + + if (!pInputCfg) + GetInputOptions(); + DBG_ASSERT( pInputCfg, "InputOptions not initialised :-(" ); + + //-------------------------------------------------------------- + + SfxViewFrame* pViewFrm = SfxViewFrame::Current(); + SfxBindings* pBindings = pViewFrm ? &pViewFrm->GetBindings() : NULL; + + ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell, SfxViewShell::Current()); + ScDocShell* pDocSh = PTR_CAST(ScDocShell, SfxObjectShell::Current()); + ScDocument* pDoc = pDocSh ? pDocSh->GetDocument() : NULL; + const SfxPoolItem* pItem = NULL; + BOOL bRepaint = FALSE; + BOOL bUpdateMarks = FALSE; + BOOL bUpdateRefDev = FALSE; + BOOL bCalcAll = FALSE; + BOOL bSaveSpellCheck = FALSE; + BOOL bSaveAppOptions = FALSE; + BOOL bSaveInputOptions = FALSE; + + //-------------------------------------------------------------------------- + + // SFX_APP()->SetOptions( rOptSet ); + + // Linguistik nicht mehr + + if ( IS_AVAILABLE(SID_ATTR_METRIC,pItem) ) + { + PutItem( *pItem ); + pAppCfg->SetAppMetric( (FieldUnit)((const SfxUInt16Item*)pItem)->GetValue() ); + bSaveAppOptions = TRUE; + } + + if ( IS_AVAILABLE(SCITEM_USERLIST,pItem) ) + { + ScGlobal::SetUserList( ((const ScUserListItem*)pItem)->GetUserList() ); + bSaveAppOptions = TRUE; + } + + if ( IS_AVAILABLE(SID_SC_OPT_SYNCZOOM,pItem) ) + { + pAppCfg->SetSynchronizeZoom( static_cast<const SfxBoolItem*>(pItem)->GetValue() ); + bSaveAppOptions = TRUE; + } + + //============================================ + // ViewOptions + //============================================ + + if ( IS_AVAILABLE(SID_SCVIEWOPTIONS,pItem) ) + { + const ScViewOptions& rNewOpt = ((const ScTpViewItem*)pItem)->GetViewOptions(); + + if ( pViewSh ) + { + ScViewData* pViewData = pViewSh->GetViewData(); + const ScViewOptions& rOldOpt = pViewData->GetOptions(); + + BOOL bAnchorList = ( rOldOpt.GetOption( VOPT_ANCHOR ) != + rNewOpt.GetOption( VOPT_ANCHOR ) ); + + if ( rOldOpt != rNewOpt ) + { + pViewData->SetOptions( rNewOpt ); // veraendert rOldOpt + pViewData->GetDocument()->SetViewOptions( rNewOpt ); + pDocSh->SetDocumentModified(); + bRepaint = TRUE; + } + if ( bAnchorList ) + pViewSh->UpdateAnchorHandles(); + } + SetViewOptions( rNewOpt ); + if (pBindings) + pBindings->Invalidate(SID_HELPLINES_MOVE); + } + + //============================================ + // GridOptions, Auswertung nach ViewOptions, + // da GridOptions Member der ViewOptions ist! + //============================================ + + if ( IS_AVAILABLE(SID_ATTR_GRID_OPTIONS,pItem) ) + { + ScGridOptions aNewGridOpt( (const SvxOptionsGrid&)((const SvxGridItem&)*pItem) ); + + if ( pViewSh ) + { + ScViewData* pViewData = pViewSh->GetViewData(); + ScViewOptions aNewViewOpt( pViewData->GetOptions() ); + const ScGridOptions& rOldGridOpt = aNewViewOpt.GetGridOptions(); + + if ( rOldGridOpt != aNewGridOpt ) + { + aNewViewOpt.SetGridOptions( aNewGridOpt ); + pViewData->SetOptions( aNewViewOpt ); + pViewData->GetDocument()->SetViewOptions( aNewViewOpt ); + pDocSh->SetDocumentModified(); + bRepaint = TRUE; + } + } + ScViewOptions aNewViewOpt ( GetViewOptions() ); + aNewViewOpt.SetGridOptions( aNewGridOpt ); + SetViewOptions( aNewViewOpt ); + if (pBindings) + { + pBindings->Invalidate(SID_GRID_VISIBLE); + pBindings->Invalidate(SID_GRID_USE); + } + } + + + //============================================ + // DocOptions + //============================================ + + if ( IS_AVAILABLE(SID_SCDOCOPTIONS,pItem) ) + { + const ScDocOptions& rNewOpt = ((const ScTpCalcItem*)pItem)->GetDocOptions(); + + if ( pDoc ) + { + const ScDocOptions& rOldOpt = pDoc->GetDocOptions(); + + bRepaint = ( bRepaint || ( rOldOpt != rNewOpt ) ); + bCalcAll = bRepaint && + ( rOldOpt.IsIter() != rNewOpt.IsIter() + || rOldOpt.GetIterCount() != rNewOpt.GetIterCount() + || rOldOpt.GetIterEps() != rNewOpt.GetIterEps() + || rOldOpt.IsIgnoreCase() != rNewOpt.IsIgnoreCase() + || rOldOpt.IsCalcAsShown() != rNewOpt.IsCalcAsShown() + || (rNewOpt.IsCalcAsShown() && + rOldOpt.GetStdPrecision() != rNewOpt.GetStdPrecision()) + || rOldOpt.IsMatchWholeCell() != rNewOpt.IsMatchWholeCell() + || rOldOpt.GetYear2000() != rNewOpt.GetYear2000() + || rOldOpt.IsFormulaRegexEnabled() != rNewOpt.IsFormulaRegexEnabled() + ); + pDoc->SetDocOptions( rNewOpt ); + pDocSh->SetDocumentModified(); + } + SetDocOptions( rNewOpt ); + } + + // nach den eigentlichen DocOptions auch noch die TabDistance setzen + if ( IS_AVAILABLE(SID_ATTR_DEFTABSTOP,pItem) ) + { + USHORT nTabDist = ((SfxUInt16Item*)pItem)->GetValue(); + ScDocOptions aOpt(GetDocOptions()); + aOpt.SetTabDistance(nTabDist); + SetDocOptions( aOpt ); + + if ( pDoc ) + { + ScDocOptions aDocOpt(pDoc->GetDocOptions()); + aDocOpt.SetTabDistance(nTabDist); + pDoc->SetDocOptions( aDocOpt ); + pDocSh->SetDocumentModified(); + if(pDoc->GetDrawLayer()) + pDoc->GetDrawLayer()->SetDefaultTabulator(nTabDist); + } + } + + // AutoSpell nach den Doc-Options (weil Member) + + if ( IS_AVAILABLE(SID_AUTOSPELL_CHECK,pItem) ) // an Doc-Options + { + BOOL bDoAutoSpell = ((const SfxBoolItem*)pItem)->GetValue(); + + if (pDoc) + { + ScDocOptions aNewOpt = pDoc->GetDocOptions(); + if ( aNewOpt.IsAutoSpell() != bDoAutoSpell ) + { + aNewOpt.SetAutoSpell( bDoAutoSpell ); + pDoc->SetDocOptions( aNewOpt ); + + if (bDoAutoSpell) + pDoc->SetOnlineSpellPos( ScAddress(0,0,0) ); // vorne anfangen + else + { + WaitObject aWait( pDocSh->GetActiveDialogParent() ); + pDoc->RemoveAutoSpellObj(); // Edit-Text-Objekte wieder zurueckwandeln + } + + //#92038#; don't set document modified, because this flag is no longer saved +// pDocSh->SetDocumentModified(); + + bRepaint = TRUE; // weil HideAutoSpell evtl. ungueltig + //! alle Views painten ??? + } + } + + if ( bOldAutoSpell != bDoAutoSpell ) + { + SetAutoSpellProperty( bDoAutoSpell ); + bSaveSpellCheck = TRUE; + } + if ( pDocSh ) + pDocSh->PostPaintGridAll(); // wegen Markierungen + ScInputHandler* pInputHandler = GetInputHdl(); + if ( pInputHandler ) + pInputHandler->UpdateSpellSettings(); // EditEngine-Flags + if ( pViewSh ) + pViewSh->UpdateDrawTextOutliner(); // EditEngine-Flags + + if (pBindings) + pBindings->Invalidate( SID_AUTOSPELL_CHECK ); + } + + //============================================ + // InputOptions + //============================================ + + if ( IS_AVAILABLE(SID_SC_INPUT_SELECTIONPOS,pItem) ) + { + pInputCfg->SetMoveDir( ((const SfxUInt16Item*)pItem)->GetValue() ); + bSaveInputOptions = TRUE; + } + if ( IS_AVAILABLE(SID_SC_INPUT_SELECTION,pItem) ) + { + pInputCfg->SetMoveSelection( ((const SfxBoolItem*)pItem)->GetValue() ); + bSaveInputOptions = TRUE; + } + if ( IS_AVAILABLE(SID_SC_INPUT_EDITMODE,pItem) ) + { + pInputCfg->SetEnterEdit( ((const SfxBoolItem*)pItem)->GetValue() ); + bSaveInputOptions = TRUE; + } + if ( IS_AVAILABLE(SID_SC_INPUT_FMT_EXPAND,pItem) ) + { + pInputCfg->SetExtendFormat( ((const SfxBoolItem*)pItem)->GetValue() ); + bSaveInputOptions = TRUE; + } + if ( IS_AVAILABLE(SID_SC_INPUT_RANGEFINDER,pItem) ) + { + pInputCfg->SetRangeFinder( ((const SfxBoolItem*)pItem)->GetValue() ); + bSaveInputOptions = TRUE; + } + if ( IS_AVAILABLE(SID_SC_INPUT_REF_EXPAND,pItem) ) + { + pInputCfg->SetExpandRefs( ((const SfxBoolItem*)pItem)->GetValue() ); + bSaveInputOptions = TRUE; + } + if ( IS_AVAILABLE(SID_SC_INPUT_MARK_HEADER,pItem) ) + { + pInputCfg->SetMarkHeader( ((const SfxBoolItem*)pItem)->GetValue() ); + bSaveInputOptions = TRUE; + bUpdateMarks = TRUE; + } + if ( IS_AVAILABLE(SID_SC_INPUT_TEXTWYSIWYG,pItem) ) + { + BOOL bNew = ((const SfxBoolItem*)pItem)->GetValue(); + if ( bNew != pInputCfg->GetTextWysiwyg() ) + { + pInputCfg->SetTextWysiwyg( bNew ); + bSaveInputOptions = TRUE; + bUpdateRefDev = TRUE; + } + } + if( IS_AVAILABLE( SID_SC_INPUT_REPLCELLSWARN, pItem ) ) + { + pInputCfg->SetReplaceCellsWarn( ((const SfxBoolItem*)pItem)->GetValue() ); + bSaveInputOptions = TRUE; + } + + //============================================ + // PrintOptions + //============================================ + + if ( IS_AVAILABLE(SID_SCPRINTOPTIONS,pItem) ) + { + const ScPrintOptions& rNewOpt = ((const ScTpPrintItem*)pItem)->GetPrintOptions(); + SetPrintOptions( rNewOpt ); + + // broadcast causes all previews to recalc page numbers + SFX_APP()->Broadcast( SfxSimpleHint( SID_SCPRINTOPTIONS ) ); + } + + //---------------------------------------------------------- + +// if ( bSaveSpellCheck ) +// { + // currently LinguProperties are saved only at program exit. + // if a save method becomes available, it should be called here. +// } + + if ( bSaveAppOptions ) + pAppCfg->OptionsChanged(); + + if ( bSaveInputOptions ) + pInputCfg->OptionsChanged(); + + // Neuberechnung anstossen? + + if ( pDoc && bCalcAll ) + { + WaitObject aWait( pDocSh->GetActiveDialogParent() ); + pDoc->CalcAll(); + if ( pViewSh ) + pViewSh->UpdateCharts( TRUE ); + else + ScDBFunc::DoUpdateCharts( ScAddress(), pDoc, TRUE ); + if (pBindings) + pBindings->Invalidate( SID_ATTR_SIZE ); //SvxPosSize-StatusControl-Update + } + + if ( pViewSh && bUpdateMarks ) + pViewSh->UpdateAutoFillMark(); + + // View neuzeichnen? + + if ( pViewSh && bRepaint ) + { + pViewSh->UpdateFixPos(); + pViewSh->PaintGrid(); + pViewSh->PaintTop(); + pViewSh->PaintLeft(); + pViewSh->PaintExtras(); + pViewSh->InvalidateBorder(); + if (pBindings) + { + pBindings->Invalidate( FID_TOGGLEHEADERS ); // -> Checks im Menue + pBindings->Invalidate( FID_TOGGLESYNTAX ); + } + } + + // update ref device (for all documents) + + if ( bUpdateRefDev ) + { + // for all documents: recalc output factor, update row heights + SfxObjectShell* pObjSh = SfxObjectShell::GetFirst(); + while ( pObjSh ) + { + if ( pObjSh->Type() == TYPE(ScDocShell) ) + { + ScDocShell* pOneDocSh = ((ScDocShell*)pObjSh); + pOneDocSh->CalcOutputFactor(); + SCTAB nTabCount = pOneDocSh->GetDocument()->GetTableCount(); + for (SCTAB nTab=0; nTab<nTabCount; nTab++) + pOneDocSh->AdjustRowHeight( 0, MAXROW, nTab ); + } + pObjSh = SfxObjectShell::GetNext( *pObjSh ); + } + + // for all (tab-) views: + TypeId aScType = TYPE(ScTabViewShell); + SfxViewShell* pSh = SfxViewShell::GetFirst( &aScType ); + while ( pSh ) + { + ScTabViewShell* pOneViewSh = (ScTabViewShell*)pSh; + + // set ref-device for EditEngine + ScInputHandler* pHdl = GetInputHdl(pOneViewSh); + if (pHdl) + pHdl->UpdateRefDevice(); + + // update view scale + ScViewData* pViewData = pOneViewSh->GetViewData(); + pOneViewSh->SetZoom( pViewData->GetZoomX(), pViewData->GetZoomY(), FALSE ); + + // repaint + pOneViewSh->PaintGrid(); + pOneViewSh->PaintTop(); + pOneViewSh->PaintLeft(); + + pSh = SfxViewShell::GetNext( *pSh, &aScType ); + } + } +} + +#undef IS_AVAILABLE + +//------------------------------------------------------------------ +// +// Input-Handler +// +//------------------------------------------------------------------ + +ScInputHandler* ScModule::GetInputHdl( ScTabViewShell* pViewSh, BOOL bUseRef ) +{ + if ( pRefInputHandler && bUseRef ) + return pRefInputHandler; + + ScInputHandler* pHdl = NULL; + if ( !pViewSh ) + { + // in case a UIActive embedded object has no ViewShell ( UNO component ) + // the own calc view shell will be set as current, but no handling should happen + + ScTabViewShell* pCurViewSh = PTR_CAST( ScTabViewShell, SfxViewShell::Current() ); + if ( pCurViewSh && !pCurViewSh->GetUIActiveClient() ) + pViewSh = pCurViewSh; + } + + if ( pViewSh ) + pHdl = pViewSh->GetInputHandler(); // Viewshell hat jetzt immer einen + + // #57989# wenn keine ViewShell uebergeben oder aktiv, kann NULL herauskommen + DBG_ASSERT( pHdl || !pViewSh, "GetInputHdl: kein InputHandler gefunden" ); + return pHdl; +} + +void ScModule::ViewShellChanged() +{ + ScInputHandler* pHdl = GetInputHdl(); + ScTabViewShell* pShell = ScTabViewShell::GetActiveViewShell(); + if ( pShell && pHdl ) + pShell->UpdateInputHandler(); +} + +void ScModule::SetInputMode( ScInputMode eMode ) +{ + ScInputHandler* pHdl = GetInputHdl(); + if (pHdl) + pHdl->SetMode( eMode ); +} + +BOOL ScModule::IsEditMode() +{ + ScInputHandler* pHdl = GetInputHdl(); + return pHdl && pHdl->IsEditMode(); +} + +BOOL ScModule::IsInputMode() +{ + ScInputHandler* pHdl = GetInputHdl(); + return pHdl && pHdl->IsInputMode(); +} + +BOOL ScModule::InputKeyEvent( const KeyEvent& rKEvt, BOOL bStartEdit ) +{ + ScInputHandler* pHdl = GetInputHdl(); + return ( pHdl ? pHdl->KeyInput( rKEvt, bStartEdit ) : FALSE ); +} + +void ScModule::InputEnterHandler( BYTE nBlockMode ) +{ + if ( !SFX_APP()->IsDowning() ) // nicht beim Programmende + { + ScInputHandler* pHdl = GetInputHdl(); + if (pHdl) + pHdl->EnterHandler( nBlockMode ); + } +} + +void ScModule::InputCancelHandler() +{ + ScInputHandler* pHdl = GetInputHdl(); + if (pHdl) + pHdl->CancelHandler(); +} + +void ScModule::InputSelection( EditView* pView ) +{ + ScInputHandler* pHdl = GetInputHdl(); + if (pHdl) + pHdl->InputSelection( pView ); +} + +void ScModule::InputChanged( EditView* pView ) +{ + ScInputHandler* pHdl = GetInputHdl(); + if (pHdl) + pHdl->InputChanged( pView ); +} + +void ScModule::ViewShellGone( ScTabViewShell* pViewSh ) +{ + ScInputHandler* pHdl = GetInputHdl(); + if (pHdl) + pHdl->ViewShellGone( pViewSh ); + + // Team dialog is opened with the window from a view as parent + // -> close it if any view is closed + if (pTeamDlg) + pTeamDlg->Close(); // resets variable pTeamDlg +} + +void ScModule::SetRefInputHdl( ScInputHandler* pNew ) +{ + pRefInputHandler = pNew; +} + +ScInputHandler* ScModule::GetRefInputHdl() +{ + return pRefInputHandler; +} + +//------------------------------------------------------------------------ +// Olk's Krempel: + +void ScModule::InputGetSelection( xub_StrLen& rStart, xub_StrLen& rEnd ) +{ + ScInputHandler* pHdl = GetInputHdl(); + if (pHdl) + pHdl->InputGetSelection( rStart, rEnd ); +} + +void ScModule::InputSetSelection( xub_StrLen nStart, xub_StrLen nEnd ) +{ + ScInputHandler* pHdl = GetInputHdl(); + if (pHdl) + pHdl->InputSetSelection( nStart, nEnd ); +} + +void ScModule::InputReplaceSelection( const String& rStr ) +{ + ScInputHandler* pHdl = GetInputHdl(); + if (pHdl) + pHdl->InputReplaceSelection( rStr ); +} + +String ScModule::InputGetFormulaStr() +{ + ScInputHandler* pHdl = GetInputHdl(); + String aStr; + if ( pHdl ) + aStr = pHdl->InputGetFormulaStr(); + return aStr; +} + +void ScModule::ActivateInputWindow( const String* pStrFormula, BOOL bMatrix ) +{ + ScInputHandler* pHdl = GetInputHdl(); + if ( pHdl ) + { + ScInputWindow* pWin = pHdl->GetInputWindow(); + if ( pStrFormula ) + { + // Formel uebernehmen + if ( pWin ) + { + pWin->SetFuncString( *pStrFormula, FALSE ); + // SetSumAssignMode wegen FALSE nicht noetig + } + BYTE nMode = bMatrix ? SC_ENTER_MATRIX : SC_ENTER_NORMAL; + pHdl->EnterHandler( nMode ); + + // ohne Invalidate bleibt die Selektion stehen, wenn die Formel unveraendert ist + if (pWin) + pWin->TextInvalidate(); + } + else + { + // Abbrechen + if ( pWin ) + { + pWin->SetFuncString( EMPTY_STRING, FALSE ); + // SetSumAssignMode wegen FALSE nicht noetig + } + pHdl->CancelHandler(); + } + } +} + +//------------------------------------------------------------------ +// +// Referenz - Dialoge +// +//------------------------------------------------------------------ + +void ScModule::SetRefDialog( USHORT nId, BOOL bVis, SfxViewFrame* pViewFrm ) +{ + //! move reference dialog handling to view + //! (only keep function autopilot here for references to other documents) + + if(nCurRefDlgId==0 || (nId==nCurRefDlgId && !bVis)) + { + if ( !pViewFrm ) + pViewFrm = SfxViewFrame::Current(); + + // #79379# bindings update causes problems with update of stylist if + // current style family has changed + //if ( pViewFrm ) + // pViewFrm->GetBindings().Update(); // to avoid trouble in LockDispatcher + + nCurRefDlgId = bVis ? nId : 0 ; // before SetChildWindow + + if ( pViewFrm ) + { + // store the dialog id also in the view shell + SfxViewShell* pViewSh = pViewFrm->GetViewShell(); + if ( pViewSh && pViewSh->ISA( ScTabViewShell ) ) + ((ScTabViewShell*)pViewSh)->SetCurRefDlgId( nCurRefDlgId ); + else + { + // no ScTabViewShell - possible for example from a Basic macro + bVis = FALSE; + nCurRefDlgId = 0; // don't set nCurRefDlgId if no dialog is created + } + + pViewFrm->SetChildWindow( nId, bVis ); + } + + SfxApplication* pSfxApp = SFX_APP(); + pSfxApp->Broadcast( SfxSimpleHint( FID_REFMODECHANGED ) ); + } +} + +void ScModule::OpenTeamDlg() +{ + if ( !pTeamDlg ) + { + // team dialog needs an existing parent window + // -> use window from active view (dialog is closed in ViewShellGone) + + ScTabViewShell* pShell = ScTabViewShell::GetActiveViewShell(); + if (pShell) + pTeamDlg = new ScTeamDlg( pShell->GetActiveWin() ); + } + else + pTeamDlg->Center(); +} + +SfxChildWindow* lcl_GetChildWinFromAnyView( USHORT nId ) +{ + // first try the current view + + SfxViewFrame* pViewFrm = SfxViewFrame::Current(); + // #i46999# current view frame can be null (for example, when closing help) + SfxChildWindow* pChildWnd = pViewFrm ? pViewFrm->GetChildWindow( nId ) : NULL; + if ( pChildWnd ) + return pChildWnd; // found in the current view + + // if not found there, get the child window from any open view + // it can be open only in one view because nCurRefDlgId is global + + pViewFrm = SfxViewFrame::GetFirst(); + while ( pViewFrm ) + { + pChildWnd = pViewFrm->GetChildWindow( nId ); + if ( pChildWnd ) + return pChildWnd; // found in any view + + pViewFrm = SfxViewFrame::GetNext( *pViewFrm ); + } + + return NULL; // none found +} + +BOOL ScModule::IsModalMode(SfxObjectShell* pDocSh) +{ + //! move reference dialog handling to view + //! (only keep function autopilot here for references to other documents) + + BOOL bIsModal = FALSE; + + if ( nCurRefDlgId ) + { + SfxChildWindow* pChildWnd = lcl_GetChildWinFromAnyView( nCurRefDlgId ); + if ( pChildWnd ) + { + IAnyRefDialog* pRefDlg = dynamic_cast<IAnyRefDialog*>(pChildWnd->GetWindow()); + bIsModal = pChildWnd->IsVisible() && + !( pRefDlg->IsRefInputMode() && pRefDlg->IsDocAllowed(pDocSh) ); + } + else + { + // in 592 and above, the dialog isn't visible in other views + // if the dialog is open but can't be accessed, disable input + + bIsModal = TRUE; + } + + // pChildWnd kann 0 sein, wenn der Dialog nach dem Umschalten + // von einer anderen Shell noch nicht erzeugt wurde (z.B. in GetFocus) + } + else if (pDocSh) + { + ScInputHandler* pHdl = GetInputHdl(); + if ( pHdl ) + bIsModal = pHdl->IsModalMode(pDocSh); + } + + return bIsModal; +} + +BOOL ScModule::IsTableLocked() +{ + //! move reference dialog handling to view + //! (only keep function autopilot here for references to other documents) + + BOOL bLocked = FALSE; + + // bisher nur bei ScAnyRefDlg + + if ( nCurRefDlgId ) + { + SfxChildWindow* pChildWnd = lcl_GetChildWinFromAnyView( nCurRefDlgId ); + if ( pChildWnd ) + bLocked = dynamic_cast<IAnyRefDialog*>(pChildWnd->GetWindow())->IsTableLocked(); + else + bLocked = TRUE; // for other views, see IsModalMode + } + + return bLocked; +} + +BOOL ScModule::IsRefDialogOpen() +{ + //! move reference dialog handling to view + //! (only keep function autopilot here for references to other documents) + + BOOL bIsOpen = FALSE; + + if ( nCurRefDlgId ) + { + SfxChildWindow* pChildWnd = lcl_GetChildWinFromAnyView( nCurRefDlgId ); + if ( pChildWnd ) + bIsOpen = pChildWnd->IsVisible(); + else + bIsOpen = TRUE; // for other views, see IsModalMode + } + + return bIsOpen; +} + +BOOL ScModule::IsFormulaMode() +{ + //! move reference dialog handling to view + //! (only keep function autopilot here for references to other documents) + + BOOL bIsFormula = FALSE; + + if ( nCurRefDlgId ) + { + SfxChildWindow* pChildWnd = lcl_GetChildWinFromAnyView( nCurRefDlgId ); + if ( pChildWnd ) + { + IAnyRefDialog* pRefDlg = dynamic_cast<IAnyRefDialog*>(pChildWnd->GetWindow()); + bIsFormula = pChildWnd->IsVisible() && pRefDlg->IsRefInputMode(); + } + } + else + { + ScInputHandler* pHdl = GetInputHdl(); + if ( pHdl ) + bIsFormula = pHdl->IsFormulaMode(); + } + + if (bIsInEditCommand) + bIsFormula = TRUE; + + return bIsFormula; +} + +void lcl_MarkedTabs( const ScMarkData& rMark, SCTAB& rStartTab, SCTAB& rEndTab ) +{ + if (rMark.GetSelectCount() > 1) + { + BOOL bFirst = TRUE; + for (SCTAB i=0; i<=MAXTAB; i++) + if (rMark.GetTableSelect(i)) + { + if (bFirst) + rStartTab = i; + rEndTab = i; + bFirst = FALSE; + } + } +} + +void ScModule::SetReference( const ScRange& rRef, ScDocument* pDoc, + const ScMarkData* pMarkData ) +{ + //! move reference dialog handling to view + //! (only keep function autopilot here for references to other documents) + + // in Ref-Dialogen wird hiermit auch das Zoom-In ausgeloest, + // wenn Start und Ende der Ref unterschiedlich sind + + ScRange aNew = rRef; + aNew.Justify(); // immer "richtig herum" + + if( nCurRefDlgId ) + { + SfxChildWindow* pChildWnd = lcl_GetChildWinFromAnyView( nCurRefDlgId ); + DBG_ASSERT( pChildWnd, "NoChildWin" ); + if ( pChildWnd ) + { + if ( nCurRefDlgId == SID_OPENDLG_CONSOLIDATE && pMarkData ) + { + SCTAB nStartTab = aNew.aStart.Tab(); + SCTAB nEndTab = aNew.aEnd.Tab(); + lcl_MarkedTabs( *pMarkData, nStartTab, nEndTab ); + aNew.aStart.SetTab(nStartTab); + aNew.aEnd.SetTab(nEndTab); + } + + IAnyRefDialog* pRefDlg = dynamic_cast<IAnyRefDialog*>(pChildWnd->GetWindow()); + + // hide the (color) selection now instead of later from LoseFocus, + // don't abort the ref input that causes this call (bDoneRefMode = FALSE) + pRefDlg->HideReference( FALSE ); + pRefDlg->SetReference( aNew, pDoc ); + } + } + else + { + ScInputHandler* pHdl = GetInputHdl(); + if (pHdl) + pHdl->SetReference( aNew, pDoc ); + else + { + DBG_ERROR("SetReference ohne Empfaenger"); + } + } +} + +void ScModule::AddRefEntry() // "Mehrfachselektion" +{ + //! move reference dialog handling to view + //! (only keep function autopilot here for references to other documents) + + if ( nCurRefDlgId ) + { + SfxChildWindow* pChildWnd = lcl_GetChildWinFromAnyView( nCurRefDlgId ); + DBG_ASSERT( pChildWnd, "NoChildWin" ); + if ( pChildWnd ) + { + IAnyRefDialog* pRefDlg = dynamic_cast<IAnyRefDialog*>(pChildWnd->GetWindow()); + pRefDlg->AddRefEntry(); + } + } + else + { + ScInputHandler* pHdl = GetInputHdl(); + if (pHdl) + pHdl->AddRefEntry(); + } +} + +void ScModule::EndReference() +{ + //! move reference dialog handling to view + //! (only keep function autopilot here for references to other documents) + + // in Ref-Dialogen wird hiermit auch das Zoom-In wieder aufgehoben + + //! ShowRefFrame am InputHdl, wenn der Funktions-AP offen ist ??? + + if ( nCurRefDlgId ) + { + SfxChildWindow* pChildWnd = lcl_GetChildWinFromAnyView( nCurRefDlgId ); + DBG_ASSERT( pChildWnd, "NoChildWin" ); + if ( pChildWnd ) + { + IAnyRefDialog* pRefDlg = dynamic_cast<IAnyRefDialog*>(pChildWnd->GetWindow()); + pRefDlg->SetActive(); + } + } +} + +//------------------------------------------------------------------ +// +// Idle / Online-Spelling +// +//------------------------------------------------------------------ + +void ScModule::AnythingChanged() +{ + ULONG nOldTime = aIdleTimer.GetTimeout(); + if ( nOldTime != SC_IDLE_MIN ) + aIdleTimer.SetTimeout( SC_IDLE_MIN ); + + nIdleCount = 0; +} + +void lcl_CheckNeedsRepaint( ScDocShell* pDocShell ) +{ + SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocShell ); + while ( pFrame ) + { + SfxViewShell* p = pFrame->GetViewShell(); + ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell,p); + if ( pViewSh ) + pViewSh->CheckNeedsRepaint(); + pFrame = SfxViewFrame::GetNext( *pFrame, pDocShell ); + } +} + +IMPL_LINK( ScModule, IdleHandler, Timer*, EMPTYARG ) +{ + if ( Application::AnyInput( INPUT_MOUSEANDKEYBOARD ) ) + { + aIdleTimer.Start(); // Timeout unveraendert + return 0; + } + + BOOL bMore = FALSE; + ScDocShell* pDocSh = PTR_CAST( ScDocShell, SfxObjectShell::Current() ); + if ( pDocSh ) + { + ScDocument* pDoc = pDocSh->GetDocument(); + if ( pDoc->IsLoadingDone() ) + { + BOOL bLinks = pDoc->IdleCheckLinks(); + BOOL bWidth = pDoc->IdleCalcTextWidth(); + BOOL bSpell = pDoc->ContinueOnlineSpelling(); + if ( bSpell ) + aSpellTimer.Start(); // da ist noch was + + bMore = bLinks || bWidth || bSpell; // ueberhaupt noch was? + + // While calculating a Basic formula, a paint event may have occured, + // so check the bNeedsRepaint flags for this document's views + if (bWidth) + lcl_CheckNeedsRepaint( pDocSh ); + } + } + + ULONG nOldTime = aIdleTimer.GetTimeout(); + ULONG nNewTime = nOldTime; + if ( bMore ) + { + nNewTime = SC_IDLE_MIN; + nIdleCount = 0; + } + else + { + // SC_IDLE_COUNT mal mit initialem Timeout, dann hochzaehlen + + if ( nIdleCount < SC_IDLE_COUNT ) + ++nIdleCount; + else + { + nNewTime += SC_IDLE_STEP; + if ( nNewTime > SC_IDLE_MAX ) + nNewTime = SC_IDLE_MAX; + } + } + if ( nNewTime != nOldTime ) + aIdleTimer.SetTimeout( nNewTime ); + + aIdleTimer.Start(); + return 0; +} + +IMPL_LINK( ScModule, SpellTimerHdl, Timer*, EMPTYARG ) +{ + if ( Application::AnyInput( INPUT_KEYBOARD ) ) + { + aSpellTimer.Start(); + return 0; // dann spaeter wieder... + } + + ScDocShell* pDocSh = PTR_CAST( ScDocShell, SfxObjectShell::Current() ); + if ( pDocSh ) + { + ScDocument* pDoc = pDocSh->GetDocument(); + if ( pDoc->ContinueOnlineSpelling() ) + aSpellTimer.Start(); + } + return 0; +} + + //virtuelle Methoden fuer den Optionendialog +SfxItemSet* ScModule::CreateItemSet( USHORT nId ) +{ + SfxItemSet* pRet = 0; + if(SID_SC_EDITOPTIONS == nId) + { + pRet = new SfxItemSet( GetPool(), + // TP_CALC: + SID_SCDOCOPTIONS, SID_SCDOCOPTIONS, + // TP_VIEW: + SID_SCVIEWOPTIONS, SID_SCVIEWOPTIONS, + SID_SC_OPT_SYNCZOOM, SID_SC_OPT_SYNCZOOM, + // TP_INPUT: + SID_SC_INPUT_SELECTION,SID_SC_INPUT_MARK_HEADER, + SID_SC_INPUT_TEXTWYSIWYG,SID_SC_INPUT_TEXTWYSIWYG, + SID_SC_INPUT_REPLCELLSWARN,SID_SC_INPUT_REPLCELLSWARN, + // TP_USERLISTS: + SCITEM_USERLIST, SCITEM_USERLIST, + // TP_PRINT: + SID_SCPRINTOPTIONS, SID_SCPRINTOPTIONS, + // TP_GRID: + SID_ATTR_GRID_OPTIONS, SID_ATTR_GRID_OPTIONS, + // + SID_ATTR_METRIC, SID_ATTR_METRIC, + SID_ATTR_DEFTABSTOP, SID_ATTR_DEFTABSTOP, + 0 ); + + ScDocShell* pDocSh = PTR_CAST(ScDocShell, + SfxObjectShell::Current()); + ScDocOptions aCalcOpt = pDocSh + ? pDocSh->GetDocument()->GetDocOptions() + : GetDocOptions(); + + ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell, + SfxViewShell::Current()); + ScViewOptions aViewOpt = pViewSh + ? pViewSh->GetViewData()->GetOptions() + : GetViewOptions(); + + ScUserListItem aULItem( SCITEM_USERLIST ); + ScUserList* pUL = ScGlobal::GetUserList(); + + // SFX_APP()->GetOptions( aSet ); + + pRet->Put( SfxUInt16Item( SID_ATTR_METRIC, + sal::static_int_cast<UINT16>(GetAppOptions().GetAppMetric()) ) ); + + // TP_CALC + pRet->Put( SfxUInt16Item( SID_ATTR_DEFTABSTOP, + aCalcOpt.GetTabDistance())); + pRet->Put( ScTpCalcItem( SID_SCDOCOPTIONS, aCalcOpt ) ); + + // TP_VIEW + pRet->Put( ScTpViewItem( SID_SCVIEWOPTIONS, aViewOpt ) ); + pRet->Put( SfxBoolItem( SID_SC_OPT_SYNCZOOM, GetAppOptions().GetSynchronizeZoom() ) ); + + // TP_INPUT + const ScInputOptions& rInpOpt = GetInputOptions(); + pRet->Put( SfxUInt16Item( SID_SC_INPUT_SELECTIONPOS, + rInpOpt.GetMoveDir() ) ); + pRet->Put( SfxBoolItem( SID_SC_INPUT_SELECTION, + rInpOpt.GetMoveSelection() ) ); + pRet->Put( SfxBoolItem( SID_SC_INPUT_EDITMODE, + rInpOpt.GetEnterEdit() ) ); + pRet->Put( SfxBoolItem( SID_SC_INPUT_FMT_EXPAND, + rInpOpt.GetExtendFormat() ) ); + pRet->Put( SfxBoolItem( SID_SC_INPUT_RANGEFINDER, + rInpOpt.GetRangeFinder() ) ); + pRet->Put( SfxBoolItem( SID_SC_INPUT_REF_EXPAND, + rInpOpt.GetExpandRefs() ) ); + pRet->Put( SfxBoolItem( SID_SC_INPUT_MARK_HEADER, + rInpOpt.GetMarkHeader() ) ); + pRet->Put( SfxBoolItem( SID_SC_INPUT_TEXTWYSIWYG, + rInpOpt.GetTextWysiwyg() ) ); + pRet->Put( SfxBoolItem( SID_SC_INPUT_REPLCELLSWARN, + rInpOpt.GetReplaceCellsWarn() ) ); + + // RID_SC_TP_PRINT + pRet->Put( ScTpPrintItem( SID_SCPRINTOPTIONS, GetPrintOptions() ) ); + + // TP_GRID + SvxGridItem* pSvxGridItem = aViewOpt.CreateGridItem(); + pRet->Put( *pSvxGridItem ); + delete pSvxGridItem; + + // TP_USERLISTS + if ( pUL ) + aULItem.SetUserList( *pUL ); + pRet->Put( aULItem ); + + } + return pRet; +} + +void ScModule::ApplyItemSet( USHORT nId, const SfxItemSet& rSet ) +{ + if(SID_SC_EDITOPTIONS == nId) + { + ModifyOptions( rSet ); + } +} + +SfxTabPage* ScModule::CreateTabPage( USHORT nId, Window* pParent, const SfxItemSet& rSet ) +{ + SfxTabPage* pRet = NULL; + ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create(); + DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001 + switch(nId) + { + case SID_SC_TP_LAYOUT: + { + //CHINA001 pRet = ScTpLayoutOptions::Create(pParent, rSet); + ::CreateTabPage ScTpLayoutOptionsCreate = pFact->GetTabPageCreatorFunc( RID_SCPAGE_LAYOUT ); + if ( ScTpLayoutOptionsCreate ) + pRet = (*ScTpLayoutOptionsCreate) (pParent, rSet); + } + break; + case SID_SC_TP_CONTENT: + { + //CHINA001 pRet = ScTpContentOptions::Create(pParent, rSet); + ::CreateTabPage ScTpContentOptionsCreate = pFact->GetTabPageCreatorFunc(RID_SCPAGE_CONTENT); + if ( ScTpContentOptionsCreate ) + pRet = (*ScTpContentOptionsCreate)(pParent, rSet); + } + break; + case SID_SC_TP_GRID: pRet = SvxGridTabPage::Create(pParent, rSet); break; + case SID_SC_TP_USERLISTS: + { + //CHINA001 pRet = ScTpUserLists::Create(pParent, rSet); + ::CreateTabPage ScTpUserListsCreate = pFact->GetTabPageCreatorFunc( RID_SCPAGE_USERLISTS ); + if ( ScTpUserListsCreate ) + pRet = (*ScTpUserListsCreate)( pParent, rSet); + } + break; + case SID_SC_TP_CALC: + { //CHINA001 pRet = ScTpCalcOptions::Create(pParent, rSet); + ::CreateTabPage ScTpCalcOptionsCreate = pFact->GetTabPageCreatorFunc( RID_SCPAGE_CALC ); + if ( ScTpCalcOptionsCreate ) + pRet = (*ScTpCalcOptionsCreate)(pParent, rSet); + } + break; + case SID_SC_TP_CHANGES: + { //CHINA001 pRet = ScRedlineOptionsTabPage::Create(pParent, rSet); + ::CreateTabPage ScRedlineOptionsTabPageCreate = pFact->GetTabPageCreatorFunc( RID_SCPAGE_OPREDLINE ); + if ( ScRedlineOptionsTabPageCreate ) + pRet =(*ScRedlineOptionsTabPageCreate)(pParent, rSet); + } + break; + case RID_SC_TP_PRINT: + {//CHINA001 pRet = ScTpPrintOptions::Create(pParent, rSet); + ::CreateTabPage ScTpPrintOptionsCreate = pFact->GetTabPageCreatorFunc( RID_SCPAGE_PRINT ); + if ( ScTpPrintOptionsCreate ) + pRet = (*ScTpPrintOptionsCreate)( pParent, rSet); + } + break; + case RID_OFA_TP_INTERNATIONAL: + { + SfxAbstractDialogFactory* pSfxFact = SfxAbstractDialogFactory::Create(); + if ( pSfxFact ) + { + ::CreateTabPage fnCreatePage = pSfxFact->GetTabPageCreatorFunc( nId ); + if ( fnCreatePage ) + pRet = (*fnCreatePage)( pParent, rSet ); + } + } + } + + DBG_ASSERT( pRet, "ScModule::CreateTabPage(): no valid ID for TabPage!" ); + + return pRet; +} + +//------------------------------------------------------------------ + +IMPL_LINK( ScModule, CalcFieldValueHdl, EditFieldInfo*, pInfo ) +{ + //! mit ScFieldEditEngine zusammenfassen !!! + + if (pInfo) + { + const SvxFieldItem& rField = pInfo->GetField(); + const SvxFieldData* pField = rField.GetField(); + + if (pField && pField->ISA(SvxURLField)) + { + /****************************************************************** + * URL-Field + ******************************************************************/ + + const SvxURLField* pURLField = (const SvxURLField*) pField; + String aURL = pURLField->GetURL(); + + switch ( pURLField->GetFormat() ) + { + case SVXURLFORMAT_APPDEFAULT: //!!! einstellbar an App??? + case SVXURLFORMAT_REPR: + { + pInfo->SetRepresentation( pURLField->GetRepresentation() ); + } + break; + + case SVXURLFORMAT_URL: + { + pInfo->SetRepresentation( aURL ); + } + break; + } + + svtools::ColorConfigEntry eEntry = + INetURLHistory::GetOrCreate()->QueryUrl( aURL ) ? svtools::LINKSVISITED : svtools::LINKS; + pInfo->SetTxtColor( GetColorConfig().GetColorValue(eEntry).nColor ); + } + else + { + DBG_ERROR("unbekannter Feldbefehl"); + pInfo->SetRepresentation(String('?')); + } + } + + return 0; +} + + + +//<!--Added by PengYunQuan for Validity Cell Range Picker +BOOL ScModule::RegisterRefWindow( USHORT nSlotId, Window *pWnd ) +{ + std::list<Window*> & rlRefWindow = m_mapRefWindow[nSlotId]; + + if( std::find( rlRefWindow.begin(), rlRefWindow.end(), pWnd ) == rlRefWindow.end() ) + { + rlRefWindow.push_back( pWnd ); + return TRUE; + } + + return FALSE; +} + +BOOL ScModule::UnregisterRefWindow( USHORT nSlotId, Window *pWnd ) +{ + std::map<USHORT, std::list<Window*> >::iterator iSlot = m_mapRefWindow.find( nSlotId ); + + if( iSlot == m_mapRefWindow.end() ) + return FALSE; + + std::list<Window*> & rlRefWindow = iSlot->second; + + std::list<Window*>::iterator i = std::find( rlRefWindow.begin(), rlRefWindow.end(), pWnd ); + + if( i == rlRefWindow.end() ) + return FALSE; + + rlRefWindow.erase( i ); + + if( !rlRefWindow.size() ) + m_mapRefWindow.erase( nSlotId ); + + return TRUE; +} + +BOOL ScModule::IsAliveRefDlg( USHORT nSlotId, Window *pWnd ) +{ + std::map<USHORT, std::list<Window*> >::iterator iSlot = m_mapRefWindow.find( nSlotId ); + + if( iSlot == m_mapRefWindow.end() ) + return FALSE; + + std::list<Window*> & rlRefWindow = iSlot->second; + + return rlRefWindow.end() != std::find( rlRefWindow.begin(), rlRefWindow.end(), pWnd ); +} + +Window * ScModule::Find1RefWindow( USHORT nSlotId, Window *pWndAncestor ) +{ + std::map<USHORT, std::list<Window*> >::iterator iSlot = m_mapRefWindow.find( nSlotId ); + + if( iSlot == m_mapRefWindow.end() ) + return FALSE; + + std::list<Window*> & rlRefWindow = iSlot->second; + + while( Window *pParent = pWndAncestor->GetParent() ) pWndAncestor = pParent; + + for( std::list<Window*>::iterator i = rlRefWindow.begin(); i!=rlRefWindow.end(); i++ ) + if ( pWndAncestor->IsWindowOrChild( *i, (*i)->IsSystemWindow() ) ) + return *i; + + return NULL; +} + +Window * ScModule::Find1RefWindow( Window *pWndAncestor ) +{ + while( Window *pParent = pWndAncestor->GetParent() ) pWndAncestor = pParent; + + for( std::map<USHORT, std::list<Window*> >::iterator i = m_mapRefWindow.begin(); + i!=m_mapRefWindow.end(); i++ ) + for( std::list<Window*>::iterator j = i->second.begin(); j!=i->second.end(); j++ ) + if ( pWndAncestor->IsWindowOrChild( *j, (*j)->IsSystemWindow() ) ) + return *j; + + return NULL; +} +//<!--Added by PengYunQuan for Validity Cell Range Picker diff --git a/sc/source/ui/app/scmod2.cxx b/sc/source/ui/app/scmod2.cxx new file mode 100644 index 000000000000..c92f0bf5d206 --- /dev/null +++ b/sc/source/ui/app/scmod2.cxx @@ -0,0 +1,107 @@ +/************************************************************************* + * + * 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_sc.hxx" + + + +//------------------------------------------------------------------ + +#include <editeng/unolingu.hxx> +#include <unotools/lingucfg.hxx> +#include <i18npool/mslangid.hxx> +#include <com/sun/star/i18n/ScriptType.hpp> +#include <com/sun/star/linguistic2/XThesaurus.hpp> +#include <com/sun/star/lang/Locale.hpp> + +using namespace com::sun::star; + +#include "scmod.hxx" + +//------------------------------------------------------------------ + +#define LINGUPROP_AUTOSPELL "IsSpellAuto" + +//------------------------------------------------------------------ + +// static +void ScModule::GetSpellSettings( USHORT& rDefLang, USHORT& rCjkLang, USHORT& rCtlLang, + BOOL& rAutoSpell ) +{ + // use SvtLinguConfig instead of service LinguProperties to avoid + // loading the linguistic component + SvtLinguConfig aConfig; + + SvtLinguOptions aOptions; + aConfig.GetOptions( aOptions ); + + rDefLang = MsLangId::resolveSystemLanguageByScriptType(aOptions.nDefaultLanguage, ::com::sun::star::i18n::ScriptType::LATIN); + rCjkLang = MsLangId::resolveSystemLanguageByScriptType(aOptions.nDefaultLanguage_CJK, ::com::sun::star::i18n::ScriptType::ASIAN); + rCtlLang = MsLangId::resolveSystemLanguageByScriptType(aOptions.nDefaultLanguage_CTL, ::com::sun::star::i18n::ScriptType::COMPLEX); + rAutoSpell = aOptions.bIsSpellAuto; +} + +// static +void ScModule::SetAutoSpellProperty( BOOL bSet ) +{ + // use SvtLinguConfig instead of service LinguProperties to avoid + // loading the linguistic component + SvtLinguConfig aConfig; + + uno::Any aAny; + aAny <<= bSet; + aConfig.SetProperty( rtl::OUString::createFromAscii( LINGUPROP_AUTOSPELL ), aAny ); +} + + + +// static +BOOL ScModule::HasThesaurusLanguage( USHORT nLang ) +{ + if ( nLang == LANGUAGE_NONE ) + return FALSE; + + lang::Locale aLocale; + SvxLanguageToLocale( aLocale, nLang ); + + BOOL bHasLang = FALSE; + try + { + uno::Reference< linguistic2::XThesaurus > xThes(LinguMgr::GetThesaurus()); + if ( xThes.is() ) + bHasLang = xThes->hasLocale( aLocale ); + } + catch( uno::Exception& ) + { + DBG_ERROR("Error in Thesaurus"); + } + + return bHasLang; +} + + diff --git a/sc/source/ui/app/seltrans.cxx b/sc/source/ui/app/seltrans.cxx new file mode 100644 index 000000000000..0b213709863d --- /dev/null +++ b/sc/source/ui/app/seltrans.cxx @@ -0,0 +1,449 @@ +/************************************************************************* + * + * 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_sc.hxx" + +// INCLUDE --------------------------------------------------------------- + + + +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/beans/XPropertySetInfo.hpp> +#include <com/sun/star/form/FormButtonType.hpp> + +#include <tools/urlobj.hxx> +#include <sfx2/docfile.hxx> +#include <svx/fmglob.hxx> +#include <svx/svdograf.hxx> +#include <svx/svdouno.hxx> + +#include "seltrans.hxx" +#include "transobj.hxx" +#include "drwtrans.hxx" +#include "scmod.hxx" +#include "dbfunc.hxx" // for CopyToClip +#include "docsh.hxx" +#include "drawview.hxx" +#include "drwlayer.hxx" + +using namespace com::sun::star; + +// ----------------------------------------------------------------------- + +BOOL lcl_IsURLButton( SdrObject* pObject ) +{ + BOOL bRet = FALSE; + + SdrUnoObj* pUnoCtrl = PTR_CAST(SdrUnoObj, pObject); + if (pUnoCtrl && FmFormInventor == pUnoCtrl->GetObjInventor()) + { + uno::Reference<awt::XControlModel> xControlModel = pUnoCtrl->GetUnoControlModel(); + DBG_ASSERT( xControlModel.is(), "uno control without model" ); + if ( xControlModel.is() ) + { + uno::Reference< beans::XPropertySet > xPropSet( xControlModel, uno::UNO_QUERY ); + uno::Reference< beans::XPropertySetInfo > xInfo = xPropSet->getPropertySetInfo(); + + rtl::OUString sPropButtonType = rtl::OUString::createFromAscii( "ButtonType" ); + if(xInfo->hasPropertyByName( sPropButtonType )) + { + uno::Any aAny = xPropSet->getPropertyValue( sPropButtonType ); + form::FormButtonType eTmp; + if ( (aAny >>= eTmp) && eTmp == form::FormButtonType_URL ) + bRet = TRUE; + } + } + } + + return bRet; +} + +// static + +ScSelectionTransferObj* ScSelectionTransferObj::CreateFromView( ScTabView* pView ) +{ + ScSelectionTransferObj* pRet = NULL; + + if ( pView ) + { + ScSelectionTransferMode eMode = SC_SELTRANS_INVALID; + + SdrView* pSdrView = pView->GetSdrView(); + if ( pSdrView ) + { + // handle selection on drawing layer + const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList(); + ULONG nMarkCount = rMarkList.GetMarkCount(); + if ( nMarkCount ) + { + if ( nMarkCount == 1 ) + { + SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); + UINT16 nSdrObjKind = pObj->GetObjIdentifier(); + + if ( nSdrObjKind == OBJ_GRAF ) + { + if ( ((SdrGrafObj*)pObj)->GetGraphic().GetType() == GRAPHIC_BITMAP ) + eMode = SC_SELTRANS_DRAW_BITMAP; + else + eMode = SC_SELTRANS_DRAW_GRAPHIC; + } + else if ( nSdrObjKind == OBJ_OLE2 ) + eMode = SC_SELTRANS_DRAW_OLE; + else if ( lcl_IsURLButton( pObj ) ) + eMode = SC_SELTRANS_DRAW_BOOKMARK; + } + + if ( eMode == SC_SELTRANS_INVALID ) + eMode = SC_SELTRANS_DRAW_OTHER; // something selected but no special selection + } + } + if ( eMode == SC_SELTRANS_INVALID ) // no drawing object selected + { + ScRange aRange; + ScViewData* pViewData = pView->GetViewData(); + const ScMarkData& rMark = pViewData->GetMarkData(); + // allow MultiMarked because GetSimpleArea may be able to merge into a simple range + // (GetSimpleArea modifies a local copy of MarkData) + // Also allow simple filtered area. + ScMarkType eMarkType; + if ( ( rMark.IsMarked() || rMark.IsMultiMarked() ) && + (((eMarkType = pViewData->GetSimpleArea( aRange )) == SC_MARK_SIMPLE) || + (eMarkType == SC_MARK_SIMPLE_FILTERED)) ) + { + // only for "real" selection, cursor alone isn't used + if ( aRange.aStart == aRange.aEnd ) + eMode = SC_SELTRANS_CELL; + else + eMode = SC_SELTRANS_CELLS; + } + } + + if ( eMode != SC_SELTRANS_INVALID ) + pRet = new ScSelectionTransferObj( pView, eMode ); + } + + return pRet; +} + + +ScSelectionTransferObj::ScSelectionTransferObj( ScTabView* pSource, ScSelectionTransferMode eNewMode ) : + pView( pSource ), + eMode( eNewMode ), + pCellData( NULL ), + pDrawData( NULL ) +{ + //! store range for StillValid +} + +ScSelectionTransferObj::~ScSelectionTransferObj() +{ + ScModule* pScMod = SC_MOD(); + if ( pScMod->GetSelectionTransfer() == this ) + { + // this is reached when the object wasn't really copied to the selection + // (CopyToSelection has no effect under Windows) + + ForgetView(); + pScMod->SetSelectionTransfer( NULL ); + } + + DBG_ASSERT( !pView, "ScSelectionTransferObj dtor: ForgetView not called" ); +} + +BOOL ScSelectionTransferObj::StillValid() +{ + //! check if view still has same cell selection + //! (but return FALSE if data has changed inbetween) + return FALSE; +} + +void ScSelectionTransferObj::ForgetView() +{ + pView = NULL; + eMode = SC_SELTRANS_INVALID; + + if (pCellData) + { + pCellData->release(); + pCellData = NULL; + } + if (pDrawData) + { + pDrawData->release(); + pDrawData = NULL; + } +} + +void ScSelectionTransferObj::AddSupportedFormats() +{ + // AddSupportedFormats must work without actually creating the + // "real" transfer object + + switch (eMode) + { + case SC_SELTRANS_CELL: + case SC_SELTRANS_CELLS: + // same formats as in ScTransferObj::AddSupportedFormats + AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ); + AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ); + AddFormat( SOT_FORMAT_GDIMETAFILE ); + AddFormat( SOT_FORMAT_BITMAP ); + AddFormat( SOT_FORMATSTR_ID_HTML ); + AddFormat( SOT_FORMATSTR_ID_SYLK ); + AddFormat( SOT_FORMATSTR_ID_LINK ); + AddFormat( SOT_FORMATSTR_ID_DIF ); + AddFormat( SOT_FORMAT_STRING ); + AddFormat( SOT_FORMAT_RTF ); + if ( eMode == SC_SELTRANS_CELL ) + AddFormat( SOT_FORMATSTR_ID_EDITENGINE ); + break; + + // different graphic formats as in ScDrawTransferObj::AddSupportedFormats: + + case SC_SELTRANS_DRAW_BITMAP: + AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ); + AddFormat( SOT_FORMATSTR_ID_SVXB ); + AddFormat( SOT_FORMAT_BITMAP ); + AddFormat( SOT_FORMAT_GDIMETAFILE ); + break; + + case SC_SELTRANS_DRAW_GRAPHIC: + AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ); + AddFormat( SOT_FORMATSTR_ID_SVXB ); + AddFormat( SOT_FORMAT_GDIMETAFILE ); + AddFormat( SOT_FORMAT_BITMAP ); + break; + + case SC_SELTRANS_DRAW_BOOKMARK: + AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ); + AddFormat( SOT_FORMATSTR_ID_SOLK ); + AddFormat( SOT_FORMAT_STRING ); + AddFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ); + AddFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ); + AddFormat( SOT_FORMATSTR_ID_DRAWING ); + break; + + case SC_SELTRANS_DRAW_OLE: + AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ); + AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ); + AddFormat( SOT_FORMAT_GDIMETAFILE ); + break; + + case SC_SELTRANS_DRAW_OTHER: + // other drawing objects + AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ); + AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ); + AddFormat( SOT_FORMATSTR_ID_DRAWING ); + AddFormat( SOT_FORMAT_BITMAP ); + AddFormat( SOT_FORMAT_GDIMETAFILE ); + break; + + default: + { + // added to avoid warnings + } + } +} + +void ScSelectionTransferObj::CreateCellData() +{ + DBG_ASSERT( !pCellData, "CreateCellData twice" ); + if ( pView ) + { + ScViewData* pViewData = pView->GetViewData(); + ScMarkData aNewMark( pViewData->GetMarkData() ); // use local copy for MarkToSimple + aNewMark.MarkToSimple(); + + // similar to ScViewFunctionSet::BeginDrag + if ( aNewMark.IsMarked() && !aNewMark.IsMultiMarked() ) + { + ScDocShell* pDocSh = pViewData->GetDocShell(); + + ScRange aSelRange; + aNewMark.GetMarkArea( aSelRange ); + ScDocShellRef aDragShellRef; + if ( pDocSh->GetDocument()->HasOLEObjectsInArea( aSelRange, &aNewMark ) ) + { + aDragShellRef = new ScDocShell; // DocShell needs a Ref immediately + aDragShellRef->DoInitNew(NULL); + } + ScDrawLayer::SetGlobalDrawPersist(aDragShellRef); + + ScDocument* pClipDoc = new ScDocument( SCDOCMODE_CLIP ); + // bApi = TRUE -> no error mesages + // #i18364# bStopEdit = FALSE -> don't end edit mode + // (this may be called from pasting into the edit line) + BOOL bCopied = pViewData->GetView()->CopyToClip( pClipDoc, FALSE, TRUE, TRUE, FALSE ); + + ScDrawLayer::SetGlobalDrawPersist(NULL); + + if ( bCopied ) + { + TransferableObjectDescriptor aObjDesc; + pDocSh->FillTransferableObjectDescriptor( aObjDesc ); + aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass(); + // maSize is set in ScTransferObj ctor + + ScTransferObj* pTransferObj = new ScTransferObj( pClipDoc, aObjDesc ); + uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj ); + + // SetDragHandlePos is not used - there is no mouse position + //? pTransferObj->SetVisibleTab( nTab ); + + SfxObjectShellRef aPersistRef( aDragShellRef ); + pTransferObj->SetDrawPersist( aPersistRef ); // keep persist for ole objects alive + + pTransferObj->SetDragSource( pDocSh, aNewMark ); + + pCellData = pTransferObj; + pCellData->acquire(); // keep ref count up - released in ForgetView + } + else + delete pClipDoc; + } + } + DBG_ASSERT( pCellData, "can't create CellData" ); +} + +//! make static member of ScDrawView +extern void lcl_CheckOle( const SdrMarkList& rMarkList, BOOL& rAnyOle, BOOL& rOneOle ); + +void ScSelectionTransferObj::CreateDrawData() +{ + DBG_ASSERT( !pDrawData, "CreateDrawData twice" ); + if ( pView ) + { + // similar to ScDrawView::BeginDrag + + ScDrawView* pDrawView = pView->GetScDrawView(); + if ( pDrawView ) + { + BOOL bAnyOle, bOneOle; + const SdrMarkList& rMarkList = pDrawView->GetMarkedObjectList(); + lcl_CheckOle( rMarkList, bAnyOle, bOneOle ); + + //--------------------------------------------------------- + ScDocShellRef aDragShellRef; + if (bAnyOle) + { + aDragShellRef = new ScDocShell; // ohne Ref lebt die DocShell nicht !!! + aDragShellRef->DoInitNew(NULL); + } + //--------------------------------------------------------- + + ScDrawLayer::SetGlobalDrawPersist(aDragShellRef); + SdrModel* pModel = pDrawView->GetAllMarkedModel(); + ScDrawLayer::SetGlobalDrawPersist(NULL); + + ScViewData* pViewData = pView->GetViewData(); + ScDocShell* pDocSh = pViewData->GetDocShell(); + + TransferableObjectDescriptor aObjDesc; + pDocSh->FillTransferableObjectDescriptor( aObjDesc ); + aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass(); + // maSize is set in ScDrawTransferObj ctor + + ScDrawTransferObj* pTransferObj = new ScDrawTransferObj( pModel, pDocSh, aObjDesc ); + uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj ); + + SfxObjectShellRef aPersistRef( aDragShellRef ); + pTransferObj->SetDrawPersist( aPersistRef ); // keep persist for ole objects alive + pTransferObj->SetDragSource( pDrawView ); // copies selection + + pDrawData = pTransferObj; + pDrawData->acquire(); // keep ref count up - released in ForgetView + } + } + DBG_ASSERT( pDrawData, "can't create DrawData" ); +} + +ScTransferObj* ScSelectionTransferObj::GetCellData() +{ + if ( !pCellData && ( eMode == SC_SELTRANS_CELL || eMode == SC_SELTRANS_CELLS ) ) + CreateCellData(); + return pCellData; +} + +ScDrawTransferObj* ScSelectionTransferObj::GetDrawData() +{ + if ( !pDrawData && ( eMode == SC_SELTRANS_DRAW_BITMAP || eMode == SC_SELTRANS_DRAW_GRAPHIC || + eMode == SC_SELTRANS_DRAW_BOOKMARK || eMode == SC_SELTRANS_DRAW_OLE || + eMode == SC_SELTRANS_DRAW_OTHER ) ) + CreateDrawData(); + return pDrawData; +} + +sal_Bool ScSelectionTransferObj::GetData( const ::com::sun::star::datatransfer::DataFlavor& rFlavor ) +{ + sal_Bool bOK = sal_False; + + uno::Reference<datatransfer::XTransferable> xSource; + switch (eMode) + { + case SC_SELTRANS_CELL: + case SC_SELTRANS_CELLS: + xSource = GetCellData(); + break; + case SC_SELTRANS_DRAW_BITMAP: + case SC_SELTRANS_DRAW_GRAPHIC: + case SC_SELTRANS_DRAW_BOOKMARK: + case SC_SELTRANS_DRAW_OLE: + case SC_SELTRANS_DRAW_OTHER: + xSource = GetDrawData(); + break; + default: + { + // added to avoid warnings + } + } + + if ( xSource.is() ) + { + TransferableDataHelper aHelper( xSource ); + uno::Any aAny = aHelper.GetAny( rFlavor ); + bOK = SetAny( aAny, rFlavor ); + } + + return bOK; +} + +void ScSelectionTransferObj::ObjectReleased() +{ + // called when another selection is set from outside + + ForgetView(); + + ScModule* pScMod = SC_MOD(); + if ( pScMod->GetSelectionTransfer() == this ) + pScMod->SetSelectionTransfer( NULL ); + + TransferableHelper::ObjectReleased(); +} + + diff --git a/sc/source/ui/app/template.cxx b/sc/source/ui/app/template.cxx new file mode 100644 index 000000000000..80dc667c5de6 --- /dev/null +++ b/sc/source/ui/app/template.cxx @@ -0,0 +1,79 @@ +/************************************************************************* + * + * 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_sc.hxx" + + + +#include "template.hxx" + +//------------------------------------------------------------------------ + +ScTemplateDlg::ScTemplateDlg(Window * pParent, USHORT nAppResource) : +// SfxTemplateDlg( pParent, nAppResource ) + SfxTemplateDialog( pParent ) +{ +} + +//------------------------------------------------------------------------ + +__EXPORT ScTemplateDlg::~ScTemplateDlg() +{ +} + +//------------------------------------------------------------------------ + +BOOL ScTemplateDlg::New(String &rNewName) +{ + return TRUE; +} + + +void ScTemplateDlg::Edit(const String &) +{ +} + + +BOOL ScTemplateDlg::Delete(const String &) +{ + return TRUE; +} + + +void ScTemplateDlg::InvalidateTemplates() +{ +} + + +void ScTemplateDlg::ToggleApplyTemplate() +{ +} + + + + diff --git a/sc/source/ui/app/transobj.cxx b/sc/source/ui/app/transobj.cxx new file mode 100644 index 000000000000..a5b286e8a9ea --- /dev/null +++ b/sc/source/ui/app/transobj.cxx @@ -0,0 +1,869 @@ +/************************************************************************* + * + * 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_sc.hxx" + +// INCLUDE --------------------------------------------------------------- + + + +#include "scitems.hxx" +#include <editeng/eeitem.hxx> + + +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/embed/XTransactedObject.hpp> + +#include <unotools/tempfile.hxx> +#include <unotools/ucbstreamhelper.hxx> +#include <comphelper/storagehelper.hxx> +#include <sot/storage.hxx> +#include <vcl/svapp.hxx> +#include <vcl/virdev.hxx> +#include <vos/mutex.hxx> +#include <sfx2/app.hxx> +#include <sfx2/docfile.hxx> + +#include "transobj.hxx" +#include "document.hxx" +#include "viewopti.hxx" +#include "editutil.hxx" +#include "impex.hxx" +#include "cell.hxx" +#include "printfun.hxx" +#include "docfunc.hxx" +#include "scmod.hxx" + +// for InitDocShell +#include <editeng/paperinf.hxx> +#include <editeng/sizeitem.hxx> +#include <svx/algitem.hxx> +#include <svl/intitem.hxx> +#include <svl/zforlist.hxx> +#include "docsh.hxx" +#include "markdata.hxx" +#include "stlpool.hxx" +#include "viewdata.hxx" +#include "dociter.hxx" +#include "cellsuno.hxx" + +using namespace com::sun::star; + +// ----------------------------------------------------------------------- + +#define SCTRANS_TYPE_IMPEX 1 +#define SCTRANS_TYPE_EDIT_RTF 2 +#define SCTRANS_TYPE_EDIT_BIN 3 +#define SCTRANS_TYPE_EMBOBJ 4 + +// ----------------------------------------------------------------------- + +// static +void ScTransferObj::GetAreaSize( ScDocument* pDoc, SCTAB nTab1, SCTAB nTab2, SCROW& nRow, SCCOL& nCol ) +{ + SCCOL nMaxCol = 0; + SCROW nMaxRow = 0; + for( SCTAB nTab = nTab1; nTab <= nTab2; nTab++ ) + { + SCCOL nLastCol = 0; + SCROW nLastRow = 0; + // GetPrintArea instead of GetCellArea - include drawing objects + if( pDoc->GetPrintArea( nTab, nLastCol, nLastRow ) ) + { + if( nLastCol > nMaxCol ) + nMaxCol = nLastCol; + if( nLastRow > nMaxRow ) + nMaxRow = nLastRow; + } + } + nRow = nMaxRow; + nCol = nMaxCol; +} + +// static +void ScTransferObj::PaintToDev( OutputDevice* pDev, ScDocument* pDoc, double nPrintFactor, + const ScRange& rBlock, BOOL bMetaFile ) +{ + if (!pDoc) + return; + + Point aPoint; + Rectangle aBound( aPoint, pDev->GetOutputSize() ); //! use size from clip area? + + ScViewData aViewData(NULL,NULL); + aViewData.InitData( pDoc ); + + aViewData.SetTabNo( rBlock.aEnd.Tab() ); + aViewData.SetScreen( rBlock.aStart.Col(), rBlock.aStart.Row(), + rBlock.aEnd.Col(), rBlock.aEnd.Row() ); + + ScPrintFunc::DrawToDev( pDoc, pDev, nPrintFactor, aBound, &aViewData, bMetaFile ); +} + +// ----------------------------------------------------------------------- + +ScTransferObj::ScTransferObj( ScDocument* pClipDoc, const TransferableObjectDescriptor& rDesc ) : + pDoc( pClipDoc ), + aObjDesc( rDesc ), + nDragHandleX( 0 ), + nDragHandleY( 0 ), + nDragSourceFlags( 0 ), + bDragWasInternal( FALSE ), + bUsedForLink( FALSE ) +{ + DBG_ASSERT(pDoc->IsClipboard(), "wrong document"); + + // + // get aBlock from clipboard doc + // + + SCCOL nCol1; + SCROW nRow1; + SCCOL nCol2; + SCROW nRow2; + pDoc->GetClipStart( nCol1, nRow1 ); + pDoc->GetClipArea( nCol2, nRow2, TRUE ); // real source area - include filtered rows + nCol2 = sal::static_int_cast<SCCOL>( nCol2 + nCol1 ); + nRow2 = sal::static_int_cast<SCROW>( nRow2 + nRow1 ); + + SCCOL nDummy; + pDoc->GetClipArea( nDummy, nNonFiltered, FALSE ); + bHasFiltered = (nNonFiltered < (nRow2 - nRow1)); + ++nNonFiltered; // to get count instead of diff + + SCTAB nTab1=0; + SCTAB nTab2=0; + BOOL bFirst = TRUE; + for (SCTAB i=0; i<=MAXTAB; i++) + if (pDoc->HasTable(i)) + { + if (bFirst) + nTab1 = i; + nTab2 = i; + bFirst = FALSE; + } + DBG_ASSERT(!bFirst, "no sheet selected"); + + // only limit to used cells if whole sheet was marked + // (so empty cell areas can be copied) + if ( nCol2>=MAXCOL && nRow2>=MAXROW ) + { + SCROW nMaxRow; + SCCOL nMaxCol; + GetAreaSize( pDoc, nTab1, nTab2, nMaxRow, nMaxCol ); + if( nMaxRow < nRow2 ) + nRow2 = nMaxRow; + if( nMaxCol < nCol2 ) + nCol2 = nMaxCol; + } + + aBlock = ScRange( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 ); + nVisibleTab = nTab1; // valid table as default + + Rectangle aMMRect = pDoc->GetMMRect( nCol1,nRow1, nCol2,nRow2, nTab1 ); + aObjDesc.maSize = aMMRect.GetSize(); + PrepareOLE( aObjDesc ); +} + +ScTransferObj::~ScTransferObj() +{ + Application::GetSolarMutex().acquire(); + + ScModule* pScMod = SC_MOD(); + if ( pScMod->GetClipData().pCellClipboard == this ) + { + DBG_ERROR("ScTransferObj wasn't released"); + pScMod->SetClipObject( NULL, NULL ); + } + if ( pScMod->GetDragData().pCellTransfer == this ) + { + DBG_ERROR("ScTransferObj wasn't released"); + pScMod->ResetDragObject(); + } + + delete pDoc; // ScTransferObj is owner of clipboard document + + aDocShellRef.Clear(); // before releasing the mutex + + aDrawPersistRef.Clear(); // after the model + + Application::GetSolarMutex().release(); +} + +// static +ScTransferObj* ScTransferObj::GetOwnClipboard( Window* pUIWin ) +{ + ScTransferObj* pObj = SC_MOD()->GetClipData().pCellClipboard; + if ( pObj && pUIWin ) + { + // check formats to see if pObj is really in the system clipboard + + // pUIWin is NULL when called from core (IsClipboardSource), + // in that case don't access the system clipboard, because the call + // may be from other clipboard operations (like flushing, #86059#) + + TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pUIWin ) ); + if ( !aDataHelper.HasFormat( SOT_FORMATSTR_ID_DIF ) ) + { +// DBG_ERROR("ScTransferObj wasn't released"); + pObj = NULL; + } + } + return pObj; +} + +void ScTransferObj::AddSupportedFormats() +{ + AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ); + AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ); + AddFormat( SOT_FORMAT_GDIMETAFILE ); + AddFormat( SOT_FORMAT_BITMAP ); + + // ScImportExport formats + AddFormat( SOT_FORMATSTR_ID_HTML ); + AddFormat( SOT_FORMATSTR_ID_SYLK ); + AddFormat( SOT_FORMATSTR_ID_LINK ); + AddFormat( SOT_FORMATSTR_ID_DIF ); + AddFormat( SOT_FORMAT_STRING ); + + AddFormat( SOT_FORMAT_RTF ); + if ( aBlock.aStart == aBlock.aEnd ) + AddFormat( SOT_FORMATSTR_ID_EDITENGINE ); +} + +sal_Bool ScTransferObj::GetData( const datatransfer::DataFlavor& rFlavor ) +{ + sal_uInt32 nFormat = SotExchange::GetFormat( rFlavor ); + sal_Bool bOK = sal_False; + + if( HasFormat( nFormat ) ) + { + if ( nFormat == SOT_FORMATSTR_ID_LINKSRCDESCRIPTOR || nFormat == SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ) + { + bOK = SetTransferableObjectDescriptor( aObjDesc, rFlavor ); + } + else if ( ( nFormat == SOT_FORMAT_RTF || nFormat == SOT_FORMATSTR_ID_EDITENGINE ) && + aBlock.aStart == aBlock.aEnd ) + { + // RTF from a single cell is handled by EditEngine + + SCCOL nCol = aBlock.aStart.Col(); + SCROW nRow = aBlock.aStart.Row(); + SCTAB nTab = aBlock.aStart.Tab(); + + const ScPatternAttr* pPattern = pDoc->GetPattern( nCol, nRow, nTab ); + ScTabEditEngine aEngine( *pPattern, pDoc->GetEditPool() ); + ScBaseCell* pCell = NULL; + pDoc->GetCell( nCol, nRow, nTab, pCell ); + if (pCell) + { + if (pCell->GetCellType() == CELLTYPE_EDIT) + { + const EditTextObject* pObj; + ((ScEditCell*)pCell)->GetData(pObj); + aEngine.SetText( *pObj ); + } + else + { + String aText; + pDoc->GetString( nCol, nRow, nTab, aText ); + aEngine.SetText(aText); + } + } + + bOK = SetObject( &aEngine, + (nFormat == FORMAT_RTF) ? SCTRANS_TYPE_EDIT_RTF : SCTRANS_TYPE_EDIT_BIN, + rFlavor ); + } + else if ( ScImportExport::IsFormatSupported( nFormat ) || nFormat == SOT_FORMAT_RTF ) + { + // if this transfer object was used to create a DDE link, filtered rows + // have to be included for subsequent calls (to be consistent with link data) + if ( nFormat == SOT_FORMATSTR_ID_LINK ) + bUsedForLink = TRUE; + + BOOL bIncludeFiltered = pDoc->IsCutMode() || bUsedForLink; + + ScImportExport aObj( pDoc, aBlock ); + if ( bUsedForLink ) + aObj.SetExportTextOptions( ScExportTextOptions( ScExportTextOptions::ToSpace, ' ', false ) ); + aObj.SetFormulas( pDoc->GetViewOptions().GetOption( VOPT_FORMULAS ) ); + aObj.SetIncludeFiltered( bIncludeFiltered ); + + // DataType depends on format type: + + if ( rFlavor.DataType.equals( ::getCppuType( (const ::rtl::OUString*) 0 ) ) ) + { + rtl::OUString aString; + if ( aObj.ExportString( aString, nFormat ) ) + bOK = SetString( aString, rFlavor ); + } + else if ( rFlavor.DataType.equals( ::getCppuType( (const uno::Sequence< sal_Int8 >*) 0 ) ) ) + { + // SetObject converts a stream into a Int8-Sequence + bOK = SetObject( &aObj, SCTRANS_TYPE_IMPEX, rFlavor ); + } + else + { + DBG_ERROR("unknown DataType"); + } + } + else if ( nFormat == SOT_FORMAT_BITMAP ) + { + Rectangle aMMRect = pDoc->GetMMRect( aBlock.aStart.Col(), aBlock.aStart.Row(), + aBlock.aEnd.Col(), aBlock.aEnd.Row(), + aBlock.aStart.Tab() ); + VirtualDevice aVirtDev; + aVirtDev.SetOutputSizePixel( aVirtDev.LogicToPixel( aMMRect.GetSize(), MAP_100TH_MM ) ); + + PaintToDev( &aVirtDev, pDoc, 1.0, aBlock, FALSE ); + + aVirtDev.SetMapMode( MapMode( MAP_PIXEL ) ); + Bitmap aBmp = aVirtDev.GetBitmap( Point(), aVirtDev.GetOutputSize() ); + bOK = SetBitmap( aBmp, rFlavor ); + } + else if ( nFormat == SOT_FORMAT_GDIMETAFILE ) + { + InitDocShell(); + SfxObjectShell* pEmbObj = aDocShellRef; + + // like SvEmbeddedTransfer::GetData: + + GDIMetaFile aMtf; + VirtualDevice aVDev; + MapMode aMapMode( pEmbObj->GetMapUnit() ); + Rectangle aVisArea( pEmbObj->GetVisArea( ASPECT_CONTENT ) ); + + aVDev.EnableOutput( FALSE ); + aVDev.SetMapMode( aMapMode ); + aMtf.SetPrefSize( aVisArea.GetSize() ); + aMtf.SetPrefMapMode( aMapMode ); + aMtf.Record( &aVDev ); + + pEmbObj->DoDraw( &aVDev, Point(), aVisArea.GetSize(), JobSetup(), ASPECT_CONTENT ); + + aMtf.Stop(); + aMtf.WindStart(); + + bOK = SetGDIMetaFile( aMtf, rFlavor ); + } + else if ( nFormat == SOT_FORMATSTR_ID_EMBED_SOURCE ) + { + //TODO/LATER: differentiate between formats?! + InitDocShell(); // set aDocShellRef + + SfxObjectShell* pEmbObj = aDocShellRef; + bOK = SetObject( pEmbObj, SCTRANS_TYPE_EMBOBJ, rFlavor ); + } + } + return bOK; +} + +sal_Bool ScTransferObj::WriteObject( SotStorageStreamRef& rxOStm, void* pUserObject, sal_uInt32 nUserObjectId, + const datatransfer::DataFlavor& rFlavor ) +{ + // called from SetObject, put data into stream + + sal_Bool bRet = sal_False; + switch (nUserObjectId) + { + case SCTRANS_TYPE_IMPEX: + { + ScImportExport* pImpEx = (ScImportExport*)pUserObject; + + sal_uInt32 nFormat = SotExchange::GetFormat( rFlavor ); + // mba: no BaseURL for data exchange + if ( pImpEx->ExportStream( *rxOStm, String(), nFormat ) ) + bRet = ( rxOStm->GetError() == ERRCODE_NONE ); + } + break; + + case SCTRANS_TYPE_EDIT_RTF: + case SCTRANS_TYPE_EDIT_BIN: + { + ScTabEditEngine* pEngine = (ScTabEditEngine*)pUserObject; + if ( nUserObjectId == SCTRANS_TYPE_EDIT_RTF ) + { + pEngine->Write( *rxOStm, EE_FORMAT_RTF ); + bRet = ( rxOStm->GetError() == ERRCODE_NONE ); + } + else + { + // #107722# can't use Write for EditEngine format because that would + // write old format without support for unicode characters. + // Get the data from the EditEngine's transferable instead. + + USHORT nParCnt = pEngine->GetParagraphCount(); + if ( nParCnt == 0 ) + nParCnt = 1; + ESelection aSel( 0, 0, nParCnt-1, pEngine->GetTextLen(nParCnt-1) ); + + uno::Reference<datatransfer::XTransferable> xEditTrans = pEngine->CreateTransferable( aSel ); + TransferableDataHelper aEditHelper( xEditTrans ); + + bRet = aEditHelper.GetSotStorageStream( rFlavor, rxOStm ); + } + } + break; + + case SCTRANS_TYPE_EMBOBJ: + { + // TODO/MBA: testing + SfxObjectShell* pEmbObj = (SfxObjectShell*) pUserObject; + ::utl::TempFile aTempFile; + aTempFile.EnableKillingFile(); + uno::Reference< embed::XStorage > xWorkStore = + ::comphelper::OStorageHelper::GetStorageFromURL( aTempFile.GetURL(), embed::ElementModes::READWRITE ); + + // write document storage + pEmbObj->SetupStorage( xWorkStore, SOFFICE_FILEFORMAT_CURRENT, sal_False ); + + // mba: no relative ULRs for clipboard! + SfxMedium aMedium( xWorkStore, String() ); + bRet = pEmbObj->DoSaveObjectAs( aMedium, FALSE ); + pEmbObj->DoSaveCompleted(); + + uno::Reference< embed::XTransactedObject > xTransact( xWorkStore, uno::UNO_QUERY ); + if ( xTransact.is() ) + xTransact->commit(); + + SvStream* pSrcStm = ::utl::UcbStreamHelper::CreateStream( aTempFile.GetURL(), STREAM_READ ); + if( pSrcStm ) + { + rxOStm->SetBufferSize( 0xff00 ); + *rxOStm << *pSrcStm; + delete pSrcStm; + } + + bRet = TRUE; + + xWorkStore->dispose(); + xWorkStore = uno::Reference < embed::XStorage >(); + rxOStm->Commit(); + } + break; + + default: + DBG_ERROR("unknown object id"); + } + return bRet; +} + +void ScTransferObj::ObjectReleased() +{ + ScModule* pScMod = SC_MOD(); + if ( pScMod->GetClipData().pCellClipboard == this ) + pScMod->SetClipObject( NULL, NULL ); + + TransferableHelper::ObjectReleased(); +} + +void ScTransferObj::DragFinished( sal_Int8 nDropAction ) +{ + if ( nDropAction == DND_ACTION_MOVE && !bDragWasInternal && !(nDragSourceFlags & SC_DROP_NAVIGATOR) ) + { + // move: delete source data + ScDocShell* pSourceSh = GetSourceDocShell(); + if (pSourceSh) + { + ScMarkData aMarkData = GetSourceMarkData(); + // external drag&drop doesn't copy objects, so they also aren't deleted: + // #105703# bApi=TRUE, don't show error messages from drag&drop + pSourceSh->GetDocFunc().DeleteContents( aMarkData, IDF_ALL & ~IDF_OBJECTS, TRUE, TRUE ); + } + } + + ScModule* pScMod = SC_MOD(); + if ( pScMod->GetDragData().pCellTransfer == this ) + pScMod->ResetDragObject(); + + xDragSourceRanges = NULL; // don't keep source after dropping + + TransferableHelper::DragFinished( nDropAction ); +} + +void ScTransferObj::SetDragHandlePos( SCCOL nX, SCROW nY ) +{ + nDragHandleX = nX; + nDragHandleY = nY; +} + +void ScTransferObj::SetVisibleTab( SCTAB nNew ) +{ + nVisibleTab = nNew; +} + +void ScTransferObj::SetDrawPersist( const SfxObjectShellRef& rRef ) +{ + aDrawPersistRef = rRef; +} + +void ScTransferObj::SetDragSource( ScDocShell* pSourceShell, const ScMarkData& rMark ) +{ + ScRangeList aRanges; + rMark.FillRangeListWithMarks( &aRanges, FALSE ); + xDragSourceRanges = new ScCellRangesObj( pSourceShell, aRanges ); +} + +void ScTransferObj::SetDragSourceFlags( USHORT nFlags ) +{ + nDragSourceFlags = nFlags; +} + +void ScTransferObj::SetDragWasInternal() +{ + bDragWasInternal = TRUE; +} + +ScDocument* ScTransferObj::GetSourceDocument() +{ + ScDocShell* pSourceDocSh = GetSourceDocShell(); + if (pSourceDocSh) + return pSourceDocSh->GetDocument(); + return NULL; +} + +ScDocShell* ScTransferObj::GetSourceDocShell() +{ + ScCellRangesBase* pRangesObj = ScCellRangesBase::getImplementation( xDragSourceRanges ); + if (pRangesObj) + return pRangesObj->GetDocShell(); + + return NULL; // none set +} + +ScMarkData ScTransferObj::GetSourceMarkData() +{ + ScMarkData aMarkData; + ScCellRangesBase* pRangesObj = ScCellRangesBase::getImplementation( xDragSourceRanges ); + if (pRangesObj) + { + const ScRangeList& rRanges = pRangesObj->GetRangeList(); + aMarkData.MarkFromRangeList( rRanges, FALSE ); + } + return aMarkData; +} + +// +// initialize aDocShellRef with a live document from the ClipDoc +// + +void ScTransferObj::InitDocShell() +{ + if ( !aDocShellRef.Is() ) + { + ScDocShell* pDocSh = new ScDocShell; + aDocShellRef = pDocSh; // ref must be there before InitNew + + pDocSh->DoInitNew(NULL); + + ScDocument* pDestDoc = pDocSh->GetDocument(); + ScMarkData aDestMark; + aDestMark.SelectTable( 0, TRUE ); + + pDestDoc->SetDocOptions( pDoc->GetDocOptions() ); // #i42666# + + String aTabName; + pDoc->GetName( aBlock.aStart.Tab(), aTabName ); + pDestDoc->RenameTab( 0, aTabName, FALSE ); // no UpdateRef (empty) + + pDestDoc->CopyStdStylesFrom( pDoc ); + + SCCOL nStartX = aBlock.aStart.Col(); + SCROW nStartY = aBlock.aStart.Row(); + SCCOL nEndX = aBlock.aEnd.Col(); + SCROW nEndY = aBlock.aEnd.Row(); + + // widths / heights + // (must be copied before CopyFromClip, for drawing objects) + + SCCOL nCol; + SCROW nRow; + SCTAB nSrcTab = aBlock.aStart.Tab(); + pDestDoc->SetLayoutRTL(0, pDoc->IsLayoutRTL(nSrcTab)); + for (nCol=nStartX; nCol<=nEndX; nCol++) + if ( pDoc->GetColFlags( nCol, nSrcTab ) & CR_HIDDEN ) + pDestDoc->ShowCol( nCol, 0, FALSE ); + else + pDestDoc->SetColWidth( nCol, 0, pDoc->GetColWidth( nCol, nSrcTab ) ); + + ScBitMaskCompressedArray< SCROW, BYTE> & rDestRowFlags = + pDestDoc->GetRowFlagsArrayModifiable(0); + ScCompressedArrayIterator< SCROW, BYTE> aIter( pDoc->GetRowFlagsArray( + nSrcTab), nStartY, nEndY); + for ( ; aIter; ++aIter ) + { + nRow = aIter.GetPos(); + BYTE nSourceFlags = *aIter; + if ( nSourceFlags & CR_HIDDEN ) + pDestDoc->ShowRow( nRow, 0, FALSE ); + else + { + pDestDoc->SetRowHeight( nRow, 0, pDoc->GetOriginalHeight( nRow, nSrcTab ) ); + + // if height was set manually, that flag has to be copied, too + if ( nSourceFlags & CR_MANUALSIZE ) + rDestRowFlags.OrValue( nRow, CR_MANUALSIZE); + } + } + + if ( pDoc->GetDrawLayer() ) + pDocSh->MakeDrawLayer(); + + // cell range is copied to the original position, but on the first sheet + // -> bCutMode must be set + // pDoc is always a Clipboard-document + + ScRange aDestRange( nStartX,nStartY,0, nEndX,nEndY,0 ); + BOOL bWasCut = pDoc->IsCutMode(); + if (!bWasCut) + pDoc->SetClipArea( aDestRange, TRUE ); // Cut + pDestDoc->CopyFromClip( aDestRange, aDestMark, IDF_ALL, NULL, pDoc, FALSE ); + pDoc->SetClipArea( aDestRange, bWasCut ); + + StripRefs( pDoc, nStartX,nStartY, nEndX,nEndY, pDestDoc, 0,0 ); + + ScRange aMergeRange = aDestRange; + pDestDoc->ExtendMerge( aMergeRange, TRUE ); + + pDoc->CopyDdeLinks( pDestDoc ); // copy values of DDE Links + + // page format (grid etc) and page size (maximum size for ole object) + + Size aPaperSize = SvxPaperInfo::GetPaperSize( PAPER_A4 ); // Twips + ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool(); + String aStyleName = pDoc->GetPageStyle( aBlock.aStart.Tab() ); + SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aStyleName, SFX_STYLE_FAMILY_PAGE ); + if (pStyleSheet) + { + const SfxItemSet& rSourceSet = pStyleSheet->GetItemSet(); + aPaperSize = ((const SvxSizeItem&) rSourceSet.Get(ATTR_PAGE_SIZE)).GetSize(); + + // CopyStyleFrom kopiert SetItems mit richtigem Pool + ScStyleSheetPool* pDestPool = pDestDoc->GetStyleSheetPool(); + pDestPool->CopyStyleFrom( pStylePool, aStyleName, SFX_STYLE_FAMILY_PAGE ); + } + + ScViewData aViewData( pDocSh, NULL ); + aViewData.SetScreen( nStartX,nStartY, nEndX,nEndY ); + aViewData.SetCurX( nStartX ); + aViewData.SetCurY( nStartY ); + + pDestDoc->SetViewOptions( pDoc->GetViewOptions() ); + + // Size + //! get while copying sizes + + long nPosX = 0; + long nPosY = 0; + + for (nCol=0; nCol<nStartX; nCol++) + nPosX += pDestDoc->GetColWidth( nCol, 0 ); + nPosY += pDestDoc->FastGetRowHeight( 0, nStartY-1, 0 ); + nPosX = (long) ( nPosX * HMM_PER_TWIPS ); + nPosY = (long) ( nPosY * HMM_PER_TWIPS ); + + + aPaperSize.Width() *= 2; // limit OLE object to double of page size + aPaperSize.Height() *= 2; + + long nSizeX = 0; + long nSizeY = 0; + for (nCol=nStartX; nCol<=nEndX; nCol++) + { + long nAdd = pDestDoc->GetColWidth( nCol, 0 ); + if ( nSizeX+nAdd > aPaperSize.Width() && nSizeX ) // above limit? + break; + nSizeX += nAdd; + } + for (nRow=nStartY; nRow<=nEndY; nRow++) + { + long nAdd = pDestDoc->FastGetRowHeight( nRow, 0 ); + if ( nSizeY+nAdd > aPaperSize.Height() && nSizeY ) // above limit? + break; + nSizeY += nAdd; + } + nSizeX = (long) ( nSizeX * HMM_PER_TWIPS ); + nSizeY = (long) ( nSizeY * HMM_PER_TWIPS ); + +// pDocSh->SetVisAreaSize( Size(nSizeX,nSizeY) ); + + Rectangle aNewArea( Point(nPosX,nPosY), Size(nSizeX,nSizeY) ); + //TODO/LATER: why twice?! + //pDocSh->SvInPlaceObject::SetVisArea( aNewArea ); + pDocSh->SetVisArea( aNewArea ); + + pDocSh->UpdateOle(&aViewData, TRUE); + + //! SetDocumentModified? + if ( pDestDoc->IsChartListenerCollectionNeedsUpdate() ) + pDestDoc->UpdateChartListenerCollection(); + } +} + +// static +SfxObjectShell* ScTransferObj::SetDrawClipDoc( BOOL bAnyOle ) +{ + // update ScGlobal::pDrawClipDocShellRef + + delete ScGlobal::pDrawClipDocShellRef; + if (bAnyOle) + { + ScGlobal::pDrawClipDocShellRef = + new ScDocShellRef(new ScDocShell(SFX_CREATE_MODE_INTERNAL)); // there must be a ref + (*ScGlobal::pDrawClipDocShellRef)->DoInitNew(NULL); + return *ScGlobal::pDrawClipDocShellRef; + } + else + { + ScGlobal::pDrawClipDocShellRef = NULL; + return NULL; + } +} + +// static +void ScTransferObj::StripRefs( ScDocument* pDoc, + SCCOL nStartX, SCROW nStartY, SCCOL nEndX, SCROW nEndY, + ScDocument* pDestDoc, SCCOL nSubX, SCROW nSubY ) +{ + if (!pDestDoc) + { + pDestDoc = pDoc; + DBG_ASSERT(nSubX==0&&nSubY==0, "can't move within the document"); + } + + // In a clipboard doc the data don't have to be on the first sheet + + SCTAB nSrcTab = 0; + while (nSrcTab<MAXTAB && !pDoc->HasTable(nSrcTab)) + ++nSrcTab; + SCTAB nDestTab = 0; + while (nDestTab<MAXTAB && !pDestDoc->HasTable(nDestTab)) + ++nDestTab; + + if (!pDoc->HasTable(nSrcTab) || !pDestDoc->HasTable(nDestTab)) + { + DBG_ERROR("Sheet not found in ScTransferObj::StripRefs"); + return; + } + + SvNumberFormatter* pFormatter = pDoc->GetFormatTable(); + ScRange aRef; + + ScCellIterator aIter( pDoc, nStartX, nStartY, nSrcTab, nEndX, nEndY, nSrcTab ); + ScBaseCell* pCell = aIter.GetFirst(); + while (pCell) + { + if (pCell->GetCellType() == CELLTYPE_FORMULA) + { + ScFormulaCell* pFCell = (ScFormulaCell*) pCell; + BOOL bOut = FALSE; + ScDetectiveRefIter aRefIter( pFCell ); + while ( !bOut && aRefIter.GetNextRef( aRef ) ) + { + if ( aRef.aStart.Tab() != nSrcTab || aRef.aEnd.Tab() != nSrcTab || + aRef.aStart.Col() < nStartX || aRef.aEnd.Col() > nEndX || + aRef.aStart.Row() < nStartY || aRef.aEnd.Row() > nEndY ) + bOut = TRUE; + } + if (bOut) + { + SCCOL nCol = aIter.GetCol() - nSubX; + SCROW nRow = aIter.GetRow() - nSubY; + + ScBaseCell* pNew = 0; + USHORT nErrCode = pFCell->GetErrCode(); + if (nErrCode) + { + pNew = new ScStringCell( ScGlobal::GetErrorString(nErrCode) ); + if ( ((const SvxHorJustifyItem*) pDestDoc->GetAttr( + nCol,nRow,nDestTab, ATTR_HOR_JUSTIFY))->GetValue() == + SVX_HOR_JUSTIFY_STANDARD ) + pDestDoc->ApplyAttr( nCol,nRow,nDestTab, + SvxHorJustifyItem(SVX_HOR_JUSTIFY_RIGHT, ATTR_HOR_JUSTIFY) ); + } + else if (pFCell->IsValue()) + { + double fVal = pFCell->GetValue(); + pNew = new ScValueCell( fVal ); + } + else + { + String aStr; + pFCell->GetString(aStr); + if ( pFCell->IsMultilineResult() ) + pNew = new ScEditCell( aStr, pDestDoc ); + else + pNew = new ScStringCell( aStr ); + } + pDestDoc->PutCell( nCol,nRow,nDestTab, pNew ); + + // number formats + + ULONG nOldFormat = ((const SfxUInt32Item*) + pDestDoc->GetAttr(nCol,nRow,nDestTab, ATTR_VALUE_FORMAT))->GetValue(); + if ( (nOldFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0 ) + { + ULONG nNewFormat = pFCell->GetStandardFormat( *pFormatter, + nOldFormat ); + pDestDoc->ApplyAttr( nCol,nRow,nDestTab, + SfxUInt32Item(ATTR_VALUE_FORMAT, nNewFormat) ); + } + } + } + pCell = aIter.GetNext(); + } +} + +const com::sun::star::uno::Sequence< sal_Int8 >& ScTransferObj::getUnoTunnelId() +{ + static com::sun::star::uno::Sequence< sal_Int8 > aSeq; + if( !aSeq.getLength() ) + { + static osl::Mutex aCreateMutex; + osl::Guard< osl::Mutex > aGuard( aCreateMutex ); + aSeq.realloc( 16 ); + rtl_createUuid( reinterpret_cast< sal_uInt8* >( aSeq.getArray() ), 0, sal_True ); + } + return aSeq; +} + +sal_Int64 SAL_CALL ScTransferObj::getSomething( const com::sun::star::uno::Sequence< sal_Int8 >& rId ) throw( com::sun::star::uno::RuntimeException ) +{ + sal_Int64 nRet; + if( ( rId.getLength() == 16 ) && + ( 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), rId.getConstArray(), 16 ) ) ) + { + nRet = reinterpret_cast< sal_Int64 >( this ); + } + else + nRet = TransferableHelper::getSomething(rId); + return nRet; +} + + diff --git a/sc/source/ui/app/typemap.cxx b/sc/source/ui/app/typemap.cxx new file mode 100644 index 000000000000..4450c00db807 --- /dev/null +++ b/sc/source/ui/app/typemap.cxx @@ -0,0 +1,135 @@ +/************************************************************************* + * + * 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_sc.hxx" + + +#include <svx/svxids.hrc> +#include "sc.hrc" +#include "scitems.hxx" +#include <editeng/memberids.hrc> + + +#define ITEMID_DBTYPE 0 + + + + + + + + + + + + + + + + + + + + + + + + +#include <sfx2/msg.hxx> +#include <svl/stritem.hxx> +#include <svl/slstitm.hxx> +#include <sfx2/objitem.hxx> +#include <editeng/fontitem.hxx> +#include <svx/hlnkitem.hxx> +#include <svl/srchitem.hxx> +#include <svx/postattr.hxx> +#include <editeng/postitem.hxx> +#include <sfx2/tplpitem.hxx> +#include <svx/zoomitem.hxx> +#include <editeng/brshitem.hxx> +#include <editeng/wghtitem.hxx> +#include <editeng/fhgtitem.hxx> +#include <editeng/colritem.hxx> +#include <editeng/boxitem.hxx> +#include <editeng/bolnitem.hxx> +#include <svl/ptitem.hxx> +#include <editeng/sizeitem.hxx> +#include <svx/algitem.hxx> +#include <svx/clipfmtitem.hxx> +#include <editeng/udlnitem.hxx> +#include <svx/xlnstit.hxx> +#include <svx/xlnedit.hxx> +#include <svx/xfillit0.hxx> +#include <svx/xflclit.hxx> +#include <svx/xgrad.hxx> +#include <svx/xflgrit.hxx> +#include <svx/xflhtit.hxx> +#include <svx/xbtmpit.hxx> +#include <svx/xlineit0.hxx> +#include <svx/xlndsit.hxx> +#include <svx/xlnwtit.hxx> +#include <svx/xlnclit.hxx> +#include <svx/xtextit0.hxx> +#include <svx/xftadit.hxx> +#include <svx/xftdiit.hxx> +#include <svx/xftstit.hxx> +#include <svx/xftmrit.hxx> +#include <svx/xftouit.hxx> +#include <svx/xftshit.hxx> +#include <svx/xftshcit.hxx> +#include <svx/xftshxy.hxx> +#include <svx/xftsfit.hxx> +#include <editeng/langitem.hxx> +#include <svx/grafctrl.hxx> +#include <editeng/shdditem.hxx> +#include <editeng/shaditem.hxx> +#include <editeng/cntritem.hxx> +#include <editeng/crsditem.hxx> +#include <editeng/brkitem.hxx> +#include <editeng/charreliefitem.hxx> +#include <svx/rotmodit.hxx> +#include <svx/drawitem.hxx> +#include <svl/ilstitem.hxx> +#include <svl/globalnameitem.hxx> +#include <svx/chrtitem.hxx> +#include <svx/zoomslideritem.hxx> + +// #i25616# +#include <svx/sdshitm.hxx> + +#include <svl/aeitem.hxx> +#include <avmedia/mediaitem.hxx> +#include "attrib.hxx" + +#define SvxDrawToolItem SfxAllEnumItem +#define SvxDrawAlignItem SfxAllEnumItem +#define SvxChooseControlItem SfxEnumItem +#define avmedia_MediaItem ::avmedia::MediaItem + +#define SFX_TYPEMAP +#include "scslots.hxx" diff --git a/sc/source/ui/app/uiitems.cxx b/sc/source/ui/app/uiitems.cxx new file mode 100644 index 000000000000..a63491f0929b --- /dev/null +++ b/sc/source/ui/app/uiitems.cxx @@ -0,0 +1,737 @@ +/************************************************************************* + * + * 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_sc.hxx" + + + +#include <editeng/editobj.hxx> + +#include "userlist.hxx" +#include "uiitems.hxx" +#include "dpsave.hxx" + +// STATIC DATA ----------------------------------------------------------- + +TYPEINIT1(ScInputStatusItem, SfxPoolItem); +TYPEINIT1(ScSortItem, SfxPoolItem); +TYPEINIT1(ScQueryItem, SfxPoolItem); +TYPEINIT1(ScSubTotalItem, SfxPoolItem); +TYPEINIT1(ScUserListItem, SfxPoolItem); +TYPEINIT1(ScConsolidateItem, SfxPoolItem); +TYPEINIT1(ScPivotItem, SfxPoolItem); +TYPEINIT1(ScSolveItem, SfxPoolItem); +TYPEINIT1(ScTabOpItem, SfxPoolItem); +TYPEINIT1(ScCondFrmtItem, SfxPoolItem); + +TYPEINIT1(ScTablesHint, SfxHint); +TYPEINIT1(ScEditViewHint, SfxHint); +TYPEINIT1(ScIndexHint, SfxHint); + +// ----------------------------------------------------------------------- +// ScInputStatusItem - Status-Update fuer Eingabezeile +// ----------------------------------------------------------------------- + +//UNUSED2008-05 ScInputStatusItem::ScInputStatusItem( USHORT nWhichP, +//UNUSED2008-05 SCTAB nTab, +//UNUSED2008-05 SCCOL nCol, SCROW nRow, +//UNUSED2008-05 SCCOL nStartCol, SCROW nStartRow, +//UNUSED2008-05 SCCOL nEndCol, SCROW nEndRow, +//UNUSED2008-05 const String& rString, const EditTextObject* pData ) +//UNUSED2008-05 +//UNUSED2008-05 : SfxPoolItem ( nWhichP ), +//UNUSED2008-05 aCursorPos ( nCol, nRow, nTab ), +//UNUSED2008-05 aStartPos ( nStartCol, nStartRow, nTab ), +//UNUSED2008-05 aEndPos ( nEndCol, nEndRow, nTab ), +//UNUSED2008-05 aString ( rString ), +//UNUSED2008-05 pEditData ( pData ? pData->Clone() : NULL ) +//UNUSED2008-05 { +//UNUSED2008-05 } + +ScInputStatusItem::ScInputStatusItem( USHORT nWhichP, + const ScAddress& rCurPos, + const ScAddress& rStartPos, + const ScAddress& rEndPos, + const String& rString, + const EditTextObject* pData ) + : SfxPoolItem ( nWhichP ), + aCursorPos ( rCurPos ), + aStartPos ( rStartPos ), + aEndPos ( rEndPos ), + aString ( rString ), + pEditData ( pData ? pData->Clone() : NULL ) +{ +} + +ScInputStatusItem::ScInputStatusItem( const ScInputStatusItem& rItem ) + : SfxPoolItem ( rItem ), + aCursorPos ( rItem.aCursorPos ), + aStartPos ( rItem.aStartPos ), + aEndPos ( rItem.aEndPos ), + aString ( rItem.aString ), + pEditData ( rItem.pEditData ? rItem.pEditData->Clone() : NULL ) +{ +} + +__EXPORT ScInputStatusItem::~ScInputStatusItem() +{ + delete pEditData; +} + +String __EXPORT ScInputStatusItem::GetValueText() const +{ + return String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("InputStatus")); +} + +int __EXPORT ScInputStatusItem::operator==( const SfxPoolItem& rItem ) const +{ + DBG_ASSERT( SfxPoolItem::operator==( rItem ), "unequal Which or Type" ); + + return ( (aStartPos == ((ScInputStatusItem&)rItem).aStartPos) + && (aEndPos == ((ScInputStatusItem&)rItem).aEndPos) + && (aCursorPos == ((ScInputStatusItem&)rItem).aCursorPos) + && (aString == ((ScInputStatusItem&)rItem).aString) ); + //! Edit-Daten vergleichen! +} + +SfxPoolItem* __EXPORT ScInputStatusItem::Clone( SfxItemPool * ) const +{ + return new ScInputStatusItem( *this ); +} + +// +// ScPaintHint ist nach schints.cxx verschoben +// + +// ----------------------------------------------------------------------- +// ScTablesHint - Views anpassen, wenn Tabellen eingefuegt / geloescht +// ----------------------------------------------------------------------- + +ScTablesHint::ScTablesHint(USHORT nNewId, SCTAB nTable1, SCTAB nTable2) : + nId( nNewId ), + nTab1( nTable1 ), + nTab2( nTable2 ) +{ +} + +ScTablesHint::~ScTablesHint() +{ +} + + +// ----------------------------------------------------------------------- +// ScIndexHint +// ----------------------------------------------------------------------- + +ScIndexHint::ScIndexHint(USHORT nNewId, USHORT nIdx) : + nId( nNewId ), + nIndex( nIdx ) +{ +} + +ScIndexHint::~ScIndexHint() +{ +} + + +// ----------------------------------------------------------------------- +// ScEditViewHint - neue EditView fuer Cursorposition anlegen +// ----------------------------------------------------------------------- + +ScEditViewHint::ScEditViewHint( ScEditEngineDefaulter* pEngine, const ScAddress& rCurPos ) : + pEditEngine( pEngine ), + aCursorPos( rCurPos ) +{ +} + +ScEditViewHint::~ScEditViewHint() +{ +} + +// ----------------------------------------------------------------------- +// ScSortItem - Daten fuer den Sortierdialog +// ----------------------------------------------------------------------- + +ScSortItem::ScSortItem( USHORT nWhichP, + ScViewData* ptrViewData, + const ScSortParam* pSortData ) : + SfxPoolItem ( nWhichP ), + pViewData ( ptrViewData ) +{ + if ( pSortData ) theSortData = *pSortData; +} + +//------------------------------------------------------------------------ + +ScSortItem::ScSortItem( USHORT nWhichP, + const ScSortParam* pSortData ) : + SfxPoolItem ( nWhichP ), + pViewData ( NULL ) +{ + if ( pSortData ) theSortData = *pSortData; +} + +//------------------------------------------------------------------------ + +ScSortItem::ScSortItem( const ScSortItem& rItem ) : + SfxPoolItem ( rItem ), + pViewData ( rItem.pViewData ), + theSortData ( rItem.theSortData ) +{ +} + +__EXPORT ScSortItem::~ScSortItem() +{ +} + +//------------------------------------------------------------------------ + +String __EXPORT ScSortItem::GetValueText() const +{ + return String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("SortItem")); +} + +//------------------------------------------------------------------------ + +int __EXPORT ScSortItem::operator==( const SfxPoolItem& rItem ) const +{ + DBG_ASSERT( SfxPoolItem::operator==( rItem ), "unequal Which or Type" ); + + const ScSortItem& rOther = (const ScSortItem&)rItem; + + return ( (pViewData == rOther.pViewData) + && (theSortData == rOther.theSortData) ); +} + +//------------------------------------------------------------------------ + +SfxPoolItem* __EXPORT ScSortItem::Clone( SfxItemPool * ) const +{ + return new ScSortItem( *this ); +} + +//------------------------------------------------------------------------ + +sal_Bool ScSortItem::QueryValue( com::sun::star::uno::Any& rVal, BYTE /* nMemberUd */ ) const +{ + // Return empty value as there is no useful conversion + rVal = com::sun::star::uno::Any(); + return sal_True; +} + +// ----------------------------------------------------------------------- +// ScQueryItem - Daten fuer den Filterdialog +// ----------------------------------------------------------------------- + +ScQueryItem::ScQueryItem( USHORT nWhichP, + ScViewData* ptrViewData, + const ScQueryParam* pQueryData ) : + SfxPoolItem ( nWhichP ), + pViewData ( ptrViewData ), + bIsAdvanced ( FALSE ) +{ + if ( pQueryData ) theQueryData = *pQueryData; +} + +//------------------------------------------------------------------------ + +ScQueryItem::ScQueryItem( USHORT nWhichP, + const ScQueryParam* pQueryData ) : + SfxPoolItem ( nWhichP ), + pViewData ( NULL ), + bIsAdvanced ( FALSE ) +{ + if ( pQueryData ) theQueryData = *pQueryData; +} + +//------------------------------------------------------------------------ + +ScQueryItem::ScQueryItem( const ScQueryItem& rItem ) : + SfxPoolItem ( rItem ), + pViewData ( rItem.pViewData ), + theQueryData( rItem.theQueryData ), + bIsAdvanced ( rItem.bIsAdvanced ), + aAdvSource ( rItem.aAdvSource ) +{ +} + +__EXPORT ScQueryItem::~ScQueryItem() +{ +} + +//------------------------------------------------------------------------ + +void ScQueryItem::SetAdvancedQuerySource(const ScRange* pSource) +{ + if (pSource) + { + aAdvSource = *pSource; + bIsAdvanced = TRUE; + } + else + bIsAdvanced = FALSE; +} + +BOOL ScQueryItem::GetAdvancedQuerySource(ScRange& rSource) const +{ + rSource = aAdvSource; + return bIsAdvanced; +} + +//------------------------------------------------------------------------ + +String __EXPORT ScQueryItem::GetValueText() const +{ + return String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("QueryItem")); +} + +//------------------------------------------------------------------------ + +int __EXPORT ScQueryItem::operator==( const SfxPoolItem& rItem ) const +{ + DBG_ASSERT( SfxPoolItem::operator==( rItem ), "unequal Which or Type" ); + + const ScQueryItem& rQueryItem = (const ScQueryItem&)rItem; + + return ( (pViewData == rQueryItem.pViewData) + && (bIsAdvanced == rQueryItem.bIsAdvanced) + && (aAdvSource == rQueryItem.aAdvSource) + && (theQueryData == rQueryItem.theQueryData) ); +} + +//------------------------------------------------------------------------ + +SfxPoolItem* __EXPORT ScQueryItem::Clone( SfxItemPool * ) const +{ + return new ScQueryItem( *this ); +} + +// ----------------------------------------------------------------------- +// ScSubTotalItem - Daten fuer den Zwischenergebnisdialog +// ----------------------------------------------------------------------- + +ScSubTotalItem::ScSubTotalItem( USHORT nWhichP, + ScViewData* ptrViewData, + const ScSubTotalParam* pSubTotalData ) : + SfxPoolItem ( nWhichP ), + pViewData ( ptrViewData ) +{ + if ( pSubTotalData ) theSubTotalData = *pSubTotalData; +} + +//------------------------------------------------------------------------ + +ScSubTotalItem::ScSubTotalItem( USHORT nWhichP, + const ScSubTotalParam* pSubTotalData ) : + SfxPoolItem ( nWhichP ), + pViewData ( NULL ) +{ + if ( pSubTotalData ) theSubTotalData = *pSubTotalData; +} + +//------------------------------------------------------------------------ + +ScSubTotalItem::ScSubTotalItem( const ScSubTotalItem& rItem ) : + SfxPoolItem ( rItem ), + pViewData ( rItem.pViewData ), + theSubTotalData ( rItem.theSubTotalData ) +{ +} + +__EXPORT ScSubTotalItem::~ScSubTotalItem() +{ +} + +//------------------------------------------------------------------------ + +String __EXPORT ScSubTotalItem::GetValueText() const +{ + return String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("SubTotalItem")); +} + +//------------------------------------------------------------------------ + +int __EXPORT ScSubTotalItem::operator==( const SfxPoolItem& rItem ) const +{ + DBG_ASSERT( SfxPoolItem::operator==( rItem ), "unequal Which or Type" ); + + const ScSubTotalItem& rSTItem = (const ScSubTotalItem&)rItem; + + return ( (pViewData == rSTItem.pViewData) + && (theSubTotalData == rSTItem.theSubTotalData) ); +} + +//------------------------------------------------------------------------ + +SfxPoolItem* __EXPORT ScSubTotalItem::Clone( SfxItemPool * ) const +{ + return new ScSubTotalItem( *this ); +} + +//------------------------------------------------------------------------ + +sal_Bool ScSubTotalItem::QueryValue( com::sun::star::uno::Any& rVal, BYTE /* nMemberUd */ ) const +{ + // Return empty value as there is no useful conversion + rVal = com::sun::star::uno::Any(); + return sal_True; +} + +// ----------------------------------------------------------------------- +// ScUserListItem - Transporter fuer den Benutzerlisten-TabPage +// ----------------------------------------------------------------------- + +ScUserListItem::ScUserListItem( USHORT nWhichP ) + : SfxPoolItem ( nWhichP ), + pUserList ( NULL ) +{ +} + +//------------------------------------------------------------------------ + +ScUserListItem::ScUserListItem( const ScUserListItem& rItem ) + : SfxPoolItem ( rItem ) +{ + if ( rItem.pUserList ) + pUserList = new ScUserList( *(rItem.pUserList) ); + else + pUserList = NULL; +} + +__EXPORT ScUserListItem::~ScUserListItem() +{ + delete pUserList; +} + +//------------------------------------------------------------------------ + +String __EXPORT ScUserListItem::GetValueText() const +{ + return String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("ScUserListItem")); +} + +//------------------------------------------------------------------------ + +int __EXPORT ScUserListItem::operator==( const SfxPoolItem& rItem ) const +{ + DBG_ASSERT( SfxPoolItem::operator==( rItem ), "unequal Which or Type" ); + + const ScUserListItem& r = (const ScUserListItem&)rItem; + BOOL bEqual = FALSE; + + if ( !pUserList || !(r.pUserList) ) + bEqual = ( !pUserList && !(r.pUserList) ); + else + bEqual = ( *pUserList == *(r.pUserList) ); + + return bEqual; +} + + +//------------------------------------------------------------------------ + +SfxPoolItem* __EXPORT ScUserListItem::Clone( SfxItemPool * ) const +{ + return new ScUserListItem( *this ); +} + +//------------------------------------------------------------------------ + +void ScUserListItem::SetUserList( const ScUserList& rUserList ) +{ + delete pUserList; + pUserList = new ScUserList( rUserList ); +} + +// ----------------------------------------------------------------------- +// ScConsolidateItem - Daten fuer den Konsolidieren-Dialog +// ----------------------------------------------------------------------- + +ScConsolidateItem::ScConsolidateItem( + USHORT nWhichP, + const ScConsolidateParam* pConsolidateData ) : + SfxPoolItem ( nWhichP ) +{ + if ( pConsolidateData ) theConsData = *pConsolidateData; +} + +//------------------------------------------------------------------------ + +ScConsolidateItem::ScConsolidateItem( const ScConsolidateItem& rItem ) : + SfxPoolItem ( rItem ), + theConsData ( rItem.theConsData ) +{ +} + +//------------------------------------------------------------------------ + +__EXPORT ScConsolidateItem::~ScConsolidateItem() +{ +} + +//------------------------------------------------------------------------ + +String __EXPORT ScConsolidateItem::GetValueText() const +{ + return String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("ScConsolidateItem")); +} + +//------------------------------------------------------------------------ + +int __EXPORT ScConsolidateItem::operator==( const SfxPoolItem& rItem ) const +{ + DBG_ASSERT( SfxPoolItem::operator==( rItem ), "unequal Which or Type" ); + + const ScConsolidateItem& rCItem = (const ScConsolidateItem&)rItem; + + return ( theConsData == rCItem.theConsData); +} + +//------------------------------------------------------------------------ + +SfxPoolItem* __EXPORT ScConsolidateItem::Clone( SfxItemPool * ) const +{ + return new ScConsolidateItem( *this ); +} + + +// ----------------------------------------------------------------------- +// ScPivotItem - Daten fuer den Pivot-Dialog +// ----------------------------------------------------------------------- + +ScPivotItem::ScPivotItem( USHORT nWhichP, const ScDPSaveData* pData, + const ScRange* pRange, BOOL bNew ) : + SfxPoolItem ( nWhichP ) +{ + // pSaveData must always exist + if ( pData ) + pSaveData = new ScDPSaveData(*pData); + else + pSaveData = new ScDPSaveData; + if ( pRange ) aDestRange = *pRange; + bNewSheet = bNew; +} + +//------------------------------------------------------------------------ + +ScPivotItem::ScPivotItem( const ScPivotItem& rItem ) : + SfxPoolItem ( rItem ), + aDestRange ( rItem.aDestRange ), + bNewSheet ( rItem.bNewSheet ) +{ + DBG_ASSERT(rItem.pSaveData, "pSaveData"); + pSaveData = new ScDPSaveData(*rItem.pSaveData); +} + +//------------------------------------------------------------------------ + +__EXPORT ScPivotItem::~ScPivotItem() +{ + delete pSaveData; +} + +//------------------------------------------------------------------------ + +String __EXPORT ScPivotItem::GetValueText() const +{ + return String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("ScPivotItem")); +} + +//------------------------------------------------------------------------ + +int __EXPORT ScPivotItem::operator==( const SfxPoolItem& rItem ) const +{ + DBG_ASSERT( SfxPoolItem::operator==( rItem ), "unequal Which or Type" ); + + const ScPivotItem& rPItem = (const ScPivotItem&)rItem; + DBG_ASSERT( pSaveData && rPItem.pSaveData, "pSaveData" ); + return ( *pSaveData == *rPItem.pSaveData && + aDestRange == rPItem.aDestRange && + bNewSheet == rPItem.bNewSheet ); +} + +//------------------------------------------------------------------------ + +SfxPoolItem* __EXPORT ScPivotItem::Clone( SfxItemPool * ) const +{ + return new ScPivotItem( *this ); +} + + +// ----------------------------------------------------------------------- +// ScSolveItem - Daten fuer den Solver-Dialog +// ----------------------------------------------------------------------- + +ScSolveItem::ScSolveItem( USHORT nWhichP, + const ScSolveParam* pSolveData ) + : SfxPoolItem ( nWhichP ) +{ + if ( pSolveData ) theSolveData = *pSolveData; +} + +//------------------------------------------------------------------------ + +ScSolveItem::ScSolveItem( const ScSolveItem& rItem ) + : SfxPoolItem ( rItem ), + theSolveData ( rItem.theSolveData ) +{ +} + +//------------------------------------------------------------------------ + +__EXPORT ScSolveItem::~ScSolveItem() +{ +} + +//------------------------------------------------------------------------ + +String __EXPORT ScSolveItem::GetValueText() const +{ + return String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("ScSolveItem")); +} + +//------------------------------------------------------------------------ + +int __EXPORT ScSolveItem::operator==( const SfxPoolItem& rItem ) const +{ + DBG_ASSERT( SfxPoolItem::operator==( rItem ), "unequal Which or Type" ); + + const ScSolveItem& rPItem = (const ScSolveItem&)rItem; + + return ( theSolveData == rPItem.theSolveData ); +} + +//------------------------------------------------------------------------ + +SfxPoolItem* __EXPORT ScSolveItem::Clone( SfxItemPool * ) const +{ + return new ScSolveItem( *this ); +} + +// ----------------------------------------------------------------------- +// ScTabOpItem - Daten fuer den TabOp-Dialog +// ----------------------------------------------------------------------- + +ScTabOpItem::ScTabOpItem( USHORT nWhichP, + const ScTabOpParam* pTabOpData ) + : SfxPoolItem ( nWhichP ) +{ + if ( pTabOpData ) theTabOpData = *pTabOpData; +} + +//------------------------------------------------------------------------ + +ScTabOpItem::ScTabOpItem( const ScTabOpItem& rItem ) + : SfxPoolItem ( rItem ), + theTabOpData ( rItem.theTabOpData ) +{ +} + +//------------------------------------------------------------------------ + +__EXPORT ScTabOpItem::~ScTabOpItem() +{ +} + +//------------------------------------------------------------------------ + +String __EXPORT ScTabOpItem::GetValueText() const +{ + return String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("ScTabOpItem")); +} + +//------------------------------------------------------------------------ + +int __EXPORT ScTabOpItem::operator==( const SfxPoolItem& rItem ) const +{ + DBG_ASSERT( SfxPoolItem::operator==( rItem ), "unequal Which or Type" ); + + const ScTabOpItem& rPItem = (const ScTabOpItem&)rItem; + + return ( theTabOpData == rPItem.theTabOpData ); +} + +//------------------------------------------------------------------------ + +SfxPoolItem* __EXPORT ScTabOpItem::Clone( SfxItemPool * ) const +{ + return new ScTabOpItem( *this ); +} + + +// ----------------------------------------------------------------------- +// ScCondFrmtItem - Daten fuer den Dialog bedingte Formatierung +// ----------------------------------------------------------------------- + +ScCondFrmtItem::ScCondFrmtItem( USHORT nWhichP, +//! const ScConditionalFormat* pCondFrmt ) + const ScConditionalFormat& rCondFrmt ) + : SfxPoolItem ( nWhichP ), + theCondFrmtData ( rCondFrmt ) //! +{ +//! if ( pCondFrmt ) theCondFrmtData = *pCondFrmt; +} + +//------------------------------------------------------------------------ + +ScCondFrmtItem::ScCondFrmtItem( const ScCondFrmtItem& rItem ) + : SfxPoolItem ( rItem ), + theCondFrmtData ( rItem.theCondFrmtData ) +{ +} + +//------------------------------------------------------------------------ + +__EXPORT ScCondFrmtItem::~ScCondFrmtItem() +{ +} + +//------------------------------------------------------------------------ + +String __EXPORT ScCondFrmtItem::GetValueText() const +{ + return String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("ScCondFrmtItem")); +} + +//------------------------------------------------------------------------ + +int __EXPORT ScCondFrmtItem::operator==( const SfxPoolItem& rItem ) const +{ + DBG_ASSERT( SfxPoolItem::operator==( rItem ), "unequal Which or Type" ); + + const ScCondFrmtItem& rPItem = (const ScCondFrmtItem&)rItem; + + return ( theCondFrmtData == rPItem.theCondFrmtData ); +} + +//------------------------------------------------------------------------ + +SfxPoolItem* __EXPORT ScCondFrmtItem::Clone( SfxItemPool * ) const +{ + return new ScCondFrmtItem( *this ); +} diff --git a/sc/source/ui/app/wtcdummy.cxx b/sc/source/ui/app/wtcdummy.cxx new file mode 100644 index 000000000000..a755830cbd71 --- /dev/null +++ b/sc/source/ui/app/wtcdummy.cxx @@ -0,0 +1,65 @@ +/************************************************************************* + * + * 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_sc.hxx" + +#include <tlgen.hxx> + +class SdbColumns +{ + public: + SdbColumns(); + ~SdbColumns(); +}; + +SdbColumns::SdbColumns() +{ + DBG_ERROR("WATCOM Hack failed !"); +} + +SdbColumns::~SdbColumns() +{ + DBG_ERROR("WATCOM Hack failed !"); +} + +class SdbRow +{ + public: + SdbRow(); + ~SdbRow(); +}; + +SdbRow::SdbRow() +{ + DBG_ERROR("WATCOM Hack failed !"); +} + +SdbRow::~SdbRow() +{ + DBG_ERROR("WATCOM Hack failed !"); +} |