Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / sw / source / uibase / docvw / SidebarTxtControl.cxx
blobd25fa9cc372b0b92a897b1f5f07ee08815a27083
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_wasm_strip.h>
22 #include "SidebarTxtControl.hxx"
24 #include <docsh.hxx>
25 #include <doc.hxx>
27 #include <PostItMgr.hxx>
29 #include <cmdid.h>
30 #include <strings.hrc>
32 #include <unotools/securityoptions.hxx>
33 #include <officecfg/Office/Common.hxx>
35 #include <sfx2/viewfrm.hxx>
36 #include <sfx2/bindings.hxx>
37 #include <sfx2/dispatch.hxx>
38 #include <sfx2/sfxhelp.hxx>
40 #include <vcl/commandevent.hxx>
41 #include <vcl/event.hxx>
42 #include <vcl/ptrstyle.hxx>
43 #include <vcl/svapp.hxx>
44 #include <vcl/weld.hxx>
45 #include <vcl/gradient.hxx>
46 #include <vcl/settings.hxx>
48 #include <editeng/outliner.hxx>
49 #include <editeng/editeng.hxx>
50 #include <editeng/editview.hxx>
51 #include <editeng/flditem.hxx>
53 #include <uitool.hxx>
54 #include <view.hxx>
55 #include <wrtsh.hxx>
56 #include <AnnotationWin.hxx>
57 #include <IDocumentDeviceAccess.hxx>
58 #include <redline.hxx>
59 #include <memory>
61 namespace sw::sidebarwindows {
63 SidebarTextControl::SidebarTextControl(sw::annotation::SwAnnotationWin& rSidebarWin,
64 SwView& rDocView,
65 SwPostItMgr& rPostItMgr)
66 : mrSidebarWin(rSidebarWin)
67 , mrDocView(rDocView)
68 , mrPostItMgr(rPostItMgr)
69 , mbMouseDownGainingFocus(false)
73 EditView* SidebarTextControl::GetEditView() const
75 OutlinerView* pOutlinerView = mrSidebarWin.GetOutlinerView();
76 if (!pOutlinerView)
77 return nullptr;
78 return &pOutlinerView->GetEditView();
81 EditEngine* SidebarTextControl::GetEditEngine() const
83 OutlinerView* pOutlinerView = mrSidebarWin.GetOutlinerView();
84 if (!pOutlinerView)
85 return nullptr;
86 return pOutlinerView->GetEditView().GetEditEngine();
89 void SidebarTextControl::SetDrawingArea(weld::DrawingArea* pDrawingArea)
91 Size aSize(0, 0);
92 pDrawingArea->set_size_request(aSize.Width(), aSize.Height());
94 SetOutputSizePixel(aSize);
96 weld::CustomWidgetController::SetDrawingArea(pDrawingArea);
98 EnableRTL(false);
100 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
101 Color aBgColor = rStyleSettings.GetWindowColor();
103 OutputDevice& rDevice = pDrawingArea->get_ref_device();
105 rDevice.SetMapMode(MapMode(MapUnit::MapTwip));
106 rDevice.SetBackground(aBgColor);
108 Size aOutputSize(rDevice.PixelToLogic(aSize));
110 EditView* pEditView = GetEditView();
111 pEditView->setEditViewCallbacks(this);
113 EditEngine* pEditEngine = GetEditEngine();
114 // For tdf#143443 note we want an 'infinite' height initially (which is the
115 // editengines default). For tdf#144686 it is helpful if the initial width
116 // is the "SidebarWidth" so the calculated text height is always meaningful
117 // for layout in the sidebar.
118 Size aPaperSize(mrPostItMgr.GetSidebarWidth(), pEditEngine->GetPaperSize().Height());
119 pEditEngine->SetPaperSize(aPaperSize);
120 pEditEngine->SetRefDevice(mrDocView.GetWrtShell().getIDocumentDeviceAccess().getReferenceDevice(false));
122 pEditView->SetOutputArea(tools::Rectangle(Point(0, 0), aOutputSize));
123 pEditView->SetBackgroundColor(aBgColor);
125 pDrawingArea->set_cursor(PointerStyle::Text);
127 #if !ENABLE_WASM_STRIP_ACCESSIBILITY
128 InitAccessible();
129 #endif
132 void SidebarTextControl::SetCursorLogicPosition(const Point& rPosition, bool bPoint, bool bClearMark)
134 Point aMousePos = EditViewOutputDevice().PixelToLogic(rPosition);
135 m_xEditView->SetCursorLogicPosition(aMousePos, bPoint, bClearMark);
138 void SidebarTextControl::GetFocus()
140 WeldEditView::GetFocus();
141 if ( !mrSidebarWin.IsMouseOver() )
142 Invalidate();
143 mrSidebarWin.SetActiveSidebarWin();
146 void SidebarTextControl::LoseFocus()
148 // write the visible text back into the SwField
149 mrSidebarWin.UpdateData();
151 WeldEditView::LoseFocus();
152 if ( !mrSidebarWin.IsMouseOver() )
154 Invalidate();
156 // set false for autoscroll to typing location
157 mrSidebarWin.LockView(false);
160 OUString SidebarTextControl::RequestHelp(tools::Rectangle& rHelpRect)
162 if (EditView* pEditView = GetEditView())
164 Point aPos = rHelpRect.TopLeft();
166 const OutputDevice& rOutDev = pEditView->GetOutputDevice();
167 Point aLogicClick = rOutDev.PixelToLogic(aPos);
168 const SvxFieldItem* pItem = pEditView->GetField(aLogicClick);
169 if (pItem)
171 const SvxFieldData* pField = pItem->GetField();
172 const SvxURLField* pURL = dynamic_cast<const SvxURLField*>( pField );
173 if (pURL)
175 rHelpRect = tools::Rectangle(aPos, Size(50, 10));
176 return SfxHelp::GetURLHelpText(pURL->GetURL());
181 TranslateId pResId;
182 switch( mrSidebarWin.GetLayoutStatus() )
184 case SwPostItHelper::INSERTED: pResId = STR_REDLINE_INSERT; break;
185 case SwPostItHelper::DELETED: pResId = STR_REDLINE_DELETE; break;
186 default: break;
189 SwContentAtPos aContentAtPos( IsAttrAtPos::Redline );
190 if ( pResId &&
191 mrDocView.GetWrtShell().GetContentAtPos( mrSidebarWin.GetAnchorPos(), aContentAtPos ) )
193 OUString sText = SwResId(pResId) + ": " +
194 aContentAtPos.aFnd.pRedl->GetAuthorString() + " - " +
195 GetAppLangDateTimeString( aContentAtPos.aFnd.pRedl->GetTimeStamp() );
196 return sText;
199 return OUString();
202 void SidebarTextControl::EditViewScrollStateChange()
204 mrSidebarWin.SetScrollbar();
207 void SidebarTextControl::DrawForPage(OutputDevice* pDev, const Point& rPt)
209 //Take the control's height, but overwrite the scrollbar area if there was one
210 OutputDevice& rDevice = GetDrawingArea()->get_ref_device();
211 Size aSize(rDevice.PixelToLogic(GetOutputSizePixel()));
213 if (OutlinerView* pOutlinerView = mrSidebarWin.GetOutlinerView())
215 pOutlinerView->GetOutliner()->Draw(*pDev, tools::Rectangle(rPt, aSize));
218 if ( mrSidebarWin.GetLayoutStatus()!=SwPostItHelper::DELETED )
219 return;
221 pDev->Push(vcl::PushFlags::LINECOLOR);
223 pDev->SetLineColor(mrSidebarWin.GetChangeColor());
224 Point aBottomRight(rPt);
225 aBottomRight.Move(aSize);
226 pDev->DrawLine(rPt, aBottomRight);
228 Point aTopRight(rPt);
229 aTopRight.Move(Size(aSize.Width(), 0));
231 Point aBottomLeft(rPt);
232 aBottomLeft.Move(Size(0, aSize.Height()));
234 pDev->DrawLine(aTopRight, aBottomLeft);
236 pDev->Pop();
239 void SidebarTextControl::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
241 Size aSize = GetOutputSizePixel();
242 Point aPos;
244 if (!rRenderContext.GetSettings().GetStyleSettings().GetHighContrastMode())
246 if (mrSidebarWin.IsMouseOverSidebarWin() || HasFocus())
248 rRenderContext.DrawGradient(tools::Rectangle(aPos, rRenderContext.PixelToLogic(aSize)),
249 Gradient(css::awt::GradientStyle_LINEAR, mrSidebarWin.ColorDark(), mrSidebarWin.ColorDark()));
251 else
253 rRenderContext.DrawGradient(tools::Rectangle(aPos, rRenderContext.PixelToLogic(aSize)),
254 Gradient(css::awt::GradientStyle_LINEAR, mrSidebarWin.ColorLight(), mrSidebarWin.ColorDark()));
258 DoPaint(rRenderContext, rRect);
260 if (mrSidebarWin.GetLayoutStatus() != SwPostItHelper::DELETED)
261 return;
263 const AntialiasingFlags nFormerAntialiasing( rRenderContext.GetAntialiasing() );
264 const bool bIsAntiAliasing = officecfg::Office::Common::Drawinglayer::AntiAliasing::get();
265 if ( bIsAntiAliasing )
266 rRenderContext.SetAntialiasing(AntialiasingFlags::Enable);
267 rRenderContext.SetLineColor(mrSidebarWin.GetChangeColor());
268 rRenderContext.DrawLine(rRenderContext.PixelToLogic(aPos),
269 rRenderContext.PixelToLogic(aPos + Point(aSize.Width(),
270 aSize.Height() * 0.95)));
271 rRenderContext.DrawLine(rRenderContext.PixelToLogic(aPos + Point(aSize.Width(),
272 0)),
273 rRenderContext.PixelToLogic(aPos + Point(0,
274 aSize.Height() * 0.95)));
275 if ( bIsAntiAliasing )
276 rRenderContext.SetAntialiasing(nFormerAntialiasing);
279 void SidebarTextControl::MakeVisible()
281 //let's make sure we see our note
282 mrPostItMgr.MakeVisible(&mrSidebarWin);
285 bool SidebarTextControl::KeyInput( const KeyEvent& rKeyEvt )
287 if (getenv("SW_DEBUG") && rKeyEvt.GetKeyCode().GetCode() == KEY_F12)
289 if (rKeyEvt.GetKeyCode().IsShift())
291 mrDocView.GetDocShell()->GetDoc()->dumpAsXml();
292 return true;
296 bool bDone = false;
298 const vcl::KeyCode& rKeyCode = rKeyEvt.GetKeyCode();
299 sal_uInt16 nKey = rKeyCode.GetCode();
300 if ( ( rKeyCode.IsMod1() && rKeyCode.IsMod2() ) &&
301 ( (nKey == KEY_PAGEUP) || (nKey == KEY_PAGEDOWN) ) )
303 mrSidebarWin.SwitchToPostIt(nKey);
304 bDone = true;
306 else if ( nKey == KEY_ESCAPE ||
307 ( rKeyCode.IsMod1() &&
308 ( nKey == KEY_PAGEUP ||
309 nKey == KEY_PAGEDOWN ) ) )
311 mrSidebarWin.SwitchToFieldPos();
312 bDone = true;
314 else if ( rKeyCode.GetFullCode() == KEY_INSERT )
316 mrSidebarWin.ToggleInsMode();
317 bDone = true;
319 else
321 MakeVisible();
323 tools::Long aOldHeight = mrSidebarWin.GetPostItTextHeight();
325 /// HACK: need to switch off processing of Undo/Redo in Outliner
326 if ( !( (nKey == KEY_Z || nKey == KEY_Y) && rKeyCode.IsMod1()) )
328 bool bIsProtected = mrSidebarWin.IsReadOnlyOrProtected();
329 if ( !bIsProtected || !EditEngine::DoesKeyChangeText(rKeyEvt) )
331 EditView* pEditView = GetEditView();
332 bDone = pEditView && pEditView->PostKeyEvent(rKeyEvt);
334 else
335 mrDocView.GetWrtShell().InfoReadOnlyDialog(false);
337 if (bDone)
338 mrSidebarWin.ResizeIfNecessary( aOldHeight, mrSidebarWin.GetPostItTextHeight() );
339 else
341 // write back data first when showing navigator
342 if ( nKey==KEY_F5 )
343 mrSidebarWin.UpdateData();
344 bDone = mrDocView.KeyInput(rKeyEvt);
348 mrDocView.GetViewFrame().GetBindings().InvalidateAll(false);
350 return bDone;
353 bool SidebarTextControl::MouseButtonDown(const MouseEvent& rMEvt)
355 if (EditView* pEditView = GetEditView())
357 bool bExecuteMod = SvtSecurityOptions::IsOptionSet( SvtSecurityOptions::EOption::CtrlClickHyperlink);
359 if ( !bExecuteMod || (rMEvt.GetModifier() == KEY_MOD1))
361 const OutputDevice& rOutDev = pEditView->GetOutputDevice();
362 Point aLogicClick = rOutDev.PixelToLogic(rMEvt.GetPosPixel());
363 if (const SvxFieldItem* pItem = pEditView->GetField(aLogicClick))
365 const SvxFieldData* pField = pItem->GetField();
366 const SvxURLField* pURL = dynamic_cast<const SvxURLField*>( pField );
367 if ( pURL )
369 pEditView->MouseButtonDown( rMEvt );
370 SwWrtShell &rSh = mrDocView.GetWrtShell();
371 const OUString& sURL( pURL->GetURL() );
372 const OUString& sTarget( pURL->GetTargetFrame() );
373 ::LoadURL(rSh, sURL, LoadUrlFlags::NONE, sTarget);
374 return true;
380 mbMouseDownGainingFocus = !HasFocus();
381 GrabFocus();
383 bool bRet = WeldEditView::MouseButtonDown(rMEvt);
385 mrDocView.GetViewFrame().GetBindings().InvalidateAll(false);
387 return bRet;
390 bool SidebarTextControl::MouseButtonUp(const MouseEvent& rMEvt)
392 bool bRet = WeldEditView::MouseButtonUp(rMEvt);
394 if (mbMouseDownGainingFocus)
396 MakeVisible();
397 mbMouseDownGainingFocus = false;
400 return bRet;
403 bool SidebarTextControl::MouseMove(const MouseEvent& rMEvt)
405 if (rMEvt.IsEnterWindow())
406 GetDrawingArea()->set_cursor(PointerStyle::Text);
407 return WeldEditView::MouseMove(rMEvt);
410 IMPL_LINK( SidebarTextControl, OnlineSpellCallback, SpellCallbackInfo&, rInfo, void )
412 if ( rInfo.nCommand == SpellCallbackCommand::STARTSPELLDLG )
414 mrDocView.GetViewFrame().GetDispatcher()->Execute( FN_SPELL_GRAMMAR_DIALOG, SfxCallMode::ASYNCHRON);
418 bool SidebarTextControl::Command( const CommandEvent& rCEvt )
420 EditView* pEditView = GetEditView();
422 if ( rCEvt.GetCommand() == CommandEventId::ContextMenu )
424 if (IsMouseCaptured())
425 ReleaseMouse();
426 if ( !mrSidebarWin.IsReadOnlyOrProtected() &&
427 pEditView &&
428 pEditView->IsWrongSpelledWordAtPos( rCEvt.GetMousePosPixel(), true ))
430 Link<SpellCallbackInfo&,void> aLink = LINK(this, SidebarTextControl, OnlineSpellCallback);
431 pEditView->ExecuteSpellPopup(rCEvt.GetMousePosPixel(), aLink);
433 else
435 Point aPos;
436 if (rCEvt.IsMouseEvent())
437 aPos = rCEvt.GetMousePosPixel();
438 else
440 const Size aSize = GetOutputSizePixel();
441 aPos = Point( aSize.getWidth()/2, aSize.getHeight()/2 );
443 SfxDispatcher::ExecutePopup(&mrSidebarWin, &aPos);
445 return true;
447 else if (rCEvt.GetCommand() == CommandEventId::Wheel)
449 // if no scrollbar, or extra keys held scroll the document and consume
450 // this event, otherwise don't consume and let the event get to the
451 // surrounding scrolled window
452 if (!mrSidebarWin.IsScrollbarVisible())
454 mrDocView.HandleWheelCommands(rCEvt);
455 return true;
457 else
459 const CommandWheelData* pData = rCEvt.GetWheelData();
460 if (pData->IsShift() || pData->IsMod1() || pData->IsMod2())
462 mrDocView.HandleWheelCommands(rCEvt);
463 return true;
468 return WeldEditView::Command(rCEvt);
471 } // end of namespace sw::sidebarwindows
473 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */