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