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