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 <comphelper/propertyvalue.hxx>
25 #include <vcl/event.hxx>
26 #include <vcl/status.hxx>
27 #include <vcl/svapp.hxx>
28 #include <vcl/weldutils.hxx>
29 #include <svl/intitem.hxx>
30 #include <tools/urlobj.hxx>
32 #include <svx/selctrl.hxx>
34 #include <bitmaps.hlst>
36 #include <com/sun/star/beans/PropertyValue.hpp>
37 #include <com/sun/star/frame/XFrame.hpp>
38 #include <com/sun/star/lang/XServiceInfo.hpp>
40 #include <svx/strings.hrc>
41 #include <svx/dialmgr.hxx>
43 SFX_IMPL_STATUSBAR_CONTROL(SvxSelectionModeControl
, SfxUInt16Item
);
47 /// Popup menu to select the selection type
48 class SelectionTypePopup
50 weld::Window
* m_pPopupParent
;
51 std::unique_ptr
<weld::Builder
> m_xBuilder
;
52 std::unique_ptr
<weld::Menu
> m_xMenu
;
53 static OUString
state_to_id(sal_uInt16 nState
);
55 SelectionTypePopup(weld::Window
* pPopupParent
, sal_uInt16 nCurrent
);
56 OUString
GetItemTextForState(sal_uInt16 nState
) { return m_xMenu
->get_label(state_to_id(nState
)); }
57 OUString
popup_at_rect(const tools::Rectangle
& rRect
)
59 return m_xMenu
->popup_at_rect(m_pPopupParent
, rRect
);
61 void HideSelectionType(const OUString
& rIdent
)
63 m_xMenu
->remove(rIdent
);
65 static sal_uInt16
id_to_state(std::u16string_view ident
);
70 sal_uInt16
SelectionTypePopup::id_to_state(std::u16string_view ident
)
72 if (ident
== u
"block")
74 else if (ident
== u
"adding")
76 else if (ident
== u
"extending")
82 OUString
SelectionTypePopup::state_to_id(sal_uInt16 nState
)
86 default: // fall through
87 case 0: return "standard";
88 case 1: return "extending";
89 case 2: return "adding";
90 case 3: return "block";
94 SelectionTypePopup::SelectionTypePopup(weld::Window
* pPopupParent
, sal_uInt16 nCurrent
)
95 : m_pPopupParent(pPopupParent
)
96 , m_xBuilder(Application::CreateBuilder(m_pPopupParent
, "svx/ui/selectionmenu.ui"))
97 , m_xMenu(m_xBuilder
->weld_menu("menu"))
99 m_xMenu
->set_active(state_to_id(nCurrent
), true);
102 SvxSelectionModeControl::SvxSelectionModeControl( sal_uInt16 _nSlotId
,
105 SfxStatusBarControl( _nSlotId
, _nId
, rStb
),
107 maImages
{Image(StockImage::Yes
, RID_SVXBMP_STANDARD_SELECTION
),
108 Image(StockImage::Yes
, RID_SVXBMP_EXTENDING_SELECTION
),
109 Image(StockImage::Yes
, RID_SVXBMP_ADDING_SELECTION
),
110 Image(StockImage::Yes
, RID_SVXBMP_BLOCK_SELECTION
)},
111 mbFeatureEnabled(false)
113 GetStatusBar().SetQuickHelpText(GetId(), u
"");
116 void SvxSelectionModeControl::StateChangedAtStatusBarControl( sal_uInt16
, SfxItemState eState
,
117 const SfxPoolItem
* pState
)
119 mbFeatureEnabled
= SfxItemState::DEFAULT
== eState
;
120 if (mbFeatureEnabled
)
122 DBG_ASSERT( dynamic_cast< const SfxUInt16Item
* >(pState
) != nullptr, "invalid item type" );
123 const SfxUInt16Item
* pItem
= static_cast<const SfxUInt16Item
*>(pState
);
124 mnState
= pItem
->GetValue();
125 SelectionTypePopup
aPop(GetStatusBar().GetFrameWeld(), mnState
);
126 GetStatusBar().SetQuickHelpText(GetId(),
127 SvxResId(RID_SVXSTR_SELECTIONMODE_HELPTEXT
).
128 replaceFirst("%1", aPop
.GetItemTextForState(mnState
)));
129 GetStatusBar().Invalidate();
133 bool SvxSelectionModeControl::MouseButtonDown( const MouseEvent
& rEvt
)
135 if (!mbFeatureEnabled
)
138 ::tools::Rectangle
aRect(rEvt
.GetPosPixel(), Size(1, 1));
139 weld::Window
* pPopupParent
= weld::GetPopupParent(GetStatusBar(), aRect
);
140 SelectionTypePopup
aPop(pPopupParent
, mnState
);
142 // Check if Calc is opened; if true, hide block selection mode tdf#122280
143 const css::uno::Reference
< css::frame::XModel
> xModel
= m_xFrame
->getController()->getModel();
144 css::uno::Reference
< css::lang::XServiceInfo
> xServices( xModel
, css::uno::UNO_QUERY
);
145 if ( xServices
.is() )
147 bool bSpecModeCalc
= xServices
->supportsService("com.sun.star.sheet.SpreadsheetDocument");
149 aPop
.HideSelectionType("block");
152 OUString sIdent
= aPop
.popup_at_rect(aRect
);
153 if (!sIdent
.isEmpty())
155 sal_uInt16 nNewState
= SelectionTypePopup::id_to_state(sIdent
);
156 if ( nNewState
!= mnState
)
161 SfxUInt16Item
aState( GetSlotId(), mnState
);
162 aState
.QueryValue( a
);
163 INetURLObject
aObj( m_aCommandURL
);
165 css::uno::Sequence
< css::beans::PropertyValue
> aArgs
{ comphelper::makePropertyValue(
166 aObj
.GetURLPath(), a
) };
174 void SvxSelectionModeControl::Click()
178 void SvxSelectionModeControl::Paint( const UserDrawEvent
& rUsrEvt
)
180 const tools::Rectangle aControlRect
= getControlRect();
181 vcl::RenderContext
* pDev
= rUsrEvt
.GetRenderContext();
182 tools::Rectangle aRect
= rUsrEvt
.GetRect();
184 Size
aImgSize( maImages
[mnState
].GetSizePixel() );
186 Point
aPos( aRect
.Left() + ( aControlRect
.GetWidth() - aImgSize
.Width() ) / 2,
187 aRect
.Top() + ( aControlRect
.GetHeight() - aImgSize
.Height() ) / 2 );
189 if (mbFeatureEnabled
)
190 pDev
->DrawImage(aPos
, maImages
[mnState
]);
192 pDev
->DrawImage(aPos
, Image());
195 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */