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 31 #include <svx/dialogs.hrc> 32 33 34 #include <tools/list.hxx> 35 #include <sfx2/viewsh.hxx> 36 #include <sfx2/objsh.hxx> 37 #include <sfx2/dispatch.hxx> 38 #include <vcl/image.hxx> 39 40 #include <svx/colrctrl.hxx> 41 42 #include <svx/svdview.hxx> 43 #include "svx/drawitem.hxx" 44 #include <editeng/colritem.hxx> 45 #include "svx/xattr.hxx" 46 #include <svx/xtable.hxx> 47 #include <svx/dialmgr.hxx> 48 #include "svx/xexch.hxx" 49 #include <vcl/svapp.hxx> 50 51 SFX_IMPL_DOCKINGWINDOW( SvxColorChildWindow, SID_COLOR_CONTROL ) 52 53 // ------------------------ 54 // - SvxColorValueSetData - 55 // ------------------------ 56 57 class SvxColorValueSetData : public TransferableHelper 58 { 59 private: 60 61 XFillExchangeData maData; 62 63 protected: 64 65 virtual void AddSupportedFormats(); 66 virtual sal_Bool GetData( const ::com::sun::star::datatransfer::DataFlavor& rFlavor ); 67 virtual sal_Bool WriteObject( SotStorageStreamRef& rxOStm, void* pUserObject, sal_uInt32 nUserObjectId, const ::com::sun::star::datatransfer::DataFlavor& rFlavor ); 68 69 public: 70 71 SvxColorValueSetData( const XFillAttrSetItem& rSetItem ) : 72 maData( rSetItem ) {} 73 }; 74 75 // ----------------------------------------------------------------------------- 76 77 void SvxColorValueSetData::AddSupportedFormats() 78 { 79 AddFormat( SOT_FORMATSTR_ID_XFA ); 80 } 81 82 // ----------------------------------------------------------------------------- 83 84 sal_Bool SvxColorValueSetData::GetData( const ::com::sun::star::datatransfer::DataFlavor& rFlavor ) 85 { 86 sal_Bool bRet = sal_False; 87 88 if( SotExchange::GetFormat( rFlavor ) == SOT_FORMATSTR_ID_XFA ) 89 { 90 SetObject( &maData, 0, rFlavor ); 91 bRet = sal_True; 92 } 93 94 return bRet; 95 } 96 97 // ----------------------------------------------------------------------------- 98 99 sal_Bool SvxColorValueSetData::WriteObject( SotStorageStreamRef& rxOStm, void*, sal_uInt32 , const ::com::sun::star::datatransfer::DataFlavor& ) 100 { 101 *rxOStm << maData; 102 return( rxOStm->GetError() == ERRCODE_NONE ); 103 } 104 105 /************************************************************************* 106 |* 107 |* SvxColorValueSet: Ctor 108 |* 109 \************************************************************************/ 110 111 SvxColorValueSet::SvxColorValueSet( Window* _pParent, WinBits nWinStyle ) : 112 ValueSet( _pParent, nWinStyle ), 113 DragSourceHelper( this ), 114 bLeft (sal_True) 115 { 116 SetAccessibleName(String( SVX_RES( STR_COLORTABLE ) ) ); 117 } 118 119 /************************************************************************* 120 |* 121 |* SvxColorValueSet: Ctor 122 |* 123 \************************************************************************/ 124 125 SvxColorValueSet::SvxColorValueSet( Window* _pParent, const ResId& rResId ) : 126 ValueSet( _pParent, rResId ), 127 DragSourceHelper( this ), 128 bLeft (sal_True) 129 { 130 SetAccessibleName(String( SVX_RES( STR_COLORTABLE ) )); 131 } 132 133 /************************************************************************* 134 |* 135 |* SvxColorValueSet: MouseButtonDown 136 |* 137 \************************************************************************/ 138 139 void SvxColorValueSet::MouseButtonDown( const MouseEvent& rMEvt ) 140 { 141 // Fuer Mac noch anders handlen ! 142 if( rMEvt.IsLeft() ) 143 { 144 bLeft = sal_True; 145 ValueSet::MouseButtonDown( rMEvt ); 146 } 147 else 148 { 149 bLeft = sal_False; 150 MouseEvent aMEvt( rMEvt.GetPosPixel(), 151 rMEvt.GetClicks(), 152 rMEvt.GetMode(), 153 MOUSE_LEFT, 154 rMEvt.GetModifier() ); 155 ValueSet::MouseButtonDown( aMEvt ); 156 } 157 158 aDragPosPixel = GetPointerPosPixel(); 159 } 160 161 /************************************************************************* 162 |* 163 |* SvxColorValueSet: MouseButtonUp 164 |* 165 \************************************************************************/ 166 167 void SvxColorValueSet::MouseButtonUp( const MouseEvent& rMEvt ) 168 { 169 // Fuer Mac noch anders handlen ! 170 if( rMEvt.IsLeft() ) 171 { 172 bLeft = sal_True; 173 ValueSet::MouseButtonUp( rMEvt ); 174 } 175 else 176 { 177 bLeft = sal_False; 178 MouseEvent aMEvt( rMEvt.GetPosPixel(), 179 rMEvt.GetClicks(), 180 rMEvt.GetMode(), 181 MOUSE_LEFT, 182 rMEvt.GetModifier() ); 183 ValueSet::MouseButtonUp( aMEvt ); 184 } 185 SetNoSelection(); 186 } 187 188 /************************************************************************* 189 |* 190 |* Command-Event 191 |* 192 \************************************************************************/ 193 194 void SvxColorValueSet::Command(const CommandEvent& rCEvt) 195 { 196 // Basisklasse 197 ValueSet::Command(rCEvt); 198 } 199 200 /************************************************************************* 201 |* 202 |* StartDrag 203 |* 204 \************************************************************************/ 205 206 void SvxColorValueSet::StartDrag( sal_Int8 , const Point& ) 207 { 208 Application::PostUserEvent(STATIC_LINK(this, SvxColorValueSet, ExecDragHdl)); 209 } 210 211 /************************************************************************* 212 |* 213 |* Drag&Drop asynchron ausfuehren 214 |* 215 \************************************************************************/ 216 217 void SvxColorValueSet::DoDrag() 218 { 219 SfxObjectShell* pDocSh = SfxObjectShell::Current(); 220 sal_uInt16 nItemId = GetItemId( aDragPosPixel ); 221 222 if( pDocSh && nItemId ) 223 { 224 XFillAttrSetItem aXFillSetItem( &pDocSh->GetPool() ); 225 SfxItemSet& rSet = aXFillSetItem.GetItemSet(); 226 227 rSet.Put( XFillColorItem( GetItemText( nItemId ), GetItemColor( nItemId ) ) ); 228 rSet.Put(XFillStyleItem( ( 1 == nItemId ) ? XFILL_NONE : XFILL_SOLID ) ); 229 230 EndSelection(); 231 ( new SvxColorValueSetData( aXFillSetItem ) )->StartDrag( this, DND_ACTION_COPY ); 232 ReleaseMouse(); 233 } 234 } 235 236 /************************************************************************* 237 |* 238 |* 239 |* 240 \************************************************************************/ 241 242 IMPL_STATIC_LINK(SvxColorValueSet, ExecDragHdl, void*, EMPTYARG) 243 { 244 // Als Link, damit asynchron ohne ImpMouseMoveMsg auf dem Stack auch die 245 // Farbleiste geloescht werden darf 246 pThis->DoDrag(); 247 return(0); 248 } 249 250 /************************************************************************* 251 |* 252 |* Ableitung vom SfxChildWindow als "Behaelter" fuer Animator 253 |* 254 \************************************************************************/ 255 256 SvxColorChildWindow::SvxColorChildWindow( Window* _pParent, 257 sal_uInt16 nId, 258 SfxBindings* pBindings, 259 SfxChildWinInfo* pInfo ) : 260 SfxChildWindow( _pParent, nId ) 261 { 262 SvxColorDockingWindow* pWin = new SvxColorDockingWindow( pBindings, this, 263 _pParent, SVX_RES( RID_SVXCTRL_COLOR ) ); 264 pWindow = pWin; 265 266 eChildAlignment = SFX_ALIGN_BOTTOM; 267 268 pWin->Initialize( pInfo ); 269 } 270 271 272 273 /************************************************************************* 274 |* 275 |* Ctor: SvxColorDockingWindow 276 |* 277 \************************************************************************/ 278 279 SvxColorDockingWindow::SvxColorDockingWindow 280 ( 281 SfxBindings* _pBindings, 282 SfxChildWindow* pCW, 283 Window* _pParent, 284 const ResId& rResId 285 ) : 286 287 SfxDockingWindow( _pBindings, pCW, _pParent, rResId ), 288 289 pColorTable ( NULL ), 290 aColorSet ( this, ResId( 1, *rResId.GetResMgr() ) ), 291 nLeftSlot ( SID_ATTR_FILL_COLOR ), 292 nRightSlot ( SID_ATTR_LINE_COLOR ), 293 nCols ( 20 ), 294 nLines ( 1 ), 295 aColorSize ( 14, 14 ) 296 297 { 298 FreeResource(); 299 300 aColorSet.SetStyle( aColorSet.GetStyle() | WB_ITEMBORDER ); 301 aColorSet.SetSelectHdl( LINK( this, SvxColorDockingWindow, SelectHdl ) ); 302 303 // Get the model from the view shell. Using SfxObjectShell::Current() 304 // is unreliable when called at the wrong times. 305 SfxObjectShell* pDocSh = NULL; 306 if (_pBindings != NULL) 307 { 308 SfxDispatcher* pDispatcher = _pBindings->GetDispatcher(); 309 if (pDispatcher != NULL) 310 { 311 SfxViewFrame* pFrame = pDispatcher->GetFrame(); 312 if (pFrame != NULL) 313 { 314 SfxViewShell* pViewShell = pFrame->GetViewShell(); 315 if (pViewShell != NULL) 316 pDocSh = pViewShell->GetObjectShell(); 317 } 318 } 319 } 320 321 if ( pDocSh ) 322 { 323 const SfxPoolItem* pItem = pDocSh->GetItem( SID_COLOR_TABLE ); 324 if( pItem ) 325 { 326 pColorTable = ( (SvxColorTableItem*) pItem )->GetColorTable(); 327 FillValueSet(); 328 } 329 } 330 aItemSize = aColorSet.CalcItemSizePixel( aColorSize ); 331 aItemSize.Width() = aItemSize.Width() + aColorSize.Width(); 332 aItemSize.Width() /= 2; 333 aItemSize.Height() = aItemSize.Height() + aColorSize.Height(); 334 aItemSize.Height() /= 2; 335 336 SetSize(); 337 aColorSet.Show(); 338 StartListening( *_pBindings, sal_True ); 339 } 340 341 342 /************************************************************************* 343 |* 344 |* Dtor: SvxColorDockingWindow 345 |* 346 \************************************************************************/ 347 348 SvxColorDockingWindow::~SvxColorDockingWindow() 349 { 350 EndListening( GetBindings() ); 351 } 352 353 /************************************************************************* 354 |* 355 |* Notify 356 |* 357 \************************************************************************/ 358 359 void SvxColorDockingWindow::Notify( SfxBroadcaster& , const SfxHint& rHint ) 360 { 361 const SfxPoolItemHint *pPoolItemHint = PTR_CAST(SfxPoolItemHint, &rHint); 362 if ( pPoolItemHint 363 && ( pPoolItemHint->GetObject()->ISA( SvxColorTableItem ) ) ) 364 { 365 // Die Liste der Farben hat sich geaendert 366 pColorTable = ( (SvxColorTableItem*) pPoolItemHint->GetObject() )->GetColorTable(); 367 FillValueSet(); 368 } 369 } 370 371 /************************************************************************* 372 |* 373 |* FillValueSet 374 |* 375 \************************************************************************/ 376 377 void SvxColorDockingWindow::FillValueSet() 378 { 379 if( pColorTable ) 380 { 381 aColorSet.Clear(); 382 383 // Erster Eintrag: unsichtbar 384 long nPtX = aColorSize.Width() - 1; 385 long nPtY = aColorSize.Height() - 1; 386 VirtualDevice aVD; 387 aVD.SetOutputSizePixel( aColorSize ); 388 aVD.SetLineColor( Color( COL_BLACK ) ); 389 aVD.SetBackground( Wallpaper( Color( COL_WHITE ) ) ); 390 aVD.DrawLine( Point(), Point( nPtX, nPtY ) ); 391 aVD.DrawLine( Point( 0, nPtY ), Point( nPtX, 0 ) ); 392 393 Bitmap aBmp( aVD.GetBitmap( Point(), aColorSize ) ); 394 395 aColorSet.InsertItem( (sal_uInt16)1, Image(aBmp), SVX_RESSTR( RID_SVXSTR_INVISIBLE ) ); 396 397 XColorEntry* pEntry; 398 nCount = pColorTable->Count(); 399 400 for( long i = 0; i < nCount; i++ ) 401 { 402 pEntry = pColorTable->GetColor( i ); 403 aColorSet.InsertItem( (sal_uInt16)i+2, 404 pEntry->GetColor(), pEntry->GetName() ); 405 } 406 } 407 } 408 409 /************************************************************************* 410 |* 411 |* SetSize 412 |* 413 \************************************************************************/ 414 415 void SvxColorDockingWindow::SetSize() 416 { 417 // Groesse fuer ValueSet berechnen 418 Size aSize = GetOutputSizePixel(); 419 aSize.Width() -= 4; 420 aSize.Height() -= 4; 421 422 // Zeilen und Spalten berechnen 423 nCols = (sal_uInt16) ( aSize.Width() / aItemSize.Width() ); 424 nLines = (sal_uInt16) ( (float) aSize.Height() / (float) aItemSize.Height() /*+ 0.35*/ ); 425 if( nLines == 0 ) 426 nLines++; 427 428 // Scrollbar setzen/entfernen 429 WinBits nBits = aColorSet.GetStyle(); 430 if ( nLines * nCols >= nCount ) 431 nBits &= ~WB_VSCROLL; 432 else 433 nBits |= WB_VSCROLL; 434 aColorSet.SetStyle( nBits ); 435 436 // ScrollBar ? 437 long nScrollWidth = aColorSet.GetScrollWidth(); 438 if( nScrollWidth > 0 ) 439 { 440 // Spalten mit ScrollBar berechnen 441 nCols = (sal_uInt16) ( ( aSize.Width() - nScrollWidth ) / aItemSize.Width() ); 442 } 443 aColorSet.SetColCount( nCols ); 444 445 if( IsFloatingMode() ) 446 aColorSet.SetLineCount( nLines ); 447 else 448 { 449 aColorSet.SetLineCount( 0 ); // sonst wird LineHeight ignoriert 450 aColorSet.SetItemHeight( aItemSize.Height() ); 451 } 452 453 aColorSet.SetPosSizePixel( Point( 2, 2 ), aSize ); 454 } 455 456 /************************************************************************* 457 |* 458 |* SvxColorDockingWindow: Close 459 |* 460 \************************************************************************/ 461 462 sal_Bool SvxColorDockingWindow::Close() 463 { 464 SfxBoolItem aItem( SID_COLOR_CONTROL, sal_False ); 465 GetBindings().GetDispatcher()->Execute( 466 SID_COLOR_CONTROL, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD, &aItem, 0L ); 467 SfxDockingWindow::Close(); 468 return( sal_True ); 469 } 470 471 /************************************************************************* 472 |* 473 |* SelectHdl 474 |* 475 \************************************************************************/ 476 477 IMPL_LINK( SvxColorDockingWindow, SelectHdl, void *, EMPTYARG ) 478 { 479 SfxDispatcher* pDispatcher = GetBindings().GetDispatcher(); 480 sal_uInt16 nPos = aColorSet.GetSelectItemId(); 481 Color aColor( aColorSet.GetItemColor( nPos ) ); 482 String aStr( aColorSet.GetItemText( nPos ) ); 483 484 if (aColorSet.IsLeftButton()) 485 { 486 if ( nLeftSlot == SID_ATTR_FILL_COLOR ) 487 { 488 if ( nPos == 1 ) // unsichtbar 489 { 490 XFillStyleItem aXFillStyleItem( XFILL_NONE ); 491 pDispatcher->Execute( nLeftSlot, SFX_CALLMODE_RECORD, &aXFillStyleItem, 0L ); 492 } 493 else 494 { 495 sal_Bool bDone = sal_False; 496 497 // Wenn wir eine DrawView haben und uns im TextEdit-Modus befinden, 498 // wird nicht die Flaechen-, sondern die Textfarbe zugewiesen 499 SfxViewShell* pViewSh = SfxViewShell::Current(); 500 if ( pViewSh ) 501 { 502 SdrView* pView = pViewSh->GetDrawView(); 503 if ( pView && pView->IsTextEdit() ) 504 { 505 SvxColorItem aTextColorItem( aColor, SID_ATTR_CHAR_COLOR ); 506 pDispatcher->Execute( 507 SID_ATTR_CHAR_COLOR, SFX_CALLMODE_RECORD, &aTextColorItem, 0L ); 508 bDone = sal_True; 509 } 510 } 511 if ( !bDone ) 512 { 513 XFillStyleItem aXFillStyleItem( XFILL_SOLID ); 514 XFillColorItem aXFillColorItem( aStr, aColor ); 515 pDispatcher->Execute( 516 nLeftSlot, SFX_CALLMODE_RECORD, &aXFillColorItem, &aXFillStyleItem, 0L ); 517 } 518 } 519 } 520 else if ( nPos != 1 ) // unsichtbar 521 { 522 SvxColorItem aLeftColorItem( aColor, nLeftSlot ); 523 pDispatcher->Execute( nLeftSlot, SFX_CALLMODE_RECORD, &aLeftColorItem, 0L ); 524 } 525 } 526 else 527 { 528 if ( nRightSlot == SID_ATTR_LINE_COLOR ) 529 { 530 if( nPos == 1 ) // unsichtbar 531 { 532 XLineStyleItem aXLineStyleItem( XLINE_NONE ); 533 pDispatcher->Execute( nRightSlot, SFX_CALLMODE_RECORD, &aXLineStyleItem, 0L ); 534 } 535 else 536 { 537 // Sollte der LineStyle unsichtbar sein, so wird er auf SOLID gesetzt 538 SfxViewShell* pViewSh = SfxViewShell::Current(); 539 if ( pViewSh ) 540 { 541 SdrView* pView = pViewSh->GetDrawView(); 542 if ( pView ) 543 { 544 SfxItemSet aAttrSet( pView->GetModel()->GetItemPool() ); 545 pView->GetAttributes( aAttrSet ); 546 if ( aAttrSet.GetItemState( XATTR_LINESTYLE ) != SFX_ITEM_DONTCARE ) 547 { 548 XLineStyle eXLS = (XLineStyle) 549 ( (const XLineStyleItem&)aAttrSet.Get( XATTR_LINESTYLE ) ).GetValue(); 550 if ( eXLS == XLINE_NONE ) 551 { 552 XLineStyleItem aXLineStyleItem( XLINE_SOLID ); 553 pDispatcher->Execute( nRightSlot, SFX_CALLMODE_RECORD, &aXLineStyleItem, 0L ); 554 } 555 } 556 } 557 } 558 559 XLineColorItem aXLineColorItem( aStr, aColor ); 560 pDispatcher->Execute( nRightSlot, SFX_CALLMODE_RECORD, &aXLineColorItem, 0L ); 561 } 562 } 563 else if ( nPos != 1 ) // unsichtbar 564 { 565 SvxColorItem aRightColorItem( aColor, nRightSlot ); 566 pDispatcher->Execute( nRightSlot, SFX_CALLMODE_RECORD, &aRightColorItem, 0L ); 567 } 568 } 569 570 return 0; 571 } 572 573 /************************************************************************* 574 |* 575 |* Resizing 576 |* 577 \************************************************************************/ 578 579 580 void SvxColorDockingWindow::Resizing( Size& rNewSize ) 581 { 582 rNewSize.Width() -= 4; 583 rNewSize.Height() -= 4; 584 585 // Spalten und Reihen ermitteln 586 nCols = (sal_uInt16) ( (float) rNewSize.Width() / (float) aItemSize.Width() + 0.5 ); 587 nLines = (sal_uInt16) ( (float) rNewSize.Height() / (float) aItemSize.Height() + 0.5 ); 588 if( nLines == 0 ) 589 nLines = 1; 590 591 // Scrollbar setzen/entfernen 592 WinBits nBits = aColorSet.GetStyle(); 593 if ( nLines * nCols >= nCount ) 594 nBits &= ~WB_VSCROLL; 595 else 596 nBits |= WB_VSCROLL; 597 aColorSet.SetStyle( nBits ); 598 599 // ScrollBar ? 600 long nScrollWidth = aColorSet.GetScrollWidth(); 601 if( nScrollWidth > 0 ) 602 { 603 // Spalten mit ScrollBar berechnen 604 nCols = (sal_uInt16) ( ( ( (float) rNewSize.Width() - (float) nScrollWidth ) ) 605 / (float) aItemSize.Width() + 0.5 ); 606 } 607 if( nCols <= 1 ) 608 nCols = 2; 609 610 // Max. Reihen anhand der gegebenen Spalten berechnen 611 long nMaxLines = nCount / nCols; 612 if( nCount % nCols ) 613 nMaxLines++; 614 615 nLines = sal::static_int_cast< sal_uInt16 >( 616 std::min< long >( nLines, nMaxLines ) ); 617 618 // Groesse des Windows setzen 619 rNewSize.Width() = nCols * aItemSize.Width() + nScrollWidth + 4; 620 rNewSize.Height() = nLines * aItemSize.Height() + 4; 621 } 622 623 /************************************************************************* 624 |* 625 |* Resize 626 |* 627 \************************************************************************/ 628 629 void SvxColorDockingWindow::Resize() 630 { 631 if ( !IsFloatingMode() || !GetFloatingWindow()->IsRollUp() ) 632 SetSize(); 633 SfxDockingWindow::Resize(); 634 } 635 636 637 638 void SvxColorDockingWindow::GetFocus (void) 639 { 640 SfxDockingWindow::GetFocus(); 641 // Grab the focus to the color value set so that it can be controlled 642 // with the keyboard. 643 aColorSet.GrabFocus(); 644 } 645 646 long SvxColorDockingWindow::Notify( NotifyEvent& rNEvt ) 647 { 648 long nRet = 0; 649 if( ( rNEvt.GetType() == EVENT_KEYINPUT ) ) 650 { 651 KeyEvent aKeyEvt = *rNEvt.GetKeyEvent(); 652 sal_uInt16 nKeyCode = aKeyEvt.GetKeyCode().GetCode(); 653 switch( nKeyCode ) 654 { 655 case KEY_ESCAPE: 656 GrabFocusToDocument(); 657 nRet = 1; 658 break; 659 } 660 } 661 662 return nRet ? nRet : SfxDockingWindow::Notify( rNEvt ); 663 } 664