1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svx.hxx"
26 #include <svx/dialmgr.hxx>
27 #ifndef _SVX_DIALOGS_HRC
28 #include <svx/dialogs.hrc>
29 #endif
30 #include <tools/shl.hxx>
31 #include <i18npool/mslangid.hxx>
32 #include <svtools/valueset.hxx>
33 #include <svl/languageoptions.hxx>
34 #ifndef _SVX_HELPID_HRC
35 #include <helpid.hrc>
36 #endif
37 #include <editeng/numitem.hxx>
38 #include <svl/eitem.hxx>
39 #include <vcl/svapp.hxx>
40 #include <svx/gallery.hxx>
41 #include <svl/urihelper.hxx>
42 #include <editeng/brshitem.hxx>
43 #include <svl/intitem.hxx>
44 #include <sfx2/objsh.hxx>
45 #include <vcl/graph.hxx>
46 #include <vcl/msgbox.hxx>
47 #include <editeng/flstitem.hxx>
48 #include <svx/dlgutil.hxx>
49 #ifndef _XTABLE_HXX //autogen
50
51 #include <svx/xtable.hxx>
52 #endif
53 #include <svx/drawitem.hxx>
54 #include <svx/numvset.hxx>
55 #include <svx/htmlmode.hxx>
56 #include <unotools/pathoptions.hxx>
57 #include <svtools/ctrltool.hxx>
58 #include <editeng/unolingu.hxx>
59 #include <com/sun/star/style/NumberingType.hpp>
60 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
61 #include <com/sun/star/container/XIndexAccess.hpp>
62 #include <com/sun/star/text/XDefaultNumberingProvider.hpp>
63 #include <com/sun/star/text/XNumberingFormatter.hpp>
64 #include <com/sun/star/beans/PropertyValue.hpp>
65 #include <comphelper/processfactory.hxx>
66 #include <com/sun/star/text/XNumberingTypeInfo.hpp>
67
68 #include <algorithm>
69 #include <sfx2/opengrf.hxx>
70
71 using namespace com::sun::star::uno;
72 using namespace com::sun::star::beans;
73 using namespace com::sun::star::lang;
74 using namespace com::sun::star::i18n;
75 using namespace com::sun::star::text;
76 using namespace com::sun::star::container;
77 using namespace com::sun::star::style;
78 using rtl::OUString;
79
80 #define C2U(cChar) OUString::createFromAscii(cChar)
81 #define NUM_PAGETYPE_BULLET 0
82 #define NUM_PAGETYPE_SINGLENUM 1
83 #define NUM_PAGETYPE_NUM 2
84 #define NUM_PAGETYPE_BMP 3
85 #define PAGETYPE_USER_START 10
86
87 #define SHOW_NUMBERING 0
88 #define SHOW_BULLET 1
89 #define SHOW_BITMAP 2
90
91 #define MAX_BMP_WIDTH 16
92 #define MAX_BMP_HEIGHT 16
93
94 static const sal_Char cNumberingType[] = "NumberingType";
95 static const sal_Char cValue[] = "Value";
96 static const sal_Char cParentNumbering[] = "ParentNumbering";
97 static const sal_Char cPrefix[] = "Prefix";
98 static const sal_Char cSuffix[] = "Suffix";
99 static const sal_Char cBulletChar[] = "BulletChar";
100 static const sal_Char cBulletFontName[] = "BulletFontName";
101
102 /* -----------------28.10.98 08:32-------------------
103 *
104 * --------------------------------------------------*/
105 // Die Auswahl an Bullets aus den StarSymbol
106 static const sal_Unicode aBulletTypes[] =
107 {
108 0x2022,
109 0x25cf,
110 0xe00c,
111 0xe00a,
112 0x2794,
113 0x27a2,
114 0x2717,
115 0x2714
116 };
117
lcl_GetDefaultBulletFont()118 static Font& lcl_GetDefaultBulletFont()
119 {
120 static sal_Bool bInit = 0;
121 static Font aDefBulletFont( UniString::CreateFromAscii(
122 RTL_CONSTASCII_STRINGPARAM( "StarSymbol" ) ),
123 String(), Size( 0, 14 ) );
124 if(!bInit)
125 {
126 aDefBulletFont.SetCharSet( RTL_TEXTENCODING_SYMBOL );
127 aDefBulletFont.SetFamily( FAMILY_DONTKNOW );
128 aDefBulletFont.SetPitch( PITCH_DONTKNOW );
129 aDefBulletFont.SetWeight( WEIGHT_DONTKNOW );
130 aDefBulletFont.SetTransparent( sal_True );
131 bInit = sal_True;
132 }
133 return aDefBulletFont;
134 }
135
lcl_PaintLevel(OutputDevice * pVDev,sal_Int16 nNumberingType,const OUString & rBulletChar,const OUString & rText,const OUString & rFontName,Point & rLeft,Font & rRuleFont,const Font & rTextFont)136 static void lcl_PaintLevel(OutputDevice* pVDev, sal_Int16 nNumberingType,
137 const OUString& rBulletChar, const OUString& rText, const OUString& rFontName,
138 Point& rLeft, Font& rRuleFont, const Font& rTextFont)
139 {
140
141 if(NumberingType::CHAR_SPECIAL == nNumberingType )
142 {
143 rRuleFont.SetStyleName(rFontName);
144 pVDev->SetFont(rRuleFont);
145 pVDev->DrawText(rLeft, rBulletChar);
146 rLeft.X() += pVDev->GetTextWidth(rBulletChar);
147 }
148 else
149 {
150 pVDev->SetFont(rTextFont);
151 pVDev->DrawText(rLeft, rText);
152 rLeft.X() += pVDev->GetTextWidth(rText);
153 }
154 }
UserDraw(const UserDrawEvent & rUDEvt)155 void SvxNumValueSet::UserDraw( const UserDrawEvent& rUDEvt )
156 {
157 static sal_uInt16 __READONLY_DATA aLinesArr[] =
158 {
159 15, 10,
160 20, 30,
161 25, 50,
162 30, 70,
163 35, 90, // up to here line positions
164 05, 10, // character positions
165 10, 30,
166 15, 50,
167 20, 70,
168 25, 90,
169 };
170
171 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
172 const Color aBackColor = rStyleSettings.GetFieldColor();
173 const Color aTextColor = rStyleSettings.GetFieldTextColor();
174
175 OutputDevice* pDev = rUDEvt.GetDevice();
176 Rectangle aRect = rUDEvt.GetRect();
177 sal_uInt16 nItemId = rUDEvt.GetItemId();
178 long nRectWidth = aRect.GetWidth();
179 long nRectHeight = aRect.GetHeight();
180 Size aRectSize(nRectWidth, aRect.GetHeight());
181 Point aBLPos = aRect.TopLeft();
182 Font aOldFont = pDev->GetFont();
183 Color aOldColor = pDev->GetLineColor();
184 pDev->SetLineColor(aTextColor);
185 Font aFont(OutputDevice::GetDefaultFont(
186 DEFAULTFONT_UI_SANS, MsLangId::getSystemLanguage(), DEFAULTFONT_FLAGS_ONLYONE));
187
188 Size aSize = aFont.GetSize();
189
190 Font aRuleFont( lcl_GetDefaultBulletFont() );
191 aSize.Height() = nRectHeight/6;
192 aRuleFont.SetSize(aSize);
193 aRuleFont.SetColor(aTextColor);
194 aRuleFont.SetFillColor(aBackColor);
195 if(nPageType == NUM_PAGETYPE_BULLET)
196 aFont = aRuleFont;
197 else if(nPageType == NUM_PAGETYPE_NUM)
198 {
199 aSize.Height() = nRectHeight/8;
200 }
201 aFont.SetColor(aTextColor);
202 aFont.SetFillColor(aBackColor);
203 aFont.SetSize( aSize );
204 pDev->SetFont(aFont);
205
206 if(!pVDev)
207 {
208 // Die Linien werden nur einmalig in das VirtualDevice gepainted
209 // nur die Gliederungspage bekommt es aktuell
210 pVDev = new VirtualDevice(*pDev);
211 pVDev->SetMapMode(pDev->GetMapMode());
212 pVDev->EnableRTL( IsRTLEnabled() );
213 pVDev->SetOutputSize( aRectSize );
214 aOrgRect = aRect;
215 pVDev->SetFillColor( aBackColor );
216 pVDev->DrawRect(aOrgRect);
217
218 if(aBackColor == aLineColor)
219 aLineColor.Invert();
220 pVDev->SetLineColor(aLineColor);
221 // Linien nur einmalig Zeichnen
222 if(nPageType != NUM_PAGETYPE_NUM)
223 {
224 Point aStart(aBLPos.X() + nRectWidth *25 / 100,0);
225 Point aEnd(aBLPos.X() + nRectWidth * 9 / 10,0);
226 for( sal_uInt16 i = 11; i < 100; i += 33)
227 {
228 aStart.Y() = aEnd.Y() = aBLPos.Y() + nRectHeight * i / 100;
229 pVDev->DrawLine(aStart, aEnd);
230 aStart.Y() = aEnd.Y() = aBLPos.Y() + nRectHeight * (i + 11) / 100;
231 pVDev->DrawLine(aStart, aEnd);
232 }
233 }
234 }
235 pDev->DrawOutDev( aRect.TopLeft(), aRectSize,
236 aOrgRect.TopLeft(), aRectSize,
237 *pVDev );
238 // jetzt kommt der Text
239 const OUString sValue(C2U(cValue));
240 if( NUM_PAGETYPE_SINGLENUM == nPageType ||
241 NUM_PAGETYPE_BULLET == nPageType )
242 {
243 Point aStart(aBLPos.X() + nRectWidth / 9,0);
244 for( sal_uInt16 i = 0; i < 3; i++ )
245 {
246 sal_uInt16 nY = 11 + i * 33;
247 aStart.Y() = aBLPos.Y() + nRectHeight * nY / 100;
248 String sText;
249 if(nPageType == NUM_PAGETYPE_BULLET)
250 {
251 sText = aBulletTypes[nItemId - 1];
252 aStart.Y() -= pDev->GetTextHeight()/2;
253 aStart.X() = aBLPos.X() + 5;
254 }
255 else
256 {
257 if(xFormatter.is() && aNumSettings.getLength() > nItemId - 1)
258 {
259 Sequence<PropertyValue> aLevel = aNumSettings.getConstArray()[nItemId - 1];
260 try
261 {
262 aLevel.realloc(aLevel.getLength() + 1);
263 PropertyValue& rValue = aLevel.getArray()[aLevel.getLength() - 1];
264 rValue.Name = sValue;
265 rValue.Value <<= (sal_Int32)(i + 1);
266 sText = xFormatter->makeNumberingString( aLevel, aLocale );
267 }
268 catch(Exception&)
269 {
270 DBG_ERROR("Exception in DefaultNumberingProvider::makeNumberingString");
271 }
272 }
273 // knapp neben dem linken Rand beginnen
274 aStart.X() = aBLPos.X() + 2;
275 aStart.Y() -= pDev->GetTextHeight()/2;
276 }
277 pDev->DrawText(aStart, sText);
278 }
279 }
280 else if(NUM_PAGETYPE_NUM == nPageType )
281 {
282 // Outline numbering has to be painted into the virtual device
283 // to get correct lines
284 // has to be made again
285 pVDev->DrawRect(aOrgRect);
286 long nStartX = aOrgRect.TopLeft().X();
287 long nStartY = aOrgRect.TopLeft().Y();
288
289 if(xFormatter.is() && aOutlineSettings.getLength() > nItemId - 1)
290 {
291 Reference<XIndexAccess> xLevel = aOutlineSettings.getArray()[nItemId - 1];
292 try
293 {
294 OUString sLevelTexts[5];
295 OUString sFontNames[5];
296 OUString sBulletChars[5];
297 sal_Int16 aNumberingTypes[5];
298 OUString sPrefixes[5];
299 OUString sSuffixes[5];
300 sal_Int16 aParentNumberings[5];
301
302 sal_Int32 nLevelCount = xLevel->getCount();
303 if(nLevelCount > 5)
304 nLevelCount = 5;
305 for( sal_Int32 i = 0; i < nLevelCount && i < 5; i++)
306 {
307 long nTop = nStartY + nRectHeight * (aLinesArr[2 * i + 11])/100 ;
308 Point aLeft(nStartX + nRectWidth * (aLinesArr[2 * i + 10])/ 100, nTop );
309
310 Any aLevelAny = xLevel->getByIndex(i);
311 Sequence<PropertyValue> aLevel;
312 aLevelAny >>= aLevel;
313 const PropertyValue* pValues = aLevel.getConstArray();
314 aNumberingTypes[i] = 0;
315 for(sal_Int32 nProperty = 0; nProperty < aLevel.getLength() - 1; nProperty++)
316 {
317 if(pValues[nProperty].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cNumberingType)))
318 pValues[nProperty].Value >>= aNumberingTypes[i];
319 else if(pValues[nProperty].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cBulletFontName)))
320 pValues[nProperty].Value >>= sFontNames[i];
321 else if(pValues[nProperty].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cBulletChar)))
322 pValues[nProperty].Value >>= sBulletChars[i];
323 else if(pValues[nProperty].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cPrefix)))
324 pValues[nProperty].Value >>= sPrefixes[i];
325 else if(pValues[nProperty].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cSuffix)))
326 pValues[nProperty].Value >>= sSuffixes[i];
327 else if(pValues[nProperty].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cParentNumbering)))
328 pValues[nProperty].Value >>= aParentNumberings[i];
329 }
330 Sequence< PropertyValue > aProperties(2);
331 PropertyValue* pProperties = aProperties.getArray();
332 pProperties[0].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("NumberingType"));
333 pProperties[0].Value <<= aNumberingTypes[i];
334 pProperties[1].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Value"));
335 pProperties[1].Value <<= (sal_Int32)1;
336 try
337 {
338 sLevelTexts[i] = xFormatter->makeNumberingString( aProperties, aLocale );
339 }
340 catch(Exception&)
341 {
342 DBG_ERROR("Exception in DefaultNumberingProvider::makeNumberingString");
343 }
344
345 aLeft.Y() -= (pDev->GetTextHeight()/2);
346 if(sPrefixes[i].getLength() &&
347 !sPrefixes[i].equalsAsciiL(" ", 1) &&
348 sPrefixes[i].getStr()[0] != 0)
349 {
350 pVDev->SetFont(aFont);
351 pVDev->DrawText(aLeft, sPrefixes[i]);
352 aLeft.X() += pDev->GetTextWidth(sPrefixes[i]);
353 }
354 if(aParentNumberings[i])
355 {
356 //insert old numberings here
357 sal_Int32 nStartLevel = std::min((sal_Int32)aParentNumberings[i], i);
358 for(sal_Int32 nParentLevel = i - nStartLevel; nParentLevel < i; nParentLevel++)
359 {
360 OUString sTmp(sLevelTexts[nParentLevel]);
361 sTmp += C2U(".");
362 lcl_PaintLevel(pVDev,
363 aNumberingTypes[nParentLevel],
364 sBulletChars[nParentLevel],
365 sTmp,
366 sFontNames[nParentLevel],
367 aLeft,
368 aRuleFont,
369 aFont);
370 }
371 }
372 lcl_PaintLevel(pVDev,
373 aNumberingTypes[i],
374 sBulletChars[i],
375 sLevelTexts[i],
376 sFontNames[i],
377 aLeft,
378 aRuleFont,
379 aFont);
380 if(sSuffixes[i].getLength()&&
381 !sSuffixes[i].equalsAsciiL(" ", 1) &&
382 sSuffixes[i].getStr()[0] != 0)
383 {
384 pVDev->SetFont(aFont);
385 pVDev->DrawText(aLeft, sSuffixes[i]);
386 aLeft.X() += pDev->GetTextWidth(sSuffixes[i]);
387 }
388
389 long nLineTop = nStartY + nRectHeight * aLinesArr[2 * i + 1]/100 ;
390 Point aLineLeft(aLeft.X() /*+ nStartX + nRectWidth * aLinesArr[2 * i]/ 100*/, nLineTop );
391 Point aLineRight(nStartX + nRectWidth * 90 /100, nLineTop );
392 pVDev->DrawLine(aLineLeft, aLineRight);
393 }
394
395 }
396 #ifdef DBG_UTIL
397 catch(Exception&)
398 {
399 static sal_Bool bAssert = sal_False;
400 if(!bAssert)
401 {
402 DBG_ERROR("exception in ::UserDraw");
403 bAssert = sal_True;
404 }
405 }
406 #else
407 catch(Exception&)
408 {
409 }
410 #endif
411 }
412 pDev->DrawOutDev( aRect.TopLeft(), aRectSize,
413 aOrgRect.TopLeft(), aRectSize,
414 *pVDev );
415 }
416
417 pDev->SetFont(aOldFont);
418 pDev->SetLineColor(aOldColor);
419 }
420
421 /**************************************************************************/
422 /* */
423 /* */
424 /**************************************************************************/
425
SvxNumValueSet(Window * pParent,const ResId & rResId,sal_uInt16 nType)426 SvxNumValueSet::SvxNumValueSet( Window* pParent, const ResId& rResId, sal_uInt16 nType ) :
427
428 ValueSet( pParent, rResId ),
429
430 aLineColor ( COL_LIGHTGRAY ),
431 nPageType ( nType ),
432 bHTMLMode ( sal_False ),
433 pVDev ( NULL )
434 {
435 SetColCount( 4 );
436 SetLineCount( 2 );
437 SetStyle( GetStyle() | WB_ITEMBORDER | WB_DOUBLEBORDER );
438 if(NUM_PAGETYPE_BULLET == nType)
439 {
440 for ( sal_uInt16 i = 0; i < 8; i++ )
441 {
442 InsertItem( i + 1, i );
443 SetItemText( i + 1, SVX_RESSTR( RID_SVXSTR_BULLET_DESCRIPTIONS + i ) );
444 }
445 }
446 }
447
448 /*-----------------08.02.97 12.38-------------------
449
450 --------------------------------------------------*/
451
~SvxNumValueSet()452 SvxNumValueSet::~SvxNumValueSet()
453 {
454 delete pVDev;
455 }
456 /* -----------------------------30.01.01 16:24--------------------------------
457
458 ---------------------------------------------------------------------------*/
SetNumberingSettings(const Sequence<Sequence<PropertyValue>> & aNum,Reference<XNumberingFormatter> & xFormat,const Locale & rLocale)459 void SvxNumValueSet::SetNumberingSettings(
460 const Sequence<Sequence<PropertyValue> >& aNum,
461 Reference<XNumberingFormatter>& xFormat,
462 const Locale& rLocale )
463 {
464 aNumSettings = aNum;
465 xFormatter = xFormat;
466 aLocale = rLocale;
467 if(aNum.getLength() > 8)
468 SetStyle( GetStyle()|WB_VSCROLL);
469 for ( sal_uInt16 i = 0; i < aNum.getLength(); i++ )
470 {
471 InsertItem( i + 1, i );
472 if( i < 8 )
473 SetItemText( i + 1, SVX_RESSTR( RID_SVXSTR_SINGLENUM_DESCRIPTIONS + i ));
474 }
475 }
476 /* -----------------------------31.01.01 09:50--------------------------------
477
478 ---------------------------------------------------------------------------*/
SetOutlineNumberingSettings(Sequence<Reference<XIndexAccess>> & rOutline,Reference<XNumberingFormatter> & xFormat,const Locale & rLocale)479 void SvxNumValueSet::SetOutlineNumberingSettings(
480 Sequence<Reference<XIndexAccess> >& rOutline,
481 Reference<XNumberingFormatter>& xFormat,
482 const Locale& rLocale)
483 {
484 aOutlineSettings = rOutline;
485 xFormatter = xFormat;
486 aLocale = rLocale;
487 if(aOutlineSettings.getLength() > 8)
488 SetStyle( GetStyle() | WB_VSCROLL );
489 for ( sal_uInt16 i = 0; i < aOutlineSettings.getLength(); i++ )
490 {
491 InsertItem( i + 1, i );
492 if( i < 8 )
493 SetItemText( i + 1, SVX_RESSTR( RID_SVXSTR_OUTLINENUM_DESCRIPTIONS + i ));
494 }
495 }
496
SvxBmpNumValueSet(Window * pParent,const ResId & rResId)497 SvxBmpNumValueSet::SvxBmpNumValueSet( Window* pParent, const ResId& rResId/*, const List& rStrNames*/ ) :
498
499 SvxNumValueSet( pParent, rResId, NUM_PAGETYPE_BMP ),
500 // rStrList ( rStrNames ),
501 bGrfNotFound( sal_False )
502
503 {
504 GalleryExplorer::BeginLocking(GALLERY_THEME_BULLETS);
505 SetStyle( GetStyle() | WB_VSCROLL );
506 SetLineCount( 3 );
507 aFormatTimer.SetTimeout(300);
508 aFormatTimer.SetTimeoutHdl(LINK(this, SvxBmpNumValueSet, FormatHdl_Impl));
509 }
510
511 /*-----------------13.02.97 09.41-------------------
512
513 --------------------------------------------------*/
514
~SvxBmpNumValueSet()515 SvxBmpNumValueSet::~SvxBmpNumValueSet()
516 {
517 GalleryExplorer::EndLocking(GALLERY_THEME_BULLETS);
518 aFormatTimer.Stop();
519 }
520 /*-----------------13.02.97 09.41-------------------
521
522 --------------------------------------------------*/
523
UserDraw(const UserDrawEvent & rUDEvt)524 void SvxBmpNumValueSet::UserDraw( const UserDrawEvent& rUDEvt )
525 {
526 SvxNumValueSet::UserDraw(rUDEvt);
527
528 Rectangle aRect = rUDEvt.GetRect();
529 OutputDevice* pDev = rUDEvt.GetDevice();
530 sal_uInt16 nItemId = rUDEvt.GetItemId();
531 Point aBLPos = aRect.TopLeft();
532
533 int nRectHeight = aRect.GetHeight();
534 Size aSize(nRectHeight/8, nRectHeight/8);
535
536 Graphic aGraphic;
537 if(!GalleryExplorer::GetGraphicObj( GALLERY_THEME_BULLETS, nItemId - 1,
538 &aGraphic, NULL))
539 {
540 bGrfNotFound = sal_True;
541 }
542 else
543 {
544 Point aPos(aBLPos.X() + 5, 0);
545 for( sal_uInt16 i = 0; i < 3; i++ )
546 {
547 sal_uInt16 nY = 11 + i * 33;
548 aPos.Y() = aBLPos.Y() + nRectHeight * nY / 100;
549 aGraphic.Draw( pDev, aPos, aSize );
550 }
551 }
552 }
553
554 /*-----------------14.02.97 07.34-------------------
555
556 --------------------------------------------------*/
557
IMPL_LINK(SvxBmpNumValueSet,FormatHdl_Impl,Timer *,EMPTYARG)558 IMPL_LINK(SvxBmpNumValueSet, FormatHdl_Impl, Timer*, EMPTYARG)
559 {
560 // nur, wenn eine Grafik nicht da war, muss formatiert werden
561 if(bGrfNotFound)
562 {
563 bGrfNotFound = sal_False;
564 Format();
565 }
566 Invalidate();
567 return 0;
568 }
569