LibreOffice Module cui (master) 1
macroass.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 <macroass.hxx>
21#include <o3tl/safeint.hxx>
22#include <o3tl/string_view.hxx>
23#include <osl/diagnose.h>
24#include <comphelper/string.hxx>
26#include <svl/macitem.hxx>
27#include <svx/svxids.hrc>
28#include <tools/debug.hxx>
29#include <vcl/idle.hxx>
30#include <cfgutil.hxx>
31#include <sfx2/evntconf.hxx>
32#include <headertablistbox.hxx>
33
34using ::com::sun::star::uno::Reference;
35using ::com::sun::star::frame::XFrame;
36
38{
39public:
41
43 std::unique_ptr<weld::Button> m_xAssignPB;
44 std::unique_ptr<weld::Button> m_xDeletePB;
45 std::unique_ptr<MacroEventListBox> m_xEventLB;
46 std::unique_ptr<weld::Widget> m_xGroupFrame;
47 std::unique_ptr<CuiConfigGroupListBox> m_xGroupLB;
48 std::unique_ptr<weld::Frame> m_xMacroFrame;
49 std::unique_ptr<CuiConfigFunctionListBox> m_xMacroLB;
50
51 Idle m_aFillGroupIdle { "cui SfxMacroTabPage m_aFillGroupIdle" };
53};
54
56 : m_bGotEvents(false)
57{
58}
59
60static sal_uInt16 aPageRg[] = {
61 SID_ATTR_MACROITEM, SID_ATTR_MACROITEM,
62 0
63};
64
65static OUString ConvertToUIName_Impl( SvxMacro const *pMacro )
66{
67 OUString aName( pMacro->GetMacName() );
68 if ( pMacro->GetLanguage() != "JavaScript" )
69 {
70 const sal_Int32 nCount = comphelper::string::getTokenCount(aName, '.');
71 OUString aEntry = aName.getToken( nCount-1, '.' );
72 if ( nCount > 2 )
73 {
74 aEntry += OUString::Concat("(") + o3tl::getToken(aName, 0, '.' ) + "." + o3tl::getToken(aName, nCount-2, '.' ) + ")";
75 }
76 return aEntry;
77 }
78 else
79 return aName;
80}
81
83{
84 // don't do anything as long as the eventbox is empty
85 weld::TreeView& rTreeView = mpImpl->m_xEventLB->GetListBox();
86 int nSelected = rTreeView.get_selected_index();
87 if (nSelected != -1)
88 {
89 // get bound macro
90 const SvxMacro* pM = aTbl.Get(static_cast<SvMacroItemId>(rTreeView.get_selected_id().toInt32()));
91 mpImpl->m_xDeletePB->set_sensitive(nullptr != pM);
92
93 OUString sEventMacro = rTreeView.get_text(nSelected, 1);
94
95 OUString sScriptURI = mpImpl->m_xMacroLB->GetSelectedScriptURI();
96 mpImpl->m_xAssignPB->set_sensitive(!sScriptURI.equalsIgnoreAsciiCase(sEventMacro));
97 }
98 else
99 mpImpl->m_xAssignPB->set_sensitive(false);
100}
101
102SfxMacroTabPage::SfxMacroTabPage(weld::Container* pPage, weld::DialogController* pController, const Reference< XFrame >& rxDocumentFrame, const SfxItemSet& rAttrSet )
103 : SfxTabPage(pPage, pController, "cui/ui/eventassignpage.ui", "EventAssignPage", &rAttrSet)
104{
105 mpImpl.reset(new SfxMacroTabPage_Impl);
106
107 mpImpl->m_aFillGroupIdle.SetInvokeHandler( LINK( this, SfxMacroTabPage, TimeOut_Impl ) );
108 mpImpl->m_aFillGroupIdle.SetPriority( TaskPriority::HIGHEST );
109
110 mpImpl->m_xEventLB.reset(new MacroEventListBox(m_xBuilder->weld_tree_view("assignments")));
111 mpImpl->m_xAssignPB = m_xBuilder->weld_button("assign");
112 mpImpl->m_xDeletePB = m_xBuilder->weld_button("delete");
113 mpImpl->m_xGroupFrame = m_xBuilder->weld_widget("groupframe");
114 mpImpl->m_xGroupLB.reset(new CuiConfigGroupListBox(m_xBuilder->weld_tree_view("libraries")));
115 mpImpl->m_xMacroFrame = m_xBuilder->weld_frame("macroframe");
116 mpImpl->m_aStaticMacroLBLabel = mpImpl->m_xMacroFrame->get_label();
117 mpImpl->m_xMacroLB.reset(new CuiConfigFunctionListBox(m_xBuilder->weld_tree_view("macros")));
118
119 SetFrame( rxDocumentFrame );
120
122
124}
125
127{
128 mpImpl.reset();
129}
130
131void SfxMacroTabPage::AddEvent(const OUString& rEventName, SvMacroItemId nEventId)
132{
133 weld::TreeView& rTreeView = mpImpl->m_xEventLB->GetListBox();
134 rTreeView.append(OUString::number(static_cast<sal_Int32>(nEventId)), rEventName);
135
136 // if the table is valid already
137 SvxMacro* pM = aTbl.Get(nEventId);
138 if (pM)
139 {
140 OUString sNew(ConvertToUIName_Impl(pM));
141 rTreeView.set_text(rTreeView.n_children() - 1, sNew, 1);
142 }
143}
144
146{
147 // get new areas and their functions
148 mpImpl->m_xGroupFrame->show();
149 mpImpl->m_xMacroFrame->show();
150
152}
153
155{
156 SvxMacroItem aItem( GetWhich( aPageRg[0] ) );
157 const_cast<SvxMacroTableDtor&>(aItem.GetMacroTable()) = aTbl;
158
159 const SfxPoolItem* pItem = nullptr;
160 SfxItemState eState = GetItemSet().GetItemState(aItem.Which(), true, &pItem);
161 if (eState == SfxItemState::DEFAULT && aTbl.empty())
162 {
163 // Don't touch the item set if there was no input and our table is empty.
164 return false;
165 }
166 if (SfxItemState::SET != eState || aItem != *static_cast<const SvxMacroItem*>(pItem))
167 {
168 rSet->Put( aItem );
169 return true;
170 }
171 return false;
172}
173
175{
176 if (! mpImpl->m_aFillGroupIdle.IsActive() )
177 mpImpl->m_aFillGroupIdle.Start();
178}
179
181{
183}
184
186{
187 if( mpImpl->m_bGotEvents )
188 return;
189 if( const SfxEventNamesItem* pEventsItem = aSet.GetItemIfSet( SID_EVENTCONFIG ) )
190 {
191 mpImpl->m_bGotEvents = true;
192 const SfxEventNamesList& rList = pEventsItem->GetEvents();
193 for ( size_t nNo = 0, nCnt = rList.size(); nNo < nCnt; ++nNo )
194 {
195 const SfxEventName &rOwn = rList.at(nNo);
196 AddEvent( rOwn.maUIName, rOwn.mnId );
197 }
198 }
199}
200
202{
203 const SfxPoolItem* pItem;
204 if( SfxItemState::SET == rSet->GetItemState( GetWhich( aPageRg[0] ), true, &pItem ))
205 aTbl = static_cast<const SvxMacroItem*>(pItem)->GetMacroTable();
206
207 const SfxEventNamesItem* pEventsItem;
208 if( !mpImpl->m_bGotEvents && (pEventsItem = rSet->GetItemIfSet( SID_EVENTCONFIG ) ) )
209 {
210 mpImpl->m_bGotEvents = true;
211 const SfxEventNamesList& rList = pEventsItem->GetEvents();
212 for ( size_t nNo = 0, nCnt = rList.size(); nNo < nCnt; ++nNo )
213 {
214 const SfxEventName &rOwn = rList.at(nNo);
215 AddEvent( rOwn.maUIName, rOwn.mnId );
216 }
217 }
218
219 FillEvents();
220
221 weld::TreeView& rListBox = mpImpl->m_xEventLB->GetListBox();
222 std::unique_ptr<weld::TreeIter> xIter(rListBox.make_iterator());
223 if (rListBox.get_iter_first(*xIter))
224 {
225 rListBox.set_cursor(*xIter);
227 }
228}
229
231{
232 return false;
233}
234
236{
237 weld::TreeView& rListBox = mpImpl->m_xEventLB->GetListBox();
238 int nSelected = rListBox.get_selected_index();
239 if (nSelected == -1)
240 {
241 DBG_ASSERT(nSelected != -1, "Where does the empty entry come from?");
242 return;
243 }
244
245 ScriptChanged();
246 EnableButtons();
247}
248
250{
251 mpImpl->m_xGroupLB->GroupSelected();
252 const OUString sScriptURI = mpImpl->m_xMacroLB->GetSelectedScriptURI();
253 OUString aLabelText;
254 if( !sScriptURI.isEmpty() )
255 aLabelText = mpImpl->m_aStaticMacroLBLabel;
256 mpImpl->m_xMacroFrame->set_label( aLabelText );
257
258 EnableButtons();
259}
260
262{
263 EnableButtons();
264}
265
266IMPL_LINK(SfxMacroTabPage, AssignDeleteClickHdl_Impl, weld::Button&, rBtn, void)
267{
268 AssignDeleteHdl(&rBtn);
269}
270
271IMPL_LINK(SfxMacroTabPage, AssignDeleteHdl_Impl, weld::TreeView&, rBtn, bool)
272{
273 AssignDeleteHdl(&rBtn);
274 return true;
275}
276
278{
279 weld::TreeView& rListBox = mpImpl->m_xEventLB->GetListBox();
280 int nSelected = rListBox.get_selected_index();
281 if (nSelected == -1)
282 {
283 DBG_ASSERT(nSelected != -1, "Where does the empty entry come from?");
284 return;
285 }
286
287 const bool bAssEnabled = pBtn != mpImpl->m_xDeletePB.get() && mpImpl->m_xAssignPB->get_sensitive();
288
289 // remove from the table
290 SvMacroItemId nEvent = static_cast<SvMacroItemId>(rListBox.get_selected_id().toInt32());
291 aTbl.Erase( nEvent );
292
293 OUString sScriptURI;
294 if( bAssEnabled )
295 {
296 sScriptURI = mpImpl->m_xMacroLB->GetSelectedScriptURI();
297 if( sScriptURI.startsWith( "vnd.sun.star.script:" ) )
298 {
299 aTbl.Insert(
300 nEvent, SvxMacro( sScriptURI, SVX_MACRO_LANGUAGE_SF ) );
301 }
302 else
303 {
304 OSL_ENSURE( false, "SfxMacroTabPage::AssignDeleteHdl_Impl: this branch is *not* dead? (out of interest: tell fs, please!)" );
305 aTbl.Insert(
306 nEvent, SvxMacro( sScriptURI, SVX_MACRO_LANGUAGE_STARBASIC ) );
307 }
308 }
309
310 rListBox.set_text(nSelected, sScriptURI, 1);
311
313}
314
315IMPL_LINK( SfxMacroTabPage, TimeOut_Impl, Timer*,, void )
316{
317 // FillMacroList() can take a long time -> show wait cursor and disable input
318 weld::Window* pDialog = GetFrameWeld();
319 // perhaps the tabpage is part of a SingleTabDialog then pDialog == nullptr
320 std::unique_ptr<weld::WaitObject> xWait(pDialog ? new weld::WaitObject(pDialog) : nullptr);
321 // fill macro list
322 mpImpl->m_xGroupLB->Init(comphelper::getProcessComponentContext(), GetFrame(),
323 OUString(), false);
324}
325
327{
328 weld::TreeView& rListBox = mpImpl->m_xEventLB->GetListBox();
329 Link<weld::TreeView&,bool> aLnk(LINK(this, SfxMacroTabPage, AssignDeleteHdl_Impl));
330 mpImpl->m_xMacroLB->connect_row_activated( aLnk);
331 mpImpl->m_xDeletePB->connect_clicked(LINK(this, SfxMacroTabPage, AssignDeleteClickHdl_Impl));
332 mpImpl->m_xAssignPB->connect_clicked(LINK(this, SfxMacroTabPage, AssignDeleteClickHdl_Impl));
333 rListBox.connect_row_activated(aLnk);
334
335 rListBox.connect_changed(LINK(this, SfxMacroTabPage, SelectEvent_Impl));
336 mpImpl->m_xGroupLB->connect_changed(LINK(this, SfxMacroTabPage, SelectGroup_Impl));
337 mpImpl->m_xMacroLB->connect_changed(LINK(this, SfxMacroTabPage, SelectMacro_Impl));
338
339 std::vector<int> aWidths
340 {
341 o3tl::narrowing<int>(rListBox.get_approximate_digit_width() * 35)
342 };
343 rListBox.set_column_fixed_widths(aWidths);
344
345 mpImpl->m_xEventLB->show();
346
347 mpImpl->m_xEventLB->set_sensitive(true);
348 mpImpl->m_xGroupLB->set_sensitive(true);
349 mpImpl->m_xMacroLB->set_sensitive(true);
350
351 mpImpl->m_xGroupLB->SetFunctionListBox(mpImpl->m_xMacroLB.get());
352}
353
355{
356 weld::TreeView& rListBox = mpImpl->m_xEventLB->GetListBox();
357
358 int nEntryCnt = rListBox.n_children();
359
360 // get events from the table and fill the EventListBox respectively
361 for (int n = 0 ; n < nEntryCnt; ++n)
362 {
363 OUString sOld = rListBox.get_text(n, 1);
364 OUString sNew;
365 SvMacroItemId nEventId = static_cast<SvMacroItemId>(rListBox.get_id(n).toInt32());
366 if (aTbl.IsKeyValid(nEventId))
367 sNew = ConvertToUIName_Impl(aTbl.Get(nEventId));
368
369 if (sOld == sNew)
370 continue;
371
372 rListBox.set_text(n, sNew, 1);
373 }
374}
375
376namespace
377{
378 std::unique_ptr<SfxMacroTabPage> CreateSfxMacroTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rAttrSet)
379 {
380 return std::make_unique<SfxMacroTabPage>( pPage, pController, nullptr, rAttrSet );
381 }
382}
383
384std::unique_ptr<SfxTabPage> SfxMacroTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet)
385{
386 return CreateSfxMacroTabPage(pPage, pController, *rAttrSet);
387}
388
390 const Reference< XFrame >& rxDocumentFrame, const SfxItemSet& rSet)
391 : SfxSingleTabDialogController(pParent, &rSet,"cui/ui/eventassigndialog.ui",
392 "EventAssignDialog")
393{
394 std::unique_ptr<SfxMacroTabPage> xPage = CreateSfxMacroTabPage(get_content_area(), this, rSet);
395 xPage->SetFrame(rxDocumentFrame);
396 SetTabPage(std::move(xPage));
398}
399
400/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const SfxEventNamesList & GetEvents() const
size_t size() const
SfxEventName & at(size_t Index)
const T * GetItemIfSet(TypedWhichId< T > nWhich, bool bSrchInParent=true) const
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
SfxMacroTabPage * GetTabPage()
Definition: macroass.hxx:84
SfxMacroAssignDlg(weld::Widget *pParent, const css::uno::Reference< css::frame::XFrame > &rxDocumentFrame, const SfxItemSet &rSet)
Definition: macroass.cxx:389
std::unique_ptr< weld::Button > m_xAssignPB
Definition: macroass.cxx:43
std::unique_ptr< CuiConfigGroupListBox > m_xGroupLB
Definition: macroass.cxx:47
std::unique_ptr< weld::Button > m_xDeletePB
Definition: macroass.cxx:44
OUString m_aStaticMacroLBLabel
Definition: macroass.cxx:42
std::unique_ptr< weld::Widget > m_xGroupFrame
Definition: macroass.cxx:46
std::unique_ptr< weld::Frame > m_xMacroFrame
Definition: macroass.cxx:48
std::unique_ptr< MacroEventListBox > m_xEventLB
Definition: macroass.cxx:45
std::unique_ptr< CuiConfigFunctionListBox > m_xMacroLB
Definition: macroass.cxx:49
void EnableButtons()
Definition: macroass.cxx:82
void FillEvents()
Definition: macroass.cxx:354
void AddEvent(const OUString &rEventName, SvMacroItemId nEventId)
Definition: macroass.cxx:131
virtual bool FillItemSet(SfxItemSet *rSet) override
Definition: macroass.cxx:154
void AssignDeleteHdl(const weld::Widget *)
Definition: macroass.cxx:277
virtual void ActivatePage(const SfxItemSet &) override
Definition: macroass.cxx:180
SvxMacroTableDtor aTbl
Definition: macroass.hxx:36
virtual void Reset(const SfxItemSet *rSet) override
Definition: macroass.cxx:201
static std::unique_ptr< SfxTabPage > Create(weld::Container *pPage, weld::DialogController *pController, const SfxItemSet *rAttrSet)
Definition: macroass.cxx:384
virtual ~SfxMacroTabPage() override
Definition: macroass.cxx:126
bool IsReadOnly() const override
Definition: macroass.cxx:230
void InitAndSetHandler()
Definition: macroass.cxx:326
virtual void PageCreated(const SfxAllItemSet &aSet) override
Definition: macroass.cxx:185
void LaunchFillGroup()
Definition: macroass.cxx:174
SfxMacroTabPage(weld::Container *pPage, weld::DialogController *pController, const css::uno::Reference< css::frame::XFrame > &rxDocumentFrame, const SfxItemSet &rSet)
Definition: macroass.cxx:102
void ScriptChanged()
Definition: macroass.cxx:145
std::unique_ptr< SfxMacroTabPage_Impl > mpImpl
Definition: macroass.hxx:46
sal_uInt16 Which() const
void SetTabPage(std::unique_ptr< SfxTabPage > xTabPage)
weld::Container * get_content_area()
const SfxItemSet & GetItemSet() const
void SetFrame(const css::uno::Reference< css::frame::XFrame > &xFrame)
sal_uInt16 GetWhich(sal_uInt16 nSlot, bool bDeep=true) const
const SvxMacroTableDtor & GetMacroTable() const
void Erase(SvMacroItemId nEvent)
SvxMacro & Insert(SvMacroItemId nEvent, const SvxMacro &rMacro)
bool empty() const
bool IsKeyValid(SvMacroItemId nEvent) const
const SvxMacro * Get(SvMacroItemId nEvent) const
const OUString & GetMacName() const
OUString GetLanguage() const
virtual std::unique_ptr< TreeIter > make_iterator(const TreeIter *pOrig=nullptr) const=0
void connect_row_activated(const Link< TreeView &, bool > &rLink)
virtual void set_text(int row, const OUString &rText, int col=-1)=0
virtual OUString get_text(int row, int col=-1) const=0
virtual int n_children() const=0
void connect_changed(const Link< TreeView &, void > &rLink)
virtual bool get_iter_first(TreeIter &rIter) const=0
void append(TreeIter *pRet=nullptr)
virtual void set_column_fixed_widths(const std::vector< int > &rWidths)=0
virtual void set_cursor(int pos)=0
virtual int get_selected_index() const=0
virtual OUString get_selected_id() const=0
virtual OUString get_id(int pos) const=0
virtual float get_approximate_digit_width() const=0
int nCount
#define DBG_ASSERT(sCon, aError)
weld::Window * GetFrameWeld(const SfxFrame *pFrame)
SvMacroItemId
OUString aName
sal_Int64 n
constexpr OUStringLiteral SVX_MACRO_LANGUAGE_STARBASIC
constexpr OUStringLiteral SVX_MACRO_LANGUAGE_SF
static sal_uInt16 aPageRg[]
Definition: macroass.cxx:60
static OUString ConvertToUIName_Impl(SvxMacro const *pMacro)
Definition: macroass.cxx:65
IMPL_LINK(SfxMacroTabPage, AssignDeleteClickHdl_Impl, weld::Button &, rBtn, void)
Definition: macroass.cxx:266
IMPL_LINK_NOARG(SfxMacroTabPage, SelectEvent_Impl, weld::TreeView &, void)
Definition: macroass.cxx:235
sal_Int32 getTokenCount(std::string_view rIn, char cTok)
Reference< XComponentContext > getProcessComponentContext()
std::basic_string_view< charT, traits > getToken(std::basic_string_view< charT, traits > sv, charT delimiter, std::size_t &position)
SfxItemState
static SfxItemSet & rSet
OUString maUIName
SvMacroItemId mnId