1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
23 #include <sal/log.hxx>
24 #include <sfx2/objsh.hxx>
25 #include <vcl/svapp.hxx>
26 #include <vcl/weld.hxx>
28 #include <strings.hrc>
29 #include <bitmaps.hlst>
30 #include <scriptdlg.hxx>
31 #include <dialmgr.hxx>
33 #include <com/sun/star/uno/XComponentContext.hpp>
34 #include <com/sun/star/script/provider/ScriptFrameworkErrorException.hpp>
35 #include <com/sun/star/script/provider/XScriptProviderSupplier.hpp>
36 #include <com/sun/star/script/provider/XScriptProvider.hpp>
37 #include <com/sun/star/script/browse/BrowseNodeTypes.hpp>
38 #include <com/sun/star/script/browse/XBrowseNodeFactory.hpp>
39 #include <com/sun/star/script/browse/BrowseNodeFactoryViewTypes.hpp>
40 #include <com/sun/star/script/browse/theBrowseNodeFactory.hpp>
41 #include <com/sun/star/script/provider/ScriptErrorRaisedException.hpp>
42 #include <com/sun/star/script/provider/ScriptExceptionRaisedException.hpp>
43 #include <com/sun/star/script/provider/ScriptFrameworkErrorType.hpp>
44 #include <com/sun/star/frame/Desktop.hpp>
45 #include <com/sun/star/frame/ModuleManager.hpp>
46 #include <com/sun/star/script/XInvocation.hpp>
47 #include <com/sun/star/document/XEmbeddedScripts.hpp>
49 #include <comphelper/SetFlagContextHelper.hxx>
50 #include <comphelper/documentinfo.hxx>
51 #include <comphelper/processfactory.hxx>
53 #include <svtools/imagemgr.hxx>
54 #include <tools/urlobj.hxx>
55 #include <tools/diagnose_ex.h>
57 using namespace ::com::sun::star
;
58 using namespace css::uno
;
59 using namespace css::script
;
60 using namespace css::frame
;
61 using namespace css::document
;
63 static void ShowErrorDialog( const Any
& aException
)
65 ScopedVclPtrInstance
<SvxScriptErrorDialog
> pDlg( aException
);
69 void SvxScriptOrgDialog::delUserData(const weld::TreeIter
& rIter
)
71 SFEntry
* pUserData
= reinterpret_cast<SFEntry
*>(m_xScriptsBox
->get_id(rIter
).toInt64());
75 // TBD seem to get a Select event on node that is remove ( below )
76 // so need to be able to detect that this node is not to be
77 // processed in order to do this, setting userData to NULL ( must
78 // be a better way to do this )
79 m_xScriptsBox
->set_id(rIter
, OUString());
83 void SvxScriptOrgDialog::deleteTree(weld::TreeIter
& rIter
)
86 std::unique_ptr
<weld::TreeIter
> xIter
= m_xScriptsBox
->make_iterator(&rIter
);
87 if (!m_xScriptsBox
->iter_children(*xIter
))
90 std::unique_ptr
<weld::TreeIter
> xAltIter
= m_xScriptsBox
->make_iterator();
94 m_xScriptsBox
->copy_iterator(*xIter
, *xAltIter
);
95 bNextEntry
= m_xScriptsBox
->iter_next_sibling(*xAltIter
);
97 m_xScriptsBox
->remove(*xIter
);
98 m_xScriptsBox
->copy_iterator(*xAltIter
, *xIter
);
103 void SvxScriptOrgDialog::deleteAllTree()
105 std::unique_ptr
<weld::TreeIter
> xIter
= m_xScriptsBox
->make_iterator();
106 if (!m_xScriptsBox
->get_iter_first(*xIter
))
109 std::unique_ptr
<weld::TreeIter
> xAltIter
= m_xScriptsBox
->make_iterator();
110 // TBD - below is a candidate for a destroyAllTrees method
114 m_xScriptsBox
->copy_iterator(*xIter
, *xAltIter
);
115 bNextEntry
= m_xScriptsBox
->iter_next_sibling(*xAltIter
);
117 m_xScriptsBox
->remove(*xIter
);
118 m_xScriptsBox
->copy_iterator(*xAltIter
, *xIter
);
123 void SvxScriptOrgDialog::Init( const OUString
& language
)
125 m_xScriptsBox
->freeze();
129 Reference
< browse::XBrowseNode
> rootNode
;
130 Reference
< XComponentContext
> xCtx(
131 comphelper::getProcessComponentContext() );
133 Sequence
< Reference
< browse::XBrowseNode
> > children
;
135 OUString
userStr("user");
136 OUString
const shareStr("share");
140 Reference
< browse::XBrowseNodeFactory
> xFac
= browse::theBrowseNodeFactory::get(xCtx
);
142 rootNode
.set( xFac
->createView(
143 browse::BrowseNodeFactoryViewTypes::MACROORGANIZER
) );
145 if ( rootNode
.is() && rootNode
->hasChildNodes() )
147 children
= rootNode
->getChildNodes();
150 catch( const Exception
& )
152 TOOLS_WARN_EXCEPTION("cui.dialogs", "Exception getting root browse node from factory");
153 // TODO exception handling
156 Reference
<XModel
> xDocumentModel
;
157 for ( sal_Int32 n
= 0; n
< children
.getLength(); n
++ )
160 OUString uiName
= children
[ n
]->getName();
162 if ( uiName
== userStr
|| uiName
== shareStr
)
165 if ( uiName
== userStr
)
167 uiName
= m_sMyMacros
;
171 uiName
= m_sProdMacros
;
176 xDocumentModel
.set(getDocumentModel(xCtx
, uiName
), UNO_QUERY
);
178 if ( xDocumentModel
.is() )
180 Reference
< frame::XModuleManager2
> xModuleManager( frame::ModuleManager::create(xCtx
) );
182 // get the long name of the document:
183 Sequence
<beans::PropertyValue
> moduleDescr
;
185 OUString appModule
= xModuleManager
->identify( xDocumentModel
);
186 xModuleManager
->getByName(appModule
) >>= moduleDescr
;
187 } catch(const uno::Exception
&)
190 beans::PropertyValue
const * pmoduleDescr
=
191 moduleDescr
.getConstArray();
192 for ( sal_Int32 pos
= moduleDescr
.getLength(); pos
--; )
194 if ( pmoduleDescr
[ pos
].Name
== "ooSetupFactoryEmptyDocumentURL" )
196 pmoduleDescr
[ pos
].Value
>>= factoryURL
;
203 Reference
< browse::XBrowseNode
> langEntries
=
204 getLangNodeFromRootNode( children
[ n
], language
);
206 insertEntry( uiName
, app
? OUStringLiteral(RID_CUIBMP_HARDDISK
) : OUStringLiteral(RID_CUIBMP_DOC
),
207 nullptr, true, std::make_unique
< SFEntry
>( langEntries
, xDocumentModel
), factoryURL
, false );
210 m_xScriptsBox
->thaw();
213 Reference
< XInterface
>
214 SvxScriptOrgDialog::getDocumentModel( Reference
< XComponentContext
> const & xCtx
, OUString
const & docName
)
216 Reference
< XInterface
> xModel
;
217 Reference
< frame::XDesktop2
> desktop
= frame::Desktop::create(xCtx
);
219 Reference
< container::XEnumerationAccess
> componentsAccess
=
220 desktop
->getComponents();
221 Reference
< container::XEnumeration
> components
=
222 componentsAccess
->createEnumeration();
223 while (components
->hasMoreElements())
225 Reference
< frame::XModel
> model(
226 components
->nextElement(), UNO_QUERY
);
229 OUString sTdocUrl
= ::comphelper::DocumentInfo::getDocumentTitle( model
);
230 if( sTdocUrl
== docName
)
240 Reference
< browse::XBrowseNode
>
241 SvxScriptOrgDialog::getLangNodeFromRootNode( Reference
< browse::XBrowseNode
> const & rootNode
, OUString
const & language
)
243 Reference
< browse::XBrowseNode
> langNode
;
248 const Sequence
<Reference
<browse::XBrowseNode
>> children
= rootNode
->getChildNodes();
249 const auto it
= std::find_if(children
.begin(), children
.end(),
250 [&](const Reference
<browse::XBrowseNode
>& child
) {
251 return child
->getName() == language
;
253 return (it
!= children
.end()) ? *it
: nullptr;
256 // First try without Java interaction, to avoid warnings for non-JRE-dependent providers
257 css::uno::ContextLayer
layer(comphelper::NoEnableJavaInteractionContext());
258 langNode
= tryFind();
262 // Now try with Java interaction enabled
263 langNode
= tryFind();
268 // if getChildNodes() throws an exception we just return
269 // the empty Reference
274 void SvxScriptOrgDialog::RequestSubEntries(const weld::TreeIter
& rRootEntry
, Reference
< css::script::browse::XBrowseNode
> const & node
,
275 Reference
< XModel
>& model
)
282 Sequence
< Reference
< browse::XBrowseNode
> > children
;
285 children
= node
->getChildNodes();
289 // if we catch an exception in getChildNodes then no entries are added
292 for ( sal_Int32 n
= 0; n
< children
.getLength(); n
++ )
294 OUString
name( children
[ n
]->getName() );
295 if ( children
[ n
]->getType() != browse::BrowseNodeTypes::SCRIPT
)
297 insertEntry(name
, RID_CUIBMP_LIB
, &rRootEntry
, true, std::make_unique
<SFEntry
>(children
[n
], model
), false);
301 insertEntry(name
, RID_CUIBMP_MACRO
, &rRootEntry
, false, std::make_unique
<SFEntry
>(children
[n
], model
), false);
306 void SvxScriptOrgDialog::insertEntry(const OUString
& rText
, const OUString
& rBitmap
,
307 const weld::TreeIter
* pParent
, bool bChildrenOnDemand
, std::unique_ptr
<SFEntry
> && aUserData
,
308 const OUString
& factoryURL
, bool bSelect
)
310 if (rBitmap
== RID_CUIBMP_DOC
&& !factoryURL
.isEmpty())
312 OUString aImage
= SvFileInformationManager::GetFileImageId(INetURLObject(factoryURL
));
313 insertEntry(rText
, aImage
, pParent
, bChildrenOnDemand
, std::move(aUserData
), bSelect
);
316 insertEntry(rText
, rBitmap
, pParent
, bChildrenOnDemand
, std::move(aUserData
), bSelect
);
319 void SvxScriptOrgDialog::insertEntry(
320 const OUString
& rText
, const OUString
& rBitmap
, const weld::TreeIter
* pParent
,
321 bool bChildrenOnDemand
, std::unique_ptr
<SFEntry
> && aUserData
, bool bSelect
)
323 std::unique_ptr
<weld::TreeIter
> xRetIter
;
325 xRetIter
= m_xScriptsBox
->make_iterator();
326 OUString
sId(OUString::number(reinterpret_cast<sal_Int64
>(aUserData
.release()))); // XXX possible leak
327 m_xScriptsBox
->insert(pParent
, -1, &rText
, &sId
, nullptr, nullptr, &rBitmap
,
328 bChildrenOnDemand
, xRetIter
.get());
331 m_xScriptsBox
->set_cursor(*xRetIter
);
332 m_xScriptsBox
->select(*xRetIter
);
336 IMPL_LINK(SvxScriptOrgDialog
, ExpandingHdl
, const weld::TreeIter
&, rIter
, bool)
338 SFEntry
* userData
= reinterpret_cast<SFEntry
*>(m_xScriptsBox
->get_id(rIter
).toInt64());
340 Reference
< browse::XBrowseNode
> node
;
341 Reference
< XModel
> model
;
342 if ( userData
&& !userData
->isLoaded() )
344 node
= userData
->GetNode();
345 model
= userData
->GetModel();
346 RequestSubEntries(rIter
, node
, model
);
347 userData
->setLoaded();
353 // CuiInputDialog ------------------------------------------------------------
354 CuiInputDialog::CuiInputDialog(weld::Window
* pParent
, InputDialogMode nMode
)
355 : GenericDialogController(pParent
, "cui/ui/newlibdialog.ui", "NewLibDialog")
356 , m_xEdit(m_xBuilder
->weld_entry("entry"))
358 m_xEdit
->grab_focus();
360 std::unique_ptr
<weld::Label
> xNewLibFT(m_xBuilder
->weld_label("newlibft"));
362 if ( nMode
== InputDialogMode::NEWMACRO
)
365 std::unique_ptr
<weld::Label
> xNewMacroFT(m_xBuilder
->weld_label("newmacroft"));
367 std::unique_ptr
<weld::Label
> xAltTitle(m_xBuilder
->weld_label("altmacrotitle"));
368 m_xDialog
->set_title(xAltTitle
->get_label());
370 else if ( nMode
== InputDialogMode::RENAME
)
373 std::unique_ptr
<weld::Label
> xRenameFT(m_xBuilder
->weld_label("renameft"));
375 std::unique_ptr
<weld::Label
> xAltTitle(m_xBuilder
->weld_label("altrenametitle"));
376 m_xDialog
->set_title(xAltTitle
->get_label());
380 // ScriptOrgDialog ------------------------------------------------------------
382 SvxScriptOrgDialog::SvxScriptOrgDialog(weld::Window
* pParent
, const OUString
& language
)
383 : SfxDialogController(pParent
, "cui/ui/scriptorganizer.ui", "ScriptOrganizerDialog")
384 , m_sLanguage(language
)
385 , m_delErrStr(CuiResId(RID_SVXSTR_DELFAILED
))
386 , m_delErrTitleStr(CuiResId(RID_SVXSTR_DELFAILED_TITLE
))
387 , m_delQueryStr(CuiResId(RID_SVXSTR_DELQUERY
))
388 , m_delQueryTitleStr(CuiResId(RID_SVXSTR_DELQUERY_TITLE
))
389 , m_createErrStr(CuiResId(RID_SVXSTR_CREATEFAILED
))
390 , m_createDupStr(CuiResId(RID_SVXSTR_CREATEFAILEDDUP
))
391 , m_createErrTitleStr(CuiResId(RID_SVXSTR_CREATEFAILED_TITLE
))
392 , m_renameErrStr(CuiResId(RID_SVXSTR_RENAMEFAILED
))
393 , m_renameErrTitleStr(CuiResId(RID_SVXSTR_RENAMEFAILED_TITLE
))
394 , m_sMyMacros(CuiResId(RID_SVXSTR_MYMACROS
))
395 , m_sProdMacros(CuiResId(RID_SVXSTR_PRODMACROS
))
396 , m_xScriptsBox(m_xBuilder
->weld_tree_view("scripts"))
397 , m_xRunButton(m_xBuilder
->weld_button("ok"))
398 , m_xCloseButton(m_xBuilder
->weld_button("close"))
399 , m_xCreateButton(m_xBuilder
->weld_button("create"))
400 , m_xEditButton(m_xBuilder
->weld_button("edit"))
401 , m_xRenameButton(m_xBuilder
->weld_button("rename"))
402 , m_xDelButton(m_xBuilder
->weld_button("delete"))
404 // must be a neater way to deal with the strings than as above
405 // append the language to the dialog title
406 OUString
winTitle(m_xDialog
->get_title());
407 winTitle
= winTitle
.replaceFirst( "%MACROLANG", m_sLanguage
);
408 m_xDialog
->set_title(winTitle
);
410 m_xScriptsBox
->set_size_request(m_xScriptsBox
->get_approximate_digit_width() * 45,
411 m_xScriptsBox
->get_height_rows(12));
413 m_xScriptsBox
->connect_changed( LINK( this, SvxScriptOrgDialog
, ScriptSelectHdl
) );
414 m_xScriptsBox
->connect_expanding(LINK( this, SvxScriptOrgDialog
, ExpandingHdl
) );
415 m_xRunButton
->connect_clicked( LINK( this, SvxScriptOrgDialog
, ButtonHdl
) );
416 m_xCloseButton
->connect_clicked( LINK( this, SvxScriptOrgDialog
, ButtonHdl
) );
417 m_xRenameButton
->connect_clicked( LINK( this, SvxScriptOrgDialog
, ButtonHdl
) );
418 m_xEditButton
->connect_clicked( LINK( this, SvxScriptOrgDialog
, ButtonHdl
) );
419 m_xDelButton
->connect_clicked( LINK( this, SvxScriptOrgDialog
, ButtonHdl
) );
420 m_xCreateButton
->connect_clicked( LINK( this, SvxScriptOrgDialog
, ButtonHdl
) );
422 m_xRunButton
->set_sensitive(false);
423 m_xRenameButton
->set_sensitive(false);
424 m_xEditButton
->set_sensitive(false);
425 m_xDelButton
->set_sensitive(false);
426 m_xCreateButton
->set_sensitive(false);
429 RestorePreviousSelection();
432 SvxScriptOrgDialog::~SvxScriptOrgDialog()
437 short SvxScriptOrgDialog::run()
439 SfxObjectShell
*pDoc
= SfxObjectShell::GetFirst();
441 // force load of MSPs for all documents
444 Reference
< provider::XScriptProviderSupplier
> xSPS( pDoc
->GetModel(), UNO_QUERY
);
447 xSPS
->getScriptProvider();
450 pDoc
= SfxObjectShell::GetNext(*pDoc
);
453 return SfxDialogController::run();
456 void SvxScriptOrgDialog::CheckButtons( Reference
< browse::XBrowseNode
> const & node
)
460 if ( node
->getType() == browse::BrowseNodeTypes::SCRIPT
)
462 m_xRunButton
->set_sensitive(true);
466 m_xRunButton
->set_sensitive(false);
468 Reference
< beans::XPropertySet
> xProps( node
, UNO_QUERY
);
472 m_xEditButton
->set_sensitive(false);
473 m_xDelButton
->set_sensitive(false);
474 m_xCreateButton
->set_sensitive(false);
475 m_xRunButton
->set_sensitive(false);
479 OUString
sName("Editable");
481 if ( getBoolProperty( xProps
, sName
) )
483 m_xEditButton
->set_sensitive(true);
487 m_xEditButton
->set_sensitive(false);
492 if ( getBoolProperty( xProps
, sName
) )
494 m_xDelButton
->set_sensitive(true);
498 m_xDelButton
->set_sensitive(false);
503 if ( getBoolProperty( xProps
, sName
) )
505 m_xCreateButton
->set_sensitive(true);
509 m_xCreateButton
->set_sensitive(false);
514 if ( getBoolProperty( xProps
, sName
) )
516 m_xRenameButton
->set_sensitive(true);
520 m_xRenameButton
->set_sensitive(false);
525 // no node info available, disable all configurable actions
526 m_xDelButton
->set_sensitive(false);
527 m_xCreateButton
->set_sensitive(false);
528 m_xEditButton
->set_sensitive(false);
529 m_xRunButton
->set_sensitive(false);
530 m_xRenameButton
->set_sensitive(false);
534 IMPL_LINK_NOARG(SvxScriptOrgDialog
, ScriptSelectHdl
, weld::TreeView
&, void)
536 std::unique_ptr
<weld::TreeIter
> xIter
= m_xScriptsBox
->make_iterator();
537 if (!m_xScriptsBox
->get_selected(xIter
.get()))
540 SFEntry
* userData
= reinterpret_cast<SFEntry
*>(m_xScriptsBox
->get_id(*xIter
).toInt64());
542 Reference
< browse::XBrowseNode
> node
;
545 node
= userData
->GetNode();
550 IMPL_LINK(SvxScriptOrgDialog
, ButtonHdl
, weld::Button
&, rButton
, void)
552 if ( &rButton
== m_xCloseButton
.get() )
554 StoreCurrentSelection();
555 m_xDialog
->response(RET_CANCEL
);
557 if (&rButton
== m_xEditButton
.get() ||
558 &rButton
== m_xCreateButton
.get() ||
559 &rButton
== m_xDelButton
.get() ||
560 &rButton
== m_xRunButton
.get() ||
561 &rButton
== m_xRenameButton
.get())
564 std::unique_ptr
<weld::TreeIter
> xIter
= m_xScriptsBox
->make_iterator();
565 if (!m_xScriptsBox
->get_selected(xIter
.get()))
567 SFEntry
* userData
= reinterpret_cast<SFEntry
*>(m_xScriptsBox
->get_id(*xIter
).toInt64());
571 Reference
< browse::XBrowseNode
> node
;
572 Reference
< XModel
> xModel
;
574 node
= userData
->GetNode();
575 xModel
= userData
->GetModel();
582 if (&rButton
== m_xRunButton
.get())
585 Reference
< beans::XPropertySet
> xProp( node
, UNO_QUERY
);
586 Reference
< provider::XScriptProvider
> mspNode
;
594 Reference
< XEmbeddedScripts
> xEmbeddedScripts( xModel
, UNO_QUERY
);
595 if( !xEmbeddedScripts
.is() )
600 if (!xEmbeddedScripts
->getAllowMacroExecution())
602 // Please FIXME: Show a message box if AllowMacroExecution is false
607 std::unique_ptr
<weld::TreeIter
> xParentIter
= m_xScriptsBox
->make_iterator(xIter
.get());
608 bool bParent
= m_xScriptsBox
->iter_parent(*xParentIter
);
609 while (bParent
&& !mspNode
.is() )
611 SFEntry
* mspUserData
= reinterpret_cast<SFEntry
*>(m_xScriptsBox
->get_id(*xParentIter
).toInt64());
612 mspNode
.set( mspUserData
->GetNode() , UNO_QUERY
);
613 bParent
= m_xScriptsBox
->iter_parent(*xParentIter
);
615 xProp
->getPropertyValue("URI") >>= tmpString
;
616 const OUString
scriptURL( tmpString
);
622 Reference
< provider::XScript
> xScript(
623 mspNode
->getScript( scriptURL
), UNO_SET_THROW
);
625 const Sequence
< Any
> args(0);
626 Sequence
< sal_Int16
> outIndex
;
627 Sequence
< Any
> outArgs( 0 );
628 xScript
->invoke( args
, outIndex
, outArgs
);
630 catch ( reflection::InvocationTargetException
& ite
)
632 ShowErrorDialog(css::uno::Any(ite
));
634 catch ( provider::ScriptFrameworkErrorException
& ite
)
636 ShowErrorDialog(css::uno::Any(ite
));
638 catch ( RuntimeException
& re
)
640 ShowErrorDialog(css::uno::Any(re
));
642 catch ( Exception
& e
)
644 ShowErrorDialog(css::uno::Any(e
));
647 StoreCurrentSelection();
648 m_xDialog
->response(RET_CANCEL
);
650 else if ( &rButton
== m_xEditButton
.get() )
652 Reference
< script::XInvocation
> xInv( node
, UNO_QUERY
);
655 StoreCurrentSelection();
656 m_xDialog
->response(RET_CANCEL
);
657 Sequence
< Any
> args(0);
658 Sequence
< Any
> outArgs( 0 );
659 Sequence
< sal_Int16
> outIndex
;
662 // ISSUE need code to run script here
663 xInv
->invoke( "Editable", args
, outIndex
, outArgs
);
665 catch( Exception
const & )
667 TOOLS_WARN_EXCEPTION("cui.dialogs", "Caught exception trying to invoke" );
671 else if ( &rButton
== m_xCreateButton
.get() )
675 else if ( &rButton
== m_xDelButton
.get() )
679 else if ( &rButton
== m_xRenameButton
.get() )
686 Reference
< browse::XBrowseNode
> SvxScriptOrgDialog::getBrowseNode(const weld::TreeIter
& rEntry
)
688 Reference
< browse::XBrowseNode
> node
;
689 SFEntry
* userData
= reinterpret_cast<SFEntry
*>(m_xScriptsBox
->get_id(rEntry
).toInt64());
692 node
= userData
->GetNode();
697 Reference
< XModel
> SvxScriptOrgDialog::getModel(const weld::TreeIter
& rEntry
)
699 Reference
< XModel
> model
;
700 SFEntry
* userData
= reinterpret_cast<SFEntry
*>(m_xScriptsBox
->get_id(rEntry
).toInt64());
703 model
= userData
->GetModel();
708 void SvxScriptOrgDialog::createEntry(weld::TreeIter
& rEntry
)
711 Reference
< browse::XBrowseNode
> aChildNode
;
712 Reference
< browse::XBrowseNode
> node
= getBrowseNode( rEntry
);
713 Reference
< script::XInvocation
> xInv( node
, UNO_QUERY
);
718 OUString aNewStdName
;
719 InputDialogMode nMode
= InputDialogMode::NEWLIB
;
720 if (m_xScriptsBox
->get_iter_depth(rEntry
) == 0)
722 aNewStdName
= "Library" ;
726 aNewStdName
= "Macro" ;
727 nMode
= InputDialogMode::NEWMACRO
;
729 //do we need L10N for this? ie something like:
730 //String aNewStdName( ResId( STR_STDMODULENAME ) );
734 Sequence
< Reference
< browse::XBrowseNode
> > childNodes
;
735 // no children => ok to create Parcel1 or Script1 without checking
738 if( !node
->hasChildNodes() )
740 aNewName
= aNewStdName
+ OUString::number(i
);
745 childNodes
= node
->getChildNodes();
750 // ignore, will continue on with empty sequence
756 aNewName
= aNewStdName
+ OUString::number(i
);
758 if(childNodes
.hasElements() )
760 OUString nodeName
= childNodes
[0]->getName();
761 sal_Int32 extnPos
= nodeName
.lastIndexOf( '.' );
763 extn
= nodeName
.copy(extnPos
);
765 for( sal_Int32 index
= 0; index
< childNodes
.getLength(); index
++ )
767 if (aNewName
+extn
== childNodes
[index
]->getName())
783 CuiInputDialog
aNewDlg(m_xDialog
.get(), nMode
);
784 aNewDlg
.SetObjectName(aNewName
);
788 if (aNewDlg
.run() && !aNewDlg
.GetObjectName().isEmpty())
790 OUString aUserSuppliedName
= aNewDlg
.GetObjectName();
792 for( sal_Int32 index
= 0; index
< childNodes
.getLength(); index
++ )
794 if (aUserSuppliedName
+extn
== childNodes
[index
]->getName())
797 OUString aError
= m_createErrStr
+ m_createDupStr
;
799 std::unique_ptr
<weld::MessageDialog
> xErrorBox(Application::CreateMessageDialog(m_xDialog
.get(),
800 VclMessageType::Warning
, VclButtonsType::Ok
, aError
));
801 xErrorBox
->set_title(m_createErrTitleStr
);
803 aNewDlg
.SetObjectName(aNewName
);
808 aNewName
= aUserSuppliedName
;
812 // user hit cancel or hit OK with nothing in the editbox
819 // open up parent node (which ensures it's loaded)
820 m_xScriptsBox
->expand_row(rEntry
);
822 Sequence
< Any
> args( 1 );
823 args
[ 0 ] <<= aNewName
;
824 Sequence
< Any
> outArgs( 0 );
825 Sequence
< sal_Int16
> outIndex
;
828 Any aResult
= xInv
->invoke( "Creatable", args
, outIndex
, outArgs
);
829 Reference
< browse::XBrowseNode
> newNode( aResult
, UNO_QUERY
);
830 aChildNode
= newNode
;
833 catch( Exception
const & )
835 TOOLS_WARN_EXCEPTION("cui.dialogs", "Caught exception trying to Create" );
838 if ( aChildNode
.is() )
840 OUString aChildName
= aChildNode
->getName();
842 Reference
<XModel
> xDocumentModel
= getModel( rEntry
);
844 // ISSUE do we need to remove all entries for parent
845 // to achieve sort? Just need to determine position
846 // -- Basic doesn't do this on create.
847 // Suppose we could avoid this too. -> created nodes are
848 // not in alphabetical order
849 if ( aChildNode
->getType() == browse::BrowseNodeTypes::SCRIPT
)
851 insertEntry(aChildName
, RID_CUIBMP_MACRO
, &rEntry
, false,
852 std::make_unique
<SFEntry
>(aChildNode
,xDocumentModel
), true);
856 insertEntry(aChildName
, RID_CUIBMP_LIB
, &rEntry
, false,
857 std::make_unique
<SFEntry
>(aChildNode
,xDocumentModel
), true);
859 // If the Parent is not loaded then set to
860 // loaded, this will prevent RequestingChildren ( called
861 // from vcl via RequestingChildren ) from
862 // creating new ( duplicate ) children
863 SFEntry
* userData
= reinterpret_cast<SFEntry
*>(m_xScriptsBox
->get_id(rEntry
).toInt64());
864 if ( userData
&& !userData
->isLoaded() )
866 userData
->setLoaded();
872 //ISSUE L10N & message from exception?
873 OUString
aError( m_createErrStr
);
874 std::unique_ptr
<weld::MessageDialog
> xErrorBox(Application::CreateMessageDialog(m_xDialog
.get(),
875 VclMessageType::Warning
, VclButtonsType::Ok
, aError
));
876 xErrorBox
->set_title(m_createErrTitleStr
);
881 void SvxScriptOrgDialog::renameEntry(const weld::TreeIter
& rEntry
)
884 Reference
< browse::XBrowseNode
> aChildNode
;
885 Reference
< browse::XBrowseNode
> node
= getBrowseNode(rEntry
);
886 Reference
< script::XInvocation
> xInv( node
, UNO_QUERY
);
890 OUString aNewName
= node
->getName();
891 sal_Int32 extnPos
= aNewName
.lastIndexOf( '.' );
894 aNewName
= aNewName
.copy(0,extnPos
);
896 CuiInputDialog
aNewDlg(m_xDialog
.get(), InputDialogMode::RENAME
);
897 aNewDlg
.SetObjectName(aNewName
);
899 if (!aNewDlg
.run() || aNewDlg
.GetObjectName().isEmpty())
900 return; // user hit cancel or hit OK with nothing in the editbox
902 aNewName
= aNewDlg
.GetObjectName();
904 Sequence
< Any
> args( 1 );
905 args
[ 0 ] <<= aNewName
;
906 Sequence
< Any
> outArgs( 0 );
907 Sequence
< sal_Int16
> outIndex
;
910 Any aResult
= xInv
->invoke( "Renamable", args
, outIndex
, outArgs
);
911 Reference
< browse::XBrowseNode
> newNode( aResult
, UNO_QUERY
);
912 aChildNode
= newNode
;
915 catch( Exception
const & )
917 TOOLS_WARN_EXCEPTION("cui.dialogs", "Caught exception trying to Rename" );
920 if ( aChildNode
.is() )
922 m_xScriptsBox
->set_text(rEntry
, aChildNode
->getName());
923 m_xScriptsBox
->set_cursor(rEntry
);
924 m_xScriptsBox
->select(rEntry
);
929 //ISSUE L10N & message from exception?
930 OUString
aError( m_renameErrStr
);
931 std::unique_ptr
<weld::MessageDialog
> xErrorBox(Application::CreateMessageDialog(m_xDialog
.get(),
932 VclMessageType::Warning
, VclButtonsType::Ok
, aError
));
933 xErrorBox
->set_title(m_renameErrTitleStr
);
938 void SvxScriptOrgDialog::deleteEntry(weld::TreeIter
& rEntry
)
941 Reference
< browse::XBrowseNode
> node
= getBrowseNode(rEntry
);
942 // ISSUE L10N string & can we centre list?
943 OUString aQuery
= m_delQueryStr
+ getListOfChildren( node
, 0 );
944 std::unique_ptr
<weld::MessageDialog
> xQueryBox(Application::CreateMessageDialog(m_xDialog
.get(),
945 VclMessageType::Question
, VclButtonsType::YesNo
, aQuery
));
946 xQueryBox
->set_title(m_delQueryTitleStr
);
947 if (xQueryBox
->run() == RET_NO
)
952 Reference
< script::XInvocation
> xInv( node
, UNO_QUERY
);
955 Sequence
< Any
> args( 0 );
956 Sequence
< Any
> outArgs( 0 );
957 Sequence
< sal_Int16
> outIndex
;
960 Any aResult
= xInv
->invoke( "Deletable", args
, outIndex
, outArgs
);
961 aResult
>>= result
; // or do we just assume true if no exception ?
963 catch( Exception
const & )
965 TOOLS_WARN_EXCEPTION("cui.dialogs", "Caught exception trying to delete" );
972 m_xScriptsBox
->remove(rEntry
);
976 //ISSUE L10N & message from exception?
977 std::unique_ptr
<weld::MessageDialog
> xErrorBox(Application::CreateMessageDialog(m_xDialog
.get(),
978 VclMessageType::Warning
, VclButtonsType::Ok
, m_delErrStr
));
979 xErrorBox
->set_title(m_delErrTitleStr
);
985 bool SvxScriptOrgDialog::getBoolProperty( Reference
< beans::XPropertySet
> const & xProps
,
986 OUString
const & propName
)
991 xProps
->getPropertyValue( propName
) >>= result
;
1000 OUString
SvxScriptOrgDialog::getListOfChildren( const Reference
< browse::XBrowseNode
>& node
, int depth
)
1002 OUStringBuffer result
= "\n";
1003 for( int i
=0;i
<=depth
;i
++ )
1005 result
.append("\t");
1007 result
.append(node
->getName());
1011 if ( node
->hasChildNodes() )
1013 Sequence
< Reference
< browse::XBrowseNode
> > children
1014 = node
->getChildNodes();
1015 for ( sal_Int32 n
= 0; n
< children
.getLength(); n
++ )
1017 result
.append( getListOfChildren( children
[ n
] , depth
+1 ) );
1021 catch ( Exception
& )
1023 // ignore, will return an empty string
1026 return result
.makeStringAndClear();
1029 Selection_hash
SvxScriptOrgDialog::m_lastSelection
;
1031 void SvxScriptOrgDialog::StoreCurrentSelection()
1033 std::unique_ptr
<weld::TreeIter
> xIter
= m_xScriptsBox
->make_iterator();
1034 if (!m_xScriptsBox
->get_selected(xIter
.get()))
1036 OUString aDescription
;
1040 aDescription
= m_xScriptsBox
->get_text(*xIter
) + aDescription
;
1041 bEntry
= m_xScriptsBox
->iter_parent(*xIter
);
1043 aDescription
= ";" + aDescription
;
1046 OUString
sDesc( aDescription
);
1047 m_lastSelection
[ m_sLanguage
] = sDesc
;
1050 void SvxScriptOrgDialog::RestorePreviousSelection()
1052 OUString aStoredEntry
= m_lastSelection
[ m_sLanguage
];
1053 if( aStoredEntry
.isEmpty() )
1055 std::unique_ptr
<weld::TreeIter
> xEntry
;
1056 std::unique_ptr
<weld::TreeIter
> xTmpEntry(m_xScriptsBox
->make_iterator());
1057 sal_Int32 nIndex
= 0;
1058 while (nIndex
!= -1)
1060 OUString
aTmp( aStoredEntry
.getToken( 0, ';', nIndex
) );
1065 xEntry
= m_xScriptsBox
->make_iterator();
1066 bTmpEntry
= m_xScriptsBox
->get_iter_first(*xEntry
);
1067 m_xScriptsBox
->copy_iterator(*xEntry
, *xTmpEntry
);
1071 m_xScriptsBox
->copy_iterator(*xEntry
, *xTmpEntry
);
1072 bTmpEntry
= m_xScriptsBox
->iter_children(*xTmpEntry
);
1077 if (m_xScriptsBox
->get_text(*xTmpEntry
) == aTmp
)
1079 m_xScriptsBox
->copy_iterator(*xTmpEntry
, *xEntry
);
1082 bTmpEntry
= m_xScriptsBox
->iter_next_sibling(*xTmpEntry
);
1088 m_xScriptsBox
->expand_row(*xEntry
);
1092 m_xScriptsBox
->set_cursor(*xEntry
);
1097 OUString
ReplaceString(
1098 const OUString
& source
,
1099 const OUString
& token
,
1100 const OUString
& value
)
1102 sal_Int32 pos
= source
.indexOf( token
);
1104 if ( pos
!= -1 && !value
.isEmpty() )
1106 return source
.replaceAt( pos
, token
.getLength(), value
);
1114 OUString
FormatErrorString(
1115 const OUString
& unformatted
,
1116 const OUString
& language
,
1117 const OUString
& script
,
1118 const OUString
& line
,
1119 const OUString
& type
,
1120 const OUString
& message
)
1122 OUString result
= unformatted
.copy( 0 );
1124 result
= ReplaceString(result
, "%LANGUAGENAME", language
);
1125 result
= ReplaceString(result
, "%SCRIPTNAME", script
);
1126 result
= ReplaceString(result
, "%LINENUMBER", line
);
1128 if ( !type
.isEmpty() )
1130 result
+= "\n\n" + CuiResId(RID_SVXSTR_ERROR_TYPE_LABEL
) + " " + type
;
1133 if ( !message
.isEmpty() )
1135 result
+= "\n\n" + CuiResId(RID_SVXSTR_ERROR_MESSAGE_LABEL
) + " " + message
;
1141 OUString
GetErrorMessage(
1142 const provider::ScriptErrorRaisedException
& eScriptError
)
1144 OUString unformatted
= CuiResId( RID_SVXSTR_ERROR_AT_LINE
);
1146 OUString
unknown("UNKNOWN");
1147 OUString language
= unknown
;
1148 OUString script
= unknown
;
1149 OUString line
= unknown
;
1151 OUString message
= eScriptError
.Message
;
1153 if ( !eScriptError
.language
.isEmpty() )
1155 language
= eScriptError
.language
;
1158 if ( !eScriptError
.scriptName
.isEmpty() )
1160 script
= eScriptError
.scriptName
;
1163 if ( !eScriptError
.Message
.isEmpty() )
1165 message
= eScriptError
.Message
;
1167 if ( eScriptError
.lineNum
!= -1 )
1169 line
= OUString::number( eScriptError
.lineNum
);
1170 unformatted
= CuiResId( RID_SVXSTR_ERROR_AT_LINE
);
1174 unformatted
= CuiResId( RID_SVXSTR_ERROR_RUNNING
);
1177 return FormatErrorString(
1178 unformatted
, language
, script
, line
, type
, message
);
1181 OUString
GetErrorMessage(
1182 const provider::ScriptExceptionRaisedException
& eScriptException
)
1184 OUString unformatted
= CuiResId( RID_SVXSTR_EXCEPTION_AT_LINE
);
1186 OUString
unknown("UNKNOWN");
1187 OUString language
= unknown
;
1188 OUString script
= unknown
;
1189 OUString line
= unknown
;
1190 OUString type
= unknown
;
1191 OUString message
= eScriptException
.Message
;
1193 if ( !eScriptException
.language
.isEmpty() )
1195 language
= eScriptException
.language
;
1197 if ( !eScriptException
.scriptName
.isEmpty() )
1199 script
= eScriptException
.scriptName
;
1202 if ( !eScriptException
.Message
.isEmpty() )
1204 message
= eScriptException
.Message
;
1207 if ( eScriptException
.lineNum
!= -1 )
1209 line
= OUString::number( eScriptException
.lineNum
);
1210 unformatted
= CuiResId( RID_SVXSTR_EXCEPTION_AT_LINE
);
1214 unformatted
= CuiResId( RID_SVXSTR_EXCEPTION_RUNNING
);
1217 if ( !eScriptException
.exceptionType
.isEmpty() )
1219 type
= eScriptException
.exceptionType
;
1222 return FormatErrorString(
1223 unformatted
, language
, script
, line
, type
, message
);
1226 OUString
GetErrorMessage(
1227 const provider::ScriptFrameworkErrorException
& sError
)
1229 OUString unformatted
= CuiResId( RID_SVXSTR_FRAMEWORK_ERROR_RUNNING
);
1231 OUString
language("UNKNOWN");
1233 OUString
script("UNKNOWN");
1237 if ( !sError
.scriptName
.isEmpty() )
1239 script
= sError
.scriptName
;
1241 if ( !sError
.language
.isEmpty() )
1243 language
= sError
.language
;
1245 if ( sError
.errorType
== provider::ScriptFrameworkErrorType::NOTSUPPORTED
)
1248 CuiResId( RID_SVXSTR_ERROR_LANG_NOT_SUPPORTED
);
1249 message
= ReplaceString(message
, "%LANGUAGENAME", language
);
1254 message
= sError
.Message
;
1256 return FormatErrorString(
1257 unformatted
, language
, script
, OUString(), OUString(), message
);
1260 OUString
GetErrorMessage( const css::uno::Any
& aException
)
1262 if ( aException
.getValueType() ==
1263 cppu::UnoType
<reflection::InvocationTargetException
>::get())
1265 reflection::InvocationTargetException ite
;
1267 if ( ite
.TargetException
.getValueType() == cppu::UnoType
<provider::ScriptErrorRaisedException
>::get())
1269 // Error raised by script
1270 provider::ScriptErrorRaisedException scriptError
;
1271 ite
.TargetException
>>= scriptError
;
1272 return GetErrorMessage( scriptError
);
1274 else if ( ite
.TargetException
.getValueType() == cppu::UnoType
<provider::ScriptExceptionRaisedException
>::get())
1276 // Exception raised by script
1277 provider::ScriptExceptionRaisedException scriptException
;
1278 ite
.TargetException
>>= scriptException
;
1279 return GetErrorMessage( scriptException
);
1283 // Unknown error, shouldn't happen
1288 else if ( aException
.getValueType() == cppu::UnoType
<provider::ScriptFrameworkErrorException
>::get())
1290 // A Script Framework error has occurred
1291 provider::ScriptFrameworkErrorException sfe
;
1293 return GetErrorMessage( sfe
);
1296 // unknown exception
1297 auto msg
= aException
.getValueTypeName();
1299 if ( (aException
>>= e
) && !e
.Message
.isEmpty() )
1301 msg
+= ": " + e
.Message
;
1308 SvxScriptErrorDialog::SvxScriptErrorDialog( css::uno::Any
const & aException
)
1311 SolarMutexGuard aGuard
;
1312 m_sMessage
= GetErrorMessage( aException
);
1315 SvxScriptErrorDialog::~SvxScriptErrorDialog()
1319 short SvxScriptErrorDialog::Execute()
1321 // Show Error dialog asynchronously
1323 // Pass a copy of the message to the ShowDialog method as the
1324 // SvxScriptErrorDialog may be deleted before ShowDialog is called
1325 Application::PostUserEvent(
1326 LINK( this, SvxScriptErrorDialog
, ShowDialog
),
1327 new OUString( m_sMessage
) );
1332 IMPL_STATIC_LINK( SvxScriptErrorDialog
, ShowDialog
, void*, p
, void )
1334 OUString
* pMessage
= static_cast<OUString
*>(p
);
1337 if ( pMessage
&& !pMessage
->isEmpty() )
1339 message
= *pMessage
;
1343 message
= CuiResId( RID_SVXSTR_ERROR_TITLE
);
1346 std::unique_ptr
<weld::MessageDialog
> xBox(Application::CreateMessageDialog(nullptr,
1347 VclMessageType::Warning
, VclButtonsType::Ok
, message
));
1348 xBox
->set_title(CuiResId(RID_SVXSTR_ERROR_TITLE
));
1354 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */