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