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 {
72 }
73 
75 {
76  disposeOnce();
77 }
78 
80 {
83 }
84 
86 {
88 }
89 
91 {
92  Window::GetFocus();
93  if ( !mrSidebarWin.IsMouseOver() )
94  {
95  Invalidate();
96  }
97 }
98 
100 {
101  // write the visible text back into the SwField
103 
104  Window::LoseFocus();
105  if ( !mrSidebarWin.IsMouseOver() )
106  {
107  Invalidate();
108  }
109 }
110 
112 {
113  const char* pResId = nullptr;
114  switch( mrSidebarWin.GetLayoutStatus() )
115  {
116  case SwPostItHelper::INSERTED: pResId = STR_REDLINE_INSERT; break;
117  case SwPostItHelper::DELETED: pResId = STR_REDLINE_DELETE; break;
118  default: pResId = nullptr;
119  }
120 
121  SwContentAtPos aContentAtPos( IsAttrAtPos::Redline );
122  if ( pResId &&
124  {
125  OUString sText = SwResId(pResId) + ": " +
126  aContentAtPos.aFnd.pRedl->GetAuthorString() + " - " +
127  GetAppLangDateTimeString( aContentAtPos.aFnd.pRedl->GetTimeStamp() );
129  }
130 }
131 
132 void SidebarTextControl::Draw(OutputDevice* pDev, const Point& rPt, DrawFlags)
133 {
134  //Take the control's height, but overwrite the scrollbar area if there was one
135  Size aSize(PixelToLogic(GetSizePixel()));
136 
137  if ( GetTextView() )
138  {
139  GetTextView()->GetOutliner()->Draw(pDev, tools::Rectangle(rPt, aSize));
140  }
141 
143  {
145  pDev->DrawLine( PixelToLogic( GetPosPixel(), pDev->GetMapMode() ),
147  Point( GetSizePixel().Width(),
148  GetSizePixel().Height() ), pDev->GetMapMode() ) );
149  pDev->DrawLine( PixelToLogic( GetPosPixel() +
150  Point( GetSizePixel().Width(),0), pDev->GetMapMode() ),
152  Point( 0, GetSizePixel().Height() ), pDev->GetMapMode() ) );
153  }
154 }
155 
157 {
158  if (!rRenderContext.GetSettings().GetStyleSettings().GetHighContrastMode())
159  {
161  {
162  rRenderContext.DrawGradient(tools::Rectangle(Point(0,0), rRenderContext.PixelToLogic(GetSizePixel())),
163  Gradient(GradientStyle::Linear, mrSidebarWin.ColorDark(), mrSidebarWin.ColorDark()));
164  }
165  else
166  {
167  rRenderContext.DrawGradient(tools::Rectangle(Point(0,0), rRenderContext.PixelToLogic(GetSizePixel())),
168  Gradient(GradientStyle::Linear, mrSidebarWin.ColorLight(), mrSidebarWin.ColorDark()));
169  }
170  }
171 
172  if (GetTextView())
173  {
174  GetTextView()->Paint(rRect, &rRenderContext);
175  }
176 
178  {
179  rRenderContext.SetLineColor(mrSidebarWin.GetChangeColor());
180  rRenderContext.DrawLine(rRenderContext.PixelToLogic(GetPosPixel()),
181  rRenderContext.PixelToLogic(GetPosPixel() + Point(GetSizePixel().Width(),
182  GetSizePixel().Height())));
183  rRenderContext.DrawLine(rRenderContext.PixelToLogic(GetPosPixel() + Point(GetSizePixel().Width(),
184  0)),
185  rRenderContext.PixelToLogic(GetPosPixel() + Point(0,
186  GetSizePixel().Height())));
187  }
188 }
189 
191 {
192  tools::Rectangle aRectangle;
193 
194  if (!pRectangle)
195  {
196  Push(PushFlags::MAPMODE);
197  EnableMapMode();
198  aRectangle = tools::Rectangle(Point(0, 0), PixelToLogic(GetSizePixel()));
199  Pop();
200  }
201  else
202  aRectangle = *pRectangle;
203 
204  // Convert from relative twips to absolute ones.
205  vcl::Window& rParent = mrSidebarWin.EditWin();
206  Point aOffset(GetOutOffXPixel() - rParent.GetOutOffXPixel(), GetOutOffYPixel() - rParent.GetOutOffYPixel());
207  rParent.Push(PushFlags::MAPMODE);
208  rParent.EnableMapMode();
209  aOffset = rParent.PixelToLogic(aOffset);
210  rParent.Pop();
211  aRectangle.Move(aOffset.getX(), aOffset.getY());
212 
213  OString sRectangle = aRectangle.toString();
214  SwWrtShell& rWrtShell = mrDocView.GetWrtShell();
215  SfxLokHelper::notifyInvalidation(rWrtShell.GetSfxViewShell(), sRectangle);
216 }
217 
219 {
220  if (getenv("SW_DEBUG") && rKeyEvt.GetKeyCode().GetCode() == KEY_F12)
221  {
222  if (rKeyEvt.GetKeyCode().IsShift())
223  {
225  return;
226  }
227  }
228 
229  const vcl::KeyCode& rKeyCode = rKeyEvt.GetKeyCode();
230  sal_uInt16 nKey = rKeyCode.GetCode();
231  if ( ( rKeyCode.IsMod1() && rKeyCode.IsMod2() ) &&
232  ( (nKey == KEY_PAGEUP) || (nKey == KEY_PAGEDOWN) ) )
233  {
235  }
236  else if ( nKey == KEY_ESCAPE ||
237  ( rKeyCode.IsMod1() &&
238  ( nKey == KEY_PAGEUP ||
239  nKey == KEY_PAGEDOWN ) ) )
240  {
242  }
243  else if ( rKeyCode.GetFullCode() == KEY_INSERT )
244  {
246  }
247  else
248  {
249  // MakeVisible can lose our MapMode, save it.
250  auto oldMapMode = GetMapMode();
251  //let's make sure we see our note
254  SetMapMode(oldMapMode);
255 
257  bool bDone = false;
258 
260  if ( !( (nKey == KEY_Z || nKey == KEY_Y) && rKeyCode.IsMod1()) )
261  {
262  bool bIsProtected = mrSidebarWin.IsProtected();
263  if ( !bIsProtected || !EditEngine::DoesKeyChangeText(rKeyEvt) )
264  {
265  bDone = GetTextView() && GetTextView()->PostKeyEvent( rKeyEvt );
266  }
267  else
268  {
269  std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "modules/swriter/ui/inforeadonlydialog.ui"));
270  std::unique_ptr<weld::MessageDialog> xQuery(xBuilder->weld_message_dialog("InfoReadonlyDialog"));
271  xQuery->run();
272  }
273  }
274  if (bDone)
276  else
277  {
278  // write back data first when showing navigator
279  if ( nKey==KEY_F5 )
281  if (!mrDocView.KeyInput(rKeyEvt))
282  Window::KeyInput(rKeyEvt);
283  }
284  }
285 
287 }
288 
290 {
291  if ( !GetTextView() )
292  return;
293 
294  OutlinerView* pOutlinerView( GetTextView() );
295  pOutlinerView->MouseMove( rMEvt );
296  // mba: why does OutlinerView not handle the modifier setting?!
297  // this forces the postit to handle *all* pointer types
298  SetPointer( pOutlinerView->GetPointer( rMEvt.GetPosPixel() ) );
299 
300  const EditView& aEV = pOutlinerView->GetEditView();
301  const SvxFieldItem* pItem = aEV.GetFieldUnderMousePointer();
302  if ( pItem )
303  {
304  const SvxFieldData* pField = pItem->GetField();
305  const SvxURLField* pURL = dynamic_cast<const SvxURLField*>( pField );
306  if ( pURL )
307  {
308  OUString sText(SfxHelp::GetURLHelpText(pURL->GetURL()));
310  this, PixelToLogic(tools::Rectangle(GetPosPixel(), Size(50, 10))), sText);
311  }
312  }
313 }
314 
316 {
317  if ( GetTextView() )
318  {
319  SvtSecurityOptions aSecOpts;
320  bool bExecuteMod = aSecOpts.IsOptionSet( SvtSecurityOptions::EOption::CtrlClickHyperlink);
321 
322  if ( !bExecuteMod || (rMEvt.GetModifier() == KEY_MOD1))
323  {
324  const EditView& aEV = GetTextView()->GetEditView();
325  const SvxFieldItem* pItem = aEV.GetFieldUnderMousePointer();
326  if ( pItem )
327  {
328  const SvxFieldData* pField = pItem->GetField();
329  const SvxURLField* pURL = dynamic_cast<const SvxURLField*>( pField );
330  if ( pURL )
331  {
332  GetTextView()->MouseButtonDown( rMEvt );
334  const OUString& sURL( pURL->GetURL() );
335  const OUString& sTarget( pURL->GetTargetFrame() );
336  ::LoadURL(rSh, sURL, LoadUrlFlags::NONE, sTarget);
337  return;
338  }
339  }
340  }
341  }
342 
343  GrabFocus();
344  if ( GetTextView() )
345  {
346  GetTextView()->MouseButtonDown( rMEvt );
347  }
349 }
350 
352 {
353  if ( GetTextView() )
354  GetTextView()->MouseButtonUp( rMEvt );
355 }
356 
357 IMPL_LINK( SidebarTextControl, OnlineSpellCallback, SpellCallbackInfo&, rInfo, void )
358 {
359  if ( rInfo.nCommand == SpellCallbackCommand::STARTSPELLDLG )
360  {
361  mrDocView.GetViewFrame()->GetDispatcher()->Execute( FN_SPELL_GRAMMAR_DIALOG, SfxCallMode::ASYNCHRON);
362  }
363 }
364 
366 {
367  if ( rCEvt.GetCommand() == CommandEventId::ContextMenu )
368  {
369  if ( !mrSidebarWin.IsProtected() &&
370  GetTextView() &&
372  {
373  Link<SpellCallbackInfo&,void> aLink = LINK(this, SidebarTextControl, OnlineSpellCallback);
375  }
376  else
377  {
378  Point aPos;
379  if (rCEvt.IsMouseEvent())
380  aPos = rCEvt.GetMousePosPixel();
381  else
382  {
383  const Size aSize = GetSizePixel();
384  aPos = Point( aSize.getWidth()/2, aSize.getHeight()/2 );
385  }
386  SfxDispatcher::ExecutePopup(this, &aPos);
387  }
388  }
389  else
390  if (rCEvt.GetCommand() == CommandEventId::Wheel)
391  {
393  {
394  const CommandWheelData* pData = rCEvt.GetWheelData();
395  if (pData->IsShift() || pData->IsMod1() || pData->IsMod2())
396  {
398  }
399  else
400  {
401  HandleScrollCommand( rCEvt, nullptr , mrSidebarWin.Scrollbar());
402  }
403  }
404  else
405  {
407  }
408  }
409  else
410  {
411  if ( GetTextView() )
412  GetTextView()->Command( rCEvt );
413  else
414  Window::Command(rCEvt);
415  }
416 }
417 
419 {
420  if (GetTextView())
421  return GetTextView()->GetSurroundingText();
422  return OUString();
423 }
424 
426 {
427  if( GetTextView() )
429  else
430  return Selection( 0, 0 );
431 }
432 
433 css::uno::Reference< css::accessibility::XAccessible > SidebarTextControl::CreateAccessible()
434 {
435 
437  css::uno::Reference< css::awt::XWindowPeer > xWinPeer( pAcc );
438  SetWindowPeer( xWinPeer, pAcc );
439 
440  css::uno::Reference< css::accessibility::XAccessible > xAcc( xWinPeer, css::uno::UNO_QUERY );
441  return xAcc;
442 }
443 
444 } // end of namespace sw::sidebarwindows
445 
446 /* 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:1747
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
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:793
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:398
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:479
OUString GetSurroundingText() const
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:1752
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:165
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:1108
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
void Command(const CommandEvent &rCEvt)
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
bool HasFocus() const
void Push(PushFlags nFlags=PushFlags::ALL)
void DrawGradient(const tools::Rectangle &rRect, const Gradient &rGradient)
static OUString GetURLHelpText(const OUString &)
Selection GetSurroundingTextSelection() const
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)