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 <vcl/event.hxx>
21 #include <vcl/metaact.hxx>
22 #include <vcl/field.hxx>
23 #include <vcl/settings.hxx>
24 #include <vcl/toolbox.hxx>
25 #include <svtools/valueset.hxx>
26 #include <svl/eitem.hxx>
27 #include <sfx2/dispatch.hxx>
28 #include <svtools/colrdlg.hxx>
29
30 #include <svx/colorbox.hxx>
31 #include <svx/dialmgr.hxx>
32 #include <svx/dlgctrl.hxx>
33 #include <svx/bmpmask.hxx>
34 #include <svx/strings.hrc>
35 #include <svx/svxids.hrc>
36 #include <memory>
37 #include <helpids.h>
38
39 #define OWN_CALLMODE SfxCallMode::ASYNCHRON | SfxCallMode::RECORD
40
41
42 #define TEST_COLS() \
43 { \
44 nR = aCol.GetRed(); nG = aCol.GetGreen(); nB = aCol.GetBlue(); \
45 for( i = 0; i < nCount; i++ ) \
46 { \
47 if ( ( pMinR[i] <= nR ) && ( pMaxR[i] >= nR ) && \
48 ( pMinG[i] <= nG ) && ( pMaxG[i] >= nG ) && \
49 ( pMinB[i] <= nB ) && ( pMaxB[i] >= nB ) ) \
50 { \
51 aCol = pDstCols[i]; bReplace = true; break; \
52 } \
53 } \
54 }
55
56 SFX_IMPL_DOCKINGWINDOW_WITHID( SvxBmpMaskChildWindow, SID_BMPMASK )
57
58 class BmpColorWindow : public Control
59 {
60 Color aColor;
61
62
63 public:
BmpColorWindow(vcl::Window * pParent)64 explicit BmpColorWindow(vcl::Window* pParent)
65 : Control(pParent, WB_BORDER)
66 , aColor( COL_WHITE )
67 {
68 }
69
SetColor(const Color & rColor)70 void SetColor( const Color& rColor )
71 {
72 aColor = rColor;
73 Invalidate();
74 }
75
76 virtual void Paint( vcl::RenderContext& /*rRenderContext*/, const tools::Rectangle& rRect ) override;
77
GetOptimalSize() const78 virtual Size GetOptimalSize() const override
79 {
80 return LogicToPixel(Size(43, 14), MapMode(MapUnit::MapAppFont));
81 }
82 };
83
84 class MaskSet : public ValueSet
85 {
86 VclPtr<SvxBmpMask> pSvxBmpMask;
87
88 public:
89 MaskSet(SvxBmpMask* pMask, vcl::Window* pParent);
~MaskSet()90 virtual ~MaskSet() override { disposeOnce(); }
dispose()91 virtual void dispose() override { pSvxBmpMask.clear(); ValueSet::dispose(); }
92 virtual void Select() override;
93 virtual void KeyInput( const KeyEvent& rKEvt ) override;
94 virtual void GetFocus() override;
GetOptimalSize() const95 virtual Size GetOptimalSize() const override
96 {
97 return LogicToPixel(Size(24, 12), MapMode(MapUnit::MapAppFont));
98 }
99
100 void onEditColor();
101 };
102
MaskSet(SvxBmpMask * pMask,vcl::Window * pParent)103 MaskSet::MaskSet(SvxBmpMask* pMask, vcl::Window* pParent)
104 : ValueSet(pParent, WB_TABSTOP)
105 , pSvxBmpMask(pMask)
106 {
107 SetHelpId(HID_BMPMASK_CTL_QCOL_1);
108 }
109
Select()110 void MaskSet::Select()
111 {
112 ValueSet::Select();
113
114 pSvxBmpMask->onSelect( this );
115 }
116
GetFocus()117 void MaskSet::GetFocus()
118 {
119 ValueSet::GetFocus();
120 SelectItem( 1 );
121 pSvxBmpMask->onSelect( this );
122 }
123
KeyInput(const KeyEvent & rKEvt)124 void MaskSet::KeyInput( const KeyEvent& rKEvt )
125 {
126 vcl::KeyCode aCode = rKEvt.GetKeyCode();
127
128 // if the key has a modifier we don't care
129 if( aCode.GetModifier() )
130 {
131 ValueSet::KeyInput( rKEvt );
132 }
133 else
134 {
135 // check for keys that interests us
136 switch ( aCode.GetCode() )
137 {
138 case KEY_SPACE:
139 onEditColor();
140 break;
141 default:
142 ValueSet::KeyInput( rKEvt );
143 }
144
145 }
146 }
147
onEditColor()148 void MaskSet::onEditColor()
149 {
150 SvColorDialog aColorDlg;
151
152 aColorDlg.SetColor(GetItemColor(1));
153
154 if (aColorDlg.Execute(GetFrameWeld()))
155 SetItemColor(1, aColorDlg.GetColor());
156 }
157
158 class MaskData
159 {
160 VclPtr<SvxBmpMask> pMask;
161 bool bIsReady;
162 bool bExecState;
163 SfxBindings& rBindings;
164
165 public:
166 MaskData( SvxBmpMask* pBmpMask, SfxBindings& rBind );
167
IsCbxReady() const168 bool IsCbxReady() const { return bIsReady; }
SetExecState(bool bState)169 void SetExecState( bool bState ) { bExecState = bState; }
IsExecReady() const170 bool IsExecReady() const { return bExecState; }
171
172 DECL_LINK( PipetteHdl, ToolBox*, void );
173 DECL_LINK( CbxHdl, Button*, void);
174 DECL_LINK( CbxTransHdl, Button*, void );
175 DECL_LINK( FocusLbHdl, Control&, void );
176 DECL_LINK(ExecHdl, Button*, void);
177 };
178
179
MaskData(SvxBmpMask * pBmpMask,SfxBindings & rBind)180 MaskData::MaskData( SvxBmpMask* pBmpMask, SfxBindings& rBind ) :
181
182 pMask ( pBmpMask ),
183 bIsReady ( false ),
184 bExecState ( false ),
185 rBindings ( rBind )
186
187 {
188 }
189
IMPL_LINK(MaskData,PipetteHdl,ToolBox *,pTbx,void)190 IMPL_LINK( MaskData, PipetteHdl, ToolBox*, pTbx, void )
191 {
192 SfxBoolItem aBItem( SID_BMPMASK_PIPETTE,
193 pTbx->IsItemChecked( pTbx->GetItemId(0) ) );
194
195 rBindings.GetDispatcher()->ExecuteList(SID_BMPMASK_PIPETTE, OWN_CALLMODE,
196 { &aBItem });
197 }
198
IMPL_LINK(MaskData,CbxHdl,Button *,pButton,void)199 IMPL_LINK( MaskData, CbxHdl, Button*, pButton, void )
200 {
201 CheckBox* pCbx = static_cast<CheckBox*>(pButton);
202 bIsReady = pMask->m_pCbx1->IsChecked() || pMask->m_pCbx2->IsChecked() ||
203 pMask->m_pCbx3->IsChecked() || pMask->m_pCbx4->IsChecked();
204
205 if ( bIsReady && IsExecReady() )
206 pMask->m_pBtnExec->Enable();
207 else
208 pMask->m_pBtnExec->Disable();
209
210 // When a checkbox is checked, the pipette is enabled
211 if ( pCbx->IsChecked() )
212 {
213 MaskSet* pSet = nullptr;
214
215 if (pCbx == pMask->m_pCbx1)
216 pSet = pMask->m_pQSet1;
217 else if (pCbx == pMask->m_pCbx2)
218 pSet = pMask->m_pQSet2;
219 else if (pCbx == pMask->m_pCbx3)
220 pSet = pMask->m_pQSet3;
221 else // if ( pCbx == pMask->m_pCbx4 )
222 pSet = pMask->m_pQSet4;
223
224 pSet->SelectItem( 1 );
225 pSet->Select();
226
227 pMask->m_pTbxPipette->CheckItem( pMask->m_pTbxPipette->GetItemId(0) );
228 PipetteHdl(pMask->m_pTbxPipette);
229 }
230 }
231
232
IMPL_LINK(MaskData,CbxTransHdl,Button *,pButton,void)233 IMPL_LINK( MaskData, CbxTransHdl, Button*, pButton, void )
234 {
235 CheckBox* pCbx = static_cast<CheckBox*>(pButton);
236 bIsReady = pCbx->IsChecked();
237 if ( bIsReady )
238 {
239 pMask->m_pQSet1->Disable();
240 pMask->m_pQSet2->Disable();
241 pMask->m_pQSet3->Disable();
242 pMask->m_pQSet4->Disable();
243 pMask->m_pCtlPipette->Disable();
244 pMask->m_pCbx1->Disable();
245 pMask->m_pSp1->Disable();
246 pMask->m_pCbx2->Disable();
247 pMask->m_pSp2->Disable();
248 pMask->m_pCbx3->Disable();
249 pMask->m_pSp3->Disable();
250 pMask->m_pCbx4->Disable();
251 pMask->m_pSp4->Disable();
252 pMask->m_pTbxPipette->Disable();
253
254 pMask->m_pLbColor1->Disable();
255 pMask->m_pLbColor2->Disable();
256 pMask->m_pLbColor3->Disable();
257 pMask->m_pLbColor4->Disable();
258 pMask->m_pLbColorTrans->Enable();
259 }
260 else
261 {
262 pMask->m_pQSet1->Enable();
263 pMask->m_pQSet2->Enable();
264 pMask->m_pQSet3->Enable();
265 pMask->m_pQSet4->Enable();
266 pMask->m_pCtlPipette->Enable();
267 pMask->m_pCbx1->Enable();
268 pMask->m_pSp1->Enable();
269 pMask->m_pCbx2->Enable();
270 pMask->m_pSp2->Enable();
271 pMask->m_pCbx3->Enable();
272 pMask->m_pSp3->Enable();
273 pMask->m_pCbx4->Enable();
274 pMask->m_pSp4->Enable();
275 pMask->m_pTbxPipette->Enable();
276
277 pMask->m_pLbColor1->Enable();
278 pMask->m_pLbColor2->Enable();
279 pMask->m_pLbColor3->Enable();
280 pMask->m_pLbColor4->Enable();
281 pMask->m_pLbColorTrans->Disable();
282
283 bIsReady = pMask->m_pCbx1->IsChecked() || pMask->m_pCbx2->IsChecked() ||
284 pMask->m_pCbx3->IsChecked() || pMask->m_pCbx4->IsChecked();
285 }
286
287 if ( bIsReady && IsExecReady() )
288 pMask->m_pBtnExec->Enable();
289 else
290 pMask->m_pBtnExec->Disable();
291 }
292
293
IMPL_LINK(MaskData,FocusLbHdl,Control &,rControl,void)294 IMPL_LINK( MaskData, FocusLbHdl, Control&, rControl, void )
295 {
296 SvxColorListBox* pLb = static_cast<SvxColorListBox*>(&rControl);
297 // MT: bFireFox as API parameter is ugly, find better solution????
298 pMask->m_pQSet1->SelectItem( pLb == pMask->m_pLbColor1 ? 1 : 0 /* , false */ );
299 pMask->m_pQSet2->SelectItem( pLb == pMask->m_pLbColor2 ? 1 : 0 /* , false */ );
300 pMask->m_pQSet3->SelectItem( pLb == pMask->m_pLbColor3 ? 1 : 0 /* , false */ );
301 pMask->m_pQSet4->SelectItem( pLb == pMask->m_pLbColor4 ? 1 : 0 /* , false */ );
302 }
303
304
IMPL_LINK_NOARG(MaskData,ExecHdl,Button *,void)305 IMPL_LINK_NOARG(MaskData, ExecHdl, Button*, void)
306 {
307 SfxBoolItem aBItem( SID_BMPMASK_EXEC, true );
308 rBindings.GetDispatcher()->ExecuteList(SID_BMPMASK_EXEC, OWN_CALLMODE,
309 { &aBItem });
310 }
311
Paint(vcl::RenderContext & rRenderContext,const tools::Rectangle &)312 void BmpColorWindow::Paint( vcl::RenderContext& rRenderContext, const tools::Rectangle& /*Rect*/)
313 {
314 rRenderContext.Push(PushFlags::LINECOLOR | PushFlags::FILLCOLOR);
315 rRenderContext.SetLineColor(aColor);
316 rRenderContext.SetFillColor(aColor);
317 rRenderContext.DrawRect(tools::Rectangle(Point(), GetSizePixel()));
318 rRenderContext.Pop();
319 }
320
SvxBmpMaskSelectItem(SvxBmpMask & rMask,SfxBindings & rBindings)321 SvxBmpMaskSelectItem::SvxBmpMaskSelectItem( SvxBmpMask& rMask,
322 SfxBindings& rBindings ) :
323 SfxControllerItem ( SID_BMPMASK_EXEC, rBindings ),
324 rBmpMask ( rMask)
325 {
326 }
327
StateChanged(sal_uInt16 nSID,SfxItemState,const SfxPoolItem * pItem)328 void SvxBmpMaskSelectItem::StateChanged( sal_uInt16 nSID, SfxItemState /*eState*/,
329 const SfxPoolItem* pItem )
330 {
331 if ( ( nSID == SID_BMPMASK_EXEC ) && pItem )
332 {
333 const SfxBoolItem* pStateItem = dynamic_cast<const SfxBoolItem*>( pItem );
334 assert(pStateItem); // SfxBoolItem expected
335 if (pStateItem)
336 rBmpMask.SetExecState( pStateItem->GetValue() );
337 }
338 }
339
SvxBmpMaskChildWindow(vcl::Window * pParent_,sal_uInt16 nId,SfxBindings * pBindings,SfxChildWinInfo * pInfo)340 SvxBmpMaskChildWindow::SvxBmpMaskChildWindow(vcl::Window* pParent_, sal_uInt16 nId,
341 SfxBindings* pBindings,
342 SfxChildWinInfo* pInfo)
343 : SfxChildWindow(pParent_, nId)
344 {
345 VclPtr<SvxBmpMask> pDlg = VclPtr<SvxBmpMask>::Create(pBindings, this, pParent_);
346
347 SetWindow( pDlg );
348
349 pDlg->Initialize( pInfo );
350 }
351
SvxBmpMask(SfxBindings * pBindinx,SfxChildWindow * pCW,vcl::Window * pParent)352 SvxBmpMask::SvxBmpMask(SfxBindings *pBindinx, SfxChildWindow *pCW, vcl::Window* pParent)
353 : SfxDockingWindow(pBindinx, pCW, pParent, "DockingColorReplace",
354 "svx/ui/dockingcolorreplace.ui" )
355 , pData(new MaskData(this, *pBindinx))
356 , aPipetteColor(COL_WHITE)
357 , aSelItem(*this, *pBindinx)
358 {
359 get(m_pTbxPipette, "toolbar");
360 m_pTbxPipette->SetItemBits(m_pTbxPipette->GetItemId(0),
361 ToolBoxItemBits::AUTOCHECK);
362 get(m_pBtnExec, "replace");
363 m_pCtlPipette = VclPtr<BmpColorWindow>::Create(get<Window>("toolgrid"));
364 m_pCtlPipette->Show();
365 m_pCtlPipette->set_grid_left_attach(1);
366 m_pCtlPipette->set_grid_top_attach(0);
367 m_pCtlPipette->set_hexpand(true);
368 get(m_pCbx1, "cbx1");
369 Window *pGrid = get<Window>("colorgrid");
370 m_pQSet1 = VclPtr<MaskSet>::Create(this, pGrid);
371 m_pQSet1->set_grid_left_attach(1);
372 m_pQSet1->set_grid_top_attach(1);
373 m_pQSet1->Show();
374 get(m_pSp1, "tol1");
375 get(m_pLbColor1, "color1");
376 m_pLbColor1->SetSlotId(SID_BMPMASK_COLOR);
377 get(m_pCbx2, "cbx2");
378 m_pQSet2 = VclPtr<MaskSet>::Create(this, pGrid);
379 m_pQSet2->set_grid_left_attach(1);
380 m_pQSet2->set_grid_top_attach(2);
381 m_pQSet2->Show();
382 get(m_pSp2, "tol2");
383 get(m_pLbColor2, "color2");
384 m_pLbColor2->SetSlotId(SID_BMPMASK_COLOR);
385 get(m_pCbx3, "cbx3");
386 m_pQSet3 = VclPtr<MaskSet>::Create(this, pGrid);
387 m_pQSet3->set_grid_left_attach(1);
388 m_pQSet3->set_grid_top_attach(3);
389 m_pQSet3->Show();
390 get(m_pSp3, "tol3");
391 get(m_pLbColor3, "color3");
392 m_pLbColor3->SetSlotId(SID_BMPMASK_COLOR);
393 get(m_pCbx4, "cbx4");
394 m_pQSet4 = VclPtr<MaskSet>::Create(this, pGrid);
395 m_pQSet4->set_grid_left_attach(1);
396 m_pQSet4->set_grid_top_attach(4);
397 m_pQSet4->Show();
398 get(m_pSp4, "tol4");
399 get(m_pLbColor4, "color4");
400 m_pLbColor4->SetSlotId(SID_BMPMASK_COLOR);
401 get(m_pCbxTrans, "cbx5");
402 get(m_pLbColorTrans, "color5");
403
404 m_pLbColorTrans->SelectEntry(COL_BLACK);
405 m_pLbColor1->SelectEntry(COL_TRANSPARENT);
406 m_pLbColor2->SelectEntry(COL_TRANSPARENT);
407 m_pLbColor3->SelectEntry(COL_TRANSPARENT);
408 m_pLbColor4->SelectEntry(COL_TRANSPARENT);
409
410 m_pTbxPipette->SetSelectHdl( LINK( pData.get(), MaskData, PipetteHdl ) );
411 m_pBtnExec->SetClickHdl( LINK( pData.get(), MaskData, ExecHdl ) );
412
413 m_pCbx1->SetClickHdl( LINK( pData.get(), MaskData, CbxHdl ) );
414 m_pCbx2->SetClickHdl( LINK( pData.get(), MaskData, CbxHdl ) );
415 m_pCbx3->SetClickHdl( LINK( pData.get(), MaskData, CbxHdl ) );
416 m_pCbx4->SetClickHdl( LINK( pData.get(), MaskData, CbxHdl ) );
417 m_pCbxTrans->SetClickHdl( LINK( pData.get(), MaskData, CbxTransHdl ) );
418
419 SetAccessibleNames ();
420
421 m_pLbColor1->SetGetFocusHdl( LINK( pData.get(), MaskData, FocusLbHdl ) );
422 m_pLbColor2->SetGetFocusHdl( LINK( pData.get(), MaskData, FocusLbHdl ) );
423 m_pLbColor3->SetGetFocusHdl( LINK( pData.get(), MaskData, FocusLbHdl ) );
424 m_pLbColor4->SetGetFocusHdl( LINK( pData.get(), MaskData, FocusLbHdl ) );
425 m_pLbColorTrans->Disable();
426
427 OUString sColorPalette (SvxResId( RID_SVXDLG_BMPMASK_STR_PALETTE));
428 OUString sColorPaletteN;
429
430 m_pQSet1->SetStyle( m_pQSet1->GetStyle() | WB_DOUBLEBORDER | WB_ITEMBORDER );
431 m_pQSet1->SetColCount();
432 m_pQSet1->SetLineCount( 1 );
433 sColorPaletteN = sColorPalette + " 1";
434 m_pQSet1->InsertItem( 1, aPipetteColor, sColorPaletteN);
435 m_pQSet1->SelectItem( 1 );
436
437 m_pQSet2->SetStyle( m_pQSet2->GetStyle() | WB_DOUBLEBORDER | WB_ITEMBORDER );
438 m_pQSet2->SetColCount();
439 m_pQSet2->SetLineCount( 1 );
440 sColorPaletteN = sColorPalette + " 2";
441 m_pQSet2->InsertItem( 1, aPipetteColor, sColorPaletteN);
442 m_pQSet2->SelectItem( 0 );
443
444 m_pQSet3->SetStyle( m_pQSet3->GetStyle() | WB_DOUBLEBORDER | WB_ITEMBORDER );
445 m_pQSet3->SetColCount();
446 m_pQSet3->SetLineCount( 1 );
447 sColorPaletteN = sColorPalette + " 3";
448 m_pQSet3->InsertItem( 1, aPipetteColor, sColorPaletteN);
449 m_pQSet3->SelectItem( 0 );
450
451 m_pQSet4->SetStyle( m_pQSet4->GetStyle() | WB_DOUBLEBORDER | WB_ITEMBORDER );
452 m_pQSet4->SetColCount();
453 m_pQSet4->SetLineCount( 1 );
454 sColorPaletteN = sColorPalette + " 4";
455 m_pQSet4->InsertItem( 1, aPipetteColor, sColorPaletteN);
456 m_pQSet4->SelectItem( 0 );
457
458 m_pQSet1->Show();
459 m_pQSet2->Show();
460 m_pQSet3->Show();
461 m_pQSet4->Show();
462 }
463
~SvxBmpMask()464 SvxBmpMask::~SvxBmpMask()
465 {
466 disposeOnce();
467 }
468
dispose()469 void SvxBmpMask::dispose()
470 {
471 m_pQSet1.disposeAndClear();
472 m_pQSet2.disposeAndClear();
473 m_pQSet3.disposeAndClear();
474 m_pQSet4.disposeAndClear();
475 m_pCtlPipette.disposeAndClear();
476 pData.reset();
477 m_pTbxPipette.clear();
478 m_pBtnExec.clear();
479 m_pCbx1.clear();
480 m_pSp1.clear();
481 m_pLbColor1.clear();
482 m_pCbx2.clear();
483 m_pSp2.clear();
484 m_pLbColor2.clear();
485 m_pCbx3.clear();
486 m_pSp3.clear();
487 m_pLbColor3.clear();
488 m_pCbx4.clear();
489 m_pSp4.clear();
490 m_pLbColor4.clear();
491 m_pCbxTrans.clear();
492 m_pLbColorTrans.clear();
493 aSelItem.dispose();
494 SfxDockingWindow::dispose();
495 }
496
497 /** is called by a MaskSet when it is selected */
onSelect(MaskSet * pSet)498 void SvxBmpMask::onSelect( MaskSet* pSet )
499 {
500 // now deselect all other value sets
501 if( pSet != m_pQSet1 )
502 m_pQSet1->SelectItem( 0 );
503
504 if( pSet != m_pQSet2 )
505 m_pQSet2->SelectItem( 0 );
506
507 if( pSet != m_pQSet3 )
508 m_pQSet3->SelectItem( 0 );
509
510 if( pSet != m_pQSet4 )
511 m_pQSet4->SelectItem( 0 );
512 }
513
Close()514 bool SvxBmpMask::Close()
515 {
516 SfxBoolItem aItem2( SID_BMPMASK_PIPETTE, false );
517 GetBindings().GetDispatcher()->ExecuteList(SID_BMPMASK_PIPETTE,
518 OWN_CALLMODE, { &aItem2 });
519
520 return SfxDockingWindow::Close();
521 }
522
SetColor(const Color & rColor)523 void SvxBmpMask::SetColor( const Color& rColor )
524 {
525 aPipetteColor = rColor;
526 m_pCtlPipette->SetColor( aPipetteColor );
527 }
528
PipetteClicked()529 void SvxBmpMask::PipetteClicked()
530 {
531 if( m_pQSet1->GetSelectedItemId() == 1 )
532 {
533 m_pCbx1->Check();
534 pData->CbxHdl(m_pCbx1);
535 m_pQSet1->SetItemColor( 1, aPipetteColor );
536 m_pQSet1->SetFormat();
537 }
538 else if( m_pQSet2->GetSelectedItemId() == 1 )
539 {
540 m_pCbx2->Check();
541 pData->CbxHdl(m_pCbx2);
542 m_pQSet2->SetItemColor( 1, aPipetteColor );
543 m_pQSet2->SetFormat();
544 }
545 else if( m_pQSet3->GetSelectedItemId() == 1 )
546 {
547 m_pCbx3->Check();
548 pData->CbxHdl(m_pCbx3);
549 m_pQSet3->SetItemColor( 1, aPipetteColor );
550 m_pQSet3->SetFormat();
551 }
552 else if( m_pQSet4->GetSelectedItemId() == 1 )
553 {
554 m_pCbx4->Check();
555 pData->CbxHdl(m_pCbx4);
556 m_pQSet4->SetItemColor( 1, aPipetteColor );
557 m_pQSet4->SetFormat();
558 }
559
560 m_pTbxPipette->CheckItem( m_pTbxPipette->GetItemId(0), false );
561 pData->PipetteHdl(m_pTbxPipette);
562 }
563
SetExecState(bool bEnable)564 void SvxBmpMask::SetExecState( bool bEnable )
565 {
566 pData->SetExecState( bEnable );
567
568 if ( pData->IsExecReady() && pData->IsCbxReady() )
569 m_pBtnExec->Enable();
570 else
571 m_pBtnExec->Disable();
572 }
573
574
InitColorArrays(Color * pSrcCols,Color * pDstCols,sal_uInt8 * pTols)575 sal_uInt16 SvxBmpMask::InitColorArrays( Color* pSrcCols, Color* pDstCols, sal_uInt8* pTols )
576 {
577 sal_uInt16 nCount = 0;
578
579 if ( m_pCbx1->IsChecked() )
580 {
581 pSrcCols[nCount] = m_pQSet1->GetItemColor( 1 );
582 pDstCols[nCount] = m_pLbColor1->GetSelectEntryColor();
583 pTols[nCount++] = static_cast<sal_uIntPtr>(m_pSp1->GetValue());
584 }
585
586 if ( m_pCbx2->IsChecked() )
587 {
588 pSrcCols[nCount] = m_pQSet2->GetItemColor( 1 );
589 pDstCols[nCount] = m_pLbColor2->GetSelectEntryColor();
590 pTols[nCount++] = static_cast<sal_uIntPtr>(m_pSp2->GetValue());
591 }
592
593 if ( m_pCbx3->IsChecked() )
594 {
595 pSrcCols[nCount] = m_pQSet3->GetItemColor( 1 );
596 pDstCols[nCount] = m_pLbColor3->GetSelectEntryColor();
597 pTols[nCount++] = static_cast<sal_uIntPtr>(m_pSp3->GetValue());
598 }
599
600 if ( m_pCbx4->IsChecked() )
601 {
602 pSrcCols[nCount] = m_pQSet4->GetItemColor( 1 );
603 pDstCols[nCount] = m_pLbColor4->GetSelectEntryColor();
604 pTols[nCount++] = static_cast<sal_uIntPtr>(m_pSp4->GetValue());
605 }
606
607 return nCount;
608 }
609
ImpMask(BitmapEx & rBitmap)610 void SvxBmpMask::ImpMask( BitmapEx& rBitmap )
611 {
612 Color pSrcCols[4];
613 Color pDstCols[4];
614 sal_uInt8 pTols[4];
615 const sal_uInt16 nCount = InitColorArrays( pSrcCols, pDstCols, pTols );
616
617 EnterWait();
618 rBitmap.Replace( pSrcCols, pDstCols, nCount, pTols );
619 LeaveWait();
620 }
621
ImpMaskTransparent(const BitmapEx & rBitmapEx,const Color & rColor,const sal_uInt8 nTol)622 BitmapEx SvxBmpMask::ImpMaskTransparent( const BitmapEx& rBitmapEx, const Color& rColor, const sal_uInt8 nTol )
623 {
624 EnterWait();
625
626 BitmapEx aBmpEx;
627 Bitmap aMask( rBitmapEx.GetBitmap().CreateMask( rColor, nTol ) );
628
629 if( rBitmapEx.IsTransparent() )
630 aMask.CombineSimple( rBitmapEx.GetMask(), BmpCombine::Or );
631
632 aBmpEx = BitmapEx( rBitmapEx.GetBitmap(), aMask );
633 LeaveWait();
634
635 return aBmpEx;
636 }
637
638
ImpMask(const Animation & rAnimation)639 Animation SvxBmpMask::ImpMask( const Animation& rAnimation )
640 {
641 Animation aAnimation( rAnimation );
642 Color pSrcCols[4];
643 Color pDstCols[4];
644 sal_uInt8 pTols[4];
645 InitColorArrays( pSrcCols, pDstCols, pTols );
646 sal_uInt16 nAnimationCount = aAnimation.Count();
647
648 for( sal_uInt16 i = 0; i < nAnimationCount; i++ )
649 {
650 AnimationBitmap aAnimationBitmap( aAnimation.Get( i ) );
651 aAnimationBitmap.maBitmapEx = Mask(aAnimationBitmap.maBitmapEx).GetBitmapEx();
652 aAnimation.Replace(aAnimationBitmap, i);
653 }
654
655 return aAnimation;
656 }
657
658
ImpMask(const GDIMetaFile & rMtf)659 GDIMetaFile SvxBmpMask::ImpMask( const GDIMetaFile& rMtf )
660 {
661 GDIMetaFile aMtf;
662 Color pSrcCols[4];
663 Color pDstCols[4];
664 sal_uInt8 pTols[4];
665 sal_uInt16 nCount = InitColorArrays( pSrcCols, pDstCols, pTols );
666
667 // If no color is selected, we copy only the Mtf
668 if( !nCount )
669 aMtf = rMtf;
670 else
671 {
672 bool pTrans[4];
673 Color aCol;
674 long nR;
675 long nG;
676 long nB;
677 std::unique_ptr<long[]> pMinR(new long[nCount]);
678 std::unique_ptr<long[]> pMaxR(new long[nCount]);
679 std::unique_ptr<long[]> pMinG(new long[nCount]);
680 std::unique_ptr<long[]> pMaxG(new long[nCount]);
681 std::unique_ptr<long[]> pMinB(new long[nCount]);
682 std::unique_ptr<long[]> pMaxB(new long[nCount]);
683 sal_uInt16 i;
684
685 aMtf.SetPrefSize( rMtf.GetPrefSize() );
686 aMtf.SetPrefMapMode( rMtf.GetPrefMapMode() );
687
688 // Prepare Color comparison array
689 for( i = 0; i < nCount; i++ )
690 {
691 long nTol = ( pTols[i] * 255L ) / 100L;
692
693 long nVal = static_cast<long>(pSrcCols[i].GetRed());
694 pMinR[i] = std::max( nVal - nTol, 0L );
695 pMaxR[i] = std::min( nVal + nTol, 255L );
696
697 nVal = static_cast<long>(pSrcCols[i].GetGreen());
698 pMinG[i] = std::max( nVal - nTol, 0L );
699 pMaxG[i] = std::min( nVal + nTol, 255L );
700
701 nVal = static_cast<long>(pSrcCols[i].GetBlue());
702 pMinB[i] = std::max( nVal - nTol, 0L );
703 pMaxB[i] = std::min( nVal + nTol, 255L );
704
705 pTrans[ i ] = (pDstCols[ i ] == COL_TRANSPARENT);
706 }
707
708 // Investigate actions and if necessary replace colors
709 for( size_t nAct = 0, nActCount = rMtf.GetActionSize(); nAct < nActCount; nAct++ )
710 {
711 MetaAction* pAction = rMtf.GetAction( nAct );
712
713 bool bReplace = false;
714
715 switch( pAction->GetType() )
716 {
717 case MetaActionType::PIXEL:
718 {
719 MetaPixelAction* pAct = static_cast<MetaPixelAction*>(pAction);
720
721 aCol = pAct->GetColor();
722 TEST_COLS();
723
724 if( bReplace )
725 pAct = new MetaPixelAction( pAct->GetPoint(), aCol );
726
727 aMtf.AddAction( pAct );
728 }
729 break;
730
731 case MetaActionType::LINECOLOR:
732 {
733 MetaLineColorAction* pAct = static_cast<MetaLineColorAction*>(pAction);
734
735 aCol = pAct->GetColor();
736 TEST_COLS();
737
738 if( bReplace )
739 pAct = new MetaLineColorAction( aCol, !pTrans[ i ] );
740
741 aMtf.AddAction( pAct );
742 }
743 break;
744
745 case MetaActionType::FILLCOLOR:
746 {
747 MetaFillColorAction* pAct = static_cast<MetaFillColorAction*>(pAction);
748
749 aCol = pAct->GetColor();
750 TEST_COLS();
751
752 if( bReplace )
753 pAct = new MetaFillColorAction( aCol, !pTrans[ i ] );
754
755 aMtf.AddAction( pAct );
756 }
757 break;
758
759 case MetaActionType::TEXTCOLOR:
760 {
761 MetaTextColorAction* pAct = static_cast<MetaTextColorAction*>(pAction);
762
763 aCol = pAct->GetColor();
764 TEST_COLS();
765
766 if( bReplace )
767 pAct = new MetaTextColorAction( aCol );
768
769 aMtf.AddAction( pAct );
770 }
771 break;
772
773 case MetaActionType::TEXTFILLCOLOR:
774 {
775 MetaTextFillColorAction* pAct = static_cast<MetaTextFillColorAction*>(pAction);
776
777 aCol = pAct->GetColor();
778 TEST_COLS();
779
780 if( bReplace )
781 pAct = new MetaTextFillColorAction( aCol, !pTrans[ i ] );
782
783 aMtf.AddAction( pAct );
784 }
785 break;
786
787 case MetaActionType::FONT:
788 {
789 MetaFontAction* pAct = static_cast<MetaFontAction*>(pAction);
790 vcl::Font aFont( pAct->GetFont() );
791
792 aCol = aFont.GetColor();
793 TEST_COLS();
794
795 if( bReplace )
796 {
797 aFont.SetColor( aCol );
798 pAct = new MetaFontAction( aFont );
799 }
800
801 aMtf.AddAction( pAct );
802 }
803 break;
804
805 case MetaActionType::WALLPAPER:
806 {
807 MetaWallpaperAction* pAct = static_cast<MetaWallpaperAction*>(pAction);
808 Wallpaper aWall( pAct->GetWallpaper() );
809
810 aCol = aWall.GetColor();
811 TEST_COLS();
812
813 if( bReplace )
814 {
815 aWall.SetColor( aCol );
816 pAct = new MetaWallpaperAction( pAct->GetRect(), aWall );
817 }
818
819 aMtf.AddAction( pAct );
820 }
821 break;
822
823 case MetaActionType::BMP:
824 {
825 MetaBmpAction* pAct = static_cast<MetaBmpAction*>(pAction);
826 const Bitmap aBmp( Mask( pAct->GetBitmap() ).GetBitmapEx().GetBitmap() );
827
828 pAct = new MetaBmpAction( pAct->GetPoint(), aBmp );
829 aMtf.AddAction( pAct );
830 }
831 break;
832
833 case MetaActionType::BMPSCALE:
834 {
835 MetaBmpScaleAction* pAct = static_cast<MetaBmpScaleAction*>(pAction);
836 const Bitmap aBmp( Mask( pAct->GetBitmap() ).GetBitmapEx().GetBitmap() );
837
838 pAct = new MetaBmpScaleAction( pAct->GetPoint(), pAct->GetSize(), aBmp );
839 aMtf.AddAction( pAct );
840 }
841 break;
842
843 case MetaActionType::BMPSCALEPART:
844 {
845 MetaBmpScalePartAction* pAct = static_cast<MetaBmpScalePartAction*>(pAction);
846 const Bitmap aBmp( Mask( pAct->GetBitmap() ).GetBitmapEx().GetBitmap() );
847
848 pAct = new MetaBmpScalePartAction( pAct->GetDestPoint(), pAct->GetDestSize(),
849 pAct->GetSrcPoint(), pAct->GetSrcSize(), aBmp );
850 aMtf.AddAction( pAct );
851 }
852 break;
853
854 case MetaActionType::BMPEX:
855 {
856 MetaBmpExAction* pAct = static_cast<MetaBmpExAction*>(pAction);
857 const BitmapEx aBmpEx( Mask( pAct->GetBitmapEx() ).GetBitmapEx() );
858
859 pAct = new MetaBmpExAction( pAct->GetPoint(), aBmpEx );
860 aMtf.AddAction( pAct );
861 }
862 break;
863
864 case MetaActionType::BMPEXSCALE:
865 {
866 MetaBmpExScaleAction* pAct = static_cast<MetaBmpExScaleAction*>(pAction);
867 const BitmapEx aBmpEx( Mask( pAct->GetBitmapEx() ).GetBitmapEx() );
868
869 pAct = new MetaBmpExScaleAction( pAct->GetPoint(), pAct->GetSize(), aBmpEx );
870 aMtf.AddAction( pAct );
871 }
872 break;
873
874 case MetaActionType::BMPEXSCALEPART:
875 {
876 MetaBmpExScalePartAction* pAct = static_cast<MetaBmpExScalePartAction*>(pAction);
877 const BitmapEx aBmpEx( Mask( pAct->GetBitmapEx() ).GetBitmapEx() );
878
879 pAct = new MetaBmpExScalePartAction( pAct->GetDestPoint(), pAct->GetDestSize(),
880 pAct->GetSrcPoint(), pAct->GetSrcSize(), aBmpEx );
881 aMtf.AddAction( pAct );
882 }
883 break;
884
885 default:
886 {
887 aMtf.AddAction( pAction );
888 }
889 break;
890 }
891 }
892 }
893
894 LeaveWait();
895
896 return aMtf;
897 }
898
899
ImpReplaceTransparency(const Animation & rAnim,const Color & rColor)900 Animation SvxBmpMask::ImpReplaceTransparency( const Animation& rAnim, const Color& rColor )
901 {
902 Animation aAnimation( rAnim );
903 sal_uInt16 nAnimationCount = aAnimation.Count();
904
905 for( sal_uInt16 i = 0; i < nAnimationCount; i++ )
906 {
907 AnimationBitmap aAnimationBitmap(aAnimation.Get(i));
908 aAnimationBitmap.maBitmapEx.ReplaceTransparency(rColor);
909 aAnimation.Replace(aAnimationBitmap, i);
910 }
911
912 return aAnimation;
913 }
914
915
ImpReplaceTransparency(const GDIMetaFile & rMtf,const Color & rColor)916 GDIMetaFile SvxBmpMask::ImpReplaceTransparency( const GDIMetaFile& rMtf, const Color& rColor )
917 {
918 ScopedVclPtrInstance< VirtualDevice > pVDev;
919 GDIMetaFile aMtf;
920 const MapMode& rPrefMap = rMtf.GetPrefMapMode();
921 const Size& rPrefSize = rMtf.GetPrefSize();
922 const size_t nActionCount = rMtf.GetActionSize();
923
924 pVDev->EnableOutput( false );
925 aMtf.Record( pVDev );
926 aMtf.SetPrefSize( rPrefSize );
927 aMtf.SetPrefMapMode( rPrefMap );
928 pVDev->SetLineColor( rColor );
929 pVDev->SetFillColor( rColor );
930
931 // retrieve one action at the time; first
932 // set the whole area to the replacement color.
933 pVDev->DrawRect( tools::Rectangle( rPrefMap.GetOrigin(), rPrefSize ) );
934 for ( size_t i = 0; i < nActionCount; i++ )
935 {
936 MetaAction* pAct = rMtf.GetAction( i );
937 aMtf.AddAction( pAct );
938 }
939
940 aMtf.Stop();
941 aMtf.WindStart();
942
943 return aMtf;
944 }
945
GetMetaFile(const Graphic & rGraphic)946 GDIMetaFile SvxBmpMask::GetMetaFile(const Graphic& rGraphic)
947 {
948 // Replace transparency?
949 if (m_pCbxTrans->IsChecked())
950 return ImpReplaceTransparency(rGraphic.GetGDIMetaFile(), m_pLbColorTrans->GetSelectEntryColor());
951 return ImpMask(rGraphic.GetGDIMetaFile());
952 }
953
Mask(const Graphic & rGraphic)954 Graphic SvxBmpMask::Mask( const Graphic& rGraphic )
955 {
956 Graphic aGraphic( rGraphic );
957 const Color aReplColor( m_pLbColorTrans->GetSelectEntryColor() );
958
959 switch( rGraphic.GetType() )
960 {
961 case GraphicType::Bitmap:
962 {
963 if( rGraphic.IsAnimated() )
964 {
965 // Replace transparency?
966 if ( m_pCbxTrans->IsChecked() )
967 aGraphic = ImpReplaceTransparency( rGraphic.GetAnimation(), aReplColor );
968 else
969 aGraphic = ImpMask( rGraphic.GetAnimation() );
970 }
971 else
972 {
973 // Replace transparency?
974 if( m_pCbxTrans->IsChecked() )
975 {
976 BitmapEx aBmpEx = aGraphic.GetBitmapEx();
977 aBmpEx.ReplaceTransparency(aReplColor);
978 aGraphic = aBmpEx;
979 }
980 else
981 {
982 Color pSrcCols[4];
983 Color pDstCols[4];
984 sal_uInt8 pTols[4];
985 sal_uInt16 nCount = InitColorArrays( pSrcCols, pDstCols, pTols );
986
987 if( nCount )
988 {
989 // first set all transparent colors
990 for( sal_uInt16 i = 0; i < nCount; i++ )
991 {
992 // Do we have a transparent color?
993 if (pDstCols[i] == COL_TRANSPARENT)
994 {
995 BitmapEx aBmpEx( ImpMaskTransparent( aGraphic.GetBitmapEx(),
996 pSrcCols[ i ], pTols[ i ] ) );
997 const Size aSize( aBmpEx.GetSizePixel() );
998
999 if( aSize.Width() && aSize.Height() )
1000 aGraphic = aBmpEx;
1001 }
1002 }
1003
1004 // now replace it again with the normal colors
1005 BitmapEx aBitmapEx( aGraphic.GetBitmapEx() );
1006 if ( aBitmapEx.GetSizePixel().Width() && aBitmapEx.GetSizePixel().Height() )
1007 {
1008 ImpMask( aBitmapEx );
1009 if ( aGraphic.IsTransparent() )
1010 aGraphic = Graphic( BitmapEx( aBitmapEx.GetBitmap(), aBitmapEx.GetMask() ) );
1011 else
1012 aGraphic = aBitmapEx;
1013 }
1014 }
1015 }
1016 }
1017 }
1018 break;
1019
1020 case GraphicType::GdiMetafile:
1021 {
1022 GDIMetaFile aMtf(GetMetaFile(rGraphic));
1023 Size aSize( aMtf.GetPrefSize() );
1024 if ( aSize.Width() && aSize.Height() )
1025 aGraphic = Graphic( aMtf );
1026 else
1027 aGraphic = rGraphic;
1028 }
1029 break;
1030
1031 default:
1032 aGraphic = rGraphic;
1033 break;
1034 }
1035
1036 if( aGraphic != rGraphic )
1037 {
1038 aGraphic.SetPrefSize( rGraphic.GetPrefSize() );
1039 aGraphic.SetPrefMapMode( rGraphic.GetPrefMapMode() );
1040 }
1041
1042 return aGraphic;
1043 }
1044
IsEyedropping() const1045 bool SvxBmpMask::IsEyedropping() const
1046 {
1047 return m_pTbxPipette->IsItemChecked( m_pTbxPipette->GetItemId(0) );
1048 }
1049
1050 /** Set an accessible name for the source color check boxes. Without this
1051 the lengthy description is read.
1052 */
SetAccessibleNames()1053 void SvxBmpMask::SetAccessibleNames()
1054 {
1055 // set the accessible name for valueset
1056 OUString sColorPalette (SvxResId( RID_SVXDLG_BMPMASK_STR_PALETTE));
1057 OUString sColorPaletteN;
1058
1059 sColorPaletteN = sColorPalette + " 1";
1060 m_pQSet1->SetText (sColorPaletteN);
1061 sColorPaletteN = sColorPalette + " 2";
1062 m_pQSet2->SetText (sColorPaletteN);
1063 sColorPaletteN = sColorPalette + " 3";
1064 m_pQSet3->SetText (sColorPaletteN);
1065 sColorPaletteN = sColorPalette + " 4";
1066 m_pQSet4->SetText (sColorPaletteN);
1067 }
1068
1069 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1070