summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorCédric Bosdonnat <cedric.bosdonnat.ooo@free.fr>2011-09-04 20:31:18 +0200
committerCédric Bosdonnat <cedric.bosdonnat.ooo@free.fr>2011-09-05 10:07:55 +0200
commitd004a81afc6652d6cb8c13cef648c273527ef1ad (patch)
tree3e73744829604c443b1d87da804f20012d6fc72d /sw
parent68795fe0dce69183400f775e06a2651565657231 (diff)
Header/Footer: Implemented the separator label as a Window
Had quite a hard time drawing the new windows at the correct position and find the proper VCL attributes. This new Window child class is using the WB_MOVEABLE and WB_OWNERDRAWDECORATION to workaround bugs in VCL.
Diffstat (limited to 'sw')
-rwxr-xr-xsw/source/core/layout/paintfrm.cxx236
-rw-r--r--sw/source/ui/app/app.src4
-rw-r--r--sw/source/ui/docvw/edtwin.cxx102
-rw-r--r--sw/source/ui/inc/edtwin.hxx22
4 files changed, 214 insertions, 150 deletions
diff --git a/sw/source/core/layout/paintfrm.cxx b/sw/source/core/layout/paintfrm.cxx
index c8138aafa28e..ad698e48abb6 100755
--- a/sw/source/core/layout/paintfrm.cxx
+++ b/sw/source/core/layout/paintfrm.cxx
@@ -127,6 +127,9 @@
#include <basegfx/color/bcolortools.hxx>
#include <algorithm>
+#include <wrtsh.hxx>
+#include <edtwin.hxx>
+#include <view.hxx>
using namespace ::editeng;
using namespace ::com::sun::star;
@@ -2796,6 +2799,14 @@ SwRootFrm::Paint(SwRect const& rRect, SwPrintData const*const pPrintData) const
else
SwRootFrm::bInPaint = bResetRootPaint = sal_True;
+ SwWrtShell* pWrtSh = dynamic_cast< SwWrtShell* >( pSh );
+ if ( pWrtSh )
+ {
+ SwEditWin& rEditWin = pWrtSh->GetView().GetEditWin();
+ rEditWin.ClearHeaderFooterControls( );
+ }
+
+
SwSavePaintStatics *pStatics = 0;
if ( pGlobalShell )
pStatics = new SwSavePaintStatics();
@@ -3303,177 +3314,106 @@ void SwLayoutFrm::Paint(SwRect const& rRect, SwPrintData const*const) const
}
drawinglayer::primitive2d::Primitive2DSequence lcl_CreateHeaderFooterSeparatorPrimitives(
- OutputDevice* pOut, drawinglayer::processor2d::BaseProcessor2D* pProcessor,
- const SwPageFrm* pPageFrm, double nLabelRight, double nLineY,
- bool bHeader, const String& rStyleName, const SwFrm* pFrm )
+ const SwPageFrm* pPageFrm, double nLineY )
{
// Adjust the Y-coordinate of the line to the header/footer box
- if ( pFrm )
- {
- const SwFrmFmt* pFmt = ((const SwLayoutFrm*)pFrm)->GetFmt();
- if ( bHeader )
- nLineY -= pFmt->GetULSpace().GetLower();
- else
- nLineY += pFmt->GetULSpace().GetUpper();
- }
-
- drawinglayer::primitive2d::Primitive2DSequence aSeq( 3 );
+ drawinglayer::primitive2d::Primitive2DSequence aSeq( 1 );
basegfx::B2DPoint aLeft ( pPageFrm->Frm().Left(), nLineY );
basegfx::B2DPoint aRight( pPageFrm->Frm().Right(), nLineY );
- // Compute the text to show
- String aText = SW_RESSTR( STR_HEADER );
- if ( !bHeader )
- aText = SW_RESSTR( STR_FOOTER );
- aText += rStyleName;
-
- // Colors
basegfx::BColor aLineColor = SwViewOption::GetHeaderFooterMarkColor().getBColor();
- 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 );
- basegfx::BColor aFillColor = basegfx::tools::hsl2rgb( aHslLine );
// Only draw the dashed line for unexisting header / footers
- if ( !pFrm )
- {
- aSeq.realloc( 4 );
-
- // Dashed line in twips
- std::vector< double > aStrokePattern;
- aStrokePattern.push_back( 110 );
- aStrokePattern.push_back( 110 );
-
-
- // Compute the dashed line primitive
- basegfx::B2DPolygon aLinePolygon;
- aLinePolygon.append( aLeft );
- aLinePolygon.append( aRight );
-
- drawinglayer::primitive2d::PolyPolygonStrokePrimitive2D * pLine =
- new drawinglayer::primitive2d::PolyPolygonStrokePrimitive2D (
- basegfx::B2DPolyPolygon( aLinePolygon ),
- drawinglayer::attribute::LineAttribute( aLineColor, 20.0 ),
- drawinglayer::attribute::StrokeAttribute( aStrokePattern ) );
-
- aSeq[3] = drawinglayer::primitive2d::Primitive2DReference( pLine );
- }
-
- const SwRect& rVisArea = pPageFrm->getRootFrm()->GetCurrShell()->VisArea();
- double nVisRight = rVisArea.Right();
-
- // Compute the text primitive
- basegfx::B2DVector aFontSize;
-
- Font aFont = pOut->GetSettings().GetStyleSettings().GetAppFont();
- aFont.SetHeight( 8 * 20 ); // 8pt to twips
+ aSeq.realloc( 4 );
- // Compute the text width
- const Font& rOldFont = pOut->GetFont();
- pOut->SetFont( aFont );
- double nTextWidth = pOut->GetTextWidth( aText );
- pOut->SetFont( rOldFont );
+ // Dashed line in twips
+ std::vector< double > aStrokePattern;
+ aStrokePattern.push_back( 110 );
+ aStrokePattern.push_back( 110 );
- drawinglayer::attribute::FontAttribute aFontAttr = drawinglayer::primitive2d::getFontAttributeFromVclFont(
- aFontSize, aFont, false, false );
- FontMetric aFontMetric = pOut->GetFontMetric( aFont );
+ // Compute the dashed line primitive
+ basegfx::B2DPolygon aLinePolygon;
+ aLinePolygon.append( aLeft );
+ aLinePolygon.append( aRight );
- double nTextOffsetY = aFontMetric.GetHeight() - aFontMetric.GetDescent() + 70.0;
- if ( !bHeader )
- nTextOffsetY = - aFontMetric.GetDescent() - 70.0;
- basegfx::B2DHomMatrix aTextMatrix( basegfx::tools::createScaleTranslateB2DHomMatrix(
- aFontSize.getX(), aFontSize.getY(),
- std::min( nLabelRight, nVisRight ) - nTextWidth - 80.0, nLineY + nTextOffsetY ) );
+ drawinglayer::primitive2d::PolyPolygonStrokePrimitive2D * pLine =
+ new drawinglayer::primitive2d::PolyPolygonStrokePrimitive2D (
+ basegfx::B2DPolyPolygon( aLinePolygon ),
+ drawinglayer::attribute::LineAttribute( aLineColor, 20.0 ),
+ drawinglayer::attribute::StrokeAttribute( aStrokePattern ) );
+ aSeq[0] = drawinglayer::primitive2d::Primitive2DReference( pLine );
+ return aSeq;
+}
- drawinglayer::primitive2d::TextSimplePortionPrimitive2D * pText =
- new drawinglayer::primitive2d::TextSimplePortionPrimitive2D(
- aTextMatrix,
- aText, 0, aText.Len(),
- std::vector< double >(),
- aFontAttr,
- lang::Locale(),
- aLineColor );
- aSeq[2] = drawinglayer::primitive2d::Primitive2DReference( pText );
- basegfx::B2DRange aTextRange = pText->getB2DRange( pProcessor->getViewInformation2D() );
+void SwPageFrm::PaintDecorators( OutputDevice *pOut ) const
+{
+ SwWrtShell* pWrtSh = dynamic_cast< SwWrtShell* >( pGlobalShell );
+ if ( pWrtSh )
+ {
+ SwEditWin& rEditWin = pWrtSh->GetView().GetEditWin();
- // Draw the polygon around the flag
- basegfx::B2DPolygon aFlagPolygon;
- basegfx::B2DVector aFlagVector( 0, 1 );
+ const SwLayoutFrm* pBody = FindBodyCont();
+ if ( pBody )
+ {
+ SwRect aBodyRect( pBody->Frm() );
- double nFlagHeight = aTextRange.getMaxY() - nLineY + 60.0;
+ if ( !pGlobalShell->GetViewOptions()->IsPrinting() &&
+ !pGlobalShell->GetViewOptions()->IsPDFExport() &&
+ !pGlobalShell->IsPreView() &&
+ pGlobalShell->IsHeaderFooterEdit( ) )
+ {
+ const rtl::OUString& rStyleName = GetPageDesc()->GetName();
+ rtl::OUString aHeaderText = ResId::toString( SW_RES( STR_HEADER ) );
+ sal_Int32 nPos = aHeaderText.lastIndexOf( rtl::OUString::createFromAscii( "%1" ) );
+ aHeaderText = aHeaderText.replaceAt( nPos, 2, rStyleName );
+ drawinglayer::processor2d::BaseProcessor2D* pProcessor = CreateProcessor2D();
+
+ // Header
+ const SwFrm* pHeaderFrm = Lower();
+ if ( !pHeaderFrm->IsHeaderFrm() )
+ pHeaderFrm = NULL;
+
+ const SwRect& rVisArea = pGlobalShell->VisArea();
+ long nXOff = std::min( aBodyRect.Right(), rVisArea.Right() );
+
+ // FIXME there are cases where the label isn't show but should be
+ if ( rVisArea.IsInside( Point( rVisArea.Left(), pHeaderFrm->Frm().Bottom() ) ) )
+ {
+ long nOutputYOff = pHeaderFrm->Frm().Bottom();
+ Point nOutputOff = rEditWin.LogicToPixel( Point( nXOff, nOutputYOff ) );
+ rEditWin.AddHeaderFooterControl( aHeaderText, true, nOutputOff );
+ }
- if ( !bHeader )
- {
- aFlagVector = - aFlagVector;
- nFlagHeight = nLineY - aTextRange.getMinY() + 60.0;
- }
- basegfx::B2DPoint aStartPt( aTextRange.getMinX() - 60.0, nLineY );
- aFlagPolygon.append( aStartPt );
- basegfx::B2DPoint aNextPt = aStartPt + aFlagVector * ( nFlagHeight );
- aFlagPolygon.append( aNextPt );
- aNextPt += ( aTextRange.getWidth() + 120.0 ) * basegfx::B2DVector( 1, 0 );
- aFlagPolygon.append( aNextPt );
- aNextPt.setY( nLineY );
- aFlagPolygon.append( aNextPt );
+ pProcessor->process( lcl_CreateHeaderFooterSeparatorPrimitives(
+ this, double( aBodyRect.Top() ) ) );
- // Compute the flag background color primitive
- aSeq[0] = drawinglayer::primitive2d::Primitive2DReference(
- new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(
- basegfx::B2DPolyPolygon( aFlagPolygon ),
- aFillColor ) );
+ // Footer
+ const SwFrm* pFooterFrm = Lower();
+ while ( pFooterFrm->GetNext() )
+ pFooterFrm = pFooterFrm->GetNext();
+ if ( !pFooterFrm->IsFooterFrm() )
+ pFooterFrm = NULL;
- drawinglayer::primitive2d::PolygonHairlinePrimitive2D * pBoxLine =
- new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(
- aFlagPolygon, aLineColor );
- aSeq[1] = drawinglayer::primitive2d::Primitive2DReference( pBoxLine );
+ rtl::OUString aFooterText = ResId::toString( SW_RES( STR_FOOTER ) );
+ nPos = aFooterText.lastIndexOf( rtl::OUString::createFromAscii( "%1" ) );
+ aFooterText = aFooterText.replaceAt( nPos, 2, rStyleName );
- return aSeq;
-}
+ // FIXME there are cases where the label isn't show but should be
+ if ( rVisArea.IsInside( Point( rVisArea.Left(), pFooterFrm->Frm().Top() ) ) )
+ {
+ long nOutputYOff = pFooterFrm->Frm().Top();
+ Point nOutputOff = rEditWin.LogicToPixel( Point( nXOff, nOutputYOff ) );
+ rEditWin.AddHeaderFooterControl( aFooterText, false, nOutputOff );
+ }
-void SwPageFrm::PaintDecorators( OutputDevice *pOut ) const
-{
- const SwLayoutFrm* pBody = FindBodyCont();
- if ( pBody )
- {
- SwRect aBodyRect( pBody->Frm() );
+ pProcessor->process( lcl_CreateHeaderFooterSeparatorPrimitives(
+ this, double( aBodyRect.Bottom() ) ) );
- if ( !pGlobalShell->GetViewOptions()->IsPrinting() &&
- !pGlobalShell->GetViewOptions()->IsPDFExport() &&
- !pGlobalShell->IsPreView() &&
- pGlobalShell->IsHeaderFooterEdit( ) )
- {
- const String aStyleName = GetPageDesc()->GetName();
- drawinglayer::processor2d::BaseProcessor2D* pProcessor = CreateProcessor2D();
-
- // Header
- const SwFrm* pHeaderFrm = Lower();
- if ( !pHeaderFrm->IsHeaderFrm() )
- pHeaderFrm = NULL;
-
- double nLabelRight = aBodyRect.Right();
- pProcessor->process( lcl_CreateHeaderFooterSeparatorPrimitives(
- pOut, pProcessor, this, nLabelRight,
- double( aBodyRect.Top() ), true, aStyleName, pHeaderFrm ) );
-
- // Footer
- const SwFrm* pFooterFrm = Lower();
- while ( pFooterFrm->GetNext() )
- pFooterFrm = pFooterFrm->GetNext();
- if ( !pFooterFrm->IsFooterFrm() )
- pFooterFrm = NULL;
-
- pProcessor->process( lcl_CreateHeaderFooterSeparatorPrimitives(
- pOut, pProcessor, this, nLabelRight,
- double( aBodyRect.Bottom() ), false, aStyleName, pFooterFrm ) );
-
- delete pProcessor;
+ delete pProcessor;
+ }
}
}
}
diff --git a/sw/source/ui/app/app.src b/sw/source/ui/app/app.src
index 7736c575c081..ac126a51d9d7 100644
--- a/sw/source/ui/app/app.src
+++ b/sw/source/ui/app/app.src
@@ -412,12 +412,12 @@ String STR_EMPTYPAGE
String STR_HEADER
{
- Text [ en-US ] = "Header: " ;
+ Text [ en-US ] = "Header (%1)" ;
};
String STR_FOOTER
{
- Text [ en-US ] = "Footer: " ;
+ Text [ en-US ] = "Footer (%1)" ;
};
QueryBox MSG_CLPBRD_CLEAR
diff --git a/sw/source/ui/docvw/edtwin.cxx b/sw/source/ui/docvw/edtwin.cxx
index 9be716fa83ba..d83f6932e753 100644
--- a/sw/source/ui/docvw/edtwin.cxx
+++ b/sw/source/ui/docvw/edtwin.cxx
@@ -74,6 +74,8 @@
#include <editeng/postitem.hxx>
#include <editeng/protitem.hxx>
#include <unotools/charclass.hxx>
+#include <basegfx/color/bcolortools.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
#include <editeng/acorrcfg.hxx>
#include <SwSmartTagMgr.hxx>
@@ -5677,4 +5679,104 @@ Selection SwEditWin::GetSurroundingTextSelection() const
}
}
+#define TEXT_PADDING 7
+#define BOX_DISTANCE 10
+
+// the WB_MOVABLE flag is used here to avoid the window to appear on all desktops (on linux)
+// and the WB_OWNERDRAWDECORATION prevents the system to draw the window decorations.
+//
+SwHeaderFooterControl::SwHeaderFooterControl( Window* pParent, const rtl::OUString& sLabel, bool bHeader, Point aOffset, Size aPosOffset ) :
+ FloatingWindow( pParent, WB_SYSTEMWINDOW | WB_NOBORDER | WB_NOSHADOW | WB_MOVEABLE | WB_OWNERDRAWDECORATION ),
+ m_sText( sLabel ),
+ m_bIsHeader( bHeader ),
+ m_aPosOffset( aPosOffset )
+{
+ // 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 ) );
+
+ // Compute the position & size of the window
+ Rectangle aTextRect;
+ GetTextBoundRect( aTextRect, String( sLabel ) );
+ Rectangle aTextPxRect = LogicToPixel( aTextRect );
+
+ Size aParentSize = pParent->GetSizePixel();
+
+ Size aBoxSize ( aTextPxRect.GetWidth() + TEXT_PADDING * 2,
+ aTextPxRect.GetHeight() + TEXT_PADDING * 2 );
+
+ long nYFooterOff = 0;
+ if ( !bHeader )
+ nYFooterOff = aBoxSize.Height();
+
+ Point aBoxPos( m_aPosOffset.Width() + aOffset.X() - aBoxSize.Width() - BOX_DISTANCE,
+ m_aPosOffset.Height() + aOffset.Y() - nYFooterOff );
+
+ // Set the position & Size of the window
+ SetPosSizePixel( aBoxPos, aBoxSize );
+
+ // TODO Add the list_add.png picture
+}
+
+void SwHeaderFooterControl::Paint( const Rectangle& rRect )
+{
+ // Colors
+ basegfx::BColor aLineColor = SwViewOption::GetHeaderFooterMarkColor().getBColor();
+ 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 );
+ basegfx::BColor aFillColor = basegfx::tools::hsl2rgb( aHslLine );
+
+ // Draw the background rect
+ SetFillColor( Color ( aFillColor ) );
+ SetLineColor( Color ( aFillColor ) );
+ DrawRect( rRect );
+
+ // Draw the lines around the rect
+ SetLineColor( Color( aLineColor ) );
+ basegfx::B2DPolygon aPolygon;
+ aPolygon.append( basegfx::B2DPoint( rRect.Left(), rRect.Top() ) );
+ aPolygon.append( basegfx::B2DPoint( rRect.Left(), rRect.Bottom() ) );
+ DrawPolyLine( aPolygon, 1.0 );
+
+ aPolygon.clear();
+ aPolygon.append( basegfx::B2DPoint( rRect.Right(), rRect.Top() ) );
+ aPolygon.append( basegfx::B2DPoint( rRect.Right(), rRect.Bottom() ) );
+ DrawPolyLine( aPolygon, 1.0 );
+
+ long nYLine = rRect.Bottom();
+ if ( !m_bIsHeader )
+ nYLine = rRect.Top();
+ aPolygon.clear();
+ aPolygon.append( basegfx::B2DPoint( rRect.Left(), nYLine ) );
+ aPolygon.append( basegfx::B2DPoint( rRect.Right(), nYLine ) );
+ DrawPolyLine( aPolygon, 1.0 );
+
+
+ // Draw the text
+ SetTextColor( Color( aLineColor ) );
+ DrawText( Point( rRect.Left() + TEXT_PADDING, rRect.Top() + TEXT_PADDING ),
+ String( m_sText ) );
+}
+
+void SwEditWin::AddHeaderFooterControl( const rtl::OUString& sLabel, bool bHeader, Point aOffset )
+{
+ SwHeaderFooterControl::Pointer pNewControl( new SwHeaderFooterControl( this, sLabel, bHeader, aOffset,
+ Size( GetOutOffXPixel(), GetOutOffYPixel() ) ) );
+ pNewControl->Show( );
+ aHeadFootControls.push_back( pNewControl );
+}
+
+void SwEditWin::ClearHeaderFooterControls( )
+{
+ aHeadFootControls.clear();
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/inc/edtwin.hxx b/sw/source/ui/inc/edtwin.hxx
index 547d67883508..7c8c9727f85a 100644
--- a/sw/source/ui/inc/edtwin.hxx
+++ b/sw/source/ui/inc/edtwin.hxx
@@ -32,12 +32,15 @@
#include <tools/link.hxx>
#include <vcl/timer.hxx>
#include <vcl/window.hxx>
+#include <vcl/floatwin.hxx>
#include <svtools/transfer.hxx>
#include <swevent.hxx>
#define _SVSTDARR_STRINGSISORTDTOR
#include <svl/svstdarr.hxx>
+#include <boost/shared_ptr.hpp>
+
class SwWrtShell;
class SwView;
class SwRect;
@@ -57,6 +60,20 @@ class SdrDropMarkerOverlay;
Description: input window
--------------------------------------------------------------------*/
+class SwHeaderFooterControl : public FloatingWindow
+{
+ const rtl::OUString m_sText;
+ bool m_bIsHeader;
+ Size m_aPosOffset;
+
+public:
+ SwHeaderFooterControl( Window* pParent, const rtl::OUString& sLabel, bool bHeader, Point aOffset, Size aOffsetPos );
+
+ virtual void Paint( const Rectangle& rRect );
+
+ typedef boost::shared_ptr< SwHeaderFooterControl > Pointer;
+};
+
class SwEditWin: public Window,
public DropTargetHelper, public DragSourceHelper
{
@@ -146,6 +163,8 @@ friend void PageNumNotify( ViewShell* pVwSh,
sal_uInt16 nKS_NUMDOWN_Count; // #i23725#
sal_uInt16 nKS_NUMINDENTINC_Count;
+ std::vector< SwHeaderFooterControl::Pointer > aHeadFootControls;
+
void LeaveArea(const Point &);
void JustifyAreaTimer();
inline void EnterArea();
@@ -299,6 +318,9 @@ public:
void SetUseInputLanguage( sal_Bool bNew );
sal_Bool IsUseInputLanguage() const { return bUseInputLanguage; }
+ void AddHeaderFooterControl( const rtl::OUString& sLabel, bool bHeader, Point aOffset );
+ void ClearHeaderFooterControls( );
+
SwEditWin(Window *pParent, SwView &);
virtual ~SwEditWin();
};