1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
21 #include <com/sun/star/chart2/data/XDataReceiver.hpp>
23 #include <com/sun/star/embed/EmbedMisc.hpp>
24 #include <com/sun/star/embed/EmbedStates.hpp>
25 #include <sfx2/app.hxx>
26 #include <toolkit/helper/vclunohelper.hxx>
27 #include <svx/svxdlg.hxx>
28 #include <svx/dataaccessdescriptor.hxx>
29 #include <svx/svditer.hxx>
30 #include <svx/svdmark.hxx>
31 #include <svx/svdograf.hxx>
32 #include <svx/svdogrp.hxx>
33 #include <svx/svdoole2.hxx>
34 #include <svx/svdouno.hxx>
35 #include <svx/svdview.hxx>
36 #include <sfx2/linkmgr.hxx>
37 #include <svx/fontworkbar.hxx>
38 #include <sfx2/bindings.hxx>
39 #include <sfx2/dispatch.hxx>
40 #include <sfx2/viewfrm.hxx>
41 #include <sfx2/filedlghelper.hxx>
42 #include <svtools/soerr.hxx>
43 #include <svl/rectitem.hxx>
44 #include <svl/slstitm.hxx>
45 #include <svl/whiter.hxx>
46 #include <unotools/moduleoptions.hxx>
47 #include <sot/exchange.hxx>
48 #include <tools/diagnose_ex.h>
50 #include "tabvwsh.hxx"
51 #include "globstr.hrc"
53 #include "document.hxx"
56 #include "fuinsert.hxx"
58 #include "chartarr.hxx"
59 #include "drawview.hxx"
60 #include "ChartRangeSelectionListener.hxx"
61 #include <gridwin.hxx>
63 #include <tools/urlobj.hxx>
64 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
66 using namespace com::sun::star
;
68 void ScTabViewShell::ConnectObject( SdrOle2Obj
* pObj
)
70 // is called from paint
72 uno::Reference
< embed::XEmbeddedObject
> xObj
= pObj
->GetObjRef();
73 vcl::Window
* pWin
= GetActiveWin();
75 // when already connected do not execute SetObjArea/SetSizeScale again
77 SfxInPlaceClient
* pClient
= FindIPClient( xObj
, pWin
);
80 pClient
= new ScClient( this, pWin
, GetSdrView()->GetModel(), pObj
);
81 Rectangle aRect
= pObj
->GetLogicRect();
82 Size aDrawSize
= aRect
.GetSize();
84 Size aOleSize
= pObj
->GetOrigObjSize();
86 Fraction
aScaleWidth (aDrawSize
.Width(), aOleSize
.Width() );
87 Fraction
aScaleHeight(aDrawSize
.Height(), aOleSize
.Height() );
88 aScaleWidth
.ReduceInaccurate(10); // compatible with SdrOle2Obj
89 aScaleHeight
.ReduceInaccurate(10);
90 pClient
->SetSizeScale(aScaleWidth
,aScaleHeight
);
92 // visible section is only changed inplace!
93 // the object area must be set after the scaling since it triggers the resizing
94 aRect
.SetSize( aOleSize
);
95 pClient
->SetObjArea( aRect
);
97 static_cast<ScClient
*>(pClient
)->SetGrafEdit( nullptr );
101 void ScTabViewShell::ActivateObject( SdrOle2Obj
* pObj
, long nVerb
)
103 // Do not leave the hint message box on top of the object
106 uno::Reference
< embed::XEmbeddedObject
> xObj
= pObj
->GetObjRef();
107 vcl::Window
* pWin
= GetActiveWin();
108 ErrCode nErr
= ERRCODE_NONE
;
109 bool bErrorShown
= false;
112 SfxInPlaceClient
* pClient
= FindIPClient( xObj
, pWin
);
114 pClient
= new ScClient( this, pWin
, GetSdrView()->GetModel(), pObj
);
116 if ( !(nErr
& ERRCODE_ERROR_MASK
) && xObj
.is() )
118 Rectangle aRect
= pObj
->GetLogicRect();
121 // #i118485# center on BoundRect for activation,
122 // OLE may be sheared/rotated now
123 const Rectangle
& rBoundRect
= pObj
->GetCurrentBoundRect();
124 const Point
aDelta(rBoundRect
.Center() - aRect
.Center());
125 aRect
.Move(aDelta
.X(), aDelta
.Y());
128 Size aDrawSize
= aRect
.GetSize();
130 MapMode
aMapMode( MAP_100TH_MM
);
131 Size aOleSize
= pObj
->GetOrigObjSize( &aMapMode
);
133 if ( pClient
->GetAspect() != embed::Aspects::MSOLE_ICON
134 && ( xObj
->getStatus( pClient
->GetAspect() ) & embed::EmbedMisc::MS_EMBED_RECOMPOSEONRESIZE
) )
136 // scale must always be 1 - change VisArea if different from client size
138 if ( aDrawSize
!= aOleSize
)
140 MapUnit aUnit
= VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj
->getMapUnit( pClient
->GetAspect() ) );
141 aOleSize
= OutputDevice::LogicToLogic( aDrawSize
,
142 MAP_100TH_MM
, aUnit
);
143 awt::Size
aSz( aOleSize
.Width(), aOleSize
.Height() );
144 xObj
->setVisualAreaSize( pClient
->GetAspect(), aSz
);
146 Fraction
aOne( 1, 1 );
147 pClient
->SetSizeScale( aOne
, aOne
);
151 // calculate scale from client and VisArea size
153 Fraction
aScaleWidth (aDrawSize
.Width(), aOleSize
.Width() );
154 Fraction
aScaleHeight(aDrawSize
.Height(), aOleSize
.Height() );
155 aScaleWidth
.ReduceInaccurate(10); // compatible with SdrOle2Obj
156 aScaleHeight
.ReduceInaccurate(10);
157 pClient
->SetSizeScale(aScaleWidth
,aScaleHeight
);
160 // visible section is only changed inplace!
161 // the object area must be set after the scaling since it triggers the resizing
162 aRect
.SetSize( aOleSize
);
163 pClient
->SetObjArea( aRect
);
165 static_cast<ScClient
*>(pClient
)->SetGrafEdit( nullptr );
167 nErr
= pClient
->DoVerb( nVerb
);
169 // SfxViewShell::DoVerb shows its error messages
171 // attach listener to selection changes in chart that affect cell
172 // ranges, so those can be highlighted
173 // note: do that after DoVerb, so that the chart controller exists
174 if ( SvtModuleOptions().IsChart() )
176 SvGlobalName
aObjClsId ( xObj
->getClassID() );
177 if (SotExchange::IsChart( aObjClsId
))
181 uno::Reference
< embed::XComponentSupplier
> xSup( xObj
, uno::UNO_QUERY_THROW
);
182 uno::Reference
< chart2::data::XDataReceiver
> xDataReceiver(
183 xSup
->getComponent(), uno::UNO_QUERY_THROW
);
184 uno::Reference
< chart2::data::XRangeHighlighter
> xRangeHightlighter(
185 xDataReceiver
->getRangeHighlighter());
186 if( xRangeHightlighter
.is())
188 uno::Reference
< view::XSelectionChangeListener
> xListener(
189 new ScChartRangeSelectionListener( this ));
190 xRangeHightlighter
->addSelectionChangeListener( xListener
);
193 catch( const uno::Exception
& )
195 OSL_FAIL( "Exception caught while querying chart" );
201 if (nErr
!= ERRCODE_NONE
&& !bErrorShown
)
202 ErrorHandler::HandleError(nErr
);
204 // #i118524# refresh handles to suppress for activated OLE
207 GetSdrView()->AdjustMarkHdl();
209 //! SetDocumentName should already happen in Sfx ???
210 //TODO/LATER: how "SetDocumentName"?
211 //xIPObj->SetDocumentName( GetViewData().GetDocShell()->GetTitle() );
214 ErrCode
ScTabViewShell::DoVerb(long nVerb
)
216 SdrView
* pView
= GetSdrView();
218 return ERRCODE_SO_NOTIMPL
; // should not be
220 SdrOle2Obj
* pOle2Obj
= nullptr;
221 ErrCode nErr
= ERRCODE_NONE
;
223 const SdrMarkList
& rMarkList
= pView
->GetMarkedObjectList();
224 if (rMarkList
.GetMarkCount() == 1)
226 SdrObject
* pObj
= rMarkList
.GetMark(0)->GetMarkedSdrObj();
227 if (pObj
->GetObjIdentifier() == OBJ_OLE2
)
228 pOle2Obj
= static_cast<SdrOle2Obj
*>(pObj
);
233 ActivateObject( pOle2Obj
, nVerb
);
237 OSL_FAIL("no object for Verb found");
243 void ScTabViewShell::DeactivateOle()
245 // deactivate inplace editing if currently active
247 ScModule
* pScMod
= SC_MOD();
248 bool bUnoRefDialog
= pScMod
->IsRefDialogOpen() && pScMod
->GetCurRefDlgId() == WID_SIMPLE_REF
;
250 ScClient
* pClient
= static_cast<ScClient
*>(GetIPClient());
251 if ( pClient
&& pClient
->IsObjectInPlaceActive() && !bUnoRefDialog
)
252 pClient
->DeactivateObject();
255 void ScTabViewShell::ExecDrawIns(SfxRequest
& rReq
)
257 sal_uInt16 nSlot
= rReq
.GetSlot();
258 if (nSlot
!= SID_OBJECTRESIZE
)
260 SC_MOD()->InputEnterHandler();
261 UpdateInputHandler();
264 // insertion of border for Chart is cancelled:
265 FuPoor
* pPoor
= GetDrawFuncPtr();
266 if ( pPoor
&& pPoor
->GetSlotID() == SID_DRAW_CHART
)
267 GetViewData().GetDispatcher().Execute(SID_DRAW_CHART
, SfxCallMode::SLOT
| SfxCallMode::RECORD
);
271 SfxBindings
& rBindings
= GetViewFrame()->GetBindings();
272 ScTabView
* pTabView
= GetViewData().GetView();
273 vcl::Window
* pWin
= pTabView
->GetActiveWin();
274 ScDrawView
* pView
= pTabView
->GetScDrawView();
275 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
276 ScDocument
& rDoc
= pDocSh
->GetDocument();
277 SdrModel
* pDrModel
= pView
->GetModel();
281 case SID_INSERT_GRAPHIC
:
282 FuInsertGraphic(this, pWin
, pView
, pDrModel
, rReq
);
283 // shell is set in MarkListHasChanged
286 case SID_INSERT_AVMEDIA
:
287 FuInsertMedia(this, pWin
, pView
, pDrModel
, rReq
);
288 // shell is set in MarkListHasChanged
291 case SID_INSERT_DIAGRAM
:
292 FuInsertChart(this, pWin
, pView
, pDrModel
, rReq
);
295 case SID_INSERT_OBJECT
:
296 case SID_INSERT_SMATH
:
297 case SID_INSERT_FLOATINGFRAME
:
298 FuInsertOLE(this, pWin
, pView
, pDrModel
, rReq
);
301 case SID_INSERT_DIAGRAM_FROM_FILE
:
304 sfx2::FileDialogHelper
aDlg(ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE
,
305 FileDialogFlags::NONE
, OUString("com.sun.star.chart2.ChartDocument"));
306 if(aDlg
.Execute() == ERRCODE_NONE
)
308 INetURLObject
aURLObj( aDlg
.GetPath() );
309 OUString aURL
= aURLObj
.GetURLNoPass();
310 FuInsertChartFromFile(this, pWin
, pView
, pDrModel
, rReq
, aURL
);
313 catch (const uno::Exception
& e
)
315 SAL_WARN( "sc", "Cannot Insert Chart: " << e
.Message
);
319 case SID_OBJECTRESIZE
:
321 // the server would like to change the client size
323 SfxInPlaceClient
* pClient
= GetIPClient();
325 if ( pClient
&& pClient
->IsObjectInPlaceActive() )
327 const SfxRectangleItem
& rRect
=
328 static_cast<const SfxRectangleItem
&>(rReq
.GetArgs()->Get(SID_OBJECTRESIZE
));
329 Rectangle
aRect( pWin
->PixelToLogic( rRect
.GetValue() ) );
331 if ( pView
->AreObjectsMarked() )
333 const SdrMarkList
& rMarkList
= pView
->GetMarkedObjectList();
335 if (rMarkList
.GetMarkCount() == 1)
337 SdrMark
* pMark
= rMarkList
.GetMark(0);
338 SdrObject
* pObj
= pMark
->GetMarkedSdrObj();
340 sal_uInt16 nSdrObjKind
= pObj
->GetObjIdentifier();
342 if (nSdrObjKind
== OBJ_OLE2
)
344 if ( static_cast<SdrOle2Obj
*>(pObj
)->GetObjRef().is() )
346 pObj
->SetLogicRect(aRect
);
357 SvxAbstractDialogFactory
* pFact
= SvxAbstractDialogFactory::Create();
358 SfxAbstractLinksDialog
* pDlg
= pFact
->CreateLinksDialog( pWin
, rDoc
.GetLinkManager() );
362 rBindings
.Invalidate( nSlot
);
363 SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED
) ); // Navigator
369 case SID_FM_CREATE_FIELDCONTROL
:
371 const SfxUnoAnyItem
* pDescriptorItem
= rReq
.GetArg
<SfxUnoAnyItem
>(SID_FM_DATACCESS_DESCRIPTOR
);
372 OSL_ENSURE( pDescriptorItem
, "SID_FM_CREATE_FIELDCONTROL: invalid request args!" );
376 //! merge with ScViewFunc::PasteDataFormat (SotClipboardFormatId::SBA_FIELDDATAEXCHANGE)?
378 ScDrawView
* pDrView
= GetScDrawView();
379 SdrPageView
* pPageView
= pDrView
? pDrView
->GetSdrPageView() : nullptr;
382 svx::ODataAccessDescriptor
aDescriptor(pDescriptorItem
->GetValue());
383 SdrObject
* pNewDBField
= pDrView
->CreateFieldControl(aDescriptor
);
387 Rectangle aVisArea
= pWin
->PixelToLogic(Rectangle(Point(0,0), pWin
->GetOutputSizePixel()));
388 Point
aObjPos(aVisArea
.Center());
389 Size
aObjSize(pNewDBField
->GetLogicRect().GetSize());
390 aObjPos
.X() -= aObjSize
.Width() / 2;
391 aObjPos
.Y() -= aObjSize
.Height() / 2;
392 Rectangle
aNewObjectRectangle(aObjPos
, aObjSize
);
394 pNewDBField
->SetLogicRect(aNewObjectRectangle
);
396 // controls must be on control layer, groups on front layer
397 if ( dynamic_cast<const SdrUnoObj
*>( pNewDBField
) != nullptr )
398 pNewDBField
->NbcSetLayer(SC_LAYER_CONTROLS
);
400 pNewDBField
->NbcSetLayer(SC_LAYER_FRONT
);
401 if (dynamic_cast<const SdrObjGroup
*>( pNewDBField
) != nullptr)
403 SdrObjListIter
aIter( *pNewDBField
, IM_DEEPWITHGROUPS
);
404 SdrObject
* pSubObj
= aIter
.Next();
407 if ( dynamic_cast<const SdrUnoObj
*>( pSubObj
) != nullptr )
408 pSubObj
->NbcSetLayer(SC_LAYER_CONTROLS
);
410 pSubObj
->NbcSetLayer(SC_LAYER_FRONT
);
411 pSubObj
= aIter
.Next();
415 pView
->InsertObjectAtView(pNewDBField
, *pPageView
);
423 case SID_FONTWORK_GALLERY_FLOATER
:
424 svx::FontworkBar::execute( pView
, rReq
, GetViewFrame()->GetBindings() );
430 void ScTabViewShell::GetDrawInsState(SfxItemSet
&rSet
)
432 bool bOle
= GetViewFrame()->GetFrame().IsInPlace();
433 bool bTabProt
= GetViewData().GetDocument()->IsTabProtected(GetViewData().GetTabNo());
434 ScDocShell
* pDocShell
= GetViewData().GetDocShell();
435 bool bShared
= pDocShell
&& pDocShell
->IsDocShared();
437 SfxWhichIter
aIter(rSet
);
438 sal_uInt16 nWhich
= aIter
.FirstWhich();
443 case SID_INSERT_DIAGRAM
:
444 if ( bOle
|| bTabProt
|| !SvtModuleOptions().IsChart() || bShared
)
445 rSet
.DisableItem( nWhich
);
448 case SID_INSERT_SMATH
:
449 if ( bOle
|| bTabProt
|| !SvtModuleOptions().IsMath() || bShared
)
450 rSet
.DisableItem( nWhich
);
453 case SID_INSERT_OBJECT
:
454 case SID_INSERT_FLOATINGFRAME
:
455 if ( bOle
|| bTabProt
|| bShared
)
456 rSet
.DisableItem( nWhich
);
459 case SID_INSERT_GRAPHIC
:
460 case SID_INSERT_AVMEDIA
:
461 case SID_FONTWORK_GALLERY_FLOATER
:
462 if ( bTabProt
|| bShared
)
463 rSet
.DisableItem( nWhich
);
468 if (GetViewData().GetDocument()->GetLinkManager()->GetLinks().empty())
469 rSet
.DisableItem( SID_LINKS
);
473 nWhich
= aIter
.NextWhich();
477 void ScTabViewShell::ExecuteUndo(SfxRequest
& rReq
)
479 SfxShell
* pSh
= GetViewData().GetDispatcher().GetShell(0);
480 ::svl::IUndoManager
* pUndoManager
= pSh
->GetUndoManager();
482 const SfxItemSet
* pReqArgs
= rReq
.GetArgs();
483 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
485 sal_uInt16 nSlot
= rReq
.GetSlot();
492 bool bIsUndo
= ( nSlot
== SID_UNDO
);
494 sal_uInt16 nCount
= 1;
495 const SfxPoolItem
* pItem
;
496 if ( pReqArgs
&& pReqArgs
->GetItemState( nSlot
, true, &pItem
) == SfxItemState::SET
)
497 nCount
= static_cast<const SfxUInt16Item
*>(pItem
)->GetValue();
499 // lock paint for more than one cell undo action (not for editing within a cell)
500 bool bLockPaint
= ( nCount
> 1 && pUndoManager
== GetUndoManager() );
506 for (sal_uInt16 i
=0; i
<nCount
; i
++)
509 pUndoManager
->Undo();
511 pUndoManager
->Redo();
514 catch ( const uno::Exception
& )
516 // no need to handle. By definition, the UndoManager handled this by clearing the
521 pDocSh
->UnlockPaint();
523 GetViewFrame()->GetBindings().InvalidateAll(false);
527 // GetViewFrame()->ExecuteSlot( rReq );
531 void ScTabViewShell::GetUndoState(SfxItemSet
&rSet
)
533 SfxShell
* pSh
= GetViewData().GetDispatcher().GetShell(0);
534 ::svl::IUndoManager
* pUndoManager
= pSh
->GetUndoManager();
536 SfxWhichIter
aIter(rSet
);
537 sal_uInt16 nWhich
= aIter
.FirstWhich();
542 case SID_GETUNDOSTRINGS
:
543 case SID_GETREDOSTRINGS
:
545 SfxStringListItem
aStrLst( nWhich
);
548 std::vector
<OUString
> &aList
= aStrLst
.GetList();
549 bool bIsUndo
= ( nWhich
== SID_GETUNDOSTRINGS
);
550 size_t nCount
= bIsUndo
? pUndoManager
->GetUndoActionCount() : pUndoManager
->GetRedoActionCount();
551 for (size_t i
=0; i
<nCount
; ++i
)
553 aList
.push_back( bIsUndo
? pUndoManager
->GetUndoActionComment(i
) :
554 pUndoManager
->GetRedoActionComment(i
) );
561 // get state from sfx view frame
562 GetViewFrame()->GetSlotState( nWhich
, nullptr, &rSet
);
565 nWhich
= aIter
.NextWhich();
569 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */