summaryrefslogtreecommitdiff
path: root/sw/source/uibase/docvw
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/uibase/docvw')
-rw-r--r--sw/source/uibase/docvw/AnchorOverlayObject.cxx449
-rw-r--r--sw/source/uibase/docvw/AnchorOverlayObject.hxx133
-rw-r--r--sw/source/uibase/docvw/AnnotationMenuButton.cxx205
-rw-r--r--sw/source/uibase/docvw/AnnotationMenuButton.hxx53
-rw-r--r--sw/source/uibase/docvw/AnnotationWin.cxx318
-rw-r--r--sw/source/uibase/docvw/DashedLine.cxx97
-rw-r--r--sw/source/uibase/docvw/FrameControlsManager.cxx159
-rw-r--r--sw/source/uibase/docvw/HeaderFooterWin.cxx520
-rw-r--r--sw/source/uibase/docvw/OverlayRanges.cxx180
-rw-r--r--sw/source/uibase/docvw/OverlayRanges.hxx78
-rw-r--r--sw/source/uibase/docvw/PageBreakWin.cxx463
-rw-r--r--sw/source/uibase/docvw/PostItMgr.cxx2029
-rw-r--r--sw/source/uibase/docvw/ShadowOverlayObject.cxx252
-rw-r--r--sw/source/uibase/docvw/ShadowOverlayObject.hxx70
-rw-r--r--sw/source/uibase/docvw/SidebarTxtControl.cxx433
-rw-r--r--sw/source/uibase/docvw/SidebarTxtControl.hxx77
-rw-r--r--sw/source/uibase/docvw/SidebarTxtControlAcc.cxx293
-rw-r--r--sw/source/uibase/docvw/SidebarTxtControlAcc.hxx46
-rw-r--r--sw/source/uibase/docvw/SidebarWin.cxx1420
-rw-r--r--sw/source/uibase/docvw/SidebarWinAcc.cxx143
-rw-r--r--sw/source/uibase/docvw/SidebarWinAcc.hxx57
-rw-r--r--sw/source/uibase/docvw/annotation.hrc44
-rw-r--r--sw/source/uibase/docvw/docvw.hrc89
-rw-r--r--sw/source/uibase/docvw/docvw.src307
-rw-r--r--sw/source/uibase/docvw/edtdd.cxx495
-rw-r--r--sw/source/uibase/docvw/edtwin.cxx6147
-rw-r--r--sw/source/uibase/docvw/edtwin2.cxx465
-rw-r--r--sw/source/uibase/docvw/edtwin3.cxx166
-rw-r--r--sw/source/uibase/docvw/frmsidebarwincontainer.cxx204
-rw-r--r--sw/source/uibase/docvw/frmsidebarwincontainer.hxx63
-rw-r--r--sw/source/uibase/docvw/romenu.cxx368
-rw-r--r--sw/source/uibase/docvw/romenu.hxx64
-rw-r--r--sw/source/uibase/docvw/srcedtw.cxx993
33 files changed, 16880 insertions, 0 deletions
diff --git a/sw/source/uibase/docvw/AnchorOverlayObject.cxx b/sw/source/uibase/docvw/AnchorOverlayObject.cxx
new file mode 100644
index 000000000000..d3f1ee04bcf8
--- /dev/null
+++ b/sw/source/uibase/docvw/AnchorOverlayObject.cxx
@@ -0,0 +1,449 @@
+/* -*- 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 <AnchorOverlayObject.hxx>
+#include <SidebarWindowsConsts.hxx>
+
+#include <swrect.hxx>
+#include <view.hxx>
+#include <svx/sdrpaintwindow.hxx>
+#include <svx/svdview.hxx>
+#include <svx/sdr/overlay/overlaymanager.hxx>
+
+#include <sw_primitivetypes2d.hxx>
+#include <drawinglayer/primitive2d/primitivetools2d.hxx>
+#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
+#include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
+#include <drawinglayer/primitive2d/shadowprimitive2d.hxx>
+
+namespace sw { namespace sidebarwindows {
+
+// helper class: Primitive for discrete visualisation
+class AnchorPrimitive : public drawinglayer::primitive2d::DiscreteMetricDependentPrimitive2D
+{
+private:
+ basegfx::B2DPolygon maTriangle;
+ basegfx::B2DPolygon maLine;
+ basegfx::B2DPolygon maLineTop;
+ const AnchorState maAnchorState;
+ basegfx::BColor maColor;
+
+ // discrete line width
+ double mfDiscreteLineWidth;
+
+ // bitfield
+ bool mbShadow : 1;
+ bool mbLineSolid : 1;
+
+protected:
+ virtual drawinglayer::primitive2d::Primitive2DSequence create2DDecomposition(
+ const drawinglayer::geometry::ViewInformation2D& rViewInformation) const SAL_OVERRIDE;
+
+public:
+ AnchorPrimitive( const basegfx::B2DPolygon& rTriangle,
+ const basegfx::B2DPolygon& rLine,
+ const basegfx::B2DPolygon& rLineTop,
+ AnchorState aAnchorState,
+ const basegfx::BColor& rColor,
+ double fDiscreteLineWidth,
+ bool bShadow,
+ bool bLineSolid )
+ : drawinglayer::primitive2d::DiscreteMetricDependentPrimitive2D(),
+ maTriangle(rTriangle),
+ maLine(rLine),
+ maLineTop(rLineTop),
+ maAnchorState(aAnchorState),
+ maColor(rColor),
+ mfDiscreteLineWidth(fDiscreteLineWidth),
+ mbShadow(bShadow),
+ mbLineSolid(bLineSolid)
+ {}
+
+ // data access
+ const basegfx::B2DPolygon& getTriangle() const { return maTriangle; }
+ const basegfx::B2DPolygon& getLine() const { return maLine; }
+ const basegfx::B2DPolygon& getLineTop() const { return maLineTop; }
+ AnchorState getAnchorState() const { return maAnchorState; }
+ const basegfx::BColor& getColor() const { return maColor; }
+ double getDiscreteLineWidth() const { return mfDiscreteLineWidth; }
+ bool getShadow() const { return mbShadow; }
+ bool getLineSolid() const { return mbLineSolid; }
+
+ virtual bool operator==( const drawinglayer::primitive2d::BasePrimitive2D& rPrimitive ) const SAL_OVERRIDE;
+
+ DeclPrimitive2DIDBlock()
+};
+
+drawinglayer::primitive2d::Primitive2DSequence AnchorPrimitive::create2DDecomposition(
+ const drawinglayer::geometry::ViewInformation2D& /*rViewInformation*/) const
+{
+ drawinglayer::primitive2d::Primitive2DSequence aRetval;
+
+ if ( AS_TRI == maAnchorState ||
+ AS_ALL == maAnchorState ||
+ AS_START == maAnchorState )
+ {
+ // create triangle
+ const drawinglayer::primitive2d::Primitive2DReference aTriangle(
+ new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(
+ basegfx::B2DPolyPolygon(getTriangle()),
+ getColor()));
+
+ drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, aTriangle);
+ }
+
+ // prepare view-independent LineWidth and color
+ const drawinglayer::attribute::LineAttribute aLineAttribute(
+ getColor(),
+ getDiscreteLineWidth() * getDiscreteUnit());
+
+ if ( AS_ALL == maAnchorState ||
+ AS_START == maAnchorState )
+ {
+ // create line start
+ if(getLineSolid())
+ {
+ const drawinglayer::primitive2d::Primitive2DReference aSolidLine(
+ new drawinglayer::primitive2d::PolygonStrokePrimitive2D(
+ getLine(),
+ aLineAttribute));
+
+ drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, aSolidLine);
+ }
+ else
+ {
+ ::std::vector< double > aDotDashArray;
+ const double fDistance(3.0 * 15.0);
+ const double fDashLen(5.0 * 15.0);
+
+ aDotDashArray.push_back(fDashLen);
+ aDotDashArray.push_back(fDistance);
+
+ const drawinglayer::attribute::StrokeAttribute aStrokeAttribute(
+ aDotDashArray,
+ fDistance + fDashLen);
+
+ const drawinglayer::primitive2d::Primitive2DReference aStrokedLine(
+ new drawinglayer::primitive2d::PolygonStrokePrimitive2D(
+ getLine(),
+ aLineAttribute,
+ aStrokeAttribute));
+
+ drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, aStrokedLine);
+ }
+ }
+
+ if(aRetval.hasElements() && getShadow())
+ {
+ // shadow is only for triangle and line start, and in upper left
+ // and lower right direction, in different colors
+ const double fColorChange(20.0 / 255.0);
+ const basegfx::B3DTuple aColorChange(fColorChange, fColorChange, fColorChange);
+ basegfx::BColor aLighterColor(getColor() + aColorChange);
+ basegfx::BColor aDarkerColor(getColor() - aColorChange);
+
+ aLighterColor.clamp();
+ aDarkerColor.clamp();
+
+ // create shadow sequence
+ drawinglayer::primitive2d::Primitive2DSequence aShadows(2);
+ basegfx::B2DHomMatrix aTransform;
+
+ aTransform.set(0, 2, -getDiscreteUnit());
+ aTransform.set(1, 2, -getDiscreteUnit());
+
+ aShadows[0] = drawinglayer::primitive2d::Primitive2DReference(
+ new drawinglayer::primitive2d::ShadowPrimitive2D(
+ aTransform,
+ aLighterColor,
+ aRetval));
+
+ aTransform.set(0, 2, getDiscreteUnit());
+ aTransform.set(1, 2, getDiscreteUnit());
+
+ aShadows[1] = drawinglayer::primitive2d::Primitive2DReference(
+ new drawinglayer::primitive2d::ShadowPrimitive2D(
+ aTransform,
+ aDarkerColor,
+ aRetval));
+
+ // add shadow before geometry to make it be proccessed first
+ const drawinglayer::primitive2d::Primitive2DSequence aTemporary(aRetval);
+
+ aRetval = aShadows;
+ drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(aRetval, aTemporary);
+ }
+
+ if ( AS_ALL == maAnchorState ||
+ AS_END == maAnchorState )
+ {
+ // LineTop has to be created, too, but uses no shadow, so add after
+ // the other parts are created
+ const drawinglayer::primitive2d::Primitive2DReference aLineTop(
+ new drawinglayer::primitive2d::PolygonStrokePrimitive2D(
+ getLineTop(),
+ aLineAttribute));
+
+ drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, aLineTop);
+ }
+
+ return aRetval;
+}
+
+bool AnchorPrimitive::operator==( const drawinglayer::primitive2d::BasePrimitive2D& rPrimitive ) const
+{
+ if(drawinglayer::primitive2d::DiscreteMetricDependentPrimitive2D::operator==(rPrimitive))
+ {
+ const AnchorPrimitive& rCompare = static_cast< const AnchorPrimitive& >(rPrimitive);
+
+ return (getTriangle() == rCompare.getTriangle()
+ && getLine() == rCompare.getLine()
+ && getLineTop() == rCompare.getLineTop()
+ && getAnchorState() == rCompare.getAnchorState()
+ && getColor() == rCompare.getColor()
+ && getDiscreteLineWidth() == rCompare.getDiscreteLineWidth()
+ && getShadow() == rCompare.getShadow()
+ && getLineSolid() == rCompare.getLineSolid());
+ }
+
+ return false;
+}
+
+ImplPrimitive2DIDBlock(AnchorPrimitive, PRIMITIVE2D_ID_SWSIDEBARANCHORPRIMITIVE)
+
+/*static*/ AnchorOverlayObject* AnchorOverlayObject::CreateAnchorOverlayObject(
+ SwView& rDocView,
+ const SwRect& aAnchorRect,
+ const long& aPageBorder,
+ const Point& aLineStart,
+ const Point& aLineEnd,
+ const Color& aColorAnchor )
+{
+ AnchorOverlayObject* pAnchorOverlayObject( 0 );
+ if ( rDocView.GetDrawView() )
+ {
+ SdrPaintWindow* pPaintWindow = rDocView.GetDrawView()->GetPaintWindow(0);
+ if( pPaintWindow )
+ {
+ rtl::Reference< ::sdr::overlay::OverlayManager > xOverlayManager = pPaintWindow->GetOverlayManager();
+
+ if ( xOverlayManager.is() )
+ {
+ pAnchorOverlayObject = new AnchorOverlayObject(
+ basegfx::B2DPoint( aAnchorRect.Left() , aAnchorRect.Bottom()-5*15),
+ basegfx::B2DPoint( aAnchorRect.Left()-5*15 , aAnchorRect.Bottom()+5*15),
+ basegfx::B2DPoint( aAnchorRect.Left()+5*15 , aAnchorRect.Bottom()+5*15),
+ basegfx::B2DPoint( aAnchorRect.Left(), aAnchorRect.Bottom()+2*15),
+ basegfx::B2DPoint( aPageBorder ,aAnchorRect.Bottom()+2*15),
+ basegfx::B2DPoint( aLineStart.X(),aLineStart.Y()),
+ basegfx::B2DPoint( aLineEnd.X(),aLineEnd.Y()) ,
+ aColorAnchor,
+ false,
+ false);
+ xOverlayManager->add(*pAnchorOverlayObject);
+ }
+ }
+ }
+
+ return pAnchorOverlayObject;
+}
+
+/*static*/ void AnchorOverlayObject::DestroyAnchorOverlayObject( AnchorOverlayObject* pAnchor )
+{
+ if ( pAnchor )
+ {
+ if ( pAnchor->getOverlayManager() )
+ {
+ // remove this object from the chain
+ pAnchor->getOverlayManager()->remove(*pAnchor);
+ }
+ delete pAnchor;
+ }
+}
+
+AnchorOverlayObject::AnchorOverlayObject( const basegfx::B2DPoint& rBasePos,
+ const basegfx::B2DPoint& rSecondPos,
+ const basegfx::B2DPoint& rThirdPos,
+ const basegfx::B2DPoint& rFourthPos,
+ const basegfx::B2DPoint& rFifthPos,
+ const basegfx::B2DPoint& rSixthPos,
+ const basegfx::B2DPoint& rSeventhPos,
+ const Color aBaseColor,
+ const bool bShadowedEffect,
+ const bool bLineSolid)
+ : OverlayObjectWithBasePosition( rBasePos, aBaseColor )
+ , maSecondPosition(rSecondPos)
+ , maThirdPosition(rThirdPos)
+ , maFourthPosition(rFourthPos)
+ , maFifthPosition(rFifthPos)
+ , maSixthPosition(rSixthPos)
+ , maSeventhPosition(rSeventhPos)
+ , maTriangle()
+ , maLine()
+ , maLineTop()
+ , mHeight(0)
+ , mAnchorState(AS_ALL)
+ , mbShadowedEffect(bShadowedEffect)
+ , mbLineSolid(bLineSolid)
+{
+}
+
+AnchorOverlayObject::~AnchorOverlayObject()
+{
+}
+
+void AnchorOverlayObject::implEnsureGeometry()
+{
+ if(!maTriangle.count())
+ {
+ maTriangle.append(getBasePosition());
+ maTriangle.append(GetSecondPosition());
+ maTriangle.append(GetThirdPosition());
+ maTriangle.setClosed(true);
+ }
+
+ if(!maLine.count())
+ {
+ maLine.append(GetFourthPosition());
+ maLine.append(GetFifthPosition());
+ maLine.append(GetSixthPosition());
+ }
+
+ if(!maLineTop.count())
+ {
+ maLineTop.append(GetSixthPosition());
+ maLineTop.append(GetSeventhPosition());
+ }
+}
+
+void AnchorOverlayObject::implResetGeometry()
+{
+ maTriangle.clear();
+ maLine.clear();
+ maLineTop.clear();
+}
+
+drawinglayer::primitive2d::Primitive2DSequence AnchorOverlayObject::createOverlayObjectPrimitive2DSequence()
+{
+ implEnsureGeometry();
+
+ static double aDiscreteLineWidth(1.6);
+ const drawinglayer::primitive2d::Primitive2DReference aReference(
+ new AnchorPrimitive( maTriangle,
+ maLine,
+ maLineTop,
+ GetAnchorState(),
+ getBaseColor().getBColor(),
+ ANCHORLINE_WIDTH * aDiscreteLineWidth,
+ getShadowedEffect(),
+ getLineSolid()) );
+
+ return drawinglayer::primitive2d::Primitive2DSequence(&aReference, 1);
+}
+
+void AnchorOverlayObject::SetAllPosition( const basegfx::B2DPoint& rPoint1,
+ const basegfx::B2DPoint& rPoint2,
+ const basegfx::B2DPoint& rPoint3,
+ const basegfx::B2DPoint& rPoint4,
+ const basegfx::B2DPoint& rPoint5,
+ const basegfx::B2DPoint& rPoint6,
+ const basegfx::B2DPoint& rPoint7)
+{
+ if ( rPoint1 != getBasePosition() ||
+ rPoint2 != GetSecondPosition() ||
+ rPoint3 != GetThirdPosition() ||
+ rPoint4 != GetFourthPosition() ||
+ rPoint5 != GetFifthPosition() ||
+ rPoint6 != GetSixthPosition() ||
+ rPoint7 != GetSeventhPosition() )
+ {
+ maBasePosition = rPoint1;
+ maSecondPosition = rPoint2;
+ maThirdPosition = rPoint3;
+ maFourthPosition = rPoint4;
+ maFifthPosition = rPoint5;
+ maSixthPosition = rPoint6;
+ maSeventhPosition = rPoint7;
+
+ implResetGeometry();
+ objectChange();
+ }
+}
+
+void AnchorOverlayObject::SetSixthPosition(const basegfx::B2DPoint& rNew)
+{
+ if(rNew != maSixthPosition)
+ {
+ maSixthPosition = rNew;
+ implResetGeometry();
+ objectChange();
+ }
+}
+
+void AnchorOverlayObject::SetSeventhPosition(const basegfx::B2DPoint& rNew)
+{
+ if(rNew != maSeventhPosition)
+ {
+ maSeventhPosition = rNew;
+ implResetGeometry();
+ objectChange();
+ }
+}
+
+void AnchorOverlayObject::SetTriPosition(const basegfx::B2DPoint& rPoint1,const basegfx::B2DPoint& rPoint2,const basegfx::B2DPoint& rPoint3,
+ const basegfx::B2DPoint& rPoint4,const basegfx::B2DPoint& rPoint5)
+{
+ if(rPoint1 != getBasePosition()
+ || rPoint2 != GetSecondPosition()
+ || rPoint3 != GetThirdPosition()
+ || rPoint4 != GetFourthPosition()
+ || rPoint5 != GetFifthPosition())
+ {
+ maBasePosition = rPoint1;
+ maSecondPosition = rPoint2;
+ maThirdPosition = rPoint3;
+ maFourthPosition = rPoint4;
+ maFifthPosition = rPoint5;
+
+ implResetGeometry();
+ objectChange();
+ }
+}
+
+void AnchorOverlayObject::setLineSolid( const bool bNew )
+{
+ if ( bNew != getLineSolid() )
+ {
+ mbLineSolid = bNew;
+ objectChange();
+ }
+}
+
+void AnchorOverlayObject::SetAnchorState( const AnchorState aState)
+{
+ if ( mAnchorState != aState)
+ {
+ mAnchorState = aState;
+ objectChange();
+ }
+}
+
+} } // end of namespace sw::annotation
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/docvw/AnchorOverlayObject.hxx b/sw/source/uibase/docvw/AnchorOverlayObject.hxx
new file mode 100644
index 000000000000..c4b4c1c5ce16
--- /dev/null
+++ b/sw/source/uibase/docvw/AnchorOverlayObject.hxx
@@ -0,0 +1,133 @@
+/* -*- 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 .
+ */
+
+#ifndef INCLUDED_SW_SOURCE_CORE_UIBASE_DOCVW_ANCHOROVERLAYOBJECT_HXX
+#define INCLUDED_SW_SOURCE_CORE_UIBASE_DOCVW_ANCHOROVERLAYOBJECT_HXX
+
+#include <svx/sdr/overlay/overlayobject.hxx>
+
+#include <basegfx/polygon/b2dpolygon.hxx>
+
+class SwView;
+class SwRect;
+class Point;
+
+namespace sw { namespace sidebarwindows {
+
+enum AnchorState
+{
+ AS_ALL,
+ AS_START,
+ AS_END,
+ AS_TRI
+};
+
+class AnchorOverlayObject: public sdr::overlay::OverlayObjectWithBasePosition
+{
+ public:
+ static AnchorOverlayObject* CreateAnchorOverlayObject( SwView& rDocView,
+ const SwRect& aAnchorRect,
+ const long& aPageBorder,
+ const Point& aLineStart,
+ const Point& aLineEnd,
+ const Color& aColorAnchor );
+ static void DestroyAnchorOverlayObject( AnchorOverlayObject* pAnchor );
+
+ inline const basegfx::B2DPoint& GetSecondPosition() const { return maSecondPosition; }
+ const basegfx::B2DPoint& GetThirdPosition() const { return maThirdPosition; }
+ const basegfx::B2DPoint& GetFourthPosition() const { return maFourthPosition; }
+ const basegfx::B2DPoint& GetFifthPosition() const { return maFifthPosition; }
+ const basegfx::B2DPoint& GetSixthPosition() const { return maSixthPosition; }
+ const basegfx::B2DPoint& GetSeventhPosition() const { return maSeventhPosition; }
+
+ void SetAllPosition( const basegfx::B2DPoint& rPoint1,
+ const basegfx::B2DPoint& rPoint2,
+ const basegfx::B2DPoint& rPoint3,
+ const basegfx::B2DPoint& rPoint4,
+ const basegfx::B2DPoint& rPoint5,
+ const basegfx::B2DPoint& rPoint6,
+ const basegfx::B2DPoint& rPoint7 );
+ void SetTriPosition( const basegfx::B2DPoint& rPoint1,
+ const basegfx::B2DPoint& rPoint2,
+ const basegfx::B2DPoint& rPoint3,
+ const basegfx::B2DPoint& rPoint4,
+ const basegfx::B2DPoint& rPoint5 );
+ void SetSixthPosition( const basegfx::B2DPoint& rNew );
+ void SetSeventhPosition( const basegfx::B2DPoint& rNew );
+
+ void setLineSolid( const bool bNew );
+ inline bool getLineSolid() const { return mbLineSolid; }
+
+ inline void SetHeight( const unsigned long aHeight ) { mHeight = aHeight; };
+
+ bool getShadowedEffect() const { return mbShadowedEffect; }
+
+ void SetAnchorState( const AnchorState aState );
+ inline AnchorState GetAnchorState() const { return mAnchorState; }
+
+ protected:
+ /* 6------------7
+ 1 /
+ /4\ ---------------5
+ 2 - 3
+ */
+
+ basegfx::B2DPoint maSecondPosition;
+ basegfx::B2DPoint maThirdPosition;
+ basegfx::B2DPoint maFourthPosition;
+ basegfx::B2DPoint maFifthPosition;
+ basegfx::B2DPoint maSixthPosition;
+ basegfx::B2DPoint maSeventhPosition;
+
+ // helpers to fill and reset geometry
+ void implEnsureGeometry();
+ void implResetGeometry();
+
+ // geometry creation for OverlayObject
+ virtual drawinglayer::primitive2d::Primitive2DSequence createOverlayObjectPrimitive2DSequence() SAL_OVERRIDE;
+
+ private:
+ // object's geometry
+ basegfx::B2DPolygon maTriangle;
+ basegfx::B2DPolygon maLine;
+ basegfx::B2DPolygon maLineTop;
+ unsigned long mHeight;
+ AnchorState mAnchorState;
+
+ bool mbShadowedEffect : 1;
+ bool mbLineSolid : 1;
+
+ AnchorOverlayObject( const basegfx::B2DPoint& rBasePos,
+ const basegfx::B2DPoint& rSecondPos,
+ const basegfx::B2DPoint& rThirdPos,
+ const basegfx::B2DPoint& rFourthPos,
+ const basegfx::B2DPoint& rFifthPos,
+ const basegfx::B2DPoint& rSixthPos,
+ const basegfx::B2DPoint& rSeventhPos,
+ const Color aBaseColor,
+ const bool bShadowedEffect,
+ const bool bLineSolid );
+ virtual ~AnchorOverlayObject();
+};
+
+} } // end of namespace sw::annotation
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/docvw/AnnotationMenuButton.cxx b/sw/source/uibase/docvw/AnnotationMenuButton.cxx
new file mode 100644
index 000000000000..051d7eebcd7c
--- /dev/null
+++ b/sw/source/uibase/docvw/AnnotationMenuButton.cxx
@@ -0,0 +1,205 @@
+/* -*- 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 <AnnotationMenuButton.hxx>
+
+#include <annotation.hrc>
+#include <app.hrc>
+#include <access.hrc>
+
+#include <unotools/useroptions.hxx>
+
+#include <vcl/svapp.hxx>
+#include <vcl/menu.hxx>
+#include <vcl/decoview.hxx>
+#include <vcl/gradient.hxx>
+#include <vcl/settings.hxx>
+
+#include <cmdid.h>
+#include <SidebarWin.hxx>
+
+namespace sw { namespace annotation {
+
+Color ColorFromAlphaColor( const sal_uInt8 aTransparency,
+ const Color &aFront,
+ const Color &aBack )
+{
+ return Color((sal_uInt8)(aFront.GetRed() * aTransparency/(double)255 + aBack.GetRed() * (1-aTransparency/(double)255)),
+ (sal_uInt8)(aFront.GetGreen() * aTransparency/(double)255 + aBack.GetGreen() * (1-aTransparency/(double)255)),
+ (sal_uInt8)(aFront.GetBlue() * aTransparency/(double)255 + aBack.GetBlue() * (1-aTransparency/(double)255)));
+}
+
+AnnotationMenuButton::AnnotationMenuButton( sw::sidebarwindows::SwSidebarWin& rSidebarWin )
+ : MenuButton( &rSidebarWin )
+ , mrSidebarWin( rSidebarWin )
+{
+ AddEventListener( LINK( &mrSidebarWin, sw::sidebarwindows::SwSidebarWin, WindowEventListener ) );
+
+ SetAccessibleName( SW_RES( STR_ACCESS_ANNOTATION_BUTTON_NAME ) );
+ SetAccessibleDescription( SW_RES( STR_ACCESS_ANNOTATION_BUTTON_DESC ) );
+ SetQuickHelpText( GetAccessibleDescription() );
+}
+
+AnnotationMenuButton::~AnnotationMenuButton()
+{
+ RemoveEventListener( LINK( &mrSidebarWin, sw::sidebarwindows::SwSidebarWin, WindowEventListener ) );
+}
+
+void AnnotationMenuButton::Select()
+{
+ mrSidebarWin.ExecuteCommand( GetCurItemId() );
+}
+
+void AnnotationMenuButton::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ PopupMenu* pButtonPopup( GetPopupMenu() );
+ if ( mrSidebarWin.IsReadOnly() )
+ {
+ pButtonPopup->EnableItem( FN_REPLY, false );
+ pButtonPopup->EnableItem( FN_DELETE_COMMENT, false );
+ pButtonPopup->EnableItem( FN_DELETE_NOTE_AUTHOR, false );
+ pButtonPopup->EnableItem( FN_DELETE_ALL_NOTES, false );
+ pButtonPopup->EnableItem( FN_FORMAT_ALL_NOTES, false );
+ }
+ else
+ {
+ pButtonPopup->EnableItem( FN_DELETE_COMMENT, !mrSidebarWin.IsProtected() );
+ pButtonPopup->EnableItem( FN_DELETE_NOTE_AUTHOR, true );
+ pButtonPopup->EnableItem( FN_DELETE_ALL_NOTES, true );
+ pButtonPopup->EnableItem( FN_FORMAT_ALL_NOTES, true );
+ }
+
+ if ( mrSidebarWin.IsProtected() )
+ {
+ pButtonPopup->EnableItem( FN_REPLY, false );
+ }
+ else
+ {
+ SvtUserOptions aUserOpt;
+ OUString sAuthor;
+ if ( (sAuthor = aUserOpt.GetFullName()).isEmpty() )
+ {
+ if ( (sAuthor = aUserOpt.GetID()).isEmpty() )
+ {
+ sAuthor = SW_RES( STR_REDLINE_UNKNOWN_AUTHOR );
+ }
+ }
+ // do not allow to reply to ourself and no answer possible if this note is in a protected section
+ if ( sAuthor == mrSidebarWin.GetAuthor() )
+ {
+ pButtonPopup->EnableItem( FN_REPLY, false );
+ }
+ else
+ {
+ pButtonPopup->EnableItem( FN_REPLY, true );
+ }
+ }
+
+ MenuButton::MouseButtonDown( rMEvt );
+}
+
+void AnnotationMenuButton::Paint( const Rectangle& /*rRect*/ )
+{
+ if ( Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
+ SetFillColor(COL_BLACK);
+ else
+ SetFillColor( mrSidebarWin.ColorDark() );
+ SetLineColor();
+ const Rectangle aRect( Rectangle( Point( 0, 0 ), PixelToLogic( GetSizePixel() ) ) );
+ DrawRect( aRect );
+
+ if ( Application::GetSettings().GetStyleSettings().GetHighContrastMode())
+ {
+ //draw rect around button
+ SetFillColor(COL_BLACK);
+ SetLineColor(COL_WHITE);
+ }
+ else
+ {
+ //draw button
+ Gradient aGradient;
+ if ( IsMouseOver() )
+ aGradient = Gradient( GradientStyle_LINEAR,
+ ColorFromAlphaColor( 80, mrSidebarWin.ColorAnchor(), mrSidebarWin.ColorDark() ),
+ ColorFromAlphaColor( 15, mrSidebarWin.ColorAnchor(), mrSidebarWin.ColorDark() ));
+ else
+ aGradient = Gradient( GradientStyle_LINEAR,
+ ColorFromAlphaColor( 15, mrSidebarWin.ColorAnchor(), mrSidebarWin.ColorDark() ),
+ ColorFromAlphaColor( 80, mrSidebarWin.ColorAnchor(), mrSidebarWin.ColorDark() ));
+ DrawGradient( aRect, aGradient );
+
+ //draw rect around button
+ SetFillColor();
+ SetLineColor( ColorFromAlphaColor( 90, mrSidebarWin.ColorAnchor(), mrSidebarWin.ColorDark() ));
+ }
+ DrawRect( aRect );
+
+ if ( mrSidebarWin.IsPreview() )
+ {
+ Font aOldFont( mrSidebarWin.GetFont() );
+ Font aFont(aOldFont);
+ Color aCol( COL_BLACK);
+ aFont.SetColor( aCol );
+ aFont.SetHeight(200);
+ aFont.SetWeight(WEIGHT_MEDIUM);
+ SetFont( aFont );
+ DrawText( aRect ,
+ OUString("Edit Note"),
+ TEXT_DRAW_CENTER );
+ SetFont( aOldFont );
+ }
+ else
+ {
+ Rectangle aSymbolRect( aRect );
+ // 25% distance to the left and right button border
+ const long nBorderDistanceLeftAndRight = ((aSymbolRect.GetWidth()*250)+500)/1000;
+ aSymbolRect.Left()+=nBorderDistanceLeftAndRight;
+ aSymbolRect.Right()-=nBorderDistanceLeftAndRight;
+ // 40% distance to the top button border
+ const long nBorderDistanceTop = ((aSymbolRect.GetHeight()*400)+500)/1000;
+ aSymbolRect.Top()+=nBorderDistanceTop;
+ // 15% distance to the bottom button border
+ const long nBorderDistanceBottom = ((aSymbolRect.GetHeight()*150)+500)/1000;
+ aSymbolRect.Bottom()-=nBorderDistanceBottom;
+ DecorationView aDecoView( this );
+ aDecoView.DrawSymbol( aSymbolRect, SYMBOL_SPIN_DOWN,
+ ( Application::GetSettings().GetStyleSettings().GetHighContrastMode()
+ ? Color( COL_WHITE )
+ : Color( COL_BLACK ) ) );
+ }
+}
+
+void AnnotationMenuButton::KeyInput( const KeyEvent& rKeyEvt )
+{
+ const KeyCode& rKeyCode = rKeyEvt.GetKeyCode();
+ const sal_uInt16 nKey = rKeyCode.GetCode();
+ if ( nKey == KEY_TAB )
+ {
+ mrSidebarWin.ActivatePostIt();
+ mrSidebarWin.GrabFocus();
+ }
+ else
+ {
+ MenuButton::KeyInput( rKeyEvt );
+ }
+}
+
+} } // end of namespace sw::annotation
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/docvw/AnnotationMenuButton.hxx b/sw/source/uibase/docvw/AnnotationMenuButton.hxx
new file mode 100644
index 000000000000..b90dea4de951
--- /dev/null
+++ b/sw/source/uibase/docvw/AnnotationMenuButton.hxx
@@ -0,0 +1,53 @@
+/* -*- 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 .
+ */
+
+#ifndef INCLUDED_SW_SOURCE_CORE_UIBASE_DOCVW_ANNOTATIONMENUBUTTON_HXX
+#define INCLUDED_SW_SOURCE_CORE_UIBASE_DOCVW_ANNOTATIONMENUBUTTON_HXX
+
+#include <vcl/menubtn.hxx>
+
+namespace sw { namespace sidebarwindows {
+ class SwSidebarWin;
+} }
+
+namespace sw { namespace annotation {
+
+class AnnotationMenuButton : public MenuButton
+{
+ public:
+ AnnotationMenuButton( sw::sidebarwindows::SwSidebarWin& rSidebarWin );
+ virtual ~AnnotationMenuButton();
+
+ // overloaded <MenuButton> methods
+ virtual void Select() SAL_OVERRIDE;
+
+ // overloaded <Window> methods
+ virtual void MouseButtonDown( const MouseEvent& rMEvt ) SAL_OVERRIDE;
+ virtual void Paint( const Rectangle& rRect ) SAL_OVERRIDE;
+ virtual void KeyInput( const KeyEvent& rKeyEvt ) SAL_OVERRIDE;
+
+ private:
+ sw::sidebarwindows::SwSidebarWin& mrSidebarWin;
+};
+
+} } // end of namespace sw::annotation
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/docvw/AnnotationWin.cxx b/sw/source/uibase/docvw/AnnotationWin.cxx
new file mode 100644
index 000000000000..9ef1e482bae0
--- /dev/null
+++ b/sw/source/uibase/docvw/AnnotationWin.cxx
@@ -0,0 +1,318 @@
+/* -*- 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 <AnnotationWin.hxx>
+
+#include <AnnotationMenuButton.hxx>
+#include <PostItMgr.hxx>
+
+#include <annotation.hrc>
+#include <popup.hrc>
+#include <cmdid.h>
+
+#include <vcl/menu.hxx>
+
+#include <svl/undo.hxx>
+#include <unotools/syslocale.hxx>
+#include <svl/languageoptions.hxx>
+
+#include <editeng/postitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/langitem.hxx>
+
+#include <editeng/editview.hxx>
+#include <editeng/outliner.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/editobj.hxx>
+
+#include <docufld.hxx>
+#include <txtfld.hxx>
+#include <ndtxt.hxx>
+#include <view.hxx>
+#include <wrtsh.hxx>
+#include <docsh.hxx>
+#include <doc.hxx>
+#include <IDocumentUndoRedo.hxx>
+#include <SwUndoField.hxx>
+
+#include <boost/scoped_ptr.hpp>
+
+namespace sw { namespace annotation {
+
+SwAnnotationWin::SwAnnotationWin( SwEditWin& rEditWin,
+ WinBits nBits,
+ SwPostItMgr& aMgr,
+ SwPostItBits aBits,
+ SwSidebarItem& rSidebarItem,
+ SwFmtFld* aField )
+ : SwSidebarWin( rEditWin, nBits, aMgr, aBits, rSidebarItem )
+ , mpFmtFld(aField)
+ , mpFld( static_cast<SwPostItField*>(aField->GetField()))
+ , mpButtonPopup(0)
+{
+}
+
+SwAnnotationWin::~SwAnnotationWin()
+{
+ delete mpButtonPopup;
+}
+
+void SwAnnotationWin::SetPostItText()
+{
+ //If the cursor was visible, then make it visible again after
+ //changing text, e.g. fdo#33599
+ Cursor *pCursor = GetOutlinerView()->GetEditView().GetCursor();
+ bool bCursorVisible = pCursor && pCursor->IsVisible();
+
+ //If the new text is the same as the old text, keep the same insertion
+ //point .e.g. fdo#33599
+ mpFld = static_cast<SwPostItField*>(mpFmtFld->GetField());
+ OUString sNewText = mpFld->GetPar2();
+ bool bTextUnchanged = sNewText.equals(Engine()->GetEditEngine().GetText());
+ ESelection aOrigSelection(GetOutlinerView()->GetEditView().GetSelection());
+
+ // get text from SwPostItField and insert into our textview
+ Engine()->SetModifyHdl( Link() );
+ Engine()->EnableUndo( false );
+ if( mpFld->GetTextObject() )
+ Engine()->SetText( *mpFld->GetTextObject() );
+ else
+ {
+ Engine()->Clear();
+ GetOutlinerView()->SetAttribs(DefaultItem());
+ GetOutlinerView()->InsertText(sNewText,false);
+ }
+
+ Engine()->ClearModifyFlag();
+ Engine()->GetUndoManager().Clear();
+ Engine()->EnableUndo( true );
+ Engine()->SetModifyHdl( LINK( this, SwAnnotationWin, ModifyHdl ) );
+ if (bTextUnchanged)
+ GetOutlinerView()->GetEditView().SetSelection(aOrigSelection);
+ if (bCursorVisible)
+ GetOutlinerView()->ShowCursor();
+ Invalidate();
+}
+
+void SwAnnotationWin::UpdateData()
+{
+ if ( Engine()->IsModified() )
+ {
+ IDocumentUndoRedo & rUndoRedo(
+ DocView().GetDocShell()->GetDoc()->GetIDocumentUndoRedo());
+ boost::scoped_ptr<SwField> pOldField;
+ if (rUndoRedo.DoesUndo())
+ {
+ pOldField.reset(mpFld->Copy());
+ }
+ mpFld->SetPar2(Engine()->GetEditEngine().GetText());
+ mpFld->SetTextObject(Engine()->CreateParaObject());
+ if (rUndoRedo.DoesUndo())
+ {
+ SwTxtFld *const pTxtFld = mpFmtFld->GetTxtFld();
+ SwPosition aPosition( pTxtFld->GetTxtNode() );
+ aPosition.nContent = *pTxtFld->GetStart();
+ rUndoRedo.AppendUndo(
+ new SwUndoFieldFromDoc(aPosition, *pOldField, *mpFld, 0, true));
+ }
+ // so we get a new layout of notes (anchor position is still the same and we would otherwise not get one)
+ Mgr().SetLayout();
+ // #i98686# if we have several views, all notes should update their text
+ mpFmtFld->Broadcast(SwFmtFldHint( 0, SWFMTFLD_CHANGED));
+ DocView().GetDocShell()->SetModified();
+ }
+ Engine()->ClearModifyFlag();
+ Engine()->GetUndoManager().Clear();
+}
+
+void SwAnnotationWin::Delete()
+{
+ SwSidebarWin::Delete();
+ // we delete the field directly, the Mgr cleans up the PostIt by listening
+ DocView().GetWrtShellPtr()->GotoField(*mpFmtFld);
+ GrabFocusToDocument();
+ DocView().GetWrtShellPtr()->DelRight();
+}
+
+void SwAnnotationWin::GotoPos()
+{
+ DocView().GetDocShell()->GetWrtShell()->GotoField(*mpFmtFld);
+}
+
+sal_uInt32 SwAnnotationWin::MoveCaret()
+{
+ // if this is an answer, do not skip over all following ones, but insert directly behind the current one
+ // but when just leaving a note, skip all following ones as well to continue typing
+ return Mgr().IsAnswer()
+ ? 1
+ : 1 + CountFollowing();
+}
+
+//returns true, if there is another note right before this note
+bool SwAnnotationWin::CalcFollow()
+{
+ SwTxtFld* pTxtFld = mpFmtFld->GetTxtFld();
+ SwPosition aPosition( pTxtFld->GetTxtNode() );
+ aPosition.nContent = *pTxtFld->GetStart();
+ SwTxtAttr * const pTxtAttr =
+ pTxtFld->GetTxtNode().GetTxtAttrForCharAt(
+ aPosition.nContent.GetIndex() - 1,
+ RES_TXTATR_ANNOTATION );
+ const SwField* pFld = pTxtAttr ? pTxtAttr->GetFmtFld().GetField() : 0;
+ return pFld && (pFld->Which()== RES_POSTITFLD);
+}
+
+// counts how many SwPostItField we have right after the current one
+sal_uInt32 SwAnnotationWin::CountFollowing()
+{
+ sal_uInt32 aCount = 1; // we start with 1, so we have to subtract one at the end again
+ SwTxtFld* pTxtFld = mpFmtFld->GetTxtFld();
+ SwPosition aPosition( pTxtFld->GetTxtNode() );
+ aPosition.nContent = *pTxtFld->GetStart();
+
+ SwTxtAttr * pTxtAttr = pTxtFld->GetTxtNode().GetTxtAttrForCharAt(
+ aPosition.nContent.GetIndex() + 1,
+ RES_TXTATR_ANNOTATION );
+ SwField* pFld = pTxtAttr
+ ? const_cast<SwField*>(pTxtAttr->GetFmtFld().GetField())
+ : 0;
+ while ( pFld && ( pFld->Which()== RES_POSTITFLD ) )
+ {
+ aCount++;
+ pTxtAttr = pTxtFld->GetTxtNode().GetTxtAttrForCharAt(
+ aPosition.nContent.GetIndex() + aCount,
+ RES_TXTATR_ANNOTATION );
+ pFld = pTxtAttr
+ ? const_cast<SwField*>(pTxtAttr->GetFmtFld().GetField())
+ : 0;
+ }
+ return aCount - 1;
+}
+
+MenuButton* SwAnnotationWin::CreateMenuButton()
+{
+ mpButtonPopup = new PopupMenu(SW_RES(MN_ANNOTATION_BUTTON));
+ OUString aText = mpButtonPopup->GetItemText( FN_DELETE_NOTE_AUTHOR );
+ SwRewriter aRewriter;
+ aRewriter.AddRule(UndoArg1,GetAuthor());
+ aText = aRewriter.Apply(aText);
+ mpButtonPopup->SetItemText(FN_DELETE_NOTE_AUTHOR,aText);
+ MenuButton* pMenuButton = new AnnotationMenuButton( *this );
+ pMenuButton->SetPopupMenu( mpButtonPopup );
+ pMenuButton->Show();
+ return pMenuButton;
+}
+
+void SwAnnotationWin::InitAnswer(OutlinerParaObject* pText)
+{
+ //collect our old meta data
+ SwSidebarWin* pWin = Mgr().GetNextPostIt(KEY_PAGEUP, this);
+ const SvtSysLocale aSysLocale;
+ const LocaleDataWrapper& rLocalData = aSysLocale.GetLocaleData();
+ SwRewriter aRewriter;
+ aRewriter.AddRule(UndoArg1, pWin->GetAuthor());
+ const OUString aText = aRewriter.Apply(SW_RESSTR(STR_REPLY))
+ + " (" + rLocalData.getDate( pWin->GetDate())
+ + ", " + rLocalData.getTime( pWin->GetTime(), false)
+ + "): \"";
+ GetOutlinerView()->InsertText(aText,false);
+
+ // insert old, selected text or "..."
+ // TODO: iterate over all paragraphs, not only first one to find out if it is empty
+ if (!pText->GetTextObject().GetText(0).isEmpty())
+ GetOutlinerView()->GetEditView().InsertText(pText->GetTextObject());
+ else
+ GetOutlinerView()->InsertText(OUString("..."),false);
+ GetOutlinerView()->InsertText(OUString("\"\n"),false);
+
+ GetOutlinerView()->SetSelection(ESelection(0,0,EE_PARA_ALL,EE_TEXTPOS_ALL));
+ SfxItemSet aAnswerSet( DocView().GetDocShell()->GetPool() );
+ aAnswerSet.Put(SvxFontHeightItem(200,80,EE_CHAR_FONTHEIGHT));
+ aAnswerSet.Put(SvxPostureItem(ITALIC_NORMAL,EE_CHAR_ITALIC));
+ GetOutlinerView()->SetAttribs(aAnswerSet);
+ GetOutlinerView()->SetSelection(ESelection(EE_PARA_MAX_COUNT,EE_TEXTPOS_MAX_COUNT,EE_PARA_MAX_COUNT,EE_TEXTPOS_MAX_COUNT));
+
+ //remove all attributes and reset our standard ones
+ GetOutlinerView()->GetEditView().RemoveAttribsKeepLanguages(true);
+ GetOutlinerView()->SetAttribs(DefaultItem());
+ // lets insert an undo step so the initial text can be easily deleted
+ // but do not use UpdateData() directly, would set modified state again and reentrance into Mgr
+ Engine()->SetModifyHdl( Link() );
+ IDocumentUndoRedo & rUndoRedo(
+ DocView().GetDocShell()->GetDoc()->GetIDocumentUndoRedo());
+ boost::scoped_ptr<SwField> pOldField;
+ if (rUndoRedo.DoesUndo())
+ {
+ pOldField.reset(mpFld->Copy());
+ }
+ mpFld->SetPar2(Engine()->GetEditEngine().GetText());
+ mpFld->SetTextObject(Engine()->CreateParaObject());
+ if (rUndoRedo.DoesUndo())
+ {
+ SwTxtFld *const pTxtFld = mpFmtFld->GetTxtFld();
+ SwPosition aPosition( pTxtFld->GetTxtNode() );
+ aPosition.nContent = *pTxtFld->GetStart();
+ rUndoRedo.AppendUndo(
+ new SwUndoFieldFromDoc(aPosition, *pOldField, *mpFld, 0, true));
+ }
+ Engine()->SetModifyHdl( LINK( this, SwAnnotationWin, ModifyHdl ) );
+ Engine()->ClearModifyFlag();
+ Engine()->GetUndoManager().Clear();
+}
+
+SvxLanguageItem SwAnnotationWin::GetLanguage(void)
+{
+ // set initial language for outliner
+ sal_uInt16 nScriptType = SvtLanguageOptions::GetScriptTypeOfLanguage( mpFld->GetLanguage() );
+ sal_uInt16 nLangWhichId = 0;
+ switch (nScriptType)
+ {
+ case SCRIPTTYPE_LATIN : nLangWhichId = EE_CHAR_LANGUAGE ; break;
+ case SCRIPTTYPE_ASIAN : nLangWhichId = EE_CHAR_LANGUAGE_CJK; break;
+ case SCRIPTTYPE_COMPLEX : nLangWhichId = EE_CHAR_LANGUAGE_CTL; break;
+ default: OSL_FAIL("GetLanguage: wrong script type");
+ }
+ return SvxLanguageItem(mpFld->GetLanguage(),nLangWhichId);
+}
+
+bool SwAnnotationWin::IsProtected()
+{
+ return SwSidebarWin::IsProtected() ||
+ GetLayoutStatus() == SwPostItHelper::DELETED ||
+ ( mpFmtFld && mpFmtFld->IsProtect() );
+}
+
+OUString SwAnnotationWin::GetAuthor()
+{
+ return mpFld->GetPar1();
+}
+
+Date SwAnnotationWin::GetDate()
+{
+ return mpFld->GetDate();
+}
+
+Time SwAnnotationWin::GetTime()
+{
+ return mpFld->GetTime();
+}
+
+} } // end of namespace sw::annotation
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/docvw/DashedLine.cxx b/sw/source/uibase/docvw/DashedLine.cxx
new file mode 100644
index 000000000000..e9e343b3dc27
--- /dev/null
+++ b/sw/source/uibase/docvw/DashedLine.cxx
@@ -0,0 +1,97 @@
+/* -*- 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/.
+ */
+
+#include <DashedLine.hxx>
+
+#include <basegfx/color/bcolortools.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
+#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
+#include <drawinglayer/processor2d/baseprocessor2d.hxx>
+#include <drawinglayer/processor2d/processorfromoutputdevice.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/settings.hxx>
+
+SwDashedLine::SwDashedLine( Window* pParent, Color& ( *pColorFn )() ) :
+ FixedLine( pParent, WB_DIALOGCONTROL | WB_HORZ ),
+ m_pColorFn( pColorFn )
+{
+}
+
+SwDashedLine::~SwDashedLine( )
+{
+}
+
+void SwDashedLine::Paint( const Rectangle& )
+{
+ const drawinglayer::geometry::ViewInformation2D aNewViewInfos;
+ drawinglayer::processor2d::BaseProcessor2D * pProcessor =
+ drawinglayer::processor2d::createBaseProcessor2DFromOutputDevice(
+ *this, aNewViewInfos );
+
+ // Compute the start and end points
+ const Rectangle aRect( Rectangle( Point( 0, 0 ), PixelToLogic( GetSizePixel() ) ) );
+ double nHalfWidth = double( aRect.Top() + aRect.Bottom() ) / 2.0;
+
+ basegfx::B2DPoint aStart( double( aRect.Left() ), nHalfWidth );
+ basegfx::B2DPoint aEnd( double( aRect.Right() ), nHalfWidth );
+
+ basegfx::B2DPolygon aPolygon;
+ aPolygon.append( aStart );
+ aPolygon.append( aEnd );
+
+ drawinglayer::primitive2d::Primitive2DSequence aSeq( 1 );
+
+ const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
+
+ std::vector< double > aStrokePattern;
+ basegfx::BColor aColor = m_pColorFn().getBColor();
+ if ( rSettings.GetHighContrastMode( ) )
+ {
+ // Only a solid line in high contrast mode
+ aColor = rSettings.GetDialogTextColor().getBColor();
+ }
+ else
+ {
+ // Get a color for the contrast
+ basegfx::BColor aHslLine = basegfx::tools::rgb2hsl( aColor );
+ double nLuminance = aHslLine.getZ();
+ nLuminance += ( 1.0 - nLuminance ) * 0.75;
+ if ( aHslLine.getZ() > 0.7 )
+ nLuminance = aHslLine.getZ() * 0.7;
+ aHslLine.setZ( nLuminance );
+ const basegfx::BColor aOtherColor = basegfx::tools::hsl2rgb( aHslLine );
+
+ // Compute the plain line
+ drawinglayer::primitive2d::PolygonHairlinePrimitive2D * pPlainLine =
+ new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(
+ aPolygon, aOtherColor );
+
+ aSeq[0] = drawinglayer::primitive2d::Primitive2DReference( pPlainLine );
+ // Dashed line in twips
+ aStrokePattern.push_back( 3 );
+ aStrokePattern.push_back( 3 );
+
+ aSeq.realloc( 2 );
+ }
+
+ // Compute the dashed line primitive
+ drawinglayer::primitive2d::PolyPolygonStrokePrimitive2D * pLine =
+ new drawinglayer::primitive2d::PolyPolygonStrokePrimitive2D (
+ basegfx::B2DPolyPolygon( aPolygon ),
+ drawinglayer::attribute::LineAttribute( m_pColorFn().getBColor() ),
+ drawinglayer::attribute::StrokeAttribute( aStrokePattern ) );
+
+ aSeq[ aSeq.getLength() - 1 ] = drawinglayer::primitive2d::Primitive2DReference( pLine );
+
+ pProcessor->process( aSeq );
+ delete pProcessor;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/docvw/FrameControlsManager.cxx b/sw/source/uibase/docvw/FrameControlsManager.cxx
new file mode 100644
index 000000000000..67d8006f4aa5
--- /dev/null
+++ b/sw/source/uibase/docvw/FrameControlsManager.cxx
@@ -0,0 +1,159 @@
+/* -*- 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/.
+ */
+
+#include <edtwin.hxx>
+#include <FrameControlsManager.hxx>
+#include <HeaderFooterWin.hxx>
+#include <PageBreakWin.hxx>
+#include <pagefrm.hxx>
+#include <viewopt.hxx>
+#include <view.hxx>
+#include <wrtsh.hxx>
+
+using namespace std;
+
+SwFrameControlsManager::SwFrameControlsManager( SwEditWin* pEditWin ) :
+ m_pEditWin( pEditWin ),
+ m_aControls( )
+{
+}
+
+SwFrameControlsManager::~SwFrameControlsManager()
+{
+}
+
+SwFrameControlsManager::SwFrameControlsManager( const SwFrameControlsManager& rCopy ) :
+ m_pEditWin( rCopy.m_pEditWin ),
+ m_aControls( rCopy.m_aControls )
+{
+}
+
+const SwFrameControlsManager& SwFrameControlsManager::operator=( const SwFrameControlsManager& rCopy )
+{
+ m_pEditWin = rCopy.m_pEditWin;
+ m_aControls = rCopy.m_aControls;
+ return *this;
+}
+
+SwFrameControlPtr SwFrameControlsManager::GetControl( FrameControlType eType, const SwFrm* pFrm )
+{
+ SwFrameControlPtrMap& rControls = m_aControls[eType];
+
+ SwFrameControlPtrMap::iterator aIt = rControls.find(pFrm);
+
+ if (aIt != rControls.end())
+ return aIt->second;
+
+ return SwFrameControlPtr();
+}
+
+void SwFrameControlsManager::RemoveControls( const SwFrm* pFrm )
+{
+ map< FrameControlType, SwFrameControlPtrMap >::iterator pIt = m_aControls.begin();
+
+ while ( pIt != m_aControls.end() )
+ {
+ SwFrameControlPtrMap& rMap = pIt->second;
+ rMap.erase(pFrm);
+ ++pIt;
+ }
+}
+
+void SwFrameControlsManager::RemoveControlsByType( FrameControlType eType, const SwFrm* pFrm )
+{
+ SwFrameControlPtrMap& rMap = m_aControls[eType];
+ rMap.erase(pFrm);
+}
+
+void SwFrameControlsManager::HideControls( FrameControlType eType )
+{
+ SwFrameControlPtrMap::iterator pIt = m_aControls[eType].begin();
+ while ( pIt != m_aControls[eType].end() )
+ {
+ pIt->second->ShowAll( false );
+ ++pIt;
+ }
+}
+
+void SwFrameControlsManager::SetReadonlyControls( bool bReadonly )
+{
+ map< FrameControlType, SwFrameControlPtrMap >::iterator pIt = m_aControls.begin();
+
+ while ( pIt != m_aControls.end() )
+ {
+ SwFrameControlPtrMap::iterator aCtrlIt = pIt->second.begin();
+ while ( aCtrlIt != pIt->second.end() )
+ {
+ aCtrlIt->second->SetReadonly( bReadonly );
+ ++aCtrlIt;
+ }
+ ++pIt;
+ }
+}
+
+void SwFrameControlsManager::SetHeaderFooterControl( const SwPageFrm* pPageFrm, FrameControlType eType, Point aOffset )
+{
+ OSL_ASSERT( eType == Header || eType == Footer );
+
+ // Check if we already have the control
+ SwFrameControlPtr pControl;
+ const bool bHeader = ( eType == Header );
+
+ SwFrameControlPtrMap& rControls = m_aControls[eType];
+
+ SwFrameControlPtrMap::iterator lb = rControls.lower_bound(pPageFrm);
+ if (lb != rControls.end() && !(rControls.key_comp()(pPageFrm, lb->first)))
+ pControl = lb->second;
+ else
+ {
+ SwFrameControlPtr pNewControl( new SwHeaderFooterWin( m_pEditWin, pPageFrm, bHeader ) );
+ const SwViewOption* pViewOpt = m_pEditWin->GetView().GetWrtShell().GetViewOptions();
+ pNewControl->SetReadonly( pViewOpt->IsReadonly() );
+ rControls.insert(lb, make_pair(pPageFrm, pNewControl));
+ pControl.swap( pNewControl );
+ }
+
+ Rectangle aPageRect = m_pEditWin->LogicToPixel( pPageFrm->Frm().SVRect() );
+
+ SwHeaderFooterWin* pHFWin = dynamic_cast< SwHeaderFooterWin* >( pControl.get() );
+ assert(pHFWin->IsHeader() == bHeader);
+ pHFWin->SetOffset( aOffset, aPageRect.Left(), aPageRect.Right() );
+
+ if ( !pHFWin->IsVisible() )
+ pControl->ShowAll( true );
+}
+
+void SwFrameControlsManager::SetPageBreakControl( const SwPageFrm* pPageFrm )
+{
+ // Check if we already have the control
+ SwFrameControlPtr pControl;
+
+ SwFrameControlPtrMap& rControls = m_aControls[PageBreak];
+
+ SwFrameControlPtrMap::iterator lb = rControls.lower_bound(pPageFrm);
+ if (lb != rControls.end() && !(rControls.key_comp()(pPageFrm, lb->first)))
+ pControl = lb->second;
+ else
+ {
+ SwFrameControlPtr pNewControl( new SwPageBreakWin( m_pEditWin, pPageFrm ) );
+ const SwViewOption* pViewOpt = m_pEditWin->GetView().GetWrtShell().GetViewOptions();
+ pNewControl->SetReadonly( pViewOpt->IsReadonly() );
+
+ rControls.insert(lb, make_pair(pPageFrm, pNewControl));
+
+ pControl.swap( pNewControl );
+ }
+
+ SwPageBreakWin* pWin = dynamic_cast< SwPageBreakWin* >( pControl.get() );
+ pWin->UpdatePosition();
+ if ( !pWin->IsVisible() )
+ pControl->ShowAll( true );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/docvw/HeaderFooterWin.cxx b/sw/source/uibase/docvw/HeaderFooterWin.cxx
new file mode 100644
index 000000000000..b68c59a194d8
--- /dev/null
+++ b/sw/source/uibase/docvw/HeaderFooterWin.cxx
@@ -0,0 +1,520 @@
+/* -*- 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/.
+ */
+
+#include <app.hrc>
+#include <docvw.hrc>
+#include <globals.hrc>
+#include <popup.hrc>
+#include <svtools/svtools.hrc>
+
+#include <cmdid.h>
+#include <DashedLine.hxx>
+#include <docsh.hxx>
+#include <edtwin.hxx>
+#include <fmthdft.hxx>
+#include <HeaderFooterWin.hxx>
+#include <pagedesc.hxx>
+#include <pagefrm.hxx>
+#include <SwRewriter.hxx>
+#include <view.hxx>
+#include <viewopt.hxx>
+#include <wrtsh.hxx>
+
+#include <basegfx/color/bcolortools.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/range/b2drectangle.hxx>
+#include <basegfx/vector/b2dsize.hxx>
+#include <drawinglayer/attribute/fillgradientattribute.hxx>
+#include <drawinglayer/attribute/fontattribute.hxx>
+#include <drawinglayer/primitive2d/fillgradientprimitive2d.hxx>
+#include <drawinglayer/primitive2d/modifiedcolorprimitive2d.hxx>
+#include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
+#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
+#include <drawinglayer/primitive2d/textlayoutdevice.hxx>
+#include <drawinglayer/primitive2d/textprimitive2d.hxx>
+#include <editeng/boxitem.hxx>
+#include <svtools/svtresid.hxx>
+#include <svx/hdft.hxx>
+#include <drawinglayer/processor2d/processorfromoutputdevice.hxx>
+#include <vcl/decoview.hxx>
+#include <vcl/gradient.hxx>
+#include <vcl/menubtn.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/settings.hxx>
+
+#define TEXT_PADDING 5
+#define BOX_DISTANCE 10
+#define BUTTON_WIDTH 18
+
+using namespace basegfx;
+using namespace basegfx::tools;
+using namespace drawinglayer::attribute;
+
+namespace
+{
+ static basegfx::BColor lcl_GetFillColor( basegfx::BColor aLineColor )
+ {
+ basegfx::BColor aHslLine = basegfx::tools::rgb2hsl( aLineColor );
+ double nLuminance = aHslLine.getZ() * 2.5;
+ if ( nLuminance == 0 )
+ nLuminance = 0.5;
+ else if ( nLuminance >= 1.0 )
+ nLuminance = aHslLine.getZ() * 0.4;
+ aHslLine.setZ( nLuminance );
+ return basegfx::tools::hsl2rgb( aHslLine );
+ }
+
+ static basegfx::BColor lcl_GetLighterGradientColor( basegfx::BColor aDarkColor )
+ {
+ basegfx::BColor aHslDark = basegfx::tools::rgb2hsl( aDarkColor );
+ double nLuminance = aHslDark.getZ() * 255 + 20;
+ aHslDark.setZ( nLuminance / 255.0 );
+ return basegfx::tools::hsl2rgb( aHslDark );
+ }
+
+ static B2DPolygon lcl_GetPolygon( const Rectangle& rRect, bool bHeader )
+ {
+ const double nRadius = 3;
+ const double nKappa((M_SQRT2 - 1.0) * 4.0 / 3.0);
+
+ B2DPolygon aPolygon;
+ aPolygon.append( B2DPoint( rRect.Left(), rRect.Top() ) );
+
+ {
+ B2DPoint aCorner( rRect.Left(), rRect.Bottom() );
+ B2DPoint aStart( rRect.Left(), rRect.Bottom() - nRadius );
+ B2DPoint aEnd( rRect.Left() + nRadius, rRect.Bottom() );
+ aPolygon.append( aStart );
+ aPolygon.appendBezierSegment(
+ interpolate( aStart, aCorner, nKappa ),
+ interpolate( aEnd, aCorner, nKappa ),
+ aEnd );
+ }
+
+ {
+ B2DPoint aCorner( rRect.Right(), rRect.Bottom() );
+ B2DPoint aStart( rRect.Right() - nRadius, rRect.Bottom() );
+ B2DPoint aEnd( rRect.Right(), rRect.Bottom() - nRadius );
+ aPolygon.append( aStart );
+ aPolygon.appendBezierSegment(
+ interpolate( aStart, aCorner, nKappa ),
+ interpolate( aEnd, aCorner, nKappa ),
+ aEnd );
+ }
+
+ aPolygon.append( B2DPoint( rRect.Right(), rRect.Top() ) );
+
+ if ( !bHeader )
+ {
+ B2DRectangle aBRect( rRect.Left(), rRect.Top(), rRect.Right(), rRect.Bottom() );
+ B2DHomMatrix aRotation = createRotateAroundPoint(
+ aBRect.getCenterX(), aBRect.getCenterY(), M_PI );
+ aPolygon.transform( aRotation );
+ }
+
+ return aPolygon;
+ }
+}
+
+SwHeaderFooterWin::SwHeaderFooterWin( SwEditWin* pEditWin, const SwPageFrm* pPageFrm, bool bHeader ) :
+ MenuButton( pEditWin, WB_DIALOGCONTROL ),
+ SwFrameControl( pEditWin, pPageFrm ),
+ m_sLabel( ),
+ m_bIsHeader( bHeader ),
+ m_pPopupMenu( NULL ),
+ m_pLine( NULL ),
+ m_bIsAppearing( false ),
+ m_nFadeRate( 100 ),
+ m_aFadeTimer( )
+{
+ // Get the font and configure it
+ Font aFont = GetSettings().GetStyleSettings().GetToolFont();
+ SetZoomedPointFont( aFont );
+
+ // Use pixels for the rest of the drawing
+ SetMapMode( MapMode ( MAP_PIXEL ) );
+
+ // Create the line control
+ m_pLine = new SwDashedLine( GetEditWin(), &SwViewOption::GetHeaderFooterMarkColor );
+ m_pLine->SetZOrder( this, WINDOW_ZORDER_BEFOR );
+
+ // Create and set the PopupMenu
+ m_pPopupMenu = new PopupMenu( SW_RES( MN_HEADERFOOTER_BUTTON ) );
+
+ // Rewrite the menu entries' text
+ if ( m_bIsHeader )
+ {
+ m_pPopupMenu->SetItemText( FN_HEADERFOOTER_EDIT, SW_RESSTR( STR_FORMAT_HEADER ) );
+ m_pPopupMenu->SetItemText( FN_HEADERFOOTER_DELETE, SW_RESSTR( STR_DELETE_HEADER ) );
+ }
+ else
+ {
+ m_pPopupMenu->SetItemText( FN_HEADERFOOTER_EDIT, SW_RESSTR( STR_FORMAT_FOOTER ) );
+ m_pPopupMenu->SetItemText( FN_HEADERFOOTER_DELETE, SW_RESSTR( STR_DELETE_FOOTER ) );
+ }
+
+ SetPopupMenu( m_pPopupMenu );
+
+ m_aFadeTimer.SetTimeout( 50 );
+ m_aFadeTimer.SetTimeoutHdl( LINK( this, SwHeaderFooterWin, FadeHandler ) );
+}
+
+SwHeaderFooterWin::~SwHeaderFooterWin( )
+{
+ delete m_pPopupMenu;
+ delete m_pLine;
+}
+
+const SwPageFrm* SwHeaderFooterWin::GetPageFrame( )
+{
+ return static_cast< const SwPageFrm * >( GetFrame( ) );
+}
+
+void SwHeaderFooterWin::SetOffset( Point aOffset, long nXLineStart, long nXLineEnd )
+{
+ // Compute the text to show
+ m_sLabel = SW_RESSTR( STR_HEADER_TITLE );
+ if ( !m_bIsHeader )
+ m_sLabel = SW_RESSTR( STR_FOOTER_TITLE );
+ sal_Int32 nPos = m_sLabel.lastIndexOf( "%1" );
+ m_sLabel = m_sLabel.replaceAt( nPos, 2, GetPageFrame()->GetPageDesc()->GetName() );
+
+ // Compute the text size and get the box position & size from it
+ Rectangle aTextRect;
+ GetTextBoundRect( aTextRect, OUString( m_sLabel ) );
+ Rectangle aTextPxRect = LogicToPixel( aTextRect );
+ FontMetric aFontMetric = GetFontMetric( GetFont() );
+ Size aBoxSize ( aTextPxRect.GetWidth() + BUTTON_WIDTH + TEXT_PADDING * 2,
+ aFontMetric.GetLineHeight() + TEXT_PADDING * 2 );
+
+ long nYFooterOff = 0;
+ if ( !m_bIsHeader )
+ nYFooterOff = aBoxSize.Height();
+
+ Point aBoxPos( aOffset.X() - aBoxSize.Width() - BOX_DISTANCE,
+ aOffset.Y() - nYFooterOff );
+
+ if ( Application::GetSettings().GetLayoutRTL() )
+ {
+ aBoxPos.setX( aOffset.X() + BOX_DISTANCE );
+ }
+
+ // Set the position & Size of the window
+ SetPosSizePixel( aBoxPos, aBoxSize );
+
+ double nYLinePos = aBoxPos.Y();
+ if ( !m_bIsHeader )
+ nYLinePos += aBoxSize.Height();
+ Point aLinePos( nXLineStart, nYLinePos );
+ Size aLineSize( nXLineEnd - nXLineStart, 1 );
+ m_pLine->SetPosSizePixel( aLinePos, aLineSize );
+}
+
+void SwHeaderFooterWin::ShowAll( bool bShow )
+{
+ if ( !PopupMenu::IsInExecute() )
+ {
+ m_bIsAppearing = bShow;
+
+ if ( m_aFadeTimer.IsActive( ) )
+ m_aFadeTimer.Stop();
+ m_aFadeTimer.Start( );
+ }
+}
+
+bool SwHeaderFooterWin::Contains( const Point &rDocPt ) const
+{
+ Rectangle aRect( GetPosPixel(), GetSizePixel() );
+ if ( aRect.IsInside( rDocPt ) )
+ return true;
+
+ Rectangle aLineRect( m_pLine->GetPosPixel(), m_pLine->GetSizePixel() );
+ if ( aLineRect.IsInside( rDocPt ) )
+ return true;
+
+ return false;
+}
+
+void SwHeaderFooterWin::Paint( const Rectangle& )
+{
+ const Rectangle aRect( Rectangle( Point( 0, 0 ), PixelToLogic( GetSizePixel() ) ) );
+ drawinglayer::primitive2d::Primitive2DSequence aSeq( 3 );
+
+ B2DPolygon aPolygon = lcl_GetPolygon( aRect, m_bIsHeader );
+
+ // Colors
+ basegfx::BColor aLineColor = SwViewOption::GetHeaderFooterMarkColor().getBColor();
+ basegfx::BColor aFillColor = lcl_GetFillColor( aLineColor );
+ basegfx::BColor aLighterColor = lcl_GetLighterGradientColor( aFillColor );
+
+ const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
+ if ( rSettings.GetHighContrastMode() )
+ {
+ aFillColor = rSettings.GetDialogColor( ).getBColor();
+ aLineColor = rSettings.GetDialogTextColor( ).getBColor();
+
+ aSeq[0] = drawinglayer::primitive2d::Primitive2DReference( new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(
+ B2DPolyPolygon( aPolygon ), aFillColor ) );
+ }
+ else
+ {
+ B2DRectangle aGradientRect( aRect.Left(), aRect.Top(), aRect.Right(), aRect.Bottom() );
+ double nAngle = M_PI;
+ if ( m_bIsHeader )
+ nAngle = 0;
+ FillGradientAttribute aFillAttrs( GRADIENTSTYLE_LINEAR, 0.0, 0.0, 0.0, nAngle,
+ aLighterColor, aFillColor, 10 );
+ aSeq[0] = drawinglayer::primitive2d::Primitive2DReference( new drawinglayer::primitive2d::FillGradientPrimitive2D(
+ aGradientRect, aFillAttrs ) );
+ }
+
+ // Create the border lines primitive
+ aSeq[1] = drawinglayer::primitive2d::Primitive2DReference( new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(
+ aPolygon, aLineColor ) );
+
+ // Create the text primitive
+ B2DVector aFontSize;
+ FontAttribute aFontAttr = drawinglayer::primitive2d::getFontAttributeFromVclFont(
+ aFontSize, GetFont(), false, false );
+
+ FontMetric aFontMetric = GetFontMetric( GetFont() );
+ double nTextOffsetY = aFontMetric.GetAscent() + TEXT_PADDING;
+ Point aTextPos( TEXT_PADDING, nTextOffsetY );
+
+ basegfx::B2DHomMatrix aTextMatrix( createScaleTranslateB2DHomMatrix(
+ aFontSize.getX(), aFontSize.getY(),
+ double( aTextPos.X() ), double( aTextPos.Y() ) ) );
+
+ aSeq[2] = drawinglayer::primitive2d::Primitive2DReference( new drawinglayer::primitive2d::TextSimplePortionPrimitive2D(
+ aTextMatrix,
+ OUString( m_sLabel ), 0, m_sLabel.getLength(),
+ std::vector< double >( ),
+ aFontAttr,
+ com::sun::star::lang::Locale(),
+ aLineColor ) );
+
+ // Create the 'plus' or 'arrow' primitive
+ B2DRectangle aSignArea( B2DPoint( aRect.Right() - BUTTON_WIDTH, 0.0 ),
+ B2DSize( aRect.Right(), aRect.getHeight() ) );
+
+ B2DPolygon aSign;
+ if ( IsEmptyHeaderFooter( ) )
+ {
+ // Create the + polygon
+ double nLeft = aSignArea.getMinX() + TEXT_PADDING;
+ double nRight = aSignArea.getMaxX() - TEXT_PADDING;
+ double nHalfW = ( nRight - nLeft ) / 2.0;
+
+ double nTop = aSignArea.getCenterY() - nHalfW;
+ double nBottom = aSignArea.getCenterY() + nHalfW;
+
+ aSign.append( B2DPoint( nLeft, aSignArea.getCenterY() - 1.0 ) );
+ aSign.append( B2DPoint( aSignArea.getCenterX() - 1.0, aSignArea.getCenterY() - 1.0 ) );
+ aSign.append( B2DPoint( aSignArea.getCenterX() - 1.0, nTop ) );
+ aSign.append( B2DPoint( aSignArea.getCenterX() + 1.0, nTop ) );
+ aSign.append( B2DPoint( aSignArea.getCenterX() + 1.0, aSignArea.getCenterY() - 1.0 ) );
+ aSign.append( B2DPoint( nRight, aSignArea.getCenterY() - 1.0 ) );
+ aSign.append( B2DPoint( nRight, aSignArea.getCenterY() + 1.0 ) );
+ aSign.append( B2DPoint( aSignArea.getCenterX() + 1.0, aSignArea.getCenterY() + 1.0 ) );
+ aSign.append( B2DPoint( aSignArea.getCenterX() + 1.0, nBottom ) );
+ aSign.append( B2DPoint( aSignArea.getCenterX() - 1.0, nBottom ) );
+ aSign.append( B2DPoint( aSignArea.getCenterX() - 1.0, aSignArea.getCenterY() + 1.0 ) );
+ aSign.append( B2DPoint( nLeft, aSignArea.getCenterY() + 1.0 ) );
+ aSign.setClosed( true );
+ }
+ else
+ {
+ // Create the v polygon
+ B2DPoint aLeft( aSignArea.getMinX() + TEXT_PADDING, aSignArea.getCenterY() );
+ B2DPoint aRight( aSignArea.getMaxX() - TEXT_PADDING, aSignArea.getCenterY() );
+ B2DPoint aBottom( ( aLeft.getX() + aRight.getX() ) / 2.0, aLeft.getY() + 4.0 );
+ aSign.append( aLeft );
+ aSign.append( aRight );
+ aSign.append( aBottom );
+ aSign.setClosed( true );
+ }
+
+ BColor aSignColor = Color( COL_BLACK ).getBColor( );
+ if ( Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
+ aSignColor = Color( COL_WHITE ).getBColor( );
+
+ aSeq.realloc( aSeq.getLength() + 1 );
+ aSeq[ aSeq.getLength() - 1 ] = drawinglayer::primitive2d::Primitive2DReference( new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(
+ B2DPolyPolygon( aSign ), aSignColor ) );
+
+ // Create the processor and process the primitives
+ const drawinglayer::geometry::ViewInformation2D aNewViewInfos;
+ drawinglayer::processor2d::BaseProcessor2D * pProcessor =
+ drawinglayer::processor2d::createBaseProcessor2DFromOutputDevice(
+ *this, aNewViewInfos );
+
+ // TODO Ghost it all if needed
+ drawinglayer::primitive2d::Primitive2DSequence aGhostedSeq( 1 );
+ double nFadeRate = double( m_nFadeRate ) / 100.0;
+ const basegfx::BColorModifierSharedPtr aBColorModifier(
+ new basegfx::BColorModifier_interpolate(
+ Color( COL_WHITE ).getBColor(),
+ 1.0 - nFadeRate));
+ aGhostedSeq[0] = drawinglayer::primitive2d::Primitive2DReference( new drawinglayer::primitive2d::ModifiedColorPrimitive2D(
+ aSeq, aBColorModifier ) );
+
+ pProcessor->process( aGhostedSeq );
+ delete pProcessor;
+}
+
+bool SwHeaderFooterWin::IsEmptyHeaderFooter( )
+{
+ bool bResult = true;
+
+ // Actually check it
+ const SwPageDesc* pDesc = GetPageFrame()->GetPageDesc();
+
+ bool const bFirst(GetPageFrame()->OnFirstPage());
+ const SwFrmFmt *const pFmt = (GetPageFrame()->OnRightPage())
+ ? pDesc->GetRightFmt(bFirst)
+ : pDesc->GetLeftFmt(bFirst);
+
+ if ( pFmt )
+ {
+ if ( m_bIsHeader )
+ bResult = !pFmt->GetHeader().IsActive();
+ else
+ bResult = !pFmt->GetFooter().IsActive();
+ }
+
+ return bResult;
+}
+
+void SwHeaderFooterWin::ExecuteCommand( sal_uInt16 nSlot )
+{
+ SwView& rView = GetEditWin()->GetView();
+ SwWrtShell& rSh = rView.GetWrtShell();
+
+ const OUString& rStyleName = GetPageFrame()->GetPageDesc()->GetName();
+ switch ( nSlot )
+ {
+ case FN_HEADERFOOTER_EDIT:
+ {
+ OString sPageId = m_bIsHeader ? OString("header") : OString("footer");
+ rView.GetDocShell()->FormatPage(rStyleName, sPageId, rSh);
+ }
+ break;
+ case FN_HEADERFOOTER_BORDERBACK:
+ {
+ const SwPageDesc* pDesc = GetPageFrame()->GetPageDesc();
+ const SwFrmFmt& rMaster = pDesc->GetMaster();
+ SwFrmFmt* pHFFmt = const_cast< SwFrmFmt* >( rMaster.GetFooter().GetFooterFmt() );
+ if ( m_bIsHeader )
+ pHFFmt = const_cast< SwFrmFmt* >( rMaster.GetHeader().GetHeaderFmt() );
+
+ SfxItemPool* pPool = pHFFmt->GetAttrSet().GetPool();
+ SfxItemSet aSet( *pPool,
+ RES_BACKGROUND, RES_BACKGROUND,
+ RES_BOX, RES_BOX,
+ SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER,
+ RES_SHADOW, RES_SHADOW, 0 );
+
+ aSet.Put( pHFFmt->GetAttrSet() );
+
+ // Create a box info item... needed by the dialog
+ SvxBoxInfoItem aBoxInfo( SID_ATTR_BORDER_INNER );
+ const SfxPoolItem *pBoxInfo;
+ if ( SFX_ITEM_SET == pHFFmt->GetAttrSet().GetItemState( SID_ATTR_BORDER_INNER,
+ true, &pBoxInfo) )
+ aBoxInfo = *(SvxBoxInfoItem*)pBoxInfo;
+
+ aBoxInfo.SetTable( false );
+ aBoxInfo.SetDist( true);
+ aBoxInfo.SetMinDist( false );
+ aBoxInfo.SetDefDist( MIN_BORDER_DIST );
+ aBoxInfo.SetValid( VALID_DISABLE );
+ aSet.Put( aBoxInfo );
+
+ if ( svx::ShowBorderBackgroundDlg( this, &aSet, true ) )
+ {
+ const SfxPoolItem* pItem;
+ if ( SFX_ITEM_SET == aSet.GetItemState( RES_BACKGROUND, false, &pItem ) ) {
+ pHFFmt->SetFmtAttr( *pItem );
+ rView.GetDocShell()->SetModified(true);
+ }
+
+ if ( SFX_ITEM_SET == aSet.GetItemState( RES_BOX, false, &pItem ) ) {
+ pHFFmt->SetFmtAttr( *pItem );
+ rView.GetDocShell()->SetModified(true);
+ }
+
+ if ( SFX_ITEM_SET == aSet.GetItemState( RES_SHADOW, false, &pItem ) ) {
+ pHFFmt->SetFmtAttr( *pItem );
+ rView.GetDocShell()->SetModified(true);
+ }
+ }
+ }
+ break;
+ case FN_HEADERFOOTER_DELETE:
+ {
+ rSh.ChangeHeaderOrFooter( rStyleName, m_bIsHeader, false, true );
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void SwHeaderFooterWin::SetReadonly( bool bReadonly )
+{
+ ShowAll( !bReadonly );
+}
+
+void SwHeaderFooterWin::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if ( IsEmptyHeaderFooter( ) )
+ {
+ SwView& rView = GetEditWin()->GetView();
+ SwWrtShell& rSh = rView.GetWrtShell();
+
+ const OUString& rStyleName = GetPageFrame()->GetPageDesc()->GetName();
+ rSh.ChangeHeaderOrFooter( rStyleName, m_bIsHeader, true, false );
+ }
+ else
+ MenuButton::MouseButtonDown( rMEvt );
+}
+
+void SwHeaderFooterWin::Select( )
+{
+ ExecuteCommand( GetCurItemId() );
+}
+
+IMPL_LINK_NOARG(SwHeaderFooterWin, FadeHandler)
+{
+ if ( m_bIsAppearing && m_nFadeRate > 0 )
+ m_nFadeRate -= 25;
+ else if ( !m_bIsAppearing && m_nFadeRate < 100 )
+ m_nFadeRate += 25;
+
+ if ( m_nFadeRate != 100 && !IsVisible() )
+ {
+ Show( true );
+ m_pLine->Show( true );
+ }
+ else if ( m_nFadeRate == 100 && IsVisible( ) )
+ {
+ Show( false );
+ m_pLine->Show( false );
+ }
+ else
+ Invalidate();
+
+ if ( IsVisible( ) && m_nFadeRate > 0 && m_nFadeRate < 100 )
+ m_aFadeTimer.Start();
+
+ return 0;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/docvw/OverlayRanges.cxx b/sw/source/uibase/docvw/OverlayRanges.cxx
new file mode 100644
index 000000000000..7b44a9b3bdb9
--- /dev/null
+++ b/sw/source/uibase/docvw/OverlayRanges.cxx
@@ -0,0 +1,180 @@
+/* -*- 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 <OverlayRanges.hxx>
+#include <view.hxx>
+#include <svx/sdrpaintwindow.hxx>
+#include <svx/svdview.hxx>
+#include <svx/sdr/overlay/overlaymanager.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolypolygon.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <basegfx/polygon/b2dpolypolygoncutter.hxx>
+#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
+#include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx>
+
+namespace
+{
+ // combine ranges geometrically to a single, ORed polygon
+ basegfx::B2DPolyPolygon impCombineRangesToPolyPolygon(const std::vector< basegfx::B2DRange >& rRanges)
+ {
+ const sal_uInt32 nCount(rRanges.size());
+ basegfx::B2DPolyPolygon aRetval;
+
+ for(sal_uInt32 a(0); a < nCount; a++)
+ {
+ const basegfx::B2DPolygon aDiscretePolygon(basegfx::tools::createPolygonFromRect(rRanges[a]));
+
+ if(0 == a)
+ {
+ aRetval.append(aDiscretePolygon);
+ }
+ else
+ {
+ aRetval = basegfx::tools::solvePolygonOperationOr(aRetval, basegfx::B2DPolyPolygon(aDiscretePolygon));
+ }
+ }
+
+ return aRetval;
+ }
+}
+
+namespace sw
+{
+ namespace overlay
+ {
+ drawinglayer::primitive2d::Primitive2DSequence OverlayRanges::createOverlayObjectPrimitive2DSequence()
+ {
+ const sal_uInt32 nCount(getRanges().size());
+ drawinglayer::primitive2d::Primitive2DSequence aRetval;
+ aRetval.realloc(nCount);
+ for ( sal_uInt32 a = 0; a < nCount; ++a )
+ {
+ const basegfx::BColor aRGBColor(getBaseColor().getBColor());
+ const basegfx::B2DPolygon aPolygon(basegfx::tools::createPolygonFromRect(maRanges[a]));
+ aRetval[a] = drawinglayer::primitive2d::Primitive2DReference(
+ new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(
+ basegfx::B2DPolyPolygon(aPolygon),
+ aRGBColor));
+ }
+ // embed all rectangles in transparent paint
+ const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer;
+ const sal_uInt16 nTransparence( aSvtOptionsDrawinglayer.GetTransparentSelectionPercent() );
+ const double fTransparence( nTransparence / 100.0 );
+ const drawinglayer::primitive2d::Primitive2DReference aUnifiedTransparence(
+ new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D(
+ aRetval,
+ fTransparence));
+
+ if ( mbShowSolidBorder )
+ {
+ const basegfx::BColor aRGBColor(getBaseColor().getBColor());
+ const basegfx::B2DPolyPolygon aPolyPolygon(impCombineRangesToPolyPolygon(getRanges()));
+ const drawinglayer::primitive2d::Primitive2DReference aOutline(
+ new drawinglayer::primitive2d::PolyPolygonHairlinePrimitive2D(
+ aPolyPolygon,
+ aRGBColor));
+
+ aRetval.realloc(2);
+ aRetval[0] = aUnifiedTransparence;
+ aRetval[1] = aOutline;
+ }
+ else
+ {
+ aRetval = drawinglayer::primitive2d::Primitive2DSequence(&aUnifiedTransparence, 1);
+ }
+
+ return aRetval;
+ }
+
+ /*static*/ OverlayRanges* OverlayRanges::CreateOverlayRange(
+ SwView& rDocView,
+ const Color& rColor,
+ const std::vector< basegfx::B2DRange >& rRanges,
+ const bool bShowSolidBorder )
+ {
+ OverlayRanges* pOverlayRanges = NULL;
+
+ SdrView* pView = rDocView.GetDrawView();
+ if ( pView != NULL )
+ {
+ SdrPaintWindow* pCandidate = pView->GetPaintWindow(0);
+ rtl::Reference<sdr::overlay::OverlayManager> xTargetOverlay = pCandidate->GetOverlayManager();
+
+ if ( xTargetOverlay.is() )
+ {
+ pOverlayRanges = new sw::overlay::OverlayRanges( rColor, rRanges, bShowSolidBorder );
+ xTargetOverlay->add( *pOverlayRanges );
+ }
+ }
+
+ return pOverlayRanges;
+ }
+
+ OverlayRanges::OverlayRanges(
+ const Color& rColor,
+ const std::vector< basegfx::B2DRange >& rRanges,
+ const bool bShowSolidBorder )
+ : sdr::overlay::OverlayObject( rColor )
+ , maRanges( rRanges )
+ , mbShowSolidBorder( bShowSolidBorder )
+ {
+ // no AA for highlight overlays
+ allowAntiAliase(false);
+ }
+
+ OverlayRanges::~OverlayRanges()
+ {
+ if( getOverlayManager() )
+ {
+ getOverlayManager()->remove(*this);
+ }
+ }
+
+ void OverlayRanges::setRanges(const std::vector< basegfx::B2DRange >& rNew)
+ {
+ if(rNew != maRanges)
+ {
+ maRanges = rNew;
+ objectChange();
+ }
+ }
+
+ void OverlayRanges::ShowSolidBorder()
+ {
+ if ( !mbShowSolidBorder )
+ {
+ mbShowSolidBorder = true;
+ objectChange();
+ }
+ }
+
+ void OverlayRanges::HideSolidBorder()
+ {
+ if ( mbShowSolidBorder )
+ {
+ mbShowSolidBorder = false;
+ objectChange();
+ }
+ }
+
+ } // end of namespace overlay
+} // end of namespace sdr
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/docvw/OverlayRanges.hxx b/sw/source/uibase/docvw/OverlayRanges.hxx
new file mode 100644
index 000000000000..4458af4587f2
--- /dev/null
+++ b/sw/source/uibase/docvw/OverlayRanges.hxx
@@ -0,0 +1,78 @@
+/* -*- 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 .
+ */
+
+#ifndef INCLUDED_SW_SOURCE_CORE_UIBASE_DOCVW_OVERLAYRANGES_HXX
+#define INCLUDED_SW_SOURCE_CORE_UIBASE_DOCVW_OVERLAYRANGES_HXX
+
+#include <svx/sdr/overlay/overlayobject.hxx>
+#include <basegfx/range/b2drange.hxx>
+
+#include <vector>
+
+class SwView;
+
+namespace sw
+{
+ namespace overlay
+ {
+ class OverlayRanges : public sdr::overlay::OverlayObject
+ {
+ protected:
+ // geometry of overlay
+ std::vector< basegfx::B2DRange > maRanges;
+
+ bool mbShowSolidBorder;
+
+ // geometry creation for OverlayObject
+ virtual drawinglayer::primitive2d::Primitive2DSequence createOverlayObjectPrimitive2DSequence() SAL_OVERRIDE;
+
+ public:
+ static OverlayRanges* CreateOverlayRange(
+ SwView& rDocView,
+ const Color& rColor,
+ const std::vector< basegfx::B2DRange >& rRanges,
+ const bool bShowSolidBorder );
+
+ virtual ~OverlayRanges();
+
+ // data read access
+ inline const std::vector< basegfx::B2DRange >& getRanges() const
+ {
+ return maRanges;
+ }
+
+ // data write access
+ void setRanges(const std::vector< basegfx::B2DRange >& rNew);
+
+ void ShowSolidBorder();
+ void HideSolidBorder();
+
+ private:
+ OverlayRanges(
+ const Color& rColor,
+ const std::vector< basegfx::B2DRange >& rRanges,
+ const bool bShowSolidBorder );
+
+ };
+ } // end of namespace overlay
+} // end of namespace sw
+
+#endif // INCLUDED_SW_SOURCE_CORE_UIBASE_DOCVW_OVERLAYRANGES_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/docvw/PageBreakWin.cxx b/sw/source/uibase/docvw/PageBreakWin.cxx
new file mode 100644
index 000000000000..876961aab601
--- /dev/null
+++ b/sw/source/uibase/docvw/PageBreakWin.cxx
@@ -0,0 +1,463 @@
+/* -*- 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/.
+ */
+
+#include <globals.hrc>
+#include <popup.hrc>
+#include <utlui.hrc>
+
+#include <cmdid.h>
+#include <cntfrm.hxx>
+#include <DashedLine.hxx>
+#include <doc.hxx>
+#include <edtwin.hxx>
+#include <fmtpdsc.hxx>
+#include <IDocumentUndoRedo.hxx>
+#include <PageBreakWin.hxx>
+#include <pagefrm.hxx>
+#include <PostItMgr.hxx>
+#include <uiitems.hxx>
+#include <view.hxx>
+#include <viewopt.hxx>
+#include <wrtsh.hxx>
+
+#include <basegfx/color/bcolortools.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <basegfx/range/b2drectangle.hxx>
+#include <drawinglayer/primitive2d/discretebitmapprimitive2d.hxx>
+#include <drawinglayer/primitive2d/modifiedcolorprimitive2d.hxx>
+#include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
+#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
+#include <drawinglayer/processor2d/processorfromoutputdevice.hxx>
+#include <editeng/formatbreakitem.hxx>
+#include <sfx2/dispatch.hxx>
+#include <svl/stritem.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/settings.hxx>
+
+#define BUTTON_WIDTH 30
+#define BUTTON_HEIGHT 19
+#define ARROW_WIDTH 9
+
+using namespace basegfx;
+using namespace basegfx::tools;
+
+namespace
+{
+ class SwBreakDashedLine : public SwDashedLine
+ {
+ private:
+ SwPageBreakWin* m_pWin;
+
+ public:
+ SwBreakDashedLine( Window* pParent, Color& ( *pColorFn )(), SwPageBreakWin* pWin ) :
+ SwDashedLine( pParent, pColorFn ),
+ m_pWin( pWin ) {};
+
+ virtual void MouseMove( const MouseEvent& rMEvt ) SAL_OVERRIDE;
+ };
+
+ void SwBreakDashedLine::MouseMove( const MouseEvent& rMEvt )
+ {
+ if ( rMEvt.IsLeaveWindow() )
+ {
+ // don't fade if we just move to the 'button'
+ Point aEventPos( GetPosPixel() + rMEvt.GetPosPixel() );
+ if ( !m_pWin->Contains( aEventPos ) || !m_pWin->IsVisible() )
+ m_pWin->Fade( false );
+ }
+ else if ( !m_pWin->IsVisible() )
+ {
+ m_pWin->Fade( true );
+ }
+
+ if ( !rMEvt.IsSynthetic() && !m_pWin->IsVisible() )
+ {
+ Point* pPtr = new Point( rMEvt.GetPosPixel() );
+ m_pWin->UpdatePosition( pPtr );
+ }
+ }
+}
+
+SwPageBreakWin::SwPageBreakWin( SwEditWin* pEditWin, const SwPageFrm* pPageFrm ) :
+ MenuButton( pEditWin, WB_DIALOGCONTROL ),
+ SwFrameControl( pEditWin, pPageFrm ),
+ m_pPopupMenu( NULL ),
+ m_pLine( NULL ),
+ m_bIsAppearing( false ),
+ m_nFadeRate( 100 ),
+ m_nDelayAppearing( 0 ),
+ m_bDestroyed( false ),
+ m_pMousePt( NULL )
+{
+ // Use pixels for the rest of the drawing
+ SetMapMode( MapMode ( MAP_PIXEL ) );
+
+ // Create the line control
+ m_pLine = new SwBreakDashedLine( GetEditWin(), &SwViewOption::GetPageBreakColor, this );
+
+ // Create the popup menu
+ m_pPopupMenu = new PopupMenu( SW_RES( MN_PAGEBREAK_BUTTON ) );
+ m_pPopupMenu->SetDeactivateHdl( LINK( this, SwPageBreakWin, HideHandler ) );
+ SetPopupMenu( m_pPopupMenu );
+
+ m_aFadeTimer.SetTimeout( 50 );
+ m_aFadeTimer.SetTimeoutHdl( LINK( this, SwPageBreakWin, FadeHandler ) );
+}
+
+SwPageBreakWin::~SwPageBreakWin( )
+{
+ m_bDestroyed = true;
+ m_aFadeTimer.Stop();
+
+ delete m_pPopupMenu;
+ delete m_pLine;
+ delete m_pMousePt;
+}
+
+void SwPageBreakWin::Paint( const Rectangle& )
+{
+ const Rectangle aRect( Rectangle( Point( 0, 0 ), PixelToLogic( GetSizePixel() ) ) );
+
+ // Properly paint the control
+ BColor aColor = SwViewOption::GetPageBreakColor().getBColor();
+
+ BColor aHslLine = rgb2hsl( aColor );
+ double nLuminance = aHslLine.getZ();
+ nLuminance += ( 1.0 - nLuminance ) * 0.75;
+ if ( aHslLine.getZ() > 0.7 )
+ nLuminance = aHslLine.getZ() * 0.7;
+ aHslLine.setZ( nLuminance );
+ BColor aOtherColor = hsl2rgb( aHslLine );
+
+ const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
+ if ( rSettings.GetHighContrastMode( ) )
+ {
+ aColor = rSettings.GetDialogTextColor().getBColor();
+ aOtherColor = rSettings.GetDialogColor( ).getBColor();
+ }
+
+ bool bRtl = Application::GetSettings().GetLayoutRTL();
+
+ drawinglayer::primitive2d::Primitive2DSequence aSeq( 3 );
+ B2DRectangle aBRect( double( aRect.Left() ), double( aRect.Top( ) ),
+ double( aRect.Right() ), double( aRect.Bottom( ) ) );
+ B2DPolygon aPolygon = createPolygonFromRect( aBRect, 3.0 / BUTTON_WIDTH, 3.0 / BUTTON_HEIGHT );
+
+ // Create the polygon primitives
+ aSeq[0] = Primitive2DReference( new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(
+ B2DPolyPolygon( aPolygon ), aOtherColor ) );
+ aSeq[1] = Primitive2DReference( new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(
+ aPolygon, aColor ) );
+
+ // Create the primitive for the image
+ Image aImg( SW_RES( IMG_PAGE_BREAK ) );
+ double nImgOfstX = 3.0;
+ if ( bRtl )
+ nImgOfstX = aRect.Right() - aImg.GetSizePixel().Width() - 3.0;
+ aSeq[2] = Primitive2DReference( new drawinglayer::primitive2d::DiscreteBitmapPrimitive2D(
+ aImg.GetBitmapEx(), B2DPoint( nImgOfstX, 1.0 ) ) );
+
+ double nTop = double( aRect.getHeight() ) / 2.0;
+ double nBottom = nTop + 4.0;
+ double nLeft = aRect.getWidth( ) - ARROW_WIDTH - 6.0;
+ if ( bRtl )
+ nLeft = ARROW_WIDTH - 2.0;
+ double nRight = nLeft + 8.0;
+
+ B2DPolygon aTriangle;
+ aTriangle.append( B2DPoint( nLeft, nTop ) );
+ aTriangle.append( B2DPoint( nRight, nTop ) );
+ aTriangle.append( B2DPoint( ( nLeft + nRight ) / 2.0, nBottom ) );
+ aTriangle.setClosed( true );
+
+ BColor aTriangleColor = Color( COL_BLACK ).getBColor( );
+ if ( Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
+ aTriangleColor = Color( COL_WHITE ).getBColor( );
+
+ aSeq.realloc( aSeq.getLength() + 1 );
+ aSeq[ aSeq.getLength() - 1 ] = Primitive2DReference( new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(
+ B2DPolyPolygon( aTriangle ), aTriangleColor ) );
+
+ Primitive2DSequence aGhostedSeq( 1 );
+ double nFadeRate = double( m_nFadeRate ) / 100.0;
+ const basegfx::BColorModifierSharedPtr aBColorModifier(
+ new basegfx::BColorModifier_interpolate(
+ Color( COL_WHITE ).getBColor(),
+ 1.0 - nFadeRate));
+ aGhostedSeq[0] = Primitive2DReference( new drawinglayer::primitive2d::ModifiedColorPrimitive2D(
+ aSeq, aBColorModifier ) );
+
+ // Create the processor and process the primitives
+ const drawinglayer::geometry::ViewInformation2D aNewViewInfos;
+ drawinglayer::processor2d::BaseProcessor2D * pProcessor =
+ drawinglayer::processor2d::createBaseProcessor2DFromOutputDevice(
+ *this, aNewViewInfos );
+
+ pProcessor->process( aGhostedSeq );
+ delete pProcessor;
+}
+
+void SwPageBreakWin::Select( )
+{
+ SwFrameControlPtr pThis = GetEditWin()->GetFrameControlsManager( ).GetControl( PageBreak, GetFrame() );
+
+ switch( GetCurItemId( ) )
+ {
+ case FN_PAGEBREAK_EDIT:
+ {
+ const SwLayoutFrm* pBodyFrm = static_cast< const SwLayoutFrm* >( GetPageFrame()->Lower() );
+ while ( pBodyFrm && !pBodyFrm->IsBodyFrm() )
+ pBodyFrm = static_cast< const SwLayoutFrm* >( pBodyFrm->GetNext() );
+
+ SwEditWin* pEditWin = GetEditWin();
+
+ if ( pBodyFrm )
+ {
+ SwWrtShell& rSh = pEditWin->GetView().GetWrtShell();
+ bool bOldLock = rSh.IsViewLocked();
+ rSh.LockView( true );
+
+ if ( pBodyFrm->Lower()->IsTabFrm() )
+ {
+ rSh.Push( );
+ rSh.ClearMark();
+
+ SwCntntFrm *pCnt = const_cast< SwCntntFrm* >( pBodyFrm->ContainsCntnt() );
+ SwCntntNode* pNd = pCnt->GetNode();
+ rSh.SetSelection( *pNd );
+
+ SfxStringItem aItem(pEditWin->GetView().GetPool().GetWhich(FN_FORMAT_TABLE_DLG), "textflow");
+ pEditWin->GetView().GetViewFrame()->GetDispatcher()->Execute(
+ FN_FORMAT_TABLE_DLG, SFX_CALLMODE_SYNCHRON|SFX_CALLMODE_RECORD, &aItem, NULL );
+
+ rSh.Pop( false );
+ }
+ else
+ {
+ SwCntntFrm *pCnt = const_cast< SwCntntFrm* >( pBodyFrm->ContainsCntnt() );
+ SwCntntNode* pNd = pCnt->GetNode();
+
+ SwPaM aPaM( *pNd );
+ SwPaMItem aPaMItem( pEditWin->GetView().GetPool( ).GetWhich( FN_PARAM_PAM ), &aPaM );
+ SfxStringItem aItem( pEditWin->GetView().GetPool( ).GetWhich( SID_PARA_DLG ), "textflow" );
+ pEditWin->GetView().GetViewFrame()->GetDispatcher()->Execute(
+ SID_PARA_DLG, SFX_CALLMODE_SYNCHRON|SFX_CALLMODE_RECORD, &aItem, &aPaMItem, NULL );
+ }
+ rSh.LockView( bOldLock );
+ pEditWin->GrabFocus( );
+ }
+ }
+ break;
+ case FN_PAGEBREAK_DELETE:
+ {
+ const SwLayoutFrm* pBodyFrm = static_cast< const SwLayoutFrm* >( GetPageFrame()->Lower() );
+ while ( pBodyFrm && !pBodyFrm->IsBodyFrm() )
+ pBodyFrm = static_cast< const SwLayoutFrm* >( pBodyFrm->GetNext() );
+
+ if ( pBodyFrm )
+ {
+ SwCntntFrm *pCnt = const_cast< SwCntntFrm* >( pBodyFrm->ContainsCntnt() );
+ SwCntntNode* pNd = pCnt->GetNode();
+
+ pNd->GetDoc()->GetIDocumentUndoRedo( ).StartUndo( UNDO_UI_DELETE_PAGE_BREAK, NULL );
+
+ SfxItemSet aSet( GetEditWin()->GetView().GetWrtShell().GetAttrPool(),
+ RES_PAGEDESC, RES_PAGEDESC,
+ RES_BREAK, RES_BREAK,
+ NULL );
+ aSet.Put( SvxFmtBreakItem( SVX_BREAK_NONE, RES_BREAK ) );
+ aSet.Put( SwFmtPageDesc( NULL ) );
+
+ SwPaM aPaM( *pNd );
+ pNd->GetDoc()->InsertItemSet( aPaM, aSet, nsSetAttrMode::SETATTR_DEFAULT );
+
+ pNd->GetDoc()->GetIDocumentUndoRedo( ).EndUndo( UNDO_UI_DELETE_PAGE_BREAK, NULL );
+ }
+ }
+ break;
+ }
+
+ // Only fade if there is more than this temporary shared pointer:
+ // The main reference has been deleted due to a page break removal
+ if ( pThis.use_count() > 1 )
+ Fade( false );
+}
+
+void SwPageBreakWin::MouseMove( const MouseEvent& rMEvt )
+{
+ if ( rMEvt.IsLeaveWindow() )
+ {
+ // don't fade if we just move to the 'line', or the popup menu is open
+ Point aEventPos( rMEvt.GetPosPixel() + rMEvt.GetPosPixel() );
+ if ( !Contains( aEventPos ) && !PopupMenu::IsInExecute() )
+ Fade( false );
+ }
+ else if ( !IsVisible() )
+ Fade( true );
+}
+
+void SwPageBreakWin::Activate( )
+{
+ Fade( true );
+ MenuButton::Activate();
+}
+
+void SwPageBreakWin::UpdatePosition( const Point* pEvtPt )
+{
+ if ( pEvtPt != NULL )
+ {
+ if ( pEvtPt == m_pMousePt )
+ return;
+ delete m_pMousePt;
+ m_pMousePt = pEvtPt;
+ }
+
+ const SwPageFrm* pPageFrm = GetPageFrame();
+ const SwFrm* pPrevPage = pPageFrm;
+ do
+ {
+ pPrevPage = pPrevPage->GetPrev();
+ }
+ while ( pPrevPage && ( ( pPrevPage->Frm().Top( ) == pPageFrm->Frm().Top( ) )
+ || static_cast< const SwPageFrm* >( pPrevPage )->IsEmptyPage( ) ) );
+
+ Rectangle aBoundRect = GetEditWin()->LogicToPixel( pPageFrm->GetBoundRect().SVRect() );
+ Rectangle aFrmRect = GetEditWin()->LogicToPixel( pPageFrm->Frm().SVRect() );
+
+ long nYLineOffset = ( aBoundRect.Top() + aFrmRect.Top() ) / 2;
+ if ( pPrevPage )
+ {
+ Rectangle aPrevFrmRect = GetEditWin()->LogicToPixel( pPrevPage->Frm().SVRect() );
+ nYLineOffset = ( aPrevFrmRect.Bottom() + aFrmRect.Top() ) / 2;
+ }
+
+ // Get the page + sidebar coords
+ long nPgLeft = aFrmRect.Left();
+ long nPgRight = aFrmRect.Right();
+
+ unsigned long nSidebarWidth = 0;
+ const SwPostItMgr* pPostItMngr = GetEditWin()->GetView().GetWrtShell().GetPostItMgr();
+ if ( pPostItMngr && pPostItMngr->HasNotes() && pPostItMngr->ShowNotes() )
+ nSidebarWidth = pPostItMngr->GetSidebarBorderWidth( true ) + pPostItMngr->GetSidebarWidth( true );
+
+ if ( pPageFrm->SidebarPosition( ) == sw::sidebarwindows::SIDEBAR_LEFT )
+ nPgLeft -= nSidebarWidth;
+ else if ( pPageFrm->SidebarPosition( ) == sw::sidebarwindows::SIDEBAR_RIGHT )
+ nPgRight += nSidebarWidth;
+
+ Size aBtnSize( BUTTON_WIDTH + ARROW_WIDTH, BUTTON_HEIGHT );
+
+ // Place the button on the left or right?
+ Rectangle aVisArea = GetEditWin()->LogicToPixel( GetEditWin()->GetView().GetVisArea() );
+
+ long nLineLeft = std::max( nPgLeft, aVisArea.Left() );
+ long nLineRight = std::min( nPgRight, aVisArea.Right() );
+ long nBtnLeft = nLineLeft;
+
+ if ( m_pMousePt )
+ {
+ nBtnLeft = nLineLeft + m_pMousePt->X() - aBtnSize.getWidth() / 2;
+
+ if ( nBtnLeft < nLineLeft )
+ nBtnLeft = nLineLeft;
+ else if ( ( nBtnLeft + aBtnSize.getWidth() ) > nLineRight )
+ nBtnLeft = nLineRight - aBtnSize.getWidth();
+ }
+
+ // Set the button position
+ Point aBtnPos( nBtnLeft, nYLineOffset - BUTTON_HEIGHT / 2 );
+ SetPosSizePixel( aBtnPos, aBtnSize );
+
+ // Set the line position
+ Point aLinePos( nLineLeft, nYLineOffset - 5 );
+ Size aLineSize( nLineRight - nLineLeft, 10 );
+ m_pLine->SetPosSizePixel( aLinePos, aLineSize );
+}
+
+void SwPageBreakWin::ShowAll( bool bShow )
+{
+ m_pLine->Show( bShow );
+}
+
+bool SwPageBreakWin::Contains( const Point &rDocPt ) const
+{
+ Rectangle aRect( GetPosPixel(), GetSizePixel() );
+ if ( aRect.IsInside( rDocPt ) )
+ return true;
+
+ Rectangle aLineRect( m_pLine->GetPosPixel(), m_pLine->GetSizePixel() );
+ if ( aLineRect.IsInside( rDocPt ) )
+ return true;
+
+ return false;
+}
+
+const SwPageFrm* SwPageBreakWin::GetPageFrame( )
+{
+ return static_cast< const SwPageFrm * >( GetFrame( ) );
+}
+
+void SwPageBreakWin::SetReadonly( bool bReadonly )
+{
+ ShowAll( !bReadonly );
+}
+
+void SwPageBreakWin::Fade( bool bFadeIn )
+{
+ m_bIsAppearing = bFadeIn;
+ if ( bFadeIn )
+ m_nDelayAppearing = 0;
+
+ if ( !m_bDestroyed && m_aFadeTimer.IsActive( ) )
+ m_aFadeTimer.Stop();
+ if ( !m_bDestroyed )
+ m_aFadeTimer.Start( );
+}
+
+IMPL_LINK_NOARG(SwPageBreakWin, HideHandler)
+{
+ Fade( false );
+
+ return 0;
+}
+
+IMPL_LINK_NOARG(SwPageBreakWin, FadeHandler)
+{
+ const int TICKS_BEFORE_WE_APPEAR = 10;
+ if ( m_bIsAppearing && m_nDelayAppearing < TICKS_BEFORE_WE_APPEAR )
+ {
+ ++m_nDelayAppearing;
+ m_aFadeTimer.Start();
+ return 0;
+ }
+
+ if ( m_bIsAppearing && m_nFadeRate > 0 )
+ m_nFadeRate -= 25;
+ else if ( !m_bIsAppearing && m_nFadeRate < 100 )
+ m_nFadeRate += 25;
+
+ if ( m_nFadeRate != 100 && !IsVisible() )
+ Show();
+ else if ( m_nFadeRate == 100 && IsVisible( ) )
+ Hide();
+ else
+ {
+ UpdatePosition();
+ Invalidate();
+ }
+
+ if ( IsVisible( ) && m_nFadeRate > 0 && m_nFadeRate < 100 )
+ m_aFadeTimer.Start();
+
+ return 0;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/docvw/PostItMgr.cxx b/sw/source/uibase/docvw/PostItMgr.cxx
new file mode 100644
index 000000000000..d51ebff2b082
--- /dev/null
+++ b/sw/source/uibase/docvw/PostItMgr.cxx
@@ -0,0 +1,2029 @@
+/* -*- 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 "PostItMgr.hxx"
+#include <postithelper.hxx>
+
+#include <SidebarWin.hxx>
+#include <AnnotationWin.hxx>
+#include <frmsidebarwincontainer.hxx>
+#include <accmap.hxx>
+
+#include <SidebarWindowsConsts.hxx>
+#include <AnchorOverlayObject.hxx>
+#include <ShadowOverlayObject.hxx>
+
+#include <vcl/svapp.hxx>
+#include <vcl/scrbar.hxx>
+#include <vcl/outdev.hxx>
+#include <vcl/settings.hxx>
+
+#include <chrdlgmodes.hxx>
+#include <viewopt.hxx>
+#include <view.hxx>
+#include <docsh.hxx>
+#include <wrtsh.hxx>
+#include <doc.hxx>
+#include <fldbas.hxx>
+#include <fmtfld.hxx>
+#include <docufld.hxx>
+#include <edtwin.hxx>
+#include <txtfld.hxx>
+#include <txtannotationfld.hxx>
+#include <ndtxt.hxx>
+#include <redline.hxx>
+#include <docary.hxx>
+#include <SwRewriter.hxx>
+#include <tools/color.hxx>
+
+#include <swmodule.hxx>
+#include <annotation.hrc>
+#include "cmdid.h"
+
+#include <sfx2/request.hxx>
+#include <sfx2/event.hxx>
+#include <svl/srchitem.hxx>
+
+#include <svl/languageoptions.hxx>
+#include <svtools/langtab.hxx>
+#include <svl/smplhint.hxx>
+
+#include <svx/svdview.hxx>
+#include <editeng/eeitem.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/kernitem.hxx>
+#include <editeng/outliner.hxx>
+
+#include <i18nlangtag/mslangid.hxx>
+#include <i18nlangtag/lang.h>
+
+#include "annotsh.hxx"
+#include "swabstdlg.hxx"
+#include "swevent.hxx"
+#include "switerator.hxx"
+
+// distance between Anchor Y and initial note position
+#define POSTIT_INITIAL_ANCHOR_DISTANCE 20
+//distance between two postits
+#define POSTIT_SPACE_BETWEEN 8
+#define POSTIT_MINIMUMSIZE_WITH_META 60
+#define POSTIT_SCROLL_SIDEBAR_HEIGHT 20
+
+// if we layout more often we stop, this should never happen
+#define MAX_LOOP_COUNT 50
+
+using namespace sw::sidebarwindows;
+
+bool comp_pos(const SwSidebarItem* a, const SwSidebarItem* b)
+{
+ // sort by anchor position
+ SwPosition aPosAnchorA = a->GetAnchorPosition();
+ SwPosition aPosAnchorB = b->GetAnchorPosition();
+
+ bool aAnchorAInFooter = false;
+ bool aAnchorBInFooter = false;
+
+ // is the anchor placed in Footnote or the Footer?
+ if( aPosAnchorA.nNode.GetNode().FindFootnoteStartNode() || aPosAnchorA.nNode.GetNode().FindFooterStartNode() )
+ aAnchorAInFooter = true;
+ if( aPosAnchorB.nNode.GetNode().FindFootnoteStartNode() || aPosAnchorB.nNode.GetNode().FindFooterStartNode() )
+ aAnchorBInFooter = true;
+
+ // fdo#34800
+ // if AnchorA is in footnote, and AnchorB isn't
+ // we do not want to change over the position
+ if( aAnchorAInFooter && !aAnchorBInFooter )
+ return false;
+ // if aAnchorA is not placed in a footnote, and aAnchorB is
+ // force a change over
+ else if( !aAnchorAInFooter && aAnchorBInFooter )
+ return true;
+ // If neither or both are in the footer, compare the positions.
+ // Since footnotes are in Inserts section of nodes array and footers
+ // in Autotext section, all footnotes precede any footers so no need
+ // to check that.
+ else
+ return aPosAnchorA < aPosAnchorB;
+}
+
+SwPostItMgr::SwPostItMgr(SwView* pView)
+ : mpView(pView)
+ , mpWrtShell(mpView->GetDocShell()->GetWrtShell())
+ , mpEditWin(&mpView->GetEditWin())
+ , mnEventId(0)
+ , mbWaitingForCalcRects(false)
+ , mpActivePostIt(0)
+ , mbLayout(false)
+ , mbLayoutHeight(0)
+ , mbLayouting(false)
+ , mbReadOnly(mpView->GetDocShell()->IsReadOnly())
+ , mbDeleteNote(true)
+ , mpAnswer(0)
+ , mbIsShowAnchor( false )
+ , mpFrmSidebarWinContainer( 0 )
+{
+ if(!mpView->GetDrawView() )
+ mpView->GetWrtShell().MakeDrawView();
+
+ SwNoteProps aProps;
+ mbIsShowAnchor = aProps.IsShowAnchor();
+
+ //make sure we get the colour yellow always, even if not the first one of comments or redlining
+ SW_MOD()->GetRedlineAuthor();
+
+ // collect all PostIts and redline comments that exist after loading the document
+ // don't check for existence for any of them, don't focus them
+ AddPostIts(false,false);
+ /* this code can be used once we want redline comments in the Sidebar
+ AddRedlineComments(false,false);
+ */
+ // we want to receive stuff like SFX_HINT_DOCCHANGED
+ StartListening(*mpView->GetDocShell());
+ if (!mvPostItFlds.empty())
+ {
+ mbWaitingForCalcRects = true;
+ mnEventId = Application::PostUserEvent( LINK( this, SwPostItMgr, CalcHdl), 0 );
+ }
+}
+
+SwPostItMgr::~SwPostItMgr()
+{
+ if ( mnEventId )
+ Application::RemoveUserEvent( mnEventId );
+ // forget about all our Sidebar windows
+ RemoveSidebarWin();
+ EndListening( *mpView->GetDocShell() );
+
+ for(std::vector<SwPostItPageItem*>::iterator i = mPages.begin(); i != mPages.end() ; ++i)
+ delete (*i);
+ mPages.clear();
+
+ delete mpFrmSidebarWinContainer;
+ mpFrmSidebarWinContainer = 0;
+}
+
+void SwPostItMgr::CheckForRemovedPostIts()
+{
+ bool bRemoved = false;
+ for(std::list<SwSidebarItem*>::iterator i = mvPostItFlds.begin(); i != mvPostItFlds.end(); )
+ {
+ std::list<SwSidebarItem*>::iterator it = i++;
+ if ( !(*it)->UseElement() )
+ {
+ SwSidebarItem* p = (*it);
+ mvPostItFlds.remove(*it);
+ if (GetActiveSidebarWin() == p->pPostIt)
+ SetActiveSidebarWin(0);
+ if (p->pPostIt)
+ delete p->pPostIt;
+ delete p;
+ bRemoved = true;
+ }
+ }
+
+ if ( bRemoved )
+ {
+ // make sure that no deleted items remain in page lists
+ // todo: only remove deleted ones?!
+ if ( mvPostItFlds.empty() )
+ {
+ PreparePageContainer();
+ PrepareView();
+ }
+ else
+ // if postits are their make sure that page lists are not empty
+ // otherwise sudden paints can cause pain (in BorderOverPageBorder)
+ CalcRects();
+ }
+}
+
+void SwPostItMgr::InsertItem(SfxBroadcaster* pItem, bool bCheckExistance, bool bFocus)
+{
+ if (bCheckExistance)
+ {
+ for(std::list<SwSidebarItem*>::iterator i = mvPostItFlds.begin(); i != mvPostItFlds.end() ; ++i)
+ {
+ if ( (*i)->GetBroadCaster() == pItem )
+ return;
+ }
+ }
+ mbLayout = bFocus;
+ if (pItem->ISA(SwFmtFld))
+ mvPostItFlds.push_back(new SwAnnotationItem(static_cast<SwFmtFld&>(*pItem), true, bFocus) );
+ OSL_ENSURE(pItem->ISA(SwFmtFld),"Mgr::InsertItem: seems like new stuff was added");
+ StartListening(*pItem);
+}
+
+void SwPostItMgr::RemoveItem( SfxBroadcaster* pBroadcast )
+{
+ EndListening(*pBroadcast);
+ for(std::list<SwSidebarItem*>::iterator i = mvPostItFlds.begin(); i != mvPostItFlds.end() ; ++i)
+ {
+ if ( (*i)->GetBroadCaster() == pBroadcast )
+ {
+ SwSidebarItem* p = (*i);
+ if (GetActiveSidebarWin() == p->pPostIt)
+ SetActiveSidebarWin(0);
+ mvPostItFlds.remove(*i);
+ delete p->pPostIt;
+ delete p;
+ break;
+ }
+ }
+ mbLayout = true;
+ PrepareView();
+}
+
+void SwPostItMgr::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
+{
+ if ( rHint.IsA(TYPE(SfxEventHint) ) )
+ {
+ sal_uInt32 nId = ((SfxEventHint&)rHint).GetEventId();
+ if ( nId == SW_EVENT_LAYOUT_FINISHED )
+ {
+ if ( !mbWaitingForCalcRects && !mvPostItFlds.empty())
+ {
+ mbWaitingForCalcRects = true;
+ mnEventId = Application::PostUserEvent( LINK( this, SwPostItMgr, CalcHdl), 0 );
+ }
+ }
+ }
+ else if ( rHint.IsA(TYPE(SfxSimpleHint) ) )
+ {
+ sal_uInt32 nId = ((SfxSimpleHint&)rHint).GetId();
+ switch ( nId )
+ {
+ case SFX_HINT_MODECHANGED:
+ {
+ if ( mbReadOnly != !!(mpView->GetDocShell()->IsReadOnly()) )
+ {
+ mbReadOnly = !mbReadOnly;
+ SetReadOnlyState();
+ mbLayout = true;
+ }
+ break;
+ }
+ case SFX_HINT_DOCCHANGED:
+ {
+ if ( mpView->GetDocShell() == &rBC )
+ {
+ if ( !mbWaitingForCalcRects && !mvPostItFlds.empty())
+ {
+ mbWaitingForCalcRects = true;
+ mnEventId = Application::PostUserEvent( LINK( this, SwPostItMgr, CalcHdl), 0 );
+ }
+ }
+ break;
+ }
+ case SFX_HINT_USER04:
+ {
+ // if we are in a SplitNode/Cut operation, do not delete note and then add again, as this will flicker
+ mbDeleteNote = !mbDeleteNote;
+ break;
+ }
+ case SFX_HINT_DYING:
+ {
+ if ( mpView->GetDocShell() != &rBC )
+ {
+ // field to be removed is the broadcaster
+ OSL_FAIL("Notification for removed SwFmtFld was not sent!");
+ RemoveItem(&rBC);
+ }
+ break;
+ }
+ }
+ }
+ else if ( rHint.IsA(TYPE(SwFmtFldHint) ) )
+ {
+ const SwFmtFldHint& rFmtHint = static_cast<const SwFmtFldHint&>(rHint);
+ SwFmtFld* pFld = const_cast <SwFmtFld*>( rFmtHint.GetField() );
+ switch ( rFmtHint.Which() )
+ {
+ case SWFMTFLD_INSERTED :
+ {
+ if (!pFld)
+ {
+ AddPostIts(true);
+ break;
+ }
+ // get field to be inserted from hint
+ if ( pFld->IsFldInDoc() )
+ {
+ bool bEmpty = !HasNotes();
+ InsertItem( pFld, true, false );
+ if (bEmpty && !mvPostItFlds.empty())
+ PrepareView(true);
+ }
+ else
+ {
+ OSL_FAIL("Inserted field not in document!" );
+ }
+ break;
+ }
+ case SWFMTFLD_REMOVED:
+ {
+ if (mbDeleteNote)
+ {
+ if (!pFld)
+ {
+ CheckForRemovedPostIts();
+ break;
+ }
+ RemoveItem(pFld);
+ }
+ break;
+ }
+ case SWFMTFLD_FOCUS:
+ {
+ if (rFmtHint.GetView()== mpView)
+ Focus(rBC);
+ break;
+ }
+ case SWFMTFLD_CHANGED:
+ {
+ SwFmtFld* pFmtFld = dynamic_cast<SwFmtFld*>(&rBC);
+ for(std::list<SwSidebarItem*>::iterator i = mvPostItFlds.begin(); i != mvPostItFlds.end() ; ++i)
+ {
+ if ( pFmtFld == (*i)->GetBroadCaster() )
+ {
+ if ((*i)->pPostIt)
+ {
+ (*i)->pPostIt->SetPostItText();
+ mbLayout = true;
+ }
+ break;
+ }
+ }
+ break;
+ }
+
+ case SWFMTFLD_LANGUAGE:
+ {
+ SwFmtFld* pFmtFld = dynamic_cast<SwFmtFld*>(&rBC);
+ for(std::list<SwSidebarItem*>::iterator i = mvPostItFlds.begin(); i != mvPostItFlds.end() ; ++i)
+ {
+ if ( pFmtFld == (*i)->GetBroadCaster() )
+ {
+ if ((*i)->pPostIt)
+ {
+ const sal_uInt16 nScriptType = SvtLanguageOptions::GetScriptTypeOfLanguage( (*i)->GetFmtFld().GetField()->GetLanguage() );
+ sal_uInt16 nLangWhichId = 0;
+ switch (nScriptType)
+ {
+ case SCRIPTTYPE_LATIN : nLangWhichId = EE_CHAR_LANGUAGE ; break;
+ case SCRIPTTYPE_ASIAN : nLangWhichId = EE_CHAR_LANGUAGE_CJK; break;
+ case SCRIPTTYPE_COMPLEX : nLangWhichId = EE_CHAR_LANGUAGE_CTL; break;
+ }
+ (*i)->pPostIt->SetLanguage(
+ SvxLanguageItem(
+ (*i)->GetFmtFld().GetField()->GetLanguage(),
+ nLangWhichId) );
+ }
+ break;
+ }
+ }
+ break;
+ }
+ }
+ }
+}
+
+void SwPostItMgr::Focus(SfxBroadcaster& rBC)
+{
+ if (!mpWrtShell->GetViewOptions()->IsPostIts())
+ {
+ SfxRequest aRequest(mpView->GetViewFrame(),FN_VIEW_NOTES);
+ mpView->ExecViewOptions(aRequest);
+ }
+
+ for(std::list<SwSidebarItem*>::iterator i = mvPostItFlds.begin(); i != mvPostItFlds.end() ; ++i)
+ {
+ // field to get the focus is the broadcaster
+ if ( &rBC == (*i)->GetBroadCaster() )
+ {
+ if ((*i)->pPostIt)
+ {
+ (*i)->pPostIt->GrabFocus();
+ MakeVisible((*i)->pPostIt);
+ }
+ else
+ {
+ // when the layout algorithm starts, this postit is created and receives focus
+ (*i)->bFocus = true;
+ }
+ }
+ }
+}
+
+bool SwPostItMgr::CalcRects()
+{
+ if ( mnEventId )
+ {
+ // if CalcRects() was forced and an event is still pending: remove it
+ // it is superfluous and also may cause reentrance problems if triggered while layouting
+ Application::RemoveUserEvent( mnEventId );
+ mnEventId = 0;
+ }
+
+ bool bChange = false;
+ bool bRepair = false;
+ PreparePageContainer();
+ if ( !mvPostItFlds.empty() )
+ {
+ for(std::list<SwSidebarItem*>::iterator i = mvPostItFlds.begin(); i != mvPostItFlds.end() ; ++i)
+ {
+ SwSidebarItem* pItem = (*i);
+ if ( !pItem->UseElement() )
+ {
+ OSL_FAIL("PostIt is not in doc or other wrong use");
+ bRepair = true;
+ continue;
+ }
+
+ const SwRect aOldAnchorRect( pItem->maLayoutInfo.mPosition );
+ const SwPostItHelper::SwLayoutStatus eOldLayoutStatus = pItem->mLayoutStatus;
+ const sal_uLong nOldStartNodeIdx( pItem->maLayoutInfo.mnStartNodeIdx );
+ const sal_Int32 nOldStartContent( pItem->maLayoutInfo.mnStartContent );
+ {
+ // update layout information
+ const SwTxtAnnotationFld* pTxtAnnotationFld =
+ dynamic_cast< const SwTxtAnnotationFld* >( pItem->GetFmtFld().GetTxtFld() );
+ const ::sw::mark::IMark* pAnnotationMark =
+ pTxtAnnotationFld != NULL ? pTxtAnnotationFld->GetAnnotationMark() : NULL;
+ if ( pAnnotationMark != NULL )
+ {
+ pItem->mLayoutStatus =
+ SwPostItHelper::getLayoutInfos(
+ pItem->maLayoutInfo,
+ pItem->GetAnchorPosition(),
+ &pAnnotationMark->GetMarkStart() );
+ }
+ else
+ {
+ pItem->mLayoutStatus =
+ SwPostItHelper::getLayoutInfos( pItem->maLayoutInfo, pItem->GetAnchorPosition() );
+ }
+ }
+ bChange = bChange
+ || pItem->maLayoutInfo.mPosition != aOldAnchorRect
+ || pItem->mLayoutStatus != eOldLayoutStatus
+ || pItem->maLayoutInfo.mnStartNodeIdx != nOldStartNodeIdx
+ || pItem->maLayoutInfo.mnStartContent != nOldStartContent;
+ }
+
+ // show notes in right order in navigator
+ //prevent Anchors during layout to overlap, e.g. when moving a frame
+ Sort(SORT_POS);
+
+ // sort the items into the right page vector, so layout can be done by page
+ for(std::list<SwSidebarItem*>::iterator i = mvPostItFlds.begin(); i != mvPostItFlds.end() ; ++i)
+ {
+ SwSidebarItem* pItem = (*i);
+ if( SwPostItHelper::INVISIBLE == pItem->mLayoutStatus )
+ {
+ if (pItem->pPostIt)
+ pItem->pPostIt->HideNote();
+ continue;
+ }
+
+ if( SwPostItHelper::HIDDEN == pItem->mLayoutStatus )
+ {
+ if (!mpWrtShell->GetViewOptions()->IsShowHiddenChar())
+ {
+ if (pItem->pPostIt)
+ pItem->pPostIt->HideNote();
+ continue;
+ }
+ }
+
+ const unsigned long aPageNum = pItem->maLayoutInfo.mnPageNumber;
+ if (aPageNum > mPages.size())
+ {
+ const unsigned long nNumberOfPages = mPages.size();
+ for (unsigned int j=0; j<aPageNum - nNumberOfPages; ++j)
+ mPages.push_back( new SwPostItPageItem());
+ }
+ mPages[aPageNum-1]->mList->push_back(pItem);
+ mPages[aPageNum-1]->mPageRect = pItem->maLayoutInfo.mPageFrame;
+ mPages[aPageNum-1]->eSidebarPosition = pItem->maLayoutInfo.meSidebarPosition;
+ }
+
+ if (!bChange && mpWrtShell->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE))
+ {
+ long nLayoutHeight = SwPostItHelper::getLayoutHeight( mpWrtShell->GetLayout() );
+ if( nLayoutHeight > mbLayoutHeight )
+ {
+ if (mPages[0]->bScrollbar || HasScrollbars())
+ bChange = true;
+ }
+ else if( nLayoutHeight < mbLayoutHeight )
+ {
+ if (mPages[0]->bScrollbar || !BorderOverPageBorder(1))
+ bChange = true;
+ }
+ }
+ }
+
+ if ( bRepair )
+ CheckForRemovedPostIts();
+
+ mbLayoutHeight = SwPostItHelper::getLayoutHeight( mpWrtShell->GetLayout() );
+ mbWaitingForCalcRects = false;
+ return bChange;
+}
+
+bool SwPostItMgr::HasScrollbars() const
+{
+ for(std::list<SwSidebarItem*>::const_iterator i = mvPostItFlds.begin(); i != mvPostItFlds.end() ; ++i)
+ {
+ if ((*i)->bShow && (*i)->pPostIt && (*i)->pPostIt->HasScrollbar())
+ return true;
+ }
+ return false;
+}
+
+void SwPostItMgr::PreparePageContainer()
+{
+ // we do not just delete the SwPostItPageItem, so offset/scrollbar is not lost
+ long lPageSize = mpWrtShell->GetNumPages();
+ long lContainerSize = mPages.size();
+
+ if (lContainerSize < lPageSize)
+ {
+ for (int i=0; i<lPageSize - lContainerSize;i++)
+ mPages.push_back( new SwPostItPageItem());
+ }
+ else if (lContainerSize > lPageSize)
+ {
+ for (int i=mPages.size()-1; i >= lPageSize;--i)
+ {
+ delete mPages[i];
+ mPages.pop_back();
+ }
+ }
+ // only clear the list, DO NOT delete the objects itself
+ for(std::vector<SwPostItPageItem*>::iterator i = mPages.begin(); i != mPages.end() ; ++i)
+ {
+ (*i)->mList->clear();
+ if (mvPostItFlds.empty())
+ (*i)->bScrollbar = false;
+
+ }
+}
+
+void SwPostItMgr::LayoutPostIts()
+{
+ if ( !mvPostItFlds.empty() && !mbWaitingForCalcRects )
+ {
+ mbLayouting = true;
+
+ //loop over all pages and do the layout
+ // - create SwPostIt if necessary
+ // - place SwPostIts on their initial position
+ // - calculate necessary height for all PostIts together
+ bool bUpdate = false;
+ for (unsigned long n=0;n<mPages.size();n++)
+ {
+ // only layout if there are notes on this page
+ if (mPages[n]->mList->size()>0)
+ {
+ std::list<SwSidebarWin*> aVisiblePostItList;
+ unsigned long lNeededHeight = 0;
+ long mlPageBorder = 0;
+ long mlPageEnd = 0;
+
+ for(SwSidebarItem_iterator i = mPages[n]->mList->begin(); i != mPages[n]->mList->end(); ++i)
+ {
+ SwSidebarItem* pItem = (*i);
+ SwSidebarWin* pPostIt = pItem->pPostIt;
+
+ if (mPages[n]->eSidebarPosition == sw::sidebarwindows::SIDEBAR_LEFT )
+ {
+ // x value for notes positioning
+ mlPageBorder = mpEditWin->LogicToPixel( Point( mPages[n]->mPageRect.Left(), 0)).X() - GetSidebarWidth(true);// - GetSidebarBorderWidth(true);
+ //bending point
+ mlPageEnd =
+ mpWrtShell->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE)
+ ? pItem->maLayoutInfo.mPagePrtArea.Left()
+ : mPages[n]->mPageRect.Left() + 350;
+ }
+ else if (mPages[n]->eSidebarPosition == sw::sidebarwindows::SIDEBAR_RIGHT )
+ {
+ // x value for notes positioning
+ mlPageBorder = mpEditWin->LogicToPixel( Point(mPages[n]->mPageRect.Right(), 0)).X() + GetSidebarBorderWidth(true);
+ //bending point
+ mlPageEnd =
+ mpWrtShell->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE)
+ ? pItem->maLayoutInfo.mPagePrtArea.Right() :
+ mPages[n]->mPageRect.Right() - 350;
+ }
+
+ if (pItem->bShow)
+ {
+ long Y = mpEditWin->LogicToPixel( Point(0,pItem->maLayoutInfo.mPosition.Bottom())).Y();
+ long aPostItHeight = 0;
+ if (!pPostIt)
+ {
+ pPostIt = (*i)->GetSidebarWindow( mpView->GetEditWin(),
+ WB_DIALOGCONTROL,
+ *this,
+ 0 );
+ pPostIt->InitControls();
+ pPostIt->SetReadonly(mbReadOnly);
+ pItem->pPostIt = pPostIt;
+ if (mpAnswer)
+ {
+ if (pPostIt->CalcFollow()) //do we really have another note in front of this one
+ static_cast<sw::annotation::SwAnnotationWin*>(pPostIt)->InitAnswer(mpAnswer);
+ delete mpAnswer;
+ mpAnswer = 0;
+ }
+ }
+
+ pPostIt->SetChangeTracking(
+ pItem->mLayoutStatus,
+ GetColorAnchor(pItem->maLayoutInfo.mRedlineAuthor));
+ pPostIt->SetSidebarPosition(mPages[n]->eSidebarPosition);
+ pPostIt->SetFollow(pPostIt->CalcFollow());
+ aPostItHeight = ( pPostIt->GetPostItTextHeight() < pPostIt->GetMinimumSizeWithoutMeta()
+ ? pPostIt->GetMinimumSizeWithoutMeta()
+ : pPostIt->GetPostItTextHeight() )
+ + pPostIt->GetMetaHeight();
+ pPostIt->SetPosSizePixelRect( mlPageBorder ,
+ Y - GetInitialAnchorDistance(),
+ GetNoteWidth() ,
+ aPostItHeight,
+ pItem->maLayoutInfo.mPosition,
+ mlPageEnd );
+ pPostIt->ChangeSidebarItem( *pItem );
+
+ if (pItem->bFocus)
+ {
+ mbLayout = true;
+ pPostIt->GrabFocus();
+ pItem->bFocus = false;
+ }
+ // only the visible postits are used for the final layout
+ aVisiblePostItList.push_back(pPostIt);
+ lNeededHeight += pPostIt->IsFollow() ? aPostItHeight : aPostItHeight+GetSpaceBetween();
+ }
+ else // we don't want to see it
+ {
+ if (pPostIt)
+ pPostIt->HideNote();
+ }
+ }
+
+ if ((!aVisiblePostItList.empty()) && ShowNotes())
+ {
+ bool bOldScrollbar = mPages[n]->bScrollbar;
+ if (ShowNotes())
+ mPages[n]->bScrollbar = LayoutByPage(aVisiblePostItList, mPages[n]->mPageRect.SVRect(), lNeededHeight);
+ else
+ mPages[n]->bScrollbar = false;
+ if (!mPages[n]->bScrollbar)
+ {
+ mPages[n]->lOffset = 0;
+ }
+ else
+ {
+ //when we changed our zoom level, the offset value can be to big, so lets check for the largest possible zoom value
+ long aAvailableHeight = mpEditWin->LogicToPixel(Size(0,mPages[n]->mPageRect.Height())).Height() - 2 * GetSidebarScrollerHeight();
+ long lOffset = -1 * GetScrollSize() * (aVisiblePostItList.size() - aAvailableHeight / GetScrollSize());
+ if (mPages[n]->lOffset < lOffset)
+ mPages[n]->lOffset = lOffset;
+ }
+ bUpdate = (bOldScrollbar != mPages[n]->bScrollbar) || bUpdate;
+ const long aSidebarheight = mPages[n]->bScrollbar ? mpEditWin->PixelToLogic(Size(0,GetSidebarScrollerHeight())).Height() : 0;
+ /*
+ TODO
+ - enlarge all notes till GetNextBorder(), as we resized to average value before
+ */
+ //lets hide the ones which overlap the page
+ for(SwSidebarWin_iterator i = aVisiblePostItList.begin(); i != aVisiblePostItList.end() ; ++i)
+ {
+ if (mPages[n]->lOffset != 0)
+ (*i)->TranslateTopPosition(mPages[n]->lOffset);
+
+ bool bBottom = mpEditWin->PixelToLogic(Point(0,(*i)->VirtualPos().Y()+(*i)->VirtualSize().Height())).Y() <= (mPages[n]->mPageRect.Bottom()-aSidebarheight);
+ bool bTop = mpEditWin->PixelToLogic(Point(0,(*i)->VirtualPos().Y())).Y() >= (mPages[n]->mPageRect.Top()+aSidebarheight);
+ if ( bBottom && bTop )
+ {
+ (*i)->ShowNote();
+ }
+ else
+ {
+ if (mpEditWin->PixelToLogic(Point(0,(*i)->VirtualPos().Y())).Y() < (mPages[n]->mPageRect.Top()+aSidebarheight))
+ {
+ if ( mPages[n]->eSidebarPosition == sw::sidebarwindows::SIDEBAR_LEFT )
+ (*i)->ShowAnchorOnly(Point( mPages[n]->mPageRect.Left(),
+ mPages[n]->mPageRect.Top()));
+ else if ( mPages[n]->eSidebarPosition == sw::sidebarwindows::SIDEBAR_RIGHT )
+ (*i)->ShowAnchorOnly(Point( mPages[n]->mPageRect.Right(),
+ mPages[n]->mPageRect.Top()));
+ }
+ else
+ {
+ if ( mPages[n]->eSidebarPosition == sw::sidebarwindows::SIDEBAR_LEFT )
+ (*i)->ShowAnchorOnly(Point(mPages[n]->mPageRect.Left(),
+ mPages[n]->mPageRect.Bottom()));
+ else if ( mPages[n]->eSidebarPosition == sw::sidebarwindows::SIDEBAR_RIGHT )
+ (*i)->ShowAnchorOnly(Point(mPages[n]->mPageRect.Right(),
+ mPages[n]->mPageRect.Bottom()));
+ }
+ OSL_ENSURE(mPages[n]->bScrollbar,"SwPostItMgr::LayoutByPage(): note overlaps, but bScrollbar is not true");
+ }
+ }
+ }
+ else
+ {
+ for(SwSidebarWin_iterator i = aVisiblePostItList.begin(); i != aVisiblePostItList.end() ; ++i)
+ (*i)->SetPosAndSize();
+
+ bool bOldScrollbar = mPages[n]->bScrollbar;
+ mPages[n]->bScrollbar = false;
+ bUpdate = (bOldScrollbar != mPages[n]->bScrollbar) || bUpdate;
+ }
+ aVisiblePostItList.clear();
+ }
+ else
+ {
+ bUpdate = true;
+ mPages[n]->bScrollbar = false;
+ }
+ }
+
+ if (!ShowNotes())
+ { // we do not want to see the notes anymore -> Options-Writer-View-Notes
+ bool bRepair = false;
+ for(SwSidebarItem_iterator i = mvPostItFlds.begin(); i != mvPostItFlds.end() ; ++i)
+ {
+ SwSidebarItem* pItem = (*i);
+ if ( !pItem->UseElement() )
+ {
+ OSL_FAIL("PostIt is not in doc!");
+ bRepair = true;
+ continue;
+ }
+
+ if ((*i)->pPostIt)
+ {
+ (*i)->pPostIt->HideNote();
+ if ((*i)->pPostIt->HasChildPathFocus())
+ {
+ SetActiveSidebarWin(0);
+ (*i)->pPostIt->GrabFocusToDocument();
+ }
+ }
+ }
+
+ if ( bRepair )
+ CheckForRemovedPostIts();
+ }
+
+ // notes scrollbar is otherwise not drawn correctly for some cases
+ // scrollbar area is enough
+ if (bUpdate)
+ mpEditWin->Invalidate();
+ mbLayouting = false;
+ }
+}
+
+bool SwPostItMgr::BorderOverPageBorder(unsigned long aPage) const
+{
+ if ( mPages[aPage-1]->mList->empty() )
+ {
+ OSL_FAIL("Notes SidePane painted but no rects and page lists calculated!");
+ return false;
+ }
+
+ SwSidebarItem_iterator aItem = mPages[aPage-1]->mList->end();
+ --aItem;
+ OSL_ENSURE ((*aItem)->pPostIt,"BorderOverPageBorder: NULL postIt, should never happen");
+ if ((*aItem)->pPostIt)
+ {
+ const long aSidebarheight = mPages[aPage-1]->bScrollbar ? mpEditWin->PixelToLogic(Size(0,GetSidebarScrollerHeight())).Height() : 0;
+ const long aEndValue = mpEditWin->PixelToLogic(Point(0,(*aItem)->pPostIt->GetPosPixel().Y()+(*aItem)->pPostIt->GetSizePixel().Height())).Y();
+ return aEndValue <= mPages[aPage-1]->mPageRect.Bottom()-aSidebarheight;
+ }
+ else
+ return false;
+}
+
+void SwPostItMgr::DrawNotesForPage(OutputDevice *pOutDev, sal_uInt32 nPage)
+{
+ assert(nPage < mPages.size());
+ if (nPage >= mPages.size())
+ return;
+ for(SwSidebarItem_iterator i = mPages[nPage]->mList->begin(); i != mPages[nPage]->mList->end(); ++i)
+ {
+ SwSidebarWin* pPostIt = (*i)->pPostIt;
+ if (!pPostIt)
+ continue;
+ Point aPoint(mpEditWin->PixelToLogic(pPostIt->GetPosPixel()));
+ Size aSize(pPostIt->PixelToLogic(pPostIt->GetSizePixel()));
+ pPostIt->Draw(pOutDev, aPoint, aSize, 0);
+ }
+}
+
+void SwPostItMgr::Scroll(const long lScroll,const unsigned long aPage)
+{
+ OSL_ENSURE((lScroll % GetScrollSize() )==0,"SwPostItMgr::Scroll: scrolling by wrong value");
+ // do not scroll more than necessary up or down
+ if ( ((mPages[aPage-1]->lOffset == 0) && (lScroll>0)) || ( BorderOverPageBorder(aPage) && (lScroll<0)) )
+ return;
+
+ const bool bOldUp = ArrowEnabled(KEY_PAGEUP,aPage);
+ const bool bOldDown = ArrowEnabled(KEY_PAGEDOWN,aPage);
+ const long aSidebarheight = mpEditWin->PixelToLogic(Size(0,GetSidebarScrollerHeight())).Height();
+ for(SwSidebarItem_iterator i = mPages[aPage-1]->mList->begin(); i != mPages[aPage-1]->mList->end(); ++i)
+ {
+ SwSidebarWin* pPostIt = (*i)->pPostIt;
+ // if this is an answer, we should take the normal position and not the real, slightly moved position
+ pPostIt->SetVirtualPosSize(pPostIt->GetPosPixel(),pPostIt->GetSizePixel());
+ pPostIt->TranslateTopPosition(lScroll);
+
+ if ((*i)->bShow)
+ {
+ bool bBottom = mpEditWin->PixelToLogic(Point(0,pPostIt->VirtualPos().Y()+pPostIt->VirtualSize().Height())).Y() <= (mPages[aPage-1]->mPageRect.Bottom()-aSidebarheight);
+ bool bTop = mpEditWin->PixelToLogic(Point(0,pPostIt->VirtualPos().Y())).Y() >= (mPages[aPage-1]->mPageRect.Top()+aSidebarheight);
+ if ( bBottom && bTop)
+ {
+ pPostIt->ShowNote();
+ }
+ else
+ {
+ if ( mpEditWin->PixelToLogic(Point(0,pPostIt->VirtualPos().Y())).Y() < (mPages[aPage-1]->mPageRect.Top()+aSidebarheight))
+ {
+ if (mPages[aPage-1]->eSidebarPosition == sw::sidebarwindows::SIDEBAR_LEFT)
+ pPostIt->ShowAnchorOnly(Point(mPages[aPage-1]->mPageRect.Left(),mPages[aPage-1]->mPageRect.Top()));
+ else if (mPages[aPage-1]->eSidebarPosition == sw::sidebarwindows::SIDEBAR_RIGHT)
+ pPostIt->ShowAnchorOnly(Point(mPages[aPage-1]->mPageRect.Right(),mPages[aPage-1]->mPageRect.Top()));
+ }
+ else
+ {
+ if (mPages[aPage-1]->eSidebarPosition == sw::sidebarwindows::SIDEBAR_LEFT)
+ pPostIt->ShowAnchorOnly(Point(mPages[aPage-1]->mPageRect.Left(),mPages[aPage-1]->mPageRect.Bottom()));
+ else if (mPages[aPage-1]->eSidebarPosition == sw::sidebarwindows::SIDEBAR_RIGHT)
+ pPostIt->ShowAnchorOnly(Point(mPages[aPage-1]->mPageRect.Right(),mPages[aPage-1]->mPageRect.Bottom()));
+ }
+ }
+ }
+ }
+ mPages[aPage-1]->lOffset += lScroll;
+ if ( (bOldUp != ArrowEnabled(KEY_PAGEUP,aPage)) ||(bOldDown != ArrowEnabled(KEY_PAGEDOWN,aPage)) )
+ {
+ mpEditWin->Invalidate(GetBottomScrollRect(aPage));
+ mpEditWin->Invalidate(GetTopScrollRect(aPage));
+ }
+}
+
+void SwPostItMgr::AutoScroll(const SwSidebarWin* pPostIt,const unsigned long aPage )
+{
+ // otherwise all notes are visible
+ if (mPages[aPage-1]->bScrollbar)
+ {
+ const long aSidebarheight = mpEditWin->PixelToLogic(Size(0,GetSidebarScrollerHeight())).Height();
+ const bool bBottom = mpEditWin->PixelToLogic(Point(0,pPostIt->GetPosPixel().Y()+pPostIt->GetSizePixel().Height())).Y() <= (mPages[aPage-1]->mPageRect.Bottom()-aSidebarheight);
+ const bool bTop = mpEditWin->PixelToLogic(Point(0,pPostIt->GetPosPixel().Y())).Y() >= (mPages[aPage-1]->mPageRect.Top()+aSidebarheight);
+ if ( !(bBottom && bTop))
+ {
+ const long aDiff = bBottom ? mpEditWin->LogicToPixel(Point(0,mPages[aPage-1]->mPageRect.Top() + aSidebarheight)).Y() - pPostIt->GetPosPixel().Y() :
+ mpEditWin->LogicToPixel(Point(0,mPages[aPage-1]->mPageRect.Bottom() - aSidebarheight)).Y() - (pPostIt->GetPosPixel().Y()+pPostIt->GetSizePixel().Height());
+ // this just adds the missing value to get the next a* GetScrollSize() after aDiff
+ // e.g aDiff= 61 POSTIT_SCOLL=50 --> lScroll = 100
+ const long lScroll = bBottom ? (aDiff + ( GetScrollSize() - (aDiff % GetScrollSize()))) : (aDiff - (GetScrollSize() + (aDiff % GetScrollSize())));
+ Scroll(lScroll, aPage);
+ }
+ }
+}
+
+void SwPostItMgr::MakeVisible(const SwSidebarWin* pPostIt,long aPage )
+{
+ if (aPage == -1)
+ {
+ // we dont know the page yet, lets find it ourselves
+ for (unsigned long n=0;n<mPages.size();n++)
+ {
+ if (mPages[n]->mList->size()>0)
+ {
+ for(SwSidebarItem_iterator i = mPages[n]->mList->begin(); i != mPages[n]->mList->end(); ++i)
+ {
+ if ((*i)->pPostIt==pPostIt)
+ {
+ aPage = n+1;
+ break;
+ }
+ }
+ }
+ }
+ }
+ if (aPage!=-1)
+ AutoScroll(pPostIt,aPage);
+ Rectangle aNoteRect (Point(pPostIt->GetPosPixel().X(),pPostIt->GetPosPixel().Y()-5),pPostIt->GetSizePixel());
+ if (!aNoteRect.IsEmpty())
+ mpWrtShell->MakeVisible(SwRect(mpEditWin->PixelToLogic(aNoteRect)));
+}
+
+bool SwPostItMgr::ArrowEnabled(sal_uInt16 aDirection,unsigned long aPage) const
+{
+ switch (aDirection)
+ {
+ case KEY_PAGEUP:
+ {
+ return (mPages[aPage-1]->lOffset != 0);
+ }
+ case KEY_PAGEDOWN:
+ {
+ return (!BorderOverPageBorder(aPage));
+ }
+ default: return false;
+ }
+}
+
+Color SwPostItMgr::GetArrowColor(sal_uInt16 aDirection,unsigned long aPage) const
+{
+ if (ArrowEnabled(aDirection,aPage))
+ {
+ if (Application::GetSettings().GetStyleSettings().GetHighContrastMode())
+ return Color(COL_WHITE);
+ else
+ return COL_NOTES_SIDEPANE_ARROW_ENABLED;
+ }
+ else
+ {
+ return COL_NOTES_SIDEPANE_ARROW_DISABLED;
+ }
+}
+
+bool SwPostItMgr::LayoutByPage(std::list<SwSidebarWin*> &aVisiblePostItList,const Rectangle aBorder, long lNeededHeight)
+{
+ /*** General layout idea:***/
+ // - if we have space left, we always move the current one up,
+ // otherwise the next one down
+ // - first all notes are resized
+ // - then the real layout starts
+
+ //rBorder is the page rect
+ const Rectangle rBorder = mpEditWin->LogicToPixel( aBorder);
+ long lTopBorder = rBorder.Top() + 5;
+ long lBottomBorder = rBorder.Bottom() - 5;
+ const long lVisibleHeight = lBottomBorder - lTopBorder; //rBorder.GetHeight() ;
+ long lTranslatePos = 0;
+ bool bScrollbars = false;
+
+ // do all necessary resizings
+ if (lVisibleHeight < lNeededHeight)
+ {
+ // ok, now we have to really resize and adding scrollbars
+ const long lAverageHeight = (lVisibleHeight - aVisiblePostItList.size()*GetSpaceBetween()) / aVisiblePostItList.size();
+ if (lAverageHeight<GetMinimumSizeWithMeta())
+ {
+ bScrollbars = true;
+ lTopBorder += GetSidebarScrollerHeight() + 10;
+ lBottomBorder -= (GetSidebarScrollerHeight() + 10);
+ for(SwSidebarWin_iterator i = aVisiblePostItList.begin(); i != aVisiblePostItList.end() ; ++i)
+ (*i)->SetSize(Size((*i)->VirtualSize().getWidth(),(*i)->GetMinimumSizeWithMeta()));
+ }
+ else
+ {
+ for(SwSidebarWin_iterator i = aVisiblePostItList.begin(); i != aVisiblePostItList.end() ; ++i)
+ {
+ if ( (*i)->VirtualSize().getHeight() > lAverageHeight)
+ (*i)->SetSize(Size((*i)->VirtualSize().getWidth(),lAverageHeight));
+ }
+ }
+ }
+
+ //start the real layout so nothing overlaps anymore
+ if (aVisiblePostItList.size()>1)
+ {
+ long lSpaceUsed = 0;
+ int loop = 0;
+ bool bDone = false;
+ // if no window is moved anymore we are finished
+ while (!bDone)
+ {
+ loop++;
+ bDone = true;
+ lSpaceUsed = lTopBorder + GetSpaceBetween();
+ for(SwSidebarWin_iterator i = aVisiblePostItList.begin(); i != aVisiblePostItList.end() ; ++i)
+ {
+ SwSidebarWin_iterator aNextPostIt = i;
+ ++aNextPostIt;
+
+ if (aNextPostIt != aVisiblePostItList.end())
+ {
+ lTranslatePos = ( (*i)->VirtualPos().Y() + (*i)->VirtualSize().Height()) - (*aNextPostIt)->VirtualPos().Y();
+ if (lTranslatePos > 0) // note windows overlaps the next one
+ {
+ // we are not done yet, loop at least once more
+ bDone = false;
+ // if there is space left, move the current note up
+ // it could also happen that there is no space left for the first note due to a scrollbar
+ // then we also jump into, so we move the current one up and the next one down
+ if ( (lSpaceUsed <= (*i)->VirtualPos().Y()) || (i==aVisiblePostItList.begin()))
+ {
+ // we have space left, so let's move the current one up
+ if ( ((*i)->VirtualPos().Y()- lTranslatePos - GetSpaceBetween()) > lTopBorder)
+ {
+ if ((*aNextPostIt)->IsFollow())
+ (*i)->TranslateTopPosition(-1*(lTranslatePos+ANCHORLINE_WIDTH));
+ else
+ (*i)->TranslateTopPosition(-1*(lTranslatePos+GetSpaceBetween()));
+ }
+ else
+ {
+ long lMoveUp = (*i)->VirtualPos().Y() - lTopBorder;
+ (*i)->TranslateTopPosition(-1* lMoveUp);
+ if ((*aNextPostIt)->IsFollow())
+ (*aNextPostIt)->TranslateTopPosition( (lTranslatePos+ANCHORLINE_WIDTH) - lMoveUp);
+ else
+ (*aNextPostIt)->TranslateTopPosition( (lTranslatePos+GetSpaceBetween()) - lMoveUp);
+ }
+ }
+ else
+ {
+ // no space left, left move the next one down
+ if ((*aNextPostIt)->IsFollow())
+ (*aNextPostIt)->TranslateTopPosition(lTranslatePos+ANCHORLINE_WIDTH);
+ else
+ (*aNextPostIt)->TranslateTopPosition(lTranslatePos+GetSpaceBetween());
+ }
+ }
+ else
+ {
+ // the first one could overlap the topborder instead of a second note
+ if (i==aVisiblePostItList.begin())
+ {
+ long lMoveDown = lTopBorder - (*i)->VirtualPos().Y();
+ if (lMoveDown>0)
+ {
+ bDone = false;
+ (*i)->TranslateTopPosition( lMoveDown);
+ }
+ }
+ }
+ if ( (*aNextPostIt)->IsFollow() )
+ lSpaceUsed += (*i)->VirtualSize().Height() + ANCHORLINE_WIDTH;
+ else
+ lSpaceUsed += (*i)->VirtualSize().Height() + GetSpaceBetween();
+ }
+ else
+ {
+ //(*i) is the last visible item
+ SwSidebarWin_iterator aPrevPostIt = i;
+ --aPrevPostIt;
+ lTranslatePos = ( (*aPrevPostIt)->VirtualPos().Y() + (*aPrevPostIt)->VirtualSize().Height() ) - (*i)->VirtualPos().Y();
+ if (lTranslatePos > 0)
+ {
+ bDone = false;
+ if ( ((*i)->VirtualPos().Y()+ (*i)->VirtualSize().Height()+lTranslatePos) < lBottomBorder)
+ {
+ if ( (*i)->IsFollow() )
+ (*i)->TranslateTopPosition(lTranslatePos+ANCHORLINE_WIDTH);
+ else
+ (*i)->TranslateTopPosition(lTranslatePos+GetSpaceBetween());
+ }
+ else
+ {
+ (*i)->TranslateTopPosition(lBottomBorder - ((*i)->VirtualPos().Y()+ (*i)->VirtualSize().Height()) );
+ }
+ }
+ else
+ {
+ // note does not overlap, but we might be over the lower border
+ // only do this if there are no scrollbars, otherwise notes are supposed to overlap the border
+ if (!bScrollbars && ((*i)->VirtualPos().Y()+ (*i)->VirtualSize().Height() > lBottomBorder) )
+ {
+ bDone = false;
+ (*i)->TranslateTopPosition(lBottomBorder - ((*i)->VirtualPos().Y()+ (*i)->VirtualSize().Height()));
+ }
+ }
+ }
+ }
+ // security check so we don't loop forever
+ if (loop>MAX_LOOP_COUNT)
+ {
+ OSL_FAIL("PostItMgr::Layout(): We are looping forever");
+ break;
+ }
+ }
+ }
+ else
+ {
+ // only one left, make sure it is not hidden at the top or bottom
+ SwSidebarWin_iterator i = aVisiblePostItList.begin();
+ lTranslatePos = lTopBorder - (*i)->VirtualPos().Y();
+ if (lTranslatePos>0)
+ {
+ (*i)->TranslateTopPosition(lTranslatePos+GetSpaceBetween());
+ }
+ lTranslatePos = lBottomBorder - ((*i)->VirtualPos().Y()+ (*i)->VirtualSize().Height());
+ if (lTranslatePos<0)
+ {
+ (*i)->TranslateTopPosition(lTranslatePos);
+ }
+ }
+ return bScrollbars;
+ }
+
+void SwPostItMgr::AddPostIts(bool bCheckExistance, bool bFocus)
+{
+ bool bEmpty = mvPostItFlds.empty();
+ SwFieldType* pType = mpView->GetDocShell()->GetDoc()->GetFldType(RES_POSTITFLD, OUString(),false);
+ SwIterator<SwFmtFld,SwFieldType> aIter( *pType );
+ SwFmtFld* pSwFmtFld = aIter.First();
+ while(pSwFmtFld)
+ {
+ if ( pSwFmtFld->GetTxtFld())
+ {
+ if ( pSwFmtFld->IsFldInDoc() )
+ InsertItem(pSwFmtFld,bCheckExistance,bFocus);
+ }
+ pSwFmtFld = aIter.Next();
+ }
+
+ // if we just added the first one we have to update the view for centering
+ if (bEmpty && !mvPostItFlds.empty())
+ PrepareView(true);
+}
+
+void SwPostItMgr::RemoveSidebarWin()
+{
+ if (!mvPostItFlds.empty())
+ {
+ for(std::list<SwSidebarItem*>::iterator i = mvPostItFlds.begin(); i != mvPostItFlds.end() ; ++i)
+ {
+ EndListening( *(const_cast<SfxBroadcaster*>((*i)->GetBroadCaster())) );
+ if ((*i)->pPostIt)
+ delete (*i)->pPostIt;
+ delete (*i);
+ }
+ mvPostItFlds.clear();
+ }
+
+ // all postits removed, no items should be left in pages
+ PreparePageContainer();
+}
+
+// copy to new vector, otherwise RemoveItem would operate and delete stuff on mvPostItFlds as well
+// RemoveItem will clean up the core field and visible postit if necessary
+// we cannot just delete everything as before, as postits could move into change tracking
+void SwPostItMgr::Delete(const OUString& aAuthor)
+{
+ mpWrtShell->StartAllAction();
+ if ( HasActiveSidebarWin() && (GetActiveSidebarWin()->GetAuthor()==aAuthor) )
+ {
+ SetActiveSidebarWin(0);
+ }
+ SwRewriter aRewriter;
+ aRewriter.AddRule(UndoArg1, SW_RESSTR(STR_DELETE_AUTHOR_NOTES) + aAuthor);
+ mpWrtShell->StartUndo( UNDO_DELETE, &aRewriter );
+
+ std::vector<const SwFmtFld*> aTmp;
+ aTmp.reserve( mvPostItFlds.size() );
+ for(std::list<SwSidebarItem*>::iterator pPostIt = mvPostItFlds.begin(); pPostIt!= mvPostItFlds.end() ; ++pPostIt)
+ {
+ if (((*pPostIt)->pPostIt->GetAuthor() == aAuthor) )
+ aTmp.push_back( &(*pPostIt)->GetFmtFld() );
+ }
+ for(std::vector<const SwFmtFld*>::iterator i = aTmp.begin(); i != aTmp.end() ; ++i)
+ {
+ mpWrtShell->GotoField( *(*i) );
+ mpWrtShell->DelRight();
+ }
+ mpWrtShell->EndUndo();
+ PrepareView();
+ mpWrtShell->EndAllAction();
+ mbLayout = true;
+ CalcRects();
+ LayoutPostIts();
+}
+
+void SwPostItMgr::Delete()
+{
+ mpWrtShell->StartAllAction();
+ SetActiveSidebarWin(0);
+ SwRewriter aRewriter;
+ aRewriter.AddRule(UndoArg1, SW_RES(STR_DELETE_ALL_NOTES) );
+ mpWrtShell->StartUndo( UNDO_DELETE, &aRewriter );
+
+ std::vector<const SwFmtFld*> aTmp;
+ aTmp.reserve( mvPostItFlds.size() );
+ for(std::list<SwSidebarItem*>::iterator pPostIt = mvPostItFlds.begin(); pPostIt!= mvPostItFlds.end() ; ++pPostIt)
+ {
+ aTmp.push_back( &(*pPostIt)->GetFmtFld() );
+ }
+ for(std::vector<const SwFmtFld*>::iterator i = aTmp.begin(); i != aTmp.end() ; ++i)
+ {
+ mpWrtShell->GotoField( *(*i) );
+ mpWrtShell->DelRight();
+ }
+
+ mpWrtShell->EndUndo();
+ PrepareView();
+ mpWrtShell->EndAllAction();
+ mbLayout = true;
+ CalcRects();
+ LayoutPostIts();
+}
+
+void SwPostItMgr::ExecuteFormatAllDialog(SwView& rView)
+{
+ if (mvPostItFlds.empty())
+ return;
+ sw::sidebarwindows::SwSidebarWin *pOrigActiveWin = GetActiveSidebarWin();
+ sw::sidebarwindows::SwSidebarWin *pWin = pOrigActiveWin;
+ if (!pWin)
+ {
+ for (SwSidebarItem_iterator i = mvPostItFlds.begin(); i != mvPostItFlds.end(); ++i)
+ {
+ pWin = (*i)->pPostIt;
+ if (pWin)
+ break;
+ }
+ }
+ if (!pWin)
+ return;
+ SetActiveSidebarWin(pWin);
+ OutlinerView* pOLV = pWin->GetOutlinerView();
+ SfxItemSet aEditAttr(pOLV->GetAttribs());
+ SfxItemPool* pPool(SwAnnotationShell::GetAnnotationPool(rView));
+ SfxItemSet aDlgAttr(*pPool, EE_ITEMS_START, EE_ITEMS_END);
+ aDlgAttr.Put(aEditAttr);
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ SfxAbstractTabDialog* pDlg = pFact->CreateSwCharDlg(rView.GetWindow(), rView, aDlgAttr, DLG_CHAR_ANN);
+ sal_uInt16 nRet = pDlg->Execute();
+ if (RET_OK == nRet)
+ {
+ aDlgAttr.Put(*pDlg->GetOutputItemSet());
+ FormatAll(aDlgAttr);
+ }
+ delete pDlg;
+ SetActiveSidebarWin(pOrigActiveWin);
+}
+
+void SwPostItMgr::FormatAll(const SfxItemSet &rNewAttr)
+{
+ mpWrtShell->StartAllAction();
+ SwRewriter aRewriter;
+ aRewriter.AddRule(UndoArg1, SW_RES(STR_FORMAT_ALL_NOTES) );
+ mpWrtShell->StartUndo( UNDO_INSATTR, &aRewriter );
+
+ for(SwSidebarItem_iterator i = mvPostItFlds.begin(); i != mvPostItFlds.end() ; ++i)
+ {
+ if (!(*i)->pPostIt)
+ continue;
+ OutlinerView* pOLV = (*i)->pPostIt->GetOutlinerView();
+ //save old selection
+ ESelection aOrigSel(pOLV->GetSelection());
+ //select all
+ Outliner *pOutliner = pOLV->GetOutliner();
+ if (pOutliner)
+ {
+ sal_Int32 nParaCount = pOutliner->GetParagraphCount();
+ if (nParaCount > 0)
+ pOLV->SelectRange(0, nParaCount);
+ }
+ //set new char properties
+ pOLV->SetAttribs(rNewAttr);
+ //restore old selection
+ pOLV->SetSelection(aOrigSel);
+ }
+
+ mpWrtShell->EndUndo();
+ PrepareView();
+ mpWrtShell->EndAllAction();
+ mbLayout = true;
+ CalcRects();
+ LayoutPostIts();
+}
+
+void SwPostItMgr::Hide( const OUString& rAuthor )
+{
+ for(SwSidebarItem_iterator i = mvPostItFlds.begin(); i != mvPostItFlds.end() ; ++i)
+ {
+ if ( (*i)->pPostIt && ((*i)->pPostIt->GetAuthor() == rAuthor) )
+ {
+ (*i)->bShow = false;
+ (*i)->pPostIt->HideNote();
+ }
+ }
+
+ LayoutPostIts();
+}
+
+void SwPostItMgr::Hide()
+{
+ for(SwSidebarItem_iterator i = mvPostItFlds.begin(); i != mvPostItFlds.end() ; ++i)
+ {
+ (*i)->bShow = false;
+ (*i)->pPostIt->HideNote();
+ }
+}
+
+void SwPostItMgr::Show()
+{
+ for(SwSidebarItem_iterator i = mvPostItFlds.begin(); i != mvPostItFlds.end() ; ++i)
+ {
+ (*i)->bShow = true;
+ }
+ LayoutPostIts();
+}
+
+void SwPostItMgr::Sort(const short aType)
+{
+ if (mvPostItFlds.size()>1 )
+ {
+ switch (aType)
+ {
+ case SORT_POS:
+ mvPostItFlds.sort(comp_pos);
+ break;
+ }
+ }
+}
+
+SwSidebarWin* SwPostItMgr::GetSidebarWin( const SfxBroadcaster* pBroadcaster) const
+{
+ for(const_iterator i = mvPostItFlds.begin(); i != mvPostItFlds.end() ; ++i)
+ {
+ if ( (*i)->GetBroadCaster() == pBroadcaster)
+ return (*i)->pPostIt;
+ }
+ return NULL;
+}
+
+sw::annotation::SwAnnotationWin* SwPostItMgr::GetAnnotationWin(const SwPostItField* pFld) const
+{
+ for(const_iterator i = mvPostItFlds.begin(); i != mvPostItFlds.end() ; ++i)
+ {
+ if ( (*i)->GetFmtFld().GetField() == pFld )
+ return dynamic_cast<sw::annotation::SwAnnotationWin*>((*i)->pPostIt);
+ }
+ return NULL;
+}
+
+SwSidebarWin* SwPostItMgr::GetNextPostIt( sal_uInt16 aDirection,
+ SwSidebarWin* aPostIt )
+{
+ if (mvPostItFlds.size()>1)
+ {
+ for(SwSidebarItem_iterator i = mvPostItFlds.begin(); i != mvPostItFlds.end() ; ++i)
+ {
+ if ( (*i)->pPostIt == aPostIt)
+ {
+ SwSidebarItem_iterator iNextPostIt = i;
+ if (aDirection == KEY_PAGEUP)
+ {
+ if ( iNextPostIt == mvPostItFlds.begin() )
+ {
+ return NULL;
+ }
+ --iNextPostIt;
+ }
+ else
+ {
+ ++iNextPostIt;
+ if ( iNextPostIt == mvPostItFlds.end() )
+ {
+ return NULL;
+ }
+ }
+ // lets quit, we are back at the beginning
+ if ( (*iNextPostIt)->pPostIt == aPostIt)
+ return NULL;
+ return (*iNextPostIt)->pPostIt;
+ }
+ }
+ return NULL;
+ }
+ else
+ return NULL;
+}
+
+long SwPostItMgr::GetNextBorder()
+{
+ for (unsigned long n=0;n<mPages.size();n++)
+ {
+ for(SwSidebarItem_iterator b = mPages[n]->mList->begin(); b!= mPages[n]->mList->end(); ++b)
+ {
+ if ((*b)->pPostIt == mpActivePostIt)
+ {
+ SwSidebarItem_iterator aNext = b;
+ ++aNext;
+ bool bFollow = (aNext == mPages[n]->mList->end()) ? false : (*aNext)->pPostIt->IsFollow();
+ if ( mPages[n]->bScrollbar || bFollow )
+ {
+ return -1;
+ }
+ else
+ {
+ //if this is the last item, return the bottom border otherwise the next item
+ if (aNext == mPages[n]->mList->end())
+ return mpEditWin->LogicToPixel(Point(0,mPages[n]->mPageRect.Bottom())).Y() - GetSpaceBetween();
+ else
+ return (*aNext)->pPostIt->GetPosPixel().Y() - GetSpaceBetween();
+ }
+ }
+ }
+ }
+
+ OSL_FAIL("SwPostItMgr::GetNextBorder(): We have to find a next border here");
+ return -1;
+}
+
+void SwPostItMgr::SetShadowState(const SwPostItField* pFld,bool bCursor)
+{
+ if (pFld)
+ {
+ if (pFld !=mShadowState.mpShadowFld)
+ {
+ if (mShadowState.mpShadowFld)
+ {
+ // reset old one if still alive
+ // TODO: does not work properly if mouse and cursor was set
+ sw::annotation::SwAnnotationWin* pOldPostIt =
+ GetAnnotationWin(mShadowState.mpShadowFld);
+ if (pOldPostIt && pOldPostIt->Shadow() && (pOldPostIt->Shadow()->GetShadowState() != SS_EDIT))
+ pOldPostIt->SetViewState(VS_NORMAL);
+ }
+ //set new one, if it is not currently edited
+ sw::annotation::SwAnnotationWin* pNewPostIt = GetAnnotationWin(pFld);
+ if (pNewPostIt && pNewPostIt->Shadow() && (pNewPostIt->Shadow()->GetShadowState() != SS_EDIT))
+ {
+ pNewPostIt->SetViewState(VS_VIEW);
+ //remember our new field
+ mShadowState.mpShadowFld = pFld;
+ mShadowState.bCursor = false;
+ mShadowState.bMouse = false;
+ }
+ }
+ if (bCursor)
+ mShadowState.bCursor = true;
+ else
+ mShadowState.bMouse = true;
+ }
+ else
+ {
+ if (mShadowState.mpShadowFld)
+ {
+ if (bCursor)
+ mShadowState.bCursor = false;
+ else
+ mShadowState.bMouse = false;
+ if (!mShadowState.bCursor && !mShadowState.bMouse)
+ {
+ // reset old one if still alive
+ sw::annotation::SwAnnotationWin* pOldPostIt = GetAnnotationWin(mShadowState.mpShadowFld);
+ if (pOldPostIt && pOldPostIt->Shadow() && (pOldPostIt->Shadow()->GetShadowState() != SS_EDIT))
+ {
+ pOldPostIt->SetViewState(VS_NORMAL);
+ mShadowState.mpShadowFld = 0;
+ }
+ }
+ }
+ }
+}
+
+void SwPostItMgr::PrepareView(bool bIgnoreCount)
+{
+ if (!HasNotes() || bIgnoreCount)
+ {
+ mpWrtShell->StartAllAction();
+ SwRootFrm* pLayout = mpWrtShell->GetLayout();
+ if ( pLayout )
+ SwPostItHelper::setSidebarChanged( pLayout,
+ mpWrtShell->getIDocumentSettingAccess()->get( IDocumentSettingAccess::BROWSE_MODE ) );
+ mpWrtShell->EndAllAction();
+ }
+}
+
+bool SwPostItMgr::ShowScrollbar(const unsigned long aPage) const
+{
+ if (mPages.size() > aPage-1)
+ return (mPages[aPage-1]->bScrollbar && !mbWaitingForCalcRects);
+ else
+ return false;
+}
+
+bool SwPostItMgr::IsHit(const Point &aPointPixel)
+{
+ if (HasNotes() && ShowNotes())
+ {
+ const Point aPoint = mpEditWin->PixelToLogic(aPointPixel);
+ const SwRootFrm* pLayout = mpWrtShell->GetLayout();
+ SwRect aPageFrm;
+ const unsigned long nPageNum = SwPostItHelper::getPageInfo( aPageFrm, pLayout, aPoint );
+ if( nPageNum )
+ {
+ Rectangle aRect;
+ OSL_ENSURE(mPages.size()>nPageNum-1,"SwPostitMgr:: page container size wrong");
+ aRect = mPages[nPageNum-1]->eSidebarPosition == sw::sidebarwindows::SIDEBAR_LEFT
+ ? Rectangle(Point(aPageFrm.Left()-GetSidebarWidth()-GetSidebarBorderWidth(),aPageFrm.Top()),Size(GetSidebarWidth(),aPageFrm.Height()))
+ : Rectangle( Point(aPageFrm.Right()+GetSidebarBorderWidth(),aPageFrm.Top()) , Size(GetSidebarWidth(),aPageFrm.Height()));
+ if (aRect.IsInside(aPoint))
+ {
+ // we hit the note's sidebar
+ // lets now test for the arrow area
+ if (mPages[nPageNum-1]->bScrollbar)
+ return ScrollbarHit(nPageNum,aPoint);
+ else
+ return false;
+ }
+ }
+ }
+ return false;
+}
+Rectangle SwPostItMgr::GetBottomScrollRect(const unsigned long aPage) const
+{
+ SwRect aPageRect = mPages[aPage-1]->mPageRect;
+ Point aPointBottom = mPages[aPage-1]->eSidebarPosition == sw::sidebarwindows::SIDEBAR_LEFT
+ ? Point(aPageRect.Left() - GetSidebarWidth() - GetSidebarBorderWidth() + mpEditWin->PixelToLogic(Size(2,0)).Width(),aPageRect.Bottom()- mpEditWin->PixelToLogic(Size(0,2+GetSidebarScrollerHeight())).Height())
+ : Point(aPageRect.Right() + GetSidebarBorderWidth() + mpEditWin->PixelToLogic(Size(2,0)).Width(),aPageRect.Bottom()- mpEditWin->PixelToLogic(Size(0,2+GetSidebarScrollerHeight())).Height());
+ Size aSize(GetSidebarWidth() - mpEditWin->PixelToLogic(Size(4,0)).Width(), mpEditWin->PixelToLogic(Size(0,GetSidebarScrollerHeight())).Height()) ;
+ return Rectangle(aPointBottom,aSize);
+}
+
+Rectangle SwPostItMgr::GetTopScrollRect(const unsigned long aPage) const
+{
+ SwRect aPageRect = mPages[aPage-1]->mPageRect;
+ Point aPointTop = mPages[aPage-1]->eSidebarPosition == sw::sidebarwindows::SIDEBAR_LEFT
+ ? Point(aPageRect.Left() - GetSidebarWidth() -GetSidebarBorderWidth()+ mpEditWin->PixelToLogic(Size(2,0)).Width(),aPageRect.Top() + mpEditWin->PixelToLogic(Size(0,2)).Height())
+ : Point(aPageRect.Right() + GetSidebarBorderWidth() + mpEditWin->PixelToLogic(Size(2,0)).Width(),aPageRect.Top() + mpEditWin->PixelToLogic(Size(0,2)).Height());
+ Size aSize(GetSidebarWidth() - mpEditWin->PixelToLogic(Size(4,0)).Width(), mpEditWin->PixelToLogic(Size(0,GetSidebarScrollerHeight())).Height()) ;
+ return Rectangle(aPointTop,aSize);
+}
+
+//IMPORTANT: if you change the rects here, also change SwPageFrm::PaintNotesSidebar()
+bool SwPostItMgr::ScrollbarHit(const unsigned long aPage,const Point &aPoint)
+{
+ SwRect aPageRect = mPages[aPage-1]->mPageRect;
+ Point aPointBottom = mPages[aPage-1]->eSidebarPosition == sw::sidebarwindows::SIDEBAR_LEFT
+ ? Point(aPageRect.Left() - GetSidebarWidth()-GetSidebarBorderWidth() + mpEditWin->PixelToLogic(Size(2,0)).Width(),aPageRect.Bottom()- mpEditWin->PixelToLogic(Size(0,2+GetSidebarScrollerHeight())).Height())
+ : Point(aPageRect.Right() + GetSidebarBorderWidth()+ mpEditWin->PixelToLogic(Size(2,0)).Width(),aPageRect.Bottom()- mpEditWin->PixelToLogic(Size(0,2+GetSidebarScrollerHeight())).Height());
+
+ Point aPointTop = mPages[aPage-1]->eSidebarPosition == sw::sidebarwindows::SIDEBAR_LEFT
+ ? Point(aPageRect.Left() - GetSidebarWidth()-GetSidebarBorderWidth()+ mpEditWin->PixelToLogic(Size(2,0)).Width(),aPageRect.Top() + mpEditWin->PixelToLogic(Size(0,2)).Height())
+ : Point(aPageRect.Right()+GetSidebarBorderWidth()+ mpEditWin->PixelToLogic(Size(2,0)).Width(),aPageRect.Top() + mpEditWin->PixelToLogic(Size(0,2)).Height());
+
+ Rectangle aRectBottom(GetBottomScrollRect(aPage));
+ Rectangle aRectTop(GetTopScrollRect(aPage));
+
+ if (aRectBottom.IsInside(aPoint))
+ {
+ if (aPoint.X() < long((aPointBottom.X() + GetSidebarWidth()/3)))
+ Scroll( GetScrollSize(),aPage);
+ else
+ Scroll( -1*GetScrollSize(), aPage);
+ return true;
+ }
+ else if (aRectTop.IsInside(aPoint))
+ {
+ if (aPoint.X() < long((aPointTop.X() + GetSidebarWidth()/3*2)))
+ Scroll(GetScrollSize(), aPage);
+ else
+ Scroll(-1*GetScrollSize(), aPage);
+ return true;
+ }
+ return false;
+}
+
+void SwPostItMgr::CorrectPositions()
+{
+ if ( mbWaitingForCalcRects || mbLayouting || mvPostItFlds.empty() )
+ return;
+
+ // find first valid note
+ SwSidebarWin *pFirstPostIt = 0;
+ for(SwSidebarItem_iterator i = mvPostItFlds.begin(); i != mvPostItFlds.end() ; ++i)
+ {
+ pFirstPostIt = (*i)->pPostIt;
+ if (pFirstPostIt)
+ break;
+ }
+
+ //if we have not found a valid note, forget about it and leave
+ if (!pFirstPostIt)
+ return;
+
+ // yeah, I know, if this is a left page it could be wrong, but finding the page and the note is probably not even faster than just doing it
+ // check, if anchor overlay object exists.
+ const long aAnchorX = pFirstPostIt->Anchor()
+ ? mpEditWin->LogicToPixel( Point((long)(pFirstPostIt->Anchor()->GetSixthPosition().getX()),0)).X()
+ : 0;
+ const long aAnchorY = pFirstPostIt->Anchor()
+ ? mpEditWin->LogicToPixel( Point(0,(long)(pFirstPostIt->Anchor()->GetSixthPosition().getY()))).Y() + 1
+ : 0;
+ if (Point(aAnchorX,aAnchorY) != pFirstPostIt->GetPosPixel())
+ {
+ long aAnchorPosX = 0;
+ long aAnchorPosY = 0;
+ for (unsigned long n=0;n<mPages.size();n++)
+ {
+ for(SwSidebarItem_iterator i = mPages[n]->mList->begin(); i != mPages[n]->mList->end(); ++i)
+ {
+ // check, if anchor overlay object exists.
+ if ( (*i)->bShow && (*i)->pPostIt && (*i)->pPostIt->Anchor() )
+ {
+ aAnchorPosX = mPages[n]->eSidebarPosition == sw::sidebarwindows::SIDEBAR_LEFT
+ ? mpEditWin->LogicToPixel( Point((long)((*i)->pPostIt->Anchor()->GetSeventhPosition().getX()),0)).X()
+ : mpEditWin->LogicToPixel( Point((long)((*i)->pPostIt->Anchor()->GetSixthPosition().getX()),0)).X();
+ aAnchorPosY = mpEditWin->LogicToPixel( Point(0,(long)((*i)->pPostIt->Anchor()->GetSixthPosition().getY()))).Y() + 1;
+ (*i)->pPostIt->SetPosPixel(Point(aAnchorPosX,aAnchorPosY));
+ }
+ }
+ }
+ }
+}
+
+bool SwPostItMgr::ShowNotes() const
+{
+ // we only want to see notes if Options - Writer - View - Notes is ticked
+ return mpWrtShell->GetViewOptions()->IsPostIts();
+}
+
+bool SwPostItMgr::HasNotes() const
+{
+ return !mvPostItFlds.empty();
+}
+
+unsigned long SwPostItMgr::GetSidebarWidth(bool bPx) const
+{
+ unsigned long aWidth = (unsigned long)(mpWrtShell->GetViewOptions()->GetZoom() * 1.8);
+ if (bPx)
+ return aWidth;
+ else
+ return mpEditWin->PixelToLogic(Size( aWidth ,0)).Width();
+}
+
+unsigned long SwPostItMgr::GetSidebarBorderWidth(bool bPx) const
+{
+ if (bPx)
+ return 2;
+ else
+ return mpEditWin->PixelToLogic(Size(2,0)).Width();
+}
+
+unsigned long SwPostItMgr::GetNoteWidth()
+{
+ return GetSidebarWidth(true);
+}
+
+Color SwPostItMgr::GetColorDark(sal_uInt16 aAuthorIndex)
+{
+ if (!Application::GetSettings().GetStyleSettings().GetHighContrastMode())
+ {
+ static const Color aArrayNormal[] = {
+ COL_AUTHOR1_NORMAL, COL_AUTHOR2_NORMAL, COL_AUTHOR3_NORMAL,
+ COL_AUTHOR4_NORMAL, COL_AUTHOR5_NORMAL, COL_AUTHOR6_NORMAL,
+ COL_AUTHOR7_NORMAL, COL_AUTHOR8_NORMAL, COL_AUTHOR9_NORMAL };
+
+ return Color( aArrayNormal[ aAuthorIndex % (sizeof( aArrayNormal )/ sizeof( aArrayNormal[0] ))]);
+ }
+ else
+ return Color(COL_WHITE);
+}
+
+Color SwPostItMgr::GetColorLight(sal_uInt16 aAuthorIndex)
+{
+ if (!Application::GetSettings().GetStyleSettings().GetHighContrastMode())
+ {
+ static const Color aArrayLight[] = {
+ COL_AUTHOR1_LIGHT, COL_AUTHOR2_LIGHT, COL_AUTHOR3_LIGHT,
+ COL_AUTHOR4_LIGHT, COL_AUTHOR5_LIGHT, COL_AUTHOR6_LIGHT,
+ COL_AUTHOR7_LIGHT, COL_AUTHOR8_LIGHT, COL_AUTHOR9_LIGHT };
+
+ return Color( aArrayLight[ aAuthorIndex % (sizeof( aArrayLight )/ sizeof( aArrayLight[0] ))]);
+ }
+ else
+ return Color(COL_WHITE);
+}
+
+Color SwPostItMgr::GetColorAnchor(sal_uInt16 aAuthorIndex)
+{
+ if (!Application::GetSettings().GetStyleSettings().GetHighContrastMode())
+ {
+ static const Color aArrayAnchor[] = {
+ COL_AUTHOR1_DARK, COL_AUTHOR2_DARK, COL_AUTHOR3_DARK,
+ COL_AUTHOR4_DARK, COL_AUTHOR5_DARK, COL_AUTHOR6_DARK,
+ COL_AUTHOR7_DARK, COL_AUTHOR8_DARK, COL_AUTHOR9_DARK };
+
+ return Color( aArrayAnchor[ aAuthorIndex % (sizeof( aArrayAnchor ) / sizeof( aArrayAnchor[0] ))]);
+ }
+ else
+ return Color(COL_WHITE);
+}
+
+void SwPostItMgr::SetActiveSidebarWin( SwSidebarWin* p)
+{
+ if ( p != mpActivePostIt )
+ {
+ // we need the temp variable so we can set mpActivePostIt before we call DeactivatePostIt
+ // therefore we get a new layout in DOCCHANGED when switching from postit to document,
+ // otherwise, GetActivePostIt() would still hold our old postit
+ SwSidebarWin* pActive = mpActivePostIt;
+ mpActivePostIt = p;
+ if (pActive)
+ {
+ pActive->DeactivatePostIt();
+ mShadowState.mpShadowFld = 0;
+ }
+ if (mpActivePostIt)
+ {
+ mpActivePostIt->GotoPos();
+ mpView->SetAnnotationMode(true);
+ mpView->AttrChangedNotify(0);
+ mpView->SetAnnotationMode(false);
+ mpActivePostIt->ActivatePostIt();
+ }
+ }
+}
+
+IMPL_LINK( SwPostItMgr, CalcHdl, void*, /* pVoid*/ )
+{
+ mnEventId = 0;
+ if ( mbLayouting )
+ {
+ OSL_FAIL("Reentrance problem in Layout Manager!");
+ mbWaitingForCalcRects = false;
+ return 0;
+ }
+
+ // do not change order, even if it would seem so in the first place, we need the calcrects always
+ if (CalcRects() || mbLayout)
+ {
+ mbLayout = false;
+ LayoutPostIts();
+ }
+ return 0;
+}
+
+void SwPostItMgr::Rescale()
+{
+ for(std::list<SwSidebarItem*>::iterator i = mvPostItFlds.begin(); i != mvPostItFlds.end() ; ++i)
+ if ( (*i)->pPostIt )
+ (*i)->pPostIt->Rescale();
+}
+
+sal_Int32 SwPostItMgr::GetInitialAnchorDistance() const
+{
+ const Fraction& f( mpEditWin->GetMapMode().GetScaleY() );
+ return POSTIT_INITIAL_ANCHOR_DISTANCE * f.GetNumerator() / f.GetDenominator();
+}
+
+sal_Int32 SwPostItMgr::GetSpaceBetween() const
+{
+ const Fraction& f( mpEditWin->GetMapMode().GetScaleY() );
+ return ( POSTIT_SPACE_BETWEEN ) * f.GetNumerator() / f.GetDenominator();
+}
+
+sal_Int32 SwPostItMgr::GetScrollSize() const
+{
+ const Fraction& f( mpEditWin->GetMapMode().GetScaleY() );
+ return ( POSTIT_SPACE_BETWEEN + POSTIT_MINIMUMSIZE_WITH_META ) * f.GetNumerator() / f.GetDenominator();
+}
+
+sal_Int32 SwPostItMgr::GetMinimumSizeWithMeta() const
+{
+ const Fraction& f( mpEditWin->GetMapMode().GetScaleY() );
+ return POSTIT_MINIMUMSIZE_WITH_META * f.GetNumerator() / f.GetDenominator();
+}
+
+sal_Int32 SwPostItMgr::GetSidebarScrollerHeight() const
+{
+ const Fraction& f( mpEditWin->GetMapMode().GetScaleY() );
+ return POSTIT_SCROLL_SIDEBAR_HEIGHT * f.GetNumerator() / f.GetDenominator();
+}
+
+void SwPostItMgr::SetSpellChecking()
+{
+ for(std::list<SwSidebarItem*>::iterator i = mvPostItFlds.begin(); i != mvPostItFlds.end() ; ++i)
+ if ( (*i)->pPostIt )
+ (*i)->pPostIt->SetSpellChecking();
+}
+
+void SwPostItMgr::SetReadOnlyState()
+{
+ for(std::list<SwSidebarItem*>::iterator i = mvPostItFlds.begin(); i != mvPostItFlds.end() ; ++i)
+ if ( (*i)->pPostIt )
+ (*i)->pPostIt->SetReadonly( mbReadOnly );
+}
+
+void SwPostItMgr::CheckMetaText()
+{
+ for(std::list<SwSidebarItem*>::iterator i = mvPostItFlds.begin(); i != mvPostItFlds.end() ; ++i)
+ if ( (*i)->pPostIt )
+ (*i)->pPostIt->CheckMetaText();
+
+}
+
+sal_uInt16 SwPostItMgr::Replace(SvxSearchItem* pItem)
+{
+ SwSidebarWin* pWin = GetActiveSidebarWin();
+ sal_uInt16 aResult = pWin->GetOutlinerView()->StartSearchAndReplace( *pItem );
+ if (!aResult)
+ SetActiveSidebarWin(0);
+ return aResult;
+}
+
+sal_uInt16 SwPostItMgr::FinishSearchReplace(const ::com::sun::star::util::SearchOptions& rSearchOptions, bool bSrchForward)
+{
+ SwSidebarWin* pWin = GetActiveSidebarWin();
+ SvxSearchItem aItem(SID_SEARCH_ITEM );
+ aItem.SetSearchOptions(rSearchOptions);
+ aItem.SetBackward(!bSrchForward);
+ sal_uInt16 aResult = pWin->GetOutlinerView()->StartSearchAndReplace( aItem );
+ if (!aResult)
+ SetActiveSidebarWin(0);
+ return aResult;
+}
+
+sal_uInt16 SwPostItMgr::SearchReplace(const SwFmtFld &pFld, const ::com::sun::star::util::SearchOptions& rSearchOptions, bool bSrchForward)
+{
+ sal_uInt16 aResult = 0;
+ SwSidebarWin* pWin = GetSidebarWin(&pFld);
+ if (pWin)
+ {
+ ESelection aOldSelection = pWin->GetOutlinerView()->GetSelection();
+ if (bSrchForward)
+ pWin->GetOutlinerView()->SetSelection(ESelection(0,0,0,0));
+ else
+ pWin->GetOutlinerView()->SetSelection(
+ ESelection(EE_PARA_MAX_COUNT,EE_TEXTPOS_MAX_COUNT,EE_PARA_MAX_COUNT,EE_TEXTPOS_MAX_COUNT));
+ SvxSearchItem aItem(SID_SEARCH_ITEM );
+ aItem.SetSearchOptions(rSearchOptions);
+ aItem.SetBackward(!bSrchForward);
+ aResult = pWin->GetOutlinerView()->StartSearchAndReplace( aItem );
+ if (!aResult)
+ pWin->GetOutlinerView()->SetSelection(aOldSelection);
+ else
+ {
+ SetActiveSidebarWin(pWin);
+ MakeVisible(pWin);
+ }
+ }
+ return aResult;
+}
+
+void SwPostItMgr::AssureStdModeAtShell()
+{
+ // deselect any drawing or frame and leave editing mode
+ SdrView* pSdrView = mpWrtShell->GetDrawView();
+ if ( pSdrView && pSdrView->IsTextEdit() )
+ {
+ bool bLockView = mpWrtShell->IsViewLocked();
+ mpWrtShell->LockView( true );
+ mpWrtShell->EndTextEdit();
+ mpWrtShell->LockView( bLockView );
+ }
+
+ if( mpWrtShell->IsSelFrmMode() || mpWrtShell->IsObjSelected())
+ {
+ mpWrtShell->UnSelectFrm();
+ mpWrtShell->LeaveSelFrmMode();
+ mpWrtShell->GetView().LeaveDrawCreate();
+ mpWrtShell->EnterStdMode();
+
+ mpWrtShell->DrawSelChanged();
+ mpView->StopShellTimer();
+ }
+}
+
+bool SwPostItMgr::HasActiveSidebarWin() const
+{
+ return mpActivePostIt != 0;
+}
+
+bool SwPostItMgr::HasActiveAnnotationWin() const
+{
+ return HasActiveSidebarWin() &&
+ dynamic_cast<sw::annotation::SwAnnotationWin*>(mpActivePostIt) != 0;
+}
+
+void SwPostItMgr::GrabFocusOnActiveSidebarWin()
+{
+ if ( HasActiveSidebarWin() )
+ {
+ mpActivePostIt->GrabFocus();
+ }
+}
+
+void SwPostItMgr::UpdateDataOnActiveSidebarWin()
+{
+ if ( HasActiveSidebarWin() )
+ {
+ mpActivePostIt->UpdateData();
+ }
+}
+
+void SwPostItMgr::DeleteActiveSidebarWin()
+{
+ if ( HasActiveSidebarWin() )
+ {
+ mpActivePostIt->Delete();
+ }
+}
+
+void SwPostItMgr::HideActiveSidebarWin()
+{
+ if ( HasActiveSidebarWin() )
+ {
+ mpActivePostIt->Hide();
+ }
+}
+
+void SwPostItMgr::ToggleInsModeOnActiveSidebarWin()
+{
+ if ( HasActiveSidebarWin() )
+ {
+ mpActivePostIt->ToggleInsMode();
+ }
+}
+
+void SwPostItMgr::ConnectSidebarWinToFrm( const SwFrm& rFrm,
+ const SwFmtFld& rFmtFld,
+ SwSidebarWin& rSidebarWin )
+{
+ if ( mpFrmSidebarWinContainer == 0 )
+ {
+ mpFrmSidebarWinContainer = new SwFrmSidebarWinContainer();
+ }
+
+ const bool bInserted = mpFrmSidebarWinContainer->insert( rFrm, rFmtFld, rSidebarWin );
+ if ( bInserted &&
+ mpWrtShell->GetAccessibleMap() )
+ {
+ mpWrtShell->GetAccessibleMap()->InvalidatePosOrSize( 0, 0, &rSidebarWin, SwRect() );
+ }
+}
+
+void SwPostItMgr::DisconnectSidebarWinFromFrm( const SwFrm& rFrm,
+ SwSidebarWin& rSidebarWin )
+{
+ if ( mpFrmSidebarWinContainer != 0 )
+ {
+ const bool bRemoved = mpFrmSidebarWinContainer->remove( rFrm, rSidebarWin );
+ if ( bRemoved &&
+ mpWrtShell->GetAccessibleMap() )
+ {
+ mpWrtShell->GetAccessibleMap()->Dispose( 0, 0, &rSidebarWin );
+ }
+ }
+}
+
+bool SwPostItMgr::HasFrmConnectedSidebarWins( const SwFrm& rFrm )
+{
+ bool bRet( false );
+
+ if ( mpFrmSidebarWinContainer != 0 )
+ {
+ bRet = !mpFrmSidebarWinContainer->empty( rFrm );
+ }
+
+ return bRet;
+}
+
+Window* SwPostItMgr::GetSidebarWinForFrmByIndex( const SwFrm& rFrm,
+ const sal_Int32 nIndex )
+{
+ Window* pSidebarWin( 0 );
+
+ if ( mpFrmSidebarWinContainer != 0 )
+ {
+ pSidebarWin = mpFrmSidebarWinContainer->get( rFrm, nIndex );
+ }
+
+ return pSidebarWin;
+}
+
+void SwPostItMgr::GetAllSidebarWinForFrm( const SwFrm& rFrm,
+ std::vector< Window* >* pChildren )
+{
+ if ( mpFrmSidebarWinContainer != 0 )
+ {
+ mpFrmSidebarWinContainer->getAll( rFrm, pChildren );
+ }
+}
+
+void SwNoteProps::Commit() {}
+void SwNoteProps::Notify( const ::com::sun::star::uno::Sequence< OUString >& ) {}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/docvw/ShadowOverlayObject.cxx b/sw/source/uibase/docvw/ShadowOverlayObject.cxx
new file mode 100644
index 000000000000..2b9b4d2fa7f8
--- /dev/null
+++ b/sw/source/uibase/docvw/ShadowOverlayObject.cxx
@@ -0,0 +1,252 @@
+/* -*- 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 <ShadowOverlayObject.hxx>
+
+#include <view.hxx>
+#include <svx/sdrpaintwindow.hxx>
+#include <svx/svdview.hxx>
+#include <svx/sdr/overlay/overlaymanager.hxx>
+
+#include <sw_primitivetypes2d.hxx>
+#include <drawinglayer/primitive2d/primitivetools2d.hxx>
+#include <drawinglayer/primitive2d/fillgradientprimitive2d.hxx>
+
+namespace sw { namespace sidebarwindows {
+
+// helper SwPostItShadowPrimitive
+
+// Used to allow view-dependent primitive definition. For that purpose, the
+// initially created primitive (this one) always has to be view-independent,
+// but the decomposition is made view-dependent. Very simple primitive which
+// just remembers the discrete data and applies it at decomposition time.
+class ShadowPrimitive : public drawinglayer::primitive2d::DiscreteMetricDependentPrimitive2D
+{
+private:
+ basegfx::B2DPoint maBasePosition;
+ basegfx::B2DPoint maSecondPosition;
+ ShadowState maShadowState;
+
+protected:
+ virtual drawinglayer::primitive2d::Primitive2DSequence create2DDecomposition(
+ const drawinglayer::geometry::ViewInformation2D& rViewInformation) const SAL_OVERRIDE;
+
+public:
+ ShadowPrimitive(
+ const basegfx::B2DPoint& rBasePosition,
+ const basegfx::B2DPoint& rSecondPosition,
+ ShadowState aShadowState)
+ : drawinglayer::primitive2d::DiscreteMetricDependentPrimitive2D(),
+ maBasePosition(rBasePosition),
+ maSecondPosition(rSecondPosition),
+ maShadowState(aShadowState)
+ {}
+
+ // data access
+ const basegfx::B2DPoint& getBasePosition() const { return maBasePosition; }
+ const basegfx::B2DPoint& getSecondPosition() const { return maSecondPosition; }
+ ShadowState getShadowState() const { return maShadowState; }
+
+ virtual bool operator==( const drawinglayer::primitive2d::BasePrimitive2D& rPrimitive ) const SAL_OVERRIDE;
+
+ DeclPrimitive2DIDBlock()
+};
+
+drawinglayer::primitive2d::Primitive2DSequence ShadowPrimitive::create2DDecomposition(
+ const drawinglayer::geometry::ViewInformation2D& /*rViewInformation*/) const
+{
+ // get logic sizes in object coordinate system
+ drawinglayer::primitive2d::Primitive2DSequence xRetval;
+ basegfx::B2DRange aRange(getBasePosition());
+
+ switch(maShadowState)
+ {
+ case SS_NORMAL:
+ {
+ aRange.expand(basegfx::B2DTuple(getSecondPosition().getX(), getSecondPosition().getY() + (2.0 * getDiscreteUnit())));
+ const ::drawinglayer::attribute::FillGradientAttribute aFillGradientAttribute(
+ drawinglayer::attribute::GRADIENTSTYLE_LINEAR,
+ 0.0,
+ 0.5,
+ 0.5,
+ 1800.0 * F_PI1800,
+ basegfx::BColor(230.0/255.0,230.0/255.0,230.0/255.0),
+ basegfx::BColor(180.0/255.0,180.0/255.0,180.0/255.0),
+ 2);
+
+ const drawinglayer::primitive2d::Primitive2DReference xReference(
+ new drawinglayer::primitive2d::FillGradientPrimitive2D(
+ aRange,
+ aFillGradientAttribute));
+
+ xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1);
+ break;
+ }
+ case SS_VIEW:
+ {
+ aRange.expand(basegfx::B2DTuple(getSecondPosition().getX(), getSecondPosition().getY() + (4.0 * getDiscreteUnit())));
+ const drawinglayer::attribute::FillGradientAttribute aFillGradientAttribute(
+ drawinglayer::attribute::GRADIENTSTYLE_LINEAR,
+ 0.0,
+ 0.5,
+ 0.5,
+ 1800.0 * F_PI1800,
+ basegfx::BColor(230.0/255.0,230.0/255.0,230.0/255.0),
+ basegfx::BColor(180.0/255.0,180.0/255.0,180.0/255.0),
+ 4);
+
+ const drawinglayer::primitive2d::Primitive2DReference xReference(
+ new drawinglayer::primitive2d::FillGradientPrimitive2D(
+ aRange,
+ aFillGradientAttribute));
+
+ xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1);
+ break;
+ }
+ case SS_EDIT:
+ {
+ aRange.expand(basegfx::B2DTuple(getSecondPosition().getX(), getSecondPosition().getY() + (4.0 * getDiscreteUnit())));
+ const drawinglayer::attribute::FillGradientAttribute aFillGradientAttribute(
+ drawinglayer::attribute::GRADIENTSTYLE_LINEAR,
+ 0.0,
+ 0.5,
+ 0.5,
+ 1800.0 * F_PI1800,
+ basegfx::BColor(230.0/255.0,230.0/255.0,230.0/255.0),
+ basegfx::BColor(83.0/255.0,83.0/255.0,83.0/255.0),
+ 4);
+
+ const drawinglayer::primitive2d::Primitive2DReference xReference(
+ new drawinglayer::primitive2d::FillGradientPrimitive2D(
+ aRange,
+ aFillGradientAttribute));
+
+ xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1);
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ return xRetval;
+}
+
+bool ShadowPrimitive::operator==( const drawinglayer::primitive2d::BasePrimitive2D& rPrimitive ) const
+{
+ if(drawinglayer::primitive2d::DiscreteMetricDependentPrimitive2D::operator==(rPrimitive))
+ {
+ const ShadowPrimitive& rCompare = static_cast< const ShadowPrimitive& >(rPrimitive);
+
+ return (getBasePosition() == rCompare.getBasePosition()
+ && getSecondPosition() == rCompare.getSecondPosition()
+ && getShadowState() == rCompare.getShadowState());
+ }
+
+ return false;
+}
+
+ImplPrimitive2DIDBlock(ShadowPrimitive, PRIMITIVE2D_ID_SWSIDEBARSHADOWPRIMITIVE)
+
+/* static */ ShadowOverlayObject* ShadowOverlayObject::CreateShadowOverlayObject( SwView& rDocView )
+{
+ ShadowOverlayObject* pShadowOverlayObject( 0 );
+
+ if ( rDocView.GetDrawView() )
+ {
+ SdrPaintWindow* pPaintWindow = rDocView.GetDrawView()->GetPaintWindow(0);
+ if( pPaintWindow )
+ {
+ rtl::Reference< ::sdr::overlay::OverlayManager > xOverlayManager = pPaintWindow->GetOverlayManager();
+
+ if ( xOverlayManager.is() )
+ {
+ pShadowOverlayObject = new ShadowOverlayObject( basegfx::B2DPoint(0,0),
+ basegfx::B2DPoint(0,0),
+ Color(0,0,0),
+ SS_NORMAL );
+ xOverlayManager->add(*pShadowOverlayObject);
+ }
+ }
+ }
+
+ return pShadowOverlayObject;
+}
+
+/* static */ void ShadowOverlayObject::DestroyShadowOverlayObject( ShadowOverlayObject* pShadow )
+{
+ if ( pShadow )
+ {
+ if ( pShadow->getOverlayManager() )
+ {
+ pShadow->getOverlayManager()->remove(*pShadow);
+ }
+ delete pShadow;
+ }
+}
+
+ShadowOverlayObject::ShadowOverlayObject( const basegfx::B2DPoint& rBasePos,
+ const basegfx::B2DPoint& rSecondPosition,
+ Color aBaseColor,
+ ShadowState aState )
+ : OverlayObjectWithBasePosition(rBasePos, aBaseColor)
+ , maSecondPosition(rSecondPosition)
+ , mShadowState(aState)
+{
+}
+
+ShadowOverlayObject::~ShadowOverlayObject()
+{
+}
+
+drawinglayer::primitive2d::Primitive2DSequence ShadowOverlayObject::createOverlayObjectPrimitive2DSequence()
+{
+ const drawinglayer::primitive2d::Primitive2DReference aReference(
+ new ShadowPrimitive( getBasePosition(),
+ GetSecondPosition(),
+ GetShadowState() ) );
+ return drawinglayer::primitive2d::Primitive2DSequence(&aReference, 1);
+}
+
+void ShadowOverlayObject::SetShadowState(ShadowState aState)
+{
+ if (mShadowState != aState)
+ {
+ mShadowState = aState;
+
+ objectChange();
+ }
+}
+
+void ShadowOverlayObject::SetPosition( const basegfx::B2DPoint& rPoint1,
+ const basegfx::B2DPoint& rPoint2)
+{
+ if(!rPoint1.equal(getBasePosition()) || !rPoint2.equal(GetSecondPosition()))
+ {
+ maBasePosition = rPoint1;
+ maSecondPosition = rPoint2;
+
+ objectChange();
+ }
+}
+
+} } // end of namespace sw::sidebarwindows
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/docvw/ShadowOverlayObject.hxx b/sw/source/uibase/docvw/ShadowOverlayObject.hxx
new file mode 100644
index 000000000000..a6751824d362
--- /dev/null
+++ b/sw/source/uibase/docvw/ShadowOverlayObject.hxx
@@ -0,0 +1,70 @@
+/* -*- 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 .
+ */
+
+#ifndef INCLUDED_SW_SOURCE_CORE_UIBASE_DOCVW_SHADOWOVERLAYOBJECT_HXX
+#define INCLUDED_SW_SOURCE_CORE_UIBASE_DOCVW_SHADOWOVERLAYOBJECT_HXX
+
+#include <svx/sdr/overlay/overlayobject.hxx>
+
+class SwView;
+
+namespace sw { namespace sidebarwindows {
+
+enum ShadowState
+{
+ SS_NORMAL,
+ SS_VIEW,
+ SS_EDIT
+};
+
+class ShadowOverlayObject: public sdr::overlay::OverlayObjectWithBasePosition
+{
+ protected:
+ // geometry creation for OverlayObject
+ virtual drawinglayer::primitive2d::Primitive2DSequence createOverlayObjectPrimitive2DSequence() SAL_OVERRIDE;
+
+ private:
+ basegfx::B2DPoint maSecondPosition;
+ ShadowState mShadowState;
+
+ ShadowOverlayObject( const basegfx::B2DPoint& rBasePos,
+ const basegfx::B2DPoint& rSecondPosition,
+ Color aBaseColor,
+ ShadowState aState );
+ virtual ~ShadowOverlayObject();
+
+ public:
+ void SetShadowState(ShadowState aState);
+ inline ShadowState GetShadowState() {return mShadowState;}
+
+ inline const basegfx::B2DPoint& GetSecondPosition() const { return maSecondPosition; }
+ void SetSecondPosition( const basegfx::B2DPoint& rNew );
+
+ void SetPosition( const basegfx::B2DPoint& rPoint1,
+ const basegfx::B2DPoint& rPoint2 );
+
+ static ShadowOverlayObject* CreateShadowOverlayObject( SwView& rDocView );
+ static void DestroyShadowOverlayObject( ShadowOverlayObject* pShadow );
+};
+
+} } // end of namespace sw::sidebarwindows
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/docvw/SidebarTxtControl.cxx b/sw/source/uibase/docvw/SidebarTxtControl.cxx
new file mode 100644
index 000000000000..5834c020832a
--- /dev/null
+++ b/sw/source/uibase/docvw/SidebarTxtControl.cxx
@@ -0,0 +1,433 @@
+/* -*- 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 <SidebarWin.hxx>
+#include <PostItMgr.hxx>
+
+#include <cmdid.h>
+#include <docvw.hrc>
+
+#include <unotools/securityoptions.hxx>
+
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/mnumgr.hxx>
+
+#include <vcl/svapp.hxx>
+#include <vcl/help.hxx>
+#include <vcl/layout.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/gradient.hxx>
+#include <vcl/scrbar.hxx>
+#include <vcl/settings.hxx>
+
+#include <editeng/outliner.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/editview.hxx>
+#include <editeng/flditem.hxx>
+
+#include <uitool.hxx>
+#include <view.hxx>
+#include <wrtsh.hxx>
+#include <shellres.hxx>
+#include <SwRewriter.hxx>
+
+namespace sw { namespace sidebarwindows {
+
+SidebarTxtControl::SidebarTxtControl( SwSidebarWin& rSidebarWin,
+ WinBits nBits,
+ SwView& rDocView,
+ SwPostItMgr& rPostItMgr )
+ : Control( &rSidebarWin, nBits )
+ , mrSidebarWin( rSidebarWin )
+ , mrDocView( rDocView )
+ , mrPostItMgr( rPostItMgr )
+{
+ AddEventListener( LINK( &mrSidebarWin, SwSidebarWin, WindowEventListener ) );
+}
+
+SidebarTxtControl::~SidebarTxtControl()
+{
+ RemoveEventListener( LINK( &mrSidebarWin, SwSidebarWin, WindowEventListener ) );
+}
+
+OutlinerView* SidebarTxtControl::GetTextView() const
+{
+ return mrSidebarWin.GetOutlinerView();
+}
+
+void SidebarTxtControl::GetFocus()
+{
+ Window::GetFocus();
+ if ( !mrSidebarWin.IsMouseOver() )
+ {
+ Invalidate();
+ }
+}
+
+void SidebarTxtControl::LoseFocus()
+{
+ // write the visible text back into the SwField
+ mrSidebarWin.UpdateData();
+
+ Window::LoseFocus();
+ if ( !mrSidebarWin.IsMouseOver() )
+ {
+ Invalidate();
+ }
+}
+
+void SidebarTxtControl::RequestHelp(const HelpEvent &rEvt)
+{
+ sal_uInt16 nResId = 0;
+ switch( mrSidebarWin.GetLayoutStatus() )
+ {
+ case SwPostItHelper::INSERTED: nResId = STR_REDLINE_INSERT; break;
+ case SwPostItHelper::DELETED: nResId = STR_REDLINE_DELETE; break;
+ default: nResId = 0;
+ }
+
+ SwContentAtPos aCntntAtPos( SwContentAtPos::SW_REDLINE );
+ if ( nResId &&
+ mrDocView.GetWrtShell().GetContentAtPos( mrSidebarWin.GetAnchorPos(), aCntntAtPos ) )
+ {
+ OUString sTxt = SW_RESSTR( nResId ) + ": " +
+ aCntntAtPos.aFnd.pRedl->GetAuthorString() + " - " +
+ GetAppLangDateTimeString( aCntntAtPos.aFnd.pRedl->GetTimeStamp() );
+ Help::ShowQuickHelp( this,PixelToLogic(Rectangle(rEvt.GetMousePosPixel(),Size(50,10))),sTxt);
+ }
+}
+
+void SidebarTxtControl::Draw(OutputDevice* pDev, const Point& rPt, const Size& rSz, sal_uLong)
+{
+ //Take the control's height, but overwrite the scrollbar area if there was one
+ Size aSize(PixelToLogic(GetSizePixel()));
+ aSize.Width() = rSz.Width();
+
+ if ( GetTextView() )
+ {
+ GetTextView()->GetOutliner()->Draw(pDev, 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 SidebarTxtControl::Paint( const Rectangle& rRect)
+{
+ if ( !Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
+ {
+ if ( mrSidebarWin.IsMouseOverSidebarWin() ||
+ HasFocus() )
+ {
+ DrawGradient( Rectangle( Point(0,0), PixelToLogic(GetSizePixel()) ),
+ Gradient( GradientStyle_LINEAR,
+ mrSidebarWin.ColorDark(),
+ mrSidebarWin.ColorDark() ) );
+ }
+ else
+ {
+ DrawGradient( Rectangle( Point(0,0), PixelToLogic(GetSizePixel()) ),
+ Gradient( GradientStyle_LINEAR,
+ mrSidebarWin.ColorLight(),
+ mrSidebarWin.ColorDark()));
+ }
+ }
+
+ if ( GetTextView() )
+ {
+ GetTextView()->Paint( rRect );
+ }
+
+ if ( mrSidebarWin.GetLayoutStatus()==SwPostItHelper::DELETED )
+ {
+ SetLineColor(mrSidebarWin.GetChangeColor());
+ DrawLine( PixelToLogic( GetPosPixel() ),
+ PixelToLogic( GetPosPixel() +
+ Point( GetSizePixel().Width(),
+ GetSizePixel().Height() ) ) );
+ DrawLine( PixelToLogic( GetPosPixel() +
+ Point( GetSizePixel().Width(),0) ),
+ PixelToLogic( GetPosPixel() +
+ Point( 0, GetSizePixel().Height() ) ) );
+ }
+}
+
+void SidebarTxtControl::KeyInput( const KeyEvent& rKeyEvt )
+{
+ const 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 ( nKey == KEY_INSERT )
+ {
+ if ( !rKeyCode.IsMod1() && !rKeyCode.IsMod2() )
+ {
+ mrSidebarWin.ToggleInsMode();
+ }
+ }
+ else
+ {
+ //let's make sure we see our note
+ mrPostItMgr.MakeVisible(&mrSidebarWin);
+
+ 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 ||
+ ( bIsProtected &&
+ !mrSidebarWin.GetOutlinerView()->GetOutliner()->GetEditEngine().DoesKeyChangeText(rKeyEvt)) )
+ {
+ bDone = GetTextView() && GetTextView()->PostKeyEvent( rKeyEvt );
+ }
+ else
+ {
+ MessageDialog(this, "InfoReadonlyDialog",
+ "modules/swriter/ui/inforeadonlydialog.ui").Execute();
+ }
+ }
+ 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 SidebarTxtControl::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* pFld = pItem->GetField();
+ const SvxURLField* pURL = PTR_CAST( SvxURLField, pFld );
+ if ( pURL )
+ {
+ OUString sURL( pURL->GetURL() );
+ SvtSecurityOptions aSecOpts;
+ if ( aSecOpts.IsOptionSet( SvtSecurityOptions::E_CTRLCLICK_HYPERLINK) )
+ sURL = SwViewShell::GetShellRes()->aLinkCtrlClick + ": " + sURL;
+ else
+ sURL = SwViewShell::GetShellRes()->aLinkClick + ": " + sURL;
+ Help::ShowQuickHelp( this,PixelToLogic(Rectangle(GetPosPixel(),Size(50,10))),sURL);
+ }
+ }
+ }
+}
+
+void SidebarTxtControl::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if ( GetTextView() )
+ {
+ SvtSecurityOptions aSecOpts;
+ bool bExecuteMod = aSecOpts.IsOptionSet( SvtSecurityOptions::E_CTRLCLICK_HYPERLINK);
+
+ if ( !bExecuteMod || (bExecuteMod && rMEvt.GetModifier() == KEY_MOD1))
+ {
+ const EditView& aEV = GetTextView()->GetEditView();
+ const SvxFieldItem* pItem = aEV.GetFieldUnderMousePointer();
+ if ( pItem )
+ {
+ const SvxFieldData* pFld = pItem->GetField();
+ const SvxURLField* pURL = PTR_CAST( SvxURLField, pFld );
+ if ( pURL )
+ {
+ GetTextView()->MouseButtonDown( rMEvt );
+ SwWrtShell &rSh = mrDocView.GetWrtShell();
+ OUString sURL( pURL->GetURL() );
+ OUString sTarget( pURL->GetTargetFrame() );
+ ::LoadURL(rSh, sURL, URLLOAD_NOFILTER, sTarget);
+ return;
+ }
+ }
+ }
+ }
+
+ GrabFocus();
+ if ( GetTextView() )
+ {
+ GetTextView()->MouseButtonDown( rMEvt );
+ }
+ mrDocView.GetViewFrame()->GetBindings().InvalidateAll(false);
+}
+
+void SidebarTxtControl::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ if ( GetTextView() )
+ GetTextView()->MouseButtonUp( rMEvt );
+}
+
+IMPL_LINK( SidebarTxtControl, OnlineSpellCallback, SpellCallbackInfo*, pInfo )
+{
+ if ( pInfo->nCommand == SPELLCMD_STARTSPELLDLG )
+ {
+ mrDocView.GetViewFrame()->GetDispatcher()->Execute( FN_SPELL_GRAMMAR_DIALOG, SFX_CALLMODE_ASYNCHRON);
+ }
+ return 0;
+}
+
+IMPL_LINK( SidebarTxtControl, Select, Menu*, pSelMenu )
+{
+ mrSidebarWin.ExecuteCommand( pSelMenu->GetCurItemId() );
+ return 0;
+}
+
+void SidebarTxtControl::Command( const CommandEvent& rCEvt )
+{
+ if ( rCEvt.GetCommand() == COMMAND_CONTEXTMENU )
+ {
+ if ( !mrSidebarWin.IsProtected() &&
+ GetTextView() &&
+ GetTextView()->IsWrongSpelledWordAtPos( rCEvt.GetMousePosPixel(), true ))
+ {
+ Link aLink = LINK(this, SidebarTxtControl, OnlineSpellCallback);
+ GetTextView()->ExecuteSpellPopup(rCEvt.GetMousePosPixel(),&aLink);
+ }
+ else
+ {
+ SfxPopupMenuManager* pMgr = mrDocView.GetViewFrame()->GetDispatcher()->Popup(0, this,&rCEvt.GetMousePosPixel());
+ ((PopupMenu*)pMgr->GetSVMenu())->SetSelectHdl( LINK(this, SidebarTxtControl, Select) );
+
+ {
+ OUString aText = ((PopupMenu*)pMgr->GetSVMenu())->GetItemText( FN_DELETE_NOTE_AUTHOR );
+ SwRewriter aRewriter;
+ aRewriter.AddRule(UndoArg1, mrSidebarWin.GetAuthor());
+ aText = aRewriter.Apply(aText);
+ ((PopupMenu*)pMgr->GetSVMenu())->SetItemText(FN_DELETE_NOTE_AUTHOR,aText);
+ }
+
+ Point aPos;
+ if (rCEvt.IsMouseEvent())
+ aPos = rCEvt.GetMousePosPixel();
+ else
+ {
+ const Size aSize = GetSizePixel();
+ aPos = Point( aSize.getWidth()/2, aSize.getHeight()/2 );
+ }
+
+ //!! call different Execute function to get rid of the new thesaurus sub menu
+ //!! pointer created in the call to Popup.
+ //!! Otherwise we would have a memory leak (see also #i107205#)
+ pMgr->Execute( aPos, this );
+ delete pMgr;
+ }
+ }
+ else
+ if (rCEvt.GetCommand() == COMMAND_WHEEL)
+ {
+ if (mrSidebarWin.IsScrollbarVisible())
+ {
+ const CommandWheelData* pData = rCEvt.GetWheelData();
+ if (pData->IsShift() || pData->IsMod1() || pData->IsMod2())
+ {
+ mrDocView.HandleWheelCommands(rCEvt);
+ }
+ else
+ {
+ HandleScrollCommand( rCEvt, 0 , mrSidebarWin.Scrollbar());
+ }
+ }
+ else
+ {
+ mrDocView.HandleWheelCommands(rCEvt);
+ }
+ }
+ else
+ {
+ if ( GetTextView() )
+ GetTextView()->Command( rCEvt );
+ else
+ Window::Command(rCEvt);
+ }
+}
+
+OUString SidebarTxtControl::GetSurroundingText() const
+{
+ if (GetTextView())
+ return GetTextView()->GetSurroundingText();
+ return OUString();
+}
+
+Selection SidebarTxtControl::GetSurroundingTextSelection() const
+{
+ if( GetTextView() )
+ return GetTextView()->GetSurroundingTextSelection();
+ else
+ return Selection( 0, 0 );
+}
+
+css::uno::Reference< css::accessibility::XAccessible > SidebarTxtControl::CreateAccessible()
+{
+
+ SidebarTxtControlAccessible* pAcc( new SidebarTxtControlAccessible( *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: */
diff --git a/sw/source/uibase/docvw/SidebarTxtControl.hxx b/sw/source/uibase/docvw/SidebarTxtControl.hxx
new file mode 100644
index 000000000000..d98503d01519
--- /dev/null
+++ b/sw/source/uibase/docvw/SidebarTxtControl.hxx
@@ -0,0 +1,77 @@
+/* -*- 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 .
+ */
+
+#ifndef INCLUDED_SW_SOURCE_CORE_UIBASE_DOCVW_SIDEBARTXTCONTROL_HXX
+#define INCLUDED_SW_SOURCE_CORE_UIBASE_DOCVW_SIDEBARTXTCONTROL_HXX
+
+#include <vcl/ctrl.hxx>
+
+class OutlinerView;
+class SwView;
+class SwPostItMgr;
+struct SpellCallbackInfo;
+
+namespace sw { namespace sidebarwindows {
+
+class SwSidebarWin;
+
+class SidebarTxtControl : public Control
+{
+ private:
+ SwSidebarWin& mrSidebarWin;
+ SwView& mrDocView;
+ SwPostItMgr& mrPostItMgr;
+
+ protected:
+ virtual void Paint( const Rectangle& rRect) SAL_OVERRIDE;
+ virtual void KeyInput( const KeyEvent& rKeyEvt ) SAL_OVERRIDE;
+ virtual void MouseMove( const MouseEvent& rMEvt ) SAL_OVERRIDE;
+ virtual void MouseButtonDown( const MouseEvent& rMEvt ) SAL_OVERRIDE;
+ virtual void MouseButtonUp( const MouseEvent& rMEvt ) SAL_OVERRIDE;
+ virtual void Command( const CommandEvent& rCEvt ) SAL_OVERRIDE;
+ virtual void LoseFocus() SAL_OVERRIDE;
+ virtual void RequestHelp(const HelpEvent &rEvt) SAL_OVERRIDE;
+ virtual OUString GetSurroundingText() const SAL_OVERRIDE;
+ virtual Selection GetSurroundingTextSelection() const SAL_OVERRIDE;
+
+ DECL_LINK( Select, Menu* );
+
+ public:
+ SidebarTxtControl( SwSidebarWin& rSidebarWin,
+ WinBits nBits,
+ SwView& rDocView,
+ SwPostItMgr& rPostItMgr );
+ virtual ~SidebarTxtControl();
+
+ virtual void GetFocus() SAL_OVERRIDE;
+
+ OutlinerView* GetTextView() const;
+
+ DECL_LINK( OnlineSpellCallback, SpellCallbackInfo*);
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > CreateAccessible() SAL_OVERRIDE;
+
+ virtual void Draw(OutputDevice* pDev, const Point&, const Size&, sal_uLong) SAL_OVERRIDE;
+};
+
+} } // end of namespace sw::sidebarwindows
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/docvw/SidebarTxtControlAcc.cxx b/sw/source/uibase/docvw/SidebarTxtControlAcc.cxx
new file mode 100644
index 000000000000..5bbd2e8eef2e
--- /dev/null
+++ b/sw/source/uibase/docvw/SidebarTxtControlAcc.cxx
@@ -0,0 +1,293 @@
+/* -*- 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 <SidebarTxtControlAcc.hxx>
+
+#include <SidebarTxtControl.hxx>
+
+#include <svl/brdcst.hxx>
+#include <toolkit/awt/vclxaccessiblecomponent.hxx>
+#include <editeng/unoedsrc.hxx>
+#include <editeng/unoforou.hxx>
+#include <editeng/unoviwou.hxx>
+#include <editeng/unoedhlp.hxx>
+#include <svx/AccessibleTextHelper.hxx>
+#include <editeng/outliner.hxx>
+
+#include <boost/scoped_ptr.hpp>
+
+namespace sw { namespace sidebarwindows {
+
+// declaration and implementation of <SvxEditSource>
+// for <::accessibiliy::AccessibleTextHelper> instance
+class SidebarTextEditSource : public SvxEditSource,
+ public SfxBroadcaster
+{
+ public:
+ SidebarTextEditSource( SidebarTxtControl& rSidebarTxtControl );
+ virtual ~SidebarTextEditSource();
+
+ virtual SvxEditSource* Clone() const SAL_OVERRIDE;
+
+ virtual SvxTextForwarder* GetTextForwarder() SAL_OVERRIDE;
+ virtual SvxViewForwarder* GetViewForwarder() SAL_OVERRIDE;
+ virtual SvxEditViewForwarder* GetEditViewForwarder( bool bCreate = false ) SAL_OVERRIDE;
+
+ virtual void UpdateData() SAL_OVERRIDE;
+
+ virtual SfxBroadcaster& GetBroadcaster() const SAL_OVERRIDE;
+ DECL_LINK( NotifyHdl, EENotify* );
+
+ private:
+ SidebarTxtControl& mrSidebarTxtControl;
+ SvxOutlinerForwarder mTextForwarder;
+ SvxDrawOutlinerViewForwarder mViewForwarder;
+};
+
+SidebarTextEditSource::SidebarTextEditSource( SidebarTxtControl& rSidebarTxtControl )
+ : SvxEditSource()
+ , mrSidebarTxtControl( rSidebarTxtControl )
+ , mTextForwarder( *(rSidebarTxtControl.GetTextView()->GetOutliner()), false )
+ , mViewForwarder( *(rSidebarTxtControl.GetTextView()) )
+{
+ if ( mrSidebarTxtControl.GetTextView() )
+ {
+ mrSidebarTxtControl.GetTextView()->GetOutliner()->SetNotifyHdl( LINK(this, SidebarTextEditSource, NotifyHdl) );
+ }
+}
+
+SidebarTextEditSource::~SidebarTextEditSource()
+{
+ if ( mrSidebarTxtControl.GetTextView() )
+ {
+ mrSidebarTxtControl.GetTextView()->GetOutliner()->SetNotifyHdl( Link() );
+ }
+}
+
+SvxEditSource* SidebarTextEditSource::Clone() const
+{
+ return new SidebarTextEditSource( mrSidebarTxtControl );
+}
+
+SvxTextForwarder* SidebarTextEditSource::GetTextForwarder()
+{
+ return &mTextForwarder;
+}
+
+SvxViewForwarder* SidebarTextEditSource::GetViewForwarder()
+{
+ return &mViewForwarder;
+}
+
+SvxEditViewForwarder* SidebarTextEditSource::GetEditViewForwarder( bool /*bCreate*/ )
+{
+ return &mViewForwarder;
+}
+
+void SidebarTextEditSource::UpdateData()
+{
+ // nothing to do
+}
+
+SfxBroadcaster& SidebarTextEditSource::GetBroadcaster() const
+{
+ return *( const_cast< SidebarTextEditSource* > (this) );
+}
+
+IMPL_LINK(SidebarTextEditSource, NotifyHdl, EENotify*, pNotify)
+{
+ if ( pNotify )
+ {
+ boost::scoped_ptr< SfxHint > aHint( SvxEditSourceHelper::EENotification2Hint( pNotify ) );
+
+ if( aHint.get() )
+ {
+ Broadcast( *aHint.get() );
+ }
+ }
+
+ return 0;
+}
+
+// declaration and implementation of accessible context for <SidebarTxtControl> instance
+class SidebarTxtControlAccessibleContext : public VCLXAccessibleComponent
+{
+ public:
+ explicit SidebarTxtControlAccessibleContext( SidebarTxtControl& rSidebarTxtControl );
+ virtual ~SidebarTxtControlAccessibleContext();
+
+ virtual sal_Int32 SAL_CALL
+ getAccessibleChildCount()
+ throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL
+ getAccessibleChild( sal_Int32 i )
+ throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
+
+ virtual void SAL_CALL
+ addAccessibleEventListener (
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleEventListener >& xListener)
+ throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
+ virtual void SAL_CALL
+ removeAccessibleEventListener (
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleEventListener >& xListener)
+ throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
+
+ protected:
+ virtual void ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) SAL_OVERRIDE;
+
+ private:
+ SidebarTxtControl& mrSidebarTxtControl;
+ ::accessibility::AccessibleTextHelper* mpAccessibleTextHelper;
+
+ ::osl::Mutex maMutex;
+
+ void defunc();
+};
+
+SidebarTxtControlAccessibleContext::SidebarTxtControlAccessibleContext( SidebarTxtControl& rSidebarTxtControl )
+ : VCLXAccessibleComponent( rSidebarTxtControl.GetWindowPeer() )
+ , mrSidebarTxtControl( rSidebarTxtControl )
+ , mpAccessibleTextHelper( 0 )
+ , maMutex()
+{
+ ::std::auto_ptr<SvxEditSource> pEditSource(
+ new SidebarTextEditSource( mrSidebarTxtControl ) );
+ mpAccessibleTextHelper = new ::accessibility::AccessibleTextHelper( pEditSource );
+ mpAccessibleTextHelper->SetEventSource( mrSidebarTxtControl.GetWindowPeer() );
+}
+
+SidebarTxtControlAccessibleContext::~SidebarTxtControlAccessibleContext()
+{
+ defunc();
+}
+
+void SidebarTxtControlAccessibleContext::defunc()
+{
+ delete mpAccessibleTextHelper;
+ mpAccessibleTextHelper = 0;
+}
+
+sal_Int32 SAL_CALL SidebarTxtControlAccessibleContext::getAccessibleChildCount()
+ throw (::com::sun::star::uno::RuntimeException, std::exception)
+{
+ osl::MutexGuard aGuard( maMutex );
+
+ sal_Int32 nChildCount( 0 );
+
+ if ( mpAccessibleTextHelper )
+ {
+ nChildCount = mpAccessibleTextHelper->GetChildCount();
+ }
+
+ return nChildCount;
+}
+
+css::uno::Reference< css::accessibility::XAccessible > SAL_CALL SidebarTxtControlAccessibleContext::getAccessibleChild( sal_Int32 i )
+ throw ( css::lang::IndexOutOfBoundsException, css::uno::RuntimeException, std::exception )
+{
+ osl::MutexGuard aGuard( maMutex );
+
+ css::uno::Reference< css::accessibility::XAccessible > xChild;
+
+ if ( mpAccessibleTextHelper )
+ {
+ xChild = mpAccessibleTextHelper->GetChild( i );
+ }
+
+ return xChild;
+}
+
+void SAL_CALL SidebarTxtControlAccessibleContext::addAccessibleEventListener (
+ const css::uno::Reference< css::accessibility::XAccessibleEventListener >& xListener)
+ throw (css::uno::RuntimeException, std::exception)
+{
+ osl::MutexGuard aGuard( maMutex );
+
+ if ( mpAccessibleTextHelper )
+ {
+ mpAccessibleTextHelper->AddEventListener(xListener);
+ }
+}
+
+void SAL_CALL SidebarTxtControlAccessibleContext::removeAccessibleEventListener (
+ const css::uno::Reference< css::accessibility::XAccessibleEventListener >& xListener)
+ throw (css::uno::RuntimeException, std::exception)
+{
+ osl::MutexGuard aGuard( maMutex );
+
+ if ( mpAccessibleTextHelper )
+ {
+ mpAccessibleTextHelper->RemoveEventListener(xListener);
+ }
+}
+
+void SidebarTxtControlAccessibleContext::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
+{
+ if ( mpAccessibleTextHelper )
+ {
+ switch ( rVclWindowEvent.GetId() )
+ {
+ case VCLEVENT_OBJECT_DYING:
+ {
+ defunc();
+ }
+ break;
+ case VCLEVENT_WINDOW_GETFOCUS:
+ case VCLEVENT_CONTROL_GETFOCUS:
+ {
+ mpAccessibleTextHelper->SetFocus( true );
+ }
+ break;
+ case VCLEVENT_WINDOW_LOSEFOCUS:
+ case VCLEVENT_CONTROL_LOSEFOCUS:
+ {
+ mpAccessibleTextHelper->SetFocus( false );
+ }
+ break;
+ }
+ }
+
+ VCLXAccessibleComponent::ProcessWindowEvent( rVclWindowEvent );
+}
+
+// implementaion of accessible for <SidebarTxtControl> instance
+SidebarTxtControlAccessible::SidebarTxtControlAccessible( SidebarTxtControl& rSidebarTxtControl )
+ : VCLXWindow()
+ , mrSidebarTxtControl( rSidebarTxtControl )
+{
+ SetWindow( &mrSidebarTxtControl );
+}
+
+SidebarTxtControlAccessible::~SidebarTxtControlAccessible()
+{
+}
+
+css::uno::Reference< css::accessibility::XAccessibleContext > SidebarTxtControlAccessible::CreateAccessibleContext()
+{
+ SidebarTxtControlAccessibleContext* pAccContext(
+ new SidebarTxtControlAccessibleContext( mrSidebarTxtControl ) );
+ css::uno::Reference< css::accessibility::XAccessibleContext > xAcc( pAccContext );
+ return xAcc;
+}
+
+} } // end of namespace sw::sidebarwindows
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/docvw/SidebarTxtControlAcc.hxx b/sw/source/uibase/docvw/SidebarTxtControlAcc.hxx
new file mode 100644
index 000000000000..7ac25969e787
--- /dev/null
+++ b/sw/source/uibase/docvw/SidebarTxtControlAcc.hxx
@@ -0,0 +1,46 @@
+/* -*- 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 .
+ */
+
+#ifndef INCLUDED_SW_SOURCE_CORE_UIBASE_DOCVW_SIDEBARTXTCONTROLACC_HXX
+#define INCLUDED_SW_SOURCE_CORE_UIBASE_DOCVW_SIDEBARTXTCONTROLACC_HXX
+
+#include <toolkit/awt/vclxwindow.hxx>
+
+namespace sw { namespace sidebarwindows {
+
+class SidebarTxtControl;
+
+class SidebarTxtControlAccessible : public VCLXWindow
+{
+ public:
+ explicit SidebarTxtControlAccessible( SidebarTxtControl& rSidebarTxtControl );
+ virtual ~SidebarTxtControlAccessible();
+
+ virtual com::sun::star::uno::Reference< com::sun::star::accessibility::XAccessibleContext >
+ CreateAccessibleContext() SAL_OVERRIDE;
+
+ private:
+ SidebarTxtControl& mrSidebarTxtControl;
+};
+
+} } // end of namespace sw::sidebarwindows
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/docvw/SidebarWin.cxx b/sw/source/uibase/docvw/SidebarWin.cxx
new file mode 100644
index 000000000000..34aaa23243c7
--- /dev/null
+++ b/sw/source/uibase/docvw/SidebarWin.cxx
@@ -0,0 +1,1420 @@
+/* -*- 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 <sal/config.h>
+
+#include <cstdlib>
+
+#include <SidebarWin.hxx>
+#include <SidebarWinAcc.hxx>
+#include <PostItMgr.hxx>
+
+#include <SidebarTxtControl.hxx>
+#include <AnchorOverlayObject.hxx>
+#include <ShadowOverlayObject.hxx>
+#include <OverlayRanges.hxx>
+
+#include <annotation.hrc>
+#include <popup.hrc>
+#include <docvw.hrc>
+#include <app.hrc>
+#include <access.hrc>
+
+#include <viewopt.hxx>
+#include <cmdid.h>
+
+#include <editeng/fontitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/editview.hxx>
+#include <editeng/outliner.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/eeitem.hxx>
+
+#include <svl/zforlist.hxx>
+#include <svl/undo.hxx>
+#include <svl/stritem.hxx>
+
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/dispatch.hxx>
+
+#include <vcl/scrbar.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/menubtn.hxx>
+#include <vcl/settings.hxx>
+
+#include <edtwin.hxx>
+#include <view.hxx>
+#include <docsh.hxx>
+#include <wrtsh.hxx>
+#include <doc.hxx>
+#include <swmodule.hxx>
+#include <langhelper.hxx>
+
+#include <txtannotationfld.hxx>
+#include <ndtxt.hxx>
+
+#include <sw_primitivetypes2d.hxx>
+#include <drawinglayer/processor2d/baseprocessor2d.hxx>
+#include <drawinglayer/primitive2d/primitivetools2d.hxx>
+#include <drawinglayer/primitive2d/fillgradientprimitive2d.hxx>
+#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
+#include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
+#include <drawinglayer/processor2d/processorfromoutputdevice.hxx>
+#include <drawinglayer/primitive2d/shadowprimitive2d.hxx>
+
+namespace sw { namespace sidebarwindows {
+
+#define METABUTTON_WIDTH 16
+#define METABUTTON_HEIGHT 18
+#define METABUTTON_AREA_WIDTH 30
+#define POSTIT_META_HEIGHT (sal_Int32) 30
+#define POSTIT_MINIMUMSIZE_WITHOUT_META 50
+
+SwSidebarWin::SwSidebarWin( SwEditWin& rEditWin,
+ WinBits nBits,
+ SwPostItMgr& aMgr,
+ SwPostItBits aBits,
+ SwSidebarItem& rSidebarItem )
+ : Window(&rEditWin, nBits)
+ , mrMgr(aMgr)
+ , mrView( rEditWin.GetView() )
+ , nFlags(aBits)
+ , mnEventId(0)
+ , mpOutlinerView(0)
+ , mpOutliner(0)
+ , mpSidebarTxtControl(0)
+ , mpVScrollbar(0)
+ , mpMetadataAuthor(0)
+ , mpMetadataDate(0)
+ , mpMenuButton(0)
+ , mpAnchor( NULL )
+ , mpShadow( NULL )
+ , mpTextRangeOverlay( NULL )
+ , mColorAnchor()
+ , mColorDark()
+ , mColorLight()
+ , mChangeColor()
+ , meSidebarPosition( sw::sidebarwindows::SIDEBAR_NONE )
+ , mPosSize()
+ , mAnchorRect()
+ , mPageBorder( 0 )
+ , mbMouseOver( false )
+ , mLayoutStatus( SwPostItHelper::INVISIBLE )
+ , mbReadonly( false )
+ , mbIsFollow( false )
+ , mrSidebarItem( rSidebarItem )
+ , mpAnchorFrm( rSidebarItem.maLayoutInfo.mpAnchorFrm )
+{
+ mpShadow = ShadowOverlayObject::CreateShadowOverlayObject( mrView );
+ if ( mpShadow )
+ {
+ mpShadow->setVisible(false);
+ }
+
+ mrMgr.ConnectSidebarWinToFrm( *(mrSidebarItem.maLayoutInfo.mpAnchorFrm),
+ mrSidebarItem.GetFmtFld(),
+ *this );
+}
+
+SwSidebarWin::~SwSidebarWin()
+{
+ mrMgr.DisconnectSidebarWinFromFrm( *(mrSidebarItem.maLayoutInfo.mpAnchorFrm),
+ *this );
+
+ Disable();
+
+ if ( mpSidebarTxtControl )
+ {
+ if ( mpOutlinerView )
+ {
+ mpOutlinerView->SetWindow( 0 );
+ }
+ delete mpSidebarTxtControl;
+ mpSidebarTxtControl = 0;
+ }
+
+ if ( mpOutlinerView )
+ {
+ delete mpOutlinerView;
+ mpOutlinerView = 0;
+ }
+
+ if (mpOutliner)
+ {
+ delete mpOutliner;
+ mpOutliner = 0;
+ }
+
+ if (mpMetadataAuthor)
+ {
+ mpMetadataAuthor->RemoveEventListener( LINK( this, SwSidebarWin, WindowEventListener ) );
+ delete mpMetadataAuthor;
+ mpMetadataAuthor = 0;
+ }
+
+ if (mpMetadataDate)
+ {
+ mpMetadataDate->RemoveEventListener( LINK( this, SwSidebarWin, WindowEventListener ) );
+ delete mpMetadataDate;
+ mpMetadataDate = 0;
+ }
+
+ if (mpVScrollbar)
+ {
+ mpVScrollbar->RemoveEventListener( LINK( this, SwSidebarWin, WindowEventListener ) );
+ delete mpVScrollbar;
+ mpVScrollbar = 0;
+ }
+
+ AnchorOverlayObject::DestroyAnchorOverlayObject( mpAnchor );
+ mpAnchor = NULL;
+
+ ShadowOverlayObject::DestroyShadowOverlayObject( mpShadow );
+ mpShadow = NULL;
+
+ delete mpTextRangeOverlay;
+ mpTextRangeOverlay = NULL;
+
+ delete mpMenuButton;
+ mpMenuButton = 0;
+
+ if (mnEventId)
+ Application::RemoveUserEvent( mnEventId );
+}
+
+void SwSidebarWin::Paint( const Rectangle& rRect)
+{
+ Window::Paint(rRect);
+
+ if (mpMetadataAuthor->IsVisible() )
+ {
+ //draw left over space
+ if ( Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
+ {
+ SetFillColor(COL_BLACK);
+ }
+ else
+ {
+ SetFillColor(mColorDark);
+ }
+ SetLineColor();
+ DrawRect( PixelToLogic(
+ Rectangle( Point( mpMetadataAuthor->GetPosPixel().X() +
+ mpMetadataAuthor->GetSizePixel().Width(),
+ mpMetadataAuthor->GetPosPixel().Y() ),
+ Size( GetMetaButtonAreaWidth(),
+ mpMetadataAuthor->GetSizePixel().Height() +
+ mpMetadataDate->GetSizePixel().Height() ) ) ) );
+ }
+}
+
+void SwSidebarWin::Draw(OutputDevice* pDev, const Point& rPt, const Size& rSz, sal_uLong nInFlags)
+{
+ if (mpMetadataAuthor->IsVisible() )
+ {
+ pDev->SetFillColor(mColorDark);
+ pDev->SetLineColor();
+ pDev->DrawRect( Rectangle( rPt, rSz ) );
+ }
+
+ if (mpMetadataAuthor->IsVisible())
+ {
+ Font aOrigFont(mpMetadataAuthor->GetControlFont());
+ Size aSize(PixelToLogic(mpMetadataAuthor->GetSizePixel()));
+ Point aPos(PixelToLogic(mpMetadataAuthor->GetPosPixel()));
+ aPos += rPt;
+ Font aFont( mpMetadataAuthor->GetSettings().GetStyleSettings().GetFieldFont() );
+ mpMetadataAuthor->SetControlFont( aFont );
+ mpMetadataAuthor->Draw(pDev, aPos, aSize, nInFlags);
+ mpMetadataAuthor->SetControlFont( aOrigFont );
+ }
+
+ if (mpMetadataDate->IsVisible())
+ {
+ Font aOrigFont(mpMetadataDate->GetControlFont());
+ Size aSize(PixelToLogic(mpMetadataDate->GetSizePixel()));
+ Point aPos(PixelToLogic(mpMetadataDate->GetPosPixel()));
+ aPos += rPt;
+ Font aFont( mpMetadataDate->GetSettings().GetStyleSettings().GetFieldFont() );
+ mpMetadataDate->SetControlFont( aFont );
+ mpMetadataDate->Draw(pDev, aPos, aSize, nInFlags);
+ mpMetadataDate->SetControlFont( aOrigFont );
+ }
+
+ mpSidebarTxtControl->Draw(pDev, rPt, rSz, nInFlags);
+
+ const drawinglayer::geometry::ViewInformation2D aNewViewInfos;
+ drawinglayer::processor2d::BaseProcessor2D * pProcessor =
+ drawinglayer::processor2d::createBaseProcessor2DFromOutputDevice(
+ *pDev, aNewViewInfos );
+
+ if (mpAnchor)
+ pProcessor->process(mpAnchor->getOverlayObjectPrimitive2DSequence());
+ if (mpTextRangeOverlay)
+ pProcessor->process(mpTextRangeOverlay->getOverlayObjectPrimitive2DSequence());
+ delete pProcessor;
+
+ if (mpVScrollbar->IsVisible())
+ {
+ Font aOrigFont(mpMetadataDate->GetControlFont());
+ Color aOrigBg( mpMetadataDate->GetControlBackground() );
+ OUString sOrigText(mpMetadataDate->GetText());
+
+ Size aSize(PixelToLogic(mpMenuButton->GetSizePixel()));
+ Point aPos(PixelToLogic(mpMenuButton->GetPosPixel()));
+ aPos += rPt;
+
+ Font aFont( mpMetadataDate->GetSettings().GetStyleSettings().GetFieldFont() );
+ mpMetadataDate->SetControlFont( aFont );
+ mpMetadataDate->SetControlBackground( 0xFFFFFF );
+ mpMetadataDate->SetText("...");
+ mpMetadataDate->Draw(pDev, aPos, aSize, nInFlags);
+
+ mpMetadataDate->SetText(sOrigText);
+ mpMetadataDate->SetControlFont( aOrigFont );
+ mpMetadataDate->SetControlBackground( aOrigBg );
+ }
+}
+
+void SwSidebarWin::SetPosSizePixelRect( long nX,
+ long nY,
+ long nWidth,
+ long nHeight,
+ const SwRect& aAnchorRect,
+ const long aPageBorder)
+{
+ mPosSize = Rectangle(Point(nX,nY),Size(nWidth,nHeight));
+ mAnchorRect = aAnchorRect;
+ mPageBorder = aPageBorder;
+}
+
+void SwSidebarWin::SetSize( const Size& rNewSize )
+{
+ mPosSize.SetSize(rNewSize);
+}
+
+void SwSidebarWin::SetVirtualPosSize( const Point& aPoint, const Size& aSize)
+{
+ mPosSize = Rectangle(aPoint,aSize);
+}
+
+void SwSidebarWin::TranslateTopPosition(const long aAmount)
+{
+ mPosSize.Move(0,aAmount);
+}
+
+void SwSidebarWin::ShowAnchorOnly(const Point &aPoint)
+{
+ HideNote();
+ SetPosAndSize();
+ if (mpAnchor)
+ {
+ mpAnchor->SetSixthPosition(basegfx::B2DPoint(aPoint.X(),aPoint.Y()));
+ mpAnchor->SetSeventhPosition(basegfx::B2DPoint(aPoint.X(),aPoint.Y()));
+ mpAnchor->SetAnchorState(AS_ALL);
+ mpAnchor->setVisible(true);
+ }
+ if (mpShadow)
+ mpShadow->setVisible(false);
+}
+
+SfxItemSet SwSidebarWin::DefaultItem()
+{
+ SfxItemSet aItem( mrView.GetDocShell()->GetPool() );
+ aItem.Put(SvxFontHeightItem(200,100,EE_CHAR_FONTHEIGHT));
+ return aItem;
+}
+
+void SwSidebarWin::InitControls()
+{
+ AddEventListener( LINK( this, SwSidebarWin, WindowEventListener ) );
+
+ // actual window which holds the user text
+ mpSidebarTxtControl = new SidebarTxtControl( *this,
+ WB_NODIALOGCONTROL,
+ mrView, mrMgr );
+ mpSidebarTxtControl->SetPointer(Pointer(POINTER_TEXT));
+
+ // window controls for author and date
+ mpMetadataAuthor = new Edit( this, 0 );
+ mpMetadataAuthor->SetAccessibleName( SW_RES( STR_ACCESS_ANNOTATION_AUTHOR_NAME ) );
+ mpMetadataAuthor->EnableRTL(Application::GetSettings().GetLayoutRTL());
+ mpMetadataAuthor->SetReadOnly();
+ mpMetadataAuthor->AlwaysDisableInput(true);
+ mpMetadataAuthor->SetCallHandlersOnInputDisabled(true);
+ mpMetadataAuthor->AddEventListener( LINK( this, SwSidebarWin, WindowEventListener ) );
+ // we should leave this setting alone, but for this we need a better layout algo
+ // with variable meta size height
+ {
+ AllSettings aSettings = mpMetadataAuthor->GetSettings();
+ StyleSettings aStyleSettings = aSettings.GetStyleSettings();
+ Font aFont = aStyleSettings.GetFieldFont();
+ aFont.SetHeight(8);
+ aStyleSettings.SetFieldFont(aFont);
+ aSettings.SetStyleSettings(aStyleSettings);
+ mpMetadataAuthor->SetSettings(aSettings);
+ }
+
+ mpMetadataDate = new Edit( this, 0 );
+ mpMetadataDate->SetAccessibleName( SW_RES( STR_ACCESS_ANNOTATION_DATE_NAME ) );
+ mpMetadataDate->EnableRTL(Application::GetSettings().GetLayoutRTL());
+ mpMetadataDate->SetReadOnly();
+ mpMetadataDate->AlwaysDisableInput(true);
+ mpMetadataDate->SetCallHandlersOnInputDisabled(true);
+ mpMetadataDate->AddEventListener( LINK( this, SwSidebarWin, WindowEventListener ) );
+ // we should leave this setting alone, but for this we need a better layout algo
+ // with variable meta size height
+ {
+ AllSettings aSettings = mpMetadataDate->GetSettings();
+ StyleSettings aStyleSettings = aSettings.GetStyleSettings();
+ Font aFont = aStyleSettings.GetFieldFont();
+ aFont.SetHeight(8);
+ aStyleSettings.SetFieldFont(aFont);
+ aSettings.SetStyleSettings(aStyleSettings);
+ mpMetadataDate->SetSettings(aSettings);
+ }
+
+ SwDocShell* aShell = mrView.GetDocShell();
+ mpOutliner = new Outliner(&aShell->GetPool(),OUTLINERMODE_TEXTOBJECT);
+ aShell->GetDoc()->SetCalcFieldValueHdl( mpOutliner );
+ mpOutliner->SetUpdateMode( true );
+ Rescale();
+
+ mpSidebarTxtControl->EnableRTL( false );
+ mpOutlinerView = new OutlinerView ( mpOutliner, mpSidebarTxtControl );
+ mpOutlinerView->SetBackgroundColor(COL_TRANSPARENT);
+ mpOutliner->InsertView(mpOutlinerView );
+ mpOutlinerView->SetOutputArea( PixelToLogic( Rectangle(0,0,1,1) ) );
+
+ mpOutlinerView->SetAttribs(DefaultItem());
+
+ //create Scrollbars
+ mpVScrollbar = new ScrollBar(this, WB_3DLOOK |WB_VSCROLL|WB_DRAG);
+ mpVScrollbar->EnableNativeWidget(false);
+ mpVScrollbar->EnableRTL( false );
+ mpVScrollbar->SetScrollHdl(LINK(this, SwSidebarWin, ScrollHdl));
+ mpVScrollbar->EnableDrag();
+ mpVScrollbar->AddEventListener( LINK( this, SwSidebarWin, WindowEventListener ) );
+
+ const SwViewOption* pVOpt = mrView.GetWrtShellPtr()->GetViewOptions();
+ sal_uLong nCntrl = mpOutliner->GetControlWord();
+ // TODO: crash when AUTOCOMPLETE enabled
+ nCntrl |= EE_CNTRL_MARKFIELDS | EE_CNTRL_PASTESPECIAL | EE_CNTRL_AUTOCORRECT | EV_CNTRL_AUTOSCROLL | EE_CNTRL_URLSFXEXECUTE; // | EE_CNTRL_AUTOCOMPLETE;
+ if (pVOpt->IsFieldShadings())
+ nCntrl |= EE_CNTRL_MARKFIELDS;
+ else
+ nCntrl &= ~EE_CNTRL_MARKFIELDS;
+ if (pVOpt->IsOnlineSpell())
+ nCntrl |= EE_CNTRL_ONLINESPELLING;
+ else
+ nCntrl &= ~EE_CNTRL_ONLINESPELLING;
+ mpOutliner->SetControlWord(nCntrl);
+
+ sal_uInt16 aIndex = SW_MOD()->InsertRedlineAuthor(GetAuthor());
+ SetColor( mrMgr.GetColorDark(aIndex),
+ mrMgr.GetColorLight(aIndex),
+ mrMgr.GetColorAnchor(aIndex));
+
+ CheckMetaText();
+
+ mpMenuButton = CreateMenuButton();
+
+ SetLanguage(GetLanguage());
+ GetOutlinerView()->StartSpeller();
+ SetPostItText();
+ Engine()->CompleteOnlineSpelling();
+
+ mpSidebarTxtControl->Show();
+ mpMetadataAuthor->Show();
+ mpMetadataDate->Show();
+ mpVScrollbar->Show();
+}
+
+void SwSidebarWin::CheckMetaText()
+{
+ const SvtSysLocale aSysLocale;
+ const LocaleDataWrapper& rLocalData = aSysLocale.GetLocaleData();
+ OUString sMeta = GetAuthor();
+ if (sMeta.isEmpty())
+ {
+ sMeta = SW_RESSTR(STR_NOAUTHOR);
+ }
+ else if (sMeta.getLength() > 23)
+ {
+ sMeta = sMeta.copy(0, 20) + "...";
+ }
+ if ( mpMetadataAuthor->GetText() != sMeta )
+ {
+ mpMetadataAuthor->SetText(sMeta);
+ }
+
+ Date aSysDate( Date::SYSTEM );
+ Date aDate = GetDate();
+ if (aDate==aSysDate)
+ {
+ sMeta = SW_RESSTR(STR_POSTIT_TODAY);
+ }
+ else if (aDate == Date(aSysDate-1))
+ {
+ sMeta = SW_RESSTR(STR_POSTIT_YESTERDAY);
+ }
+ else if (aDate.IsValidAndGregorian() )
+ {
+ sMeta = rLocalData.getDate(aDate);
+ }
+ else
+ {
+ sMeta = SW_RESSTR(STR_NODATE);
+ }
+ if (GetTime()!=0)
+ {
+ sMeta += " " + rLocalData.getTime( GetTime(),false );
+ }
+ if ( mpMetadataDate->GetText() != sMeta )
+ {
+ mpMetadataDate->SetText(sMeta);
+ }
+}
+
+void SwSidebarWin::Rescale()
+{
+ MapMode aMode = GetParent()->GetMapMode();
+ aMode.SetOrigin( Point() );
+ mpOutliner->SetRefMapMode( aMode );
+ SetMapMode( aMode );
+ mpSidebarTxtControl->SetMapMode( aMode );
+ if ( mpMetadataAuthor )
+ {
+ Font aFont( mpMetadataAuthor->GetSettings().GetStyleSettings().GetFieldFont() );
+ sal_Int32 nHeight = aFont.GetHeight();
+ nHeight = nHeight * aMode.GetScaleY().GetNumerator() / aMode.GetScaleY().GetDenominator();
+ aFont.SetHeight( nHeight );
+ mpMetadataAuthor->SetControlFont( aFont );
+ }
+ if ( mpMetadataDate )
+ {
+ Font aFont( mpMetadataDate->GetSettings().GetStyleSettings().GetFieldFont() );
+ sal_Int32 nHeight = aFont.GetHeight();
+ nHeight = nHeight * aMode.GetScaleY().GetNumerator() / aMode.GetScaleY().GetDenominator();
+ aFont.SetHeight( nHeight );
+ mpMetadataDate->SetControlFont( aFont );
+ }
+}
+
+void SwSidebarWin::SetPosAndSize()
+{
+ bool bChange = false;
+
+ if (GetSizePixel() != mPosSize.GetSize())
+ {
+ bChange = true;
+ SetSizePixel(mPosSize.GetSize());
+ DoResize();
+ }
+
+ if (GetPosPixel().X() != mPosSize.TopLeft().X() || (std::abs(GetPosPixel().Y() - mPosSize.TopLeft().Y()) > 5) )
+ {
+ bChange = true;
+ SetPosPixel(mPosSize.TopLeft());
+
+ Point aLineStart;
+ Point aLineEnd ;
+ switch ( meSidebarPosition )
+ {
+ case sw::sidebarwindows::SIDEBAR_LEFT:
+ {
+ aLineStart = EditWin()->PixelToLogic( Point(GetPosPixel().X()+GetSizePixel().Width(),GetPosPixel().Y()-1) );
+ aLineEnd = EditWin()->PixelToLogic( Point(GetPosPixel().X(),GetPosPixel().Y()-1) );
+ }
+ break;
+ case sw::sidebarwindows::SIDEBAR_RIGHT:
+ {
+ aLineStart = EditWin()->PixelToLogic( Point(GetPosPixel().X(),GetPosPixel().Y()-1) );
+ aLineEnd = EditWin()->PixelToLogic( Point(GetPosPixel().X()+GetSizePixel().Width(),GetPosPixel().Y()-1) );
+ }
+ break;
+ default:
+ OSL_FAIL( "<SwSidebarWin::SetPosAndSize()> - unexpected position of sidebar" );
+ break;
+ }
+
+ if (!IsPreview())
+ {
+ if (mpAnchor)
+ {
+ mpAnchor->SetAllPosition( basegfx::B2DPoint( mAnchorRect.Left() , mAnchorRect.Bottom() - 5* 15),
+ basegfx::B2DPoint( mAnchorRect.Left()-5*15 , mAnchorRect.Bottom()+5*15),
+ basegfx::B2DPoint( mAnchorRect.Left()+5*15 , mAnchorRect.Bottom()+5*15),
+ basegfx::B2DPoint( mAnchorRect.Left(), mAnchorRect.Bottom()+2*15),
+ basegfx::B2DPoint( mPageBorder ,mAnchorRect.Bottom()+2*15),
+ basegfx::B2DPoint( aLineStart.X(),aLineStart.Y()),
+ basegfx::B2DPoint( aLineEnd.X(),aLineEnd.Y()));
+ mpAnchor->SetHeight(mAnchorRect.Height());
+ }
+ else
+ {
+ mpAnchor = AnchorOverlayObject::CreateAnchorOverlayObject( mrView,
+ mAnchorRect,
+ mPageBorder,
+ aLineStart,
+ aLineEnd,
+ mColorAnchor );
+ if ( mpAnchor )
+ {
+ mpAnchor->SetHeight(mAnchorRect.Height());
+ mpAnchor->setVisible(true);
+ mpAnchor->SetAnchorState(AS_TRI);
+ if (HasChildPathFocus())
+ {
+ mpAnchor->setLineSolid(true);
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ if ( mpAnchor &&
+ ( mpAnchor->getBasePosition() != basegfx::B2DPoint( mAnchorRect.Left() , mAnchorRect.Bottom()-5*15) ) )
+ {
+ mpAnchor->SetTriPosition( basegfx::B2DPoint( mAnchorRect.Left() , mAnchorRect.Bottom() - 5* 15),
+ basegfx::B2DPoint( mAnchorRect.Left()-5*15 , mAnchorRect.Bottom()+5*15),
+ basegfx::B2DPoint( mAnchorRect.Left()+5*15 , mAnchorRect.Bottom()+5*15),
+ basegfx::B2DPoint( mAnchorRect.Left(), mAnchorRect.Bottom()+2*15),
+ basegfx::B2DPoint( mPageBorder , mAnchorRect.Bottom()+2*15));
+ }
+ }
+
+ if (bChange)
+ {
+ Point aStart = EditWin()->PixelToLogic(GetPosPixel()+Point(0,GetSizePixel().Height()));
+ Point aEnd = EditWin()->PixelToLogic(GetPosPixel()+Point(GetSizePixel().Width()-1,GetSizePixel().Height()));
+ mpShadow->SetPosition(basegfx::B2DPoint(aStart.X(),aStart.Y()), basegfx::B2DPoint(aEnd.X(),aEnd.Y()));
+ }
+
+ if (mrMgr.ShowNotes())
+ {
+ if (IsFollow() && !HasChildPathFocus())
+ {
+ // #i111964#
+ if ( mpAnchor )
+ {
+ mpAnchor->SetAnchorState(AS_END);
+ }
+ }
+ else
+ {
+ // #i111964#
+ if ( mpAnchor )
+ {
+ mpAnchor->SetAnchorState(AS_ALL);
+ }
+ SwSidebarWin* pWin = GetTopReplyNote();
+ // #i111964#
+ if ( pWin && pWin->Anchor() )
+ {
+ pWin->Anchor()->SetAnchorState(AS_END);
+ }
+ }
+ }
+
+ // text range overlay
+ if ( mrMgr.ShowNotes()
+ && mrSidebarItem.maLayoutInfo.mnStartNodeIdx != 0
+ && mrSidebarItem.maLayoutInfo.mnStartContent != -1 )
+ {
+ std::vector< basegfx::B2DRange > aAnnotationTextRanges;
+ {
+ const SwTxtAnnotationFld* pTxtAnnotationFld =
+ dynamic_cast< const SwTxtAnnotationFld* >( mrSidebarItem.GetFmtFld().GetTxtFld() );
+ if ( pTxtAnnotationFld != NULL
+ && pTxtAnnotationFld->GetpTxtNode() != NULL )
+ {
+ SwTxtNode* pTxtNode = pTxtAnnotationFld->GetpTxtNode();
+ SwNodes& rNds = pTxtNode->GetDoc()->GetNodes();
+ SwCntntNode* const pCntntNd = rNds[mrSidebarItem.maLayoutInfo.mnStartNodeIdx]->GetCntntNode();
+ SwPosition aStartPos( *pCntntNd, mrSidebarItem.maLayoutInfo.mnStartContent );
+ SwShellCrsr* pTmpCrsr = NULL;
+ const bool bTableCrsrNeeded = pTxtNode->FindTableBoxStartNode() != pCntntNd->FindTableBoxStartNode();
+ if ( bTableCrsrNeeded )
+ {
+ SwShellTableCrsr* pTableCrsr = new SwShellTableCrsr( DocView().GetWrtShell(), aStartPos );
+ pTableCrsr->SetMark();
+ pTableCrsr->GetMark()->nNode = *pTxtNode;
+ pTableCrsr->GetMark()->nContent.Assign( pTxtNode, *(pTxtAnnotationFld->GetStart())+1 );
+ pTableCrsr->NewTableSelection();
+ pTmpCrsr = pTableCrsr;
+ }
+ else
+ {
+ SwShellCrsr* pCrsr = new SwShellCrsr( DocView().GetWrtShell(), aStartPos );
+ pCrsr->SetMark();
+ pCrsr->GetMark()->nNode = *pTxtNode;
+ pCrsr->GetMark()->nContent.Assign( pTxtNode, *(pTxtAnnotationFld->GetStart())+1 );
+ pTmpCrsr = pCrsr;
+ }
+ ::boost::scoped_ptr<SwShellCrsr> pTmpCrsrForAnnotationTextRange( pTmpCrsr );
+
+ pTmpCrsrForAnnotationTextRange->FillRects();
+
+ for( sal_uInt16 a(0); a < pTmpCrsrForAnnotationTextRange->size(); ++a )
+ {
+ const SwRect aNextRect((*pTmpCrsrForAnnotationTextRange)[a]);
+ const Rectangle aPntRect(aNextRect.SVRect());
+
+ aAnnotationTextRanges.push_back(basegfx::B2DRange(
+ aPntRect.Left(), aPntRect.Top(),
+ aPntRect.Right() + 1, aPntRect.Bottom() + 1));
+ }
+ }
+ }
+
+ if ( mpTextRangeOverlay != NULL )
+ {
+ mpTextRangeOverlay->setRanges( aAnnotationTextRanges );
+ if ( mpAnchor != NULL && mpAnchor->getLineSolid() )
+ {
+ mpTextRangeOverlay->ShowSolidBorder();
+ }
+ else
+ {
+ mpTextRangeOverlay->HideSolidBorder();
+ }
+ }
+ else
+ {
+ mpTextRangeOverlay =
+ sw::overlay::OverlayRanges::CreateOverlayRange(
+ DocView(),
+ mColorAnchor,
+ aAnnotationTextRanges,
+ mpAnchor && mpAnchor->getLineSolid() );
+ }
+ }
+ else
+ {
+ delete mpTextRangeOverlay;
+ mpTextRangeOverlay = NULL;
+ }
+}
+
+void SwSidebarWin::DoResize()
+{
+ long aTextHeight = LogicToPixel( mpOutliner->CalcTextSize()).Height();
+ long aHeight = GetSizePixel().Height();
+ unsigned long aWidth = GetSizePixel().Width();
+
+ aHeight -= GetMetaHeight();
+ mpMetadataAuthor->Show();
+ mpMetadataDate->Show();
+ mpSidebarTxtControl->SetQuickHelpText(OUString());
+
+ if ((aTextHeight > aHeight) && !IsPreview())
+ { // we need vertical scrollbars and have to reduce the width
+ aWidth -= GetScrollbarWidth();
+ mpVScrollbar->Show();
+ }
+ else
+ {
+ mpVScrollbar->Hide();
+ }
+
+ {
+ const Size aSizeOfMetadataControls( GetSizePixel().Width() - GetMetaButtonAreaWidth(),
+ GetMetaHeight()/2 );
+ mpMetadataAuthor->setPosSizePixel( 0,
+ aHeight,
+ aSizeOfMetadataControls.Width(),
+ aSizeOfMetadataControls.Height() );
+ mpMetadataDate->setPosSizePixel( 0,
+ aHeight + aSizeOfMetadataControls.Height(),
+ aSizeOfMetadataControls.Width(),
+ aSizeOfMetadataControls.Height() );
+ }
+
+ mpOutliner->SetPaperSize( PixelToLogic( Size(aWidth,aHeight) ) ) ;
+ if (!mpVScrollbar->IsVisible())
+ { // if we do not have a scrollbar anymore, we want to see the complete text
+ mpOutlinerView->SetVisArea( PixelToLogic( Rectangle(0,0,aWidth,aHeight) ) );
+ }
+ mpOutlinerView->SetOutputArea( PixelToLogic( Rectangle(0,0,aWidth,aHeight) ) );
+
+ if (!Application::GetSettings().GetLayoutRTL())
+ {
+ mpSidebarTxtControl->setPosSizePixel(0, 0, aWidth, aHeight);
+ mpVScrollbar->setPosSizePixel( aWidth, 0, GetScrollbarWidth(), aHeight);
+ }
+ else
+ {
+ mpSidebarTxtControl->setPosSizePixel( ( (aTextHeight > aHeight) && !IsPreview()
+ ? GetScrollbarWidth() : 0 ) , 0,
+ aWidth, aHeight);
+ mpVScrollbar->setPosSizePixel( 0, 0, GetScrollbarWidth(), aHeight);
+ }
+
+ mpVScrollbar->SetVisibleSize( PixelToLogic(Size(0,aHeight)).Height() );
+ mpVScrollbar->SetPageSize( PixelToLogic(Size(0,aHeight)).Height() * 8 / 10 );
+ mpVScrollbar->SetLineSize( mpOutliner->GetTextHeight() / 10 );
+ SetScrollbar();
+ mpVScrollbar->SetRange( Range(0, mpOutliner->GetTextHeight()));
+
+ //calculate rects for meta- button
+ const Fraction& fx( GetMapMode().GetScaleX() );
+ const Fraction& fy( GetMapMode().GetScaleY() );
+
+ const Point aPos( mpMetadataAuthor->GetPosPixel());
+ Rectangle aRectMetaButton;
+ if (IsPreview())
+ {
+ aRectMetaButton = PixelToLogic(
+ Rectangle( Point( aPos.X()+GetSizePixel().Width()-(METABUTTON_WIDTH*4+10)*fx.GetNumerator()/fx.GetDenominator(),
+ aPos.Y()+5*fy.GetNumerator()/fy.GetDenominator() ),
+ Size( METABUTTON_WIDTH*4*fx.GetNumerator()/fx.GetDenominator(),
+ METABUTTON_HEIGHT*fy.GetNumerator()/fy.GetDenominator() ) ) );
+ }
+ else
+ {
+ aRectMetaButton = PixelToLogic(
+ Rectangle( Point( aPos.X()+GetSizePixel().Width()-(METABUTTON_WIDTH+10)*fx.GetNumerator()/fx.GetDenominator(),
+ aPos.Y()+5*fy.GetNumerator()/fy.GetDenominator() ),
+ Size( METABUTTON_WIDTH*fx.GetNumerator()/fx.GetDenominator(),
+ METABUTTON_HEIGHT*fy.GetNumerator()/fy.GetDenominator() ) ) );
+ }
+
+ {
+ const Rectangle aRectMetaButtonPixel( LogicToPixel( aRectMetaButton ) );
+ mpMenuButton->setPosSizePixel( aRectMetaButtonPixel.Left(),
+ aRectMetaButtonPixel.Top(),
+ aRectMetaButtonPixel.GetWidth(),
+ aRectMetaButtonPixel.GetHeight() );
+ }
+}
+
+void SwSidebarWin::SetSizePixel( const Size& rNewSize )
+{
+ Window::SetSizePixel(rNewSize);
+
+ if (mpShadow)
+ {
+ Point aStart = EditWin()->PixelToLogic(GetPosPixel()+Point(0,GetSizePixel().Height()));
+ Point aEnd = EditWin()->PixelToLogic(GetPosPixel()+Point(GetSizePixel().Width()-1,GetSizePixel().Height()));
+ mpShadow->SetPosition(basegfx::B2DPoint(aStart.X(),aStart.Y()), basegfx::B2DPoint(aEnd.X(),aEnd.Y()));
+ }
+}
+
+void SwSidebarWin::SetScrollbar()
+{
+ mpVScrollbar->SetThumbPos(mpOutlinerView->GetVisArea().Top());
+}
+
+void SwSidebarWin::ResizeIfNecessary(long aOldHeight, long aNewHeight)
+{
+ if (aOldHeight != aNewHeight)
+ {
+ //check for lower border or next note
+ long aBorder = mrMgr.GetNextBorder();
+ if (aBorder != -1)
+ {
+ if (aNewHeight > GetMinimumSizeWithoutMeta())
+ {
+ long aNewLowerValue = GetPosPixel().Y() + aNewHeight + GetMetaHeight();
+ if (aNewLowerValue < aBorder)
+ SetSizePixel(Size(GetSizePixel().Width(),aNewHeight+GetMetaHeight()));
+ else
+ SetSizePixel(Size(GetSizePixel().Width(),aBorder - GetPosPixel().Y()));
+ DoResize();
+ Invalidate();
+ }
+ else
+ {
+ if (GetSizePixel().Height() != GetMinimumSizeWithoutMeta() + GetMetaHeight())
+ SetSizePixel(Size(GetSizePixel().Width(),GetMinimumSizeWithoutMeta() + GetMetaHeight()));
+ DoResize();
+ Invalidate();
+ }
+ }
+ else
+ {
+ DoResize();
+ Invalidate();
+ }
+ }
+ else
+ {
+ SetScrollbar();
+ }
+}
+
+void SwSidebarWin::SetColor(Color aColorDark,Color aColorLight, Color aColorAnchor)
+{
+ mColorDark = aColorDark;
+ mColorLight = aColorLight;
+ mColorAnchor = aColorAnchor;
+
+ if ( !Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
+ {
+ {
+ mpMetadataAuthor->SetControlBackground(mColorDark);
+ AllSettings aSettings = mpMetadataAuthor->GetSettings();
+ StyleSettings aStyleSettings = aSettings.GetStyleSettings();
+ aStyleSettings.SetFieldTextColor(aColorAnchor);
+ aSettings.SetStyleSettings(aStyleSettings);
+ mpMetadataAuthor->SetSettings(aSettings);
+ }
+
+ {
+ mpMetadataDate->SetControlBackground(mColorDark);
+ AllSettings aSettings = mpMetadataDate->GetSettings();
+ StyleSettings aStyleSettings = aSettings.GetStyleSettings();
+ aStyleSettings.SetFieldTextColor(aColorAnchor);
+ aSettings.SetStyleSettings(aStyleSettings);
+ mpMetadataDate->SetSettings(aSettings);
+ }
+
+ AllSettings aSettings2 = mpVScrollbar->GetSettings();
+ StyleSettings aStyleSettings2 = aSettings2.GetStyleSettings();
+ aStyleSettings2.SetButtonTextColor(Color(0,0,0));
+ aStyleSettings2.SetCheckedColor(mColorLight); // backgound
+ aStyleSettings2.SetShadowColor(mColorAnchor);
+ aStyleSettings2.SetFaceColor(mColorDark);
+ aSettings2.SetStyleSettings(aStyleSettings2);
+ mpVScrollbar->SetSettings(aSettings2);
+ }
+}
+
+void SwSidebarWin::SetSidebarPosition(sw::sidebarwindows::SidebarPosition eSidebarPosition)
+{
+ meSidebarPosition = eSidebarPosition;
+}
+
+void SwSidebarWin::SetReadonly(bool bSet)
+{
+ mbReadonly = bSet;
+ GetOutlinerView()->SetReadOnly(bSet);
+}
+
+void SwSidebarWin::SetLanguage(const SvxLanguageItem aNewItem)
+{
+ Link pLink = Engine()->GetModifyHdl();
+ Engine()->SetModifyHdl( Link() );
+ ESelection aOld = GetOutlinerView()->GetSelection();
+
+ ESelection aNewSelection( 0, 0, Engine()->GetParagraphCount()-1, EE_TEXTPOS_ALL );
+ GetOutlinerView()->SetSelection( aNewSelection );
+ SfxItemSet aEditAttr(GetOutlinerView()->GetAttribs());
+ aEditAttr.Put(aNewItem);
+ GetOutlinerView()->SetAttribs( aEditAttr );
+
+ GetOutlinerView()->SetSelection(aOld);
+ Engine()->SetModifyHdl( pLink );
+
+ const SwViewOption* pVOpt = mrView.GetWrtShellPtr()->GetViewOptions();
+ sal_uLong nCntrl = Engine()->GetControlWord();
+ // turn off
+ nCntrl &= ~EE_CNTRL_ONLINESPELLING;
+ Engine()->SetControlWord(nCntrl);
+
+ //turn back on
+ if (pVOpt->IsOnlineSpell())
+ nCntrl |= EE_CNTRL_ONLINESPELLING;
+ else
+ nCntrl &= ~EE_CNTRL_ONLINESPELLING;
+ Engine()->SetControlWord(nCntrl);
+
+ Engine()->CompleteOnlineSpelling();
+ Invalidate();
+}
+
+void SwSidebarWin::DataChanged( const DataChangedEvent& aEvent)
+{
+ Window::DataChanged( aEvent );
+}
+
+void SwSidebarWin::GetFocus()
+{
+ if (mpSidebarTxtControl)
+ mpSidebarTxtControl->GrabFocus();
+}
+
+void SwSidebarWin::LoseFocus()
+{
+}
+
+void SwSidebarWin::ShowNote()
+{
+ SetPosAndSize();
+ if (!IsVisible())
+ Window::Show();
+ if (mpShadow && !mpShadow->isVisible())
+ mpShadow->setVisible(true);
+ if (mpAnchor && !mpAnchor->isVisible())
+ mpAnchor->setVisible(true);
+}
+
+void SwSidebarWin::HideNote()
+{
+ if (IsVisible())
+ Window::Hide();
+ if (mpAnchor)
+ {
+ if (mrMgr.IsShowAnchor())
+ mpAnchor->SetAnchorState(AS_TRI);
+ else
+ mpAnchor->setVisible(false);
+ }
+ if (mpShadow && mpShadow->isVisible())
+ mpShadow->setVisible(false);
+}
+
+void SwSidebarWin::ActivatePostIt()
+{
+ mrMgr.AssureStdModeAtShell();
+
+ mpOutliner->ClearModifyFlag();
+ mpOutliner->GetUndoManager().Clear();
+
+ CheckMetaText();
+ SetViewState(VS_EDIT);
+ GetOutlinerView()->ShowCursor();
+
+ mpOutlinerView->GetEditView().SetInsertMode(mrView.GetWrtShellPtr()->IsInsMode());
+
+ if ( !Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
+ GetOutlinerView()->SetBackgroundColor(mColorDark);
+}
+
+void SwSidebarWin::DeactivatePostIt()
+{
+ // remove selection, #i87073#
+ if (GetOutlinerView()->GetEditView().HasSelection())
+ {
+ ESelection aSelection = GetOutlinerView()->GetEditView().GetSelection();
+ aSelection.nEndPara = aSelection.nStartPara;
+ aSelection.nEndPos = aSelection.nStartPos;
+ GetOutlinerView()->GetEditView().SetSelection(aSelection);
+ }
+
+ mpOutliner->CompleteOnlineSpelling();
+
+ SetViewState(VS_NORMAL);
+ // write the visible text back into the SwField
+ UpdateData();
+
+ if ( !Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
+ GetOutlinerView()->SetBackgroundColor(COL_TRANSPARENT);
+
+ if ( !IsProtected() && Engine()->GetEditEngine().GetText().isEmpty() )
+ {
+ mnEventId = Application::PostUserEvent( LINK( this, SwSidebarWin, DeleteHdl), 0 );
+ }
+}
+
+void SwSidebarWin::ToggleInsMode()
+{
+ if (!mrView.GetWrtShell().IsRedlineOn())
+ {
+ //change outliner
+ mpOutlinerView->GetEditView().SetInsertMode(!mpOutlinerView->GetEditView().IsInsertMode());
+ //change document
+ mrView.GetWrtShell().ToggleInsMode();
+ //update statusbar
+ SfxBindings &rBnd = mrView.GetViewFrame()->GetBindings();
+ rBnd.Invalidate(SID_ATTR_INSERT);
+ rBnd.Update(SID_ATTR_INSERT);
+ }
+}
+
+void SwSidebarWin::ExecuteCommand(sal_uInt16 nSlot)
+{
+ mrMgr.AssureStdModeAtShell();
+
+ switch (nSlot)
+ {
+ case FN_POSTIT:
+ case FN_REPLY:
+ {
+ // if this note is empty, it will be deleted once losing the focus, so no reply, but only a new note
+ // will be created
+ if (!Engine()->GetEditEngine().GetText().isEmpty())
+ {
+ OutlinerParaObject* pPara = new OutlinerParaObject(*GetOutlinerView()->GetEditView().CreateTextObject());
+ mrMgr.RegisterAnswer(pPara);
+ }
+ if (mrMgr.HasActiveSidebarWin())
+ mrMgr.SetActiveSidebarWin(0);
+ SwitchToFieldPos();
+ mrView.GetViewFrame()->GetDispatcher()->Execute(FN_POSTIT);
+ break;
+ }
+ case FN_DELETE_COMMENT:
+
+ //Delete(); // do not kill the parent of our open popup menu
+ mnEventId = Application::PostUserEvent( LINK( this, SwSidebarWin, DeleteHdl), 0 );
+ break;
+ case FN_FORMAT_ALL_NOTES:
+ case FN_DELETE_ALL_NOTES:
+ case FN_HIDE_ALL_NOTES:
+ // not possible as slot as this would require that "this" is the active postit
+ mrView.GetViewFrame()->GetBindings().Execute( nSlot, 0, 0, SFX_CALLMODE_ASYNCHRON );
+ break;
+ case FN_DELETE_NOTE_AUTHOR:
+ case FN_HIDE_NOTE_AUTHOR:
+ {
+ // not possible as slot as this would require that "this" is the active postit
+ SfxStringItem aItem( nSlot, GetAuthor() );
+ const SfxPoolItem* aItems[2];
+ aItems[0] = &aItem;
+ aItems[1] = 0;
+ mrView.GetViewFrame()->GetBindings().Execute( nSlot, aItems, 0, SFX_CALLMODE_ASYNCHRON );
+ }
+ break;
+ default:
+ mrView.GetViewFrame()->GetBindings().Execute( nSlot );
+ break;
+ }
+}
+
+SwEditWin* SwSidebarWin::EditWin()
+{
+ return &mrView.GetEditWin();
+}
+
+long SwSidebarWin::GetPostItTextHeight()
+{
+ return mpOutliner ? LogicToPixel(mpOutliner->CalcTextSize()).Height() : 0;
+}
+
+void SwSidebarWin::SwitchToPostIt(sal_uInt16 aDirection)
+{
+ SwSidebarWin* pPostIt = mrMgr.GetNextPostIt(aDirection, this);
+ if (pPostIt)
+ pPostIt->GrabFocus();
+}
+
+IMPL_LINK( SwSidebarWin, WindowEventListener, VclSimpleEvent*, pEvent )
+{
+ VclWindowEvent* pWinEvent = dynamic_cast<VclWindowEvent*>(pEvent);
+ if ( pWinEvent )
+ {
+ if ( pWinEvent->GetId() == VCLEVENT_WINDOW_MOUSEMOVE )
+ {
+ MouseEvent* pMouseEvt = (MouseEvent*)pWinEvent->GetData();
+ if ( pMouseEvt->IsEnterWindow() )
+ {
+ mbMouseOver = true;
+ if ( !HasFocus() )
+ {
+ SetViewState(VS_VIEW);
+ Invalidate();
+ }
+ }
+ else if ( pMouseEvt->IsLeaveWindow())
+ {
+ if (!IsPreview())
+ {
+ mbMouseOver = false;
+ if ( !HasFocus() )
+ {
+ SetViewState(VS_NORMAL);
+ Invalidate();
+ }
+ }
+ }
+ }
+ else if ( pWinEvent->GetId() == VCLEVENT_WINDOW_ACTIVATE &&
+ pWinEvent->GetWindow() == mpSidebarTxtControl )
+ {
+ const bool bLockView = mrView.GetWrtShell().IsViewLocked();
+ mrView.GetWrtShell().LockView( true );
+
+ if ( !IsPreview() )
+ {
+ mrMgr.SetActiveSidebarWin( this );
+ }
+
+ mrView.GetWrtShell().LockView( bLockView );
+ mrMgr.MakeVisible( this );
+ }
+ }
+ return sal_True;
+}
+
+void SwSidebarWin::Delete()
+{
+ if ( mrMgr.GetActiveSidebarWin() == this)
+ {
+ mrMgr.SetActiveSidebarWin(0);
+ // if the note is empty, the previous line will send a delete event, but we are already there
+ if (mnEventId)
+ {
+ Application::RemoveUserEvent( mnEventId );
+ mnEventId = 0;
+ }
+ }
+}
+
+IMPL_LINK(SwSidebarWin, ScrollHdl, ScrollBar*, pScroll)
+{
+ long nDiff = GetOutlinerView()->GetEditView().GetVisArea().Top() - pScroll->GetThumbPos();
+ GetOutlinerView()->Scroll( 0, nDiff );
+ return 0;
+}
+
+IMPL_LINK_NOARG(SwSidebarWin, ModifyHdl)
+{
+ mrView.GetDocShell()->SetModified(true);
+ return 0;
+}
+
+IMPL_LINK_NOARG(SwSidebarWin, DeleteHdl)
+{
+ mnEventId = 0;
+ Delete();
+ return 0;
+}
+
+void SwSidebarWin::ResetAttributes()
+{
+ mpOutlinerView->RemoveAttribsKeepLanguages(true);
+ mpOutliner->RemoveFields(true);
+ mpOutlinerView->SetAttribs(DefaultItem());
+}
+
+sal_Int32 SwSidebarWin::GetScrollbarWidth()
+{
+ return mrView.GetWrtShell().GetViewOptions()->GetZoom() / 10;
+}
+
+sal_Int32 SwSidebarWin::GetMetaButtonAreaWidth()
+{
+ const Fraction& f( GetMapMode().GetScaleX() );
+ if (IsPreview())
+ return 3 * METABUTTON_AREA_WIDTH * f.GetNumerator() / f.GetDenominator();
+ else
+ return METABUTTON_AREA_WIDTH * f.GetNumerator() / f.GetDenominator();
+}
+
+sal_Int32 SwSidebarWin::GetMetaHeight()
+{
+ const Fraction& f( GetMapMode().GetScaleY() );
+ return POSTIT_META_HEIGHT * f.GetNumerator() / f.GetDenominator();
+}
+
+sal_Int32 SwSidebarWin::GetMinimumSizeWithMeta()
+{
+ return mrMgr.GetMinimumSizeWithMeta();
+}
+
+sal_Int32 SwSidebarWin::GetMinimumSizeWithoutMeta()
+{
+ const Fraction& f( GetMapMode().GetScaleY() );
+ return POSTIT_MINIMUMSIZE_WITHOUT_META * f.GetNumerator() / f.GetDenominator();
+}
+
+void SwSidebarWin::SetSpellChecking()
+{
+ const SwViewOption* pVOpt = mrView.GetWrtShellPtr()->GetViewOptions();
+ sal_uLong nCntrl = mpOutliner->GetControlWord();
+ if (pVOpt->IsOnlineSpell())
+ nCntrl |= EE_CNTRL_ONLINESPELLING;
+ else
+ nCntrl &= ~EE_CNTRL_ONLINESPELLING;
+ mpOutliner->SetControlWord(nCntrl);
+
+ mpOutliner->CompleteOnlineSpelling();
+ Invalidate();
+}
+
+void SwSidebarWin::SetViewState(ViewState bViewState)
+{
+ switch (bViewState)
+ {
+ case VS_EDIT:
+ {
+ if (mpAnchor)
+ {
+ mpAnchor->SetAnchorState(AS_ALL);
+ SwSidebarWin* pWin = GetTopReplyNote();
+ // #i111964#
+ if ( pWin && pWin->Anchor() )
+ {
+ pWin->Anchor()->SetAnchorState(AS_END);
+ }
+ mpAnchor->setLineSolid(true);
+ if ( mpTextRangeOverlay != NULL )
+ {
+ mpTextRangeOverlay->ShowSolidBorder();
+ }
+ }
+ if (mpShadow)
+ mpShadow->SetShadowState(SS_EDIT);
+ break;
+ }
+ case VS_VIEW:
+ {
+ if (mpAnchor)
+ {
+ mpAnchor->setLineSolid(true);
+ if ( mpTextRangeOverlay != NULL )
+ {
+ mpTextRangeOverlay->ShowSolidBorder();
+ }
+ }
+ if (mpShadow)
+ mpShadow->SetShadowState(SS_VIEW);
+ break;
+ }
+ case VS_NORMAL:
+ {
+ if (mpAnchor)
+ {
+ if (IsFollow())
+ {
+ // if there is no visible parent note, we want to see the complete anchor ??
+ //if (IsAnyStackParentVisible())
+ mpAnchor->SetAnchorState(AS_END);
+ SwSidebarWin* pTopWinSelf = GetTopReplyNote();
+ SwSidebarWin* pTopWinActive = mrMgr.HasActiveSidebarWin()
+ ? mrMgr.GetActiveSidebarWin()->GetTopReplyNote()
+ : 0;
+ // #i111964#
+ if ( pTopWinSelf && ( pTopWinSelf != pTopWinActive ) &&
+ pTopWinSelf->Anchor() )
+ {
+ if ( pTopWinSelf != mrMgr.GetActiveSidebarWin() )
+ {
+ pTopWinSelf->Anchor()->setLineSolid(false);
+ if ( pTopWinSelf->TextRange() != NULL )
+ {
+ pTopWinSelf->TextRange()->HideSolidBorder();
+ }
+ }
+ pTopWinSelf->Anchor()->SetAnchorState(AS_ALL);
+ }
+ }
+ mpAnchor->setLineSolid(false);
+ if ( mpTextRangeOverlay != NULL )
+ {
+ mpTextRangeOverlay->HideSolidBorder();
+ }
+ }
+ if ( mpShadow )
+ {
+ mpShadow->SetShadowState(SS_NORMAL);
+ }
+ break;
+ }
+ }
+}
+
+SwSidebarWin* SwSidebarWin::GetTopReplyNote()
+{
+ SwSidebarWin* pTopNote = 0;
+ SwSidebarWin* pSidebarWin = IsFollow() ? mrMgr.GetNextPostIt(KEY_PAGEUP, this) : 0;
+ while (pSidebarWin)
+ {
+ pTopNote = pSidebarWin;
+ pSidebarWin = pSidebarWin->IsFollow() ? mrMgr.GetNextPostIt(KEY_PAGEUP, pSidebarWin) : 0;
+ }
+ return pTopNote;
+}
+
+void SwSidebarWin::SwitchToFieldPos()
+{
+ if ( mrMgr.GetActiveSidebarWin() == this )
+ mrMgr.SetActiveSidebarWin(0);
+ GotoPos();
+ sal_uInt32 aCount = MoveCaret();
+ if (aCount)
+ mrView.GetDocShell()->GetWrtShell()->SwCrsrShell::Right(aCount, 0, false);
+ GrabFocusToDocument();
+}
+
+SvxLanguageItem SwSidebarWin::GetLanguage(void)
+{
+ return SvxLanguageItem(SwLangHelper::GetLanguage(mrView.GetWrtShell(),RES_CHRATR_LANGUAGE),RES_CHRATR_LANGUAGE);
+}
+
+void SwSidebarWin::SetChangeTracking( const SwPostItHelper::SwLayoutStatus aLayoutStatus,
+ const Color& aChangeColor )
+{
+ if ( (mLayoutStatus != aLayoutStatus) ||
+ (mChangeColor != aChangeColor) )
+ {
+ mLayoutStatus = aLayoutStatus;
+ mChangeColor = aChangeColor;
+ Invalidate();
+ }
+}
+
+bool SwSidebarWin::HasScrollbar() const
+{
+ return mpVScrollbar != 0;
+}
+
+bool SwSidebarWin::IsScrollbarVisible() const
+{
+ return HasScrollbar() && mpVScrollbar->IsVisible();
+}
+
+void SwSidebarWin::ChangeSidebarItem( SwSidebarItem& rSidebarItem )
+{
+ const bool bAnchorChanged = mpAnchorFrm != rSidebarItem.maLayoutInfo.mpAnchorFrm;
+ if ( bAnchorChanged )
+ {
+ mrMgr.DisconnectSidebarWinFromFrm( *(mpAnchorFrm), *this );
+ }
+
+ mrSidebarItem = rSidebarItem;
+ mpAnchorFrm = mrSidebarItem.maLayoutInfo.mpAnchorFrm;
+
+ if ( GetWindowPeer() )
+ {
+ SidebarWinAccessible* pAcc =
+ static_cast<SidebarWinAccessible*>( GetWindowPeer() );
+ OSL_ENSURE( dynamic_cast<SidebarWinAccessible*>( GetWindowPeer() ),
+ "<SwSidebarWin::ChangeSidebarItem(..)> - unexpected type of window peer -> crash possible!" );
+ pAcc->ChangeSidebarItem( mrSidebarItem );
+ }
+
+ if ( bAnchorChanged )
+ {
+ mrMgr.ConnectSidebarWinToFrm( *(mrSidebarItem.maLayoutInfo.mpAnchorFrm),
+ mrSidebarItem.GetFmtFld(),
+ *this );
+ }
+}
+
+css::uno::Reference< css::accessibility::XAccessible > SwSidebarWin::CreateAccessible()
+{
+ SidebarWinAccessible* pAcc( new SidebarWinAccessible( *this,
+ mrView.GetWrtShell(),
+ mrSidebarItem ) );
+ 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;
+}
+
+} } // eof of namespace sw::sidebarwindows
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/docvw/SidebarWinAcc.cxx b/sw/source/uibase/docvw/SidebarWinAcc.cxx
new file mode 100644
index 000000000000..57850b9b3af6
--- /dev/null
+++ b/sw/source/uibase/docvw/SidebarWinAcc.cxx
@@ -0,0 +1,143 @@
+/* -*- 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 <SidebarWinAcc.hxx>
+
+#include <SidebarWin.hxx>
+#include <viewsh.hxx>
+#include <accmap.hxx>
+#include <toolkit/awt/vclxaccessiblecomponent.hxx>
+
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+
+namespace sw { namespace sidebarwindows {
+
+// declaration and implementation of accessible context for <SidebarWinAccessible> instance
+class SidebarWinAccessibleContext : public VCLXAccessibleComponent
+{
+ public:
+ explicit SidebarWinAccessibleContext( SwSidebarWin& rSidebarWin,
+ SwViewShell& rViewShell,
+ const SwFrm* pAnchorFrm )
+ : VCLXAccessibleComponent( rSidebarWin.GetWindowPeer() )
+ , mrViewShell( rViewShell )
+ , mpAnchorFrm( pAnchorFrm )
+ , maMutex()
+ {
+ rSidebarWin.SetAccessibleRole( css::accessibility::AccessibleRole::COMMENT );
+ }
+
+ virtual ~SidebarWinAccessibleContext()
+ {}
+
+ void ChangeAnchor( const SwFrm* pAnchorFrm )
+ {
+ osl::MutexGuard aGuard(maMutex);
+
+ mpAnchorFrm = pAnchorFrm;
+ }
+
+ virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL
+ getAccessibleParent() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
+ {
+ osl::MutexGuard aGuard(maMutex);
+
+ css::uno::Reference< css::accessibility::XAccessible > xAccParent;
+
+ if ( mpAnchorFrm &&
+ mrViewShell.GetAccessibleMap() )
+ {
+ xAccParent = mrViewShell.GetAccessibleMap()->GetContext( mpAnchorFrm, false );
+ }
+
+ return xAccParent;
+ }
+
+ virtual sal_Int32 SAL_CALL getAccessibleIndexInParent() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
+ {
+ osl::MutexGuard aGuard(maMutex);
+
+ sal_Int32 nIndex( -1 );
+
+ if ( mpAnchorFrm && GetWindow() &&
+ mrViewShell.GetAccessibleMap() )
+ {
+ nIndex = mrViewShell.GetAccessibleMap()->GetChildIndex( *mpAnchorFrm,
+ *GetWindow() );
+ }
+
+ return nIndex;
+ }
+
+ private:
+ SwViewShell& mrViewShell;
+ const SwFrm* mpAnchorFrm;
+
+ ::osl::Mutex maMutex;
+};
+
+// implementaion of accessible for <SwSidebarWin> instance
+SidebarWinAccessible::SidebarWinAccessible( SwSidebarWin& rSidebarWin,
+ SwViewShell& rViewShell,
+ const SwSidebarItem& rSidebarItem )
+ : VCLXWindow()
+ , mrSidebarWin( rSidebarWin )
+ , mrViewShell( rViewShell )
+ , mpAnchorFrm( rSidebarItem.maLayoutInfo.mpAnchorFrm )
+ , bAccContextCreated( false )
+{
+ SetWindow( &mrSidebarWin );
+}
+
+SidebarWinAccessible::~SidebarWinAccessible()
+{
+}
+
+void SidebarWinAccessible::ChangeSidebarItem( const SwSidebarItem& rSidebarItem )
+{
+ if ( bAccContextCreated )
+ {
+ css::uno::Reference< css::accessibility::XAccessibleContext > xAcc
+ = getAccessibleContext();
+ if ( xAcc.is() )
+ {
+ SidebarWinAccessibleContext* pAccContext =
+ dynamic_cast<SidebarWinAccessibleContext*>(xAcc.get());
+ if ( pAccContext )
+ {
+ pAccContext->ChangeAnchor( rSidebarItem.maLayoutInfo.mpAnchorFrm );
+ }
+ }
+ }
+}
+
+css::uno::Reference< css::accessibility::XAccessibleContext > SidebarWinAccessible::CreateAccessibleContext()
+{
+ SidebarWinAccessibleContext* pAccContext =
+ new SidebarWinAccessibleContext( mrSidebarWin,
+ mrViewShell,
+ mpAnchorFrm );
+ css::uno::Reference< css::accessibility::XAccessibleContext > xAcc( pAccContext );
+ bAccContextCreated = true;
+ return xAcc;
+}
+
+} } // end of namespace sw::sidebarwindows
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/docvw/SidebarWinAcc.hxx b/sw/source/uibase/docvw/SidebarWinAcc.hxx
new file mode 100644
index 000000000000..9d4dc49436b4
--- /dev/null
+++ b/sw/source/uibase/docvw/SidebarWinAcc.hxx
@@ -0,0 +1,57 @@
+/* -*- 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 .
+ */
+
+#ifndef INCLUDED_SW_SOURCE_CORE_UIBASE_DOCVW_SIDEBARWINACC_HXX
+#define INCLUDED_SW_SOURCE_CORE_UIBASE_DOCVW_SIDEBARWINACC_HXX
+
+#include <toolkit/awt/vclxwindow.hxx>
+
+class SwViewShell;
+class SwSidebarItem;
+class SwFrm;
+
+namespace sw { namespace sidebarwindows {
+
+class SwSidebarWin;
+
+class SidebarWinAccessible : public VCLXWindow
+{
+ public:
+ explicit SidebarWinAccessible( SwSidebarWin& rSidebarWin,
+ SwViewShell& rViewShell,
+ const SwSidebarItem& rSidebarItem );
+ virtual ~SidebarWinAccessible();
+
+ virtual com::sun::star::uno::Reference< com::sun::star::accessibility::XAccessibleContext >
+ CreateAccessibleContext() SAL_OVERRIDE;
+
+ void ChangeSidebarItem( const SwSidebarItem& rSidebarItem );
+
+ private:
+ SwSidebarWin& mrSidebarWin;
+ SwViewShell& mrViewShell;
+ const SwFrm* mpAnchorFrm;
+ bool bAccContextCreated;
+};
+
+} } // end of namespace sw::sidebarwindows
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/docvw/annotation.hrc b/sw/source/uibase/docvw/annotation.hrc
new file mode 100644
index 000000000000..e94aa557b29b
--- /dev/null
+++ b/sw/source/uibase/docvw/annotation.hrc
@@ -0,0 +1,44 @@
+/* -*- 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 .
+ */
+
+#ifndef _ANNOTATION_HRC
+#define _ANNOTATION_HRC
+
+#include "rcid.hrc"
+
+#define STR_POSTIT_TODAY (RC_ANNOTATION_BEGIN + 1)
+#define STR_POSTIT_YESTERDAY (RC_ANNOTATION_BEGIN + 2)
+
+#define STR_DELETE_ALL_NOTES (RC_ANNOTATION_BEGIN + 3)
+#define STR_DELETE_AUTHOR_NOTES (RC_ANNOTATION_BEGIN + 4)
+
+#define STR_NODATE (RC_ANNOTATION_BEGIN + 5)
+#define STR_NOAUTHOR (RC_ANNOTATION_BEGIN + 6)
+
+#define STR_REPLY (RC_ANNOTATION_BEGIN + 7)
+#define STR_FORMAT_ALL_NOTES (RC_ANNOTATION_BEGIN + 8)
+
+#define ANNOTATION_ACT_END STR_REPLY
+#if ANNOTATION_ACT_END > RC_ANNOTATION_END
+#error Resource-Id Ueberlauf in #file, #line
+#endif
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/docvw/docvw.hrc b/sw/source/uibase/docvw/docvw.hrc
new file mode 100644
index 000000000000..3347b1862639
--- /dev/null
+++ b/sw/source/uibase/docvw/docvw.hrc
@@ -0,0 +1,89 @@
+/* -*- 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 .
+ */
+
+#ifndef _DOCVW_HRC
+#define _DOCVW_HRC
+
+#include "rcid.hrc"
+
+#define MN_READONLY_POPUP (RC_DOCVW_BEGIN + 1)
+#define MN_READONLY_OPENURL (RC_DOCVW_BEGIN + 2)
+#define MN_READONLY_OPENURLNEW (RC_DOCVW_BEGIN + 3)
+#define MN_READONLY_EDITDOC (RC_DOCVW_BEGIN + 4)
+// free (5)
+#define MN_READONLY_BROWSE_BACKWARD (RC_DOCVW_BEGIN + 6)
+#define MN_READONLY_BROWSE_FORWARD (RC_DOCVW_BEGIN + 7)
+#define MN_READONLY_SELECTION_MODE (RC_DOCVW_BEGIN + 8)
+#define MN_READONLY_SAVEGRAPHIC (RC_DOCVW_BEGIN + 11)
+#define MN_READONLY_SAVEBACKGROUND (RC_DOCVW_BEGIN + 12)
+#define MN_READONLY_COPYLINK (RC_DOCVW_BEGIN + 13)
+#define MN_READONLY_COPYGRAPHIC (RC_DOCVW_BEGIN + 14)
+#define MN_READONLY_LOADGRAPHIC (RC_DOCVW_BEGIN + 15)
+#define MN_READONLY_GRAPHICOFF (RC_DOCVW_BEGIN + 16)
+#define MN_READONLY_PLUGINOFF (RC_DOCVW_BEGIN + 17)
+#define MN_READONLY_TOGALLERYLINK (RC_DOCVW_BEGIN + 18)
+#define MN_READONLY_TOGALLERYCOPY (RC_DOCVW_BEGIN + 19)
+#define MN_READONLY_SOURCEVIEW (RC_DOCVW_BEGIN + 20)
+#define MN_READONLY_RELOAD_FRAME (RC_DOCVW_BEGIN + 21)
+#define MN_READONLY_RELOAD (RC_DOCVW_BEGIN + 22)
+#define MN_READONLY_COPY (RC_DOCVW_BEGIN + 23)
+
+//For the following we need space for the gallery-themes
+#define MN_READONLY_GRAPHICTOGALLERY (RC_DOCVW_BEGIN + 24)
+#define MN_READONLY_BACKGROUNDTOGALLERY (RC_DOCVW_BEGIN + 60)
+
+#define STR_CHAIN_OK (RC_DOCVW_BEGIN + 2)
+#define STR_CHAIN_NOT_EMPTY (RC_DOCVW_BEGIN + 3)
+#define STR_CHAIN_IS_IN_CHAIN (RC_DOCVW_BEGIN + 4)
+#define STR_CHAIN_WRONG_AREA (RC_DOCVW_BEGIN + 5)
+#define STR_CHAIN_NOT_FOUND (RC_DOCVW_BEGIN + 6)
+#define STR_CHAIN_SOURCE_CHAINED (RC_DOCVW_BEGIN + 7)
+#define STR_CHAIN_SELF (RC_DOCVW_BEGIN + 8)
+#define STR_REDLINE_INSERT (RC_DOCVW_BEGIN + 9)
+#define STR_REDLINE_DELETE (RC_DOCVW_BEGIN + 10)
+#define STR_REDLINE_FORMAT (RC_DOCVW_BEGIN + 11)
+#define STR_REDLINE_TABLE (RC_DOCVW_BEGIN + 12)
+#define STR_REDLINE_FMTCOLL (RC_DOCVW_BEGIN + 13)
+#define STR_ENDNOTE (RC_DOCVW_BEGIN + 14)
+#define STR_FTNNOTE (RC_DOCVW_BEGIN + 15)
+
+#define STR_TABLE_COL_ADJUST (RC_DOCVW_BEGIN + 16)
+#define STR_TABLE_ROW_ADJUST (RC_DOCVW_BEGIN + 17)
+#define STR_TABLE_SELECT_ALL (RC_DOCVW_BEGIN + 18)
+#define STR_TABLE_SELECT_ROW (RC_DOCVW_BEGIN + 19)
+#define STR_TABLE_SELECT_COL (RC_DOCVW_BEGIN + 20)
+
+#define STR_SMARTTAG_CLICK (RC_DOCVW_BEGIN + 21)
+
+#define STR_HEADER_TITLE (RC_DOCVW_BEGIN + 22)
+#define STR_FOOTER_TITLE (RC_DOCVW_BEGIN + 23)
+#define STR_DELETE_HEADER (RC_DOCVW_BEGIN + 24)
+#define STR_FORMAT_HEADER (RC_DOCVW_BEGIN + 25)
+#define STR_DELETE_FOOTER (RC_DOCVW_BEGIN + 26)
+#define STR_FORMAT_FOOTER (RC_DOCVW_BEGIN + 27)
+
+#define DOCVW_ACT_END STR_SMARTTAG_CLICK
+
+#if DOCVW_ACT_END > RC_DOCVW_END
+#error Resource-Id Ueberlauf in #file, #line
+#endif
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/docvw/docvw.src b/sw/source/uibase/docvw/docvw.src
new file mode 100644
index 000000000000..ff10f368a012
--- /dev/null
+++ b/sw/source/uibase/docvw/docvw.src
@@ -0,0 +1,307 @@
+/* -*- 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 "docvw.hrc"
+#include "cmdid.h"
+#include "helpid.h"
+#define SEPARATOR MenuItem { Separator = TRUE; };
+Menu MN_READONLY_POPUP
+{
+ ItemList =
+ {
+ MenuItem
+ {
+ Identifier = MN_READONLY_OPENURL ;
+ HelpId = CMD_SID_OPENDOC ;
+ Text [ en-US ] = "~Open" ;
+ };
+ MenuItem
+ {
+ Identifier = MN_READONLY_OPENURLNEW ;
+ HelpId = CMD_SID_OPENDOC ;
+ Text [ en-US ] = "Open in New Window" ;
+ };
+ MenuItem
+ {
+ Identifier = MN_READONLY_EDITDOC ;
+ HelpId = CMD_SID_EDITDOC ;
+ Text [ en-US ] = "~Edit" ;
+ };
+ MenuItem
+ {
+ Identifier = MN_READONLY_SELECTION_MODE ;
+ HelpId = CMD_FN_READONLY_SELECTION_MODE ;
+ Text [ en-US ] = "Select Text";
+ };
+ MenuItem
+ {
+ Identifier = MN_READONLY_RELOAD;
+ HelpId = CMD_SID_RELOAD;
+ Text [ en-US ] = "Re~load";
+ };
+ MenuItem
+ {
+ Identifier = MN_READONLY_RELOAD_FRAME;
+ HelpId = CMD_SID_RELOAD;
+ Text [ en-US ] = "Reload Frame";
+ };
+ MenuItem
+ {
+ Identifier = MN_READONLY_SOURCEVIEW ;
+ HelpId = HID_SOURCEVIEW ;
+ Text [ en-US ] = "HT~ML Source" ;
+ };
+ SEPARATOR
+ MenuItem
+ {
+ Identifier = MN_READONLY_BROWSE_BACKWARD ;
+ HelpId = CMD_SID_BROWSE_BACKWARD ;
+ Text [ en-US ] = "Backwards" ;
+ };
+ MenuItem
+ {
+ Identifier = MN_READONLY_BROWSE_FORWARD ;
+ HelpId = CMD_SID_BROWSE_FORWARD ;
+ Text [ en-US ] = "~Forward" ;
+ };
+ SEPARATOR
+ MenuItem
+ {
+ Identifier = MN_READONLY_SAVEGRAPHIC ;
+ HelpID = HID_MN_READONLY_SAVEGRAPHIC ;
+ Text [ en-US ] = "Save Image..." ;
+ };
+ MenuItem
+ {
+ Identifier = MN_READONLY_GRAPHICTOGALLERY ;
+ HelpID = HID_MN_READONLY_GRAPHICTOGALLERY ;
+ SubMenu = Menu
+ {
+ ItemList =
+ {
+ MenuItem
+ {
+ Identifier = MN_READONLY_TOGALLERYLINK ;
+ HelpID = HID_MN_READONLY_TOGALLERYLINK ;
+ Text [ en-US ] = "As Link" ;
+ };
+ MenuItem
+ {
+ Identifier = MN_READONLY_TOGALLERYCOPY ;
+ HelpID = HID_MN_READONLY_TOGALLERYCOPY ;
+ Text [ en-US ] = "Copy" ;
+ };
+ SEPARATOR
+ };
+ };
+ Text [ en-US ] = "Add Image" ;
+ };
+ MenuItem
+ {
+ Identifier = MN_READONLY_SAVEBACKGROUND ;
+ HelpID = HID_MN_READONLY_SAVEBACKGROUND ;
+ Text [ en-US ] = "Save Background..." ;
+ };
+ MenuItem
+ {
+ Identifier = MN_READONLY_BACKGROUNDTOGALLERY ;
+ HelpID = HID_MN_READONLY_BACKGROUNDTOGALLERY ;
+ SubMenu = Menu
+ {
+ ItemList =
+ {
+ MenuItem
+ {
+ Identifier = MN_READONLY_TOGALLERYLINK ;
+ HelpID = HID_MN_READONLY_TOGALLERYLINK ;
+ Text [ en-US ] = "As Link" ;
+ };
+ MenuItem
+ {
+ Identifier = MN_READONLY_TOGALLERYCOPY ;
+ HelpID = HID_MN_READONLY_TOGALLERYCOPY ;
+ Text [ en-US ] = "Copy" ;
+ };
+ SEPARATOR
+ };
+ };
+ Text [ en-US ] = "Add Background" ;
+ };
+ SEPARATOR
+ MenuItem
+ {
+ Identifier = MN_READONLY_COPYLINK ;
+ HelpID = HID_MN_READONLY_COPYLINK ;
+ Text [ en-US ] = "Copy ~Link" ;
+ };
+ MenuItem
+ {
+ Identifier = MN_READONLY_COPYGRAPHIC ;
+ HelpID = HID_MN_READONLY_COPYGRAPHIC ;
+ Text [ en-US ] = "Copy ~Image" ;
+ };
+ SEPARATOR
+ MenuItem
+ {
+ Identifier = MN_READONLY_LOADGRAPHIC ;
+ HelpID = HID_MN_READONLY_LOADGRAPHIC ;
+ Text [ en-US ] = "Load Image" ;
+ };
+ MenuItem
+ {
+ Identifier = MN_READONLY_GRAPHICOFF ;
+ HelpID = HID_MN_READONLY_GRAPHICOFF ;
+ Text [ en-US ] = "Image Off" ;
+ };
+ MenuItem
+ {
+ Identifier = MN_READONLY_PLUGINOFF ;
+ HelpID = HID_MN_READONLY_PLUGINOFF ;
+ Text [ en-US ] = "Plug-ins Off" ;
+ };
+ SEPARATOR
+ MenuItem
+ {
+ Identifier = SID_WIN_FULLSCREEN;
+ HelpId = CMD_SID_WIN_FULLSCREEN;
+ Text [ en-US ] = "Leave Full-Screen Mode" ;
+ };
+ SEPARATOR
+ MenuItem
+ {
+ Identifier = MN_READONLY_COPY ;
+ HelpId = CMD_SID_COPY;
+ Text [ en-US ] = "~Copy" ;
+ };
+ };
+};
+String STR_CHAIN_OK
+{
+ Text [ en-US ] = "Click the left mouse button to link the frames." ;
+};
+String STR_CHAIN_NOT_EMPTY
+{
+ Text [ en-US ] = "Target frame not empty." ;
+};
+String STR_CHAIN_IS_IN_CHAIN
+{
+ Text [ en-US ] = "Target frame is already linked." ;
+};
+String STR_CHAIN_WRONG_AREA
+{
+ Text [ en-US ] = "The target frame for the link is in an invalid area." ;
+};
+String STR_CHAIN_NOT_FOUND
+{
+ Text [ en-US ] = "Target frame not found at current position." ;
+};
+String STR_CHAIN_SOURCE_CHAINED
+{
+ Text [ en-US ] = "The source frame is already the source of a link." ;
+};
+String STR_CHAIN_SELF
+{
+ Text [ en-US ] = "A closed link is not possible." ;
+};
+String STR_REDLINE_INSERT
+{
+ Text [ en-US ] = "Inserted" ;
+};
+String STR_REDLINE_DELETE
+{
+ Text [ en-US ] = "Deleted" ;
+};
+String STR_REDLINE_FORMAT
+{
+ Text [ en-US ] = "Formatted" ;
+};
+String STR_REDLINE_TABLE
+{
+ Text [ en-US ] = "Table changed" ;
+};
+String STR_REDLINE_FMTCOLL
+{
+ Text [ en-US ] = "Applied Paragraph Styles";
+};
+String STR_ENDNOTE
+{
+ Text [ en-US ] = "Endnote: " ;
+};
+String STR_FTNNOTE
+{
+ Text [ en-US ] = "Footnote: " ;
+};
+
+String STR_TABLE_COL_ADJUST
+{
+ Text [ en-US ] = "Adjust table column" ;
+};
+String STR_TABLE_ROW_ADJUST
+{
+ Text [ en-US ] = "Adjust table row" ;
+};
+String STR_TABLE_SELECT_ALL
+{
+ Text [ en-US ] = "Select whole table" ;
+};
+String STR_TABLE_SELECT_ROW
+{
+ Text [ en-US ] = "Select table row" ;
+};
+String STR_TABLE_SELECT_COL
+{
+ Text [ en-US ] = "Select table column" ;
+};
+
+String STR_SMARTTAG_CLICK
+{
+ Text [ en-US ] = "%s-click to open Smart Tag menu" ;
+};
+
+String STR_HEADER_TITLE
+{
+ Text [ en-US ] = "Header (%1)" ;
+};
+
+String STR_FOOTER_TITLE
+{
+ Text [ en-US ] = "Footer (%1)" ;
+};
+
+String STR_DELETE_HEADER
+{
+ Text [ en-US ] = "Delete Header..." ;
+};
+
+String STR_FORMAT_HEADER
+{
+ Text [ en-US ] = "Format Header..." ;
+};
+
+String STR_DELETE_FOOTER
+{
+ Text [ en-US ] = "Delete Footer..." ;
+};
+
+String STR_FORMAT_FOOTER
+{
+ Text [ en-US ] = "Format Footer..." ;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/docvw/edtdd.cxx b/sw/source/uibase/docvw/edtdd.cxx
new file mode 100644
index 000000000000..c43fb80eb81e
--- /dev/null
+++ b/sw/source/uibase/docvw/edtdd.cxx
@@ -0,0 +1,495 @@
+/* -*- 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 <hintids.hxx>
+
+#include <svx/svdview.hxx>
+#include <editeng/outliner.hxx>
+#include <svx/svdobj.hxx>
+#include <sot/exchange.hxx>
+#include <sot/formats.hxx>
+#include <sfx2/bindings.hxx>
+
+#include <sfx2/viewfrm.hxx>
+#include <fmturl.hxx>
+#include <frmfmt.hxx>
+#include <wrtsh.hxx>
+#include <edtwin.hxx>
+#include <view.hxx>
+#include <viewopt.hxx>
+#include <swdtflvr.hxx>
+#include <swmodule.hxx>
+#include <docsh.hxx>
+#include <wdocsh.hxx>
+#include <swundo.hxx>
+
+using namespace ::com::sun::star;
+
+// no include "dbgoutsw.hxx" here!!!!!!
+
+extern bool bNoInterrupt;
+extern bool bFrmDrag;
+extern bool bDDTimerStarted;
+
+bool bExecuteDrag = false;
+
+void SwEditWin::StartDDTimer()
+{
+ m_aTimer.SetTimeoutHdl(LINK(this, SwEditWin, DDHandler));
+ m_aTimer.SetTimeout(480);
+ m_aTimer.Start();
+ bDDTimerStarted = true;
+}
+
+void SwEditWin::StopDDTimer(SwWrtShell *pSh, const Point &rPt)
+{
+ m_aTimer.Stop();
+ bDDTimerStarted = false;
+ if(!pSh->IsSelFrmMode())
+ pSh->SetCursor(&rPt, false);
+ m_aTimer.SetTimeoutHdl(LINK(this,SwEditWin, TimerHandler));
+}
+
+void SwEditWin::StartDrag( sal_Int8 /*nAction*/, const Point& rPosPixel )
+{
+ SwWrtShell &rSh = m_rView.GetWrtShell();
+ if( rSh.GetDrawView() )
+ {
+ CommandEvent aDragEvent( rPosPixel, COMMAND_STARTDRAG, true );
+ if( rSh.GetDrawView()->Command( aDragEvent, this ) )
+ {
+ m_rView.GetViewFrame()->GetBindings().InvalidateAll(false);
+ return; // Event evaluated by SdrView
+ }
+ }
+
+ if ( !m_pApplyTempl && !rSh.IsDrawCreate() && !IsDrawAction())
+ {
+ bool bStart = false, bDelSelect = false;
+ SdrObject *pObj = NULL;
+ Point aDocPos( PixelToLogic( rPosPixel ) );
+ if ( !rSh.IsInSelect() && rSh.ChgCurrPam( aDocPos, true, true))
+ //We are not selecting and aren't at a selection
+ bStart = true;
+ else if ( !bFrmDrag && rSh.IsSelFrmMode() &&
+ rSh.IsInsideSelectedObj( aDocPos ) )
+ {
+ //We are not dragging internally and are not at an
+ //object (frame, draw object)
+
+ bStart = true;
+ }
+ else if( !bFrmDrag && m_rView.GetDocShell()->IsReadOnly() &&
+ OBJCNT_NONE != rSh.GetObjCntType( aDocPos, pObj ))
+ {
+ rSh.LockPaint();
+ if( rSh.SelectObj( aDocPos, 0, pObj ))
+ bStart = bDelSelect = true;
+ else
+ rSh.UnlockPaint();
+ }
+ else
+ {
+ SwContentAtPos aSwContentAtPos( SwContentAtPos::SW_INETATTR );
+ bStart = rSh.GetContentAtPos( aDocPos,
+ aSwContentAtPos,
+ false );
+ }
+
+ if ( bStart && !m_bIsInDrag )
+ {
+ m_bMBPressed = false;
+ ReleaseMouse();
+ bFrmDrag = false;
+ bExecuteDrag = true;
+ SwEditWin::m_nDDStartPosY = aDocPos.Y();
+ SwEditWin::m_nDDStartPosX = aDocPos.X();
+ m_aMovePos = aDocPos;
+ StartExecuteDrag();
+ if( bDelSelect )
+ {
+ rSh.UnSelectFrm();
+ rSh.UnlockPaint();
+ }
+ }
+ }
+}
+
+void SwEditWin::StartExecuteDrag()
+{
+ if( !bExecuteDrag || m_bIsInDrag )
+ return;
+
+ m_bIsInDrag = true;
+
+ SwTransferable* pTransfer = new SwTransferable( m_rView.GetWrtShell() );
+ uno::Reference<
+ datatransfer::XTransferable > xRef( pTransfer );
+
+ pTransfer->StartDrag( this, m_aMovePos );
+}
+
+void SwEditWin::DragFinished()
+{
+ DropCleanup();
+ m_aTimer.SetTimeoutHdl( LINK(this,SwEditWin, TimerHandler) );
+ m_bIsInDrag = false;
+}
+
+void SwEditWin::DropCleanup()
+{
+ SwWrtShell &rSh = m_rView.GetWrtShell();
+
+ // reset statuses
+ bNoInterrupt = false;
+ if ( m_bOldIdleSet )
+ {
+ ((SwViewOption*)rSh.GetViewOptions())->SetIdle( m_bOldIdle );
+ m_bOldIdleSet = false;
+ }
+ if ( m_pUserMarker )
+ CleanupDropUserMarker();
+ else
+ rSh.UnSetVisCrsr();
+
+}
+
+void SwEditWin::CleanupDropUserMarker()
+{
+ if ( m_pUserMarker )
+ {
+ delete m_pUserMarker;
+ m_pUserMarker = 0;
+ m_pUserMarkerObj = 0;
+ }
+}
+
+//exhibition hack (MA,MBA)
+void SwView::SelectShellForDrop()
+{
+ if ( !GetCurShell() )
+ SelectShell();
+}
+
+sal_Int8 SwEditWin::ExecuteDrop( const ExecuteDropEvent& rEvt )
+{
+ GetView().SelectShellForDrop();
+ DropCleanup();
+ sal_Int8 nRet = DND_ACTION_NONE;
+
+ //A Drop to an open OutlinerView doesn't concern us (also see QueryDrop)
+ SwWrtShell &rSh = m_rView.GetWrtShell();
+ const Point aDocPt( PixelToLogic( rEvt.maPosPixel ));
+ SdrObject *pObj = 0;
+ OutlinerView* pOLV;
+ rSh.GetObjCntType( aDocPt, pObj );
+
+ if( pObj && 0 != ( pOLV = rSh.GetDrawView()->GetTextEditOutlinerView() ))
+ {
+ Rectangle aRect( pOLV->GetOutputArea() );
+ aRect.Union( pObj->GetLogicRect() );
+ const Point aPos = pOLV->GetWindow()->PixelToLogic(rEvt.maPosPixel);
+ if ( aRect.IsInside(aPos) )
+ {
+ rSh.StartAllAction();
+ rSh.EndAllAction();
+ return nRet;
+ }
+ }
+
+ // There's a special treatment for file lists with a single
+ // element, that depends on the actual content of the
+ // Transferable to be accessible. Since the transferable
+ // may only be accessed after the drop has been accepted
+ // (according to KA due to Java D&D), we'll have to
+ // reevaluate the drop action once more _with_ the
+ // Transferable.
+ sal_uInt16 nEventAction;
+ sal_Int8 nUserOpt = rEvt.mbDefault ? EXCHG_IN_ACTION_DEFAULT
+ : rEvt.mnAction;
+ m_nDropAction = SotExchange::GetExchangeAction(
+ GetDataFlavorExVector(),
+ m_nDropDestination,
+ rEvt.mnAction,
+ nUserOpt, m_nDropFormat, nEventAction, 0,
+ &rEvt.maDropEvent.Transferable );
+
+ TransferableDataHelper aData( rEvt.maDropEvent.Transferable );
+ nRet = rEvt.mnAction;
+ if( !SwTransferable::PasteData( aData, rSh, m_nDropAction, m_nDropFormat,
+ m_nDropDestination, false, rEvt.mbDefault, &aDocPt, nRet))
+ nRet = DND_ACTION_NONE;
+ else if ( SW_MOD()->pDragDrop )
+ //Don't clean up anymore at internal D&D!
+ SW_MOD()->pDragDrop->SetCleanUp( false );
+
+ return nRet;
+}
+
+sal_uInt16 SwEditWin::GetDropDestination( const Point& rPixPnt, SdrObject ** ppObj )
+{
+ SwWrtShell &rSh = m_rView.GetWrtShell();
+ const Point aDocPt( PixelToLogic( rPixPnt ) );
+ if( rSh.ChgCurrPam( aDocPt )
+ || rSh.IsOverReadOnlyPos( aDocPt )
+ || rSh.DocPtInsideInputFld( aDocPt ) )
+ return 0;
+
+ SdrObject *pObj = NULL;
+ const ObjCntType eType = rSh.GetObjCntType( aDocPt, pObj );
+
+ //Drop to OutlinerView (TextEdit in Drawing) should decide it on its own!
+ if( pObj )
+ {
+ OutlinerView* pOLV = rSh.GetDrawView()->GetTextEditOutlinerView();
+ if ( pOLV )
+ {
+ Rectangle aRect( pOLV->GetOutputArea() );
+ aRect.Union( pObj->GetLogicRect() );
+ const Point aPos = pOLV->GetWindow()->PixelToLogic( rPixPnt );
+ if( aRect.IsInside( aPos ) )
+ return 0;
+ }
+ }
+
+ //What do we want to drop on now?
+ sal_uInt16 nDropDestination = 0;
+
+ //Did anything else arrive from the DrawingEngine?
+ if( OBJCNT_NONE != eType )
+ {
+ switch ( eType )
+ {
+ case OBJCNT_GRF:
+ {
+ bool bLink,
+ bIMap = 0 != rSh.GetFmtFromObj( aDocPt )->GetURL().GetMap();
+ OUString aDummy;
+ rSh.GetGrfAtPos( aDocPt, aDummy, bLink );
+ if ( bLink && bIMap )
+ nDropDestination = EXCHG_DEST_DOC_LNKD_GRAPH_W_IMAP;
+ else if ( bLink )
+ nDropDestination = EXCHG_DEST_DOC_LNKD_GRAPHOBJ;
+ else if ( bIMap )
+ nDropDestination = EXCHG_DEST_DOC_GRAPH_W_IMAP;
+ else
+ nDropDestination = EXCHG_DEST_DOC_GRAPHOBJ;
+ }
+ break;
+ case OBJCNT_FLY:
+ if( rSh.GetView().GetDocShell()->ISA(SwWebDocShell) )
+ nDropDestination = EXCHG_DEST_DOC_TEXTFRAME_WEB;
+ else
+ nDropDestination = EXCHG_DEST_DOC_TEXTFRAME;
+ break;
+ case OBJCNT_OLE: nDropDestination = EXCHG_DEST_DOC_OLEOBJ; break;
+ case OBJCNT_CONTROL: /* no Action avail */
+ case OBJCNT_SIMPLE: nDropDestination = EXCHG_DEST_DOC_DRAWOBJ; break;
+ case OBJCNT_URLBUTTON: nDropDestination = EXCHG_DEST_DOC_URLBUTTON; break;
+ case OBJCNT_GROUPOBJ: nDropDestination = EXCHG_DEST_DOC_GROUPOBJ; break;
+
+ default: OSL_ENSURE( !this, "new ObjectType?" );
+ }
+ }
+ if ( !nDropDestination )
+ {
+ if( rSh.GetView().GetDocShell()->ISA(SwWebDocShell) )
+ nDropDestination = EXCHG_DEST_SWDOC_FREE_AREA_WEB;
+ else
+ nDropDestination = EXCHG_DEST_SWDOC_FREE_AREA;
+ }
+ if( ppObj )
+ *ppObj = pObj;
+ return nDropDestination;
+}
+
+sal_Int8 SwEditWin::AcceptDrop( const AcceptDropEvent& rEvt )
+{
+ if( rEvt.mbLeaving )
+ {
+ DropCleanup();
+ return rEvt.mnAction;
+ }
+
+ if( m_rView.GetDocShell()->IsReadOnly() )
+ return DND_ACTION_NONE;
+
+ SwWrtShell &rSh = m_rView.GetWrtShell();
+
+ Point aPixPt( rEvt.maPosPixel );
+
+ // If the cursor is near the inner boundary
+ // we attempt to scroll towards the desired direction.
+ Point aPoint;
+ Rectangle aWin(aPoint,GetOutputSizePixel());
+ const int nMargin = 10;
+ aWin.Left() += nMargin;
+ aWin.Top() += nMargin;
+ aWin.Right() -= nMargin;
+ aWin.Bottom() -= nMargin;
+ if(!aWin.IsInside(aPixPt)) {
+ static sal_uLong last_tick = 0;
+ sal_uLong current_tick = Time::GetSystemTicks();
+ if((current_tick-last_tick) > 500) {
+ last_tick = current_tick;
+ if(!m_bOldIdleSet) {
+ m_bOldIdle = rSh.GetViewOptions()->IsIdle();
+ ((SwViewOption *)rSh.GetViewOptions())->SetIdle(false);
+ m_bOldIdleSet = true;
+ }
+ CleanupDropUserMarker();
+ if(aPixPt.X() > aWin.Right()) aPixPt.X() += nMargin;
+ if(aPixPt.X() < aWin.Left()) aPixPt.X() -= nMargin;
+ if(aPixPt.Y() > aWin.Bottom()) aPixPt.Y() += nMargin;
+ if(aPixPt.Y() < aWin.Top()) aPixPt.Y() -= nMargin;
+ Point aDocPt(PixelToLogic(aPixPt));
+ SwRect rect(aDocPt,Size(1,1));
+ rSh.MakeVisible(rect);
+ }
+ }
+
+ if(m_bOldIdleSet) {
+ ((SwViewOption *)rSh.GetViewOptions())->SetIdle( m_bOldIdle );
+ m_bOldIdleSet = false;
+ }
+
+ SdrObject *pObj = NULL;
+ m_nDropDestination = GetDropDestination( aPixPt, &pObj );
+ if( !m_nDropDestination )
+ return DND_ACTION_NONE;
+
+ sal_uInt16 nEventAction;
+ sal_Int8 nUserOpt = rEvt.mbDefault ? EXCHG_IN_ACTION_DEFAULT
+ : rEvt.mnAction;
+
+ m_nDropAction = SotExchange::GetExchangeAction(
+ GetDataFlavorExVector(),
+ m_nDropDestination,
+ rEvt.mnAction,
+ nUserOpt, m_nDropFormat, nEventAction );
+
+ if( EXCHG_INOUT_ACTION_NONE != m_nDropAction )
+ {
+ const Point aDocPt( PixelToLogic( aPixPt ) );
+
+ //With the default action we still want to have a say.
+ SwModule *pMod = SW_MOD();
+ if( pMod->pDragDrop )
+ {
+ bool bCleanup = false;
+ //Drawing objects in Headers/Footers are not allowed
+
+ SwWrtShell *pSrcSh = pMod->pDragDrop->GetShell();
+ if( (pSrcSh->GetSelFrmType() == FRMTYPE_DRAWOBJ) &&
+ pSrcSh->IsSelContainsControl() &&
+ (rSh.GetFrmType( &aDocPt, false ) & (FRMTYPE_HEADER|FRMTYPE_FOOTER)) )
+ {
+ bCleanup = true;
+ }
+ // don't more position protected objects!
+ else if( DND_ACTION_MOVE == rEvt.mnAction &&
+ pSrcSh->IsSelObjProtected( FLYPROTECT_POS ) )
+ {
+ bCleanup = true;
+ }
+ else if( rEvt.mbDefault )
+ {
+ // internal Drag&Drop: within same Doc a Move
+ // otherwise a Copy - Task 54974
+ nEventAction = pSrcSh->GetDoc() == rSh.GetDoc()
+ ? DND_ACTION_MOVE
+ : DND_ACTION_COPY;
+ }
+ if ( bCleanup )
+ {
+ CleanupDropUserMarker();
+ rSh.UnSetVisCrsr();
+ return DND_ACTION_NONE;
+ }
+ }
+ else
+ {
+ //D&D from outside of SW should be a Copy per default.
+ if( EXCHG_IN_ACTION_DEFAULT == nEventAction &&
+ DND_ACTION_MOVE == rEvt.mnAction )
+ nEventAction = DND_ACTION_COPY;
+
+ if( (SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE == m_nDropFormat &&
+ EXCHG_IN_ACTION_LINK == m_nDropAction) ||
+ SOT_FORMATSTR_ID_SBA_CTRLDATAEXCHANGE == m_nDropFormat )
+ {
+ SdrMarkView* pMView = PTR_CAST( SdrMarkView, rSh.GetDrawView() );
+ if( pMView && !pMView->IsDesignMode() )
+ return DND_ACTION_NONE;
+ }
+ }
+
+ if ( EXCHG_IN_ACTION_DEFAULT != nEventAction )
+ nUserOpt = (sal_Int8)nEventAction;
+
+ // show DropCursor or UserMarker ?
+ if( EXCHG_DEST_SWDOC_FREE_AREA_WEB == m_nDropDestination ||
+ EXCHG_DEST_SWDOC_FREE_AREA == m_nDropDestination )
+ {
+ CleanupDropUserMarker();
+ SwContentAtPos aCont( SwContentAtPos::SW_CONTENT_CHECK );
+ if(rSh.GetContentAtPos(aDocPt, aCont))
+ rSh.SwCrsrShell::SetVisCrsr( aDocPt );
+ }
+ else
+ {
+ rSh.UnSetVisCrsr();
+
+ if ( m_pUserMarkerObj != pObj )
+ {
+ CleanupDropUserMarker();
+ m_pUserMarkerObj = pObj;
+
+ if(m_pUserMarkerObj)
+ {
+ m_pUserMarker = new SdrDropMarkerOverlay( *rSh.GetDrawView(), *m_pUserMarkerObj );
+ }
+ }
+ }
+ return nUserOpt;
+ }
+
+ CleanupDropUserMarker();
+ rSh.UnSetVisCrsr();
+ return DND_ACTION_NONE;
+}
+
+IMPL_LINK_NOARG(SwEditWin, DDHandler)
+{
+ bDDTimerStarted = false;
+ m_aTimer.Stop();
+ m_aTimer.SetTimeout(240);
+ m_bMBPressed = false;
+ ReleaseMouse();
+ bFrmDrag = false;
+
+ if ( m_rView.GetViewFrame() )
+ {
+ bExecuteDrag = true;
+ StartExecuteDrag();
+ }
+ return 0;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/docvw/edtwin.cxx b/sw/source/uibase/docvw/edtwin.cxx
new file mode 100644
index 000000000000..5b96f7945d1e
--- /dev/null
+++ b/sw/source/uibase/docvw/edtwin.cxx
@@ -0,0 +1,6147 @@
+/* -*- 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 <config_features.h>
+
+#include <swtypes.hxx>
+#include <hintids.hxx>
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/string.hxx>
+#include <com/sun/star/i18n/XBreakIterator.hpp>
+#include <com/sun/star/i18n/ScriptType.hpp>
+#include <com/sun/star/i18n/InputSequenceCheckMode.hpp>
+
+#include <com/sun/star/i18n/UnicodeScript.hpp>
+
+#include <vcl/help.hxx>
+#include <vcl/graph.hxx>
+#include <vcl/msgbox.hxx>
+#include <sot/storage.hxx>
+#include <svl/macitem.hxx>
+#include <unotools/securityoptions.hxx>
+#include <basic/sbxvar.hxx>
+#include <svl/ctloptions.hxx>
+#include <basic/sbx.hxx>
+#include <svl/eitem.hxx>
+#include <svl/stritem.hxx>
+#include <sfx2/ipclient.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/dispatch.hxx>
+#include <svl/ptitem.hxx>
+#include <editeng/sizeitem.hxx>
+#include <editeng/langitem.hxx>
+#include <sfx2/htmlmode.hxx>
+#include <svx/svdview.hxx>
+#include <svx/svdhdl.hxx>
+#include <svx/svdoutl.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/svxacorr.hxx>
+#include <editeng/scripttypeitem.hxx>
+#include <editeng/flditem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/brushitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/protitem.hxx>
+#include <unotools/charclass.hxx>
+#include <basegfx/color/bcolortools.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+
+#include <touch/touch-impl.h>
+
+#include <editeng/acorrcfg.hxx>
+#include <SwSmartTagMgr.hxx>
+#include <edtwin.hxx>
+#include <view.hxx>
+#include <wrtsh.hxx>
+#include <IDocumentSettingAccess.hxx>
+#include <fldbas.hxx>
+#include <swmodule.hxx>
+#include <docsh.hxx>
+#include <viewopt.hxx>
+#include <drawbase.hxx>
+#include <dselect.hxx>
+#include <textsh.hxx>
+#include <shdwcrsr.hxx>
+#include <txatbase.hxx>
+#include <fmtanchr.hxx>
+#include <fmtornt.hxx>
+#include <fmtfsize.hxx>
+#include <fmtclds.hxx>
+#include <fmthdft.hxx>
+#include <frmfmt.hxx>
+#include <modcfg.hxx>
+#include <fmtcol.hxx>
+#include <wview.hxx>
+#include <listsh.hxx>
+#include <gloslst.hxx>
+#include <inputwin.hxx>
+#include <gloshdl.hxx>
+#include <swundo.hxx>
+#include <drwtxtsh.hxx>
+#include <fchrfmt.hxx>
+#include <fmturl.hxx>
+#include <romenu.hxx>
+#include <initui.hxx>
+#include <frmatr.hxx>
+#include <extinput.hxx>
+#include <acmplwrd.hxx>
+#include <swcalwrp.hxx>
+#include <swdtflvr.hxx>
+#include <wdocsh.hxx>
+#include <crsskip.hxx>
+#include <breakit.hxx>
+#include <checkit.hxx>
+#include <pagefrm.hxx>
+#include <HeaderFooterWin.hxx>
+
+#include <helpid.h>
+#include <cmdid.h>
+#include <docvw.hrc>
+#include <uitool.hxx>
+#include <fmtfollowtextflow.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <charfmt.hxx>
+#include <numrule.hxx>
+#include <pagedesc.hxx>
+#include <svtools/ruler.hxx>
+#include "formatclipboard.hxx"
+#include <osl/mutex.hxx>
+#include <vcl/svapp.hxx>
+#include <docstat.hxx>
+#include <wordcountdialog.hxx>
+#include <swwait.hxx>
+
+#include <IMark.hxx>
+#include <doc.hxx>
+#include <xmloff/odffields.hxx>
+
+#include <PostItMgr.hxx>
+
+#include <algorithm>
+#include <vector>
+
+#include "../../core/inc/rootfrm.hxx"
+
+#include <unotools/syslocaleoptions.hxx>
+
+using namespace sw::mark;
+using namespace ::com::sun::star;
+
+/**
+ * Globals
+ */
+static bool bInputLanguageSwitched = false;
+extern bool bNoInterrupt; // in mainwn.cxx
+
+// Usually in MouseButtonUp a selection is revoked when the selection is
+// not currently being pulled open. Unfortunately in MouseButtonDown there
+// is being selected at double/triple click. That selection is completely
+// finished in the Handler and thus can't be distinguished in the Up.
+// To resolve this bHoldSelection is set in Down at evaluated in Up.
+static bool bHoldSelection = false;
+
+bool bFrmDrag = false;
+bool bValidCrsrPos = false;
+bool bModePushed = false;
+bool bDDTimerStarted = false;
+bool bFlushCharBuffer = false;
+bool bDDINetAttr = false;
+SdrHdlKind eSdrMoveHdl = HDL_USER;
+
+QuickHelpData* SwEditWin::m_pQuickHlpData = 0;
+
+long SwEditWin::m_nDDStartPosY = 0;
+long SwEditWin::m_nDDStartPosX = 0;
+/**
+ * The initial color shown on the button is set in /core/svx/source/tbxctrls/tbxcolorupdate.cxx
+ * (ToolboxButtonColorUpdater::ToolboxButtonColorUpdater()) .
+ * The initial color used by the button is set in /core/svx/source/tbxcntrls/tbcontrl.cxx
+ * (SvxColorToolBoxControl::SvxColorToolBoxControl())
+ * and in case of writer for text(background)color also in /core/sw/source/uibase/docvw/edtwin.cxx
+ * (SwEditWin::m_aTextBackColor and SwEditWin::m_aTextColor)
+ */
+Color SwEditWin::m_aTextBackColor(COL_YELLOW);
+Color SwEditWin::m_aTextColor(COL_RED);
+
+extern bool bExecuteDrag;
+
+static SfxShell* lcl_GetShellFromDispatcher( SwView& rView, TypeId nType );
+
+class SwAnchorMarker
+{
+ SdrHdl* pHdl;
+ Point aHdlPos;
+ Point aLastPos;
+ bool bTopRightHandle;
+public:
+ SwAnchorMarker( SdrHdl* pH )
+ : pHdl( pH )
+ , aHdlPos( pH->GetPos() )
+ , aLastPos( pH->GetPos() )
+ , bTopRightHandle( pH->GetKind() == HDL_ANCHOR_TR )
+ {}
+ const Point& GetLastPos() const { return aLastPos; }
+ void SetLastPos( const Point& rNew ) { aLastPos = rNew; }
+ void SetPos( const Point& rNew ) { pHdl->SetPos( rNew ); }
+ const Point& GetPos() { return pHdl->GetPos(); }
+ const Point& GetHdlPos() { return aHdlPos; }
+ SdrHdl* GetHdl() const { return pHdl; }
+ void ChgHdl( SdrHdl* pNew )
+ {
+ pHdl = pNew;
+ if ( pHdl )
+ {
+ bTopRightHandle = (pHdl->GetKind() == HDL_ANCHOR_TR);
+ }
+ }
+ const Point GetPosForHitTest( const OutputDevice& rOut )
+ {
+ Point aHitTestPos( GetPos() );
+ aHitTestPos = rOut.LogicToPixel( aHitTestPos );
+ if ( bTopRightHandle )
+ {
+ aHitTestPos += Point( -1, 1 );
+ }
+ else
+ {
+ aHitTestPos += Point( 1, 1 );
+ }
+ aHitTestPos = rOut.PixelToLogic( aHitTestPos );
+
+ return aHitTestPos;
+ }
+};
+
+/// Assists with auto-completion of AutoComplete words and AutoText names.
+struct QuickHelpData
+{
+ /// Strings that at least partially match an input word.
+ std::vector<OUString> m_aHelpStrings;
+ /// Index of the current help string.
+ sal_uInt16 nCurArrPos;
+ /// Length of the input word associated with the help data.
+ sal_uInt16 nLen;
+
+ /// Help data stores AutoText names rather than AutoComplete words.
+ bool m_bIsAutoText;
+ /// Display help string as a tip rather than inline.
+ bool m_bIsTip;
+ /// Tip ID when a help string is displayed as a tip.
+ sal_uLong nTipId;
+ /// Append a space character to the displayed help string (if appropriate).
+ bool m_bAppendSpace;
+
+ /// Help string is currently displayed.
+ bool m_bIsDisplayed;
+
+ QuickHelpData() { ClearCntnt(); }
+
+ void Move( QuickHelpData& rCpy );
+ void ClearCntnt();
+ void Start( SwWrtShell& rSh, sal_uInt16 nWrdLen );
+ void Stop( SwWrtShell& rSh );
+
+ bool HasCntnt() const { return !m_aHelpStrings.empty() && 0 != nLen; }
+
+ /// Next help string.
+ void Next( bool bEndLess )
+ {
+ if( ++nCurArrPos >= m_aHelpStrings.size() )
+ nCurArrPos = (bEndLess && !m_bIsAutoText ) ? 0 : nCurArrPos-1;
+ }
+ /// Previous help string.
+ void Previous( bool bEndLess )
+ {
+ if( 0 == nCurArrPos-- )
+ nCurArrPos = (bEndLess && !m_bIsAutoText ) ? m_aHelpStrings.size()-1 : 0;
+ }
+
+ // Fills internal structures with hopefully helpful information.
+ void FillStrArr( SwWrtShell& rSh, const OUString& rWord );
+ void SortAndFilter(const OUString &rOrigWord);
+};
+
+/**
+ * Avoid minimal movement shiver
+ */
+#define HIT_PIX 2 /* hit tolerance in pixel */
+#define MIN_MOVE 4
+
+inline bool IsMinMove(const Point &rStartPos, const Point &rLPt)
+{
+ return std::abs(rStartPos.X() - rLPt.X()) > MIN_MOVE ||
+ std::abs(rStartPos.Y() - rLPt.Y()) > MIN_MOVE;
+}
+
+/**
+ * For MouseButtonDown - determine whether a DrawObject
+ * an NO SwgFrame was hit! Shift/Ctrl should only result
+ * in selecting, with DrawObjects; at SwgFlys to trigger
+ * hyperlinks if applicable (Download/NewWindow!)
+ */
+inline bool IsDrawObjSelectable( const SwWrtShell& rSh, const Point& rPt )
+{
+ bool bRet = true;
+ SdrObject* pObj;
+ switch( rSh.GetObjCntType( rPt, pObj ))
+ {
+ case OBJCNT_NONE:
+ case OBJCNT_FLY:
+ case OBJCNT_GRF:
+ case OBJCNT_OLE:
+ bRet = false;
+ break;
+ default:; //prevent warning
+ }
+ return bRet;
+}
+
+/*
+ * Switch pointer
+ */
+void SwEditWin::UpdatePointer(const Point &rLPt, sal_uInt16 nModifier )
+{
+ SwWrtShell &rSh = m_rView.GetWrtShell();
+ if( m_pApplyTempl )
+ {
+ PointerStyle eStyle = POINTER_FILL;
+ if ( rSh.IsOverReadOnlyPos( rLPt ) )
+ {
+ delete m_pUserMarker;
+ m_pUserMarker = 0L;
+
+ eStyle = POINTER_NOTALLOWED;
+ }
+ else
+ {
+ SwRect aRect;
+ SwRect* pRect = &aRect;
+ const SwFrmFmt* pFmt = 0;
+
+ bool bFrameIsValidTarget = false;
+ if( m_pApplyTempl->m_pFormatClipboard )
+ bFrameIsValidTarget = m_pApplyTempl->m_pFormatClipboard->HasContentForThisType( nsSelectionType::SEL_FRM );
+ else if( !m_pApplyTempl->nColor )
+ bFrameIsValidTarget = ( m_pApplyTempl->eType == SFX_STYLE_FAMILY_FRAME );
+
+ if( bFrameIsValidTarget &&
+ 0 !=(pFmt = rSh.GetFmtFromObj( rLPt, &pRect )) &&
+ PTR_CAST(SwFlyFrmFmt, pFmt))
+ {
+ //turn on highlight for frame
+ Rectangle aTmp( pRect->SVRect() );
+
+ if ( !m_pUserMarker )
+ {
+ m_pUserMarker = new SdrDropMarkerOverlay( *rSh.GetDrawView(), aTmp );
+ }
+ }
+ else
+ {
+ delete m_pUserMarker;
+ m_pUserMarker = 0L;
+ }
+
+ rSh.SwCrsrShell::SetVisCrsr( rLPt );
+ }
+ SetPointer( eStyle );
+ return;
+ }
+
+ if( !rSh.VisArea().Width() )
+ return;
+
+ SET_CURR_SHELL(&rSh);
+
+ if ( IsChainMode() )
+ {
+ SwRect aRect;
+ int nChainable = rSh.Chainable( aRect, *rSh.GetFlyFrmFmt(), rLPt );
+ PointerStyle eStyle = nChainable
+ ? POINTER_CHAIN_NOTALLOWED : POINTER_CHAIN;
+ if ( !nChainable )
+ {
+ Rectangle aTmp( aRect.SVRect() );
+
+ if ( !m_pUserMarker )
+ {
+ m_pUserMarker = new SdrDropMarkerOverlay( *rSh.GetDrawView(), aTmp );
+ }
+ }
+ else
+ {
+ delete m_pUserMarker;
+ m_pUserMarker = 0L;
+ }
+
+ SetPointer( eStyle );
+ return;
+ }
+
+ bool bExecHyperlinks = m_rView.GetDocShell()->IsReadOnly();
+ if ( !bExecHyperlinks )
+ {
+ SvtSecurityOptions aSecOpts;
+ const bool bSecureOption = aSecOpts.IsOptionSet( SvtSecurityOptions::E_CTRLCLICK_HYPERLINK );
+ if ( ( bSecureOption && nModifier == KEY_MOD1 ) ||
+ ( !bSecureOption && nModifier != KEY_MOD1 ) )
+ bExecHyperlinks = true;
+ }
+
+ const bool bExecSmarttags = nModifier == KEY_MOD1;
+
+ SdrView *pSdrView = rSh.GetDrawView();
+ bool bPrefSdrPointer = false;
+ bool bHitHandle = false;
+ bool bCntAtPos = false;
+ bool bIsDocReadOnly = m_rView.GetDocShell()->IsReadOnly() &&
+ rSh.IsCrsrReadonly();
+ m_aActHitType = SDRHIT_NONE;
+ PointerStyle eStyle = POINTER_TEXT;
+ if ( !pSdrView )
+ bCntAtPos = true;
+ else if ( (bHitHandle = pSdrView->PickHandle( rLPt ) != 0) )
+ {
+ m_aActHitType = SDRHIT_OBJECT;
+ bPrefSdrPointer = true;
+ }
+ else
+ {
+ const bool bNotInSelObj = !rSh.IsInsideSelectedObj( rLPt );
+ if ( m_rView.GetDrawFuncPtr() && !m_bInsDraw && bNotInSelObj )
+ {
+ m_aActHitType = SDRHIT_OBJECT;
+ if (IsObjectSelect())
+ eStyle = POINTER_ARROW;
+ else
+ bPrefSdrPointer = true;
+ }
+ else
+ {
+ SdrObject* pObj; SdrPageView* pPV;
+ pSdrView->SetHitTolerancePixel( HIT_PIX );
+ if ( bNotInSelObj && bExecHyperlinks &&
+ pSdrView->PickObj( rLPt, pSdrView->getHitTolLog(), pObj, pPV, SDRSEARCH_PICKMACRO ))
+ {
+ SdrObjMacroHitRec aTmp;
+ aTmp.aPos = rLPt;
+ aTmp.pPageView = pPV;
+ SetPointer( pObj->GetMacroPointer( aTmp ) );
+ return;
+ }
+ else
+ {
+ // dvo: IsObjSelectable() eventually calls SdrView::PickObj, so
+ // apparently this is used to determine whether this is a
+ // drawling layer object or not.
+ if ( rSh.IsObjSelectable( rLPt ) )
+ {
+ if (pSdrView->IsTextEdit())
+ {
+ m_aActHitType = SDRHIT_NONE;
+ bPrefSdrPointer = true;
+ }
+ else
+ {
+ SdrViewEvent aVEvt;
+ SdrHitKind eHit = pSdrView->PickAnything(rLPt, aVEvt);
+
+ if (eHit == SDRHIT_URLFIELD && bExecHyperlinks)
+ {
+ m_aActHitType = SDRHIT_OBJECT;
+ bPrefSdrPointer = true;
+ }
+ else
+ {
+ // if we're over a selected object, we show an
+ // ARROW by default. We only show a MOVE if 1) the
+ // object is selected, and 2) it may be moved
+ // (i.e., position is not protected).
+ bool bMovable =
+ (!bNotInSelObj) &&
+ (rSh.IsObjSelected() || rSh.IsFrmSelected()) &&
+ (!rSh.IsSelObjProtected(FLYPROTECT_POS));
+
+ SdrObject* pSelectableObj = rSh.GetObjAt(rLPt);
+ // Don't update pointer if this is a background image only.
+ if (pSelectableObj->GetLayer() != rSh.GetDoc()->GetHellId())
+ eStyle = bMovable ? POINTER_MOVE : POINTER_ARROW;
+ m_aActHitType = SDRHIT_OBJECT;
+ }
+ }
+ }
+ else
+ {
+ if ( rSh.IsFrmSelected() && !bNotInSelObj )
+ {
+ // dvo: this branch appears to be dead and should be
+ // removed in a future version. Reason: The condition
+ // !bNotInSelObj means that this branch will only be
+ // executed in the cursor points inside a selected
+ // object. However, if this is the case, the previous
+ // if( rSh.IsObjSelectable(rLPt) ) must always be true:
+ // rLPt is inside a selected object, then obviously
+ // rLPt is over a selectable object.
+ if (rSh.IsSelObjProtected(FLYPROTECT_SIZE))
+ eStyle = POINTER_NOTALLOWED;
+ else
+ eStyle = POINTER_MOVE;
+ m_aActHitType = SDRHIT_OBJECT;
+ }
+ else
+ {
+ if ( m_rView.GetDrawFuncPtr() )
+ bPrefSdrPointer = true;
+ else
+ bCntAtPos = true;
+ }
+ }
+ }
+ }
+ }
+ if ( bPrefSdrPointer )
+ {
+ if (bIsDocReadOnly || (rSh.IsObjSelected() && rSh.IsSelObjProtected(FLYPROTECT_CONTENT)))
+ SetPointer( POINTER_NOTALLOWED );
+ else
+ {
+ if (m_rView.GetDrawFuncPtr() && m_rView.GetDrawFuncPtr()->IsInsertForm() && !bHitHandle)
+ SetPointer( POINTER_DRAW_RECT );
+ else
+ SetPointer( pSdrView->GetPreferredPointer( rLPt, rSh.GetOut() ) );
+ }
+ }
+ else
+ {
+ if( !rSh.IsPageAtPos( rLPt ) || m_pAnchorMarker )
+ eStyle = POINTER_ARROW;
+ else
+ {
+ // Even if we already have something, prefer URLs if possible.
+ SwContentAtPos aUrlPos(SwContentAtPos::SW_INETATTR);
+ if (bCntAtPos || rSh.GetContentAtPos(rLPt, aUrlPos))
+ {
+ SwContentAtPos aSwContentAtPos(
+ SwContentAtPos::SW_CLICKFIELD|
+ SwContentAtPos::SW_INETATTR|
+ SwContentAtPos::SW_FTN |
+ SwContentAtPos::SW_SMARTTAG );
+ if( rSh.GetContentAtPos( rLPt, aSwContentAtPos) )
+ {
+ const bool bClickToFollow = SwContentAtPos::SW_INETATTR == aSwContentAtPos.eCntntAtPos ||
+ SwContentAtPos::SW_SMARTTAG == aSwContentAtPos.eCntntAtPos;
+
+ if( !bClickToFollow ||
+ (SwContentAtPos::SW_INETATTR == aSwContentAtPos.eCntntAtPos && bExecHyperlinks) ||
+ (SwContentAtPos::SW_SMARTTAG == aSwContentAtPos.eCntntAtPos && bExecSmarttags) )
+ eStyle = POINTER_REFHAND;
+ }
+ }
+ }
+
+ // which kind of text pointer have we to show - horz / vert - ?
+ if( POINTER_TEXT == eStyle && rSh.IsInVerticalText( &rLPt ))
+ eStyle = POINTER_TEXT_VERTICAL;
+
+ SetPointer( eStyle );
+ }
+}
+
+/**
+ * Increase timer for selection
+ */
+IMPL_LINK_NOARG(SwEditWin, TimerHandler)
+{
+ SwWrtShell &rSh = m_rView.GetWrtShell();
+ Point aModPt( m_aMovePos );
+ const SwRect aOldVis( rSh.VisArea() );
+ bool bDone = false;
+
+ if ( !rSh.VisArea().IsInside( aModPt ) )
+ {
+ if ( m_bInsDraw )
+ {
+ const int nMaxScroll = 40;
+ m_rView.Scroll( Rectangle(aModPt,Size(1,1)), nMaxScroll, nMaxScroll);
+ bDone = true;
+ }
+ else if ( bFrmDrag )
+ {
+ rSh.Drag(&aModPt, false);
+ bDone = true;
+ }
+ if ( !bDone )
+ aModPt = rSh.GetCntntPos( aModPt,aModPt.Y() > rSh.VisArea().Bottom() );
+ }
+ if ( !bDone && !(bFrmDrag || m_bInsDraw) )
+ {
+ if ( m_pRowColumnSelectionStart )
+ {
+ Point aPos( aModPt );
+ rSh.SelectTableRowCol( *m_pRowColumnSelectionStart, &aPos, m_bIsRowDrag );
+ }
+ else
+ rSh.SetCursor( &aModPt, false );
+
+ // It can be that a "jump" over a table cannot be accomplished like
+ // that. So we jump over the table by Up/Down here.
+ const SwRect& rVisArea = rSh.VisArea();
+ if( aOldVis == rVisArea && !rSh.IsStartOfDoc() && !rSh.IsEndOfDoc() )
+ {
+ // take the center point of VisArea to
+ // decide in which direction the user want.
+ if( aModPt.Y() < ( rVisArea.Top() + rVisArea.Height() / 2 ) )
+ rSh.Up( true, 1 );
+ else
+ rSh.Down( true, 1 );
+ }
+ }
+
+ m_aMovePos += rSh.VisArea().Pos() - aOldVis.Pos();
+ JustifyAreaTimer();
+ return 0;
+}
+
+void SwEditWin::JustifyAreaTimer()
+{
+ const Rectangle &rVisArea = GetView().GetVisArea();
+#ifdef UNX
+ const long coMinLen = 100;
+#else
+ const long coMinLen = 50;
+#endif
+ long nTimeout = 800,
+ nDiff = std::max(
+ std::max( m_aMovePos.Y() - rVisArea.Bottom(), rVisArea.Top() - m_aMovePos.Y() ),
+ std::max( m_aMovePos.X() - rVisArea.Right(), rVisArea.Left() - m_aMovePos.X()));
+ m_aTimer.SetTimeout( std::max( coMinLen, nTimeout - nDiff*2L) );
+}
+
+void SwEditWin::LeaveArea(const Point &rPos)
+{
+ m_aMovePos = rPos;
+ JustifyAreaTimer();
+ if( !m_aTimer.IsActive() )
+ m_aTimer.Start();
+ delete m_pShadCrsr, m_pShadCrsr = 0;
+}
+
+inline void SwEditWin::EnterArea()
+{
+ m_aTimer.Stop();
+}
+
+/**
+ * Insert mode for frames
+ */
+void SwEditWin::InsFrm(sal_uInt16 nCols)
+{
+ StdDrawMode( OBJ_NONE, false );
+ m_bInsFrm = true;
+ m_nInsFrmColCount = nCols;
+}
+
+void SwEditWin::StdDrawMode( SdrObjKind eSdrObjectKind, bool bObjSelect )
+{
+ SetSdrDrawMode( eSdrObjectKind );
+
+ if (bObjSelect)
+ m_rView.SetDrawFuncPtr(new DrawSelection( &m_rView.GetWrtShell(), this, &m_rView ));
+ else
+ m_rView.SetDrawFuncPtr(new SwDrawBase( &m_rView.GetWrtShell(), this, &m_rView ));
+
+ m_rView.SetSelDrawSlot();
+ SetSdrDrawMode( eSdrObjectKind );
+ if (bObjSelect)
+ m_rView.GetDrawFuncPtr()->Activate( SID_OBJECT_SELECT );
+ else
+ m_rView.GetDrawFuncPtr()->Activate( sal::static_int_cast< sal_uInt16 >(eSdrObjectKind) );
+ m_bInsFrm = false;
+ m_nInsFrmColCount = 1;
+}
+
+void SwEditWin::StopInsFrm()
+{
+ if (m_rView.GetDrawFuncPtr())
+ {
+ m_rView.GetDrawFuncPtr()->Deactivate();
+ m_rView.SetDrawFuncPtr(NULL);
+ }
+ m_rView.LeaveDrawCreate(); // leave construction mode
+ m_bInsFrm = false;
+ m_nInsFrmColCount = 1;
+}
+
+bool SwEditWin::IsInputSequenceCheckingRequired( const OUString &rText, const SwPaM& rCrsr ) const
+{
+ const SvtCTLOptions& rCTLOptions = SW_MOD()->GetCTLOptions();
+ if ( !rCTLOptions.IsCTLFontEnabled() ||
+ !rCTLOptions.IsCTLSequenceChecking() )
+ return false;
+
+ if ( 0 == rCrsr.Start()->nContent.GetIndex() ) /* first char needs not to be checked */
+ return false;
+
+ SwBreakIt *pBreakIter = SwBreakIt::Get();
+ uno::Reference < i18n::XBreakIterator > xBI = pBreakIter->GetBreakIter();
+ long nCTLScriptPos = -1;
+
+ if (xBI.is())
+ {
+ if (xBI->getScriptType( rText, 0 ) == i18n::ScriptType::COMPLEX)
+ nCTLScriptPos = 0;
+ else
+ nCTLScriptPos = xBI->nextScript( rText, 0, i18n::ScriptType::COMPLEX );
+ }
+
+ return (0 <= nCTLScriptPos && nCTLScriptPos <= rText.getLength());
+}
+
+//return INVALID_HINT if language should not be explictly overridden, the correct
+//HintId to use for the eBufferLanguage otherwise
+static sal_uInt16 lcl_isNonDefaultLanguage(LanguageType eBufferLanguage, SwView& rView,
+ const OUString &rInBuffer)
+{
+ sal_uInt16 nWhich = INVALID_HINT;
+
+ //If the option to IgnoreLanguageChange is set, short-circuit this method
+ //which results in the document/paragraph language remaining the same
+ //despite a change to the keyboard/input language
+ SvtSysLocaleOptions aSysLocaleOptions;
+ if(aSysLocaleOptions.IsIgnoreLanguageChange())
+ {
+ return INVALID_HINT;
+ }
+
+ bool bLang = true;
+ if(eBufferLanguage != LANGUAGE_DONTKNOW)
+ {
+ switch( GetI18NScriptTypeOfLanguage( eBufferLanguage ))
+ {
+ case i18n::ScriptType::ASIAN: nWhich = RES_CHRATR_CJK_LANGUAGE; break;
+ case i18n::ScriptType::COMPLEX: nWhich = RES_CHRATR_CTL_LANGUAGE; break;
+ case i18n::ScriptType::LATIN: nWhich = RES_CHRATR_LANGUAGE; break;
+ default: bLang = false;
+ }
+ if(bLang)
+ {
+ SfxItemSet aLangSet(rView.GetPool(), nWhich, nWhich);
+ SwWrtShell& rSh = rView.GetWrtShell();
+ rSh.GetCurAttr(aLangSet);
+ if(SFX_ITEM_DEFAULT <= aLangSet.GetItemState(nWhich, true))
+ {
+ LanguageType eLang = static_cast<const SvxLanguageItem&>(aLangSet.Get(nWhich)).GetLanguage();
+ if ( eLang == eBufferLanguage )
+ {
+ // current language attribute equal to language reported from system
+ bLang = false;
+ }
+ else if ( !bInputLanguageSwitched && RES_CHRATR_LANGUAGE == nWhich )
+ {
+ // special case: switching between two "LATIN" languages
+ // In case the current keyboard setting might be suitable
+ // for both languages we can't safely assume that the user
+ // wants to use the language reported from the system,
+ // except if we knew that it was explicitly switched (thus
+ // the check for "bInputLangeSwitched").
+
+ // The language reported by the system could be just the
+ // system default language that the user is not even aware
+ // of, because no language selection tool is installed at
+ // all. In this case the OOo language should get preference
+ // as it might have been selected by the user explicitly.
+
+ // Usually this case happens if the OOo language is
+ // different to the system language but the system keyboard
+ // is still suitable for the OOo language (e.g. writing
+ // English texts with a German keyboard).
+
+ // For non-latin keyboards overwriting the attribute is
+ // still valid. We do this for kyrillic and greek ATM. In
+ // future versions of OOo this should be replaced by a
+ // configuration switch that allows to give the preference
+ // to the OOo setting or the system setting explicitly
+ // and/or a better handling of the script type.
+ i18n::UnicodeScript eType = !rInBuffer.isEmpty() ?
+ (i18n::UnicodeScript)GetAppCharClass().getScript( rInBuffer, 0 ) :
+ i18n::UnicodeScript_kScriptCount;
+
+ bool bSystemIsNonLatin = false;
+ switch ( eType )
+ {
+ case i18n::UnicodeScript_kGreek:
+ case i18n::UnicodeScript_kCyrillic:
+ // in case other UnicodeScripts require special
+ // keyboards they can be added here
+ bSystemIsNonLatin = true;
+ break;
+ default:
+ break;
+ }
+
+ bool bOOoLangIsNonLatin = MsLangId::isNonLatinWestern( eLang);
+
+ bLang = (bSystemIsNonLatin != bOOoLangIsNonLatin);
+ }
+ }
+ }
+ }
+ return bLang ? nWhich : INVALID_HINT;
+}
+
+/**
+ * Character buffer is inserted into the document
+ */
+void SwEditWin::FlushInBuffer()
+{
+ if ( !m_aInBuffer.isEmpty() )
+ {
+ SwWrtShell& rSh = m_rView.GetWrtShell();
+
+ // generate new sequence input checker if not already done
+ if ( !pCheckIt )
+ pCheckIt = new SwCheckIt;
+
+ uno::Reference < i18n::XExtendedInputSequenceChecker > xISC = pCheckIt->xCheck;
+ if ( xISC.is() && IsInputSequenceCheckingRequired( m_aInBuffer, *rSh.GetCrsr() ) )
+ {
+
+ // apply (Thai) input sequence checking/correction
+
+ rSh.Push(); // push current cursor to stack
+
+ // get text from the beginning (i.e left side) of current selection
+ // to the start of the paragraph
+ rSh.NormalizePam(); // make point be the first (left) one
+ if (!rSh.GetCrsr()->HasMark())
+ rSh.GetCrsr()->SetMark();
+ rSh.GetCrsr()->GetMark()->nContent = 0;
+
+ const OUString aOldText( rSh.GetCrsr()->GetTxt() );
+ const sal_Int32 nOldLen = aOldText.getLength();
+
+ SvtCTLOptions& rCTLOptions = SW_MOD()->GetCTLOptions();
+
+ sal_Int32 nExpandSelection = 0;
+ if (nOldLen > 0)
+ {
+ sal_Int32 nTmpPos = nOldLen;
+ sal_Int16 nCheckMode = rCTLOptions.IsCTLSequenceCheckingRestricted() ?
+ i18n::InputSequenceCheckMode::STRICT : i18n::InputSequenceCheckMode::BASIC;
+
+ OUString aNewText( aOldText );
+ if (rCTLOptions.IsCTLSequenceCheckingTypeAndReplace())
+ {
+ for( sal_Int32 k = 0; k < m_aInBuffer.getLength(); ++k)
+ {
+ const sal_Unicode cChar = m_aInBuffer[k];
+ const sal_Int32 nPrevPos =xISC->correctInputSequence( aNewText, nTmpPos - 1, cChar, nCheckMode );
+
+ // valid sequence or sequence could be corrected:
+ if (nPrevPos != aNewText.getLength())
+ nTmpPos = nPrevPos + 1;
+ }
+
+ // find position of first character that has changed
+ sal_Int32 nNewLen = aNewText.getLength();
+ const sal_Unicode *pOldTxt = aOldText.getStr();
+ const sal_Unicode *pNewTxt = aNewText.getStr();
+ sal_Int32 nChgPos = 0;
+ while ( nChgPos < nOldLen && nChgPos < nNewLen &&
+ pOldTxt[nChgPos] == pNewTxt[nChgPos] )
+ ++nChgPos;
+
+ const sal_Int32 nChgLen = nNewLen - nChgPos;
+ if (nChgLen)
+ {
+ m_aInBuffer = aNewText.copy( nChgPos, nChgLen );
+ nExpandSelection = nOldLen - nChgPos;
+ }
+ else
+ m_aInBuffer = "";
+ }
+ else
+ {
+ for( sal_Int32 k = 0; k < m_aInBuffer.getLength(); ++k )
+ {
+ const sal_Unicode cChar = m_aInBuffer[k];
+ if (xISC->checkInputSequence( aNewText, nTmpPos - 1, cChar, nCheckMode ))
+ {
+ // character can be inserted:
+ aNewText += OUString( (sal_Unicode) cChar );
+ ++nTmpPos;
+ }
+ }
+ m_aInBuffer = aNewText.copy( aOldText.getLength() ); // copy new text to be inserted to buffer
+ }
+ }
+
+ // at this point now we will insert the buffer text 'normally' some lines below...
+
+ rSh.Pop( false ); // pop old cursor from stack
+
+ if (m_aInBuffer.isEmpty())
+ return;
+
+ // if text prior to the original selection needs to be changed
+ // as well, we now expand the selection accordingly.
+ SwPaM &rCrsr = *rSh.GetCrsr();
+ const sal_Int32 nCrsrStartPos = rCrsr.Start()->nContent.GetIndex();
+ OSL_ENSURE( nCrsrStartPos >= nExpandSelection, "cannot expand selection as specified!!" );
+ if (nExpandSelection && nCrsrStartPos >= nExpandSelection)
+ {
+ if (!rCrsr.HasMark())
+ rCrsr.SetMark();
+ rCrsr.Start()->nContent -= nExpandSelection;
+ }
+ }
+
+ uno::Reference< frame::XDispatchRecorder > xRecorder =
+ m_rView.GetViewFrame()->GetBindings().GetRecorder();
+ if ( xRecorder.is() )
+ {
+ // determine shell
+ SfxShell *pSfxShell = lcl_GetShellFromDispatcher( m_rView, TYPE(SwTextShell) );
+ // generate request and record
+ if (pSfxShell)
+ {
+ SfxRequest aReq( m_rView.GetViewFrame(), FN_INSERT_STRING );
+ aReq.AppendItem( SfxStringItem( FN_INSERT_STRING, m_aInBuffer ) );
+ aReq.Done();
+ }
+ }
+
+ sal_uInt16 nWhich = lcl_isNonDefaultLanguage(m_eBufferLanguage, m_rView, m_aInBuffer);
+ if (nWhich != INVALID_HINT )
+ {
+ SvxLanguageItem aLangItem( m_eBufferLanguage, nWhich );
+ rSh.SetAttrItem( aLangItem );
+ }
+
+ rSh.Insert( m_aInBuffer );
+ m_eBufferLanguage = LANGUAGE_DONTKNOW;
+ m_aInBuffer = "";
+ bFlushCharBuffer = false;
+ }
+}
+
+#define MOVE_LEFT_SMALL 0
+#define MOVE_UP_SMALL 1
+#define MOVE_RIGHT_BIG 2
+#define MOVE_DOWN_BIG 3
+#define MOVE_LEFT_BIG 4
+#define MOVE_UP_BIG 5
+#define MOVE_RIGHT_SMALL 6
+#define MOVE_DOWN_SMALL 7
+
+// #i121236# Support for shift key in writer
+#define MOVE_LEFT_HUGE 8
+#define MOVE_UP_HUGE 9
+#define MOVE_RIGHT_HUGE 10
+#define MOVE_DOWN_HUGE 11
+
+void SwEditWin::ChangeFly( sal_uInt8 nDir, bool bWeb )
+{
+ SwWrtShell &rSh = m_rView.GetWrtShell();
+ SwRect aTmp = rSh.GetFlyRect();
+ if( aTmp.HasArea() &&
+ !rSh.IsSelObjProtected( FLYPROTECT_POS ) )
+ {
+ SfxItemSet aSet(rSh.GetAttrPool(),
+ RES_FRM_SIZE, RES_FRM_SIZE,
+ RES_VERT_ORIENT, RES_ANCHOR,
+ RES_COL, RES_COL,
+ RES_PROTECT, RES_PROTECT,
+ RES_FOLLOW_TEXT_FLOW, RES_FOLLOW_TEXT_FLOW, 0);
+ rSh.GetFlyFrmAttr( aSet );
+ RndStdIds eAnchorId = ((SwFmtAnchor&)aSet.Get(RES_ANCHOR)).GetAnchorId();
+ Size aSnap;
+ bool bHuge(MOVE_LEFT_HUGE == nDir ||
+ MOVE_UP_HUGE == nDir ||
+ MOVE_RIGHT_HUGE == nDir ||
+ MOVE_DOWN_HUGE == nDir);
+
+ if(MOVE_LEFT_SMALL == nDir ||
+ MOVE_UP_SMALL == nDir ||
+ MOVE_RIGHT_SMALL == nDir ||
+ MOVE_DOWN_SMALL == nDir )
+ {
+ aSnap = PixelToLogic(Size(1,1));
+ }
+ else
+ {
+ aSnap = rSh.GetViewOptions()->GetSnapSize();
+ short nDiv = rSh.GetViewOptions()->GetDivisionX();
+ if ( nDiv > 0 )
+ aSnap.Width() = std::max( (sal_uLong)1, (sal_uLong)aSnap.Width() / nDiv );
+ nDiv = rSh.GetViewOptions()->GetDivisionY();
+ if ( nDiv > 0 )
+ aSnap.Height() = std::max( (sal_uLong)1, (sal_uLong)aSnap.Height() / nDiv );
+ }
+
+ if(bHuge)
+ {
+ // #i121236# 567twips == 1cm, but just take three times the normal snap
+ aSnap = Size(aSnap.Width() * 3, aSnap.Height() * 3);
+ }
+
+ SwRect aBoundRect;
+ Point aRefPoint;
+ // adjustment for allowing vertical position
+ // aligned to page for fly frame anchored to paragraph or to character.
+ {
+ SwFmtVertOrient aVert( (SwFmtVertOrient&)aSet.Get(RES_VERT_ORIENT) );
+ const bool bFollowTextFlow =
+ static_cast<const SwFmtFollowTextFlow&>(aSet.Get(RES_FOLLOW_TEXT_FLOW)).GetValue();
+ const SwPosition* pToCharCntntPos = ((SwFmtAnchor&)aSet.Get(RES_ANCHOR)).GetCntntAnchor();
+ rSh.CalcBoundRect( aBoundRect, eAnchorId,
+ text::RelOrientation::FRAME, aVert.GetRelationOrient(),
+ pToCharCntntPos, bFollowTextFlow,
+ false, &aRefPoint );
+ }
+ long nLeft = std::min( aTmp.Left() - aBoundRect.Left(), aSnap.Width() );
+ long nRight = std::min( aBoundRect.Right() - aTmp.Right(), aSnap.Width() );
+ long nUp = std::min( aTmp.Top() - aBoundRect.Top(), aSnap.Height() );
+ long nDown = std::min( aBoundRect.Bottom() - aTmp.Bottom(), aSnap.Height() );
+
+ switch ( nDir )
+ {
+ case MOVE_LEFT_BIG:
+ case MOVE_LEFT_HUGE:
+ case MOVE_LEFT_SMALL: aTmp.Left( aTmp.Left() - nLeft );
+ break;
+
+ case MOVE_UP_BIG:
+ case MOVE_UP_HUGE:
+ case MOVE_UP_SMALL: aTmp.Top( aTmp.Top() - nUp );
+ break;
+
+ case MOVE_RIGHT_SMALL:
+ if( aTmp.Width() < aSnap.Width() + MINFLY )
+ break;
+ nRight = aSnap.Width(); // no break
+ case MOVE_RIGHT_HUGE:
+ case MOVE_RIGHT_BIG: aTmp.Left( aTmp.Left() + nRight );
+ break;
+
+ case MOVE_DOWN_SMALL:
+ if( aTmp.Height() < aSnap.Height() + MINFLY )
+ break;
+ nDown = aSnap.Height(); // no break
+ case MOVE_DOWN_HUGE:
+ case MOVE_DOWN_BIG: aTmp.Top( aTmp.Top() + nDown );
+ break;
+
+ default: OSL_ENSURE(true, "ChangeFly: Unknown direction." );
+ }
+ bool bSet = false;
+ if ((FLY_AS_CHAR == eAnchorId) && ( nDir % 2 ))
+ {
+ long aDiff = aTmp.Top() - aRefPoint.Y();
+ if( aDiff > 0 )
+ aDiff = 0;
+ else if ( aDiff < -aTmp.Height() )
+ aDiff = -aTmp.Height();
+ SwFmtVertOrient aVert( (SwFmtVertOrient&)aSet.Get(RES_VERT_ORIENT) );
+ sal_Int16 eNew;
+ if( bWeb )
+ {
+ eNew = aVert.GetVertOrient();
+ bool bDown = 0 != ( nDir & 0x02 );
+ switch( eNew )
+ {
+ case text::VertOrientation::CHAR_TOP:
+ if( bDown ) eNew = text::VertOrientation::CENTER;
+ break;
+ case text::VertOrientation::CENTER:
+ eNew = bDown ? text::VertOrientation::TOP : text::VertOrientation::CHAR_TOP;
+ break;
+ case text::VertOrientation::TOP:
+ if( !bDown ) eNew = text::VertOrientation::CENTER;
+ break;
+ case text::VertOrientation::LINE_TOP:
+ if( bDown ) eNew = text::VertOrientation::LINE_CENTER;
+ break;
+ case text::VertOrientation::LINE_CENTER:
+ eNew = bDown ? text::VertOrientation::LINE_BOTTOM : text::VertOrientation::LINE_TOP;
+ break;
+ case text::VertOrientation::LINE_BOTTOM:
+ if( !bDown ) eNew = text::VertOrientation::LINE_CENTER;
+ break;
+ default:; //prevent warning
+ }
+ }
+ else
+ {
+ aVert.SetPos( aDiff );
+ eNew = text::VertOrientation::NONE;
+ }
+ aVert.SetVertOrient( eNew );
+ aSet.Put( aVert );
+ bSet = true;
+ }
+ if (bWeb && (FLY_AT_PARA == eAnchorId)
+ && ( nDir==MOVE_LEFT_SMALL || nDir==MOVE_RIGHT_BIG ))
+ {
+ SwFmtHoriOrient aHori( (SwFmtHoriOrient&)aSet.Get(RES_HORI_ORIENT) );
+ sal_Int16 eNew;
+ eNew = aHori.GetHoriOrient();
+ switch( eNew )
+ {
+ case text::HoriOrientation::RIGHT:
+ if( nDir==MOVE_LEFT_SMALL )
+ eNew = text::HoriOrientation::LEFT;
+ break;
+ case text::HoriOrientation::LEFT:
+ if( nDir==MOVE_RIGHT_BIG )
+ eNew = text::HoriOrientation::RIGHT;
+ break;
+ default:; //prevent warning
+ }
+ if( eNew != aHori.GetHoriOrient() )
+ {
+ aHori.SetHoriOrient( eNew );
+ aSet.Put( aHori );
+ bSet = true;
+ }
+ }
+ rSh.StartAllAction();
+ if( bSet )
+ rSh.SetFlyFrmAttr( aSet );
+ bool bSetPos = (FLY_AS_CHAR != eAnchorId);
+ if(bSetPos && bWeb)
+ {
+ if (FLY_AT_PAGE != eAnchorId)
+ {
+ bSetPos = false;
+ }
+ else
+ {
+ bSetPos = true;
+ }
+ }
+ if( bSetPos )
+ rSh.SetFlyPos( aTmp.Pos() );
+ rSh.EndAllAction();
+ }
+}
+
+void SwEditWin::ChangeDrawing( sal_uInt8 nDir )
+{
+ // start undo action in order to get only one
+ // undo action for this change.
+ SwWrtShell &rSh = m_rView.GetWrtShell();
+ rSh.StartUndo();
+
+ long nX = 0;
+ long nY = 0;
+ const bool bOnePixel(
+ MOVE_LEFT_SMALL == nDir ||
+ MOVE_UP_SMALL == nDir ||
+ MOVE_RIGHT_SMALL == nDir ||
+ MOVE_DOWN_SMALL == nDir);
+ const bool bHuge(
+ MOVE_LEFT_HUGE == nDir ||
+ MOVE_UP_HUGE == nDir ||
+ MOVE_RIGHT_HUGE == nDir ||
+ MOVE_DOWN_HUGE == nDir);
+ sal_uInt16 nAnchorDir = SW_MOVE_UP;
+ switch(nDir)
+ {
+ case MOVE_LEFT_SMALL:
+ case MOVE_LEFT_HUGE:
+ case MOVE_LEFT_BIG:
+ nX = -1;
+ nAnchorDir = SW_MOVE_LEFT;
+ break;
+ case MOVE_UP_SMALL:
+ case MOVE_UP_HUGE:
+ case MOVE_UP_BIG:
+ nY = -1;
+ break;
+ case MOVE_RIGHT_SMALL:
+ case MOVE_RIGHT_HUGE:
+ case MOVE_RIGHT_BIG:
+ nX = +1;
+ nAnchorDir = SW_MOVE_RIGHT;
+ break;
+ case MOVE_DOWN_SMALL:
+ case MOVE_DOWN_HUGE:
+ case MOVE_DOWN_BIG:
+ nY = +1;
+ nAnchorDir = SW_MOVE_DOWN;
+ break;
+ }
+
+ if(0 != nX || 0 != nY)
+ {
+ sal_uInt8 nProtect = rSh.IsSelObjProtected( FLYPROTECT_POS|FLYPROTECT_SIZE );
+ Size aSnap( rSh.GetViewOptions()->GetSnapSize() );
+ short nDiv = rSh.GetViewOptions()->GetDivisionX();
+ if ( nDiv > 0 )
+ aSnap.Width() = std::max( (sal_uLong)1, (sal_uLong)aSnap.Width() / nDiv );
+ nDiv = rSh.GetViewOptions()->GetDivisionY();
+ if ( nDiv > 0 )
+ aSnap.Height() = std::max( (sal_uLong)1, (sal_uLong)aSnap.Height() / nDiv );
+
+ if(bOnePixel)
+ {
+ aSnap = PixelToLogic(Size(1,1));
+ }
+ else if(bHuge)
+ {
+ // #i121236# 567twips == 1cm, but just take three times the normal snap
+ aSnap = Size(aSnap.Width() * 3, aSnap.Height() * 3);
+ }
+
+ nX *= aSnap.Width();
+ nY *= aSnap.Height();
+
+ SdrView *pSdrView = rSh.GetDrawView();
+ const SdrHdlList& rHdlList = pSdrView->GetHdlList();
+ SdrHdl* pHdl = rHdlList.GetFocusHdl();
+ rSh.StartAllAction();
+ if(0L == pHdl)
+ {
+ // now move the selected draw objects
+ // if the object's position is not protected
+ if(0 == (nProtect&FLYPROTECT_POS))
+ {
+ // Check if object is anchored as character and move direction
+ bool bDummy1, bDummy2;
+ const bool bVertAnchor = rSh.IsFrmVertical( true, bDummy1, bDummy2 );
+ bool bHoriMove = !bVertAnchor == !( nDir % 2 );
+ bool bMoveAllowed =
+ !bHoriMove || (rSh.GetAnchorId() != FLY_AS_CHAR);
+ if ( bMoveAllowed )
+ {
+ pSdrView->MoveAllMarked(Size(nX, nY));
+ rSh.SetModified();
+ }
+ }
+ }
+ else
+ {
+ // move handle with index nHandleIndex
+ if(pHdl && (nX || nY))
+ {
+ if( HDL_ANCHOR == pHdl->GetKind() ||
+ HDL_ANCHOR_TR == pHdl->GetKind() )
+ {
+ // anchor move cannot be allowed when position is protected
+ if(0 == (nProtect&FLYPROTECT_POS))
+ rSh.MoveAnchor( nAnchorDir );
+ }
+ //now resize if size is protected
+ else if(0 == (nProtect&FLYPROTECT_SIZE))
+ {
+ // now move the Handle (nX, nY)
+ Point aStartPoint(pHdl->GetPos());
+ Point aEndPoint(pHdl->GetPos() + Point(nX, nY));
+ const SdrDragStat& rDragStat = pSdrView->GetDragStat();
+
+ // start dragging
+ pSdrView->BegDragObj(aStartPoint, 0, pHdl, 0);
+
+ if(pSdrView->IsDragObj())
+ {
+ bool bWasNoSnap = rDragStat.IsNoSnap();
+ bool bWasSnapEnabled = pSdrView->IsSnapEnabled();
+
+ // switch snapping off
+ if(!bWasNoSnap)
+ ((SdrDragStat&)rDragStat).SetNoSnap(true);
+ if(bWasSnapEnabled)
+ pSdrView->SetSnapEnabled(false);
+
+ pSdrView->MovAction(aEndPoint);
+ pSdrView->EndDragObj();
+ rSh.SetModified();
+
+ // restore snap
+ if(!bWasNoSnap)
+ ((SdrDragStat&)rDragStat).SetNoSnap(bWasNoSnap);
+ if(bWasSnapEnabled)
+ pSdrView->SetSnapEnabled(bWasSnapEnabled);
+ }
+ }
+ }
+ }
+ rSh.EndAllAction();
+ }
+
+ rSh.EndUndo();
+}
+
+/**
+ * KeyEvents
+ */
+void SwEditWin::KeyInput(const KeyEvent &rKEvt)
+{
+ SwWrtShell &rSh = m_rView.GetWrtShell();
+
+ if( rKEvt.GetKeyCode().GetCode() == KEY_ESCAPE &&
+ m_pApplyTempl && m_pApplyTempl->m_pFormatClipboard )
+ {
+ m_pApplyTempl->m_pFormatClipboard->Erase();
+ SetApplyTemplate(SwApplyTemplate());
+ m_rView.GetViewFrame()->GetBindings().Invalidate(SID_FORMATPAINTBRUSH);
+ }
+ else if ( rKEvt.GetKeyCode().GetCode() == KEY_ESCAPE &&
+ rSh.IsHeaderFooterEdit( ) )
+ {
+ bool bHeader = FRMTYPE_HEADER & rSh.GetFrmType(0,false);
+ if ( bHeader )
+ rSh.SttPg();
+ else
+ rSh.EndPg();
+ rSh.ToggleHeaderFooterEdit();
+ }
+
+ SfxObjectShell *pObjSh = (SfxObjectShell*)m_rView.GetViewFrame()->GetObjectShell();
+ if ( m_bLockInput || (pObjSh && pObjSh->GetProgress()) )
+ // When the progress bar is active or a progress is
+ // running on a document, no order is being taken
+ return;
+
+ delete m_pShadCrsr, m_pShadCrsr = 0;
+ m_aKeyInputFlushTimer.Stop();
+
+ bool bIsDocReadOnly = m_rView.GetDocShell()->IsReadOnly() &&
+ rSh.IsCrsrReadonly();
+
+ //if the language changes the buffer must be flushed
+ LanguageType eNewLanguage = GetInputLanguage();
+ if(!bIsDocReadOnly && m_eBufferLanguage != eNewLanguage && !m_aInBuffer.isEmpty())
+ {
+ FlushInBuffer();
+ }
+ m_eBufferLanguage = eNewLanguage;
+
+ QuickHelpData aTmpQHD;
+ if( m_pQuickHlpData->m_bIsDisplayed )
+ {
+ aTmpQHD.Move( *m_pQuickHlpData );
+ m_pQuickHlpData->Stop( rSh );
+ }
+
+ // OS:the DrawView also needs a readonly-Flag as well
+ if ( !bIsDocReadOnly && rSh.GetDrawView() && rSh.GetDrawView()->KeyInput( rKEvt, this ) )
+ {
+ rSh.GetView().GetViewFrame()->GetBindings().InvalidateAll( false );
+ rSh.SetModified();
+ return; // Event evaluated by SdrView
+ }
+
+ if ( m_rView.GetDrawFuncPtr() && m_bInsFrm )
+ {
+ StopInsFrm();
+ rSh.Edit();
+ }
+
+ bool bFlushBuffer = false;
+ bool bNormalChar = false;
+ bool bAppendSpace = m_pQuickHlpData->m_bAppendSpace;
+ m_pQuickHlpData->m_bAppendSpace = false;
+
+ if ( getenv("SW_DEBUG") && rKEvt.GetKeyCode().GetCode() == KEY_F12 )
+ {
+ if( rKEvt.GetKeyCode().IsShift())
+ {
+ GetView().GetDocShell()->GetDoc()->dumpAsXml();
+ return;
+ }
+ else
+ {
+ SwRootFrm* pLayout = GetView().GetDocShell()->GetWrtShell()->GetLayout();
+ pLayout->dumpAsXml( );
+ return;
+ }
+ }
+
+ KeyEvent aKeyEvent( rKEvt );
+ // look for vertical mappings
+ if( !bIsDocReadOnly && !rSh.IsSelFrmMode() && !rSh.IsObjSelected() )
+ {
+ // must changed from switch to if, because the Linux
+ // compiler has problem with the code. Has to remove if the new general
+ // handler exist.
+ sal_uInt16 nKey = rKEvt.GetKeyCode().GetCode();
+
+ if( KEY_UP == nKey || KEY_DOWN == nKey ||
+ KEY_LEFT == nKey || KEY_RIGHT == nKey )
+ {
+ // In general, we want to map the direction keys if we are inside
+ // some vertical formatted text.
+ // 1. Exception: For a table cursor in a horizontal table, the
+ // directions should never be mapped.
+ // 2. Exception: For a table cursor in a vertical table, the
+ // directions should always be mapped.
+ const bool bVertText = rSh.IsInVerticalText();
+ const bool bTblCrsr = rSh.GetTableCrsr();
+ const bool bVertTable = rSh.IsTableVertical();
+ if( ( bVertText && ( !bTblCrsr || bVertTable ) ) ||
+ ( bTblCrsr && bVertTable ) )
+ {
+ // Attempt to integrate cursor travelling for mongolian layout does not work.
+ // Thus, back to previous mapping of cursor keys to direction keys.
+ if( KEY_UP == nKey ) nKey = KEY_LEFT;
+ else if( KEY_DOWN == nKey ) nKey = KEY_RIGHT;
+ else if( KEY_LEFT == nKey ) nKey = KEY_DOWN;
+ else if( KEY_RIGHT == nKey ) nKey = KEY_UP;
+ }
+
+ if ( rSh.IsInRightToLeftText() )
+ {
+ if( KEY_LEFT == nKey ) nKey = KEY_RIGHT;
+ else if( KEY_RIGHT == nKey ) nKey = KEY_LEFT;
+ }
+
+ aKeyEvent = KeyEvent( rKEvt.GetCharCode(),
+ KeyCode( nKey, rKEvt.GetKeyCode().GetModifier() ),
+ rKEvt.GetRepeat() );
+ }
+ }
+
+ const KeyCode& rKeyCode = aKeyEvent.GetKeyCode();
+ sal_Unicode aCh = aKeyEvent.GetCharCode();
+
+ // enable switching to notes ankor with Ctrl - Alt - Page Up/Down
+ // pressing this inside a note will switch to next/previous note
+ if ((rKeyCode.IsMod1() && rKeyCode.IsMod2()) && ((rKeyCode.GetCode() == KEY_PAGEUP) || (rKeyCode.GetCode() == KEY_PAGEDOWN)))
+ {
+ const bool bNext = rKeyCode.GetCode()==KEY_PAGEDOWN;
+ const SwFieldType* pFldType = rSh.GetFldType( 0, RES_POSTITFLD );
+ rSh.MoveFldType( pFldType, bNext );
+ return;
+ }
+
+ const SwFrmFmt* pFlyFmt = rSh.GetFlyFrmFmt();
+ if( pFlyFmt )
+ {
+ sal_uInt16 nEvent;
+
+ if( 32 <= aCh &&
+ 0 == (( KEY_MOD1 | KEY_MOD2 ) & rKeyCode.GetModifier() ))
+ nEvent = SW_EVENT_FRM_KEYINPUT_ALPHA;
+ else
+ nEvent = SW_EVENT_FRM_KEYINPUT_NOALPHA;
+
+ const SvxMacro* pMacro = pFlyFmt->GetMacro().GetMacroTable().Get( nEvent );
+ if( pMacro )
+ {
+ SbxArrayRef xArgs = new SbxArray;
+ SbxVariableRef xVar = new SbxVariable;
+ xVar->PutString( pFlyFmt->GetName() );
+ xArgs->Put( &xVar, 1 );
+
+ xVar = new SbxVariable;
+ if( SW_EVENT_FRM_KEYINPUT_ALPHA == nEvent )
+ xVar->PutChar( aCh );
+ else
+ xVar->PutUShort( rKeyCode.GetModifier() | rKeyCode.GetCode() );
+ xArgs->Put( &xVar, 2 );
+
+ OUString sRet;
+ rSh.ExecMacro( *pMacro, &sRet, &xArgs );
+ if( !sRet.isEmpty() && sRet.toInt32()!=0 )
+ return ;
+ }
+ }
+ int nLclSelectionType;
+ //A is converted to 1
+ if( rKeyCode.GetFullCode() == (KEY_A | KEY_MOD1 |KEY_SHIFT)
+ && rSh.HasDrawView() &&
+ (0 != (nLclSelectionType = rSh.GetSelectionType()) &&
+ ((nLclSelectionType & (nsSelectionType::SEL_FRM|nsSelectionType::SEL_GRF)) ||
+ ((nLclSelectionType & (nsSelectionType::SEL_DRW|nsSelectionType::SEL_DRW_FORM)) &&
+ rSh.GetDrawView()->GetMarkedObjectList().GetMarkCount() == 1))))
+ {
+ SdrHdlList& rHdlList = (SdrHdlList&)rSh.GetDrawView()->GetHdlList();
+ SdrHdl* pAnchor = rHdlList.GetHdl(HDL_ANCHOR);
+ if ( ! pAnchor )
+ pAnchor = rHdlList.GetHdl(HDL_ANCHOR_TR);
+ if(pAnchor)
+ rHdlList.SetFocusHdl(pAnchor);
+ return;
+ }
+
+ SvxAutoCorrCfg* pACfg = 0;
+ SvxAutoCorrect* pACorr = 0;
+
+ uno::Reference< frame::XDispatchRecorder > xRecorder =
+ m_rView.GetViewFrame()->GetBindings().GetRecorder();
+ if ( !xRecorder.is() )
+ {
+ pACfg = &SvxAutoCorrCfg::Get();
+ pACorr = pACfg->GetAutoCorrect();
+ }
+
+ SwModuleOptions* pModOpt = SW_MOD()->GetModuleConfig();
+
+ TblChgWidthHeightType eTblChgMode = nsTblChgWidthHeightType::WH_COL_LEFT; // initialization just for warning-free code
+ sal_uInt16 nTblChgSize = 0;
+ bool bStopKeyInputTimer = true;
+ OUString sFmlEntry;
+
+ enum SW_KeyState { KS_Start,
+ KS_CheckKey, KS_InsChar, KS_InsTab,
+ KS_NoNum, KS_NumOff, KS_NumOrNoNum, KS_NumDown, KS_NumUp,
+ KS_NumIndentInc, KS_NumIndentDec,
+
+ KS_OutlineLvOff,
+ KS_NextCell, KS_PrevCell, KS_OutlineUp, KS_OutlineDown,
+ KS_GlossaryExpand, KS_NextPrevGlossary,
+ KS_AutoFmtByInput,
+ KS_NextObject, KS_PrevObject,
+ KS_KeyToView,
+ KS_LaunchOLEObject, KS_GoIntoFly, KS_GoIntoDrawing,
+ KS_EnterDrawHandleMode,
+ KS_CheckDocReadOnlyKeys,
+ KS_CheckAutoCorrect, KS_EditFormula,
+ KS_ColLeftBig, KS_ColRightBig,
+ KS_ColLeftSmall, KS_ColRightSmall,
+ KS_ColTopBig, KS_ColBottomBig,
+ KS_ColTopSmall, KS_ColBottomSmall,
+ KS_CellLeftBig, KS_CellRightBig,
+ KS_CellLeftSmall, KS_CellRightSmall,
+ KS_CellTopBig, KS_CellBottomBig,
+ KS_CellTopSmall, KS_CellBottomSmall,
+
+ KS_InsDel_ColLeftBig, KS_InsDel_ColRightBig,
+ KS_InsDel_ColLeftSmall, KS_InsDel_ColRightSmall,
+ KS_InsDel_ColTopBig, KS_InsDel_ColBottomBig,
+ KS_InsDel_ColTopSmall, KS_InsDel_ColBottomSmall,
+ KS_InsDel_CellLeftBig, KS_InsDel_CellRightBig,
+ KS_InsDel_CellLeftSmall, KS_InsDel_CellRightSmall,
+ KS_InsDel_CellTopBig, KS_InsDel_CellBottomBig,
+ KS_InsDel_CellTopSmall, KS_InsDel_CellBottomSmall,
+ KS_TblColCellInsDel,
+
+ KS_Fly_Change, KS_Draw_Change,
+ KS_SpecialInsert,
+ KS_EnterCharCell,
+ KS_GotoNextFieldMark,
+ KS_GotoPrevFieldMark,
+ KS_End };
+
+ SW_KeyState eKeyState = bIsDocReadOnly ? KS_CheckDocReadOnlyKeys : KS_CheckKey;
+ SW_KeyState eNextKeyState = KS_End;
+ sal_uInt8 nDir = 0;
+
+ if (m_nKS_NUMDOWN_Count > 0)
+ m_nKS_NUMDOWN_Count--;
+
+ if (m_nKS_NUMINDENTINC_Count > 0)
+ m_nKS_NUMINDENTINC_Count--;
+
+ while( KS_End != eKeyState )
+ {
+ SW_KeyState eFlyState = KS_KeyToView;
+
+ switch( eKeyState )
+ {
+ case KS_CheckKey:
+ eKeyState = KS_KeyToView; // default forward to View
+
+#if OSL_DEBUG_LEVEL > 1
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ // for switching curor behaviour in ReadOnly regions
+ if( 0x7210 == rKeyCode.GetFullCode() )
+ rSh.SetReadOnlyAvailable( !rSh.IsReadOnlyAvailable() );
+ else
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+#endif
+
+ if( !rKeyCode.IsMod2() && '=' == aCh &&
+ !rSh.IsTableMode() && rSh.GetTableFmt() &&
+ rSh.IsSttPara() &&
+ !rSh.HasReadonlySel() )
+ {
+ // at the beginning of the table's cell a '=' ->
+ // call EditRow (F2-functionality)
+ rSh.Push();
+ if( !rSh.MoveSection( fnSectionCurr, fnSectionStart) &&
+ !rSh.IsTableBoxTextFormat() )
+ {
+ // is at the beginning of the box
+ eKeyState = KS_EditFormula;
+ if( rSh.HasMark() )
+ rSh.SwapPam();
+ else
+ rSh.SttSelect();
+ rSh.MoveSection( fnSectionCurr, fnSectionEnd );
+ rSh.Pop( true );
+ rSh.EndSelect();
+ sFmlEntry = "=";
+ }
+ else
+ rSh.Pop( false );
+ }
+ else
+ {
+ if( pACorr && aTmpQHD.HasCntnt() && !rSh.HasSelection() &&
+ !rSh.HasReadonlySel() && !aTmpQHD.m_bIsAutoText &&
+ pACorr->GetSwFlags().nAutoCmpltExpandKey ==
+ (rKeyCode.GetModifier() | rKeyCode.GetCode()) )
+ {
+ eKeyState = KS_GlossaryExpand;
+ break;
+ }
+
+ switch( rKeyCode.GetModifier() | rKeyCode.GetCode() )
+ {
+ case KEY_RIGHT | KEY_MOD2:
+ eKeyState = KS_ColRightBig;
+ eFlyState = KS_Fly_Change;
+ nDir = MOVE_RIGHT_SMALL;
+ goto KEYINPUT_CHECKTABLE;
+
+ case KEY_LEFT | KEY_MOD2:
+ eKeyState = KS_ColRightSmall;
+ eFlyState = KS_Fly_Change;
+ nDir = MOVE_LEFT_SMALL;
+ goto KEYINPUT_CHECKTABLE;
+
+ case KEY_RIGHT | KEY_MOD2 | KEY_SHIFT:
+ eKeyState = KS_ColLeftSmall;
+ goto KEYINPUT_CHECKTABLE;
+
+ case KEY_LEFT | KEY_MOD2 | KEY_SHIFT:
+ eKeyState = KS_ColLeftBig;
+ goto KEYINPUT_CHECKTABLE;
+
+ case KEY_RIGHT | KEY_MOD2 | KEY_MOD1:
+ eKeyState = KS_CellRightBig;
+ goto KEYINPUT_CHECKTABLE;
+
+ case KEY_LEFT | KEY_MOD2 | KEY_MOD1:
+ eKeyState = KS_CellRightSmall;
+ goto KEYINPUT_CHECKTABLE;
+
+ case KEY_RIGHT | KEY_MOD2 | KEY_SHIFT | KEY_MOD1:
+ eKeyState = KS_CellLeftSmall;
+ goto KEYINPUT_CHECKTABLE;
+
+ case KEY_LEFT | KEY_MOD2 | KEY_SHIFT | KEY_MOD1:
+ eKeyState = KS_CellLeftBig;
+ goto KEYINPUT_CHECKTABLE;
+
+ case KEY_UP | KEY_MOD2:
+ eKeyState = KS_ColBottomSmall;
+ eFlyState = KS_Fly_Change;
+ nDir = MOVE_UP_SMALL;
+ goto KEYINPUT_CHECKTABLE;
+
+ case KEY_DOWN | KEY_MOD2:
+ eKeyState = KS_ColBottomBig;
+ eFlyState = KS_Fly_Change;
+ nDir = MOVE_DOWN_SMALL;
+ goto KEYINPUT_CHECKTABLE;
+
+ case KEY_UP | KEY_MOD2 | KEY_MOD1:
+ eKeyState = KS_CellBottomSmall;
+ goto KEYINPUT_CHECKTABLE;
+
+ case KEY_DOWN | KEY_MOD2 | KEY_MOD1:
+ eKeyState = KS_CellBottomBig;
+ goto KEYINPUT_CHECKTABLE;
+
+ case KEY_UP | KEY_MOD2 | KEY_SHIFT | KEY_MOD1:
+ eKeyState = KS_CellTopBig;
+ goto KEYINPUT_CHECKTABLE;
+
+ case KEY_DOWN | KEY_MOD2 | KEY_SHIFT | KEY_MOD1:
+ eKeyState = KS_CellTopSmall;
+ goto KEYINPUT_CHECKTABLE;
+
+KEYINPUT_CHECKTABLE:
+ if( rSh.IsTableMode() || !rSh.GetTableFmt() )
+ {
+ if(KS_KeyToView != eFlyState)
+ {
+ if(!pFlyFmt && KS_KeyToView != eFlyState &&
+ (rSh.GetSelectionType() & (nsSelectionType::SEL_DRW|nsSelectionType::SEL_DRW_FORM)) &&
+ rSh.GetDrawView()->AreObjectsMarked())
+ eKeyState = KS_Draw_Change;
+ }
+
+ if( pFlyFmt )
+ eKeyState = eFlyState;
+ else if( KS_Draw_Change != eKeyState)
+ eKeyState = KS_EnterCharCell;
+ }
+ break;
+
+ // huge object move
+ case KEY_RIGHT | KEY_SHIFT:
+ case KEY_LEFT | KEY_SHIFT:
+ case KEY_UP | KEY_SHIFT:
+ case KEY_DOWN | KEY_SHIFT:
+ {
+ const int nSelectionType = rSh.GetSelectionType();
+ if ( ( pFlyFmt
+ && ( nSelectionType & (nsSelectionType::SEL_FRM|nsSelectionType::SEL_OLE|nsSelectionType::SEL_GRF) ) )
+ || ( ( nSelectionType & (nsSelectionType::SEL_DRW|nsSelectionType::SEL_DRW_FORM) )
+ && rSh.GetDrawView()->AreObjectsMarked() ) )
+ {
+ eKeyState = pFlyFmt ? KS_Fly_Change : KS_Draw_Change;
+ switch ( rKeyCode.GetCode() )
+ {
+ case KEY_RIGHT: nDir = MOVE_RIGHT_HUGE; break;
+ case KEY_LEFT: nDir = MOVE_LEFT_HUGE; break;
+ case KEY_UP: nDir = MOVE_UP_HUGE; break;
+ case KEY_DOWN: nDir = MOVE_DOWN_HUGE; break;
+ }
+ }
+ break;
+ }
+
+ case KEY_LEFT:
+ case KEY_LEFT | KEY_MOD1:
+ {
+ bool bMod1 = 0 != (rKeyCode.GetModifier() & KEY_MOD1);
+ if(!bMod1)
+ {
+ eFlyState = KS_Fly_Change;
+ nDir = MOVE_LEFT_BIG;
+ }
+ eTblChgMode = nsTblChgWidthHeightType::WH_FLAG_INSDEL |
+ ( bMod1
+ ? nsTblChgWidthHeightType::WH_CELL_LEFT
+ : nsTblChgWidthHeightType::WH_COL_LEFT );
+ nTblChgSize = pModOpt->GetTblVInsert();
+ }
+ goto KEYINPUT_CHECKTABLE_INSDEL;
+ case KEY_RIGHT | KEY_MOD1:
+ {
+ eTblChgMode = nsTblChgWidthHeightType::WH_FLAG_INSDEL | nsTblChgWidthHeightType::WH_CELL_RIGHT;
+ nTblChgSize = pModOpt->GetTblVInsert();
+ }
+ goto KEYINPUT_CHECKTABLE_INSDEL;
+ case KEY_UP:
+ case KEY_UP | KEY_MOD1:
+ {
+ bool bMod1 = 0 != (rKeyCode.GetModifier() & KEY_MOD1);
+ if(!bMod1)
+ {
+ eFlyState = KS_Fly_Change;
+ nDir = MOVE_UP_BIG;
+ }
+ eTblChgMode = nsTblChgWidthHeightType::WH_FLAG_INSDEL |
+ ( bMod1
+ ? nsTblChgWidthHeightType::WH_CELL_TOP
+ : nsTblChgWidthHeightType::WH_ROW_TOP );
+ nTblChgSize = pModOpt->GetTblHInsert();
+ }
+ goto KEYINPUT_CHECKTABLE_INSDEL;
+ case KEY_DOWN:
+ case KEY_DOWN | KEY_MOD1:
+ {
+ bool bMod1 = 0 != (rKeyCode.GetModifier() & KEY_MOD1);
+ if(!bMod1)
+ {
+ eFlyState = KS_Fly_Change;
+ nDir = MOVE_DOWN_BIG;
+ }
+ eTblChgMode = nsTblChgWidthHeightType::WH_FLAG_INSDEL |
+ ( bMod1
+ ? nsTblChgWidthHeightType::WH_CELL_BOTTOM
+ : nsTblChgWidthHeightType::WH_ROW_BOTTOM );
+ nTblChgSize = pModOpt->GetTblHInsert();
+ }
+ goto KEYINPUT_CHECKTABLE_INSDEL;
+
+KEYINPUT_CHECKTABLE_INSDEL:
+ if( rSh.IsTableMode() || !rSh.GetTableFmt() ||
+ !m_bTblInsDelMode ||
+ false /* table protected */
+ )
+ {
+ const int nSelectionType = rSh.GetSelectionType();
+
+ eKeyState = KS_KeyToView;
+ if(KS_KeyToView != eFlyState)
+ {
+ if((nSelectionType & (nsSelectionType::SEL_DRW|nsSelectionType::SEL_DRW_FORM)) &&
+ rSh.GetDrawView()->AreObjectsMarked())
+ eKeyState = KS_Draw_Change;
+ else if(nSelectionType & (nsSelectionType::SEL_FRM|nsSelectionType::SEL_OLE|nsSelectionType::SEL_GRF))
+ eKeyState = KS_Fly_Change;
+ }
+ }
+ else
+ {
+ if( !m_bTblIsInsMode )
+ eTblChgMode = eTblChgMode | nsTblChgWidthHeightType::WH_FLAG_BIGGER;
+ eKeyState = KS_TblColCellInsDel;
+ }
+ break;
+
+ case KEY_DELETE:
+ if ( !rSh.HasReadonlySel() )
+ {
+ if (rSh.IsInFrontOfLabel() && rSh.NumOrNoNum(false))
+ eKeyState = KS_NumOrNoNum;
+ }
+ else
+ {
+ MessageDialog(this, "InfoReadonlyDialog",
+ "modules/swriter/ui/inforeadonlydialog.ui").Execute();
+ eKeyState = KS_End;
+ }
+ break;
+
+ case KEY_DELETE | KEY_MOD2:
+ if( !rSh.IsTableMode() && rSh.GetTableFmt() )
+ {
+ eKeyState = KS_End;
+ m_bTblInsDelMode = true;
+ m_bTblIsInsMode = false;
+ m_aKeyInputTimer.Start();
+ bStopKeyInputTimer = false;
+ }
+ break;
+ case KEY_INSERT | KEY_MOD2:
+ if( !rSh.IsTableMode() && rSh.GetTableFmt() )
+ {
+ eKeyState = KS_End;
+ m_bTblInsDelMode = true;
+ m_bTblIsInsMode = true;
+ m_aKeyInputTimer.Start();
+ bStopKeyInputTimer = false;
+ }
+ break;
+
+ case KEY_RETURN:
+ {
+ if ( !rSh.HasReadonlySel()
+ && !rSh.CrsrInsideInputFld() )
+ {
+ const int nSelectionType = rSh.GetSelectionType();
+ if(nSelectionType & nsSelectionType::SEL_OLE)
+ eKeyState = KS_LaunchOLEObject;
+ else if(nSelectionType & nsSelectionType::SEL_FRM)
+ eKeyState = KS_GoIntoFly;
+ else if((nSelectionType & nsSelectionType::SEL_DRW) &&
+ 0 == (nSelectionType & nsSelectionType::SEL_DRW_TXT) &&
+ rSh.GetDrawView()->GetMarkedObjectList().GetMarkCount() == 1)
+ eKeyState = KS_GoIntoDrawing;
+ else if( aTmpQHD.HasCntnt() && !rSh.HasSelection() &&
+ aTmpQHD.m_bIsAutoText )
+ eKeyState = KS_GlossaryExpand;
+
+ //RETURN and empty paragraph in numbering -> end numbering
+ else if( m_aInBuffer.isEmpty() &&
+ rSh.GetNumRuleAtCurrCrsrPos() &&
+ !rSh.GetNumRuleAtCurrCrsrPos()->IsOutlineRule() &&
+ !rSh.HasSelection() &&
+ rSh.IsSttPara() && rSh.IsEndPara() )
+ eKeyState = KS_NumOff, eNextKeyState = KS_OutlineLvOff;
+
+ //RETURN for new paragraph with AutoFormating
+ else if( pACfg && pACfg->IsAutoFmtByInput() &&
+ !(nSelectionType & (nsSelectionType::SEL_GRF |
+ nsSelectionType::SEL_OLE | nsSelectionType::SEL_FRM |
+ nsSelectionType::SEL_TBL_CELLS | nsSelectionType::SEL_DRW |
+ nsSelectionType::SEL_DRW_TXT)) )
+ eKeyState = KS_CheckAutoCorrect, eNextKeyState = KS_AutoFmtByInput;
+ else
+ eNextKeyState = eKeyState, eKeyState = KS_CheckAutoCorrect;
+ }
+ }
+ break;
+ case KEY_RETURN | KEY_MOD2:
+ {
+ if ( !rSh.HasReadonlySel()
+ && !rSh.IsSttPara()
+ && rSh.GetNumRuleAtCurrCrsrPos()
+ && !rSh.CrsrInsideInputFld() )
+ {
+ eKeyState = KS_NoNum;
+ }
+ else if( rSh.CanSpecialInsert() )
+ eKeyState = KS_SpecialInsert;
+ }
+ break;
+ case KEY_BACKSPACE:
+ case KEY_BACKSPACE | KEY_SHIFT:
+ if ( !rSh.HasReadonlySel()
+ && !rSh.CrsrInsideInputFld() )
+ {
+ bool bDone = false;
+ // try to add comment for code snip:
+ // Remove the paragraph indent, if the cursor is at the
+ // beginning of a paragraph, there is no selection
+ // and no numbering rule found at the current paragraph
+ // Also try to remove indent, if current paragraph
+ // has numbering rule, but isn't counted and only
+ // key <backspace> is hit.
+ const bool bOnlyBackspaceKey( KEY_BACKSPACE == rKeyCode.GetFullCode() );
+ if ( rSh.IsSttPara()
+ && !rSh.HasSelection()
+ && ( rSh.GetNumRuleAtCurrCrsrPos() == NULL
+ || ( rSh.IsNoNum() && bOnlyBackspaceKey ) ) )
+ {
+ bDone = rSh.TryRemoveIndent();
+ }
+
+ if (bDone)
+ eKeyState = KS_End;
+ else
+ {
+ if ( rSh.IsSttPara() && !rSh.IsNoNum() )
+ {
+ if (m_nKS_NUMDOWN_Count > 0 &&
+ 0 < rSh.GetNumLevel())
+ {
+ eKeyState = KS_NumUp;
+ m_nKS_NUMDOWN_Count = 2;
+ bDone = true;
+ }
+ else if (m_nKS_NUMINDENTINC_Count > 0)
+ {
+ eKeyState = KS_NumIndentDec;
+ m_nKS_NUMINDENTINC_Count = 2;
+ bDone = true;
+ }
+ }
+
+ // If the cursor is in an empty paragraph, which has
+ // a numbering, but not the outline numbering, and
+ // there is no selection, the numbering has to be
+ // deleted on key <Backspace>.
+ // Otherwise method <SwEditShell::NumOrNoNum(..)>
+ // should only change the <IsCounted()> state of
+ // the current paragraph depending of the key.
+ // On <backspace> it is set to <false>,
+ // on <shift-backspace> it is set to <true>.
+ // Thus, assure that method <SwEditShell::NumOrNum(..)>
+ // is only called for the intended purpose.
+ if ( !bDone && rSh.IsSttPara() )
+ {
+ bool bCallNumOrNoNum( false );
+ if ( bOnlyBackspaceKey && !rSh.IsNoNum() )
+ {
+ bCallNumOrNoNum = true;
+ }
+ else if ( !bOnlyBackspaceKey && rSh.IsNoNum() )
+ {
+ bCallNumOrNoNum = true;
+ }
+ else if ( bOnlyBackspaceKey
+ && rSh.IsSttPara()
+ && rSh.IsEndPara()
+ && !rSh.HasSelection() )
+ {
+ const SwNumRule* pCurrNumRule( rSh.GetNumRuleAtCurrCrsrPos() );
+ if ( pCurrNumRule != NULL
+ && pCurrNumRule != rSh.GetOutlineNumRule() )
+ {
+ bCallNumOrNoNum = true;
+ }
+ }
+ if ( bCallNumOrNoNum
+ && rSh.NumOrNoNum( !bOnlyBackspaceKey, true ) )
+ {
+ eKeyState = KS_NumOrNoNum;
+ }
+ }
+ }
+ }
+ else
+ {
+ MessageDialog(this, "InfoReadonlyDialog",
+ "modules/swriter/ui/inforeadonlydialog.ui").Execute();
+ eKeyState = KS_End;
+ }
+ break;
+
+ case KEY_RIGHT:
+ {
+ eFlyState = KS_Fly_Change;
+ nDir = MOVE_RIGHT_BIG;
+ eTblChgMode = nsTblChgWidthHeightType::WH_FLAG_INSDEL | nsTblChgWidthHeightType::WH_COL_RIGHT;
+ nTblChgSize = pModOpt->GetTblVInsert();
+ goto KEYINPUT_CHECKTABLE_INSDEL;
+ }
+ case KEY_TAB:
+ {
+
+ if (rSh.IsFormProtected() || rSh.GetCurrentFieldmark() || rSh.GetChar(false)==CH_TXT_ATR_FORMELEMENT)
+ {
+ eKeyState=KS_GotoNextFieldMark;
+ }
+ else if ( !rSh.IsMultiSelection() && rSh.CrsrInsideInputFld() )
+ {
+ GetView().GetViewFrame()->GetDispatcher()->Execute( FN_GOTO_NEXT_INPUTFLD );
+ eKeyState = KS_End;
+ }
+ else if( rSh.GetNumRuleAtCurrCrsrPos()
+ && rSh.IsSttOfPara()
+ && !rSh.HasReadonlySel() )
+ {
+ if ( !rSh.IsMultiSelection()
+ && rSh.IsFirstOfNumRuleAtCrsrPos()
+ && numfunc::ChangeIndentOnTabAtFirstPosOfFirstListItem() )
+ eKeyState = KS_NumIndentInc;
+ else
+ eKeyState = KS_NumDown;
+ }
+ else if ( rSh.GetTableFmt() )
+ {
+ if( rSh.HasSelection() || rSh.HasReadonlySel() )
+ eKeyState = KS_NextCell;
+ else
+ eKeyState = KS_CheckAutoCorrect, eNextKeyState = KS_NextCell;
+ }
+ else if ( rSh.GetSelectionType() &
+ (nsSelectionType::SEL_GRF |
+ nsSelectionType::SEL_FRM |
+ nsSelectionType::SEL_OLE |
+ nsSelectionType::SEL_DRW |
+ nsSelectionType::SEL_DRW_FORM))
+
+ eKeyState = KS_NextObject;
+ else
+ {
+ eKeyState = KS_InsTab;
+ if( rSh.IsSttOfPara() && !rSh.HasReadonlySel() )
+ {
+ SwTxtFmtColl* pColl = rSh.GetCurTxtFmtColl();
+ if( pColl &&
+
+ pColl->IsAssignedToListLevelOfOutlineStyle()
+ && MAXLEVEL-1 > pColl->GetAssignedOutlineStyleLevel() )
+ eKeyState = KS_OutlineDown;
+ }
+ }
+ }
+ break;
+ case KEY_TAB | KEY_SHIFT:
+ {
+ if (rSh.IsFormProtected() || rSh.GetCurrentFieldmark()|| rSh.GetChar(false)==CH_TXT_ATR_FORMELEMENT)
+ {
+ eKeyState=KS_GotoPrevFieldMark;
+ }
+ else if ( !rSh.IsMultiSelection() && rSh.CrsrInsideInputFld() )
+ {
+ GetView().GetViewFrame()->GetDispatcher()->Execute( FN_GOTO_PREV_INPUTFLD );
+ eKeyState = KS_End;
+ }
+ else if( rSh.GetNumRuleAtCurrCrsrPos()
+ && rSh.IsSttOfPara()
+ && !rSh.HasReadonlySel() )
+ {
+ if ( !rSh.IsMultiSelection()
+ && rSh.IsFirstOfNumRuleAtCrsrPos()
+ && numfunc::ChangeIndentOnTabAtFirstPosOfFirstListItem() )
+ eKeyState = KS_NumIndentDec;
+ else
+ eKeyState = KS_NumUp;
+ }
+ else if ( rSh.GetTableFmt() )
+ {
+ if( rSh.HasSelection() || rSh.HasReadonlySel() )
+ eKeyState = KS_PrevCell;
+ else
+ eKeyState = KS_CheckAutoCorrect, eNextKeyState = KS_PrevCell;
+ }
+ else if ( rSh.GetSelectionType() &
+ (nsSelectionType::SEL_GRF |
+ nsSelectionType::SEL_FRM |
+ nsSelectionType::SEL_OLE |
+ nsSelectionType::SEL_DRW |
+ nsSelectionType::SEL_DRW_FORM))
+
+ eKeyState = KS_PrevObject;
+ else
+ {
+ eKeyState = KS_End;
+ if( rSh.IsSttOfPara() && !rSh.HasReadonlySel() )
+ {
+ SwTxtFmtColl* pColl = rSh.GetCurTxtFmtColl();
+ if( pColl &&
+ pColl->IsAssignedToListLevelOfOutlineStyle() &&
+ 0 < pColl->GetAssignedOutlineStyleLevel())
+ eKeyState = KS_OutlineUp;
+ }
+ }
+ }
+ break;
+ case KEY_TAB | KEY_MOD1:
+ case KEY_TAB | KEY_MOD2:
+ if( !rSh.HasReadonlySel() )
+ {
+ if( aTmpQHD.HasCntnt() && !rSh.HasSelection() )
+ {
+ // Next auto-complete suggestion
+ aTmpQHD.Next( pACorr &&
+ pACorr->GetSwFlags().bAutoCmpltEndless );
+ eKeyState = KS_NextPrevGlossary;
+ }
+ else if( rSh.GetTableFmt() )
+ eKeyState = KS_InsTab;
+ else if((rSh.GetSelectionType() &
+ (nsSelectionType::SEL_DRW|nsSelectionType::SEL_DRW_FORM|
+ nsSelectionType::SEL_FRM|nsSelectionType::SEL_OLE|nsSelectionType::SEL_GRF)) &&
+ rSh.GetDrawView()->AreObjectsMarked())
+ eKeyState = KS_EnterDrawHandleMode;
+ else
+ {
+ eKeyState = KS_InsTab;
+ }
+ }
+ break;
+
+ case KEY_TAB | KEY_MOD1 | KEY_SHIFT:
+ {
+ if( aTmpQHD.HasCntnt() && !rSh.HasSelection() &&
+ !rSh.HasReadonlySel() )
+ {
+ // Previous auto-complete suggestion.
+ aTmpQHD.Previous( pACorr &&
+ pACorr->GetSwFlags().bAutoCmpltEndless );
+ eKeyState = KS_NextPrevGlossary;
+ }
+ else if((rSh.GetSelectionType() & (nsSelectionType::SEL_DRW|nsSelectionType::SEL_DRW_FORM|
+ nsSelectionType::SEL_FRM|nsSelectionType::SEL_OLE|nsSelectionType::SEL_GRF)) &&
+ rSh.GetDrawView()->AreObjectsMarked())
+ {
+ eKeyState = KS_EnterDrawHandleMode;
+ }
+ }
+ break;
+ case KEY_F2 :
+ if( !rSh.HasReadonlySel() )
+ {
+ const int nSelectionType = rSh.GetSelectionType();
+ if(nSelectionType & nsSelectionType::SEL_FRM)
+ eKeyState = KS_GoIntoFly;
+ else if((nSelectionType & nsSelectionType::SEL_DRW))
+ eKeyState = KS_GoIntoDrawing;
+ }
+ break;
+ }
+ }
+ break;
+ case KS_CheckDocReadOnlyKeys:
+ {
+ eKeyState = KS_KeyToView;
+ switch( rKeyCode.GetModifier() | rKeyCode.GetCode() )
+ {
+ case KEY_TAB:
+ case KEY_TAB | KEY_SHIFT:
+ bNormalChar = false;
+ eKeyState = KS_End;
+ if ( rSh.GetSelectionType() &
+ (nsSelectionType::SEL_GRF |
+ nsSelectionType::SEL_FRM |
+ nsSelectionType::SEL_OLE |
+ nsSelectionType::SEL_DRW |
+ nsSelectionType::SEL_DRW_FORM))
+
+ {
+ eKeyState = rKeyCode.GetModifier() & KEY_SHIFT ?
+ KS_PrevObject : KS_NextObject;
+ }
+ else if ( !rSh.IsMultiSelection() && rSh.CrsrInsideInputFld() )
+ {
+ GetView().GetViewFrame()->GetDispatcher()->Execute(
+ KEY_SHIFT != rKeyCode.GetModifier() ? FN_GOTO_NEXT_INPUTFLD : FN_GOTO_PREV_INPUTFLD );
+ }
+ else
+ {
+ rSh.SelectNextPrevHyperlink( KEY_SHIFT != rKeyCode.GetModifier() );
+ }
+ break;
+ case KEY_RETURN:
+ {
+ const int nSelectionType = rSh.GetSelectionType();
+ if(nSelectionType & nsSelectionType::SEL_FRM)
+ eKeyState = KS_GoIntoFly;
+ else
+ {
+ SfxItemSet aSet(rSh.GetAttrPool(), RES_TXTATR_INETFMT, RES_TXTATR_INETFMT);
+ rSh.GetCurAttr(aSet);
+ if(SFX_ITEM_SET == aSet.GetItemState(RES_TXTATR_INETFMT, false))
+ {
+ const SfxPoolItem& rItem = aSet.Get(RES_TXTATR_INETFMT, true);
+ bNormalChar = false;
+ eKeyState = KS_End;
+ rSh.ClickToINetAttr((const SwFmtINetFmt&)rItem, URLLOAD_NOFILTER);
+ }
+ }
+ }
+ break;
+ }
+ }
+ break;
+
+ case KS_EnterCharCell:
+ {
+ eKeyState = KS_KeyToView;
+ switch ( rKeyCode.GetModifier() | rKeyCode.GetCode() )
+ {
+ case KEY_RIGHT | KEY_MOD2:
+ rSh.Right( CRSR_SKIP_CHARS, false, 1, false );
+ eKeyState = KS_End;
+ FlushInBuffer();
+ break;
+ case KEY_LEFT | KEY_MOD2:
+ rSh.Left( CRSR_SKIP_CHARS, false, 1, false );
+ eKeyState = KS_End;
+ FlushInBuffer();
+ break;
+ }
+ }
+ break;
+
+ case KS_KeyToView:
+ {
+ eKeyState = KS_End;
+ bNormalChar =
+ !rKeyCode.IsMod2() &&
+ rKeyCode.GetModifier() != (KEY_MOD1) &&
+ rKeyCode.GetModifier() != (KEY_MOD1|KEY_SHIFT) &&
+ SW_ISPRINTABLE( aCh );
+
+ if( bNormalChar && rSh.IsInFrontOfLabel() )
+ {
+ rSh.NumOrNoNum(false);
+ }
+
+ if( !m_aInBuffer.isEmpty() && ( !bNormalChar || bIsDocReadOnly ))
+ FlushInBuffer();
+
+ if( m_rView.KeyInput( aKeyEvent ) )
+ bFlushBuffer = true, bNormalChar = false;
+ else
+ {
+ // Because Sfx accelerators are only called when they were
+ // enabled at the last status update, copy has to called
+ // 'forcefully' by us if necessary.
+ if( rKeyCode.GetFunction() == KEYFUNC_COPY )
+ GetView().GetViewFrame()->GetBindings().Execute(SID_COPY);
+
+ if( !bIsDocReadOnly && bNormalChar )
+ {
+ const int nSelectionType = rSh.GetSelectionType();
+ if((nSelectionType & nsSelectionType::SEL_DRW) &&
+ 0 == (nSelectionType & nsSelectionType::SEL_DRW_TXT) &&
+ rSh.GetDrawView()->GetMarkedObjectList().GetMarkCount() == 1)
+ {
+ SdrObject* pObj = rSh.GetDrawView()->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj();
+ if(pObj)
+ {
+ EnterDrawTextMode(pObj->GetLogicRect().Center());
+ if ( m_rView.GetCurShell()->ISA(SwDrawTextShell) )
+ ((SwDrawTextShell*)m_rView.GetCurShell())->Init();
+ rSh.GetDrawView()->KeyInput( rKEvt, this );
+ }
+ }
+ else if(nSelectionType & nsSelectionType::SEL_FRM)
+ {
+ rSh.UnSelectFrm();
+ rSh.LeaveSelFrmMode();
+ m_rView.AttrChangedNotify(&rSh);
+ rSh.MoveSection( fnSectionCurr, fnSectionEnd );
+ }
+ eKeyState = KS_InsChar;
+ }
+ else
+ {
+ bNormalChar = false;
+ Window::KeyInput( aKeyEvent );
+ }
+ }
+ }
+ break;
+ case KS_LaunchOLEObject:
+ {
+ rSh.LaunchOLEObj();
+ eKeyState = KS_End;
+ }
+ break;
+ case KS_GoIntoFly:
+ {
+ rSh.UnSelectFrm();
+ rSh.LeaveSelFrmMode();
+ m_rView.AttrChangedNotify(&rSh);
+ rSh.MoveSection( fnSectionCurr, fnSectionEnd );
+ eKeyState = KS_End;
+ }
+ break;
+ case KS_GoIntoDrawing:
+ {
+ SdrObject* pObj = rSh.GetDrawView()->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj();
+ if(pObj)
+ {
+ EnterDrawTextMode(pObj->GetLogicRect().Center());
+ if ( m_rView.GetCurShell()->ISA(SwDrawTextShell) )
+ ((SwDrawTextShell*)m_rView.GetCurShell())->Init();
+ }
+ eKeyState = KS_End;
+ }
+ break;
+ case KS_EnterDrawHandleMode:
+ {
+ const SdrHdlList& rHdlList = rSh.GetDrawView()->GetHdlList();
+ bool bForward(!aKeyEvent.GetKeyCode().IsShift());
+
+ ((SdrHdlList&)rHdlList).TravelFocusHdl(bForward);
+ eKeyState = KS_End;
+ }
+ break;
+ case KS_InsTab:
+ if( m_rView.ISA( SwWebView )) // no Tab for WebView
+ {
+ // then it should be passed along
+ Window::KeyInput( aKeyEvent );
+ eKeyState = KS_End;
+ break;
+ }
+ aCh = '\t';
+ // no break!
+ case KS_InsChar:
+ if (rSh.GetChar(false)==CH_TXT_ATR_FORMELEMENT)
+ {
+ ::sw::mark::ICheckboxFieldmark* pFieldmark =
+ dynamic_cast< ::sw::mark::ICheckboxFieldmark* >
+ (rSh.GetCurrentFieldmark());
+ OSL_ENSURE(pFieldmark,
+ "Where is my FieldMark??");
+ if(pFieldmark)
+ {
+ pFieldmark->SetChecked(!pFieldmark->IsChecked());
+ OSL_ENSURE(pFieldmark->IsExpanded(),
+ "where is the otherpos?");
+ if (pFieldmark->IsExpanded())
+ {
+ rSh.CalcLayout();
+ }
+ }
+ eKeyState = KS_End;
+ }
+ else if ( !rSh.HasReadonlySel()
+ || rSh.CrsrInsideInputFld() )
+ {
+ const bool bIsNormalChar =
+ GetAppCharClass().isLetterNumeric( OUString( aCh ), 0 );
+ if( bAppendSpace && bIsNormalChar &&
+ (!m_aInBuffer.isEmpty() || !rSh.IsSttPara() || !rSh.IsEndPara() ))
+ {
+ // insert a blank ahead of the character. this ends up
+ // between the expanded text and the new "non-word-separator".
+ m_aInBuffer += " ";
+ }
+
+ const bool bIsAutoCorrectChar = SvxAutoCorrect::IsAutoCorrectChar( aCh );
+ const bool bRunNext = pACorr != NULL && pACorr->HasRunNext();
+ if( !aKeyEvent.GetRepeat() && pACorr && ( bIsAutoCorrectChar || bRunNext ) &&
+ pACfg->IsAutoFmtByInput() &&
+ (( pACorr->IsAutoCorrFlag( ChgWeightUnderl ) &&
+ ( '*' == aCh || '_' == aCh ) ) ||
+ ( pACorr->IsAutoCorrFlag( ChgQuotes ) && ('\"' == aCh ))||
+ ( pACorr->IsAutoCorrFlag( ChgSglQuotes ) && ( '\'' == aCh))))
+ {
+ FlushInBuffer();
+ rSh.AutoCorrect( *pACorr, aCh );
+ if( '\"' != aCh && '\'' != aCh ) // only call when "*_"!
+ rSh.UpdateAttr();
+ }
+ else if( !aKeyEvent.GetRepeat() && pACorr && ( bIsAutoCorrectChar || bRunNext ) &&
+ pACfg->IsAutoFmtByInput() &&
+ pACorr->IsAutoCorrFlag( CptlSttSntnc | CptlSttWrd |
+ ChgOrdinalNumber | AddNonBrkSpace |
+ ChgToEnEmDash | SetINetAttr |
+ Autocorrect ) &&
+ '\"' != aCh && '\'' != aCh && '*' != aCh && '_' != aCh
+ )
+ {
+ FlushInBuffer();
+ rSh.AutoCorrect( *pACorr, aCh );
+ }
+ else
+ {
+ OUStringBuffer aBuf(m_aInBuffer);
+ comphelper::string::padToLength(aBuf,
+ m_aInBuffer.getLength() + aKeyEvent.GetRepeat() + 1, aCh);
+ m_aInBuffer = aBuf.makeStringAndClear();
+ bFlushCharBuffer = Application::AnyInput( VCL_INPUT_KEYBOARD );
+ bFlushBuffer = !bFlushCharBuffer;
+ if( bFlushCharBuffer )
+ m_aKeyInputFlushTimer.Start();
+ }
+ eKeyState = KS_End;
+ }
+ else
+ {
+ MessageDialog(this, "InfoReadonlyDialog",
+ "modules/swriter/ui/inforeadonlydialog.ui").Execute();
+ eKeyState = KS_End;
+ }
+ break;
+
+ case KS_CheckAutoCorrect:
+ {
+ if( pACorr && pACfg->IsAutoFmtByInput() &&
+ pACorr->IsAutoCorrFlag( CptlSttSntnc | CptlSttWrd |
+ ChgOrdinalNumber |
+ ChgToEnEmDash | SetINetAttr |
+ Autocorrect ) &&
+ !rSh.HasReadonlySel() )
+ {
+ FlushInBuffer();
+ rSh.AutoCorrect( *pACorr, static_cast< sal_Unicode >('\0') );
+ }
+ eKeyState = eNextKeyState;
+ }
+ break;
+
+ default:
+ {
+ sal_uInt16 nSlotId = 0;
+ FlushInBuffer();
+ switch( eKeyState )
+ {
+ case KS_SpecialInsert:
+ rSh.DoSpecialInsert();
+ break;
+
+ case KS_NoNum:
+ rSh.NoNum();
+ break;
+
+ case KS_NumOff:
+ // shell change - so record in advance
+ rSh.DelNumRules();
+ eKeyState = eNextKeyState;
+ break;
+ case KS_OutlineLvOff: // delete autofmt outlinelevel later
+ break;
+
+ case KS_NumDown:
+ rSh.NumUpDown( true );
+ m_nKS_NUMDOWN_Count = 2;
+ break;
+ case KS_NumUp:
+ rSh.NumUpDown( false );
+ break;
+
+ case KS_NumIndentInc:
+ rSh.ChangeIndentOfAllListLevels(360);
+ m_nKS_NUMINDENTINC_Count = 2;
+ break;
+
+ case KS_GotoNextFieldMark:
+ {
+ ::sw::mark::IFieldmark const * const pFieldmark = rSh.GetFieldmarkAfter();
+ if(pFieldmark) rSh.GotoFieldmark(pFieldmark);
+ }
+ break;
+
+ case KS_GotoPrevFieldMark:
+ {
+ ::sw::mark::IFieldmark const * const pFieldmark = rSh.GetFieldmarkBefore();
+ if( pFieldmark )
+ rSh.GotoFieldmark(pFieldmark);
+ }
+ break;
+
+ case KS_NumIndentDec:
+ rSh.ChangeIndentOfAllListLevels(-360);
+ break;
+
+ case KS_OutlineDown:
+ rSh.OutlineUpDown( 1 );
+ break;
+ case KS_OutlineUp:
+ rSh.OutlineUpDown( -1 );
+ break;
+
+ case KS_NextCell:
+ // always 'flush' in tables
+ rSh.GoNextCell();
+ nSlotId = FN_GOTO_NEXT_CELL;
+ break;
+ case KS_PrevCell:
+ rSh.GoPrevCell();
+ nSlotId = FN_GOTO_PREV_CELL;
+ break;
+ case KS_AutoFmtByInput:
+ rSh.SplitNode( true );
+ break;
+
+ case KS_NextObject:
+ case KS_PrevObject:
+ if(rSh.GotoObj( KS_NextObject == eKeyState, GOTOOBJ_GOTO_ANY))
+ {
+ if( rSh.IsFrmSelected() &&
+ m_rView.GetDrawFuncPtr() )
+ {
+ m_rView.GetDrawFuncPtr()->Deactivate();
+ m_rView.SetDrawFuncPtr(NULL);
+ m_rView.LeaveDrawCreate();
+ m_rView.AttrChangedNotify( &rSh );
+ }
+ rSh.HideCrsr();
+ rSh.EnterSelFrmMode();
+ }
+ break;
+ case KS_GlossaryExpand:
+ {
+ // replace the word or abbreviation with the auto text
+ rSh.StartUndo( UNDO_START );
+
+ OUString sFnd( aTmpQHD.m_aHelpStrings[ aTmpQHD.nCurArrPos ] );
+ if( aTmpQHD.m_bIsAutoText )
+ {
+ SwGlossaryList* pList = ::GetGlossaryList();
+ OUString sShrtNm;
+ OUString sGroup;
+ if(pList->GetShortName( sFnd, sShrtNm, sGroup))
+ {
+ rSh.SttSelect();
+ rSh.ExtendSelection( false, aTmpQHD.nLen );
+ SwGlossaryHdl* pGlosHdl = GetView().GetGlosHdl();
+ pGlosHdl->SetCurGroup(sGroup, true);
+ pGlosHdl->InsertGlossary( sShrtNm);
+ m_pQuickHlpData->m_bAppendSpace = true;
+ }
+ }
+ else
+ {
+ sFnd = sFnd.copy( aTmpQHD.nLen );
+ rSh.Insert( sFnd );
+ m_pQuickHlpData->m_bAppendSpace = !pACorr ||
+ pACorr->GetSwFlags().bAutoCmpltAppendBlanc;
+ }
+ rSh.EndUndo( UNDO_END );
+ }
+ break;
+
+ case KS_NextPrevGlossary:
+ m_pQuickHlpData->Move( aTmpQHD );
+ m_pQuickHlpData->Start( rSh, USHRT_MAX );
+ break;
+
+ case KS_EditFormula:
+ {
+ const sal_uInt16 nId = SwInputChild::GetChildWindowId();
+
+ SfxViewFrame* pVFrame = GetView().GetViewFrame();
+ pVFrame->ToggleChildWindow( nId );
+ SwInputChild* pChildWin = (SwInputChild*)pVFrame->
+ GetChildWindow( nId );
+ if( pChildWin )
+ pChildWin->SetFormula( sFmlEntry );
+ }
+ break;
+
+ case KS_ColLeftBig: rSh.SetColRowWidthHeight( nsTblChgWidthHeightType::WH_COL_LEFT|nsTblChgWidthHeightType::WH_FLAG_BIGGER, pModOpt->GetTblHMove() ); break;
+ case KS_ColRightBig: rSh.SetColRowWidthHeight( nsTblChgWidthHeightType::WH_COL_RIGHT|nsTblChgWidthHeightType::WH_FLAG_BIGGER, pModOpt->GetTblHMove() ); break;
+ case KS_ColLeftSmall: rSh.SetColRowWidthHeight( nsTblChgWidthHeightType::WH_COL_LEFT, pModOpt->GetTblHMove() ); break;
+ case KS_ColRightSmall: rSh.SetColRowWidthHeight( nsTblChgWidthHeightType::WH_COL_RIGHT, pModOpt->GetTblHMove() ); break;
+ case KS_ColBottomBig: rSh.SetColRowWidthHeight( nsTblChgWidthHeightType::WH_ROW_BOTTOM|nsTblChgWidthHeightType::WH_FLAG_BIGGER, pModOpt->GetTblVMove() ); break;
+ case KS_ColBottomSmall: rSh.SetColRowWidthHeight( nsTblChgWidthHeightType::WH_ROW_BOTTOM, pModOpt->GetTblVMove() ); break;
+ case KS_CellLeftBig: rSh.SetColRowWidthHeight( nsTblChgWidthHeightType::WH_CELL_LEFT|nsTblChgWidthHeightType::WH_FLAG_BIGGER, pModOpt->GetTblHMove() ); break;
+ case KS_CellRightBig: rSh.SetColRowWidthHeight( nsTblChgWidthHeightType::WH_CELL_RIGHT|nsTblChgWidthHeightType::WH_FLAG_BIGGER, pModOpt->GetTblHMove() ); break;
+ case KS_CellLeftSmall: rSh.SetColRowWidthHeight( nsTblChgWidthHeightType::WH_CELL_LEFT, pModOpt->GetTblHMove() ); break;
+ case KS_CellRightSmall: rSh.SetColRowWidthHeight( nsTblChgWidthHeightType::WH_CELL_RIGHT, pModOpt->GetTblHMove() ); break;
+ case KS_CellTopBig: rSh.SetColRowWidthHeight( nsTblChgWidthHeightType::WH_CELL_TOP|nsTblChgWidthHeightType::WH_FLAG_BIGGER, pModOpt->GetTblVMove() ); break;
+ case KS_CellBottomBig: rSh.SetColRowWidthHeight( nsTblChgWidthHeightType::WH_CELL_BOTTOM|nsTblChgWidthHeightType::WH_FLAG_BIGGER, pModOpt->GetTblVMove() ); break;
+ case KS_CellTopSmall: rSh.SetColRowWidthHeight( nsTblChgWidthHeightType::WH_CELL_TOP, pModOpt->GetTblVMove() ); break;
+ case KS_CellBottomSmall: rSh.SetColRowWidthHeight( nsTblChgWidthHeightType::WH_CELL_BOTTOM, pModOpt->GetTblVMove() ); break;
+
+ case KS_InsDel_ColLeftBig: rSh.SetColRowWidthHeight( nsTblChgWidthHeightType::WH_FLAG_INSDEL|nsTblChgWidthHeightType::WH_COL_LEFT|nsTblChgWidthHeightType::WH_FLAG_BIGGER, pModOpt->GetTblHInsert() ); break;
+ case KS_InsDel_ColRightBig: rSh.SetColRowWidthHeight( nsTblChgWidthHeightType::WH_FLAG_INSDEL|nsTblChgWidthHeightType::WH_COL_RIGHT|nsTblChgWidthHeightType::WH_FLAG_BIGGER, pModOpt->GetTblHInsert() ); break;
+ case KS_InsDel_ColLeftSmall: rSh.SetColRowWidthHeight( nsTblChgWidthHeightType::WH_FLAG_INSDEL|nsTblChgWidthHeightType::WH_COL_LEFT, pModOpt->GetTblHInsert() ); break;
+ case KS_InsDel_ColRightSmall: rSh.SetColRowWidthHeight( nsTblChgWidthHeightType::WH_FLAG_INSDEL|nsTblChgWidthHeightType::WH_COL_RIGHT, pModOpt->GetTblHInsert() ); break;
+ case KS_InsDel_ColTopBig: rSh.SetColRowWidthHeight( nsTblChgWidthHeightType::WH_FLAG_INSDEL|nsTblChgWidthHeightType::WH_ROW_TOP|nsTblChgWidthHeightType::WH_FLAG_BIGGER, pModOpt->GetTblVInsert() ); break;
+ case KS_InsDel_ColBottomBig: rSh.SetColRowWidthHeight( nsTblChgWidthHeightType::WH_FLAG_INSDEL|nsTblChgWidthHeightType::WH_ROW_BOTTOM|nsTblChgWidthHeightType::WH_FLAG_BIGGER, pModOpt->GetTblVInsert() ); break;
+ case KS_InsDel_ColTopSmall: rSh.SetColRowWidthHeight( nsTblChgWidthHeightType::WH_FLAG_INSDEL|nsTblChgWidthHeightType::WH_ROW_TOP, pModOpt->GetTblVInsert() ); break;
+ case KS_InsDel_ColBottomSmall: rSh.SetColRowWidthHeight( nsTblChgWidthHeightType::WH_FLAG_INSDEL|nsTblChgWidthHeightType::WH_ROW_BOTTOM, pModOpt->GetTblVInsert() ); break;
+ case KS_InsDel_CellLeftBig: rSh.SetColRowWidthHeight( nsTblChgWidthHeightType::WH_FLAG_INSDEL|nsTblChgWidthHeightType::WH_CELL_LEFT|nsTblChgWidthHeightType::WH_FLAG_BIGGER, pModOpt->GetTblHInsert() ); break;
+ case KS_InsDel_CellRightBig: rSh.SetColRowWidthHeight( nsTblChgWidthHeightType::WH_FLAG_INSDEL|nsTblChgWidthHeightType::WH_CELL_RIGHT|nsTblChgWidthHeightType::WH_FLAG_BIGGER, pModOpt->GetTblHInsert() ); break;
+ case KS_InsDel_CellLeftSmall: rSh.SetColRowWidthHeight( nsTblChgWidthHeightType::WH_FLAG_INSDEL|nsTblChgWidthHeightType::WH_CELL_LEFT, pModOpt->GetTblHInsert() ); break;
+ case KS_InsDel_CellRightSmall: rSh.SetColRowWidthHeight( nsTblChgWidthHeightType::WH_FLAG_INSDEL|nsTblChgWidthHeightType::WH_CELL_RIGHT, pModOpt->GetTblHInsert() ); break;
+ case KS_InsDel_CellTopBig: rSh.SetColRowWidthHeight( nsTblChgWidthHeightType::WH_FLAG_INSDEL|nsTblChgWidthHeightType::WH_CELL_TOP|nsTblChgWidthHeightType::WH_FLAG_BIGGER, pModOpt->GetTblVInsert() ); break;
+ case KS_InsDel_CellBottomBig: rSh.SetColRowWidthHeight( nsTblChgWidthHeightType::WH_FLAG_INSDEL|nsTblChgWidthHeightType::WH_CELL_BOTTOM|nsTblChgWidthHeightType::WH_FLAG_BIGGER, pModOpt->GetTblVInsert() ); break;
+ case KS_InsDel_CellTopSmall: rSh.SetColRowWidthHeight( nsTblChgWidthHeightType::WH_FLAG_INSDEL|nsTblChgWidthHeightType::WH_CELL_TOP, pModOpt->GetTblVInsert() ); break;
+ case KS_InsDel_CellBottomSmall: rSh.SetColRowWidthHeight( nsTblChgWidthHeightType::WH_FLAG_INSDEL|nsTblChgWidthHeightType::WH_CELL_BOTTOM, pModOpt->GetTblVInsert() ); break;
+
+ case KS_TblColCellInsDel:
+ rSh.SetColRowWidthHeight( eTblChgMode, nTblChgSize );
+ break;
+ case KS_Fly_Change:
+ {
+ SdrView *pSdrView = rSh.GetDrawView();
+ const SdrHdlList& rHdlList = pSdrView->GetHdlList();
+ if(rHdlList.GetFocusHdl())
+ ChangeDrawing( nDir );
+ else
+ ChangeFly( nDir, m_rView.ISA( SwWebView ) );
+ }
+ break;
+ case KS_Draw_Change :
+ ChangeDrawing( nDir );
+ break;
+ default:
+ break;
+ }
+ if( nSlotId && m_rView.GetViewFrame()->GetBindings().GetRecorder().is() )
+ {
+ SfxRequest aReq(m_rView.GetViewFrame(), nSlotId );
+ aReq.Done();
+ }
+ eKeyState = KS_End;
+ }
+ }
+ }
+
+ if( bStopKeyInputTimer )
+ {
+ m_aKeyInputTimer.Stop();
+ m_bTblInsDelMode = false;
+ }
+
+ // in case the buffered characters are inserted
+ if( bFlushBuffer && !m_aInBuffer.isEmpty() )
+ {
+ // bFlushCharBuffer was not resetted here
+ // why not?
+ bool bSave = bFlushCharBuffer;
+ FlushInBuffer();
+ bFlushCharBuffer = bSave;
+
+ // maybe show Tip-Help
+ OUString sWord;
+ if( bNormalChar && pACfg && pACorr &&
+ ( pACfg->IsAutoTextTip() ||
+ pACorr->GetSwFlags().bAutoCompleteWords ) &&
+ rSh.GetPrevAutoCorrWord( *pACorr, sWord ) )
+ {
+ ShowAutoTextCorrectQuickHelp(sWord, pACfg, pACorr);
+ }
+ }
+
+ // get the word count dialog to update itself
+ SwWordCountWrapper *pWrdCnt = (SwWordCountWrapper*)GetView().GetViewFrame()->GetChildWindow(SwWordCountWrapper::GetChildWindowId());
+ if( pWrdCnt )
+ pWrdCnt->UpdateCounts();
+
+}
+
+/**
+ * MouseEvents
+ */
+void SwEditWin::RstMBDownFlags()
+{
+ // Not on all systems a MouseButtonUp is used ahead
+ // of the modal dialog (like on WINDOWS).
+ // So reset the statuses here and release the mouse
+ // for the dialog.
+ m_bMBPressed = false;
+ bNoInterrupt = false;
+ EnterArea();
+ ReleaseMouse();
+}
+
+/**
+ * Determines if the current position has a clickable url over a background
+ * frame. In that case, ctrl-click should select the url, not the frame.
+ */
+static bool lcl_urlOverBackground(SwWrtShell& rSh, const Point& rDocPos)
+{
+ SwContentAtPos aSwContentAtPos(SwContentAtPos::SW_INETATTR);
+ SdrObject* pSelectableObj = rSh.GetObjAt(rDocPos);
+
+ return rSh.GetContentAtPos(rDocPos, aSwContentAtPos) && pSelectableObj->GetLayer() == rSh.GetDoc()->GetHellId();
+}
+
+#if !HAVE_FEATURE_DESKTOP
+
+// As such these two functions could be more or less anywhere, I have
+// them now in this source file because the act of moving a selection
+// end point is somewhat the same as what happens when one
+// shift-clicks on either side of an existing selection.
+
+void touch_lo_selection_start_move_impl(const void *documentHandle,
+ int x,
+ int y)
+{
+ SwWrtShell *pWrtShell = reinterpret_cast<SwWrtShell*>(const_cast<void*>(documentHandle));
+
+ if (!pWrtShell)
+ return;
+
+ const OutputDevice *pOut = pWrtShell->GetWin();
+ if (!pOut)
+ pOut = pWrtShell->GetOut();
+
+ const Point aDocPos( pOut->PixelToLogic( Point(x, y) ) );
+
+ // Don't allow moving the start of the selection beyond the end
+ // (point) of the selection.
+
+ SwRect startCharRect;
+ pWrtShell->GetCharRectAt(startCharRect, pWrtShell->GetCrsr()->GetPoint());
+ const Point startCharPos = startCharRect.Center();
+
+ if (startCharPos.Y() < aDocPos.Y() ||
+ (startCharPos.Y() == aDocPos.Y() && startCharPos.X() - startCharRect.Width() <= aDocPos.X()))
+ return;
+
+ pWrtShell->ChgCurrPam( aDocPos );
+
+ // Keep mark normally at the start and point at the end,
+ // just exchange for the duration of moving the start.
+ pWrtShell->GetCrsr()->Exchange();
+ {
+ SwMvContext aMvContext( pWrtShell );
+ pWrtShell->SwCrsrShell::SetCrsr( aDocPos );
+ }
+ pWrtShell->GetCrsr()->Exchange();
+}
+
+void touch_lo_selection_end_move_impl(const void *documentHandle,
+ int x,
+ int y)
+{
+ SwWrtShell *pWrtShell = reinterpret_cast<SwWrtShell*>(const_cast<void*>(documentHandle));
+
+ if (!pWrtShell)
+ return;
+
+ const OutputDevice *pOut = pWrtShell->GetWin();
+ if (!pOut)
+ pOut = pWrtShell->GetOut();
+
+ const Point aDocPos( pOut->PixelToLogic( Point(x, y) ) );
+
+ // Don't allow moving the end of the selection beyond the start
+ // (mark) of the selection.
+
+ SwRect endCharRect;
+ pWrtShell->GetCharRectAt(endCharRect, pWrtShell->GetCrsr()->GetMark());
+ const Point endCharPos = endCharRect.Center();
+
+ if (endCharPos.Y() > aDocPos.Y() ||
+ (endCharPos.Y() == aDocPos.Y() && endCharPos.X() + endCharRect.Width() >= aDocPos.X()))
+ return;
+
+ pWrtShell->ChgCurrPam( aDocPos );
+
+ {
+ SwMvContext aMvContext( pWrtShell );
+ pWrtShell->SwCrsrShell::SetCrsr( aDocPos );
+ }
+}
+
+#endif
+
+void SwEditWin::MouseButtonDown(const MouseEvent& _rMEvt)
+{
+ SwWrtShell &rSh = m_rView.GetWrtShell();
+
+ // We have to check if a context menu is shown and we have an UI
+ // active inplace client. In that case we have to ignore the mouse
+ // button down event. Otherwise we would crash (context menu has been
+ // opened by inplace client and we would deactivate the inplace client,
+ // the contex menu is closed by VCL asynchronously which in the end
+ // would work on deleted objects or the context menu has no parent anymore)
+ SfxInPlaceClient* pIPClient = rSh.GetSfxViewShell()->GetIPClient();
+ bool bIsOleActive = ( pIPClient && pIPClient->IsObjectInPlaceActive() );
+
+ if ( bIsOleActive && PopupMenu::IsInExecute() )
+ return;
+
+ MouseEvent rMEvt(_rMEvt);
+
+ if (m_rView.GetPostItMgr()->IsHit(rMEvt.GetPosPixel()))
+ return;
+
+ m_rView.GetPostItMgr()->SetActiveSidebarWin(0);
+
+ GrabFocus();
+
+ //ignore key modifiers for format paintbrush
+ {
+ bool bExecFormatPaintbrush = m_pApplyTempl && m_pApplyTempl->m_pFormatClipboard
+ && m_pApplyTempl->m_pFormatClipboard->HasContent();
+ if( bExecFormatPaintbrush )
+ rMEvt = MouseEvent( _rMEvt.GetPosPixel(), _rMEvt.GetClicks(),
+ _rMEvt.GetMode(), _rMEvt.GetButtons() );
+ }
+
+ m_bWasShdwCrsr = 0 != m_pShadCrsr;
+ delete m_pShadCrsr, m_pShadCrsr = 0;
+
+ const Point aDocPos( PixelToLogic( rMEvt.GetPosPixel() ) );
+
+ // How many clicks do we need to select a fly frame?
+ FrameControlType eControl;
+ bool bOverFly = false;
+ bool bPageAnchored = false;
+ bool bOverHeaderFooterFly = IsOverHeaderFooterFly( aDocPos, eControl, bOverFly, bPageAnchored );
+
+ bool bIsDocReadOnly = m_rView.GetDocShell()->IsReadOnly();
+ if (bOverHeaderFooterFly && (!bIsDocReadOnly && rSh.GetCurFld()))
+ // We have a field here, that should have priority over header/footer fly.
+ bOverHeaderFooterFly = false;
+
+ int nNbFlyClicks = 1;
+ // !bOverHeaderFooterFly doesn't mean we have a frame to select
+ if ( !bPageAnchored && ( ( rSh.IsHeaderFooterEdit( ) && !bOverHeaderFooterFly && bOverFly ) ||
+ ( !rSh.IsHeaderFooterEdit( ) && bOverHeaderFooterFly ) ) )
+ {
+ nNbFlyClicks = 2;
+ if ( _rMEvt.GetClicks( ) < nNbFlyClicks )
+ return;
+ }
+
+ // Are we clicking on a blank header/footer area?
+ if ( IsInHeaderFooter( aDocPos, eControl ) || bOverHeaderFooterFly )
+ {
+ const SwPageFrm* pPageFrm = rSh.GetLayout()->GetPageAtPos( aDocPos );
+
+ // Is it active?
+ bool bActive = true;
+ const SwPageDesc* pDesc = pPageFrm->GetPageDesc();
+
+ const SwFrmFmt* pFmt = pDesc->GetLeftFmt();
+ if ( pPageFrm->OnRightPage() )
+ pFmt = pDesc->GetRightFmt();
+
+ if ( pFmt )
+ {
+ if ( eControl == Header )
+ bActive = pFmt->GetHeader().IsActive();
+ else
+ bActive = pFmt->GetFooter().IsActive();
+ }
+
+ if ( !bActive )
+ {
+ SwPaM aPam( *rSh.GetCurrentShellCursor().GetPoint() );
+ bool bWasInHeader = aPam.GetPoint( )->nNode.GetNode( ).FindHeaderStartNode( ) != NULL;
+ bool bWasInFooter = aPam.GetPoint( )->nNode.GetNode( ).FindFooterStartNode( ) != NULL;
+
+ // Is the cursor in a part like similar to the one we clicked on? For example,
+ // if the cursor is in a header and we click on an empty header... don't change anything to
+ // keep consistent behaviour due to header edit mode (and the same for the footer as well).
+
+ // Otherwise, we hide the header/footer control if a separator is shown, and vice versa.
+ if ( !( bWasInHeader && eControl == Header ) &&
+ !( bWasInFooter && eControl == Footer ) )
+ {
+ rSh.SetShowHeaderFooterSeparator( eControl, !rSh.IsShowHeaderFooterSeparator( eControl ) );
+ }
+
+ // Repaint everything
+ Invalidate();
+ }
+ else
+ {
+ // Make sure we have the proper Header/Footer separators shown
+ // as these may be changed if clicking on an empty Header/Footer
+ rSh.SetShowHeaderFooterSeparator( Header, eControl == Header );
+ rSh.SetShowHeaderFooterSeparator( Footer, eControl == Footer );
+
+ if ( !rSh.IsHeaderFooterEdit() )
+ rSh.ToggleHeaderFooterEdit();
+
+ // Repaint everything
+ rSh.GetWin()->Invalidate();
+ }
+ }
+ else
+ {
+ if ( rSh.IsHeaderFooterEdit( ) )
+ rSh.ToggleHeaderFooterEdit( );
+ else
+ {
+ // Make sure that the separators are hidden
+ rSh.SetShowHeaderFooterSeparator( Header, false );
+ rSh.SetShowHeaderFooterSeparator( Footer, false );
+
+ // Repaint everything
+ // FIXME fdo#67358 for unknown reasons this causes painting
+ // problems when resizing table columns, so disable it
+// rSh.GetWin()->Invalidate();
+ }
+ }
+
+ if ( IsChainMode() )
+ {
+ SetChainMode( false );
+ SwRect aDummy;
+ SwFlyFrmFmt *pFmt = (SwFlyFrmFmt*)rSh.GetFlyFrmFmt();
+ if ( !rSh.Chainable( aDummy, *pFmt, aDocPos ) )
+ rSh.Chain( *pFmt, aDocPos );
+ UpdatePointer( aDocPos, rMEvt.GetModifier() );
+ return;
+ }
+
+ // After GrabFocus a shell should be pushed. That should actually
+ // work but in practice ...
+ m_rView.SelectShellForDrop();
+
+ bool bCallBase = true;
+
+ if( m_pQuickHlpData->m_bIsDisplayed )
+ m_pQuickHlpData->Stop( rSh );
+ m_pQuickHlpData->m_bAppendSpace = false;
+
+ if( rSh.FinishOLEObj() )
+ return; // end InPlace and the click doesn't count anymore
+
+ SET_CURR_SHELL( &rSh );
+
+ SdrView *pSdrView = rSh.GetDrawView();
+ if ( pSdrView )
+ {
+ if (pSdrView->MouseButtonDown( rMEvt, this ) )
+ {
+ rSh.GetView().GetViewFrame()->GetBindings().InvalidateAll(false);
+ return; // SdrView's event evaluated
+ }
+ }
+
+ m_bIsInMove = false;
+ m_aStartPos = rMEvt.GetPosPixel();
+ m_aRszMvHdlPt.X() = 0, m_aRszMvHdlPt.Y() = 0;
+
+ sal_uInt8 nMouseTabCol = 0;
+ const bool bTmp = !rSh.IsDrawCreate() && !m_pApplyTempl && !rSh.IsInSelect() &&
+ rMEvt.GetClicks() == 1 && MOUSE_LEFT == rMEvt.GetButtons();
+ if ( bTmp &&
+ 0 != (nMouseTabCol = rSh.WhichMouseTabCol( aDocPos ) ) &&
+ !rSh.IsObjSelectable( aDocPos ) )
+ {
+ // Enhanced table selection
+ if ( SW_TABSEL_HORI <= nMouseTabCol && SW_TABCOLSEL_VERT >= nMouseTabCol )
+ {
+ rSh.EnterStdMode();
+ rSh.SelectTableRowCol( aDocPos );
+ if( SW_TABSEL_HORI != nMouseTabCol && SW_TABSEL_HORI_RTL != nMouseTabCol)
+ {
+ m_pRowColumnSelectionStart = new Point( aDocPos );
+ m_bIsRowDrag = SW_TABROWSEL_HORI == nMouseTabCol||
+ SW_TABROWSEL_HORI_RTL == nMouseTabCol ||
+ SW_TABCOLSEL_VERT == nMouseTabCol;
+ m_bMBPressed = true;
+ CaptureMouse();
+ }
+ return;
+ }
+
+ if ( !rSh.IsTableMode() )
+ {
+ // comes from table columns out of the document.
+ if(SW_TABCOL_VERT == nMouseTabCol || SW_TABCOL_HORI == nMouseTabCol)
+ m_rView.SetTabColFromDoc( true );
+ else
+ m_rView.SetTabRowFromDoc( true );
+
+ m_rView.SetTabColFromDocPos( aDocPos );
+ m_rView.InvalidateRulerPos();
+ SfxBindings& rBind = m_rView.GetViewFrame()->GetBindings();
+ rBind.Update();
+ if ( RulerColumnDrag( rMEvt,
+ (SW_TABCOL_VERT == nMouseTabCol || SW_TABROW_HORI == nMouseTabCol)) )
+ {
+ m_rView.SetTabColFromDoc( false );
+ m_rView.SetTabRowFromDoc( false );
+ m_rView.InvalidateRulerPos();
+ rBind.Update();
+ bCallBase = false;
+ }
+ else
+ {
+ return;
+ }
+ }
+ }
+ else if (bTmp &&
+ rSh.IsNumLabel(aDocPos))
+ {
+ SwTxtNode* pNodeAtPos = rSh.GetNumRuleNodeAtPos( aDocPos );
+ m_rView.SetNumRuleNodeFromDoc( pNodeAtPos );
+ m_rView.InvalidateRulerPos();
+ SfxBindings& rBind = m_rView.GetViewFrame()->GetBindings();
+ rBind.Update();
+
+ if ( RulerMarginDrag( rMEvt,
+ rSh.IsVerticalModeAtNdAndPos( *pNodeAtPos, aDocPos ) ) )
+ {
+ m_rView.SetNumRuleNodeFromDoc( NULL );
+ m_rView.InvalidateRulerPos();
+ rBind.Update();
+ bCallBase = false;
+ }
+ else
+ {
+ // Make sure the pointer is set to 0, otherwise it may point to
+ // nowhere after deleting the corresponding text node.
+ m_rView.SetNumRuleNodeFromDoc( NULL );
+ return;
+ }
+ }
+
+ if ( rSh.IsInSelect() )
+ rSh.EndSelect();
+
+ // query against LEFT because otherwise for example also a right
+ // click releases the selection.
+ if ( MOUSE_LEFT == rMEvt.GetButtons() )
+ {
+ bool bOnlyText = false;
+ m_bMBPressed = true;
+ bNoInterrupt = true;
+ m_nKS_NUMDOWN_Count = 0;
+
+ CaptureMouse();
+
+ // reset curor position if applicable
+ rSh.ResetCursorStack();
+
+ switch ( rMEvt.GetModifier() + rMEvt.GetButtons() )
+ {
+ case MOUSE_LEFT:
+ case MOUSE_LEFT + KEY_SHIFT:
+ case MOUSE_LEFT + KEY_MOD2:
+ if( rSh.IsObjSelected() )
+ {
+ SdrHdl* pHdl;
+ if( !bIsDocReadOnly &&
+ !m_pAnchorMarker &&
+ 0 != ( pHdl = pSdrView->PickHandle(aDocPos) ) &&
+ ( pHdl->GetKind() == HDL_ANCHOR ||
+ pHdl->GetKind() == HDL_ANCHOR_TR ) )
+ {
+ // #i121463# Set selected during drag
+ pHdl->SetSelected(true);
+ m_pAnchorMarker = new SwAnchorMarker( pHdl );
+ UpdatePointer( aDocPos, rMEvt.GetModifier() );
+ return;
+ }
+ }
+ if ( EnterDrawMode( rMEvt, aDocPos ) )
+ {
+ bNoInterrupt = false;
+ return;
+ }
+ else if ( m_rView.GetDrawFuncPtr() && m_bInsFrm )
+ {
+ StopInsFrm();
+ rSh.Edit();
+ }
+
+ // Without SHIFT because otherwise Toggle doesn't work at selection
+ if (rMEvt.GetClicks() == 1)
+ {
+ if ( rSh.IsSelFrmMode())
+ {
+ SdrHdl* pHdl = rSh.GetDrawView()->PickHandle(aDocPos);
+ bool bHitHandle = pHdl && pHdl->GetKind() != HDL_ANCHOR &&
+ pHdl->GetKind() != HDL_ANCHOR_TR;
+
+ if ((rSh.IsInsideSelectedObj(aDocPos) || bHitHandle) &&
+ !(rMEvt.GetModifier() == KEY_SHIFT && !bHitHandle))
+ {
+ rSh.EnterSelFrmMode( &aDocPos );
+ if ( !m_pApplyTempl )
+ {
+ // only if no position to size was hit.
+ if (!bHitHandle)
+ {
+ StartDDTimer();
+ SwEditWin::m_nDDStartPosY = aDocPos.Y();
+ SwEditWin::m_nDDStartPosX = aDocPos.X();
+ }
+ bFrmDrag = true;
+ }
+ bNoInterrupt = false;
+ return;
+ }
+ }
+ }
+ }
+
+ bool bExecHyperlinks = m_rView.GetDocShell()->IsReadOnly();
+ if ( !bExecHyperlinks )
+ {
+ SvtSecurityOptions aSecOpts;
+ const bool bSecureOption = aSecOpts.IsOptionSet( SvtSecurityOptions::E_CTRLCLICK_HYPERLINK );
+ if ( ( bSecureOption && rMEvt.GetModifier() == KEY_MOD1 ) ||
+ ( !bSecureOption && rMEvt.GetModifier() != KEY_MOD1 ) )
+ bExecHyperlinks = true;
+ }
+
+ // Enhanced selection
+ sal_uInt8 nNumberOfClicks = static_cast< sal_uInt8 >(rMEvt.GetClicks() % 4);
+ if ( 0 == nNumberOfClicks && 0 < rMEvt.GetClicks() )
+ nNumberOfClicks = 4;
+
+ bool bExecDrawTextLink = false;
+
+ switch ( rMEvt.GetModifier() + rMEvt.GetButtons() )
+ {
+ case MOUSE_LEFT:
+ case MOUSE_LEFT + KEY_MOD1:
+ case MOUSE_LEFT + KEY_MOD2:
+ {
+
+ bool bHandledFlyClick = false;
+ if ( nNumberOfClicks == nNbFlyClicks )
+ {
+ bHandledFlyClick = true;
+ // only try to select frame, if pointer already was
+ // switched accordingly
+ if ( m_aActHitType != SDRHIT_NONE && !rSh.IsSelFrmMode() &&
+ !GetView().GetViewFrame()->GetDispatcher()->IsLocked() &&
+ !bExecDrawTextLink)
+ {
+ // Test if there is a draw object at that position and if it should be selected.
+ bool bShould = rSh.ShouldObjectBeSelected(aDocPos);
+
+ if(bShould)
+ {
+ m_rView.NoRotate();
+ rSh.HideCrsr();
+
+ bool bUnLockView = !rSh.IsViewLocked();
+ rSh.LockView( true );
+ bool bSelObj = rSh.SelectObj( aDocPos,
+ rMEvt.IsMod1() ? SW_ENTER_GROUP : 0);
+ if( bUnLockView )
+ rSh.LockView( false );
+
+ if( bSelObj )
+ {
+ // if the frame was deselected in the macro
+ // the cursor just has to be displayed again
+ if( FRMTYPE_NONE == rSh.GetSelFrmType() )
+ rSh.ShowCrsr();
+ else
+ {
+ if (rSh.IsFrmSelected() && m_rView.GetDrawFuncPtr())
+ {
+ m_rView.GetDrawFuncPtr()->Deactivate();
+ m_rView.SetDrawFuncPtr(NULL);
+ m_rView.LeaveDrawCreate();
+ m_rView.AttrChangedNotify( &rSh );
+ }
+
+ rSh.EnterSelFrmMode( &aDocPos );
+ bFrmDrag = true;
+ UpdatePointer( aDocPos, rMEvt.GetModifier() );
+ }
+ return;
+ }
+ else
+ bOnlyText = rSh.IsObjSelectable( aDocPos );
+
+ if (!m_rView.GetDrawFuncPtr())
+ rSh.ShowCrsr();
+ }
+ else
+ bOnlyText = KEY_MOD1 != rMEvt.GetModifier();
+ }
+ else if ( rSh.IsSelFrmMode() &&
+ (m_aActHitType == SDRHIT_NONE ||
+ !rSh.IsInsideSelectedObj( aDocPos )))
+ {
+ m_rView.NoRotate();
+ SdrHdl *pHdl;
+ if( !bIsDocReadOnly && !m_pAnchorMarker && 0 !=
+ ( pHdl = pSdrView->PickHandle(aDocPos) ) &&
+ ( pHdl->GetKind() == HDL_ANCHOR ||
+ pHdl->GetKind() == HDL_ANCHOR_TR ) )
+ {
+ m_pAnchorMarker = new SwAnchorMarker( pHdl );
+ UpdatePointer( aDocPos, rMEvt.GetModifier() );
+ return;
+ }
+ else
+ {
+ bool bUnLockView = !rSh.IsViewLocked();
+ rSh.LockView( true );
+ sal_uInt8 nFlag = rMEvt.IsShift() ? SW_ADD_SELECT :0;
+ if( rMEvt.IsMod1() )
+ nFlag = nFlag | SW_ENTER_GROUP;
+
+ if ( rSh.IsSelFrmMode() )
+ {
+ rSh.UnSelectFrm();
+ rSh.LeaveSelFrmMode();
+ m_rView.AttrChangedNotify(&rSh);
+ }
+
+ bool bSelObj = rSh.SelectObj( aDocPos, nFlag );
+ if( bUnLockView )
+ rSh.LockView( false );
+
+ if( !bSelObj )
+ {
+ // move cursor here so that it is not drawn in the
+ // frame first; ShowCrsr() happens in LeaveSelFrmMode()
+ bValidCrsrPos = !(CRSR_POSCHG & rSh.SetCursor(&aDocPos, false));
+ rSh.LeaveSelFrmMode();
+ m_rView.AttrChangedNotify( &rSh );
+ bCallBase = false;
+ }
+ else
+ {
+ rSh.HideCrsr();
+ rSh.EnterSelFrmMode( &aDocPos );
+ rSh.SelFlyGrabCrsr();
+ rSh.MakeSelVisible();
+ bFrmDrag = true;
+ if( rSh.IsFrmSelected() &&
+ m_rView.GetDrawFuncPtr() )
+ {
+ m_rView.GetDrawFuncPtr()->Deactivate();
+ m_rView.SetDrawFuncPtr(NULL);
+ m_rView.LeaveDrawCreate();
+ m_rView.AttrChangedNotify( &rSh );
+ }
+ UpdatePointer( aDocPos, rMEvt.GetModifier() );
+ return;
+ }
+ }
+ }
+ }
+
+ switch ( nNumberOfClicks )
+ {
+ case 1:
+ {
+ UpdatePointer( aDocPos, rMEvt.GetModifier() );
+ SwEditWin::m_nDDStartPosY = aDocPos.Y();
+ SwEditWin::m_nDDStartPosX = aDocPos.X();
+
+ // hit an URL in DrawText object?
+ if (bExecHyperlinks && pSdrView)
+ {
+ SdrViewEvent aVEvt;
+ pSdrView->PickAnything(rMEvt, SDRMOUSEBUTTONDOWN, aVEvt);
+
+ if (aVEvt.eEvent == SDREVENT_EXECUTEURL)
+ bExecDrawTextLink = true;
+ }
+ break;
+ }
+ case 2:
+ {
+ bFrmDrag = false;
+ if ( !bHandledFlyClick && !bIsDocReadOnly && rSh.IsInsideSelectedObj(aDocPos) &&
+ 0 == rSh.IsSelObjProtected( FLYPROTECT_CONTENT|FLYPROTECT_PARENT ) )
+ {
+ /* This is no good: on the one hand GetSelectionType is used as flag field
+ * (take a look into the GetSelectionType method) and on the other hand the
+ * return value is used in a switch without proper masking (very nice), this must lead to trouble
+ */
+ switch ( rSh.GetSelectionType() &~ ( nsSelectionType::SEL_FONTWORK | nsSelectionType::SEL_EXTRUDED_CUSTOMSHAPE ) )
+ {
+ case nsSelectionType::SEL_GRF:
+ RstMBDownFlags();
+ GetView().GetViewFrame()->GetBindings().Execute(
+ FN_FORMAT_GRAFIC_DLG, 0, 0,
+ SFX_CALLMODE_RECORD|SFX_CALLMODE_SLOT);
+ return;
+
+ // double click on OLE object --> OLE-InPlace
+ case nsSelectionType::SEL_OLE:
+ if (!rSh.IsSelObjProtected(FLYPROTECT_CONTENT))
+ {
+ RstMBDownFlags();
+ rSh.LaunchOLEObj();
+ }
+ return;
+
+ case nsSelectionType::SEL_FRM:
+ RstMBDownFlags();
+ GetView().GetViewFrame()->GetBindings().Execute(
+ FN_FORMAT_FRAME_DLG, 0, 0, SFX_CALLMODE_RECORD|SFX_CALLMODE_SLOT);
+ return;
+
+ case nsSelectionType::SEL_DRW:
+ RstMBDownFlags();
+ EnterDrawTextMode(aDocPos);
+ if ( m_rView.GetCurShell()->ISA(SwDrawTextShell) )
+ ((SwDrawTextShell*)m_rView.GetCurShell())->Init();
+ return;
+ }
+ }
+
+ // if the cursor position was corrected or if a Fly
+ // was selected in ReadOnlyMode, no word selection.
+ if ( !bValidCrsrPos || rSh.IsFrmSelected() )
+ return;
+
+ SwField *pFld;
+ bool bFtn = false;
+
+ if( !bIsDocReadOnly &&
+ ( 0 != ( pFld = rSh.GetCurFld() ) ||
+ ( bFtn = rSh.GetCurFtn() ) ) )
+ {
+ RstMBDownFlags();
+ if( bFtn )
+ GetView().GetViewFrame()->GetBindings().Execute( FN_EDIT_FOOTNOTE );
+ else
+ {
+ sal_uInt16 nTypeId = pFld->GetTypeId();
+ SfxViewFrame* pVFrame = GetView().GetViewFrame();
+ switch( nTypeId )
+ {
+ case TYP_POSTITFLD:
+ case TYP_SCRIPTFLD:
+ {
+ // if it's a Readonly region, status has to be enabled
+ sal_uInt16 nSlot = TYP_POSTITFLD == nTypeId ? FN_POSTIT : FN_JAVAEDIT;
+ SfxBoolItem aItem(nSlot, true);
+ pVFrame->GetBindings().SetState(aItem);
+ pVFrame->GetBindings().Execute(nSlot);
+ break;
+ }
+ case TYP_AUTHORITY :
+ pVFrame->GetBindings().Execute(FN_EDIT_AUTH_ENTRY_DLG);
+ break;
+ default:
+ pVFrame->GetBindings().Execute(FN_EDIT_FIELD);
+ }
+ }
+ return;
+ }
+ // in extended mode double and triple
+ // click has no effect.
+ if ( rSh.IsExtMode() || rSh.IsBlockMode() )
+ return;
+
+ // select work, AdditionalMode if applicable
+ if ( KEY_MOD1 == rMEvt.GetModifier() && !rSh.IsAddMode() )
+ {
+ rSh.EnterAddMode();
+ rSh.SelWrd( &aDocPos );
+ rSh.LeaveAddMode();
+ }
+ else
+ rSh.SelWrd( &aDocPos );
+ bHoldSelection = true;
+ return;
+ }
+ case 3:
+ case 4:
+ {
+ bFrmDrag = false;
+ // in extended mode double and triple
+ // click has no effect.
+ if ( rSh.IsExtMode() )
+ return;
+
+ // if the cursor position was corrected or if a Fly
+ // was selected in ReadOnlyMode, no word selection.
+ if ( !bValidCrsrPos || rSh.IsFrmSelected() )
+ return;
+
+ // select line, AdditionalMode if applicable
+ const bool bMod = KEY_MOD1 == rMEvt.GetModifier() &&
+ !rSh.IsAddMode();
+
+ if ( bMod )
+ rSh.EnterAddMode();
+
+ // Enhanced selection
+ if ( 3 == nNumberOfClicks )
+ rSh.SelSentence( &aDocPos );
+ else
+ rSh.SelPara( &aDocPos );
+
+ if ( bMod )
+ rSh.LeaveAddMode();
+
+ bHoldSelection = true;
+ return;
+ }
+
+ default:
+ return;
+ }
+ }
+ /* no break */
+ case MOUSE_LEFT + KEY_SHIFT:
+ case MOUSE_LEFT + KEY_SHIFT + KEY_MOD1:
+ {
+ bool bLockView = m_bWasShdwCrsr;
+
+ switch ( rMEvt.GetModifier() )
+ {
+ case KEY_MOD1 + KEY_SHIFT:
+ {
+ if ( !m_bInsDraw && IsDrawObjSelectable( rSh, aDocPos ) )
+ {
+ m_rView.NoRotate();
+ rSh.HideCrsr();
+ if ( rSh.IsSelFrmMode() )
+ rSh.SelectObj(aDocPos, SW_ADD_SELECT | SW_ENTER_GROUP);
+ else
+ { if ( rSh.SelectObj( aDocPos, SW_ADD_SELECT | SW_ENTER_GROUP ) )
+ {
+ rSh.EnterSelFrmMode( &aDocPos );
+ SwEditWin::m_nDDStartPosY = aDocPos.Y();
+ SwEditWin::m_nDDStartPosX = aDocPos.X();
+ bFrmDrag = true;
+ return;
+ }
+ }
+ }
+ else if( rSh.IsSelFrmMode() &&
+ rSh.GetDrawView()->PickHandle( aDocPos ))
+ {
+ bFrmDrag = true;
+ bNoInterrupt = false;
+ return;
+ }
+ }
+ break;
+ case KEY_MOD1:
+ if ( !bExecDrawTextLink )
+ {
+ if ( !m_bInsDraw && IsDrawObjSelectable( rSh, aDocPos ) && !lcl_urlOverBackground( rSh, aDocPos ) )
+ {
+ m_rView.NoRotate();
+ rSh.HideCrsr();
+ if ( rSh.IsSelFrmMode() )
+ rSh.SelectObj(aDocPos, SW_ENTER_GROUP);
+ else
+ { if ( rSh.SelectObj( aDocPos, SW_ENTER_GROUP ) )
+ {
+ rSh.EnterSelFrmMode( &aDocPos );
+ SwEditWin::m_nDDStartPosY = aDocPos.Y();
+ SwEditWin::m_nDDStartPosX = aDocPos.X();
+ bFrmDrag = true;
+ return;
+ }
+ }
+ }
+ else if( rSh.IsSelFrmMode() &&
+ rSh.GetDrawView()->PickHandle( aDocPos ))
+ {
+ bFrmDrag = true;
+ bNoInterrupt = false;
+ return;
+ }
+ else
+ {
+ if ( !rSh.IsAddMode() && !rSh.IsExtMode() && !rSh.IsBlockMode() )
+ {
+ rSh.PushMode();
+ bModePushed = true;
+
+ bool bUnLockView = !rSh.IsViewLocked();
+ rSh.LockView( true );
+ rSh.EnterAddMode();
+ if( bUnLockView )
+ rSh.LockView( false );
+ }
+ bCallBase = false;
+ }
+ }
+ break;
+ case KEY_MOD2:
+ {
+ if ( !rSh.IsAddMode() && !rSh.IsExtMode() && !rSh.IsBlockMode() )
+ {
+ rSh.PushMode();
+ bModePushed = true;
+ bool bUnLockView = !rSh.IsViewLocked();
+ rSh.LockView( true );
+ rSh.EnterBlockMode();
+ if( bUnLockView )
+ rSh.LockView( false );
+ }
+ bCallBase = false;
+ }
+ break;
+ case KEY_SHIFT:
+ {
+ if ( !m_bInsDraw && IsDrawObjSelectable( rSh, aDocPos ) )
+ {
+ m_rView.NoRotate();
+ rSh.HideCrsr();
+ if ( rSh.IsSelFrmMode() )
+ {
+ rSh.SelectObj(aDocPos, SW_ADD_SELECT);
+
+ const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
+ if (rMarkList.GetMark(0) == NULL)
+ {
+ rSh.LeaveSelFrmMode();
+ m_rView.AttrChangedNotify(&rSh);
+ bFrmDrag = false;
+ }
+ }
+ else
+ { if ( rSh.SelectObj( aDocPos ) )
+ {
+ rSh.EnterSelFrmMode( &aDocPos );
+ SwEditWin::m_nDDStartPosY = aDocPos.Y();
+ SwEditWin::m_nDDStartPosX = aDocPos.X();
+ bFrmDrag = true;
+ return;
+ }
+ }
+ }
+ else
+ {
+ if ( rSh.IsSelFrmMode() &&
+ rSh.IsInsideSelectedObj( aDocPos ) )
+ {
+ rSh.EnterSelFrmMode( &aDocPos );
+ SwEditWin::m_nDDStartPosY = aDocPos.Y();
+ SwEditWin::m_nDDStartPosX = aDocPos.X();
+ bFrmDrag = true;
+ return;
+ }
+ if ( rSh.IsSelFrmMode() )
+ {
+ rSh.UnSelectFrm();
+ rSh.LeaveSelFrmMode();
+ m_rView.AttrChangedNotify(&rSh);
+ bFrmDrag = false;
+ }
+ if ( !rSh.IsExtMode() )
+ {
+ // don't start a selection when an
+ // URL field or a graphic is clicked
+ bool bSttSelect = rSh.HasSelection() ||
+ Pointer(POINTER_REFHAND) != GetPointer();
+
+ if( !bSttSelect )
+ {
+ bSttSelect = true;
+ if( bExecHyperlinks )
+ {
+ SwContentAtPos aCntntAtPos(
+ SwContentAtPos::SW_FTN |
+ SwContentAtPos::SW_INETATTR );
+
+ if( rSh.GetContentAtPos( aDocPos, aCntntAtPos ) )
+ {
+ if( !rSh.IsViewLocked() &&
+ !rSh.IsReadOnlyAvailable() &&
+ aCntntAtPos.IsInProtectSect() )
+ bLockView = true;
+
+ bSttSelect = false;
+ }
+ else if( rSh.IsURLGrfAtPos( aDocPos ))
+ bSttSelect = false;
+ }
+ }
+
+ if( bSttSelect )
+ rSh.SttSelect();
+ }
+ }
+ bCallBase = false;
+ break;
+ }
+ default:
+ if( !rSh.IsViewLocked() )
+ {
+ SwContentAtPos aCntntAtPos( SwContentAtPos::SW_CLICKFIELD |
+ SwContentAtPos::SW_INETATTR );
+ if( rSh.GetContentAtPos( aDocPos, aCntntAtPos, false ) &&
+ !rSh.IsReadOnlyAvailable() &&
+ aCntntAtPos.IsInProtectSect() )
+ bLockView = true;
+ }
+ }
+
+ if ( rSh.IsGCAttr() )
+ {
+ rSh.GCAttr();
+ rSh.ClearGCAttr();
+ }
+
+ SwContentAtPos aFieldAtPos(SwContentAtPos::SW_FIELD);
+
+ // Are we clicking on a field?
+ if (rSh.GetContentAtPos(aDocPos, aFieldAtPos))
+ {
+ bool bEditableField = (aFieldAtPos.pFndTxtAttr != NULL
+ && aFieldAtPos.pFndTxtAttr->Which() == RES_TXTATR_INPUTFIELD);
+
+ if (!bEditableField)
+ {
+ rSh.SetCursor(&aDocPos, bOnlyText);
+ // Unfortunately the cursor may be on field
+ // position or on position after field depending on which
+ // half of the field was clicked on.
+ SwTxtAttr const*const pTxtFld(aFieldAtPos.pFndTxtAttr);
+ if (rSh.GetCurrentShellCursor().GetPoint()->nContent
+ .GetIndex() != *pTxtFld->GetStart())
+ {
+ assert(rSh.GetCurrentShellCursor().GetPoint()->nContent
+ .GetIndex() == (*pTxtFld->GetStart() + 1));
+ rSh.Left( CRSR_SKIP_CHARS, false, 1, false );
+ }
+ // don't go into the !bOverSelect block below - it moves
+ // the cursor
+ break;
+ }
+ }
+
+ bool bOverSelect = rSh.ChgCurrPam( aDocPos ), bOverURLGrf = false;
+ if( !bOverSelect )
+ bOverURLGrf = bOverSelect = 0 != rSh.IsURLGrfAtPos( aDocPos );
+
+ if ( !bOverSelect )
+ {
+ const bool bTmpNoInterrupt = bNoInterrupt;
+ bNoInterrupt = false;
+
+ if( !rSh.IsViewLocked() && bLockView )
+ rSh.LockView( true );
+ else
+ bLockView = false;
+
+ int nTmpSetCrsr = 0;
+
+ { // only temporary generate Move-Kontext because otherwise
+ // the query to the content form doesn't work!!!
+ SwMvContext aMvContext( &rSh );
+ nTmpSetCrsr = rSh.SetCursor(&aDocPos, bOnlyText);
+ bValidCrsrPos = !(CRSR_POSCHG & nTmpSetCrsr);
+ bCallBase = false;
+ }
+
+ // notify the edit window that from now on we do not use the input language
+ if ( !(CRSR_POSOLD & nTmpSetCrsr) )
+ SetUseInputLanguage( false );
+
+ if( bLockView )
+ rSh.LockView( false );
+
+ bNoInterrupt = bTmpNoInterrupt;
+ }
+ if ( !bOverURLGrf && !bOnlyText )
+ {
+ const int nSelType = rSh.GetSelectionType();
+ // Check in general, if an object is selectable at given position.
+ // Thus, also text fly frames in background become selectable via Ctrl-Click.
+ if ( ( nSelType & nsSelectionType::SEL_OLE ||
+ nSelType & nsSelectionType::SEL_GRF ||
+ rSh.IsObjSelectable( aDocPos ) ) && !lcl_urlOverBackground( rSh, aDocPos ) )
+ {
+ SwMvContext aMvContext( &rSh );
+ if( !rSh.IsFrmSelected() )
+ rSh.GotoNextFly();
+ rSh.EnterSelFrmMode();
+ bCallBase = false;
+ }
+ }
+ // don't reset here any longer so that, in case through MouseMove
+ // with pressed Ctrl key a multiple-selection should happen,
+ // the previous selection is not released in Drag.
+ break;
+ }
+ }
+ }
+ if (bCallBase)
+ Window::MouseButtonDown(rMEvt);
+}
+
+void SwEditWin::MouseMove(const MouseEvent& _rMEvt)
+{
+ MouseEvent rMEvt(_rMEvt);
+
+ //ignore key modifiers for format paintbrush
+ {
+ bool bExecFormatPaintbrush = m_pApplyTempl && m_pApplyTempl->m_pFormatClipboard
+ && m_pApplyTempl->m_pFormatClipboard->HasContent();
+ if( bExecFormatPaintbrush )
+ rMEvt = MouseEvent( _rMEvt.GetPosPixel(), _rMEvt.GetClicks(),
+ _rMEvt.GetMode(), _rMEvt.GetButtons() );
+ }
+
+ // as long as an action is running the MouseMove should be disconnected
+ // otherwise bug 40102 occurs
+ SwWrtShell &rSh = m_rView.GetWrtShell();
+ if( rSh.ActionPend() )
+ return ;
+
+ if( m_pShadCrsr && 0 != (rMEvt.GetModifier() + rMEvt.GetButtons() ) )
+ delete m_pShadCrsr, m_pShadCrsr = 0;
+
+ bool bIsDocReadOnly = m_rView.GetDocShell()->IsReadOnly();
+
+ SET_CURR_SHELL( &rSh );
+
+ //aPixPt == Point in Pixel, relative to ChildWin
+ //aDocPt == Point in Twips, document coordinates
+ const Point aPixPt( rMEvt.GetPosPixel() );
+ const Point aDocPt( PixelToLogic( aPixPt ) );
+
+ if ( IsChainMode() )
+ {
+ UpdatePointer( aDocPt, rMEvt.GetModifier() );
+ return;
+ }
+
+ SdrView *pSdrView = rSh.GetDrawView();
+
+ const SwCallMouseEvent aLastCallEvent( m_aSaveCallEvent );
+ m_aSaveCallEvent.Clear();
+
+ if ( !bIsDocReadOnly && pSdrView && pSdrView->MouseMove(rMEvt,this) )
+ {
+ SetPointer( POINTER_TEXT );
+ return; // evaluate SdrView's event
+ }
+
+ const Point aOldPt( rSh.VisArea().Pos() );
+ const bool bInsWin = rSh.VisArea().IsInside( aDocPt );
+
+ if( m_pShadCrsr && !bInsWin )
+ delete m_pShadCrsr, m_pShadCrsr = 0;
+
+ if( bInsWin && m_pRowColumnSelectionStart )
+ {
+ EnterArea();
+ Point aPos( aDocPt );
+ if( rSh.SelectTableRowCol( *m_pRowColumnSelectionStart, &aPos, m_bIsRowDrag ))
+ return;
+ }
+
+ // position is necessary for OS/2 because obviously after a MB-Down
+ // a MB-Move is called immediately.
+ if( bDDTimerStarted )
+ {
+ Point aDD( SwEditWin::m_nDDStartPosX, SwEditWin::m_nDDStartPosY );
+ aDD = LogicToPixel( aDD );
+ Rectangle aRect( aDD.X()-3, aDD.Y()-3, aDD.X()+3, aDD.Y()+3 );
+ if ( !aRect.IsInside( aPixPt ) )
+ StopDDTimer( &rSh, aDocPt );
+ }
+
+ if(m_rView.GetDrawFuncPtr())
+ {
+ if( m_bInsDraw )
+ {
+ m_rView.GetDrawFuncPtr()->MouseMove( rMEvt );
+ if ( !bInsWin )
+ {
+ Point aTmp( aDocPt );
+ aTmp += rSh.VisArea().Pos() - aOldPt;
+ LeaveArea( aTmp );
+ }
+ else
+ EnterArea();
+ return;
+ }
+ else if(!rSh.IsFrmSelected() && !rSh.IsObjSelected())
+ {
+ SfxBindings &rBnd = rSh.GetView().GetViewFrame()->GetBindings();
+ Point aRelPos = rSh.GetRelativePagePosition(aDocPt);
+ if(aRelPos.X() >= 0)
+ {
+ FieldUnit eMetric = ::GetDfltMetric(0 != PTR_CAST(SwWebView, &GetView()));
+ SW_MOD()->PutItem(SfxUInt16Item(SID_ATTR_METRIC, static_cast< sal_uInt16 >(eMetric)));
+ const SfxPointItem aTmp1( SID_ATTR_POSITION, aRelPos );
+ rBnd.SetState( aTmp1 );
+ }
+ else
+ {
+ rBnd.Invalidate(SID_ATTR_POSITION);
+ }
+ rBnd.Invalidate(SID_ATTR_SIZE);
+ const SfxStringItem aCell( SID_TABLE_CELL, OUString() );
+ rBnd.SetState( aCell );
+ }
+ }
+
+ sal_uInt8 nMouseTabCol;
+ if( !bIsDocReadOnly && bInsWin && !m_pApplyTempl && !rSh.IsInSelect() )
+ {
+ if ( SW_TABCOL_NONE != (nMouseTabCol = rSh.WhichMouseTabCol( aDocPt ) ) &&
+ !rSh.IsObjSelectable( aDocPt ) )
+ {
+ sal_uInt16 nPointer = USHRT_MAX;
+ bool bChkTblSel = false;
+
+ switch ( nMouseTabCol )
+ {
+ case SW_TABCOL_VERT :
+ case SW_TABROW_HORI :
+ nPointer = POINTER_VSIZEBAR;
+ bChkTblSel = true;
+ break;
+ case SW_TABROW_VERT :
+ case SW_TABCOL_HORI :
+ nPointer = POINTER_HSIZEBAR;
+ bChkTblSel = true;
+ break;
+ // Enhanced table selection
+ case SW_TABSEL_HORI :
+ nPointer = POINTER_TAB_SELECT_SE;
+ break;
+ case SW_TABSEL_HORI_RTL :
+ case SW_TABSEL_VERT :
+ nPointer = POINTER_TAB_SELECT_SW;
+ break;
+ case SW_TABCOLSEL_HORI :
+ case SW_TABROWSEL_VERT :
+ nPointer = POINTER_TAB_SELECT_S;
+ break;
+ case SW_TABROWSEL_HORI :
+ nPointer = POINTER_TAB_SELECT_E;
+ break;
+ case SW_TABROWSEL_HORI_RTL :
+ case SW_TABCOLSEL_VERT :
+ nPointer = POINTER_TAB_SELECT_W;
+ break;
+ }
+
+ if ( USHRT_MAX != nPointer &&
+ // i#35543 - Enhanced table selection is explicitly allowed in table mode
+ ( !bChkTblSel || !rSh.IsTableMode() ) )
+ {
+ SetPointer( nPointer );
+ }
+
+ return;
+ }
+ else if (rSh.IsNumLabel(aDocPt, RULER_MOUSE_MARGINWIDTH))
+ {
+ // i#42921 - consider vertical mode
+ SwTxtNode* pNodeAtPos = rSh.GetNumRuleNodeAtPos( aDocPt );
+ const sal_uInt16 nPointer =
+ rSh.IsVerticalModeAtNdAndPos( *pNodeAtPos, aDocPt )
+ ? POINTER_VSIZEBAR
+ : POINTER_HSIZEBAR;
+ SetPointer( nPointer );
+
+ return;
+ }
+ }
+
+ bool bDelShadCrsr = true;
+
+ switch ( rMEvt.GetModifier() + rMEvt.GetButtons() )
+ {
+ case MOUSE_LEFT:
+ if( m_pAnchorMarker )
+ {
+ // Now we need to refresh the SdrHdl pointer of m_pAnchorMarker.
+ // This looks a little bit tricky, but it solves the following
+ // problem: the m_pAnchorMarker contains a pointer to an SdrHdl,
+ // if the FindAnchorPos-call cause a scrolling of the visible
+ // area, it's possible that the SdrHdl will be destroyed and a
+ // new one will initialized at the original position(GetHdlPos).
+ // So the m_pAnchorMarker has to find the right SdrHdl, if it's
+ // the old one, it will find it with position aOld, if this one
+ // is destroyed, it will find a new one at position GetHdlPos().
+
+ const Point aOld = m_pAnchorMarker->GetPosForHitTest( *(rSh.GetOut()) );
+ Point aNew = rSh.FindAnchorPos( aDocPt );
+ SdrHdl* pHdl;
+ if( (0!=( pHdl = pSdrView->PickHandle( aOld ) )||
+ 0 !=(pHdl = pSdrView->PickHandle( m_pAnchorMarker->GetHdlPos()) ) ) &&
+ ( pHdl->GetKind() == HDL_ANCHOR ||
+ pHdl->GetKind() == HDL_ANCHOR_TR ) )
+ {
+ m_pAnchorMarker->ChgHdl( pHdl );
+ if( aNew.X() || aNew.Y() )
+ {
+ m_pAnchorMarker->SetPos( aNew );
+ m_pAnchorMarker->SetLastPos( aDocPt );
+ }
+ }
+ else
+ {
+ delete m_pAnchorMarker;
+ m_pAnchorMarker = NULL;
+ }
+ }
+ if ( m_bInsDraw )
+ {
+ if ( !m_bMBPressed )
+ break;
+ if ( m_bIsInMove || IsMinMove( m_aStartPos, aPixPt ) )
+ {
+ if ( !bInsWin )
+ LeaveArea( aDocPt );
+ else
+ EnterArea();
+ if ( m_rView.GetDrawFuncPtr() )
+ {
+ pSdrView->SetOrtho(false);
+ m_rView.GetDrawFuncPtr()->MouseMove( rMEvt );
+ }
+ m_bIsInMove = true;
+ }
+ return;
+ }
+
+ {
+ SwWordCountWrapper *pWrdCnt = (SwWordCountWrapper*)GetView().GetViewFrame()->GetChildWindow(SwWordCountWrapper::GetChildWindowId());
+ if (pWrdCnt)
+ pWrdCnt->UpdateCounts();
+ }
+
+ case MOUSE_LEFT + KEY_SHIFT:
+ case MOUSE_LEFT + KEY_SHIFT + KEY_MOD1:
+ if ( !m_bMBPressed )
+ break;
+ case MOUSE_LEFT + KEY_MOD1:
+ if ( bFrmDrag && rSh.IsSelFrmMode() )
+ {
+ if( !m_bMBPressed )
+ break;
+
+ if ( m_bIsInMove || IsMinMove( m_aStartPos, aPixPt ) )
+ {
+ // event processing for resizing
+ if( pSdrView->AreObjectsMarked() )
+ {
+ const SwFrmFmt* pFlyFmt;
+ const SvxMacro* pMacro;
+
+ const Point aSttPt( PixelToLogic( m_aStartPos ) );
+
+ // can we start?
+ if( HDL_USER == eSdrMoveHdl )
+ {
+ SdrHdl* pHdl = pSdrView->PickHandle( aSttPt );
+ eSdrMoveHdl = pHdl ? pHdl->GetKind() : HDL_MOVE;
+ }
+
+ sal_uInt16 nEvent = HDL_MOVE == eSdrMoveHdl
+ ? SW_EVENT_FRM_MOVE
+ : SW_EVENT_FRM_RESIZE;
+
+ if( 0 != ( pFlyFmt = rSh.GetFlyFrmFmt() ) &&
+ 0 != ( pMacro = pFlyFmt->GetMacro().GetMacroTable().
+ Get( nEvent )) &&
+ // or notify only e.g. every 20 Twip?
+ m_aRszMvHdlPt != aDocPt )
+ {
+ m_aRszMvHdlPt = aDocPt;
+ sal_uInt16 nPos = 0;
+ SbxArrayRef xArgs = new SbxArray;
+ SbxVariableRef xVar = new SbxVariable;
+ xVar->PutString( pFlyFmt->GetName() );
+ xArgs->Put( &xVar, ++nPos );
+
+ if( SW_EVENT_FRM_RESIZE == nEvent )
+ {
+ xVar = new SbxVariable;
+ xVar->PutUShort( static_cast< sal_uInt16 >(eSdrMoveHdl) );
+ xArgs->Put( &xVar, ++nPos );
+ }
+
+ xVar = new SbxVariable;
+ xVar->PutLong( aDocPt.X() - aSttPt.X() );
+ xArgs->Put( &xVar, ++nPos );
+ xVar = new SbxVariable;
+ xVar->PutLong( aDocPt.Y() - aSttPt.Y() );
+ xArgs->Put( &xVar, ++nPos );
+
+ OUString sRet;
+
+ ReleaseMouse();
+
+ rSh.ExecMacro( *pMacro, &sRet, &xArgs );
+
+ CaptureMouse();
+
+ if( !sRet.isEmpty() && sRet.toInt32()!=0 )
+ return ;
+ }
+ }
+ // event processing for resizing
+
+ if( bIsDocReadOnly )
+ break;
+
+ bool bIsSelectionGfx = rSh.GetSelectionType() & nsSelectionType::SEL_GRF;
+ bool bisResize = eSdrMoveHdl != HDL_MOVE;
+
+ if ( rMEvt.IsShift() )
+ {
+ pSdrView->SetAngleSnapEnabled(!bIsSelectionGfx);
+ if (bisResize)
+ pSdrView->SetOrtho(!bIsSelectionGfx);
+ else
+ pSdrView->SetOrtho(true);
+ }
+ else
+ {
+ pSdrView->SetAngleSnapEnabled(bIsSelectionGfx);
+ if (bisResize)
+ pSdrView->SetOrtho(bIsSelectionGfx);
+ else
+ pSdrView->SetOrtho(false);
+ }
+
+ rSh.Drag( &aDocPt, rMEvt.IsShift() );
+ m_bIsInMove = true;
+ }
+ else if( bIsDocReadOnly )
+ break;
+
+ if ( !bInsWin )
+ {
+ Point aTmp( aDocPt );
+ aTmp += rSh.VisArea().Pos() - aOldPt;
+ LeaveArea( aTmp );
+ }
+ else if(m_bIsInMove)
+ EnterArea();
+ return;
+ }
+ if ( !rSh.IsSelFrmMode() && !bDDINetAttr &&
+ (IsMinMove( m_aStartPos,aPixPt ) || m_bIsInMove) &&
+ (rSh.IsInSelect() || !rSh.ChgCurrPam( aDocPt )) )
+ {
+ if ( pSdrView )
+ {
+ if ( rMEvt.IsShift() )
+ pSdrView->SetOrtho(true);
+ else
+ pSdrView->SetOrtho(false);
+ }
+ if ( !bInsWin )
+ {
+ Point aTmp( aDocPt );
+ aTmp += rSh.VisArea().Pos() - aOldPt;
+ LeaveArea( aTmp );
+ }
+ else
+ {
+ if( !rMEvt.IsSynthetic() &&
+ !(( MOUSE_LEFT + KEY_MOD1 ==
+ rMEvt.GetModifier() + rMEvt.GetButtons() ) &&
+ rSh.Is_FnDragEQBeginDrag() && !rSh.IsAddMode() ))
+ {
+ rSh.Drag( &aDocPt, false );
+
+ bValidCrsrPos = !(CRSR_POSCHG & rSh.SetCursor(&aDocPt, false));
+ EnterArea();
+ }
+ }
+ }
+ bDDINetAttr = false;
+ break;
+ case 0:
+ {
+ if ( m_pApplyTempl )
+ {
+ UpdatePointer(aDocPt, 0); // maybe a frame has to be marked here
+ break;
+ }
+ // change ui if mouse is over SwPostItField
+ // TODO: do the same thing for redlines SW_REDLINE
+ SwRect aFldRect;
+ SwContentAtPos aCntntAtPos( SwContentAtPos::SW_FIELD);
+ if( rSh.GetContentAtPos( aDocPt, aCntntAtPos, false, &aFldRect ) )
+ {
+ const SwField* pFld = aCntntAtPos.aFnd.pFld;
+ if (pFld->Which()== RES_POSTITFLD)
+ {
+ m_rView.GetPostItMgr()->SetShadowState(reinterpret_cast<const SwPostItField*>(pFld),false);
+ }
+ else
+ m_rView.GetPostItMgr()->SetShadowState(0,false);
+ }
+ else
+ m_rView.GetPostItMgr()->SetShadowState(0,false);
+ }
+ // no break;
+ case KEY_SHIFT:
+ case KEY_MOD2:
+ case KEY_MOD1:
+ if ( !m_bInsDraw )
+ {
+ bool bTstShdwCrsr = true;
+
+ UpdatePointer( aDocPt, rMEvt.GetModifier() );
+
+ const SwFrmFmt* pFmt = 0;
+ const SwFmtINetFmt* pINet = 0;
+ SwContentAtPos aCntntAtPos( SwContentAtPos::SW_INETATTR );
+ if( rSh.GetContentAtPos( aDocPt, aCntntAtPos ) )
+ pINet = (SwFmtINetFmt*)aCntntAtPos.aFnd.pAttr;
+
+ const void* pTmp = pINet;
+
+ if( pINet ||
+ 0 != ( pTmp = pFmt = rSh.GetFmtFromAnyObj( aDocPt )))
+ {
+ bTstShdwCrsr = false;
+ if( pTmp == pINet )
+ m_aSaveCallEvent.Set( pINet );
+ else
+ {
+ IMapObject* pIMapObj = pFmt->GetIMapObject( aDocPt );
+ if( pIMapObj )
+ m_aSaveCallEvent.Set( pFmt, pIMapObj );
+ else
+ m_aSaveCallEvent.Set( EVENT_OBJECT_URLITEM, pFmt );
+ }
+
+ // should be be over a InternetField with an
+ // embedded macro?
+ if( m_aSaveCallEvent != aLastCallEvent )
+ {
+ if( aLastCallEvent.HasEvent() )
+ rSh.CallEvent( SFX_EVENT_MOUSEOUT_OBJECT,
+ aLastCallEvent, true );
+ // 0 says that the object doesn't have any table
+ if( !rSh.CallEvent( SFX_EVENT_MOUSEOVER_OBJECT,
+ m_aSaveCallEvent ))
+ m_aSaveCallEvent.Clear();
+ }
+ }
+ else if( aLastCallEvent.HasEvent() )
+ {
+ // cursor was on an object
+ rSh.CallEvent( SFX_EVENT_MOUSEOUT_OBJECT,
+ aLastCallEvent, true );
+ }
+
+ if( bTstShdwCrsr && bInsWin && !bIsDocReadOnly &&
+ !m_bInsFrm &&
+ !rSh.GetViewOptions()->getBrowseMode() &&
+ rSh.GetViewOptions()->IsShadowCursor() &&
+ !(rMEvt.GetModifier() + rMEvt.GetButtons()) &&
+ !rSh.HasSelection() && !GetConnectMetaFile() )
+ {
+ SwRect aRect;
+ sal_Int16 eOrient;
+ SwFillMode eMode = (SwFillMode)rSh.GetViewOptions()->GetShdwCrsrFillMode();
+ if( rSh.GetShadowCrsrPos( aDocPt, eMode, aRect, eOrient ))
+ {
+ if( !m_pShadCrsr )
+ m_pShadCrsr = new SwShadowCursor( *this,
+ SwViewOption::GetDirectCursorColor() );
+ if( text::HoriOrientation::RIGHT != eOrient && text::HoriOrientation::CENTER != eOrient )
+ eOrient = text::HoriOrientation::LEFT;
+ m_pShadCrsr->SetPos( aRect.Pos(), aRect.Height(), static_cast< sal_uInt16 >(eOrient) );
+ bDelShadCrsr = false;
+ }
+ }
+ }
+ break;
+ case MOUSE_LEFT + KEY_MOD2:
+ if( rSh.IsBlockMode() && !rMEvt.IsSynthetic() )
+ {
+ rSh.Drag( &aDocPt, false );
+ bValidCrsrPos = !(CRSR_POSCHG & rSh.SetCursor(&aDocPt, false));
+ EnterArea();
+ }
+ break;
+ }
+
+ if( bDelShadCrsr && m_pShadCrsr )
+ delete m_pShadCrsr, m_pShadCrsr = 0;
+ m_bWasShdwCrsr = false;
+}
+
+/**
+ * Button Up
+ */
+void SwEditWin::MouseButtonUp(const MouseEvent& rMEvt)
+{
+ bool bCallBase = true;
+
+ bool bCallShadowCrsr = m_bWasShdwCrsr;
+ m_bWasShdwCrsr = false;
+ if( m_pShadCrsr )
+ delete m_pShadCrsr, m_pShadCrsr = 0;
+
+ if( m_pRowColumnSelectionStart )
+ DELETEZ( m_pRowColumnSelectionStart );
+
+ SdrHdlKind eOldSdrMoveHdl = eSdrMoveHdl;
+ eSdrMoveHdl = HDL_USER; // for MoveEvents - reset again
+
+ // preventively reset
+ m_rView.SetTabColFromDoc( false );
+ m_rView.SetNumRuleNodeFromDoc(NULL);
+
+ SwWrtShell &rSh = m_rView.GetWrtShell();
+ SET_CURR_SHELL( &rSh );
+ SdrView *pSdrView = rSh.GetDrawView();
+ if ( pSdrView )
+ {
+ pSdrView->SetOrtho(false);
+
+ if ( pSdrView->MouseButtonUp( rMEvt,this ) )
+ {
+ rSh.GetView().GetViewFrame()->GetBindings().InvalidateAll(false);
+ return; // SdrView's event evaluated
+ }
+ }
+ // only process MouseButtonUp when the Down went to that windows as well.
+ if ( !m_bMBPressed )
+ {
+ // Undo for the watering can is already in CommandHdl
+ // that's the way it should be!
+
+ return;
+ }
+
+ Point aDocPt( PixelToLogic( rMEvt.GetPosPixel() ) );
+
+ if ( bDDTimerStarted )
+ {
+ StopDDTimer( &rSh, aDocPt );
+ m_bMBPressed = false;
+ if ( rSh.IsSelFrmMode() )
+ {
+ rSh.EndDrag( &aDocPt, false );
+ bFrmDrag = false;
+ }
+ bNoInterrupt = false;
+ const Point aDocPos( PixelToLogic( rMEvt.GetPosPixel() ) );
+ if ((PixelToLogic(m_aStartPos).Y() == (aDocPos.Y())) && (PixelToLogic(m_aStartPos).X() == (aDocPos.X())))//To make sure it was not moved
+ {
+ SdrObject* pObj;
+ SdrPageView* pPV;
+ if (pSdrView->PickObj(aDocPos, pSdrView->getHitTolLog(), pObj, pPV, SDRSEARCH_ALSOONMASTER ))
+ {
+ pSdrView->UnmarkAllObj();
+ pSdrView->MarkObj(pObj,pPV,false,false);
+ }
+ }
+ ReleaseMouse();
+ return;
+ }
+
+ if( m_pAnchorMarker )
+ {
+ if(m_pAnchorMarker->GetHdl())
+ {
+ // #i121463# delete selected after drag
+ m_pAnchorMarker->GetHdl()->SetSelected(false);
+ }
+
+ Point aPnt( m_pAnchorMarker->GetLastPos() );
+ DELETEZ( m_pAnchorMarker );
+ if( aPnt.X() || aPnt.Y() )
+ rSh.FindAnchorPos( aPnt, true );
+ }
+ if ( m_bInsDraw && m_rView.GetDrawFuncPtr() )
+ {
+ if ( m_rView.GetDrawFuncPtr()->MouseButtonUp( rMEvt ) )
+ {
+ if (m_rView.GetDrawFuncPtr()) // could have been destroyed in MouseButtonUp
+ {
+ m_rView.GetDrawFuncPtr()->Deactivate();
+
+ if (!m_rView.IsDrawMode())
+ {
+ m_rView.SetDrawFuncPtr(NULL);
+ SfxBindings& rBind = m_rView.GetViewFrame()->GetBindings();
+ rBind.Invalidate( SID_ATTR_SIZE );
+ rBind.Invalidate( SID_TABLE_CELL );
+ }
+ }
+
+ if ( rSh.IsObjSelected() )
+ {
+ rSh.EnterSelFrmMode();
+ if (!m_rView.GetDrawFuncPtr())
+ StdDrawMode( OBJ_NONE, true );
+ }
+ else if ( rSh.IsFrmSelected() )
+ {
+ rSh.EnterSelFrmMode();
+ StopInsFrm();
+ }
+ else
+ {
+ const Point aDocPos( PixelToLogic( m_aStartPos ) );
+ bValidCrsrPos = !(CRSR_POSCHG & rSh.SetCursor(&aDocPos, false));
+ rSh.Edit();
+ }
+
+ m_rView.AttrChangedNotify( &rSh );
+ }
+ else if (rMEvt.GetButtons() == MOUSE_RIGHT && rSh.IsDrawCreate())
+ m_rView.GetDrawFuncPtr()->BreakCreate(); // abort drawing
+
+ bNoInterrupt = false;
+ ReleaseMouse();
+ return;
+ }
+ bool bPopMode = false;
+ switch ( rMEvt.GetModifier() + rMEvt.GetButtons() )
+ {
+ case MOUSE_LEFT:
+ if ( m_bInsDraw && rSh.IsDrawCreate() )
+ {
+ if ( m_rView.GetDrawFuncPtr() && m_rView.GetDrawFuncPtr()->MouseButtonUp(rMEvt) )
+ {
+ m_rView.GetDrawFuncPtr()->Deactivate();
+ m_rView.AttrChangedNotify( &rSh );
+ if ( rSh.IsObjSelected() )
+ rSh.EnterSelFrmMode();
+ if ( m_rView.GetDrawFuncPtr() && m_bInsFrm )
+ StopInsFrm();
+ }
+ bCallBase = false;
+ break;
+ }
+ case MOUSE_LEFT + KEY_MOD1:
+ case MOUSE_LEFT + KEY_MOD2:
+ case MOUSE_LEFT + KEY_SHIFT + KEY_MOD1:
+ if ( bFrmDrag && rSh.IsSelFrmMode() )
+ {
+ if ( rMEvt.IsMod1() ) // copy and don't move.
+ {
+ // abort drag, use internal Copy instead
+ Rectangle aRect;
+ rSh.GetDrawView()->TakeActionRect( aRect );
+ if (!aRect.IsEmpty())
+ {
+ rSh.BreakDrag();
+ Point aEndPt, aSttPt;
+ if ( rSh.GetSelFrmType() & FRMTYPE_FLY_ATCNT )
+ {
+ aEndPt = aRect.TopLeft();
+ aSttPt = rSh.GetDrawView()->GetAllMarkedRect().TopLeft();
+ }
+ else
+ {
+ aEndPt = aRect.Center();
+ aSttPt = rSh.GetDrawView()->GetAllMarkedRect().Center();
+ }
+ if ( aSttPt != aEndPt )
+ {
+ rSh.StartUndo( UNDO_UI_DRAG_AND_COPY );
+ rSh.Copy(&rSh, aSttPt, aEndPt, false);
+ rSh.EndUndo( UNDO_UI_DRAG_AND_COPY );
+ }
+ }
+ else {
+ rSh.EndDrag( &aDocPt, false );
+ }
+ }
+ else
+ {
+ {
+ const SwFrmFmt* pFlyFmt;
+ const SvxMacro* pMacro;
+
+ sal_uInt16 nEvent = HDL_MOVE == eOldSdrMoveHdl
+ ? SW_EVENT_FRM_MOVE
+ : SW_EVENT_FRM_RESIZE;
+
+ if( 0 != ( pFlyFmt = rSh.GetFlyFrmFmt() ) &&
+ 0 != ( pMacro = pFlyFmt->GetMacro().GetMacroTable().
+ Get( nEvent )) )
+ {
+ const Point aSttPt( PixelToLogic( m_aStartPos ) );
+ m_aRszMvHdlPt = aDocPt;
+ sal_uInt16 nPos = 0;
+ SbxArrayRef xArgs = new SbxArray;
+ SbxVariableRef xVar = new SbxVariable;
+ xVar->PutString( pFlyFmt->GetName() );
+ xArgs->Put( &xVar, ++nPos );
+
+ if( SW_EVENT_FRM_RESIZE == nEvent )
+ {
+ xVar = new SbxVariable;
+ xVar->PutUShort( static_cast< sal_uInt16 >(eOldSdrMoveHdl) );
+ xArgs->Put( &xVar, ++nPos );
+ }
+
+ xVar = new SbxVariable;
+ xVar->PutLong( aDocPt.X() - aSttPt.X() );
+ xArgs->Put( &xVar, ++nPos );
+ xVar = new SbxVariable;
+ xVar->PutLong( aDocPt.Y() - aSttPt.Y() );
+ xArgs->Put( &xVar, ++nPos );
+
+ xVar = new SbxVariable;
+ xVar->PutUShort( 1 );
+ xArgs->Put( &xVar, ++nPos );
+
+ ReleaseMouse();
+
+ rSh.ExecMacro( *pMacro, 0, &xArgs );
+
+ CaptureMouse();
+ }
+ }
+ rSh.EndDrag( &aDocPt, false );
+ }
+ bFrmDrag = false;
+ bCallBase = false;
+ break;
+ }
+ bPopMode = true;
+ // no break
+ case MOUSE_LEFT + KEY_SHIFT:
+ if (rSh.IsSelFrmMode())
+ {
+
+ rSh.EndDrag( &aDocPt, false );
+ bFrmDrag = false;
+ bCallBase = false;
+ break;
+ }
+
+ if( bHoldSelection )
+ {
+ // the EndDrag should be called in any case
+ bHoldSelection = false;
+ rSh.EndDrag( &aDocPt, false );
+ }
+ else
+ {
+ SwContentAtPos aFieldAtPos ( SwContentAtPos::SW_FIELD );
+ if ( !rSh.IsInSelect() && rSh.ChgCurrPam( aDocPt ) && !rSh.GetContentAtPos( aDocPt, aFieldAtPos ) )
+ {
+ const bool bTmpNoInterrupt = bNoInterrupt;
+ bNoInterrupt = false;
+ { // create only temporary move context because otherwise
+ // the query to the content form doesn't work!!!
+ SwMvContext aMvContext( &rSh );
+ const Point aDocPos( PixelToLogic( m_aStartPos ) );
+ bValidCrsrPos = !(CRSR_POSCHG & rSh.SetCursor(&aDocPos, false));
+ }
+ bNoInterrupt = bTmpNoInterrupt;
+
+ }
+ else
+ {
+ bool bInSel = rSh.IsInSelect();
+ rSh.EndDrag( &aDocPt, false );
+
+ // Internetfield? --> call link (load doc!!)
+ if( !bInSel )
+ {
+ sal_uInt16 nFilter = URLLOAD_NOFILTER;
+ if( KEY_MOD1 == rMEvt.GetModifier() )
+ nFilter |= URLLOAD_NEWVIEW;
+
+ bool bExecHyperlinks = m_rView.GetDocShell()->IsReadOnly();
+ if ( !bExecHyperlinks )
+ {
+ SvtSecurityOptions aSecOpts;
+ const bool bSecureOption = aSecOpts.IsOptionSet( SvtSecurityOptions::E_CTRLCLICK_HYPERLINK );
+ if ( ( bSecureOption && rMEvt.GetModifier() == KEY_MOD1 ) ||
+ ( !bSecureOption && rMEvt.GetModifier() != KEY_MOD1 ) )
+ bExecHyperlinks = true;
+ }
+
+ const bool bExecSmarttags = rMEvt.GetModifier() == KEY_MOD1;
+
+ if(m_pApplyTempl)
+ bExecHyperlinks = false;
+
+ SwContentAtPos aCntntAtPos( SwContentAtPos::SW_FIELD |
+ SwContentAtPos::SW_INETATTR |
+ SwContentAtPos::SW_SMARTTAG | SwContentAtPos::SW_FORMCTRL);
+
+ if( rSh.GetContentAtPos( aDocPt, aCntntAtPos, false ) )
+ {
+ // Do it again if we're not on a field/hyperlink to update the cursor accordingly
+ if ( SwContentAtPos::SW_FIELD != aCntntAtPos.eCntntAtPos
+ && SwContentAtPos::SW_INETATTR != aCntntAtPos.eCntntAtPos )
+ rSh.GetContentAtPos( aDocPt, aCntntAtPos, true );
+
+ bool bViewLocked = rSh.IsViewLocked();
+ if( !bViewLocked && !rSh.IsReadOnlyAvailable() &&
+ aCntntAtPos.IsInProtectSect() )
+ rSh.LockView( true );
+
+ ReleaseMouse();
+
+ if( SwContentAtPos::SW_FIELD == aCntntAtPos.eCntntAtPos )
+ {
+ bool bAddMode(false);
+ // AdditionalMode if applicable
+ if (KEY_MOD1 == rMEvt.GetModifier()
+ && !rSh.IsAddMode())
+ {
+ bAddMode = true;
+ rSh.EnterAddMode();
+ }
+ if ( aCntntAtPos.pFndTxtAttr != NULL
+ && aCntntAtPos.pFndTxtAttr->Which() == RES_TXTATR_INPUTFIELD )
+ {
+ // select content of Input Field, but exclude CH_TXT_ATR_INPUTFIELDSTART
+ // and CH_TXT_ATR_INPUTFIELDEND
+ rSh.SttSelect();
+ rSh.SelectTxt( *(aCntntAtPos.pFndTxtAttr->GetStart()) + 1,
+ *(aCntntAtPos.pFndTxtAttr->End()) - 1 );
+ }
+ else
+ {
+ rSh.ClickToField( *aCntntAtPos.aFnd.pFld );
+ }
+ // a bit of a mystery what this is good for?
+ // in this case we assume it's valid since we
+ // just selected a field
+ bValidCrsrPos = true;
+ if (bAddMode)
+ {
+ rSh.LeaveAddMode();
+ }
+ }
+ else if ( SwContentAtPos::SW_SMARTTAG == aCntntAtPos.eCntntAtPos )
+ {
+ // execute smarttag menu
+ if ( bExecSmarttags && SwSmartTagMgr::Get().IsSmartTagsEnabled() )
+ m_rView.ExecSmartTagPopup( aDocPt );
+ }
+ else if ( SwContentAtPos::SW_FORMCTRL == aCntntAtPos.eCntntAtPos )
+ {
+ OSL_ENSURE( aCntntAtPos.aFnd.pFldmark != NULL, "where is my field ptr???");
+ if ( aCntntAtPos.aFnd.pFldmark != NULL)
+ {
+ IFieldmark *fieldBM = const_cast< IFieldmark* > ( aCntntAtPos.aFnd.pFldmark );
+ if ( fieldBM->GetFieldname( ) == ODF_FORMCHECKBOX )
+ {
+ ICheckboxFieldmark* pCheckboxFm = dynamic_cast<ICheckboxFieldmark*>(fieldBM);
+ pCheckboxFm->SetChecked(!pCheckboxFm->IsChecked());
+ pCheckboxFm->Invalidate();
+ rSh.InvalidateWindows( m_rView.GetVisArea() );
+ } else if ( fieldBM->GetFieldname() == ODF_FORMDROPDOWN ) {
+ m_rView.ExecFieldPopup( aDocPt, fieldBM );
+ fieldBM->Invalidate();
+ rSh.InvalidateWindows( m_rView.GetVisArea() );
+ } else {
+ // unknown type..
+ }
+ }
+ }
+ else if ( SwContentAtPos::SW_INETATTR == aCntntAtPos.eCntntAtPos )
+ {
+ if ( bExecHyperlinks && aCntntAtPos.aFnd.pAttr )
+ rSh.ClickToINetAttr( *(SwFmtINetFmt*)aCntntAtPos.aFnd.pAttr, nFilter );
+ }
+
+ rSh.LockView( bViewLocked );
+ bCallShadowCrsr = false;
+ }
+ else
+ {
+ aCntntAtPos = SwContentAtPos( SwContentAtPos::SW_FTN );
+ if( !rSh.GetContentAtPos( aDocPt, aCntntAtPos, true ) && bExecHyperlinks )
+ {
+ SdrViewEvent aVEvt;
+
+ if (pSdrView)
+ pSdrView->PickAnything(rMEvt, SDRMOUSEBUTTONDOWN, aVEvt);
+
+ if (pSdrView && aVEvt.eEvent == SDREVENT_EXECUTEURL)
+ {
+ // hit URL field
+ const SvxURLField *pField = aVEvt.pURLField;
+ if (pField)
+ {
+ OUString sURL(pField->GetURL());
+ OUString sTarget(pField->GetTargetFrame());
+ ::LoadURL(rSh, sURL, nFilter, sTarget);
+ }
+ bCallShadowCrsr = false;
+ }
+ else
+ {
+ // hit graphic
+ ReleaseMouse();
+ if( rSh.ClickToINetGrf( aDocPt, nFilter ))
+ bCallShadowCrsr = false;
+ }
+ }
+ }
+
+ if( bCallShadowCrsr &&
+ rSh.GetViewOptions()->IsShadowCursor() &&
+ MOUSE_LEFT == (rMEvt.GetModifier() + rMEvt.GetButtons()) &&
+ !rSh.HasSelection() &&
+ !GetConnectMetaFile() &&
+ rSh.VisArea().IsInside( aDocPt ))
+ {
+ SwUndoId nLastUndoId(UNDO_EMPTY);
+ if (rSh.GetLastUndoInfo(0, & nLastUndoId))
+ {
+ if (UNDO_INS_FROM_SHADOWCRSR == nLastUndoId)
+ {
+ rSh.Undo();
+ }
+ }
+ SwFillMode eMode = (SwFillMode)rSh.GetViewOptions()->GetShdwCrsrFillMode();
+ rSh.SetShadowCrsrPos( aDocPt, eMode );
+ }
+ }
+ }
+ bCallBase = false;
+
+ }
+
+ // reset pushed mode in Down again if applicable
+ if ( bPopMode && bModePushed )
+ {
+ rSh.PopMode();
+ bModePushed = false;
+ bCallBase = false;
+ }
+ break;
+
+ default:
+ ReleaseMouse();
+ return;
+ }
+
+ if( m_pApplyTempl )
+ {
+ int eSelection = rSh.GetSelectionType();
+ SwFormatClipboard* pFormatClipboard = m_pApplyTempl->m_pFormatClipboard;
+ if( pFormatClipboard )//apply format paintbrush
+ {
+ //get some parameters
+ SwWrtShell& rWrtShell = m_rView.GetWrtShell();
+ SfxStyleSheetBasePool* pPool=0;
+ bool bNoCharacterFormats = false;
+ bool bNoParagraphFormats = true;
+ {
+ SwDocShell* pDocSh = m_rView.GetDocShell();
+ if(pDocSh)
+ pPool = pDocSh->GetStyleSheetPool();
+ if( (rMEvt.GetModifier()&KEY_MOD1) && (rMEvt.GetModifier()&KEY_SHIFT) )
+ {
+ bNoCharacterFormats = true;
+ bNoParagraphFormats = false;
+ }
+ else if( rMEvt.GetModifier() & KEY_MOD1 )
+ bNoParagraphFormats = false;
+ }
+ //execute paste
+ pFormatClipboard->Paste( rWrtShell, pPool, bNoCharacterFormats, bNoParagraphFormats );
+
+ //if the clipboard is empty after paste remove the ApplyTemplate
+ if(!pFormatClipboard->HasContent())
+ SetApplyTemplate(SwApplyTemplate());
+ }
+ else if( m_pApplyTempl->nColor )
+ {
+ sal_uInt16 nId = 0;
+ switch( m_pApplyTempl->nColor )
+ {
+ case SID_ATTR_CHAR_COLOR_EXT:
+ case SID_ATTR_CHAR_COLOR2:
+ nId = RES_CHRATR_COLOR;
+ break;
+ case SID_ATTR_CHAR_COLOR_BACKGROUND_EXT:
+ case SID_ATTR_CHAR_COLOR_BACKGROUND:
+ nId = RES_CHRATR_BACKGROUND;
+ break;
+ }
+ if( nId && (nsSelectionType::SEL_TXT|nsSelectionType::SEL_TBL) & eSelection)
+ {
+ if( rSh.IsSelection() && !rSh.HasReadonlySel() )
+ {
+ if(nId == RES_CHRATR_BACKGROUND)
+ rSh.SetAttrItem( SvxBrushItem( SwEditWin::m_aTextBackColor, nId ) );
+ else
+ rSh.SetAttrItem( SvxColorItem( SwEditWin::m_aTextColor, nId ) );
+ rSh.UnSetVisCrsr();
+ rSh.EnterStdMode();
+ rSh.SetVisCrsr(aDocPt);
+
+ m_pApplyTempl->bUndo = true;
+ bCallBase = false;
+ m_aTemplateTimer.Stop();
+ }
+ else if(rMEvt.GetClicks() == 1)
+ {
+ // no selection -> so turn off watering can
+ m_aTemplateTimer.Start();
+ }
+ }
+ }
+ else
+ {
+ OUString aStyleName;
+ switch ( m_pApplyTempl->eType )
+ {
+ case SFX_STYLE_FAMILY_PARA:
+ if( (( nsSelectionType::SEL_TXT | nsSelectionType::SEL_TBL )
+ & eSelection ) && !rSh.HasReadonlySel() )
+ {
+ rSh.SetTxtFmtColl( m_pApplyTempl->aColl.pTxtColl );
+ m_pApplyTempl->bUndo = true;
+ bCallBase = false;
+ if ( m_pApplyTempl->aColl.pTxtColl )
+ aStyleName = m_pApplyTempl->aColl.pTxtColl->GetName();
+ }
+ break;
+ case SFX_STYLE_FAMILY_CHAR:
+ if( (( nsSelectionType::SEL_TXT | nsSelectionType::SEL_TBL )
+ & eSelection ) && !rSh.HasReadonlySel() )
+ {
+ rSh.SetAttrItem( SwFmtCharFmt(m_pApplyTempl->aColl.pCharFmt) );
+ rSh.UnSetVisCrsr();
+ rSh.EnterStdMode();
+ rSh.SetVisCrsr(aDocPt);
+ m_pApplyTempl->bUndo = true;
+ bCallBase = false;
+ if ( m_pApplyTempl->aColl.pCharFmt )
+ aStyleName = m_pApplyTempl->aColl.pCharFmt->GetName();
+ }
+ break;
+ case SFX_STYLE_FAMILY_FRAME :
+ {
+ const SwFrmFmt* pFmt = rSh.GetFmtFromObj( aDocPt );
+ if(PTR_CAST(SwFlyFrmFmt, pFmt))
+ {
+ rSh.SetFrmFmt( m_pApplyTempl->aColl.pFrmFmt, false, &aDocPt );
+ m_pApplyTempl->bUndo = true;
+ bCallBase = false;
+ if( m_pApplyTempl->aColl.pFrmFmt )
+ aStyleName = m_pApplyTempl->aColl.pFrmFmt->GetName();
+ }
+ break;
+ }
+ case SFX_STYLE_FAMILY_PAGE:
+ // no Undo with page templates
+ rSh.ChgCurPageDesc( *m_pApplyTempl->aColl.pPageDesc );
+ if ( m_pApplyTempl->aColl.pPageDesc )
+ aStyleName = m_pApplyTempl->aColl.pPageDesc->GetName();
+ bCallBase = false;
+ break;
+ case SFX_STYLE_FAMILY_PSEUDO:
+ if( !rSh.HasReadonlySel() )
+ {
+ rSh.SetCurNumRule( *m_pApplyTempl->aColl.pNumRule,
+ false,
+ m_pApplyTempl->aColl.pNumRule->GetDefaultListId() );
+ bCallBase = false;
+ m_pApplyTempl->bUndo = true;
+ if( m_pApplyTempl->aColl.pNumRule )
+ aStyleName = m_pApplyTempl->aColl.pNumRule->GetName();
+ }
+ break;
+ }
+
+ uno::Reference< frame::XDispatchRecorder > xRecorder =
+ m_rView.GetViewFrame()->GetBindings().GetRecorder();
+ if ( !aStyleName.isEmpty() && xRecorder.is() )
+ {
+ SfxShell *pSfxShell = lcl_GetShellFromDispatcher( m_rView, TYPE(SwTextShell) );
+ if ( pSfxShell )
+ {
+ SfxRequest aReq( m_rView.GetViewFrame(), SID_STYLE_APPLY );
+ aReq.AppendItem( SfxStringItem( SID_STYLE_APPLY, aStyleName ) );
+ aReq.AppendItem( SfxUInt16Item( SID_STYLE_FAMILY, (sal_uInt16) m_pApplyTempl->eType ) );
+ aReq.Done();
+ }
+ }
+ }
+
+ }
+ ReleaseMouse();
+ // Only processed MouseEvents arrive here; only at these the moduses can
+ // be resetted.
+ m_bMBPressed = false;
+
+ // Make this call just to be sure. Selecting has finished surely by now.
+ // Otherwise the timeout's timer could give problems.
+ EnterArea();
+ bNoInterrupt = false;
+
+ if (bCallBase)
+ Window::MouseButtonUp(rMEvt);
+}
+
+/**
+ * Apply template
+ */
+void SwEditWin::SetApplyTemplate(const SwApplyTemplate &rTempl)
+{
+ static bool bIdle = false;
+ DELETEZ(m_pApplyTempl);
+ SwWrtShell &rSh = m_rView.GetWrtShell();
+
+ if(rTempl.m_pFormatClipboard)
+ {
+ m_pApplyTempl = new SwApplyTemplate( rTempl );
+ SetPointer( POINTER_FILL );//@todo #i20119# maybe better a new brush pointer here in future
+ rSh.NoEdit( false );
+ bIdle = rSh.GetViewOptions()->IsIdle();
+ ((SwViewOption *)rSh.GetViewOptions())->SetIdle( false );
+ }
+ else if(rTempl.nColor)
+ {
+ m_pApplyTempl = new SwApplyTemplate( rTempl );
+ SetPointer( POINTER_FILL );
+ rSh.NoEdit( false );
+ bIdle = rSh.GetViewOptions()->IsIdle();
+ ((SwViewOption *)rSh.GetViewOptions())->SetIdle( false );
+ }
+ else if( rTempl.eType )
+ {
+ m_pApplyTempl = new SwApplyTemplate( rTempl );
+ SetPointer( POINTER_FILL );
+ rSh.NoEdit( false );
+ bIdle = rSh.GetViewOptions()->IsIdle();
+ ((SwViewOption *)rSh.GetViewOptions())->SetIdle( false );
+ }
+ else
+ {
+ SetPointer( POINTER_TEXT );
+ rSh.UnSetVisCrsr();
+
+ ((SwViewOption *)rSh.GetViewOptions())->SetIdle( bIdle );
+ if ( !rSh.IsSelFrmMode() )
+ rSh.Edit();
+ }
+
+ static sal_uInt16 aInva[] =
+ {
+ SID_STYLE_WATERCAN,
+ SID_ATTR_CHAR_COLOR_EXT,
+ SID_ATTR_CHAR_COLOR_BACKGROUND_EXT,
+ 0
+ };
+ m_rView.GetViewFrame()->GetBindings().Invalidate(aInva);
+}
+
+/**
+ * Ctor
+ */
+SwEditWin::SwEditWin(Window *pParent, SwView &rMyView):
+ Window(pParent, WinBits(WB_CLIPCHILDREN | WB_DIALOGCONTROL)),
+ DropTargetHelper( this ),
+ DragSourceHelper( this ),
+
+ m_eBufferLanguage(LANGUAGE_DONTKNOW),
+ m_pApplyTempl(0),
+ m_pAnchorMarker( 0 ),
+ m_pUserMarker( 0 ),
+ m_pUserMarkerObj( 0 ),
+ m_pShadCrsr( 0 ),
+ m_pRowColumnSelectionStart( 0 ),
+
+ m_rView( rMyView ),
+
+ m_aActHitType(SDRHIT_NONE),
+ m_nDropFormat( 0 ),
+ m_nDropAction( 0 ),
+ m_nDropDestination( 0 ),
+
+ m_eBezierMode(SID_BEZIER_INSERT),
+ m_nInsFrmColCount( 1 ),
+ m_eDrawMode(OBJ_NONE),
+
+ m_bMBPressed(false),
+ m_bInsDraw(false),
+ m_bInsFrm(false),
+ m_bIsInMove(false),
+ m_bIsInDrag(false),
+ m_bOldIdle(false),
+ m_bOldIdleSet(false),
+ m_bTblInsDelMode(false),
+ m_bTblIsInsMode(false),
+ m_bChainMode(false),
+ m_bWasShdwCrsr(false),
+ m_bLockInput(false),
+ m_bIsRowDrag(false),
+ m_bUseInputLanguage(false),
+ m_bObjectSelect(false),
+ m_nKS_NUMDOWN_Count(0),
+ m_nKS_NUMINDENTINC_Count(0),
+ m_aFrameControlsManager( this )
+{
+ SetHelpId(HID_EDIT_WIN);
+ EnableChildTransparentMode();
+ SetDialogControlFlags( WINDOW_DLGCTRL_RETURN | WINDOW_DLGCTRL_WANTFOCUS );
+
+ m_bMBPressed = m_bInsDraw = m_bInsFrm =
+ m_bIsInDrag = m_bOldIdle = m_bOldIdleSet = m_bChainMode = m_bWasShdwCrsr = false;
+ // initially use the input language
+ m_bUseInputLanguage = true;
+
+ SetMapMode(MapMode(MAP_TWIP));
+
+ SetPointer( POINTER_TEXT );
+ m_aTimer.SetTimeoutHdl(LINK(this, SwEditWin, TimerHandler));
+
+ m_bTblInsDelMode = false;
+ m_aKeyInputTimer.SetTimeout( 3000 );
+ m_aKeyInputTimer.SetTimeoutHdl(LINK(this, SwEditWin, KeyInputTimerHandler));
+
+ m_aKeyInputFlushTimer.SetTimeout( 200 );
+ m_aKeyInputFlushTimer.SetTimeoutHdl(LINK(this, SwEditWin, KeyInputFlushHandler));
+
+ // TemplatePointer for colors should be resetted without
+ // selection after single click
+ m_aTemplateTimer.SetTimeout(400);
+ m_aTemplateTimer.SetTimeoutHdl(LINK(this, SwEditWin, TemplateTimerHdl));
+
+ // temporary solution!!! Should set the font of the current
+ // insert position at every curor movement!
+ if( !rMyView.GetDocShell()->IsReadOnly() )
+ {
+ Font aFont;
+ SetInputContext( InputContext( aFont, INPUTCONTEXT_TEXT |
+ INPUTCONTEXT_EXTTEXTINPUT ) );
+ }
+}
+
+SwEditWin::~SwEditWin()
+{
+ m_aKeyInputTimer.Stop();
+ delete m_pShadCrsr;
+ delete m_pRowColumnSelectionStart;
+ if( m_pQuickHlpData->m_bIsDisplayed && m_rView.GetWrtShellPtr() )
+ m_pQuickHlpData->Stop( m_rView.GetWrtShell() );
+ bExecuteDrag = false;
+ delete m_pApplyTempl;
+ m_rView.SetDrawFuncPtr(NULL);
+
+ delete m_pUserMarker;
+ delete m_pAnchorMarker;
+}
+
+/**
+ * Turn on DrawTextEditMode
+ */
+void SwEditWin::EnterDrawTextMode( const Point& aDocPos )
+{
+ if ( m_rView.EnterDrawTextMode(aDocPos) )
+ {
+ if (m_rView.GetDrawFuncPtr())
+ {
+ m_rView.GetDrawFuncPtr()->Deactivate();
+ m_rView.SetDrawFuncPtr(NULL);
+ m_rView.LeaveDrawCreate();
+ }
+ m_rView.NoRotate();
+ m_rView.AttrChangedNotify( &m_rView.GetWrtShell() );
+ }
+}
+
+/**
+ * Turn on DrawMode
+ */
+bool SwEditWin::EnterDrawMode(const MouseEvent& rMEvt, const Point& aDocPos)
+{
+ SwWrtShell &rSh = m_rView.GetWrtShell();
+ SdrView *pSdrView = rSh.GetDrawView();
+
+ if ( m_rView.GetDrawFuncPtr() )
+ {
+ if (rSh.IsDrawCreate())
+ return true;
+
+ bool bRet = m_rView.GetDrawFuncPtr()->MouseButtonDown( rMEvt );
+ m_rView.AttrChangedNotify( &rSh );
+ return bRet;
+ }
+
+ if ( pSdrView && pSdrView->IsTextEdit() )
+ {
+ bool bUnLockView = !rSh.IsViewLocked();
+ rSh.LockView( true );
+
+ rSh.EndTextEdit(); // clicked aside, end Edit
+ rSh.SelectObj( aDocPos );
+ if ( !rSh.IsObjSelected() && !rSh.IsFrmSelected() )
+ rSh.LeaveSelFrmMode();
+ else
+ {
+ SwEditWin::m_nDDStartPosY = aDocPos.Y();
+ SwEditWin::m_nDDStartPosX = aDocPos.X();
+ bFrmDrag = true;
+ }
+ if( bUnLockView )
+ rSh.LockView( false );
+ m_rView.AttrChangedNotify( &rSh );
+ return true;
+ }
+ return false;
+}
+
+bool SwEditWin::IsDrawSelMode()
+{
+ return IsObjectSelect();
+}
+
+void SwEditWin::GetFocus()
+{
+ if ( m_rView.GetPostItMgr()->HasActiveSidebarWin() )
+ {
+ m_rView.GetPostItMgr()->GrabFocusOnActiveSidebarWin();
+ }
+ else
+ {
+ m_rView.GotFocus();
+ Window::GetFocus();
+ m_rView.GetWrtShell().InvalidateAccessibleFocus();
+ }
+}
+
+void SwEditWin::LoseFocus()
+{
+ m_rView.GetWrtShell().InvalidateAccessibleFocus();
+ Window::LoseFocus();
+ if( m_pQuickHlpData->m_bIsDisplayed )
+ m_pQuickHlpData->Stop( m_rView.GetWrtShell() );
+ m_rView.LostFocus();
+}
+
+void SwEditWin::Command( const CommandEvent& rCEvt )
+{
+ SwWrtShell &rSh = m_rView.GetWrtShell();
+
+ if ( !m_rView.GetViewFrame() )
+ {
+ // If ViewFrame dies shortly, no popup anymore!
+ Window::Command(rCEvt);
+ return;
+ }
+
+ // The command event is send to the window after a possible context
+ // menu from an inplace client has been closed. Now we have the chance
+ // to deactivate the inplace client without any problem regarding parent
+ // windows and code on the stack.
+ SfxInPlaceClient* pIPClient = rSh.GetSfxViewShell()->GetIPClient();
+ bool bIsOleActive = ( pIPClient && pIPClient->IsObjectInPlaceActive() );
+ if ( bIsOleActive && ( rCEvt.GetCommand() == COMMAND_CONTEXTMENU ))
+ {
+ rSh.FinishOLEObj();
+ return;
+ }
+
+ bool bCallBase = true;
+
+ switch ( rCEvt.GetCommand() )
+ {
+ case COMMAND_CONTEXTMENU:
+ {
+ const sal_uInt16 nId = SwInputChild::GetChildWindowId();
+ SwInputChild* pChildWin = (SwInputChild*)GetView().GetViewFrame()->
+ GetChildWindow( nId );
+
+ if (m_rView.GetPostItMgr()->IsHit(rCEvt.GetMousePosPixel()))
+ return;
+
+ Point aDocPos( PixelToLogic( rCEvt.GetMousePosPixel() ) );
+ if ( !rCEvt.IsMouseEvent() )
+ aDocPos = rSh.GetCharRect().Center();
+
+ // Don't trigger the command on a frame anchored to header/footer is not editing it
+ FrameControlType eControl;
+ bool bOverFly = false;
+ bool bPageAnchored = false;
+ bool bOverHeaderFooterFly = IsOverHeaderFooterFly( aDocPos, eControl, bOverFly, bPageAnchored );
+ // !bOverHeaderFooterFly doesn't mean we have a frame to select
+ if ( !bPageAnchored && rCEvt.IsMouseEvent( ) &&
+ ( ( rSh.IsHeaderFooterEdit( ) && !bOverHeaderFooterFly && bOverFly ) ||
+ ( !rSh.IsHeaderFooterEdit( ) && bOverHeaderFooterFly ) ) )
+ {
+ return;
+ }
+
+ if((!pChildWin || pChildWin->GetView() != &m_rView) &&
+ !rSh.IsDrawCreate() && !IsDrawAction())
+ {
+ SET_CURR_SHELL( &rSh );
+ if (!m_pApplyTempl)
+ {
+ if (bNoInterrupt)
+ {
+ ReleaseMouse();
+ bNoInterrupt = false;
+ m_bMBPressed = false;
+ }
+ if ( rCEvt.IsMouseEvent() )
+ {
+ SelectMenuPosition(rSh, rCEvt.GetMousePosPixel());
+ m_rView.StopShellTimer();
+ }
+ const Point aPixPos = LogicToPixel( aDocPos );
+
+ if ( m_rView.GetDocShell()->IsReadOnly() )
+ {
+ SwReadOnlyPopup* pROPopup = new SwReadOnlyPopup( aDocPos, m_rView );
+
+ ui::ContextMenuExecuteEvent aEvent;
+ aEvent.SourceWindow = VCLUnoHelper::GetInterface( this );
+ aEvent.ExecutePosition.X = aPixPos.X();
+ aEvent.ExecutePosition.Y = aPixPos.Y();
+ Menu* pMenu = 0;
+ OUString sMenuName("private:resource/ReadonlyContextMenu");
+ if( GetView().TryContextMenuInterception( *pROPopup, sMenuName, pMenu, aEvent ) )
+ {
+ if ( pMenu )
+ {
+ sal_uInt16 nExecId = ((PopupMenu*)pMenu)->Execute(this, aPixPos);
+ if( !::ExecuteMenuCommand( *static_cast<PopupMenu*>(pMenu), *m_rView.GetViewFrame(), nExecId ))
+ pROPopup->Execute(this, nExecId);
+ }
+ else
+ pROPopup->Execute(this, aPixPos);
+ }
+ delete pROPopup;
+ }
+ else if ( !m_rView.ExecSpellPopup( aDocPos ) )
+ GetView().GetViewFrame()->GetDispatcher()->ExecutePopup( 0, this, &aPixPos);
+ }
+ else if (m_pApplyTempl->bUndo)
+ rSh.Do(SwWrtShell::UNDO);
+ bCallBase = false;
+ }
+ }
+ break;
+
+ case COMMAND_WHEEL:
+ case COMMAND_STARTAUTOSCROLL:
+ case COMMAND_AUTOSCROLL:
+ if( m_pShadCrsr )
+ delete m_pShadCrsr, m_pShadCrsr = 0;
+ bCallBase = !m_rView.HandleWheelCommands( rCEvt );
+ break;
+
+ case COMMAND_STARTEXTTEXTINPUT:
+ {
+ bool bIsDocReadOnly = m_rView.GetDocShell()->IsReadOnly() &&
+ rSh.IsCrsrReadonly();
+ if(!bIsDocReadOnly)
+ {
+ if( rSh.HasDrawView() && rSh.GetDrawView()->IsTextEdit() )
+ {
+ bCallBase = false;
+ rSh.GetDrawView()->GetTextEditOutlinerView()->Command( rCEvt );
+ }
+ else
+ {
+ if( rSh.HasSelection() )
+ rSh.DelRight();
+
+ bCallBase = false;
+ LanguageType eInputLanguage = GetInputLanguage();
+ rSh.CreateExtTextInput(eInputLanguage);
+ }
+ }
+ break;
+ }
+ case COMMAND_ENDEXTTEXTINPUT:
+ {
+ bool bIsDocReadOnly = m_rView.GetDocShell()->IsReadOnly() &&
+ rSh.IsCrsrReadonly();
+ if(!bIsDocReadOnly)
+ {
+ if( rSh.HasDrawView() && rSh.GetDrawView()->IsTextEdit() )
+ {
+ bCallBase = false;
+ rSh.GetDrawView()->GetTextEditOutlinerView()->Command( rCEvt );
+ }
+ else
+ {
+ bCallBase = false;
+ OUString sRecord = rSh.DeleteExtTextInput();
+ uno::Reference< frame::XDispatchRecorder > xRecorder =
+ m_rView.GetViewFrame()->GetBindings().GetRecorder();
+
+ if ( !sRecord.isEmpty() )
+ {
+ // convert quotes in IME text
+ // works on the last input character, this is escpecially in Korean text often done
+ // quotes that are inside of the string are not replaced!
+ const sal_Unicode aCh = sRecord[sRecord.getLength() - 1];
+ SvxAutoCorrCfg& rACfg = SvxAutoCorrCfg::Get();
+ SvxAutoCorrect* pACorr = rACfg.GetAutoCorrect();
+ if(pACorr &&
+ (( pACorr->IsAutoCorrFlag( ChgQuotes ) && ('\"' == aCh ))||
+ ( pACorr->IsAutoCorrFlag( ChgSglQuotes ) && ( '\'' == aCh))))
+ {
+ rSh.DelLeft();
+ rSh.AutoCorrect( *pACorr, aCh );
+ }
+
+ if ( xRecorder.is() )
+ {
+ // determine Shell
+ SfxShell *pSfxShell = lcl_GetShellFromDispatcher( m_rView, TYPE(SwTextShell) );
+ // generate request and record
+ if (pSfxShell)
+ {
+ SfxRequest aReq( m_rView.GetViewFrame(), FN_INSERT_STRING );
+ aReq.AppendItem( SfxStringItem( FN_INSERT_STRING, sRecord ) );
+ aReq.Done();
+ }
+ }
+ }
+ }
+ }
+ }
+ break;
+ case COMMAND_EXTTEXTINPUT:
+ {
+ bool bIsDocReadOnly = m_rView.GetDocShell()->IsReadOnly() &&
+ rSh.IsCrsrReadonly();
+ if(!bIsDocReadOnly)
+ {
+ if( m_pQuickHlpData->m_bIsDisplayed )
+ m_pQuickHlpData->Stop( rSh );
+
+ OUString sWord;
+ if( rSh.HasDrawView() && rSh.GetDrawView()->IsTextEdit() )
+ {
+ bCallBase = false;
+ rSh.GetDrawView()->GetTextEditOutlinerView()->Command( rCEvt );
+ }
+ else
+ {
+ const CommandExtTextInputData* pData = rCEvt.GetExtTextInputData();
+ if( pData )
+ {
+ sWord = pData->GetText();
+ bCallBase = false;
+ rSh.SetExtTextInputData( *pData );
+ }
+ }
+ uno::Reference< frame::XDispatchRecorder > xRecorder =
+ m_rView.GetViewFrame()->GetBindings().GetRecorder();
+ if(!xRecorder.is())
+ {
+ SvxAutoCorrCfg& rACfg = SvxAutoCorrCfg::Get();
+ SvxAutoCorrect* pACorr = rACfg.GetAutoCorrect();
+ if( pACorr &&
+ // If autocompletion required...
+ ( rACfg.IsAutoTextTip() ||
+ pACorr->GetSwFlags().bAutoCompleteWords ) &&
+ // ... and extraction of last word from text input was successful...
+ rSh.GetPrevAutoCorrWord( *pACorr, sWord ) )
+ {
+ // ... request for auto completion help to be shown.
+ ShowAutoTextCorrectQuickHelp(sWord, &rACfg, pACorr, true);
+ }
+ }
+ }
+ }
+ break;
+ case COMMAND_CURSORPOS:
+ // will be handled by the base class
+ break;
+
+ case COMMAND_PASTESELECTION:
+ if( !m_rView.GetDocShell()->IsReadOnly() )
+ {
+ TransferableDataHelper aDataHelper(
+ TransferableDataHelper::CreateFromSelection( this ));
+ if( !aDataHelper.GetXTransferable().is() )
+ break;
+
+ sal_uLong nDropFormat;
+ sal_uInt16 nEventAction, nDropAction, nDropDestination;
+ nDropDestination = GetDropDestination( rCEvt.GetMousePosPixel() );
+ if( !nDropDestination )
+ break;
+
+ nDropAction = SotExchange::GetExchangeAction(
+ aDataHelper.GetDataFlavorExVector(),
+ nDropDestination, EXCHG_IN_ACTION_COPY,
+ EXCHG_IN_ACTION_COPY, nDropFormat,
+ nEventAction );
+ if( EXCHG_INOUT_ACTION_NONE != nDropAction )
+ {
+ const Point aDocPt( PixelToLogic( rCEvt.GetMousePosPixel() ) );
+ SwTransferable::PasteData( aDataHelper, rSh, nDropAction,
+ nDropFormat, nDropDestination, false,
+ false, &aDocPt, EXCHG_IN_ACTION_COPY,
+ true );
+ }
+ }
+ break;
+ case COMMAND_MODKEYCHANGE :
+ {
+ const CommandModKeyData* pCommandData = (const CommandModKeyData*)rCEvt.GetData();
+ if(pCommandData->IsMod1() && !pCommandData->IsMod2())
+ {
+ sal_uInt16 nSlot = 0;
+ if(pCommandData->IsLeftShift() && !pCommandData->IsRightShift())
+ nSlot = SID_ATTR_PARA_LEFT_TO_RIGHT;
+ else if(!pCommandData->IsLeftShift() && pCommandData->IsRightShift())
+ nSlot = SID_ATTR_PARA_RIGHT_TO_LEFT;
+ if(nSlot && SW_MOD()->GetCTLOptions().IsCTLFontEnabled())
+ GetView().GetViewFrame()->GetDispatcher()->Execute(nSlot);
+ }
+ }
+ break;
+ case COMMAND_HANGUL_HANJA_CONVERSION :
+ GetView().GetViewFrame()->GetDispatcher()->Execute(SID_HANGUL_HANJA_CONVERSION);
+ break;
+ case COMMAND_INPUTLANGUAGECHANGE :
+ // i#42732 - update state of fontname if input language changes
+ bInputLanguageSwitched = true;
+ SetUseInputLanguage( true );
+ break;
+ case COMMAND_SELECTIONCHANGE:
+ {
+ const CommandSelectionChangeData *pData = rCEvt.GetSelectionChangeData();
+ rSh.SttCrsrMove();
+ rSh.GoStartSentence();
+ rSh.GetCrsr()->GetPoint()->nContent += sal::static_int_cast<sal_uInt16, sal_uLong>(pData->GetStart());
+ rSh.SetMark();
+ rSh.GetCrsr()->GetMark()->nContent += sal::static_int_cast<sal_uInt16, sal_uLong>(pData->GetEnd() - pData->GetStart());
+ rSh.EndCrsrMove( true );
+ }
+ break;
+ case COMMAND_PREPARERECONVERSION:
+ if( rSh.HasSelection() )
+ {
+ SwPaM *pCrsr = (SwPaM*)rSh.GetCrsr();
+
+ if( rSh.IsMultiSelection() )
+ {
+ if( pCrsr && !pCrsr->HasMark() &&
+ pCrsr->GetPoint() == pCrsr->GetMark() )
+ {
+ rSh.GoPrevCrsr();
+ pCrsr = (SwPaM*)rSh.GetCrsr();
+ }
+
+ // Cancel all selections other than the last selected one.
+ while( rSh.GetCrsr()->GetNext() != rSh.GetCrsr() )
+ delete rSh.GetCrsr()->GetNext();
+ }
+
+ if( pCrsr )
+ {
+ sal_uLong nPosNodeIdx = pCrsr->GetPoint()->nNode.GetIndex();
+ const sal_Int32 nPosIdx = pCrsr->GetPoint()->nContent.GetIndex();
+ sal_uLong nMarkNodeIdx = pCrsr->GetMark()->nNode.GetIndex();
+ const sal_Int32 nMarkIdx = pCrsr->GetMark()->nContent.GetIndex();
+
+ if( !rSh.GetCrsr()->HasMark() )
+ rSh.GetCrsr()->SetMark();
+
+ rSh.SttCrsrMove();
+
+ if( nPosNodeIdx < nMarkNodeIdx )
+ {
+ rSh.GetCrsr()->GetPoint()->nNode = nPosNodeIdx;
+ rSh.GetCrsr()->GetPoint()->nContent = nPosIdx;
+ rSh.GetCrsr()->GetMark()->nNode = nPosNodeIdx;
+ rSh.GetCrsr()->GetMark()->nContent =
+ rSh.GetCrsr()->GetCntntNode( true )->Len();
+ }
+ else if( nPosNodeIdx == nMarkNodeIdx )
+ {
+ rSh.GetCrsr()->GetPoint()->nNode = nPosNodeIdx;
+ rSh.GetCrsr()->GetPoint()->nContent = nPosIdx;
+ rSh.GetCrsr()->GetMark()->nNode = nMarkNodeIdx;
+ rSh.GetCrsr()->GetMark()->nContent = nMarkIdx;
+ }
+ else
+ {
+ rSh.GetCrsr()->GetMark()->nNode = nMarkNodeIdx;
+ rSh.GetCrsr()->GetMark()->nContent = nMarkIdx;
+ rSh.GetCrsr()->GetPoint()->nNode = nMarkNodeIdx;
+ rSh.GetCrsr()->GetPoint()->nContent =
+ rSh.GetCrsr()->GetCntntNode( false )->Len();
+ }
+
+ rSh.EndCrsrMove( true );
+ }
+ }
+ break;
+ case COMMAND_QUERYCHARPOSITION:
+ {
+ bool bVertical = rSh.IsInVerticalText();
+ const SwPosition& rPos = *rSh.GetCrsr()->GetPoint();
+ SwDocShell* pDocSh = m_rView.GetDocShell();
+ SwDoc *pDoc = pDocSh->GetDoc();
+ SwExtTextInput* pInput = pDoc->GetExtTextInput( rPos.nNode.GetNode(), rPos.nContent.GetIndex() );
+ if ( pInput )
+ {
+ const SwPosition& rStart = *pInput->Start();
+ const SwPosition& rEnd = *pInput->End();
+ int nSize = 0;
+ for ( SwIndex nIndex = rStart.nContent; nIndex < rEnd.nContent; ++nIndex )
+ {
+ ++nSize;
+ }
+ Window& rWin = rSh.GetView().GetEditWin();
+ if ( nSize == 0 )
+ {
+ // When the composition does not exist, use Caret rect instead.
+ SwRect aCaretRect ( rSh.GetCharRect() );
+ Rectangle aRect( aCaretRect.Left(), aCaretRect.Top(), aCaretRect.Right(), aCaretRect.Bottom() );
+ rWin.SetCompositionCharRect( &aRect, 1, bVertical );
+ }
+ else
+ {
+ Rectangle* aRects = new Rectangle[ nSize ];
+ int nRectIndex = 0;
+ for ( SwIndex nIndex = rStart.nContent; nIndex < rEnd.nContent; ++nIndex )
+ {
+ const SwPosition aPos( rStart.nNode, nIndex );
+ SwRect aRect ( rSh.GetCharRect() );
+ rSh.GetCharRectAt( aRect, &aPos );
+ aRects[ nRectIndex ] = Rectangle( aRect.Left(), aRect.Top(), aRect.Right(), aRect.Bottom() );
+ ++nRectIndex;
+ }
+ rWin.SetCompositionCharRect( aRects, nSize, bVertical );
+ delete[] aRects;
+ }
+ }
+ bCallBase = false;
+ }
+ break;
+#if OSL_DEBUG_LEVEL > 0
+ default:
+ OSL_ENSURE( !this, "unknown command." );
+#endif
+ }
+ if (bCallBase)
+ Window::Command(rCEvt);
+}
+
+/* i#18686 select the object/cursor at the mouse
+ position of the context menu request */
+bool SwEditWin::SelectMenuPosition(SwWrtShell& rSh, const Point& rMousePos )
+{
+ bool bRet = false;
+ const Point aDocPos( PixelToLogic( rMousePos ) );
+ const bool bIsInsideSelectedObj( rSh.IsInsideSelectedObj( aDocPos ) );
+ //create a synthetic mouse event out of the coordinates
+ MouseEvent aMEvt(rMousePos);
+ SdrView *pSdrView = rSh.GetDrawView();
+ if ( pSdrView )
+ {
+ // no close of insert_draw and reset of
+ // draw mode, if context menu position is inside a selected object.
+ if ( !bIsInsideSelectedObj && m_rView.GetDrawFuncPtr() )
+ {
+
+ m_rView.GetDrawFuncPtr()->Deactivate();
+ m_rView.SetDrawFuncPtr(NULL);
+ m_rView.LeaveDrawCreate();
+ SfxBindings& rBind = m_rView.GetViewFrame()->GetBindings();
+ rBind.Invalidate( SID_ATTR_SIZE );
+ rBind.Invalidate( SID_TABLE_CELL );
+ }
+
+ // if draw text is active and there's a text selection
+ // at the mouse position then do nothing
+ if(rSh.GetSelectionType() & nsSelectionType::SEL_DRW_TXT)
+ {
+ OutlinerView* pOLV = pSdrView->GetTextEditOutlinerView();
+ ESelection aSelection = pOLV->GetSelection();
+ if(!aSelection.IsZero())
+ {
+ SdrOutliner* pOutliner = pSdrView->GetTextEditOutliner();
+ bool bVertical = pOutliner->IsVertical();
+ const EditEngine& rEditEng = pOutliner->GetEditEngine();
+ Point aEEPos(aDocPos);
+ const Rectangle& rOutputArea = pOLV->GetOutputArea();
+ // regard vertical mode
+ if(bVertical)
+ {
+ aEEPos -= rOutputArea.TopRight();
+ //invert the horizontal direction and exchange X and Y
+ long nTemp = -aEEPos.X();
+ aEEPos.X() = aEEPos.Y();
+ aEEPos.Y() = nTemp;
+ }
+ else
+ aEEPos -= rOutputArea.TopLeft();
+
+ EPosition aDocPosition = rEditEng.FindDocPosition(aEEPos);
+ ESelection aCompare(aDocPosition.nPara, aDocPosition.nIndex);
+ // make it a forward selection - otherwise the IsLess/IsGreater do not work :-(
+ aSelection.Adjust();
+ if(!aCompare.IsLess(aSelection) && !aCompare.IsGreater(aSelection))
+ {
+ return false;
+ }
+ }
+
+ }
+
+ if (pSdrView->MouseButtonDown( aMEvt, this ) )
+ {
+ pSdrView->MouseButtonUp( aMEvt, this );
+ rSh.GetView().GetViewFrame()->GetBindings().InvalidateAll(false);
+ return true;
+ }
+ }
+ rSh.ResetCursorStack();
+
+ if ( EnterDrawMode( aMEvt, aDocPos ) )
+ {
+ return true;
+ }
+ if ( m_rView.GetDrawFuncPtr() && m_bInsFrm )
+ {
+ StopInsFrm();
+ rSh.Edit();
+ }
+
+ UpdatePointer( aDocPos, 0 );
+
+ if( !rSh.IsSelFrmMode() &&
+ !GetView().GetViewFrame()->GetDispatcher()->IsLocked() )
+ {
+ // Test if there is a draw object at that position and if it should be selected.
+ bool bShould = rSh.ShouldObjectBeSelected(aDocPos);
+
+ if(bShould)
+ {
+ m_rView.NoRotate();
+ rSh.HideCrsr();
+
+ bool bUnLockView = !rSh.IsViewLocked();
+ rSh.LockView( true );
+ bool bSelObj = rSh.SelectObj( aDocPos, 0);
+ if( bUnLockView )
+ rSh.LockView( false );
+
+ if( bSelObj )
+ {
+ bRet = true;
+ // in case the frame was deselected in the macro
+ // just the cursor has to be displayed again.
+ if( FRMTYPE_NONE == rSh.GetSelFrmType() )
+ rSh.ShowCrsr();
+ else
+ {
+ if (rSh.IsFrmSelected() && m_rView.GetDrawFuncPtr())
+ {
+ m_rView.GetDrawFuncPtr()->Deactivate();
+ m_rView.SetDrawFuncPtr(NULL);
+ m_rView.LeaveDrawCreate();
+ m_rView.AttrChangedNotify( &rSh );
+ }
+
+ rSh.EnterSelFrmMode( &aDocPos );
+ bFrmDrag = true;
+ UpdatePointer( aDocPos, 0 );
+ return bRet;
+ }
+ }
+
+ if (!m_rView.GetDrawFuncPtr())
+ rSh.ShowCrsr();
+ }
+ }
+ else if ( rSh.IsSelFrmMode() &&
+ (m_aActHitType == SDRHIT_NONE ||
+ !bIsInsideSelectedObj))
+ {
+ m_rView.NoRotate();
+ bool bUnLockView = !rSh.IsViewLocked();
+ rSh.LockView( true );
+ sal_uInt8 nFlag = 0;
+
+ if ( rSh.IsSelFrmMode() )
+ {
+ rSh.UnSelectFrm();
+ rSh.LeaveSelFrmMode();
+ m_rView.AttrChangedNotify(&rSh);
+ bRet = true;
+ }
+
+ bool bSelObj = rSh.SelectObj( aDocPos, nFlag );
+ if( bUnLockView )
+ rSh.LockView( false );
+
+ if( !bSelObj )
+ {
+ // move cursor here so that it is not drawn in the
+ // frame at first; ShowCrsr() happens in LeaveSelFrmMode()
+ bValidCrsrPos = !(CRSR_POSCHG & rSh.SetCursor(&aDocPos, false));
+ rSh.LeaveSelFrmMode();
+ m_rView.LeaveDrawCreate();
+ m_rView.AttrChangedNotify( &rSh );
+ bRet = true;
+ }
+ else
+ {
+ rSh.HideCrsr();
+ rSh.EnterSelFrmMode( &aDocPos );
+ rSh.SelFlyGrabCrsr();
+ rSh.MakeSelVisible();
+ bFrmDrag = true;
+ if( rSh.IsFrmSelected() &&
+ m_rView.GetDrawFuncPtr() )
+ {
+ m_rView.GetDrawFuncPtr()->Deactivate();
+ m_rView.SetDrawFuncPtr(NULL);
+ m_rView.LeaveDrawCreate();
+ m_rView.AttrChangedNotify( &rSh );
+ }
+ UpdatePointer( aDocPos, 0 );
+ bRet = true;
+ }
+ }
+ else if ( rSh.IsSelFrmMode() && bIsInsideSelectedObj )
+ {
+ // Object at the mouse cursor is already selected - do nothing
+ return false;
+ }
+
+ if ( rSh.IsGCAttr() )
+ {
+ rSh.GCAttr();
+ rSh.ClearGCAttr();
+ }
+
+ bool bOverSelect = rSh.ChgCurrPam( aDocPos ), bOverURLGrf = false;
+ if( !bOverSelect )
+ bOverURLGrf = bOverSelect = 0 != rSh.IsURLGrfAtPos( aDocPos );
+
+ if ( !bOverSelect )
+ {
+ { // create only temporary move context because otherwise
+ // the query against the content form doesn't work!!!
+ SwMvContext aMvContext( &rSh );
+ rSh.SetCursor(&aDocPos, false);
+ bRet = true;
+ }
+ }
+ if( !bOverURLGrf )
+ {
+ const int nSelType = rSh.GetSelectionType();
+ if( nSelType == nsSelectionType::SEL_OLE ||
+ nSelType == nsSelectionType::SEL_GRF )
+ {
+ SwMvContext aMvContext( &rSh );
+ if( !rSh.IsFrmSelected() )
+ rSh.GotoNextFly();
+ rSh.EnterSelFrmMode();
+ bRet = true;
+ }
+ }
+ return bRet;
+}
+
+static SfxShell* lcl_GetShellFromDispatcher( SwView& rView, TypeId nType )
+{
+ // determine Shell
+ SfxShell* pShell;
+ SfxDispatcher* pDispatcher = rView.GetViewFrame()->GetDispatcher();
+ for(sal_uInt16 i = 0; true; ++i )
+ {
+ pShell = pDispatcher->GetShell( i );
+ if( !pShell || pShell->IsA( nType ) )
+ break;
+ }
+ return pShell;
+}
+
+IMPL_LINK_NOARG(SwEditWin, KeyInputFlushHandler)
+{
+ FlushInBuffer();
+ return 0;
+}
+
+IMPL_LINK_NOARG(SwEditWin, KeyInputTimerHandler)
+{
+ m_bTblInsDelMode = false;
+ return 0;
+}
+
+void SwEditWin::_InitStaticData()
+{
+ m_pQuickHlpData = new QuickHelpData();
+}
+
+void SwEditWin::_FinitStaticData()
+{
+ delete m_pQuickHlpData;
+}
+/* i#3370 - remove quick help to prevent saving
+ * of autocorrection suggestions */
+void SwEditWin::StopQuickHelp()
+{
+ if( HasFocus() && m_pQuickHlpData && m_pQuickHlpData->m_bIsDisplayed )
+ m_pQuickHlpData->Stop( m_rView.GetWrtShell() );
+}
+
+IMPL_LINK_NOARG(SwEditWin, TemplateTimerHdl)
+{
+ SetApplyTemplate(SwApplyTemplate());
+ return 0;
+}
+
+void SwEditWin::SetChainMode( bool bOn )
+{
+ if ( !m_bChainMode )
+ StopInsFrm();
+
+ if ( m_pUserMarker )
+ {
+ delete m_pUserMarker;
+ m_pUserMarker = 0L;
+ }
+
+ m_bChainMode = bOn;
+
+ static sal_uInt16 aInva[] =
+ {
+ FN_FRAME_CHAIN, FN_FRAME_UNCHAIN, 0
+ };
+ m_rView.GetViewFrame()->GetBindings().Invalidate(aInva);
+}
+
+uno::Reference< ::com::sun::star::accessibility::XAccessible > SwEditWin::CreateAccessible()
+{
+ SolarMutexGuard aGuard; // this should have happened already!!!
+ SwWrtShell *pSh = m_rView.GetWrtShellPtr();
+ OSL_ENSURE( pSh, "no writer shell, no accessible object" );
+ uno::Reference<
+ ::com::sun::star::accessibility::XAccessible > xAcc;
+ if( pSh )
+ xAcc = pSh->CreateAccessible();
+
+ return xAcc;
+}
+
+void QuickHelpData::Move( QuickHelpData& rCpy )
+{
+ m_aHelpStrings.clear();
+ m_aHelpStrings.swap( rCpy.m_aHelpStrings );
+
+ m_bIsDisplayed = rCpy.m_bIsDisplayed;
+ nLen = rCpy.nLen;
+ nCurArrPos = rCpy.nCurArrPos;
+ m_bAppendSpace = rCpy.m_bAppendSpace;
+ m_bIsTip = rCpy.m_bIsTip;
+ m_bIsAutoText = rCpy.m_bIsAutoText;
+}
+
+void QuickHelpData::ClearCntnt()
+{
+ nLen = nCurArrPos = 0;
+ m_bIsDisplayed = m_bAppendSpace = false;
+ nTipId = 0;
+ m_aHelpStrings.clear();
+ m_bIsTip = true;
+ m_bIsAutoText = true;
+}
+
+void QuickHelpData::Start( SwWrtShell& rSh, sal_uInt16 nWrdLen )
+{
+ if( USHRT_MAX != nWrdLen )
+ {
+ nLen = nWrdLen;
+ nCurArrPos = 0;
+ }
+ m_bIsDisplayed = true;
+
+ Window& rWin = rSh.GetView().GetEditWin();
+ if( m_bIsTip )
+ {
+ Point aPt( rWin.OutputToScreenPixel( rWin.LogicToPixel(
+ rSh.GetCharRect().Pos() )));
+ aPt.Y() -= 3;
+ nTipId = Help::ShowTip( &rWin, Rectangle( aPt, Size( 1, 1 )),
+ m_aHelpStrings[ nCurArrPos ],
+ QUICKHELP_LEFT | QUICKHELP_BOTTOM );
+ }
+ else
+ {
+ OUString sStr( m_aHelpStrings[ nCurArrPos ] );
+ sStr = sStr.copy( nLen );
+ sal_uInt16 nL = sStr.getLength();
+ const sal_uInt16 nVal = EXTTEXTINPUT_ATTR_DOTTEDUNDERLINE |
+ EXTTEXTINPUT_ATTR_HIGHLIGHT;
+ const std::vector<sal_uInt16> aAttrs( nL, nVal );
+ CommandExtTextInputData aCETID( sStr, &aAttrs[0], nL,
+ 0, false );
+
+ //fdo#33092. If the current input language is the default
+ //language that text would appear in if typed, then don't
+ //force a language on for the ExtTextInput.
+ LanguageType eInputLanguage = rWin.GetInputLanguage();
+ if (lcl_isNonDefaultLanguage(eInputLanguage,
+ rSh.GetView(), sStr) == INVALID_HINT)
+ {
+ eInputLanguage = LANGUAGE_DONTKNOW;
+ }
+
+ rSh.CreateExtTextInput(eInputLanguage);
+ rSh.SetExtTextInputData( aCETID );
+ }
+}
+
+void QuickHelpData::Stop( SwWrtShell& rSh )
+{
+ if( !m_bIsTip )
+ rSh.DeleteExtTextInput( 0, false );
+ else if( nTipId )
+ Help::HideTip( nTipId );
+ ClearCntnt();
+}
+
+void QuickHelpData::FillStrArr( SwWrtShell& rSh, const OUString& rWord )
+{
+ enum Capitalization { CASE_LOWER, CASE_UPPER, CASE_SENTENCE, CASE_OTHER };
+
+ // Determine word capitalization
+ const CharClass& rCC = GetAppCharClass();
+ const OUString sWordLower = rCC.lowercase( rWord );
+ Capitalization aWordCase = CASE_OTHER;
+ if ( !rWord.isEmpty() )
+ {
+ if ( rWord[0] == sWordLower[0] )
+ {
+ if ( rWord == sWordLower )
+ aWordCase = CASE_LOWER;
+ }
+ else
+ {
+ // First character is not lower case i.e. assume upper or title case
+ OUString sWordSentence = sWordLower;
+ sWordSentence = sWordSentence.replaceAt( 0, 1, OUString(rWord[0]) );
+ if ( rWord == sWordSentence )
+ aWordCase = CASE_SENTENCE;
+ else
+ {
+ if ( rWord == rCC.uppercase( rWord ) )
+ aWordCase = CASE_UPPER;
+ }
+ }
+ }
+
+ salhelper::SingletonRef<SwCalendarWrapper>* pCalendar = s_getCalendarWrapper();
+ (*pCalendar)->LoadDefaultCalendar( rSh.GetCurLang() );
+
+ // Add matching calendar month and day names
+ uno::Sequence< i18n::CalendarItem2 > aNames( (*pCalendar)->getMonths() );
+ for ( sal_uInt16 i = 0; i < 2; ++i )
+ {
+ for ( long n = 0; n < aNames.getLength(); ++n )
+ {
+ const OUString& rStr( aNames[n].FullName );
+ // Check string longer than word and case insensitive match
+ if( rStr.getLength() > rWord.getLength() &&
+ rCC.lowercase( rStr, 0, rWord.getLength() ) == sWordLower )
+ {
+ //fdo#61251 if it's an exact match, ensure unchanged replacement
+ //exists as a candidate
+ if (rStr.startsWith(rWord))
+ m_aHelpStrings.push_back(rStr);
+
+ if ( aWordCase == CASE_LOWER )
+ m_aHelpStrings.push_back( rCC.lowercase( rStr ) );
+ else if ( aWordCase == CASE_SENTENCE )
+ {
+ OUString sTmp = rCC.lowercase( rStr );
+ sTmp = sTmp.replaceAt( 0, 1, OUString(rStr[0]) );
+ m_aHelpStrings.push_back( sTmp );
+ }
+ else if ( aWordCase == CASE_UPPER )
+ m_aHelpStrings.push_back( rCC.uppercase( rStr ) );
+ else // CASE_OTHER - use retrieved capitalization
+ m_aHelpStrings.push_back( rStr );
+ }
+ }
+ // Data for second loop iteration
+ if ( i == 0 )
+ aNames = (*pCalendar)->getDays();
+ }
+
+ // Add matching words from AutoCompleteWord list
+ const SwAutoCompleteWord& rACList = rSh.GetAutoCompleteWords();
+ std::vector<OUString> strings;
+
+ if ( rACList.GetWordsMatching( rWord, strings ) )
+ {
+ for (unsigned int i= 0; i<strings.size(); i++)
+ {
+ OUString aCompletedString = strings[i];
+ //fdo#61251 if it's an exact match, ensure unchanged replacement
+ //exists as a candidate
+ if (aCompletedString.startsWith(rWord))
+ m_aHelpStrings.push_back(aCompletedString);
+ if ( aWordCase == CASE_LOWER )
+ m_aHelpStrings.push_back( rCC.lowercase( aCompletedString ) );
+ else if ( aWordCase == CASE_SENTENCE )
+ {
+ OUString sTmp = rCC.lowercase( aCompletedString );
+ sTmp = sTmp.replaceAt( 0, 1, OUString(aCompletedString[0]) );
+ m_aHelpStrings.push_back( sTmp );
+ }
+ else if ( aWordCase == CASE_UPPER )
+ m_aHelpStrings.push_back( rCC.uppercase( aCompletedString ) );
+ else // CASE_OTHER - use retrieved capitalization
+ m_aHelpStrings.push_back( aCompletedString );
+ }
+ }
+
+}
+
+namespace {
+
+class CompareIgnoreCaseAsciiFavorExact
+ : public std::binary_function<const OUString&, const OUString&, bool>
+{
+ const OUString &m_rOrigWord;
+public:
+ CompareIgnoreCaseAsciiFavorExact(const OUString& rOrigWord)
+ : m_rOrigWord(rOrigWord)
+ {
+ }
+
+ bool operator()(const OUString& s1, const OUString& s2) const
+ {
+ int nRet = s1.compareToIgnoreAsciiCase(s2);
+ if (nRet == 0)
+ {
+ //fdo#61251 sort stuff that starts with the exact rOrigWord before
+ //another ignore-case candidate
+ int n1StartsWithOrig = s1.startsWith(m_rOrigWord) ? 0 : 1;
+ int n2StartsWithOrig = s2.startsWith(m_rOrigWord) ? 0 : 1;
+ return n1StartsWithOrig < n2StartsWithOrig;
+ }
+ return nRet < 0;
+ }
+};
+
+struct EqualIgnoreCaseAscii
+{
+ bool operator()(const OUString& s1, const OUString& s2) const
+ {
+ return s1.equalsIgnoreAsciiCase(s2);
+ }
+};
+
+} // anonymous namespace
+
+// TODO Implement an i18n aware sort
+void QuickHelpData::SortAndFilter(const OUString &rOrigWord)
+{
+ std::sort( m_aHelpStrings.begin(),
+ m_aHelpStrings.end(),
+ CompareIgnoreCaseAsciiFavorExact(rOrigWord) );
+
+ std::vector<OUString>::iterator it = std::unique( m_aHelpStrings.begin(),
+ m_aHelpStrings.end(),
+ EqualIgnoreCaseAscii() );
+ m_aHelpStrings.erase( it, m_aHelpStrings.end() );
+
+ nCurArrPos = 0;
+}
+
+void SwEditWin::ShowAutoTextCorrectQuickHelp(
+ const OUString& rWord, SvxAutoCorrCfg* pACfg, SvxAutoCorrect* pACorr,
+ bool bFromIME )
+{
+ SwWrtShell& rSh = m_rView.GetWrtShell();
+ m_pQuickHlpData->ClearCntnt();
+ if( pACfg->IsAutoTextTip() )
+ {
+ SwGlossaryList* pList = ::GetGlossaryList();
+ pList->HasLongName( rWord, &m_pQuickHlpData->m_aHelpStrings );
+ }
+
+ if( m_pQuickHlpData->m_aHelpStrings.empty() &&
+ pACorr->GetSwFlags().bAutoCompleteWords )
+ {
+ m_pQuickHlpData->m_bIsAutoText = false;
+ m_pQuickHlpData->m_bIsTip = bFromIME ||
+ !pACorr ||
+ pACorr->GetSwFlags().bAutoCmpltShowAsTip;
+
+ // Get the necessary data to show help text.
+ m_pQuickHlpData->FillStrArr( rSh, rWord );
+ }
+
+ if( !m_pQuickHlpData->m_aHelpStrings.empty() )
+ {
+ m_pQuickHlpData->SortAndFilter(rWord);
+ m_pQuickHlpData->Start( rSh, rWord.getLength() );
+ }
+}
+
+bool SwEditWin::IsInHeaderFooter( const Point &rDocPt, FrameControlType &rControl ) const
+{
+ SwWrtShell &rSh = m_rView.GetWrtShell();
+ const SwPageFrm* pPageFrm = rSh.GetLayout()->GetPageAtPos( rDocPt );
+
+ if ( pPageFrm && pPageFrm->IsOverHeaderFooterArea( rDocPt, rControl ) )
+ return true;
+
+ if ( rSh.IsShowHeaderFooterSeparator( Header ) || rSh.IsShowHeaderFooterSeparator( Footer ) )
+ {
+ SwFrameControlsManager &rMgr = rSh.GetView().GetEditWin().GetFrameControlsManager();
+ Point aPoint( LogicToPixel( rDocPt ) );
+
+ if ( rSh.IsShowHeaderFooterSeparator( Header ) )
+ {
+ SwFrameControlPtr pControl = rMgr.GetControl( Header, pPageFrm );
+ if ( pControl.get() && pControl->Contains( aPoint ) )
+ {
+ rControl = Header;
+ return true;
+ }
+ }
+
+ if ( rSh.IsShowHeaderFooterSeparator( Footer ) )
+ {
+ SwFrameControlPtr pControl = rMgr.GetControl( Footer, pPageFrm );
+ if ( pControl.get() && pControl->Contains( aPoint ) )
+ {
+ rControl = Footer;
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+bool SwEditWin::IsOverHeaderFooterFly( const Point& rDocPos, FrameControlType& rControl, bool& bOverFly, bool& bPageAnchored ) const
+{
+ bool bRet = false;
+ Point aPt( rDocPos );
+ SwWrtShell &rSh = m_rView.GetWrtShell();
+ SwPaM aPam( *rSh.GetCurrentShellCursor().GetPoint() );
+ rSh.GetLayout()->GetCrsrOfst( aPam.GetPoint(), aPt, NULL, true );
+
+ const SwStartNode* pStartFly = aPam.GetPoint()->nNode.GetNode().FindFlyStartNode();
+ if ( pStartFly )
+ {
+ bOverFly = true;
+ SwFrmFmt* pFlyFmt = pStartFly->GetFlyFmt( );
+ if ( pFlyFmt )
+ {
+ const SwPosition* pAnchor = pFlyFmt->GetAnchor( ).GetCntntAnchor( );
+ if ( pAnchor )
+ {
+ bool bInHeader = pAnchor->nNode.GetNode( ).FindHeaderStartNode( ) != NULL;
+ bool bInFooter = pAnchor->nNode.GetNode( ).FindFooterStartNode( ) != NULL;
+
+ bRet = bInHeader || bInFooter;
+ if ( bInHeader )
+ rControl = Header;
+ else if ( bInFooter )
+ rControl = Footer;
+ }
+ else
+ bPageAnchored = pFlyFmt->GetAnchor( ).GetAnchorId( ) == FLY_AT_PAGE;
+ }
+ }
+ else
+ bOverFly = false;
+ return bRet;
+}
+
+void SwEditWin::SetUseInputLanguage( bool bNew )
+{
+ if ( bNew || m_bUseInputLanguage )
+ {
+ SfxBindings& rBind = GetView().GetViewFrame()->GetBindings();
+ rBind.Invalidate( SID_ATTR_CHAR_FONT );
+ rBind.Invalidate( SID_ATTR_CHAR_FONTHEIGHT );
+ }
+ m_bUseInputLanguage = bNew;
+}
+
+OUString SwEditWin::GetSurroundingText() const
+{
+ OUString sReturn;
+ SwWrtShell& rSh = m_rView.GetWrtShell();
+ if( rSh.HasSelection() && !rSh.IsMultiSelection() && rSh.IsSelOnePara() )
+ rSh.GetSelectedText( sReturn, GETSELTXT_PARABRK_TO_ONLYCR );
+ else if( !rSh.HasSelection() )
+ {
+ SwPosition *pPos = rSh.GetCrsr()->GetPoint();
+ const sal_Int32 nPos = pPos->nContent.GetIndex();
+
+ // get the sentence around the cursor
+ rSh.HideCrsr();
+ rSh.GoStartSentence();
+ rSh.SetMark();
+ rSh.GoEndSentence();
+ rSh.GetSelectedText( sReturn, GETSELTXT_PARABRK_TO_ONLYCR );
+
+ pPos->nContent = nPos;
+ rSh.ClearMark();
+ rSh.HideCrsr();
+ }
+
+ return sReturn;
+}
+
+Selection SwEditWin::GetSurroundingTextSelection() const
+{
+ SwWrtShell& rSh = m_rView.GetWrtShell();
+ if( rSh.HasSelection() )
+ {
+ OUString sReturn;
+ rSh.GetSelectedText( sReturn, GETSELTXT_PARABRK_TO_ONLYCR );
+ return Selection( 0, sReturn.getLength() );
+ }
+ else
+ {
+ // Return the position of the visible cursor in the sentence
+ // around the visible cursor.
+ SwPosition *pPos = rSh.GetCrsr()->GetPoint();
+ const sal_Int32 nPos = pPos->nContent.GetIndex();
+
+ rSh.HideCrsr();
+ rSh.GoStartSentence();
+ const sal_Int32 nStartPos = rSh.GetCrsr()->GetPoint()->nContent.GetIndex();
+
+ pPos->nContent = nPos;
+ rSh.ClearMark();
+ rSh.ShowCrsr();
+
+ return Selection( nPos - nStartPos, nPos - nStartPos );
+ }
+}
+
+// MT: Removed Windows::SwitchView() introduced with IA2 CWS.
+// There are other notifications for this when the active view has changed, so please update the code to use that event mechanism
+void SwEditWin::SwitchView()
+{
+#ifdef ACCESSIBLE_LAYOUT
+ if (!Application::IsAccessibilityEnabled())
+ {
+ return ;
+ }
+ rView.GetWrtShell().InvalidateAccessibleFocus();
+#endif
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/docvw/edtwin2.cxx b/sw/source/uibase/docvw/edtwin2.cxx
new file mode 100644
index 000000000000..bbcaaf1a6399
--- /dev/null
+++ b/sw/source/uibase/docvw/edtwin2.cxx
@@ -0,0 +1,465 @@
+/* -*- 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 <comphelper/string.hxx>
+#include <hintids.hxx>
+
+#include <doc.hxx>
+#if OSL_DEBUG_LEVEL > 1
+#include <stdio.h>
+#endif
+#include <osl/thread.h>
+#include <vcl/help.hxx>
+#include <svl/stritem.hxx>
+#include <unotools/securityoptions.hxx>
+#include <tools/urlobj.hxx>
+#include <txtrfmrk.hxx>
+#include <fmtrfmrk.hxx>
+#include <editeng/flditem.hxx>
+#include <svl/urihelper.hxx>
+#include <svx/svdotext.hxx>
+#include <editeng/outliner.hxx>
+#include <svl/itemiter.hxx>
+#include <svx/svdview.hxx>
+#include <svx/svdpagv.hxx>
+#include <swmodule.hxx>
+#include <modcfg.hxx>
+#include <view.hxx>
+#include <wrtsh.hxx>
+#include <docsh.hxx>
+#include <edtwin.hxx>
+#include <dpage.hxx>
+#include <shellres.hxx>
+#include <docufld.hxx>
+#include <dbfld.hxx>
+#include <reffld.hxx>
+#include <cellatr.hxx>
+#include <shdwcrsr.hxx>
+#include <fmtcol.hxx>
+#include <charfmt.hxx>
+#include <fmtftn.hxx>
+#include <redline.hxx>
+#include <tox.hxx>
+#include <txttxmrk.hxx>
+#include <uitool.hxx>
+#include <viewopt.hxx>
+#include <docvw.hrc>
+#include <utlui.hrc>
+
+#include <PostItMgr.hxx>
+#include <fmtfld.hxx>
+
+#include <IDocumentMarkAccess.hxx>
+#include <ndtxt.hxx>
+
+static OUString lcl_GetRedlineHelp( const SwRangeRedline& rRedl, bool bBalloon )
+{
+ sal_uInt16 nResId = 0;
+ switch( rRedl.GetType() )
+ {
+ case nsRedlineType_t::REDLINE_INSERT: nResId = STR_REDLINE_INSERT; break;
+ case nsRedlineType_t::REDLINE_DELETE: nResId = STR_REDLINE_DELETE; break;
+ case nsRedlineType_t::REDLINE_FORMAT: nResId = STR_REDLINE_FORMAT; break;
+ case nsRedlineType_t::REDLINE_TABLE: nResId = STR_REDLINE_TABLE; break;
+ case nsRedlineType_t::REDLINE_FMTCOLL: nResId = STR_REDLINE_FMTCOLL; break;
+ }
+
+ OUStringBuffer sBuf;
+ if( nResId )
+ {
+ sBuf.append(SW_RESSTR(nResId));
+ sBuf.append(": ");
+ sBuf.append(rRedl.GetAuthorString());
+ sBuf.append(" - ");
+ sBuf.append(GetAppLangDateTimeString(rRedl.GetTimeStamp()));
+ if( bBalloon && !rRedl.GetComment().isEmpty() )
+ sBuf.append('\n').append(rRedl.GetComment());
+ }
+ return sBuf.makeStringAndClear();
+}
+
+void SwEditWin::RequestHelp(const HelpEvent &rEvt)
+{
+ SwWrtShell &rSh = m_rView.GetWrtShell();
+ bool bQuickBalloon = 0 != (rEvt.GetMode() & ( HELPMODE_QUICK | HELPMODE_BALLOON ));
+ if(bQuickBalloon && !rSh.GetViewOptions()->IsShowContentTips())
+ return;
+ bool bContinue = true;
+ SET_CURR_SHELL(&rSh);
+ OUString sTxt;
+ Point aPos( PixelToLogic( ScreenToOutputPixel( rEvt.GetMousePosPixel() ) ));
+ bool bBalloon = static_cast< bool >(rEvt.GetMode() & HELPMODE_BALLOON);
+
+ SdrView *pSdrView = rSh.GetDrawView();
+
+ if( bQuickBalloon )
+ {
+ if( pSdrView )
+ {
+ SdrPageView* pPV = pSdrView->GetSdrPageView();
+ SwDPage* pPage = pPV ? ((SwDPage*)pPV->GetPage()) : 0;
+ bContinue = pPage && pPage->RequestHelp(this, pSdrView, rEvt);
+ }
+ }
+
+ if( bContinue && bQuickBalloon)
+ {
+ SwRect aFldRect;
+ SwContentAtPos aCntntAtPos( SwContentAtPos::SW_FIELD |
+ SwContentAtPos::SW_INETATTR |
+ SwContentAtPos::SW_FTN |
+ SwContentAtPos::SW_REDLINE |
+ SwContentAtPos::SW_TOXMARK |
+ SwContentAtPos::SW_REFMARK |
+ SwContentAtPos::SW_SMARTTAG |
+#ifdef DBG_UTIL
+ SwContentAtPos::SW_TABLEBOXVALUE |
+ ( bBalloon ? SwContentAtPos::SW_CURR_ATTRS : 0) |
+#endif
+ SwContentAtPos::SW_TABLEBOXFML );
+
+ if( rSh.GetContentAtPos( aPos, aCntntAtPos, false, &aFldRect ) )
+ {
+ sal_uInt16 nStyle = 0; // style of quick help
+ switch( aCntntAtPos.eCntntAtPos )
+ {
+ case SwContentAtPos::SW_TABLEBOXFML:
+ sTxt = "= ";
+ sTxt += ((SwTblBoxFormula*)aCntntAtPos.aFnd.pAttr)->GetFormula();
+ break;
+#ifdef DBG_UTIL
+ case SwContentAtPos::SW_TABLEBOXVALUE:
+ {
+ sTxt = OStringToOUString(OString::number(
+ ((SwTblBoxValue*)aCntntAtPos.aFnd.pAttr)->GetValue()),
+ osl_getThreadTextEncoding());
+ }
+ break;
+ case SwContentAtPos::SW_CURR_ATTRS:
+ sTxt = aCntntAtPos.sStr;
+ break;
+#endif
+
+ case SwContentAtPos::SW_INETATTR:
+ {
+ sTxt = ((SfxStringItem*)aCntntAtPos.aFnd.pAttr)->GetValue();
+ sTxt = URIHelper::removePassword( sTxt,
+ INetURLObject::WAS_ENCODED,
+ INetURLObject::DECODE_UNAMBIGUOUS);
+ //#i63832# remove the link target type
+ sal_Int32 nFound = sTxt.indexOf(cMarkSeparator);
+ if( nFound != -1 && (++nFound) < sTxt.getLength() )
+ {
+ OUString sSuffix( sTxt.copy(nFound) );
+ if( sSuffix == "table" ||
+ sSuffix == "frame" ||
+ sSuffix == "region" ||
+ sSuffix == "outline" ||
+ sSuffix == "text" ||
+ sSuffix == "graphic" ||
+ sSuffix == "ole" )
+ sTxt = sTxt.copy( 0, nFound - 1);
+ }
+ // #i104300#
+ // special handling if target is a cross-reference bookmark
+ {
+ OUString sTmpSearchStr = sTxt.copy( 1 );
+ IDocumentMarkAccess* const pMarkAccess =
+ rSh.getIDocumentMarkAccess();
+ IDocumentMarkAccess::const_iterator_t ppBkmk =
+ pMarkAccess->findBookmark( sTmpSearchStr );
+ if ( ppBkmk != pMarkAccess->getBookmarksEnd() &&
+ IDocumentMarkAccess::GetType( *(ppBkmk->get()) )
+ == IDocumentMarkAccess::CROSSREF_HEADING_BOOKMARK )
+ {
+ SwTxtNode* pTxtNode = ppBkmk->get()->GetMarkStart().nNode.GetNode().GetTxtNode();
+ if ( pTxtNode )
+ {
+ sTxt = pTxtNode->GetExpandTxt( 0, pTxtNode->Len(), true, true );
+
+ if( !sTxt.isEmpty() )
+ {
+ OUStringBuffer sTmp(comphelper::string::remove(sTxt, 0xad));
+ for (sal_Int32 i = 0; i < sTmp.getLength(); ++i)
+ {
+ if (sTmp[i] < 0x20)
+ sTmp[i] = 0x20;
+ else if (sTmp[i] == 0x2011)
+ sTmp[i] = '-';
+ }
+ sTxt = sTmp.makeStringAndClear();
+ }
+ }
+ }
+ }
+ // #i80029#
+ bool bExecHyperlinks = m_rView.GetDocShell()->IsReadOnly();
+ if ( !bExecHyperlinks )
+ {
+ SvtSecurityOptions aSecOpts;
+ bExecHyperlinks = !aSecOpts.IsOptionSet( SvtSecurityOptions::E_CTRLCLICK_HYPERLINK );
+
+ sTxt = ": " + sTxt;
+ if ( !bExecHyperlinks )
+ sTxt = SwViewShell::GetShellRes()->aLinkCtrlClick + sTxt;
+ else
+ sTxt = SwViewShell::GetShellRes()->aLinkClick + sTxt;
+ }
+ break;
+ }
+ case SwContentAtPos::SW_SMARTTAG:
+ {
+ KeyCode aCode( KEY_SPACE );
+ KeyCode aModifiedCode( KEY_SPACE, KEY_MOD1 );
+ OUString aModStr( aModifiedCode.GetName() );
+ aModStr = aModStr.replaceFirst(aCode.GetName(), OUString());
+ aModStr = aModStr.replaceAll("+", OUString());
+ sTxt = SW_RESSTR(STR_SMARTTAG_CLICK).replaceAll("%s", aModStr);
+ }
+ break;
+
+ case SwContentAtPos::SW_FTN:
+ if( aCntntAtPos.pFndTxtAttr && aCntntAtPos.aFnd.pAttr )
+ {
+ const SwFmtFtn* pFtn = (SwFmtFtn*)aCntntAtPos.aFnd.pAttr;
+ OUString sTmp;
+ pFtn->GetFtnText( sTmp );
+ sTxt = SW_RESSTR( pFtn->IsEndNote()
+ ? STR_ENDNOTE : STR_FTNNOTE ) + sTmp;
+ bBalloon = true;
+ if( aCntntAtPos.IsInRTLText() )
+ nStyle |= QUICKHELP_BIDI_RTL;
+ }
+ break;
+
+ case SwContentAtPos::SW_REDLINE:
+ sTxt = lcl_GetRedlineHelp(*aCntntAtPos.aFnd.pRedl, bBalloon);
+ break;
+
+ case SwContentAtPos::SW_TOXMARK:
+ sTxt = aCntntAtPos.sStr;
+ if( !sTxt.isEmpty() && aCntntAtPos.pFndTxtAttr )
+ {
+ const SwTOXType* pTType = aCntntAtPos.pFndTxtAttr->
+ GetTOXMark().GetTOXType();
+ if( pTType && !pTType->GetTypeName().isEmpty() )
+ {
+ sTxt = ": " + sTxt;
+ sTxt = pTType->GetTypeName() + sTxt;
+ }
+ }
+ break;
+ case SwContentAtPos::SW_REFMARK:
+ if(aCntntAtPos.aFnd.pAttr)
+ {
+ sTxt = SW_RESSTR(STR_CONTENT_TYPE_SINGLE_REFERENCE);
+ sTxt += ": ";
+ sTxt += ((const SwFmtRefMark*)aCntntAtPos.aFnd.pAttr)->GetRefName();
+ }
+ break;
+
+ default:
+ {
+ SwModuleOptions* pModOpt = SW_MOD()->GetModuleConfig();
+ if(!pModOpt->IsHideFieldTips())
+ {
+ const SwField* pFld = aCntntAtPos.aFnd.pFld;
+ switch( pFld->Which() )
+ {
+ case RES_SETEXPFLD:
+ case RES_TABLEFLD:
+ case RES_GETEXPFLD:
+ {
+ sal_uInt16 nOldSubType = pFld->GetSubType();
+ ((SwField*)pFld)->SetSubType(nsSwExtendedSubType::SUB_CMD);
+ sTxt = pFld->ExpandField(true);
+ ((SwField*)pFld)->SetSubType(nOldSubType);
+ }
+ break;
+
+ case RES_POSTITFLD:
+ {
+ break;
+ }
+ case RES_INPUTFLD: // BubbleHelp, because the suggestion could be quite long
+ bBalloon = true;
+ /* no break */
+ case RES_JUMPEDITFLD:
+ sTxt = pFld->GetPar2();
+ break;
+
+ case RES_DBFLD:
+ sTxt = pFld->GetFieldName();
+ break;
+
+ case RES_USERFLD:
+ case RES_HIDDENTXTFLD:
+ sTxt = pFld->GetPar1();
+ break;
+
+ case RES_DOCSTATFLD:
+ break;
+
+ case RES_MACROFLD:
+ sTxt = ((const SwMacroField*)pFld)->GetMacro();
+ break;
+
+ case RES_GETREFFLD:
+ {
+ // #i85090#
+ const SwGetRefField* pRefFld( dynamic_cast<const SwGetRefField*>(pFld) );
+ OSL_ENSURE( pRefFld,
+ "<SwEditWin::RequestHelp(..)> - unexpected type of <pFld>" );
+ if ( pRefFld )
+ {
+ if ( pRefFld->IsRefToHeadingCrossRefBookmark() ||
+ pRefFld->IsRefToNumItemCrossRefBookmark() )
+ {
+ sTxt = pRefFld->GetExpandedTxtOfReferencedTxtNode();
+ if ( sTxt.getLength() > 80 )
+ {
+ sTxt = sTxt.copy(0, 80) + "...";
+ }
+ }
+ else
+ {
+ sTxt = ((SwGetRefField*)pFld)->GetSetRefName();
+ }
+ }
+ }
+ break;
+ }
+ }
+
+ if( sTxt.isEmpty() )
+ {
+ aCntntAtPos.eCntntAtPos = SwContentAtPos::SW_REDLINE;
+ if( rSh.GetContentAtPos( aPos, aCntntAtPos, false, &aFldRect ) )
+ sTxt = lcl_GetRedlineHelp(*aCntntAtPos.aFnd.pRedl, bBalloon);
+ }
+ }
+ }
+ if (!sTxt.isEmpty())
+ {
+ if( bBalloon )
+ Help::ShowBalloon( this, rEvt.GetMousePosPixel(), sTxt );
+ else
+ {
+ // the show the help
+ Rectangle aRect( aFldRect.SVRect() );
+ Point aPt( OutputToScreenPixel( LogicToPixel( aRect.TopLeft() )));
+ aRect.Left() = aPt.X();
+ aRect.Top() = aPt.Y();
+ aPt = OutputToScreenPixel( LogicToPixel( aRect.BottomRight() ));
+ aRect.Right() = aPt.X();
+ aRect.Bottom() = aPt.Y();
+ Help::ShowQuickHelp( this, aRect, sTxt, nStyle );
+ }
+ }
+
+ bContinue = false;
+ }
+ if( bContinue )
+ {
+ sal_uInt8 nTabCols = rSh.WhichMouseTabCol(aPos);
+ sal_uInt16 nTabRes = 0;
+ switch(nTabCols)
+ {
+ case SW_TABCOL_HORI:
+ case SW_TABCOL_VERT:
+ nTabRes = STR_TABLE_COL_ADJUST;
+ break;
+ case SW_TABROW_HORI:
+ case SW_TABROW_VERT:
+ nTabRes = STR_TABLE_ROW_ADJUST;
+ break;
+ // #i32329# Enhanced table selection
+ case SW_TABSEL_HORI:
+ case SW_TABSEL_HORI_RTL:
+ case SW_TABSEL_VERT:
+ nTabRes = STR_TABLE_SELECT_ALL;
+ break;
+ case SW_TABROWSEL_HORI:
+ case SW_TABROWSEL_HORI_RTL:
+ case SW_TABROWSEL_VERT:
+ nTabRes = STR_TABLE_SELECT_ROW;
+ break;
+ case SW_TABCOLSEL_HORI:
+ case SW_TABCOLSEL_VERT:
+ nTabRes = STR_TABLE_SELECT_COL;
+ break;
+ }
+ if(nTabRes)
+ {
+ sTxt = SW_RESSTR(nTabRes);
+ Size aTxtSize( GetTextWidth(sTxt), GetTextHeight());
+ Rectangle aRect(rEvt.GetMousePosPixel(), aTxtSize);
+ Help::ShowQuickHelp(this, aRect, sTxt);
+ }
+ bContinue = false;
+ }
+ }
+
+ if( bContinue )
+ Window::RequestHelp( rEvt );
+}
+
+void SwEditWin::PrePaint()
+{
+ SwWrtShell* pWrtShell = GetView().GetWrtShellPtr();
+
+ if(pWrtShell)
+ {
+ pWrtShell->PrePaint();
+ }
+}
+
+void SwEditWin::Paint(const Rectangle& rRect)
+{
+ SwWrtShell* pWrtShell = GetView().GetWrtShellPtr();
+ if(!pWrtShell)
+ return;
+ bool bPaintShadowCrsr = false;
+ if( m_pShadCrsr )
+ {
+ Rectangle aRect( m_pShadCrsr->GetRect());
+ // fully resides inside?
+ if( rRect.IsInside( aRect ) )
+ // dann aufheben
+ delete m_pShadCrsr, m_pShadCrsr = 0;
+ else if( rRect.IsOver( aRect ))
+ {
+ // resides somewhat above, then everything is clipped outside
+ // and we have to make the "inner part" at the end of the
+ // Paint visible again. Otherwise Paint errors occur!
+ bPaintShadowCrsr = true;
+ }
+ }
+
+ if ( GetView().GetVisArea().GetWidth() <= 0 ||
+ GetView().GetVisArea().GetHeight() <= 0 )
+ Invalidate( rRect );
+ else
+ pWrtShell->Paint( rRect );
+
+ if( bPaintShadowCrsr )
+ m_pShadCrsr->Paint();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/docvw/edtwin3.cxx b/sw/source/uibase/docvw/edtwin3.cxx
new file mode 100644
index 000000000000..c627b7772ef1
--- /dev/null
+++ b/sw/source/uibase/docvw/edtwin3.cxx
@@ -0,0 +1,166 @@
+/* -*- 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 <hintids.hxx>
+#include <vcl/settings.hxx>
+#include <svx/ruler.hxx>
+#include <viewopt.hxx>
+#include "view.hxx"
+#include "wrtsh.hxx"
+#include "basesh.hxx"
+#include "pview.hxx"
+#include "mdiexp.hxx"
+#include "edtwin.hxx"
+#include "swmodule.hxx"
+#include "modcfg.hxx"
+#include "swtable.hxx"
+#include "docsh.hxx"
+#include "pagedesc.hxx"
+#include <frmatr.hxx>
+#include <editeng/frmdiritem.hxx>
+
+// Core-Notify
+void ScrollMDI( SwViewShell* pVwSh, const SwRect &rRect,
+ sal_uInt16 nRangeX, sal_uInt16 nRangeY)
+{
+ SfxViewShell *pSfxVwSh = pVwSh->GetSfxViewShell();
+ if (pSfxVwSh && pSfxVwSh->ISA(SwView))
+ ((SwView *)pSfxVwSh)->Scroll( rRect.SVRect(), nRangeX, nRangeY );
+}
+
+// Docmdi - movable
+bool IsScrollMDI( SwViewShell* pVwSh, const SwRect &rRect )
+{
+ SfxViewShell *pSfxVwSh = pVwSh->GetSfxViewShell();
+ if (pSfxVwSh && pSfxVwSh->ISA(SwView))
+ return (((SwView *)pSfxVwSh)->IsScroll(rRect.SVRect()));
+ return false;
+}
+
+// Notify for size change
+void SizeNotify(SwViewShell* pVwSh, const Size &rSize)
+{
+ SfxViewShell *pSfxVwSh = pVwSh->GetSfxViewShell();
+ if (pSfxVwSh)
+ {
+ if (pSfxVwSh->ISA(SwView))
+ ((SwView *)pSfxVwSh)->DocSzChgd(rSize);
+ else if (pSfxVwSh->ISA(SwPagePreview))
+ ((SwPagePreview *)pSfxVwSh)->DocSzChgd( rSize );
+ }
+}
+
+// Notify for page number update
+void PageNumNotify( SwViewShell* pVwSh, sal_uInt16 nPhyNum, sal_uInt16 nVirtNum,
+ const OUString& rPgStr)
+{
+ SfxViewShell *pSfxVwSh = pVwSh->GetSfxViewShell();
+ if ( pSfxVwSh && pSfxVwSh->ISA(SwView) &&
+ ((SwView*)pSfxVwSh)->GetCurShell() )
+ ((SwView *)pSfxVwSh)->UpdatePageNums(nPhyNum, nVirtNum, rPgStr);
+}
+
+void FrameNotify( SwViewShell* pVwSh, FlyMode eMode )
+{
+ if ( pVwSh->ISA(SwCrsrShell) )
+ SwBaseShell::SetFrmMode( eMode, (SwWrtShell*)pVwSh );
+}
+
+// Notify for page number update
+bool SwEditWin::RulerColumnDrag( const MouseEvent& rMEvt, bool bVerticalMode)
+{
+ SvxRuler& rRuler = bVerticalMode ? m_rView.GetVRuler() : m_rView.GetHRuler();
+ return (!rRuler.StartDocDrag( rMEvt, RULER_TYPE_BORDER ) &&
+ !rRuler.StartDocDrag( rMEvt, RULER_TYPE_MARGIN1) &&
+ !rRuler.StartDocDrag( rMEvt, RULER_TYPE_MARGIN2));
+}
+
+// #i23726#
+// #i42921# - add 3rd parameter <bVerticalMode> in order
+// to consider vertical layout
+bool SwEditWin::RulerMarginDrag( const MouseEvent& rMEvt,
+ const bool bVerticalMode )
+{
+ SvxRuler& rRuler = bVerticalMode ? m_rView.GetVRuler() : m_rView.GetHRuler();
+ return !rRuler.StartDocDrag( rMEvt, RULER_TYPE_INDENT);
+}
+
+TblChgMode GetTblChgDefaultMode()
+{
+ SwModuleOptions* pOpt = SW_MOD()->GetModuleConfig();
+ return pOpt ? pOpt->GetTblMode() : TBLVAR_CHGABS;
+}
+
+void RepaintPagePreview( SwViewShell* pVwSh, const SwRect& rRect )
+{
+ SfxViewShell *pSfxVwSh = pVwSh->GetSfxViewShell();
+ if (pSfxVwSh && pSfxVwSh->ISA( SwPagePreview ))
+ ((SwPagePreview *)pSfxVwSh)->RepaintCoreRect( rRect );
+}
+
+bool JumpToSwMark( SwViewShell* pVwSh, const OUString& rMark )
+{
+ SfxViewShell *pSfxVwSh = pVwSh->GetSfxViewShell();
+ if( pSfxVwSh && pSfxVwSh->ISA( SwView ) )
+ return ((SwView *)pSfxVwSh)->JumpToSwMark( rMark );
+ return false;
+}
+
+void SwEditWin::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Window::DataChanged( rDCEvt );
+
+ SwWrtShell* pSh = GetView().GetWrtShellPtr();
+ // DataChanged() is sometimes called prior to creating
+ // the SwWrtShell
+ if(!pSh)
+ return;
+ bool bViewWasLocked = pSh->IsViewLocked(), bUnlockPaint = false;
+ pSh->LockView( true );
+ switch( rDCEvt.GetType() )
+ {
+ case DATACHANGED_SETTINGS:
+ // rearrange ScrollBars, respectively trigger resize, because
+ // the ScrollBar size can have change. For that, in the reset
+ // handler, the size of the ScrollBars also has to be queried
+ // from the settings.
+ if( rDCEvt.GetFlags() & SETTINGS_STYLE )
+ {
+ pSh->LockPaint();
+ bUnlockPaint = true;
+ SwViewShell::DeleteReplacementBitmaps();
+ GetView().InvalidateBorder(); //Scrollbar work
+ }
+ break;
+
+ case DATACHANGED_PRINTER:
+ case DATACHANGED_DISPLAY:
+ case DATACHANGED_FONTS:
+ case DATACHANGED_FONTSUBSTITUTION:
+ pSh->LockPaint();
+ bUnlockPaint = true;
+ GetView().GetDocShell()->UpdateFontList(); //e.g. printer change
+ break;
+ }
+ pSh->LockView( bViewWasLocked );
+ if( bUnlockPaint )
+ pSh->UnlockPaint();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/docvw/frmsidebarwincontainer.cxx b/sw/source/uibase/docvw/frmsidebarwincontainer.cxx
new file mode 100644
index 000000000000..3760f9778446
--- /dev/null
+++ b/sw/source/uibase/docvw/frmsidebarwincontainer.cxx
@@ -0,0 +1,204 @@
+/* -*- 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 <frmsidebarwincontainer.hxx>
+
+#include <map>
+#include <fmtfld.hxx>
+#include <txtfld.hxx>
+#include <SidebarWin.hxx>
+
+namespace {
+ struct SidebarWinKey
+ {
+ const sal_Int32 mnIndex;
+
+ explicit SidebarWinKey( const sal_Int32 nIndex )
+ : mnIndex( nIndex )
+ {}
+
+ bool operator < ( const SidebarWinKey& rSidebarWinKey ) const
+ {
+ return mnIndex < rSidebarWinKey.mnIndex;
+ }
+ };
+
+ struct SidebarWinOrder
+ {
+ bool operator()( const SidebarWinKey& rSidebarWinKeyA,
+ const SidebarWinKey& rSidebarWinKeyB ) const
+ {
+ return rSidebarWinKeyA < rSidebarWinKeyB;
+ }
+ };
+
+ typedef ::std::map < SidebarWinKey, sw::sidebarwindows::SwSidebarWin*, SidebarWinOrder > SidebarWinContainer;
+
+ struct FrmKey
+ {
+ const SwFrm* mpFrm;
+
+ explicit FrmKey( const SwFrm* pFrm )
+ : mpFrm( pFrm )
+ {}
+
+ bool operator < ( const FrmKey& rFrmKey ) const
+ {
+ return mpFrm < rFrmKey.mpFrm;
+ }
+ };
+
+ struct FrmOrder
+ {
+ bool operator()( const FrmKey& rFrmKeyA,
+ const FrmKey& rFrmKeyB ) const
+ {
+ return rFrmKeyA < rFrmKeyB;
+ }
+ };
+
+ typedef ::std::map < FrmKey, SidebarWinContainer, FrmOrder > _FrmSidebarWinContainer;
+}
+
+namespace sw { namespace sidebarwindows {
+
+class FrmSidebarWinContainer : public _FrmSidebarWinContainer
+{
+};
+
+SwFrmSidebarWinContainer::SwFrmSidebarWinContainer()
+ : mpFrmSidebarWinContainer( new FrmSidebarWinContainer() )
+{}
+
+SwFrmSidebarWinContainer::~SwFrmSidebarWinContainer()
+{
+ mpFrmSidebarWinContainer->clear();
+ delete mpFrmSidebarWinContainer;
+}
+
+bool SwFrmSidebarWinContainer::insert( const SwFrm& rFrm,
+ const SwFmtFld& rFmtFld,
+ SwSidebarWin& rSidebarWin )
+{
+ bool bInserted( false );
+
+ FrmKey aFrmKey( &rFrm );
+ SidebarWinContainer& rSidebarWinContainer = (*mpFrmSidebarWinContainer)[ aFrmKey ];
+
+ SidebarWinKey aSidebarWinKey( *(rFmtFld.GetTxtFld()->GetStart()) );
+ if ( rSidebarWinContainer.empty() ||
+ rSidebarWinContainer.find( aSidebarWinKey) == rSidebarWinContainer.end() )
+ {
+ rSidebarWinContainer[ aSidebarWinKey ] = &rSidebarWin;
+ bInserted = true;
+ }
+
+ return bInserted;
+}
+
+bool SwFrmSidebarWinContainer::remove( const SwFrm& rFrm,
+ const SwSidebarWin& rSidebarWin )
+{
+ bool bRemoved( false );
+
+ FrmKey aFrmKey( &rFrm );
+ FrmSidebarWinContainer::iterator aFrmIter = mpFrmSidebarWinContainer->find( aFrmKey );
+ if ( aFrmIter != mpFrmSidebarWinContainer->end() )
+ {
+ SidebarWinContainer& rSidebarWinContainer = (*aFrmIter).second;
+ for ( SidebarWinContainer::iterator aIter = rSidebarWinContainer.begin();
+ aIter != rSidebarWinContainer.end();
+ ++aIter )
+ {
+ if ( (*aIter).second == &rSidebarWin )
+ {
+ rSidebarWinContainer.erase( aIter );
+ bRemoved = true;
+ break;
+ }
+ }
+ }
+
+ return bRemoved;
+}
+
+bool SwFrmSidebarWinContainer::empty( const SwFrm& rFrm )
+{
+ bool bEmpty( true );
+
+ FrmKey aFrmKey( &rFrm );
+ FrmSidebarWinContainer::iterator aFrmIter = mpFrmSidebarWinContainer->find( aFrmKey );
+ if ( aFrmIter != mpFrmSidebarWinContainer->end() )
+ {
+ bEmpty = (*aFrmIter).second.empty();
+ }
+
+ return bEmpty;
+}
+
+SwSidebarWin* SwFrmSidebarWinContainer::get( const SwFrm& rFrm,
+ const sal_Int32 nIndex )
+{
+ SwSidebarWin* pRet( 0 );
+
+ FrmKey aFrmKey( &rFrm );
+ FrmSidebarWinContainer::iterator aFrmIter = mpFrmSidebarWinContainer->find( aFrmKey );
+ if ( aFrmIter != mpFrmSidebarWinContainer->end() )
+ {
+ SidebarWinContainer& rSidebarWinContainer = (*aFrmIter).second;
+ sal_Int32 nCounter( nIndex );
+ for ( SidebarWinContainer::iterator aIter = rSidebarWinContainer.begin();
+ nCounter >= 0 && aIter != rSidebarWinContainer.end();
+ ++aIter )
+ {
+ if ( nCounter == 0 )
+ {
+ pRet = (*aIter).second;
+ break;
+ }
+
+ --nCounter;
+ }
+ }
+
+ return pRet;
+}
+
+void SwFrmSidebarWinContainer::getAll( const SwFrm& rFrm,
+ std::vector< Window* >* pSidebarWins )
+{
+ pSidebarWins->clear();
+
+ FrmKey aFrmKey( &rFrm );
+ FrmSidebarWinContainer::iterator aFrmIter = mpFrmSidebarWinContainer->find( aFrmKey );
+ if ( aFrmIter != mpFrmSidebarWinContainer->end() )
+ {
+ SidebarWinContainer& rSidebarWinContainer = (*aFrmIter).second;
+ for ( SidebarWinContainer::iterator aIter = rSidebarWinContainer.begin();
+ aIter != rSidebarWinContainer.end();
+ ++aIter )
+ {
+ pSidebarWins->push_back( (*aIter).second );
+ }
+ }
+}
+
+} } // eof of namespace sw::sidebarwindows::
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/docvw/frmsidebarwincontainer.hxx b/sw/source/uibase/docvw/frmsidebarwincontainer.hxx
new file mode 100644
index 000000000000..225399360248
--- /dev/null
+++ b/sw/source/uibase/docvw/frmsidebarwincontainer.hxx
@@ -0,0 +1,63 @@
+/* -*- 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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_CORE_UIBASE_DOCVW_FRMSIDEBARWINCONTAINER_HXX
+#define INCLUDED_SW_SOURCE_CORE_UIBASE_DOCVW_FRMSIDEBARWINCONTAINER_HXX
+
+#include <sal/types.h>
+#include <vector>
+
+class SwFrm;
+class SwFmtFld;
+class Window;
+
+namespace sw { namespace sidebarwindows {
+
+class SwSidebarWin;
+class FrmSidebarWinContainer;
+
+class SwFrmSidebarWinContainer
+{
+ public:
+ SwFrmSidebarWinContainer();
+ ~SwFrmSidebarWinContainer();
+
+ bool insert( const SwFrm& rFrm,
+ const SwFmtFld& rFmtFld,
+ SwSidebarWin& rSidebarWin );
+
+ bool remove( const SwFrm& rFrm,
+ const SwSidebarWin& rSidebarWin );
+
+ bool empty( const SwFrm& rFrm );
+
+ SwSidebarWin* get( const SwFrm& rFrm,
+ const sal_Int32 nIndex );
+
+ void getAll( const SwFrm& rFrm,
+ std::vector< Window* >* pSidebarWins );
+
+ private:
+ FrmSidebarWinContainer* mpFrmSidebarWinContainer;
+};
+
+} } // eof of namespace sw::sidebarwindows::
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/docvw/romenu.cxx b/sw/source/uibase/docvw/romenu.cxx
new file mode 100644
index 000000000000..37e6c32ea4d2
--- /dev/null
+++ b/sw/source/uibase/docvw/romenu.cxx
@@ -0,0 +1,368 @@
+/* -*- 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 <hintids.hxx>
+
+#include <svl/eitem.hxx>
+#include <svl/stritem.hxx>
+#include <svtools/imap.hxx>
+#include <svtools/inetimg.hxx>
+#include <svtools/transfer.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/dispatch.hxx>
+#include <svx/gallery.hxx>
+#include <svx/graphichelper.hxx>
+#include <editeng/brushitem.hxx>
+
+#include <frmatr.hxx>
+#include <fmturl.hxx>
+#include <fmtinfmt.hxx>
+#include <docsh.hxx>
+#include <view.hxx>
+#include <wrtsh.hxx>
+#include <viewopt.hxx>
+#include <swmodule.hxx>
+#include <romenu.hxx>
+#include <pagedesc.hxx>
+#include <modcfg.hxx>
+
+#include <cmdid.h>
+#include <helpid.h>
+#include <docvw.hrc>
+
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star;
+using namespace ::sfx2;
+
+SwReadOnlyPopup::~SwReadOnlyPopup()
+{
+ delete pImageMap;
+ delete pTargetURL;
+}
+
+void SwReadOnlyPopup::Check( sal_uInt16 nMID, sal_uInt16 nSID, SfxDispatcher &rDis )
+{
+ SfxPoolItem *_pItem = 0;
+ SfxItemState eState = rDis.GetBindings()->QueryState( nSID, _pItem );
+ if (eState >= SFX_ITEM_AVAILABLE)
+ {
+ EnableItem( nMID, true );
+ if (_pItem)
+ {
+ CheckItem ( nMID, !_pItem->ISA(SfxVoidItem) &&
+ _pItem->ISA(SfxBoolItem) &&
+ ((SfxBoolItem*)_pItem)->GetValue());
+ //remove full screen entry when not in full screen mode
+ if( SID_WIN_FULLSCREEN == nSID && !IsItemChecked(SID_WIN_FULLSCREEN) )
+ EnableItem(nMID, false);
+ }
+ }
+ else
+ EnableItem( nMID, false );
+
+ delete _pItem;
+}
+
+SwReadOnlyPopup::SwReadOnlyPopup( const Point &rDPos, SwView &rV ) :
+ PopupMenu( SW_RES(MN_READONLY_POPUP) ),
+ rView ( rV ),
+ rDocPos( rDPos ),
+ pImageMap( 0 ),
+ pTargetURL( 0 )
+{
+ bGrfToGalleryAsLnk = SW_MOD()->GetModuleConfig()->IsGrfToGalleryAsLnk();
+ SwWrtShell &rSh = rView.GetWrtShell();
+ rSh.IsURLGrfAtPos( rDocPos, &sURL, &sTargetFrameName, &sDescription );
+ if ( sURL.isEmpty() )
+ {
+ SwContentAtPos aCntntAtPos( SwContentAtPos::SW_INETATTR );
+ if( rSh.GetContentAtPos( rDocPos, aCntntAtPos, false))
+ {
+ SwFmtINetFmt &rIItem = *(SwFmtINetFmt*)aCntntAtPos.aFnd.pAttr;
+ sURL = rIItem.GetValue();
+ sTargetFrameName = rIItem.GetTargetFrame();
+ sDescription = aCntntAtPos.sStr;
+ }
+ }
+
+ bool bLink = false;
+ const Graphic *pGrf;
+ if ( 0 == (pGrf = rSh.GetGrfAtPos( rDocPos, sGrfName, bLink )) )
+ {
+ EnableItem( MN_READONLY_SAVEGRAPHIC, false );
+ EnableItem( MN_READONLY_COPYGRAPHIC, false );
+ }
+ else
+ {
+ aGraphic = *pGrf;
+ const SwFrmFmt* pGrfFmt = rSh.GetFmtFromObj( rDocPos );
+ const SfxPoolItem* pURLItem;
+ if( pGrfFmt && SFX_ITEM_SET == pGrfFmt->GetItemState(
+ RES_URL, true, &pURLItem ))
+ {
+ const SwFmtURL& rURL = *(SwFmtURL*)pURLItem;
+ if( rURL.GetMap() )
+ pImageMap = new ImageMap( *rURL.GetMap() );
+ else if( !rURL.GetURL().isEmpty() )
+ pTargetURL = new INetImage( bLink ? sGrfName : OUString(),
+ rURL.GetURL(),
+ rURL.GetTargetFrameName(),
+ OUString(), Size() );
+ }
+ }
+
+ bool bEnableGraphicToGallery = bLink;
+ if ( bEnableGraphicToGallery )
+ {
+ if (GalleryExplorer::FillThemeList( aThemeList ))
+ {
+ PopupMenu *pMenu = GetPopupMenu(MN_READONLY_GRAPHICTOGALLERY);
+ pMenu->CheckItem( MN_READONLY_TOGALLERYLINK, bGrfToGalleryAsLnk );
+ pMenu->CheckItem( MN_READONLY_TOGALLERYCOPY, !bGrfToGalleryAsLnk );
+
+ for ( sal_uInt16 i=0; i < aThemeList.size(); ++i )
+ pMenu->InsertItem( MN_READONLY_GRAPHICTOGALLERY+i + 3, aThemeList[ i ] );
+ }
+ else
+ bEnableGraphicToGallery = false;
+ }
+
+ EnableItem( MN_READONLY_GRAPHICTOGALLERY, bEnableGraphicToGallery );
+
+ SfxViewFrame * pVFrame = rV.GetViewFrame();
+ SfxDispatcher &rDis = *pVFrame->GetDispatcher();
+ const SwPageDesc &rDesc = rSh.GetPageDesc( rSh.GetCurPageDesc() );
+ pItem = &rDesc.GetMaster().GetBackground();
+ bool bEnableBackGallery = false,
+ bEnableBack = false;
+
+ if ( GPOS_NONE != pItem->GetGraphicPos() )
+ {
+ bEnableBack = true;
+ if ( !pItem->GetGraphicLink().isEmpty() )
+ {
+ if ( aThemeList.empty() )
+ GalleryExplorer::FillThemeList( aThemeList );
+
+ if ( !aThemeList.empty() )
+ {
+ PopupMenu *pMenu = GetPopupMenu(MN_READONLY_BACKGROUNDTOGALLERY);
+ pMenu->CheckItem( MN_READONLY_TOGALLERYLINK, bGrfToGalleryAsLnk );
+ pMenu->CheckItem( MN_READONLY_TOGALLERYCOPY, !bGrfToGalleryAsLnk );
+ bEnableBackGallery = true;
+
+ for ( sal_uInt16 i=0; i < aThemeList.size(); ++i )
+ pMenu->InsertItem( MN_READONLY_GRAPHICTOGALLERY+i + 3, aThemeList[ i ] );
+ }
+ }
+ }
+ EnableItem( MN_READONLY_SAVEBACKGROUND, bEnableBack );
+ EnableItem( MN_READONLY_BACKGROUNDTOGALLERY, bEnableBackGallery );
+
+ if ( !rSh.GetViewOptions()->IsGraphic() )
+ CheckItem( MN_READONLY_GRAPHICOFF );
+ else
+ EnableItem( MN_READONLY_LOADGRAPHIC, false );
+
+ bool bReloadFrame = 0 != rSh.GetView().GetViewFrame()->GetFrame().GetParentFrame();
+ EnableItem( MN_READONLY_RELOAD_FRAME,
+ bReloadFrame );
+ EnableItem( MN_READONLY_RELOAD, !bReloadFrame);
+
+ Check( MN_READONLY_EDITDOC, SID_EDITDOC, rDis );
+ Check( MN_READONLY_SELECTION_MODE, FN_READONLY_SELECTION_MODE, rDis );
+ Check( MN_READONLY_SOURCEVIEW, SID_SOURCEVIEW, rDis );
+ Check( MN_READONLY_BROWSE_BACKWARD, SID_BROWSE_BACKWARD,rDis );
+ Check( MN_READONLY_BROWSE_FORWARD, SID_BROWSE_FORWARD, rDis );
+#ifdef WNT
+ Check( MN_READONLY_PLUGINOFF, SID_PLUGINS_ACTIVE, rDis );
+#endif
+ Check( MN_READONLY_OPENURL, SID_OPENDOC, rDis );
+ Check( MN_READONLY_OPENURLNEW, SID_OPENDOC, rDis );
+
+ SfxPoolItem* pState = NULL;
+
+ SfxItemState eState = pVFrame->GetBindings().QueryState( SID_COPY, pState );
+ Check( MN_READONLY_COPY, SID_COPY, rDis );
+ if(eState < SFX_ITEM_AVAILABLE)
+ EnableItem( MN_READONLY_COPY, false );
+ delete pState;
+ pState = NULL;
+
+ eState = pVFrame->GetBindings().QueryState( SID_EDITDOC, pState );
+ if (
+ eState < SFX_ITEM_DEFAULT ||
+ (rSh.IsGlobalDoc() && rView.GetDocShell()->IsReadOnlyUI())
+ )
+ {
+ EnableItem( MN_READONLY_EDITDOC, false );
+ }
+ delete pState;
+
+ if ( sURL.isEmpty() )
+ {
+ EnableItem( MN_READONLY_OPENURL, false );
+ EnableItem( MN_READONLY_OPENURLNEW, false );
+ EnableItem( MN_READONLY_COPYLINK, false );
+ }
+ Check( SID_WIN_FULLSCREEN, SID_WIN_FULLSCREEN, rDis );
+
+ RemoveDisabledEntries( true, true );
+}
+
+void SwReadOnlyPopup::Execute( Window* pWin, const Point &rPixPos )
+{
+ sal_uInt16 nId = PopupMenu::Execute(
+ pWin,
+ rPixPos );
+ Execute(pWin, nId);
+}
+
+// execute the resulting ID only - necessary to support XContextMenuInterception
+void SwReadOnlyPopup::Execute( Window* pWin, sal_uInt16 nId )
+{
+ SwWrtShell &rSh = rView.GetWrtShell();
+ SfxDispatcher &rDis = *rView.GetViewFrame()->GetDispatcher();
+ if ( nId >= MN_READONLY_GRAPHICTOGALLERY )
+ {
+ OUString sTmp;
+ sal_uInt16 nSaveId;
+ if ( nId >= MN_READONLY_BACKGROUNDTOGALLERY )
+ {
+ nId -= MN_READONLY_BACKGROUNDTOGALLERY+3;
+ nSaveId = MN_READONLY_SAVEBACKGROUND;
+ sTmp = pItem->GetGraphicLink();
+ }
+ else
+ {
+ nId -= MN_READONLY_GRAPHICTOGALLERY+3;
+ nSaveId = MN_READONLY_SAVEGRAPHIC;
+ sTmp = sGrfName;
+ }
+ if ( !bGrfToGalleryAsLnk )
+ sTmp = SaveGraphic( nSaveId );
+
+ if ( !sTmp.isEmpty() )
+ GalleryExplorer::InsertURL( aThemeList[nId], sTmp );
+
+ return;
+ }
+
+ TransferDataContainer* pClipCntnr = 0;
+
+ sal_uInt16 nExecId = USHRT_MAX;
+ sal_uInt16 nFilter = USHRT_MAX;
+ switch( nId )
+ {
+ case SID_WIN_FULLSCREEN : nExecId = SID_WIN_FULLSCREEN; break;
+ case MN_READONLY_OPENURL: nFilter = URLLOAD_NOFILTER; break;
+ case MN_READONLY_OPENURLNEW: nFilter = URLLOAD_NEWVIEW; break;
+ case MN_READONLY_COPY: nExecId = SID_COPY; break;
+
+ case MN_READONLY_EDITDOC: nExecId = SID_EDITDOC; break;
+ case MN_READONLY_SELECTION_MODE: nExecId = FN_READONLY_SELECTION_MODE; break;
+ case MN_READONLY_RELOAD:
+ case MN_READONLY_RELOAD_FRAME:
+ rSh.GetView().GetViewFrame()->GetDispatcher()->Execute(SID_RELOAD);
+ break;
+
+ case MN_READONLY_BROWSE_BACKWARD: nExecId = SID_BROWSE_BACKWARD;break;
+ case MN_READONLY_BROWSE_FORWARD: nExecId = SID_BROWSE_FORWARD; break;
+ case MN_READONLY_SOURCEVIEW: nExecId = SID_SOURCEVIEW; break;
+ case MN_READONLY_SAVEGRAPHIC:
+ case MN_READONLY_SAVEBACKGROUND:
+ {
+ SaveGraphic( nId );
+ break;
+ }
+ case MN_READONLY_COPYLINK:
+ pClipCntnr = new TransferDataContainer;
+ pClipCntnr->CopyString( sURL );
+ break;
+
+ case MN_READONLY_COPYGRAPHIC:
+ pClipCntnr = new TransferDataContainer;
+ pClipCntnr->CopyGraphic( aGraphic );
+
+ if( pImageMap )
+ pClipCntnr->CopyImageMap( *pImageMap );
+ if( pTargetURL )
+ pClipCntnr->CopyINetImage( *pTargetURL );
+ break;
+
+ case MN_READONLY_LOADGRAPHIC:
+ {
+ bool bModified = rSh.IsModified();
+ SwViewOption aOpt( *rSh.GetViewOptions() );
+ aOpt.SetGraphic( true );
+ rSh.ApplyViewOptions( aOpt );
+ if(!bModified)
+ rSh.ResetModified();
+ break;
+ }
+ case MN_READONLY_GRAPHICOFF: nExecId = FN_VIEW_GRAPHIC; break;
+#ifdef WNT
+ case MN_READONLY_PLUGINOFF: nExecId = SID_PLUGINS_ACTIVE; break;
+#endif
+ case MN_READONLY_TOGALLERYLINK:
+ SW_MOD()->GetModuleConfig()->SetGrfToGalleryAsLnk( true );
+ break;
+ case MN_READONLY_TOGALLERYCOPY:
+ SW_MOD()->GetModuleConfig()->SetGrfToGalleryAsLnk( false );
+ break;
+
+ default: //forward the id to the SfxBindings
+ nExecId = nId;
+ }
+ if( USHRT_MAX != nExecId )
+ rDis.GetBindings()->Execute( nExecId );
+ if( USHRT_MAX != nFilter )
+ ::LoadURL(rSh, sURL, nFilter, sTargetFrameName);
+
+ if( pClipCntnr )
+ {
+ ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XTransferable > xRef( pClipCntnr );
+ if( pClipCntnr->HasAnyData() )
+ pClipCntnr->CopyToClipboard( pWin );
+ }
+}
+
+OUString SwReadOnlyPopup::SaveGraphic( sal_uInt16 nId )
+{
+ // fish out the graphic's name
+ if ( MN_READONLY_SAVEBACKGROUND == nId )
+ {
+ if ( !pItem->GetGraphicLink().isEmpty() )
+ sGrfName = pItem->GetGraphicLink();
+ ((SvxBrushItem*)pItem)->SetDoneLink( Link() );
+ const Graphic *pGrf = pItem->GetGraphic();
+ if ( pGrf )
+ {
+ aGraphic = *pGrf;
+ if ( !pItem->GetGraphicLink().isEmpty() )
+ sGrfName = pItem->GetGraphicLink();
+ }
+ else
+ return OUString();
+ }
+ return GraphicHelper::ExportGraphic( aGraphic, sGrfName );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/docvw/romenu.hxx b/sw/source/uibase/docvw/romenu.hxx
new file mode 100644
index 000000000000..eae84d594181
--- /dev/null
+++ b/sw/source/uibase/docvw/romenu.hxx
@@ -0,0 +1,64 @@
+/* -*- 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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_CORE_UIBASE_DOCVW_ROMENU_HXX
+#define INCLUDED_SW_SOURCE_CORE_UIBASE_DOCVW_ROMENU_HXX
+
+#include <vcl/graph.hxx>
+#include <vcl/menu.hxx>
+#include <svl/stritem.hxx>
+
+class SwView;
+class SfxDispatcher;
+class SvxBrushItem;
+class ImageMap;
+class INetImage;
+
+class SwReadOnlyPopup : public PopupMenu
+{
+ SwView &rView;
+ const SvxBrushItem *pItem;
+ const Point &rDocPos;
+ Graphic aGraphic;
+ OUString sURL,
+ sTargetFrameName,
+ sDescription;
+ OUString sGrfName;
+ std::vector<OUString> aThemeList;
+ bool bGrfToGalleryAsLnk;
+ ImageMap* pImageMap;
+ INetImage* pTargetURL;
+
+ void Check( sal_uInt16 nMID, sal_uInt16 nSID, SfxDispatcher &rDis );
+ OUString SaveGraphic( sal_uInt16 nId );
+
+ using PopupMenu::Execute;
+
+public:
+ SwReadOnlyPopup( const Point &rDPos, SwView &rV );
+ virtual ~SwReadOnlyPopup();
+
+ void Execute( Window* pWin, const Point &rPPos );
+ void Execute( Window* pWin, sal_uInt16 nId );
+};
+
+void GetPreferredExtension( OUString &rExt, const Graphic &rGrf );
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/docvw/srcedtw.cxx b/sw/source/uibase/docvw/srcedtw.cxx
new file mode 100644
index 000000000000..353780925449
--- /dev/null
+++ b/sw/source/uibase/docvw/srcedtw.cxx
@@ -0,0 +1,993 @@
+/* -*- 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 <sal/config.h>
+
+#include <hintids.hxx>
+#include <cmdid.h>
+
+#include <com/sun/star/beans/XMultiPropertySet.hpp>
+#include <com/sun/star/beans/XPropertiesChangeListener.hpp>
+#include <cppuhelper/implbase1.hxx>
+#include <officecfg/Office/Common.hxx>
+#include <rtl/ustring.hxx>
+#include <sal/log.hxx>
+#include <vcl/textview.hxx>
+#include <svx/svxids.hrc>
+#include <vcl/scrbar.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/app.hxx>
+#include <svtools/htmltokn.h>
+#include <vcl/txtattr.hxx>
+#include <vcl/settings.hxx>
+#include <svtools/colorcfg.hxx>
+#include <editeng/flstitem.hxx>
+#include <vcl/metric.hxx>
+#include <svtools/ctrltool.hxx>
+#include <tools/time.hxx>
+#include <swmodule.hxx>
+#include <docsh.hxx>
+#include <srcview.hxx>
+#include <helpid.h>
+#include <deque>
+
+struct SwTextPortion
+{
+ sal_uInt16 nLine;
+ sal_uInt16 nStart, nEnd;
+ svtools::ColorConfigEntry eType;
+};
+
+#define MAX_SYNTAX_HIGHLIGHT 20
+#define MAX_HIGHLIGHTTIME 200
+#define SYNTAX_HIGHLIGHT_TIMEOUT 200
+
+typedef std::deque<SwTextPortion> SwTextPortions;
+
+static void lcl_Highlight(const OUString& rSource, SwTextPortions& aPortionList)
+{
+ const sal_Unicode cOpenBracket = '<';
+ const sal_Unicode cCloseBracket= '>';
+ const sal_Unicode cSlash = '/';
+ const sal_Unicode cExclamation = '!';
+ const sal_Unicode cMinus = '-';
+ const sal_Unicode cSpace = ' ';
+ const sal_Unicode cTab = 0x09;
+ const sal_Unicode cLF = 0x0a;
+ const sal_Unicode cCR = 0x0d;
+
+ const sal_uInt16 nStrLen = rSource.getLength();
+ sal_uInt16 nInsert = 0; // number of inserted portions
+ sal_uInt16 nActPos = 0; // position, where '<' was found
+ sal_uInt16 nOffset = 0; // Offset of nActPos to '<'
+ sal_uInt16 nPortStart = USHRT_MAX; // for the TextPortion
+ sal_uInt16 nPortEnd = 0;
+ SwTextPortion aText;
+ while(nActPos < nStrLen)
+ {
+ svtools::ColorConfigEntry eFoundType = svtools::HTMLUNKNOWN;
+ if((nActPos < nStrLen - 2) && (rSource[nActPos] == cOpenBracket))
+ {
+ // insert 'empty' portion
+ if(nPortEnd < nActPos - 1 )
+ {
+ aText.nLine = 0;
+ // don't move at the beginning
+ aText.nStart = nPortEnd;
+ if(nInsert)
+ aText.nStart += 1;
+ aText.nEnd = nActPos - 1;
+ aText.eType = svtools::HTMLUNKNOWN;
+ aPortionList.push_back( aText );
+ nInsert++;
+ }
+ sal_Unicode cFollowFirst = rSource[nActPos + 1];
+ sal_Unicode cFollowNext = rSource[nActPos + 2];
+ if(cExclamation == cFollowFirst)
+ {
+ // "<!" SGML or comment
+ if(cMinus == cFollowNext &&
+ nActPos < nStrLen - 3 && cMinus == rSource[nActPos + 3])
+ {
+ eFoundType = svtools::HTMLCOMMENT;
+ }
+ else
+ eFoundType = svtools::HTMLSGML;
+ nPortStart = nActPos;
+ nPortEnd = nActPos + 1;
+ }
+ else if(cSlash == cFollowFirst)
+ {
+ // "</" ignore slash
+ nPortStart = nActPos;
+ nActPos++;
+ nOffset++;
+ }
+ if(svtools::HTMLUNKNOWN == eFoundType)
+ {
+ // now here a keyword could follow
+ sal_uInt16 nSrchPos = nActPos;
+ while(++nSrchPos < nStrLen - 1)
+ {
+ sal_Unicode cNext = rSource[nSrchPos];
+ if( cNext == cSpace ||
+ cNext == cTab ||
+ cNext == cLF ||
+ cNext == cCR)
+ break;
+ else if(cNext == cCloseBracket)
+ {
+ break;
+ }
+ }
+ if(nSrchPos > nActPos + 1)
+ {
+ // some string was found
+ OUString sToken = rSource.copy(nActPos + 1, nSrchPos - nActPos - 1 );
+ sToken = sToken.toAsciiUpperCase();
+ int nToken = ::GetHTMLToken(sToken);
+ if(nToken)
+ {
+ // Token was found
+ eFoundType = svtools::HTMLKEYWORD;
+ nPortEnd = nSrchPos;
+ nPortStart = nActPos;
+ }
+ else
+ {
+ // what was that?
+ SAL_WARN(
+ "sw.level2",
+ "Token " << sToken
+ << " not recognised!");
+ }
+
+ }
+ }
+ // now we still have to look for '>'
+ if(svtools::HTMLUNKNOWN != eFoundType)
+ {
+ bool bFound = false;
+ for(sal_uInt16 i = nPortEnd; i < nStrLen; i++)
+ if(cCloseBracket == rSource[i])
+ {
+ bFound = true;
+ nPortEnd = i;
+ break;
+ }
+ if(!bFound && (eFoundType == svtools::HTMLCOMMENT))
+ {
+ // comment without ending in this line
+ bFound = true;
+ nPortEnd = nStrLen - 1;
+ }
+
+ if(bFound ||(eFoundType == svtools::HTMLCOMMENT))
+ {
+ SwTextPortion aTextPortion;
+ aTextPortion.nLine = 0;
+ aTextPortion.nStart = nPortStart + 1;
+ aTextPortion.nEnd = nPortEnd;
+ aTextPortion.eType = eFoundType;
+ aPortionList.push_back( aTextPortion );
+ nInsert++;
+ eFoundType = svtools::HTMLUNKNOWN;
+ }
+
+ }
+ }
+ nActPos++;
+ }
+ if(nInsert && nPortEnd < nActPos - 1)
+ {
+ aText.nLine = 0;
+ aText.nStart = nPortEnd + 1;
+ aText.nEnd = nActPos - 1;
+ aText.eType = svtools::HTMLUNKNOWN;
+ aPortionList.push_back( aText );
+ nInsert++;
+ }
+}
+
+class SwSrcEditWindow::ChangesListener:
+ public cppu::WeakImplHelper1< css::beans::XPropertiesChangeListener >
+{
+public:
+ ChangesListener(SwSrcEditWindow & editor): editor_(editor) {}
+
+private:
+ virtual ~ChangesListener() {}
+
+ virtual void SAL_CALL disposing(css::lang::EventObject const &)
+ throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
+ {
+ osl::MutexGuard g(editor_.mutex_);
+ editor_.notifier_.clear();
+ }
+
+ virtual void SAL_CALL propertiesChange(
+ css::uno::Sequence< css::beans::PropertyChangeEvent > const &)
+ throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
+ {
+ SolarMutexGuard g;
+ editor_.SetFont();
+ }
+
+ SwSrcEditWindow & editor_;
+};
+
+SwSrcEditWindow::SwSrcEditWindow( Window* pParent, SwSrcView* pParentView ) :
+ Window( pParent, WB_BORDER|WB_CLIPCHILDREN ),
+
+ pTextEngine(0),
+
+ pOutWin(0),
+ pHScrollbar(0),
+ pVScrollbar(0),
+
+ pSrcView(pParentView),
+
+ nCurTextWidth(0),
+ nStartLine(USHRT_MAX),
+ eSourceEncoding(osl_getThreadTextEncoding()),
+ bDoSyntaxHighlight(true),
+ bHighlighting(false)
+{
+ SetHelpId(HID_SOURCE_EDITWIN);
+ CreateTextEngine();
+
+ // Using "this" in ctor is a little fishy, but should work here at least as
+ // long as there are no derivations:
+ listener_ = new ChangesListener(*this);
+ css::uno::Reference< css::beans::XMultiPropertySet > n(
+ officecfg::Office::Common::Font::SourceViewFont::get(),
+ css::uno::UNO_QUERY_THROW);
+ {
+ osl::MutexGuard g(mutex_);
+ notifier_ = n;
+ }
+ css::uno::Sequence< OUString > s(2);
+ s[0] = "FontHeight";
+ s[1] = "FontName";
+ n->addPropertiesChangeListener(s, listener_.get());
+}
+
+ SwSrcEditWindow::~SwSrcEditWindow()
+{
+ css::uno::Reference< css::beans::XMultiPropertySet > n;
+ {
+ osl::MutexGuard g(mutex_);
+ n = notifier_;
+ }
+ if (n.is()) {
+ n->removePropertiesChangeListener(listener_.get());
+ }
+ aSyntaxIdleTimer.Stop();
+ if ( pTextEngine )
+ {
+ EndListening( *pTextEngine );
+ pTextEngine->RemoveView( pTextView );
+
+ delete pHScrollbar;
+ delete pVScrollbar;
+
+ delete pTextView;
+ delete pTextEngine;
+ }
+ delete pOutWin;
+}
+
+void SwSrcEditWindow::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Window::DataChanged( rDCEvt );
+
+ switch ( rDCEvt.GetType() )
+ {
+ case DATACHANGED_SETTINGS:
+ // newly rearrange ScrollBars or trigger Resize, because
+ // ScrollBar size could have changed. For this, in the
+ // Resize handler the size of ScrollBars has to be queried
+ // from the settings as well.
+ if( rDCEvt.GetFlags() & SETTINGS_STYLE )
+ Resize();
+ break;
+ }
+}
+
+void SwSrcEditWindow::Resize()
+{
+ // ScrollBars, etc. happens in Adjust...
+ if ( pTextView )
+ {
+ long nVisY = pTextView->GetStartDocPos().Y();
+ pTextView->ShowCursor();
+ Size aOutSz( GetOutputSizePixel() );
+ long nMaxVisAreaStart = pTextView->GetTextEngine()->GetTextHeight() - aOutSz.Height();
+ if ( nMaxVisAreaStart < 0 )
+ nMaxVisAreaStart = 0;
+ if ( pTextView->GetStartDocPos().Y() > nMaxVisAreaStart )
+ {
+ Point aStartDocPos( pTextView->GetStartDocPos() );
+ aStartDocPos.Y() = nMaxVisAreaStart;
+ pTextView->SetStartDocPos( aStartDocPos );
+ pTextView->ShowCursor();
+ }
+ long nScrollStd = GetSettings().GetStyleSettings().GetScrollBarSize();
+ Size aScrollSz(aOutSz.Width() - nScrollStd, nScrollStd );
+ Point aScrollPos(0, aOutSz.Height() - nScrollStd);
+
+ pHScrollbar->SetPosSizePixel( aScrollPos, aScrollSz);
+
+ aScrollSz.Width() = aScrollSz.Height();
+ aScrollSz.Height() = aOutSz.Height();
+ aScrollPos = Point(aOutSz.Width() - nScrollStd, 0);
+
+ pVScrollbar->SetPosSizePixel( aScrollPos, aScrollSz);
+ aOutSz.Width() -= nScrollStd;
+ aOutSz.Height() -= nScrollStd;
+ pOutWin->SetOutputSizePixel(aOutSz);
+ InitScrollBars();
+
+ // set line in first Resize
+ if(USHRT_MAX != nStartLine)
+ {
+ if(nStartLine < pTextEngine->GetParagraphCount())
+ {
+ TextSelection aSel(TextPaM( nStartLine, 0 ), TextPaM( nStartLine, 0x0 ));
+ pTextView->SetSelection(aSel);
+ pTextView->ShowCursor();
+ }
+ nStartLine = USHRT_MAX;
+ }
+
+ if ( nVisY != pTextView->GetStartDocPos().Y() )
+ Invalidate();
+ }
+
+}
+
+void TextViewOutWin::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Window::DataChanged( rDCEvt );
+
+ switch( rDCEvt.GetType() )
+ {
+ case DATACHANGED_SETTINGS:
+ // query settings
+ if( rDCEvt.GetFlags() & SETTINGS_STYLE )
+ {
+ const Color &rCol = GetSettings().GetStyleSettings().GetWindowColor();
+ SetBackground( rCol );
+ Font aFont( pTextView->GetTextEngine()->GetFont() );
+ aFont.SetFillColor( rCol );
+ pTextView->GetTextEngine()->SetFont( aFont );
+ }
+ break;
+ }
+}
+
+void TextViewOutWin::MouseMove( const MouseEvent &rEvt )
+{
+ if ( pTextView )
+ pTextView->MouseMove( rEvt );
+}
+
+void TextViewOutWin::MouseButtonUp( const MouseEvent &rEvt )
+{
+ if ( pTextView )
+ {
+ pTextView->MouseButtonUp( rEvt );
+ SfxBindings& rBindings = ((SwSrcEditWindow*)GetParent())->GetSrcView()->GetViewFrame()->GetBindings();
+ rBindings.Invalidate( SID_TABLE_CELL );
+ rBindings.Invalidate( SID_CUT );
+ rBindings.Invalidate( SID_COPY );
+ }
+}
+
+void TextViewOutWin::MouseButtonDown( const MouseEvent &rEvt )
+{
+ GrabFocus();
+ if ( pTextView )
+ pTextView->MouseButtonDown( rEvt );
+}
+
+void TextViewOutWin::Command( const CommandEvent& rCEvt )
+{
+ switch(rCEvt.GetCommand())
+ {
+ case COMMAND_CONTEXTMENU:
+ ((SwSrcEditWindow*)GetParent())->GetSrcView()->GetViewFrame()->
+ GetDispatcher()->ExecutePopup();
+ break;
+ case COMMAND_WHEEL:
+ case COMMAND_STARTAUTOSCROLL:
+ case COMMAND_AUTOSCROLL:
+ {
+ const CommandWheelData* pWData = rCEvt.GetWheelData();
+ if( !pWData || COMMAND_WHEEL_ZOOM != pWData->GetMode() )
+ {
+ ((SwSrcEditWindow*)GetParent())->HandleWheelCommand( rCEvt );
+ }
+ }
+ break;
+
+ default:
+ if ( pTextView )
+ pTextView->Command( rCEvt );
+ else
+ Window::Command(rCEvt);
+ }
+}
+
+void TextViewOutWin::KeyInput( const KeyEvent& rKEvt )
+{
+ bool bDone = false;
+ SwSrcEditWindow* pSrcEditWin = (SwSrcEditWindow*)GetParent();
+ bool bChange = !pSrcEditWin->IsReadonly() || !TextEngine::DoesKeyChangeText( rKEvt );
+ if(bChange)
+ bDone = pTextView->KeyInput( rKEvt );
+
+ SfxBindings& rBindings = ((SwSrcEditWindow*)GetParent())->GetSrcView()->GetViewFrame()->GetBindings();
+ if ( !bDone )
+ {
+ if ( !SfxViewShell::Current()->KeyInput( rKEvt ) )
+ Window::KeyInput( rKEvt );
+ }
+ else
+ {
+ rBindings.Invalidate( SID_TABLE_CELL );
+ if ( rKEvt.GetKeyCode().GetGroup() == KEYGROUP_CURSOR )
+ rBindings.Update( SID_BASICIDE_STAT_POS );
+ if (pSrcEditWin->GetTextEngine()->IsModified() )
+ {
+ rBindings.Invalidate( SID_SAVEDOC );
+ rBindings.Invalidate( SID_DOC_MODIFIED );
+ }
+ if( rKEvt.GetKeyCode().GetCode() == KEY_INSERT )
+ rBindings.Invalidate( SID_ATTR_INSERT );
+ }
+
+ rBindings.Invalidate( SID_CUT );
+ rBindings.Invalidate( SID_COPY );
+
+ SwDocShell* pDocShell = pSrcEditWin->GetSrcView()->GetDocShell();
+ if(pSrcEditWin->GetTextEngine()->IsModified())
+ {
+ pDocShell->SetModified();
+ }
+}
+
+void TextViewOutWin::Paint( const Rectangle& rRect )
+{
+ pTextView->Paint( rRect );
+}
+
+void SwSrcEditWindow::CreateTextEngine()
+{
+ const Color &rCol = GetSettings().GetStyleSettings().GetWindowColor();
+ pOutWin = new TextViewOutWin(this, 0);
+ pOutWin->SetBackground(Wallpaper(rCol));
+ pOutWin->SetPointer(Pointer(POINTER_TEXT));
+ pOutWin->Show();
+
+ // create Scrollbars
+ pHScrollbar = new ScrollBar(this, WB_3DLOOK |WB_HSCROLL|WB_DRAG);
+ pHScrollbar->EnableRTL( false ); // --- RTL --- no mirroring for scrollbars
+ pHScrollbar->SetScrollHdl(LINK(this, SwSrcEditWindow, ScrollHdl));
+ pHScrollbar->Show();
+
+ pVScrollbar = new ScrollBar(this, WB_3DLOOK |WB_VSCROLL|WB_DRAG);
+ pVScrollbar->EnableRTL( false ); // --- RTL --- no mirroring for scrollbars
+ pVScrollbar->SetScrollHdl(LINK(this, SwSrcEditWindow, ScrollHdl));
+ pHScrollbar->EnableDrag();
+ pVScrollbar->Show();
+
+ pTextEngine = new ExtTextEngine;
+ pTextView = new ExtTextView( pTextEngine, pOutWin );
+ pTextView->SetAutoIndentMode(true);
+ pOutWin->SetTextView(pTextView);
+
+ pTextEngine->SetUpdateMode( false );
+ pTextEngine->InsertView( pTextView );
+
+ Font aFont;
+ aFont.SetTransparent( false );
+ aFont.SetFillColor( rCol );
+ SetPointFont( aFont );
+ aFont = GetFont();
+ aFont.SetFillColor( rCol );
+ pOutWin->SetFont( aFont );
+ pTextEngine->SetFont( aFont );
+
+ aSyntaxIdleTimer.SetTimeout( SYNTAX_HIGHLIGHT_TIMEOUT );
+ aSyntaxIdleTimer.SetTimeoutHdl( LINK( this, SwSrcEditWindow, SyntaxTimerHdl ) );
+
+ pTextEngine->EnableUndo( true );
+ pTextEngine->SetUpdateMode( true );
+
+ pTextView->ShowCursor( true, true );
+ InitScrollBars();
+ StartListening( *pTextEngine );
+
+ SfxBindings& rBind = GetSrcView()->GetViewFrame()->GetBindings();
+ rBind.Invalidate( SID_TABLE_CELL );
+}
+
+void SwSrcEditWindow::SetScrollBarRanges()
+{
+ // Extra method, not InitScrollBars, because also for TextEngine events.
+
+ pHScrollbar->SetRange( Range( 0, nCurTextWidth-1 ) );
+ pVScrollbar->SetRange( Range(0, pTextEngine->GetTextHeight()-1) );
+}
+
+void SwSrcEditWindow::InitScrollBars()
+{
+ SetScrollBarRanges();
+
+ Size aOutSz( pOutWin->GetOutputSizePixel() );
+ pVScrollbar->SetVisibleSize( aOutSz.Height() );
+ pVScrollbar->SetPageSize( aOutSz.Height() * 8 / 10 );
+ pVScrollbar->SetLineSize( pOutWin->GetTextHeight() );
+ pVScrollbar->SetThumbPos( pTextView->GetStartDocPos().Y() );
+ pHScrollbar->SetVisibleSize( aOutSz.Width() );
+ pHScrollbar->SetPageSize( aOutSz.Width() * 8 / 10 );
+ pHScrollbar->SetLineSize( pOutWin->GetTextWidth(OUString('x')) );
+ pHScrollbar->SetThumbPos( pTextView->GetStartDocPos().X() );
+
+}
+
+IMPL_LINK(SwSrcEditWindow, ScrollHdl, ScrollBar*, pScroll)
+{
+ if(pScroll == pVScrollbar)
+ {
+ long nDiff = pTextView->GetStartDocPos().Y() - pScroll->GetThumbPos();
+ GetTextView()->Scroll( 0, nDiff );
+ pTextView->ShowCursor( false, true );
+ pScroll->SetThumbPos( pTextView->GetStartDocPos().Y() );
+ }
+ else
+ {
+ long nDiff = pTextView->GetStartDocPos().X() - pScroll->GetThumbPos();
+ GetTextView()->Scroll( nDiff, 0 );
+ pTextView->ShowCursor( false, true );
+ pScroll->SetThumbPos( pTextView->GetStartDocPos().X() );
+ }
+ GetSrcView()->GetViewFrame()->GetBindings().Invalidate( SID_TABLE_CELL );
+ return 0;
+}
+
+IMPL_LINK( SwSrcEditWindow, SyntaxTimerHdl, Timer *, pTimer )
+{
+ Time aSyntaxCheckStart( Time::SYSTEM );
+ SAL_WARN_IF(pTextView == 0, "sw", "No View yet, but syntax highlighting?!");
+
+ bHighlighting = true;
+ sal_uInt16 nCount = 0;
+ // at first the region around the cursor is processed
+ TextSelection aSel = pTextView->GetSelection();
+ sal_uInt16 nCur = (sal_uInt16)aSel.GetStart().GetPara();
+ if(nCur > 40)
+ nCur -= 40;
+ else
+ nCur = 0;
+ if(!aSyntaxLineTable.empty())
+ for(sal_uInt16 i = 0; i < 80 && nCount < 40; i++, nCur++)
+ {
+ if(aSyntaxLineTable.find(nCur) != aSyntaxLineTable.end())
+ {
+ DoSyntaxHighlight( nCur );
+ aSyntaxLineTable.erase( nCur );
+ nCount++;
+ if(aSyntaxLineTable.empty())
+ break;
+ if((Time( Time::SYSTEM ).GetTime() - aSyntaxCheckStart.GetTime()) > MAX_HIGHLIGHTTIME )
+ {
+ pTimer->SetTimeout( 2 * SYNTAX_HIGHLIGHT_TIMEOUT );
+ break;
+ }
+ }
+ }
+
+ // when there is still anything left by then, go on from the beginning
+ while ( !aSyntaxLineTable.empty() && nCount < MAX_SYNTAX_HIGHLIGHT)
+ {
+ sal_uInt16 nLine = *aSyntaxLineTable.begin();
+ DoSyntaxHighlight( nLine );
+ aSyntaxLineTable.erase(nLine);
+ nCount ++;
+ if(Time( Time::SYSTEM ).GetTime() - aSyntaxCheckStart.GetTime() > MAX_HIGHLIGHTTIME)
+ {
+ pTimer->SetTimeout( 2 * SYNTAX_HIGHLIGHT_TIMEOUT );
+ break;
+ }
+ }
+
+ if(!aSyntaxLineTable.empty() && !pTimer->IsActive())
+ pTimer->Start();
+ // SyntaxTimerHdl is called when text changed
+ // => good opportunity to determine text width!
+ long nPrevTextWidth = nCurTextWidth;
+ nCurTextWidth = pTextEngine->CalcTextWidth() + 25; // kleine Toleranz
+ if ( nCurTextWidth != nPrevTextWidth )
+ SetScrollBarRanges();
+ bHighlighting = false;
+
+ return 0;
+}
+
+void SwSrcEditWindow::DoSyntaxHighlight( sal_uInt16 nPara )
+{
+ // Because of DelayedSyntaxHighlight it could happen,
+ // that the line doesn't exist anymore!
+ if ( nPara < pTextEngine->GetParagraphCount() )
+ {
+ bool bTempModified = IsModified();
+ pTextEngine->RemoveAttribs( nPara, true );
+ OUString aSource( pTextEngine->GetText( nPara ) );
+ pTextEngine->SetUpdateMode( false );
+ ImpDoHighlight( aSource, nPara );
+ TextView* pTmp = pTextEngine->GetActiveView();
+ pTmp->SetAutoScroll(false);
+ pTextEngine->SetActiveView(0);
+ pTextEngine->SetUpdateMode( true );
+ pTextEngine->SetActiveView(pTmp);
+ pTmp->SetAutoScroll(true);
+ pTmp->ShowCursor( false/*pTmp->IsAutoScroll()*/ );
+
+ if(!bTempModified)
+ ClearModifyFlag();
+ }
+}
+
+void SwSrcEditWindow::DoDelayedSyntaxHighlight( sal_uInt16 nPara )
+{
+ if ( !bHighlighting && bDoSyntaxHighlight )
+ {
+ aSyntaxLineTable.insert( nPara );
+ aSyntaxIdleTimer.Start();
+ }
+}
+
+void SwSrcEditWindow::ImpDoHighlight( const OUString& rSource, sal_uInt16 nLineOff )
+{
+ SwTextPortions aPortionList;
+ lcl_Highlight(rSource, aPortionList);
+
+ size_t nCount = aPortionList.size();
+ if ( !nCount )
+ return;
+
+ SwTextPortion& rLast = aPortionList[nCount-1];
+ if ( rLast.nStart > rLast.nEnd ) // Only until Bug from MD is resolved
+ {
+ nCount--;
+ aPortionList.pop_back();
+ if ( !nCount )
+ return;
+ }
+
+ {
+ // Only blanks and tabs have to be attributed along.
+ // When two identical attributes are placed consecutively,
+ // it optimises the TextEngine.
+ sal_uInt16 nLastEnd = 0;
+
+ for ( size_t i = 0; i < nCount; i++ )
+ {
+ SwTextPortion& r = aPortionList[i];
+ SAL_WARN_IF(
+ r.nLine != aPortionList[0].nLine, "sw.level2",
+ "multiple lines after all?");
+ if ( r.nStart > r.nEnd ) // only until Bug from MD is resolved
+ continue;
+
+ if ( r.nStart > nLastEnd )
+ {
+ // Can I rely on the fact that all except blank and tab
+ // are being highlighted?!
+ r.nStart = nLastEnd;
+ }
+ nLastEnd = r.nEnd+1;
+ if ( ( i == (nCount-1) ) && ( r.nEnd < rSource.getLength() ) )
+ r.nEnd = rSource.getLength();
+ }
+ }
+
+ for ( size_t i = 0; i < aPortionList.size(); i++ )
+ {
+ SwTextPortion& r = aPortionList[i];
+ if ( r.nStart > r.nEnd ) // only until Bug from MD is resolved
+ continue;
+ if(r.eType != svtools::HTMLSGML &&
+ r.eType != svtools::HTMLCOMMENT &&
+ r.eType != svtools::HTMLKEYWORD &&
+ r.eType != svtools::HTMLUNKNOWN)
+ r.eType = svtools::HTMLUNKNOWN;
+ Color aColor((ColorData)SW_MOD()->GetColorConfig().GetColorValue((svtools::ColorConfigEntry)r.eType).nColor);
+ sal_uInt16 nLine = nLineOff+r.nLine;
+ pTextEngine->SetAttrib( TextAttribFontColor( aColor ), nLine, r.nStart, r.nEnd+1, true );
+ }
+}
+
+void SwSrcEditWindow::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
+{
+ if ( rHint.ISA( TextHint ) )
+ {
+ const TextHint& rTextHint = (const TextHint&)rHint;
+ if( rTextHint.GetId() == TEXT_HINT_VIEWSCROLLED )
+ {
+ pHScrollbar->SetThumbPos( pTextView->GetStartDocPos().X() );
+ pVScrollbar->SetThumbPos( pTextView->GetStartDocPos().Y() );
+ }
+ else if( rTextHint.GetId() == TEXT_HINT_TEXTHEIGHTCHANGED )
+ {
+ if ( (long)pTextEngine->GetTextHeight() < pOutWin->GetOutputSizePixel().Height() )
+ pTextView->Scroll( 0, pTextView->GetStartDocPos().Y() );
+ pVScrollbar->SetThumbPos( pTextView->GetStartDocPos().Y() );
+ SetScrollBarRanges();
+ }
+ else if( ( rTextHint.GetId() == TEXT_HINT_PARAINSERTED ) ||
+ ( rTextHint.GetId() == TEXT_HINT_PARACONTENTCHANGED ) )
+ {
+ DoDelayedSyntaxHighlight( (sal_uInt16)rTextHint.GetValue() );
+ }
+ }
+}
+
+void SwSrcEditWindow::Invalidate(sal_uInt16 )
+{
+ pOutWin->Invalidate();
+ Window::Invalidate();
+
+}
+
+void SwSrcEditWindow::Command( const CommandEvent& rCEvt )
+{
+ switch(rCEvt.GetCommand())
+ {
+ case COMMAND_WHEEL:
+ case COMMAND_STARTAUTOSCROLL:
+ case COMMAND_AUTOSCROLL:
+ {
+ const CommandWheelData* pWData = rCEvt.GetWheelData();
+ if( !pWData || COMMAND_WHEEL_ZOOM != pWData->GetMode() )
+ HandleScrollCommand( rCEvt, pHScrollbar, pVScrollbar );
+ }
+ break;
+ default:
+ Window::Command(rCEvt);
+ }
+}
+
+void SwSrcEditWindow::HandleWheelCommand( const CommandEvent& rCEvt )
+{
+ pTextView->Command(rCEvt);
+ HandleScrollCommand( rCEvt, pHScrollbar, pVScrollbar );
+}
+
+void SwSrcEditWindow::GetFocus()
+{
+ pOutWin->GrabFocus();
+}
+
+static bool lcl_GetLanguagesForEncoding(rtl_TextEncoding eEnc, LanguageType aLanguages[])
+{
+ switch(eEnc)
+ {
+ case RTL_TEXTENCODING_UTF7 :
+ case RTL_TEXTENCODING_UTF8 :
+ // don#t fill - all LANGUAGE_SYSTEM means unicode font has to be used
+ break;
+
+ case RTL_TEXTENCODING_ISO_8859_3:
+ case RTL_TEXTENCODING_ISO_8859_1 :
+ case RTL_TEXTENCODING_MS_1252 :
+ case RTL_TEXTENCODING_APPLE_ROMAN :
+ case RTL_TEXTENCODING_IBM_850 :
+ case RTL_TEXTENCODING_ISO_8859_14 :
+ case RTL_TEXTENCODING_ISO_8859_15 :
+ //fill with western languages
+ aLanguages[0] = LANGUAGE_GERMAN;
+ aLanguages[1] = LANGUAGE_FRENCH;
+ aLanguages[2] = LANGUAGE_ITALIAN;
+ aLanguages[3] = LANGUAGE_SPANISH;
+ break;
+
+ case RTL_TEXTENCODING_IBM_865 :
+ //scandinavian
+ aLanguages[0] = LANGUAGE_FINNISH;
+ aLanguages[1] = LANGUAGE_NORWEGIAN;
+ aLanguages[2] = LANGUAGE_SWEDISH;
+ aLanguages[3] = LANGUAGE_DANISH;
+ break;
+
+ case RTL_TEXTENCODING_ISO_8859_10 :
+ case RTL_TEXTENCODING_ISO_8859_13 :
+ case RTL_TEXTENCODING_ISO_8859_2 :
+ case RTL_TEXTENCODING_IBM_852 :
+ case RTL_TEXTENCODING_MS_1250 :
+ case RTL_TEXTENCODING_APPLE_CENTEURO :
+ aLanguages[0] = LANGUAGE_POLISH;
+ aLanguages[1] = LANGUAGE_CZECH;
+ aLanguages[2] = LANGUAGE_HUNGARIAN;
+ aLanguages[3] = LANGUAGE_SLOVAK;
+ break;
+
+ case RTL_TEXTENCODING_ISO_8859_4 :
+ case RTL_TEXTENCODING_IBM_775 :
+ case RTL_TEXTENCODING_MS_1257 :
+ aLanguages[0] = LANGUAGE_LATVIAN ;
+ aLanguages[1] = LANGUAGE_LITHUANIAN;
+ aLanguages[2] = LANGUAGE_ESTONIAN ;
+ break;
+
+ case RTL_TEXTENCODING_IBM_863 : aLanguages[0] = LANGUAGE_FRENCH_CANADIAN; break;
+ case RTL_TEXTENCODING_APPLE_FARSI : aLanguages[0] = LANGUAGE_FARSI; break;
+ case RTL_TEXTENCODING_APPLE_ROMANIAN:aLanguages[0] = LANGUAGE_ROMANIAN; break;
+
+ case RTL_TEXTENCODING_IBM_861 :
+ case RTL_TEXTENCODING_APPLE_ICELAND :
+ aLanguages[0] = LANGUAGE_ICELANDIC;
+ break;
+
+ case RTL_TEXTENCODING_APPLE_CROATIAN:aLanguages[0] = LANGUAGE_CROATIAN; break;
+
+ case RTL_TEXTENCODING_IBM_437 :
+ case RTL_TEXTENCODING_ASCII_US : aLanguages[0] = LANGUAGE_ENGLISH; break;
+
+ case RTL_TEXTENCODING_IBM_862 :
+ case RTL_TEXTENCODING_MS_1255 :
+ case RTL_TEXTENCODING_APPLE_HEBREW :
+ case RTL_TEXTENCODING_ISO_8859_8 :
+ aLanguages[0] = LANGUAGE_HEBREW;
+ break;
+
+ case RTL_TEXTENCODING_IBM_857 :
+ case RTL_TEXTENCODING_MS_1254 :
+ case RTL_TEXTENCODING_APPLE_TURKISH:
+ case RTL_TEXTENCODING_ISO_8859_9 :
+ aLanguages[0] = LANGUAGE_TURKISH;
+ break;
+
+ case RTL_TEXTENCODING_IBM_860 :
+ aLanguages[0] = LANGUAGE_PORTUGUESE;
+ break;
+
+ case RTL_TEXTENCODING_IBM_869 :
+ case RTL_TEXTENCODING_MS_1253 :
+ case RTL_TEXTENCODING_APPLE_GREEK :
+ case RTL_TEXTENCODING_ISO_8859_7 :
+ case RTL_TEXTENCODING_IBM_737 :
+ aLanguages[0] = LANGUAGE_GREEK;
+ break;
+
+ case RTL_TEXTENCODING_KOI8_R :
+ case RTL_TEXTENCODING_ISO_8859_5 :
+ case RTL_TEXTENCODING_IBM_855 :
+ case RTL_TEXTENCODING_MS_1251 :
+ case RTL_TEXTENCODING_IBM_866 :
+ case RTL_TEXTENCODING_APPLE_CYRILLIC :
+ aLanguages[0] = LANGUAGE_RUSSIAN;
+ break;
+
+ case RTL_TEXTENCODING_APPLE_UKRAINIAN:
+ case RTL_TEXTENCODING_KOI8_U:
+ aLanguages[0] = LANGUAGE_UKRAINIAN;
+ break;
+
+ case RTL_TEXTENCODING_IBM_864 :
+ case RTL_TEXTENCODING_MS_1256 :
+ case RTL_TEXTENCODING_ISO_8859_6 :
+ case RTL_TEXTENCODING_APPLE_ARABIC :
+ aLanguages[0] = LANGUAGE_ARABIC_SAUDI_ARABIA;
+ break;
+
+ case RTL_TEXTENCODING_APPLE_CHINTRAD :
+ case RTL_TEXTENCODING_MS_950 :
+ case RTL_TEXTENCODING_GBT_12345 :
+ case RTL_TEXTENCODING_BIG5 :
+ case RTL_TEXTENCODING_EUC_TW :
+ case RTL_TEXTENCODING_BIG5_HKSCS :
+ aLanguages[0] = LANGUAGE_CHINESE_TRADITIONAL;
+ break;
+
+ case RTL_TEXTENCODING_EUC_JP :
+ case RTL_TEXTENCODING_ISO_2022_JP :
+ case RTL_TEXTENCODING_JIS_X_0201 :
+ case RTL_TEXTENCODING_JIS_X_0208 :
+ case RTL_TEXTENCODING_JIS_X_0212 :
+ case RTL_TEXTENCODING_APPLE_JAPANESE :
+ case RTL_TEXTENCODING_MS_932 :
+ case RTL_TEXTENCODING_SHIFT_JIS :
+ aLanguages[0] = LANGUAGE_JAPANESE;
+ break;
+
+ case RTL_TEXTENCODING_GB_2312 :
+ case RTL_TEXTENCODING_MS_936 :
+ case RTL_TEXTENCODING_GBK :
+ case RTL_TEXTENCODING_GB_18030 :
+ case RTL_TEXTENCODING_APPLE_CHINSIMP :
+ case RTL_TEXTENCODING_EUC_CN :
+ case RTL_TEXTENCODING_ISO_2022_CN :
+ aLanguages[0] = LANGUAGE_CHINESE_SIMPLIFIED;
+ break;
+
+ case RTL_TEXTENCODING_APPLE_KOREAN :
+ case RTL_TEXTENCODING_MS_949 :
+ case RTL_TEXTENCODING_EUC_KR :
+ case RTL_TEXTENCODING_ISO_2022_KR :
+ case RTL_TEXTENCODING_MS_1361 :
+ aLanguages[0] = LANGUAGE_KOREAN;
+ break;
+
+ case RTL_TEXTENCODING_APPLE_THAI :
+ case RTL_TEXTENCODING_MS_874 :
+ case RTL_TEXTENCODING_TIS_620 :
+ aLanguages[0] = LANGUAGE_THAI;
+ break;
+ default: aLanguages[0] = Application::GetSettings().GetUILanguageTag().getLanguageType();
+ }
+ return aLanguages[0] != LANGUAGE_SYSTEM;
+}
+void SwSrcEditWindow::SetFont()
+{
+ OUString sFontName(
+ officecfg::Office::Common::Font::SourceViewFont::FontName::get().
+ get_value_or(OUString()));
+ if(sFontName.isEmpty())
+ {
+ LanguageType aLanguages[5] =
+ {
+ LANGUAGE_SYSTEM, LANGUAGE_SYSTEM, LANGUAGE_SYSTEM, LANGUAGE_SYSTEM, LANGUAGE_SYSTEM
+ };
+ Font aFont;
+ if(lcl_GetLanguagesForEncoding(eSourceEncoding, aLanguages))
+ {
+ //TODO: check for multiple languages
+ aFont = OutputDevice::GetDefaultFont(DEFAULTFONT_FIXED, aLanguages[0], 0, this);
+ }
+ else
+ aFont = OutputDevice::GetDefaultFont(DEFAULTFONT_SANS_UNICODE,
+ Application::GetSettings().GetLanguageTag().getLanguageType(), 0, this);
+ sFontName = aFont.GetName();
+ }
+ const SvxFontListItem* pFontListItem =
+ (const SvxFontListItem* )pSrcView->GetDocShell()->GetItem( SID_ATTR_CHAR_FONTLIST );
+ const FontList* pList = pFontListItem->GetFontList();
+ FontInfo aInfo = pList->Get(sFontName,WEIGHT_NORMAL, ITALIC_NONE);
+
+ const Font& rFont = GetTextEngine()->GetFont();
+ Font aFont(aInfo);
+ Size aSize(rFont.GetSize());
+ //font height is stored in point and set in twip
+ aSize.Height() =
+ officecfg::Office::Common::Font::SourceViewFont::FontHeight::get() * 20;
+ aFont.SetSize(pOutWin->LogicToPixel(aSize, MAP_TWIP));
+ GetTextEngine()->SetFont( aFont );
+ pOutWin->SetFont(aFont);
+}
+
+void SwSrcEditWindow::SetTextEncoding(rtl_TextEncoding eEncoding)
+{
+ eSourceEncoding = eEncoding;
+ SetFont();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */