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