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 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 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 } 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 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 452 SvxNumValueSet::~SvxNumValueSet() 453 { 454 delete pVDev; 455 } 456 /* -----------------------------30.01.01 16:24-------------------------------- 457 458 ---------------------------------------------------------------------------*/ 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 ---------------------------------------------------------------------------*/ 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 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 515 SvxBmpNumValueSet::~SvxBmpNumValueSet() 516 { 517 GalleryExplorer::EndLocking(GALLERY_THEME_BULLETS); 518 aFormatTimer.Stop(); 519 } 520 /*-----------------13.02.97 09.41------------------- 521 522 --------------------------------------------------*/ 523 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 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