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 <comphelper/lok.hxx>
21 #include <sfx2/bindings.hxx>
22 #include <sfx2/viewfrm.hxx>
23 #include <svl/whiter.hxx>
24 #include <unotools/moduleoptions.hxx>
25 #include <svl/cjkoptions.hxx>
26 #include <sfx2/dispatch.hxx>
27 #include <tools/UnitConversion.hxx>
29 #include <tabvwsh.hxx>
30 #include <drawview.hxx>
32 #include <fuconrec.hxx>
33 #include <fuconpol.hxx>
34 #include <fuconarc.hxx>
35 #include <fuconuno.hxx>
38 #include <fuinsert.hxx>
41 #include <appoptio.hxx>
42 #include <gridwin.hxx>
44 // Create default drawing objects via keyboard
45 #include <svx/svdpagv.hxx>
46 #include <svl/stritem.hxx>
47 #include <fuconcustomshape.hxx>
49 SdrView
* ScTabViewShell::GetDrawView() const
51 return const_cast<ScTabViewShell
*>(this)->GetScDrawView(); // GetScDrawView is non-const
54 void ScTabViewShell::WindowChanged()
56 vcl::Window
* pWin
= GetActiveWin();
58 ScDrawView
* pDrView
= GetScDrawView();
60 pDrView
->SetActualWin(pWin
->GetOutDev());
62 FuPoor
* pFunc
= GetDrawFuncPtr();
64 pFunc
->SetWindow(pWin
);
66 // when font from InputContext is used,
67 // this must be moved to change of cursor position:
71 void ScTabViewShell::ExecDraw(SfxRequest
& rReq
)
73 ScModule
* mod
= ScModule::get();
74 mod
->InputEnterHandler();
79 ScTabView
* pTabView
= GetViewData().GetView();
80 SfxBindings
& rBindings
= GetViewFrame().GetBindings();
82 vcl::Window
* pWin
= pTabView
->GetActiveWin();
83 ScDrawView
* pView
= pTabView
->GetScDrawView();
84 SdrModel
& rModel
= pView
->GetModel();
86 const SfxItemSet
*pArgs
= rReq
.GetArgs();
87 sal_uInt16 nNewId
= rReq
.GetSlot();
89 if ( nNewId
== SID_DRAW_CHART
)
91 // #i71254# directly insert a chart instead of drawing its output rectangle
92 FuInsertChart(*this, pWin
, pView
, &rModel
, rReq
, LINK( this, ScTabViewShell
, DialogClosedHdl
));
96 if ( nNewId
== SID_DRAW_SELECT
)
97 nNewId
= SID_OBJECT_SELECT
;
99 SdrObjKind eNewFormObjKind
= SdrObjKind::NONE
;
100 if (nNewId
== SID_FM_CREATE_CONTROL
)
102 const SfxUInt16Item
* pIdentifierItem
= rReq
.GetArg
<SfxUInt16Item
>(SID_FM_CONTROL_IDENTIFIER
);
104 eNewFormObjKind
= static_cast<SdrObjKind
>(pIdentifierItem
->GetValue());
107 OUString sStringItemValue
;
110 const SfxPoolItem
* pItem
;
111 if ( pArgs
->GetItemState( nNewId
, true, &pItem
) == SfxItemState::SET
)
112 if (auto pStringItem
= dynamic_cast<const SfxStringItem
*>(pItem
) )
113 sStringItemValue
= pStringItem
->GetValue();
115 bool bSwitchCustom
= ( !sStringItemValue
.isEmpty() && !sDrawCustom
.isEmpty() && sStringItemValue
!= sDrawCustom
);
117 if (nNewId
== SID_INSERT_FRAME
) // from Tbx button
118 nNewId
= SID_DRAW_TEXT
;
120 // CTRL-SID_OBJECT_SELECT is used to select the first object,
121 // but not if SID_OBJECT_SELECT is the result of clicking a create function again,
122 // so this must be tested before changing nNewId below.
123 bool bSelectFirst
= ( nNewId
== SID_OBJECT_SELECT
&& (rReq
.GetModifier() & KEY_MOD1
) );
125 bool bEx
= IsDrawSelMode();
126 if ( rReq
.GetModifier() & KEY_MOD1
)
128 // always allow keyboard selection also on background layer
129 // also allow creation of default objects if the same object type
130 // was already active
133 else if ( nNewId
== nDrawSfxId
&& ( nNewId
!= SID_FM_CREATE_CONTROL
||
134 eNewFormObjKind
== eFormObjKind
|| eNewFormObjKind
== SdrObjKind::NONE
) && !bSwitchCustom
)
136 // #i52871# if a different custom shape is selected, the slot id can be the same,
137 // so the custom shape type string has to be compared, too.
139 // SID_FM_CREATE_CONTROL with eNewFormObjKind==OBJ_NONE (without parameter) comes
140 // from FuConstruct::SimpleMouseButtonUp when deactivating
141 // Execute for the form shell, to deselect the controller
142 if ( nNewId
== SID_FM_CREATE_CONTROL
)
144 GetViewData().GetDispatcher().Execute(SID_FM_LEAVE_CREATE
);
145 GetViewFrame().GetBindings().InvalidateAll(false);
146 //! what kind of slot does the weird controller really need to display this????
150 nNewId
= SID_OBJECT_SELECT
;
155 if ( nDrawSfxId
== SID_FM_CREATE_CONTROL
&& nNewId
!= nDrawSfxId
)
157 // switching from control- to paint function -> deselect in control-controller
158 GetViewData().GetDispatcher().Execute(SID_FM_LEAVE_CREATE
);
159 GetViewFrame().GetBindings().InvalidateAll(false);
160 //! what kind of slot does the weird controller really need to display this????
165 pView
->LockBackgroundLayer( !bEx
);
167 const SdrMarkList
& rMarkList
= pView
->GetMarkedObjectList();
170 // select first draw object if none is selected yet
171 if(rMarkList
.GetMarkCount() == 0)
173 // select first object
174 pView
->UnmarkAllObj();
175 pView
->MarkNextObj(true);
177 // ...and make it visible
178 if(rMarkList
.GetMarkCount() != 0)
179 pView
->MakeVisible(pView
->GetAllMarkedRect(), *pWin
);
184 sDrawCustom
.clear(); // value is set below for custom shapes
186 if (nNewId
== SID_DRAW_TEXT
|| nNewId
== SID_DRAW_TEXT_VERTICAL
187 || nNewId
== SID_DRAW_TEXT_MARQUEE
|| nNewId
== SID_DRAW_NOTEEDIT
)
188 SetDrawTextShell(true);
191 if (bEx
|| rMarkList
.GetMarkCount() != 0)
197 if (pTabView
->GetDrawFuncPtr())
199 if (pTabView
->GetDrawFuncOldPtr() != pTabView
->GetDrawFuncPtr())
200 delete pTabView
->GetDrawFuncOldPtr();
202 pTabView
->GetDrawFuncPtr()->Deactivate();
203 pTabView
->SetDrawFuncOldPtr(pTabView
->GetDrawFuncPtr());
204 pTabView
->SetDrawFuncPtr(nullptr);
207 SfxRequest
aNewReq(rReq
);
208 aNewReq
.SetSlot(nDrawSfxId
);
210 assert(nNewId
!= SID_DRAW_CHART
); //#i71254# handled already above
212 // for LibreOfficeKit - choosing a shape should construct it directly
213 bool bCreateDirectly
= false;
217 case SID_OBJECT_SELECT
:
218 // not always switch back
219 if(rMarkList
.GetMarkCount() == 0) SetDrawShell(bEx
);
220 pTabView
->SetDrawFuncPtr(new FuSelection(*this, pWin
, pView
, &rModel
, aNewReq
));
225 case SID_LINE_ARROW_END
:
226 case SID_LINE_ARROW_CIRCLE
:
227 case SID_LINE_ARROW_SQUARE
:
228 case SID_LINE_ARROW_START
:
229 case SID_LINE_CIRCLE_ARROW
:
230 case SID_LINE_SQUARE_ARROW
:
231 case SID_LINE_ARROWS
:
233 case SID_DRAW_ELLIPSE
:
234 case SID_DRAW_MEASURELINE
:
235 pTabView
->SetDrawFuncPtr(new FuConstRectangle(*this, pWin
, pView
, &rModel
, aNewReq
));
236 bCreateDirectly
= comphelper::LibreOfficeKit::isActive();
239 case SID_DRAW_CAPTION
:
240 case SID_DRAW_CAPTION_VERTICAL
:
241 pTabView
->SetDrawFuncPtr(new FuConstRectangle(*this, pWin
, pView
, &rModel
, aNewReq
));
242 pView
->SetFrameDragSingles( false );
243 rBindings
.Invalidate( SID_BEZIER_EDIT
);
246 case SID_DRAW_XPOLYGON
:
247 case SID_DRAW_XPOLYGON_NOFILL
:
248 case SID_DRAW_POLYGON
:
249 case SID_DRAW_POLYGON_NOFILL
:
250 case SID_DRAW_BEZIER_NOFILL
:
251 case SID_DRAW_BEZIER_FILL
:
252 case SID_DRAW_FREELINE
:
253 case SID_DRAW_FREELINE_NOFILL
:
254 pTabView
->SetDrawFuncPtr(new FuConstPolygon(*this, pWin
, pView
, &rModel
, aNewReq
));
259 case SID_DRAW_CIRCLECUT
:
260 pTabView
->SetDrawFuncPtr(new FuConstArc(*this, pWin
, pView
, &rModel
, aNewReq
));
264 case SID_DRAW_TEXT_VERTICAL
:
265 case SID_DRAW_TEXT_MARQUEE
:
266 case SID_DRAW_NOTEEDIT
:
267 pTabView
->SetDrawFuncPtr(new FuText(*this, pWin
, pView
, &rModel
, aNewReq
));
268 bCreateDirectly
= comphelper::LibreOfficeKit::isActive();
271 case SID_FM_CREATE_CONTROL
:
272 SetDrawFormShell(true);
273 pTabView
->SetDrawFuncPtr(new FuConstUnoControl(*this, pWin
, pView
, &rModel
, aNewReq
));
274 eFormObjKind
= eNewFormObjKind
;
277 case SID_DRAWTBX_CS_BASIC
:
278 case SID_DRAWTBX_CS_SYMBOL
:
279 case SID_DRAWTBX_CS_ARROW
:
280 case SID_DRAWTBX_CS_FLOWCHART
:
281 case SID_DRAWTBX_CS_CALLOUT
:
282 case SID_DRAWTBX_CS_STAR
:
283 case SID_DRAW_CS_ID
:
285 pTabView
->SetDrawFuncPtr(new FuConstCustomShape(*this, pWin
, pView
, &rModel
, aNewReq
));
287 bCreateDirectly
= comphelper::LibreOfficeKit::isActive();
289 if ( nNewId
!= SID_DRAW_CS_ID
)
291 const SfxStringItem
* pEnumCommand
= rReq
.GetArg
<SfxStringItem
>(nNewId
);
294 SfxBindings
& rBind
= GetViewFrame().GetBindings();
295 rBind
.Invalidate( nNewId
);
296 rBind
.Update( nNewId
);
298 sDrawCustom
= pEnumCommand
->GetValue(); // to detect when a different shape type is selected
308 if (pTabView
->GetDrawFuncPtr())
309 pTabView
->GetDrawFuncPtr()->Activate();
315 // Create default drawing objects via keyboard
316 // with qualifier construct directly
317 FuPoor
* pFuActual
= GetDrawFuncPtr();
319 if(!(pFuActual
&& ((rReq
.GetModifier() & KEY_MOD1
) || bCreateDirectly
)))
322 // Create default drawing objects via keyboard
323 const ScAppOptions
& rAppOpt
= mod
->GetAppOptions();
324 sal_uInt32 nDefaultObjectSizeWidth
= rAppOpt
.GetDefaultObjectSizeWidth();
325 sal_uInt32 nDefaultObjectSizeHeight
= rAppOpt
.GetDefaultObjectSizeHeight();
327 // calc position and size
328 bool bLOKIsActive
= comphelper::LibreOfficeKit::isActive();
332 tools::Rectangle aVisArea
= pWin
->PixelToLogic(tools::Rectangle(Point(0,0), pWin
->GetOutputSizePixel()));
333 aInsertPos
= aVisArea
.Center();
334 aInsertPos
.AdjustX( -sal_Int32(nDefaultObjectSizeWidth
/ 2) );
335 aInsertPos
.AdjustY( -sal_Int32(nDefaultObjectSizeHeight
/ 2) );
339 ScViewData
& rViewData
= GetViewData();
340 tools::Long nLayoutSign
= rViewData
.GetDocument().IsLayoutRTL(rViewData
.GetTabNo()) ? -1 : 1;
341 aInsertPos
= rViewData
.getLOKVisibleArea().Center();
342 if (comphelper::LibreOfficeKit::isCompatFlagSet(
343 comphelper::LibreOfficeKit::Compat::scPrintTwipsMsgs
))
344 aInsertPos
= rViewData
.GetPrintTwipsPosFromTileTwips(aInsertPos
);
346 aInsertPos
.setX(nLayoutSign
* convertTwipToMm100(aInsertPos
.X()));
347 aInsertPos
.setY(convertTwipToMm100(aInsertPos
.Y()));
349 aInsertPos
.AdjustX( -sal_Int32(nDefaultObjectSizeWidth
/ 2) );
350 aInsertPos
.AdjustY( -sal_Int32(nDefaultObjectSizeHeight
/ 2) );
353 tools::Rectangle
aNewObjectRectangle(aInsertPos
, Size(nDefaultObjectSizeWidth
, nDefaultObjectSizeHeight
));
355 ScDrawView
* pDrView
= GetScDrawView();
360 SdrPageView
* pPageView
= pDrView
->GetSdrPageView();
365 // create the default object
366 rtl::Reference
<SdrObject
> pObj
= pFuActual
->CreateDefaultObject(nNewId
, aNewObjectRectangle
);
372 pView
->InsertObjectAtView(pObj
.get(), *pPageView
);
376 case SID_DRAW_CAPTION
:
377 case SID_DRAW_CAPTION_VERTICAL
:
379 case SID_DRAW_TEXT_VERTICAL
:
380 // use KeyInput to start edit mode (FuText is created).
381 // For FuText objects, edit mode is handled within CreateDefaultObject.
382 // KEY_F2 is handled in FuDraw::KeyInput.
384 pFuActual
->KeyInput( KeyEvent( 0, vcl::KeyCode( KEY_F2
) ) );
391 void ScTabViewShell::GetDrawState(SfxItemSet
&rSet
)
393 SfxWhichIter
aIter(rSet
);
394 sal_uInt16 nWhich
= aIter
.FirstWhich();
402 bool bOle
= GetViewFrame().GetFrame().IsInPlace();
403 if ( bOle
|| !SvtModuleOptions().IsChartInstalled() )
404 rSet
.DisableItem( nWhich
);
410 case SID_LINE_ARROW_END
:
411 case SID_LINE_ARROW_CIRCLE
:
412 case SID_LINE_ARROW_SQUARE
:
413 case SID_LINE_ARROW_START
:
414 case SID_LINE_CIRCLE_ARROW
:
415 case SID_LINE_SQUARE_ARROW
:
416 case SID_LINE_ARROWS
:
417 case SID_DRAW_MEASURELINE
:
419 case SID_DRAW_ELLIPSE
:
420 case SID_DRAW_POLYGON
:
421 case SID_DRAW_POLYGON_NOFILL
:
422 case SID_DRAW_XPOLYGON
:
423 case SID_DRAW_XPOLYGON_NOFILL
:
424 case SID_DRAW_BEZIER_FILL
:
425 case SID_DRAW_BEZIER_NOFILL
:
426 case SID_DRAW_FREELINE
:
427 case SID_DRAW_FREELINE_NOFILL
:
430 case SID_DRAW_CIRCLECUT
:
432 case SID_DRAW_TEXT_MARQUEE
:
433 case SID_DRAW_CAPTION
:
434 rSet
.Put( SfxBoolItem( nWhich
, nDrawSfxId
== nWhich
) );
437 case SID_DRAW_TEXT_VERTICAL
:
438 case SID_DRAW_CAPTION_VERTICAL
:
439 if ( !SvtCJKOptions::IsVerticalTextEnabled() )
440 rSet
.DisableItem( nWhich
);
442 rSet
.Put( SfxBoolItem( nWhich
, nDrawSfxId
== nWhich
) );
445 case SID_OBJECT_SELECT
: // important for the old control-controller
446 rSet
.Put( SfxBoolItem( nWhich
, nDrawSfxId
== SID_OBJECT_SELECT
&& IsDrawSelMode() ) );
449 case SID_DRAWTBX_CS_BASIC
:
450 case SID_DRAWTBX_CS_SYMBOL
:
451 case SID_DRAWTBX_CS_ARROW
:
452 case SID_DRAWTBX_CS_FLOWCHART
:
453 case SID_DRAWTBX_CS_CALLOUT
:
454 case SID_DRAWTBX_CS_STAR
:
455 rSet
.Put( SfxStringItem( nWhich
, nDrawSfxId
== nWhich
? sDrawCustom
: OUString() ) );
458 nWhich
= aIter
.NextWhich();
462 bool ScTabViewShell::SelectObject( std::u16string_view rName
)
464 ScDrawView
* pView
= GetViewData().GetScDrawView();
468 bool bFound
= pView
->SelectObject( rName
);
469 // DrawShell etc. is handled in MarkListHasChanged
474 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */