tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / sc / source / ui / view / tabvwsh2.cxx
blob545f8ce8841a2e78ea89a369ec89c932bd828ddd
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
31 #include <fupoor.hxx>
32 #include <fuconrec.hxx>
33 #include <fuconpol.hxx>
34 #include <fuconarc.hxx>
35 #include <fuconuno.hxx>
36 #include <fusel.hxx>
37 #include <futext.hxx>
38 #include <fuinsert.hxx>
39 #include <sc.hrc>
40 #include <scmod.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();
59 if (pDrView)
60 pDrView->SetActualWin(pWin->GetOutDev());
62 FuPoor* pFunc = GetDrawFuncPtr();
63 if (pFunc)
64 pFunc->SetWindow(pWin);
66 // when font from InputContext is used,
67 // this must be moved to change of cursor position:
68 UpdateInputContext();
71 void ScTabViewShell::ExecDraw(SfxRequest& rReq)
73 ScModule* mod = ScModule::get();
74 mod->InputEnterHandler();
75 UpdateInputHandler();
77 MakeDrawLayer();
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 ));
93 return;
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);
103 if (pIdentifierItem)
104 eNewFormObjKind = static_cast<SdrObjKind>(pIdentifierItem->GetValue());
107 OUString sStringItemValue;
108 if ( pArgs )
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
131 bEx = true;
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????
149 bEx = !bEx;
150 nNewId = SID_OBJECT_SELECT;
152 else
153 bEx = true;
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????
163 SetDrawSelMode(bEx);
165 pView->LockBackgroundLayer( !bEx );
167 const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
168 if ( bSelectFirst )
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);
183 nDrawSfxId = nNewId;
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);
189 else
191 if (bEx || rMarkList.GetMarkCount() != 0)
192 SetDrawShellOrSub();
193 else
194 SetDrawShell(false);
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;
215 switch (nNewId)
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));
221 break;
223 case SID_DRAW_LINE:
224 case SID_DRAW_XLINE:
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:
232 case SID_DRAW_RECT:
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();
237 break;
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 );
244 break;
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));
255 break;
257 case SID_DRAW_ARC:
258 case SID_DRAW_PIE:
259 case SID_DRAW_CIRCLECUT:
260 pTabView->SetDrawFuncPtr(new FuConstArc(*this, pWin, pView, &rModel, aNewReq));
261 break;
263 case SID_DRAW_TEXT:
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();
269 break;
271 case SID_FM_CREATE_CONTROL:
272 SetDrawFormShell(true);
273 pTabView->SetDrawFuncPtr(new FuConstUnoControl(*this, pWin, pView, &rModel, aNewReq));
274 eFormObjKind = eNewFormObjKind;
275 break;
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);
292 if ( pEnumCommand )
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
302 break;
304 default:
305 break;
308 if (pTabView->GetDrawFuncPtr())
309 pTabView->GetDrawFuncPtr()->Activate();
311 rReq.Done();
313 Invalidate();
315 // Create default drawing objects via keyboard
316 // with qualifier construct directly
317 FuPoor* pFuActual = GetDrawFuncPtr();
319 if(!(pFuActual && ((rReq.GetModifier() & KEY_MOD1) || bCreateDirectly)))
320 return;
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();
329 Point aInsertPos;
330 if(!bLOKIsActive)
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) );
337 else
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();
357 if(!pDrView)
358 return;
360 SdrPageView* pPageView = pDrView->GetSdrPageView();
362 if(!pPageView)
363 return;
365 // create the default object
366 rtl::Reference<SdrObject> pObj = pFuActual->CreateDefaultObject(nNewId, aNewObjectRectangle);
368 if(!pObj)
369 return;
371 // insert into page
372 pView->InsertObjectAtView(pObj.get(), *pPageView);
374 switch ( nNewId )
376 case SID_DRAW_CAPTION:
377 case SID_DRAW_CAPTION_VERTICAL:
378 case SID_DRAW_TEXT:
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 ) ) );
385 break;
386 default:
387 break;
391 void ScTabViewShell::GetDrawState(SfxItemSet &rSet)
393 SfxWhichIter aIter(rSet);
394 sal_uInt16 nWhich = aIter.FirstWhich();
396 while ( nWhich )
398 switch ( nWhich )
400 case SID_DRAW_CHART:
402 bool bOle = GetViewFrame().GetFrame().IsInPlace();
403 if ( bOle || !SvtModuleOptions().IsChartInstalled() )
404 rSet.DisableItem( nWhich );
406 break;
408 case SID_DRAW_LINE:
409 case SID_DRAW_XLINE:
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:
418 case SID_DRAW_RECT:
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:
428 case SID_DRAW_ARC:
429 case SID_DRAW_PIE:
430 case SID_DRAW_CIRCLECUT:
431 case SID_DRAW_TEXT:
432 case SID_DRAW_TEXT_MARQUEE:
433 case SID_DRAW_CAPTION:
434 rSet.Put( SfxBoolItem( nWhich, nDrawSfxId == nWhich ) );
435 break;
437 case SID_DRAW_TEXT_VERTICAL:
438 case SID_DRAW_CAPTION_VERTICAL:
439 if ( !SvtCJKOptions::IsVerticalTextEnabled() )
440 rSet.DisableItem( nWhich );
441 else
442 rSet.Put( SfxBoolItem( nWhich, nDrawSfxId == nWhich ) );
443 break;
445 case SID_OBJECT_SELECT: // important for the old control-controller
446 rSet.Put( SfxBoolItem( nWhich, nDrawSfxId == SID_OBJECT_SELECT && IsDrawSelMode() ) );
447 break;
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() ) );
456 break;
458 nWhich = aIter.NextWhich();
462 bool ScTabViewShell::SelectObject( std::u16string_view rName )
464 ScDrawView* pView = GetViewData().GetScDrawView();
465 if (!pView)
466 return false;
468 bool bFound = pView->SelectObject( rName );
469 // DrawShell etc. is handled in MarkListHasChanged
471 return bFound;
474 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */