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 <vcl/settings.hxx>
38 : #include <editeng/flstitem.hxx>
39 : #include <svx/dlgutil.hxx>
40 : #include <svx/xtable.hxx>
41 : #include <svx/drawitem.hxx>
42 : #include <svx/numvset.hxx>
43 : #include <sfx2/htmlmode.hxx>
44 : #include <unotools/pathoptions.hxx>
45 : #include <svtools/ctrltool.hxx>
46 : #include <editeng/unolingu.hxx>
47 : #include <com/sun/star/style/NumberingType.hpp>
48 : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
49 : #include <com/sun/star/container/XIndexAccess.hpp>
50 : #include <com/sun/star/text/XDefaultNumberingProvider.hpp>
51 : #include <com/sun/star/text/XNumberingFormatter.hpp>
52 : #include <com/sun/star/beans/PropertyValue.hpp>
53 : #include <comphelper/processfactory.hxx>
54 : #include <com/sun/star/text/XNumberingTypeInfo.hpp>
55 :
56 : #include <algorithm>
57 : #include <sfx2/opengrf.hxx>
58 :
59 : using namespace com::sun::star::uno;
60 : using namespace com::sun::star::beans;
61 : using namespace com::sun::star::lang;
62 : using namespace com::sun::star::i18n;
63 : using namespace com::sun::star::text;
64 : using namespace com::sun::star::container;
65 : using namespace com::sun::star::style;
66 :
67 : #define NUM_PAGETYPE_BULLET 0
68 : #define NUM_PAGETYPE_SINGLENUM 1
69 : #define NUM_PAGETYPE_NUM 2
70 : #define NUM_PAGETYPE_BMP 3
71 :
72 : static const sal_Char cNumberingType[] = "NumberingType";
73 : static const sal_Char cValue[] = "Value";
74 : static const sal_Char cParentNumbering[] = "ParentNumbering";
75 : static const sal_Char cPrefix[] = "Prefix";
76 : static const sal_Char cSuffix[] = "Suffix";
77 : static const sal_Char cBulletChar[] = "BulletChar";
78 : static const sal_Char cBulletFontName[] = "BulletFontName";
79 :
80 : // The selection of bullets from the star symbol
81 : static const sal_Unicode aBulletTypes[] =
82 : {
83 : 0x2022,
84 : 0x25cf,
85 : 0xe00c,
86 : 0xe00a,
87 : 0x2794,
88 : 0x27a2,
89 : 0x2717,
90 : 0x2714
91 : };
92 :
93 0 : static Font& lcl_GetDefaultBulletFont()
94 : {
95 : static sal_Bool bInit = 0;
96 0 : static Font aDefBulletFont( "StarSymbol", "", 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( 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 : OUString sText;
222 0 : if(nPageType == NUM_PAGETYPE_BULLET)
223 : {
224 0 : sText = OUString( 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 = "NumberingType";
306 0 : pProperties[0].Value <<= aNumberingTypes[i];
307 0 : pProperties[1].Name = "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 : {
322 0 : pVDev->SetFont(aFont);
323 0 : pVDev->DrawText(aLeft, sPrefixes[i]);
324 0 : aLeft.X() += pDev->GetTextWidth(sPrefixes[i]);
325 : }
326 0 : if(aParentNumberings[i])
327 : {
328 : //insert old numberings here
329 0 : sal_Int32 nStartLevel = std::min((sal_Int32)aParentNumberings[i], i);
330 0 : for(sal_Int32 nParentLevel = i - nStartLevel; nParentLevel < i; nParentLevel++)
331 : {
332 0 : OUString sTmp(sLevelTexts[nParentLevel]);
333 0 : sTmp += ".";
334 : lcl_PaintLevel(pVDev,
335 0 : aNumberingTypes[nParentLevel],
336 : sBulletChars[nParentLevel],
337 : sTmp,
338 : sFontNames[nParentLevel],
339 : aLeft,
340 : aRuleFont,
341 0 : aFont);
342 0 : }
343 : }
344 : lcl_PaintLevel(pVDev,
345 0 : aNumberingTypes[i],
346 0 : sBulletChars[i],
347 0 : sLevelTexts[i],
348 0 : sFontNames[i],
349 : aLeft,
350 : aRuleFont,
351 0 : aFont);
352 0 : if(!sSuffixes[i].isEmpty() &&
353 0 : !sSuffixes[i].startsWith(" "))
354 : {
355 0 : pVDev->SetFont(aFont);
356 0 : pVDev->DrawText(aLeft, sSuffixes[i]);
357 0 : aLeft.X() += pDev->GetTextWidth(sSuffixes[i]);
358 : }
359 :
360 0 : long nLineTop = nStartY + nRectHeight * aLinesArr[2 * i + 1]/100 ;
361 0 : Point aLineLeft(aLeft.X(), nLineTop );
362 0 : Point aLineRight(nStartX + nRectWidth * 90 /100, nLineTop );
363 0 : pVDev->DrawLine(aLineLeft, aLineRight);
364 0 : }
365 :
366 : }
367 : #ifdef DBG_UTIL
368 : catch(Exception&)
369 : {
370 : static sal_Bool bAssert = sal_False;
371 : if(!bAssert)
372 : {
373 : OSL_FAIL("exception in ::UserDraw");
374 : bAssert = sal_True;
375 : }
376 : }
377 : #else
378 0 : catch(Exception&)
379 : {
380 0 : }
381 : #endif
382 : }
383 : pDev->DrawOutDev( aRect.TopLeft(), aRectSize,
384 0 : aOrgRect.TopLeft(), aRectSize,
385 0 : *pVDev );
386 : }
387 :
388 0 : pDev->SetFont(aOldFont);
389 0 : pDev->SetLineColor(aOldColor);
390 0 : }
391 :
392 0 : SvxNumValueSet::SvxNumValueSet(Window* pParent, WinBits nWinBits)
393 : : ValueSet(pParent, nWinBits)
394 : , nPageType(0)
395 : , bHTMLMode(false)
396 0 : , pVDev(NULL)
397 : {
398 0 : }
399 :
400 0 : extern "C" SAL_DLLPUBLIC_EXPORT Window* SAL_CALL makeSvxNumValueSet(Window *pParent, VclBuilder::stringmap &)
401 : {
402 0 : return new SvxNumValueSet(pParent, WB_TABSTOP);
403 : }
404 :
405 0 : void SvxNumValueSet::init(sal_uInt16 nType)
406 : {
407 0 : aLineColor = COL_LIGHTGRAY;
408 0 : nPageType = nType;
409 0 : bHTMLMode = false;
410 0 : pVDev = NULL;
411 :
412 0 : SetColCount( 4 );
413 0 : SetLineCount( 2 );
414 0 : SetStyle( GetStyle() | WB_ITEMBORDER | WB_DOUBLEBORDER );
415 0 : if(NUM_PAGETYPE_BULLET == nType)
416 : {
417 0 : for ( sal_uInt16 i = 0; i < 8; i++ )
418 : {
419 0 : InsertItem( i + 1, i );
420 0 : SetItemText( i + 1, SVX_RESSTR( RID_SVXSTR_BULLET_DESCRIPTIONS + i ) );
421 : }
422 : }
423 0 : }
424 :
425 0 : SvxNumValueSet::~SvxNumValueSet()
426 : {
427 0 : delete pVDev;
428 0 : }
429 :
430 0 : void SvxNumValueSet::SetNumberingSettings(
431 : const Sequence<Sequence<PropertyValue> >& aNum,
432 : Reference<XNumberingFormatter>& xFormat,
433 : const Locale& rLocale )
434 : {
435 0 : aNumSettings = aNum;
436 0 : xFormatter = xFormat;
437 0 : aLocale = rLocale;
438 0 : if(aNum.getLength() > 8)
439 0 : SetStyle( GetStyle()|WB_VSCROLL);
440 0 : for ( sal_uInt16 i = 0; i < aNum.getLength(); i++ )
441 : {
442 0 : InsertItem( i + 1, i );
443 0 : if( i < 8 )
444 0 : SetItemText( i + 1, SVX_RESSTR( RID_SVXSTR_SINGLENUM_DESCRIPTIONS + i ));
445 : }
446 0 : }
447 :
448 0 : void SvxNumValueSet::SetOutlineNumberingSettings(
449 : Sequence<Reference<XIndexAccess> >& rOutline,
450 : Reference<XNumberingFormatter>& xFormat,
451 : const Locale& rLocale)
452 : {
453 0 : aOutlineSettings = rOutline;
454 0 : xFormatter = xFormat;
455 0 : aLocale = rLocale;
456 0 : if(aOutlineSettings.getLength() > 8)
457 0 : SetStyle( GetStyle() | WB_VSCROLL );
458 0 : for ( sal_uInt16 i = 0; i < aOutlineSettings.getLength(); i++ )
459 : {
460 0 : InsertItem( i + 1, i );
461 0 : if( i < 8 )
462 0 : SetItemText( i + 1, SVX_RESSTR( RID_SVXSTR_OUTLINENUM_DESCRIPTIONS + i ));
463 : }
464 0 : }
465 :
466 0 : SvxBmpNumValueSet::SvxBmpNumValueSet(Window* pParent, WinBits nWinBits)
467 0 : : SvxNumValueSet(pParent, nWinBits)
468 : {
469 0 : init();
470 0 : }
471 :
472 0 : extern "C" SAL_DLLPUBLIC_EXPORT Window* SAL_CALL makeSvxBmpNumValueSet(Window *pParent, VclBuilder::stringmap &)
473 : {
474 0 : return new SvxBmpNumValueSet(pParent, WB_TABSTOP);
475 : }
476 :
477 0 : void SvxBmpNumValueSet::init()
478 : {
479 0 : SvxNumValueSet::init(NUM_PAGETYPE_BMP);
480 0 : bGrfNotFound = false;
481 0 : GalleryExplorer::BeginLocking(GALLERY_THEME_BULLETS);
482 0 : SetStyle( GetStyle() | WB_VSCROLL );
483 0 : SetLineCount( 3 );
484 0 : aFormatTimer.SetTimeout(300);
485 0 : aFormatTimer.SetTimeoutHdl(LINK(this, SvxBmpNumValueSet, FormatHdl_Impl));
486 0 : }
487 :
488 :
489 0 : SvxBmpNumValueSet::~SvxBmpNumValueSet()
490 : {
491 0 : GalleryExplorer::EndLocking(GALLERY_THEME_BULLETS);
492 0 : aFormatTimer.Stop();
493 0 : }
494 :
495 0 : void SvxBmpNumValueSet::UserDraw( const UserDrawEvent& rUDEvt )
496 : {
497 0 : SvxNumValueSet::UserDraw(rUDEvt);
498 :
499 0 : Rectangle aRect = rUDEvt.GetRect();
500 0 : OutputDevice* pDev = rUDEvt.GetDevice();
501 0 : sal_uInt16 nItemId = rUDEvt.GetItemId();
502 0 : Point aBLPos = aRect.TopLeft();
503 :
504 0 : int nRectHeight = aRect.GetHeight();
505 0 : Size aSize(nRectHeight/8, nRectHeight/8);
506 :
507 0 : Graphic aGraphic;
508 0 : if(!GalleryExplorer::GetGraphicObj( GALLERY_THEME_BULLETS, nItemId - 1,
509 0 : &aGraphic, NULL))
510 : {
511 0 : bGrfNotFound = true;
512 : }
513 : else
514 : {
515 0 : Point aPos(aBLPos.X() + 5, 0);
516 0 : for( sal_uInt16 i = 0; i < 3; i++ )
517 : {
518 0 : sal_uInt16 nY = 11 + i * 33;
519 0 : aPos.Y() = aBLPos.Y() + nRectHeight * nY / 100;
520 0 : aGraphic.Draw( pDev, aPos, aSize );
521 : }
522 0 : }
523 0 : }
524 :
525 0 : IMPL_LINK_NOARG(SvxBmpNumValueSet, FormatHdl_Impl)
526 : {
527 : // only when a graphics was not there, it needs to be formatted
528 0 : if(bGrfNotFound)
529 : {
530 0 : bGrfNotFound = false;
531 0 : Format();
532 : }
533 0 : Invalidate();
534 0 : return 0;
535 : }
536 :
537 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|