summaryrefslogtreecommitdiff
path: root/sw/source/uibase/docvw/PageBreakWin.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/uibase/docvw/PageBreakWin.cxx')
-rw-r--r--sw/source/uibase/docvw/PageBreakWin.cxx463
1 files changed, 463 insertions, 0 deletions
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: */