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 <string_view>
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>
31 #include <svx/selctrl.hxx>
33 #include <bitmaps.hlst>
35 #include <com/sun/star/beans/PropertyValue.hpp>
36 #include <com/sun/star/frame/XFrame.hpp>
37 #include <com/sun/star/lang/XServiceInfo.hpp>
39 #include <svx/strings.hrc>
40 #include <svx/dialmgr.hxx>
42 SFX_IMPL_STATUSBAR_CONTROL(SvxSelectionModeControl
, SfxUInt16Item
);
46 /// Popup menu to select the selection type
47 class SelectionTypePopup
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
);
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
)
58 return m_xMenu
->popup_at_rect(m_pPopupParent
, rRect
);
60 void HideSelectionType(const OString
& rIdent
)
62 m_xMenu
->remove(rIdent
);
64 static sal_uInt16
id_to_state(std::string_view ident
);
69 sal_uInt16
SelectionTypePopup::id_to_state(std::string_view ident
)
73 else if (ident
== "adding")
75 else if (ident
== "extending")
81 OString
SelectionTypePopup::state_to_id(sal_uInt16 nState
)
85 default: // fall through
86 case 0: return "standard";
87 case 1: return "extending";
88 case 2: return "adding";
89 case 3: return "block";
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"))
98 m_xMenu
->set_active(state_to_id(nCurrent
), true);
101 SvxSelectionModeControl::SvxSelectionModeControl( sal_uInt16 _nSlotId
,
104 SfxStatusBarControl( _nSlotId
, _nId
, rStb
),
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)
112 GetStatusBar().SetQuickHelpText(GetId(), u
"");
115 void SvxSelectionModeControl::StateChanged( sal_uInt16
, SfxItemState eState
,
116 const SfxPoolItem
* pState
)
118 mbFeatureEnabled
= SfxItemState::DEFAULT
== eState
;
119 if (mbFeatureEnabled
)
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
);
125 GetStatusBar().SetQuickHelpText(GetId(),
126 SvxResId(RID_SVXSTR_SELECTIONMODE_HELPTEXT
).
127 replaceFirst("%1", aPop
.GetItemTextForState(mnState
)));
128 GetStatusBar().Invalidate();
132 bool SvxSelectionModeControl::MouseButtonDown( const MouseEvent
& rEvt
)
134 if (!mbFeatureEnabled
)
137 ::tools::Rectangle
aRect(rEvt
.GetPosPixel(), Size(1, 1));
138 weld::Window
* pPopupParent
= weld::GetPopupParent(GetStatusBar(), aRect
);
139 SelectionTypePopup
aPop(pPopupParent
, mnState
);
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() )
146 bool bSpecModeCalc
= xServices
->supportsService("com.sun.star.sheet.SpreadsheetDocument");
148 aPop
.HideSelectionType("block");
151 OString sIdent
= aPop
.popup_at_rect(aRect
);
152 if (!sIdent
.isEmpty())
154 sal_uInt16 nNewState
= SelectionTypePopup::id_to_state(sIdent
);
155 if ( nNewState
!= mnState
)
160 SfxUInt16Item
aState( GetSlotId(), mnState
);
161 INetURLObject
aObj( m_aCommandURL
);
163 css::uno::Sequence
< css::beans::PropertyValue
> aArgs( 1 );
164 aArgs
[0].Name
= aObj
.GetURLPath();
165 aState
.QueryValue( a
);
175 void SvxSelectionModeControl::Click()
179 void SvxSelectionModeControl::Paint( const UserDrawEvent
& rUsrEvt
)
181 const tools::Rectangle aControlRect
= getControlRect();
182 vcl::RenderContext
* pDev
= rUsrEvt
.GetRenderContext();
183 tools::Rectangle aRect
= rUsrEvt
.GetRect();
185 Size
aImgSize( maImages
[mnState
].GetSizePixel() );
187 Point
aPos( aRect
.Left() + ( aControlRect
.GetWidth() - aImgSize
.Width() ) / 2,
188 aRect
.Top() + ( aControlRect
.GetHeight() - aImgSize
.Height() ) / 2 );
190 if (mbFeatureEnabled
)
191 pDev
->DrawImage(aPos
, maImages
[mnState
]);
193 pDev
->DrawImage(aPos
, Image());
196 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */