LibreOffice Module sw (master)  1
SidebarTxtControl.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include "SidebarTxtControl.hxx"
21 
22 #include "SidebarTxtControlAcc.hxx"
23 #include <docsh.hxx>
24 #include <doc.hxx>
25 
26 #include <PostItMgr.hxx>
27 #include <edtwin.hxx>
28 
29 #include <cmdid.h>
30 #include <strings.hrc>
31 
33 
34 #include <sfx2/viewfrm.hxx>
35 #include <sfx2/bindings.hxx>
36 #include <sfx2/dispatch.hxx>
37 #include <sfx2/sfxhelp.hxx>
38 
39 #include <vcl/commandevent.hxx>
40 #include <vcl/svapp.hxx>
41 #include <vcl/help.hxx>
42 #include <vcl/weld.hxx>
43 #include <vcl/gradient.hxx>
44 #include <vcl/settings.hxx>
45 
46 #include <editeng/outliner.hxx>
47 #include <editeng/editeng.hxx>
48 #include <editeng/editview.hxx>
49 #include <editeng/flditem.hxx>
50 #include <comphelper/lok.hxx>
51 #include <sfx2/lokhelper.hxx>
52 
53 #include <uitool.hxx>
54 #include <view.hxx>
55 #include <wrtsh.hxx>
56 #include <AnnotationWin.hxx>
57 #include <redline.hxx>
58 #include <memory>
59 
60 namespace sw::sidebarwindows {
61 
63  WinBits nBits,
64  SwView& rDocView,
65  SwPostItMgr& rPostItMgr )
66  : Control( &rSidebarWin, nBits )
67  , mrSidebarWin( rSidebarWin )
68  , mrDocView( rDocView )
69  , mrPostItMgr( rPostItMgr )
70  , mbMouseDownGainingFocus(false)
71 {
73 }
74 
76 {
77  disposeOnce();
78 }
79 
81 {
84 }
85 
87 {
89 }
90 
92 {
93  Window::GetFocus();
94  if ( !mrSidebarWin.IsMouseOver() )
95  {
96  Invalidate();
97  }
98 }
99 
101 {
102  // write the visible text back into the SwField
104 
105  Window::LoseFocus();
106  if ( !mrSidebarWin.IsMouseOver() )
107  {
108  Invalidate();
109  }
110 }
111 
113 {
114  const char* pResId = nullptr;
115  switch( mrSidebarWin.GetLayoutStatus() )
116  {
117  case SwPostItHelper::INSERTED: pResId = STR_REDLINE_INSERT; break;
118  case SwPostItHelper::DELETED: pResId = STR_REDLINE_DELETE; break;
119  default: pResId = nullptr;
120  }
121 
122  SwContentAtPos aContentAtPos( IsAttrAtPos::Redline );
123  if ( pResId &&
125  {
126  OUString sText = SwResId(pResId) + ": " +
127  aContentAtPos.aFnd.pRedl->GetAuthorString() + " - " +
128  GetAppLangDateTimeString( aContentAtPos.aFnd.pRedl->GetTimeStamp() );
130  }
131 }
132 
133 void SidebarTextControl::Draw(OutputDevice* pDev, const Point& rPt, DrawFlags)
134 {
135  //Take the control's height, but overwrite the scrollbar area if there was one
136  Size aSize(PixelToLogic(GetSizePixel()));
137 
138  if ( GetTextView() )
139  {
140  GetTextView()->GetOutliner()->Draw(pDev, tools::Rectangle(rPt, aSize));
141  }
142 
144  {
146  pDev->DrawLine( PixelToLogic( GetPosPixel(), pDev->GetMapMode() ),
148  Point( GetSizePixel().Width(),
149  GetSizePixel().Height() ), pDev->GetMapMode() ) );
150  pDev->DrawLine( PixelToLogic( GetPosPixel() +
151  Point( GetSizePixel().Width(),0), pDev->GetMapMode() ),
153  Point( 0, GetSizePixel().Height() ), pDev->GetMapMode() ) );
154  }
155 }
156 
158 {
159  if (!rRenderContext.GetSettings().GetStyleSettings().GetHighContrastMode())
160  {
162  {
163  rRenderContext.DrawGradient(tools::Rectangle(Point(0,0), rRenderContext.PixelToLogic(GetSizePixel())),
164  Gradient(GradientStyle::Linear, mrSidebarWin.ColorDark(), mrSidebarWin.ColorDark()));
165  }
166  else
167  {
168  rRenderContext.DrawGradient(tools::Rectangle(Point(0,0), rRenderContext.PixelToLogic(GetSizePixel())),
169  Gradient(GradientStyle::Linear, mrSidebarWin.ColorLight(), mrSidebarWin.ColorDark()));
170  }
171  }
172 
173  if (GetTextView())
174  {
175  GetTextView()->Paint(rRect, &rRenderContext);
176  }
177 
179  {
180  rRenderContext.SetLineColor(mrSidebarWin.GetChangeColor());
181  rRenderContext.DrawLine(rRenderContext.PixelToLogic(GetPosPixel()),
182  rRenderContext.PixelToLogic(GetPosPixel() + Point(GetSizePixel().Width(),
183  GetSizePixel().Height())));
184  rRenderContext.DrawLine(rRenderContext.PixelToLogic(GetPosPixel() + Point(GetSizePixel().Width(),
185  0)),
186  rRenderContext.PixelToLogic(GetPosPixel() + Point(0,
187  GetSizePixel().Height())));
188  }
189 }
190 
192 {
193  tools::Rectangle aRectangle;
194 
195  if (!pRectangle)
196  {
197  Push(PushFlags::MAPMODE);
198  EnableMapMode();
199  aRectangle = tools::Rectangle(Point(0, 0), PixelToLogic(GetSizePixel()));
200  Pop();
201  }
202  else
203  aRectangle = *pRectangle;
204 
205  // Convert from relative twips to absolute ones.
206  vcl::Window& rParent = mrSidebarWin.EditWin();
207  Point aOffset(GetOutOffXPixel() - rParent.GetOutOffXPixel(), GetOutOffYPixel() - rParent.GetOutOffYPixel());
208  rParent.Push(PushFlags::MAPMODE);
209  rParent.EnableMapMode();
210  aOffset = rParent.PixelToLogic(aOffset);
211  rParent.Pop();
212  aRectangle.Move(aOffset.getX(), aOffset.getY());
213 
214  OString sRectangle = aRectangle.toString();
215  SwWrtShell& rWrtShell = mrDocView.GetWrtShell();
216  SfxLokHelper::notifyInvalidation(rWrtShell.GetSfxViewShell(), sRectangle);
217 }
218 
220 {
221  // PostItMgr::MakeVisible can lose our MapMode, save it.
222  auto oldMapMode = GetMapMode();
223  //let's make sure we see our note
226  SetMapMode(oldMapMode);
227 }
228 
230 {
231  if (getenv("SW_DEBUG") && rKeyEvt.GetKeyCode().GetCode() == KEY_F12)
232  {
233  if (rKeyEvt.GetKeyCode().IsShift())
234  {
236  return;
237  }
238  }
239 
240  const vcl::KeyCode& rKeyCode = rKeyEvt.GetKeyCode();
241  sal_uInt16 nKey = rKeyCode.GetCode();
242  if ( ( rKeyCode.IsMod1() && rKeyCode.IsMod2() ) &&
243  ( (nKey == KEY_PAGEUP) || (nKey == KEY_PAGEDOWN) ) )
244  {
246  }
247  else if ( nKey == KEY_ESCAPE ||
248  ( rKeyCode.IsMod1() &&
249  ( nKey == KEY_PAGEUP ||
250  nKey == KEY_PAGEDOWN ) ) )
251  {
253  }
254  else if ( rKeyCode.GetFullCode() == KEY_INSERT )
255  {
257  }
258  else
259  {
260  MakeVisible();
261 
263  bool bDone = false;
264 
266  if ( !( (nKey == KEY_Z || nKey == KEY_Y) && rKeyCode.IsMod1()) )
267  {
268  bool bIsProtected = mrSidebarWin.IsProtected();
269  if ( !bIsProtected || !EditEngine::DoesKeyChangeText(rKeyEvt) )
270  {
271  bDone = GetTextView() && GetTextView()->PostKeyEvent( rKeyEvt );
272  }
273  else
274  {
275  std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "modules/swriter/ui/inforeadonlydialog.ui"));
276  std::unique_ptr<weld::MessageDialog> xQuery(xBuilder->weld_message_dialog("InfoReadonlyDialog"));
277  xQuery->run();
278  }
279  }
280  if (bDone)
282  else
283  {
284  // write back data first when showing navigator
285  if ( nKey==KEY_F5 )
287  if (!mrDocView.KeyInput(rKeyEvt))
288  Window::KeyInput(rKeyEvt);
289  }
290  }
291 
293 }
294 
296 {
297  if ( !GetTextView() )
298  return;
299 
300  OutlinerView* pOutlinerView( GetTextView() );
301  pOutlinerView->MouseMove( rMEvt );
302  // mba: why does OutlinerView not handle the modifier setting?!
303  // this forces the postit to handle *all* pointer types
304  SetPointer( pOutlinerView->GetPointer( rMEvt.GetPosPixel() ) );
305 
306  const EditView& aEV = pOutlinerView->GetEditView();
307  const SvxFieldItem* pItem = aEV.GetFieldUnderMousePointer();
308  if ( pItem )
309  {
310  const SvxFieldData* pField = pItem->GetField();
311  const SvxURLField* pURL = dynamic_cast<const SvxURLField*>( pField );
312  if ( pURL )
313  {
314  OUString sText(SfxHelp::GetURLHelpText(pURL->GetURL()));
316  this, PixelToLogic(tools::Rectangle(GetPosPixel(), Size(50, 10))), sText);
317  }
318  }
319 }
320 
322 {
323  if ( GetTextView() )
324  {
325  SvtSecurityOptions aSecOpts;
326  bool bExecuteMod = aSecOpts.IsOptionSet( SvtSecurityOptions::EOption::CtrlClickHyperlink);
327 
328  if ( !bExecuteMod || (rMEvt.GetModifier() == KEY_MOD1))
329  {
330  const EditView& aEV = GetTextView()->GetEditView();
331  const SvxFieldItem* pItem = aEV.GetFieldUnderMousePointer();
332  if ( pItem )
333  {
334  const SvxFieldData* pField = pItem->GetField();
335  const SvxURLField* pURL = dynamic_cast<const SvxURLField*>( pField );
336  if ( pURL )
337  {
338  GetTextView()->MouseButtonDown( rMEvt );
340  const OUString& sURL( pURL->GetURL() );
341  const OUString& sTarget( pURL->GetTargetFrame() );
342  ::LoadURL(rSh, sURL, LoadUrlFlags::NONE, sTarget);
343  return;
344  }
345  }
346  }
347  }
348 
350  GrabFocus();
351 
352  if ( GetTextView() )
353  {
354  GetTextView()->MouseButtonDown( rMEvt );
355  }
357 }
358 
360 {
361  if ( GetTextView() )
362  GetTextView()->MouseButtonUp( rMEvt );
364  {
365  MakeVisible();
366  mbMouseDownGainingFocus = false;
367  }
368 }
369 
370 IMPL_LINK( SidebarTextControl, OnlineSpellCallback, SpellCallbackInfo&, rInfo, void )
371 {
372  if ( rInfo.nCommand == SpellCallbackCommand::STARTSPELLDLG )
373  {
374  mrDocView.GetViewFrame()->GetDispatcher()->Execute( FN_SPELL_GRAMMAR_DIALOG, SfxCallMode::ASYNCHRON);
375  }
376 }
377 
379 {
380  if ( rCEvt.GetCommand() == CommandEventId::ContextMenu )
381  {
382  if ( !mrSidebarWin.IsProtected() &&
383  GetTextView() &&
385  {
386  Link<SpellCallbackInfo&,void> aLink = LINK(this, SidebarTextControl, OnlineSpellCallback);
388  }
389  else
390  {
391  Point aPos;
392  if (rCEvt.IsMouseEvent())
393  aPos = rCEvt.GetMousePosPixel();
394  else
395  {
396  const Size aSize = GetSizePixel();
397  aPos = Point( aSize.getWidth()/2, aSize.getHeight()/2 );
398  }
399  SfxDispatcher::ExecutePopup(this, &aPos);
400  }
401  }
402  else
403  if (rCEvt.GetCommand() == CommandEventId::Wheel)
404  {
406  {
407  const CommandWheelData* pData = rCEvt.GetWheelData();
408  if (pData->IsShift() || pData->IsMod1() || pData->IsMod2())
409  {
411  }
412  else
413  {
414  HandleScrollCommand( rCEvt, nullptr , mrSidebarWin.Scrollbar());
415  }
416  }
417  else
418  {
420  }
421  }
422  else
423  {
424  if ( GetTextView() )
425  GetTextView()->Command( rCEvt );
426  else
427  Window::Command(rCEvt);
428  }
429 }
430 
432 {
433  if (OutlinerView* pTextView = GetTextView())
434  return pTextView->GetSurroundingText();
435  return OUString();
436 }
437 
439 {
440  if (OutlinerView* pTextView = GetTextView())
441  return pTextView->GetSurroundingTextSelection();
442  return Selection( 0, 0 );
443 }
444 
446 {
447  if (OutlinerView* pTextView = GetTextView())
448  return pTextView->DeleteSurroundingText(rSelection);
449  return false;
450 }
451 
452 css::uno::Reference< css::accessibility::XAccessible > SidebarTextControl::CreateAccessible()
453 {
454 
456  css::uno::Reference< css::awt::XWindowPeer > xWinPeer( pAcc );
457  SetWindowPeer( xWinPeer, pAcc );
458 
459  css::uno::Reference< css::accessibility::XAccessible > xAcc( xWinPeer, css::uno::UNO_QUERY );
460  return xAcc;
461 }
462 
463 } // end of namespace sw::sidebarwindows
464 
465 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool IsOptionSet(EOption eOption) const
virtual Point GetPosPixel() const
bool MouseButtonDown(const MouseEvent &)
SfxViewFrame * GetViewFrame() const
virtual void Command(const CommandEvent &rCEvt) override
bool IsMod1() const
const SvxFieldItem * GetFieldUnderMousePointer() const
void ExecuteSpellPopup(const Point &rPosPixel, Link< SpellCallbackInfo &, void > const *pCallBack)
constexpr sal_uInt16 KEY_MOD1
OUString const & GetAuthorString(sal_uInt16 nPos=0) const
Definition: docredln.cxx:1755
SwPostItHelper::SwLayoutStatus GetLayoutStatus() const
std::unique_ptr< ContentProperties > pData
virtual css::uno::Reference< css::accessibility::XAccessible > CreateAccessible() override
virtual void MouseMove(const MouseEvent &rMEvt) override
tools::Long getWidth() const
long Long
const StyleSettings & GetStyleSettings() const
constexpr sal_uInt16 KEY_F5
tools::Long GetOutOffXPixel() const
bool MouseButtonUp(const MouseEvent &)
IMPL_LINK(SidebarTextControl, OnlineSpellCallback, SpellCallbackInfo &, rInfo, void)
virtual Size GetSizePixel() const
void Draw(OutputDevice *pOutDev, const tools::Rectangle &rOutRect)
static weld::Builder * CreateBuilder(weld::Widget *pParent, const OUString &rUIFile, bool bMobile=false)
bool IsShift() const
const MapMode & GetMapMode() const
sal_uInt16 GetCode() const
virtual bool DeleteSurroundingText(const Selection &rSelection) override
void EnableMapMode(bool bEnable=true)
const CommandWheelData * GetWheelData() const
SfxViewShell * GetSfxViewShell() const
Definition: viewsh.hxx:441
virtual Selection GetSurroundingTextSelection() const override
OUString GetAppLangDateTimeString(const DateTime &)
Definition: uitool.cxx:800
bool HandleScrollCommand(const CommandEvent &rCmd, ScrollBar *pHScrl, ScrollBar *pVScrl)
const OUString & GetTargetFrame() const
constexpr sal_uInt16 KEY_Y
void SetMapMode()
void ExecutePopup(const OUString &rResName, vcl::Window *pWin=nullptr, const Point *pPos=nullptr)
SwWrtShell & GetWrtShell() const
Definition: view.hxx:399
Used by the UI to modify the document model.
Definition: wrtsh.hxx:90
weld::Window * GetFrameWeld() const
sal_Int64 WinBits
void LoadURL(SwViewShell &rVSh, const OUString &rURL, LoadUrlFlags nFilter, const OUString &rTargetFrameName)
Definition: wrtsh2.cxx:478
static void notifyInvalidation(SfxViewShell const *pThisView, const OString &rPayload)
virtual void Draw(OutputDevice *pDev, const Point &, DrawFlags) override
virtual void MouseButtonDown(const MouseEvent &rMouseEvent) override
bool IsMouseEvent() const
const DateTime & GetTimeStamp(sal_uInt16 nPos=0) const
Definition: docredln.cxx:1760
constexpr sal_uInt16 KEY_PAGEUP
bool GetHighContrastMode() const
union SwContentAtPos::@24 aFnd
SidebarTextControl(sw::annotation::SwAnnotationWin &rSidebarWin, WinBits nBits, SwView &rDocView, SwPostItMgr &rPostItMgr)
void DrawLine(const Point &rStartPt, const Point &rEndPt)
PointerStyle GetPointer(const Point &rPosPixel)
virtual void Paint(vcl::RenderContext &rRenderContext, const tools::Rectangle &rRect) override
void LogicInvalidate(const tools::Rectangle *pRectangle) override
EditView & GetEditView() const
const Point & GetMousePosPixel() const
SwDoc * GetDoc()
returns Doc. But be careful!
Definition: docsh.hxx:203
tools::Long getHeight() const
static bool DoesKeyChangeText(const KeyEvent &rKeyEvent)
void SetLineColor()
void SetWindowPeer(css::uno::Reference< css::awt::XWindowPeer > const &xPeer, VCLXWindow *pVCLXWindow)
DrawFlags
virtual void RequestHelp(const HelpEvent &rEvt) override
void dumpAsXml(xmlTextWriterPtr=nullptr) const
Dumps the entire nodes structure to the given destination (file nodes.xml in the current directory by...
Definition: docfmt.cxx:1932
bool IsMod2() const
SfxBindings & GetBindings()
const Color & GetChangeColor() const
virtual void Invalidate(InvalidateFlags nFlags=InvalidateFlags::NONE)
void MakeVisible(const sw::annotation::SwAnnotationWin *pPostIt)
Definition: PostItMgr.cxx:1072
CommandEventId GetCommand() const
constexpr sal_uInt16 KEY_PAGEDOWN
Outliner * GetOutliner() const
void SwitchToPostIt(sal_uInt16 aDirection)
virtual void dispose() override
const AllSettings & GetSettings() const
OUString SwResId(const char *pId)
Definition: swmodule.cxx:166
bool MouseMove(const MouseEvent &)
sal_uInt16 GetModifier() const
void ResizeIfNecessary(tools::Long aOldHeight, tools::Long aNewHeight)
void GrabFocus()
static void ShowQuickHelp(vcl::Window *pParent, const tools::Rectangle &rScreenRect, const OUString &rHelpText, QuickHelpFlags nStyle=QuickHelpFlags::NONE)
SwDocShell * GetDocShell()
Definition: view.cxx:1109
tools::Long GetOutOffYPixel() const
const OUString & GetURL() const
const Point & GetMousePosPixel() const
Point PixelToLogic(const Point &rDevicePt) const
void AddEventListener(const Link< VclWindowEvent &, void > &rEventListener)
void SetPointer(PointerStyle)
const vcl::KeyCode & GetKeyCode() const
bool IsShift() const
bool IsMouseOver() const
#define FN_SPELL_GRAMMAR_DIALOG
Definition: cmdid.h:601
constexpr sal_uInt16 KEY_ESCAPE
virtual void KeyInput(const KeyEvent &rKeyEvt) override
constexpr sal_uInt16 KEY_F12
bool PostKeyEvent(const KeyEvent &rKEvt, vcl::Window const *pFrameWin=nullptr)
bool IsMod1() const
const Point & GetPosPixel() const
sal_uInt16 GetFullCode() const
const SwRangeRedline * pRedl
Definition: crsrsh.hxx:97
void Move(tools::Long nHorzMoveDelta, tools::Long nVertMoveDelta)
virtual bool KeyInput(const KeyEvent &rKeyEvent)
constexpr sal_uInt16 KEY_Z
void InvalidateAll(bool bWithMsg)
void RemoveEventListener(const Link< VclWindowEvent &, void > &rEventListener)
bool HandleWheelCommands(const CommandEvent &)
Definition: viewport.cxx:1194
bool GetContentAtPos(const Point &rPt, SwContentAtPos &rContentAtPos, bool bSetCursor=false, SwRect *pFieldRect=nullptr)
Definition: crstrvl.cxx:1246
constexpr sal_uInt16 KEY_INSERT
virtual OUString GetSurroundingText() const override
rtl::OString toString() const
static OUString GetURLHelpText(std::u16string_view)
bool Command(const CommandEvent &rCEvt)
bool HasFocus() const
void Push(PushFlags nFlags=PushFlags::ALL)
void DrawGradient(const tools::Rectangle &rRect, const Gradient &rGradient)
sw::annotation::SwAnnotationWin & mrSidebarWin
Definition: view.hxx:144
virtual void MouseButtonUp(const MouseEvent &rMEvt) override
const SvxFieldData * GetField() const
bool IsMod2() const
bool IsWrongSpelledWordAtPos(const Point &rPosPixel, bool bMarkIfWrong=false)
void Paint(const tools::Rectangle &rRect, OutputDevice *pTargetDevice=nullptr)