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.get());
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  , pColorList()
185  , xColorSet(new SvxColorValueSet_docking(m_xBuilder->weld_scrolled_window("valuesetwin", true)))
186  , xColorSetWin(new weld::CustomWeld(*m_xBuilder, "valueset", *xColorSet))
187 {
188  SetText(SvxResId(STR_COLORTABLE));
189  SetQuickHelpText(SvxResId(RID_SVXSTR_COLORBAR));
190  SetSizePixel(LogicToPixel(Size(150, 22), MapMode(MapUnit::MapAppFont)));
191  SetHelpId(HID_CTRL_COLOR);
192 
193  xColorSet->SetSelectHdl( LINK( this, SvxColorDockingWindow, SelectHdl ) );
194  xColorSet->SetHelpId(HID_COLOR_CTL_COLORS);
195 
196  // Get the model from the view shell. Using SfxObjectShell::Current()
197  // is unreliable when called at the wrong times.
198  SfxObjectShell* pDocSh = nullptr;
199  if (_pBindings != nullptr)
200  {
201  SfxDispatcher* pDispatcher = _pBindings->GetDispatcher();
202  if (pDispatcher != nullptr)
203  {
204  SfxViewFrame* pFrame = pDispatcher->GetFrame();
205  if (pFrame != nullptr)
206  {
207  SfxViewShell* pViewShell = pFrame->GetViewShell();
208  if (pViewShell != nullptr)
209  pDocSh = pViewShell->GetObjectShell();
210  }
211  }
212  }
213 
214  if ( pDocSh )
215  {
216  const SfxPoolItem* pItem = pDocSh->GetItem( SID_COLOR_TABLE );
217  if( pItem )
218  {
219  pColorList = static_cast<const SvxColorListItem*>(pItem)->GetColorList();
220  FillValueSet();
221  }
222  }
223 
225  aItemSize.setWidth( aItemSize.Width() + SvxColorValueSet::getEntryEdgeLength() );
226  aItemSize.setWidth( aItemSize.Width() / 2 );
227  aItemSize.setHeight( aItemSize.Height() + SvxColorValueSet::getEntryEdgeLength() );
228  aItemSize.setHeight( aItemSize.Height() / 2 );
229 
230  fprintf(stderr, "size is %" SAL_PRIdINT64 " %" SAL_PRIdINT64 "\n", sal_Int64(aItemSize.Width()), sal_Int64(aItemSize.Height()));
231 
232  if (_pBindings != nullptr)
233  StartListening(*_pBindings, DuplicateHandling::Prevent);
234 }
235 
237 {
238  disposeOnce();
239 }
240 
242 {
244  xColorSetWin.reset();
245  xColorSet.reset();
247 }
248 
250 {
251  const SfxPoolItemHint* pPoolItemHint = dynamic_cast<const SfxPoolItemHint*>(&rHint);
252  if ( pPoolItemHint )
253  if (auto pColorListItem = dynamic_cast<const SvxColorListItem*>(pPoolItemHint->GetObject()))
254  {
255  // The list of colors has changed
256  pColorList = pColorListItem->GetColorList();
257  FillValueSet();
258  }
259 }
260 
262 {
263  if( !pColorList.is() )
264  return;
265 
266  xColorSet->Clear();
267 
268  xColorSet->addEntriesForXColorList(*pColorList, 2);
269 
270  // create the last entry for 'invisible/none'
272  tools::Long nPtX = aColorSize.Width() - 1;
273  tools::Long nPtY = aColorSize.Height() - 1;
275 
276  pVD->SetOutputSizePixel( aColorSize );
277  pVD->SetLineColor( COL_BLACK );
278  pVD->SetBackground( Wallpaper( COL_WHITE ) );
279  pVD->DrawLine( Point(), Point( nPtX, nPtY ) );
280  pVD->DrawLine( Point( 0, nPtY ), Point( nPtX, 0 ) );
281 
282  BitmapEx aBmp( pVD->GetBitmapEx( Point(), aColorSize ) );
283 
284  xColorSet->InsertItem( sal_uInt16(1), Image(aBmp), SvxResId( RID_SVXSTR_INVISIBLE ) );
285 }
286 
288 {
289  SfxBoolItem aItem( SID_COLOR_CONTROL, false );
290  GetBindings().GetDispatcher()->ExecuteList(SID_COLOR_CONTROL,
291  SfxCallMode::ASYNCHRON | SfxCallMode::RECORD, { &aItem });
293  return true;
294 }
295 
297 {
298  SfxDispatcher* pDispatcher = GetBindings().GetDispatcher();
299  sal_uInt16 nPos = xColorSet->GetSelectedItemId();
300  Color aColor( xColorSet->GetItemColor( nPos ) );
301  OUString aStr( xColorSet->GetItemText( nPos ) );
302 
303  if (xColorSet->IsLeftButton())
304  {
305  if ( gnLeftSlot == SID_ATTR_FILL_COLOR )
306  {
307  if ( nPos == 1 ) // invisible
308  {
309  XFillStyleItem aXFillStyleItem( drawing::FillStyle_NONE );
310  pDispatcher->ExecuteList(gnLeftSlot, SfxCallMode::RECORD,
311  { &aXFillStyleItem });
312  }
313  else
314  {
315  bool bDone = false;
316 
317  // If we have a DrawView and we are in TextEdit mode, then
318  // not the area color but the text color is assigned
319  SfxViewShell* pViewSh = SfxViewShell::Current();
320  if ( pViewSh )
321  {
322  SdrView* pView = pViewSh->GetDrawView();
323  if ( pView && pView->IsTextEdit() )
324  {
325  SvxColorItem aTextColorItem( aColor, SID_ATTR_CHAR_COLOR );
326  pDispatcher->ExecuteList(SID_ATTR_CHAR_COLOR,
327  SfxCallMode::RECORD, { &aTextColorItem });
328  bDone = true;
329  }
330  }
331  if ( !bDone )
332  {
333  XFillStyleItem aXFillStyleItem( drawing::FillStyle_SOLID );
334  XFillColorItem aXFillColorItem( aStr, aColor );
335  pDispatcher->ExecuteList(gnLeftSlot, SfxCallMode::RECORD,
336  { &aXFillColorItem, &aXFillStyleItem });
337  }
338  }
339  }
340  else if ( nPos != 1 ) // invisible
341  {
342  SvxColorItem aLeftColorItem( aColor, gnLeftSlot );
343  pDispatcher->ExecuteList(gnLeftSlot, SfxCallMode::RECORD,
344  { &aLeftColorItem });
345  }
346  }
347  else
348  {
349  if ( gnRightSlot == SID_ATTR_LINE_COLOR )
350  {
351  if( nPos == 1 ) // invisible
352  {
353  XLineStyleItem aXLineStyleItem( drawing::LineStyle_NONE );
354  pDispatcher->ExecuteList(gnRightSlot, SfxCallMode::RECORD,
355  { &aXLineStyleItem });
356  }
357  else
358  {
359  // If the LineStyle is invisible, it is set to SOLID
360  SfxViewShell* pViewSh = SfxViewShell::Current();
361  if ( pViewSh )
362  {
363  SdrView* pView = pViewSh->GetDrawView();
364  if ( pView )
365  {
366  SfxItemSet aAttrSet( pView->GetModel()->GetItemPool() );
367  pView->GetAttributes( aAttrSet );
368  if ( aAttrSet.GetItemState( XATTR_LINESTYLE ) != SfxItemState::DONTCARE )
369  {
370  drawing::LineStyle eXLS =
371  aAttrSet.Get( XATTR_LINESTYLE ).GetValue();
372  if ( eXLS == drawing::LineStyle_NONE )
373  {
374  XLineStyleItem aXLineStyleItem( drawing::LineStyle_SOLID );
375  pDispatcher->ExecuteList(gnRightSlot,
376  SfxCallMode::RECORD, { &aXLineStyleItem });
377  }
378  }
379  }
380  }
381 
382  XLineColorItem aXLineColorItem( aStr, aColor );
383  pDispatcher->ExecuteList(gnRightSlot, SfxCallMode::RECORD,
384  { &aXLineColorItem });
385  }
386  }
387  else if ( nPos != 1 ) // invisible
388  {
389  SvxColorItem aRightColorItem( aColor, gnRightSlot );
390  pDispatcher->ExecuteList(gnRightSlot, SfxCallMode::RECORD,
391  { &aRightColorItem });
392  }
393  }
394 }
395 
397 {
398  SfxDockingWindow::GetFocus();
399  if (xColorSet)
400  {
401  // Grab the focus to the color value set so that it can be controlled
402  // with the keyboard.
403  xColorSet->GrabFocus();
404  }
405 }
406 
408 {
409  bool bRet = false;
410  if( rNEvt.GetType() == MouseNotifyEvent::KEYINPUT )
411  {
412  KeyEvent aKeyEvt = *rNEvt.GetKeyEvent();
413  sal_uInt16 nKeyCode = aKeyEvt.GetKeyCode().GetCode();
414  switch( nKeyCode )
415  {
416  case KEY_ESCAPE:
417  GrabFocusToDocument();
418  bRet = true;
419  break;
420  }
421  }
422 
423  return bRet || SfxDockingWindow::EventNotify(rNEvt);
424 }
425 
426 /* 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:287
IMPL_LINK_NOARG(SvxColorDockingWindow, SelectHdl, ValueSet *, void)
Definition: colrctrl.cxx:296
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:396
std::unique_ptr< SvxColorValueSet_docking > xColorSet
Definition: colrctrl.hxx:75
sal_uInt16 GetSelectedItemId() const
static sal_uInt32 getEntryEdgeLength()
virtual ~SvxColorDockingWindow() override
Definition: colrctrl.cxx:236
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:407
Value
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:249
OUString SvxResId(const char *pId)
Definition: dialmgr.cxx:25
#define WB_ITEMBORDER
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:241
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
tools::Long Width() const
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:1663
Any makeAny(Color const &value)
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:245
bool IsLeft() const
SfxViewFrame * GetFrame() const
void EndListening(SfxBroadcaster &rBroadcaster, bool bRemoveAllDuplicates=false)
tools::Long Height() const
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:314
virtual void SetDrawingArea(weld::DrawingArea *pDrawingArea) override
Definition: colrctrl.cxx:89
virtual void dispose() override
SdrModel * GetModel() const
Definition: svdpntv.hxx:264
aStr
Color GetItemColor(sal_uInt16 nItemId) const
rtl::Reference< SvxColorValueSetData > m_xHelper
Definition: colrctrl.hxx:47
sal_uInt16 nPos