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 <config_wasm_strip.h>
21
22#include "SidebarTxtControl.hxx"
23
24#include <docsh.hxx>
25#include <doc.hxx>
26
27#include <PostItMgr.hxx>
28
29#include <cmdid.h>
30#include <strings.hrc>
31
33#include <officecfg/Office/Common.hxx>
34
35#include <sfx2/viewfrm.hxx>
36#include <sfx2/bindings.hxx>
37#include <sfx2/dispatch.hxx>
38#include <sfx2/sfxhelp.hxx>
39
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>
47
48#include <editeng/outliner.hxx>
49#include <editeng/editeng.hxx>
50#include <editeng/editview.hxx>
51#include <editeng/flditem.hxx>
52
53#include <uitool.hxx>
54#include <view.hxx>
55#include <wrtsh.hxx>
56#include <AnnotationWin.hxx>
58#include <redline.hxx>
59#include <memory>
60
61namespace sw::sidebarwindows {
62
64 SwView& rDocView,
65 SwPostItMgr& rPostItMgr)
66 : mrSidebarWin(rSidebarWin)
67 , mrDocView(rDocView)
68 , mrPostItMgr(rPostItMgr)
69 , mbMouseDownGainingFocus(false)
70{
71}
72
74{
75 OutlinerView* pOutlinerView = mrSidebarWin.GetOutlinerView();
76 if (!pOutlinerView)
77 return nullptr;
78 return &pOutlinerView->GetEditView();
79}
80
82{
83 OutlinerView* pOutlinerView = mrSidebarWin.GetOutlinerView();
84 if (!pOutlinerView)
85 return nullptr;
86 return pOutlinerView->GetEditView().GetEditEngine();
87}
88
90{
91 Size aSize(0, 0);
92 pDrawingArea->set_size_request(aSize.Width(), aSize.Height());
93
94 SetOutputSizePixel(aSize);
95
97
98 EnableRTL(false);
99
100 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
101 Color aBgColor = rStyleSettings.GetWindowColor();
102
103 OutputDevice& rDevice = pDrawingArea->get_ref_device();
104
105 rDevice.SetMapMode(MapMode(MapUnit::MapTwip));
106 rDevice.SetBackground(aBgColor);
107
108 Size aOutputSize(rDevice.PixelToLogic(aSize));
109
110 EditView* pEditView = GetEditView();
111 pEditView->setEditViewCallbacks(this);
112
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);
121
122 pEditView->SetOutputArea(tools::Rectangle(Point(0, 0), aOutputSize));
123 pEditView->SetBackgroundColor(aBgColor);
124
125 pDrawingArea->set_cursor(PointerStyle::Text);
126
127#if !ENABLE_WASM_STRIP_ACCESSIBILITY
129#endif
130}
131
132void SidebarTextControl::SetCursorLogicPosition(const Point& rPosition, bool bPoint, bool bClearMark)
133{
134 Point aMousePos = EditViewOutputDevice().PixelToLogic(rPosition);
135 m_xEditView->SetCursorLogicPosition(aMousePos, bPoint, bClearMark);
136}
137
139{
141 if ( !mrSidebarWin.IsMouseOver() )
142 Invalidate();
144}
145
147{
148 // write the visible text back into the SwField
150
152 if ( !mrSidebarWin.IsMouseOver() )
153 {
154 Invalidate();
155 }
156 // set false for autoscroll to typing location
157 mrSidebarWin.LockView(false);
158}
159
161{
162 if (EditView* pEditView = GetEditView())
163 {
164 Point aPos = rHelpRect.TopLeft();
165
166 const OutputDevice& rOutDev = pEditView->GetOutputDevice();
167 Point aLogicClick = rOutDev.PixelToLogic(aPos);
168 const SvxFieldItem* pItem = pEditView->GetField(aLogicClick);
169 if (pItem)
170 {
171 const SvxFieldData* pField = pItem->GetField();
172 const SvxURLField* pURL = dynamic_cast<const SvxURLField*>( pField );
173 if (pURL)
174 {
175 rHelpRect = tools::Rectangle(aPos, Size(50, 10));
176 return SfxHelp::GetURLHelpText(pURL->GetURL());
177 }
178 }
179 }
180
181 TranslateId pResId;
182 switch( mrSidebarWin.GetLayoutStatus() )
183 {
184 case SwPostItHelper::INSERTED: pResId = STR_REDLINE_INSERT; break;
185 case SwPostItHelper::DELETED: pResId = STR_REDLINE_DELETE; break;
186 default: break;
187 }
188
189 SwContentAtPos aContentAtPos( IsAttrAtPos::Redline );
190 if ( pResId &&
192 {
193 OUString sText = SwResId(pResId) + ": " +
194 aContentAtPos.aFnd.pRedl->GetAuthorString() + " - " +
196 return sText;
197 }
198
199 return OUString();
200}
201
203{
205}
206
208{
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()));
212
213 if (OutlinerView* pOutlinerView = mrSidebarWin.GetOutlinerView())
214 {
215 pOutlinerView->GetOutliner()->Draw(*pDev, tools::Rectangle(rPt, aSize));
216 }
217
219 return;
220
222
224 Point aBottomRight(rPt);
225 aBottomRight.Move(aSize);
226 pDev->DrawLine(rPt, aBottomRight);
227
228 Point aTopRight(rPt);
229 aTopRight.Move(Size(aSize.Width(), 0));
230
231 Point aBottomLeft(rPt);
232 aBottomLeft.Move(Size(0, aSize.Height()));
233
234 pDev->DrawLine(aTopRight, aBottomLeft);
235
236 pDev->Pop();
237}
238
240{
241 Size aSize = GetOutputSizePixel();
242 Point aPos;
243
244 if (!rRenderContext.GetSettings().GetStyleSettings().GetHighContrastMode())
245 {
246 if (mrSidebarWin.IsMouseOverSidebarWin() || HasFocus())
247 {
248 rRenderContext.DrawGradient(tools::Rectangle(aPos, rRenderContext.PixelToLogic(aSize)),
249 Gradient(css::awt::GradientStyle_LINEAR, mrSidebarWin.ColorDark(), mrSidebarWin.ColorDark()));
250 }
251 else
252 {
253 rRenderContext.DrawGradient(tools::Rectangle(aPos, rRenderContext.PixelToLogic(aSize)),
254 Gradient(css::awt::GradientStyle_LINEAR, mrSidebarWin.ColorLight(), mrSidebarWin.ColorDark()));
255 }
256 }
257
258 DoPaint(rRenderContext, rRect);
259
261 return;
262
263 const AntialiasingFlags nFormerAntialiasing( rRenderContext.GetAntialiasing() );
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);
277}
278
280{
281 //let's make sure we see our note
283}
284
286{
287 if (getenv("SW_DEBUG") && rKeyEvt.GetKeyCode().GetCode() == KEY_F12)
288 {
289 if (rKeyEvt.GetKeyCode().IsShift())
290 {
292 return true;
293 }
294 }
295
296 bool bDone = false;
297
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) ) )
302 {
304 bDone = true;
305 }
306 else if ( nKey == KEY_ESCAPE ||
307 ( rKeyCode.IsMod1() &&
308 ( nKey == KEY_PAGEUP ||
309 nKey == KEY_PAGEDOWN ) ) )
310 {
312 bDone = true;
313 }
314 else if ( rKeyCode.GetFullCode() == KEY_INSERT )
315 {
317 bDone = true;
318 }
319 else
320 {
321 MakeVisible();
322
324
326 if ( !( (nKey == KEY_Z || nKey == KEY_Y) && rKeyCode.IsMod1()) )
327 {
328 bool bIsProtected = mrSidebarWin.IsReadOnlyOrProtected();
329 if ( !bIsProtected || !EditEngine::DoesKeyChangeText(rKeyEvt) )
330 {
331 EditView* pEditView = GetEditView();
332 bDone = pEditView && pEditView->PostKeyEvent(rKeyEvt);
333 }
334 else
336 }
337 if (bDone)
339 else
340 {
341 // write back data first when showing navigator
342 if ( nKey==KEY_F5 )
344 bDone = mrDocView.KeyInput(rKeyEvt);
345 }
346 }
347
349
350 return bDone;
351}
352
354{
355 if (EditView* pEditView = GetEditView())
356 {
358
359 if ( !bExecuteMod || (rMEvt.GetModifier() == KEY_MOD1))
360 {
361 const OutputDevice& rOutDev = pEditView->GetOutputDevice();
362 Point aLogicClick = rOutDev.PixelToLogic(rMEvt.GetPosPixel());
363 if (const SvxFieldItem* pItem = pEditView->GetField(aLogicClick))
364 {
365 const SvxFieldData* pField = pItem->GetField();
366 const SvxURLField* pURL = dynamic_cast<const SvxURLField*>( pField );
367 if ( pURL )
368 {
369 pEditView->MouseButtonDown( rMEvt );
371 const OUString& sURL( pURL->GetURL() );
372 const OUString& sTarget( pURL->GetTargetFrame() );
373 ::LoadURL(rSh, sURL, LoadUrlFlags::NONE, sTarget);
374 return true;
375 }
376 }
377 }
378 }
379
380 mbMouseDownGainingFocus = !HasFocus();
381 GrabFocus();
382
383 bool bRet = WeldEditView::MouseButtonDown(rMEvt);
384
386
387 return bRet;
388}
389
391{
392 bool bRet = WeldEditView::MouseButtonUp(rMEvt);
393
395 {
396 MakeVisible();
398 }
399
400 return bRet;
401}
402
404{
405 if (rMEvt.IsEnterWindow())
406 GetDrawingArea()->set_cursor(PointerStyle::Text);
407 return WeldEditView::MouseMove(rMEvt);
408}
409
410IMPL_LINK( SidebarTextControl, OnlineSpellCallback, SpellCallbackInfo&, rInfo, void )
411{
412 if ( rInfo.nCommand == SpellCallbackCommand::STARTSPELLDLG )
413 {
414 mrDocView.GetViewFrame().GetDispatcher()->Execute( FN_SPELL_GRAMMAR_DIALOG, SfxCallMode::ASYNCHRON);
415 }
416}
417
419{
420 EditView* pEditView = GetEditView();
421
422 if ( rCEvt.GetCommand() == CommandEventId::ContextMenu )
423 {
424 if (IsMouseCaptured())
425 ReleaseMouse();
427 pEditView &&
428 pEditView->IsWrongSpelledWordAtPos( rCEvt.GetMousePosPixel(), true ))
429 {
430 Link<SpellCallbackInfo&,void> aLink = LINK(this, SidebarTextControl, OnlineSpellCallback);
431 pEditView->ExecuteSpellPopup(rCEvt.GetMousePosPixel(), aLink);
432 }
433 else
434 {
435 Point aPos;
436 if (rCEvt.IsMouseEvent())
437 aPos = rCEvt.GetMousePosPixel();
438 else
439 {
440 const Size aSize = GetOutputSizePixel();
441 aPos = Point( aSize.getWidth()/2, aSize.getHeight()/2 );
442 }
444 }
445 return true;
446 }
447 else if (rCEvt.GetCommand() == CommandEventId::Wheel)
448 {
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
453 {
455 return true;
456 }
457 else
458 {
459 const CommandWheelData* pData = rCEvt.GetWheelData();
460 if (pData->IsShift() || pData->IsMod1() || pData->IsMod2())
461 {
463 return true;
464 }
465 }
466 }
467
468 return WeldEditView::Command(rCEvt);
469}
470
471} // end of namespace sw::sidebarwindows
472
473/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
AntialiasingFlags
const StyleSettings & GetStyleSettings() const
static const AllSettings & GetSettings()
CommandEventId GetCommand() const
const CommandWheelData * GetWheelData() const
const Point & GetMousePosPixel() const
bool IsMouseEvent() const
const Size & GetPaperSize() const
void SetRefDevice(OutputDevice *pRefDef)
void SetPaperSize(const Size &rSize)
static bool DoesKeyChangeText(const KeyEvent &rKeyEvent)
bool IsWrongSpelledWordAtPos(const Point &rPosPixel, bool bMarkIfWrong=false)
bool ExecuteSpellPopup(const Point &rPosPixel, const Link< SpellCallbackInfo &, void > &rCallBack)
void SetOutputArea(const tools::Rectangle &rRect)
bool PostKeyEvent(const KeyEvent &rKeyEvent, vcl::Window const *pFrameWin=nullptr)
void SetBackgroundColor(const Color &rColor)
EditEngine * GetEditEngine() const
void setEditViewCallbacks(EditViewCallbacks *pEditViewCallbacks)
virtual OutputDevice * getReferenceDevice(bool bCreate) const =0
Returns the current reference device.
const vcl::KeyCode & GetKeyCode() const
bool IsEnterWindow() const
sal_uInt16 GetModifier() const
const Point & GetPosPixel() const
EditView & GetEditView() const
void SetAntialiasing(AntialiasingFlags nMode)
SAL_WARN_UNUSED_RESULT Point PixelToLogic(const Point &rDevicePt) const
void DrawLine(const Point &rStartPt, const Point &rEndPt)
void SetLineColor()
void SetMapMode()
void Push(vcl::PushFlags nFlags=vcl::PushFlags::ALL)
void DrawGradient(const tools::Rectangle &rRect, const Gradient &rGradient)
void SetBackground()
AntialiasingFlags GetAntialiasing() const
const AllSettings & GetSettings() const
void Move(tools::Long nHorzMove, tools::Long nVertMove)
void InvalidateAll(bool bWithMsg)
void ExecutePopup(const OUString &rResName, vcl::Window *pWin=nullptr, const Point *pPos=nullptr)
static OUString GetURLHelpText(std::u16string_view)
SfxBindings & GetBindings()
SfxViewFrame & GetViewFrame() const
virtual bool KeyInput(const KeyEvent &rKeyEvent)
constexpr tools::Long getHeight() const
constexpr tools::Long Height() const
constexpr tools::Long getWidth() const
constexpr tools::Long Width() const
const Color & GetWindowColor() const
bool GetHighContrastMode() const
const SvxFieldData * GetField() const
const OUString & GetTargetFrame() const
const OUString & GetURL() const
bool GetContentAtPos(const Point &rPt, SwContentAtPos &rContentAtPos, bool bSetCursor=false, SwRect *pFieldRect=nullptr)
Definition: crstrvl.cxx:1433
SwDoc * GetDoc()
returns Doc. But be careful!
Definition: docsh.hxx:204
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:1966
void MakeVisible(const sw::annotation::SwAnnotationWin *pPostIt)
Definition: PostItMgr.cxx:1083
tools::ULong GetSidebarWidth(bool bPx=false) const
Definition: PostItMgr.cxx:2121
OUString const & GetAuthorString(sal_uInt16 nPos=0) const
Definition: docredln.cxx:1965
const DateTime & GetTimeStamp(sal_uInt16 nPos=0) const
Definition: docredln.cxx:1970
const IDocumentDeviceAccess & getIDocumentDeviceAccess() const
Provides access to the document device interface.
Definition: viewsh.cxx:2819
Definition: view.hxx:146
SwWrtShell & GetWrtShell() const
Definition: view.hxx:423
bool HandleWheelCommands(const CommandEvent &)
Definition: viewport.cxx:1190
SwDocShell * GetDocShell()
Definition: view.cxx:1193
Used by the UI to modify the document model.
Definition: wrtsh.hxx:97
virtual void InfoReadOnlyDialog(bool bAsync) const override
Selected area has readonly content.
Definition: wrtsh1.cxx:2666
std::unique_ptr< EditView > m_xEditView
void DoPaint(vcl::RenderContext &rRenderContext, const tools::Rectangle &rRect)
virtual bool Command(const CommandEvent &rCEvt) override
virtual OutputDevice & EditViewOutputDevice() const override
virtual bool MouseButtonDown(const MouseEvent &rMEvt) override
virtual bool MouseMove(const MouseEvent &rMEvt) override
void InitAccessible()
virtual bool MouseButtonUp(const MouseEvent &rMEvt) override
virtual void GetFocus() override
virtual void LoseFocus() override
void SwitchToPostIt(sal_uInt16 aDirection)
SwPostItHelper::SwLayoutStatus GetLayoutStatus() const
const Color & GetChangeColor() const
void ResizeIfNecessary(tools::Long aOldHeight, tools::Long aNewHeight)
SidebarTextControl(sw::annotation::SwAnnotationWin &rSidebarWin, SwView &rDocView, SwPostItMgr &rPostItMgr)
virtual bool MouseButtonDown(const MouseEvent &rMEvt) override
virtual bool MouseMove(const MouseEvent &rMEvt) override
void DrawForPage(OutputDevice *pDev, const Point &rPos)
void SetDrawingArea(weld::DrawingArea *pDrawingArea) override
virtual void EditViewScrollStateChange() override
virtual bool MouseButtonUp(const MouseEvent &rMEvt) override
virtual OUString RequestHelp(tools::Rectangle &rRect) override
virtual void Paint(vcl::RenderContext &rRenderContext, const tools::Rectangle &rRect) override
sw::annotation::SwAnnotationWin & mrSidebarWin
void SetCursorLogicPosition(const Point &rPosition, bool bPoint, bool bClearMark)
virtual bool Command(const CommandEvent &rCEvt) override
virtual EditView * GetEditView() const override
virtual bool KeyInput(const KeyEvent &rKeyEvt) override
virtual EditEngine * GetEditEngine() const override
constexpr Point TopLeft() const
bool IsMod1() const
sal_uInt16 GetCode() const
bool IsShift() const
bool IsMod2() const
sal_uInt16 GetFullCode() const
bool IsMouseOver() const
virtual void SetDrawingArea(weld::DrawingArea *pDrawingArea)
virtual OutputDevice & get_ref_device()=0
virtual void set_cursor(PointerStyle ePointerStyle)=0
virtual void set_size_request(int nWidth, int nHeight)=0
#define FN_SPELL_GRAMMAR_DIALOG
Definition: cmdid.h:637
constexpr sal_uInt16 KEY_ESCAPE
constexpr sal_uInt16 KEY_MOD1
constexpr sal_uInt16 KEY_F5
constexpr sal_uInt16 KEY_PAGEDOWN
constexpr sal_uInt16 KEY_Z
constexpr sal_uInt16 KEY_Y
constexpr sal_uInt16 KEY_F12
constexpr sal_uInt16 KEY_PAGEUP
constexpr sal_uInt16 KEY_INSERT
std::unique_ptr< sal_Int32[]> pData
bool IsOptionSet(EOption eOption)
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
IMPL_LINK(SidebarTextControl, OnlineSpellCallback, SpellCallbackInfo &, rInfo, void)
long Long
union SwContentAtPos::@21 aFnd
const SwRangeRedline * pRedl
Definition: crsrsh.hxx:108
OUString SwResId(TranslateId aId)
Definition: swmodule.cxx:168
OUString GetAppLangDateTimeString(const DateTime &)
Definition: uitool.cxx:863
void LoadURL(SwViewShell &rVSh, const OUString &rURL, LoadUrlFlags nFilter, const OUString &rTargetFrameName)
Definition: wrtsh2.cxx:555