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