1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <svx/dialmgr.hxx>
21 #include <svx/dialogs.hrc>
22 #include <tools/shl.hxx>
23 #include <i18nlangtag/mslangid.hxx>
24 #include <svtools/valueset.hxx>
25 #include <svl/languageoptions.hxx>
27 #include <editeng/numitem.hxx>
28 #include <svl/eitem.hxx>
29 #include <vcl/svapp.hxx>
30 #include <svx/gallery.hxx>
31 #include <svl/urihelper.hxx>
32 #include <editeng/brushitem.hxx>
33 #include <svl/intitem.hxx>
34 #include <sfx2/objsh.hxx>
35 #include <vcl/graph.hxx>
36 #include <vcl/msgbox.hxx>
37 #include <editeng/flstitem.hxx>
38 #include <svx/dlgutil.hxx>
39 #include <svx/xtable.hxx>
40 #include <svx/drawitem.hxx>
41 #include <svx/numvset.hxx>
42 #include <sfx2/htmlmode.hxx>
43 #include <unotools/pathoptions.hxx>
44 #include <svtools/ctrltool.hxx>
45 #include <editeng/unolingu.hxx>
46 #include <com/sun/star/style/NumberingType.hpp>
47 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
48 #include <com/sun/star/container/XIndexAccess.hpp>
49 #include <com/sun/star/text/XDefaultNumberingProvider.hpp>
50 #include <com/sun/star/text/XNumberingFormatter.hpp>
51 #include <com/sun/star/beans/PropertyValue.hpp>
52 #include <comphelper/processfactory.hxx>
53 #include <com/sun/star/text/XNumberingTypeInfo.hpp>
56 #include <sfx2/opengrf.hxx>
58 using namespace com::sun::star::uno
;
59 using namespace com::sun::star::beans
;
60 using namespace com::sun::star::lang
;
61 using namespace com::sun::star::i18n
;
62 using namespace com::sun::star::text
;
63 using namespace com::sun::star::container
;
64 using namespace com::sun::star::style
;
66 #define NUM_PAGETYPE_BULLET 0
67 #define NUM_PAGETYPE_SINGLENUM 1
68 #define NUM_PAGETYPE_NUM 2
69 #define NUM_PAGETYPE_BMP 3
71 static const sal_Char cNumberingType
[] = "NumberingType";
72 static const sal_Char cValue
[] = "Value";
73 static const sal_Char cParentNumbering
[] = "ParentNumbering";
74 static const sal_Char cPrefix
[] = "Prefix";
75 static const sal_Char cSuffix
[] = "Suffix";
76 static const sal_Char cBulletChar
[] = "BulletChar";
77 static const sal_Char cBulletFontName
[] = "BulletFontName";
79 // The selection of bullets from the star symbol
80 static const sal_Unicode aBulletTypes
[] =
92 static Font
& lcl_GetDefaultBulletFont()
94 static sal_Bool bInit
= 0;
95 static Font
aDefBulletFont( OUString("StarSymbol"),
96 String(), Size( 0, 14 ) );
99 aDefBulletFont
.SetCharSet( RTL_TEXTENCODING_SYMBOL
);
100 aDefBulletFont
.SetFamily( FAMILY_DONTKNOW
);
101 aDefBulletFont
.SetPitch( PITCH_DONTKNOW
);
102 aDefBulletFont
.SetWeight( WEIGHT_DONTKNOW
);
103 aDefBulletFont
.SetTransparent( sal_True
);
106 return aDefBulletFont
;
109 static void lcl_PaintLevel(OutputDevice
* pVDev
, sal_Int16 nNumberingType
,
110 const OUString
& rBulletChar
, const OUString
& rText
, const OUString
& rFontName
,
111 Point
& rLeft
, Font
& rRuleFont
, const Font
& rTextFont
)
114 if(NumberingType::CHAR_SPECIAL
== nNumberingType
)
116 rRuleFont
.SetStyleName(rFontName
);
117 pVDev
->SetFont(rRuleFont
);
118 pVDev
->DrawText(rLeft
, rBulletChar
);
119 rLeft
.X() += pVDev
->GetTextWidth(rBulletChar
);
123 pVDev
->SetFont(rTextFont
);
124 pVDev
->DrawText(rLeft
, rText
);
125 rLeft
.X() += pVDev
->GetTextWidth(rText
);
128 void SvxNumValueSet::UserDraw( const UserDrawEvent
& rUDEvt
)
130 static sal_uInt16 aLinesArr
[] =
136 35, 90, // up to here line positions
137 05, 10, // character positions
144 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
145 const Color aBackColor
= rStyleSettings
.GetFieldColor();
146 const Color aTextColor
= rStyleSettings
.GetFieldTextColor();
148 OutputDevice
* pDev
= rUDEvt
.GetDevice();
149 Rectangle aRect
= rUDEvt
.GetRect();
150 sal_uInt16 nItemId
= rUDEvt
.GetItemId();
151 long nRectWidth
= aRect
.GetWidth();
152 long nRectHeight
= aRect
.GetHeight();
153 Size
aRectSize(nRectWidth
, aRect
.GetHeight());
154 Point aBLPos
= aRect
.TopLeft();
155 Font aOldFont
= pDev
->GetFont();
156 Color aOldColor
= pDev
->GetLineColor();
157 pDev
->SetLineColor(aTextColor
);
158 Font
aFont(OutputDevice::GetDefaultFont(
159 DEFAULTFONT_UI_SANS
, MsLangId::getSystemLanguage(), DEFAULTFONT_FLAGS_ONLYONE
));
161 Size aSize
= aFont
.GetSize();
163 Font
aRuleFont( lcl_GetDefaultBulletFont() );
164 aSize
.Height() = nRectHeight
/6;
165 aRuleFont
.SetSize(aSize
);
166 aRuleFont
.SetColor(aTextColor
);
167 aRuleFont
.SetFillColor(aBackColor
);
168 if(nPageType
== NUM_PAGETYPE_BULLET
)
170 else if(nPageType
== NUM_PAGETYPE_NUM
)
172 aSize
.Height() = nRectHeight
/8;
174 aFont
.SetColor(aTextColor
);
175 aFont
.SetFillColor(aBackColor
);
176 aFont
.SetSize( aSize
);
177 pDev
->SetFont(aFont
);
181 // The lines are only one time in the virtual device, only the outline
182 // page is currently done
183 pVDev
= new VirtualDevice(*pDev
);
184 pVDev
->SetMapMode(pDev
->GetMapMode());
185 pVDev
->EnableRTL( IsRTLEnabled() );
186 pVDev
->SetOutputSize( aRectSize
);
188 pVDev
->SetFillColor( aBackColor
);
189 pVDev
->DrawRect(aOrgRect
);
191 if(aBackColor
== aLineColor
)
193 pVDev
->SetLineColor(aLineColor
);
194 // Draw line only once
195 if(nPageType
!= NUM_PAGETYPE_NUM
)
197 Point
aStart(aBLPos
.X() + nRectWidth
*25 / 100,0);
198 Point
aEnd(aBLPos
.X() + nRectWidth
* 9 / 10,0);
199 for( sal_uInt16 i
= 11; i
< 100; i
+= 33)
201 aStart
.Y() = aEnd
.Y() = aBLPos
.Y() + nRectHeight
* i
/ 100;
202 pVDev
->DrawLine(aStart
, aEnd
);
203 aStart
.Y() = aEnd
.Y() = aBLPos
.Y() + nRectHeight
* (i
+ 11) / 100;
204 pVDev
->DrawLine(aStart
, aEnd
);
208 pDev
->DrawOutDev( aRect
.TopLeft(), aRectSize
,
209 aOrgRect
.TopLeft(), aRectSize
,
211 // Now comes the text
212 const OUString
sValue(cValue
);
213 if( NUM_PAGETYPE_SINGLENUM
== nPageType
||
214 NUM_PAGETYPE_BULLET
== nPageType
)
216 Point
aStart(aBLPos
.X() + nRectWidth
/ 9,0);
217 for( sal_uInt16 i
= 0; i
< 3; i
++ )
219 sal_uInt16 nY
= 11 + i
* 33;
220 aStart
.Y() = aBLPos
.Y() + nRectHeight
* nY
/ 100;
222 if(nPageType
== NUM_PAGETYPE_BULLET
)
224 sText
= aBulletTypes
[nItemId
- 1];
225 aStart
.Y() -= pDev
->GetTextHeight()/2;
226 aStart
.X() = aBLPos
.X() + 5;
230 if(xFormatter
.is() && aNumSettings
.getLength() > nItemId
- 1)
232 Sequence
<PropertyValue
> aLevel
= aNumSettings
.getConstArray()[nItemId
- 1];
235 aLevel
.realloc(aLevel
.getLength() + 1);
236 PropertyValue
& rValue
= aLevel
.getArray()[aLevel
.getLength() - 1];
237 rValue
.Name
= sValue
;
238 rValue
.Value
<<= (sal_Int32
)(i
+ 1);
239 sText
= xFormatter
->makeNumberingString( aLevel
, aLocale
);
243 OSL_FAIL("Exception in DefaultNumberingProvider::makeNumberingString");
246 // start just next to the left edge
247 aStart
.X() = aBLPos
.X() + 2;
248 aStart
.Y() -= pDev
->GetTextHeight()/2;
250 pDev
->DrawText(aStart
, sText
);
253 else if(NUM_PAGETYPE_NUM
== nPageType
)
255 // Outline numbering has to be painted into the virtual device
256 // to get correct lines
257 // has to be made again
258 pVDev
->DrawRect(aOrgRect
);
259 long nStartX
= aOrgRect
.TopLeft().X();
260 long nStartY
= aOrgRect
.TopLeft().Y();
262 if(xFormatter
.is() && aOutlineSettings
.getLength() > nItemId
- 1)
264 Reference
<XIndexAccess
> xLevel
= aOutlineSettings
.getArray()[nItemId
- 1];
267 OUString sLevelTexts
[5];
268 OUString sFontNames
[5];
269 OUString sBulletChars
[5];
270 sal_Int16 aNumberingTypes
[5];
271 OUString sPrefixes
[5];
272 OUString sSuffixes
[5];
273 sal_Int16 aParentNumberings
[5];
275 sal_Int32 nLevelCount
= xLevel
->getCount();
278 for( sal_Int32 i
= 0; i
< nLevelCount
&& i
< 5; i
++)
280 long nTop
= nStartY
+ nRectHeight
* (aLinesArr
[2 * i
+ 11])/100 ;
281 Point
aLeft(nStartX
+ nRectWidth
* (aLinesArr
[2 * i
+ 10])/ 100, nTop
);
283 Any aLevelAny
= xLevel
->getByIndex(i
);
284 Sequence
<PropertyValue
> aLevel
;
285 aLevelAny
>>= aLevel
;
286 const PropertyValue
* pValues
= aLevel
.getConstArray();
287 aNumberingTypes
[i
] = 0;
288 for(sal_Int32 nProperty
= 0; nProperty
< aLevel
.getLength() - 1; nProperty
++)
290 if ( pValues
[nProperty
].Name
== cNumberingType
)
291 pValues
[nProperty
].Value
>>= aNumberingTypes
[i
];
292 else if ( pValues
[nProperty
].Name
== cBulletFontName
)
293 pValues
[nProperty
].Value
>>= sFontNames
[i
];
294 else if ( pValues
[nProperty
].Name
== cBulletChar
)
295 pValues
[nProperty
].Value
>>= sBulletChars
[i
];
296 else if ( pValues
[nProperty
].Name
== cPrefix
)
297 pValues
[nProperty
].Value
>>= sPrefixes
[i
];
298 else if ( pValues
[nProperty
].Name
== cSuffix
)
299 pValues
[nProperty
].Value
>>= sSuffixes
[i
];
300 else if ( pValues
[nProperty
].Name
== cParentNumbering
)
301 pValues
[nProperty
].Value
>>= aParentNumberings
[i
];
303 Sequence
< PropertyValue
> aProperties(2);
304 PropertyValue
* pProperties
= aProperties
.getArray();
305 pProperties
[0].Name
= OUString("NumberingType");
306 pProperties
[0].Value
<<= aNumberingTypes
[i
];
307 pProperties
[1].Name
= OUString("Value");
308 pProperties
[1].Value
<<= (sal_Int32
)1;
311 sLevelTexts
[i
] = xFormatter
->makeNumberingString( aProperties
, aLocale
);
315 OSL_FAIL("Exception in DefaultNumberingProvider::makeNumberingString");
318 aLeft
.Y() -= (pDev
->GetTextHeight()/2);
319 if(!sPrefixes
[i
].isEmpty() &&
320 sPrefixes
[i
] != " " &&
321 sPrefixes
[i
].getStr()[0] != 0)
323 pVDev
->SetFont(aFont
);
324 pVDev
->DrawText(aLeft
, sPrefixes
[i
]);
325 aLeft
.X() += pDev
->GetTextWidth(sPrefixes
[i
]);
327 if(aParentNumberings
[i
])
329 //insert old numberings here
330 sal_Int32 nStartLevel
= std::min((sal_Int32
)aParentNumberings
[i
], i
);
331 for(sal_Int32 nParentLevel
= i
- nStartLevel
; nParentLevel
< i
; nParentLevel
++)
333 OUString
sTmp(sLevelTexts
[nParentLevel
]);
335 lcl_PaintLevel(pVDev
,
336 aNumberingTypes
[nParentLevel
],
337 sBulletChars
[nParentLevel
],
339 sFontNames
[nParentLevel
],
345 lcl_PaintLevel(pVDev
,
353 if(!sSuffixes
[i
].isEmpty()&&
354 !sSuffixes
[i
].equalsAsciiL(" ", 1) &&
355 sSuffixes
[i
].getStr()[0] != 0)
357 pVDev
->SetFont(aFont
);
358 pVDev
->DrawText(aLeft
, sSuffixes
[i
]);
359 aLeft
.X() += pDev
->GetTextWidth(sSuffixes
[i
]);
362 long nLineTop
= nStartY
+ nRectHeight
* aLinesArr
[2 * i
+ 1]/100 ;
363 Point
aLineLeft(aLeft
.X(), nLineTop
);
364 Point
aLineRight(nStartX
+ nRectWidth
* 90 /100, nLineTop
);
365 pVDev
->DrawLine(aLineLeft
, aLineRight
);
372 static sal_Bool bAssert
= sal_False
;
375 OSL_FAIL("exception in ::UserDraw");
385 pDev
->DrawOutDev( aRect
.TopLeft(), aRectSize
,
386 aOrgRect
.TopLeft(), aRectSize
,
390 pDev
->SetFont(aOldFont
);
391 pDev
->SetLineColor(aOldColor
);
394 SvxNumValueSet::SvxNumValueSet(Window
* pParent
, WinBits nWinBits
)
395 : ValueSet(pParent
, nWinBits
)
399 extern "C" SAL_DLLPUBLIC_EXPORT Window
* SAL_CALL
makeSvxNumValueSet(Window
*pParent
, VclBuilder::stringmap
&)
401 return new SvxNumValueSet(pParent
, WB_TABSTOP
);
404 void SvxNumValueSet::init(sal_uInt16 nType
)
406 aLineColor
= COL_LIGHTGRAY
;
408 bHTMLMode
= sal_False
;
413 SetStyle( GetStyle() | WB_ITEMBORDER
| WB_DOUBLEBORDER
);
414 if(NUM_PAGETYPE_BULLET
== nType
)
416 for ( sal_uInt16 i
= 0; i
< 8; i
++ )
418 InsertItem( i
+ 1, i
);
419 SetItemText( i
+ 1, SVX_RESSTR( RID_SVXSTR_BULLET_DESCRIPTIONS
+ i
) );
424 SvxNumValueSet::~SvxNumValueSet()
429 void SvxNumValueSet::SetNumberingSettings(
430 const Sequence
<Sequence
<PropertyValue
> >& aNum
,
431 Reference
<XNumberingFormatter
>& xFormat
,
432 const Locale
& rLocale
)
435 xFormatter
= xFormat
;
437 if(aNum
.getLength() > 8)
438 SetStyle( GetStyle()|WB_VSCROLL
);
439 for ( sal_uInt16 i
= 0; i
< aNum
.getLength(); i
++ )
441 InsertItem( i
+ 1, i
);
443 SetItemText( i
+ 1, SVX_RESSTR( RID_SVXSTR_SINGLENUM_DESCRIPTIONS
+ i
));
447 void SvxNumValueSet::SetOutlineNumberingSettings(
448 Sequence
<Reference
<XIndexAccess
> >& rOutline
,
449 Reference
<XNumberingFormatter
>& xFormat
,
450 const Locale
& rLocale
)
452 aOutlineSettings
= rOutline
;
453 xFormatter
= xFormat
;
455 if(aOutlineSettings
.getLength() > 8)
456 SetStyle( GetStyle() | WB_VSCROLL
);
457 for ( sal_uInt16 i
= 0; i
< aOutlineSettings
.getLength(); i
++ )
459 InsertItem( i
+ 1, i
);
461 SetItemText( i
+ 1, SVX_RESSTR( RID_SVXSTR_OUTLINENUM_DESCRIPTIONS
+ i
));
465 SvxBmpNumValueSet::SvxBmpNumValueSet(Window
* pParent
, WinBits nWinBits
)
466 : SvxNumValueSet(pParent
, nWinBits
)
471 extern "C" SAL_DLLPUBLIC_EXPORT Window
* SAL_CALL
makeSvxBmpNumValueSet(Window
*pParent
, VclBuilder::stringmap
&)
473 return new SvxBmpNumValueSet(pParent
, WB_TABSTOP
);
476 void SvxBmpNumValueSet::init()
478 SvxNumValueSet::init(NUM_PAGETYPE_BMP
);
479 bGrfNotFound
= sal_False
;
480 GalleryExplorer::BeginLocking(GALLERY_THEME_BULLETS
);
481 SetStyle( GetStyle() | WB_VSCROLL
);
483 aFormatTimer
.SetTimeout(300);
484 aFormatTimer
.SetTimeoutHdl(LINK(this, SvxBmpNumValueSet
, FormatHdl_Impl
));
488 SvxBmpNumValueSet::~SvxBmpNumValueSet()
490 GalleryExplorer::EndLocking(GALLERY_THEME_BULLETS
);
494 void SvxBmpNumValueSet::UserDraw( const UserDrawEvent
& rUDEvt
)
496 SvxNumValueSet::UserDraw(rUDEvt
);
498 Rectangle aRect
= rUDEvt
.GetRect();
499 OutputDevice
* pDev
= rUDEvt
.GetDevice();
500 sal_uInt16 nItemId
= rUDEvt
.GetItemId();
501 Point aBLPos
= aRect
.TopLeft();
503 int nRectHeight
= aRect
.GetHeight();
504 Size
aSize(nRectHeight
/8, nRectHeight
/8);
507 if(!GalleryExplorer::GetGraphicObj( GALLERY_THEME_BULLETS
, nItemId
- 1,
510 bGrfNotFound
= sal_True
;
514 Point
aPos(aBLPos
.X() + 5, 0);
515 for( sal_uInt16 i
= 0; i
< 3; i
++ )
517 sal_uInt16 nY
= 11 + i
* 33;
518 aPos
.Y() = aBLPos
.Y() + nRectHeight
* nY
/ 100;
519 aGraphic
.Draw( pDev
, aPos
, aSize
);
524 IMPL_LINK_NOARG(SvxBmpNumValueSet
, FormatHdl_Impl
)
526 // only when a graphics was not there, it needs to be formatted
529 bGrfNotFound
= sal_False
;
536 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */