LibreOffice Module cui (master) 1
cfgutil.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 <cfgutil.hxx>
21
22#include <com/sun/star/beans/XPropertySet.hpp>
23#include <com/sun/star/container/XEnumerationAccess.hpp>
24#include <com/sun/star/container/XEnumeration.hpp>
25#include <com/sun/star/document/XScriptInvocationContext.hpp>
26#include <com/sun/star/frame/ModuleManager.hpp>
27#include <com/sun/star/frame/Desktop.hpp>
28#include <com/sun/star/frame/theUICommandDescription.hpp>
29#include <com/sun/star/frame/XDispatchInformationProvider.hpp>
30#include <com/sun/star/script/browse/XBrowseNode.hpp>
31#include <com/sun/star/script/browse/BrowseNodeTypes.hpp>
32#include <com/sun/star/script/browse/theBrowseNodeFactory.hpp>
33#include <com/sun/star/script/browse/BrowseNodeFactoryViewTypes.hpp>
34#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
35#include <com/sun/star/uno/RuntimeException.hpp>
36#include <com/sun/star/ui/theUICategoryDescription.hpp>
37
38#include <basic/basmgr.hxx>
39#include <tools/urlobj.hxx>
40#include <strings.hrc>
41#include <bitmaps.hlst>
42#include <sfx2/minfitem.hxx>
45#include <comphelper/lok.hxx>
48#include <svtools/imagemgr.hxx>
49#include <sal/log.hxx>
50#include <osl/diagnose.h>
51#include <dialmgr.hxx>
53#include <vcl/commandevent.hxx>
55#include <vcl/help.hxx>
56#include <vcl/svapp.hxx>
57#include <o3tl/string_view.hxx>
58
62
63using namespace ::com::sun::star;
64using namespace ::com::sun::star::uno;
65using namespace ::com::sun::star::script;
66using namespace ::com::sun::star::frame;
67using namespace ::com::sun::star::document;
68
70{}
71
72void SfxStylesInfo_Impl::init(const OUString& rModuleName, const css::uno::Reference< css::frame::XModel >& xModel)
73{
74 m_aModuleName = rModuleName;
75 m_xDoc = xModel;
76}
77
78const char CMDURL_STYLEPROT_ONLY[] = ".uno:StyleApply?";
79const char CMDURL_SPART_ONLY [] = "Style:string=";
80const char CMDURL_FPART_ONLY [] = "FamilyName:string=";
81
82constexpr OUStringLiteral STYLEPROP_UINAME = u"DisplayName";
83constexpr OUStringLiteral MACRO_SELECTOR_CONFIGNAME = u"MacroSelectorDialog";
84constexpr OUStringLiteral LAST_RUN_MACRO_INFO = u"LastRunMacro";
85
87 std::u16string_view sFamily, std::u16string_view sStyle)
88{
89 return OUString::Concat(".uno:StyleApply?Style:string=")
90 + sStyle
91 + "&FamilyName:string="
92 + sFamily;
93}
94
96{
97 static const sal_Int32 LEN_STYLEPROT = strlen(CMDURL_STYLEPROT_ONLY);
98 static const sal_Int32 LEN_SPART = strlen(CMDURL_SPART_ONLY);
99 static const sal_Int32 LEN_FPART = strlen(CMDURL_FPART_ONLY);
100
101 if (!aStyle.sCommand.startsWith(CMDURL_STYLEPROT_ONLY))
102 return false;
103
104 aStyle.sFamily.clear();
105 aStyle.sStyle.clear();
106
107 sal_Int32 nCmdLen = aStyle.sCommand.getLength();
108 OUString sCmdArgs = aStyle.sCommand.copy(LEN_STYLEPROT, nCmdLen-LEN_STYLEPROT);
109 sal_Int32 i = sCmdArgs.indexOf('&');
110 if (i<0)
111 return false;
112
113 OUString sArg = sCmdArgs.copy(0, i);
114 if (sArg.startsWith(CMDURL_SPART_ONLY))
115 aStyle.sStyle = sArg.copy(LEN_SPART);
116 else if (sArg.startsWith(CMDURL_FPART_ONLY))
117 aStyle.sFamily = sArg.copy(LEN_FPART);
118
119 sArg = sCmdArgs.copy(i+1, sCmdArgs.getLength()-i-1);
120 if (sArg.startsWith(CMDURL_SPART_ONLY))
121 aStyle.sStyle = sArg.copy(LEN_SPART);
122 else if (sArg.startsWith(CMDURL_FPART_ONLY))
123 aStyle.sFamily = sArg.copy(LEN_FPART);
124
125 return !(aStyle.sFamily.isEmpty() || aStyle.sStyle.isEmpty());
126}
127
129{
130 try
131 {
132 css::uno::Reference< css::style::XStyleFamiliesSupplier > xModel(m_xDoc, css::uno::UNO_QUERY);
133
134 css::uno::Reference< css::container::XNameAccess > xFamilies;
135 if (xModel.is())
136 xFamilies = xModel->getStyleFamilies();
137
138 css::uno::Reference< css::container::XNameAccess > xStyleSet;
139 if (xFamilies.is())
140 xFamilies->getByName(aStyle.sFamily) >>= xStyleSet;
141
142 css::uno::Reference< css::beans::XPropertySet > xStyle;
143 if (xStyleSet.is())
144 xStyleSet->getByName(aStyle.sStyle) >>= xStyle;
145
146 aStyle.sLabel.clear();
147 if (xStyle.is())
148 xStyle->getPropertyValue(STYLEPROP_UINAME) >>= aStyle.sLabel;
149 }
150 catch(const css::uno::RuntimeException&)
151 { throw; }
152 catch(const css::uno::Exception&)
153 { aStyle.sLabel.clear(); }
154
155 if (aStyle.sLabel.isEmpty())
156 {
157 aStyle.sLabel = aStyle.sCommand;
158 }
159}
160
161std::vector< SfxStyleInfo_Impl > SfxStylesInfo_Impl::getStyleFamilies() const
162{
163 // It's an optional interface!
164 css::uno::Reference< css::style::XStyleFamiliesSupplier > xModel(m_xDoc, css::uno::UNO_QUERY);
165 if (!xModel.is())
166 return std::vector< SfxStyleInfo_Impl >();
167
168 css::uno::Reference< css::container::XNameAccess > xCont = xModel->getStyleFamilies();
169 const css::uno::Sequence< OUString > lFamilyNames = xCont->getElementNames();
170 std::vector< SfxStyleInfo_Impl > lFamilies;
171 for (const auto& aFamily : lFamilyNames)
172 {
173 if ((aFamily == "CellStyles" && m_aModuleName != "com.sun.star.sheet.SpreadsheetDocument") ||
174 aFamily == "cell" || aFamily == "table" || aFamily == "Default")
175 continue;
176
177 SfxStyleInfo_Impl aFamilyInfo;
178 aFamilyInfo.sFamily = aFamily;
179
180 try
181 {
182 css::uno::Reference< css::beans::XPropertySet > xFamilyInfo;
183 xCont->getByName(aFamilyInfo.sFamily) >>= xFamilyInfo;
184 if (!xFamilyInfo.is())
185 {
186 // TODO_AS currently there is no support for an UIName property .. use internal family name instead
187 aFamilyInfo.sLabel = aFamilyInfo.sFamily;
188 }
189 else
190 xFamilyInfo->getPropertyValue(STYLEPROP_UINAME) >>= aFamilyInfo.sLabel;
191 }
192 catch(const css::uno::RuntimeException&)
193 { throw; }
194 catch(const css::uno::Exception&)
195 { return std::vector< SfxStyleInfo_Impl >(); }
196
197 lFamilies.push_back(aFamilyInfo);
198 }
199
200 return lFamilies;
201}
202
203std::vector< SfxStyleInfo_Impl > SfxStylesInfo_Impl::getStyles(const OUString& sFamily)
204{
205 css::uno::Sequence< OUString > lStyleNames;
206 css::uno::Reference< css::style::XStyleFamiliesSupplier > xModel(m_xDoc, css::uno::UNO_QUERY_THROW);
207 css::uno::Reference< css::container::XNameAccess > xFamilies = xModel->getStyleFamilies();
208 css::uno::Reference< css::container::XNameAccess > xStyleSet;
209 try
210 {
211 xFamilies->getByName(sFamily) >>= xStyleSet;
212 lStyleNames = xStyleSet->getElementNames();
213 }
214 catch(const css::uno::RuntimeException&)
215 { throw; }
216 catch(const css::uno::Exception&)
217 { return std::vector< SfxStyleInfo_Impl >(); }
218
219 std::vector< SfxStyleInfo_Impl > lStyles;
220 sal_Int32 c = lStyleNames.getLength();
221 sal_Int32 i = 0;
222 for (i=0; i<c; ++i)
223 {
224 SfxStyleInfo_Impl aStyleInfo;
225 aStyleInfo.sFamily = sFamily;
226 aStyleInfo.sStyle = lStyleNames[i];
227 aStyleInfo.sCommand = SfxStylesInfo_Impl::generateCommand(aStyleInfo.sFamily, aStyleInfo.sStyle);
228
229 try
230 {
231 css::uno::Reference< css::beans::XPropertySet > xStyle;
232 xStyleSet->getByName(aStyleInfo.sStyle) >>= xStyle;
233 if (!xStyle.is())
234 continue;
235 xStyle->getPropertyValue("DisplayName") >>= aStyleInfo.sLabel;
236 }
237 catch(const css::uno::RuntimeException&)
238 { throw; }
239 catch(const css::uno::Exception&)
240 { continue; }
241
242 lStyles.push_back(aStyleInfo);
243 }
244 return lStyles;
245}
246
247OUString CuiConfigFunctionListBox::GetHelpText( bool bConsiderParent )
248{
249 SfxGroupInfo_Impl *pData = weld::fromId<SfxGroupInfo_Impl*>(get_selected_id());
250 if (pData)
251 {
252 if ( pData->nKind == SfxCfgKind::FUNCTION_SLOT )
253 {
254 if (bConsiderParent)
255 return Application::GetHelp()->GetHelpText(pData->sCommand, m_xTreeView.get());
256 else
257 return Application::GetHelp()->GetHelpText(pData->sCommand, static_cast<weld::Widget*>(nullptr));
258 }
259 else if ( pData->nKind == SfxCfgKind::FUNCTION_SCRIPT )
260 {
261 return pData->sHelpText;
262 }
263 }
264 return OUString();
265}
266
268{
269 SfxGroupInfo_Impl *pData = weld::fromId<SfxGroupInfo_Impl*>(get_selected_id());
270 if (!pData)
271 return OUString();
272 return pData->sCommand;
273}
274
276{
277 SfxGroupInfo_Impl *pData = weld::fromId<SfxGroupInfo_Impl*>(get_selected_id());
278 if (!pData)
279 return OUString();
280 if (!pData->sLabel.isEmpty())
281 return pData->sLabel;
282 return pData->sCommand;
283}
284
285CuiConfigFunctionListBox::CuiConfigFunctionListBox(std::unique_ptr<weld::TreeView> xTreeView)
286 : m_xTreeView(std::move(xTreeView))
287 , m_xScratchIter(m_xTreeView->make_iterator())
288{
289 m_xTreeView->make_sorted();
290 m_xTreeView->set_size_request(m_xTreeView->get_approximate_digit_width() * 35, m_xTreeView->get_height_rows(9));
291 m_xTreeView->connect_query_tooltip(LINK(this, CuiConfigFunctionListBox, QueryTooltip));
292}
293
295{
296 ClearAll();
297}
298
299IMPL_LINK(CuiConfigFunctionListBox, QueryTooltip, const weld::TreeIter&, rIter, OUString)
300{
301 SfxGroupInfo_Impl *pData = weld::fromId<SfxGroupInfo_Impl*>(m_xTreeView->get_id(rIter));
302 if (!pData)
303 return OUString();
304 OUString aLabel = CuiResId(RID_CUISTR_COMMANDLABEL) + ": ";
305 OUString aName = CuiResId(RID_CUISTR_COMMANDNAME) + ": ";
306 OUString aTip = CuiResId(RID_CUISTR_COMMANDTIP) + ": ";
307 return aLabel + pData->sLabel + "\n" + aName + pData->sCommand+ "\n" + aTip + pData->sTooltip;
308}
309
311/* Description
312 Deletes all entries in the FunctionListBox, all UserData and all
313 possibly existing MacroInfo.
314*/
315{
316 sal_uInt16 nCount = aArr.size();
317 for ( sal_uInt16 i=0; i<nCount; ++i )
318 {
319 SfxGroupInfo_Impl *pData = aArr[i].get();
320
321 if ( pData->nKind == SfxCfgKind::FUNCTION_SCRIPT )
322 {
323 OUString* pScriptURI = static_cast<OUString*>(pData->pObject);
324 delete pScriptURI;
325 }
326
328 {
329 XInterface* xi = static_cast<XInterface *>(pData->pObject);
330 if (xi != nullptr)
331 {
332 xi->release();
333 }
334 }
335 }
336
337 aArr.clear();
338 m_xTreeView->clear();
339}
340
342{
343 SfxGroupInfo_Impl *pData = weld::fromId<SfxGroupInfo_Impl*>(get_selected_id());
344 if (pData && pData->nKind == SfxCfgKind::FUNCTION_SCRIPT)
345 return *static_cast<OUString*>(pData->pObject);
346 return OUString();
347}
348
350{
351 OUString m_sMyMacros;
353 OUString m_sDlgMacros;
356
358};
359
361 m_sMyMacros(CuiResId(RID_CUISTR_MYMACROS)),
362 m_sProdMacros(CuiResId(RID_CUISTR_PRODMACROS)),
363 m_sDlgMacros(CuiResId(RID_CUISTR_PRODMACROS)),
364 m_aStrGroupStyles(CuiResId(RID_CUISTR_GROUP_STYLES)),
365 m_aStrGroupSidebarDecks(CuiResId(RID_CUISTR_GROUP_SIDEBARDECKS))
366{
367}
368
370{
371 m_pStylesInfo = pStyles;
372}
373
374namespace
375{
376
383 Reference< XModel > lcl_getDocumentWithScripts_throw( const Reference< XInterface >& _rxComponent )
384 {
385 Reference< XEmbeddedScripts > xScripts( _rxComponent, UNO_QUERY );
386 if ( !xScripts.is() )
387 {
388 Reference< XScriptInvocationContext > xContext( _rxComponent, UNO_QUERY );
389 if ( xContext.is() )
390 xScripts = xContext->getScriptContainer();
391 }
392
393 return Reference< XModel >( xScripts, UNO_QUERY );
394 }
395
396
397 Reference< XModel > lcl_getScriptableDocument_nothrow( const Reference< XFrame >& _rxFrame )
398 {
399 Reference< XModel > xDocument;
400
401 // examine our associated frame
402 try
403 {
404 OSL_ENSURE( _rxFrame.is(), "lcl_getScriptableDocument_nothrow: you need to pass a frame to this dialog/tab page!" );
405 if ( _rxFrame.is() )
406 {
407 // first try the model in the frame
408 Reference< XController > xController( _rxFrame->getController(), UNO_SET_THROW );
409 xDocument = lcl_getDocumentWithScripts_throw( xController->getModel() );
410
411 if ( !xDocument.is() )
412 {
413 // if there is no suitable document in the frame, try the controller
414 xDocument = lcl_getDocumentWithScripts_throw( _rxFrame->getController() );
415 }
416 }
417 }
418 catch( const Exception& )
419 {
420 }
421
422 return xDocument;
423 }
424}
425
426CuiConfigGroupListBox::CuiConfigGroupListBox(std::unique_ptr<weld::TreeView> xTreeView)
428 , m_pFunctionListBox(nullptr)
429 , m_pStylesInfo(nullptr)
430 , m_xTreeView(std::move(xTreeView))
431 , m_xScratchIter(m_xTreeView->make_iterator())
432{
433 m_xTreeView->connect_expanding(LINK(this, CuiConfigGroupListBox, ExpandingHdl));
434 m_xTreeView->set_size_request(m_xTreeView->get_approximate_digit_width() * 35, m_xTreeView->get_height_rows(9));
435}
436
438{
439 ClearAll();
440}
441
443{
444 sal_uInt16 nCount = aArr.size();
445 for ( sal_uInt16 i=0; i<nCount; ++i )
446 {
447 SfxGroupInfo_Impl *pData = aArr[i].get();
448 if (pData->nKind == SfxCfgKind::GROUP_STYLES && pData->pObject)
449 {
450 SfxStyleInfo_Impl* pStyle = static_cast<SfxStyleInfo_Impl*>(pData->pObject);
451 delete pStyle;
452 }
453 else if (pData->nKind == SfxCfgKind::FUNCTION_SCRIPT && pData->pObject )
454 {
455 OUString* pScriptURI = static_cast<OUString*>(pData->pObject);
456 delete pScriptURI;
457 }
458 else if (pData->nKind == SfxCfgKind::GROUP_SCRIPTCONTAINER)
459 {
460 XInterface* xi = static_cast<XInterface *>(pData->pObject);
461 if (xi != nullptr)
462 {
463 xi->release();
464 }
465 }
466 }
467
468 aArr.clear();
469 m_xTreeView->clear();
470}
471
473{
474 try
475 {
476 css::uno::Reference< css::frame::XDispatchInformationProvider > xProvider(m_xFrame, css::uno::UNO_QUERY_THROW);
477 css::uno::Sequence< sal_Int16 > lGroups = xProvider->getSupportedCommandGroups();
478 sal_Int32 c1 = lGroups.getLength();
479 sal_Int32 i1 = 0;
480
481 if ( c1 )
482 {
483 // Add All Commands category
484 aArr.push_back(std::make_unique<SfxGroupInfo_Impl>(SfxCfgKind::GROUP_ALLFUNCTIONS, 0));
485 m_xTreeView->append(weld::toId(aArr.back().get()), CuiResId(RID_CUISTR_ALLFUNCTIONS));
486 }
487
488 for (i1=0; i1<c1; ++i1)
489 {
490 sal_Int16 nGroupID = lGroups[i1];
491 OUString sGroupID = OUString::number(nGroupID);
492 OUString sGroupName ;
493
494 try
495 {
496 m_xModuleCategoryInfo->getByName(sGroupID) >>= sGroupName;
497 if (sGroupName.isEmpty())
498 continue;
499 }
500 catch(const css::container::NoSuchElementException&)
501 { continue; }
502
503 aArr.push_back( std::make_unique<SfxGroupInfo_Impl>( SfxCfgKind::GROUP_FUNCTION, nGroupID ) );
504 m_xTreeView->append(weld::toId(aArr.back().get()), sGroupName);
505 }
506 }
507 catch(const css::uno::RuntimeException&)
508 { throw; }
509 catch(const css::uno::Exception&)
510 {}
511}
512
513void CuiConfigGroupListBox::FillScriptList(const css::uno::Reference< css::script::browse::XBrowseNode >& xRootNode,
514 const weld::TreeIter* pParentEntry)
515{
516 try {
517 if ( xRootNode->hasChildNodes() )
518 {
519 // tdf#120362: Don't ask to enable disabled Java when filling script list
520 css::uno::ContextLayer layer(comphelper::NoEnableJavaInteractionContext());
521
522 const Sequence< Reference< browse::XBrowseNode > > children =
523 xRootNode->getChildNodes();
524 bool bIsRootNode = false;
525
526 OUString user("user");
527 OUString share("share");
528 if ( xRootNode->getName() == "Root" )
529 {
530 bIsRootNode = true;
531 }
532
533 //To mimic current starbasic behaviour we
534 //need to make sure that only the current document
535 //is displayed in the config tree. Tests below
536 //set the bDisplay flag to FALSE if the current
537 //node is a first level child of the Root and is NOT
538 //either the current document, user or share
539 OUString currentDocTitle;
540 Reference< XModel > xDocument( lcl_getScriptableDocument_nothrow( m_xFrame ) );
541 if ( xDocument.is() )
542 {
543 currentDocTitle = ::comphelper::DocumentInfo::getDocumentTitle( xDocument );
544 }
545
546 for ( Reference< browse::XBrowseNode > const & theChild : children )
547 {
548 bool bDisplay = true;
549 OUString uiName = theChild->getName();
550 if ( bIsRootNode )
551 {
552 if ( ! (uiName == user || uiName == share ||
553 uiName == currentDocTitle ) )
554 {
555 bDisplay=false;
556 }
557 else
558 {
559 if ( uiName == user )
560 {
561 uiName = xImp->m_sMyMacros;
562 }
563 else if ( uiName == share )
564 {
565 uiName = xImp->m_sProdMacros;
566 }
567 }
568 }
569 if (theChild->getType() != browse::BrowseNodeTypes::SCRIPT && bDisplay )
570 {
571// We call acquire on the XBrowseNode so that it does not
572// get autodestructed and become invalid when accessed later.
573 theChild->acquire();
574
575 bool bChildOnDemand = false;
576
577 if ( theChild->hasChildNodes() )
578 {
579 const Sequence< Reference< browse::XBrowseNode > > grandchildren =
580 theChild->getChildNodes();
581
582 for ( const auto& rxNode : grandchildren )
583 {
584 if ( rxNode->getType() == browse::BrowseNodeTypes::CONTAINER )
585 {
586 bChildOnDemand = true;
587 break;
588 }
589 }
590 }
591
592 OUString aImage = GetImage(theChild, m_xContext, bIsRootNode);
593
594 aArr.push_back( std::make_unique<SfxGroupInfo_Impl>(SfxCfgKind::GROUP_SCRIPTCONTAINER,
595 0, static_cast<void *>( theChild.get())));
596
597 OUString sId(weld::toId(aArr.back().get()));
598 m_xTreeView->insert(pParentEntry, -1, &uiName, &sId, nullptr, nullptr, bChildOnDemand, m_xScratchIter.get());
599 m_xTreeView->set_image(*m_xScratchIter, aImage);
600 }
601 }
602 }
603 }
604 catch (RuntimeException&) {
605 // do nothing, the entry will not be displayed in the UI
606 }
607}
608
609void CuiConfigGroupListBox::FillFunctionsList(const css::uno::Sequence<DispatchInformation>& xCommands)
610{
612 for (const auto & rInfo : xCommands)
613 {
615
616 OUString sUIName = MapCommand2UIName(rInfo.Command);
617 aArr.push_back( std::make_unique<SfxGroupInfo_Impl>( SfxCfgKind::FUNCTION_SLOT, 0 ) );
618 SfxGroupInfo_Impl* pGrpInfo = aArr.back().get();
619 pGrpInfo->sCommand = rInfo.Command;
620 pGrpInfo->sLabel = sUIName;
622 m_pFunctionListBox->append(weld::toId(pGrpInfo), sUIName);
623 }
625}
626
627void CuiConfigGroupListBox::Init(const css::uno::Reference< css::uno::XComponentContext >& xContext,
628 const css::uno::Reference< css::frame::XFrame >& xFrame,
629 const OUString& sModuleLongName,
630 bool bEventMode)
631{
632 m_xTreeView->freeze();
633 ClearAll(); // Remove all old entries from treelist box
634
635 m_xContext = xContext;
637 if( bEventMode )
638 {
639 m_sModuleLongName = sModuleLongName;
640 m_xGlobalCategoryInfo = css::ui::theUICategoryDescription::get( m_xContext );
641 m_xModuleCategoryInfo.set(m_xGlobalCategoryInfo->getByName(m_sModuleLongName), css::uno::UNO_QUERY_THROW);
642 m_xUICmdDescription = css::frame::theUICommandDescription::get( m_xContext );
643
644 InitModule();
645 }
646
647 SAL_INFO("cui.customize", "** ** About to initialise SF Scripts");
648 // Add Scripting Framework entries
649 Reference< browse::XBrowseNode > rootNode;
650 try
651 {
652 Reference< browse::XBrowseNodeFactory > xFac = browse::theBrowseNodeFactory::get( m_xContext );
653 rootNode.set( xFac->createView( browse::BrowseNodeFactoryViewTypes::MACROSELECTOR ) );
654 }
655 catch( const Exception& )
656 {
657 TOOLS_WARN_EXCEPTION("cui.customize", "Caught some exception whilst retrieving browse nodes from factory");
658 // TODO exception handling
659 }
660
661
662 if ( rootNode.is() )
663 {
664 if ( bEventMode )
665 {
666 //We call acquire on the XBrowseNode so that it does not
667 //get autodestructed and become invalid when accessed later.
668 rootNode->acquire();
669
670 aArr.push_back( std::make_unique<SfxGroupInfo_Impl>( SfxCfgKind::GROUP_SCRIPTCONTAINER, 0,
671 static_cast<void *>(rootNode.get())));
672 OUString aTitle(xImp->m_sDlgMacros);
673 OUString sId(weld::toId(aArr.back().get()));
674 m_xTreeView->insert(nullptr, -1, &aTitle, &sId, nullptr, nullptr, true, nullptr);
675 }
676 else
677 {
678 //We are only showing scripts not slot APIs so skip
679 //Root node and show location nodes
680 FillScriptList(rootNode, nullptr);
681 }
682 }
683
684 // add styles and sidebar decks
685 if ( bEventMode )
686 {
687 aArr.push_back( std::make_unique<SfxGroupInfo_Impl>( SfxCfgKind::GROUP_STYLES, 0, nullptr ) ); // TODO last parameter should contain user data
688 OUString sStyle(xImp->m_aStrGroupStyles);
689 OUString sId(weld::toId(aArr.back().get()));
690 m_xTreeView->insert(nullptr, -1, &sStyle, &sId, nullptr, nullptr, true, nullptr);
691
692 aArr.push_back( std::make_unique<SfxGroupInfo_Impl>(SfxCfgKind::GROUP_SIDEBARDECKS, 0));
693 OUString sSidebarDecks(xImp->m_aStrGroupSidebarDecks);
694 sId = weld::toId(aArr.back().get());
695 m_xTreeView->insert(nullptr, -1, &sSidebarDecks, &sId, nullptr, nullptr, false, nullptr);
696 }
697
698 m_xTreeView->thaw();
699 m_xTreeView->scroll_to_row(0);
700 m_xTreeView->select(0);
701}
702
704 const Reference< browse::XBrowseNode >& node,
705 Reference< XComponentContext > const & xCtx,
706 bool bIsRootNode)
707{
708 OUString aImage;
709 if ( bIsRootNode )
710 {
711 if (node->getName() == "user" || node->getName() == "share" )
712 {
713 aImage = RID_CUIBMP_HARDDISK;
714 }
715 else
716 {
717 OUString factoryURL;
718 OUString nodeName = node->getName();
719 Reference<XInterface> xDocumentModel = getDocumentModel(xCtx, nodeName );
720 if ( xDocumentModel.is() )
721 {
722 Reference< frame::XModuleManager2 > xModuleManager( frame::ModuleManager::create(xCtx) );
723 // get the long name of the document:
724 OUString appModule( xModuleManager->identify(
725 xDocumentModel ) );
726 Sequence<beans::PropertyValue> moduleDescr;
727 Any aAny = xModuleManager->getByName(appModule);
728 if( !( aAny >>= moduleDescr ) )
729 {
730 throw RuntimeException("SFTreeListBox::Init: failed to get PropertyValue");
731 }
732 beans::PropertyValue const * pmoduleDescr =
733 moduleDescr.getConstArray();
734 for ( sal_Int32 pos = moduleDescr.getLength(); pos--; )
735 {
736 if ( pmoduleDescr[ pos ].Name == "ooSetupFactoryEmptyDocumentURL" )
737 {
738 pmoduleDescr[ pos ].Value >>= factoryURL;
739 SAL_INFO("cui.customize", "factory url for doc images is " << factoryURL);
740 break;
741 }
742 }
743 }
744 if( !factoryURL.isEmpty() )
745 {
747 }
748 else
749 {
750 aImage = RID_CUIBMP_DOC;
751 }
752 }
753 }
754 else
755 {
756 if( node->getType() == browse::BrowseNodeTypes::SCRIPT )
757 aImage = RID_CUIBMP_MACRO;
758 else
759 aImage = RID_CUIBMP_LIB;
760 }
761 return aImage;
762}
763
764Reference< XInterface >
765CuiConfigGroupListBox::getDocumentModel( Reference< XComponentContext > const & xCtx, std::u16string_view docName )
766{
767 Reference< XInterface > xModel;
768 Reference< frame::XDesktop2 > desktop = frame::Desktop::create( xCtx );
769
770 Reference< container::XEnumerationAccess > componentsAccess =
771 desktop->getComponents();
772 Reference< container::XEnumeration > components =
773 componentsAccess->createEnumeration();
774 while (components->hasMoreElements())
775 {
777 components->nextElement(), UNO_QUERY );
778 if ( model.is() )
779 {
780 OUString sTdocUrl =
781 ::comphelper::DocumentInfo::getDocumentTitle( model );
782 if( sTdocUrl == docName )
783 {
784 xModel = model;
785 break;
786 }
787 }
788 }
789 return xModel;
790}
791
792OUString CuiConfigGroupListBox::MapCommand2UIName(const OUString& sCommand)
793{
794 OUString sUIName;
795 try
796 {
797 css::uno::Reference< css::container::XNameAccess > xModuleConf;
798 m_xUICmdDescription->getByName(m_sModuleLongName) >>= xModuleConf;
799 if (xModuleConf.is())
800 {
801 ::comphelper::SequenceAsHashMap lProps(xModuleConf->getByName(sCommand));
802 sUIName = lProps.getUnpackedValueOrDefault("Name", OUString());
803 }
804 }
805 catch(const css::uno::RuntimeException&)
806 { throw; }
807 catch(css::uno::Exception&)
808 { sUIName.clear(); }
809
810 // fallback for missing UINames !?
811 if (sUIName.isEmpty())
812 {
813 sUIName = sCommand;
814 }
815
816 return sUIName;
817}
818
820/* Description
821 A function group or a basic module has been selected.
822 All functions/macros are displayed in the functionlistbox.
823*/
824{
825 std::unique_ptr<weld::TreeIter> xIter(m_xTreeView->make_iterator());
826 if (!m_xTreeView->get_selected(xIter.get()))
827 return;
828
829 SfxGroupInfo_Impl *pInfo = weld::fromId<SfxGroupInfo_Impl*>(m_xTreeView->get_id(*xIter));
832
833 switch ( pInfo->nKind )
834 {
836 {
837 css::uno::Reference< css::frame::XDispatchInformationProvider > xProvider( m_xFrame, UNO_QUERY );
838 bool bValidIter = m_xTreeView->get_iter_first(*xIter);
839 while (bValidIter)
840 {
841 SfxGroupInfo_Impl *pCurrentInfo = weld::fromId<SfxGroupInfo_Impl*>(m_xTreeView->get_id(*xIter));
842 if (pCurrentInfo->nKind == SfxCfgKind::GROUP_FUNCTION)
843 {
844 css::uno::Sequence< css::frame::DispatchInformation > lCommands;
845 try
846 {
847 lCommands = xProvider->getConfigurableDispatchInformation( pCurrentInfo->nUniqueID );
848 FillFunctionsList( lCommands );
849 }
850 catch ( container::NoSuchElementException& )
851 {
852 }
853 }
854 bValidIter = m_xTreeView->iter_next(*xIter);
855 }
856 break;
857 }
858
860 {
861 sal_uInt16 nGroup = pInfo->nUniqueID;
862 css::uno::Reference< css::frame::XDispatchInformationProvider > xProvider (m_xFrame, css::uno::UNO_QUERY_THROW);
863 css::uno::Sequence< css::frame::DispatchInformation > lCommands = xProvider->getConfigurableDispatchInformation(nGroup);
864 FillFunctionsList( lCommands );
865 break;
866 }
867
869 {
870 if (!m_xTreeView->iter_has_child(*xIter))
871 {
872 Reference< browse::XBrowseNode > rootNode(
873 static_cast< browse::XBrowseNode* >( pInfo->pObject ) ) ;
874
875 try {
876 if ( rootNode->hasChildNodes() )
877 {
878 const Sequence< Reference< browse::XBrowseNode > > children =
879 rootNode->getChildNodes();
880
881 for ( const Reference< browse::XBrowseNode >& childNode : children )
882 {
883 if (childNode->getType() == browse::BrowseNodeTypes::SCRIPT)
884 {
885 OUString uri, description;
886
887 Reference < beans::XPropertySet >xPropSet( childNode, UNO_QUERY );
888 if (!xPropSet.is())
889 {
890 continue;
891 }
892
893 Any value =
894 xPropSet->getPropertyValue("URI");
895 value >>= uri;
896
897 try
898 {
899 value = xPropSet->getPropertyValue("Description");
900 value >>= description;
901 }
902 catch (Exception &) {
903 // do nothing, the description will be empty
904 }
905
906 OUString* pScriptURI = new OUString( uri );
907
908 OUString aImage = GetImage(childNode, Reference< XComponentContext >(), false);
909 m_pFunctionListBox->aArr.push_back( std::make_unique<SfxGroupInfo_Impl>( SfxCfgKind::FUNCTION_SCRIPT, 0, pScriptURI ));
910 m_pFunctionListBox->aArr.back()->sCommand = uri;
911 m_pFunctionListBox->aArr.back()->sLabel = childNode->getName();
912 m_pFunctionListBox->aArr.back()->sHelpText = description;
913
914 OUString sId(weld::toId(m_pFunctionListBox->aArr.back().get()));
915 m_pFunctionListBox->append(sId, childNode->getName(), aImage);
916 }
917 }
918 }
919 }
920 catch (RuntimeException&) {
921 // do nothing, the entry will not be displayed in the UI
922 }
923 }
924 break;
925 }
926
928 {
929 SfxStyleInfo_Impl* pFamily = static_cast<SfxStyleInfo_Impl*>(pInfo->pObject);
930 if (pFamily)
931 {
932 const std::vector< SfxStyleInfo_Impl > lStyles = m_pStylesInfo->getStyles(pFamily->sFamily);
933 for (auto const& lStyle : lStyles)
934 {
935 SfxStyleInfo_Impl* pStyle = new SfxStyleInfo_Impl(lStyle);
936 m_pFunctionListBox->aArr.push_back(std::make_unique<SfxGroupInfo_Impl>(SfxCfgKind::GROUP_STYLES, 0, pStyle));
937 m_pFunctionListBox->aArr.back()->sCommand = pStyle->sCommand;
938 m_pFunctionListBox->aArr.back()->sLabel = pStyle->sLabel;
939 OUString sId(weld::toId(m_pFunctionListBox->aArr.back().get()));
941 }
942 }
943 break;
944 }
945
947 {
948 sfx2::sidebar::ResourceManager aResourceManager;
949 sfx2::sidebar::Context aContext(m_sModuleLongName, OUString());
951 aResourceManager.GetMatchingDecks(aDecks, aContext, false, m_xFrame->getController());
952
953 for (auto const& rDeck : aDecks)
954 {
955 const OUString sCommand = ".uno:SidebarDeck." + rDeck.msId;
956 m_pFunctionListBox->aArr.push_back(std::make_unique<SfxGroupInfo_Impl>(
958 nullptr));
959 m_pFunctionListBox->aArr.back()->sCommand = sCommand;
960 m_pFunctionListBox->aArr.back()->sLabel = rDeck.msId;
961 m_pFunctionListBox->aArr.back()->sTooltip =
964 rDeck.msId);
965 }
966
967 break;
968 }
969
970 default:
971 // Do nothing, the list box will stay empty
972 SAL_INFO( "cui.customize", "Ignoring unexpected SfxCfgKind: " << static_cast<int>(pInfo->nKind) );
973 break;
974 }
975
977
980}
981
982/* Description
983 A basic or a library is opened.
984*/
985IMPL_LINK(CuiConfigGroupListBox, ExpandingHdl, const weld::TreeIter&, rIter, bool)
986{
987 SfxGroupInfo_Impl *pInfo = weld::fromId<SfxGroupInfo_Impl*>(m_xTreeView->get_id(rIter));
988 switch ( pInfo->nKind )
989 {
991 {
992 if (!m_xTreeView->iter_has_child(rIter))
993 {
994 Reference< browse::XBrowseNode > rootNode(
995 static_cast< browse::XBrowseNode* >( pInfo->pObject ) ) ;
996 FillScriptList(rootNode, &rIter);
997 }
998 break;
999 }
1000
1002 {
1003 if (!m_xTreeView->iter_has_child(rIter))
1004 {
1005 const std::vector<SfxStyleInfo_Impl> lStyleFamilies = m_pStylesInfo->getStyleFamilies();
1006 for (auto const& lStyleFamily : lStyleFamilies)
1007 {
1008 SfxStyleInfo_Impl* pFamily = new SfxStyleInfo_Impl(lStyleFamily);
1009 aArr.push_back( std::make_unique<SfxGroupInfo_Impl>( SfxCfgKind::GROUP_STYLES, 0, pFamily ));
1010 OUString sId(weld::toId(aArr.back().get()));
1011 m_xTreeView->insert(&rIter, -1, &pFamily->sLabel, &sId, nullptr, nullptr, false, nullptr);
1012 }
1013 }
1014 break;
1015 }
1016
1017 default:
1018 OSL_FAIL( "Wrong group type!" );
1019 break;
1020 }
1021 return true;
1022}
1023
1024#if HAVE_FEATURE_SCRIPTING
1025void CuiConfigGroupListBox::SelectMacro( const SfxMacroInfoItem *pItem )
1026{
1027 auto const rMacro = pItem->GetQualifiedName();
1028 sal_Int32 nIdx {rMacro.lastIndexOf('.')};
1029 const std::u16string_view aMethod( rMacro.subView(nIdx + 1) );
1030 std::u16string_view aLib;
1031 std::u16string_view aModule;
1032 if ( nIdx>0 )
1033 {
1034 // string contains at least 2 tokens
1035 nIdx = rMacro.lastIndexOf('.', nIdx);
1036 if (nIdx != -1)
1037 {
1038 // string contains at least 3 tokens
1039 aLib = o3tl::getToken(rMacro, 0, '.' );
1040 sal_Int32 nIdx2 = nIdx + 1;
1041 aModule = o3tl::getToken(rMacro, 0, '.', nIdx2 );
1042 }
1043 }
1044
1045 std::unique_ptr<weld::TreeIter> xIter = m_xTreeView->make_iterator();
1046 if (!m_xTreeView->get_iter_first(*xIter))
1047 return;
1048
1049 do
1050 {
1051 OUString aEntryBas = m_xTreeView->get_text(*xIter);
1052 if (aEntryBas == xImp->m_sDlgMacros)
1053 {
1054 m_xTreeView->expand_row(*xIter);
1055 std::unique_ptr<weld::TreeIter> xLocationIter = m_xTreeView->make_iterator(xIter.get());
1056 if (m_xTreeView->iter_children(*xLocationIter))
1057 {
1058 do
1059 {
1060 m_xTreeView->expand_row(*xLocationIter);
1061 std::unique_ptr<weld::TreeIter> xLibIter = m_xTreeView->make_iterator(xLocationIter.get());
1062 if (m_xTreeView->iter_children(*xLibIter))
1063 {
1064 do
1065 {
1066 OUString aEntryLib = m_xTreeView->get_text(*xLibIter);
1067 if (aEntryLib == aLib)
1068 {
1069 m_xTreeView->expand_row(*xLibIter);
1070 std::unique_ptr<weld::TreeIter> xModIter = m_xTreeView->make_iterator(xLibIter.get());
1071 if (m_xTreeView->iter_children(*xModIter))
1072 {
1073 do
1074 {
1075 OUString aEntryMod = m_xTreeView->get_text(*xModIter);
1076 if ( aEntryMod == aModule )
1077 {
1078 m_xTreeView->expand_row(*xModIter);
1079 m_xTreeView->scroll_to_row(*xModIter);
1080 m_xTreeView->select(*xModIter);
1081 GroupSelected();
1082 for (int i = 0, nCount = m_pFunctionListBox->n_children(); i < nCount; ++i)
1083 {
1084 OUString aEntryMethod = m_pFunctionListBox->get_text(i);
1085 if (aEntryMethod == aMethod)
1086 {
1089 return;
1090 }
1091 }
1092 m_xTreeView->collapse_row(*xModIter);
1093 }
1094 } while (m_xTreeView->iter_next_sibling(*xModIter));
1095 }
1096 m_xTreeView->collapse_row(*xLibIter);
1097 }
1098 } while (m_xTreeView->iter_next_sibling(*xLibIter));
1099 }
1100 m_xTreeView->collapse_row(*xLocationIter);
1101 } while (m_xTreeView->iter_next_sibling(*xLocationIter));
1102 }
1103 // If the macro can't be located, preselect the "Application Macros" category:
1104 m_xTreeView->scroll_to_row(*xIter);
1105 m_xTreeView->select(*xIter);
1106 return;
1107 }
1108 } while (m_xTreeView->iter_next_sibling(*xIter));
1109}
1110#endif
1111
1112/*
1113 * Implementation of SvxScriptSelectorDialog
1114 *
1115 * This dialog is used for selecting Slot API commands
1116 * and Scripting Framework Scripts.
1117 */
1118
1120 weld::Window* pParent, const css::uno::Reference< css::frame::XFrame >& xFrame)
1121 : GenericDialogController(pParent, "cui/ui/macroselectordialog.ui", "MacroSelectorDialog")
1122 , m_xDialogDescription(m_xBuilder->weld_label("helpmacro"))
1123 , m_xCategories(new CuiConfigGroupListBox(m_xBuilder->weld_tree_view("categories")))
1124 , m_xCommands(new CuiConfigFunctionListBox(m_xBuilder->weld_tree_view("commands")))
1125 , m_xLibraryFT(m_xBuilder->weld_label("libraryft"))
1126 , m_xMacronameFT(m_xBuilder->weld_label("macronameft"))
1127 , m_xOKButton(m_xBuilder->weld_button("ok"))
1128 , m_xCancelButton(m_xBuilder->weld_button("cancel"))
1129 , m_xDescriptionText(m_xBuilder->weld_text_view("description"))
1130 , m_xDescriptionFrame(m_xBuilder->weld_frame("descriptionframe"))
1131{
1132 m_xCancelButton->show();
1133 m_xDialogDescription->show();
1134 m_xOKButton->show();
1135
1136 m_xLibraryFT->set_visible(true);
1137 m_xMacronameFT->set_visible(true);
1138
1139 const OUString aModuleName(vcl::CommandInfoProvider::GetModuleIdentifier(xFrame));
1140 m_xCategories->SetFunctionListBox(m_xCommands.get());
1141 m_xCategories->Init(comphelper::getProcessComponentContext(), xFrame, aModuleName, /*bShowSlots*/false);
1142
1143 m_xCategories->connect_changed(
1144 LINK( this, SvxScriptSelectorDialog, SelectHdl ) );
1145 m_xCommands->connect_changed( LINK( this, SvxScriptSelectorDialog, SelectHdl ) );
1146 m_xCommands->connect_row_activated( LINK( this, SvxScriptSelectorDialog, FunctionDoubleClickHdl ) );
1147 m_xCommands->connect_popup_menu( LINK( this, SvxScriptSelectorDialog, ContextMenuHdl ) );
1148
1149 m_xOKButton->connect_clicked( LINK( this, SvxScriptSelectorDialog, ClickHdl ) );
1150 m_xCancelButton->connect_clicked( LINK( this, SvxScriptSelectorDialog, ClickHdl ) );
1151
1152 m_sDefaultDesc = m_xDescriptionText->get_text();
1153
1154 // Support style commands
1157 if (xFrame.is())
1158 xController = xFrame->getController();
1159 if (xController.is())
1160 xModel = xController->getModel();
1161
1162 m_aStylesInfo.init(aModuleName, xModel);
1163 m_xCategories->SetStylesInfo(&m_aStylesInfo);
1164
1165 // The following call is a workaround to make scroll_to_row work as expected in kf5/x11
1166 m_xDialog->resize_to_request();
1167
1169 UpdateUI();
1170
1172 m_xDescriptionFrame->hide();
1173}
1174
1176{
1177}
1178
1180{
1181 if (&rCtrl == &m_xCategories->get_widget())
1182 {
1183 m_xCategories->GroupSelected();
1184 }
1185 UpdateUI();
1186}
1187
1189{
1190 if (m_xOKButton->get_sensitive())
1191 ClickHdl(*m_xOKButton);
1192 return true;
1193}
1194
1195IMPL_LINK(SvxScriptSelectorDialog, ContextMenuHdl, const CommandEvent&, rCEvt, bool)
1196{
1197 weld::TreeView& xTreeView = m_xCommands->get_widget();
1198 if (rCEvt.GetCommand() != CommandEventId::ContextMenu || !xTreeView.n_children())
1199 return false;
1200
1201 std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(&xTreeView, "modules/BasicIDE/ui/sortmenu.ui"));
1202 std::unique_ptr<weld::Menu> xPopup(xBuilder->weld_menu("sortmenu"));
1203 std::unique_ptr<weld::Menu> xDropMenu(xBuilder->weld_menu("sortsubmenu"));
1204 xDropMenu->set_active("alphabetically", xTreeView.get_sort_order());
1205 xDropMenu->set_active("properorder", !xTreeView.get_sort_order());
1206
1207 OString sCommand(xPopup->popup_at_rect(&xTreeView, tools::Rectangle(rCEvt.GetMousePosPixel(), Size(1,1))));
1208 if (sCommand == "alphabetically")
1209 {
1210 xTreeView.make_sorted();
1211 }
1212 else if (sCommand == "properorder")
1213 {
1214 xTreeView.make_unsorted();
1215 m_xCategories->GroupSelected();
1216 }
1217 else if (!sCommand.isEmpty())
1218 {
1219 SAL_WARN("cui.customize", "Unknown context menu action: " << sCommand );
1220 }
1221
1222 return true;
1223}
1224
1225// Check if command is selected and enable the OK button accordingly
1226// Grab the help text for this id if available and update the description field
1227void
1229{
1230 OUString url = GetScriptURL();
1231 if ( !url.isEmpty() )
1232 {
1233 OUString sMessage = m_xCommands->GetHelpText();
1234 m_xDescriptionText->set_text(sMessage.isEmpty() ? m_sDefaultDesc : sMessage);
1235 m_xOKButton->set_sensitive(true);
1236 }
1237 else
1238 {
1240 m_xOKButton->set_sensitive(false);
1241 }
1242}
1243
1245{
1246 if (&rButton == m_xCancelButton.get())
1247 {
1248 m_xDialog->response(RET_CANCEL);
1249 }
1250 else if (&rButton == m_xOKButton.get())
1251 {
1252 SaveLastUsedMacro();
1253 m_xDialog->response(RET_OK);
1254 }
1255}
1256
1257void
1259{
1260 m_xOKButton->set_label(CuiResId(RID_CUISTR_SELECTOR_RUN));
1261}
1262
1263OUString
1265{
1266 OUString result;
1267
1268 std::unique_ptr<weld::TreeIter> xIter = m_xCommands->make_iterator();
1269 if (m_xCommands->get_selected(xIter.get()))
1270 {
1271 SfxGroupInfo_Impl *pData = weld::fromId<SfxGroupInfo_Impl*>(m_xCommands->get_id(*xIter));
1272 if ( ( pData->nKind == SfxCfgKind::FUNCTION_SLOT )
1273 || ( pData->nKind == SfxCfgKind::FUNCTION_SCRIPT )
1274 || ( pData->nKind == SfxCfgKind::GROUP_STYLES )
1275 )
1276 {
1277 result = pData->sCommand;
1278 }
1279 }
1280
1281 return result;
1282}
1283
1284void
1286{
1287 // Gets the current selection in the dialog as a series of selected entries
1288 OUString sMacroInfo;
1289 sMacroInfo = m_xCommands->get_selected_text();
1290 weld::TreeView& xCategories = m_xCategories->get_widget();
1291 std::unique_ptr<weld::TreeIter> xIter = xCategories.make_iterator();
1292
1293 if (!xCategories.get_selected(xIter.get()))
1294 return;
1295
1296 do
1297 {
1298 sMacroInfo = xCategories.get_text(*xIter) + "|" + sMacroInfo;
1299 } while (xCategories.iter_parent(*xIter));
1300
1302 LAST_RUN_MACRO_INFO, Any(sMacroInfo));
1303}
1304
1305void
1307{
1308 SvtViewOptions aDlgOpt( EViewType::Dialog, MACRO_SELECTOR_CONFIGNAME );
1309 if (!aDlgOpt.Exists())
1310 return;
1311
1312 OUString sMacroInfo;
1313 aDlgOpt.GetUserItem(LAST_RUN_MACRO_INFO) >>= sMacroInfo;
1314 if (sMacroInfo.isEmpty())
1315 return;
1316
1317 // Counts how many entries exist in the macro info string
1318 sal_Int16 nInfoParts = 0;
1319 sal_Int16 nLastIndex = sMacroInfo.indexOf('|');
1320 if (nLastIndex > -1)
1321 {
1322 nInfoParts = 1;
1323 while ( nLastIndex != -1 )
1324 {
1325 nInfoParts++;
1326 nLastIndex = sMacroInfo.indexOf('|', nLastIndex + 1);
1327 }
1328 }
1329
1330 weld::TreeView& xCategories = m_xCategories->get_widget();
1331 std::unique_ptr<weld::TreeIter> xIter = xCategories.make_iterator();
1332 if (!xCategories.get_iter_first(*xIter))
1333 return;
1334
1335 // Expand the nodes in the category tree
1336 OUString sNodeToExpand;
1337 bool bIsIterValid;
1338 sal_Int16 nOpenedNodes = 0;
1339 for (sal_Int16 i=0; i<nInfoParts - 1; i++)
1340 {
1341 sNodeToExpand = sMacroInfo.getToken(i, '|');
1342 bIsIterValid = true;
1343 while (bIsIterValid && xCategories.get_text(*xIter) != sNodeToExpand)
1344 bIsIterValid = xCategories.iter_next_sibling(*xIter);
1345
1346 if (bIsIterValid)
1347 {
1348 xCategories.expand_row(*xIter);
1349 nOpenedNodes++;
1350 }
1351 if (xCategories.iter_has_child(*xIter))
1352 (void)xCategories.iter_children(*xIter);
1353 else if (nOpenedNodes < nInfoParts - 1)
1354 // If the number of levels in the tree is smaller than the
1355 // number of parts in the macro info string, then return
1356 return;
1357 }
1358 xCategories.select(*xIter);
1359 xCategories.scroll_to_row(*xIter);
1360 m_xCategories->GroupSelected();
1361
1362 // Select the macro in the command tree
1363 weld::TreeView& xCommands = m_xCommands->get_widget();
1364 xIter = xCommands.make_iterator();
1365 if (!xCommands.get_iter_first(*xIter))
1366 return;
1367
1368 OUString sMacroName = sMacroInfo.getToken(nInfoParts - 1, '|');
1369 bIsIterValid = true;
1370 while (bIsIterValid && xCommands.get_text(*xIter) != sMacroName)
1371 bIsIterValid = xCommands.iter_next_sibling(*xIter);
1372
1373 if (bIsIterValid)
1374 {
1375 xCommands.scroll_to_row(*xIter);
1376 xCommands.select(*xIter);
1377 }
1378}
1379
1380/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
PropertiesInfo aProperties
Reference< XExecutableDialog > m_xDialog
constexpr OUStringLiteral MACRO_SELECTOR_CONFIGNAME
Definition: cfgutil.cxx:83
IMPL_LINK_NOARG(SvxScriptSelectorDialog, FunctionDoubleClickHdl, weld::TreeView &, bool)
Definition: cfgutil.cxx:1188
constexpr OUStringLiteral LAST_RUN_MACRO_INFO
Definition: cfgutil.cxx:84
const char CMDURL_SPART_ONLY[]
Definition: cfgutil.cxx:79
constexpr OUStringLiteral STYLEPROP_UINAME
Definition: cfgutil.cxx:82
const char CMDURL_STYLEPROT_ONLY[]
Definition: cfgutil.cxx:78
IMPL_LINK(CuiConfigFunctionListBox, QueryTooltip, const weld::TreeIter &, rIter, OUString)
Definition: cfgutil.cxx:299
const char CMDURL_FPART_ONLY[]
Definition: cfgutil.cxx:80
@ GROUP_SCRIPTCONTAINER
@ GROUP_SIDEBARDECKS
@ GROUP_ALLFUNCTIONS
static std::unique_ptr< weld::Builder > CreateBuilder(weld::Widget *pParent, const OUString &rUIFile, bool bMobile=false, sal_uInt64 nLOKWindowId=0)
static Help * GetHelp()
void select(int pos)
Definition: cfgutil.hxx:166
OUString GetCurLabel() const
Definition: cfgutil.cxx:275
SfxGroupInfoArr_Impl aArr
Definition: cfgutil.hxx:111
OUString get_text(int nPos) const
Definition: cfgutil.hxx:151
OUString GetCurCommand() const
Definition: cfgutil.cxx:267
void scroll_to_row(int pos)
Definition: cfgutil.hxx:145
OUString get_selected_id() const
Definition: cfgutil.hxx:160
void append(const OUString &rId, const OUString &rStr, const weld::TreeIter *pParent=nullptr)
Definition: cfgutil.hxx:124
OUString GetSelectedScriptURI() const
Definition: cfgutil.cxx:341
OUString GetHelpText(bool bConsiderParent=true)
Definition: cfgutil.cxx:247
int n_children() const
Definition: cfgutil.hxx:148
std::unique_ptr< weld::TreeView > m_xTreeView
Definition: cfgutil.hxx:113
CuiConfigFunctionListBox(std::unique_ptr< weld::TreeView > xTreeView)
Definition: cfgutil.cxx:285
void SetStylesInfo(SfxStylesInfo_Impl *pStyles)
Definition: cfgutil.cxx:369
OUString m_sModuleLongName
Definition: cfgutil.hxx:188
CuiConfigFunctionListBox * m_pFunctionListBox
Definition: cfgutil.hxx:186
std::unique_ptr< weld::TreeView > m_xTreeView
Definition: cfgutil.hxx:195
SfxStylesInfo_Impl * m_pStylesInfo
Definition: cfgutil.hxx:194
void Init(const css::uno::Reference< css::uno::XComponentContext > &xContext, const css::uno::Reference< css::frame::XFrame > &xFrame, const OUString &sModuleLongName, bool bEventMode)
Definition: cfgutil.cxx:627
static OUString GetImage(const css::uno::Reference< css::script::browse::XBrowseNode > &node, css::uno::Reference< css::uno::XComponentContext > const &xCtx, bool bIsRootNode)
Definition: cfgutil.cxx:703
static css::uno::Reference< css::uno::XInterface > getDocumentModel(css::uno::Reference< css::uno::XComponentContext > const &xCtx, std::u16string_view docName)
Definition: cfgutil.cxx:765
CuiConfigGroupListBox(std::unique_ptr< weld::TreeView > xTreeView)
Definition: cfgutil.cxx:426
SfxGroupInfoArr_Impl aArr
Definition: cfgutil.hxx:187
std::unique_ptr< SvxConfigGroupBoxResource_Impl > xImp
Definition: cfgutil.hxx:185
css::uno::Reference< css::container::XNameAccess > m_xGlobalCategoryInfo
Definition: cfgutil.hxx:191
OUString MapCommand2UIName(const OUString &sCommand)
Definition: cfgutil.cxx:792
void FillFunctionsList(const css::uno::Sequence< css::frame::DispatchInformation > &xCommands)
Definition: cfgutil.cxx:609
css::uno::Reference< css::container::XNameAccess > m_xModuleCategoryInfo
Definition: cfgutil.hxx:192
std::unique_ptr< weld::TreeIter > m_xScratchIter
Definition: cfgutil.hxx:196
void FillScriptList(const css::uno::Reference< css::script::browse::XBrowseNode > &xRootNode, const weld::TreeIter *pParentEntry)
Definition: cfgutil.cxx:513
css::uno::Reference< css::frame::XFrame > m_xFrame
Definition: cfgutil.hxx:190
css::uno::Reference< css::container::XNameAccess > m_xUICmdDescription
Definition: cfgutil.hxx:193
css::uno::Reference< css::uno::XComponentContext > m_xContext
Definition: cfgutil.hxx:189
virtual OUString GetHelpText(const OUString &aHelpURL, const weld::Widget *pWidget)
static SVT_DLLPUBLIC OUString GetFileImageId(const INetURLObject &rURL)
css::uno::Any GetUserItem(const OUString &sName) const
void SetUserItem(const OUString &sName, const css::uno::Any &aValue)
bool Exists() const
SvxScriptSelectorDialog(weld::Window *pParent, const css::uno::Reference< css::frame::XFrame > &xFrame)
Definition: cfgutil.cxx:1119
std::unique_ptr< weld::Label > m_xDialogDescription
Definition: cfgutil.hxx:242
std::unique_ptr< weld::Button > m_xOKButton
Definition: cfgutil.hxx:247
OUString GetScriptURL() const
Definition: cfgutil.cxx:1264
std::unique_ptr< CuiConfigGroupListBox > m_xCategories
Definition: cfgutil.hxx:243
std::unique_ptr< weld::Label > m_xMacronameFT
Definition: cfgutil.hxx:246
std::unique_ptr< CuiConfigFunctionListBox > m_xCommands
Definition: cfgutil.hxx:244
std::unique_ptr< weld::TextView > m_xDescriptionText
Definition: cfgutil.hxx:249
std::unique_ptr< weld::Label > m_xLibraryFT
Definition: cfgutil.hxx:245
std::unique_ptr< weld::Button > m_xCancelButton
Definition: cfgutil.hxx:248
SfxStylesInfo_Impl m_aStylesInfo
Definition: cfgutil.hxx:240
std::unique_ptr< weld::Frame > m_xDescriptionFrame
Definition: cfgutil.hxx:250
virtual ~SvxScriptSelectorDialog() override
Definition: cfgutil.cxx:1175
TValueType getUnpackedValueOrDefault(const OUString &sKey, const TValueType &aDefault) const
std::vector< DeckContextDescriptor > DeckContextDescriptorContainer
const DeckContextDescriptorContainer & GetMatchingDecks(DeckContextDescriptorContainer &rDeckDescriptors, const Context &rContext, const bool bIsDocumentReadOnly, const css::uno::Reference< css::frame::XController > &rxController)
std::shared_ptr< weld::Dialog > m_xDialog
virtual void scroll_to_row(int row)=0
virtual std::unique_ptr< TreeIter > make_iterator(const TreeIter *pOrig=nullptr) const=0
virtual bool get_selected(TreeIter *pIter) const=0
virtual void make_sorted()=0
virtual void expand_row(const TreeIter &rIter)=0
virtual OUString get_text(int row, int col=-1) const=0
virtual int n_children() const=0
virtual bool get_iter_first(TreeIter &rIter) const=0
virtual bool iter_next_sibling(TreeIter &rIter) const=0
virtual void select(int pos)=0
virtual bool iter_parent(TreeIter &rIter) const=0
virtual bool iter_children(TreeIter &rIter) const=0
virtual bool iter_has_child(const TreeIter &rIter) const=0
virtual bool get_sort_order() const=0
virtual void make_unsorted()=0
Any value
OUString CuiResId(TranslateId aKey)
Definition: cuiresmgr.cxx:23
int nCount
#define TOOLS_WARN_EXCEPTION(area, stream)
float u
std::unique_ptr< weld::Button > m_xOKButton
OUString aName
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
std::unique_ptr< sal_Int32[]> pData
@ Exception
css::uno::Reference< css::uno::XCurrentContext > NoEnableJavaInteractionContext()
Reference< XComponentContext > getProcessComponentContext()
model
int i
std::basic_string_view< charT, traits > getToken(std::basic_string_view< charT, traits > sv, charT delimiter, std::size_t &position)
Sequence< beans::PropertyValue > GetCommandProperties(const OUString &rsCommandName, const OUString &rsModuleName)
OUString GetTooltipForCommand(const OUString &rsCommandName, const css::uno::Sequence< css::beans::PropertyValue > &rProperties, const Reference< frame::XFrame > &rxFrame)
OUString GetCommandShortcut(const OUString &rsCommandName, const Reference< frame::XFrame > &rxFrame)
OUString GetModuleIdentifier(const Reference< frame::XFrame > &rxFrame)
OUString toId(const void *pValue)
const SvxPageUsage aArr[]
Definition: page.cxx:72
OUString sMessage
OUString sTooltip
Definition: cfgutil.hxx:100
OUString sLabel
Definition: cfgutil.hxx:98
sal_uInt16 nUniqueID
Definition: cfgutil.hxx:95
OUString sCommand
Definition: cfgutil.hxx:97
SfxCfgKind nKind
Definition: cfgutil.hxx:94
OUString sStyle
Definition: cfgutil.hxx:45
OUString sCommand
Definition: cfgutil.hxx:46
OUString sFamily
Definition: cfgutil.hxx:44
OUString sLabel
Definition: cfgutil.hxx:47
void init(const OUString &rModuleName, const css::uno::Reference< css::frame::XModel > &xModel)
Definition: cfgutil.cxx:72
static bool parseStyleCommand(SfxStyleInfo_Impl &aStyle)
Definition: cfgutil.cxx:95
static OUString generateCommand(std::u16string_view sFamily, std::u16string_view sStyle)
Definition: cfgutil.cxx:86
std::vector< SfxStyleInfo_Impl > getStyleFamilies() const
Definition: cfgutil.cxx:161
std::vector< SfxStyleInfo_Impl > getStyles(const OUString &sFamily)
Definition: cfgutil.cxx:203
css::uno::Reference< css::frame::XModel > m_xDoc
Definition: cfgutil.hxx:65
void getLabel4Style(SfxStyleInfo_Impl &aStyle)
Definition: cfgutil.cxx:128
OUString m_aModuleName
Definition: cfgutil.hxx:64
Reference< XController > xController
Reference< XFrame > xFrame
Reference< XModel > xModel
OUString Name
Any result
OUString aLabel
OUString sId
constexpr OUStringLiteral sMacroName
RET_OK
RET_CANCEL
size_t pos