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 // return the number of added groups
477 css::uno::Reference< css::frame::XDispatchInformationProvider > xProvider(m_xFrame, css::uno::UNO_QUERY_THROW);
478 css::uno::Sequence< sal_Int16 > lGroups = xProvider->getSupportedCommandGroups();
479 sal_Int32 c1 = lGroups.getLength();
480 sal_Int32 i1 = 0;
481 sal_Int32 nAddedGroups = 0;
482
483 for (i1=0; i1<c1; ++i1)
484 {
485 sal_Int16 nGroupID = lGroups[i1];
486 OUString sGroupID = OUString::number(nGroupID);
487 OUString sGroupName ;
488
489 try
490 {
491 m_xModuleCategoryInfo->getByName(sGroupID) >>= sGroupName;
492 if (sGroupName.isEmpty())
493 continue;
494 }
495 catch(const css::container::NoSuchElementException&)
496 { continue; }
497
498 aArr.push_back( std::make_unique<SfxGroupInfo_Impl>( SfxCfgKind::GROUP_FUNCTION, nGroupID ) );
499 m_xTreeView->append(weld::toId(aArr.back().get()), sGroupName);
500 nAddedGroups++;
501 }
502 return nAddedGroups;
503 }
504 catch(const css::uno::RuntimeException&)
505 { throw; }
506 catch(const css::uno::Exception&)
507 {}
508 return 0;
509}
510
511void CuiConfigGroupListBox::FillScriptList(const css::uno::Reference< css::script::browse::XBrowseNode >& xRootNode,
512 const weld::TreeIter* pParentEntry)
513{
514 try {
515 if ( xRootNode->hasChildNodes() )
516 {
517 // tdf#120362: Don't ask to enable disabled Java when filling script list
518 css::uno::ContextLayer layer(comphelper::NoEnableJavaInteractionContext());
519
520 const Sequence< Reference< browse::XBrowseNode > > children =
521 xRootNode->getChildNodes();
522 bool bIsRootNode = false;
523
524 OUString user("user");
525 OUString share("share");
526 if ( xRootNode->getName() == "Root" )
527 {
528 bIsRootNode = true;
529 }
530
531 //To mimic current starbasic behaviour we
532 //need to make sure that only the current document
533 //is displayed in the config tree. Tests below
534 //set the bDisplay flag to FALSE if the current
535 //node is a first level child of the Root and is NOT
536 //either the current document, user or share
537 OUString currentDocTitle;
538 Reference< XModel > xDocument( lcl_getScriptableDocument_nothrow( m_xFrame ) );
539 if ( xDocument.is() )
540 {
541 currentDocTitle = ::comphelper::DocumentInfo::getDocumentTitle( xDocument );
542 }
543
544 for ( Reference< browse::XBrowseNode > const & theChild : children )
545 {
546 bool bDisplay = true;
547 OUString uiName = theChild->getName();
548 if ( bIsRootNode )
549 {
550 if ( ! (uiName == user || uiName == share ||
551 uiName == currentDocTitle ) )
552 {
553 bDisplay=false;
554 }
555 else
556 {
557 if ( uiName == user )
558 {
559 uiName = xImp->m_sMyMacros;
560 }
561 else if ( uiName == share )
562 {
563 uiName = xImp->m_sProdMacros;
564 }
565 }
566 }
567 if (theChild->getType() != browse::BrowseNodeTypes::SCRIPT && bDisplay )
568 {
569// We call acquire on the XBrowseNode so that it does not
570// get autodestructed and become invalid when accessed later.
571 theChild->acquire();
572
573 bool bChildOnDemand = false;
574
575 if ( theChild->hasChildNodes() )
576 {
577 const Sequence< Reference< browse::XBrowseNode > > grandchildren =
578 theChild->getChildNodes();
579
580 for ( const auto& rxNode : grandchildren )
581 {
582 if ( rxNode->getType() == browse::BrowseNodeTypes::CONTAINER )
583 {
584 bChildOnDemand = true;
585 break;
586 }
587 }
588 }
589
590 OUString aImage = GetImage(theChild, m_xContext, bIsRootNode);
591
592 aArr.push_back( std::make_unique<SfxGroupInfo_Impl>(SfxCfgKind::GROUP_SCRIPTCONTAINER,
593 0, static_cast<void *>( theChild.get())));
594
595 OUString sId(weld::toId(aArr.back().get()));
596 m_xTreeView->insert(pParentEntry, -1, &uiName, &sId, nullptr, nullptr, bChildOnDemand, m_xScratchIter.get());
597 m_xTreeView->set_image(*m_xScratchIter, aImage);
598 }
599 }
600 }
601 }
602 catch (RuntimeException&) {
603 // do nothing, the entry will not be displayed in the UI
604 }
605}
606
607void CuiConfigGroupListBox::FillFunctionsList(const css::uno::Sequence<DispatchInformation>& xCommands)
608{
610 for (const auto & rInfo : xCommands)
611 {
613
614 OUString sUIName = MapCommand2UIName(rInfo.Command);
615 aArr.push_back( std::make_unique<SfxGroupInfo_Impl>( SfxCfgKind::FUNCTION_SLOT, 0 ) );
616 SfxGroupInfo_Impl* pGrpInfo = aArr.back().get();
617 pGrpInfo->sCommand = rInfo.Command;
618 pGrpInfo->sLabel = sUIName;
620 m_pFunctionListBox->append(weld::toId(pGrpInfo), sUIName);
621 }
623}
624
625void CuiConfigGroupListBox::Init(const css::uno::Reference< css::uno::XComponentContext >& xContext,
626 const css::uno::Reference< css::frame::XFrame >& xFrame,
627 const OUString& sModuleLongName,
628 bool bEventMode)
629{
630 m_xTreeView->freeze();
631 ClearAll(); // Remove all old entries from treelist box
632
633 m_xContext = xContext;
635 sal_Int32 nAddedGroups = 0;
636 if( bEventMode )
637 {
638 m_sModuleLongName = sModuleLongName;
639 m_xGlobalCategoryInfo = css::ui::theUICategoryDescription::get( m_xContext );
640 m_xModuleCategoryInfo.set(m_xGlobalCategoryInfo->getByName(m_sModuleLongName), css::uno::UNO_QUERY_THROW);
641 m_xUICmdDescription = css::frame::theUICommandDescription::get( m_xContext );
642
643 nAddedGroups = InitModule();
644 }
645
646 SAL_INFO("cui.customize", "** ** About to initialise SF Scripts");
647 // Add Scripting Framework entries
648 Reference< browse::XBrowseNode > rootNode;
649 try
650 {
651 Reference< browse::XBrowseNodeFactory > xFac = browse::theBrowseNodeFactory::get( m_xContext );
652 rootNode.set( xFac->createView( browse::BrowseNodeFactoryViewTypes::MACROSELECTOR ) );
653 }
654 catch( const Exception& )
655 {
656 TOOLS_WARN_EXCEPTION("cui.customize", "Caught some exception whilst retrieving browse nodes from factory");
657 // TODO exception handling
658 }
659
660 m_xTreeView->thaw();
661 m_xTreeView->make_sorted();
662 m_xTreeView->make_unsorted();
663 m_xTreeView->freeze();
664
665 // add All Commands to the top
666 if ( bEventMode && nAddedGroups )
667 {
668 aArr.insert(aArr.begin(), std::make_unique<SfxGroupInfo_Impl>(SfxCfgKind::GROUP_ALLFUNCTIONS, 0));
669 OUString sId(weld::toId(aArr.front().get()));
670 OUString s(CuiResId(RID_CUISTR_ALLFUNCTIONS));
671 m_xTreeView->insert(nullptr, 0, &s, &sId, nullptr, nullptr, false, nullptr);
672 }
673
674 // add application macros to the end
675 if ( rootNode.is() )
676 {
677 if ( bEventMode )
678 {
679 //We call acquire on the XBrowseNode so that it does not
680 //get autodestructed and become invalid when accessed later.
681 rootNode->acquire();
682
683 aArr.push_back( std::make_unique<SfxGroupInfo_Impl>( SfxCfgKind::GROUP_SCRIPTCONTAINER, 0,
684 static_cast<void *>(rootNode.get())));
685 OUString aTitle(xImp->m_sDlgMacros);
686 OUString sId(weld::toId(aArr.back().get()));
687 m_xTreeView->insert(nullptr, -1, &aTitle, &sId, nullptr, nullptr, true, nullptr);
688 }
689 else
690 {
691 //We are only showing scripts not slot APIs so skip
692 //Root node and show location nodes
693 FillScriptList(rootNode, nullptr);
694 }
695 }
696
697 // add styles and sidebar decks to the end
698 if ( bEventMode )
699 {
700 aArr.push_back( std::make_unique<SfxGroupInfo_Impl>( SfxCfgKind::GROUP_STYLES, 0, nullptr ) ); // TODO last parameter should contain user data
701 OUString sStyle(xImp->m_aStrGroupStyles);
702 OUString sId(weld::toId(aArr.back().get()));
703 m_xTreeView->insert(nullptr, -1, &sStyle, &sId, nullptr, nullptr, true, nullptr);
704
705 aArr.push_back( std::make_unique<SfxGroupInfo_Impl>(SfxCfgKind::GROUP_SIDEBARDECKS, 0));
706 OUString sSidebarDecks(xImp->m_aStrGroupSidebarDecks);
707 sId = weld::toId(aArr.back().get());
708 m_xTreeView->insert(nullptr, -1, &sSidebarDecks, &sId, nullptr, nullptr, false, nullptr);
709 }
710
711 m_xTreeView->thaw();
712 m_xTreeView->scroll_to_row(0);
713 m_xTreeView->select(0);
714}
715
717 const Reference< browse::XBrowseNode >& node,
718 Reference< XComponentContext > const & xCtx,
719 bool bIsRootNode)
720{
721 OUString aImage;
722 if ( bIsRootNode )
723 {
724 if (node->getName() == "user" || node->getName() == "share" )
725 {
726 aImage = RID_CUIBMP_HARDDISK;
727 }
728 else
729 {
730 OUString factoryURL;
731 OUString nodeName = node->getName();
732 Reference<XInterface> xDocumentModel = getDocumentModel(xCtx, nodeName );
733 if ( xDocumentModel.is() )
734 {
735 Reference< frame::XModuleManager2 > xModuleManager( frame::ModuleManager::create(xCtx) );
736 // get the long name of the document:
737 OUString appModule( xModuleManager->identify(
738 xDocumentModel ) );
739 Sequence<beans::PropertyValue> moduleDescr;
740 Any aAny = xModuleManager->getByName(appModule);
741 if( !( aAny >>= moduleDescr ) )
742 {
743 throw RuntimeException("SFTreeListBox::Init: failed to get PropertyValue");
744 }
745 beans::PropertyValue const * pmoduleDescr =
746 moduleDescr.getConstArray();
747 for ( sal_Int32 pos = moduleDescr.getLength(); pos--; )
748 {
749 if ( pmoduleDescr[ pos ].Name == "ooSetupFactoryEmptyDocumentURL" )
750 {
751 pmoduleDescr[ pos ].Value >>= factoryURL;
752 SAL_INFO("cui.customize", "factory url for doc images is " << factoryURL);
753 break;
754 }
755 }
756 }
757 if( !factoryURL.isEmpty() )
758 {
760 }
761 else
762 {
763 aImage = RID_CUIBMP_DOC;
764 }
765 }
766 }
767 else
768 {
769 if( node->getType() == browse::BrowseNodeTypes::SCRIPT )
770 aImage = RID_CUIBMP_MACRO;
771 else
772 aImage = RID_CUIBMP_LIB;
773 }
774 return aImage;
775}
776
777Reference< XInterface >
778CuiConfigGroupListBox::getDocumentModel( Reference< XComponentContext > const & xCtx, std::u16string_view docName )
779{
780 Reference< XInterface > xModel;
781 Reference< frame::XDesktop2 > desktop = frame::Desktop::create( xCtx );
782
783 Reference< container::XEnumerationAccess > componentsAccess =
784 desktop->getComponents();
785 Reference< container::XEnumeration > components =
786 componentsAccess->createEnumeration();
787 while (components->hasMoreElements())
788 {
790 components->nextElement(), UNO_QUERY );
791 if ( model.is() )
792 {
793 OUString sTdocUrl =
794 ::comphelper::DocumentInfo::getDocumentTitle( model );
795 if( sTdocUrl == docName )
796 {
797 xModel = model;
798 break;
799 }
800 }
801 }
802 return xModel;
803}
804
805OUString CuiConfigGroupListBox::MapCommand2UIName(const OUString& sCommand)
806{
807 OUString sUIName;
808 try
809 {
810 css::uno::Reference< css::container::XNameAccess > xModuleConf;
811 m_xUICmdDescription->getByName(m_sModuleLongName) >>= xModuleConf;
812 if (xModuleConf.is())
813 {
814 ::comphelper::SequenceAsHashMap lProps(xModuleConf->getByName(sCommand));
815 sUIName = lProps.getUnpackedValueOrDefault("Name", OUString());
816 }
817 }
818 catch(const css::uno::RuntimeException&)
819 { throw; }
820 catch(css::uno::Exception&)
821 { sUIName.clear(); }
822
823 // fallback for missing UINames !?
824 if (sUIName.isEmpty())
825 {
826 sUIName = sCommand;
827 }
828
829 return sUIName;
830}
831
833/* Description
834 A function group or a basic module has been selected.
835 All functions/macros are displayed in the functionlistbox.
836*/
837{
838 std::unique_ptr<weld::TreeIter> xIter(m_xTreeView->make_iterator());
839 if (!m_xTreeView->get_selected(xIter.get()))
840 return;
841
842 SfxGroupInfo_Impl *pInfo = weld::fromId<SfxGroupInfo_Impl*>(m_xTreeView->get_id(*xIter));
845
846 switch ( pInfo->nKind )
847 {
849 {
850 css::uno::Reference< css::frame::XDispatchInformationProvider > xProvider( m_xFrame, UNO_QUERY );
851 bool bValidIter = m_xTreeView->get_iter_first(*xIter);
852 while (bValidIter)
853 {
854 SfxGroupInfo_Impl *pCurrentInfo = weld::fromId<SfxGroupInfo_Impl*>(m_xTreeView->get_id(*xIter));
855 if (pCurrentInfo->nKind == SfxCfgKind::GROUP_FUNCTION)
856 {
857 css::uno::Sequence< css::frame::DispatchInformation > lCommands;
858 try
859 {
860 lCommands = xProvider->getConfigurableDispatchInformation( pCurrentInfo->nUniqueID );
861 FillFunctionsList( lCommands );
862 }
863 catch ( container::NoSuchElementException& )
864 {
865 }
866 }
867 bValidIter = m_xTreeView->iter_next(*xIter);
868 }
869 break;
870 }
871
873 {
874 sal_uInt16 nGroup = pInfo->nUniqueID;
875 css::uno::Reference< css::frame::XDispatchInformationProvider > xProvider (m_xFrame, css::uno::UNO_QUERY_THROW);
876 css::uno::Sequence< css::frame::DispatchInformation > lCommands = xProvider->getConfigurableDispatchInformation(nGroup);
877 FillFunctionsList( lCommands );
878 break;
879 }
880
882 {
883 if (!m_xTreeView->iter_has_child(*xIter))
884 {
885 Reference< browse::XBrowseNode > rootNode(
886 static_cast< browse::XBrowseNode* >( pInfo->pObject ) ) ;
887
888 try {
889 if ( rootNode->hasChildNodes() )
890 {
891 const Sequence< Reference< browse::XBrowseNode > > children =
892 rootNode->getChildNodes();
893
894 for ( const Reference< browse::XBrowseNode >& childNode : children )
895 {
896 if (childNode->getType() == browse::BrowseNodeTypes::SCRIPT)
897 {
898 OUString uri, description;
899
900 Reference < beans::XPropertySet >xPropSet( childNode, UNO_QUERY );
901 if (!xPropSet.is())
902 {
903 continue;
904 }
905
906 Any value =
907 xPropSet->getPropertyValue("URI");
908 value >>= uri;
909
910 try
911 {
912 value = xPropSet->getPropertyValue("Description");
913 value >>= description;
914 }
915 catch (Exception &) {
916 // do nothing, the description will be empty
917 }
918
919 OUString* pScriptURI = new OUString( uri );
920
921 OUString aImage = GetImage(childNode, Reference< XComponentContext >(), false);
922 m_pFunctionListBox->aArr.push_back( std::make_unique<SfxGroupInfo_Impl>( SfxCfgKind::FUNCTION_SCRIPT, 0, pScriptURI ));
923 m_pFunctionListBox->aArr.back()->sCommand = uri;
924 m_pFunctionListBox->aArr.back()->sLabel = childNode->getName();
925 m_pFunctionListBox->aArr.back()->sHelpText = description;
926
927 OUString sId(weld::toId(m_pFunctionListBox->aArr.back().get()));
928 m_pFunctionListBox->append(sId, childNode->getName(), aImage);
929 }
930 }
931 }
932 }
933 catch (RuntimeException&) {
934 // do nothing, the entry will not be displayed in the UI
935 }
936 }
937 break;
938 }
939
941 {
942 SfxStyleInfo_Impl* pFamily = static_cast<SfxStyleInfo_Impl*>(pInfo->pObject);
943 if (pFamily)
944 {
945 const std::vector< SfxStyleInfo_Impl > lStyles = m_pStylesInfo->getStyles(pFamily->sFamily);
946 for (auto const& lStyle : lStyles)
947 {
948 SfxStyleInfo_Impl* pStyle = new SfxStyleInfo_Impl(lStyle);
949 m_pFunctionListBox->aArr.push_back(std::make_unique<SfxGroupInfo_Impl>(SfxCfgKind::GROUP_STYLES, 0, pStyle));
950 m_pFunctionListBox->aArr.back()->sCommand = pStyle->sCommand;
951 m_pFunctionListBox->aArr.back()->sLabel = pStyle->sLabel;
952 OUString sId(weld::toId(m_pFunctionListBox->aArr.back().get()));
954 }
955 }
956 break;
957 }
958
960 {
961 sfx2::sidebar::ResourceManager aResourceManager;
962 sfx2::sidebar::Context aContext(m_sModuleLongName, OUString());
964 aResourceManager.GetMatchingDecks(aDecks, aContext, false, m_xFrame->getController());
965
966 for (auto const& rDeck : aDecks)
967 {
968 const OUString sCommand = ".uno:SidebarDeck." + rDeck.msId;
969 m_pFunctionListBox->aArr.push_back(std::make_unique<SfxGroupInfo_Impl>(
971 nullptr));
972 m_pFunctionListBox->aArr.back()->sCommand = sCommand;
973 m_pFunctionListBox->aArr.back()->sLabel = rDeck.msId;
974 m_pFunctionListBox->aArr.back()->sTooltip =
977 rDeck.msId);
978 }
979
980 break;
981 }
982
983 default:
984 // Do nothing, the list box will stay empty
985 SAL_INFO( "cui.customize", "Ignoring unexpected SfxCfgKind: " << static_cast<int>(pInfo->nKind) );
986 break;
987 }
988
990
993}
994
995/* Description
996 A basic or a library is opened.
997*/
998IMPL_LINK(CuiConfigGroupListBox, ExpandingHdl, const weld::TreeIter&, rIter, bool)
999{
1000 SfxGroupInfo_Impl *pInfo = weld::fromId<SfxGroupInfo_Impl*>(m_xTreeView->get_id(rIter));
1001 switch ( pInfo->nKind )
1002 {
1004 {
1005 if (!m_xTreeView->iter_has_child(rIter))
1006 {
1007 Reference< browse::XBrowseNode > rootNode(
1008 static_cast< browse::XBrowseNode* >( pInfo->pObject ) ) ;
1009 FillScriptList(rootNode, &rIter);
1010 }
1011 break;
1012 }
1013
1015 {
1016 if (!m_xTreeView->iter_has_child(rIter))
1017 {
1018 const std::vector<SfxStyleInfo_Impl> lStyleFamilies = m_pStylesInfo->getStyleFamilies();
1019 for (auto const& lStyleFamily : lStyleFamilies)
1020 {
1021 SfxStyleInfo_Impl* pFamily = new SfxStyleInfo_Impl(lStyleFamily);
1022 aArr.push_back( std::make_unique<SfxGroupInfo_Impl>( SfxCfgKind::GROUP_STYLES, 0, pFamily ));
1023 OUString sId(weld::toId(aArr.back().get()));
1024 m_xTreeView->insert(&rIter, -1, &pFamily->sLabel, &sId, nullptr, nullptr, false, nullptr);
1025 }
1026 }
1027 break;
1028 }
1029
1030 default:
1031 OSL_FAIL( "Wrong group type!" );
1032 break;
1033 }
1034 return true;
1035}
1036
1037#if HAVE_FEATURE_SCRIPTING
1038void CuiConfigGroupListBox::SelectMacro( const SfxMacroInfoItem *pItem )
1039{
1040 auto const rMacro = pItem->GetQualifiedName();
1041 sal_Int32 nIdx {rMacro.lastIndexOf('.')};
1042 const std::u16string_view aMethod( rMacro.subView(nIdx + 1) );
1043 std::u16string_view aLib;
1044 std::u16string_view aModule;
1045 if ( nIdx>0 )
1046 {
1047 // string contains at least 2 tokens
1048 nIdx = rMacro.lastIndexOf('.', nIdx);
1049 if (nIdx != -1)
1050 {
1051 // string contains at least 3 tokens
1052 aLib = o3tl::getToken(rMacro, 0, '.' );
1053 sal_Int32 nIdx2 = nIdx + 1;
1054 aModule = o3tl::getToken(rMacro, 0, '.', nIdx2 );
1055 }
1056 }
1057
1058 std::unique_ptr<weld::TreeIter> xIter = m_xTreeView->make_iterator();
1059 if (!m_xTreeView->get_iter_first(*xIter))
1060 return;
1061
1062 do
1063 {
1064 OUString aEntryBas = m_xTreeView->get_text(*xIter);
1065 if (aEntryBas == xImp->m_sDlgMacros)
1066 {
1067 m_xTreeView->expand_row(*xIter);
1068 std::unique_ptr<weld::TreeIter> xLocationIter = m_xTreeView->make_iterator(xIter.get());
1069 if (m_xTreeView->iter_children(*xLocationIter))
1070 {
1071 do
1072 {
1073 m_xTreeView->expand_row(*xLocationIter);
1074 std::unique_ptr<weld::TreeIter> xLibIter = m_xTreeView->make_iterator(xLocationIter.get());
1075 if (m_xTreeView->iter_children(*xLibIter))
1076 {
1077 do
1078 {
1079 OUString aEntryLib = m_xTreeView->get_text(*xLibIter);
1080 if (aEntryLib == aLib)
1081 {
1082 m_xTreeView->expand_row(*xLibIter);
1083 std::unique_ptr<weld::TreeIter> xModIter = m_xTreeView->make_iterator(xLibIter.get());
1084 if (m_xTreeView->iter_children(*xModIter))
1085 {
1086 do
1087 {
1088 OUString aEntryMod = m_xTreeView->get_text(*xModIter);
1089 if ( aEntryMod == aModule )
1090 {
1091 m_xTreeView->expand_row(*xModIter);
1092 m_xTreeView->scroll_to_row(*xModIter);
1093 m_xTreeView->select(*xModIter);
1094 GroupSelected();
1095 for (int i = 0, nCount = m_pFunctionListBox->n_children(); i < nCount; ++i)
1096 {
1097 OUString aEntryMethod = m_pFunctionListBox->get_text(i);
1098 if (aEntryMethod == aMethod)
1099 {
1102 return;
1103 }
1104 }
1105 m_xTreeView->collapse_row(*xModIter);
1106 }
1107 } while (m_xTreeView->iter_next_sibling(*xModIter));
1108 }
1109 m_xTreeView->collapse_row(*xLibIter);
1110 }
1111 } while (m_xTreeView->iter_next_sibling(*xLibIter));
1112 }
1113 m_xTreeView->collapse_row(*xLocationIter);
1114 } while (m_xTreeView->iter_next_sibling(*xLocationIter));
1115 }
1116 // If the macro can't be located, preselect the "Application Macros" category:
1117 m_xTreeView->scroll_to_row(*xIter);
1118 m_xTreeView->select(*xIter);
1119 return;
1120 }
1121 } while (m_xTreeView->iter_next_sibling(*xIter));
1122}
1123#endif
1124
1125/*
1126 * Implementation of SvxScriptSelectorDialog
1127 *
1128 * This dialog is used for selecting Slot API commands
1129 * and Scripting Framework Scripts.
1130 */
1131
1133 weld::Window* pParent, const css::uno::Reference< css::frame::XFrame >& xFrame)
1134 : GenericDialogController(pParent, "cui/ui/macroselectordialog.ui", "MacroSelectorDialog")
1135 , m_xDialogDescription(m_xBuilder->weld_label("helpmacro"))
1136 , m_xCategories(new CuiConfigGroupListBox(m_xBuilder->weld_tree_view("categories")))
1137 , m_xCommands(new CuiConfigFunctionListBox(m_xBuilder->weld_tree_view("commands")))
1138 , m_xLibraryFT(m_xBuilder->weld_label("libraryft"))
1139 , m_xMacronameFT(m_xBuilder->weld_label("macronameft"))
1140 , m_xOKButton(m_xBuilder->weld_button("ok"))
1141 , m_xCancelButton(m_xBuilder->weld_button("cancel"))
1142 , m_xDescriptionText(m_xBuilder->weld_text_view("description"))
1143 , m_xDescriptionFrame(m_xBuilder->weld_frame("descriptionframe"))
1144{
1145 m_xCancelButton->show();
1146 m_xDialogDescription->show();
1147 m_xOKButton->show();
1148
1149 m_xLibraryFT->set_visible(true);
1150 m_xMacronameFT->set_visible(true);
1151
1152 const OUString aModuleName(vcl::CommandInfoProvider::GetModuleIdentifier(xFrame));
1153 m_xCategories->SetFunctionListBox(m_xCommands.get());
1154 m_xCategories->Init(comphelper::getProcessComponentContext(), xFrame, aModuleName, /*bShowSlots*/false);
1155
1156 m_xCategories->connect_changed(
1157 LINK( this, SvxScriptSelectorDialog, SelectHdl ) );
1158 m_xCommands->connect_changed( LINK( this, SvxScriptSelectorDialog, SelectHdl ) );
1159 m_xCommands->connect_row_activated( LINK( this, SvxScriptSelectorDialog, FunctionDoubleClickHdl ) );
1160 m_xCommands->connect_popup_menu( LINK( this, SvxScriptSelectorDialog, ContextMenuHdl ) );
1161
1162 m_xOKButton->connect_clicked( LINK( this, SvxScriptSelectorDialog, ClickHdl ) );
1163 m_xCancelButton->connect_clicked( LINK( this, SvxScriptSelectorDialog, ClickHdl ) );
1164
1165 m_sDefaultDesc = m_xDescriptionText->get_text();
1166
1167 // Support style commands
1170 if (xFrame.is())
1171 xController = xFrame->getController();
1172 if (xController.is())
1173 xModel = xController->getModel();
1174
1175 m_aStylesInfo.init(aModuleName, xModel);
1176 m_xCategories->SetStylesInfo(&m_aStylesInfo);
1177
1178 // The following call is a workaround to make scroll_to_row work as expected in kf5/x11
1179 m_xDialog->resize_to_request();
1180
1182 UpdateUI();
1183
1185 m_xDescriptionFrame->hide();
1186}
1187
1189{
1190}
1191
1193{
1194 if (&rCtrl == &m_xCategories->get_widget())
1195 {
1196 m_xCategories->GroupSelected();
1197 }
1198 UpdateUI();
1199}
1200
1202{
1203 if (m_xOKButton->get_sensitive())
1204 ClickHdl(*m_xOKButton);
1205 return true;
1206}
1207
1208IMPL_LINK(SvxScriptSelectorDialog, ContextMenuHdl, const CommandEvent&, rCEvt, bool)
1209{
1210 weld::TreeView& xTreeView = m_xCommands->get_widget();
1211 if (rCEvt.GetCommand() != CommandEventId::ContextMenu || !xTreeView.n_children())
1212 return false;
1213
1214 std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(&xTreeView, "modules/BasicIDE/ui/sortmenu.ui"));
1215 std::unique_ptr<weld::Menu> xPopup(xBuilder->weld_menu("sortmenu"));
1216 std::unique_ptr<weld::Menu> xDropMenu(xBuilder->weld_menu("sortsubmenu"));
1217 xDropMenu->set_active("alphabetically", xTreeView.get_sort_order());
1218 xDropMenu->set_active("properorder", !xTreeView.get_sort_order());
1219
1220 OUString sCommand(xPopup->popup_at_rect(&xTreeView, tools::Rectangle(rCEvt.GetMousePosPixel(), Size(1,1))));
1221 if (sCommand == "alphabetically")
1222 {
1223 xTreeView.make_sorted();
1224 }
1225 else if (sCommand == "properorder")
1226 {
1227 xTreeView.make_unsorted();
1228 m_xCategories->GroupSelected();
1229 }
1230 else if (!sCommand.isEmpty())
1231 {
1232 SAL_WARN("cui.customize", "Unknown context menu action: " << sCommand );
1233 }
1234
1235 return true;
1236}
1237
1238// Check if command is selected and enable the OK button accordingly
1239// Grab the help text for this id if available and update the description field
1240void
1242{
1243 OUString url = GetScriptURL();
1244 if ( !url.isEmpty() )
1245 {
1246 OUString sMessage = m_xCommands->GetHelpText();
1247 m_xDescriptionText->set_text(sMessage.isEmpty() ? m_sDefaultDesc : sMessage);
1248 m_xOKButton->set_sensitive(true);
1249 }
1250 else
1251 {
1253 m_xOKButton->set_sensitive(false);
1254 }
1255}
1256
1258{
1259 if (&rButton == m_xCancelButton.get())
1260 {
1261 m_xDialog->response(RET_CANCEL);
1262 }
1263 else if (&rButton == m_xOKButton.get())
1264 {
1265 SaveLastUsedMacro();
1266 m_xDialog->response(RET_OK);
1267 }
1268}
1269
1270void
1272{
1273 m_xOKButton->set_label(CuiResId(RID_CUISTR_SELECTOR_RUN));
1274}
1275
1276OUString
1278{
1279 OUString result;
1280
1281 std::unique_ptr<weld::TreeIter> xIter = m_xCommands->make_iterator();
1282 if (m_xCommands->get_selected(xIter.get()))
1283 {
1284 SfxGroupInfo_Impl *pData = weld::fromId<SfxGroupInfo_Impl*>(m_xCommands->get_id(*xIter));
1285 if ( ( pData->nKind == SfxCfgKind::FUNCTION_SLOT )
1286 || ( pData->nKind == SfxCfgKind::FUNCTION_SCRIPT )
1287 || ( pData->nKind == SfxCfgKind::GROUP_STYLES )
1288 )
1289 {
1290 result = pData->sCommand;
1291 }
1292 }
1293
1294 return result;
1295}
1296
1297void
1299{
1300 // Gets the current selection in the dialog as a series of selected entries
1301 OUString sMacroInfo;
1302 sMacroInfo = m_xCommands->get_selected_text();
1303 weld::TreeView& xCategories = m_xCategories->get_widget();
1304 std::unique_ptr<weld::TreeIter> xIter = xCategories.make_iterator();
1305
1306 if (!xCategories.get_selected(xIter.get()))
1307 return;
1308
1309 do
1310 {
1311 sMacroInfo = xCategories.get_text(*xIter) + "|" + sMacroInfo;
1312 } while (xCategories.iter_parent(*xIter));
1313
1315 LAST_RUN_MACRO_INFO, Any(sMacroInfo));
1316}
1317
1318void
1320{
1321 SvtViewOptions aDlgOpt( EViewType::Dialog, MACRO_SELECTOR_CONFIGNAME );
1322 if (!aDlgOpt.Exists())
1323 return;
1324
1325 OUString sMacroInfo;
1326 aDlgOpt.GetUserItem(LAST_RUN_MACRO_INFO) >>= sMacroInfo;
1327 if (sMacroInfo.isEmpty())
1328 return;
1329
1330 // Counts how many entries exist in the macro info string
1331 sal_Int16 nInfoParts = 0;
1332 sal_Int16 nLastIndex = sMacroInfo.indexOf('|');
1333 if (nLastIndex > -1)
1334 {
1335 nInfoParts = 1;
1336 while ( nLastIndex != -1 )
1337 {
1338 nInfoParts++;
1339 nLastIndex = sMacroInfo.indexOf('|', nLastIndex + 1);
1340 }
1341 }
1342
1343 weld::TreeView& xCategories = m_xCategories->get_widget();
1344 std::unique_ptr<weld::TreeIter> xIter = xCategories.make_iterator();
1345 if (!xCategories.get_iter_first(*xIter))
1346 return;
1347
1348 // Expand the nodes in the category tree
1349 OUString sNodeToExpand;
1350 bool bIsIterValid;
1351 sal_Int16 nOpenedNodes = 0;
1352 for (sal_Int16 i=0; i<nInfoParts - 1; i++)
1353 {
1354 sNodeToExpand = sMacroInfo.getToken(i, '|');
1355 bIsIterValid = true;
1356 while (bIsIterValid && xCategories.get_text(*xIter) != sNodeToExpand)
1357 bIsIterValid = xCategories.iter_next_sibling(*xIter);
1358
1359 if (bIsIterValid)
1360 {
1361 xCategories.expand_row(*xIter);
1362 nOpenedNodes++;
1363 }
1364 if (xCategories.iter_has_child(*xIter))
1365 (void)xCategories.iter_children(*xIter);
1366 else if (nOpenedNodes < nInfoParts - 1)
1367 // If the number of levels in the tree is smaller than the
1368 // number of parts in the macro info string, then return
1369 return;
1370 }
1371 xCategories.select(*xIter);
1372 xCategories.scroll_to_row(*xIter);
1373 m_xCategories->GroupSelected();
1374
1375 // Select the macro in the command tree
1376 weld::TreeView& xCommands = m_xCommands->get_widget();
1377 xIter = xCommands.make_iterator();
1378 if (!xCommands.get_iter_first(*xIter))
1379 return;
1380
1381 OUString sMacroName = sMacroInfo.getToken(nInfoParts - 1, '|');
1382 bIsIterValid = true;
1383 while (bIsIterValid && xCommands.get_text(*xIter) != sMacroName)
1384 bIsIterValid = xCommands.iter_next_sibling(*xIter);
1385
1386 if (bIsIterValid)
1387 {
1388 xCommands.scroll_to_row(*xIter);
1389 xCommands.select(*xIter);
1390 }
1391}
1392
1393/* 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:1201
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:625
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:716
static css::uno::Reference< css::uno::XInterface > getDocumentModel(css::uno::Reference< css::uno::XComponentContext > const &xCtx, std::u16string_view docName)
Definition: cfgutil.cxx:778
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
sal_Int32 InitModule()
Definition: cfgutil.cxx:472
css::uno::Reference< css::container::XNameAccess > m_xGlobalCategoryInfo
Definition: cfgutil.hxx:191
OUString MapCommand2UIName(const OUString &sCommand)
Definition: cfgutil.cxx:805
void FillFunctionsList(const css::uno::Sequence< css::frame::DispatchInformation > &xCommands)
Definition: cfgutil.cxx:607
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:511
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:1132
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:1277
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:1188
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()
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