1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 <sal/config.h>
22 #include <sot/exchange.hxx>
23 #include <svx/strings.hrc>
24 #include <svx/svxids.hrc>
26 #include <sfx2/viewsh.hxx>
27 #include <sfx2/objsh.hxx>
28 #include <sfx2/dispatch.hxx>
29 #include <sfx2/viewfrm.hxx>
30 #include <vcl/image.hxx>
31 #include <vcl/transfer.hxx>
33 #include <colrctrl.hxx>
35 #include <svx/svdview.hxx>
36 #include <svx/drawitem.hxx>
37 #include <svx/xfillit0.hxx>
38 #include <svx/xflclit.hxx>
39 #include <editeng/colritem.hxx>
40 #include <svx/xlineit0.hxx>
41 #include <svx/xlnclit.hxx>
42 #include <svx/dialmgr.hxx>
44 #include <vcl/virdev.hxx>
46 #include <com/sun/star/beans/NamedValue.hpp>
48 using namespace com::sun::star
;
50 class SvxColorValueSetData final
: public TransferDataContainer
53 uno::Sequence
<beans::NamedValue
> m_Data
;
55 virtual void AddSupportedFormats() override
;
56 virtual bool GetData(const css::datatransfer::DataFlavor
& rFlavor
, const OUString
& rDestDoc
) override
;
59 SvxColorValueSetData()
63 void SetData(const uno::Sequence
<beans::NamedValue
>& rData
)
66 ClearFormats(); // invalidate m_aAny so new data will take effect
70 void SvxColorValueSetData::AddSupportedFormats()
72 AddFormat( SotClipboardFormatId::XFA
);
75 bool SvxColorValueSetData::GetData( const css::datatransfer::DataFlavor
& rFlavor
, const OUString
& /*rDestDoc*/ )
79 if( SotExchange::GetFormat( rFlavor
) == SotClipboardFormatId::XFA
)
81 SetAny(uno::Any(m_Data
));
88 void SvxColorValueSet_docking::SetDrawingArea(weld::DrawingArea
* pDrawingArea
)
90 SvxColorValueSet::SetDrawingArea(pDrawingArea
);
91 SetAccessibleName(SvxResId(STR_COLORTABLE
));
92 SetStyle(GetStyle() | WB_ITEMBORDER
);
94 m_xHelper
.set(new SvxColorValueSetData
);
95 rtl::Reference
<TransferDataContainer
> xHelper(m_xHelper
);
96 SetDragDataTransferable(xHelper
, DND_ACTION_COPY
);
99 SvxColorValueSet_docking::SvxColorValueSet_docking(std::unique_ptr
<weld::ScrolledWindow
> xWindow
)
100 : SvxColorValueSet(std::move(xWindow
))
105 bool SvxColorValueSet_docking::MouseButtonDown( const MouseEvent
& rMEvt
)
109 // For Mac still handle differently!
113 bRet
= SvxColorValueSet::MouseButtonDown( rMEvt
);
117 mbLeftButton
= false;
118 MouseEvent
aMEvt( rMEvt
.GetPosPixel(),
122 rMEvt
.GetModifier() );
123 bRet
= SvxColorValueSet::MouseButtonDown( aMEvt
);
129 bool SvxColorValueSet_docking::MouseButtonUp( const MouseEvent
& rMEvt
)
133 // For Mac still handle differently!
137 bRet
= SvxColorValueSet::MouseButtonUp( rMEvt
);
141 mbLeftButton
= false;
142 MouseEvent
aMEvt( rMEvt
.GetPosPixel(),
146 rMEvt
.GetModifier() );
147 bRet
= SvxColorValueSet::MouseButtonUp( aMEvt
);
154 bool SvxColorValueSet_docking::StartDrag()
156 sal_uInt16 nPos
= GetSelectedItemId();
157 Color
aItemColor( GetItemColor( nPos
) );
158 OUString
sItemText( GetItemText( nPos
) );
160 drawing::FillStyle eStyle
= ((1 == nPos
)
161 ? drawing::FillStyle_NONE
162 : drawing::FillStyle_SOLID
);
164 XFillColorItem
const color(sItemText
, aItemColor
);
165 XFillStyleItem
const style(eStyle
);
167 color
.QueryValue(c
, 0);
168 style
.QueryValue(s
, 0);
170 uno::Sequence
<beans::NamedValue
> props
{ { u
"FillColor"_ustr
, std::move(c
) },
171 { u
"FillStyle"_ustr
, std::move(s
) } };
172 m_xHelper
->SetData(props
);
177 constexpr sal_uInt16 gnLeftSlot
= SID_ATTR_FILL_COLOR
;
178 constexpr sal_uInt16 gnRightSlot
= SID_ATTR_LINE_COLOR
;
180 SvxColorDockingWindow::SvxColorDockingWindow(SfxBindings
* _pBindings
, SfxChildWindow
* pCW
, vcl::Window
* _pParent
)
181 : SfxDockingWindow(_pBindings
, pCW
, _pParent
,
182 u
"DockingColorWindow"_ustr
, u
"svx/ui/dockingcolorwindow.ui"_ustr
)
183 , xColorSet(new SvxColorValueSet_docking(m_xBuilder
->weld_scrolled_window(u
"valuesetwin"_ustr
, true)))
184 , xColorSetWin(new weld::CustomWeld(*m_xBuilder
, u
"valueset"_ustr
, *xColorSet
))
186 SetText(SvxResId(STR_COLORTABLE
));
187 SetQuickHelpText(SvxResId(RID_SVXSTR_COLORBAR
));
188 SetSizePixel(LogicToPixel(Size(150, 22), MapMode(MapUnit::MapAppFont
)));
189 SetHelpId(HID_CTRL_COLOR
);
191 xColorSet
->SetSelectHdl( LINK( this, SvxColorDockingWindow
, SelectHdl
) );
192 xColorSet
->SetHelpId(HID_COLOR_CTL_COLORS
);
194 // Get the model from the view shell. Using SfxObjectShell::Current()
195 // is unreliable when called at the wrong times.
196 SfxObjectShell
* pDocSh
= nullptr;
197 if (_pBindings
!= nullptr)
199 SfxDispatcher
* pDispatcher
= _pBindings
->GetDispatcher();
200 if (pDispatcher
!= nullptr)
202 SfxViewFrame
* pFrame
= pDispatcher
->GetFrame();
203 if (pFrame
!= nullptr)
205 SfxViewShell
* pViewShell
= pFrame
->GetViewShell();
206 if (pViewShell
!= nullptr)
207 pDocSh
= pViewShell
->GetObjectShell();
214 const SfxPoolItem
* pItem
= pDocSh
->GetItem( SID_COLOR_TABLE
);
217 pColorList
= static_cast<const SvxColorListItem
*>(pItem
)->GetColorList();
222 Size aItemSize
= xColorSet
->CalcItemSizePixel(Size(SvxColorValueSet::getEntryEdgeLength(), SvxColorValueSet::getEntryEdgeLength()));
223 aItemSize
.setWidth( aItemSize
.Width() + SvxColorValueSet::getEntryEdgeLength() );
224 aItemSize
.setWidth( aItemSize
.Width() / 2 );
225 aItemSize
.setHeight( aItemSize
.Height() + SvxColorValueSet::getEntryEdgeLength() );
226 aItemSize
.setHeight( aItemSize
.Height() / 2 );
228 if (_pBindings
!= nullptr)
229 StartListening(*_pBindings
, DuplicateHandling::Prevent
);
232 SvxColorDockingWindow::~SvxColorDockingWindow()
237 void SvxColorDockingWindow::dispose()
239 EndListening( GetBindings() );
240 xColorSetWin
.reset();
242 SfxDockingWindow::dispose();
245 void SvxColorDockingWindow::Notify( SfxBroadcaster
& , const SfxHint
& rHint
)
247 if (rHint
.GetId() == SfxHintId::PoolItem
)
249 const SfxPoolItemHint
* pPoolItemHint
= static_cast<const SfxPoolItemHint
*>(&rHint
);
250 if (auto pColorListItem
= dynamic_cast<const SvxColorListItem
*>(pPoolItemHint
->GetObject()))
252 // The list of colors has changed
253 pColorList
= pColorListItem
->GetColorList();
259 void SvxColorDockingWindow::FillValueSet()
261 if( !pColorList
.is() )
266 xColorSet
->addEntriesForXColorList(*pColorList
, 2);
268 // create the last entry for 'invisible/none'
269 const Size
aColorSize(SvxColorValueSet::getEntryEdgeLength(), SvxColorValueSet::getEntryEdgeLength());
270 tools::Long nPtX
= aColorSize
.Width() - 1;
271 tools::Long nPtY
= aColorSize
.Height() - 1;
272 ScopedVclPtrInstance
< VirtualDevice
> pVD
;
274 pVD
->SetOutputSizePixel( aColorSize
);
275 pVD
->SetLineColor( COL_BLACK
);
276 pVD
->SetBackground( Wallpaper( COL_WHITE
) );
277 pVD
->DrawLine( Point(), Point( nPtX
, nPtY
) );
278 pVD
->DrawLine( Point( 0, nPtY
), Point( nPtX
, 0 ) );
280 BitmapEx
aBmp( pVD
->GetBitmapEx( Point(), aColorSize
) );
282 xColorSet
->InsertItem( sal_uInt16(1), Image(aBmp
), SvxResId( RID_SVXSTR_INVISIBLE
) );
285 bool SvxColorDockingWindow::Close()
287 SfxBoolItem
aItem( SID_COLOR_CONTROL
, false );
288 GetBindings().GetDispatcher()->ExecuteList(SID_COLOR_CONTROL
,
289 SfxCallMode::ASYNCHRON
| SfxCallMode::RECORD
, { &aItem
});
290 SfxDockingWindow::Close();
294 IMPL_LINK_NOARG(SvxColorDockingWindow
, SelectHdl
, ValueSet
*, void)
296 SfxDispatcher
* pDispatcher
= GetBindings().GetDispatcher();
297 sal_uInt16 nPos
= xColorSet
->GetSelectedItemId();
298 Color
aColor( xColorSet
->GetItemColor( nPos
) );
299 OUString
aStr( xColorSet
->GetItemText( nPos
) );
301 if (xColorSet
->IsLeftButton())
303 if ( gnLeftSlot
== SID_ATTR_FILL_COLOR
)
305 if ( nPos
== 1 ) // invisible
307 XFillStyleItem
aXFillStyleItem( drawing::FillStyle_NONE
);
308 pDispatcher
->ExecuteList(gnLeftSlot
, SfxCallMode::RECORD
,
309 { &aXFillStyleItem
});
315 // If we have a DrawView and we are in TextEdit mode, then
316 // not the area color but the text color is assigned
317 SfxViewShell
* pViewSh
= SfxViewShell::Current();
320 SdrView
* pView
= pViewSh
->GetDrawView();
321 if ( pView
&& pView
->IsTextEdit() )
323 SvxColorItem
aTextColorItem( aColor
, SID_ATTR_CHAR_COLOR
);
324 pDispatcher
->ExecuteList(SID_ATTR_CHAR_COLOR
,
325 SfxCallMode::RECORD
, { &aTextColorItem
});
331 XFillStyleItem
aXFillStyleItem( drawing::FillStyle_SOLID
);
332 XFillColorItem
aXFillColorItem( aStr
, aColor
);
333 pDispatcher
->ExecuteList(gnLeftSlot
, SfxCallMode::RECORD
,
334 { &aXFillColorItem
, &aXFillStyleItem
});
338 else if ( nPos
!= 1 ) // invisible
340 SvxColorItem
aLeftColorItem( aColor
, gnLeftSlot
);
341 pDispatcher
->ExecuteList(gnLeftSlot
, SfxCallMode::RECORD
,
342 { &aLeftColorItem
});
347 if ( gnRightSlot
== SID_ATTR_LINE_COLOR
)
349 if( nPos
== 1 ) // invisible
351 XLineStyleItem
aXLineStyleItem( drawing::LineStyle_NONE
);
352 pDispatcher
->ExecuteList(gnRightSlot
, SfxCallMode::RECORD
,
353 { &aXLineStyleItem
});
357 // If the LineStyle is invisible, it is set to SOLID
358 SfxViewShell
* pViewSh
= SfxViewShell::Current();
361 SdrView
* pView
= pViewSh
->GetDrawView();
364 SfxItemSet
aAttrSet(pView
->GetModel().GetItemPool());
365 pView
->GetAttributes( aAttrSet
);
366 if ( aAttrSet
.GetItemState( XATTR_LINESTYLE
) != SfxItemState::INVALID
)
368 drawing::LineStyle eXLS
=
369 aAttrSet
.Get( XATTR_LINESTYLE
).GetValue();
370 if ( eXLS
== drawing::LineStyle_NONE
)
372 XLineStyleItem
aXLineStyleItem( drawing::LineStyle_SOLID
);
373 pDispatcher
->ExecuteList(gnRightSlot
,
374 SfxCallMode::RECORD
, { &aXLineStyleItem
});
380 XLineColorItem
aXLineColorItem( aStr
, aColor
);
381 pDispatcher
->ExecuteList(gnRightSlot
, SfxCallMode::RECORD
,
382 { &aXLineColorItem
});
385 else if ( nPos
!= 1 ) // invisible
387 SvxColorItem
aRightColorItem( aColor
, gnRightSlot
);
388 pDispatcher
->ExecuteList(gnRightSlot
, SfxCallMode::RECORD
,
389 { &aRightColorItem
});
394 void SvxColorDockingWindow::GetFocus()
396 SfxDockingWindow::GetFocus();
399 // Grab the focus to the color value set so that it can be controlled
400 // with the keyboard.
401 xColorSet
->GrabFocus();
405 bool SvxColorDockingWindow::EventNotify( NotifyEvent
& rNEvt
)
408 if( rNEvt
.GetType() == NotifyEventType::KEYINPUT
)
410 KeyEvent aKeyEvt
= *rNEvt
.GetKeyEvent();
411 sal_uInt16 nKeyCode
= aKeyEvt
.GetKeyCode().GetCode();
415 GrabFocusToDocument();
421 return bRet
|| SfxDockingWindow::EventNotify(rNEvt
);
424 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */