1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <com/sun/star/uno/XComponentContext.hpp>
21 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
22 #include <com/sun/star/beans/XPropertyAccess.hpp>
23 #include <com/sun/star/lang/XInitialization.hpp>
24 #include <com/sun/star/lang/XServiceInfo.hpp>
25 #include <com/sun/star/awt/XWindow.hpp>
26 #include <cppuhelper/compbase.hxx>
27 #include <cppuhelper/supportsservice.hxx>
28 #include <cppuhelper/basemutex.hxx>
29 #include <vcl/customweld.hxx>
30 #include <vcl/event.hxx>
31 #include <vcl/svapp.hxx>
32 #include <vcl/virdev.hxx>
33 #include <vcl/weld.hxx>
34 #include <svx/hexcolorcontrol.hxx>
35 #include <basegfx/color/bcolortools.hxx>
36 #include <colorpicker.hxx>
37 #include <cmath>
38 #include <o3tl/typed_flags_set.hxx>
39 
40 using namespace ::com::sun::star::uno;
41 using namespace ::com::sun::star::lang;
42 using namespace ::com::sun::star::ui::dialogs;
43 using namespace ::com::sun::star::beans;
44 using namespace ::basegfx;
45 
46 enum class UpdateFlags
47 {
48     NONE         = 0x00,
49     RGB          = 0x01,
50     CMYK         = 0x02,
51     HSB          = 0x04,
52     ColorChooser = 0x08,
53     ColorSlider  = 0x10,
54     Hex          = 0x20,
55     All          = 0x3f,
56 };
57 namespace o3tl {
58     template<> struct typed_flags<UpdateFlags> : is_typed_flags<UpdateFlags, 0x3f> {};
59 }
60 
61 
62 namespace cui
63 {
64 
65 enum class ColorComponent {
66     Red,
67     Green,
68     Blue,
69     Hue,
70     Saturation,
71     Brightness,
72     Cyan,
73     Yellow,
74     Magenta,
75     Key,
76 };
77 
78 
79 // color space conversion helpers
80 
RGBtoHSV(double dR,double dG,double dB,double & dH,double & dS,double & dV)81 static void RGBtoHSV( double dR, double dG, double dB, double& dH, double& dS, double& dV )
82 {
83     BColor result = basegfx::utils::rgb2hsv( BColor( dR, dG, dB ) );
84 
85     dH = result.getX();
86     dS = result.getY();
87     dV = result.getZ();
88 }
89 
HSVtoRGB(double dH,double dS,double dV,double & dR,double & dG,double & dB)90 static void HSVtoRGB(double dH, double dS, double dV, double& dR, double& dG, double& dB )
91 {
92     BColor result = basegfx::utils::hsv2rgb( BColor( dH, dS, dV ) );
93 
94     dR = result.getRed();
95     dG = result.getGreen();
96     dB = result.getBlue();
97 }
98 
99 // CMYK values from 0 to 1
CMYKtoRGB(double fCyan,double fMagenta,double fYellow,double fKey,double & dR,double & dG,double & dB)100 static void CMYKtoRGB( double fCyan, double fMagenta, double fYellow, double fKey, double& dR, double& dG, double& dB )
101 {
102     fCyan = (fCyan * ( 1.0 - fKey )) + fKey;
103     fMagenta = (fMagenta * ( 1.0 - fKey )) + fKey;
104     fYellow = (fYellow * ( 1.0 - fKey )) + fKey;
105 
106     dR = std::max( std::min( ( 1.0 - fCyan ), 1.0), 0.0 );
107     dG = std::max( std::min( ( 1.0 - fMagenta ), 1.0), 0.0 );
108     dB = std::max( std::min( ( 1.0 - fYellow ), 1.0), 0.0 );
109 }
110 
111 // CMY results from 0 to 1
RGBtoCMYK(double dR,double dG,double dB,double & fCyan,double & fMagenta,double & fYellow,double & fKey)112 static void RGBtoCMYK( double dR, double dG, double dB, double& fCyan, double& fMagenta, double& fYellow, double& fKey )
113 {
114     fCyan = 1 - dR;
115     fMagenta = 1 - dG;
116     fYellow = 1 - dB;
117 
118     //CMYK and CMY values from 0 to 1
119     fKey = 1.0;
120     if( fCyan < fKey ) fKey = fCyan;
121     if( fMagenta < fKey ) fKey = fMagenta;
122     if( fYellow < fKey ) fKey = fYellow;
123 
124     if( fKey >= 1.0 )
125     {
126         //Black
127        fCyan = 0.0;
128        fMagenta = 0.0;
129        fYellow = 0.0;
130     }
131     else
132     {
133        fCyan = ( fCyan - fKey ) / ( 1.0 - fKey );
134        fMagenta = ( fMagenta - fKey ) / ( 1.0 - fKey );
135        fYellow = ( fYellow - fKey ) / ( 1.0 - fKey );
136     }
137 }
138 
139 class ColorPreviewControl : public weld::CustomWidgetController
140 {
141 private:
142     Color m_aColor;
143 
144     virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&) override;
145 public:
ColorPreviewControl()146     ColorPreviewControl()
147     {
148     }
149 
SetDrawingArea(weld::DrawingArea * pDrawingArea)150     virtual void SetDrawingArea(weld::DrawingArea* pDrawingArea) override
151     {
152         CustomWidgetController::SetDrawingArea(pDrawingArea);
153         pDrawingArea->set_size_request(pDrawingArea->get_approximate_digit_width() * 10,
154                                        pDrawingArea->get_text_height() * 2);
155     }
156 
SetColor(const Color & rCol)157     void SetColor(const Color& rCol)
158     {
159         if (rCol != m_aColor)
160         {
161             m_aColor = rCol;
162             Invalidate();
163         }
164     }
165 };
166 
Paint(vcl::RenderContext & rRenderContext,const tools::Rectangle &)167 void ColorPreviewControl::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&)
168 {
169     rRenderContext.SetFillColor(m_aColor);
170     rRenderContext.SetLineColor(m_aColor);
171     rRenderContext.DrawRect(tools::Rectangle(Point(0, 0), GetOutputSizePixel()));
172 }
173 
174 enum ColorMode { HUE, SATURATION, BRIGHTNESS, RED, GREEN, BLUE };
175 const ColorMode DefaultMode = HUE;
176 
177 class ColorFieldControl : public weld::CustomWidgetController
178 {
179 public:
ColorFieldControl()180     ColorFieldControl()
181         : meMode( DefaultMode )
182         , mdX( -1.0 )
183         , mdY( -1.0 )
184         , mbMouseCaptured(false)
185     {
186     }
187 
SetDrawingArea(weld::DrawingArea * pDrawingArea)188     virtual void SetDrawingArea(weld::DrawingArea* pDrawingArea) override
189     {
190         CustomWidgetController::SetDrawingArea(pDrawingArea);
191         pDrawingArea->set_size_request(pDrawingArea->get_approximate_digit_width() * 40,
192                                        pDrawingArea->get_text_height() * 10);
193     }
194 
~ColorFieldControl()195     virtual ~ColorFieldControl() override
196     {
197         mxBitmap.disposeAndClear();
198     }
199 
200     virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) override;
201     virtual void Resize() override;
202     virtual bool MouseButtonDown(const MouseEvent& rMEvt) override;
203     virtual bool MouseMove(const MouseEvent& rMEvt) override;
204     virtual bool MouseButtonUp(const MouseEvent& rMEvt) override;
205 
206     void UpdateBitmap();
207     void ShowPosition( const Point& rPos, bool bUpdate );
208     void UpdatePosition();
209     void Modify();
210 
211     void SetValues(Color aColor, ColorMode eMode, double x, double y);
GetX() const212     double GetX() const { return mdX;}
GetY() const213     double GetY() const { return mdY;}
214 
SetModifyHdl(const Link<ColorFieldControl &,void> & rLink)215     void SetModifyHdl(const Link<ColorFieldControl&,void>& rLink) { maModifyHdl = rLink; }
216 
217 private:
218     ColorMode meMode;
219     Color maColor;
220     double mdX;
221     double mdY;
222     bool mbMouseCaptured;
223     Point maPosition;
224     VclPtr<VirtualDevice> mxBitmap;
225     Link<ColorFieldControl&,void> maModifyHdl;
226     std::vector<sal_uInt8>  maRGB_Horiz;
227     std::vector<sal_uInt16> maGrad_Horiz;
228     std::vector<sal_uInt16> maPercent_Horiz;
229     std::vector<sal_uInt8>  maRGB_Vert;
230     std::vector<sal_uInt16> maPercent_Vert;
231 };
232 
UpdateBitmap()233 void ColorFieldControl::UpdateBitmap()
234 {
235     const Size aSize(GetOutputSizePixel());
236 
237     if (mxBitmap && mxBitmap->GetOutputSizePixel() != aSize)
238         mxBitmap.disposeAndClear();
239 
240     const sal_Int32 nWidth = aSize.Width();
241     const sal_Int32 nHeight = aSize.Height();
242 
243     if (nWidth == 0 || nHeight == 0)
244         return;
245 
246     if (!mxBitmap)
247     {
248         mxBitmap = VclPtr<VirtualDevice>::Create();
249         mxBitmap->SetOutputSizePixel(aSize);
250 
251         maRGB_Horiz.resize( nWidth );
252         maGrad_Horiz.resize( nWidth );
253         maPercent_Horiz.resize( nWidth );
254 
255         sal_uInt8* pRGB = maRGB_Horiz.data();
256         sal_uInt16* pGrad = maGrad_Horiz.data();
257         sal_uInt16* pPercent = maPercent_Horiz.data();
258 
259         for( sal_Int32 x = 0; x < nWidth; x++ )
260         {
261             *pRGB++ = static_cast<sal_uInt8>((x * 256) / nWidth);
262             *pGrad++ = static_cast<sal_uInt16>((x * 359) / nWidth);
263             *pPercent++ = static_cast<sal_uInt16>((x * 100) / nWidth);
264         }
265 
266         maRGB_Vert.resize(nHeight);
267         maPercent_Vert.resize(nHeight);
268 
269         pRGB = maRGB_Vert.data();
270         pPercent = maPercent_Vert.data();
271 
272         sal_Int32 y = nHeight;
273         while (y--)
274         {
275             *pRGB++ = static_cast<sal_uInt8>((y * 256) / nHeight);
276             *pPercent++ = static_cast<sal_uInt16>((y * 100) / nHeight);
277         }
278     }
279 
280     sal_uInt8* pRGB_Horiz = maRGB_Horiz.data();
281     sal_uInt16* pGrad_Horiz = maGrad_Horiz.data();
282     sal_uInt16* pPercent_Horiz = maPercent_Horiz.data();
283     sal_uInt8* pRGB_Vert = maRGB_Vert.data();
284     sal_uInt16* pPercent_Vert = maPercent_Vert.data();
285 
286     Color aBitmapColor(maColor);
287 
288     sal_uInt16 nHue, nSat, nBri;
289     maColor.RGBtoHSB(nHue, nSat, nBri);
290 
291         // this has been unlooped for performance reason, please do not merge back!
292 
293     sal_uInt16 y = nHeight,x;
294 
295     switch(meMode)
296     {
297         case HUE:
298             while (y--)
299             {
300                 nBri = pPercent_Vert[y];
301                 x = nWidth;
302                 while (x--)
303                 {
304                     nSat = pPercent_Horiz[x];
305                     mxBitmap->DrawPixel(Point(x,y), Color::HSBtoRGB(nHue, nSat, nBri));
306                 }
307             }
308             break;
309         case SATURATION:
310             while (y--)
311             {
312                 nBri = pPercent_Vert[y];
313                 x = nWidth;
314                 while (x--)
315                 {
316                     nHue = pGrad_Horiz[x];
317                     mxBitmap->DrawPixel(Point(x,y), Color::HSBtoRGB(nHue, nSat, nBri));
318                 }
319             }
320             break;
321         case BRIGHTNESS:
322             while (y--)
323             {
324                 nSat = pPercent_Vert[y];
325                 x = nWidth;
326                 while (x--)
327                 {
328                     nHue = pGrad_Horiz[x];
329                     mxBitmap->DrawPixel(Point(x,y), Color::HSBtoRGB(nHue, nSat, nBri));
330                 }
331             }
332             break;
333         case RED:
334             while (y--)
335             {
336                 aBitmapColor.SetGreen(pRGB_Vert[y]);
337                 x = nWidth;
338                 while (x--)
339                 {
340                     aBitmapColor.SetBlue(pRGB_Horiz[x]);
341                     mxBitmap->DrawPixel(Point(x,y), aBitmapColor);
342                 }
343             }
344             break;
345         case GREEN:
346             while (y--)
347             {
348                 aBitmapColor.SetRed(pRGB_Vert[y]);
349                 x = nWidth;
350                 while (x--)
351                 {
352                     aBitmapColor.SetBlue(pRGB_Horiz[x]);
353                     mxBitmap->DrawPixel(Point(x,y), aBitmapColor);
354                 }
355             }
356             break;
357         case BLUE:
358             while (y--)
359             {
360                 aBitmapColor.SetGreen(pRGB_Vert[y]);
361                 x = nWidth;
362                 while (x--)
363                 {
364                     aBitmapColor.SetRed(pRGB_Horiz[x]);
365                     mxBitmap->DrawPixel(Point(x,y), aBitmapColor);
366                 }
367             }
368             break;
369     }
370 }
371 
ShowPosition(const Point & rPos,bool bUpdate)372 void ColorFieldControl::ShowPosition( const Point& rPos, bool bUpdate )
373 {
374     if (!mxBitmap)
375     {
376         UpdateBitmap();
377         Invalidate();
378     }
379 
380     if (!mxBitmap)
381         return;
382 
383     const Size aSize(mxBitmap->GetOutputSizePixel());
384 
385     long nX = rPos.X();
386     long nY = rPos.Y();
387     if (nX < 0)
388         nX = 0;
389     else if (nX >= aSize.Width())
390         nX = aSize.Width() - 1;
391 
392     if (nY < 0)
393         nY = 0;
394     else if (nY >= aSize.Height())
395         nY = aSize.Height() - 1;
396 
397     Point aPos = maPosition;
398     maPosition.setX( nX - 5 );
399     maPosition.setY( nY - 5 );
400     Invalidate(tools::Rectangle(aPos, Size(11, 11)));
401     Invalidate(tools::Rectangle(maPosition, Size(11, 11)));
402 
403     if (bUpdate)
404     {
405         mdX = double(nX) / double(aSize.Width() - 1.0);
406         mdY = double(aSize.Height() - 1.0 - nY) / double(aSize.Height() - 1.0);
407 
408         maColor = mxBitmap->GetPixel(Point(nX, nY));
409     }
410 }
411 
MouseButtonDown(const MouseEvent & rMEvt)412 bool ColorFieldControl::MouseButtonDown(const MouseEvent& rMEvt)
413 {
414     CaptureMouse();
415     mbMouseCaptured = true;
416     ShowPosition(rMEvt.GetPosPixel(), true);
417     Modify();
418     return true;
419 }
420 
MouseMove(const MouseEvent & rMEvt)421 bool ColorFieldControl::MouseMove(const MouseEvent& rMEvt)
422 {
423     if (mbMouseCaptured)
424     {
425         ShowPosition(rMEvt.GetPosPixel(), true);
426         Modify();
427     }
428     return true;
429 }
430 
MouseButtonUp(const MouseEvent &)431 bool ColorFieldControl::MouseButtonUp(const MouseEvent&)
432 {
433     ReleaseMouse();
434     mbMouseCaptured = false;
435     return true;
436 }
437 
Paint(vcl::RenderContext & rRenderContext,const tools::Rectangle &)438 void ColorFieldControl::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&)
439 {
440     if (!mxBitmap)
441         UpdateBitmap();
442 
443     if (mxBitmap)
444     {
445         Size aSize(GetOutputSizePixel());
446         rRenderContext.DrawOutDev(Point(0, 0), aSize, Point(0, 0), aSize, *mxBitmap);
447     }
448 
449     // draw circle around current color
450     if (maColor.IsDark())
451         rRenderContext.SetLineColor( COL_WHITE );
452     else
453         rRenderContext.SetLineColor( COL_BLACK );
454 
455     rRenderContext.SetFillColor();
456 
457     rRenderContext.DrawEllipse(::tools::Rectangle(maPosition, Size(11, 11)));
458 }
459 
Resize()460 void ColorFieldControl::Resize()
461 {
462     CustomWidgetController::Resize();
463     UpdateBitmap();
464     UpdatePosition();
465 }
466 
Modify()467 void ColorFieldControl::Modify()
468 {
469     maModifyHdl.Call( *this );
470 }
471 
SetValues(Color aColor,ColorMode eMode,double x,double y)472 void ColorFieldControl::SetValues( Color aColor, ColorMode eMode, double x, double y )
473 {
474     bool bUpdateBitmap = (maColor!= aColor) || (meMode != eMode);
475     if( bUpdateBitmap || (mdX != x) || (mdY != y) )
476     {
477         maColor = aColor;
478         meMode = eMode;
479         mdX = x;
480         mdY = y;
481 
482         if (bUpdateBitmap)
483             UpdateBitmap();
484         UpdatePosition();
485         if (bUpdateBitmap)
486             Invalidate();
487     }
488 }
489 
UpdatePosition()490 void ColorFieldControl::UpdatePosition()
491 {
492     Size aSize(GetOutputSizePixel());
493     ShowPosition(Point(static_cast<long>(mdX * aSize.Width()), static_cast<long>((1.0 - mdY) * aSize.Height())), false);
494 }
495 
496 class ColorSliderControl : public weld::CustomWidgetController
497 {
498 public:
499     ColorSliderControl();
500     virtual ~ColorSliderControl() override;
501 
502     virtual void SetDrawingArea(weld::DrawingArea* pDrawingArea) override;
503 
504     virtual bool MouseButtonDown(const MouseEvent& rMEvt) override;
505     virtual bool MouseMove(const MouseEvent& rMEvt) override;
506     virtual bool MouseButtonUp(const MouseEvent& rMEvt) override;
507     virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&) override;
508     virtual void Resize() override;
509 
510     void UpdateBitmap();
511     void ChangePosition( long nY );
512     void Modify();
513 
514     void SetValue( const Color& rColor, ColorMode eMode, double dValue );
GetValue() const515     double GetValue() const { return mdValue; }
516 
SetModifyHdl(const Link<ColorSliderControl &,void> & rLink)517     void SetModifyHdl( const Link<ColorSliderControl&,void>& rLink ) { maModifyHdl = rLink; }
518 
GetLevel() const519     sal_Int16 GetLevel() const { return mnLevel; }
520 
521 private:
522     Link<ColorSliderControl&,void> maModifyHdl;
523     Color maColor;
524     ColorMode meMode;
525     VclPtr<VirtualDevice> mxBitmap;
526     sal_Int16 mnLevel;
527     double mdValue;
528 };
529 
ColorSliderControl()530 ColorSliderControl::ColorSliderControl()
531     : meMode( DefaultMode )
532     , mnLevel( 0 )
533     , mdValue( -1.0 )
534 {
535 }
536 
SetDrawingArea(weld::DrawingArea * pDrawingArea)537 void ColorSliderControl::SetDrawingArea(weld::DrawingArea* pDrawingArea)
538 {
539     CustomWidgetController::SetDrawingArea(pDrawingArea);
540     pDrawingArea->set_size_request(pDrawingArea->get_approximate_digit_width() * 3, -1);
541 }
542 
~ColorSliderControl()543 ColorSliderControl::~ColorSliderControl()
544 {
545     mxBitmap.disposeAndClear();
546 }
547 
UpdateBitmap()548 void ColorSliderControl::UpdateBitmap()
549 {
550     Size aSize(1, GetOutputSizePixel().Height());
551 
552     if (mxBitmap && mxBitmap->GetOutputSizePixel() != aSize)
553         mxBitmap.disposeAndClear();
554 
555     if (!mxBitmap)
556     {
557         mxBitmap = VclPtr<VirtualDevice>::Create();
558         mxBitmap->SetOutputSizePixel(aSize);
559     }
560 
561     const long nY = aSize.Height() - 1;
562 
563     Color aBitmapColor(maColor);
564 
565     sal_uInt16 nHue, nSat, nBri;
566     maColor.RGBtoHSB(nHue, nSat, nBri);
567 
568     // this has been unlooped for performance reason, please do not merge back!
569 
570     switch (meMode)
571     {
572     case HUE:
573         nSat = 100;
574         nBri = 100;
575         for (long y = 0; y <= nY; y++)
576         {
577             nHue = static_cast<sal_uInt16>((359 * y) / nY);
578             mxBitmap->DrawPixel(Point(0, nY - y), Color::HSBtoRGB(nHue, nSat, nBri));
579         }
580         break;
581 
582     case SATURATION:
583         nBri = std::max(sal_uInt16(32), nBri);
584         for (long y = 0; y <= nY; y++)
585         {
586             nSat = static_cast<sal_uInt16>((100 * y) / nY);
587             mxBitmap->DrawPixel(Point(0, nY - y), Color::HSBtoRGB(nHue, nSat, nBri));
588         }
589         break;
590 
591     case BRIGHTNESS:
592         for (long y = 0; y <= nY; y++)
593         {
594             nBri = static_cast<sal_uInt16>((100 * y) / nY);
595             mxBitmap->DrawPixel(Point(0, nY - y), Color::HSBtoRGB(nHue, nSat, nBri));
596         }
597         break;
598 
599     case RED:
600         for (long y = 0; y <= nY; y++)
601         {
602             aBitmapColor.SetRed(sal_uInt8((long(255) * y) / nY));
603             mxBitmap->DrawPixel(Point(0, nY - y), aBitmapColor);
604         }
605         break;
606 
607     case GREEN:
608         for (long y = 0; y <= nY; y++)
609         {
610             aBitmapColor.SetGreen(sal_uInt8((long(255) * y) / nY));
611             mxBitmap->DrawPixel(Point(0, nY - y), aBitmapColor);
612         }
613         break;
614 
615     case BLUE:
616         for (long y = 0; y <= nY; y++)
617         {
618             aBitmapColor.SetBlue(sal_uInt8((long(255) * y) / nY));
619             mxBitmap->DrawPixel(Point(0, nY - y), aBitmapColor);
620         }
621         break;
622     }
623 }
624 
ChangePosition(long nY)625 void ColorSliderControl::ChangePosition(long nY)
626 {
627     const long nHeight = GetOutputSizePixel().Height() - 1;
628 
629     if (nY < 0)
630         nY = 0;
631     else if (nY > nHeight)
632         nY = nHeight;
633 
634     mnLevel = nY;
635     mdValue = double(nHeight - nY) / double(nHeight);
636 }
637 
MouseButtonDown(const MouseEvent & rMEvt)638 bool ColorSliderControl::MouseButtonDown(const MouseEvent& rMEvt)
639 {
640     CaptureMouse();
641     ChangePosition(rMEvt.GetPosPixel().Y());
642     Modify();
643     return true;
644 }
645 
MouseMove(const MouseEvent & rMEvt)646 bool ColorSliderControl::MouseMove(const MouseEvent& rMEvt)
647 {
648     if (IsMouseCaptured())
649     {
650         ChangePosition(rMEvt.GetPosPixel().Y());
651         Modify();
652     }
653     return true;
654 }
655 
MouseButtonUp(const MouseEvent &)656 bool ColorSliderControl::MouseButtonUp(const MouseEvent&)
657 {
658     ReleaseMouse();
659     return true;
660 }
661 
Paint(vcl::RenderContext & rRenderContext,const tools::Rectangle &)662 void ColorSliderControl::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&)
663 {
664     if (!mxBitmap)
665         UpdateBitmap();
666 
667     const Size aSize(GetOutputSizePixel());
668 
669     Point aPos;
670     int x = aSize.Width();
671     while (x--)
672     {
673         rRenderContext.DrawOutDev(aPos, aSize, Point(0,0), aSize, *mxBitmap);
674         aPos.AdjustX(1);
675     }
676 }
677 
Resize()678 void ColorSliderControl::Resize()
679 {
680     CustomWidgetController::Resize();
681     UpdateBitmap();
682 }
683 
Modify()684 void ColorSliderControl::Modify()
685 {
686     maModifyHdl.Call(*this);
687 }
688 
SetValue(const Color & rColor,ColorMode eMode,double dValue)689 void ColorSliderControl::SetValue(const Color& rColor, ColorMode eMode, double dValue)
690 {
691     bool bUpdateBitmap = (rColor != maColor) || (eMode != meMode);
692     if( bUpdateBitmap || (mdValue != dValue))
693     {
694         maColor = rColor;
695         mdValue = dValue;
696         mnLevel = static_cast<sal_Int16>((1.0-dValue) * GetOutputSizePixel().Height());
697         meMode = eMode;
698         if (bUpdateBitmap)
699             UpdateBitmap();
700         Invalidate();
701     }
702 }
703 
704 class ColorPickerDialog : public weld::GenericDialogController
705 {
706 private:
707     ColorFieldControl m_aColorField;
708     ColorSliderControl m_aColorSlider;
709     ColorPreviewControl m_aColorPreview;
710     ColorPreviewControl m_aColorPrevious;
711 
712     std::unique_ptr<weld::CustomWeld> m_xColorField;
713     std::unique_ptr<weld::CustomWeld> m_xColorSlider;
714     std::unique_ptr<weld::CustomWeld> m_xColorPreview;
715     std::unique_ptr<weld::CustomWeld> m_xColorPrevious;
716 
717     std::unique_ptr<weld::Widget> m_xFISliderLeft;
718     std::unique_ptr<weld::Widget> m_xFISliderRight;
719     std::unique_ptr<weld::RadioButton> m_xRBRed;
720     std::unique_ptr<weld::RadioButton> m_xRBGreen;
721     std::unique_ptr<weld::RadioButton> m_xRBBlue;
722     std::unique_ptr<weld::RadioButton> m_xRBHue;
723     std::unique_ptr<weld::RadioButton> m_xRBSaturation;
724     std::unique_ptr<weld::RadioButton> m_xRBBrightness;
725 
726     std::unique_ptr<weld::SpinButton> m_xMFRed;
727     std::unique_ptr<weld::SpinButton> m_xMFGreen;
728     std::unique_ptr<weld::SpinButton> m_xMFBlue;
729     std::unique_ptr<weld::HexColorControl> m_xEDHex;
730 
731     std::unique_ptr<weld::MetricSpinButton> m_xMFHue;
732     std::unique_ptr<weld::MetricSpinButton> m_xMFSaturation;
733     std::unique_ptr<weld::MetricSpinButton> m_xMFBrightness;
734 
735     std::unique_ptr<weld::MetricSpinButton> m_xMFCyan;
736     std::unique_ptr<weld::MetricSpinButton> m_xMFMagenta;
737     std::unique_ptr<weld::MetricSpinButton> m_xMFYellow;
738     std::unique_ptr<weld::MetricSpinButton> m_xMFKey;
739 
740 public:
741     ColorPickerDialog(weld::Window* pParent, Color nColor, sal_Int16 nMode);
742 
743     void update_color(UpdateFlags n = UpdateFlags::All);
744 
745     DECL_LINK(ColorFieldControlModifydl, ColorFieldControl&, void);
746     DECL_LINK(ColorSliderControlModifyHdl, ColorSliderControl&, void);
747     DECL_LINK(ColorModifyMetricHdl, weld::MetricSpinButton&, void);
748     DECL_LINK(ColorModifySpinHdl, weld::SpinButton&, void);
749     DECL_LINK(ColorModifyEditHdl, weld::Entry&, void);
750     DECL_LINK(ModeModifyHdl, weld::ToggleButton&, void);
751 
752     Color GetColor() const;
753 
754     void setColorComponent(ColorComponent nComp, double dValue);
755 
756 private:
757     ColorMode meMode;
758 
759     double mdRed, mdGreen, mdBlue;
760     double mdHue, mdSat, mdBri;
761     double mdCyan, mdMagenta, mdYellow, mdKey;
762 };
763 
ColorPickerDialog(weld::Window * pParent,Color nColor,sal_Int16 nDialogMode)764 ColorPickerDialog::ColorPickerDialog(weld::Window* pParent, Color nColor, sal_Int16 nDialogMode)
765     : GenericDialogController(pParent, "cui/ui/colorpickerdialog.ui", "ColorPicker")
766     , m_xColorField(new weld::CustomWeld(*m_xBuilder, "colorField", m_aColorField))
767     , m_xColorSlider(new weld::CustomWeld(*m_xBuilder, "colorSlider", m_aColorSlider))
768     , m_xColorPreview(new weld::CustomWeld(*m_xBuilder, "preview", m_aColorPreview))
769     , m_xColorPrevious(new weld::CustomWeld(*m_xBuilder, "previous", m_aColorPrevious))
770     , m_xFISliderLeft(m_xBuilder->weld_widget("leftImage"))
771     , m_xFISliderRight(m_xBuilder->weld_widget("rightImage"))
772     , m_xRBRed(m_xBuilder->weld_radio_button("redRadiobutton"))
773     , m_xRBGreen(m_xBuilder->weld_radio_button("greenRadiobutton"))
774     , m_xRBBlue(m_xBuilder->weld_radio_button("blueRadiobutton"))
775     , m_xRBHue(m_xBuilder->weld_radio_button("hueRadiobutton"))
776     , m_xRBSaturation(m_xBuilder->weld_radio_button("satRadiobutton"))
777     , m_xRBBrightness(m_xBuilder->weld_radio_button("brightRadiobutton"))
778     , m_xMFRed(m_xBuilder->weld_spin_button("redSpinbutton"))
779     , m_xMFGreen(m_xBuilder->weld_spin_button("greenSpinbutton"))
780     , m_xMFBlue(m_xBuilder->weld_spin_button("blueSpinbutton"))
781     , m_xEDHex(new weld::HexColorControl(m_xBuilder->weld_entry("hexEntry")))
782     , m_xMFHue(m_xBuilder->weld_metric_spin_button("hueSpinbutton", FieldUnit::DEGREE))
783     , m_xMFSaturation(m_xBuilder->weld_metric_spin_button("satSpinbutton", FieldUnit::PERCENT))
784     , m_xMFBrightness(m_xBuilder->weld_metric_spin_button("brightSpinbutton", FieldUnit::PERCENT))
785     , m_xMFCyan(m_xBuilder->weld_metric_spin_button("cyanSpinbutton", FieldUnit::PERCENT))
786     , m_xMFMagenta(m_xBuilder->weld_metric_spin_button("magSpinbutton", FieldUnit::PERCENT))
787     , m_xMFYellow(m_xBuilder->weld_metric_spin_button("yellowSpinbutton", FieldUnit::PERCENT))
788     , m_xMFKey(m_xBuilder->weld_metric_spin_button("keySpinbutton", FieldUnit::PERCENT))
789     , meMode( DefaultMode )
790 {
791     m_aColorField.SetModifyHdl( LINK( this, ColorPickerDialog, ColorFieldControlModifydl ) );
792     m_aColorSlider.SetModifyHdl( LINK( this, ColorPickerDialog, ColorSliderControlModifyHdl ) );
793 
794     int nMargin = (m_xFISliderLeft->get_preferred_size().Height() + 1) / 2;
795     m_xColorSlider->set_margin_top(nMargin);
796     m_xColorSlider->set_margin_bottom(nMargin);
797 
798     Link<weld::MetricSpinButton&,void> aLink3( LINK( this, ColorPickerDialog, ColorModifyMetricHdl ) );
799     m_xMFCyan->connect_value_changed( aLink3 );
800     m_xMFMagenta->connect_value_changed( aLink3 );
801     m_xMFYellow->connect_value_changed( aLink3 );
802     m_xMFKey->connect_value_changed( aLink3 );
803 
804     m_xMFHue->connect_value_changed( aLink3 );
805     m_xMFSaturation->connect_value_changed( aLink3 );
806     m_xMFBrightness->connect_value_changed( aLink3 );
807 
808     Link<weld::SpinButton&,void> aLink4(LINK(this, ColorPickerDialog, ColorModifySpinHdl));
809     m_xMFRed->connect_value_changed(aLink4);
810     m_xMFGreen->connect_value_changed(aLink4);
811     m_xMFBlue->connect_value_changed(aLink4);
812 
813     m_xEDHex->connect_changed(LINK(this, ColorPickerDialog, ColorModifyEditHdl));
814 
815     Link<weld::ToggleButton&,void> aLink2 = LINK( this, ColorPickerDialog, ModeModifyHdl );
816     m_xRBRed->connect_toggled( aLink2 );
817     m_xRBGreen->connect_toggled( aLink2 );
818     m_xRBBlue->connect_toggled( aLink2 );
819     m_xRBHue->connect_toggled( aLink2 );
820     m_xRBSaturation->connect_toggled( aLink2 );
821     m_xRBBrightness->connect_toggled( aLink2 );
822 
823     Color aColor(nColor);
824 
825     // modify
826     if (nDialogMode == 2)
827     {
828         m_aColorPrevious.SetColor(aColor);
829         m_xColorPrevious->show();
830     }
831 
832     mdRed = static_cast<double>(aColor.GetRed()) / 255.0;
833     mdGreen = static_cast<double>(aColor.GetGreen()) / 255.0;
834     mdBlue = static_cast<double>(aColor.GetBlue()) / 255.0;
835 
836     RGBtoHSV( mdRed, mdGreen, mdBlue, mdHue, mdSat, mdBri );
837     RGBtoCMYK( mdRed, mdGreen, mdBlue, mdCyan, mdMagenta, mdYellow, mdKey );
838 
839     update_color();
840 }
841 
toInt(double dValue,double dRange)842 static int toInt( double dValue, double dRange )
843 {
844     return static_cast< int >( std::floor((dValue * dRange) + 0.5 ) );
845 }
846 
GetColor() const847 Color ColorPickerDialog::GetColor() const
848 {
849     return Color( toInt(mdRed,255.0), toInt(mdGreen,255.0), toInt(mdBlue,255.0) );
850 }
851 
update_color(UpdateFlags n)852 void ColorPickerDialog::update_color( UpdateFlags n )
853 {
854     sal_uInt8 nRed = toInt(mdRed,255.0);
855     sal_uInt8 nGreen = toInt(mdGreen,255.0);
856     sal_uInt8 nBlue = toInt(mdBlue,255.0);
857 
858     Color aColor(nRed, nGreen, nBlue);
859 
860     if (n & UpdateFlags::RGB) // update RGB
861     {
862         m_xMFRed->set_value(nRed);
863         m_xMFGreen->set_value(nGreen);
864         m_xMFBlue->set_value(nBlue);
865     }
866 
867     if (n & UpdateFlags::CMYK) // update CMYK
868     {
869         m_xMFCyan->set_value(toInt(mdCyan, 100.0), FieldUnit::PERCENT);
870         m_xMFMagenta->set_value(toInt(mdMagenta, 100.0), FieldUnit::PERCENT);
871         m_xMFYellow->set_value(toInt(mdYellow, 100.0), FieldUnit::PERCENT);
872         m_xMFKey->set_value(toInt(mdKey, 100.0), FieldUnit::PERCENT);
873     }
874 
875     if (n & UpdateFlags::HSB ) // update HSB
876     {
877         m_xMFHue->set_value(toInt(mdHue, 1.0), FieldUnit::DEGREE);
878         m_xMFSaturation->set_value(toInt( mdSat, 100.0), FieldUnit::PERCENT);
879         m_xMFBrightness->set_value(toInt( mdBri, 100.0), FieldUnit::PERCENT);
880     }
881 
882     if (n & UpdateFlags::ColorChooser ) // update Color Chooser 1
883     {
884         switch( meMode )
885         {
886         case HUE:
887             m_aColorField.SetValues(aColor, meMode, mdSat, mdBri);
888             break;
889         case SATURATION:
890             m_aColorField.SetValues(aColor, meMode, mdHue / 360.0, mdBri);
891             break;
892         case BRIGHTNESS:
893             m_aColorField.SetValues(aColor, meMode, mdHue / 360.0, mdSat);
894             break;
895         case RED:
896             m_aColorField.SetValues(aColor, meMode, mdBlue, mdGreen);
897             break;
898         case GREEN:
899             m_aColorField.SetValues(aColor, meMode, mdBlue, mdRed);
900             break;
901         case BLUE:
902             m_aColorField.SetValues(aColor, meMode, mdRed, mdGreen);
903             break;
904         }
905     }
906 
907     if (n & UpdateFlags::ColorSlider) // update Color Chooser 2
908     {
909         switch (meMode)
910         {
911         case HUE:
912             m_aColorSlider.SetValue(aColor, meMode, mdHue / 360.0);
913             break;
914         case SATURATION:
915             m_aColorSlider.SetValue(aColor, meMode, mdSat);
916             break;
917         case BRIGHTNESS:
918             m_aColorSlider.SetValue(aColor, meMode, mdBri);
919             break;
920         case RED:
921             m_aColorSlider.SetValue(aColor, meMode, mdRed);
922             break;
923         case GREEN:
924             m_aColorSlider.SetValue(aColor, meMode, mdGreen);
925             break;
926         case BLUE:
927             m_aColorSlider.SetValue(aColor, meMode, mdBlue);
928             break;
929         }
930     }
931 
932     if (n & UpdateFlags::Hex) // update hex
933     {
934         m_xFISliderLeft->set_margin_top(m_aColorSlider.GetLevel());
935         m_xFISliderRight->set_margin_top(m_aColorSlider.GetLevel());
936         m_xEDHex->SetColor(aColor);
937     }
938     m_aColorPreview.SetColor(aColor);
939 }
940 
IMPL_LINK_NOARG(ColorPickerDialog,ColorFieldControlModifydl,ColorFieldControl &,void)941 IMPL_LINK_NOARG(ColorPickerDialog, ColorFieldControlModifydl, ColorFieldControl&, void)
942 {
943     double x = m_aColorField.GetX();
944     double y = m_aColorField.GetY();
945 
946     switch( meMode )
947     {
948     case HUE:
949         mdSat = x;
950         setColorComponent( ColorComponent::Brightness, y );
951         break;
952     case SATURATION:
953         mdHue = x * 360.0;
954         setColorComponent( ColorComponent::Brightness, y );
955         break;
956     case BRIGHTNESS:
957         mdHue = x * 360.0;
958         setColorComponent( ColorComponent::Saturation, y );
959         break;
960     case RED:
961         mdBlue = x;
962         setColorComponent( ColorComponent::Green, y );
963         break;
964     case GREEN:
965         mdBlue = x;
966         setColorComponent( ColorComponent::Red, y );
967         break;
968     case BLUE:
969         mdRed = x;
970         setColorComponent( ColorComponent::Green, y );
971         break;
972     }
973 
974     update_color(UpdateFlags::All & ~UpdateFlags::ColorChooser);
975 }
976 
IMPL_LINK_NOARG(ColorPickerDialog,ColorSliderControlModifyHdl,ColorSliderControl &,void)977 IMPL_LINK_NOARG(ColorPickerDialog, ColorSliderControlModifyHdl, ColorSliderControl&, void)
978 {
979     double dValue = m_aColorSlider.GetValue();
980     switch (meMode)
981     {
982     case HUE:
983         setColorComponent( ColorComponent::Hue, dValue * 360.0 );
984         break;
985     case SATURATION:
986         setColorComponent( ColorComponent::Saturation, dValue );
987         break;
988     case BRIGHTNESS:
989         setColorComponent( ColorComponent::Brightness, dValue );
990         break;
991     case RED:
992         setColorComponent( ColorComponent::Red, dValue );
993         break;
994     case GREEN:
995         setColorComponent( ColorComponent::Green, dValue );
996         break;
997     case BLUE:
998         setColorComponent( ColorComponent::Blue, dValue );
999         break;
1000     }
1001 
1002     update_color(UpdateFlags::All & ~UpdateFlags::ColorSlider);
1003 }
1004 
IMPL_LINK(ColorPickerDialog,ColorModifyMetricHdl,weld::MetricSpinButton &,rEdit,void)1005 IMPL_LINK(ColorPickerDialog, ColorModifyMetricHdl, weld::MetricSpinButton&, rEdit, void)
1006 {
1007     UpdateFlags n = UpdateFlags::NONE;
1008 
1009     if (&rEdit == m_xMFHue.get())
1010     {
1011         setColorComponent( ColorComponent::Hue, static_cast<double>(m_xMFHue->get_value(FieldUnit::DEGREE)) );
1012         n = UpdateFlags::All & ~UpdateFlags::HSB;
1013     }
1014     else if (&rEdit == m_xMFSaturation.get())
1015     {
1016         setColorComponent( ColorComponent::Saturation, static_cast<double>(m_xMFSaturation->get_value(FieldUnit::PERCENT)) / 100.0 );
1017         n = UpdateFlags::All & ~UpdateFlags::HSB;
1018     }
1019     else if (&rEdit == m_xMFBrightness.get())
1020     {
1021         setColorComponent( ColorComponent::Brightness, static_cast<double>(m_xMFBrightness->get_value(FieldUnit::PERCENT)) / 100.0 );
1022         n = UpdateFlags::All & ~UpdateFlags::HSB;
1023     }
1024     else if (&rEdit == m_xMFCyan.get())
1025     {
1026         setColorComponent( ColorComponent::Cyan, static_cast<double>(m_xMFCyan->get_value(FieldUnit::PERCENT)) / 100.0 );
1027         n = UpdateFlags::All & ~UpdateFlags::CMYK;
1028     }
1029     else if (&rEdit == m_xMFMagenta.get())
1030     {
1031         setColorComponent( ColorComponent::Magenta, static_cast<double>(m_xMFMagenta->get_value(FieldUnit::PERCENT)) / 100.0 );
1032         n = UpdateFlags::All & ~UpdateFlags::CMYK;
1033     }
1034     else if (&rEdit == m_xMFYellow.get())
1035     {
1036         setColorComponent( ColorComponent::Yellow, static_cast<double>(m_xMFYellow->get_value(FieldUnit::PERCENT)) / 100.0 );
1037         n = UpdateFlags::All & ~UpdateFlags::CMYK;
1038     }
1039     else if (&rEdit == m_xMFKey.get())
1040     {
1041         setColorComponent( ColorComponent::Key, static_cast<double>(m_xMFKey->get_value(FieldUnit::PERCENT)) / 100.0 );
1042         n = UpdateFlags::All & ~UpdateFlags::CMYK;
1043     }
1044 
1045     if (n != UpdateFlags::NONE)
1046         update_color(n);
1047 }
1048 
IMPL_LINK_NOARG(ColorPickerDialog,ColorModifyEditHdl,weld::Entry &,void)1049 IMPL_LINK_NOARG(ColorPickerDialog, ColorModifyEditHdl, weld::Entry&, void)
1050 {
1051     UpdateFlags n = UpdateFlags::NONE;
1052 
1053     Color aColor = m_xEDHex->GetColor();
1054 
1055     if (aColor != Color(0xffffffff) && aColor != GetColor())
1056     {
1057         mdRed = static_cast<double>(aColor.GetRed()) / 255.0;
1058         mdGreen = static_cast<double>(aColor.GetGreen()) / 255.0;
1059         mdBlue = static_cast<double>(aColor.GetBlue()) / 255.0;
1060 
1061         RGBtoHSV( mdRed, mdGreen, mdBlue, mdHue, mdSat, mdBri );
1062         RGBtoCMYK( mdRed, mdGreen, mdBlue, mdCyan, mdMagenta, mdYellow, mdKey );
1063         n = UpdateFlags::All & ~UpdateFlags::Hex;
1064     }
1065 
1066     if (n != UpdateFlags::NONE)
1067         update_color(n);
1068 }
1069 
IMPL_LINK(ColorPickerDialog,ColorModifySpinHdl,weld::SpinButton &,rEdit,void)1070 IMPL_LINK(ColorPickerDialog, ColorModifySpinHdl, weld::SpinButton&, rEdit, void)
1071 {
1072     UpdateFlags n = UpdateFlags::NONE;
1073 
1074     if (&rEdit == m_xMFRed.get())
1075     {
1076         setColorComponent( ColorComponent::Red, static_cast<double>(m_xMFRed->get_value()) / 255.0 );
1077         n = UpdateFlags::All & ~UpdateFlags::RGB;
1078     }
1079     else if (&rEdit == m_xMFGreen.get())
1080     {
1081         setColorComponent( ColorComponent::Green, static_cast<double>(m_xMFGreen->get_value()) / 255.0 );
1082         n = UpdateFlags::All & ~UpdateFlags::RGB;
1083     }
1084     else if (&rEdit == m_xMFBlue.get())
1085     {
1086         setColorComponent( ColorComponent::Blue, static_cast<double>(m_xMFBlue->get_value()) / 255.0 );
1087         n = UpdateFlags::All & ~UpdateFlags::RGB;
1088     }
1089 
1090     if (n != UpdateFlags::NONE)
1091         update_color(n);
1092 }
1093 
1094 
IMPL_LINK_NOARG(ColorPickerDialog,ModeModifyHdl,weld::ToggleButton &,void)1095 IMPL_LINK_NOARG(ColorPickerDialog, ModeModifyHdl, weld::ToggleButton&, void)
1096 {
1097     ColorMode eMode = HUE;
1098 
1099     if (m_xRBRed->get_active())
1100     {
1101         eMode = RED;
1102     }
1103     else if (m_xRBGreen->get_active())
1104     {
1105         eMode = GREEN;
1106     }
1107     else if (m_xRBBlue->get_active())
1108     {
1109         eMode = BLUE;
1110     }
1111     else if (m_xRBSaturation->get_active())
1112     {
1113         eMode = SATURATION;
1114     }
1115     else if (m_xRBBrightness->get_active())
1116     {
1117         eMode = BRIGHTNESS;
1118     }
1119 
1120     if (meMode != eMode)
1121     {
1122         meMode = eMode;
1123         update_color(UpdateFlags::ColorChooser | UpdateFlags::ColorSlider);
1124     }
1125 }
1126 
setColorComponent(ColorComponent nComp,double dValue)1127 void ColorPickerDialog::setColorComponent( ColorComponent nComp, double dValue )
1128 {
1129     switch( nComp )
1130     {
1131     case ColorComponent::Red:
1132         mdRed = dValue;
1133         break;
1134     case ColorComponent::Green:
1135         mdGreen = dValue;
1136         break;
1137     case ColorComponent::Blue:
1138         mdBlue = dValue;
1139         break;
1140     case ColorComponent::Hue:
1141         mdHue = dValue;
1142         break;
1143     case ColorComponent::Saturation:
1144         mdSat = dValue;
1145         break;
1146     case ColorComponent::Brightness:
1147         mdBri = dValue;
1148         break;
1149     case ColorComponent::Cyan:
1150         mdCyan = dValue;
1151         break;
1152     case ColorComponent::Yellow:
1153         mdYellow = dValue;
1154         break;
1155     case ColorComponent::Magenta:
1156         mdMagenta = dValue;
1157         break;
1158     case ColorComponent::Key:
1159         mdKey = dValue;
1160         break;
1161     }
1162 
1163     if (nComp == ColorComponent::Red || nComp == ColorComponent::Green || nComp == ColorComponent::Blue)
1164     {
1165         RGBtoHSV( mdRed, mdGreen, mdBlue, mdHue, mdSat, mdBri );
1166         RGBtoCMYK( mdRed, mdGreen, mdBlue, mdCyan, mdMagenta, mdYellow, mdKey );
1167     }
1168     else if (nComp == ColorComponent::Hue || nComp == ColorComponent::Saturation || nComp == ColorComponent::Brightness)
1169     {
1170         HSVtoRGB( mdHue, mdSat, mdBri, mdRed, mdGreen, mdBlue );
1171         RGBtoCMYK( mdRed, mdGreen, mdBlue, mdCyan, mdMagenta, mdYellow, mdKey );
1172     }
1173     else
1174     {
1175         CMYKtoRGB( mdCyan, mdMagenta, mdYellow, mdKey, mdRed, mdGreen, mdBlue );
1176         RGBtoHSV( mdRed, mdGreen, mdBlue, mdHue, mdSat, mdBri );
1177     }
1178 }
1179 
1180 typedef ::cppu::WeakComponentImplHelper< XServiceInfo, XExecutableDialog, XInitialization, XPropertyAccess > ColorPickerBase;
1181 
1182 class ColorPicker : protected ::cppu::BaseMutex,    // Struct for right initialization of mutex member! Must be first of baseclasses.
1183                     public ColorPickerBase
1184 {
1185 public:
1186     explicit ColorPicker();
1187 
1188     // XInitialization
1189     virtual void SAL_CALL initialize( const Sequence< Any >& aArguments ) override;
1190 
1191     // XInitialization
1192     virtual OUString SAL_CALL getImplementationName(  ) override;
1193     virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
1194     virtual Sequence< OUString > SAL_CALL getSupportedServiceNames(  ) override;
1195 
1196     // XPropertyAccess
1197     virtual Sequence< PropertyValue > SAL_CALL getPropertyValues(  ) override;
1198     virtual void SAL_CALL setPropertyValues( const Sequence< PropertyValue >& aProps ) override;
1199 
1200     // XExecutableDialog
1201     virtual void SAL_CALL setTitle( const OUString& aTitle ) override;
1202     virtual sal_Int16 SAL_CALL execute(  ) override;
1203 
1204 private:
1205     Color mnColor;
1206     sal_Int16 mnMode;
1207     Reference<css::awt::XWindow> mxParent;
1208 };
1209 
ColorPicker_getImplementationName()1210 OUString ColorPicker_getImplementationName()
1211 {
1212     return "com.sun.star.cui.ColorPicker";
1213 }
1214 
ColorPicker_createInstance(Reference<XComponentContext> const &)1215 Reference< XInterface > ColorPicker_createInstance( Reference< XComponentContext > const & )
1216 {
1217     return static_cast<XWeak*>( new ColorPicker );
1218 }
1219 
ColorPicker_getSupportedServiceNames()1220 Sequence< OUString > ColorPicker_getSupportedServiceNames()
1221 {
1222     Sequence< OUString > seq { "com.sun.star.ui.dialogs.ColorPicker" };
1223     return seq;
1224 }
1225 
1226 static const OUStringLiteral gsColorKey( "Color" );
1227 static const OUStringLiteral gsModeKey( "Mode" );
1228 
ColorPicker()1229 ColorPicker::ColorPicker()
1230     : ColorPickerBase( m_aMutex )
1231     , mnColor( 0 )
1232     , mnMode( 0 )
1233 {
1234 }
1235 
1236 // XInitialization
initialize(const Sequence<Any> & aArguments)1237 void SAL_CALL ColorPicker::initialize( const Sequence< Any >& aArguments )
1238 {
1239     if( aArguments.getLength() == 1 )
1240     {
1241         aArguments[0] >>= mxParent;
1242     }
1243 }
1244 
1245 // XInitialization
getImplementationName()1246 OUString SAL_CALL ColorPicker::getImplementationName(  )
1247 {
1248     return ColorPicker_getImplementationName();
1249 }
1250 
supportsService(const OUString & sServiceName)1251 sal_Bool SAL_CALL ColorPicker::supportsService( const OUString& sServiceName )
1252 {
1253     return cppu::supportsService(this, sServiceName);
1254 }
1255 
getSupportedServiceNames()1256 Sequence< OUString > SAL_CALL ColorPicker::getSupportedServiceNames(  )
1257 {
1258     return ColorPicker_getSupportedServiceNames();
1259 }
1260 
1261 // XPropertyAccess
getPropertyValues()1262 Sequence< PropertyValue > SAL_CALL ColorPicker::getPropertyValues(  )
1263 {
1264     Sequence< PropertyValue > props(1);
1265     props[0].Name = gsColorKey;
1266     props[0].Value <<= mnColor;
1267     return props;
1268 }
1269 
setPropertyValues(const Sequence<PropertyValue> & aProps)1270 void SAL_CALL ColorPicker::setPropertyValues( const Sequence< PropertyValue >& aProps )
1271 {
1272     for( sal_Int32 n = 0; n < aProps.getLength(); n++ )
1273     {
1274         if( aProps[n].Name == gsColorKey )
1275         {
1276             aProps[n].Value >>= mnColor;
1277         }
1278         else if( aProps[n].Name == gsModeKey )
1279         {
1280             aProps[n].Value >>= mnMode;
1281         }
1282     }
1283 }
1284 
1285 // XExecutableDialog
setTitle(const OUString &)1286 void SAL_CALL ColorPicker::setTitle( const OUString& )
1287 {
1288 }
1289 
execute()1290 sal_Int16 SAL_CALL ColorPicker::execute()
1291 {
1292     std::unique_ptr<ColorPickerDialog> xDlg(new ColorPickerDialog(Application::GetFrameWeld(mxParent), mnColor, mnMode));
1293     sal_Int16 ret = xDlg->run();
1294     if (ret)
1295         mnColor = xDlg->GetColor();
1296     return ret;
1297 }
1298 
1299 }
1300 
1301 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1302