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 // MARKER(update_precomp.py): autogen include statement, do not remove
23 #include "precompiled_cui.hxx"
24 
25 #include <com/sun/star/uno/XComponentContext.hpp>
26 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
27 #include <com/sun/star/beans/XPropertyAccess.hpp>
28 #include <com/sun/star/lang/XInitialization.hpp>
29 #include <com/sun/star/lang/XServiceInfo.hpp>
30 #include <com/sun/star/datatransfer/XTransferable.hpp>
31 #include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
32 #include <com/sun/star/awt/XWindow.hpp>
33 #include <cppuhelper/compbase4.hxx>
34 #include <comphelper/broadcasthelper.hxx>
35 #include <vcl/dialog.hxx>
36 #include <vcl/button.hxx>
37 #include <vcl/fixed.hxx>
38 #include <vcl/edit.hxx>
39 #include <vcl/field.hxx>
40 #include <vcl/bmpacc.hxx>
41 #include <vcl/decoview.hxx>
42 #include <vcl/sound.hxx>
43 #include <vcl/svapp.hxx>
44 #include <toolkit/helper/vclunohelper.hxx>
45 #include <sot/exchange.hxx>
46 #include <sot/formats.hxx>
47 #include <sax/tools/converter.hxx>
48 #include "dialmgr.hxx"
49 #include "colorpicker.hrc"
50 #include <cmath>
51 
52 using rtl::OUString;
53 using namespace ::com::sun::star::uno;
54 using namespace ::com::sun::star::lang;
55 using namespace ::com::sun::star::ui::dialogs;
56 using namespace ::com::sun::star::beans;
57 
58 namespace cui
59 {
60 const sal_uInt16 COLORMODE_RGB =  0x10;
61 const sal_uInt16 COLORMODE_HSV =  0x20;
62 const sal_uInt16 COLORMODE_CMYK = 0x40;
63 
64 const sal_uInt16 COLORCOMP_RED   = 0x10;
65 const sal_uInt16 COLORCOMP_GREEN = 0x11;
66 const sal_uInt16 COLORCOMP_BLUE  = 0x12;
67 
68 const sal_uInt16 COLORCOMP_HUE  = 0x20;
69 const sal_uInt16 COLORCOMP_SAT  = 0x21;
70 const sal_uInt16 COLORCOMP_BRI  = 0x22;
71 
72 const sal_uInt16 COLORCOMP_CYAN    = 0x40;
73 const sal_uInt16 COLORCOMP_YELLOW  = 0x41;
74 const sal_uInt16 COLORCOMP_MAGENTA = 0x42;
75 const sal_uInt16 COLORCOMP_KEY     = 0x43;
76 
77 // -----------------------------------------------------------------------
78 // color space conversion
79 // RGB  = 0 .. 1
80 // H    = 0 .. 360
81 // SV   = 0 .. 1
82 // CMYK = 0 .. 1
83 // -----------------------------------------------------------------------
84 
RGBtoHSV(double dR,double dG,double dB,double & dH,double & dS,double & dV)85 static void RGBtoHSV( double dR, double dG, double dB, double& dH, double& dS, double& dV )
86 {
87     // Brightness = max(R, G, B);
88     dV = std::max( dR, std::max( dG, dB ) );
89 
90     double cDelta = dV - std::min( dR, std::min( dG, dB ) );
91 
92     // Saturation = max - min / max
93     if( dV > 0 )
94         dS = cDelta / dV;
95     else
96         dS = 0.0;
97 
98     dH = 0.0;
99 
100     if( !basegfx::fTools::equalZero( dS ) )
101     {
102         if( basegfx::fTools::equal( dR, dV ) )
103         {
104             dH = ( dG - dB ) / cDelta;
105         }
106         else if( basegfx::fTools::equal( dG, dV ) )
107         {
108             dH = 2.0 + ( dB - dR ) / cDelta;
109         }
110         else if ( basegfx::fTools::equal( dB, dV ) )
111         {
112             dH = 4.0 + ( dR - dG ) / cDelta;
113         }
114         dH *= 60.0;
115 
116         if( dH < 0.0 )
117             dH += 360.0;
118     }
119 }
120 
HSVtoRGB(double dH,double dS,double dV,double & dR,double & dG,double & dB)121 static void HSVtoRGB(double dH, double dS, double dV, double& dR, double& dG, double& dB )
122 {
123     if( basegfx::fTools::equalZero( dS ) )
124     {
125         dR = dV;
126         dG = dV;
127         dB = dV;
128     }
129     else
130     {
131         if( basegfx::fTools::equal( dH, 360.0 ) )
132             dH = 0.0;
133         else
134             dH /= 60.0;
135 
136         sal_uInt16 n = (sal_uInt16) dH;
137         double f = dH - n;
138 
139         double a = dV * ( 1.0 - dS );
140         double b = dV * ( 1.0 - ( dS * f ) );
141         double c = dV * ( 1.0 - ( dS * ( 1.0 - f ) ) );
142 
143         switch( n )
144         {
145             case 0: dR = dV; dG = c;  dB = a;  break;
146             case 1: dR = b;  dG = dV; dB = a;  break;
147             case 2: dR = a;  dG = dV; dB = c;  break;
148             case 3: dR = a;  dG = b;  dB = dV; break;
149             case 4: dR = c;  dG = a;  dB = dV; break;
150             case 5: dR = dV; dG = a;  dB = b;  break;
151         }
152     }
153 }
154 
155 // -----------------------------------------------------------------------
156 
157 // CMYK values from 0 to 1
CMYKtoRGB(double fCyan,double fMagenta,double fYellow,double fKey,double & dR,double & dG,double & dB)158 static void CMYKtoRGB( double fCyan, double fMagenta, double fYellow, double fKey, double& dR, double& dG, double& dB )
159 {
160     fCyan = (fCyan * ( 1.0 - fKey )) + fKey;
161     fMagenta = (fMagenta * ( 1.0 - fKey )) + fKey;
162     fYellow = (fYellow * ( 1.0 - fKey )) + fKey;
163 
164     dR = std::max( std::min( ( 1.0 - fCyan ), 1.0), 0.0 );
165     dG = std::max( std::min( ( 1.0 - fMagenta ), 1.0), 0.0 );
166     dB = std::max( std::min( ( 1.0 - fYellow ), 1.0), 0.0 );
167 }
168 
169 // -----------------------------------------------------------------------
170 
171 // CMY results from 0 to 1
RGBtoCMYK(double dR,double dG,double dB,double & fCyan,double & fMagenta,double & fYellow,double & fKey)172 static void RGBtoCMYK( double dR, double dG, double dB, double& fCyan, double& fMagenta, double& fYellow, double& fKey )
173 {
174     fCyan = 1 - dR;
175     fMagenta = 1 - dG;
176     fYellow = 1 - dB;
177 
178     //CMYK and CMY values from 0 to 1
179     fKey = 1.0;
180     if( fCyan < fKey ) fKey = fCyan;
181     if( fMagenta < fKey ) fKey = fMagenta;
182     if( fYellow < fKey ) fKey = fYellow;
183 
184     if( basegfx::fTools::equal( fKey, 1.0 ) )
185     {
186         //Black
187        fCyan = 0.0;
188        fMagenta = 0.0;
189        fYellow = 0.0;
190     }
191     else
192     {
193        fCyan = ( fCyan - fKey ) / ( 1.0 - fKey );
194        fMagenta = ( fMagenta - fKey ) / ( 1.0 - fKey );
195        fYellow = ( fYellow - fKey ) / ( 1.0 - fKey );
196     }
197 }
198 
199 // ====================================================================
200 
201 class HexColorControl : public Edit
202 {
203 public:
204     HexColorControl( Window* pParent, const ResId& rResId );
205 
206     virtual long PreNotify( NotifyEvent& rNEvt );
207     virtual void Paste();
208 
209     void SetColor( sal_Int32 nColor );
210     sal_Int32 GetColor();
211 
212 private:
213     bool ImplProcessKeyInput( const KeyEvent& rKEv );
214 };
215 
HexColorControl(Window * pParent,const ResId & rResId)216 HexColorControl::HexColorControl( Window* pParent, const ResId& rResId )
217 : Edit( pParent, rResId )
218 {
219     SetMaxTextLen( 6 );
220 }
221 
222 // -----------------------------------------------------------------------
223 
SetColor(sal_Int32 nColor)224 void HexColorControl::SetColor( sal_Int32 nColor )
225 {
226     ::rtl::OUStringBuffer aBuffer;
227     sax::Converter::convertColor( aBuffer, nColor );
228     SetText( aBuffer.makeStringAndClear().copy(1) );
229 }
230 
231 // -----------------------------------------------------------------------
232 
GetColor()233 sal_Int32 HexColorControl::GetColor()
234 {
235     sal_Int32 nColor = -1;
236 
237     OUString aStr( RTL_CONSTASCII_USTRINGPARAM( "#" ) );
238     aStr += GetText();
239     sal_Int32 nLen = aStr.getLength();
240     if( nLen < 7 )
241     {
242         static const sal_Char* pNullStr = "000000";
243         aStr += OUString::createFromAscii( &pNullStr[nLen-1] );
244     }
245 
246     sax::Converter::convertColor( nColor, aStr );
247 
248     if( nColor == -1 )
249         SetControlBackground( Color( COL_RED ) );
250     else
251         SetControlBackground();
252 
253     return nColor;
254 }
255 
256 // -----------------------------------------------------------------------
257 
PreNotify(NotifyEvent & rNEvt)258 long HexColorControl::PreNotify( NotifyEvent& rNEvt )
259 {
260     if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() )
261     {
262         if ( ImplProcessKeyInput( *rNEvt.GetKeyEvent() ) )
263             return 1;
264     }
265 
266     return Edit::PreNotify( rNEvt );
267 }
268 
269 // -----------------------------------------------------------------------
270 
Paste()271 void HexColorControl::Paste()
272 {
273     ::com::sun::star::uno::Reference<com::sun::star::datatransfer::clipboard::XClipboard> aClipboard(GetClipboard());
274     if ( aClipboard.is() )
275     {
276         ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XTransferable > xDataObj;
277 
278         const sal_uInt32 nRef = Application::ReleaseSolarMutex();
279 
280         try
281         {
282             xDataObj = aClipboard->getContents();
283         }
284         catch( const ::com::sun::star::uno::Exception& )
285         {
286         }
287 
288         Application::AcquireSolarMutex( nRef );
289 
290         if ( xDataObj.is() )
291         {
292             ::com::sun::star::datatransfer::DataFlavor aFlavor;
293             SotExchange::GetFormatDataFlavor( SOT_FORMAT_STRING, aFlavor );
294             try
295             {
296                 ::com::sun::star::uno::Any aData = xDataObj->getTransferData( aFlavor );
297                 ::rtl::OUString aText;
298                 aData >>= aText;
299 
300                 if( aText.getLength() && aText.matchAsciiL( "#", 1, 0 ) )
301                     aText = aText.copy(1);
302 
303                 if( aText.getLength() > 6 )
304                     aText = aText.copy( 0, 6 );
305 
306                 SetText( aText );
307             }
308             catch( const ::com::sun::star::uno::Exception& )
309             {
310             }
311         }
312     }
313 }
314 
315 // -----------------------------------------------------------------------
316 
ImplProcessKeyInput(const KeyEvent & rKEv)317 bool HexColorControl::ImplProcessKeyInput( const KeyEvent& rKEv )
318 {
319     const KeyCode& rKeyCode = rKEv.GetKeyCode();
320 
321     if( rKeyCode.GetGroup() == KEYGROUP_ALPHA && !rKeyCode.IsMod1() && !rKeyCode.IsMod2() )
322     {
323         if( (rKeyCode.GetCode() < KEY_A) || (rKeyCode.GetCode() > KEY_F) )
324         {
325             Sound::Beep();
326             return true;
327         }
328     }
329     else if( rKeyCode.GetGroup() == KEYGROUP_NUM )
330     {
331         if( rKeyCode.IsShift() )
332         {
333             Sound::Beep();
334             return true;
335         }
336     }
337     return false;
338 }
339 
340 // ====================================================================
341 
342 class ColorPreviewControl : public Control
343 {
344 public:
345     ColorPreviewControl( Window* pParent, const ResId& rResId );
346 
347     virtual void        Paint( const Rectangle& rRect );
348 
349     void SetColor( const Color& rColor );
350 private:
351     Color maColor;
352 };
353 
354 // -----------------------------------------------------------------------
355 
ColorPreviewControl(Window * pParent,const ResId & rResId)356 ColorPreviewControl::ColorPreviewControl( Window* pParent, const ResId& rResId )
357 : Control( pParent, rResId )
358 {
359     SetFillColor( maColor );
360     SetLineColor( maColor );
361 }
362 
363 // -----------------------------------------------------------------------
364 
SetColor(const Color & rCol)365 void ColorPreviewControl::SetColor( const Color& rCol )
366 {
367     if( rCol != maColor )
368     {
369         maColor = rCol;
370         SetFillColor( maColor );
371         SetLineColor( maColor );
372         Invalidate();
373     }
374 }
375 
376 // -----------------------------------------------------------------------
377 
Paint(const Rectangle & rRect)378 void ColorPreviewControl::Paint( const Rectangle& rRect )
379 {
380     DrawRect( rRect );
381 }
382 
383 // ====================================================================
384 
385 enum ColorMode { HUE, SATURATION, BRIGHTNESS, RED, GREEN, BLUE };
386 const ColorMode DefaultMode = HUE;
387 
388 class ColorFieldControl : public Control
389 {
390 public:
391     ColorFieldControl( Window* pParent, const ResId& rResId );
392     ~ColorFieldControl();
393 
394     virtual void        MouseMove( const MouseEvent& rMEvt );
395     virtual void        MouseButtonDown( const MouseEvent& rMEvt );
396     virtual void        MouseButtonUp( const MouseEvent& rMEvt );
397     virtual void        KeyInput( const KeyEvent& rKEvt );
398     virtual void        Paint( const Rectangle& rRect );
399     virtual void        Resize();
400 
401     void                UpdateBitmap();
402     void                ShowPosition( const Point& rPos, bool bUpdate );
403     void                UpdatePosition();
404     void                Modify();
405 
406     void                SetValues( Color aColor, ColorMode eMode, double x, double y );
407     double              GetX();
408     double              GetY();
409 
410     void                KeyMove( int dx, int dy );
411 
SetModifyHdl(Link & rLink)412     void                SetModifyHdl( Link& rLink ) { maModifyHdl = rLink; }
413 
414 private:
415     Link maModifyHdl;
416     ColorMode meMode;
417     Color maColor;
418     double mdX;
419     double mdY;
420     Point maPosition;
421     Bitmap* mpBitmap;
422     std::vector< sal_uInt8 > maRGB_Horiz;
423     std::vector< sal_uInt16 > maGrad_Horiz;
424     std::vector< sal_uInt16 > maPercent_Horiz;
425     std::vector< sal_uInt8 > maRGB_Vert;
426     std::vector< sal_uInt16 > maPercent_Vert;
427     bool mbInit;
428 };
429 
430 // -----------------------------------------------------------------------
431 
ColorFieldControl(Window * pParent,const ResId & rResId)432 ColorFieldControl::ColorFieldControl( Window* pParent, const ResId& rResId )
433 : Control( pParent, rResId )
434 , meMode( DefaultMode )
435 , mdX( -1.0 )
436 , mdY( -1.0 )
437 , mpBitmap( 0 )
438 , mbInit( false )
439 {
440     SetControlBackground();
441 }
442 
443 // -----------------------------------------------------------------------
444 
~ColorFieldControl()445 ColorFieldControl::~ColorFieldControl()
446 {
447     delete mpBitmap;
448 }
449 
450 // -----------------------------------------------------------------------
451 
UpdateBitmap()452 void ColorFieldControl::UpdateBitmap()
453 {
454     const Size aSize( GetOutputSizePixel() );
455 
456     if( mpBitmap && mpBitmap->GetSizePixel() != aSize )
457         delete mpBitmap, mpBitmap = NULL;
458 
459     const sal_Int32 nWidth = aSize.Width();
460     const sal_Int32 nHeight = aSize.Height();
461 
462     if( !mpBitmap )
463     {
464         mpBitmap = new Bitmap( aSize, 24 );
465 
466         maRGB_Horiz.resize( nWidth );
467         maGrad_Horiz.resize( nWidth );
468         maPercent_Horiz.resize( nWidth );
469 
470         sal_uInt8* pRGB = &(*maRGB_Horiz.begin());
471         sal_uInt16* pGrad = &(*maGrad_Horiz.begin());
472         sal_uInt16* pPercent = &(*maPercent_Horiz.begin());
473 
474         for( sal_Int32 x = 0; x < nWidth; x++ )
475         {
476             *pRGB++ = static_cast< sal_uInt8 >( (x * 256) / nWidth );
477             *pGrad++ = static_cast< sal_uInt16 >( (x * 359) / nWidth );
478             *pPercent++ = static_cast< sal_uInt16 >( (x * 100) / nWidth );
479         }
480 
481         maRGB_Vert.resize( nHeight );
482         maPercent_Vert.resize( nHeight );
483 
484         pRGB = &(*maRGB_Vert.begin());
485         pPercent = &(*maPercent_Vert.begin());
486 
487         sal_Int32 y = nHeight;
488         while( y-- )
489         {
490             *pRGB++ = static_cast< sal_uInt8 >( (y * 256) / nHeight );
491             *pPercent++ = static_cast< sal_uInt16 >( (y * 100) / nHeight );
492         }
493     }
494 
495     sal_uInt8* pRGB_Horiz = &(*maRGB_Horiz.begin());
496     sal_uInt16* pGrad_Horiz = &(*maGrad_Horiz.begin());
497     sal_uInt16* pPercent_Horiz = &(*maPercent_Horiz.begin());
498     sal_uInt8* pRGB_Vert = &(*maRGB_Vert.begin());
499     sal_uInt16* pPercent_Vert = &(*maPercent_Vert.begin());
500 
501     BitmapWriteAccess* pWriteAccess = mpBitmap->AcquireWriteAccess();
502     if( pWriteAccess )
503     {
504         BitmapColor aBitmapColor( maColor );
505 
506         sal_uInt16 nHue, nSat, nBri;
507         maColor.RGBtoHSB( nHue, nSat, nBri );
508 
509         // this has been unlooped for performance reason, please do not merge back!
510 
511         sal_uInt16 y = nHeight,x;
512 
513         switch( meMode )
514         {
515         case HUE:
516             while( y-- )
517             {
518                 nBri = pPercent_Vert[y];
519                 x = nWidth;
520                 while( x-- )
521                 {
522                     nSat = pPercent_Horiz[x];
523                     pWriteAccess->SetPixel( y, x, BitmapColor( Color( Color::HSBtoRGB( nHue, nSat, nBri ) ) ) );
524                 }
525             }
526             break;
527         case SATURATION:
528             while( y-- )
529             {
530                 nBri = pPercent_Vert[y];
531                 x = nWidth;
532                 while( x-- )
533                 {
534                     nHue = pGrad_Horiz[x];
535                     pWriteAccess->SetPixel( y, x, BitmapColor( Color( Color::HSBtoRGB( nHue, nSat, nBri ) ) ) );
536                 }
537             }
538             break;
539         case BRIGHTNESS:
540             while( y-- )
541             {
542                 nSat = pPercent_Vert[y];
543                 x = nWidth;
544                 while( x-- )
545                 {
546                     nHue = pGrad_Horiz[x];
547                     pWriteAccess->SetPixel( y, x, BitmapColor( Color( Color::HSBtoRGB( nHue, nSat, nBri ) ) ) );
548                 }
549             }
550             break;
551         case RED:
552             while( y-- )
553             {
554                 aBitmapColor.SetGreen( pRGB_Vert[y] );
555                 x = nWidth;
556                 while( x-- )
557                 {
558                     aBitmapColor.SetBlue( pRGB_Horiz[x] );
559                     pWriteAccess->SetPixel( y, x, aBitmapColor );
560                 }
561             }
562             break;
563         case GREEN:
564             while( y-- )
565             {
566                 aBitmapColor.SetRed( pRGB_Vert[y] );
567                 x = nWidth;
568                 while( x-- )
569                 {
570                     aBitmapColor.SetBlue( pRGB_Horiz[x] );
571                     pWriteAccess->SetPixel( y, x, aBitmapColor );
572                 }
573             }
574             break;
575         case BLUE:
576             while( y-- )
577             {
578                 aBitmapColor.SetGreen( pRGB_Vert[y] );
579                 x = nWidth;
580                 while( x-- )
581                 {
582                     aBitmapColor.SetRed( pRGB_Horiz[x] );
583                     pWriteAccess->SetPixel( y, x, aBitmapColor );
584                 }
585             }
586             break;
587         }
588 
589         mpBitmap->ReleaseAccess( pWriteAccess );
590     }
591 }
592 
593 // -----------------------------------------------------------------------
594 
ShowPosition(const Point & rPos,bool bUpdate)595 void ColorFieldControl::ShowPosition( const Point& rPos, bool bUpdate )
596 {
597     if( !mpBitmap )
598     {
599         UpdateBitmap();
600         Invalidate();
601     }
602 
603     const Size aSize( mpBitmap->GetSizePixel() );
604 
605     long nX = rPos.X();
606     long nY = rPos.Y();
607     if( nX < 0L )
608         nX = 0L;
609     else if( nX >= aSize.Width() )
610         nX = aSize.Width() - 1L;
611 
612     if( nY < 0L )
613         nY= 0L;
614     else if( nY >= aSize.Height() )
615         nY = aSize.Height() - 1L;
616 
617     Point aPos = maPosition;
618     maPosition.X() = nX - 5;
619     maPosition.Y() = nY - 5;
620     Invalidate( Rectangle( aPos, Size( 11, 11) ) );
621     Invalidate( Rectangle( maPosition, Size( 11, 11) ) );
622 
623     if( bUpdate )
624     {
625         mdX = (double)nX / (double)(aSize.Width()-1);
626         mdY = (double)(aSize.Height()-1-nY) / (double)(aSize.Height()-1);
627 
628         BitmapReadAccess* pReadAccess = mpBitmap->AcquireReadAccess();
629         if( pReadAccess != NULL )
630         {
631             // mpBitmap always has a bit count of 24 => use of GetPixel(...) is safe
632             maColor = pReadAccess->GetPixel( nY, nX );
633             mpBitmap->ReleaseAccess( pReadAccess );
634             pReadAccess = NULL;
635         }
636     }
637 }
638 // -----------------------------------------------------------------------
639 
MouseMove(const MouseEvent & rMEvt)640 void ColorFieldControl::MouseMove( const MouseEvent& rMEvt )
641 {
642     if( rMEvt.IsLeft() )
643     {
644         ShowPosition( rMEvt.GetPosPixel(), true );
645         Modify();
646     }
647 }
648 
649 // -----------------------------------------------------------------------
MouseButtonDown(const MouseEvent & rMEvt)650 void ColorFieldControl::MouseButtonDown( const MouseEvent& rMEvt )
651 {
652     if( rMEvt.IsLeft() && !rMEvt.IsShift() )
653     {
654         CaptureMouse();
655         ShowPosition( rMEvt.GetPosPixel(), true );
656         Modify();
657     }
658 }
659 
660 // -----------------------------------------------------------------------
MouseButtonUp(const MouseEvent &)661 void ColorFieldControl::MouseButtonUp( const MouseEvent& )
662 {
663     if( IsMouseCaptured() )
664         ReleaseMouse();
665 }
666 
667 // -----------------------------------------------------------------------
668 
KeyMove(int dx,int dy)669 void ColorFieldControl::KeyMove( int dx, int dy )
670 {
671     Size aSize( GetOutputSizePixel() );
672     Point aPos( mdX * aSize.Width(), (1.0 - mdY) * aSize.Height() );
673     aPos.X() += dx;
674     aPos.Y() += dy;
675     if( aPos.X() < 0 )
676         aPos.X() += aSize.Width();
677     else if( aPos.X() >= aSize.Width() )
678         aPos.X() -= aSize.Width();
679 
680     if( aPos.Y() < 0 )
681         aPos.Y() += aSize.Height();
682     else if( aPos.Y() >= aSize.Height() )
683         aPos.Y() -= aSize.Height();
684 
685     ShowPosition( aPos, true );
686     Modify();
687 }
688 
689 // -----------------------------------------------------------------------
690 
KeyInput(const KeyEvent & rKEvt)691 void ColorFieldControl::KeyInput( const KeyEvent& rKEvt )
692 {
693     bool   bShift = rKEvt.GetKeyCode().IsShift();
694     bool   bCtrl = rKEvt.GetKeyCode().IsMod1();
695     bool   bAlt = rKEvt.GetKeyCode().IsMod2();
696 
697     if ( !bAlt && !bShift )
698     {
699         switch( rKEvt.GetKeyCode().GetCode() )
700         {
701         case KEY_DOWN:      KeyMove(  0, bCtrl ?  5  :  1 ); return;
702         case KEY_UP:        KeyMove(  0, bCtrl ? -5  : -1 ); return;
703         case KEY_LEFT:      KeyMove( bCtrl ? -5  : -1,  0 ); return;
704         case KEY_RIGHT:     KeyMove( bCtrl ?  5  :  1,  0 ); return;
705         }
706     }
707     Control::KeyInput( rKEvt );
708 }
709 
710 // -----------------------------------------------------------------------
711 
Paint(const Rectangle & rRect)712 void ColorFieldControl::Paint( const Rectangle& rRect )
713 {
714     if( !mpBitmap )
715         UpdateBitmap();
716 
717     Bitmap aOutputBitmap( *mpBitmap );
718 
719     if( GetBitCount() <= 8 )
720         aOutputBitmap.Dither();
721 
722     DrawBitmap( rRect.TopLeft(), rRect.GetSize(), rRect.TopLeft(), rRect.GetSize(), aOutputBitmap );
723 
724     // draw circle around current color
725     if( maColor.IsDark() )
726         SetLineColor( COL_WHITE );
727     else
728         SetLineColor( COL_BLACK );
729 
730     SetFillColor();
731 
732     DrawEllipse( Rectangle( maPosition, Size( 11, 11) ) );
733 }
734 
735 // -----------------------------------------------------------------------
736 
Resize()737 void ColorFieldControl::Resize()
738 {
739     UpdateBitmap();
740     Control::Resize();
741 }
742 
743 // -----------------------------------------------------------------------
744 
Modify()745 void ColorFieldControl::Modify()
746 {
747     maModifyHdl.Call( this );
748 }
749 
750 // -----------------------------------------------------------------------
751 
SetValues(Color aColor,ColorMode eMode,double x,double y)752 void ColorFieldControl::SetValues( Color aColor, ColorMode eMode, double x, double y )
753 {
754     bool bUpdateBitmap = (maColor!= aColor) || (meMode != eMode);
755     if( bUpdateBitmap || (mdX != x) || (mdY != y) )
756     {
757         maColor = aColor;
758         meMode = eMode;
759         mdX = x;
760         mdY = y;
761 
762         if( bUpdateBitmap )
763             UpdateBitmap();
764         UpdatePosition();
765         if( bUpdateBitmap )
766             Invalidate();
767     }
768 }
769 
770 // -----------------------------------------------------------------------
771 
GetX()772 double ColorFieldControl::GetX()
773 {
774     return mdX;
775 }
776 
777 // -----------------------------------------------------------------------
778 
GetY()779 double ColorFieldControl::GetY()
780 {
781     return mdY;
782 }
783 
784 // -----------------------------------------------------------------------
785 
UpdatePosition()786 void ColorFieldControl::UpdatePosition()
787 {
788     Size aSize( GetOutputSizePixel() );
789     ShowPosition( Point( mdX * aSize.Width(), (1.0 - mdY) * aSize.Height() ), false );
790 }
791 
792 // ====================================================================
793 
794 class ColorSliderControl : public Control
795 {
796 public:
797     ColorSliderControl( Window* pParent, const ResId& rResId );
798     ~ColorSliderControl();
799 
800     virtual void        MouseMove( const MouseEvent& rMEvt );
801     virtual void        MouseButtonDown( const MouseEvent& rMEvt );
802     virtual void        MouseButtonUp( const MouseEvent& rMEvt );
803     virtual void        KeyInput( const KeyEvent& rKEvt );
804     virtual void        Paint( const Rectangle& rRect );
805     virtual void        Resize();
806 
807     void                UpdateBitmap();
808     void                ChangePosition( long nY );
809     void                Modify();
810 
811     void SetValue( const Color& rColor, ColorMode eMode, double dValue );
GetValue() const812     double GetValue() const { return mdValue; }
813 
814     void                KeyMove( int dy );
815 
SetModifyHdl(Link & rLink)816     void SetModifyHdl( Link& rLink ) { maModifyHdl = rLink; }
817 
GetLevel() const818     sal_Int16 GetLevel() const { return mnLevel; }
819 
820 private:
821     Link maModifyHdl;
822     Color maColor;
823     ColorMode meMode;
824     Bitmap* mpBitmap;
825     sal_Int16 mnLevel;
826     double mdValue;
827 };
828 
829 // -----------------------------------------------------------------------
830 
ColorSliderControl(Window * pParent,const ResId & rResId)831 ColorSliderControl::ColorSliderControl( Window* pParent, const ResId& rResId )
832 : Control( pParent, rResId )
833 , meMode( DefaultMode )
834 , mpBitmap( 0 )
835 , mnLevel( 0 )
836 , mdValue( -1.0 )
837 {
838     SetControlBackground();
839 }
840 
841 // -----------------------------------------------------------------------
842 
~ColorSliderControl()843 ColorSliderControl::~ColorSliderControl()
844 {
845     delete mpBitmap;
846 }
847 
848 // -----------------------------------------------------------------------
849 
UpdateBitmap()850 void ColorSliderControl::UpdateBitmap()
851 {
852     Size aSize( 1, GetOutputSizePixel().Height() );
853 
854     if( mpBitmap && mpBitmap->GetSizePixel() != aSize )
855         delete mpBitmap, mpBitmap = NULL;
856 
857     if( !mpBitmap )
858         mpBitmap = new Bitmap( aSize, 24 );
859 
860     BitmapWriteAccess* pWriteAccess = mpBitmap->AcquireWriteAccess();
861 
862     if( pWriteAccess )
863     {
864         const long nY = aSize.Height()-1;
865 
866         BitmapColor aBitmapColor( maColor );
867 
868         sal_uInt16 nHue, nSat, nBri;
869         maColor.RGBtoHSB( nHue, nSat, nBri );
870 
871         // this has been unlooped for performance reason, please do not merge back!
872 
873         switch( meMode )
874         {
875         case HUE:
876             nSat = 100;
877             nBri = 100;
878             for( long y = 0; y <= nY; y++ )
879             {
880                 nHue = static_cast< sal_uInt16 >( (359 * y) / nY );
881                 aBitmapColor = BitmapColor( Color( Color::HSBtoRGB( nHue, nSat, nBri ) ) );
882                 pWriteAccess->SetPixel( nY-y, 0, aBitmapColor );
883             }
884             break;
885 
886         case SATURATION:
887             nBri = std::max( (sal_uInt16)32, nBri );
888             for( long y = 0; y <= nY; y++ )
889             {
890                 nSat = static_cast< sal_uInt16 >( (100 * y) / nY );
891                 pWriteAccess->SetPixel( nY-y, 0, BitmapColor( Color( Color::HSBtoRGB( nHue, nSat, nBri ) ) ) );
892             }
893             break;
894 
895         case BRIGHTNESS:
896             for( long y = 0; y <= nY; y++ )
897             {
898                 nBri = static_cast< sal_uInt16 >( (100 * y) / nY );
899                 pWriteAccess->SetPixel( nY-y, 0, BitmapColor( Color( Color::HSBtoRGB( nHue, nSat, nBri ) ) ) );
900             }
901             break;
902 
903         case RED:
904             for( long y = 0; y <= nY; y++ )
905             {
906                 aBitmapColor.SetRed( sal_uInt8( ((long)255 * y) / nY ) );
907                 pWriteAccess->SetPixel( nY-y, 0, aBitmapColor );
908             }
909             break;
910 
911         case GREEN:
912             for( long y = 0; y <= nY; y++ )
913             {
914                 aBitmapColor.SetGreen( sal_uInt8( ((long)255 * y) / nY ) );
915                 pWriteAccess->SetPixel( nY-y, 0, aBitmapColor );
916             }
917             break;
918 
919         case BLUE:
920             for( long y = 0; y <= nY; y++ )
921             {
922                 aBitmapColor.SetBlue( sal_uInt8( ((long)255 * y) / nY ) );
923                 pWriteAccess->SetPixel( nY-y, 0, aBitmapColor );
924             }
925             break;
926         }
927 
928         mpBitmap->ReleaseAccess( pWriteAccess );
929     }
930 }
931 
932 // -----------------------------------------------------------------------
933 
ChangePosition(long nY)934 void ColorSliderControl::ChangePosition( long nY )
935 {
936     const long nHeight = GetOutputSizePixel().Height() - 1;
937 
938     if( nY < 0L )
939         nY = 0;
940     else if( nY > nHeight )
941         nY = nHeight;
942 
943     mnLevel = nY;
944     mdValue = ((double)(nHeight - nY)) / (double)nHeight;
945 }
946 
947 // -----------------------------------------------------------------------
948 
MouseMove(const MouseEvent & rMEvt)949 void ColorSliderControl::MouseMove( const MouseEvent& rMEvt )
950 {
951     if( rMEvt.IsLeft() )
952     {
953         ChangePosition( rMEvt.GetPosPixel().Y() );
954         Modify();
955     }
956 }
957 
958 // -----------------------------------------------------------------------
MouseButtonDown(const MouseEvent & rMEvt)959 void ColorSliderControl::MouseButtonDown( const MouseEvent& rMEvt )
960 {
961     if( rMEvt.IsLeft() && !rMEvt.IsShift() )
962     {
963         CaptureMouse();
964         ChangePosition( rMEvt.GetPosPixel().Y() );
965         Modify();
966     }
967 }
968 
969 // -----------------------------------------------------------------------
MouseButtonUp(const MouseEvent &)970 void ColorSliderControl::MouseButtonUp( const MouseEvent& )
971 {
972     if( IsMouseCaptured() )
973         ReleaseMouse();
974 }
975 
976 // -----------------------------------------------------------------------
977 
KeyMove(int dy)978 void ColorSliderControl::KeyMove( int dy )
979 {
980     ChangePosition( mnLevel + dy );
981     Modify();
982 }
983 
984 // -----------------------------------------------------------------------
985 
KeyInput(const KeyEvent & rKEvt)986 void ColorSliderControl::KeyInput( const KeyEvent& rKEvt )
987 {
988     if ( !rKEvt.GetKeyCode().IsMod2() && !rKEvt.GetKeyCode().IsShift() )
989     {
990         switch( rKEvt.GetKeyCode().GetCode() )
991         {
992         case KEY_DOWN:      KeyMove(  rKEvt.GetKeyCode().IsMod1() ?  5 :  1 ); return;
993         case KEY_UP:        KeyMove(  rKEvt.GetKeyCode().IsMod1() ? -5 : -1 ); return;
994         }
995     }
996 
997     Control::KeyInput( rKEvt );
998 }
999 // -----------------------------------------------------------------------
1000 
Paint(const Rectangle &)1001 void ColorSliderControl::Paint( const Rectangle& /*rRect*/ )
1002 {
1003     if( !mpBitmap )
1004         UpdateBitmap();
1005 
1006     const Size aSize( GetOutputSizePixel() );
1007 
1008     Bitmap aOutputBitmap( *mpBitmap );
1009 
1010     if( GetBitCount() <= 8 )
1011         aOutputBitmap.Dither();
1012 
1013     Point aPos;
1014     int x = aSize.Width();
1015     while( x-- )
1016     {
1017         DrawBitmap( aPos, aOutputBitmap );
1018         aPos.X() += 1;
1019     }
1020 }
1021 
1022 // -----------------------------------------------------------------------
1023 
Resize()1024 void ColorSliderControl::Resize()
1025 {
1026     UpdateBitmap();
1027     Control::Resize();
1028 }
1029 
1030 // -----------------------------------------------------------------------
1031 
Modify()1032 void ColorSliderControl::Modify()
1033 {
1034     maModifyHdl.Call( this );
1035 }
1036 
1037 // -----------------------------------------------------------------------
1038 
SetValue(const Color & rColor,ColorMode eMode,double dValue)1039 void ColorSliderControl::SetValue( const Color& rColor, ColorMode eMode, double dValue )
1040 {
1041     bool bUpdateBitmap = (rColor != maColor) || (eMode != meMode);
1042     if( bUpdateBitmap || (mdValue != dValue))
1043     {
1044         maColor = rColor;
1045         mdValue = dValue;
1046         mnLevel = (1.0-dValue) * GetOutputSizePixel().Height();
1047         meMode = eMode;
1048         if( bUpdateBitmap )
1049             UpdateBitmap();
1050         Invalidate();
1051     }
1052 }
1053 
1054 // ====================================================================
1055 
1056 const sal_uInt16 UPDATE_RGB = 0x01;
1057 const sal_uInt16 UPDATE_CMYK = 0x02;
1058 const sal_uInt16 UPDATE_HSB = 0x04;
1059 const sal_uInt16 UPDATE_COLORCHOOSER = 0x08;
1060 const sal_uInt16 UPDATE_COLORSLIDER = 0x10;
1061 const sal_uInt16 UPDATE_HEX = 0x20;
1062 const sal_uInt16 UPDATE_ALL = 0xff;
1063 
1064 class ColorPickerDialog : public ModalDialog
1065 {
1066 public:
1067     ColorPickerDialog( Window* pParent, sal_Int32 nColor, sal_Int16 nMode );
1068 
1069     void update_color( sal_uInt16 n = UPDATE_ALL );
1070 
1071     DECL_LINK( ColorModifyHdl, void * );
1072     DECL_LINK( ModeModifyHdl, void * );
1073 
1074     sal_Int32 GetColor() const;
1075 
1076     void setColorComponent( sal_uInt16 nComp, double dValue );
1077 
1078 private:
1079     Color maPreviousColor;
1080     sal_Int16 mnDialogMode;
1081     ColorMode meMode;
1082 
1083     double mdRed, mdGreen, mdBlue;
1084     double mdHue, mdSat, mdBri;
1085     double mdCyan, mdMagenta, mdYellow, mdKey;
1086 
1087 private:
1088     ColorFieldControl  maColorField;
1089     ColorSliderControl maColorSlider;
1090     ColorPreviewControl maColorPreview;
1091     ColorPreviewControl maColorPrevious;
1092 
1093     FixedImage maFISliderLeft;
1094     FixedImage maFISliderRight;
1095     Image maSliderImage;
1096 
1097 #if 0
1098     ImageButton maBtnPicker;
1099 #endif
1100 
1101     FixedLine maFLRGB;
1102 
1103     RadioButton maRBRed;
1104     RadioButton maRBGreen;
1105     RadioButton maRBBlue;
1106     RadioButton maRBHue;
1107     RadioButton maRBSaturation;
1108     RadioButton maRBBrightness;
1109 
1110     FixedText maFTRed;
1111     MetricField maMFRed;
1112     FixedText maFTGreen;
1113     MetricField maMFGreen;
1114     FixedText maFTBlue;
1115     MetricField maMFBlue;
1116     FixedText maFTHex;
1117     HexColorControl maEDHex;
1118 
1119     FixedLine maFLHSB;
1120     FixedText maFTHue;
1121     MetricField maMFHue;
1122     FixedText maFTSaturation;
1123     MetricField maMFSaturation;
1124     FixedText maFTBrightness;
1125     MetricField maMFBrightness;
1126 
1127     FixedLine maFLCMYK;
1128     FixedText maFTCyan;
1129     MetricField maMFCyan;
1130     FixedText maFTMagenta;
1131     MetricField maMFMagenta;
1132     FixedText maFTYellow;
1133     MetricField maMFYellow;
1134     FixedText maFTKey;
1135     MetricField maMFKey;
1136 
1137     FixedLine maFLBottmLine;
1138     HelpButton maBTNHelp;
1139     OKButton maBTNOk;
1140     CancelButton maBTNCancel;
1141 };
1142 
1143 // --------------------------------------------------------------------
1144 
ColorPickerDialog(Window * pParent,sal_Int32 nColor,sal_Int16 nMode)1145 ColorPickerDialog::ColorPickerDialog( Window* pParent, sal_Int32 nColor, sal_Int16 nMode )
1146 : ModalDialog( pParent, CUI_RES( RID_CUI_DIALOG_COLORPICKER ) )
1147 , maPreviousColor( nColor )
1148 , mnDialogMode( nMode )
1149 , meMode( DefaultMode )
1150 , maColorField( this, CUI_RES( CT_COLORFIELD ) )
1151 , maColorSlider( this, CUI_RES( CT_COLORSLIDER ) )
1152 , maColorPreview( this, CUI_RES( CT_PREVIEW ) )
1153 , maColorPrevious( this, CUI_RES( CT_PREVIOUS ) )
1154 , maFISliderLeft(  this, CUI_RES( CT_LEFT_SLIDER ) )
1155 , maFISliderRight( this, CUI_RES( CT_RIGHT_SLIDER ) )
1156 , maSliderImage( CUI_RES( CT_SLIDERIMG ) )
1157 #if 0
1158 , maBtnPicker( this, CUI_RES( PB_PICKER ) )
1159 #endif
1160 , maFLRGB( this, CUI_RES( FL_RGB ) )
1161 , maRBRed( this, CUI_RES( CT_RED ) )
1162 , maRBGreen( this, CUI_RES( CT_GREEN ) )
1163 , maRBBlue( this, CUI_RES( CT_BLUE ) )
1164 , maRBHue( this, CUI_RES( CT_HUE ) )
1165 , maRBSaturation( this, CUI_RES( CT_SATURATION ) )
1166 , maRBBrightness( this, CUI_RES( CT_BRIGHTNESS ) )
1167 , maFTRed( this, CUI_RES( CT_RED ) )
1168 , maMFRed( this, CUI_RES( CT_RED ) )
1169 , maFTGreen( this, CUI_RES( CT_GREEN ) )
1170 , maMFGreen( this, CUI_RES( CT_GREEN ) )
1171 , maFTBlue( this, CUI_RES( CT_BLUE ) )
1172 , maMFBlue( this, CUI_RES( CT_BLUE ) )
1173 , maFTHex( this, CUI_RES( CT_HEX ) )
1174 , maEDHex( this, CUI_RES( CT_HEX ) )
1175 , maFLHSB( this, CUI_RES( FL_HSB ) )
1176 , maFTHue( this, CUI_RES( CT_HUE ) )
1177 , maMFHue( this, CUI_RES( CT_HUE ) )
1178 , maFTSaturation( this, CUI_RES( CT_SATURATION ) )
1179 , maMFSaturation( this, CUI_RES( CT_SATURATION ) )
1180 , maFTBrightness( this, CUI_RES( CT_BRIGHTNESS ) )
1181 , maMFBrightness( this, CUI_RES( CT_BRIGHTNESS ) )
1182 , maFLCMYK( this, CUI_RES( FL_CMYK ) )
1183 , maFTCyan( this, CUI_RES( CT_CYAN ) )
1184 , maMFCyan( this, CUI_RES( CT_CYAN ) )
1185 , maFTMagenta( this, CUI_RES( CT_MAGENTA ) )
1186 , maMFMagenta( this, CUI_RES( CT_MAGENTA ) )
1187 , maFTYellow( this, CUI_RES( CT_YELLOW ) )
1188 , maMFYellow( this, CUI_RES( CT_YELLOW ) )
1189 , maFTKey( this, CUI_RES( CT_KEY ) )
1190 , maMFKey( this, CUI_RES( CT_KEY ) )
1191 
1192 , maFLBottmLine( this, CUI_RES( FT_BOTTOMLINE ) )
1193 , maBTNHelp( this, CUI_RES( BTN_HELP ) )
1194 , maBTNOk( this, CUI_RES( BTN_OK ) )
1195 , maBTNCancel( this, CUI_RES( BTN_CANCEL ) )
1196 {
1197     FreeResource();
1198 
1199     String sUnitText( (sal_Unicode) 0xb0 );
1200 
1201     maMFHue.SetCustomUnitText( sUnitText );
1202 
1203     Link aLink( LINK( this, ColorPickerDialog, ColorModifyHdl ) );
1204     maColorField.SetModifyHdl( aLink );
1205     maColorSlider.SetModifyHdl( aLink );
1206 
1207     maMFRed.SetModifyHdl( aLink );
1208     maMFGreen.SetModifyHdl( aLink );
1209     maMFBlue.SetModifyHdl( aLink );
1210 
1211     maMFCyan.SetModifyHdl( aLink );
1212     maMFMagenta.SetModifyHdl( aLink );
1213     maMFYellow.SetModifyHdl( aLink );
1214     maMFKey.SetModifyHdl( aLink );
1215 
1216     maMFHue.SetModifyHdl( aLink );
1217     maMFSaturation.SetModifyHdl( aLink );
1218     maMFBrightness.SetModifyHdl( aLink );
1219 
1220     maEDHex.SetModifyHdl( aLink );
1221 
1222     aLink = LINK( this, ColorPickerDialog, ModeModifyHdl );
1223     maRBRed.SetToggleHdl( aLink );
1224     maRBGreen.SetToggleHdl( aLink );
1225     maRBBlue.SetToggleHdl( aLink );
1226     maRBHue.SetToggleHdl( aLink );
1227     maRBSaturation.SetToggleHdl( aLink );
1228     maRBBrightness.SetToggleHdl( aLink );
1229 
1230     Image aSliderImage( maSliderImage );
1231 
1232     maFISliderLeft.SetImage( aSliderImage );
1233 
1234     BitmapEx aTmpBmp( maSliderImage.GetBitmapEx() );
1235     aTmpBmp.Mirror( BMP_MIRROR_HORZ );
1236     maFISliderRight.SetImage( Image( aTmpBmp  ) );
1237 
1238     Size aSize( maSliderImage.GetSizePixel() );
1239     maFISliderLeft.SetSizePixel( aSize );
1240     maFISliderRight.SetSizePixel( aSize );
1241 
1242     Point aPos( maColorSlider.GetPosPixel() );
1243 
1244     aPos.X() -= aSize.Width();
1245     aPos.Y() -= aSize.Height() / 2;
1246     maFISliderLeft.SetPosPixel( aPos );
1247 
1248     aPos.X() += aSize.Width() + maColorSlider.GetSizePixel().Width();
1249     maFISliderRight.SetPosPixel( aPos );
1250 
1251     Color aColor( nColor );
1252 
1253     // modify
1254     if( mnDialogMode == 2 )
1255     {
1256         maColorPreview.SetSizePixel( maColorPrevious.GetSizePixel() );
1257         maColorPrevious.SetColor( aColor );
1258         maColorPrevious.Show( true );
1259     }
1260 
1261     mdRed = ((double)aColor.GetRed()) / 255.0;
1262     mdGreen = ((double)aColor.GetGreen()) / 255.0;
1263     mdBlue = ((double)aColor.GetBlue()) / 255.0;
1264 
1265     RGBtoHSV( mdRed, mdGreen, mdBlue, mdHue, mdSat, mdBri );
1266     RGBtoCMYK( mdRed, mdGreen, mdBlue, mdCyan, mdMagenta, mdYellow, mdKey );
1267 
1268     update_color();
1269 }
1270 
1271 // --------------------------------------------------------------------
1272 
toInt(double dValue,double bRange)1273 static int toInt( double dValue, double bRange )
1274 {
1275     return static_cast< int >( std::floor((dValue * bRange) + 0.5 ) );
1276 }
1277 
GetColor() const1278 sal_Int32 ColorPickerDialog::GetColor() const
1279 {
1280     return Color( toInt(mdRed,255.0), toInt(mdGreen,255.0), toInt(mdBlue,255.0) ).GetColor();
1281 }
1282 
update_color(sal_uInt16 n)1283 void ColorPickerDialog::update_color( sal_uInt16 n )
1284 {
1285     sal_uInt8 nRed = toInt(mdRed,255.0);
1286     sal_uInt8 nGreen = toInt(mdGreen,255.0);
1287     sal_uInt8 nBlue = toInt(mdBlue,255.0);
1288 
1289     Color aColor( nRed, nGreen, nBlue );
1290 
1291     if( n & UPDATE_RGB ) // update RGB
1292     {
1293         maMFRed.SetValue( nRed );
1294         maMFGreen.SetValue( nGreen );
1295         maMFBlue.SetValue( nBlue );
1296     }
1297 
1298     if( n & UPDATE_CMYK ) // update CMYK
1299     {
1300         maMFCyan.SetValue( toInt( mdCyan, 100.0 ) );
1301         maMFMagenta.SetValue( toInt( mdMagenta, 100.0 ) );
1302         maMFYellow.SetValue( toInt( mdYellow, 100.0 ) );
1303         maMFKey.SetValue( toInt( mdKey, 100.0 ) );
1304     }
1305 
1306     if( n & UPDATE_HSB ) // update HSB
1307     {
1308         maMFHue.SetValue( toInt( mdHue, 1.0 ) );
1309         maMFSaturation.SetValue( toInt( mdSat, 100.0 ) );
1310         maMFBrightness.SetValue( toInt( mdBri, 100.0 ) );
1311     }
1312 
1313     if( n & UPDATE_COLORCHOOSER ) // update Color Chooser 1
1314     {
1315         switch( meMode )
1316         {
1317         case HUE:           maColorField.SetValues( aColor, meMode, mdSat, mdBri ); break;
1318         case SATURATION:    maColorField.SetValues( aColor, meMode, mdHue / 360.0, mdBri ); break;
1319         case BRIGHTNESS:    maColorField.SetValues( aColor, meMode, mdHue / 360.0, mdSat ); break;
1320         case RED:           maColorField.SetValues( aColor, meMode, mdBlue, mdGreen ); break;
1321         case GREEN:         maColorField.SetValues( aColor, meMode, mdBlue, mdRed ); break;
1322         case BLUE:          maColorField.SetValues( aColor, meMode, mdRed, mdGreen ); break;
1323         }
1324     }
1325 
1326     if( n & UPDATE_COLORSLIDER ) // update Color Chooser 2
1327     {
1328         switch( meMode )
1329         {
1330         case HUE:           maColorSlider.SetValue( aColor, meMode, mdHue / 360.0 ); break;
1331         case SATURATION:    maColorSlider.SetValue( aColor, meMode, mdSat ); break;
1332         case BRIGHTNESS:    maColorSlider.SetValue( aColor, meMode, mdBri ); break;
1333         case RED:           maColorSlider.SetValue( aColor, meMode, mdRed ); break;
1334         case GREEN:         maColorSlider.SetValue( aColor, meMode, mdGreen ); break;
1335         case BLUE:          maColorSlider.SetValue( aColor, meMode, mdBlue ); break;
1336         }
1337     }
1338 
1339     if( n & UPDATE_HEX ) // update hex
1340     {
1341         maEDHex.SetColor( aColor.GetColor()  );
1342     }
1343 
1344     {
1345         Point aPos( 0, maColorSlider.GetLevel() + maColorSlider.GetPosPixel().Y() - 1 );
1346 
1347         aPos.X() = maFISliderLeft.GetPosPixel().X();
1348         if( aPos != maFISliderLeft.GetPosPixel() )
1349         {
1350             maFISliderLeft.SetPosPixel( aPos );
1351 
1352             aPos.X() = maFISliderRight.GetPosPixel().X();
1353             maFISliderRight.SetPosPixel( aPos );
1354         }
1355     }
1356 
1357     maColorPreview.SetColor( aColor );
1358 }
1359 
1360 // --------------------------------------------------------------------
1361 
IMPL_LINK(ColorPickerDialog,ColorModifyHdl,void *,p)1362 IMPL_LINK( ColorPickerDialog, ColorModifyHdl, void *, p )
1363 {
1364     sal_uInt16 n = 0;
1365 
1366     if( p == &maColorField )
1367     {
1368         double x = maColorField.GetX();
1369         double y = maColorField.GetY();
1370 
1371         switch( meMode )
1372         {
1373         case HUE:           mdSat = x; setColorComponent( COLORCOMP_BRI, y ); break;
1374         case SATURATION:    mdHue = x * 360.0; setColorComponent( COLORCOMP_BRI, y ); break;
1375         case BRIGHTNESS:    mdHue = x * 360.0; setColorComponent( COLORCOMP_SAT, y ); break;
1376         case RED:           mdBlue = x; setColorComponent( COLORCOMP_GREEN, y ); break;
1377         case GREEN:         mdBlue = x; setColorComponent( COLORCOMP_RED, y ); break;
1378         case BLUE:          mdRed = x; setColorComponent( COLORCOMP_GREEN, y ); break;
1379         }
1380 
1381         n = UPDATE_ALL&~(UPDATE_COLORCHOOSER);
1382     }
1383     else if( p == &maColorSlider )
1384     {
1385         double dValue = maColorSlider.GetValue();
1386         switch( meMode )
1387         {
1388         case HUE:           setColorComponent( COLORCOMP_HUE, dValue * 360.0 ); break;
1389         case SATURATION:    setColorComponent( COLORCOMP_SAT, dValue ); break;
1390         case BRIGHTNESS:    setColorComponent( COLORCOMP_BRI, dValue ); break;
1391         case RED:           setColorComponent( COLORCOMP_RED, dValue ); break;
1392         case GREEN:         setColorComponent( COLORCOMP_GREEN, dValue ); break;
1393         case BLUE:          setColorComponent( COLORCOMP_BLUE, dValue ); break;
1394         }
1395 
1396         n = UPDATE_ALL&~(UPDATE_COLORSLIDER);
1397     }
1398     else if( p == &maMFRed )
1399     {
1400         setColorComponent( COLORCOMP_RED, ((double)maMFRed.GetValue()) / 255.0 );
1401         n = UPDATE_ALL&~(UPDATE_RGB);
1402     }
1403     else if( p == &maMFGreen )
1404     {
1405         setColorComponent( COLORCOMP_GREEN, ((double)maMFGreen.GetValue()) / 255.0 );
1406         n = UPDATE_ALL&~(UPDATE_RGB);
1407     }
1408     else if( p == &maMFBlue )
1409     {
1410         setColorComponent( COLORCOMP_BLUE, ((double)maMFBlue.GetValue()) / 255.0 );
1411         n = UPDATE_ALL&~(UPDATE_RGB);
1412     }
1413     else if( p == &maMFHue )
1414     {
1415         setColorComponent( COLORCOMP_HUE, (double)maMFHue.GetValue() );
1416         n = UPDATE_ALL&~(UPDATE_HSB);
1417     }
1418     else if( p == &maMFSaturation )
1419     {
1420         setColorComponent( COLORCOMP_SAT, ((double)maMFSaturation.GetValue()) / 100.0 );
1421         n = UPDATE_ALL&~(UPDATE_HSB);
1422     }
1423     else if( p == &maMFBrightness )
1424     {
1425         setColorComponent( COLORCOMP_BRI, ((double)maMFBrightness.GetValue()) / 100.0 );
1426         n = UPDATE_ALL&~(UPDATE_HSB);
1427     }
1428     else if( p == &maMFCyan )
1429     {
1430         setColorComponent( COLORCOMP_CYAN, ((double)maMFCyan.GetValue()) / 100.0 );
1431         n = UPDATE_ALL&~(UPDATE_CMYK);
1432     }
1433     else if( p == &maMFMagenta )
1434     {
1435         setColorComponent( COLORCOMP_MAGENTA, ((double)maMFMagenta.GetValue()) / 100.0 );
1436         n = UPDATE_ALL&~(UPDATE_CMYK);
1437     }
1438     else if( p == &maMFYellow )
1439     {
1440         setColorComponent( COLORCOMP_YELLOW, ((double)maMFYellow.GetValue()) / 100.0 );
1441         n = UPDATE_ALL&~(UPDATE_CMYK);
1442     }
1443     else if( p == &maMFKey )
1444     {
1445         setColorComponent( COLORCOMP_KEY, ((double)maMFKey.GetValue()) / 100.0 );
1446         n = UPDATE_ALL&~(UPDATE_CMYK);
1447     }
1448     else if( p == &maEDHex )
1449     {
1450         sal_Int32 nColor = maEDHex.GetColor();
1451 
1452         if( nColor != -1 )
1453         {
1454             Color aColor( nColor );
1455 
1456             if( aColor != GetColor() )
1457             {
1458                 // #121251# green and blue were wrongly taken
1459                 mdRed = ((double)aColor.GetRed()) / 255.0;
1460                 mdGreen = ((double)aColor.GetGreen()) / 255.0;
1461                 mdBlue = ((double)aColor.GetBlue()) / 255.0;
1462 
1463                 RGBtoHSV( mdRed, mdGreen, mdBlue, mdHue, mdSat, mdBri );
1464                 RGBtoCMYK( mdRed, mdGreen, mdBlue, mdCyan, mdMagenta, mdYellow, mdKey );
1465                 n = UPDATE_ALL&~(UPDATE_HEX);
1466             }
1467         }
1468     }
1469 
1470     if( n )
1471         update_color( n );
1472 
1473     return 0;
1474 }
1475 
1476 // --------------------------------------------------------------------
1477 
IMPL_LINK(ColorPickerDialog,ModeModifyHdl,void *,EMPTYARG)1478 IMPL_LINK( ColorPickerDialog, ModeModifyHdl, void *, EMPTYARG )
1479 {
1480     ColorMode eMode = HUE;
1481 
1482     if( maRBRed.IsChecked() )
1483     {
1484         eMode = RED;
1485     }
1486     else if( maRBGreen.IsChecked() )
1487     {
1488         eMode = GREEN;
1489     }
1490     else if( maRBBlue.IsChecked() )
1491     {
1492         eMode = BLUE;
1493     }
1494     else if( maRBSaturation.IsChecked() )
1495     {
1496         eMode = SATURATION;
1497     }
1498     else if( maRBBrightness.IsChecked() )
1499     {
1500         eMode = BRIGHTNESS;
1501     }
1502 
1503     if( meMode != eMode )
1504     {
1505         meMode = eMode;
1506         update_color( UPDATE_COLORCHOOSER | UPDATE_COLORSLIDER );
1507     }
1508 
1509     return 0;
1510 }
1511 
1512 // --------------------------------------------------------------------
1513 
setColorComponent(sal_uInt16 nComp,double dValue)1514 void ColorPickerDialog::setColorComponent( sal_uInt16 nComp, double dValue )
1515 {
1516     switch( nComp )
1517     {
1518     case COLORCOMP_RED:     mdRed = dValue; break;
1519     case COLORCOMP_GREEN:   mdGreen = dValue; break;
1520     case COLORCOMP_BLUE:    mdBlue = dValue; break;
1521     case COLORCOMP_HUE:     mdHue = dValue; break;
1522     case COLORCOMP_SAT:     mdSat = dValue; break;
1523     case COLORCOMP_BRI:     mdBri = dValue; break;
1524     case COLORCOMP_CYAN:    mdCyan = dValue; break;
1525     case COLORCOMP_YELLOW:  mdYellow = dValue; break;
1526     case COLORCOMP_MAGENTA: mdMagenta = dValue; break;
1527     case COLORCOMP_KEY:     mdKey = dValue; break;
1528     }
1529 
1530     if( nComp & COLORMODE_RGB )
1531     {
1532         RGBtoHSV( mdRed, mdGreen, mdBlue, mdHue, mdSat, mdBri );
1533         RGBtoCMYK( mdRed, mdGreen, mdBlue, mdCyan, mdMagenta, mdYellow, mdKey );
1534     }
1535     else if( nComp & COLORMODE_HSV )
1536     {
1537         HSVtoRGB( mdHue, mdSat, mdBri, mdRed, mdGreen, mdBlue );
1538         RGBtoCMYK( mdRed, mdGreen, mdBlue, mdCyan, mdMagenta, mdYellow, mdKey );
1539     }
1540     else
1541     {
1542         CMYKtoRGB( mdCyan, mdMagenta, mdYellow, mdKey, mdRed, mdGreen, mdBlue );
1543         RGBtoHSV( mdRed, mdGreen, mdBlue, mdHue, mdSat, mdBri );
1544     }
1545 }
1546 
1547 // --------------------------------------------------------------------
1548 
1549 typedef ::cppu::WeakComponentImplHelper4< XServiceInfo, XExecutableDialog, XInitialization, XPropertyAccess > ColorPickerBase;
1550 
1551 class ColorPicker : protected ::comphelper::OBaseMutex,    // Struct for right initalization of mutex member! Must be first of baseclasses.
1552                     public ColorPickerBase
1553 {
1554 public:
1555     ColorPicker( Reference< XComponentContext > const & xContext );
1556 
1557     // XInitialization
1558     virtual void SAL_CALL initialize( const Sequence< Any >& aArguments ) throw (Exception, RuntimeException);
1559 
1560     // XInitialization
1561     virtual OUString SAL_CALL getImplementationName(  ) throw (RuntimeException);
1562     virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw (RuntimeException);
1563     virtual Sequence< OUString > SAL_CALL getSupportedServiceNames(  ) throw (RuntimeException);
1564 
1565     // XPropertyAccess
1566     virtual Sequence< PropertyValue > SAL_CALL getPropertyValues(  ) throw (RuntimeException);
1567     virtual void SAL_CALL setPropertyValues( const Sequence< PropertyValue >& aProps ) throw (UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException);
1568 
1569     // XExecutableDialog
1570     virtual void SAL_CALL setTitle( const OUString& aTitle ) throw (RuntimeException);
1571     virtual sal_Int16 SAL_CALL execute(  ) throw (RuntimeException);
1572 
1573 private:
1574     Reference< XComponentContext > mxContext;
1575     OUString msTitle;
1576     const OUString msColorKey;
1577     const OUString msModeKey;
1578     sal_Int32 mnColor;
1579     sal_Int16 mnMode;
1580     Reference< ::com::sun::star::awt::XWindow > mxParent;
1581 };
1582 
1583 // --------------------------------------------------------------------
1584 
ColorPicker_getImplementationName()1585 OUString SAL_CALL ColorPicker_getImplementationName()
1586 {
1587     return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.cui.ColorPicker" ) );
1588 }
1589 
1590 // --------------------------------------------------------------------
1591 
ColorPicker_createInstance(Reference<XComponentContext> const & xContext)1592 Reference< XInterface > SAL_CALL ColorPicker_createInstance( Reference< XComponentContext > const & xContext ) SAL_THROW( (Exception) )
1593 {
1594     return static_cast<XWeak*>( new ColorPicker( xContext ) );
1595 }
1596 
1597 // --------------------------------------------------------------------
1598 
ColorPicker_getSupportedServiceNames()1599 Sequence< OUString > SAL_CALL ColorPicker_getSupportedServiceNames() throw( RuntimeException )
1600 {
1601     Sequence< OUString > seq(1);
1602     seq[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ui.dialogs.ColorPicker" ) );
1603     return seq;
1604 }
1605 
1606 // --------------------------------------------------------------------
1607 
ColorPicker(Reference<XComponentContext> const & xContext)1608 ColorPicker::ColorPicker( Reference< XComponentContext > const & xContext )
1609 : ColorPickerBase( m_aMutex )
1610 , mxContext( xContext )
1611 , msColorKey( RTL_CONSTASCII_USTRINGPARAM( "Color" ) )
1612 , msModeKey( RTL_CONSTASCII_USTRINGPARAM( "Mode" ) )
1613 , mnColor( 0 )
1614 , mnMode( 0 )
1615 {
1616 }
1617 
1618 // --------------------------------------------------------------------
1619 
1620 // XInitialization
initialize(const Sequence<Any> & aArguments)1621 void SAL_CALL ColorPicker::initialize( const Sequence< Any >& aArguments ) throw (Exception, RuntimeException)
1622 {
1623     if( aArguments.getLength() == 1 )
1624     {
1625         aArguments[0] >>= mxParent;
1626     }
1627 }
1628 
1629 // --------------------------------------------------------------------
1630 
1631 // XInitialization
getImplementationName()1632 OUString SAL_CALL ColorPicker::getImplementationName(  ) throw (RuntimeException)
1633 {
1634     return ColorPicker_getImplementationName();
1635 }
1636 
1637 // --------------------------------------------------------------------
1638 
supportsService(const OUString & sServiceName)1639 sal_Bool SAL_CALL ColorPicker::supportsService( const OUString& sServiceName ) throw (RuntimeException)
1640 {
1641     return sServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.ui.dialogs.ColorPicker" ) );
1642 }
1643 
1644 // --------------------------------------------------------------------
1645 
getSupportedServiceNames()1646 Sequence< OUString > SAL_CALL ColorPicker::getSupportedServiceNames(  ) throw (RuntimeException)
1647 {
1648     return ColorPicker_getSupportedServiceNames();
1649 }
1650 
1651 // --------------------------------------------------------------------
1652 
1653 // XPropertyAccess
getPropertyValues()1654 Sequence< PropertyValue > SAL_CALL ColorPicker::getPropertyValues(  ) throw (RuntimeException)
1655 {
1656     Sequence< PropertyValue > props(1);
1657     props[0].Name = msColorKey;
1658     props[0].Value <<= mnColor;
1659     return props;
1660 }
1661 
1662 // --------------------------------------------------------------------
1663 
setPropertyValues(const Sequence<PropertyValue> & aProps)1664 void SAL_CALL ColorPicker::setPropertyValues( const Sequence< PropertyValue >& aProps ) throw (UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException)
1665 {
1666     for( sal_Int32 n = 0; n < aProps.getLength(); n++ )
1667     {
1668         if( aProps[n].Name.equals( msColorKey ) )
1669         {
1670             aProps[n].Value >>= mnColor;
1671         }
1672         else if( aProps[n].Name.equals( msModeKey ) )
1673         {
1674             aProps[n].Value >>= mnMode;
1675         }
1676     }
1677 }
1678 
1679 // --------------------------------------------------------------------
1680 
1681 // XExecutableDialog
setTitle(const OUString & sTitle)1682 void SAL_CALL ColorPicker::setTitle( const OUString& sTitle ) throw (RuntimeException)
1683 {
1684     msTitle = sTitle;
1685 }
1686 
1687 // --------------------------------------------------------------------
1688 
execute()1689 sal_Int16 SAL_CALL ColorPicker::execute(  ) throw (RuntimeException)
1690 {
1691     ColorPickerDialog aDlg( VCLUnoHelper::GetWindow( mxParent ), mnColor, mnMode );
1692     sal_Int16 ret = aDlg.Execute();
1693     if( ret )
1694         mnColor = aDlg.GetColor();
1695 
1696     return ret;
1697 }
1698 
1699 // --------------------------------------------------------------------
1700 
1701 }
1702 
1703 // eof
1704