Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
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>
26 : #include <helpid.hrc>
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>
54 :
55 : #include <algorithm>
56 : #include <sfx2/opengrf.hxx>
57 :
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;
65 :
66 : #define NUM_PAGETYPE_BULLET 0
67 : #define NUM_PAGETYPE_SINGLENUM 1
68 : #define NUM_PAGETYPE_NUM 2
69 : #define NUM_PAGETYPE_BMP 3
70 :
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";
78 :
79 : // The selection of bullets from the star symbol
80 : static const sal_Unicode aBulletTypes[] =
81 : {
82 : 0x2022,
83 : 0x25cf,
84 : 0xe00c,
85 : 0xe00a,
86 : 0x2794,
87 : 0x27a2,
88 : 0x2717,
89 : 0x2714
90 : };
91 :
92 0 : static Font& lcl_GetDefaultBulletFont()
93 : {
94 : static sal_Bool bInit = 0;
95 : static Font aDefBulletFont( OUString("StarSymbol"),
96 0 : String(), Size( 0, 14 ) );
97 0 : if(!bInit)
98 : {
99 0 : aDefBulletFont.SetCharSet( RTL_TEXTENCODING_SYMBOL );
100 0 : aDefBulletFont.SetFamily( FAMILY_DONTKNOW );
101 0 : aDefBulletFont.SetPitch( PITCH_DONTKNOW );
102 0 : aDefBulletFont.SetWeight( WEIGHT_DONTKNOW );
103 0 : aDefBulletFont.SetTransparent( sal_True );
104 0 : bInit = sal_True;
105 : }
106 0 : return aDefBulletFont;
107 : }
108 :
109 0 : 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)
112 : {
113 :
114 0 : if(NumberingType::CHAR_SPECIAL == nNumberingType )
115 : {
116 0 : rRuleFont.SetStyleName(rFontName);
117 0 : pVDev->SetFont(rRuleFont);
118 0 : pVDev->DrawText(rLeft, rBulletChar);
119 0 : rLeft.X() += pVDev->GetTextWidth(rBulletChar);
120 : }
121 : else
122 : {
123 0 : pVDev->SetFont(rTextFont);
124 0 : pVDev->DrawText(rLeft, rText);
125 0 : rLeft.X() += pVDev->GetTextWidth(rText);
126 : }
127 0 : }
128 0 : void SvxNumValueSet::UserDraw( const UserDrawEvent& rUDEvt )
129 : {
130 : static const sal_uInt16 aLinesArr[] =
131 : {
132 : 15, 10,
133 : 20, 30,
134 : 25, 50,
135 : 30, 70,
136 : 35, 90, // up to here line positions
137 : 05, 10, // character positions
138 : 10, 30,
139 : 15, 50,
140 : 20, 70,
141 : 25, 90,
142 : };
143 :
144 0 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
145 0 : const Color aBackColor = rStyleSettings.GetFieldColor();
146 0 : const Color aTextColor = rStyleSettings.GetFieldTextColor();
147 :
148 0 : OutputDevice* pDev = rUDEvt.GetDevice();
149 0 : Rectangle aRect = rUDEvt.GetRect();
150 0 : sal_uInt16 nItemId = rUDEvt.GetItemId();
151 0 : long nRectWidth = aRect.GetWidth();
152 0 : long nRectHeight = aRect.GetHeight();
153 0 : Size aRectSize(nRectWidth, aRect.GetHeight());
154 0 : Point aBLPos = aRect.TopLeft();
155 0 : Font aOldFont = pDev->GetFont();
156 0 : Color aOldColor = pDev->GetLineColor();
157 0 : pDev->SetLineColor(aTextColor);
158 : Font aFont(OutputDevice::GetDefaultFont(
159 0 : DEFAULTFONT_UI_SANS, MsLangId::getSystemLanguage(), DEFAULTFONT_FLAGS_ONLYONE));
160 :
161 0 : Size aSize = aFont.GetSize();
162 :
163 0 : Font aRuleFont( lcl_GetDefaultBulletFont() );
164 0 : aSize.Height() = nRectHeight/6;
165 0 : aRuleFont.SetSize(aSize);
166 0 : aRuleFont.SetColor(aTextColor);
167 0 : aRuleFont.SetFillColor(aBackColor);
168 0 : if(nPageType == NUM_PAGETYPE_BULLET)
169 0 : aFont = aRuleFont;
170 0 : else if(nPageType == NUM_PAGETYPE_NUM)
171 : {
172 0 : aSize.Height() = nRectHeight/8;
173 : }
174 0 : aFont.SetColor(aTextColor);
175 0 : aFont.SetFillColor(aBackColor);
176 0 : aFont.SetSize( aSize );
177 0 : pDev->SetFont(aFont);
178 :
179 0 : if(!pVDev)
180 : {
181 : // The lines are only one time in the virtual device, only the outline
182 : // page is currently done
183 0 : pVDev = new VirtualDevice(*pDev);
184 0 : pVDev->SetMapMode(pDev->GetMapMode());
185 0 : pVDev->EnableRTL( IsRTLEnabled() );
186 0 : pVDev->SetOutputSize( aRectSize );
187 0 : aOrgRect = aRect;
188 0 : pVDev->SetFillColor( aBackColor );
189 0 : pVDev->DrawRect(aOrgRect);
190 :
191 0 : if(aBackColor == aLineColor)
192 0 : aLineColor.Invert();
193 0 : pVDev->SetLineColor(aLineColor);
194 : // Draw line only once
195 0 : if(nPageType != NUM_PAGETYPE_NUM)
196 : {
197 0 : Point aStart(aBLPos.X() + nRectWidth *25 / 100,0);
198 0 : Point aEnd(aBLPos.X() + nRectWidth * 9 / 10,0);
199 0 : for( sal_uInt16 i = 11; i < 100; i += 33)
200 : {
201 0 : aStart.Y() = aEnd.Y() = aBLPos.Y() + nRectHeight * i / 100;
202 0 : pVDev->DrawLine(aStart, aEnd);
203 0 : aStart.Y() = aEnd.Y() = aBLPos.Y() + nRectHeight * (i + 11) / 100;
204 0 : pVDev->DrawLine(aStart, aEnd);
205 : }
206 : }
207 : }
208 : pDev->DrawOutDev( aRect.TopLeft(), aRectSize,
209 0 : aOrgRect.TopLeft(), aRectSize,
210 0 : *pVDev );
211 : // Now comes the text
212 0 : const OUString sValue(cValue);
213 0 : if( NUM_PAGETYPE_SINGLENUM == nPageType ||
214 0 : NUM_PAGETYPE_BULLET == nPageType )
215 : {
216 0 : Point aStart(aBLPos.X() + nRectWidth / 9,0);
217 0 : for( sal_uInt16 i = 0; i < 3; i++ )
218 : {
219 0 : sal_uInt16 nY = 11 + i * 33;
220 0 : aStart.Y() = aBLPos.Y() + nRectHeight * nY / 100;
221 0 : String sText;
222 0 : if(nPageType == NUM_PAGETYPE_BULLET)
223 : {
224 0 : sText = aBulletTypes[nItemId - 1];
225 0 : aStart.Y() -= pDev->GetTextHeight()/2;
226 0 : aStart.X() = aBLPos.X() + 5;
227 : }
228 : else
229 : {
230 0 : if(xFormatter.is() && aNumSettings.getLength() > nItemId - 1)
231 : {
232 0 : Sequence<PropertyValue> aLevel = aNumSettings.getConstArray()[nItemId - 1];
233 : try
234 : {
235 0 : aLevel.realloc(aLevel.getLength() + 1);
236 0 : PropertyValue& rValue = aLevel.getArray()[aLevel.getLength() - 1];
237 0 : rValue.Name = sValue;
238 0 : rValue.Value <<= (sal_Int32)(i + 1);
239 0 : sText = xFormatter->makeNumberingString( aLevel, aLocale );
240 : }
241 0 : catch(Exception&)
242 : {
243 : OSL_FAIL("Exception in DefaultNumberingProvider::makeNumberingString");
244 0 : }
245 : }
246 : // start just next to the left edge
247 0 : aStart.X() = aBLPos.X() + 2;
248 0 : aStart.Y() -= pDev->GetTextHeight()/2;
249 : }
250 0 : pDev->DrawText(aStart, sText);
251 0 : }
252 : }
253 0 : else if(NUM_PAGETYPE_NUM == nPageType )
254 : {
255 : // Outline numbering has to be painted into the virtual device
256 : // to get correct lines
257 : // has to be made again
258 0 : pVDev->DrawRect(aOrgRect);
259 0 : long nStartX = aOrgRect.TopLeft().X();
260 0 : long nStartY = aOrgRect.TopLeft().Y();
261 :
262 0 : if(xFormatter.is() && aOutlineSettings.getLength() > nItemId - 1)
263 : {
264 0 : Reference<XIndexAccess> xLevel = aOutlineSettings.getArray()[nItemId - 1];
265 : try
266 : {
267 0 : OUString sLevelTexts[5];
268 0 : OUString sFontNames[5];
269 0 : OUString sBulletChars[5];
270 : sal_Int16 aNumberingTypes[5];
271 0 : OUString sPrefixes[5];
272 0 : OUString sSuffixes[5];
273 : sal_Int16 aParentNumberings[5];
274 :
275 0 : sal_Int32 nLevelCount = xLevel->getCount();
276 0 : if(nLevelCount > 5)
277 0 : nLevelCount = 5;
278 0 : for( sal_Int32 i = 0; i < nLevelCount && i < 5; i++)
279 : {
280 0 : long nTop = nStartY + nRectHeight * (aLinesArr[2 * i + 11])/100 ;
281 0 : Point aLeft(nStartX + nRectWidth * (aLinesArr[2 * i + 10])/ 100, nTop );
282 :
283 0 : Any aLevelAny = xLevel->getByIndex(i);
284 0 : Sequence<PropertyValue> aLevel;
285 0 : aLevelAny >>= aLevel;
286 0 : const PropertyValue* pValues = aLevel.getConstArray();
287 0 : aNumberingTypes[i] = 0;
288 0 : for(sal_Int32 nProperty = 0; nProperty < aLevel.getLength() - 1; nProperty++)
289 : {
290 0 : if ( pValues[nProperty].Name == cNumberingType )
291 0 : pValues[nProperty].Value >>= aNumberingTypes[i];
292 0 : else if ( pValues[nProperty].Name == cBulletFontName )
293 0 : pValues[nProperty].Value >>= sFontNames[i];
294 0 : else if ( pValues[nProperty].Name == cBulletChar )
295 0 : pValues[nProperty].Value >>= sBulletChars[i];
296 0 : else if ( pValues[nProperty].Name == cPrefix )
297 0 : pValues[nProperty].Value >>= sPrefixes[i];
298 0 : else if ( pValues[nProperty].Name == cSuffix )
299 0 : pValues[nProperty].Value >>= sSuffixes[i];
300 0 : else if ( pValues[nProperty].Name == cParentNumbering )
301 0 : pValues[nProperty].Value >>= aParentNumberings[i];
302 : }
303 0 : Sequence< PropertyValue > aProperties(2);
304 0 : PropertyValue* pProperties = aProperties.getArray();
305 0 : pProperties[0].Name = OUString("NumberingType");
306 0 : pProperties[0].Value <<= aNumberingTypes[i];
307 0 : pProperties[1].Name = OUString("Value");
308 0 : pProperties[1].Value <<= (sal_Int32)1;
309 : try
310 : {
311 0 : sLevelTexts[i] = xFormatter->makeNumberingString( aProperties, aLocale );
312 : }
313 0 : catch(Exception&)
314 : {
315 : OSL_FAIL("Exception in DefaultNumberingProvider::makeNumberingString");
316 : }
317 :
318 0 : aLeft.Y() -= (pDev->GetTextHeight()/2);
319 0 : if(!sPrefixes[i].isEmpty() &&
320 0 : sPrefixes[i] != " " &&
321 0 : sPrefixes[i].getStr()[0] != 0)
322 : {
323 0 : pVDev->SetFont(aFont);
324 0 : pVDev->DrawText(aLeft, sPrefixes[i]);
325 0 : aLeft.X() += pDev->GetTextWidth(sPrefixes[i]);
326 : }
327 0 : if(aParentNumberings[i])
328 : {
329 : //insert old numberings here
330 0 : sal_Int32 nStartLevel = std::min((sal_Int32)aParentNumberings[i], i);
331 0 : for(sal_Int32 nParentLevel = i - nStartLevel; nParentLevel < i; nParentLevel++)
332 : {
333 0 : OUString sTmp(sLevelTexts[nParentLevel]);
334 0 : sTmp += ".";
335 : lcl_PaintLevel(pVDev,
336 0 : aNumberingTypes[nParentLevel],
337 : sBulletChars[nParentLevel],
338 : sTmp,
339 : sFontNames[nParentLevel],
340 : aLeft,
341 : aRuleFont,
342 0 : aFont);
343 0 : }
344 : }
345 : lcl_PaintLevel(pVDev,
346 0 : aNumberingTypes[i],
347 0 : sBulletChars[i],
348 0 : sLevelTexts[i],
349 0 : sFontNames[i],
350 : aLeft,
351 : aRuleFont,
352 0 : aFont);
353 0 : if(!sSuffixes[i].isEmpty()&&
354 0 : !sSuffixes[i].equalsAsciiL(" ", 1) &&
355 0 : sSuffixes[i].getStr()[0] != 0)
356 : {
357 0 : pVDev->SetFont(aFont);
358 0 : pVDev->DrawText(aLeft, sSuffixes[i]);
359 0 : aLeft.X() += pDev->GetTextWidth(sSuffixes[i]);
360 : }
361 :
362 0 : long nLineTop = nStartY + nRectHeight * aLinesArr[2 * i + 1]/100 ;
363 0 : Point aLineLeft(aLeft.X(), nLineTop );
364 0 : Point aLineRight(nStartX + nRectWidth * 90 /100, nLineTop );
365 0 : pVDev->DrawLine(aLineLeft, aLineRight);
366 0 : }
367 :
368 : }
369 : #ifdef DBG_UTIL
370 : catch(Exception&)
371 : {
372 : static sal_Bool bAssert = sal_False;
373 : if(!bAssert)
374 : {
375 : OSL_FAIL("exception in ::UserDraw");
376 : bAssert = sal_True;
377 : }
378 : }
379 : #else
380 0 : catch(Exception&)
381 : {
382 0 : }
383 : #endif
384 : }
385 : pDev->DrawOutDev( aRect.TopLeft(), aRectSize,
386 0 : aOrgRect.TopLeft(), aRectSize,
387 0 : *pVDev );
388 : }
389 :
390 0 : pDev->SetFont(aOldFont);
391 0 : pDev->SetLineColor(aOldColor);
392 0 : }
393 :
394 0 : SvxNumValueSet::SvxNumValueSet(Window* pParent, WinBits nWinBits)
395 0 : : ValueSet(pParent, nWinBits)
396 : {
397 0 : }
398 :
399 0 : extern "C" SAL_DLLPUBLIC_EXPORT Window* SAL_CALL makeSvxNumValueSet(Window *pParent, VclBuilder::stringmap &)
400 : {
401 0 : return new SvxNumValueSet(pParent, WB_TABSTOP);
402 : }
403 :
404 0 : void SvxNumValueSet::init(sal_uInt16 nType)
405 : {
406 0 : aLineColor = COL_LIGHTGRAY;
407 0 : nPageType = nType;
408 0 : bHTMLMode = sal_False;
409 0 : pVDev = NULL;
410 :
411 0 : SetColCount( 4 );
412 0 : SetLineCount( 2 );
413 0 : SetStyle( GetStyle() | WB_ITEMBORDER | WB_DOUBLEBORDER );
414 0 : if(NUM_PAGETYPE_BULLET == nType)
415 : {
416 0 : for ( sal_uInt16 i = 0; i < 8; i++ )
417 : {
418 0 : InsertItem( i + 1, i );
419 0 : SetItemText( i + 1, SVX_RESSTR( RID_SVXSTR_BULLET_DESCRIPTIONS + i ) );
420 : }
421 : }
422 0 : }
423 :
424 0 : SvxNumValueSet::~SvxNumValueSet()
425 : {
426 0 : delete pVDev;
427 0 : }
428 :
429 0 : void SvxNumValueSet::SetNumberingSettings(
430 : const Sequence<Sequence<PropertyValue> >& aNum,
431 : Reference<XNumberingFormatter>& xFormat,
432 : const Locale& rLocale )
433 : {
434 0 : aNumSettings = aNum;
435 0 : xFormatter = xFormat;
436 0 : aLocale = rLocale;
437 0 : if(aNum.getLength() > 8)
438 0 : SetStyle( GetStyle()|WB_VSCROLL);
439 0 : for ( sal_uInt16 i = 0; i < aNum.getLength(); i++ )
440 : {
441 0 : InsertItem( i + 1, i );
442 0 : if( i < 8 )
443 0 : SetItemText( i + 1, SVX_RESSTR( RID_SVXSTR_SINGLENUM_DESCRIPTIONS + i ));
444 : }
445 0 : }
446 :
447 0 : void SvxNumValueSet::SetOutlineNumberingSettings(
448 : Sequence<Reference<XIndexAccess> >& rOutline,
449 : Reference<XNumberingFormatter>& xFormat,
450 : const Locale& rLocale)
451 : {
452 0 : aOutlineSettings = rOutline;
453 0 : xFormatter = xFormat;
454 0 : aLocale = rLocale;
455 0 : if(aOutlineSettings.getLength() > 8)
456 0 : SetStyle( GetStyle() | WB_VSCROLL );
457 0 : for ( sal_uInt16 i = 0; i < aOutlineSettings.getLength(); i++ )
458 : {
459 0 : InsertItem( i + 1, i );
460 0 : if( i < 8 )
461 0 : SetItemText( i + 1, SVX_RESSTR( RID_SVXSTR_OUTLINENUM_DESCRIPTIONS + i ));
462 : }
463 0 : }
464 :
465 0 : SvxBmpNumValueSet::SvxBmpNumValueSet(Window* pParent, WinBits nWinBits)
466 0 : : SvxNumValueSet(pParent, nWinBits)
467 : {
468 0 : init();
469 0 : }
470 :
471 0 : extern "C" SAL_DLLPUBLIC_EXPORT Window* SAL_CALL makeSvxBmpNumValueSet(Window *pParent, VclBuilder::stringmap &)
472 : {
473 0 : return new SvxBmpNumValueSet(pParent, WB_TABSTOP);
474 : }
475 :
476 0 : void SvxBmpNumValueSet::init()
477 : {
478 0 : SvxNumValueSet::init(NUM_PAGETYPE_BMP);
479 0 : bGrfNotFound = sal_False;
480 0 : GalleryExplorer::BeginLocking(GALLERY_THEME_BULLETS);
481 0 : SetStyle( GetStyle() | WB_VSCROLL );
482 0 : SetLineCount( 3 );
483 0 : aFormatTimer.SetTimeout(300);
484 0 : aFormatTimer.SetTimeoutHdl(LINK(this, SvxBmpNumValueSet, FormatHdl_Impl));
485 0 : }
486 :
487 :
488 0 : SvxBmpNumValueSet::~SvxBmpNumValueSet()
489 : {
490 0 : GalleryExplorer::EndLocking(GALLERY_THEME_BULLETS);
491 0 : aFormatTimer.Stop();
492 0 : }
493 :
494 0 : void SvxBmpNumValueSet::UserDraw( const UserDrawEvent& rUDEvt )
495 : {
496 0 : SvxNumValueSet::UserDraw(rUDEvt);
497 :
498 0 : Rectangle aRect = rUDEvt.GetRect();
499 0 : OutputDevice* pDev = rUDEvt.GetDevice();
500 0 : sal_uInt16 nItemId = rUDEvt.GetItemId();
501 0 : Point aBLPos = aRect.TopLeft();
502 :
503 0 : int nRectHeight = aRect.GetHeight();
504 0 : Size aSize(nRectHeight/8, nRectHeight/8);
505 :
506 0 : Graphic aGraphic;
507 0 : if(!GalleryExplorer::GetGraphicObj( GALLERY_THEME_BULLETS, nItemId - 1,
508 0 : &aGraphic, NULL))
509 : {
510 0 : bGrfNotFound = sal_True;
511 : }
512 : else
513 : {
514 0 : Point aPos(aBLPos.X() + 5, 0);
515 0 : for( sal_uInt16 i = 0; i < 3; i++ )
516 : {
517 0 : sal_uInt16 nY = 11 + i * 33;
518 0 : aPos.Y() = aBLPos.Y() + nRectHeight * nY / 100;
519 0 : aGraphic.Draw( pDev, aPos, aSize );
520 : }
521 0 : }
522 0 : }
523 :
524 0 : IMPL_LINK_NOARG(SvxBmpNumValueSet, FormatHdl_Impl)
525 : {
526 : // only when a graphics was not there, it needs to be formatted
527 0 : if(bGrfNotFound)
528 : {
529 0 : bGrfNotFound = sal_False;
530 0 : Format();
531 : }
532 0 : Invalidate();
533 0 : return 0;
534 216 : }
535 :
536 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|