xref: /AOO41X/main/svx/source/tbxctrls/colrctrl.cxx (revision 3ce09a58b0d6873449cda31e55c66dba2dbc8f7f)
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 
SvxColorValueSetData(const XFillAttrSetItem & rSetItem)65                             SvxColorValueSetData( const XFillAttrSetItem& rSetItem ) :
66                                 maData( rSetItem ) {}
67 };
68 
69 // -----------------------------------------------------------------------------
70 
AddSupportedFormats()71 void SvxColorValueSetData::AddSupportedFormats()
72 {
73     AddFormat( SOT_FORMATSTR_ID_XFA );
74 }
75 
76 // -----------------------------------------------------------------------------
77 
GetData(const::com::sun::star::datatransfer::DataFlavor & rFlavor)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 
WriteObject(SotStorageStreamRef & rxOStm,void *,sal_uInt32,const::com::sun::star::datatransfer::DataFlavor &)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 
SvxColorValueSet_docking(Window * _pParent,WinBits nWinStyle)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 
SvxColorValueSet_docking(Window * _pParent,const ResId & rResId)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 
MouseButtonDown(const MouseEvent & rMEvt)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 
MouseButtonUp(const MouseEvent & rMEvt)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 
Command(const CommandEvent & rCEvt)188 void SvxColorValueSet_docking::Command(const CommandEvent& rCEvt)
189 {
190     // Basisklasse
191     SvxColorValueSet::Command(rCEvt);
192 }
193 
194 /*************************************************************************
195 |*
196 |* StartDrag
197 |*
198 \************************************************************************/
199 
StartDrag(sal_Int8,const Point &)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 
DoDrag()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 
IMPL_STATIC_LINK(SvxColorValueSet_docking,ExecDragHdl,void *,EMPTYARG)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 
SvxColorDockingWindow(SfxBindings * _pBindings,SfxChildWindow * pCW,Window * _pParent,const ResId & rResId)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     maColorTable(),
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             maColorTable = static_cast< const 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 
~SvxColorDockingWindow()319 SvxColorDockingWindow::~SvxColorDockingWindow()
320 {
321     EndListening( GetBindings() );
322 }
323 
324 /*************************************************************************
325 |*
326 |* Notify
327 |*
328 \************************************************************************/
329 
Notify(SfxBroadcaster &,const SfxHint & rHint)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         maColorTable = static_cast< SvxColorTableItem* >(pPoolItemHint->GetObject())->GetColorTable();
338         FillValueSet();
339     }
340 }
341 
342 /*************************************************************************
343 |*
344 |* FillValueSet
345 |*
346 \************************************************************************/
347 
FillValueSet()348 void SvxColorDockingWindow::FillValueSet()
349 {
350     if( maColorTable.get() )
351     {
352         nCount = maColorTable->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(maColorTable, 2);
371     }
372 }
373 
374 /*************************************************************************
375 |*
376 |* SetSize
377 |*
378 \************************************************************************/
379 
SetSize()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 
Close()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 
IMPL_LINK(SvxColorDockingWindow,SelectHdl,void *,EMPTYARG)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 
Resizing(Size & rNewSize)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 
Resize()594 void SvxColorDockingWindow::Resize()
595 {
596     if ( !IsFloatingMode() || !GetFloatingWindow()->IsRollUp() )
597         SetSize();
598     SfxDockingWindow::Resize();
599 }
600 
601 
602 
GetFocus(void)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 
Notify(NotifyEvent & rNEvt)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