Best effort to create directories of SAL_LOG_FILE
[LibreOffice.git] / svx / source / dialog / _bmpmask.cxx
blob1385aea0c974e49dc178c4d2416505453a0473ef
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <vcl/event.hxx>
21 #include <vcl/metaact.hxx>
22 #include <vcl/virdev.hxx>
23 #include <svtools/valueset.hxx>
24 #include <svl/eitem.hxx>
25 #include <svl/itemset.hxx>
26 #include <sfx2/dispatch.hxx>
27 #include <svtools/colrdlg.hxx>
29 #include <svx/colorbox.hxx>
30 #include <svx/dialmgr.hxx>
31 #include <svx/bmpmask.hxx>
32 #include <svx/strings.hrc>
33 #include <svx/svxids.hrc>
34 #include <memory>
35 #include <helpids.h>
37 #define OWN_CALLMODE SfxCallMode::ASYNCHRON | SfxCallMode::RECORD
40 #define TEST_COLS() \
41 { \
42 nR = aCol.GetRed(); nG = aCol.GetGreen(); nB = aCol.GetBlue(); \
43 for( i = 0; i < nCount; i++ ) \
44 { \
45 if ( ( pMinR[i] <= nR ) && ( pMaxR[i] >= nR ) && \
46 ( pMinG[i] <= nG ) && ( pMaxG[i] >= nG ) && \
47 ( pMinB[i] <= nB ) && ( pMaxB[i] >= nB ) ) \
48 { \
49 aCol = pDstCols[i]; bReplace = true; break; \
50 } \
51 } \
54 SFX_IMPL_DOCKINGWINDOW_WITHID( SvxBmpMaskChildWindow, SID_BMPMASK )
56 class BmpColorWindow : public weld::CustomWidgetController
58 Color aColor;
61 public:
62 explicit BmpColorWindow()
63 : aColor( COL_WHITE )
67 void SetColor( const Color& rColor )
69 aColor = rColor;
70 Invalidate();
73 virtual void Paint( vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect ) override;
75 virtual void SetDrawingArea(weld::DrawingArea* pArea) override
77 Size aSize(pArea->get_ref_device().LogicToPixel(Size(43, 14), MapMode(MapUnit::MapAppFont)));
78 CustomWidgetController::SetDrawingArea(pArea);
79 pArea->set_size_request(aSize.Width(), aSize.Height());
80 SetOutputSizePixel(aSize);
84 class MaskSet : public ValueSet
86 VclPtr<SvxBmpMask> pSvxBmpMask;
88 public:
89 MaskSet(SvxBmpMask* pMask);
90 virtual void Select() override;
91 virtual bool KeyInput( const KeyEvent& rKEvt ) override;
92 virtual void GetFocus() override;
93 virtual void SetDrawingArea(weld::DrawingArea* pArea) override
95 Size aSize(pArea->get_ref_device().LogicToPixel(Size(24, 12), MapMode(MapUnit::MapAppFont)));
96 ValueSet::SetDrawingArea(pArea);
97 pArea->set_size_request(aSize.Width(), aSize.Height());
98 SetOutputSizePixel(aSize);
99 SetHelpId(HID_BMPMASK_CTL_QCOL_1);
101 void onEditColor();
104 MaskSet::MaskSet(SvxBmpMask* pMask)
105 : ValueSet(nullptr)
106 , pSvxBmpMask(pMask)
110 void MaskSet::Select()
112 ValueSet::Select();
114 pSvxBmpMask->onSelect( this );
117 void MaskSet::GetFocus()
119 ValueSet::GetFocus();
120 SelectItem( 1 );
121 pSvxBmpMask->onSelect( this );
124 bool MaskSet::KeyInput( const KeyEvent& rKEvt )
126 bool bRet = false;
128 vcl::KeyCode aCode = rKEvt.GetKeyCode();
130 // if the key has a modifier we don't care
131 if( aCode.GetModifier() )
133 bRet = ValueSet::KeyInput( rKEvt );
135 else
137 // check for keys that interests us
138 switch ( aCode.GetCode() )
140 case KEY_SPACE:
141 onEditColor();
142 bRet = true;
143 break;
144 default:
145 bRet = ValueSet::KeyInput( rKEvt );
148 return bRet;
151 void MaskSet::onEditColor()
153 SvColorDialog aColorDlg;
155 aColorDlg.SetColor(GetItemColor(1));
157 if (aColorDlg.Execute(pSvxBmpMask->GetFrameWeld()))
158 SetItemColor(1, aColorDlg.GetColor());
161 class MaskData
163 VclPtr<SvxBmpMask> pMask;
164 bool bIsReady;
165 bool bExecState;
166 SfxBindings& rBindings;
168 public:
169 MaskData( SvxBmpMask* pBmpMask, SfxBindings& rBind );
171 bool IsCbxReady() const { return bIsReady; }
172 void SetExecState( bool bState ) { bExecState = bState; }
173 bool IsExecReady() const { return bExecState; }
175 DECL_LINK( PipetteHdl, const OUString&, void );
176 DECL_LINK( CbxHdl, weld::Toggleable&, void);
177 DECL_LINK( CbxTransHdl, weld::Toggleable&, void );
178 DECL_LINK( FocusLbHdl, weld::Widget&, void );
179 DECL_LINK(ExecHdl, weld::Button&, void);
183 MaskData::MaskData( SvxBmpMask* pBmpMask, SfxBindings& rBind ) :
185 pMask ( pBmpMask ),
186 bIsReady ( false ),
187 bExecState ( false ),
188 rBindings ( rBind )
193 IMPL_LINK( MaskData, PipetteHdl, const OUString&, rId, void )
195 SfxBoolItem aBItem( SID_BMPMASK_PIPETTE,
196 pMask->m_xTbxPipette->get_item_active(rId) );
198 rBindings.GetDispatcher()->ExecuteList(SID_BMPMASK_PIPETTE, OWN_CALLMODE,
199 { &aBItem });
202 IMPL_LINK( MaskData, CbxHdl, weld::Toggleable&, rCbx, void )
204 bIsReady = pMask->m_xCbx1->get_active() || pMask->m_xCbx2->get_active() ||
205 pMask->m_xCbx3->get_active() || pMask->m_xCbx4->get_active();
207 if ( bIsReady && IsExecReady() )
208 pMask->m_xBtnExec->set_sensitive(true);
209 else
210 pMask->m_xBtnExec->set_sensitive(false);
212 // When a checkbox is checked, the pipette is enabled
213 if ( !rCbx.get_active() )
214 return;
216 MaskSet* pSet = nullptr;
218 if (&rCbx == pMask->m_xCbx1.get())
219 pSet = pMask->m_xQSet1.get();
220 else if (&rCbx == pMask->m_xCbx2.get())
221 pSet = pMask->m_xQSet2.get();
222 else if (&rCbx == pMask->m_xCbx3.get())
223 pSet = pMask->m_xQSet3.get();
224 else // if ( &rCbx == pMask->m_xCbx4 )
225 pSet = pMask->m_xQSet4.get();
227 pSet->SelectItem( 1 );
228 pSet->Select();
230 pMask->m_xTbxPipette->set_item_active("pipette", true);
231 PipetteHdl("pipette");
234 IMPL_LINK( MaskData, CbxTransHdl, weld::Toggleable&, rCbx, void )
236 bIsReady = rCbx.get_active();
237 if ( bIsReady )
239 pMask->m_xQSet1->Disable();
240 pMask->m_xQSet2->Disable();
241 pMask->m_xQSet3->Disable();
242 pMask->m_xQSet4->Disable();
243 pMask->m_xCtlPipette->Disable();
244 pMask->m_xCbx1->set_sensitive(false);
245 pMask->m_xSp1->set_sensitive(false);
246 pMask->m_xCbx2->set_sensitive(false);
247 pMask->m_xSp2->set_sensitive(false);
248 pMask->m_xCbx3->set_sensitive(false);
249 pMask->m_xSp3->set_sensitive(false);
250 pMask->m_xCbx4->set_sensitive(false);
251 pMask->m_xSp4->set_sensitive(false);
252 pMask->m_xTbxPipette->set_sensitive(false);
254 pMask->m_xLbColor1->set_sensitive(false);
255 pMask->m_xLbColor2->set_sensitive(false);
256 pMask->m_xLbColor3->set_sensitive(false);
257 pMask->m_xLbColor4->set_sensitive(false);
258 pMask->m_xLbColorTrans->set_sensitive(true);
260 else
262 pMask->m_xQSet1->Enable();
263 pMask->m_xQSet2->Enable();
264 pMask->m_xQSet3->Enable();
265 pMask->m_xQSet4->Enable();
266 pMask->m_xCtlPipette->Enable();
267 pMask->m_xCbx1->set_sensitive(true);
268 pMask->m_xSp1->set_sensitive(true);
269 pMask->m_xCbx2->set_sensitive(true);
270 pMask->m_xSp2->set_sensitive(true);
271 pMask->m_xCbx3->set_sensitive(true);
272 pMask->m_xSp3->set_sensitive(true);
273 pMask->m_xCbx4->set_sensitive(true);
274 pMask->m_xSp4->set_sensitive(true);
275 pMask->m_xTbxPipette->set_sensitive(true);
277 pMask->m_xLbColor1->set_sensitive(true);
278 pMask->m_xLbColor2->set_sensitive(true);
279 pMask->m_xLbColor3->set_sensitive(true);
280 pMask->m_xLbColor4->set_sensitive(true);
281 pMask->m_xLbColorTrans->set_sensitive(false);
283 bIsReady = pMask->m_xCbx1->get_active() || pMask->m_xCbx2->get_active() ||
284 pMask->m_xCbx3->get_active() || pMask->m_xCbx4->get_active();
287 if ( bIsReady && IsExecReady() )
288 pMask->m_xBtnExec->set_sensitive(true);
289 else
290 pMask->m_xBtnExec->set_sensitive(false);
293 IMPL_LINK( MaskData, FocusLbHdl, weld::Widget&, rLb, void )
295 pMask->m_xQSet1->SelectItem( &rLb == &pMask->m_xLbColor1->get_widget() ? 1 : 0 /* , false */ );
296 pMask->m_xQSet2->SelectItem( &rLb == &pMask->m_xLbColor2->get_widget() ? 1 : 0 /* , false */ );
297 pMask->m_xQSet3->SelectItem( &rLb == &pMask->m_xLbColor3->get_widget() ? 1 : 0 /* , false */ );
298 pMask->m_xQSet4->SelectItem( &rLb == &pMask->m_xLbColor4->get_widget() ? 1 : 0 /* , false */ );
301 IMPL_LINK_NOARG(MaskData, ExecHdl, weld::Button&, void)
303 SfxBoolItem aBItem( SID_BMPMASK_EXEC, true );
304 rBindings.GetDispatcher()->ExecuteList(SID_BMPMASK_EXEC, OWN_CALLMODE,
305 { &aBItem });
308 void BmpColorWindow::Paint( vcl::RenderContext& rRenderContext, const tools::Rectangle& /*Rect*/)
310 rRenderContext.Push(vcl::PushFlags::LINECOLOR | vcl::PushFlags::FILLCOLOR);
311 rRenderContext.SetLineColor(aColor);
312 rRenderContext.SetFillColor(aColor);
313 rRenderContext.DrawRect(tools::Rectangle(Point(), GetOutputSizePixel()));
314 rRenderContext.Pop();
317 SvxBmpMaskSelectItem::SvxBmpMaskSelectItem( SvxBmpMask& rMask,
318 SfxBindings& rBindings ) :
319 SfxControllerItem ( SID_BMPMASK_EXEC, rBindings ),
320 rBmpMask ( rMask)
324 void SvxBmpMaskSelectItem::StateChangedAtToolBoxControl( sal_uInt16 nSID, SfxItemState /*eState*/,
325 const SfxPoolItem* pItem )
327 if ( ( nSID == SID_BMPMASK_EXEC ) && pItem )
329 const SfxBoolItem* pStateItem = dynamic_cast<const SfxBoolItem*>( pItem );
330 assert(pStateItem); // SfxBoolItem expected
331 if (pStateItem)
332 rBmpMask.SetExecState( pStateItem->GetValue() );
336 SvxBmpMaskChildWindow::SvxBmpMaskChildWindow(vcl::Window* pParent_, sal_uInt16 nId,
337 SfxBindings* pBindings,
338 SfxChildWinInfo* pInfo)
339 : SfxChildWindow(pParent_, nId)
341 VclPtr<SvxBmpMask> pDlg = VclPtr<SvxBmpMask>::Create(pBindings, this, pParent_);
343 SetWindow( pDlg );
345 pDlg->Initialize( pInfo );
348 SvxBmpMask::SvxBmpMask(SfxBindings *pBindinx, SfxChildWindow *pCW, vcl::Window* pParent)
349 : SfxDockingWindow(pBindinx, pCW, pParent, "DockingColorReplace",
350 "svx/ui/dockingcolorreplace.ui")
351 , m_xTbxPipette(m_xBuilder->weld_toolbar("toolbar"))
352 , m_xCtlPipette(new BmpColorWindow)
353 , m_xCtlPipetteWin(new weld::CustomWeld(*m_xBuilder, "toolcolor", *m_xCtlPipette))
354 , m_xBtnExec(m_xBuilder->weld_button("replace"))
355 , m_xCbx1(m_xBuilder->weld_check_button("cbx1"))
356 , m_xQSet1(new MaskSet(this))
357 , m_xQSetWin1(new weld::CustomWeld(*m_xBuilder, "qset1", *m_xQSet1))
358 , m_xSp1(m_xBuilder->weld_metric_spin_button("tol1", FieldUnit::PERCENT))
359 , m_xLbColor1(new ColorListBox(m_xBuilder->weld_menu_button("color1"), [this]{ return GetFrameWeld(); }))
360 , m_xCbx2(m_xBuilder->weld_check_button("cbx2"))
361 , m_xQSet2(new MaskSet(this))
362 , m_xQSetWin2(new weld::CustomWeld(*m_xBuilder, "qset2", *m_xQSet2))
363 , m_xSp2(m_xBuilder->weld_metric_spin_button("tol2", FieldUnit::PERCENT))
364 , m_xLbColor2(new ColorListBox(m_xBuilder->weld_menu_button("color2"), [this]{ return GetFrameWeld(); }))
365 , m_xCbx3(m_xBuilder->weld_check_button("cbx3"))
366 , m_xQSet3(new MaskSet(this))
367 , m_xQSetWin3(new weld::CustomWeld(*m_xBuilder, "qset3", *m_xQSet3))
368 , m_xSp3(m_xBuilder->weld_metric_spin_button("tol3", FieldUnit::PERCENT))
369 , m_xLbColor3(new ColorListBox(m_xBuilder->weld_menu_button("color3"), [this]{ return GetFrameWeld(); }))
370 , m_xCbx4(m_xBuilder->weld_check_button("cbx4"))
371 , m_xQSet4(new MaskSet(this))
372 , m_xQSetWin4(new weld::CustomWeld(*m_xBuilder, "qset4", *m_xQSet4))
373 , m_xSp4(m_xBuilder->weld_metric_spin_button("tol4", FieldUnit::PERCENT))
374 , m_xLbColor4(new ColorListBox(m_xBuilder->weld_menu_button("color4"), [this]{ return GetFrameWeld(); }))
375 , m_xCbxTrans(m_xBuilder->weld_check_button("cbx5"))
376 , m_xLbColorTrans(new ColorListBox(m_xBuilder->weld_menu_button("color5"), [this]{ return GetFrameWeld(); }))
377 , m_xData(new MaskData(this, *pBindinx))
378 , aPipetteColor(COL_WHITE)
379 , aSelItem(*this, *pBindinx)
381 SetText(SvxResId(RID_SVXDLG_BMPMASK_STR_TITLE));
383 m_xLbColor1->SetSlotId(SID_BMPMASK_COLOR);
384 m_xLbColor2->SetSlotId(SID_BMPMASK_COLOR);
385 m_xLbColor3->SetSlotId(SID_BMPMASK_COLOR);
386 m_xLbColor4->SetSlotId(SID_BMPMASK_COLOR);
388 m_xLbColorTrans->SelectEntry(COL_BLACK);
389 m_xLbColor1->SelectEntry(COL_TRANSPARENT);
390 m_xLbColor2->SelectEntry(COL_TRANSPARENT);
391 m_xLbColor3->SelectEntry(COL_TRANSPARENT);
392 m_xLbColor4->SelectEntry(COL_TRANSPARENT);
394 m_xTbxPipette->connect_clicked( LINK( m_xData.get(), MaskData, PipetteHdl ) );
395 m_xBtnExec->connect_clicked( LINK( m_xData.get(), MaskData, ExecHdl ) );
397 m_xCbx1->connect_toggled( LINK( m_xData.get(), MaskData, CbxHdl ) );
398 m_xCbx2->connect_toggled( LINK( m_xData.get(), MaskData, CbxHdl ) );
399 m_xCbx3->connect_toggled( LINK( m_xData.get(), MaskData, CbxHdl ) );
400 m_xCbx4->connect_toggled( LINK( m_xData.get(), MaskData, CbxHdl ) );
401 m_xCbxTrans->connect_toggled( LINK( m_xData.get(), MaskData, CbxTransHdl ) );
403 SetAccessibleNames ();
405 m_xLbColor1->connect_focus_in( LINK( m_xData.get(), MaskData, FocusLbHdl ) );
406 m_xLbColor2->connect_focus_in( LINK( m_xData.get(), MaskData, FocusLbHdl ) );
407 m_xLbColor3->connect_focus_in( LINK( m_xData.get(), MaskData, FocusLbHdl ) );
408 m_xLbColor4->connect_focus_in( LINK( m_xData.get(), MaskData, FocusLbHdl ) );
409 m_xLbColorTrans->set_sensitive(false);
411 OUString sColorPalette (SvxResId( RID_SVXDLG_BMPMASK_STR_PALETTE));
412 OUString sColorPaletteN;
414 m_xQSet1->SetStyle( m_xQSet1->GetStyle() | WB_DOUBLEBORDER | WB_ITEMBORDER );
415 m_xQSet1->SetColCount();
416 m_xQSet1->SetLineCount( 1 );
417 sColorPaletteN = sColorPalette + " 1";
418 m_xQSet1->InsertItem( 1, aPipetteColor, sColorPaletteN);
419 m_xQSet1->SelectItem( 1 );
421 m_xQSet2->SetStyle( m_xQSet2->GetStyle() | WB_DOUBLEBORDER | WB_ITEMBORDER );
422 m_xQSet2->SetColCount();
423 m_xQSet2->SetLineCount( 1 );
424 sColorPaletteN = sColorPalette + " 2";
425 m_xQSet2->InsertItem( 1, aPipetteColor, sColorPaletteN);
426 m_xQSet2->SelectItem( 0 );
428 m_xQSet3->SetStyle( m_xQSet3->GetStyle() | WB_DOUBLEBORDER | WB_ITEMBORDER );
429 m_xQSet3->SetColCount();
430 m_xQSet3->SetLineCount( 1 );
431 sColorPaletteN = sColorPalette + " 3";
432 m_xQSet3->InsertItem( 1, aPipetteColor, sColorPaletteN);
433 m_xQSet3->SelectItem( 0 );
435 m_xQSet4->SetStyle( m_xQSet4->GetStyle() | WB_DOUBLEBORDER | WB_ITEMBORDER );
436 m_xQSet4->SetColCount();
437 m_xQSet4->SetLineCount( 1 );
438 sColorPaletteN = sColorPalette + " 4";
439 m_xQSet4->InsertItem( 1, aPipetteColor, sColorPaletteN);
440 m_xQSet4->SelectItem( 0 );
442 m_xQSet1->Show();
443 m_xQSet2->Show();
444 m_xQSet3->Show();
445 m_xQSet4->Show();
448 SvxBmpMask::~SvxBmpMask()
450 disposeOnce();
453 void SvxBmpMask::dispose()
455 m_xQSetWin1.reset();
456 m_xQSet1.reset();
457 m_xQSetWin2.reset();
458 m_xQSet2.reset();
459 m_xQSetWin3.reset();
460 m_xQSet3.reset();
461 m_xQSetWin4.reset();
462 m_xQSet4.reset();
463 m_xCtlPipetteWin.reset();
464 m_xCtlPipette.reset();
465 m_xData.reset();
466 m_xTbxPipette.reset();
467 m_xBtnExec.reset();
468 m_xCbx1.reset();
469 m_xSp1.reset();
470 m_xLbColor1.reset();
471 m_xCbx2.reset();
472 m_xSp2.reset();
473 m_xLbColor2.reset();
474 m_xCbx3.reset();
475 m_xSp3.reset();
476 m_xLbColor3.reset();
477 m_xCbx4.reset();
478 m_xSp4.reset();
479 m_xLbColor4.reset();
480 m_xCbxTrans.reset();
481 m_xLbColorTrans.reset();
482 aSelItem.dispose();
483 SfxDockingWindow::dispose();
486 /** is called by a MaskSet when it is selected */
487 void SvxBmpMask::onSelect( const MaskSet* pSet )
489 // now deselect all other value sets
490 if( pSet != m_xQSet1.get() )
491 m_xQSet1->SelectItem( 0 );
493 if( pSet != m_xQSet2.get() )
494 m_xQSet2->SelectItem( 0 );
496 if( pSet != m_xQSet3.get() )
497 m_xQSet3->SelectItem( 0 );
499 if( pSet != m_xQSet4.get() )
500 m_xQSet4->SelectItem( 0 );
503 bool SvxBmpMask::Close()
505 SfxBoolItem aItem2( SID_BMPMASK_PIPETTE, false );
506 GetBindings().GetDispatcher()->ExecuteList(SID_BMPMASK_PIPETTE,
507 OWN_CALLMODE, { &aItem2 });
509 return SfxDockingWindow::Close();
512 void SvxBmpMask::SetColor( const Color& rColor )
514 aPipetteColor = rColor;
515 m_xCtlPipette->SetColor( aPipetteColor );
518 void SvxBmpMask::PipetteClicked()
520 if( m_xQSet1->GetSelectedItemId() == 1 )
522 m_xCbx1->set_active(true);
523 m_xData->CbxHdl(*m_xCbx1);
524 m_xQSet1->SetItemColor( 1, aPipetteColor );
525 m_xQSet1->SetFormat();
527 else if( m_xQSet2->GetSelectedItemId() == 1 )
529 m_xCbx2->set_active(true);
530 m_xData->CbxHdl(*m_xCbx2);
531 m_xQSet2->SetItemColor( 1, aPipetteColor );
532 m_xQSet2->SetFormat();
534 else if( m_xQSet3->GetSelectedItemId() == 1 )
536 m_xCbx3->set_active(true);
537 m_xData->CbxHdl(*m_xCbx3);
538 m_xQSet3->SetItemColor( 1, aPipetteColor );
539 m_xQSet3->SetFormat();
541 else if( m_xQSet4->GetSelectedItemId() == 1 )
543 m_xCbx4->set_active(true);
544 m_xData->CbxHdl(*m_xCbx4);
545 m_xQSet4->SetItemColor( 1, aPipetteColor );
546 m_xQSet4->SetFormat();
549 m_xTbxPipette->set_item_active("pipette", false);
550 m_xData->PipetteHdl("pipette");
553 void SvxBmpMask::SetExecState( bool bEnable )
555 m_xData->SetExecState( bEnable );
557 if ( m_xData->IsExecReady() && m_xData->IsCbxReady() )
558 m_xBtnExec->set_sensitive(true);
559 else
560 m_xBtnExec->set_sensitive(false);
564 sal_uInt16 SvxBmpMask::InitColorArrays( Color* pSrcCols, Color* pDstCols, sal_uInt8* pTols )
566 sal_uInt16 nCount = 0;
568 if ( m_xCbx1->get_active() )
570 pSrcCols[nCount] = m_xQSet1->GetItemColor( 1 );
571 pDstCols[nCount] = m_xLbColor1->GetSelectEntryColor();
572 pTols[nCount++] = static_cast<sal_uInt8>(m_xSp1->get_value(FieldUnit::PERCENT));
575 if ( m_xCbx2->get_active() )
577 pSrcCols[nCount] = m_xQSet2->GetItemColor( 1 );
578 pDstCols[nCount] = m_xLbColor2->GetSelectEntryColor();
579 pTols[nCount++] = static_cast<sal_uInt8>(m_xSp2->get_value(FieldUnit::PERCENT));
582 if ( m_xCbx3->get_active() )
584 pSrcCols[nCount] = m_xQSet3->GetItemColor( 1 );
585 pDstCols[nCount] = m_xLbColor3->GetSelectEntryColor();
586 pTols[nCount++] = static_cast<sal_uInt8>(m_xSp3->get_value(FieldUnit::PERCENT));
589 if ( m_xCbx4->get_active() )
591 pSrcCols[nCount] = m_xQSet4->GetItemColor( 1 );
592 pDstCols[nCount] = m_xLbColor4->GetSelectEntryColor();
593 pTols[nCount++] = static_cast<sal_uInt8>(m_xSp4->get_value(FieldUnit::PERCENT));
596 return nCount;
599 void SvxBmpMask::ImpMask( BitmapEx& rBitmap )
601 Color pSrcCols[4];
602 Color pDstCols[4];
603 sal_uInt8 pTols[4];
604 const sal_uInt16 nCount = InitColorArrays( pSrcCols, pDstCols, pTols );
606 EnterWait();
607 rBitmap.Replace( pSrcCols, pDstCols, nCount, pTols );
608 LeaveWait();
611 BitmapEx SvxBmpMask::ImpMaskTransparent( const BitmapEx& rBitmapEx, const Color& rColor, const sal_uInt8 nTol )
613 EnterWait();
615 BitmapEx aBmpEx;
616 AlphaMask aMask( rBitmapEx.GetBitmap().CreateAlphaMask( rColor, nTol ) );
618 if( rBitmapEx.IsAlpha() )
619 aMask.AlphaCombineOr( rBitmapEx.GetAlphaMask() );
621 aBmpEx = BitmapEx( rBitmapEx.GetBitmap(), aMask );
622 LeaveWait();
624 return aBmpEx;
628 Animation SvxBmpMask::ImpMask( const Animation& rAnimation )
630 Animation aAnimation( rAnimation );
631 Color pSrcCols[4];
632 Color pDstCols[4];
633 sal_uInt8 pTols[4];
634 InitColorArrays( pSrcCols, pDstCols, pTols );
635 sal_uInt16 nAnimationCount = aAnimation.Count();
637 for( sal_uInt16 i = 0; i < nAnimationCount; i++ )
639 AnimationFrame aAnimationFrame( aAnimation.Get( i ) );
640 aAnimationFrame.maBitmapEx = Mask(aAnimationFrame.maBitmapEx).GetBitmapEx();
641 aAnimation.Replace(aAnimationFrame, i);
644 return aAnimation;
648 GDIMetaFile SvxBmpMask::ImpMask( const GDIMetaFile& rMtf )
650 GDIMetaFile aMtf;
651 Color pSrcCols[4];
652 Color pDstCols[4];
653 sal_uInt8 pTols[4];
654 sal_uInt16 nCount = InitColorArrays( pSrcCols, pDstCols, pTols );
656 // If no color is selected, we copy only the Mtf
657 if( !nCount )
658 aMtf = rMtf;
659 else
661 bool pTrans[4];
662 Color aCol;
663 tools::Long nR;
664 tools::Long nG;
665 tools::Long nB;
666 std::unique_ptr<tools::Long[]> pMinR(new tools::Long[nCount]);
667 std::unique_ptr<tools::Long[]> pMaxR(new tools::Long[nCount]);
668 std::unique_ptr<tools::Long[]> pMinG(new tools::Long[nCount]);
669 std::unique_ptr<tools::Long[]> pMaxG(new tools::Long[nCount]);
670 std::unique_ptr<tools::Long[]> pMinB(new tools::Long[nCount]);
671 std::unique_ptr<tools::Long[]> pMaxB(new tools::Long[nCount]);
672 sal_uInt16 i;
674 aMtf.SetPrefSize( rMtf.GetPrefSize() );
675 aMtf.SetPrefMapMode( rMtf.GetPrefMapMode() );
677 // Prepare Color comparison array
678 for( i = 0; i < nCount; i++ )
680 tools::Long nTol = ( pTols[i] * 255 ) / 100;
682 tools::Long nVal = static_cast<tools::Long>(pSrcCols[i].GetRed());
683 pMinR[i] = std::max( nVal - nTol, tools::Long(0) );
684 pMaxR[i] = std::min( nVal + nTol, tools::Long(255) );
686 nVal = static_cast<tools::Long>(pSrcCols[i].GetGreen());
687 pMinG[i] = std::max( nVal - nTol, tools::Long(0) );
688 pMaxG[i] = std::min( nVal + nTol, tools::Long(255) );
690 nVal = static_cast<tools::Long>(pSrcCols[i].GetBlue());
691 pMinB[i] = std::max( nVal - nTol, tools::Long(0) );
692 pMaxB[i] = std::min( nVal + nTol, tools::Long(255) );
694 pTrans[ i ] = (pDstCols[ i ] == COL_TRANSPARENT);
697 // Investigate actions and if necessary replace colors
698 for( size_t nAct = 0, nActCount = rMtf.GetActionSize(); nAct < nActCount; nAct++ )
700 MetaAction* pAction = rMtf.GetAction( nAct );
702 bool bReplace = false;
704 switch( pAction->GetType() )
706 case MetaActionType::PIXEL:
708 MetaPixelAction* pAct = static_cast<MetaPixelAction*>(pAction);
710 aCol = pAct->GetColor();
711 TEST_COLS();
713 if( bReplace )
714 pAct = new MetaPixelAction( pAct->GetPoint(), aCol );
716 aMtf.AddAction( pAct );
718 break;
720 case MetaActionType::LINECOLOR:
722 MetaLineColorAction* pAct = static_cast<MetaLineColorAction*>(pAction);
724 aCol = pAct->GetColor();
725 TEST_COLS();
727 if( bReplace )
728 pAct = new MetaLineColorAction( aCol, !pTrans[ i ] );
730 aMtf.AddAction( pAct );
732 break;
734 case MetaActionType::FILLCOLOR:
736 MetaFillColorAction* pAct = static_cast<MetaFillColorAction*>(pAction);
738 aCol = pAct->GetColor();
739 TEST_COLS();
741 if( bReplace )
742 pAct = new MetaFillColorAction( aCol, !pTrans[ i ] );
744 aMtf.AddAction( pAct );
746 break;
748 case MetaActionType::TEXTCOLOR:
750 MetaTextColorAction* pAct = static_cast<MetaTextColorAction*>(pAction);
752 aCol = pAct->GetColor();
753 TEST_COLS();
755 if( bReplace )
756 pAct = new MetaTextColorAction( aCol );
758 aMtf.AddAction( pAct );
760 break;
762 case MetaActionType::TEXTFILLCOLOR:
764 MetaTextFillColorAction* pAct = static_cast<MetaTextFillColorAction*>(pAction);
766 aCol = pAct->GetColor();
767 TEST_COLS();
769 if( bReplace )
770 pAct = new MetaTextFillColorAction( aCol, !pTrans[ i ] );
772 aMtf.AddAction( pAct );
774 break;
776 case MetaActionType::FONT:
778 MetaFontAction* pAct = static_cast<MetaFontAction*>(pAction);
779 vcl::Font aFont( pAct->GetFont() );
781 aCol = aFont.GetColor();
782 TEST_COLS();
784 if( bReplace )
786 aFont.SetColor( aCol );
787 pAct = new MetaFontAction( std::move(aFont) );
790 aMtf.AddAction( pAct );
792 break;
794 case MetaActionType::WALLPAPER:
796 MetaWallpaperAction* pAct = static_cast<MetaWallpaperAction*>(pAction);
797 Wallpaper aWall( pAct->GetWallpaper() );
799 aCol = aWall.GetColor();
800 TEST_COLS();
802 if( bReplace )
804 aWall.SetColor( aCol );
805 pAct = new MetaWallpaperAction( pAct->GetRect(), std::move(aWall) );
808 aMtf.AddAction( pAct );
810 break;
812 case MetaActionType::BMP:
814 MetaBmpAction* pAct = static_cast<MetaBmpAction*>(pAction);
815 const Bitmap aBmp( Mask(BitmapEx(pAct->GetBitmap())).GetBitmapEx().GetBitmap() );
817 pAct = new MetaBmpAction( pAct->GetPoint(), aBmp );
818 aMtf.AddAction( pAct );
820 break;
822 case MetaActionType::BMPSCALE:
824 MetaBmpScaleAction* pAct = static_cast<MetaBmpScaleAction*>(pAction);
825 const Bitmap aBmp( Mask(BitmapEx(pAct->GetBitmap())).GetBitmapEx().GetBitmap() );
827 pAct = new MetaBmpScaleAction( pAct->GetPoint(), pAct->GetSize(), aBmp );
828 aMtf.AddAction( pAct );
830 break;
832 case MetaActionType::BMPSCALEPART:
834 MetaBmpScalePartAction* pAct = static_cast<MetaBmpScalePartAction*>(pAction);
835 const Bitmap aBmp( Mask(BitmapEx(pAct->GetBitmap())).GetBitmapEx().GetBitmap() );
837 pAct = new MetaBmpScalePartAction( pAct->GetDestPoint(), pAct->GetDestSize(),
838 pAct->GetSrcPoint(), pAct->GetSrcSize(), aBmp );
839 aMtf.AddAction( pAct );
841 break;
843 case MetaActionType::BMPEX:
845 MetaBmpExAction* pAct = static_cast<MetaBmpExAction*>(pAction);
846 const BitmapEx aBmpEx( Mask( pAct->GetBitmapEx() ).GetBitmapEx() );
848 pAct = new MetaBmpExAction( pAct->GetPoint(), aBmpEx );
849 aMtf.AddAction( pAct );
851 break;
853 case MetaActionType::BMPEXSCALE:
855 MetaBmpExScaleAction* pAct = static_cast<MetaBmpExScaleAction*>(pAction);
856 const BitmapEx aBmpEx( Mask( pAct->GetBitmapEx() ).GetBitmapEx() );
858 pAct = new MetaBmpExScaleAction( pAct->GetPoint(), pAct->GetSize(), aBmpEx );
859 aMtf.AddAction( pAct );
861 break;
863 case MetaActionType::BMPEXSCALEPART:
865 MetaBmpExScalePartAction* pAct = static_cast<MetaBmpExScalePartAction*>(pAction);
866 const BitmapEx aBmpEx( Mask( pAct->GetBitmapEx() ).GetBitmapEx() );
868 pAct = new MetaBmpExScalePartAction( pAct->GetDestPoint(), pAct->GetDestSize(),
869 pAct->GetSrcPoint(), pAct->GetSrcSize(), aBmpEx );
870 aMtf.AddAction( pAct );
872 break;
874 default:
876 aMtf.AddAction( pAction );
878 break;
883 LeaveWait();
885 return aMtf;
889 Animation SvxBmpMask::ImpReplaceTransparency( const Animation& rAnim, const Color& rColor )
891 Animation aAnimation( rAnim );
892 sal_uInt16 nAnimationCount = aAnimation.Count();
894 for( sal_uInt16 i = 0; i < nAnimationCount; i++ )
896 AnimationFrame aAnimationFrame(aAnimation.Get(i));
897 aAnimationFrame.maBitmapEx.ReplaceTransparency(rColor);
898 aAnimation.Replace(aAnimationFrame, i);
901 return aAnimation;
905 GDIMetaFile SvxBmpMask::ImpReplaceTransparency( const GDIMetaFile& rMtf, const Color& rColor )
907 ScopedVclPtrInstance< VirtualDevice > pVDev;
908 GDIMetaFile aMtf;
909 const MapMode& rPrefMap = rMtf.GetPrefMapMode();
910 const Size& rPrefSize = rMtf.GetPrefSize();
911 const size_t nActionCount = rMtf.GetActionSize();
913 pVDev->EnableOutput( false );
914 aMtf.Record( pVDev );
915 aMtf.SetPrefSize( rPrefSize );
916 aMtf.SetPrefMapMode( rPrefMap );
917 pVDev->SetLineColor( rColor );
918 pVDev->SetFillColor( rColor );
920 // retrieve one action at the time; first
921 // set the whole area to the replacement color.
922 pVDev->DrawRect( tools::Rectangle( rPrefMap.GetOrigin(), rPrefSize ) );
923 for ( size_t i = 0; i < nActionCount; i++ )
925 MetaAction* pAct = rMtf.GetAction( i );
926 aMtf.AddAction( pAct );
929 aMtf.Stop();
930 aMtf.WindStart();
932 return aMtf;
935 GDIMetaFile SvxBmpMask::GetMetaFile(const Graphic& rGraphic)
937 // Replace transparency?
938 if (m_xCbxTrans->get_active())
939 return ImpReplaceTransparency(rGraphic.GetGDIMetaFile(), m_xLbColorTrans->GetSelectEntryColor());
940 return ImpMask(rGraphic.GetGDIMetaFile());
943 Graphic SvxBmpMask::Mask( const Graphic& rGraphic )
945 Graphic aGraphic( rGraphic );
946 const Color aReplColor( m_xLbColorTrans->GetSelectEntryColor() );
948 switch( rGraphic.GetType() )
950 case GraphicType::Bitmap:
952 if( rGraphic.IsAnimated() )
954 // Replace transparency?
955 if ( m_xCbxTrans->get_active() )
956 aGraphic = ImpReplaceTransparency( rGraphic.GetAnimation(), aReplColor );
957 else
958 aGraphic = ImpMask( rGraphic.GetAnimation() );
960 else
962 // Replace transparency?
963 if( m_xCbxTrans->get_active() )
965 BitmapEx aBmpEx = aGraphic.GetBitmapEx();
966 aBmpEx.ReplaceTransparency(aReplColor);
967 aGraphic = aBmpEx;
969 else
971 Color pSrcCols[4];
972 Color pDstCols[4];
973 sal_uInt8 pTols[4];
974 sal_uInt16 nCount = InitColorArrays( pSrcCols, pDstCols, pTols );
976 if( nCount )
978 // first set all transparent colors
979 for( sal_uInt16 i = 0; i < nCount; i++ )
981 // Do we have a transparent color?
982 if (pDstCols[i] == COL_TRANSPARENT)
984 BitmapEx aBmpEx( ImpMaskTransparent( aGraphic.GetBitmapEx(),
985 pSrcCols[ i ], pTols[ i ] ) );
986 const Size aSize( aBmpEx.GetSizePixel() );
988 if( aSize.Width() && aSize.Height() )
989 aGraphic = aBmpEx;
993 // now replace it again with the normal colors
994 BitmapEx aBitmapEx( aGraphic.GetBitmapEx() );
995 if ( aBitmapEx.GetSizePixel().Width() && aBitmapEx.GetSizePixel().Height() )
997 ImpMask( aBitmapEx );
998 aGraphic = Graphic( aBitmapEx );
1004 break;
1006 case GraphicType::GdiMetafile:
1008 GDIMetaFile aMtf(GetMetaFile(rGraphic));
1009 Size aSize( aMtf.GetPrefSize() );
1010 if ( aSize.Width() && aSize.Height() )
1011 aGraphic = Graphic( aMtf );
1012 else
1013 aGraphic = rGraphic;
1015 break;
1017 default:
1018 aGraphic = rGraphic;
1019 break;
1022 if( aGraphic != rGraphic )
1024 aGraphic.SetPrefSize( rGraphic.GetPrefSize() );
1025 aGraphic.SetPrefMapMode( rGraphic.GetPrefMapMode() );
1028 return aGraphic;
1031 bool SvxBmpMask::IsEyedropping() const
1033 return m_xTbxPipette->get_item_active("pipette");
1036 /** Set an accessible name for the source color check boxes. Without this
1037 the lengthy description is read.
1039 void SvxBmpMask::SetAccessibleNames()
1041 // set the accessible name for valueset
1042 OUString sColorPalette (SvxResId( RID_SVXDLG_BMPMASK_STR_PALETTE));
1043 OUString sColorPaletteN;
1045 sColorPaletteN = sColorPalette + " 1";
1046 m_xQSet1->SetText (sColorPaletteN);
1047 sColorPaletteN = sColorPalette + " 2";
1048 m_xQSet2->SetText (sColorPaletteN);
1049 sColorPaletteN = sColorPalette + " 3";
1050 m_xQSet3->SetText (sColorPaletteN);
1051 sColorPaletteN = sColorPalette + " 4";
1052 m_xQSet4->SetText (sColorPaletteN);
1055 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */