LibreOffice Module svx (master)  1
colrctrl.cxx
Go to the documentation of this file.
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 <sal/config.h>
21 
22 #include <sot/exchange.hxx>
23 #include <svx/strings.hrc>
24 #include <svx/svxids.hrc>
25 
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>
32 
33 #include <colrctrl.hxx>
34 
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/xtable.hxx>
43 #include <svx/dialmgr.hxx>
44 #include <helpids.h>
45 #include <vcl/virdev.hxx>
46 
47 #include <com/sun/star/beans/NamedValue.hpp>
48 
49 using namespace com::sun::star;
50 
52 {
53 private:
54  uno::Sequence<beans::NamedValue> m_Data;
55 
56  virtual void AddSupportedFormats() override;
57  virtual bool GetData(const css::datatransfer::DataFlavor& rFlavor, const OUString& rDestDoc) override;
58 
59 public:
61  {
62  }
63 
64  void SetData(const uno::Sequence<beans::NamedValue>& rData)
65  {
66  m_Data = rData;
67  ClearFormats(); // invalidate m_aAny so new data will take effect
68  }
69 };
70 
72 {
73  AddFormat( SotClipboardFormatId::XFA );
74 }
75 
76 bool SvxColorValueSetData::GetData( const css::datatransfer::DataFlavor& rFlavor, const OUString& /*rDestDoc*/ )
77 {
78  bool bRet = false;
79 
80  if( SotExchange::GetFormat( rFlavor ) == SotClipboardFormatId::XFA )
81  {
82  SetAny(uno::makeAny(m_Data));
83  bRet = true;
84  }
85 
86  return bRet;
87 }
88 
90 {
92  SetAccessibleName(SvxResId(STR_COLORTABLE));
93  SetStyle(GetStyle() | WB_ITEMBORDER);
94 
95  m_xHelper.set(new SvxColorValueSetData);
96  rtl::Reference<TransferDataContainer> xHelper(m_xHelper);
97  SetDragDataTransferrable(xHelper, DND_ACTION_COPY);
98 }
99 
100 SvxColorValueSet_docking::SvxColorValueSet_docking(std::unique_ptr<weld::ScrolledWindow> xWindow)
101  : SvxColorValueSet(std::move(xWindow))
102  , mbLeftButton(true)
103 {
104 }
105 
107 {
108  bool bRet;
109 
110  // For Mac still handle differently!
111  if( rMEvt.IsLeft() )
112  {
113  mbLeftButton = true;
114  bRet = SvxColorValueSet::MouseButtonDown( rMEvt );
115  }
116  else
117  {
118  mbLeftButton = false;
119  MouseEvent aMEvt( rMEvt.GetPosPixel(),
120  rMEvt.GetClicks(),
121  rMEvt.GetMode(),
122  MOUSE_LEFT,
123  rMEvt.GetModifier() );
124  bRet = SvxColorValueSet::MouseButtonDown( aMEvt );
125  }
126 
127  return bRet;
128 }
129 
131 {
132  bool bRet;
133 
134  // For Mac still handle differently!
135  if( rMEvt.IsLeft() )
136  {
137  mbLeftButton = true;
138  bRet = SvxColorValueSet::MouseButtonUp( rMEvt );
139  }
140  else
141  {
142  mbLeftButton = false;
143  MouseEvent aMEvt( rMEvt.GetPosPixel(),
144  rMEvt.GetClicks(),
145  rMEvt.GetMode(),
146  MOUSE_LEFT,
147  rMEvt.GetModifier() );
148  bRet = SvxColorValueSet::MouseButtonUp( aMEvt );
149  }
150  SetNoSelection();
151 
152  return bRet;
153 }
154 
156 {
157  sal_uInt16 nPos = GetSelectedItemId();
158  Color aItemColor( GetItemColor( nPos ) );
159  OUString sItemText( GetItemText( nPos ) );
160 
161  drawing::FillStyle eStyle = ((1 == nPos)
162  ? drawing::FillStyle_NONE
163  : drawing::FillStyle_SOLID);
164 
165  uno::Sequence<beans::NamedValue> props(2);
166  XFillColorItem const color(sItemText, aItemColor);
167  props[0].Name = "FillColor";
168  color.QueryValue(props[0].Value, 0);
169  XFillStyleItem const style(eStyle);
170  props[1].Name = "FillStyle";
171  style.QueryValue(props[1].Value, 0);
172 
173  m_xHelper->SetData(props);
174 
175  return false;
176 }
177 
178 constexpr sal_uInt16 gnLeftSlot = SID_ATTR_FILL_COLOR;
179 constexpr sal_uInt16 gnRightSlot = SID_ATTR_LINE_COLOR;
180 
182  : SfxDockingWindow(_pBindings, pCW, _pParent,
183  "DockingColorWindow", "svx/ui/dockingcolorwindow.ui")
184  , xColorSet(new SvxColorValueSet_docking(m_xBuilder->weld_scrolled_window("valuesetwin", true)))
185  , xColorSetWin(new weld::CustomWeld(*m_xBuilder, "valueset", *xColorSet))
186 {
187  SetText(SvxResId(STR_COLORTABLE));
188  SetQuickHelpText(SvxResId(RID_SVXSTR_COLORBAR));
189  SetSizePixel(LogicToPixel(Size(150, 22), MapMode(MapUnit::MapAppFont)));
190  SetHelpId(HID_CTRL_COLOR);
191 
192  xColorSet->SetSelectHdl( LINK( this, SvxColorDockingWindow, SelectHdl ) );
193  xColorSet->SetHelpId(HID_COLOR_CTL_COLORS);
194 
195  // Get the model from the view shell. Using SfxObjectShell::Current()
196  // is unreliable when called at the wrong times.
197  SfxObjectShell* pDocSh = nullptr;
198  if (_pBindings != nullptr)
199  {
200  SfxDispatcher* pDispatcher = _pBindings->GetDispatcher();
201  if (pDispatcher != nullptr)
202  {
203  SfxViewFrame* pFrame = pDispatcher->GetFrame();
204  if (pFrame != nullptr)
205  {
206  SfxViewShell* pViewShell = pFrame->GetViewShell();
207  if (pViewShell != nullptr)
208  pDocSh = pViewShell->GetObjectShell();
209  }
210  }
211  }
212 
213  if ( pDocSh )
214  {
215  const SfxPoolItem* pItem = pDocSh->GetItem( SID_COLOR_TABLE );
216  if( pItem )
217  {
218  pColorList = static_cast<const SvxColorListItem*>(pItem)->GetColorList();
219  FillValueSet();
220  }
221  }
222 
224  aItemSize.setWidth( aItemSize.Width() + SvxColorValueSet::getEntryEdgeLength() );
225  aItemSize.setWidth( aItemSize.Width() / 2 );
226  aItemSize.setHeight( aItemSize.Height() + SvxColorValueSet::getEntryEdgeLength() );
227  aItemSize.setHeight( aItemSize.Height() / 2 );
228 
229  if (_pBindings != nullptr)
230  StartListening(*_pBindings, DuplicateHandling::Prevent);
231 }
232 
234 {
235  disposeOnce();
236 }
237 
239 {
241  xColorSetWin.reset();
242  xColorSet.reset();
244 }
245 
247 {
248  const SfxPoolItemHint* pPoolItemHint = dynamic_cast<const SfxPoolItemHint*>(&rHint);
249  if ( pPoolItemHint )
250  if (auto pColorListItem = dynamic_cast<const SvxColorListItem*>(pPoolItemHint->GetObject()))
251  {
252  // The list of colors has changed
253  pColorList = pColorListItem->GetColorList();
254  FillValueSet();
255  }
256 }
257 
259 {
260  if( !pColorList.is() )
261  return;
262 
263  xColorSet->Clear();
264 
265  xColorSet->addEntriesForXColorList(*pColorList, 2);
266 
267  // create the last entry for 'invisible/none'
269  tools::Long nPtX = aColorSize.Width() - 1;
270  tools::Long nPtY = aColorSize.Height() - 1;
272 
273  pVD->SetOutputSizePixel( aColorSize );
274  pVD->SetLineColor( COL_BLACK );
275  pVD->SetBackground( Wallpaper( COL_WHITE ) );
276  pVD->DrawLine( Point(), Point( nPtX, nPtY ) );
277  pVD->DrawLine( Point( 0, nPtY ), Point( nPtX, 0 ) );
278 
279  BitmapEx aBmp( pVD->GetBitmapEx( Point(), aColorSize ) );
280 
281  xColorSet->InsertItem( sal_uInt16(1), Image(aBmp), SvxResId( RID_SVXSTR_INVISIBLE ) );
282 }
283 
285 {
286  SfxBoolItem aItem( SID_COLOR_CONTROL, false );
287  GetBindings().GetDispatcher()->ExecuteList(SID_COLOR_CONTROL,
288  SfxCallMode::ASYNCHRON | SfxCallMode::RECORD, { &aItem });
290  return true;
291 }
292 
294 {
295  SfxDispatcher* pDispatcher = GetBindings().GetDispatcher();
296  sal_uInt16 nPos = xColorSet->GetSelectedItemId();
297  Color aColor( xColorSet->GetItemColor( nPos ) );
298  OUString aStr( xColorSet->GetItemText( nPos ) );
299 
300  if (xColorSet->IsLeftButton())
301  {
302  if ( gnLeftSlot == SID_ATTR_FILL_COLOR )
303  {
304  if ( nPos == 1 ) // invisible
305  {
306  XFillStyleItem aXFillStyleItem( drawing::FillStyle_NONE );
307  pDispatcher->ExecuteList(gnLeftSlot, SfxCallMode::RECORD,
308  { &aXFillStyleItem });
309  }
310  else
311  {
312  bool bDone = false;
313 
314  // If we have a DrawView and we are in TextEdit mode, then
315  // not the area color but the text color is assigned
316  SfxViewShell* pViewSh = SfxViewShell::Current();
317  if ( pViewSh )
318  {
319  SdrView* pView = pViewSh->GetDrawView();
320  if ( pView && pView->IsTextEdit() )
321  {
322  SvxColorItem aTextColorItem( aColor, SID_ATTR_CHAR_COLOR );
323  pDispatcher->ExecuteList(SID_ATTR_CHAR_COLOR,
324  SfxCallMode::RECORD, { &aTextColorItem });
325  bDone = true;
326  }
327  }
328  if ( !bDone )
329  {
330  XFillStyleItem aXFillStyleItem( drawing::FillStyle_SOLID );
331  XFillColorItem aXFillColorItem( aStr, aColor );
332  pDispatcher->ExecuteList(gnLeftSlot, SfxCallMode::RECORD,
333  { &aXFillColorItem, &aXFillStyleItem });
334  }
335  }
336  }
337  else if ( nPos != 1 ) // invisible
338  {
339  SvxColorItem aLeftColorItem( aColor, gnLeftSlot );
340  pDispatcher->ExecuteList(gnLeftSlot, SfxCallMode::RECORD,
341  { &aLeftColorItem });
342  }
343  }
344  else
345  {
346  if ( gnRightSlot == SID_ATTR_LINE_COLOR )
347  {
348  if( nPos == 1 ) // invisible
349  {
350  XLineStyleItem aXLineStyleItem( drawing::LineStyle_NONE );
351  pDispatcher->ExecuteList(gnRightSlot, SfxCallMode::RECORD,
352  { &aXLineStyleItem });
353  }
354  else
355  {
356  // If the LineStyle is invisible, it is set to SOLID
357  SfxViewShell* pViewSh = SfxViewShell::Current();
358  if ( pViewSh )
359  {
360  SdrView* pView = pViewSh->GetDrawView();
361  if ( pView )
362  {
363  SfxItemSet aAttrSet( pView->GetModel()->GetItemPool() );
364  pView->GetAttributes( aAttrSet );
365  if ( aAttrSet.GetItemState( XATTR_LINESTYLE ) != SfxItemState::DONTCARE )
366  {
367  drawing::LineStyle eXLS =
368  aAttrSet.Get( XATTR_LINESTYLE ).GetValue();
369  if ( eXLS == drawing::LineStyle_NONE )
370  {
371  XLineStyleItem aXLineStyleItem( drawing::LineStyle_SOLID );
372  pDispatcher->ExecuteList(gnRightSlot,
373  SfxCallMode::RECORD, { &aXLineStyleItem });
374  }
375  }
376  }
377  }
378 
379  XLineColorItem aXLineColorItem( aStr, aColor );
380  pDispatcher->ExecuteList(gnRightSlot, SfxCallMode::RECORD,
381  { &aXLineColorItem });
382  }
383  }
384  else if ( nPos != 1 ) // invisible
385  {
386  SvxColorItem aRightColorItem( aColor, gnRightSlot );
387  pDispatcher->ExecuteList(gnRightSlot, SfxCallMode::RECORD,
388  { &aRightColorItem });
389  }
390  }
391 }
392 
394 {
395  SfxDockingWindow::GetFocus();
396  if (xColorSet)
397  {
398  // Grab the focus to the color value set so that it can be controlled
399  // with the keyboard.
400  xColorSet->GrabFocus();
401  }
402 }
403 
405 {
406  bool bRet = false;
407  if( rNEvt.GetType() == MouseNotifyEvent::KEYINPUT )
408  {
409  KeyEvent aKeyEvt = *rNEvt.GetKeyEvent();
410  sal_uInt16 nKeyCode = aKeyEvt.GetKeyCode().GetCode();
411  switch( nKeyCode )
412  {
413  case KEY_ESCAPE:
414  GrabFocusToDocument();
415  bRet = true;
416  break;
417  }
418  }
419 
420  return bRet || SfxDockingWindow::EventNotify(rNEvt);
421 }
422 
423 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const SfxPoolItem * ExecuteList(sal_uInt16 nSlot, SfxCallMode nCall, std::initializer_list< SfxPoolItem const * > args, std::initializer_list< SfxPoolItem const * > internalargs=std::initializer_list< SfxPoolItem const * >())
virtual void SetDrawingArea(weld::DrawingArea *pDrawingArea) override
virtual bool Close() override
Definition: colrctrl.cxx:284
IMPL_LINK_NOARG(SvxColorDockingWindow, SelectHdl, ValueSet *, void)
Definition: colrctrl.cxx:293
void setWidth(tools::Long nWidth)
#define DND_ACTION_COPY
virtual bool MouseButtonUp(const MouseEvent &rMEvt) override
MouseEventModifiers GetMode() const
long Long
sal_uInt16 GetCode() const
constexpr TypedWhichId< XLineStyleItem > XATTR_LINESTYLE(XATTR_LINE_FIRST)
const KeyEvent * GetKeyEvent() const
virtual void GetFocus() override
This function is called when the window gets the focus.
Definition: colrctrl.cxx:393
std::unique_ptr< SvxColorValueSet_docking > xColorSet
Definition: colrctrl.hxx:75
sal_uInt16 GetSelectedItemId() const
static sal_uInt32 getEntryEdgeLength()
virtual ~SvxColorDockingWindow() override
Definition: colrctrl.cxx:233
virtual void AddSupportedFormats() override
Definition: colrctrl.cxx:71
#define HID_COLOR_CTL_COLORS
Definition: helpids.h:23
virtual bool EventNotify(NotifyEvent &rNEvt) override
Definition: colrctrl.cxx:404
Value
constexpr tools::Long Width() const
uno::Sequence< beans::NamedValue > m_Data
Definition: colrctrl.cxx:54
sal_uInt16 GetClicks() const
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
Definition: colrctrl.cxx:246
#define WB_ITEMBORDER
OUString SvxResId(TranslateId aId)
Definition: dialmgr.cxx:24
static SfxViewShell * Current()
SvxColorValueSet_docking(std::unique_ptr< weld::ScrolledWindow > pWindow)
Definition: colrctrl.cxx:100
virtual bool StartDrag() override
Definition: colrctrl.cxx:155
virtual bool Close() override
constexpr sal_uInt16 gnRightSlot
Definition: colrctrl.cxx:179
#define MOUSE_LEFT
virtual bool EventNotify(NotifyEvent &rNEvt) override
const SfxPoolItem * GetItem(sal_uInt16 nSlotId) const
virtual void dispose() override
Definition: colrctrl.cxx:238
virtual bool MouseButtonDown(const MouseEvent &rMEvt) override
SvxColorDockingWindow(SfxBindings *pBindings, SfxChildWindow *pCW, vcl::Window *pParent)
Definition: colrctrl.cxx:181
SfxPoolItem * GetObject() const
constexpr sal_uInt16 gnLeftSlot
Definition: colrctrl.cxx:178
XColorListRef pColorList
Definition: colrctrl.hxx:74
virtual bool QueryValue(css::uno::Any &rVal, sal_uInt8 nMemberId=0) const override
Definition: xattr.cxx:1895
dictionary props
OUString GetItemText(sal_uInt16 nItemId) const
MouseNotifyEvent GetType() const
virtual bool GetData(const css::datatransfer::DataFlavor &rFlavor, const OUString &rDestDoc) override
Definition: colrctrl.cxx:76
void StartListening(SfxBroadcaster &rBroadcaster, DuplicateHandling eDuplicateHanding=DuplicateHandling::Unexpected)
sal_uInt16 GetModifier() const
virtual bool MouseButtonDown(const MouseEvent &rMEvt) override
Definition: colrctrl.cxx:106
#define HID_CTRL_COLOR
Definition: helpids.h:27
SfxViewShell * GetViewShell() const
exports com.sun.star. style
virtual bool QueryValue(css::uno::Any &rVal, sal_uInt8 nMemberId=0) const override
Definition: xattr.cxx:1791
virtual bool MouseButtonUp(const MouseEvent &rMEvt) override
Definition: colrctrl.cxx:130
const vcl::KeyCode & GetKeyCode() const
static SotClipboardFormatId GetFormat(const css::datatransfer::DataFlavor &rFlavor)
virtual bool IsTextEdit() const final override
Definition: svdedxv.cxx:1687
Any makeAny(Color const &value)
constexpr tools::Long Height() const
void SetNoSelection()
constexpr sal_uInt16 KEY_ESCAPE
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_WHITE
std::unique_ptr< weld::CustomWeld > xColorSetWin
Definition: colrctrl.hxx:76
void GetAttributes(SfxItemSet &rTargetSet, bool bOnlyHardAttr=false) const
Definition: svdview.cxx:249
bool IsLeft() const
SfxViewFrame * GetFrame() const
void EndListening(SfxBroadcaster &rBroadcaster, bool bRemoveAllDuplicates=false)
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_BLACK
SfxBindings & GetBindings() const
const Point & GetPosPixel() const
virtual SdrView * GetDrawView() const
void SetData(const uno::Sequence< beans::NamedValue > &rData)
Definition: colrctrl.cxx:64
void setHeight(tools::Long nHeight)
virtual SfxObjectShell * GetObjectShell() override
SfxDispatcher * GetDispatcher() const
const SfxItemPool & GetItemPool() const
Definition: svdmodel.hxx:311
virtual void SetDrawingArea(weld::DrawingArea *pDrawingArea) override
Definition: colrctrl.cxx:89
virtual void dispose() override
SdrModel * GetModel() const
Definition: svdpntv.hxx:260
aStr
Color GetItemColor(sal_uInt16 nItemId) const
rtl::Reference< SvxColorValueSetData > m_xHelper
Definition: colrctrl.hxx:47
sal_uInt16 nPos