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 27 // include --------------------------------------------------------------- 28 29 #include <stdio.h> 30 31 #define _SVX_CHARMAP_CXX_ 32 #include <vcl/svapp.hxx> 33 #include <svtools/colorcfg.hxx> 34 35 #include <rtl/textenc.h> 36 #include <svx/ucsubset.hxx> 37 38 #include <svx/dialogs.hrc> 39 40 #include <svx/charmap.hxx> 41 #include <svx/dialmgr.hxx> 42 #include <svx/svxdlg.hxx> 43 44 #include "charmapacc.hxx" 45 #include <com/sun/star/accessibility/AccessibleEventObject.hpp> 46 #include <com/sun/star/accessibility/AccessibleEventId.hpp> 47 #include <com/sun/star/accessibility/AccessibleStateType.hpp> 48 #include <comphelper/types.hxx> 49 #include <svl/itemset.hxx> 50 51 #include "rtl/ustrbuf.hxx" 52 53 using namespace ::com::sun::star::accessibility; 54 using namespace ::com::sun::star::uno; 55 using namespace ::com::sun::star; 56 57 // ----------------------------------------------------------------------- 58 sal_uInt32& SvxShowCharSet::getSelectedChar() 59 { 60 static sal_uInt32 cSelectedChar = ' '; // keeps selected character over app livetime 61 return cSelectedChar; 62 } 63 64 // class SvxShowCharSet ================================================== 65 66 #define SBWIDTH 16 67 68 SvxShowCharSet::SvxShowCharSet( Window* pParent, const ResId& rResId ) : 69 Control( pParent, rResId ) 70 ,m_pAccessible(NULL) 71 ,aVscrollSB( this, WB_VERT) 72 { 73 nSelectedIndex = -1; // TODO: move into init list when it is no longer static 74 75 aOrigSize = GetOutputSizePixel(); 76 aOrigPos = GetPosPixel(); 77 78 SetStyle( GetStyle() | WB_CLIPCHILDREN ); 79 aVscrollSB.SetScrollHdl( LINK( this, SvxShowCharSet, VscrollHdl ) ); 80 aVscrollSB.EnableDrag( sal_True ); 81 // other settings like aVscroll depend on selected font => see SetFont 82 83 bDrag = sal_False; 84 InitSettings( sal_True, sal_True ); 85 } 86 87 // ----------------------------------------------------------------------- 88 89 void SvxShowCharSet::GetFocus() 90 { 91 Control::GetFocus(); 92 SelectIndex( nSelectedIndex, sal_True ); 93 } 94 95 // ----------------------------------------------------------------------- 96 97 void SvxShowCharSet::LoseFocus() 98 { 99 Control::LoseFocus(); 100 SelectIndex( nSelectedIndex, sal_False ); 101 } 102 103 // ----------------------------------------------------------------------- 104 105 void SvxShowCharSet::StateChanged( StateChangedType nType ) 106 { 107 if ( nType == STATE_CHANGE_CONTROLFOREGROUND ) 108 InitSettings( sal_True, sal_False ); 109 else if ( nType == STATE_CHANGE_CONTROLBACKGROUND ) 110 InitSettings( sal_False, sal_True ); 111 112 Control::StateChanged( nType ); 113 } 114 115 // ----------------------------------------------------------------------- 116 117 void SvxShowCharSet::DataChanged( const DataChangedEvent& rDCEvt ) 118 { 119 if ( ( rDCEvt.GetType() == DATACHANGED_SETTINGS ) 120 && ( rDCEvt.GetFlags() & SETTINGS_STYLE ) ) 121 InitSettings( sal_True, sal_True ); 122 else 123 Control::DataChanged( rDCEvt ); 124 } 125 126 // ----------------------------------------------------------------------- 127 128 void SvxShowCharSet::MouseButtonDown( const MouseEvent& rMEvt ) 129 { 130 if ( rMEvt.IsLeft() ) 131 { 132 if ( rMEvt.GetClicks() == 1 ) 133 { 134 GrabFocus(); 135 bDrag = sal_True; 136 CaptureMouse(); 137 138 int nIndex = PixelToMapIndex( rMEvt.GetPosPixel() ); 139 SelectIndex( nIndex ); 140 } 141 142 if ( !(rMEvt.GetClicks() % 2) ) 143 aDoubleClkHdl.Call( this ); 144 } 145 } 146 147 // ----------------------------------------------------------------------- 148 149 void SvxShowCharSet::MouseButtonUp( const MouseEvent& rMEvt ) 150 { 151 if ( bDrag && rMEvt.IsLeft() ) 152 { 153 // released mouse over character map 154 if ( Rectangle(Point(), GetOutputSize()).IsInside(rMEvt.GetPosPixel())) 155 aSelectHdl.Call( this ); 156 ReleaseMouse(); 157 bDrag = sal_False; 158 } 159 } 160 161 // ----------------------------------------------------------------------- 162 163 void SvxShowCharSet::MouseMove( const MouseEvent& rMEvt ) 164 { 165 if ( rMEvt.IsLeft() && bDrag ) 166 { 167 Point aPos = rMEvt.GetPosPixel(); 168 Size aSize = GetSizePixel(); 169 170 if ( aPos.X() < 0 ) 171 aPos.X() = 0; 172 else if ( aPos.X() > aSize.Width()-5 ) 173 aPos.X() = aSize.Width()-5; 174 if ( aPos.Y() < 0 ) 175 aPos.Y() = 0; 176 else if ( aPos.Y() > aSize.Height()-5 ) 177 aPos.Y() = aSize.Height()-5; 178 179 int nIndex = PixelToMapIndex( aPos ); 180 SelectIndex( nIndex ); 181 } 182 } 183 184 // ----------------------------------------------------------------------- 185 186 void SvxShowCharSet::Command( const CommandEvent& rCEvt ) 187 { 188 if( !HandleScrollCommand( rCEvt, 0, &aVscrollSB ) ) 189 Control::Command( rCEvt ); 190 } 191 192 // ----------------------------------------------------------------------------- 193 194 sal_uInt16 SvxShowCharSet::GetRowPos(sal_uInt16 _nPos) const 195 { 196 return _nPos / COLUMN_COUNT ; 197 } 198 199 // ----------------------------------------------------------------------------- 200 201 sal_uInt16 SvxShowCharSet::GetColumnPos(sal_uInt16 _nPos) const 202 { 203 return _nPos % COLUMN_COUNT ; 204 } 205 206 // ----------------------------------------------------------------------- 207 208 int SvxShowCharSet::FirstInView( void ) const 209 { 210 int nIndex = 0; 211 if( aVscrollSB.IsVisible() ) 212 nIndex += aVscrollSB.GetThumbPos() * COLUMN_COUNT; 213 return nIndex; 214 } 215 216 // ----------------------------------------------------------------------- 217 218 int SvxShowCharSet::LastInView( void ) const 219 { 220 sal_uIntPtr nIndex = FirstInView(); 221 nIndex += ROW_COUNT * COLUMN_COUNT - 1; 222 sal_uIntPtr nCompare = sal::static_int_cast<sal_uIntPtr>( maFontCharMap.GetCharCount() - 1 ); 223 if( nIndex > nCompare ) 224 nIndex = nCompare; 225 return nIndex; 226 } 227 228 // ----------------------------------------------------------------------- 229 230 inline Point SvxShowCharSet::MapIndexToPixel( int nIndex ) const 231 { 232 const int nBase = FirstInView(); 233 int x = ((nIndex - nBase) % COLUMN_COUNT) * nX; 234 int y = ((nIndex - nBase) / COLUMN_COUNT) * nY; 235 return Point( x, y ); 236 } 237 // ----------------------------------------------------------------------------- 238 239 int SvxShowCharSet::PixelToMapIndex( const Point& point) const 240 { 241 int nBase = FirstInView(); 242 return (nBase + (point.X()/nX) + (point.Y()/nY) * COLUMN_COUNT); 243 } 244 245 // ----------------------------------------------------------------------- 246 247 void SvxShowCharSet::KeyInput( const KeyEvent& rKEvt ) 248 { 249 KeyCode aCode = rKEvt.GetKeyCode(); 250 251 if( aCode.GetModifier() ) 252 { 253 Control::KeyInput( rKEvt ); 254 return; 255 } 256 257 int tmpSelected = nSelectedIndex; 258 259 switch ( aCode.GetCode() ) 260 { 261 case KEY_SPACE: 262 aSelectHdl.Call( this ); 263 break; 264 case KEY_LEFT: 265 --tmpSelected; 266 break; 267 case KEY_RIGHT: 268 ++tmpSelected; 269 break; 270 case KEY_UP: 271 tmpSelected -= COLUMN_COUNT; 272 break; 273 case KEY_DOWN: 274 tmpSelected += COLUMN_COUNT; 275 break; 276 case KEY_PAGEUP: 277 tmpSelected -= ROW_COUNT * COLUMN_COUNT; 278 break; 279 case KEY_PAGEDOWN: 280 tmpSelected += ROW_COUNT * COLUMN_COUNT; 281 break; 282 case KEY_HOME: 283 tmpSelected = 0; 284 break; 285 case KEY_END: 286 tmpSelected = maFontCharMap.GetCharCount() - 1; 287 break; 288 case KEY_TAB: // some fonts have a character at these unicode control codes 289 case KEY_ESCAPE: 290 case KEY_RETURN: 291 Control::KeyInput( rKEvt ); 292 tmpSelected = - 1; // mark as invalid 293 break; 294 default: 295 { 296 sal_UCS4 cChar = rKEvt.GetCharCode(); 297 sal_UCS4 cNext = maFontCharMap.GetNextChar( cChar - 1 ); 298 tmpSelected = maFontCharMap.GetIndexFromChar( cNext ); 299 if( tmpSelected < 0 || (cChar != cNext) ) 300 { 301 Control::KeyInput( rKEvt ); 302 tmpSelected = - 1; // mark as invalid 303 } 304 } 305 } 306 307 if ( tmpSelected >= 0 ) 308 { 309 SelectIndex( tmpSelected, sal_True ); 310 aPreSelectHdl.Call( this ); 311 } 312 } 313 314 // ----------------------------------------------------------------------- 315 316 void SvxShowCharSet::Paint( const Rectangle& ) 317 { 318 DrawChars_Impl( FirstInView(), LastInView() ); 319 } 320 // ----------------------------------------------------------------------------- 321 void SvxShowCharSet::DeSelect() 322 { 323 DrawChars_Impl(nSelectedIndex,nSelectedIndex); 324 } 325 // ----------------------------------------------------------------------- 326 327 void SvxShowCharSet::DrawChars_Impl( int n1, int n2 ) 328 { 329 if( n1 > LastInView() || n2 < FirstInView() ) 330 return; 331 332 Size aOutputSize = GetOutputSizePixel(); 333 if( aVscrollSB.IsVisible() ) 334 aOutputSize.setWidth( aOutputSize.Width() - SBWIDTH ); 335 336 int i; 337 for ( i = 1; i < COLUMN_COUNT; ++i ) 338 DrawLine( Point( nX * i, 0 ), Point( nX * i, aOutputSize.Height() ) ); 339 for ( i = 1; i < ROW_COUNT; ++i ) 340 DrawLine( Point( 0, nY * i ), Point( aOutputSize.Width(), nY * i ) ); 341 342 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings(); 343 const Color aWindowTextColor( rStyleSettings.GetFieldTextColor() ); 344 Color aHighlightColor( rStyleSettings.GetHighlightColor() ); 345 Color aHighlightTextColor( rStyleSettings.GetHighlightTextColor() ); 346 Color aFaceColor( rStyleSettings.GetFaceColor() ); 347 Color aLightColor( rStyleSettings.GetLightColor() ); 348 Color aShadowColor( rStyleSettings.GetShadowColor() ); 349 350 int nTextHeight = GetTextHeight(); 351 Rectangle aBoundRect; 352 for( i = n1; i <= n2; ++i ) 353 { 354 Point pix = MapIndexToPixel( i ); 355 int x = pix.X(); 356 int y = pix.Y(); 357 358 rtl::OUStringBuffer buf; 359 buf.appendUtf32( maFontCharMap.GetCharFromIndex( i ) ); 360 String aCharStr(buf.makeStringAndClear()); 361 int nTextWidth = GetTextWidth(aCharStr); 362 int tx = x + (nX - nTextWidth + 1) / 2; 363 int ty = y + (nY - nTextHeight + 1) / 2; 364 Point aPointTxTy( tx, ty ); 365 366 // adjust position before it gets out of bounds 367 if( GetTextBoundRect( aBoundRect, aCharStr ) && !aBoundRect.IsEmpty() ) 368 { 369 // zero advance width => use ink width to center glyph 370 if( !nTextWidth ) 371 { 372 aPointTxTy.X() = x - aBoundRect.Left() 373 + (nX - aBoundRect.GetWidth() + 1) / 2; 374 } 375 376 aBoundRect += aPointTxTy; 377 378 // shift back vertically if needed 379 int nYLDelta = aBoundRect.Top() - y; 380 int nYHDelta = (y + nY) - aBoundRect.Bottom(); 381 if( nYLDelta <= 0 ) 382 aPointTxTy.Y() -= nYLDelta - 1; 383 else if( nYHDelta <= 0 ) 384 aPointTxTy.Y() += nYHDelta - 1; 385 386 // shift back horizontally if needed 387 int nXLDelta = aBoundRect.Left() - x; 388 int nXHDelta = (x + nX) - aBoundRect.Right(); 389 if( nXLDelta <= 0 ) 390 aPointTxTy.X() -= nXLDelta - 1; 391 else if( nXHDelta <= 0 ) 392 aPointTxTy.X() += nXHDelta - 1; 393 } 394 395 Color aTextCol = GetTextColor(); 396 if ( i != nSelectedIndex ) 397 { 398 SetTextColor( aWindowTextColor ); 399 DrawText( aPointTxTy, aCharStr ); 400 } 401 else 402 { 403 Color aLineCol = GetLineColor(); 404 Color aFillCol = GetFillColor(); 405 SetLineColor(); 406 Point aPointUL( x + 1, y + 1 ); 407 if( HasFocus() ) 408 { 409 SetFillColor( aHighlightColor ); 410 DrawRect( Rectangle( aPointUL, Size(nX-1,nY-1) ) ); 411 412 SetTextColor( aHighlightTextColor ); 413 DrawText( aPointTxTy, aCharStr ); 414 } 415 else 416 { 417 SetFillColor( aFaceColor ); 418 DrawRect( Rectangle( aPointUL, Size( nX-1, nY-1) ) ); 419 420 SetLineColor( aLightColor ); 421 DrawLine( aPointUL, Point( x+nX-1, y+1) ); 422 DrawLine( aPointUL, Point( x+1, y+nY-1) ); 423 424 SetLineColor( aShadowColor ); 425 DrawLine( Point( x+1, y+nY-1), Point( x+nX-1, y+nY-1) ); 426 DrawLine( Point( x+nX-1, y+nY-1), Point( x+nX-1, y+1) ); 427 428 DrawText( aPointTxTy, aCharStr ); 429 } 430 SetLineColor( aLineCol ); 431 SetFillColor( aFillCol ); 432 } 433 SetTextColor( aTextCol ); 434 } 435 } 436 437 // ----------------------------------------------------------------------- 438 439 void SvxShowCharSet::InitSettings( sal_Bool bForeground, sal_Bool bBackground ) 440 { 441 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings(); 442 443 if ( bForeground ) 444 { 445 Color aTextColor( rStyleSettings.GetDialogTextColor() ); 446 447 if ( IsControlForeground() ) 448 aTextColor = GetControlForeground(); 449 SetTextColor( aTextColor ); 450 } 451 452 if ( bBackground ) 453 { 454 if ( IsControlBackground() ) 455 SetBackground( GetControlBackground() ); 456 else 457 SetBackground( rStyleSettings.GetWindowColor() ); 458 } 459 460 Invalidate(); 461 } 462 463 // ----------------------------------------------------------------------- 464 465 sal_UCS4 SvxShowCharSet::GetSelectCharacter() const 466 { 467 if( nSelectedIndex >= 0 ) 468 getSelectedChar() = maFontCharMap.GetCharFromIndex( nSelectedIndex ); 469 return getSelectedChar(); 470 } 471 472 // ----------------------------------------------------------------------- 473 474 void SvxShowCharSet::SetFont( const Font& rFont ) 475 { 476 // save last selected unicode 477 if( nSelectedIndex >= 0 ) 478 getSelectedChar() = maFontCharMap.GetCharFromIndex( nSelectedIndex ); 479 480 Font aFont = rFont; 481 aFont.SetWeight( WEIGHT_LIGHT ); 482 aFont.SetAlign( ALIGN_TOP ); 483 int nFontHeight = (aOrigSize.Height() - 5) * 2 / (3 * ROW_COUNT); 484 aFont.SetSize( PixelToLogic( Size( 0, nFontHeight ) ) ); 485 aFont.SetTransparent( sal_True ); 486 Control::SetFont( aFont ); 487 GetFontCharMap( maFontCharMap ); 488 489 // hide scrollbar when there is nothing to scroll 490 sal_Bool bNeedVscroll = (maFontCharMap.GetCharCount() > ROW_COUNT*COLUMN_COUNT); 491 492 nX = (aOrigSize.Width() - (bNeedVscroll ? SBWIDTH : 0)) / COLUMN_COUNT; 493 nY = aOrigSize.Height() / ROW_COUNT; 494 495 if( bNeedVscroll) 496 { 497 aVscrollSB.SetPosSizePixel( nX * COLUMN_COUNT, 0, SBWIDTH, nY * ROW_COUNT ); 498 aVscrollSB.SetRangeMin( 0 ); 499 int nLastRow = (maFontCharMap.GetCharCount() - 1 + COLUMN_COUNT) / COLUMN_COUNT; 500 aVscrollSB.SetRangeMax( nLastRow ); 501 aVscrollSB.SetPageSize( ROW_COUNT-1 ); 502 aVscrollSB.SetVisibleSize( ROW_COUNT ); 503 } 504 505 // restore last selected unicode 506 int nMapIndex = maFontCharMap.GetIndexFromChar( getSelectedChar() ); 507 SelectIndex( nMapIndex ); 508 509 // rearrange CharSet element in sync with nX- and nY-multiples 510 Size aNewSize( nX * COLUMN_COUNT + (bNeedVscroll ? SBWIDTH : 0), nY * ROW_COUNT ); 511 Point aNewPos = aOrigPos + Point( (aOrigSize.Width() - aNewSize.Width()) / 2, 0 ); 512 SetPosPixel( aNewPos ); 513 SetOutputSizePixel( aNewSize ); 514 515 aVscrollSB.Show( bNeedVscroll ); 516 Invalidate(); 517 } 518 519 // ----------------------------------------------------------------------- 520 521 void SvxShowCharSet::SelectIndex( int nNewIndex, sal_Bool bFocus ) 522 { 523 if( nNewIndex < 0 ) 524 { 525 // need to scroll see closest unicode 526 sal_uInt32 cPrev = maFontCharMap.GetPrevChar( getSelectedChar() ); 527 int nMapIndex = maFontCharMap.GetIndexFromChar( cPrev ); 528 int nNewPos = nMapIndex / COLUMN_COUNT; 529 aVscrollSB.SetThumbPos( nNewPos ); 530 nSelectedIndex = bFocus ? nMapIndex+1 : -1; 531 Invalidate(); 532 Update(); 533 } 534 else if( nNewIndex < FirstInView() ) 535 { 536 // need to scroll up to see selected item 537 int nOldPos = aVscrollSB.GetThumbPos(); 538 int nDelta = (FirstInView() - nNewIndex + COLUMN_COUNT-1) / COLUMN_COUNT; 539 aVscrollSB.SetThumbPos( nOldPos - nDelta ); 540 nSelectedIndex = nNewIndex; 541 Invalidate(); 542 if( nDelta ) 543 Update(); 544 } 545 else if( nNewIndex > LastInView() ) 546 { 547 // need to scroll down to see selected item 548 int nOldPos = aVscrollSB.GetThumbPos(); 549 int nDelta = (nNewIndex - LastInView() + COLUMN_COUNT) / COLUMN_COUNT; 550 aVscrollSB.SetThumbPos( nOldPos + nDelta ); 551 if( nNewIndex < maFontCharMap.GetCharCount() ) 552 { 553 nSelectedIndex = nNewIndex; 554 Invalidate(); 555 } 556 if( nOldPos != aVscrollSB.GetThumbPos() ) 557 { 558 Invalidate(); 559 Update(); 560 } 561 } 562 else 563 { 564 // remove highlighted view 565 Color aLineCol = GetLineColor(); 566 Color aFillCol = GetFillColor(); 567 SetLineColor(); 568 SetFillColor( GetBackground().GetColor() ); 569 570 Point aOldPixel = MapIndexToPixel( nSelectedIndex ); 571 aOldPixel.Move( +1, +1); 572 DrawRect( Rectangle( aOldPixel, Size( nX-1, nY-1 ) ) ); 573 SetLineColor( aLineCol ); 574 SetFillColor( aFillCol ); 575 576 int nOldIndex = nSelectedIndex; 577 nSelectedIndex = nNewIndex; 578 DrawChars_Impl( nOldIndex, nOldIndex ); 579 DrawChars_Impl( nNewIndex, nNewIndex ); 580 } 581 582 if( nSelectedIndex >= 0 ) 583 { 584 getSelectedChar() = maFontCharMap.GetCharFromIndex( nSelectedIndex ); 585 if( m_pAccessible ) 586 { 587 ::svx::SvxShowCharSetItem* pItem = ImplGetItem(nSelectedIndex); 588 m_pAccessible->fireEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, Any(), makeAny(pItem->GetAccessible()) ); // this call asures that m_pItem is set 589 590 OSL_ENSURE(pItem->m_pItem,"No accessible created!"); 591 Any aOldAny, aNewAny; 592 aNewAny <<= AccessibleStateType::FOCUSED; 593 pItem->m_pItem->fireEvent( AccessibleEventId::STATE_CHANGED, aOldAny, aNewAny ); 594 595 aNewAny <<= AccessibleStateType::SELECTED; 596 pItem->m_pItem->fireEvent( AccessibleEventId::STATE_CHANGED, aOldAny, aNewAny ); 597 } 598 } 599 600 601 aHighHdl.Call( this ); 602 } 603 604 // ----------------------------------------------------------------------- 605 606 void SvxShowCharSet::SelectCharacter( sal_UCS4 cNew, sal_Bool bFocus ) 607 { 608 // get next available char of current font 609 sal_UCS4 cNext = maFontCharMap.GetNextChar( cNew - 1 ); 610 611 int nMapIndex = maFontCharMap.GetIndexFromChar( cNext ); 612 SelectIndex( nMapIndex, bFocus ); 613 if( !bFocus ) 614 { 615 // move selected item to top row if not in focus 616 aVscrollSB.SetThumbPos( nMapIndex / COLUMN_COUNT ); 617 Invalidate(); 618 } 619 } 620 621 // ----------------------------------------------------------------------- 622 623 IMPL_LINK( SvxShowCharSet, VscrollHdl, ScrollBar *, EMPTYARG ) 624 { 625 if( nSelectedIndex < FirstInView() ) 626 { 627 SelectIndex( FirstInView() + (nSelectedIndex % COLUMN_COUNT) ); 628 } 629 else if( nSelectedIndex > LastInView() ) 630 { 631 if( m_pAccessible ) 632 { 633 ::com::sun::star::uno::Any aOldAny, aNewAny; 634 int nLast = LastInView(); 635 for ( ; nLast != nSelectedIndex; ++nLast) 636 { 637 aOldAny <<= ImplGetItem(nLast)->GetAccessible(); 638 m_pAccessible ->fireEvent( AccessibleEventId::CHILD, aOldAny, aNewAny ); 639 } 640 } 641 SelectIndex( (LastInView() - COLUMN_COUNT + 1) + (nSelectedIndex % COLUMN_COUNT) ); 642 } 643 644 Invalidate(); 645 return 0; 646 } 647 648 // ----------------------------------------------------------------------- 649 650 SvxShowCharSet::~SvxShowCharSet() 651 { 652 if ( m_pAccessible ) 653 ReleaseAccessible(); 654 } 655 // ----------------------------------------------------------------------------- 656 void SvxShowCharSet::ReleaseAccessible() 657 { 658 m_aItems.clear(); 659 m_pAccessible = NULL; 660 m_xAccessible = NULL; 661 } 662 // ----------------------------------------------------------------------------- 663 ::com::sun::star::uno::Reference< XAccessible > SvxShowCharSet::CreateAccessible() 664 { 665 OSL_ENSURE(!m_pAccessible,"Accessible already created!"); 666 m_pAccessible = new ::svx::SvxShowCharSetVirtualAcc(this); 667 m_xAccessible = m_pAccessible; 668 return m_xAccessible; 669 } 670 // ----------------------------------------------------------------------------- 671 ::svx::SvxShowCharSetItem* SvxShowCharSet::ImplGetItem( int _nPos ) 672 { 673 ItemsMap::iterator aFind = m_aItems.find(_nPos); 674 if ( aFind == m_aItems.end() ) 675 { 676 OSL_ENSURE(m_pAccessible,"Who wants to create a child of my table without a parent?"); 677 aFind = m_aItems.insert(ItemsMap::value_type(_nPos,new ::svx::SvxShowCharSetItem(*this,m_pAccessible->getTable(),sal::static_int_cast< sal_uInt16 >(_nPos)))).first; 678 rtl::OUStringBuffer buf; 679 buf.appendUtf32( maFontCharMap.GetCharFromIndex( _nPos ) ); 680 aFind->second->maText = buf.makeStringAndClear(); 681 Point pix = MapIndexToPixel( _nPos ); 682 aFind->second->maRect = Rectangle( Point( pix.X() + 1, pix.Y() + 1 ), Size(nX-1,nY-1) ); 683 } 684 685 return aFind->second; 686 } 687 // ----------------------------------------------------------------------------- 688 void SvxShowCharSet::ImplFireAccessibleEvent( short nEventId, const ::com::sun::star::uno::Any& rOldValue, const ::com::sun::star::uno::Any& rNewValue ) 689 { 690 if( m_pAccessible ) 691 m_pAccessible->fireEvent( nEventId, rOldValue, rNewValue ); 692 } 693 // ----------------------------------------------------------------------------- 694 ScrollBar* SvxShowCharSet::getScrollBar() 695 { 696 return &aVscrollSB; 697 } 698 // ----------------------------------------------------------------------- 699 sal_Int32 SvxShowCharSet::getMaxCharCount() const 700 { 701 return maFontCharMap.GetCharCount(); 702 } 703 704 705 // class SubsetMap ======================================================= 706 // TODO: should be moved into Font Attributes stuff 707 // we let it mature here though because it is currently the only use 708 709 SubsetMap::SubsetMap( const FontCharMap* pFontCharMap ) 710 : Resource( SVX_RES(RID_SUBSETMAP) ) 711 { 712 InitList(); 713 ApplyCharMap( pFontCharMap ); 714 FreeResource(); 715 } 716 717 const Subset* SubsetMap::GetNextSubset( bool bFirst ) const 718 { 719 if( bFirst ) 720 maSubsetIterator = maSubsets.begin(); 721 if( maSubsetIterator == maSubsets.end() ) 722 return NULL; 723 const Subset* s = &*(maSubsetIterator++); 724 return s; 725 } 726 727 const Subset* SubsetMap::GetSubsetByUnicode( sal_UCS4 cChar ) const 728 { 729 // TODO: is it worth to avoid a linear search? 730 for( const Subset* s = GetNextSubset( true ); s; s = GetNextSubset( false ) ) 731 if( (s->GetRangeMin() <= cChar) && (cChar <= s->GetRangeMax()) ) 732 return s; 733 return NULL; 734 } 735 736 inline Subset::Subset( sal_UCS4 nMin, sal_UCS4 nMax, int resId) 737 : mnRangeMin(nMin), mnRangeMax(nMax), maRangeName( SVX_RES(resId) ) 738 {} 739 740 void SubsetMap::InitList() 741 { 742 static SubsetList aAllSubsets; 743 static bool bInit = true; 744 if( bInit ) 745 { 746 bInit = false; 747 748 // TODO: eventually merge or split unicode subranges 749 // a "native writer" should decide for his subsets 750 aAllSubsets.push_back( Subset( 0x0020, 0x007F, RID_SUBSETSTR_BASIC_LATIN ) ); 751 aAllSubsets.push_back( Subset( 0x0080, 0x00FF, RID_SUBSETSTR_LATIN_1 ) ); 752 aAllSubsets.push_back( Subset( 0x0100, 0x017F, RID_SUBSETSTR_LATIN_EXTENDED_A ) ); 753 aAllSubsets.push_back( Subset( 0x0180, 0x024F, RID_SUBSETSTR_LATIN_EXTENDED_B ) ); 754 aAllSubsets.push_back( Subset( 0x0250, 0x02AF, RID_SUBSETSTR_IPA_EXTENSIONS ) ); 755 aAllSubsets.push_back( Subset( 0x02B0, 0x02FF, RID_SUBSETSTR_SPACING_MODIFIERS ) ); 756 aAllSubsets.push_back( Subset( 0x0300, 0x036F, RID_SUBSETSTR_COMB_DIACRITICAL ) ); 757 aAllSubsets.push_back( Subset( 0x0370, 0x03FF, RID_SUBSETSTR_BASIC_GREEK ) ); 758 // aAllSubsets.push_back( Subset( 0x03D0, 0x03F3, RID_SUBSETSTR_GREEK_SYMS_COPTIC ) ); 759 aAllSubsets.push_back( Subset( 0x0400, 0x04FF, RID_SUBSETSTR_CYRILLIC ) ); 760 aAllSubsets.push_back( Subset( 0x0530, 0x058F, RID_SUBSETSTR_ARMENIAN ) ); 761 aAllSubsets.push_back( Subset( 0x0590, 0x05FF, RID_SUBSETSTR_BASIC_HEBREW ) ); 762 // aAllSubsets.push_back( Subset( 0x0591, 0x05C4, RID_SUBSETSTR_HEBREW_EXTENDED ) ); 763 aAllSubsets.push_back( Subset( 0x0600, 0x065F, RID_SUBSETSTR_BASIC_ARABIC ) ); 764 aAllSubsets.push_back( Subset( 0x0660, 0x06FF, RID_SUBSETSTR_ARABIC_EXTENDED ) ); 765 aAllSubsets.push_back( Subset( 0x0700, 0x074F, RID_SUBSETSTR_SYRIAC ) ); 766 aAllSubsets.push_back( Subset( 0x0780, 0x07BF, RID_SUBSETSTR_THAANA ) ); 767 aAllSubsets.push_back( Subset( 0x0900, 0x097F, RID_SUBSETSTR_DEVANAGARI ) ); 768 aAllSubsets.push_back( Subset( 0x0980, 0x09FF, RID_SUBSETSTR_BENGALI ) ); 769 aAllSubsets.push_back( Subset( 0x0A00, 0x0A7F, RID_SUBSETSTR_GURMUKHI ) ); 770 aAllSubsets.push_back( Subset( 0x0A80, 0x0AFF, RID_SUBSETSTR_GUJARATI ) ); 771 aAllSubsets.push_back( Subset( 0x0B00, 0x0B7F, RID_SUBSETSTR_ORIYA ) ); 772 aAllSubsets.push_back( Subset( 0x0B80, 0x0BFF, RID_SUBSETSTR_TAMIL ) ); 773 aAllSubsets.push_back( Subset( 0x0C00, 0x0C7F, RID_SUBSETSTR_TELUGU ) ); 774 aAllSubsets.push_back( Subset( 0x0C80, 0x0CFF, RID_SUBSETSTR_KANNADA ) ); 775 aAllSubsets.push_back( Subset( 0x0D00, 0x0D7F, RID_SUBSETSTR_MALAYALAM ) ); 776 aAllSubsets.push_back( Subset( 0x0D80, 0x0DFF, RID_SUBSETSTR_SINHALA ) ); 777 aAllSubsets.push_back( Subset( 0x0E00, 0x0E7F, RID_SUBSETSTR_THAI ) ); 778 aAllSubsets.push_back( Subset( 0x0E80, 0x0EFF, RID_SUBSETSTR_LAO ) ); 779 aAllSubsets.push_back( Subset( 0x0F00, 0x0FBF, RID_SUBSETSTR_TIBETAN ) ); 780 aAllSubsets.push_back( Subset( 0x1000, 0x109F, RID_SUBSETSTR_MYANMAR ) ); 781 aAllSubsets.push_back( Subset( 0x10A0, 0x10FF, RID_SUBSETSTR_BASIC_GEORGIAN ) ); 782 // aAllSubsets.push_back( Subset( 0x10A0, 0x10C5, RID_SUBSETSTR_GEORGIAN_EXTENDED ) ); 783 aAllSubsets.push_back( Subset( 0x1100, 0x11FF, RID_SUBSETSTR_HANGUL_JAMO ) ); 784 aAllSubsets.push_back( Subset( 0x1200, 0x137F, RID_SUBSETSTR_ETHIOPIC ) ); 785 aAllSubsets.push_back( Subset( 0x13A0, 0x13FF, RID_SUBSETSTR_CHEROKEE ) ); 786 aAllSubsets.push_back( Subset( 0x1400, 0x167F, RID_SUBSETSTR_CANADIAN_ABORIGINAL ) ); 787 aAllSubsets.push_back( Subset( 0x1680, 0x169F, RID_SUBSETSTR_OGHAM ) ); 788 aAllSubsets.push_back( Subset( 0x16A0, 0x16F0, RID_SUBSETSTR_RUNIC ) ); 789 aAllSubsets.push_back( Subset( 0x1700, 0x171F, RID_SUBSETSTR_TAGALOG ) ); 790 aAllSubsets.push_back( Subset( 0x1720, 0x173F, RID_SUBSETSTR_HANUNOO ) ); 791 aAllSubsets.push_back( Subset( 0x1740, 0x175F, RID_SUBSETSTR_BUHID ) ); 792 aAllSubsets.push_back( Subset( 0x1760, 0x177F, RID_SUBSETSTR_TAGBANWA ) ); 793 aAllSubsets.push_back( Subset( 0x1780, 0x17FF, RID_SUBSETSTR_KHMER ) ); 794 aAllSubsets.push_back( Subset( 0x1800, 0x18AF, RID_SUBSETSTR_MONGOLIAN ) ); 795 aAllSubsets.push_back( Subset( 0x1E00, 0x1EFF, RID_SUBSETSTR_LATIN_EXTENDED_ADDS ) ); 796 aAllSubsets.push_back( Subset( 0x1F00, 0x1FFF, RID_SUBSETSTR_GREEK_EXTENDED ) ); 797 798 aAllSubsets.push_back( Subset( 0x2000, 0x206F, RID_SUBSETSTR_GENERAL_PUNCTUATION ) ); 799 aAllSubsets.push_back( Subset( 0x2070, 0x209F, RID_SUBSETSTR_SUB_SUPER_SCRIPTS ) ); 800 aAllSubsets.push_back( Subset( 0x20A0, 0x20CF, RID_SUBSETSTR_CURRENCY_SYMBOLS ) ); 801 aAllSubsets.push_back( Subset( 0x20D0, 0x20FF, RID_SUBSETSTR_COMB_DIACRITIC_SYMS ) ); 802 aAllSubsets.push_back( Subset( 0x2100, 0x214F, RID_SUBSETSTR_LETTERLIKE_SYMBOLS ) ); 803 aAllSubsets.push_back( Subset( 0x2150, 0x218F, RID_SUBSETSTR_NUMBER_FORMS ) ); 804 aAllSubsets.push_back( Subset( 0x2190, 0x21FF, RID_SUBSETSTR_ARROWS ) ); 805 aAllSubsets.push_back( Subset( 0x2200, 0x22FF, RID_SUBSETSTR_MATH_OPERATORS ) ); 806 aAllSubsets.push_back( Subset( 0x2300, 0x23FF, RID_SUBSETSTR_MISC_TECHNICAL ) ); 807 aAllSubsets.push_back( Subset( 0x2400, 0x243F, RID_SUBSETSTR_CONTROL_PICTURES ) ); 808 aAllSubsets.push_back( Subset( 0x2440, 0x245F, RID_SUBSETSTR_OPTICAL_CHAR_REC ) ); 809 aAllSubsets.push_back( Subset( 0x2460, 0x24FF, RID_SUBSETSTR_ENCLOSED_ALPHANUM ) ); 810 aAllSubsets.push_back( Subset( 0x2500, 0x257F, RID_SUBSETSTR_BOX_DRAWING ) ); 811 aAllSubsets.push_back( Subset( 0x2580, 0x259F, RID_SUBSETSTR_BLOCK_ELEMENTS ) ); 812 aAllSubsets.push_back( Subset( 0x25A0, 0x25FF, RID_SUBSETSTR_GEOMETRIC_SHAPES ) ); 813 aAllSubsets.push_back( Subset( 0x2600, 0x26FF, RID_SUBSETSTR_MISC_DINGBATS ) ); 814 aAllSubsets.push_back( Subset( 0x2700, 0x27BF, RID_SUBSETSTR_DINGBATS ) ); 815 816 aAllSubsets.push_back( Subset( 0x27C0, 0x27FF, RID_SUBSETSTR_MISC_MATH_SYMS_A ) ); 817 aAllSubsets.push_back( Subset( 0x27F0, 0x27FF, RID_SUBSETSTR_SUPPL_ARROWS_A ) ); 818 aAllSubsets.push_back( Subset( 0x2800, 0x28FF, RID_SUBSETSTR_BRAILLE_PATTERNS ) ); 819 aAllSubsets.push_back( Subset( 0x2900, 0x297F, RID_SUBSETSTR_SUPPL_ARROWS_B ) ); 820 aAllSubsets.push_back( Subset( 0x2980, 0x29FF, RID_SUBSETSTR_MISC_MATH_SYMS_B ) ); 821 aAllSubsets.push_back( Subset( 0x2E80, 0x2EFF, RID_SUBSETSTR_CJK_RADICAL_SUPPL ) ); 822 aAllSubsets.push_back( Subset( 0x2F00, 0x2FDF, RID_SUBSETSTR_KANXI_RADICALS ) ); 823 aAllSubsets.push_back( Subset( 0x2FF0, 0x2FFF, RID_SUBSETSTR_IDEO_DESC_CHARS ) ); 824 825 aAllSubsets.push_back( Subset( 0x3000, 0x303F, RID_SUBSETSTR_CJK_SYMS_PUNCTUATION ) ); 826 aAllSubsets.push_back( Subset( 0x3040, 0x309F, RID_SUBSETSTR_HIRAGANA ) ); 827 aAllSubsets.push_back( Subset( 0x30A0, 0x30FF, RID_SUBSETSTR_KATAKANA ) ); 828 aAllSubsets.push_back( Subset( 0x3100, 0x312F, RID_SUBSETSTR_BOPOMOFO ) ); 829 aAllSubsets.push_back( Subset( 0x3130, 0x318F, RID_SUBSETSTR_HANGUL_COMPAT_JAMO ) ); 830 aAllSubsets.push_back( Subset( 0x3190, 0x319F, RID_SUBSETSTR_KANBUN ) ); 831 aAllSubsets.push_back( Subset( 0x31A0, 0x31BF, RID_SUBSETSTR_BOPOMOFO_EXTENDED ) ); 832 aAllSubsets.push_back( Subset( 0x31C0, 0x31FF, RID_SUBSETSTR_KATAKANA_PHONETIC ) ); 833 aAllSubsets.push_back( Subset( 0x3200, 0x32FF, RID_SUBSETSTR_ENCLOSED_CJK_LETTERS ) ); 834 aAllSubsets.push_back( Subset( 0x3300, 0x33FF, RID_SUBSETSTR_CJK_COMPATIBILITY ) ); 835 836 aAllSubsets.push_back( Subset( 0x3400, 0x4DFF, RID_SUBSETSTR_CJK_EXT_A_UNIFIED_IDGRAPH ) ); 837 aAllSubsets.push_back( Subset( 0x4E00, 0x9FA5, RID_SUBSETSTR_CJK_UNIFIED_IDGRAPH ) ); 838 aAllSubsets.push_back( Subset( 0xA000, 0xA4CF, RID_SUBSETSTR_YI ) ); 839 aAllSubsets.push_back( Subset( 0xAC00, 0xB097, RID_SUBSETSTR_HANGUL_GA ) ); 840 aAllSubsets.push_back( Subset( 0xB098, 0xB2E3, RID_SUBSETSTR_HANGUL_NA ) ); 841 aAllSubsets.push_back( Subset( 0xB2E4, 0xB77B, RID_SUBSETSTR_HANGUL_DA ) ); 842 aAllSubsets.push_back( Subset( 0xB77C, 0xB9C7, RID_SUBSETSTR_HANGUL_RA ) ); 843 aAllSubsets.push_back( Subset( 0xB9C8, 0xBC13, RID_SUBSETSTR_HANGUL_MA ) ); 844 aAllSubsets.push_back( Subset( 0xBC14, 0xC0AB, RID_SUBSETSTR_HANGUL_BA ) ); 845 aAllSubsets.push_back( Subset( 0xC0AC, 0xC543, RID_SUBSETSTR_HANGUL_SA ) ); 846 aAllSubsets.push_back( Subset( 0xC544, 0xC78F, RID_SUBSETSTR_HANGUL_AH ) ); 847 aAllSubsets.push_back( Subset( 0xC790, 0xCC27, RID_SUBSETSTR_HANGUL_JA ) ); 848 aAllSubsets.push_back( Subset( 0xCC28, 0xCE73, RID_SUBSETSTR_HANGUL_CHA ) ); 849 aAllSubsets.push_back( Subset( 0xCE74, 0xD0BF, RID_SUBSETSTR_HANGUL_KA ) ); 850 aAllSubsets.push_back( Subset( 0xD0C0, 0xD30B, RID_SUBSETSTR_HANGUL_TA ) ); 851 aAllSubsets.push_back( Subset( 0xD30C, 0xD557, RID_SUBSETSTR_HANGUL_PA ) ); 852 aAllSubsets.push_back( Subset( 0xD558, 0xD7A3, RID_SUBSETSTR_HANGUL_HA ) ); 853 // aAllSubsets.push_back( Subset( 0xAC00, 0xD7AF, RID_SUBSETSTR_HANGUL ) ); 854 855 // aAllSubsets.push_back( Subset( 0xD800, 0xDFFF, RID_SUBSETSTR_SURROGATE ) ); 856 aAllSubsets.push_back( Subset( 0xE000, 0xF8FF, RID_SUBSETSTR_PRIVATE_USE_AREA ) ); 857 aAllSubsets.push_back( Subset( 0xF900, 0xFAFF, RID_SUBSETSTR_CJK_COMPAT_IDGRAPHS ) ); 858 aAllSubsets.push_back( Subset( 0xFB00, 0xFB4F, RID_SUBSETSTR_ALPHA_PRESENTATION ) ); 859 aAllSubsets.push_back( Subset( 0xFB50, 0xFDFF, RID_SUBSETSTR_ARABIC_PRESENT_A ) ); 860 aAllSubsets.push_back( Subset( 0xFE20, 0xFE2F, RID_SUBSETSTR_COMBINING_HALF_MARKS ) ); 861 aAllSubsets.push_back( Subset( 0xFE30, 0xFE4F, RID_SUBSETSTR_CJK_COMPAT_FORMS ) ); 862 aAllSubsets.push_back( Subset( 0xFE50, 0xFE6F, RID_SUBSETSTR_SMALL_FORM_VARIANTS ) ); 863 aAllSubsets.push_back( Subset( 0xFE70, 0xFEFF, RID_SUBSETSTR_ARABIC_PRESENT_B ) ); 864 aAllSubsets.push_back( Subset( 0xFF00, 0xFFEF, RID_SUBSETSTR_HALFW_FULLW_FORMS ) ); 865 aAllSubsets.push_back( Subset( 0xFFF0, 0xFFFF, RID_SUBSETSTR_SPECIALS ) ); 866 } 867 868 maSubsets = aAllSubsets; 869 } 870 871 void SubsetMap::ApplyCharMap( const FontCharMap* pFontCharMap ) 872 { 873 if( !pFontCharMap ) 874 return; 875 876 // remove subsets that are not matched in any range 877 SubsetList::iterator it_next = maSubsets.begin(); 878 while( it_next != maSubsets.end() ) 879 { 880 SubsetList::iterator it = it_next++; 881 const Subset& rSubset = *it; 882 sal_uInt32 cMin = rSubset.GetRangeMin(); 883 sal_uInt32 cMax = rSubset.GetRangeMax(); 884 885 int nCount = pFontCharMap->CountCharsInRange( cMin, cMax ); 886 if( nCount <= 0 ) 887 maSubsets.erase( it ); 888 } 889 } 890