Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <hintids.hxx>
30 : :
31 : : #include "cmdid.h"
32 : : #include "swmodule.hxx"
33 : : #include "view.hxx"
34 : : #include "wrtsh.hxx"
35 : : #include "globals.hrc"
36 : :
37 : : #include <vcl/metric.hxx>
38 : : #include <svl/stritem.hxx>
39 : : #include <editeng/fontitem.hxx>
40 : : #include <svx/htmlmode.hxx>
41 : : #include <sfx2/objsh.hxx>
42 : : #include <editeng/svxfont.hxx>
43 : : #include <vcl/print.hxx>
44 : : #include <sfx2/printer.hxx>
45 : : #include <com/sun/star/i18n/ScriptType.hpp>
46 : : #include <editeng/scripttypeitem.hxx>
47 : : #include <com/sun/star/i18n/XBreakIterator.hpp>
48 : : #include <comphelper/processfactory.hxx>
49 : :
50 : : #include "charatr.hxx"
51 : : #include "viewopt.hxx"
52 : : #include "drpcps.hxx"
53 : : #include "paratr.hxx"
54 : : #include "uitool.hxx"
55 : : #include "charfmt.hxx"
56 : :
57 : : #include "chrdlg.hrc"
58 : : #include "drpcps.hrc"
59 : :
60 : :
61 : : using namespace ::com::sun::star;
62 : : using namespace ::com::sun::star::uno;
63 : : using namespace ::com::sun::star::lang;
64 : : //using namespace i18n; !using this namespace leads to mysterious conflicts with ScriptType::...!
65 : : // so don't use this instead of the following defines!
66 : :
67 : : #define I18N ::com::sun::star::i18n
68 : : #define I18N_SCRIPTTYPE ::com::sun::star::i18n::ScriptType
69 : :
70 : : // Globals ******************************************************************
71 : :
72 : : static sal_uInt16 aPageRg[] = {
73 : : RES_PARATR_DROP, RES_PARATR_DROP,
74 : : 0
75 : : };
76 : :
77 : : class SwDropCapsPict : public Control
78 : : {
79 : : String maText;
80 : : String maScriptText;
81 : : Color maBackColor;
82 : : Color maTextLineColor;
83 : : sal_uInt8 mnLines;
84 : : long mnTotLineH;
85 : : long mnLineH;
86 : : long mnTextH;
87 : : sal_uInt16 mnDistance;
88 : : sal_Int32 mnLeading;
89 : : Printer* mpPrinter;
90 : : sal_Bool mbDelPrinter;
91 : : /// The _ScriptInfo structure holds information on where we change from one
92 : : /// script to another.
93 : : struct _ScriptInfo
94 : : {
95 : : sal_uLong textWidth; ///< Physical width of this segment.
96 : : sal_uInt16 scriptType; ///< Script type (e.g. Latin, Asian, Complex)
97 : : xub_StrLen changePos; ///< Character position where the script changes.
98 : 0 : _ScriptInfo(sal_uLong txtWidth, sal_uInt16 scrptType, xub_StrLen position)
99 : 0 : : textWidth(txtWidth), scriptType(scrptType), changePos(position) {}
100 : : bool operator<(_ScriptInfo other) { return changePos < other.changePos; }
101 : : };
102 : : std::vector<_ScriptInfo> maScriptChanges;
103 : : SvxFont maFont;
104 : : SvxFont maCJKFont;
105 : : SvxFont maCTLFont;
106 : : Size maTextSize;
107 : : Reference< I18N::XBreakIterator > xBreak;
108 : :
109 : : virtual void Paint(const Rectangle &rRect);
110 : : void CheckScript( void );
111 : : Size CalcTextSize( void );
112 : : inline void InitPrinter( void );
113 : : void _InitPrinter( void );
114 : : void GetFontSettings( const SwDropCapsPage& _rPage, Font& _rFont, sal_uInt16 _nWhich );
115 : : void GetFirstScriptSegment(xub_StrLen &start, xub_StrLen &end, sal_uInt16 &scriptType);
116 : : bool GetNextScriptSegment(size_t &nIdx, xub_StrLen &start, xub_StrLen &end, sal_uInt16 &scriptType);
117 : : public:
118 : :
119 : 0 : SwDropCapsPict(Window *pParent, const ResId &rResId)
120 : : : Control(pParent, rResId)
121 : : , mnTotLineH(0)
122 : : , mnLineH(0)
123 : : , mnTextH(0)
124 : : , mpPrinter( NULL )
125 : 0 : , mbDelPrinter( sal_False )
126 : 0 : {}
127 : : ~SwDropCapsPict();
128 : :
129 : : void UpdatePaintSettings( void ); // also invalidates control!
130 : :
131 : : inline void SetText( const String& rT );
132 : : inline void SetLines( sal_uInt8 nL );
133 : : inline void SetDistance( sal_uInt16 nD );
134 : : inline void SetValues( const String& rText, sal_uInt8 nLines, sal_uInt16 nDistance );
135 : :
136 : : void DrawPrev( const Point& rPt );
137 : : };
138 : :
139 : 0 : inline void SwDropCapsPict::SetText( const String& rT )
140 : : {
141 : 0 : maText = rT;
142 : 0 : UpdatePaintSettings();
143 : 0 : }
144 : :
145 : 0 : inline void SwDropCapsPict::SetLines( sal_uInt8 nL )
146 : : {
147 : 0 : mnLines = nL;
148 : 0 : UpdatePaintSettings();
149 : 0 : }
150 : :
151 : 0 : inline void SwDropCapsPict::SetDistance( sal_uInt16 nD )
152 : : {
153 : 0 : mnDistance = nD;
154 : 0 : UpdatePaintSettings();
155 : 0 : }
156 : :
157 : 0 : inline void SwDropCapsPict::SetValues( const String& rText, sal_uInt8 nLines, sal_uInt16 nDistance )
158 : : {
159 : 0 : maText = rText;
160 : 0 : mnLines = nLines;
161 : 0 : mnDistance = nDistance;
162 : :
163 : 0 : UpdatePaintSettings();
164 : 0 : }
165 : :
166 : 0 : inline void SwDropCapsPict::InitPrinter( void )
167 : : {
168 : 0 : if( !mpPrinter )
169 : 0 : _InitPrinter();
170 : 0 : }
171 : :
172 : : /****************************************************************************
173 : : Create Default-String from character-count (A, AB, ABC, ...)
174 : : ****************************************************************************/
175 : :
176 : :
177 : 0 : String GetDefaultString(sal_uInt16 nChars)
178 : : {
179 : 0 : String aStr;
180 : 0 : for (sal_uInt16 i = 0; i < nChars; i++)
181 : 0 : aStr += rtl::OUString((char) (i + 65));
182 : 0 : return aStr;
183 : : }
184 : :
185 : 0 : static void calcFontHeightAnyAscent( OutputDevice* _pWin, Font& _rFont, long& _nHeight, long& _nAscent )
186 : : {
187 : 0 : if ( !_nHeight )
188 : : {
189 : 0 : _pWin->SetFont( _rFont );
190 : 0 : FontMetric aMetric( _pWin->GetFontMetric() );
191 : 0 : _nHeight = aMetric.GetLineHeight();
192 : 0 : _nAscent = aMetric.GetAscent();
193 : : }
194 : 0 : }
195 : :
196 : 0 : SwDropCapsPict::~SwDropCapsPict()
197 : : {
198 : 0 : if( mbDelPrinter )
199 : 0 : delete mpPrinter;
200 : 0 : }
201 : :
202 : : /// Get the details of the first script change.
203 : : /// @param[out] start The character position of the start of the segment.
204 : : /// @param[out] end The character position of the end of the segment.
205 : : /// @param[out] scriptType The script type (Latin, Asian, Complex etc.)
206 : 0 : void SwDropCapsPict::GetFirstScriptSegment(xub_StrLen &start, xub_StrLen &end, sal_uInt16 &scriptType)
207 : : {
208 : 0 : start = 0;
209 : 0 : if( maScriptChanges.empty() )
210 : : {
211 : 0 : end = maText.Len();
212 : 0 : scriptType = I18N_SCRIPTTYPE::LATIN;
213 : : }
214 : : else
215 : : {
216 : 0 : end = maScriptChanges[ 0 ].changePos;
217 : 0 : scriptType = maScriptChanges[ 0 ].scriptType;
218 : : }
219 : 0 : }
220 : :
221 : : /// Get the details of the first script change.
222 : : /// @param[in,out] nIdx Index of the current script change.
223 : : /// @param[out] start The character position of the start of the segment.
224 : : /// @param[in,out] end The character position of the end of the segment.
225 : : /// @param[out] scriptType The script type (Latin, Asian, Complex etc.)
226 : : /// @returns True if there was a next segment, false if not.
227 : 0 : bool SwDropCapsPict::GetNextScriptSegment(size_t &nIdx, xub_StrLen &start, xub_StrLen &end, sal_uInt16 &scriptType)
228 : : {
229 : 0 : if (maScriptChanges.empty() || nIdx >= maScriptChanges.size() - 1 || end >= maText.Len())
230 : 0 : return false;
231 : 0 : start = maScriptChanges[nIdx++].changePos;
232 : 0 : end = maScriptChanges[ nIdx ].changePos;
233 : 0 : scriptType = maScriptChanges[ nIdx ].scriptType;
234 : 0 : return true;
235 : : }
236 : :
237 : : #define LINES 10
238 : : #define BORDER 2
239 : :
240 : 0 : void SwDropCapsPict::GetFontSettings( const SwDropCapsPage& _rPage, Font& _rFont, sal_uInt16 _nWhich )
241 : : {
242 : 0 : SfxItemSet aSet( _rPage.rSh.GetAttrPool(), _nWhich, _nWhich);
243 : 0 : _rPage.rSh.GetCurAttr(aSet);
244 : 0 : SvxFontItem aFmtFont((SvxFontItem &) aSet.Get(_nWhich));
245 : :
246 : 0 : _rFont.SetFamily (aFmtFont.GetFamily());
247 : 0 : _rFont.SetName (aFmtFont.GetFamilyName());
248 : 0 : _rFont.SetPitch (aFmtFont.GetPitch());
249 : 0 : _rFont.SetCharSet(aFmtFont.GetCharSet());
250 : 0 : }
251 : :
252 : 0 : void SwDropCapsPict::UpdatePaintSettings( void )
253 : : {
254 : 0 : maBackColor = GetSettings().GetStyleSettings().GetWindowColor();
255 : 0 : maTextLineColor = Color( COL_LIGHTGRAY );
256 : :
257 : : // gray lines
258 : 0 : mnTotLineH = (GetOutputSizePixel().Height() - 2 * BORDER) / LINES;
259 : 0 : mnLineH = mnTotLineH - 2;
260 : 0 : mnLeading = GetFontMetric().GetIntLeading();
261 : :
262 : 0 : Font aFont;
263 : : {
264 : 0 : SwDropCapsPage* pPage = ( SwDropCapsPage* ) GetParent();
265 : 0 : if (!pPage->aTemplateBox.GetSelectEntryPos())
266 : : {
267 : : // query the Font at paragraph's beginning
268 : 0 : pPage->rSh.SttCrsrMove();
269 : 0 : pPage->rSh.Push();
270 : 0 : pPage->rSh.ClearMark();
271 : 0 : SwWhichPara pSwuifnParaCurr = GetfnParaCurr();
272 : 0 : SwPosPara pSwuifnParaStart = GetfnParaStart();
273 : 0 : pPage->rSh.MovePara(pSwuifnParaCurr,pSwuifnParaStart);
274 : : // normal
275 : 0 : GetFontSettings( *pPage, aFont, RES_CHRATR_FONT );
276 : :
277 : : // CJK
278 : 0 : GetFontSettings( *pPage, maCJKFont, RES_CHRATR_CJK_FONT );
279 : :
280 : : // CTL
281 : 0 : GetFontSettings( *pPage, maCTLFont, RES_CHRATR_CTL_FONT );
282 : :
283 : 0 : pPage->rSh.Pop(sal_False);
284 : 0 : pPage->rSh.EndCrsrMove();
285 : : }
286 : : else
287 : : {
288 : : // query Font at character template
289 : : SwCharFmt *pFmt = pPage->rSh.GetCharStyle(
290 : : pPage->aTemplateBox.GetSelectEntry(),
291 : 0 : SwWrtShell::GETSTYLE_CREATEANY );
292 : : OSL_ENSURE(pFmt, "character style doesn't exist!");
293 : 0 : const SvxFontItem &rFmtFont = pFmt->GetFont();
294 : :
295 : 0 : aFont.SetFamily (rFmtFont.GetFamily());
296 : 0 : aFont.SetName (rFmtFont.GetFamilyName());
297 : 0 : aFont.SetPitch (rFmtFont.GetPitch());
298 : 0 : aFont.SetCharSet(rFmtFont.GetCharSet());
299 : : }
300 : : }
301 : :
302 : 0 : mnTextH = mnLines * mnTotLineH;
303 : 0 : aFont.SetSize(Size(0, mnTextH));
304 : 0 : maCJKFont.SetSize(Size(0, mnTextH));
305 : 0 : maCTLFont.SetSize(Size(0, mnTextH));
306 : :
307 : 0 : aFont.SetTransparent(sal_True);
308 : 0 : maCJKFont.SetTransparent(sal_True);
309 : 0 : maCTLFont.SetTransparent(sal_True);
310 : :
311 : 0 : aFont.SetColor( SwViewOption::GetFontColor() );
312 : 0 : maCJKFont.SetColor( SwViewOption::GetFontColor() );
313 : 0 : maCTLFont.SetColor( SwViewOption::GetFontColor() );
314 : :
315 : 0 : aFont.SetFillColor(GetSettings().GetStyleSettings().GetWindowColor());
316 : 0 : maCJKFont.SetFillColor(GetSettings().GetStyleSettings().GetWindowColor());
317 : 0 : maCTLFont.SetFillColor(GetSettings().GetStyleSettings().GetWindowColor());
318 : :
319 : 0 : maCJKFont.SetSize(Size(0, maCJKFont.GetSize().Height() + mnLeading));
320 : 0 : maCTLFont.SetSize(Size(0, maCTLFont.GetSize().Height() + mnLeading));
321 : :
322 : 0 : SetFont(aFont);
323 : 0 : aFont.SetSize(Size(0, aFont.GetSize().Height() + mnLeading));
324 : 0 : SetFont(aFont);
325 : 0 : maFont = aFont;
326 : :
327 : 0 : CheckScript();
328 : :
329 : 0 : maTextSize = CalcTextSize();
330 : :
331 : 0 : Invalidate();
332 : 0 : }
333 : :
334 : : /****************************************************************************
335 : : Pict: Paint-Overload
336 : : ****************************************************************************/
337 : :
338 : 0 : void SwDropCapsPict::Paint(const Rectangle &/*rRect*/)
339 : : {
340 : 0 : if (!IsVisible())
341 : 0 : return;
342 : :
343 : 0 : SetMapMode(MapMode(MAP_PIXEL));
344 : 0 : SetLineColor();
345 : :
346 : 0 : SetFillColor( maBackColor );
347 : :
348 : 0 : Size aOutputSizePixel( GetOutputSizePixel() );
349 : :
350 : 0 : DrawRect(Rectangle(Point(0, 0), aOutputSizePixel ));
351 : : SetClipRegion(Region(Rectangle(
352 : : Point(BORDER, BORDER),
353 : 0 : Size (aOutputSizePixel.Width () - 2 * BORDER,
354 : 0 : aOutputSizePixel.Height() - 2 * BORDER))));
355 : :
356 : : OSL_ENSURE(mnLineH > 0, "We cannot make it that small");
357 : 0 : long nY0 = (aOutputSizePixel.Height() - (LINES * mnTotLineH)) / 2;
358 : 0 : SetFillColor( maTextLineColor );
359 : 0 : for (sal_uInt16 i = 0; i < LINES; ++i)
360 : 0 : DrawRect(Rectangle(Point(BORDER, nY0 + i * mnTotLineH), Size(aOutputSizePixel.Width() - 2 * BORDER, mnLineH)));
361 : :
362 : : // Text background with gap (240 twips ~ 1 line height)
363 : 0 : sal_uLong lDistance = mnDistance;
364 : 0 : sal_uInt16 nDistW = (sal_uInt16) (sal_uLong) (((lDistance * 100) / 240) * mnTotLineH) / 100;
365 : 0 : SetFillColor( maBackColor );
366 : 0 : if(((SwDropCapsPage*)GetParent())->aDropCapsBox.IsChecked())
367 : : {
368 : 0 : Size aTextSize( maTextSize );
369 : 0 : aTextSize.Width() += nDistW;
370 : 0 : DrawRect( Rectangle( Point( BORDER, nY0 ), aTextSize ) );
371 : :
372 : : // draw Text
373 : 0 : DrawPrev( Point( BORDER, nY0 - mnLeading ) );
374 : : }
375 : :
376 : 0 : SetClipRegion();
377 : : }
378 : :
379 : 0 : void SwDropCapsPict::DrawPrev( const Point& rPt )
380 : : {
381 : 0 : Point aPt(rPt);
382 : 0 : InitPrinter();
383 : :
384 : 0 : Font aOldFont = mpPrinter->GetFont();
385 : : sal_uInt16 nScript;
386 : 0 : size_t nIdx = 0;
387 : : xub_StrLen nStart;
388 : : xub_StrLen nEnd;
389 : 0 : GetFirstScriptSegment(nStart, nEnd, nScript);
390 : 0 : do
391 : : {
392 : 0 : SvxFont& rFnt = (nScript==I18N_SCRIPTTYPE::ASIAN) ? maCJKFont : ((nScript==I18N_SCRIPTTYPE::COMPLEX) ? maCTLFont : maFont);
393 : 0 : mpPrinter->SetFont( rFnt );
394 : :
395 : 0 : rFnt.DrawPrev( this, mpPrinter, aPt, maText, nStart, nEnd - nStart );
396 : :
397 : 0 : aPt.X() += maScriptChanges[ nIdx ].textWidth;
398 : 0 : if ( !GetNextScriptSegment(nIdx, nStart, nEnd, nScript) )
399 : 0 : break;
400 : : }
401 : : while( sal_True );
402 : 0 : mpPrinter->SetFont( aOldFont );
403 : 0 : }
404 : :
405 : 0 : void SwDropCapsPict::CheckScript( void )
406 : : {
407 : 0 : if( maScriptText == maText )
408 : 0 : return;
409 : :
410 : 0 : maScriptText = maText;
411 : 0 : maScriptChanges.clear();
412 : 0 : if( !xBreak.is() )
413 : : {
414 : 0 : Reference< XMultiServiceFactory > xMSF = ::comphelper::getProcessServiceFactory();
415 : 0 : xBreak = Reference< I18N::XBreakIterator >(xMSF->createInstance(
416 : 0 : ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.i18n.BreakIterator")) ),UNO_QUERY);
417 : : }
418 : 0 : if( xBreak.is() )
419 : : {
420 : 0 : sal_uInt16 nScript = xBreak->getScriptType( maText, 0 );
421 : 0 : sal_uInt16 nChg = 0;
422 : 0 : if( I18N_SCRIPTTYPE::WEAK == nScript )
423 : : {
424 : 0 : nChg = (xub_StrLen)xBreak->endOfScript( maText, nChg, nScript );
425 : 0 : if( nChg < maText.Len() )
426 : 0 : nScript = xBreak->getScriptType( maText, nChg );
427 : : else
428 : 0 : nScript = I18N_SCRIPTTYPE::LATIN;
429 : : }
430 : :
431 : 0 : do
432 : : {
433 : 0 : nChg = (xub_StrLen)xBreak->endOfScript( maText, nChg, nScript );
434 : 0 : maScriptChanges.push_back( _ScriptInfo(0, nScript, nChg) );
435 : :
436 : 0 : if( nChg < maText.Len() )
437 : 0 : nScript = xBreak->getScriptType( maText, nChg );
438 : : else
439 : 0 : break;
440 : : } while( sal_True );
441 : : }
442 : : }
443 : :
444 : 0 : Size SwDropCapsPict::CalcTextSize( void )
445 : : {
446 : 0 : InitPrinter();
447 : :
448 : : sal_uInt16 nScript;
449 : 0 : size_t nIdx = 0;
450 : : xub_StrLen nStart;
451 : : xub_StrLen nEnd;
452 : 0 : GetFirstScriptSegment(nStart, nEnd, nScript);
453 : 0 : long nTxtWidth = 0;
454 : 0 : long nCJKHeight = 0;
455 : 0 : long nCTLHeight = 0;
456 : 0 : long nHeight = 0;
457 : 0 : long nAscent = 0;
458 : 0 : long nCJKAscent = 0;
459 : 0 : long nCTLAscent = 0;
460 : 0 : do
461 : : {
462 : : SvxFont& rFnt = ( nScript == I18N_SCRIPTTYPE::ASIAN )? maCJKFont :
463 : 0 : ( ( nScript == I18N_SCRIPTTYPE::COMPLEX )? maCTLFont : maFont );
464 : 0 : sal_uLong nWidth = rFnt.GetTxtSize( mpPrinter, maText, nStart, nEnd-nStart ).Width();
465 : :
466 : 0 : if( nIdx < maScriptChanges.size() )
467 : 0 : maScriptChanges[ nIdx ].textWidth = nWidth;
468 : 0 : nTxtWidth += nWidth;
469 : 0 : switch(nScript)
470 : : {
471 : : case I18N_SCRIPTTYPE::ASIAN:
472 : 0 : calcFontHeightAnyAscent( this, maCJKFont, nCJKHeight, nCJKAscent );
473 : 0 : break;
474 : : case I18N_SCRIPTTYPE::COMPLEX:
475 : 0 : calcFontHeightAnyAscent( this, maCTLFont, nCTLHeight, nCTLAscent );
476 : 0 : break;
477 : : default:
478 : 0 : calcFontHeightAnyAscent( this, maFont, nHeight, nAscent );
479 : : }
480 : :
481 : 0 : if ( !GetNextScriptSegment(nIdx, nStart, nEnd, nScript) )
482 : 0 : break;
483 : : }
484 : : while( sal_True );
485 : 0 : nHeight -= nAscent;
486 : 0 : nCJKHeight -= nCJKAscent;
487 : 0 : nCTLHeight -= nCTLAscent;
488 : 0 : if( nHeight < nCJKHeight )
489 : 0 : nHeight = nCJKHeight;
490 : 0 : if( nAscent < nCJKAscent )
491 : 0 : nAscent = nCJKAscent;
492 : 0 : if( nHeight < nCTLHeight )
493 : 0 : nHeight = nCTLHeight;
494 : 0 : if( nAscent < nCTLAscent )
495 : 0 : nAscent = nCTLAscent;
496 : 0 : nHeight += nAscent;
497 : :
498 : 0 : Size aTxtSize( nTxtWidth, nHeight );
499 : 0 : return aTxtSize;
500 : : }
501 : :
502 : 0 : void SwDropCapsPict::_InitPrinter()
503 : : {
504 : 0 : SfxViewShell* pSh = SfxViewShell::Current();
505 : :
506 : 0 : if ( pSh )
507 : 0 : mpPrinter = pSh->GetPrinter();
508 : :
509 : 0 : if ( !mpPrinter )
510 : : {
511 : 0 : mpPrinter = new Printer;
512 : 0 : mbDelPrinter = sal_True;
513 : : }
514 : 0 : }
515 : :
516 : 0 : SwDropCapsDlg::SwDropCapsDlg(Window *pParent, const SfxItemSet &rSet ) :
517 : :
518 : 0 : SfxSingleTabDialog(pParent, rSet, 0)
519 : :
520 : : {
521 : 0 : SwDropCapsPage* pNewPage = (SwDropCapsPage*) SwDropCapsPage::Create(this, rSet);
522 : 0 : pNewPage->SetFormat(sal_False);
523 : 0 : SetTabPage(pNewPage);
524 : 0 : }
525 : :
526 : 0 : SwDropCapsDlg::~SwDropCapsDlg()
527 : : {
528 : 0 : }
529 : :
530 : 0 : SwDropCapsPage::SwDropCapsPage(Window *pParent, const SfxItemSet &rSet) :
531 : :
532 : : SfxTabPage(pParent, SW_RES(TP_DROPCAPS), rSet),
533 : :
534 : : aSettingsFL (this, SW_RES(FL_SETTINGS)),
535 : : aDropCapsBox (this, SW_RES(CB_SWITCH )),
536 : : aWholeWordCB (this, SW_RES(CB_WORD )),
537 : : aSwitchText (this, SW_RES(FT_DROPCAPS )),
538 : : aDropCapsField(this, SW_RES(FLD_DROPCAPS)),
539 : : aLinesText (this, SW_RES(TXT_LINES )),
540 : : aLinesField (this, SW_RES(FLD_LINES )),
541 : : aDistanceText (this, SW_RES(TXT_DISTANCE)),
542 : : aDistanceField(this, SW_RES(FLD_DISTANCE)),
543 : :
544 : : aContentFL (this, SW_RES(FL_CONTENT )),
545 : : aTextText (this, SW_RES(TXT_TEXT )),
546 : : aTextEdit (this, SW_RES(EDT_TEXT )),
547 : : aTemplateText (this, SW_RES(TXT_TEMPLATE)),
548 : : aTemplateBox (this, SW_RES(BOX_TEMPLATE)),
549 : :
550 : 0 : pPict (new SwDropCapsPict(this, SW_RES(CNT_PICT))),
551 : :
552 : : bModified(sal_False),
553 : : bFormat(sal_True),
554 : 0 : rSh(::GetActiveView()->GetWrtShell())
555 : : {
556 : 0 : FreeResource();
557 : 0 : SetExchangeSupport();
558 : :
559 : 0 : sal_uInt16 nHtmlMode = ::GetHtmlMode((const SwDocShell*)SfxObjectShell::Current());
560 : 0 : bHtmlMode = nHtmlMode & HTMLMODE_ON ? sal_True : sal_False;
561 : :
562 : : // In the template dialog the text is not influenceable
563 : 0 : aTextText.Enable( !bFormat );
564 : 0 : aTextEdit.Enable( !bFormat );
565 : :
566 : : // Metrics
567 : 0 : SetMetric( aDistanceField, GetDfltMetric(bHtmlMode) );
568 : :
569 : 0 : pPict->SetBorderStyle( WINDOW_BORDER_MONO );
570 : :
571 : : // Install handler
572 : 0 : Link aLk = LINK(this, SwDropCapsPage, ModifyHdl);
573 : 0 : aDropCapsField.SetModifyHdl( aLk );
574 : 0 : aLinesField .SetModifyHdl( aLk );
575 : 0 : aDistanceField.SetModifyHdl( aLk );
576 : 0 : aTextEdit .SetModifyHdl( aLk );
577 : 0 : aDropCapsBox .SetClickHdl (LINK(this, SwDropCapsPage, ClickHdl ));
578 : 0 : aTemplateBox .SetSelectHdl(LINK(this, SwDropCapsPage, SelectHdl));
579 : 0 : aWholeWordCB .SetClickHdl (LINK(this, SwDropCapsPage, WholeWordHdl ));
580 : 0 : }
581 : :
582 : 0 : SwDropCapsPage::~SwDropCapsPage()
583 : : {
584 : 0 : delete pPict;
585 : 0 : }
586 : :
587 : 0 : int SwDropCapsPage::DeactivatePage(SfxItemSet * _pSet)
588 : : {
589 : 0 : if ( _pSet )
590 : 0 : FillSet( *_pSet );
591 : :
592 : 0 : return LEAVE_PAGE;
593 : : }
594 : :
595 : : /****************************************************************************
596 : : Page: Factory
597 : : ****************************************************************************/
598 : :
599 : 0 : SfxTabPage* SwDropCapsPage::Create(Window *pParent,
600 : : const SfxItemSet &rSet)
601 : : {
602 : 0 : return new SwDropCapsPage(pParent, rSet);
603 : : }
604 : :
605 : : /****************************************************************************
606 : : Page: FillItemSet-Overload
607 : : ****************************************************************************/
608 : :
609 : 0 : sal_Bool SwDropCapsPage::FillItemSet(SfxItemSet &rSet)
610 : : {
611 : 0 : if(bModified)
612 : 0 : FillSet(rSet);
613 : 0 : return bModified;
614 : : }
615 : :
616 : : /****************************************************************************
617 : : Page: Reset-Overload
618 : : ****************************************************************************/
619 : :
620 : 0 : void SwDropCapsPage::Reset(const SfxItemSet &rSet)
621 : : {
622 : : // Characters, lines, gap and text
623 : 0 : SwFmtDrop aFmtDrop((SwFmtDrop &) rSet.Get(RES_PARATR_DROP));
624 : 0 : if (aFmtDrop.GetLines() > 1)
625 : : {
626 : 0 : aDropCapsField.SetValue(aFmtDrop.GetChars());
627 : 0 : aLinesField .SetValue(aFmtDrop.GetLines());
628 : 0 : aDistanceField.SetValue(aDistanceField.Normalize(aFmtDrop.GetDistance()), FUNIT_TWIP);
629 : 0 : aWholeWordCB .Check (aFmtDrop.GetWholeWord());
630 : : }
631 : : else
632 : : {
633 : 0 : aDropCapsField.SetValue(1);
634 : 0 : aLinesField .SetValue(3);
635 : 0 : aDistanceField.SetValue(0);
636 : : }
637 : :
638 : 0 : ::FillCharStyleListBox(aTemplateBox, rSh.GetView().GetDocShell(), sal_True);
639 : :
640 : 0 : aTemplateBox.InsertEntry(SW_RESSTR(SW_STR_NONE), 0);
641 : :
642 : : // Reset format
643 : 0 : aTemplateBox.SelectEntryPos(0);
644 : 0 : if (aFmtDrop.GetCharFmt())
645 : 0 : aTemplateBox.SelectEntry(aFmtDrop.GetCharFmt()->GetName());
646 : :
647 : : // Enable controls
648 : 0 : aDropCapsBox.Check(aFmtDrop.GetLines() > 1);
649 : 0 : const sal_uInt16 nVal = sal_uInt16(aDropCapsField.GetValue());
650 : 0 : if (bFormat)
651 : 0 : aTextEdit.SetText(GetDefaultString(nVal));
652 : : else
653 : : {
654 : 0 : aTextEdit.SetText(rSh.GetDropTxt(nVal));
655 : 0 : aTextEdit.Enable();
656 : 0 : aTextText.Enable();
657 : : }
658 : :
659 : : // Preview
660 : : pPict->SetValues( aTextEdit.GetText(),
661 : 0 : sal_uInt8( aLinesField.GetValue() ),
662 : 0 : sal_uInt16( aDistanceField.Denormalize( aDistanceField.GetValue( FUNIT_TWIP ) ) ) );
663 : :
664 : 0 : ClickHdl(&aDropCapsBox);
665 : 0 : bModified = sal_False;
666 : 0 : }
667 : :
668 : : /****************************************************************************
669 : : Page: CheckBox's Click-Handler
670 : : ****************************************************************************/
671 : :
672 : :
673 : 0 : IMPL_LINK_NOARG(SwDropCapsPage, ClickHdl)
674 : : {
675 : 0 : sal_Bool bChecked = aDropCapsBox.IsChecked();
676 : :
677 : 0 : aWholeWordCB .Enable( bChecked && !bHtmlMode );
678 : :
679 : 0 : aSwitchText.Enable( bChecked && !aWholeWordCB.IsChecked() );
680 : 0 : aDropCapsField.Enable( bChecked && !aWholeWordCB.IsChecked() );
681 : 0 : aLinesText .Enable( bChecked );
682 : 0 : aLinesField .Enable( bChecked );
683 : 0 : aDistanceText.Enable( bChecked );
684 : 0 : aDistanceField.Enable( bChecked );
685 : 0 : aTemplateText .Enable( bChecked );
686 : 0 : aTemplateBox .Enable( bChecked );
687 : 0 : aTextEdit .Enable( bChecked && !bFormat );
688 : 0 : aTextText .Enable( bChecked && !bFormat );
689 : :
690 : 0 : if ( bChecked )
691 : : {
692 : 0 : ModifyHdl(&aDropCapsField);
693 : 0 : aDropCapsField.GrabFocus();
694 : : }
695 : : else
696 : 0 : pPict->SetText(aEmptyStr);
697 : :
698 : 0 : bModified = sal_True;
699 : :
700 : 0 : return 0;
701 : : }
702 : :
703 : : /****************************************************************************
704 : : Page: CheckBox's Click-Handler
705 : : ****************************************************************************/
706 : :
707 : :
708 : 0 : IMPL_LINK_NOARG(SwDropCapsPage, WholeWordHdl)
709 : : {
710 : 0 : aDropCapsField.Enable( !aWholeWordCB.IsChecked() );
711 : :
712 : 0 : ModifyHdl(&aDropCapsField);
713 : :
714 : 0 : bModified = sal_True;
715 : :
716 : 0 : return 0;
717 : : }
718 : :
719 : : /****************************************************************************
720 : : Page: SpinFields' Modify-Handler
721 : : ****************************************************************************/
722 : :
723 : :
724 : 0 : IMPL_LINK( SwDropCapsPage, ModifyHdl, Edit *, pEdit )
725 : : {
726 : 0 : String sPreview;
727 : :
728 : : // set text if applicable
729 : 0 : if (pEdit == &aDropCapsField)
730 : : {
731 : : sal_uInt16 nVal;
732 : 0 : sal_Bool bSetText = sal_False;
733 : :
734 : 0 : if (!aWholeWordCB.IsChecked())
735 : 0 : nVal = (sal_uInt16)aDropCapsField.GetValue();
736 : : else
737 : 0 : nVal = 0;
738 : :
739 : 0 : if (bFormat || !rSh.GetDropTxt(1).Len())
740 : 0 : sPreview = GetDefaultString(nVal);
741 : : else
742 : : {
743 : 0 : bSetText = sal_True;
744 : 0 : sPreview = rSh.GetDropTxt(nVal);
745 : : }
746 : :
747 : 0 : String sEdit(aTextEdit.GetText());
748 : :
749 : 0 : if (sEdit.Len() && sPreview.CompareTo(sEdit, sEdit.Len()) != COMPARE_EQUAL)
750 : : {
751 : 0 : sPreview = sEdit.Copy(0, sPreview.Len());
752 : 0 : bSetText = sal_False;
753 : : }
754 : :
755 : 0 : if (bSetText)
756 : 0 : aTextEdit.SetText(sPreview);
757 : : }
758 : 0 : else if (pEdit == &aTextEdit) // set quantity if applicable
759 : : {
760 : 0 : sal_uInt16 nTmp = aTextEdit.GetText().Len();
761 : 0 : aDropCapsField.SetValue(Max((sal_uInt16)1, nTmp));
762 : :
763 : 0 : sPreview = aTextEdit.GetText().Copy(0, nTmp);
764 : : }
765 : :
766 : : // adjust image
767 : 0 : if (pEdit == &aDropCapsField || pEdit == &aTextEdit)
768 : 0 : pPict->SetText (sPreview);
769 : 0 : else if (pEdit == &aLinesField)
770 : 0 : pPict->SetLines((sal_uInt8)aLinesField.GetValue());
771 : : else
772 : 0 : pPict->SetDistance((sal_uInt16)aDistanceField.Denormalize(aDistanceField.GetValue(FUNIT_TWIP)));
773 : :
774 : 0 : bModified = sal_True;
775 : :
776 : 0 : return 0;
777 : : }
778 : :
779 : : /****************************************************************************
780 : : Page: Template-Box' Select-Handler.
781 : : *****************************************************************************/
782 : :
783 : :
784 : 0 : IMPL_LINK_NOARG_INLINE_START(SwDropCapsPage, SelectHdl)
785 : : {
786 : 0 : pPict->UpdatePaintSettings();
787 : 0 : bModified = sal_True;
788 : 0 : return 0;
789 : : }
790 : 0 : IMPL_LINK_NOARG_INLINE_END(SwDropCapsPage, SelectHdl)
791 : :
792 : 0 : sal_uInt16* SwDropCapsPage::GetRanges()
793 : : {
794 : 0 : return aPageRg;
795 : : }
796 : :
797 : 0 : void SwDropCapsPage::FillSet( SfxItemSet &rSet )
798 : : {
799 : 0 : if(bModified)
800 : : {
801 : 0 : SwFmtDrop aFmt;
802 : :
803 : 0 : sal_Bool bOn = aDropCapsBox.IsChecked();
804 : 0 : if(bOn)
805 : : {
806 : : // quantity, lines, gap
807 : 0 : aFmt.GetChars() = (sal_uInt8) aDropCapsField.GetValue();
808 : 0 : aFmt.GetLines() = (sal_uInt8) aLinesField.GetValue();
809 : 0 : aFmt.GetDistance() = (sal_uInt16) aDistanceField.Denormalize(aDistanceField.GetValue(FUNIT_TWIP));
810 : 0 : aFmt.GetWholeWord() = aWholeWordCB.IsChecked();
811 : :
812 : : // template
813 : 0 : if (aTemplateBox.GetSelectEntryPos())
814 : 0 : aFmt.SetCharFmt(rSh.GetCharStyle(aTemplateBox.GetSelectEntry()));
815 : : }
816 : : else
817 : : {
818 : 0 : aFmt.GetChars() = 1;
819 : 0 : aFmt.GetLines() = 1;
820 : 0 : aFmt.GetDistance() = 0;
821 : : }
822 : :
823 : : // set attributes
824 : : const SfxPoolItem* pOldItem;
825 : 0 : if(0 == (pOldItem = GetOldItem( rSet, FN_FORMAT_DROPCAPS )) ||
826 : 0 : aFmt != *pOldItem )
827 : 0 : rSet.Put(aFmt);
828 : :
829 : : // hard text formatting
830 : : // Bug 24974: in designer/template catalog this doesn't make sense!!
831 : 0 : if( !bFormat && aDropCapsBox.IsChecked() )
832 : : {
833 : 0 : String sText(aTextEdit.GetText());
834 : :
835 : 0 : if (!aWholeWordCB.IsChecked())
836 : 0 : sText.Erase( static_cast< xub_StrLen >(aDropCapsField.GetValue()));
837 : :
838 : 0 : SfxStringItem aStr(FN_PARAM_1, sText);
839 : 0 : rSet.Put( aStr );
840 : 0 : }
841 : : }
842 : 0 : }
843 : :
844 : :
845 : :
846 : :
847 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|