ddf1b13a52
Change-Id: I4040baa1a0202426df80a0ea94abde55e2b6ca65
834 lines
25 KiB
C++
834 lines
25 KiB
C++
/* -*- 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 "cmdid.h"
|
|
#include "swmodule.hxx"
|
|
#include "view.hxx"
|
|
#include "wrtsh.hxx"
|
|
#include "globals.hrc"
|
|
|
|
#include <vcl/metric.hxx>
|
|
#include <svl/stritem.hxx>
|
|
#include <editeng/fontitem.hxx>
|
|
#include <svx/htmlmode.hxx>
|
|
#include <sfx2/objsh.hxx>
|
|
#include <editeng/svxfont.hxx>
|
|
#include <vcl/print.hxx>
|
|
#include <sfx2/printer.hxx>
|
|
#include <com/sun/star/i18n/ScriptType.hpp>
|
|
#include <editeng/scripttypeitem.hxx>
|
|
#include <com/sun/star/i18n/BreakIterator.hpp>
|
|
#include <comphelper/processfactory.hxx>
|
|
|
|
#include "charatr.hxx"
|
|
#include "viewopt.hxx"
|
|
#include "drpcps.hxx"
|
|
#include "paratr.hxx"
|
|
#include "uitool.hxx"
|
|
#include "charfmt.hxx"
|
|
|
|
#include "chrdlg.hrc"
|
|
#include "drpcps.hrc"
|
|
|
|
|
|
using namespace ::com::sun::star;
|
|
using namespace ::com::sun::star::uno;
|
|
using namespace ::com::sun::star::lang;
|
|
//using namespace i18n; !using this namespace leads to mysterious conflicts with ScriptType::...!
|
|
// so don't use this instead of the following defines!
|
|
|
|
#define I18N ::com::sun::star::i18n
|
|
#define I18N_SCRIPTTYPE ::com::sun::star::i18n::ScriptType
|
|
|
|
// Globals ******************************************************************
|
|
|
|
static sal_uInt16 aPageRg[] = {
|
|
RES_PARATR_DROP, RES_PARATR_DROP,
|
|
0
|
|
};
|
|
|
|
class SwDropCapsPict : public Control
|
|
{
|
|
String maText;
|
|
String maScriptText;
|
|
Color maBackColor;
|
|
Color maTextLineColor;
|
|
sal_uInt8 mnLines;
|
|
long mnTotLineH;
|
|
long mnLineH;
|
|
long mnTextH;
|
|
sal_uInt16 mnDistance;
|
|
sal_Int32 mnLeading;
|
|
Printer* mpPrinter;
|
|
bool mbDelPrinter;
|
|
/// The _ScriptInfo structure holds information on where we change from one
|
|
/// script to another.
|
|
struct _ScriptInfo
|
|
{
|
|
sal_uLong textWidth; ///< Physical width of this segment.
|
|
sal_uInt16 scriptType; ///< Script type (e.g. Latin, Asian, Complex)
|
|
xub_StrLen changePos; ///< Character position where the script changes.
|
|
_ScriptInfo(sal_uLong txtWidth, sal_uInt16 scrptType, xub_StrLen position)
|
|
: textWidth(txtWidth), scriptType(scrptType), changePos(position) {}
|
|
bool operator<(_ScriptInfo other) { return changePos < other.changePos; }
|
|
};
|
|
std::vector<_ScriptInfo> maScriptChanges;
|
|
SvxFont maFont;
|
|
SvxFont maCJKFont;
|
|
SvxFont maCTLFont;
|
|
Size maTextSize;
|
|
Reference< I18N::XBreakIterator > xBreak;
|
|
|
|
virtual void Paint(const Rectangle &rRect);
|
|
void CheckScript( void );
|
|
Size CalcTextSize( void );
|
|
inline void InitPrinter( void );
|
|
void _InitPrinter( void );
|
|
void GetFontSettings( const SwDropCapsPage& _rPage, Font& _rFont, sal_uInt16 _nWhich );
|
|
void GetFirstScriptSegment(xub_StrLen &start, xub_StrLen &end, sal_uInt16 &scriptType);
|
|
bool GetNextScriptSegment(size_t &nIdx, xub_StrLen &start, xub_StrLen &end, sal_uInt16 &scriptType);
|
|
public:
|
|
|
|
SwDropCapsPict(Window *pParent, const ResId &rResId)
|
|
: Control(pParent, rResId)
|
|
, mnTotLineH(0)
|
|
, mnLineH(0)
|
|
, mnTextH(0)
|
|
, mpPrinter( NULL )
|
|
, mbDelPrinter( false )
|
|
{}
|
|
~SwDropCapsPict();
|
|
|
|
void UpdatePaintSettings( void ); // also invalidates control!
|
|
|
|
inline void SetText( const OUString& rT );
|
|
inline void SetLines( sal_uInt8 nL );
|
|
inline void SetDistance( sal_uInt16 nD );
|
|
inline void SetValues( const String& rText, sal_uInt8 nLines, sal_uInt16 nDistance );
|
|
|
|
void DrawPrev( const Point& rPt );
|
|
};
|
|
|
|
inline void SwDropCapsPict::SetText( const OUString& rT )
|
|
{
|
|
maText = rT;
|
|
UpdatePaintSettings();
|
|
}
|
|
|
|
inline void SwDropCapsPict::SetLines( sal_uInt8 nL )
|
|
{
|
|
mnLines = nL;
|
|
UpdatePaintSettings();
|
|
}
|
|
|
|
inline void SwDropCapsPict::SetDistance( sal_uInt16 nD )
|
|
{
|
|
mnDistance = nD;
|
|
UpdatePaintSettings();
|
|
}
|
|
|
|
inline void SwDropCapsPict::SetValues( const String& rText, sal_uInt8 nLines, sal_uInt16 nDistance )
|
|
{
|
|
maText = rText;
|
|
mnLines = nLines;
|
|
mnDistance = nDistance;
|
|
|
|
UpdatePaintSettings();
|
|
}
|
|
|
|
inline void SwDropCapsPict::InitPrinter( void )
|
|
{
|
|
if( !mpPrinter )
|
|
_InitPrinter();
|
|
}
|
|
|
|
/****************************************************************************
|
|
Create Default-String from character-count (A, AB, ABC, ...)
|
|
****************************************************************************/
|
|
|
|
|
|
String GetDefaultString(sal_uInt16 nChars)
|
|
{
|
|
String aStr;
|
|
for (sal_uInt16 i = 0; i < nChars; i++)
|
|
aStr += rtl::OUString((char) (i + 65));
|
|
return aStr;
|
|
}
|
|
|
|
static void calcFontHeightAnyAscent( OutputDevice* _pWin, Font& _rFont, long& _nHeight, long& _nAscent )
|
|
{
|
|
if ( !_nHeight )
|
|
{
|
|
_pWin->SetFont( _rFont );
|
|
FontMetric aMetric( _pWin->GetFontMetric() );
|
|
_nHeight = aMetric.GetLineHeight();
|
|
_nAscent = aMetric.GetAscent();
|
|
}
|
|
}
|
|
|
|
SwDropCapsPict::~SwDropCapsPict()
|
|
{
|
|
if( mbDelPrinter )
|
|
delete mpPrinter;
|
|
}
|
|
|
|
/// Get the details of the first script change.
|
|
/// @param[out] start The character position of the start of the segment.
|
|
/// @param[out] end The character position of the end of the segment.
|
|
/// @param[out] scriptType The script type (Latin, Asian, Complex etc.)
|
|
void SwDropCapsPict::GetFirstScriptSegment(xub_StrLen &start, xub_StrLen &end, sal_uInt16 &scriptType)
|
|
{
|
|
start = 0;
|
|
if( maScriptChanges.empty() )
|
|
{
|
|
end = maText.Len();
|
|
scriptType = I18N_SCRIPTTYPE::LATIN;
|
|
}
|
|
else
|
|
{
|
|
end = maScriptChanges[ 0 ].changePos;
|
|
scriptType = maScriptChanges[ 0 ].scriptType;
|
|
}
|
|
}
|
|
|
|
/// Get the details of the first script change.
|
|
/// @param[in,out] nIdx Index of the current script change.
|
|
/// @param[out] start The character position of the start of the segment.
|
|
/// @param[in,out] end The character position of the end of the segment.
|
|
/// @param[out] scriptType The script type (Latin, Asian, Complex etc.)
|
|
/// @returns True if there was a next segment, false if not.
|
|
bool SwDropCapsPict::GetNextScriptSegment(size_t &nIdx, xub_StrLen &start, xub_StrLen &end, sal_uInt16 &scriptType)
|
|
{
|
|
if (maScriptChanges.empty() || nIdx >= maScriptChanges.size() - 1 || end >= maText.Len())
|
|
return false;
|
|
start = maScriptChanges[nIdx++].changePos;
|
|
end = maScriptChanges[ nIdx ].changePos;
|
|
scriptType = maScriptChanges[ nIdx ].scriptType;
|
|
return true;
|
|
}
|
|
|
|
#define LINES 10
|
|
#define BORDER 2
|
|
|
|
void SwDropCapsPict::GetFontSettings( const SwDropCapsPage& _rPage, Font& _rFont, sal_uInt16 _nWhich )
|
|
{
|
|
SfxItemSet aSet( _rPage.rSh.GetAttrPool(), _nWhich, _nWhich);
|
|
_rPage.rSh.GetCurAttr(aSet);
|
|
SvxFontItem aFmtFont((SvxFontItem &) aSet.Get(_nWhich));
|
|
|
|
_rFont.SetFamily (aFmtFont.GetFamily());
|
|
_rFont.SetName (aFmtFont.GetFamilyName());
|
|
_rFont.SetPitch (aFmtFont.GetPitch());
|
|
_rFont.SetCharSet(aFmtFont.GetCharSet());
|
|
}
|
|
|
|
void SwDropCapsPict::UpdatePaintSettings( void )
|
|
{
|
|
maBackColor = GetSettings().GetStyleSettings().GetWindowColor();
|
|
maTextLineColor = Color( COL_LIGHTGRAY );
|
|
|
|
// gray lines
|
|
mnTotLineH = (GetOutputSizePixel().Height() - 2 * BORDER) / LINES;
|
|
mnLineH = mnTotLineH - 2;
|
|
mnLeading = GetFontMetric().GetIntLeading();
|
|
|
|
Font aFont;
|
|
{
|
|
SwDropCapsPage* pPage = ( SwDropCapsPage* ) GetParent();
|
|
if (!pPage->aTemplateBox.GetSelectEntryPos())
|
|
{
|
|
// query the Font at paragraph's beginning
|
|
pPage->rSh.SttCrsrMove();
|
|
pPage->rSh.Push();
|
|
pPage->rSh.ClearMark();
|
|
SwWhichPara pSwuifnParaCurr = GetfnParaCurr();
|
|
SwPosPara pSwuifnParaStart = GetfnParaStart();
|
|
pPage->rSh.MovePara(pSwuifnParaCurr,pSwuifnParaStart);
|
|
// normal
|
|
GetFontSettings( *pPage, aFont, RES_CHRATR_FONT );
|
|
|
|
// CJK
|
|
GetFontSettings( *pPage, maCJKFont, RES_CHRATR_CJK_FONT );
|
|
|
|
// CTL
|
|
GetFontSettings( *pPage, maCTLFont, RES_CHRATR_CTL_FONT );
|
|
|
|
pPage->rSh.Pop(sal_False);
|
|
pPage->rSh.EndCrsrMove();
|
|
}
|
|
else
|
|
{
|
|
// query Font at character template
|
|
SwCharFmt *pFmt = pPage->rSh.GetCharStyle(
|
|
pPage->aTemplateBox.GetSelectEntry(),
|
|
SwWrtShell::GETSTYLE_CREATEANY );
|
|
OSL_ENSURE(pFmt, "character style doesn't exist!");
|
|
const SvxFontItem &rFmtFont = pFmt->GetFont();
|
|
|
|
aFont.SetFamily (rFmtFont.GetFamily());
|
|
aFont.SetName (rFmtFont.GetFamilyName());
|
|
aFont.SetPitch (rFmtFont.GetPitch());
|
|
aFont.SetCharSet(rFmtFont.GetCharSet());
|
|
}
|
|
}
|
|
|
|
mnTextH = mnLines * mnTotLineH;
|
|
aFont.SetSize(Size(0, mnTextH));
|
|
maCJKFont.SetSize(Size(0, mnTextH));
|
|
maCTLFont.SetSize(Size(0, mnTextH));
|
|
|
|
aFont.SetTransparent(sal_True);
|
|
maCJKFont.SetTransparent(sal_True);
|
|
maCTLFont.SetTransparent(sal_True);
|
|
|
|
aFont.SetColor( SwViewOption::GetFontColor() );
|
|
maCJKFont.SetColor( SwViewOption::GetFontColor() );
|
|
maCTLFont.SetColor( SwViewOption::GetFontColor() );
|
|
|
|
aFont.SetFillColor(GetSettings().GetStyleSettings().GetWindowColor());
|
|
maCJKFont.SetFillColor(GetSettings().GetStyleSettings().GetWindowColor());
|
|
maCTLFont.SetFillColor(GetSettings().GetStyleSettings().GetWindowColor());
|
|
|
|
maCJKFont.SetSize(Size(0, maCJKFont.GetSize().Height() + mnLeading));
|
|
maCTLFont.SetSize(Size(0, maCTLFont.GetSize().Height() + mnLeading));
|
|
|
|
SetFont(aFont);
|
|
aFont.SetSize(Size(0, aFont.GetSize().Height() + mnLeading));
|
|
SetFont(aFont);
|
|
maFont = aFont;
|
|
|
|
CheckScript();
|
|
|
|
maTextSize = CalcTextSize();
|
|
|
|
Invalidate();
|
|
}
|
|
|
|
/****************************************************************************
|
|
Pict: Paint-Overload
|
|
****************************************************************************/
|
|
|
|
void SwDropCapsPict::Paint(const Rectangle &/*rRect*/)
|
|
{
|
|
if (!IsVisible())
|
|
return;
|
|
|
|
SetMapMode(MapMode(MAP_PIXEL));
|
|
SetLineColor();
|
|
|
|
SetFillColor( maBackColor );
|
|
|
|
Size aOutputSizePixel( GetOutputSizePixel() );
|
|
|
|
DrawRect(Rectangle(Point(0, 0), aOutputSizePixel ));
|
|
SetClipRegion(Region(Rectangle(
|
|
Point(BORDER, BORDER),
|
|
Size (aOutputSizePixel.Width () - 2 * BORDER,
|
|
aOutputSizePixel.Height() - 2 * BORDER))));
|
|
|
|
OSL_ENSURE(mnLineH > 0, "We cannot make it that small");
|
|
long nY0 = (aOutputSizePixel.Height() - (LINES * mnTotLineH)) / 2;
|
|
SetFillColor( maTextLineColor );
|
|
for (sal_uInt16 i = 0; i < LINES; ++i)
|
|
DrawRect(Rectangle(Point(BORDER, nY0 + i * mnTotLineH), Size(aOutputSizePixel.Width() - 2 * BORDER, mnLineH)));
|
|
|
|
// Text background with gap (240 twips ~ 1 line height)
|
|
sal_uLong lDistance = mnDistance;
|
|
sal_uInt16 nDistW = (sal_uInt16) (sal_uLong) (((lDistance * 100) / 240) * mnTotLineH) / 100;
|
|
SetFillColor( maBackColor );
|
|
if(((SwDropCapsPage*)GetParent())->aDropCapsBox.IsChecked())
|
|
{
|
|
Size aTextSize( maTextSize );
|
|
aTextSize.Width() += nDistW;
|
|
DrawRect( Rectangle( Point( BORDER, nY0 ), aTextSize ) );
|
|
|
|
// draw Text
|
|
DrawPrev( Point( BORDER, nY0 - mnLeading ) );
|
|
}
|
|
|
|
SetClipRegion();
|
|
}
|
|
|
|
void SwDropCapsPict::DrawPrev( const Point& rPt )
|
|
{
|
|
Point aPt(rPt);
|
|
InitPrinter();
|
|
|
|
Font aOldFont = mpPrinter->GetFont();
|
|
sal_uInt16 nScript;
|
|
size_t nIdx = 0;
|
|
xub_StrLen nStart;
|
|
xub_StrLen nEnd;
|
|
GetFirstScriptSegment(nStart, nEnd, nScript);
|
|
do
|
|
{
|
|
SvxFont& rFnt = (nScript==I18N_SCRIPTTYPE::ASIAN) ? maCJKFont : ((nScript==I18N_SCRIPTTYPE::COMPLEX) ? maCTLFont : maFont);
|
|
mpPrinter->SetFont( rFnt );
|
|
|
|
rFnt.DrawPrev( this, mpPrinter, aPt, maText, nStart, nEnd - nStart );
|
|
|
|
aPt.X() += maScriptChanges[ nIdx ].textWidth;
|
|
if ( !GetNextScriptSegment(nIdx, nStart, nEnd, nScript) )
|
|
break;
|
|
}
|
|
while( true );
|
|
mpPrinter->SetFont( aOldFont );
|
|
}
|
|
|
|
void SwDropCapsPict::CheckScript( void )
|
|
{
|
|
if( maScriptText == maText )
|
|
return;
|
|
|
|
maScriptText = maText;
|
|
maScriptChanges.clear();
|
|
if( !xBreak.is() )
|
|
{
|
|
Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
|
|
xBreak = I18N::BreakIterator::create(xContext);
|
|
}
|
|
sal_uInt16 nScript = xBreak->getScriptType( maText, 0 );
|
|
sal_uInt16 nChg = 0;
|
|
if( I18N_SCRIPTTYPE::WEAK == nScript )
|
|
{
|
|
nChg = (xub_StrLen)xBreak->endOfScript( maText, nChg, nScript );
|
|
if( nChg < maText.Len() )
|
|
nScript = xBreak->getScriptType( maText, nChg );
|
|
else
|
|
nScript = I18N_SCRIPTTYPE::LATIN;
|
|
}
|
|
|
|
do
|
|
{
|
|
nChg = (xub_StrLen)xBreak->endOfScript( maText, nChg, nScript );
|
|
maScriptChanges.push_back( _ScriptInfo(0, nScript, nChg) );
|
|
|
|
if( nChg < maText.Len() )
|
|
nScript = xBreak->getScriptType( maText, nChg );
|
|
else
|
|
break;
|
|
} while( true );
|
|
}
|
|
|
|
Size SwDropCapsPict::CalcTextSize( void )
|
|
{
|
|
InitPrinter();
|
|
|
|
sal_uInt16 nScript;
|
|
size_t nIdx = 0;
|
|
xub_StrLen nStart;
|
|
xub_StrLen nEnd;
|
|
GetFirstScriptSegment(nStart, nEnd, nScript);
|
|
long nTxtWidth = 0;
|
|
long nCJKHeight = 0;
|
|
long nCTLHeight = 0;
|
|
long nHeight = 0;
|
|
long nAscent = 0;
|
|
long nCJKAscent = 0;
|
|
long nCTLAscent = 0;
|
|
do
|
|
{
|
|
SvxFont& rFnt = ( nScript == I18N_SCRIPTTYPE::ASIAN )? maCJKFont :
|
|
( ( nScript == I18N_SCRIPTTYPE::COMPLEX )? maCTLFont : maFont );
|
|
sal_uLong nWidth = rFnt.GetTxtSize( mpPrinter, maText, nStart, nEnd-nStart ).Width();
|
|
|
|
if( nIdx < maScriptChanges.size() )
|
|
maScriptChanges[ nIdx ].textWidth = nWidth;
|
|
nTxtWidth += nWidth;
|
|
switch(nScript)
|
|
{
|
|
case I18N_SCRIPTTYPE::ASIAN:
|
|
calcFontHeightAnyAscent( this, maCJKFont, nCJKHeight, nCJKAscent );
|
|
break;
|
|
case I18N_SCRIPTTYPE::COMPLEX:
|
|
calcFontHeightAnyAscent( this, maCTLFont, nCTLHeight, nCTLAscent );
|
|
break;
|
|
default:
|
|
calcFontHeightAnyAscent( this, maFont, nHeight, nAscent );
|
|
}
|
|
|
|
if ( !GetNextScriptSegment(nIdx, nStart, nEnd, nScript) )
|
|
break;
|
|
}
|
|
while( true );
|
|
nHeight -= nAscent;
|
|
nCJKHeight -= nCJKAscent;
|
|
nCTLHeight -= nCTLAscent;
|
|
if( nHeight < nCJKHeight )
|
|
nHeight = nCJKHeight;
|
|
if( nAscent < nCJKAscent )
|
|
nAscent = nCJKAscent;
|
|
if( nHeight < nCTLHeight )
|
|
nHeight = nCTLHeight;
|
|
if( nAscent < nCTLAscent )
|
|
nAscent = nCTLAscent;
|
|
nHeight += nAscent;
|
|
|
|
Size aTxtSize( nTxtWidth, nHeight );
|
|
return aTxtSize;
|
|
}
|
|
|
|
void SwDropCapsPict::_InitPrinter()
|
|
{
|
|
SfxViewShell* pSh = SfxViewShell::Current();
|
|
|
|
if ( pSh )
|
|
mpPrinter = pSh->GetPrinter();
|
|
|
|
if ( !mpPrinter )
|
|
{
|
|
mpPrinter = new Printer;
|
|
mbDelPrinter = true;
|
|
}
|
|
}
|
|
|
|
SwDropCapsDlg::SwDropCapsDlg(Window *pParent, const SfxItemSet &rSet ) :
|
|
|
|
SfxNoLayoutSingleTabDialog(pParent, rSet, 0)
|
|
|
|
{
|
|
SwDropCapsPage* pNewPage = (SwDropCapsPage*) SwDropCapsPage::Create(this, rSet);
|
|
pNewPage->SetFormat(sal_False);
|
|
SetTabPage(pNewPage);
|
|
}
|
|
|
|
SwDropCapsDlg::~SwDropCapsDlg()
|
|
{
|
|
}
|
|
|
|
SwDropCapsPage::SwDropCapsPage(Window *pParent, const SfxItemSet &rSet) :
|
|
|
|
SfxTabPage(pParent, SW_RES(TP_DROPCAPS), rSet),
|
|
|
|
aSettingsFL (this, SW_RES(FL_SETTINGS)),
|
|
aDropCapsBox (this, SW_RES(CB_SWITCH )),
|
|
aWholeWordCB (this, SW_RES(CB_WORD )),
|
|
aSwitchText (this, SW_RES(FT_DROPCAPS )),
|
|
aDropCapsField(this, SW_RES(FLD_DROPCAPS)),
|
|
aLinesText (this, SW_RES(TXT_LINES )),
|
|
aLinesField (this, SW_RES(FLD_LINES )),
|
|
aDistanceText (this, SW_RES(TXT_DISTANCE)),
|
|
aDistanceField(this, SW_RES(FLD_DISTANCE)),
|
|
|
|
aContentFL (this, SW_RES(FL_CONTENT )),
|
|
aTextText (this, SW_RES(TXT_TEXT )),
|
|
aTextEdit (this, SW_RES(EDT_TEXT )),
|
|
aTemplateText (this, SW_RES(TXT_TEMPLATE)),
|
|
aTemplateBox (this, SW_RES(BOX_TEMPLATE)),
|
|
|
|
pPict (new SwDropCapsPict(this, SW_RES(CNT_PICT))),
|
|
|
|
bModified(sal_False),
|
|
bFormat(sal_True),
|
|
rSh(::GetActiveView()->GetWrtShell())
|
|
{
|
|
FreeResource();
|
|
SetExchangeSupport();
|
|
|
|
sal_uInt16 nHtmlMode = ::GetHtmlMode((const SwDocShell*)SfxObjectShell::Current());
|
|
bHtmlMode = nHtmlMode & HTMLMODE_ON ? sal_True : sal_False;
|
|
|
|
// In the template dialog the text is not influenceable
|
|
aTextText.Enable( !bFormat );
|
|
aTextEdit.Enable( !bFormat );
|
|
|
|
// Metrics
|
|
SetMetric( aDistanceField, GetDfltMetric(bHtmlMode) );
|
|
|
|
pPict->SetBorderStyle( WINDOW_BORDER_MONO );
|
|
|
|
// Install handler
|
|
Link aLk = LINK(this, SwDropCapsPage, ModifyHdl);
|
|
aDropCapsField.SetModifyHdl( aLk );
|
|
aLinesField .SetModifyHdl( aLk );
|
|
aDistanceField.SetModifyHdl( aLk );
|
|
aTextEdit .SetModifyHdl( aLk );
|
|
aDropCapsBox .SetClickHdl (LINK(this, SwDropCapsPage, ClickHdl ));
|
|
aTemplateBox .SetSelectHdl(LINK(this, SwDropCapsPage, SelectHdl));
|
|
aWholeWordCB .SetClickHdl (LINK(this, SwDropCapsPage, WholeWordHdl ));
|
|
}
|
|
|
|
SwDropCapsPage::~SwDropCapsPage()
|
|
{
|
|
delete pPict;
|
|
}
|
|
|
|
int SwDropCapsPage::DeactivatePage(SfxItemSet * _pSet)
|
|
{
|
|
if ( _pSet )
|
|
FillSet( *_pSet );
|
|
|
|
return LEAVE_PAGE;
|
|
}
|
|
|
|
/****************************************************************************
|
|
Page: Factory
|
|
****************************************************************************/
|
|
|
|
SfxTabPage* SwDropCapsPage::Create(Window *pParent,
|
|
const SfxItemSet &rSet)
|
|
{
|
|
return new SwDropCapsPage(pParent, rSet);
|
|
}
|
|
|
|
/****************************************************************************
|
|
Page: FillItemSet-Overload
|
|
****************************************************************************/
|
|
|
|
sal_Bool SwDropCapsPage::FillItemSet(SfxItemSet &rSet)
|
|
{
|
|
if(bModified)
|
|
FillSet(rSet);
|
|
return bModified;
|
|
}
|
|
|
|
/****************************************************************************
|
|
Page: Reset-Overload
|
|
****************************************************************************/
|
|
|
|
void SwDropCapsPage::Reset(const SfxItemSet &rSet)
|
|
{
|
|
// Characters, lines, gap and text
|
|
SwFmtDrop aFmtDrop((SwFmtDrop &) rSet.Get(RES_PARATR_DROP));
|
|
if (aFmtDrop.GetLines() > 1)
|
|
{
|
|
aDropCapsField.SetValue(aFmtDrop.GetChars());
|
|
aLinesField .SetValue(aFmtDrop.GetLines());
|
|
aDistanceField.SetValue(aDistanceField.Normalize(aFmtDrop.GetDistance()), FUNIT_TWIP);
|
|
aWholeWordCB .Check (aFmtDrop.GetWholeWord());
|
|
}
|
|
else
|
|
{
|
|
aDropCapsField.SetValue(1);
|
|
aLinesField .SetValue(3);
|
|
aDistanceField.SetValue(0);
|
|
}
|
|
|
|
::FillCharStyleListBox(aTemplateBox, rSh.GetView().GetDocShell(), true);
|
|
|
|
aTemplateBox.InsertEntry(SW_RESSTR(SW_STR_NONE), 0);
|
|
|
|
// Reset format
|
|
aTemplateBox.SelectEntryPos(0);
|
|
if (aFmtDrop.GetCharFmt())
|
|
aTemplateBox.SelectEntry(aFmtDrop.GetCharFmt()->GetName());
|
|
|
|
// Enable controls
|
|
aDropCapsBox.Check(aFmtDrop.GetLines() > 1);
|
|
const sal_uInt16 nVal = sal_uInt16(aDropCapsField.GetValue());
|
|
if (bFormat)
|
|
aTextEdit.SetText(GetDefaultString(nVal));
|
|
else
|
|
{
|
|
aTextEdit.SetText(rSh.GetDropTxt(nVal));
|
|
aTextEdit.Enable();
|
|
aTextText.Enable();
|
|
}
|
|
|
|
// Preview
|
|
pPict->SetValues( aTextEdit.GetText(),
|
|
sal_uInt8( aLinesField.GetValue() ),
|
|
sal_uInt16( aDistanceField.Denormalize( aDistanceField.GetValue( FUNIT_TWIP ) ) ) );
|
|
|
|
ClickHdl(&aDropCapsBox);
|
|
bModified = sal_False;
|
|
}
|
|
|
|
/****************************************************************************
|
|
Page: CheckBox's Click-Handler
|
|
****************************************************************************/
|
|
|
|
|
|
IMPL_LINK_NOARG(SwDropCapsPage, ClickHdl)
|
|
{
|
|
sal_Bool bChecked = aDropCapsBox.IsChecked();
|
|
|
|
aWholeWordCB .Enable( bChecked && !bHtmlMode );
|
|
|
|
aSwitchText.Enable( bChecked && !aWholeWordCB.IsChecked() );
|
|
aDropCapsField.Enable( bChecked && !aWholeWordCB.IsChecked() );
|
|
aLinesText .Enable( bChecked );
|
|
aLinesField .Enable( bChecked );
|
|
aDistanceText.Enable( bChecked );
|
|
aDistanceField.Enable( bChecked );
|
|
aTemplateText .Enable( bChecked );
|
|
aTemplateBox .Enable( bChecked );
|
|
aTextEdit .Enable( bChecked && !bFormat );
|
|
aTextText .Enable( bChecked && !bFormat );
|
|
|
|
if ( bChecked )
|
|
{
|
|
ModifyHdl(&aDropCapsField);
|
|
aDropCapsField.GrabFocus();
|
|
}
|
|
else
|
|
pPict->SetText(aEmptyStr);
|
|
|
|
bModified = sal_True;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/****************************************************************************
|
|
Page: CheckBox's Click-Handler
|
|
****************************************************************************/
|
|
|
|
|
|
IMPL_LINK_NOARG(SwDropCapsPage, WholeWordHdl)
|
|
{
|
|
aDropCapsField.Enable( !aWholeWordCB.IsChecked() );
|
|
|
|
ModifyHdl(&aDropCapsField);
|
|
|
|
bModified = sal_True;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/****************************************************************************
|
|
Page: SpinFields' Modify-Handler
|
|
****************************************************************************/
|
|
|
|
|
|
IMPL_LINK( SwDropCapsPage, ModifyHdl, Edit *, pEdit )
|
|
{
|
|
String sPreview;
|
|
|
|
// set text if applicable
|
|
if (pEdit == &aDropCapsField)
|
|
{
|
|
sal_uInt16 nVal;
|
|
bool bSetText = false;
|
|
|
|
if (!aWholeWordCB.IsChecked())
|
|
nVal = (sal_uInt16)aDropCapsField.GetValue();
|
|
else
|
|
nVal = 0;
|
|
|
|
if (bFormat || !rSh.GetDropTxt(1).Len())
|
|
sPreview = GetDefaultString(nVal);
|
|
else
|
|
{
|
|
bSetText = true;
|
|
sPreview = rSh.GetDropTxt(nVal);
|
|
}
|
|
|
|
String sEdit(aTextEdit.GetText());
|
|
|
|
if (sEdit.Len() && sPreview.CompareTo(sEdit, sEdit.Len()) != COMPARE_EQUAL)
|
|
{
|
|
sPreview = sEdit.Copy(0, sPreview.Len());
|
|
bSetText = false;
|
|
}
|
|
|
|
if (bSetText)
|
|
aTextEdit.SetText(sPreview);
|
|
}
|
|
else if (pEdit == &aTextEdit) // set quantity if applicable
|
|
{
|
|
sal_Int32 nTmp = aTextEdit.GetText().getLength();
|
|
aDropCapsField.SetValue(Max((sal_uInt16)1, (sal_uInt16)nTmp));
|
|
|
|
sPreview = aTextEdit.GetText().copy(0, nTmp);
|
|
}
|
|
|
|
// adjust image
|
|
if (pEdit == &aDropCapsField || pEdit == &aTextEdit)
|
|
pPict->SetText (sPreview);
|
|
else if (pEdit == &aLinesField)
|
|
pPict->SetLines((sal_uInt8)aLinesField.GetValue());
|
|
else
|
|
pPict->SetDistance((sal_uInt16)aDistanceField.Denormalize(aDistanceField.GetValue(FUNIT_TWIP)));
|
|
|
|
bModified = sal_True;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/****************************************************************************
|
|
Page: Template-Box' Select-Handler.
|
|
*****************************************************************************/
|
|
|
|
|
|
IMPL_LINK_NOARG_INLINE_START(SwDropCapsPage, SelectHdl)
|
|
{
|
|
pPict->UpdatePaintSettings();
|
|
bModified = sal_True;
|
|
return 0;
|
|
}
|
|
IMPL_LINK_NOARG_INLINE_END(SwDropCapsPage, SelectHdl)
|
|
|
|
sal_uInt16* SwDropCapsPage::GetRanges()
|
|
{
|
|
return aPageRg;
|
|
}
|
|
|
|
void SwDropCapsPage::FillSet( SfxItemSet &rSet )
|
|
{
|
|
if(bModified)
|
|
{
|
|
SwFmtDrop aFmt;
|
|
|
|
sal_Bool bOn = aDropCapsBox.IsChecked();
|
|
if(bOn)
|
|
{
|
|
// quantity, lines, gap
|
|
aFmt.GetChars() = (sal_uInt8) aDropCapsField.GetValue();
|
|
aFmt.GetLines() = (sal_uInt8) aLinesField.GetValue();
|
|
aFmt.GetDistance() = (sal_uInt16) aDistanceField.Denormalize(aDistanceField.GetValue(FUNIT_TWIP));
|
|
aFmt.GetWholeWord() = aWholeWordCB.IsChecked();
|
|
|
|
// template
|
|
if (aTemplateBox.GetSelectEntryPos())
|
|
aFmt.SetCharFmt(rSh.GetCharStyle(aTemplateBox.GetSelectEntry()));
|
|
}
|
|
else
|
|
{
|
|
aFmt.GetChars() = 1;
|
|
aFmt.GetLines() = 1;
|
|
aFmt.GetDistance() = 0;
|
|
}
|
|
|
|
// set attributes
|
|
const SfxPoolItem* pOldItem;
|
|
if(0 == (pOldItem = GetOldItem( rSet, FN_FORMAT_DROPCAPS )) ||
|
|
aFmt != *pOldItem )
|
|
rSet.Put(aFmt);
|
|
|
|
// hard text formatting
|
|
// Bug 24974: in designer/template catalog this doesn't make sense!!
|
|
if( !bFormat && aDropCapsBox.IsChecked() )
|
|
{
|
|
String sText(aTextEdit.GetText());
|
|
|
|
if (!aWholeWordCB.IsChecked())
|
|
sText.Erase( static_cast< xub_StrLen >(aDropCapsField.GetValue()));
|
|
|
|
SfxStringItem aStr(FN_PARAM_1, sText);
|
|
rSet.Put( aStr );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|