LibreOffice Module svx (master)  1
selctrl.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 <string_view>
23 
24 #include <vcl/event.hxx>
25 #include <vcl/status.hxx>
26 #include <vcl/svapp.hxx>
27 #include <vcl/weldutils.hxx>
28 #include <svl/intitem.hxx>
29 #include <tools/urlobj.hxx>
30 
31 #include <svx/selctrl.hxx>
32 
33 #include <bitmaps.hlst>
34 
35 #include <com/sun/star/beans/PropertyValue.hpp>
36 #include <com/sun/star/frame/XFrame.hpp>
37 #include <com/sun/star/lang/XServiceInfo.hpp>
38 
39 #include <svx/strings.hrc>
40 #include <svx/dialmgr.hxx>
41 
43 
44 namespace {
45 
47 class SelectionTypePopup
48 {
49  weld::Window* m_pPopupParent;
50  std::unique_ptr<weld::Builder> m_xBuilder;
51  std::unique_ptr<weld::Menu> m_xMenu;
52  static OString state_to_id(sal_uInt16 nState);
53 public:
54  SelectionTypePopup(weld::Window* pPopupParent, sal_uInt16 nCurrent);
55  OUString GetItemTextForState(sal_uInt16 nState) { return m_xMenu->get_label(state_to_id(nState)); }
56  OString popup_at_rect(const tools::Rectangle& rRect)
57  {
58  return m_xMenu->popup_at_rect(m_pPopupParent, rRect);
59  }
60  void HideSelectionType(const OString& rIdent)
61  {
62  m_xMenu->remove(rIdent);
63  }
64  static sal_uInt16 id_to_state(std::string_view ident);
65 };
66 
67 }
68 
69 sal_uInt16 SelectionTypePopup::id_to_state(std::string_view ident)
70 {
71  if (ident == "block")
72  return 3;
73  else if (ident == "adding")
74  return 2;
75  else if (ident == "extending")
76  return 1;
77  else // fall through
78  return 0;
79 }
80 
81 OString SelectionTypePopup::state_to_id(sal_uInt16 nState)
82 {
83  switch (nState)
84  {
85  default: // fall through
86  case 0: return "standard";
87  case 1: return "extending";
88  case 2: return "adding";
89  case 3: return "block";
90  }
91 }
92 
93 SelectionTypePopup::SelectionTypePopup(weld::Window* pPopupParent, sal_uInt16 nCurrent)
94  : m_pPopupParent(pPopupParent)
95  , m_xBuilder(Application::CreateBuilder(m_pPopupParent, "svx/ui/selectionmenu.ui"))
96  , m_xMenu(m_xBuilder->weld_menu("menu"))
97 {
98  m_xMenu->set_active(state_to_id(nCurrent), true);
99 }
100 
102  sal_uInt16 _nId,
103  StatusBar& rStb ) :
104  SfxStatusBarControl( _nSlotId, _nId, rStb ),
105  mnState( 0 ),
106  maImages{Image(StockImage::Yes, RID_SVXBMP_STANDARD_SELECTION),
107  Image(StockImage::Yes, RID_SVXBMP_EXTENDING_SELECTION),
108  Image(StockImage::Yes, RID_SVXBMP_ADDING_SELECTION),
109  Image(StockImage::Yes, RID_SVXBMP_BLOCK_SELECTION)},
110  mbFeatureEnabled(false)
111 {
112  GetStatusBar().SetQuickHelpText(GetId(), u"");
113 }
114 
116  const SfxPoolItem* pState )
117 {
118  mbFeatureEnabled = SfxItemState::DEFAULT == eState;
119  if (mbFeatureEnabled)
120  {
121  DBG_ASSERT( dynamic_cast< const SfxUInt16Item* >(pState) != nullptr, "invalid item type" );
122  const SfxUInt16Item* pItem = static_cast<const SfxUInt16Item*>(pState);
123  mnState = pItem->GetValue();
124  SelectionTypePopup aPop(GetStatusBar().GetFrameWeld(), mnState);
126  SvxResId(RID_SVXSTR_SELECTIONMODE_HELPTEXT).
127  replaceFirst("%1", aPop.GetItemTextForState(mnState)));
129  }
130 }
131 
133 {
134  if (!mbFeatureEnabled)
135  return true;
136 
137  ::tools::Rectangle aRect(rEvt.GetPosPixel(), Size(1, 1));
138  weld::Window* pPopupParent = weld::GetPopupParent(GetStatusBar(), aRect);
139  SelectionTypePopup aPop(pPopupParent, mnState);
140 
141  // Check if Calc is opened; if true, hide block selection mode tdf#122280
142  const css::uno::Reference < css::frame::XModel > xModel = m_xFrame->getController()->getModel();
143  css::uno::Reference< css::lang::XServiceInfo > xServices( xModel, css::uno::UNO_QUERY );
144  if ( xServices.is() )
145  {
146  bool bSpecModeCalc = xServices->supportsService("com.sun.star.sheet.SpreadsheetDocument");
147  if (bSpecModeCalc)
148  aPop.HideSelectionType("block");
149  }
150 
151  OString sIdent = aPop.popup_at_rect(aRect);
152  if (!sIdent.isEmpty())
153  {
154  sal_uInt16 nNewState = SelectionTypePopup::id_to_state(sIdent);
155  if ( nNewState != mnState )
156  {
157  mnState = nNewState;
158 
159  css::uno::Any a;
160  SfxUInt16Item aState( GetSlotId(), mnState );
161  INetURLObject aObj( m_aCommandURL );
162 
163  css::uno::Sequence< css::beans::PropertyValue > aArgs( 1 );
164  aArgs[0].Name = aObj.GetURLPath();
165  aState.QueryValue( a );
166  aArgs[0].Value = a;
167 
168  execute( aArgs );
169  }
170  }
171 
172  return true;
173 }
174 
176 {
177 }
178 
180 {
181  const tools::Rectangle aControlRect = getControlRect();
182  vcl::RenderContext* pDev = rUsrEvt.GetRenderContext();
183  tools::Rectangle aRect = rUsrEvt.GetRect();
184 
185  Size aImgSize( maImages[mnState].GetSizePixel() );
186 
187  Point aPos( aRect.Left() + ( aControlRect.GetWidth() - aImgSize.Width() ) / 2,
188  aRect.Top() + ( aControlRect.GetHeight() - aImgSize.Height() ) / 2 );
189 
190  if (mbFeatureEnabled)
191  pDev->DrawImage(aPos, maImages[mnState]);
192  else
193  pDev->DrawImage(aPos, Image());
194 }
195 
196 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sal_uInt16 GetSlotId() const
void DrawImage(const Point &rPos, const Image &rImage, DrawImageFlags nStyle=DrawImageFlags::NONE)
const tools::Rectangle & GetRect() const
OUString GetURLPath(DecodeMechanism eMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
SFX_IMPL_STATUSBAR_CONTROL(SvxSelectionModeControl, SfxUInt16Item)
Status bar control that indicates or changes the selection mode (standard / block / etc...
Definition: selctrl.hxx:27
css::uno::Reference< css::lang::XComponent > m_xFrame
sal_uInt16 GetValue() const
constexpr tools::Long Width() const
tools::Long Left() const
constexpr tools::Long GetWidth() const
virtual bool MouseButtonDown(const MouseEvent &rEvt) override
Definition: selctrl.cxx:132
SvxSelectionModeControl(sal_uInt16 nSlotId, sal_uInt16 nId, StatusBar &rStb)
Definition: selctrl.cxx:101
sal_uInt16 GetId() const
OUString SvxResId(std::string_view aId)
Definition: dialmgr.cxx:25
vcl::RenderContext * GetRenderContext() const
#define DBG_ASSERT(sCon, aError)
uno_Any a
weld::Window * GetPopupParent(vcl::Window &rOutWin, tools::Rectangle &rRect)
virtual void Invalidate(InvalidateFlags nFlags=InvalidateFlags::NONE)
tools::Long Top() const
virtual void Click() override
Definition: selctrl.cxx:175
void SetQuickHelpText(sal_uInt16 nItemId, const OUString &rText)
SfxItemState
constexpr tools::Long Height() const
StatusBar & GetStatusBar() const
virtual void StateChangedAtStatusBarControl(sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem *pState) override
Definition: selctrl.cxx:115
const Point & GetPosPixel() const
Reference< XModel > xModel
virtual bool QueryValue(css::uno::Any &rVal, sal_uInt8 nMemberId=0) const override
weld::Window * GetFrameWeld(const SfxFrame *pFrame)
constexpr tools::Long GetHeight() const
virtual void Paint(const UserDrawEvent &rEvt) override
Definition: selctrl.cxx:179