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/pfiledlg.hxx>
30 #include <svx/svditer.hxx>
31 #include <svx/svdmark.hxx>
32 #include <svx/svdograf.hxx>
33 #include <svx/svdogrp.hxx>
34 #include <svx/svdoole2.hxx>
35 #include <svx/svdouno.hxx>
36 #include <svx/svdview.hxx>
37 #include <sfx2/linkmgr.hxx>
38 #include <svx/fontworkbar.hxx>
39 #include <sfx2/bindings.hxx>
40 #include <sfx2/dispatch.hxx>
41 #include <sfx2/viewfrm.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 // STATIC DATA -----------------------------------------------------------
70 void ScTabViewShell::ConnectObject( SdrOle2Obj
* pObj
)
72 // wird aus dem Paint gerufen
74 uno::Reference
< embed::XEmbeddedObject
> xObj
= pObj
->GetObjRef();
75 vcl::Window
* pWin
= GetActiveWin();
77 // wenn schon connected ist, nicht nochmal SetObjArea/SetSizeScale
79 SfxInPlaceClient
* pClient
= FindIPClient( xObj
, pWin
);
82 pClient
= new ScClient( this, pWin
, GetSdrView()->GetModel(), pObj
);
83 Rectangle aRect
= pObj
->GetLogicRect();
84 Size aDrawSize
= aRect
.GetSize();
86 Size aOleSize
= pObj
->GetOrigObjSize();
88 Fraction
aScaleWidth (aDrawSize
.Width(), aOleSize
.Width() );
89 Fraction
aScaleHeight(aDrawSize
.Height(), aOleSize
.Height() );
90 aScaleWidth
.ReduceInaccurate(10); // kompatibel zum SdrOle2Obj
91 aScaleHeight
.ReduceInaccurate(10);
92 pClient
->SetSizeScale(aScaleWidth
,aScaleHeight
);
94 // sichtbarer Ausschnitt wird nur inplace veraendert!
95 // the object area must be set after the scaling since it triggers the resizing
96 aRect
.SetSize( aOleSize
);
97 pClient
->SetObjArea( aRect
);
99 static_cast<ScClient
*>(pClient
)->SetGrafEdit( NULL
);
103 bool ScTabViewShell::ActivateObject( SdrOle2Obj
* pObj
, long nVerb
)
105 // Gueltigkeits-Hinweisfenster nicht ueber dem Objekt stehenlassen
108 uno::Reference
< embed::XEmbeddedObject
> xObj
= pObj
->GetObjRef();
109 vcl::Window
* pWin
= GetActiveWin();
110 ErrCode nErr
= ERRCODE_NONE
;
111 bool bErrorShown
= false;
114 SfxInPlaceClient
* pClient
= FindIPClient( xObj
, pWin
);
116 pClient
= new ScClient( this, pWin
, GetSdrView()->GetModel(), pObj
);
118 if ( !(nErr
& ERRCODE_ERROR_MASK
) && xObj
.is() )
120 Rectangle aRect
= pObj
->GetLogicRect();
123 // #i118485# center on BoundRect for activation,
124 // OLE may be sheared/rotated now
125 const Rectangle
& rBoundRect
= pObj
->GetCurrentBoundRect();
126 const Point
aDelta(rBoundRect
.Center() - aRect
.Center());
127 aRect
.Move(aDelta
.X(), aDelta
.Y());
130 Size aDrawSize
= aRect
.GetSize();
132 MapMode
aMapMode( MAP_100TH_MM
);
133 Size aOleSize
= pObj
->GetOrigObjSize( &aMapMode
);
135 if ( pClient
->GetAspect() != embed::Aspects::MSOLE_ICON
136 && ( xObj
->getStatus( pClient
->GetAspect() ) & embed::EmbedMisc::MS_EMBED_RECOMPOSEONRESIZE
) )
138 // scale must always be 1 - change VisArea if different from client size
140 if ( aDrawSize
!= aOleSize
)
142 MapUnit aUnit
= VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj
->getMapUnit( pClient
->GetAspect() ) );
143 aOleSize
= OutputDevice::LogicToLogic( aDrawSize
,
144 MAP_100TH_MM
, aUnit
);
145 awt::Size
aSz( aOleSize
.Width(), aOleSize
.Height() );
146 xObj
->setVisualAreaSize( pClient
->GetAspect(), aSz
);
148 Fraction
aOne( 1, 1 );
149 pClient
->SetSizeScale( aOne
, aOne
);
153 // calculate scale from client and VisArea size
155 Fraction
aScaleWidth (aDrawSize
.Width(), aOleSize
.Width() );
156 Fraction
aScaleHeight(aDrawSize
.Height(), aOleSize
.Height() );
157 aScaleWidth
.ReduceInaccurate(10); // kompatibel zum SdrOle2Obj
158 aScaleHeight
.ReduceInaccurate(10);
159 pClient
->SetSizeScale(aScaleWidth
,aScaleHeight
);
162 // sichtbarer Ausschnitt wird nur inplace veraendert!
163 // the object area must be set after the scaling since it triggers the resizing
164 aRect
.SetSize( aOleSize
);
165 pClient
->SetObjArea( aRect
);
167 static_cast<ScClient
*>(pClient
)->SetGrafEdit( NULL
);
169 nErr
= pClient
->DoVerb( nVerb
);
171 // SfxViewShell::DoVerb zeigt seine Fehlermeldungen selber an
173 // attach listener to selection changes in chart that affect cell
174 // ranges, so those can be highlighted
175 // note: do that after DoVerb, so that the chart controller exists
176 if ( SvtModuleOptions().IsChart() )
178 SvGlobalName
aObjClsId ( xObj
->getClassID() );
179 if (SotExchange::IsChart( aObjClsId
))
183 uno::Reference
< embed::XComponentSupplier
> xSup( xObj
, uno::UNO_QUERY_THROW
);
184 uno::Reference
< chart2::data::XDataReceiver
> xDataReceiver(
185 xSup
->getComponent(), uno::UNO_QUERY_THROW
);
186 uno::Reference
< chart2::data::XRangeHighlighter
> xRangeHightlighter(
187 xDataReceiver
->getRangeHighlighter());
188 if( xRangeHightlighter
.is())
190 uno::Reference
< view::XSelectionChangeListener
> xListener(
191 new ScChartRangeSelectionListener( this ));
192 xRangeHightlighter
->addSelectionChangeListener( xListener
);
195 catch( const uno::Exception
& )
197 OSL_FAIL( "Exception caught while querying chart" );
203 if (nErr
!= ERRCODE_NONE
&& !bErrorShown
)
204 ErrorHandler::HandleError(nErr
);
206 // #i118524# refresh handles to suppress for activated OLE
209 GetSdrView()->AdjustMarkHdl();
211 //! SetDocumentName sollte schon im Sfx passieren ???
212 //TODO/LATER: how "SetDocumentName"?
213 //xIPObj->SetDocumentName( GetViewData().GetDocShell()->GetTitle() );
215 return ( !(nErr
& ERRCODE_ERROR_MASK
) );
218 ErrCode
ScTabViewShell::DoVerb(long nVerb
)
220 SdrView
* pView
= GetSdrView();
222 return ERRCODE_SO_NOTIMPL
; // soll nicht sein
224 SdrOle2Obj
* pOle2Obj
= NULL
;
225 ErrCode nErr
= ERRCODE_NONE
;
227 const SdrMarkList
& rMarkList
= pView
->GetMarkedObjectList();
228 if (rMarkList
.GetMarkCount() == 1)
230 SdrObject
* pObj
= rMarkList
.GetMark(0)->GetMarkedSdrObj();
231 if (pObj
->GetObjIdentifier() == OBJ_OLE2
)
232 pOle2Obj
= static_cast<SdrOle2Obj
*>(pObj
);
237 ActivateObject( pOle2Obj
, nVerb
);
241 OSL_FAIL("kein Objekt fuer Verb gefunden");
247 void ScTabViewShell::DeactivateOle()
249 // deactivate inplace editing if currently active
251 ScModule
* pScMod
= SC_MOD();
252 bool bUnoRefDialog
= pScMod
->IsRefDialogOpen() && pScMod
->GetCurRefDlgId() == WID_SIMPLE_REF
;
254 ScClient
* pClient
= static_cast<ScClient
*>(GetIPClient());
255 if ( pClient
&& pClient
->IsObjectInPlaceActive() && !bUnoRefDialog
)
256 pClient
->DeactivateObject();
259 void ScTabViewShell::ExecDrawIns(SfxRequest
& rReq
)
261 sal_uInt16 nSlot
= rReq
.GetSlot();
262 if (nSlot
!= SID_OBJECTRESIZE
)
264 SC_MOD()->InputEnterHandler();
265 UpdateInputHandler();
268 // Rahmen fuer Chart einfuegen wird abgebrochen:
269 FuPoor
* pPoor
= GetDrawFuncPtr();
270 if ( pPoor
&& pPoor
->GetSlotID() == SID_DRAW_CHART
)
271 GetViewData().GetDispatcher().Execute(SID_DRAW_CHART
, SfxCallMode::SLOT
| SfxCallMode::RECORD
);
275 SfxBindings
& rBindings
= GetViewFrame()->GetBindings();
276 ScTabView
* pTabView
= GetViewData().GetView();
277 vcl::Window
* pWin
= pTabView
->GetActiveWin();
278 ScDrawView
* pView
= pTabView
->GetScDrawView();
279 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
280 ScDocument
& rDoc
= pDocSh
->GetDocument();
281 SdrModel
* pDrModel
= pView
->GetModel();
285 case SID_INSERT_GRAPHIC
:
286 FuInsertGraphic(this, pWin
, pView
, pDrModel
, rReq
);
287 // shell is set in MarkListHasChanged
290 case SID_INSERT_AVMEDIA
:
291 FuInsertMedia(this, pWin
, pView
, pDrModel
, rReq
);
292 // shell is set in MarkListHasChanged
295 case SID_INSERT_DIAGRAM
:
296 FuInsertChart(this, pWin
, pView
, pDrModel
, rReq
);
299 case SID_INSERT_OBJECT
:
300 case SID_INSERT_PLUGIN
:
301 case SID_INSERT_SOUND
:
302 case SID_INSERT_VIDEO
:
303 case SID_INSERT_SMATH
:
304 case SID_INSERT_FLOATINGFRAME
:
305 FuInsertOLE(this, pWin
, pView
, pDrModel
, rReq
);
308 case SID_INSERT_DIAGRAM_FROM_FILE
:
311 sfx2::FileDialogHelper
aDlg(ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE
,
312 0, OUString("com.sun.star.chart2.ChartDocument"));
313 if(aDlg
.Execute() == ERRCODE_NONE
)
315 INetURLObject
aURLObj( aDlg
.GetPath() );
316 OUString aURL
= aURLObj
.GetURLNoPass();
317 FuInsertChartFromFile(this, pWin
, pView
, pDrModel
, rReq
, aURL
);
320 catch (const uno::Exception
& e
)
322 SAL_WARN( "sc", "Cannot Insert Chart: " << e
.Message
);
326 case SID_OBJECTRESIZE
:
328 // Der Server moechte die Clientgrosse verandern
330 SfxInPlaceClient
* pClient
= GetIPClient();
332 if ( pClient
&& pClient
->IsObjectInPlaceActive() )
334 const SfxRectangleItem
& rRect
=
335 static_cast<const SfxRectangleItem
&>(rReq
.GetArgs()->Get(SID_OBJECTRESIZE
));
336 Rectangle
aRect( pWin
->PixelToLogic( rRect
.GetValue() ) );
338 if ( pView
->AreObjectsMarked() )
340 const SdrMarkList
& rMarkList
= pView
->GetMarkedObjectList();
342 if (rMarkList
.GetMarkCount() == 1)
344 SdrMark
* pMark
= rMarkList
.GetMark(0);
345 SdrObject
* pObj
= pMark
->GetMarkedSdrObj();
347 sal_uInt16 nSdrObjKind
= pObj
->GetObjIdentifier();
349 if (nSdrObjKind
== OBJ_OLE2
)
351 if ( static_cast<SdrOle2Obj
*>(pObj
)->GetObjRef().is() )
353 pObj
->SetLogicRect(aRect
);
364 SvxAbstractDialogFactory
* pFact
= SvxAbstractDialogFactory::Create();
365 SfxAbstractLinksDialog
* pDlg
= pFact
->CreateLinksDialog( pWin
, rDoc
.GetLinkManager() );
369 rBindings
.Invalidate( nSlot
);
370 SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED
) ); // Navigator
377 case SID_FM_CREATE_FIELDCONTROL
:
379 SFX_REQUEST_ARG( rReq
, pDescriptorItem
, SfxUnoAnyItem
, SID_FM_DATACCESS_DESCRIPTOR
, false );
380 OSL_ENSURE( pDescriptorItem
, "SID_FM_CREATE_FIELDCONTROL: invalid request args!" );
384 //! merge with ScViewFunc::PasteDataFormat (SotClipboardFormatId::SBA_FIELDDATAEXCHANGE)?
386 ScDrawView
* pDrView
= GetScDrawView();
387 SdrPageView
* pPageView
= pDrView
? pDrView
->GetSdrPageView() : NULL
;
390 svx::ODataAccessDescriptor
aDescriptor(pDescriptorItem
->GetValue());
391 SdrObject
* pNewDBField
= pDrView
->CreateFieldControl(aDescriptor
);
395 Rectangle aVisArea
= pWin
->PixelToLogic(Rectangle(Point(0,0), pWin
->GetOutputSizePixel()));
396 Point
aObjPos(aVisArea
.Center());
397 Size
aObjSize(pNewDBField
->GetLogicRect().GetSize());
398 aObjPos
.X() -= aObjSize
.Width() / 2;
399 aObjPos
.Y() -= aObjSize
.Height() / 2;
400 Rectangle
aNewObjectRectangle(aObjPos
, aObjSize
);
402 pNewDBField
->SetLogicRect(aNewObjectRectangle
);
404 // controls must be on control layer, groups on front layer
405 if ( pNewDBField
->ISA(SdrUnoObj
) )
406 pNewDBField
->NbcSetLayer(SC_LAYER_CONTROLS
);
408 pNewDBField
->NbcSetLayer(SC_LAYER_FRONT
);
409 if (pNewDBField
->ISA(SdrObjGroup
))
411 SdrObjListIter
aIter( *pNewDBField
, IM_DEEPWITHGROUPS
);
412 SdrObject
* pSubObj
= aIter
.Next();
415 if ( pSubObj
->ISA(SdrUnoObj
) )
416 pSubObj
->NbcSetLayer(SC_LAYER_CONTROLS
);
418 pSubObj
->NbcSetLayer(SC_LAYER_FRONT
);
419 pSubObj
= aIter
.Next();
423 pView
->InsertObjectAtView(pNewDBField
, *pPageView
);
431 case SID_FONTWORK_GALLERY_FLOATER
:
432 svx::FontworkBar::execute( pView
, rReq
, GetViewFrame()->GetBindings() );
438 void ScTabViewShell::GetDrawInsState(SfxItemSet
&rSet
)
440 bool bOle
= GetViewFrame()->GetFrame().IsInPlace();
441 bool bTabProt
= GetViewData().GetDocument()->IsTabProtected(GetViewData().GetTabNo());
442 ScDocShell
* pDocShell
= GetViewData().GetDocShell();
443 bool bShared
= pDocShell
&& pDocShell
->IsDocShared();
445 SfxWhichIter
aIter(rSet
);
446 sal_uInt16 nWhich
= aIter
.FirstWhich();
451 case SID_INSERT_DIAGRAM
:
452 if ( bOle
|| bTabProt
|| !SvtModuleOptions().IsChart() || bShared
)
453 rSet
.DisableItem( nWhich
);
456 case SID_INSERT_SMATH
:
457 if ( bOle
|| bTabProt
|| !SvtModuleOptions().IsMath() || bShared
)
458 rSet
.DisableItem( nWhich
);
461 case SID_INSERT_OBJECT
:
462 case SID_INSERT_PLUGIN
:
463 case SID_INSERT_FLOATINGFRAME
:
464 if ( bOle
|| bTabProt
|| bShared
)
465 rSet
.DisableItem( nWhich
);
468 case SID_INSERT_SOUND
:
469 case SID_INSERT_VIDEO
:
470 /* #i102735# discussed with NN: removed for performance reasons
471 || !SvxPluginFileDlg::IsAvailable(nWhich)
473 if ( bOle
|| bTabProt
|| bShared
)
474 rSet
.DisableItem( nWhich
);
477 case SID_INSERT_GRAPHIC
:
478 case SID_INSERT_AVMEDIA
:
479 case SID_FONTWORK_GALLERY_FLOATER
:
480 if ( bTabProt
|| bShared
)
481 rSet
.DisableItem( nWhich
);
486 if (GetViewData().GetDocument()->GetLinkManager()->GetLinks().empty())
487 rSet
.DisableItem( SID_LINKS
);
491 nWhich
= aIter
.NextWhich();
495 void ScTabViewShell::ExecuteUndo(SfxRequest
& rReq
)
497 SfxShell
* pSh
= GetViewData().GetDispatcher().GetShell(0);
498 ::svl::IUndoManager
* pUndoManager
= pSh
->GetUndoManager();
500 const SfxItemSet
* pReqArgs
= rReq
.GetArgs();
501 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
503 sal_uInt16 nSlot
= rReq
.GetSlot();
510 bool bIsUndo
= ( nSlot
== SID_UNDO
);
512 sal_uInt16 nCount
= 1;
513 const SfxPoolItem
* pItem
;
514 if ( pReqArgs
&& pReqArgs
->GetItemState( nSlot
, true, &pItem
) == SfxItemState::SET
)
515 nCount
= static_cast<const SfxUInt16Item
*>(pItem
)->GetValue();
517 // lock paint for more than one cell undo action (not for editing within a cell)
518 bool bLockPaint
= ( nCount
> 1 && pUndoManager
== GetUndoManager() );
524 for (sal_uInt16 i
=0; i
<nCount
; i
++)
527 pUndoManager
->Undo();
529 pUndoManager
->Redo();
532 catch ( const uno::Exception
& )
534 // no need to handle. By definition, the UndoManager handled this by clearing the
539 pDocSh
->UnlockPaint();
541 GetViewFrame()->GetBindings().InvalidateAll(false);
545 // GetViewFrame()->ExecuteSlot( rReq );
549 void ScTabViewShell::GetUndoState(SfxItemSet
&rSet
)
551 SfxShell
* pSh
= GetViewData().GetDispatcher().GetShell(0);
552 ::svl::IUndoManager
* pUndoManager
= pSh
->GetUndoManager();
554 SfxWhichIter
aIter(rSet
);
555 sal_uInt16 nWhich
= aIter
.FirstWhich();
560 case SID_GETUNDOSTRINGS
:
561 case SID_GETREDOSTRINGS
:
563 SfxStringListItem
aStrLst( nWhich
);
566 std::vector
<OUString
> &aList
= aStrLst
.GetList();
567 bool bIsUndo
= ( nWhich
== SID_GETUNDOSTRINGS
);
568 size_t nCount
= bIsUndo
? pUndoManager
->GetUndoActionCount() : pUndoManager
->GetRedoActionCount();
569 for (size_t i
=0; i
<nCount
; ++i
)
571 aList
.push_back( bIsUndo
? pUndoManager
->GetUndoActionComment(i
) :
572 pUndoManager
->GetRedoActionComment(i
) );
579 // get state from sfx view frame
580 GetViewFrame()->GetSlotState( nWhich
, NULL
, &rSet
);
583 nWhich
= aIter
.NextWhich();
587 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */