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