summaryrefslogtreecommitdiffstats
path: root/sw/source/uibase/docvw/SidebarTxtControl.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/uibase/docvw/SidebarTxtControl.cxx')
-rw-r--r--sw/source/uibase/docvw/SidebarTxtControl.cxx446
1 files changed, 446 insertions, 0 deletions
diff --git a/sw/source/uibase/docvw/SidebarTxtControl.cxx b/sw/source/uibase/docvw/SidebarTxtControl.cxx
new file mode 100644
index 000000000..65c67d098
--- /dev/null
+++ b/sw/source/uibase/docvw/SidebarTxtControl.cxx
@@ -0,0 +1,446 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "SidebarTxtControl.hxx"
+
+#include "SidebarTxtControlAcc.hxx"
+#include <docsh.hxx>
+#include <doc.hxx>
+
+#include <PostItMgr.hxx>
+#include <edtwin.hxx>
+
+#include <cmdid.h>
+#include <strings.hrc>
+
+#include <unotools/securityoptions.hxx>
+
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/sfxhelp.hxx>
+
+#include <vcl/commandevent.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/help.hxx>
+#include <vcl/weld.hxx>
+#include <vcl/gradient.hxx>
+#include <vcl/settings.hxx>
+
+#include <editeng/outliner.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/editview.hxx>
+#include <editeng/flditem.hxx>
+#include <comphelper/lok.hxx>
+#include <sfx2/lokhelper.hxx>
+
+#include <uitool.hxx>
+#include <view.hxx>
+#include <wrtsh.hxx>
+#include <AnnotationWin.hxx>
+#include <redline.hxx>
+#include <memory>
+
+namespace sw::sidebarwindows {
+
+SidebarTextControl::SidebarTextControl( sw::annotation::SwAnnotationWin& rSidebarWin,
+ WinBits nBits,
+ SwView& rDocView,
+ SwPostItMgr& rPostItMgr )
+ : Control( &rSidebarWin, nBits )
+ , mrSidebarWin( rSidebarWin )
+ , mrDocView( rDocView )
+ , mrPostItMgr( rPostItMgr )
+{
+ AddEventListener( LINK( &mrSidebarWin, sw::annotation::SwAnnotationWin, WindowEventListener ) );
+}
+
+SidebarTextControl::~SidebarTextControl()
+{
+ disposeOnce();
+}
+
+void SidebarTextControl::dispose()
+{
+ RemoveEventListener( LINK( &mrSidebarWin, sw::annotation::SwAnnotationWin, WindowEventListener ) );
+ Control::dispose();
+}
+
+OutlinerView* SidebarTextControl::GetTextView() const
+{
+ return mrSidebarWin.GetOutlinerView();
+}
+
+void SidebarTextControl::GetFocus()
+{
+ Window::GetFocus();
+ if ( !mrSidebarWin.IsMouseOver() )
+ {
+ Invalidate();
+ }
+}
+
+void SidebarTextControl::LoseFocus()
+{
+ // write the visible text back into the SwField
+ mrSidebarWin.UpdateData();
+
+ Window::LoseFocus();
+ if ( !mrSidebarWin.IsMouseOver() )
+ {
+ Invalidate();
+ }
+}
+
+void SidebarTextControl::RequestHelp(const HelpEvent &rEvt)
+{
+ const char* pResId = nullptr;
+ switch( mrSidebarWin.GetLayoutStatus() )
+ {
+ case SwPostItHelper::INSERTED: pResId = STR_REDLINE_INSERT; break;
+ case SwPostItHelper::DELETED: pResId = STR_REDLINE_DELETE; break;
+ default: pResId = nullptr;
+ }
+
+ SwContentAtPos aContentAtPos( IsAttrAtPos::Redline );
+ if ( pResId &&
+ mrDocView.GetWrtShell().GetContentAtPos( mrSidebarWin.GetAnchorPos(), aContentAtPos ) )
+ {
+ OUString sText = SwResId(pResId) + ": " +
+ aContentAtPos.aFnd.pRedl->GetAuthorString() + " - " +
+ GetAppLangDateTimeString( aContentAtPos.aFnd.pRedl->GetTimeStamp() );
+ Help::ShowQuickHelp( this,PixelToLogic(tools::Rectangle(rEvt.GetMousePosPixel(),Size(50,10))),sText);
+ }
+}
+
+void SidebarTextControl::Draw(OutputDevice* pDev, const Point& rPt, DrawFlags)
+{
+ //Take the control's height, but overwrite the scrollbar area if there was one
+ Size aSize(PixelToLogic(GetSizePixel()));
+
+ if ( GetTextView() )
+ {
+ GetTextView()->GetOutliner()->Draw(pDev, tools::Rectangle(rPt, aSize));
+ }
+
+ if ( mrSidebarWin.GetLayoutStatus()==SwPostItHelper::DELETED )
+ {
+ SetLineColor(mrSidebarWin.GetChangeColor());
+ pDev->DrawLine( PixelToLogic( GetPosPixel(), pDev->GetMapMode() ),
+ PixelToLogic( GetPosPixel() +
+ Point( GetSizePixel().Width(),
+ GetSizePixel().Height() ), pDev->GetMapMode() ) );
+ pDev->DrawLine( PixelToLogic( GetPosPixel() +
+ Point( GetSizePixel().Width(),0), pDev->GetMapMode() ),
+ PixelToLogic( GetPosPixel() +
+ Point( 0, GetSizePixel().Height() ), pDev->GetMapMode() ) );
+ }
+}
+
+void SidebarTextControl::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
+{
+ if (!rRenderContext.GetSettings().GetStyleSettings().GetHighContrastMode())
+ {
+ if (mrSidebarWin.IsMouseOverSidebarWin() || HasFocus())
+ {
+ rRenderContext.DrawGradient(tools::Rectangle(Point(0,0), rRenderContext.PixelToLogic(GetSizePixel())),
+ Gradient(GradientStyle::Linear, mrSidebarWin.ColorDark(), mrSidebarWin.ColorDark()));
+ }
+ else
+ {
+ rRenderContext.DrawGradient(tools::Rectangle(Point(0,0), rRenderContext.PixelToLogic(GetSizePixel())),
+ Gradient(GradientStyle::Linear, mrSidebarWin.ColorLight(), mrSidebarWin.ColorDark()));
+ }
+ }
+
+ if (GetTextView())
+ {
+ GetTextView()->Paint(rRect, &rRenderContext);
+ }
+
+ if (mrSidebarWin.GetLayoutStatus() == SwPostItHelper::DELETED)
+ {
+ rRenderContext.SetLineColor(mrSidebarWin.GetChangeColor());
+ rRenderContext.DrawLine(rRenderContext.PixelToLogic(GetPosPixel()),
+ rRenderContext.PixelToLogic(GetPosPixel() + Point(GetSizePixel().Width(),
+ GetSizePixel().Height())));
+ rRenderContext.DrawLine(rRenderContext.PixelToLogic(GetPosPixel() + Point(GetSizePixel().Width(),
+ 0)),
+ rRenderContext.PixelToLogic(GetPosPixel() + Point(0,
+ GetSizePixel().Height())));
+ }
+}
+
+void SidebarTextControl::LogicInvalidate(const tools::Rectangle* pRectangle)
+{
+ tools::Rectangle aRectangle;
+
+ if (!pRectangle)
+ {
+ Push(PushFlags::MAPMODE);
+ EnableMapMode();
+ aRectangle = tools::Rectangle(Point(0, 0), PixelToLogic(GetSizePixel()));
+ Pop();
+ }
+ else
+ aRectangle = *pRectangle;
+
+ // Convert from relative twips to absolute ones.
+ vcl::Window& rParent = mrSidebarWin.EditWin();
+ Point aOffset(GetOutOffXPixel() - rParent.GetOutOffXPixel(), GetOutOffYPixel() - rParent.GetOutOffYPixel());
+ rParent.Push(PushFlags::MAPMODE);
+ rParent.EnableMapMode();
+ aOffset = rParent.PixelToLogic(aOffset);
+ rParent.Pop();
+ aRectangle.Move(aOffset.getX(), aOffset.getY());
+
+ OString sRectangle = aRectangle.toString();
+ SwWrtShell& rWrtShell = mrDocView.GetWrtShell();
+ SfxLokHelper::notifyInvalidation(rWrtShell.GetSfxViewShell(), sRectangle);
+}
+
+void SidebarTextControl::KeyInput( const KeyEvent& rKeyEvt )
+{
+ if (getenv("SW_DEBUG") && rKeyEvt.GetKeyCode().GetCode() == KEY_F12)
+ {
+ if (rKeyEvt.GetKeyCode().IsShift())
+ {
+ mrDocView.GetDocShell()->GetDoc()->dumpAsXml();
+ return;
+ }
+ }
+
+ const vcl::KeyCode& rKeyCode = rKeyEvt.GetKeyCode();
+ sal_uInt16 nKey = rKeyCode.GetCode();
+ if ( ( rKeyCode.IsMod1() && rKeyCode.IsMod2() ) &&
+ ( (nKey == KEY_PAGEUP) || (nKey == KEY_PAGEDOWN) ) )
+ {
+ mrSidebarWin.SwitchToPostIt(nKey);
+ }
+ else if ( nKey == KEY_ESCAPE ||
+ ( rKeyCode.IsMod1() &&
+ ( nKey == KEY_PAGEUP ||
+ nKey == KEY_PAGEDOWN ) ) )
+ {
+ mrSidebarWin.SwitchToFieldPos();
+ }
+ else if ( rKeyCode.GetFullCode() == KEY_INSERT )
+ {
+ mrSidebarWin.ToggleInsMode();
+ }
+ else
+ {
+ // MakeVisible can lose our MapMode, save it.
+ auto oldMapMode = GetMapMode();
+ //let's make sure we see our note
+ mrPostItMgr.MakeVisible(&mrSidebarWin);
+ if (comphelper::LibreOfficeKit::isActive())
+ SetMapMode(oldMapMode);
+
+ long aOldHeight = mrSidebarWin.GetPostItTextHeight();
+ bool bDone = false;
+
+ /// HACK: need to switch off processing of Undo/Redo in Outliner
+ if ( !( (nKey == KEY_Z || nKey == KEY_Y) && rKeyCode.IsMod1()) )
+ {
+ bool bIsProtected = mrSidebarWin.IsProtected();
+ if ( !bIsProtected || !EditEngine::DoesKeyChangeText(rKeyEvt) )
+ {
+ bDone = GetTextView() && GetTextView()->PostKeyEvent( rKeyEvt );
+ }
+ else
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "modules/swriter/ui/inforeadonlydialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xQuery(xBuilder->weld_message_dialog("InfoReadonlyDialog"));
+ xQuery->run();
+ }
+ }
+ if (bDone)
+ mrSidebarWin.ResizeIfNecessary( aOldHeight, mrSidebarWin.GetPostItTextHeight() );
+ else
+ {
+ // write back data first when showing navigator
+ if ( nKey==KEY_F5 )
+ mrSidebarWin.UpdateData();
+ if (!mrDocView.KeyInput(rKeyEvt))
+ Window::KeyInput(rKeyEvt);
+ }
+ }
+
+ mrDocView.GetViewFrame()->GetBindings().InvalidateAll(false);
+}
+
+void SidebarTextControl::MouseMove( const MouseEvent& rMEvt )
+{
+ if ( GetTextView() )
+ {
+ OutlinerView* pOutlinerView( GetTextView() );
+ pOutlinerView->MouseMove( rMEvt );
+ // mba: why does OutlinerView not handle the modifier setting?!
+ // this forces the postit to handle *all* pointer types
+ SetPointer( pOutlinerView->GetPointer( rMEvt.GetPosPixel() ) );
+
+ const EditView& aEV = pOutlinerView->GetEditView();
+ const SvxFieldItem* pItem = aEV.GetFieldUnderMousePointer();
+ if ( pItem )
+ {
+ const SvxFieldData* pField = pItem->GetField();
+ const SvxURLField* pURL = dynamic_cast<const SvxURLField*>( pField );
+ if ( pURL )
+ {
+ OUString sText(SfxHelp::GetURLHelpText(pURL->GetURL()));
+ Help::ShowQuickHelp(
+ this, PixelToLogic(tools::Rectangle(GetPosPixel(), Size(50, 10))), sText);
+ }
+ }
+ }
+}
+
+void SidebarTextControl::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if ( GetTextView() )
+ {
+ SvtSecurityOptions aSecOpts;
+ bool bExecuteMod = aSecOpts.IsOptionSet( SvtSecurityOptions::EOption::CtrlClickHyperlink);
+
+ if ( !bExecuteMod || (rMEvt.GetModifier() == KEY_MOD1))
+ {
+ const EditView& aEV = GetTextView()->GetEditView();
+ const SvxFieldItem* pItem = aEV.GetFieldUnderMousePointer();
+ if ( pItem )
+ {
+ const SvxFieldData* pField = pItem->GetField();
+ const SvxURLField* pURL = dynamic_cast<const SvxURLField*>( pField );
+ if ( pURL )
+ {
+ GetTextView()->MouseButtonDown( rMEvt );
+ SwWrtShell &rSh = mrDocView.GetWrtShell();
+ const OUString& sURL( pURL->GetURL() );
+ const OUString& sTarget( pURL->GetTargetFrame() );
+ ::LoadURL(rSh, sURL, LoadUrlFlags::NONE, sTarget);
+ return;
+ }
+ }
+ }
+ }
+
+ GrabFocus();
+ if ( GetTextView() )
+ {
+ GetTextView()->MouseButtonDown( rMEvt );
+ }
+ mrDocView.GetViewFrame()->GetBindings().InvalidateAll(false);
+}
+
+void SidebarTextControl::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ if ( GetTextView() )
+ GetTextView()->MouseButtonUp( rMEvt );
+}
+
+IMPL_LINK( SidebarTextControl, OnlineSpellCallback, SpellCallbackInfo&, rInfo, void )
+{
+ if ( rInfo.nCommand == SpellCallbackCommand::STARTSPELLDLG )
+ {
+ mrDocView.GetViewFrame()->GetDispatcher()->Execute( FN_SPELL_GRAMMAR_DIALOG, SfxCallMode::ASYNCHRON);
+ }
+}
+
+void SidebarTextControl::Command( const CommandEvent& rCEvt )
+{
+ if ( rCEvt.GetCommand() == CommandEventId::ContextMenu )
+ {
+ if ( !mrSidebarWin.IsProtected() &&
+ GetTextView() &&
+ GetTextView()->IsWrongSpelledWordAtPos( rCEvt.GetMousePosPixel(), true ))
+ {
+ Link<SpellCallbackInfo&,void> aLink = LINK(this, SidebarTextControl, OnlineSpellCallback);
+ GetTextView()->ExecuteSpellPopup(rCEvt.GetMousePosPixel(),&aLink);
+ }
+ else
+ {
+ Point aPos;
+ if (rCEvt.IsMouseEvent())
+ aPos = rCEvt.GetMousePosPixel();
+ else
+ {
+ const Size aSize = GetSizePixel();
+ aPos = Point( aSize.getWidth()/2, aSize.getHeight()/2 );
+ }
+ SfxDispatcher::ExecutePopup(this, &aPos);
+ }
+ }
+ else
+ if (rCEvt.GetCommand() == CommandEventId::Wheel)
+ {
+ if (mrSidebarWin.IsScrollbarVisible())
+ {
+ const CommandWheelData* pData = rCEvt.GetWheelData();
+ if (pData->IsShift() || pData->IsMod1() || pData->IsMod2())
+ {
+ mrDocView.HandleWheelCommands(rCEvt);
+ }
+ else
+ {
+ HandleScrollCommand( rCEvt, nullptr , mrSidebarWin.Scrollbar());
+ }
+ }
+ else
+ {
+ mrDocView.HandleWheelCommands(rCEvt);
+ }
+ }
+ else
+ {
+ if ( GetTextView() )
+ GetTextView()->Command( rCEvt );
+ else
+ Window::Command(rCEvt);
+ }
+}
+
+OUString SidebarTextControl::GetSurroundingText() const
+{
+ if (GetTextView())
+ return GetTextView()->GetSurroundingText();
+ return OUString();
+}
+
+Selection SidebarTextControl::GetSurroundingTextSelection() const
+{
+ if( GetTextView() )
+ return GetTextView()->GetSurroundingTextSelection();
+ else
+ return Selection( 0, 0 );
+}
+
+css::uno::Reference< css::accessibility::XAccessible > SidebarTextControl::CreateAccessible()
+{
+
+ SidebarTextControlAccessible* pAcc( new SidebarTextControlAccessible( *this ) );
+ css::uno::Reference< css::awt::XWindowPeer > xWinPeer( pAcc );
+ SetWindowPeer( xWinPeer, pAcc );
+
+ css::uno::Reference< css::accessibility::XAccessible > xAcc( xWinPeer, css::uno::UNO_QUERY );
+ return xAcc;
+}
+
+} // end of namespace sw::sidebarwindows
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */