| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_sc.hxx" |
| #include <com/sun/star/embed/NoVisualAreaSizeException.hpp> |
| #include <com/sun/star/chart2/data/XDataReceiver.hpp> |
| |
| |
| |
| //------------------------------------------------------------------ |
| |
| #ifdef _MSC_VER |
| #pragma optimize ("", off) |
| #endif |
| |
| // INCLUDE --------------------------------------------------------------- |
| |
| #include <com/sun/star/embed/EmbedMisc.hpp> |
| #include <com/sun/star/embed/EmbedStates.hpp> |
| #include <sfx2/app.hxx> |
| #include <toolkit/helper/vclunohelper.hxx> |
| #include <svx/svxdlg.hxx> |
| #include <svx/dataaccessdescriptor.hxx> |
| #include <svx/pfiledlg.hxx> |
| #include <svx/svditer.hxx> |
| #include <svx/svdmark.hxx> |
| #include <svx/svdograf.hxx> |
| #include <svx/svdogrp.hxx> |
| #include <svx/svdoole2.hxx> |
| #include <svx/svdouno.hxx> |
| #include <svx/svdview.hxx> |
| #include <sfx2/linkmgr.hxx> |
| #include <svx/fontworkbar.hxx> |
| #include <sfx2/bindings.hxx> |
| #include <sfx2/dispatch.hxx> |
| #include <sfx2/viewfrm.hxx> |
| #include <svtools/soerr.hxx> |
| #include <svl/rectitem.hxx> |
| #include <svl/slstitm.hxx> |
| #include <svl/whiter.hxx> |
| #include <unotools/moduleoptions.hxx> |
| #include <sot/exchange.hxx> |
| #include <tools/diagnose_ex.h> |
| |
| #include "tabvwsh.hxx" |
| #include "globstr.hrc" |
| #include "scmod.hxx" |
| #include "document.hxx" |
| #include "sc.hrc" |
| #include "client.hxx" |
| #include "fuinsert.hxx" |
| #include "docsh.hxx" |
| #include "chartarr.hxx" |
| #include "drawview.hxx" |
| #include "ChartRangeSelectionListener.hxx" |
| |
| using namespace com::sun::star; |
| |
| // STATIC DATA ----------------------------------------------------------- |
| |
| void ScTabViewShell::ConnectObject( SdrOle2Obj* pObj ) |
| { |
| // wird aus dem Paint gerufen |
| |
| uno::Reference < embed::XEmbeddedObject > xObj = pObj->GetObjRef(); |
| Window* pWin = GetActiveWin(); |
| |
| // #41412# wenn schon connected ist, nicht nochmal SetObjArea/SetSizeScale |
| |
| SfxInPlaceClient* pClient = FindIPClient( xObj, pWin ); |
| if ( !pClient ) |
| { |
| pClient = new ScClient( this, pWin, GetSdrView()->GetModel(), pObj ); |
| Rectangle aRect = pObj->GetLogicRect(); |
| Size aDrawSize = aRect.GetSize(); |
| |
| Size aOleSize = pObj->GetOrigObjSize(); |
| |
| Fraction aScaleWidth (aDrawSize.Width(), aOleSize.Width() ); |
| Fraction aScaleHeight(aDrawSize.Height(), aOleSize.Height() ); |
| aScaleWidth.ReduceInaccurate(10); // kompatibel zum SdrOle2Obj |
| aScaleHeight.ReduceInaccurate(10); |
| pClient->SetSizeScale(aScaleWidth,aScaleHeight); |
| |
| // sichtbarer Ausschnitt wird nur inplace veraendert! |
| // the object area must be set after the scaling since it triggers the resizing |
| aRect.SetSize( aOleSize ); |
| pClient->SetObjArea( aRect ); |
| |
| ((ScClient*)pClient)->SetGrafEdit( NULL ); |
| } |
| } |
| |
| sal_Bool ScTabViewShell::ActivateObject( SdrOle2Obj* pObj, long nVerb ) |
| { |
| // #41081# Gueltigkeits-Hinweisfenster nicht ueber dem Objekt stehenlassen |
| RemoveHintWindow(); |
| |
| uno::Reference < embed::XEmbeddedObject > xObj = pObj->GetObjRef(); |
| Window* pWin = GetActiveWin(); |
| ErrCode nErr = ERRCODE_NONE; |
| sal_Bool bErrorShown = sal_False; |
| |
| // linked objects aren't supported |
| // if ( xIPObj->IsLink() ) |
| // nErr = xIPObj->DoVerb(nVerb); // gelinkt -> ohne Client etc. |
| // else |
| { |
| SfxInPlaceClient* pClient = FindIPClient( xObj, pWin ); |
| if ( !pClient ) |
| pClient = new ScClient( this, pWin, GetSdrView()->GetModel(), pObj ); |
| |
| if ( !(nErr & ERRCODE_ERROR_MASK) && xObj.is() ) |
| { |
| Rectangle aRect = pObj->GetLogicRect(); |
| |
| { |
| // #i118485# center on BoundRect for activation, |
| // OLE may be sheared/rotated now |
| const Rectangle& rBoundRect = pObj->GetCurrentBoundRect(); |
| const Point aDelta(rBoundRect.Center() - aRect.Center()); |
| aRect.Move(aDelta.X(), aDelta.Y()); |
| } |
| |
| Size aDrawSize = aRect.GetSize(); |
| |
| MapMode aMapMode( MAP_100TH_MM ); |
| Size aOleSize = pObj->GetOrigObjSize( &aMapMode ); |
| |
| if ( pClient->GetAspect() != embed::Aspects::MSOLE_ICON |
| && ( xObj->getStatus( pClient->GetAspect() ) & embed::EmbedMisc::MS_EMBED_RECOMPOSEONRESIZE ) ) |
| { |
| // scale must always be 1 - change VisArea if different from client size |
| |
| if ( aDrawSize != aOleSize ) |
| { |
| MapUnit aUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( pClient->GetAspect() ) ); |
| aOleSize = OutputDevice::LogicToLogic( aDrawSize, |
| MAP_100TH_MM, aUnit ); |
| awt::Size aSz( aOleSize.Width(), aOleSize.Height() ); |
| xObj->setVisualAreaSize( pClient->GetAspect(), aSz ); |
| } |
| Fraction aOne( 1, 1 ); |
| pClient->SetSizeScale( aOne, aOne ); |
| } |
| else |
| { |
| // calculate scale from client and VisArea size |
| |
| Fraction aScaleWidth (aDrawSize.Width(), aOleSize.Width() ); |
| Fraction aScaleHeight(aDrawSize.Height(), aOleSize.Height() ); |
| aScaleWidth.ReduceInaccurate(10); // kompatibel zum SdrOle2Obj |
| aScaleHeight.ReduceInaccurate(10); |
| pClient->SetSizeScale(aScaleWidth,aScaleHeight); |
| } |
| |
| // sichtbarer Ausschnitt wird nur inplace veraendert! |
| // the object area must be set after the scaling since it triggers the resizing |
| aRect.SetSize( aOleSize ); |
| pClient->SetObjArea( aRect ); |
| |
| ((ScClient*)pClient)->SetGrafEdit( NULL ); |
| |
| nErr = pClient->DoVerb( nVerb ); |
| bErrorShown = sal_True; |
| // SfxViewShell::DoVerb zeigt seine Fehlermeldungen selber an |
| |
| SetNewVisArea(); |
| |
| // attach listener to selection changes in chart that affect cell |
| // ranges, so those can be highlighted |
| // note: do that after DoVerb, so that the chart controller exists |
| if ( SvtModuleOptions().IsChart() ) |
| { |
| SvGlobalName aObjClsId ( xObj->getClassID() ); |
| if (SotExchange::IsChart( aObjClsId )) |
| { |
| try |
| { |
| uno::Reference < embed::XComponentSupplier > xSup( xObj, uno::UNO_QUERY_THROW ); |
| uno::Reference< chart2::data::XDataReceiver > xDataReceiver( |
| xSup->getComponent(), uno::UNO_QUERY_THROW ); |
| uno::Reference< chart2::data::XRangeHighlighter > xRangeHightlighter( |
| xDataReceiver->getRangeHighlighter()); |
| if( xRangeHightlighter.is()) |
| { |
| uno::Reference< view::XSelectionChangeListener > xListener( |
| new ScChartRangeSelectionListener( this )); |
| xRangeHightlighter->addSelectionChangeListener( xListener ); |
| } |
| } |
| catch( const uno::Exception & ) |
| { |
| DBG_ERROR( "Exception caught while querying chart" ); |
| } |
| } |
| } |
| } |
| } |
| if (nErr != ERRCODE_NONE && !bErrorShown) |
| ErrorHandler::HandleError(nErr); |
| |
| // #i118524# refresh handles to suppress for activated OLE |
| if(GetSdrView()) |
| { |
| GetSdrView()->AdjustMarkHdl(); |
| } |
| //! SetDocumentName sollte schon im Sfx passieren ??? |
| //TODO/LATER: how "SetDocumentName"? |
| //xIPObj->SetDocumentName( GetViewData()->GetDocShell()->GetTitle() ); |
| |
| return ( !(nErr & ERRCODE_ERROR_MASK) ); |
| } |
| |
| ErrCode __EXPORT ScTabViewShell::DoVerb(long nVerb) |
| { |
| SdrView* pView = GetSdrView(); |
| if (!pView) |
| return ERRCODE_SO_NOTIMPL; // soll nicht sein |
| |
| SdrOle2Obj* pOle2Obj = NULL; |
| SdrGrafObj* pGrafObj = NULL; |
| SdrObject* pObj = NULL; |
| ErrCode nErr = ERRCODE_NONE; |
| |
| const SdrMarkList& rMarkList = pView->GetMarkedObjectList(); |
| if (rMarkList.GetMarkCount() == 1) |
| { |
| pObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); |
| if (pObj->GetObjIdentifier() == OBJ_OLE2) |
| pOle2Obj = (SdrOle2Obj*) pObj; |
| else if (pObj->GetObjIdentifier() == OBJ_GRAF) |
| { |
| pGrafObj = (SdrGrafObj*) pObj; |
| } |
| } |
| |
| if (pOle2Obj) |
| { |
| ActivateObject( pOle2Obj, nVerb ); |
| } |
| else |
| { |
| DBG_ERROR("kein Objekt fuer Verb gefunden"); |
| } |
| |
| return nErr; |
| } |
| |
| void ScTabViewShell::DeactivateOle() |
| { |
| // deactivate inplace editing if currently active |
| |
| ScModule* pScMod = SC_MOD(); |
| bool bUnoRefDialog = pScMod->IsRefDialogOpen() && pScMod->GetCurRefDlgId() == WID_SIMPLE_REF; |
| |
| ScClient* pClient = (ScClient*) GetIPClient(); |
| if ( pClient && pClient->IsObjectInPlaceActive() && !bUnoRefDialog ) |
| pClient->DeactivateObject(); |
| } |
| |
| void ScTabViewShell::ExecDrawIns(SfxRequest& rReq) |
| { |
| sal_uInt16 nSlot = rReq.GetSlot(); |
| if (nSlot != SID_OBJECTRESIZE ) |
| { |
| SC_MOD()->InputEnterHandler(); |
| UpdateInputHandler(); |
| } |
| |
| // Rahmen fuer Chart einfuegen wird abgebrochen: |
| FuPoor* pPoor = GetDrawFuncPtr(); |
| if ( pPoor && pPoor->GetSlotID() == SID_DRAW_CHART ) |
| GetViewData()->GetDispatcher().Execute(SID_DRAW_CHART, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD); |
| |
| MakeDrawLayer(); |
| |
| SfxBindings& rBindings = GetViewFrame()->GetBindings(); |
| ScTabView* pTabView = GetViewData()->GetView(); |
| Window* pWin = pTabView->GetActiveWin(); |
| ScDrawView* pView = pTabView->GetScDrawView(); |
| ScDocShell* pDocSh = GetViewData()->GetDocShell(); |
| ScDocument* pDoc = pDocSh->GetDocument(); |
| // SdrModel* pDrModel = pDocSh->MakeDrawLayer(); |
| SdrModel* pDrModel = pView->GetModel(); |
| |
| switch ( nSlot ) |
| { |
| case SID_INSERT_GRAPHIC: |
| FuInsertGraphic(this, pWin, pView, pDrModel, rReq); |
| // shell is set in MarkListHasChanged |
| break; |
| |
| case SID_INSERT_AVMEDIA: |
| FuInsertMedia(this, pWin, pView, pDrModel, rReq); |
| // shell is set in MarkListHasChanged |
| break; |
| |
| case SID_INSERT_DIAGRAM: |
| FuInsertChart(this, pWin, pView, pDrModel, rReq); |
| //? SC_MOD()->SetFunctionDlg( NULL );//XXX |
| break; |
| |
| case SID_INSERT_OBJECT: |
| case SID_INSERT_PLUGIN: |
| case SID_INSERT_SOUND: |
| case SID_INSERT_VIDEO: |
| case SID_INSERT_SMATH: |
| case SID_INSERT_FLOATINGFRAME: |
| FuInsertOLE(this, pWin, pView, pDrModel, rReq); |
| break; |
| |
| case SID_OBJECTRESIZE: |
| { |
| // Der Server moechte die Clientgrosse verandern |
| |
| SfxInPlaceClient* pClient = GetIPClient(); |
| |
| if ( pClient && pClient->IsObjectInPlaceActive() ) |
| { |
| const SfxRectangleItem& rRect = |
| (SfxRectangleItem&)rReq.GetArgs()->Get(SID_OBJECTRESIZE); |
| Rectangle aRect( pWin->PixelToLogic( rRect.GetValue() ) ); |
| |
| if ( pView->AreObjectsMarked() ) |
| { |
| const SdrMarkList& rMarkList = pView->GetMarkedObjectList(); |
| |
| if (rMarkList.GetMarkCount() == 1) |
| { |
| SdrMark* pMark = rMarkList.GetMark(0); |
| SdrObject* pObj = pMark->GetMarkedSdrObj(); |
| |
| sal_uInt16 nSdrObjKind = pObj->GetObjIdentifier(); |
| |
| if (nSdrObjKind == OBJ_OLE2) |
| { |
| if ( ( (SdrOle2Obj*) pObj)->GetObjRef().is() ) |
| { |
| pObj->SetLogicRect(aRect); |
| } |
| } |
| } |
| } |
| } |
| } |
| break; |
| |
| case SID_LINKS: |
| { |
| SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create(); |
| SfxAbstractLinksDialog* pDlg = pFact->CreateLinksDialog( pWin, pDoc->GetLinkManager() ); |
| if ( pDlg ) |
| { |
| pDlg->Execute(); |
| rBindings.Invalidate( nSlot ); |
| SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) ); // Navigator |
| rReq.Done(); |
| } |
| } |
| break; |
| |
| // #98721# |
| case SID_FM_CREATE_FIELDCONTROL: |
| { |
| SFX_REQUEST_ARG( rReq, pDescriptorItem, SfxUnoAnyItem, SID_FM_DATACCESS_DESCRIPTOR, sal_False ); |
| DBG_ASSERT( pDescriptorItem, "SID_FM_CREATE_FIELDCONTROL: invalid request args!" ); |
| |
| if(pDescriptorItem) |
| { |
| //! merge with ScViewFunc::PasteDataFormat (SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE)? |
| |
| ScDrawView* pDrView = GetScDrawView(); |
| SdrPageView* pPageView = pDrView ? pDrView->GetSdrPageView() : NULL; |
| if(pPageView) |
| { |
| ::svx::ODataAccessDescriptor aDescriptor(pDescriptorItem->GetValue()); |
| SdrObject* pNewDBField = pDrView->CreateFieldControl(aDescriptor); |
| |
| if(pNewDBField) |
| { |
| Rectangle aVisArea = pWin->PixelToLogic(Rectangle(Point(0,0), pWin->GetOutputSizePixel())); |
| Point aObjPos(aVisArea.Center()); |
| Size aObjSize(pNewDBField->GetLogicRect().GetSize()); |
| aObjPos.X() -= aObjSize.Width() / 2; |
| aObjPos.Y() -= aObjSize.Height() / 2; |
| Rectangle aNewObjectRectangle(aObjPos, aObjSize); |
| |
| pNewDBField->SetLogicRect(aNewObjectRectangle); |
| |
| // controls must be on control layer, groups on front layer |
| if ( pNewDBField->ISA(SdrUnoObj) ) |
| pNewDBField->NbcSetLayer(SC_LAYER_CONTROLS); |
| else |
| pNewDBField->NbcSetLayer(SC_LAYER_FRONT); |
| if (pNewDBField->ISA(SdrObjGroup)) |
| { |
| SdrObjListIter aIter( *pNewDBField, IM_DEEPWITHGROUPS ); |
| SdrObject* pSubObj = aIter.Next(); |
| while (pSubObj) |
| { |
| if ( pSubObj->ISA(SdrUnoObj) ) |
| pSubObj->NbcSetLayer(SC_LAYER_CONTROLS); |
| else |
| pSubObj->NbcSetLayer(SC_LAYER_FRONT); |
| pSubObj = aIter.Next(); |
| } |
| } |
| |
| pView->InsertObjectAtView(pNewDBField, *pPageView); |
| } |
| } |
| } |
| rReq.Done(); |
| } |
| break; |
| |
| case SID_FONTWORK_GALLERY_FLOATER: |
| svx::FontworkBar::execute( pView, rReq, GetViewFrame()->GetBindings() ); |
| rReq.Ignore(); |
| break; |
| } |
| } |
| |
| void ScTabViewShell::GetDrawInsState(SfxItemSet &rSet) |
| { |
| sal_Bool bOle = GetViewFrame()->GetFrame().IsInPlace(); |
| sal_Bool bTabProt = GetViewData()->GetDocument()->IsTabProtected(GetViewData()->GetTabNo()); |
| ScDocShell* pDocShell = ( GetViewData() ? GetViewData()->GetDocShell() : NULL ); |
| bool bShared = ( pDocShell ? pDocShell->IsDocShared() : false ); |
| |
| SfxWhichIter aIter(rSet); |
| sal_uInt16 nWhich = aIter.FirstWhich(); |
| while ( nWhich ) |
| { |
| switch ( nWhich ) |
| { |
| case SID_INSERT_DIAGRAM: |
| if ( bOle || bTabProt || !SvtModuleOptions().IsChart() || bShared ) |
| rSet.DisableItem( nWhich ); |
| break; |
| |
| case SID_INSERT_SMATH: |
| if ( bOle || bTabProt || !SvtModuleOptions().IsMath() || bShared ) |
| rSet.DisableItem( nWhich ); |
| break; |
| |
| case SID_INSERT_OBJECT: |
| case SID_INSERT_PLUGIN: |
| case SID_INSERT_FLOATINGFRAME: |
| if ( bOle || bTabProt || bShared ) |
| rSet.DisableItem( nWhich ); |
| break; |
| |
| case SID_INSERT_SOUND: |
| case SID_INSERT_VIDEO: |
| /* #i102735# discussed with NN: removed for performance reasons |
| || !SvxPluginFileDlg::IsAvailable(nWhich) |
| */ |
| if ( bOle || bTabProt || bShared ) |
| rSet.DisableItem( nWhich ); |
| break; |
| |
| case SID_INSERT_GRAPHIC: |
| case SID_INSERT_AVMEDIA: |
| case SID_FONTWORK_GALLERY_FLOATER: |
| if ( bTabProt || bShared ) |
| rSet.DisableItem( nWhich ); |
| break; |
| |
| case SID_LINKS: |
| { |
| if (GetViewData()->GetDocument()->GetLinkManager()->GetLinks().Count() == 0 ) |
| rSet.DisableItem( SID_LINKS ); |
| } |
| break; |
| } |
| nWhich = aIter.NextWhich(); |
| } |
| } |
| |
| |
| //------------------------------------------------------------------ |
| |
| void ScTabViewShell::ExecuteUndo(SfxRequest& rReq) |
| { |
| SfxShell* pSh = GetViewData()->GetDispatcher().GetShell(0); |
| ::svl::IUndoManager* pUndoManager = pSh->GetUndoManager(); |
| |
| const SfxItemSet* pReqArgs = rReq.GetArgs(); |
| ScDocShell* pDocSh = GetViewData()->GetDocShell(); |
| |
| sal_uInt16 nSlot = rReq.GetSlot(); |
| switch ( nSlot ) |
| { |
| case SID_UNDO: |
| case SID_REDO: |
| if ( pUndoManager ) |
| { |
| sal_Bool bIsUndo = ( nSlot == SID_UNDO ); |
| |
| sal_uInt16 nCount = 1; |
| const SfxPoolItem* pItem; |
| if ( pReqArgs && pReqArgs->GetItemState( nSlot, sal_True, &pItem ) == SFX_ITEM_SET ) |
| nCount = ((const SfxUInt16Item*)pItem)->GetValue(); |
| |
| // lock paint for more than one cell undo action (not for editing within a cell) |
| sal_Bool bLockPaint = ( nCount > 1 && pUndoManager == GetUndoManager() ); |
| if ( bLockPaint ) |
| pDocSh->LockPaint(); |
| |
| try |
| { |
| for (sal_uInt16 i=0; i<nCount; i++) |
| { |
| if ( bIsUndo ) |
| pUndoManager->Undo(); |
| else |
| pUndoManager->Redo(); |
| } |
| } |
| catch ( const uno::Exception& ) |
| { |
| // no need to handle. By definition, the UndoManager handled this by clearing the |
| // Undo/Redo stacks |
| } |
| |
| if ( bLockPaint ) |
| pDocSh->UnlockPaint(); |
| |
| GetViewFrame()->GetBindings().InvalidateAll(sal_False); |
| } |
| break; |
| // default: |
| // GetViewFrame()->ExecuteSlot( rReq ); |
| } |
| } |
| |
| void ScTabViewShell::GetUndoState(SfxItemSet &rSet) |
| { |
| SfxShell* pSh = GetViewData()->GetDispatcher().GetShell(0); |
| ::svl::IUndoManager* pUndoManager = pSh->GetUndoManager(); |
| |
| SfxWhichIter aIter(rSet); |
| sal_uInt16 nWhich = aIter.FirstWhich(); |
| while ( nWhich ) |
| { |
| switch (nWhich) |
| { |
| case SID_GETUNDOSTRINGS: |
| case SID_GETREDOSTRINGS: |
| { |
| SfxStringListItem aStrLst( nWhich ); |
| if ( pUndoManager ) |
| { |
| List* pList = aStrLst.GetList(); |
| sal_Bool bIsUndo = ( nWhich == SID_GETUNDOSTRINGS ); |
| size_t nCount = bIsUndo ? pUndoManager->GetUndoActionCount() : pUndoManager->GetRedoActionCount(); |
| for (size_t i=0; i<nCount; i++) |
| pList->Insert( new String( bIsUndo ? pUndoManager->GetUndoActionComment(i) : |
| pUndoManager->GetRedoActionComment(i) ), |
| LIST_APPEND ); |
| } |
| rSet.Put( aStrLst ); |
| } |
| break; |
| default: |
| // get state from sfx view frame |
| GetViewFrame()->GetSlotState( nWhich, NULL, &rSet ); |
| } |
| |
| nWhich = aIter.NextWhich(); |
| } |
| } |
| |
| |
| |