cid#1607171 Data race condition
[LibreOffice.git] / sd / source / ui / view / drviewse.cxx
blob2b354a104556969e5f9c725f132e524e60dbcac1
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 <config_features.h>
22 #include <com/sun/star/presentation/XPresentation2.hpp>
23 #include <com/sun/star/form/FormButtonType.hpp>
24 #include <com/sun/star/beans/XPropertySet.hpp>
25 #include <i18nutil/unicode.hxx>
26 #include <i18nutil/transliteration.hxx>
27 #include <com/sun/star/beans/PropertyValue.hpp>
28 #include <com/sun/star/uno/Any.hxx>
30 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
31 #include <comphelper/lok.hxx>
32 #include <comphelper/propertyvalue.hxx>
33 #include <editeng/editstat.hxx>
34 #include <editeng/outlobj.hxx>
35 #include <vcl/svapp.hxx>
36 #include <vcl/weld.hxx>
37 #include <svl/urlbmk.hxx>
38 #include <svx/clipfmtitem.hxx>
39 #include <svx/svdpagv.hxx>
40 #include <svx/svdopath.hxx>
41 #include <svx/svdundo.hxx>
42 #include <svx/svdorect.hxx>
43 #include <svl/eitem.hxx>
44 #include <svl/intitem.hxx>
45 #include <svl/poolitem.hxx>
46 #include <svl/stritem.hxx>
47 #include <editeng/eeitem.hxx>
48 #include <sfx2/dispatch.hxx>
49 #include <sfx2/viewfrm.hxx>
50 #include <sfx2/request.hxx>
51 #include <svx/svxids.hrc>
52 #include <editeng/flditem.hxx>
53 #include <svx/obj3d.hxx>
54 #include <svx/svdobjkind.hxx>
55 #include <svx/svdouno.hxx>
56 #include <svx/dataaccessdescriptor.hxx>
57 #include <tools/urlobj.hxx>
58 #include <sfx2/ipclient.hxx>
59 #include <avmedia/mediawindow.hxx>
60 #include <svl/urihelper.hxx>
61 #include <sfx2/docfile.hxx>
62 #include <sfx2/notebookbar/SfxNotebookBar.hxx>
63 #include <osl/diagnose.h>
65 #include <DrawViewShell.hxx>
66 #include <slideshow.hxx>
67 #include <ViewShellHint.hxx>
68 #include <framework/FrameworkHelper.hxx>
69 #include <app.hrc>
70 #include <strings.hrc>
72 #include <drawdoc.hxx>
73 #include <fusel.hxx>
74 #include <futext.hxx>
75 #include <fuconrec.hxx>
76 #include <fuconcs.hxx>
77 #include <fuconuno.hxx>
78 #include <fuconbez.hxx>
79 #include <fuediglu.hxx>
80 #include <fuconarc.hxx>
81 #include <fucon3d.hxx>
82 #include <sdresid.hxx>
83 #include <unokywds.hxx>
84 #include <Outliner.hxx>
85 #include <sdpage.hxx>
86 #include <FrameView.hxx>
87 #include <zoomlist.hxx>
88 #include <drawview.hxx>
89 #include <DrawDocShell.hxx>
90 #include <ViewShellBase.hxx>
91 #include <ToolBarManager.hxx>
92 #include <anminfo.hxx>
93 #include <optsitem.hxx>
94 #include <Window.hxx>
95 #include <fuformatpaintbrush.hxx>
96 #include <fuzoom.hxx>
97 #include <sdmod.hxx>
98 #include <basegfx/utils/zoomtools.hxx>
99 #include <officecfg/Office/Draw.hxx>
100 #include <officecfg/Office/Impress.hxx>
102 using namespace ::com::sun::star;
103 using namespace ::com::sun::star::uno;
104 using namespace ::com::sun::star::presentation;
105 using namespace ::com::sun::star::beans;
107 namespace sd {
109 // Permanent Functions
111 static void ImpAddPrintableCharactersToTextEdit(SfxRequest const & rReq, ::sd::View* pView)
113 // evtl. feed characters to activated textedit
114 const SfxItemSet* pSet = rReq.GetArgs();
116 if(!pSet)
117 return;
119 OUString aInputString;
121 if(SfxItemState::SET == pSet->GetItemState(SID_ATTR_CHAR))
122 aInputString = pSet->Get(SID_ATTR_CHAR).GetValue();
124 if(aInputString.isEmpty())
125 return;
127 OutlinerView* pOLV = pView->GetTextEditOutlinerView();
129 if(pOLV)
131 for(sal_Int32 a(0); a < aInputString.getLength(); a++)
133 vcl::KeyCode aKeyCode;
134 // tdf#38669 - create the key event using a Unicode character
135 KeyEvent aKeyEvent(aInputString[a], aKeyCode);
137 // add actual character
138 pOLV->PostKeyEvent(aKeyEvent);
143 void DrawViewShell::FuPermanent(SfxRequest& rReq)
145 // We do not execute a thing during a native slide show
147 if (SlideShow::IsRunning(GetViewShellBase()) && !SlideShow::IsInteractiveSlideshow(&GetViewShellBase())) // IASS
148 return;
150 sal_uInt16 nSId = rReq.GetSlot();
152 if( HasCurrentFunction() &&
153 ( nSId == SID_TEXTEDIT || nSId == SID_ATTR_CHAR || nSId == SID_TEXT_FITTOSIZE ||
154 nSId == SID_ATTR_CHAR_VERTICAL || nSId == SID_TEXT_FITTOSIZE_VERTICAL ) )
156 rtl::Reference<FuPoor> xFunc( GetCurrentFunction() );
158 FuText* pFuText = dynamic_cast< FuText* >( xFunc.get() );
160 if( pFuText )
162 pFuText->SetPermanent(true);
163 xFunc->ReceiveRequest( rReq );
165 Invalidate();
167 // evtl. feed characters to activated textedit
168 if(SID_ATTR_CHAR == nSId && GetView() && GetView()->IsTextEdit())
169 ImpAddPrintableCharactersToTextEdit(rReq, GetView());
171 rReq.Done();
172 return;
176 CheckLineTo (rReq);
177 sal_uInt16 nOldSId = 0;
178 bool bPermanent = false;
180 if( !mpDrawView )
181 return;
183 if(HasCurrentFunction())
185 if( (nSId == SID_FORMATPAINTBRUSH) && (GetCurrentFunction()->GetSlotID() == SID_TEXTEDIT) )
187 // save text edit mode for format paintbrush!
188 SetOldFunction( GetCurrentFunction() );
190 else
192 if(GetOldFunction() == GetCurrentFunction())
194 SetOldFunction(nullptr);
198 if ( nSId != SID_TEXTEDIT && nSId != SID_ATTR_CHAR && nSId != SID_TEXT_FITTOSIZE &&
199 nSId != SID_ATTR_CHAR_VERTICAL && nSId != SID_TEXT_FITTOSIZE_VERTICAL &&
200 nSId != SID_FORMATPAINTBRUSH &&
201 mpDrawView->IsTextEdit() )
203 mpDrawView->SdrEndTextEdit();
206 if( HasCurrentFunction() )
208 nOldSId = GetCurrentFunction()->GetSlotID();
210 if (nOldSId == nSId ||
211 ((nOldSId == SID_TEXTEDIT || nOldSId == SID_ATTR_CHAR || nOldSId == SID_TEXT_FITTOSIZE ||
212 nOldSId == SID_ATTR_CHAR_VERTICAL || nOldSId == SID_TEXT_FITTOSIZE_VERTICAL) &&
213 (nSId == SID_TEXTEDIT || nSId == SID_ATTR_CHAR || nSId == SID_TEXT_FITTOSIZE ||
214 nSId == SID_ATTR_CHAR_VERTICAL || nSId == SID_TEXT_FITTOSIZE_VERTICAL )))
216 bPermanent = true;
219 GetCurrentFunction()->Deactivate();
222 SetCurrentFunction(nullptr);
224 SfxBindings& rBind = GetViewFrame()->GetBindings();
225 rBind.Invalidate(nOldSId);
226 rBind.Update(nOldSId);
229 // for LibreOfficeKit - choosing a shape should construct it directly
230 bool bCreateDirectly = false;
232 switch ( nSId )
234 case SID_TEXTEDIT: // BASIC ???
235 case SID_ATTR_CHAR:
236 case SID_ATTR_CHAR_VERTICAL:
237 case SID_TEXT_FITTOSIZE:
238 case SID_TEXT_FITTOSIZE_VERTICAL:
240 SetCurrentFunction( FuText::Create(this, GetActiveWindow(), mpDrawView.get(), GetDoc(), rReq) );
241 GetCurrentFunction()->DoExecute(rReq);
243 SfxBindings& rBindings = GetViewFrame()->GetBindings();
244 rBindings.Invalidate( SID_ATTR_CHAR );
245 rBindings.Invalidate( SID_ATTR_CHAR_VERTICAL );
246 rBindings.Invalidate( SID_TEXT_FITTOSIZE );
247 rBindings.Invalidate( SID_TEXT_FITTOSIZE_VERTICAL );
249 // evtl. feed characters to activated textedit
250 if(SID_ATTR_CHAR == nSId && GetView() && GetView()->IsTextEdit())
251 ImpAddPrintableCharactersToTextEdit(rReq, GetView());
253 rReq.Done();
255 const SfxItemSet* pArgs = rReq.GetArgs();
256 if (pArgs && pArgs->HasItem(FN_PARAM_1))
257 bCreateDirectly = static_cast<const SfxBoolItem&>(pArgs->Get(FN_PARAM_1)).GetValue();
259 break;
261 case SID_FM_CREATE_CONTROL:
263 SetCurrentFunction( FuConstructUnoControl::Create( this, GetActiveWindow(), mpDrawView.get(), GetDoc(), rReq, bPermanent ) );
264 rReq.Done();
266 break;
268 case SID_FM_CREATE_FIELDCONTROL:
270 const SfxUnoAnyItem* pDescriptorItem = rReq.GetArg<SfxUnoAnyItem>(SID_FM_DATACCESS_DESCRIPTOR);
271 DBG_ASSERT( pDescriptorItem, "DrawViewShell::FuPermanent(SID_FM_CREATE_FIELDCONTROL): invalid request args!" );
273 if(pDescriptorItem)
275 // get the form view
276 FmFormView* pFormView = mpDrawView.get();
277 SdrPageView* pPageView = pFormView ? pFormView->GetSdrPageView() : nullptr;
279 if(pPageView)
281 svx::ODataAccessDescriptor aDescriptor(pDescriptorItem->GetValue());
282 rtl::Reference<SdrObject> pNewDBField = pFormView->CreateFieldControl(aDescriptor);
284 if(pNewDBField)
286 ::tools::Rectangle aVisArea = GetActiveWindow()->PixelToLogic(::tools::Rectangle(Point(0,0), GetActiveWindow()->GetOutputSizePixel()));
287 Point aObjPos(aVisArea.Center());
288 Size aObjSize(pNewDBField->GetLogicRect().GetSize());
289 aObjPos.AdjustX( -(aObjSize.Width() / 2) );
290 aObjPos.AdjustY( -(aObjSize.Height() / 2) );
291 ::tools::Rectangle aNewObjectRectangle(aObjPos, aObjSize);
293 pNewDBField->SetLogicRect(aNewObjectRectangle);
295 GetView()->InsertObjectAtView(pNewDBField.get(), *pPageView);
299 rReq.Done();
301 break;
303 case SID_OBJECT_SELECT:
304 case SID_OBJECT_ROTATE:
305 case SID_OBJECT_MIRROR:
306 case SID_OBJECT_CROP:
307 case SID_OBJECT_TRANSPARENCE:
308 case SID_OBJECT_GRADIENT:
309 case SID_OBJECT_SHEAR:
310 case SID_OBJECT_CROOK_ROTATE:
311 case SID_OBJECT_CROOK_SLANT:
312 case SID_OBJECT_CROOK_STRETCH:
313 case SID_CONVERT_TO_3D_LATHE:
315 sal_uInt16 nSlotId = rReq.GetSlot();
317 // toggle function
318 if( nOldSId == nSlotId )
320 nSlotId = SID_OBJECT_SELECT;
321 rReq.SetSlot( nSlotId );
324 const SdrMarkList& rMarkList = mpDrawView->GetMarkedObjectList();
325 if (nSlotId == SID_OBJECT_CROOK_ROTATE ||
326 nSlotId == SID_OBJECT_CROOK_SLANT ||
327 nSlotId == SID_OBJECT_CROOK_STRETCH)
329 if ( rMarkList.GetMarkCount() > 0 &&
330 !mpDrawView->IsCrookAllowed( mpDrawView->IsCrookNoContortion() ) )
332 if ( mpDrawView->IsPresObjSelected() )
334 std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(GetFrameWeld(),
335 VclMessageType::Info, VclButtonsType::Ok,
336 SdResId(STR_ACTION_NOTPOSSIBLE)));
337 xInfoBox->run();
339 else
341 std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(GetFrameWeld(),
342 VclMessageType::Question, VclButtonsType::YesNo,
343 SdResId(STR_ASK_FOR_CONVERT_TO_BEZIER)));
344 if (xQueryBox->run() == RET_YES )
346 // implicit transformation into bezier
347 weld::WaitObject aWait(GetFrameWeld());
348 mpDrawView->ConvertMarkedToPathObj(false);
353 else if (nSlotId == SID_OBJECT_SHEAR)
355 size_t i = 0;
356 const size_t nMarkCnt = rMarkList.GetMarkCount();
357 bool b3DObjMarked = false;
359 while (i < nMarkCnt && !b3DObjMarked)
361 if (DynCastE3dObject( rMarkList.GetMark(i)->GetMarkedSdrObj() ))
363 b3DObjMarked = true;
365 else
367 i++;
371 if ( nMarkCnt > 0 && !b3DObjMarked &&
372 (!mpDrawView->IsShearAllowed() || !mpDrawView->IsDistortAllowed()) )
374 if ( mpDrawView->IsPresObjSelected() )
376 std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(GetFrameWeld(),
377 VclMessageType::Info, VclButtonsType::Ok,
378 SdResId(STR_ACTION_NOTPOSSIBLE)));
379 xInfoBox->run();
381 else
383 std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(GetFrameWeld(),
384 VclMessageType::Question, VclButtonsType::YesNo,
385 SdResId(STR_ASK_FOR_CONVERT_TO_BEZIER)));
386 if (xQueryBox->run() == RET_YES)
388 // implicit transformation into bezier
389 weld::WaitObject aWait(GetFrameWeld());
390 mpDrawView->ConvertMarkedToPathObj(false);
396 SetCurrentFunction( FuSelection::Create(this, GetActiveWindow(), mpDrawView.get(), GetDoc(), rReq) );
397 rReq.Done();
398 Invalidate( SID_OBJECT_SELECT );
400 break;
402 case SID_DRAW_LINE:
403 case SID_DRAW_XLINE:
404 case SID_DRAW_MEASURELINE:
405 case SID_LINE_ARROW_START:
406 case SID_LINE_ARROW_END:
407 case SID_LINE_ARROWS:
408 case SID_LINE_ARROW_CIRCLE:
409 case SID_LINE_CIRCLE_ARROW:
410 case SID_LINE_ARROW_SQUARE:
411 case SID_LINE_SQUARE_ARROW:
413 case SID_DRAW_RECT:
414 case SID_DRAW_RECT_NOFILL:
415 case SID_DRAW_RECT_ROUND:
416 case SID_DRAW_RECT_ROUND_NOFILL:
417 case SID_DRAW_SQUARE:
418 case SID_DRAW_SQUARE_NOFILL:
419 case SID_DRAW_SQUARE_ROUND:
420 case SID_DRAW_SQUARE_ROUND_NOFILL:
421 case SID_DRAW_ELLIPSE:
422 case SID_DRAW_ELLIPSE_NOFILL:
423 case SID_DRAW_CIRCLE:
424 case SID_DRAW_CIRCLE_NOFILL:
425 case SID_DRAW_CAPTION:
426 case SID_DRAW_CAPTION_VERTICAL:
427 case SID_TOOL_CONNECTOR:
428 case SID_CONNECTOR_ARROW_START:
429 case SID_CONNECTOR_ARROW_END:
430 case SID_CONNECTOR_ARROWS:
431 case SID_CONNECTOR_CIRCLE_START:
432 case SID_CONNECTOR_CIRCLE_END:
433 case SID_CONNECTOR_CIRCLES:
434 case SID_CONNECTOR_LINE:
435 case SID_CONNECTOR_LINE_ARROW_START:
436 case SID_CONNECTOR_LINE_ARROW_END:
437 case SID_CONNECTOR_LINE_ARROWS:
438 case SID_CONNECTOR_LINE_CIRCLE_START:
439 case SID_CONNECTOR_LINE_CIRCLE_END:
440 case SID_CONNECTOR_LINE_CIRCLES:
441 case SID_CONNECTOR_CURVE:
442 case SID_CONNECTOR_CURVE_ARROW_START:
443 case SID_CONNECTOR_CURVE_ARROW_END:
444 case SID_CONNECTOR_CURVE_ARROWS:
445 case SID_CONNECTOR_CURVE_CIRCLE_START:
446 case SID_CONNECTOR_CURVE_CIRCLE_END:
447 case SID_CONNECTOR_CURVE_CIRCLES:
448 case SID_CONNECTOR_LINES:
449 case SID_CONNECTOR_LINES_ARROW_START:
450 case SID_CONNECTOR_LINES_ARROW_END:
451 case SID_CONNECTOR_LINES_ARROWS:
452 case SID_CONNECTOR_LINES_CIRCLE_START:
453 case SID_CONNECTOR_LINES_CIRCLE_END:
454 case SID_CONNECTOR_LINES_CIRCLES:
455 case SID_INSERT_SIGNATURELINE:
457 bCreateDirectly = comphelper::LibreOfficeKit::isActive();
458 SetCurrentFunction( FuConstructRectangle::Create( this, GetActiveWindow(), mpDrawView.get(), GetDoc(), rReq, bPermanent ) );
459 rReq.Done();
461 break;
462 case SID_DRAW_POLYGON:
463 case SID_DRAW_POLYGON_NOFILL:
464 case SID_DRAW_XPOLYGON:
465 case SID_DRAW_XPOLYGON_NOFILL:
466 case SID_DRAW_FREELINE:
467 case SID_DRAW_FREELINE_NOFILL:
468 case SID_DRAW_BEZIER_FILL: // BASIC
469 case SID_DRAW_BEZIER_NOFILL: // BASIC
471 // Direct mode means no interactive drawing, just insert the shape with reasonable
472 // defaults -- to be consistent with the line insert case above.
473 bCreateDirectly = comphelper::LibreOfficeKit::isActive();
475 SetCurrentFunction( FuConstructBezierPolygon::Create(this, GetActiveWindow(), mpDrawView.get(), GetDoc(), rReq, bPermanent) );
476 rReq.Done();
478 break;
480 case SID_GLUE_EDITMODE:
482 if (nOldSId != SID_GLUE_EDITMODE)
484 SetCurrentFunction( FuEditGluePoints::Create( this, GetActiveWindow(), mpDrawView.get(), GetDoc(), rReq, bPermanent ) );
486 else
488 GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT, SfxCallMode::ASYNCHRON);
491 rReq.Done();
493 break;
495 case SID_DRAW_ARC:
496 case SID_DRAW_CIRCLEARC:
497 case SID_DRAW_PIE:
498 case SID_DRAW_PIE_NOFILL:
499 case SID_DRAW_CIRCLEPIE:
500 case SID_DRAW_CIRCLEPIE_NOFILL:
501 case SID_DRAW_ELLIPSECUT:
502 case SID_DRAW_ELLIPSECUT_NOFILL:
503 case SID_DRAW_CIRCLECUT:
504 case SID_DRAW_CIRCLECUT_NOFILL:
506 SetCurrentFunction( FuConstructArc::Create( this, GetActiveWindow(), mpDrawView.get(), GetDoc(), rReq, bPermanent) );
507 rReq.Done();
509 break;
511 case SID_3D_CUBE:
512 case SID_3D_SHELL:
513 case SID_3D_SPHERE:
514 case SID_3D_TORUS:
515 case SID_3D_HALF_SPHERE:
516 case SID_3D_CYLINDER:
517 case SID_3D_CONE:
518 case SID_3D_PYRAMID:
520 SetCurrentFunction( FuConstruct3dObject::Create(this, GetActiveWindow(), mpDrawView.get(), GetDoc(), rReq, bPermanent ) );
521 rReq.Done();
523 break;
525 case SID_DRAWTBX_CS_BASIC :
526 case SID_DRAWTBX_CS_SYMBOL :
527 case SID_DRAWTBX_CS_ARROW :
528 case SID_DRAWTBX_CS_FLOWCHART :
529 case SID_DRAWTBX_CS_CALLOUT :
530 case SID_DRAWTBX_CS_STAR :
531 case SID_DRAW_CS_ID :
533 SetCurrentFunction( FuConstructCustomShape::Create( this, GetActiveWindow(), mpDrawView.get(), GetDoc(), rReq, bPermanent ) );
534 rReq.Done();
536 bCreateDirectly = comphelper::LibreOfficeKit::isActive();
537 const SfxItemSet* pArgs = rReq.GetArgs();
538 if (pArgs && pArgs->HasItem(FN_PARAM_1))
540 bCreateDirectly = static_cast<const SfxBoolItem&>(pArgs->Get(FN_PARAM_1)).GetValue();
543 if ( nSId != SID_DRAW_CS_ID )
545 SfxBindings& rBind = GetViewFrame()->GetBindings();
546 rBind.Invalidate( nSId );
547 rBind.Update( nSId );
550 break;
552 case SID_FORMATPAINTBRUSH:
554 SetCurrentFunction( FuFormatPaintBrush::Create( this, GetActiveWindow(), mpDrawView.get(), GetDoc(), rReq ) );
555 rReq.Done();
556 SfxBindings& rBind = GetViewFrame()->GetBindings();
557 rBind.Invalidate( nSId );
558 rBind.Update( nSId );
559 break;
562 case SID_ZOOM_MODE:
563 case SID_ZOOM_PANNING:
565 if (nOldSId != nSId)
567 mbZoomOnPage = false;
568 SetCurrentFunction( FuZoom::Create(this, GetActiveWindow(), mpDrawView.get(), GetDoc(), rReq ) );
570 else
572 GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT, SfxCallMode::ASYNCHRON);
574 rReq.Done();
576 break;
578 default:
579 break;
582 if(HasOldFunction())
584 sal_uInt16 nSlotId = GetOldFunction()->GetSlotID();
586 GetOldFunction()->Deactivate();
587 SetOldFunction(nullptr);
589 SfxBindings& rBind = GetViewFrame()->GetBindings();
590 rBind.Invalidate( nSlotId );
591 rBind.Update( nSlotId );
594 if(HasCurrentFunction())
596 GetCurrentFunction()->Activate();
597 SetOldFunction( GetCurrentFunction() );
600 // invalidate shell, is faster than every individually (says MI)
601 // now explicit the last slot incl. Update()
602 Invalidate();
604 // CTRL-SID_OBJECT_SELECT -> select first draw object if none is selected yet
605 if(SID_OBJECT_SELECT == nSId && HasCurrentFunction() && (rReq.GetModifier() & KEY_MOD1))
607 const SdrMarkList& rMarkList = GetView()->GetMarkedObjectList();
608 if(rMarkList.GetMarkCount() == 0)
610 // select first object
611 GetView()->UnmarkAllObj();
612 GetView()->MarkNextObj(true);
614 // ...and make it visible
615 if(rMarkList.GetMarkCount() != 0)
616 GetView()->MakeVisible(GetView()->GetAllMarkedRect(), *GetActiveWindow());
620 // with qualifier construct directly
621 if(!(HasCurrentFunction() && ((rReq.GetModifier() & KEY_MOD1) || bCreateDirectly)))
622 return;
624 // get SdOptions
625 SdOptions* pOptions = SdModule::get()->GetSdOptions(GetDoc()->GetDocumentType());
626 sal_uInt32 nDefaultObjectSizeWidth(pOptions->GetDefaultObjectSizeWidth());
627 sal_uInt32 nDefaultObjectSizeHeight(pOptions->GetDefaultObjectSizeHeight());
629 // calc position and size
630 ::tools::Rectangle aVisArea = GetActiveWindow()->PixelToLogic(::tools::Rectangle(Point(0,0), GetActiveWindow()->GetOutputSizePixel()));
631 if (comphelper::LibreOfficeKit::isActive())
633 // aVisArea is nonsensical in the LOK case, use the slide size
634 aVisArea = ::tools::Rectangle(Point(), getCurrentPage()->GetSize());
637 Point aPagePos = aVisArea.Center();
638 aPagePos.AdjustX( -sal_Int32(nDefaultObjectSizeWidth / 2) );
639 aPagePos.AdjustY( -sal_Int32(nDefaultObjectSizeHeight / 2) );
640 ::tools::Rectangle aNewObjectRectangle(aPagePos, Size(nDefaultObjectSizeWidth, nDefaultObjectSizeHeight));
641 SdrPageView* pPageView = mpDrawView->GetSdrPageView();
643 if(!pPageView)
644 return;
646 // create the default object
647 rtl::Reference<SdrObject> pObj = GetCurrentFunction()->CreateDefaultObject(nSId, aNewObjectRectangle);
649 if(!pObj)
650 return;
652 auto pObjTmp = pObj.get();
653 // insert into page
654 GetView()->InsertObjectAtView(pObj.get(), *pPageView);
656 // Now that pFuActual has done what it was created for we
657 // can switch on the edit mode for callout objects.
658 switch (nSId)
660 case SID_DRAW_CAPTION:
661 case SID_DRAW_CAPTION_VERTICAL:
662 case SID_ATTR_CHAR:
663 case SID_ATTR_CHAR_VERTICAL:
664 case SID_TEXT_FITTOSIZE:
665 case SID_TEXT_FITTOSIZE_VERTICAL:
667 // Make FuText the current function.
668 SfxUInt16Item aItem (SID_TEXTEDIT, 1);
669 GetViewFrame()->GetDispatcher()->
670 ExecuteList(SID_TEXTEDIT, SfxCallMode::SYNCHRON |
671 SfxCallMode::RECORD, { &aItem });
672 // Put text object into edit mode.
673 GetView()->SdrBeginTextEdit(static_cast<SdrTextObj*>(pObjTmp), pPageView);
674 break;
679 void DrawViewShell::FuDeleteSelectedObjects()
681 if( !mpDrawView )
682 return;
684 bool bConsumed = false;
686 //if any placeholders are selected
687 if (mpDrawView->IsPresObjSelected(false))
689 //If there are placeholders in the list which can be toggled
690 //off in edit->master->master elements then do that here,
691 std::vector<SdrObject*> aPresMarksToRemove;
692 const SdrMarkList& rMarkList = mpDrawView->GetMarkedObjectList();
693 for (size_t i=0; i < rMarkList.GetMarkCount(); ++i)
695 SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
696 SdPage* pPage = static_cast<SdPage*>(pObj->getSdrPageFromSdrObject());
697 PresObjKind eKind = pPage->GetPresObjKind(pObj);
698 if (eKind == PresObjKind::Footer || eKind == PresObjKind::Header ||
699 eKind == PresObjKind::DateTime || eKind == PresObjKind::SlideNumber)
701 aPresMarksToRemove.push_back(pObj);
705 for (SdrObject* pObj : aPresMarksToRemove)
707 //Unmark object
708 mpDrawView->MarkObj(pObj, mpDrawView->GetSdrPageView(), true);
709 SdPage* pPage = static_cast<SdPage*>(pObj->getSdrPageFromSdrObject());
710 //remove placeholder from master page
711 pPage->DestroyDefaultPresObj(pPage->GetPresObjKind(pObj));
714 bConsumed = true;
717 // placeholders which cannot be deleted selected
718 if (mpDrawView->IsPresObjSelected(false, true, false, true))
720 std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(GetFrameWeld(),
721 VclMessageType::Info, VclButtonsType::Ok,
722 SdResId(STR_ACTION_NOTPOSSIBLE)));
723 xInfoBox->run();
724 bConsumed = true;
727 if (bConsumed)
728 return;
730 vcl::KeyCode aKCode(KEY_DELETE);
731 KeyEvent aKEvt( 0, aKCode);
733 bConsumed = mpDrawView->getSmartTags().KeyInput( aKEvt );
735 if (!bConsumed && HasCurrentFunction())
736 bConsumed = GetCurrentFunction()->KeyInput(aKEvt);
738 if (!bConsumed)
739 mpDrawView->DeleteMarked();
742 void DrawViewShell::FuSupport(SfxRequest& rReq)
744 if( rReq.GetSlot() == SID_STYLE_FAMILY && rReq.GetArgs())
745 GetDocSh()->SetStyleFamily(static_cast<SfxStyleFamily>(rReq.GetArgs()->Get( SID_STYLE_FAMILY ).GetValue()));
747 // We do not execute a thing during a native slide show
748 if((SlideShow::IsRunning(GetViewShellBase())
749 && !SlideShow::IsInteractiveSlideshow(&GetViewShellBase())) // IASS
750 && (rReq.GetSlot() != SID_PRESENTATION_END && rReq.GetSlot() != SID_SIZE_PAGE))
751 return;
753 CheckLineTo (rReq);
755 if( !mpDrawView )
756 return;
758 sal_uInt16 nSId = rReq.GetSlot();
760 switch ( nSId )
762 case SID_CLEAR_UNDO_STACK:
764 GetDocSh()->ClearUndoBuffer();
765 rReq.Ignore ();
767 break;
769 case SID_PRESENTATION:
770 case SID_PRESENTATION_CURRENT_SLIDE:
771 case SID_REHEARSE_TIMINGS:
773 slideshowhelp::ShowSlideShow(rReq, *GetDoc());
774 rReq.Ignore ();
776 break;
778 case SID_PRESENTATION_END:
780 StopSlideShow();
782 rReq.Ignore ();
784 break;
786 case SID_BEZIER_EDIT:
788 mpDrawView->SetFrameDragSingles(!mpDrawView->IsFrameDragSingles());
790 /******************************************************************
791 * turn ObjectBar on
792 ******************************************************************/
793 if( dynamic_cast< FuSelection* >( GetCurrentFunction().get() ) || dynamic_cast< FuConstructBezierPolygon* >( GetCurrentFunction().get() ) )
795 // Tell the tool bar manager about the context change.
796 GetViewShellBase().GetToolBarManager()->SelectionHasChanged(*this,*mpDrawView);
799 Invalidate(SID_BEZIER_EDIT);
800 rReq.Ignore();
802 break;
804 case SID_OBJECT_CLOSE:
806 const SdrMarkList& rMarkList = mpDrawView->GetMarkedObjectList();
807 if ( rMarkList.GetMark(0) && !mpDrawView->IsAction() )
809 SdrPathObj* pPathObj = static_cast<SdrPathObj*>( rMarkList.GetMark(0)->GetMarkedSdrObj());
810 const bool bUndo = mpDrawView->IsUndoEnabled();
811 if( bUndo )
812 mpDrawView->BegUndo(SdResId(STR_UNDO_BEZCLOSE));
814 mpDrawView->UnmarkAllPoints();
816 if( bUndo )
817 mpDrawView->AddUndo(std::make_unique<SdrUndoGeoObj>(*pPathObj));
819 pPathObj->ToggleClosed();
821 if( bUndo )
822 mpDrawView->EndUndo();
824 rReq.Done();
826 break;
828 case SID_CUT:
830 if ( mpDrawView->IsPresObjSelected(false, true, false, true) )
832 std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(GetFrameWeld(),
833 VclMessageType::Info, VclButtonsType::Ok,
834 SdResId(STR_ACTION_NOTPOSSIBLE)));
835 xInfoBox->run();
837 else
839 //tdf#126197: EndTextEdit in all views if current one is not in TextEdit
840 if ( !mpDrawView->IsTextEdit() )
841 mpDrawView->EndTextEditAllViews();
843 if(HasCurrentFunction())
845 GetCurrentFunction()->DoCut();
847 else if(mpDrawView)
849 mpDrawView->DoCut();
852 rReq.Ignore ();
854 break;
856 case SID_COPY:
858 if ( mpDrawView->IsPresObjSelected(false, true, false, true) )
860 std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(GetFrameWeld(),
861 VclMessageType::Info, VclButtonsType::Ok,
862 SdResId(STR_ACTION_NOTPOSSIBLE)));
863 xInfoBox->run();
865 else
867 if(HasCurrentFunction())
869 GetCurrentFunction()->DoCopy();
871 else if( mpDrawView )
873 mpDrawView->DoCopy();
876 rReq.Ignore ();
878 break;
880 case SID_PASTE:
882 weld::WaitObject aWait(GetFrameWeld());
884 if(HasCurrentFunction())
886 GetCurrentFunction()->DoPaste();
888 else if(mpDrawView)
890 mpDrawView->DoPaste();
893 rReq.Ignore ();
895 break;
897 case SID_UNICODE_NOTATION_TOGGLE:
899 if( mpDrawView->IsTextEdit() )
901 OutlinerView* pOLV = mpDrawView->GetTextEditOutlinerView();
902 if( pOLV )
904 OUString sInput = pOLV->GetSurroundingText();
905 ESelection aSel( pOLV->GetSelection() );
906 if (aSel.start.nIndex > aSel.end.nIndex)
907 aSel.end.nIndex = aSel.start.nIndex;
909 //calculate a valid end-position by reading logical characters
910 sal_Int32 nUtf16Pos=0;
911 while ((nUtf16Pos < sInput.getLength()) && (nUtf16Pos < aSel.end.nIndex))
913 sInput.iterateCodePoints(&nUtf16Pos);
914 //The mouse can set the cursor in the middle of a multi-unit character,
915 // so reset to the proper end of the logical characters
916 if (nUtf16Pos > aSel.end.nIndex)
917 aSel.end.nIndex = nUtf16Pos;
920 ToggleUnicodeCodepoint aToggle;
921 while( nUtf16Pos && aToggle.AllowMoreInput( sInput[nUtf16Pos-1]) )
922 --nUtf16Pos;
923 OUString sReplacement = aToggle.ReplacementString();
924 if( !sReplacement.isEmpty() )
926 OUString sStringToReplace = aToggle.StringToReplace();
927 mpDrawView->BegUndo(sStringToReplace +"->"+ sReplacement);
928 aSel.start.nIndex = aSel.end.nIndex - sStringToReplace.getLength();
929 pOLV->SetSelection( aSel );
930 pOLV->InsertText(sReplacement, true);
931 mpDrawView->EndUndo();
936 break;
938 case SID_PASTE_UNFORMATTED:
940 weld::WaitObject aWait(GetFrameWeld());
942 if(HasCurrentFunction())
944 GetCurrentFunction()->DoPasteUnformatted();
946 else if(mpDrawView)
948 TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( GetActiveWindow() ) );
949 if (aDataHelper.GetTransferable().is())
951 sal_Int8 nAction = DND_ACTION_COPY;
952 mpDrawView->InsertData( aDataHelper,
953 GetActiveWindow()->PixelToLogic( ::tools::Rectangle( Point(), GetActiveWindow()->GetOutputSizePixel() ).Center() ),
954 nAction, false, SotClipboardFormatId::STRING);
958 rReq.Ignore ();
960 break;
962 case SID_CLIPBOARD_FORMAT_ITEMS:
964 weld::WaitObject aWait(GetFrameWeld());
965 TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( GetActiveWindow() ) );
966 const SfxItemSet* pReqArgs = rReq.GetArgs();
967 SotClipboardFormatId nFormat = SotClipboardFormatId::NONE;
969 if( pReqArgs )
971 const SfxUInt32Item* pIsActive = rReq.GetArg<SfxUInt32Item>(SID_CLIPBOARD_FORMAT_ITEMS);
972 nFormat = static_cast<SotClipboardFormatId>(pIsActive->GetValue());
975 if( nFormat != SotClipboardFormatId::NONE && aDataHelper.GetTransferable().is() )
977 sal_Int8 nAction = DND_ACTION_COPY;
979 if( !mpDrawView->InsertData( aDataHelper,
980 GetActiveWindow()->PixelToLogic( ::tools::Rectangle( Point(), GetActiveWindow()->GetOutputSizePixel() ).Center() ),
981 nAction, false, nFormat ) )
983 INetBookmark aINetBookmark( u""_ustr, u""_ustr );
985 if( ( aDataHelper.HasFormat( SotClipboardFormatId::NETSCAPE_BOOKMARK ) &&
986 aDataHelper.GetINetBookmark( SotClipboardFormatId::NETSCAPE_BOOKMARK, aINetBookmark ) ) ||
987 ( aDataHelper.HasFormat( SotClipboardFormatId::FILEGRPDESCRIPTOR ) &&
988 aDataHelper.GetINetBookmark( SotClipboardFormatId::FILEGRPDESCRIPTOR, aINetBookmark ) ) ||
989 ( aDataHelper.HasFormat( SotClipboardFormatId::UNIFORMRESOURCELOCATOR ) &&
990 aDataHelper.GetINetBookmark( SotClipboardFormatId::UNIFORMRESOURCELOCATOR, aINetBookmark ) ) )
992 InsertURLField( aINetBookmark.GetURL(), aINetBookmark.GetDescription(), u""_ustr );
997 break;
999 case SID_DELETE:
1001 if ( mpDrawView->IsTextEdit() )
1003 OutlinerView* pOLV = mpDrawView->GetTextEditOutlinerView();
1005 if (pOLV)
1007 vcl::KeyCode aKCode(KEY_DELETE);
1008 KeyEvent aKEvt( 0, aKCode);
1009 // We use SdrObjEditView to handle DEL for underflow handling
1010 (void)mpDrawView->KeyInput(aKEvt, nullptr);
1013 else
1015 mpDrawView->EndTextEditAllViews();
1016 FuDeleteSelectedObjects();
1018 rReq.Ignore ();
1020 break;
1022 case SID_NOTES_MODE:
1023 case SID_SLIDE_MASTER_MODE:
1024 case SID_NOTES_MASTER_MODE:
1025 case SID_HANDOUT_MASTER_MODE:
1027 // AutoLayouts have to be ready.
1028 GetDoc()->StopWorkStartupDelay();
1029 [[fallthrough]];
1031 case SID_DRAWINGMODE:
1032 case SID_SLIDE_SORTER_MODE:
1033 case SID_OUTLINE_MODE:
1034 // Let the sub-shell manager handle the slot handling.
1035 framework::FrameworkHelper::Instance(GetViewShellBase())->HandleModeChangeSlot(
1036 nSId,
1037 rReq);
1038 rReq.Ignore ();
1039 break;
1041 case SID_MASTERPAGE: // BASIC
1043 // AutoLayouts needs to be finished
1044 GetDoc()->StopWorkStartupDelay();
1046 const SfxItemSet* pReqArgs = rReq.GetArgs();
1048 if ( pReqArgs )
1050 const SfxBoolItem* pIsActive = rReq.GetArg<SfxBoolItem>(SID_MASTERPAGE);
1051 mbIsLayerModeActive = pIsActive->GetValue ();
1054 Broadcast (
1055 ViewShellHint(ViewShellHint::HINT_CHANGE_EDIT_MODE_START));
1057 // turn on default layer of MasterPage
1058 mpDrawView->SetActiveLayer(sUNO_LayerName_background_objects);
1060 ChangeEditMode(EditMode::MasterPage, mbIsLayerModeActive);
1062 if(HasCurrentFunction(SID_BEZIER_EDIT))
1063 GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT, SfxCallMode::ASYNCHRON);
1065 Broadcast (
1066 ViewShellHint(ViewShellHint::HINT_CHANGE_EDIT_MODE_END));
1068 InvalidateWindows();
1069 Invalidate();
1071 rReq.Done();
1073 break;
1075 case SID_CLOSE_MASTER_VIEW:
1077 Broadcast (
1078 ViewShellHint(ViewShellHint::HINT_CHANGE_EDIT_MODE_START));
1080 // Switch page back to the first one. Not doing so leads to a
1081 // crash. This seems to be some bug in the edit mode switching
1082 // and page switching methods.
1083 SwitchPage (0);
1084 ChangeEditMode(EditMode::Page, IsLayerModeActive());
1085 Broadcast (
1086 ViewShellHint(ViewShellHint::HINT_CHANGE_EDIT_MODE_END));
1088 if(HasCurrentFunction(SID_BEZIER_EDIT))
1090 GetViewFrame()->GetDispatcher()->Execute(
1091 SID_OBJECT_SELECT,
1092 SfxCallMode::ASYNCHRON);
1095 rReq.Done();
1097 break;
1099 case SID_RULER:
1101 const SfxItemSet* pReqArgs = rReq.GetArgs();
1103 // Remember old ruler state
1104 bool bOldHasRuler(HasRuler());
1106 if ( pReqArgs )
1108 const SfxBoolItem* pIsActive = rReq.GetArg<SfxBoolItem>(SID_RULER);
1109 SetRuler (pIsActive->GetValue ());
1111 else SetRuler (!HasRuler());
1113 // Did ruler state change? Tell that to SdOptions, too.
1114 bool bHasRuler(HasRuler());
1116 if(bOldHasRuler != bHasRuler)
1118 std::shared_ptr<comphelper::ConfigurationChanges> batch(
1119 comphelper::ConfigurationChanges::create());
1121 if (GetDoc()->GetDocumentType() == DocumentType::Impress)
1123 officecfg::Office::Impress::Layout::Display::Ruler::set(bHasRuler, batch);
1125 else
1127 officecfg::Office::Draw::Layout::Display::Ruler::set(bHasRuler, batch);
1130 batch->commit();
1133 Invalidate (SID_RULER);
1134 Resize();
1135 rReq.Done ();
1137 break;
1139 case SID_SIZE_PAGE:
1140 case SID_SIZE_PAGE_WIDTH: // BASIC
1142 mbZoomOnPage = ( rReq.GetSlot() == SID_SIZE_PAGE );
1144 SdrPageView* pPageView = mpDrawView->GetSdrPageView();
1146 if ( pPageView )
1148 Point aPagePos(0, 0); // = pPageView->GetOffset();
1149 Size aPageSize = pPageView->GetPage()->GetSize();
1151 aPagePos.AdjustX(aPageSize.Width() / 2 );
1152 aPageSize.setWidth( static_cast<::tools::Long>(aPageSize.Width() * 1.03) );
1154 if( rReq.GetSlot() == SID_SIZE_PAGE )
1156 aPagePos.AdjustY(aPageSize.Height() / 2 );
1157 aPageSize.setHeight( static_cast<::tools::Long>(aPageSize.Height() * 1.03) );
1158 aPagePos.AdjustY( -(aPageSize.Height() / 2) );
1160 else
1162 Point aPt = GetActiveWindow()->PixelToLogic( Point( 0, GetActiveWindow()->GetSizePixel().Height() / 2 ) );
1163 aPagePos.AdjustY(aPt.Y() );
1164 aPageSize.setHeight( 2 );
1167 aPagePos.AdjustX( -(aPageSize.Width() / 2) );
1169 SetZoomRect( ::tools::Rectangle( aPagePos, aPageSize ) );
1171 ::tools::Rectangle aVisAreaWin = GetActiveWindow()->PixelToLogic( ::tools::Rectangle( Point(0,0),
1172 GetActiveWindow()->GetOutputSizePixel()) );
1173 mpZoomList->InsertZoomRect(aVisAreaWin);
1175 Invalidate( SID_ZOOM_IN );
1176 Invalidate( SID_ZOOM_OUT );
1177 Invalidate( SID_ZOOM_PANNING );
1178 rReq.Done ();
1180 break;
1182 case SID_SIZE_REAL: // BASIC
1184 mbZoomOnPage = false;
1185 SetZoom( 100 );
1186 ::tools::Rectangle aVisAreaWin = GetActiveWindow()->PixelToLogic( ::tools::Rectangle( Point(0,0),
1187 GetActiveWindow()->GetOutputSizePixel()) );
1188 mpZoomList->InsertZoomRect(aVisAreaWin);
1189 Invalidate( SID_ZOOM_IN );
1190 Invalidate( SID_ZOOM_OUT );
1191 Invalidate( SID_ZOOM_PANNING );
1192 rReq.Done ();
1194 break;
1196 case SID_ZOOM_OUT: // BASIC
1198 const sal_uInt16 nOldZoom = GetActiveWindow()->GetZoom();
1199 const sal_uInt16 nNewZoom = basegfx::zoomtools::zoomOut(nOldZoom);
1200 SetZoom(nNewZoom);
1202 mbZoomOnPage = false;
1203 ::tools::Rectangle aVisAreaWin = GetActiveWindow()->PixelToLogic( ::tools::Rectangle( Point(0,0),
1204 GetActiveWindow()->GetOutputSizePixel()) );
1205 mpZoomList->InsertZoomRect(aVisAreaWin);
1206 Invalidate( SID_ZOOM_IN );
1207 Invalidate( SID_ZOOM_OUT );
1208 Invalidate( SID_ZOOM_PANNING );
1209 rReq.Done ();
1211 break;
1213 case SID_ZOOM_IN:
1215 const sal_uInt16 nOldZoom = GetActiveWindow()->GetZoom();
1216 const sal_uInt16 nNewZoom = basegfx::zoomtools::zoomIn(nOldZoom);
1217 SetZoom(nNewZoom);
1219 mbZoomOnPage = false;
1220 ::tools::Rectangle aVisAreaWin = GetActiveWindow()->PixelToLogic( ::tools::Rectangle( Point(0,0),
1221 GetActiveWindow()->GetOutputSizePixel()) );
1222 mpZoomList->InsertZoomRect(aVisAreaWin);
1223 Invalidate( SID_ZOOM_IN );
1224 Invalidate(SID_ZOOM_OUT);
1225 Invalidate( SID_ZOOM_PANNING );
1226 rReq.Done ();
1228 break;
1230 case SID_SIZE_VISAREA:
1232 ::tools::Rectangle aVisArea = mpFrameView->GetVisArea();
1233 Size aVisAreaSize = aVisArea.GetSize();
1235 if (!aVisAreaSize.IsEmpty())
1237 mbZoomOnPage = false;
1238 SetZoomRect(aVisArea);
1239 Invalidate( SID_ZOOM_IN );
1240 Invalidate( SID_ZOOM_OUT );
1241 Invalidate( SID_ZOOM_PANNING );
1243 rReq.Done ();
1245 break;
1247 // name confusion: SID_SIZE_OPTIMAL -> Zoom onto selected objects
1248 // --> Is offered as object zoom in program
1249 case SID_SIZE_OPTIMAL: // BASIC
1251 mbZoomOnPage = false;
1252 const SdrMarkList& rMarkList = mpDrawView->GetMarkedObjectList();
1253 if ( rMarkList.GetMarkCount() != 0 )
1255 maMarkRect = mpDrawView->GetAllMarkedRect();
1256 ::tools::Long nW = static_cast<::tools::Long>(maMarkRect.GetWidth() * 1.03);
1257 ::tools::Long nH = static_cast<::tools::Long>(maMarkRect.GetHeight() * 1.03);
1258 Point aPos = maMarkRect.Center();
1259 aPos.AdjustX( -(nW / 2) );
1260 aPos.AdjustY( -(nH / 2) );
1261 if ( nW && nH )
1263 SetZoomRect(::tools::Rectangle(aPos, Size(nW, nH)));
1265 ::tools::Rectangle aVisAreaWin = GetActiveWindow()->PixelToLogic( ::tools::Rectangle( Point(0,0),
1266 GetActiveWindow()->GetOutputSizePixel()) );
1267 mpZoomList->InsertZoomRect(aVisAreaWin);
1270 Invalidate( SID_ZOOM_IN );
1271 Invalidate( SID_ZOOM_OUT );
1272 Invalidate( SID_ZOOM_PANNING );
1273 rReq.Done ();
1275 break;
1277 // name confusion: SID_SIZE_ALL -> Zoom onto all objects
1278 // --> Is offered as optimal in program
1279 case SID_SIZE_ALL: // BASIC
1281 mbZoomOnPage = false;
1282 SdrPageView* pPageView = mpDrawView->GetSdrPageView();
1284 if( pPageView )
1286 ::tools::Rectangle aBoundRect( pPageView->GetObjList()->GetAllObjBoundRect() );
1288 ::tools::Long nW = static_cast<::tools::Long>(aBoundRect.GetWidth() * 1.03);
1289 ::tools::Long nH = static_cast<::tools::Long>(aBoundRect.GetHeight() * 1.03);
1290 Point aPos = aBoundRect.Center();
1291 aPos.AdjustX( -(nW / 2) );
1292 aPos.AdjustY( -(nH / 2) );
1293 if ( nW && nH )
1295 SetZoomRect( ::tools::Rectangle( aPos, Size( nW, nH ) ) );
1297 ::tools::Rectangle aVisAreaWin = GetActiveWindow()->PixelToLogic( ::tools::Rectangle( Point(0,0),
1298 GetActiveWindow()->GetOutputSizePixel()) );
1299 mpZoomList->InsertZoomRect(aVisAreaWin);
1302 Invalidate( SID_ZOOM_IN );
1303 Invalidate( SID_ZOOM_OUT );
1304 Invalidate( SID_ZOOM_PANNING );
1306 rReq.Done ();
1308 break;
1310 case SID_ZOOM_PREV:
1312 if (mpDrawView->IsTextEdit())
1314 mpDrawView->SdrEndTextEdit();
1317 if (mpZoomList->IsPreviousPossible())
1319 // set previous ZoomRect
1320 SetZoomRect(mpZoomList->GetPreviousZoomRect());
1322 rReq.Done ();
1324 break;
1326 case SID_ZOOM_NEXT:
1328 if (mpDrawView->IsTextEdit())
1330 mpDrawView->SdrEndTextEdit();
1333 if (mpZoomList->IsNextPossible())
1335 // set next ZoomRect
1336 SetZoomRect(mpZoomList->GetNextZoomRect());
1338 rReq.Done ();
1340 break;
1342 case SID_GLUE_INSERT_POINT:
1343 case SID_GLUE_PERCENT:
1344 case SID_GLUE_ESCDIR:
1345 case SID_GLUE_ESCDIR_LEFT:
1346 case SID_GLUE_ESCDIR_RIGHT:
1347 case SID_GLUE_ESCDIR_TOP:
1348 case SID_GLUE_ESCDIR_BOTTOM:
1349 case SID_GLUE_HORZALIGN_CENTER:
1350 case SID_GLUE_HORZALIGN_LEFT:
1351 case SID_GLUE_HORZALIGN_RIGHT:
1352 case SID_GLUE_VERTALIGN_CENTER:
1353 case SID_GLUE_VERTALIGN_TOP:
1354 case SID_GLUE_VERTALIGN_BOTTOM:
1356 rtl::Reference<FuPoor> xFunc( GetCurrentFunction() );
1357 FuEditGluePoints* pFunc = dynamic_cast< FuEditGluePoints* >( xFunc.get() );
1359 if(pFunc)
1360 pFunc->ReceiveRequest(rReq);
1362 rReq.Done();
1364 break;
1366 case SID_AUTOSPELL_CHECK:
1368 bool bOnlineSpell;
1369 const SfxPoolItem* pItem;
1371 if (rReq.GetArgs()->HasItem(FN_PARAM_1, &pItem))
1372 bOnlineSpell = static_cast<const SfxBoolItem*>(pItem)->GetValue();
1373 else // Toggle
1374 bOnlineSpell = !GetDoc()->GetOnlineSpell();
1376 GetDoc()->SetOnlineSpell(bOnlineSpell);
1378 ::Outliner* pOL = mpDrawView->GetTextEditOutliner();
1380 if (pOL)
1382 EEControlBits nCntrl = pOL->GetControlWord();
1384 if (bOnlineSpell)
1385 nCntrl |= EEControlBits::ONLINESPELLING;
1386 else
1387 nCntrl &= ~EEControlBits::ONLINESPELLING;
1389 pOL->SetControlWord(nCntrl);
1392 GetActiveWindow()->Invalidate();
1393 rReq.Done ();
1395 break;
1397 case SID_TRANSLITERATE_SENTENCE_CASE:
1398 case SID_TRANSLITERATE_TITLE_CASE:
1399 case SID_TRANSLITERATE_TOGGLE_CASE:
1400 case SID_TRANSLITERATE_UPPER:
1401 case SID_TRANSLITERATE_LOWER:
1402 case SID_TRANSLITERATE_HALFWIDTH:
1403 case SID_TRANSLITERATE_FULLWIDTH:
1404 case SID_TRANSLITERATE_HIRAGANA:
1405 case SID_TRANSLITERATE_KATAKANA:
1407 OutlinerView* pOLV = GetView()->GetTextEditOutlinerView();
1408 if( pOLV )
1410 TransliterationFlags nType = TransliterationFlags::NONE;
1412 switch( nSId )
1414 case SID_TRANSLITERATE_SENTENCE_CASE:
1415 nType = TransliterationFlags::SENTENCE_CASE;
1416 break;
1417 case SID_TRANSLITERATE_TITLE_CASE:
1418 nType = TransliterationFlags::TITLE_CASE;
1419 break;
1420 case SID_TRANSLITERATE_TOGGLE_CASE:
1421 nType = TransliterationFlags::TOGGLE_CASE;
1422 break;
1423 case SID_TRANSLITERATE_UPPER:
1424 nType = TransliterationFlags::LOWERCASE_UPPERCASE;
1425 break;
1426 case SID_TRANSLITERATE_LOWER:
1427 nType = TransliterationFlags::UPPERCASE_LOWERCASE;
1428 break;
1429 case SID_TRANSLITERATE_HALFWIDTH:
1430 nType = TransliterationFlags::FULLWIDTH_HALFWIDTH;
1431 break;
1432 case SID_TRANSLITERATE_FULLWIDTH:
1433 nType = TransliterationFlags::HALFWIDTH_FULLWIDTH;
1434 break;
1435 case SID_TRANSLITERATE_HIRAGANA:
1436 nType = TransliterationFlags::KATAKANA_HIRAGANA;
1437 break;
1438 case SID_TRANSLITERATE_KATAKANA:
1439 nType = TransliterationFlags::HIRAGANA_KATAKANA;
1440 break;
1443 pOLV->TransliterateText( nType );
1446 rReq.Done();
1448 break;
1450 // #UndoRedo#
1451 case SID_UNDO :
1453 // moved implementation to BaseClass
1454 ImpSidUndo(rReq);
1456 break;
1457 case SID_REDO :
1459 // moved implementation to BaseClass
1460 ImpSidRedo(rReq);
1462 break;
1464 default:
1465 break;
1469 void DrawViewShell::FuSupportRotate(SfxRequest const &rReq)
1471 if( rReq.GetSlot() != SID_TRANSLITERATE_ROTATE_CASE )
1472 return;
1474 ::sd::View* pView = GetView();
1476 if (!pView)
1477 return;
1479 OutlinerView* pOLV = pView->GetTextEditOutlinerView();
1481 if (!pOLV)
1482 return;
1483 TransliterationFlags transFlags = m_aRotateCase.getNextMode();
1484 if (TransliterationFlags::SENTENCE_CASE == transFlags)
1486 OUString SelectedText = pOLV->GetSelected().trim();
1487 if (SelectedText.getLength() <= 2 || (SelectedText.indexOf(' ') < 0 && SelectedText.indexOf('\t') < 0))
1488 transFlags = m_aRotateCase.getNextMode();
1490 pOLV->TransliterateText( transFlags );
1493 void DrawViewShell::InsertURLField(const OUString& rURL, const OUString& rText,
1494 const OUString& rTarget)
1496 OutlinerView* pOLV = mpDrawView->GetTextEditOutlinerView();
1498 if (pOLV)
1500 ESelection aSel( pOLV->GetSelection() );
1501 SvxFieldItem aURLItem( SvxURLField( rURL, rText, SvxURLFormat::Repr ), EE_FEATURE_FIELD );
1502 pOLV->InsertField( aURLItem );
1503 if (aSel.start.nIndex <= aSel.end.nIndex)
1504 aSel.end.nIndex = aSel.start.nIndex + 1;
1505 else
1506 aSel.start.nIndex = aSel.end.nIndex + 1;
1507 pOLV->SetSelection( aSel );
1509 else
1511 Outliner* pOutl = GetDoc()->GetInternalOutliner();
1512 pOutl->Init( OutlinerMode::TextObject );
1513 OutlinerMode nOutlMode = pOutl->GetOutlinerMode();
1515 SvxURLField aURLField(rURL, rText, SvxURLFormat::Repr);
1516 aURLField.SetTargetFrame(rTarget);
1517 SvxFieldItem aURLItem(aURLField, EE_FEATURE_FIELD);
1518 pOutl->QuickInsertField( aURLItem, ESelection() );
1519 std::optional<OutlinerParaObject> pOutlParaObject = pOutl->CreateParaObject();
1521 rtl::Reference<SdrRectObj> pRectObj = new SdrRectObj(
1522 GetView()->getSdrModelFromSdrView(),
1523 SdrObjKind::Text);
1525 pOutl->UpdateFields();
1526 pOutl->SetUpdateLayout( true );
1527 Size aSize(pOutl->CalcTextSize());
1528 pOutl->SetUpdateLayout( false );
1530 Point aPos;
1531 ::tools::Rectangle aRect(aPos, GetActiveWindow()->GetOutputSizePixel() );
1532 aPos = aRect.Center();
1533 aPos = GetActiveWindow()->PixelToLogic(aPos);
1535 if (aPos.getX() - (aSize.Width() / 2) >= 0)
1536 aPos.AdjustX( -(aSize.Width() / 2) );
1537 if (aPos.getY() - (aSize.Height() / 2) >= 0)
1538 aPos.AdjustY( -(aSize.Height() / 2) );
1540 ::tools::Rectangle aLogicRect(aPos, aSize);
1541 pRectObj->SetLogicRect(aLogicRect);
1542 pRectObj->SetOutlinerParaObject( std::move(pOutlParaObject) );
1543 mpDrawView->InsertObjectAtView(pRectObj.get(), *mpDrawView->GetSdrPageView());
1544 pOutl->Init( nOutlMode );
1548 void DrawViewShell::InsertURLButton(const OUString& rURL, const OUString& rText,
1549 const OUString& rTarget, const Point* pPos)
1551 bool bNewObj = true;
1553 const OUString sTargetURL( ::URIHelper::SmartRel2Abs( INetURLObject( GetDocSh()->GetMedium()->GetBaseURL() ), rURL, URIHelper::GetMaybeFileHdl(), true, false,
1554 INetURLObject::EncodeMechanism::WasEncoded,
1555 INetURLObject::DecodeMechanism::Unambiguous ) );
1556 const SdrMarkList& rMarkList = mpDrawView->GetMarkedObjectList();
1557 if (rMarkList.GetMarkCount() > 0)
1559 SdrObject* pMarkedObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
1560 if( pMarkedObj ) try
1562 // change first marked object
1563 if (SdrInventor::FmForm == pMarkedObj->GetObjInventor())
1565 SdrUnoObj* pUnoCtrl = static_cast< SdrUnoObj* >( pMarkedObj );
1567 Reference< awt::XControlModel > xControlModel( pUnoCtrl->GetUnoControlModel(), UNO_SET_THROW );
1568 Reference< beans::XPropertySet > xPropSet( xControlModel, UNO_QUERY_THROW );
1570 bool bIsButton = pMarkedObj->GetObjIdentifier() == SdrObjKind::FormButton;
1571 if (!bIsButton && pMarkedObj->GetObjIdentifier() == SdrObjKind::UNO)
1573 const Reference<beans::XPropertySetInfo> xInfo(xPropSet->getPropertySetInfo());
1574 bIsButton = xInfo.is() && xInfo->hasPropertyByName(u"ButtonType"_ustr)
1575 && xInfo->hasPropertyByName(u"Label"_ustr)
1576 && xInfo->hasPropertyByName(u"TargetURL"_ustr);
1578 if (bIsButton)
1580 bNewObj = false;
1582 xPropSet->setPropertyValue(u"Label"_ustr, Any(rText));
1583 xPropSet->setPropertyValue(u"TargetURL"_ustr, Any(sTargetURL));
1585 if (!rTarget.isEmpty())
1586 xPropSet->setPropertyValue(u"TargetFrame"_ustr, Any(rTarget));
1588 xPropSet->setPropertyValue(u"ButtonType"_ustr, Any(form::FormButtonType_URL));
1589 #if HAVE_FEATURE_AVMEDIA
1590 if (::avmedia::MediaWindow::isMediaURL(rURL, u""_ustr/*TODO?*/))
1592 xPropSet->setPropertyValue(u"DispatchURLInternal"_ustr, Any(true));
1594 #endif
1597 if (bNewObj)
1599 // add url as interaction for first selected shape
1600 bNewObj = false;
1602 SdAnimationInfo* pInfo = SdDrawDocument::GetShapeUserData(*pMarkedObj, true);
1603 pInfo->meClickAction = presentation::ClickAction_DOCUMENT;
1604 pInfo->SetBookmark( sTargetURL );
1607 catch( uno::Exception& )
1612 if (!bNewObj)
1613 return;
1617 rtl::Reference<SdrUnoObj> pUnoCtrl = static_cast< SdrUnoObj* >(
1618 SdrObjFactory::MakeNewObject(
1619 GetView()->getSdrModelFromSdrView(),
1620 SdrInventor::FmForm,
1621 SdrObjKind::FormButton).get()); //,
1622 //mpDrawView->GetSdrPageView()->GetPage()));
1624 Reference< awt::XControlModel > xControlModel( pUnoCtrl->GetUnoControlModel(), uno::UNO_SET_THROW );
1625 Reference< beans::XPropertySet > xPropSet( xControlModel, uno::UNO_QUERY_THROW );
1627 xPropSet->setPropertyValue( u"Label"_ustr , Any( rText ) );
1628 xPropSet->setPropertyValue( u"TargetURL"_ustr , Any( sTargetURL ) );
1630 if( !rTarget.isEmpty() )
1631 xPropSet->setPropertyValue( u"TargetFrame"_ustr , Any( rTarget ) );
1633 xPropSet->setPropertyValue( u"ButtonType"_ustr , Any( form::FormButtonType_URL ) );
1634 #if HAVE_FEATURE_AVMEDIA
1635 if ( ::avmedia::MediaWindow::isMediaURL( rURL, u""_ustr/*TODO?*/ ) )
1636 xPropSet->setPropertyValue( u"DispatchURLInternal"_ustr , Any( true ) );
1637 #endif
1639 Point aPos;
1641 if (pPos)
1643 aPos = *pPos;
1645 else
1647 aPos = ::tools::Rectangle(aPos, GetActiveWindow()->GetOutputSizePixel()).Center();
1648 aPos = GetActiveWindow()->PixelToLogic(aPos);
1651 Size aSize(4000, 1000);
1652 aPos.AdjustX( -(aSize.Width() / 2) );
1653 aPos.AdjustY( -(aSize.Height() / 2) );
1654 pUnoCtrl->SetLogicRect(::tools::Rectangle(aPos, aSize));
1656 SdrInsertFlags nOptions = SdrInsertFlags::SETDEFLAYER;
1658 OSL_ASSERT (GetViewShell()!=nullptr);
1659 SfxInPlaceClient* pIpClient = GetViewShell()->GetIPClient();
1660 if (pIpClient!=nullptr && pIpClient->IsObjectInPlaceActive())
1662 nOptions |= SdrInsertFlags::DONTMARK;
1665 mpDrawView->InsertObjectAtView(pUnoCtrl.get(), *mpDrawView->GetSdrPageView(), nOptions);
1667 catch( Exception& )
1672 void DrawViewShell::ShowUIControls (bool bVisible)
1674 ViewShell::ShowUIControls (bVisible);
1675 maTabControl->Show (bVisible);
1678 namespace slideshowhelp
1680 void ShowSlideShow(SfxRequest const & rReq, SdDrawDocument &rDoc)
1682 Reference< XPresentation2 > xPresentation( rDoc.getPresentation() );
1683 if( !xPresentation.is() )
1684 return;
1686 sfx2::SfxNotebookBar::LockNotebookBar();
1687 if (SID_REHEARSE_TIMINGS == rReq.GetSlot())
1688 xPresentation->rehearseTimings();
1689 else if (rDoc.getPresentationSettings().mbCustomShow)
1691 //fdo#69975 if a custom show has been set, then
1692 //use it whether or not we've been asked to
1693 //start from the current or first slide
1694 xPresentation->start();
1696 // if the custom show not set by default, only show it.
1697 if (rDoc.getPresentationSettings().mbStartCustomShow)
1698 rDoc.getPresentationSettings().mbCustomShow = false;
1700 else if (SID_PRESENTATION_CURRENT_SLIDE == rReq.GetSlot())
1702 //If there is no custom show set, start will automatically
1703 //start at the current page
1704 xPresentation->start();
1706 else
1708 //Start at page 0, this would blow away any custom
1709 //show settings if any were set
1710 const SfxUInt16Item* pStartingSlide = rReq.GetArg<SfxUInt16Item>(FN_PARAM_1);
1711 const sal_uInt16 nStartingSlide = pStartingSlide ? pStartingSlide->GetValue() - 1 : 0;
1712 SdPage* pSlide = rDoc.GetSdPage(nStartingSlide, PageKind::Standard);
1713 const OUString aStartingSlide = pSlide ? pSlide->GetName() : OUString();
1715 Sequence< PropertyValue > aArguments{ comphelper::makePropertyValue(u"FirstPage"_ustr,
1716 aStartingSlide) };
1717 xPresentation->startWithArguments( aArguments );
1719 sfx2::SfxNotebookBar::UnlockNotebookBar();
1723 void DrawViewShell::StopSlideShow()
1725 Reference< XPresentation2 > xPresentation( GetDoc()->getPresentation() );
1726 if(xPresentation.is() && xPresentation->isRunning())
1728 if( mpDrawView->IsTextEdit() )
1729 mpDrawView->SdrEndTextEdit();
1731 xPresentation->end();
1735 } // end of namespace sd
1737 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */