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>
32 #include <cfgutil.hxx>
34 #include <com/sun/star/uno/XComponentContext.hpp>
35 #include <com/sun/star/script/provider/ScriptFrameworkErrorException.hpp>
36 #include <com/sun/star/script/provider/XScriptProviderSupplier.hpp>
37 #include <com/sun/star/script/provider/XScriptProvider.hpp>
38 #include <com/sun/star/script/browse/BrowseNodeTypes.hpp>
39 #include <com/sun/star/script/browse/XBrowseNodeFactory.hpp>
40 #include <com/sun/star/script/browse/BrowseNodeFactoryViewTypes.hpp>
41 #include <com/sun/star/script/browse/theBrowseNodeFactory.hpp>
42 #include <com/sun/star/script/provider/ScriptErrorRaisedException.hpp>
43 #include <com/sun/star/script/provider/ScriptExceptionRaisedException.hpp>
44 #include <com/sun/star/script/provider/ScriptFrameworkErrorType.hpp>
45 #include <com/sun/star/frame/Desktop.hpp>
46 #include <com/sun/star/frame/ModuleManager.hpp>
47 #include <com/sun/star/script/XInvocation.hpp>
48 #include <com/sun/star/document/XEmbeddedScripts.hpp>
50 #include <comphelper/documentinfo.hxx>
51 #include <comphelper/processfactory.hxx>
53 #include <basic/sbx.hxx>
54 #include <svtools/imagemgr.hxx>
55 #include <tools/urlobj.hxx>
56 #include <tools/diagnose_ex.h>
60 using namespace ::com::sun::star
;
61 using namespace css::uno
;
62 using namespace css::script
;
63 using namespace css::frame
;
64 using namespace css::document
;
66 static void ShowErrorDialog( const Any
& aException
)
68 ScopedVclPtrInstance
<SvxScriptErrorDialog
> pDlg( aException
);
72 void SvxScriptOrgDialog::delUserData(weld::TreeIter
& rIter
)
74 SFEntry
* pUserData
= reinterpret_cast<SFEntry
*>(m_xScriptsBox
->get_id(rIter
).toInt64());
78 // TBD seem to get a Select event on node that is remove ( below )
79 // so need to be able to detect that this node is not to be
80 // processed in order to do this, setting userData to NULL ( must
81 // be a better way to do this )
82 m_xScriptsBox
->set_id(rIter
, OUString());
86 void SvxScriptOrgDialog::deleteTree(weld::TreeIter
& rIter
)
89 std::unique_ptr
<weld::TreeIter
> xIter
= m_xScriptsBox
->make_iterator(&rIter
);
90 if (!m_xScriptsBox
->iter_children(*xIter
))
93 std::unique_ptr
<weld::TreeIter
> xAltIter
= m_xScriptsBox
->make_iterator();
97 m_xScriptsBox
->copy_iterator(*xIter
, *xAltIter
);
98 bNextEntry
= m_xScriptsBox
->iter_next_sibling(*xAltIter
);
100 m_xScriptsBox
->remove(*xIter
);
101 m_xScriptsBox
->copy_iterator(*xAltIter
, *xIter
);
106 void SvxScriptOrgDialog::deleteAllTree()
108 std::unique_ptr
<weld::TreeIter
> xIter
= m_xScriptsBox
->make_iterator();
109 if (!m_xScriptsBox
->get_iter_first(*xIter
))
112 std::unique_ptr
<weld::TreeIter
> xAltIter
= m_xScriptsBox
->make_iterator();
113 // TBD - below is a candidate for a destroyAllTrees method
117 m_xScriptsBox
->copy_iterator(*xIter
, *xAltIter
);
118 bNextEntry
= m_xScriptsBox
->iter_next_sibling(*xAltIter
);
120 m_xScriptsBox
->remove(*xIter
);
121 m_xScriptsBox
->copy_iterator(*xAltIter
, *xIter
);
126 void SvxScriptOrgDialog::Init( const OUString
& language
)
128 m_xScriptsBox
->freeze();
132 Reference
< browse::XBrowseNode
> rootNode
;
133 Reference
< XComponentContext
> xCtx(
134 comphelper::getProcessComponentContext() );
136 Sequence
< Reference
< browse::XBrowseNode
> > children
;
138 OUString
userStr("user");
139 OUString
const shareStr("share");
143 Reference
< browse::XBrowseNodeFactory
> xFac
= browse::theBrowseNodeFactory::get(xCtx
);
145 rootNode
.set( xFac
->createView(
146 browse::BrowseNodeFactoryViewTypes::MACROORGANIZER
) );
148 if ( rootNode
.is() && rootNode
->hasChildNodes() )
150 children
= rootNode
->getChildNodes();
153 catch( Exception
& e
)
155 SAL_WARN("cui.dialogs", "Exception getting root browse node from factory: " << e
);
156 // TODO exception handling
159 Reference
<XModel
> xDocumentModel
;
160 for ( sal_Int32 n
= 0; n
< children
.getLength(); n
++ )
163 OUString uiName
= children
[ n
]->getName();
165 if ( uiName
== userStr
|| uiName
== shareStr
)
168 if ( uiName
== userStr
)
170 uiName
= m_sMyMacros
;
174 uiName
= m_sProdMacros
;
179 xDocumentModel
.set(getDocumentModel(xCtx
, uiName
), UNO_QUERY
);
181 if ( xDocumentModel
.is() )
183 Reference
< frame::XModuleManager2
> xModuleManager( frame::ModuleManager::create(xCtx
) );
185 // get the long name of the document:
186 Sequence
<beans::PropertyValue
> moduleDescr
;
188 OUString appModule
= xModuleManager
->identify( xDocumentModel
);
189 xModuleManager
->getByName(appModule
) >>= moduleDescr
;
190 } catch(const uno::Exception
&)
193 beans::PropertyValue
const * pmoduleDescr
=
194 moduleDescr
.getConstArray();
195 for ( sal_Int32 pos
= moduleDescr
.getLength(); pos
--; )
197 if ( pmoduleDescr
[ pos
].Name
== "ooSetupFactoryEmptyDocumentURL" )
199 pmoduleDescr
[ pos
].Value
>>= factoryURL
;
206 Reference
< browse::XBrowseNode
> langEntries
=
207 getLangNodeFromRootNode( children
[ n
], language
);
209 insertEntry( uiName
, app
? OUStringLiteral(RID_CUIBMP_HARDDISK
) : OUStringLiteral(RID_CUIBMP_DOC
),
210 nullptr, true, std::make_unique
< SFEntry
>( langEntries
, xDocumentModel
), factoryURL
, false );
213 m_xScriptsBox
->thaw();
216 Reference
< XInterface
>
217 SvxScriptOrgDialog::getDocumentModel( Reference
< XComponentContext
> const & xCtx
, OUString
const & docName
)
219 Reference
< XInterface
> xModel
;
220 Reference
< frame::XDesktop2
> desktop
= frame::Desktop::create(xCtx
);
222 Reference
< container::XEnumerationAccess
> componentsAccess
=
223 desktop
->getComponents();
224 Reference
< container::XEnumeration
> components
=
225 componentsAccess
->createEnumeration();
226 while (components
->hasMoreElements())
228 Reference
< frame::XModel
> model(
229 components
->nextElement(), UNO_QUERY
);
232 OUString sTdocUrl
= ::comphelper::DocumentInfo::getDocumentTitle( model
);
233 if( sTdocUrl
== docName
)
243 Reference
< browse::XBrowseNode
>
244 SvxScriptOrgDialog::getLangNodeFromRootNode( Reference
< browse::XBrowseNode
> const & rootNode
, OUString
const & language
)
246 Reference
< browse::XBrowseNode
> langNode
;
250 Sequence
< Reference
< browse::XBrowseNode
> > children
= rootNode
->getChildNodes();
251 for ( sal_Int32 n
= 0; n
< children
.getLength(); n
++ )
253 if ( children
[ n
]->getName() == language
)
255 langNode
= children
[ n
];
262 // if getChildNodes() throws an exception we just return
263 // the empty Reference
268 void SvxScriptOrgDialog::RequestSubEntries(const weld::TreeIter
& rRootEntry
, Reference
< css::script::browse::XBrowseNode
> const & node
,
269 Reference
< XModel
>& model
)
276 Sequence
< Reference
< browse::XBrowseNode
> > children
;
279 children
= node
->getChildNodes();
283 // if we catch an exception in getChildNodes then no entries are added
286 for ( sal_Int32 n
= 0; n
< children
.getLength(); n
++ )
288 OUString
name( children
[ n
]->getName() );
289 if ( children
[ n
]->getType() != browse::BrowseNodeTypes::SCRIPT
)
291 insertEntry(name
, RID_CUIBMP_LIB
, &rRootEntry
, true, std::make_unique
<SFEntry
>(children
[n
], model
), false);
295 insertEntry(name
, RID_CUIBMP_MACRO
, &rRootEntry
, false, std::make_unique
<SFEntry
>(children
[n
], model
), false);
300 void SvxScriptOrgDialog::insertEntry(const OUString
& rText
, const OUString
& rBitmap
,
301 const weld::TreeIter
* pParent
, bool bChildrenOnDemand
, std::unique_ptr
<SFEntry
> && aUserData
,
302 const OUString
& factoryURL
, bool bSelect
)
304 if (rBitmap
== RID_CUIBMP_DOC
&& !factoryURL
.isEmpty())
306 OUString aImage
= SvFileInformationManager::GetFileImageId(INetURLObject(factoryURL
));
307 insertEntry(rText
, aImage
, pParent
, bChildrenOnDemand
, std::move(aUserData
), bSelect
);
310 insertEntry(rText
, rBitmap
, pParent
, bChildrenOnDemand
, std::move(aUserData
), bSelect
);
313 void SvxScriptOrgDialog::insertEntry(
314 const OUString
& rText
, const OUString
& rBitmap
, const weld::TreeIter
* pParent
,
315 bool bChildrenOnDemand
, std::unique_ptr
<SFEntry
> && aUserData
, bool bSelect
)
317 std::unique_ptr
<weld::TreeIter
> xRetIter
;
319 xRetIter
= m_xScriptsBox
->make_iterator();
320 OUString
sId(OUString::number(reinterpret_cast<sal_Int64
>(aUserData
.release()))); // XXX possible leak
321 m_xScriptsBox
->insert(pParent
, -1, &rText
, &sId
, nullptr, nullptr, &rBitmap
,
322 bChildrenOnDemand
, xRetIter
.get());
325 m_xScriptsBox
->set_cursor(*xRetIter
);
326 m_xScriptsBox
->select(*xRetIter
);
330 IMPL_LINK(SvxScriptOrgDialog
, ExpandingHdl
, const weld::TreeIter
&, rIter
, bool)
332 SFEntry
* userData
= reinterpret_cast<SFEntry
*>(m_xScriptsBox
->get_id(rIter
).toInt64());
334 Reference
< browse::XBrowseNode
> node
;
335 Reference
< XModel
> model
;
336 if ( userData
&& !userData
->isLoaded() )
338 node
= userData
->GetNode();
339 model
= userData
->GetModel();
340 RequestSubEntries(rIter
, node
, model
);
341 userData
->setLoaded();
347 // CuiInputDialog ------------------------------------------------------------
348 CuiInputDialog::CuiInputDialog(weld::Window
* pParent
, InputDialogMode nMode
)
349 : GenericDialogController(pParent
, "cui/ui/newlibdialog.ui", "NewLibDialog")
350 , m_xEdit(m_xBuilder
->weld_entry("entry"))
352 m_xEdit
->grab_focus();
354 std::unique_ptr
<weld::Label
> xNewLibFT(m_xBuilder
->weld_label("newlibft"));
356 if ( nMode
== InputDialogMode::NEWMACRO
)
359 std::unique_ptr
<weld::Label
> xNewMacroFT(m_xBuilder
->weld_label("newmacroft"));
361 std::unique_ptr
<weld::Label
> xAltTitle(m_xBuilder
->weld_label("altmacrotitle"));
362 m_xDialog
->set_title(xAltTitle
->get_label());
364 else if ( nMode
== InputDialogMode::RENAME
)
367 std::unique_ptr
<weld::Label
> xRenameFT(m_xBuilder
->weld_label("renameft"));
369 std::unique_ptr
<weld::Label
> xAltTitle(m_xBuilder
->weld_label("altrenametitle"));
370 m_xDialog
->set_title(xAltTitle
->get_label());
374 // ScriptOrgDialog ------------------------------------------------------------
376 SvxScriptOrgDialog::SvxScriptOrgDialog(weld::Window
* pParent
, const OUString
& language
)
377 : SfxDialogController(pParent
, "cui/ui/scriptorganizer.ui", "ScriptOrganizerDialog")
378 , m_sLanguage(language
)
379 , m_delErrStr(CuiResId(RID_SVXSTR_DELFAILED
))
380 , m_delErrTitleStr(CuiResId(RID_SVXSTR_DELFAILED_TITLE
))
381 , m_delQueryStr(CuiResId(RID_SVXSTR_DELQUERY
))
382 , m_delQueryTitleStr(CuiResId(RID_SVXSTR_DELQUERY_TITLE
))
383 , m_createErrStr(CuiResId(RID_SVXSTR_CREATEFAILED
))
384 , m_createDupStr(CuiResId(RID_SVXSTR_CREATEFAILEDDUP
))
385 , m_createErrTitleStr(CuiResId(RID_SVXSTR_CREATEFAILED_TITLE
))
386 , m_renameErrStr(CuiResId(RID_SVXSTR_RENAMEFAILED
))
387 , m_renameErrTitleStr(CuiResId(RID_SVXSTR_RENAMEFAILED_TITLE
))
388 , m_sMyMacros(CuiResId(RID_SVXSTR_MYMACROS
))
389 , m_sProdMacros(CuiResId(RID_SVXSTR_PRODMACROS
))
390 , m_xScriptsBox(m_xBuilder
->weld_tree_view("scripts"))
391 , m_xRunButton(m_xBuilder
->weld_button("ok"))
392 , m_xCloseButton(m_xBuilder
->weld_button("close"))
393 , m_xCreateButton(m_xBuilder
->weld_button("create"))
394 , m_xEditButton(m_xBuilder
->weld_button("edit"))
395 , m_xRenameButton(m_xBuilder
->weld_button("rename"))
396 , m_xDelButton(m_xBuilder
->weld_button("delete"))
398 // must be a neater way to deal with the strings than as above
399 // append the language to the dialog title
400 OUString
winTitle(m_xDialog
->get_title());
401 winTitle
= winTitle
.replaceFirst( "%MACROLANG", m_sLanguage
);
402 m_xDialog
->set_title(winTitle
);
404 m_xScriptsBox
->set_size_request(m_xScriptsBox
->get_approximate_digit_width() * 45,
405 m_xScriptsBox
->get_height_rows(12));
407 m_xScriptsBox
->connect_changed( LINK( this, SvxScriptOrgDialog
, ScriptSelectHdl
) );
408 m_xScriptsBox
->connect_expanding(LINK( this, SvxScriptOrgDialog
, ExpandingHdl
) );
409 m_xRunButton
->connect_clicked( LINK( this, SvxScriptOrgDialog
, ButtonHdl
) );
410 m_xCloseButton
->connect_clicked( LINK( this, SvxScriptOrgDialog
, ButtonHdl
) );
411 m_xRenameButton
->connect_clicked( LINK( this, SvxScriptOrgDialog
, ButtonHdl
) );
412 m_xEditButton
->connect_clicked( LINK( this, SvxScriptOrgDialog
, ButtonHdl
) );
413 m_xDelButton
->connect_clicked( LINK( this, SvxScriptOrgDialog
, ButtonHdl
) );
414 m_xCreateButton
->connect_clicked( LINK( this, SvxScriptOrgDialog
, ButtonHdl
) );
416 m_xRunButton
->set_sensitive(false);
417 m_xRenameButton
->set_sensitive(false);
418 m_xEditButton
->set_sensitive(false);
419 m_xDelButton
->set_sensitive(false);
420 m_xCreateButton
->set_sensitive(false);
423 RestorePreviousSelection();
426 SvxScriptOrgDialog::~SvxScriptOrgDialog()
431 short SvxScriptOrgDialog::run()
433 SfxObjectShell
*pDoc
= SfxObjectShell::GetFirst();
435 // force load of MSPs for all documents
438 Reference
< provider::XScriptProviderSupplier
> xSPS
=
439 Reference
< provider::XScriptProviderSupplier
>
440 ( pDoc
->GetModel(), UNO_QUERY
);
443 xSPS
->getScriptProvider();
446 pDoc
= SfxObjectShell::GetNext(*pDoc
);
449 return SfxDialogController::run();
452 void SvxScriptOrgDialog::CheckButtons( Reference
< browse::XBrowseNode
> const & node
)
456 if ( node
->getType() == browse::BrowseNodeTypes::SCRIPT
)
458 m_xRunButton
->set_sensitive(true);
462 m_xRunButton
->set_sensitive(false);
464 Reference
< beans::XPropertySet
> xProps( node
, UNO_QUERY
);
468 m_xEditButton
->set_sensitive(false);
469 m_xDelButton
->set_sensitive(false);
470 m_xCreateButton
->set_sensitive(false);
471 m_xRunButton
->set_sensitive(false);
475 OUString
sName("Editable");
477 if ( getBoolProperty( xProps
, sName
) )
479 m_xEditButton
->set_sensitive(true);
483 m_xEditButton
->set_sensitive(false);
488 if ( getBoolProperty( xProps
, sName
) )
490 m_xDelButton
->set_sensitive(true);
494 m_xDelButton
->set_sensitive(false);
499 if ( getBoolProperty( xProps
, sName
) )
501 m_xCreateButton
->set_sensitive(true);
505 m_xCreateButton
->set_sensitive(false);
510 if ( getBoolProperty( xProps
, sName
) )
512 m_xRenameButton
->set_sensitive(true);
516 m_xRenameButton
->set_sensitive(false);
521 // no node info available, disable all configurable actions
522 m_xDelButton
->set_sensitive(false);
523 m_xCreateButton
->set_sensitive(false);
524 m_xEditButton
->set_sensitive(false);
525 m_xRunButton
->set_sensitive(false);
526 m_xRenameButton
->set_sensitive(false);
530 IMPL_LINK_NOARG(SvxScriptOrgDialog
, ScriptSelectHdl
, weld::TreeView
&, void)
532 std::unique_ptr
<weld::TreeIter
> xIter
= m_xScriptsBox
->make_iterator();
533 if (!m_xScriptsBox
->get_selected(xIter
.get()))
536 SFEntry
* userData
= reinterpret_cast<SFEntry
*>(m_xScriptsBox
->get_id(*xIter
).toInt64());
538 Reference
< browse::XBrowseNode
> node
;
541 node
= userData
->GetNode();
546 IMPL_LINK(SvxScriptOrgDialog
, ButtonHdl
, weld::Button
&, rButton
, void)
548 if ( &rButton
== m_xCloseButton
.get() )
550 StoreCurrentSelection();
551 m_xDialog
->response(RET_CANCEL
);
553 if (&rButton
== m_xEditButton
.get() ||
554 &rButton
== m_xCreateButton
.get() ||
555 &rButton
== m_xDelButton
.get() ||
556 &rButton
== m_xRunButton
.get() ||
557 &rButton
== m_xRenameButton
.get())
560 std::unique_ptr
<weld::TreeIter
> xIter
= m_xScriptsBox
->make_iterator();
561 if (!m_xScriptsBox
->get_selected(xIter
.get()))
563 SFEntry
* userData
= reinterpret_cast<SFEntry
*>(m_xScriptsBox
->get_id(*xIter
).toInt64());
567 Reference
< browse::XBrowseNode
> node
;
568 Reference
< XModel
> xModel
;
570 node
= userData
->GetNode();
571 xModel
= userData
->GetModel();
578 if (&rButton
== m_xRunButton
.get())
581 Reference
< beans::XPropertySet
> xProp( node
, UNO_QUERY
);
582 Reference
< provider::XScriptProvider
> mspNode
;
590 Reference
< XEmbeddedScripts
> xEmbeddedScripts( xModel
, UNO_QUERY
);
591 if( !xEmbeddedScripts
.is() )
596 if (!xEmbeddedScripts
->getAllowMacroExecution())
598 // Please FIXME: Show a message box if AllowMacroExecution is false
603 std::unique_ptr
<weld::TreeIter
> xParentIter
= m_xScriptsBox
->make_iterator(xIter
.get());
604 bool bParent
= m_xScriptsBox
->iter_parent(*xParentIter
);
605 while (bParent
&& !mspNode
.is() )
607 SFEntry
* mspUserData
= reinterpret_cast<SFEntry
*>(m_xScriptsBox
->get_id(*xParentIter
).toInt64());
608 mspNode
.set( mspUserData
->GetNode() , UNO_QUERY
);
609 bParent
= m_xScriptsBox
->iter_parent(*xParentIter
);
611 xProp
->getPropertyValue("URI") >>= tmpString
;
612 const OUString
scriptURL( tmpString
);
618 Reference
< provider::XScript
> xScript(
619 mspNode
->getScript( scriptURL
), UNO_SET_THROW
);
621 const Sequence
< Any
> args(0);
622 Sequence
< sal_Int16
> outIndex
;
623 Sequence
< Any
> outArgs( 0 );
624 xScript
->invoke( args
, outIndex
, outArgs
);
626 catch ( reflection::InvocationTargetException
& ite
)
628 ShowErrorDialog(css::uno::Any(ite
));
630 catch ( provider::ScriptFrameworkErrorException
& ite
)
632 ShowErrorDialog(css::uno::Any(ite
));
634 catch ( RuntimeException
& re
)
636 ShowErrorDialog(css::uno::Any(re
));
638 catch ( Exception
& e
)
640 ShowErrorDialog(css::uno::Any(e
));
643 StoreCurrentSelection();
644 m_xDialog
->response(RET_CANCEL
);
646 else if ( &rButton
== m_xEditButton
.get() )
648 Reference
< script::XInvocation
> xInv( node
, UNO_QUERY
);
651 StoreCurrentSelection();
652 m_xDialog
->response(RET_CANCEL
);
653 Sequence
< Any
> args(0);
654 Sequence
< Any
> outArgs( 0 );
655 Sequence
< sal_Int16
> outIndex
;
658 // ISSUE need code to run script here
659 xInv
->invoke( "Editable", args
, outIndex
, outArgs
);
661 catch( Exception
const & )
663 css::uno::Any
ex( cppu::getCaughtException() );
664 SAL_WARN("cui.dialogs", "Caught exception trying to invoke " << exceptionToString(ex
) );
668 else if ( &rButton
== m_xCreateButton
.get() )
672 else if ( &rButton
== m_xDelButton
.get() )
676 else if ( &rButton
== m_xRenameButton
.get() )
683 Reference
< browse::XBrowseNode
> SvxScriptOrgDialog::getBrowseNode(const weld::TreeIter
& rEntry
)
685 Reference
< browse::XBrowseNode
> node
;
686 SFEntry
* userData
= reinterpret_cast<SFEntry
*>(m_xScriptsBox
->get_id(rEntry
).toInt64());
689 node
= userData
->GetNode();
694 Reference
< XModel
> SvxScriptOrgDialog::getModel(const weld::TreeIter
& rEntry
)
696 Reference
< XModel
> model
;
697 SFEntry
* userData
= reinterpret_cast<SFEntry
*>(m_xScriptsBox
->get_id(rEntry
).toInt64());
700 model
= userData
->GetModel();
705 void SvxScriptOrgDialog::createEntry(weld::TreeIter
& rEntry
)
708 Reference
< browse::XBrowseNode
> aChildNode
;
709 Reference
< browse::XBrowseNode
> node
= getBrowseNode( rEntry
);
710 Reference
< script::XInvocation
> xInv( node
, UNO_QUERY
);
715 OUString aNewStdName
;
716 InputDialogMode nMode
= InputDialogMode::NEWLIB
;
717 if (m_xScriptsBox
->get_iter_depth(rEntry
) == 0)
719 aNewStdName
= "Library" ;
723 aNewStdName
= "Macro" ;
724 nMode
= InputDialogMode::NEWMACRO
;
726 //do we need L10N for this? ie something like:
727 //String aNewStdName( ResId( STR_STDMODULENAME ) );
731 Sequence
< Reference
< browse::XBrowseNode
> > childNodes
;
732 // no children => ok to create Parcel1 or Script1 without checking
735 if( !node
->hasChildNodes() )
737 aNewName
= aNewStdName
+ OUString::number(i
);
742 childNodes
= node
->getChildNodes();
747 // ignore, will continue on with empty sequence
753 aNewName
= aNewStdName
+ OUString::number(i
);
755 if(childNodes
.getLength() > 0 )
757 OUString nodeName
= childNodes
[0]->getName();
758 sal_Int32 extnPos
= nodeName
.lastIndexOf( '.' );
760 extn
= nodeName
.copy(extnPos
);
762 for( sal_Int32 index
= 0; index
< childNodes
.getLength(); index
++ )
764 if (aNewName
+extn
== childNodes
[index
]->getName())
780 CuiInputDialog
aNewDlg(m_xDialog
.get(), nMode
);
781 aNewDlg
.SetObjectName(aNewName
);
785 if (aNewDlg
.run() && !aNewDlg
.GetObjectName().isEmpty())
787 OUString aUserSuppliedName
= aNewDlg
.GetObjectName();
789 for( sal_Int32 index
= 0; index
< childNodes
.getLength(); index
++ )
791 if (aUserSuppliedName
+extn
== childNodes
[index
]->getName())
794 OUString aError
= m_createErrStr
+ m_createDupStr
;
796 std::unique_ptr
<weld::MessageDialog
> xErrorBox(Application::CreateMessageDialog(m_xDialog
.get(),
797 VclMessageType::Warning
, VclButtonsType::Ok
, aError
));
798 xErrorBox
->set_title(m_createErrTitleStr
);
800 aNewDlg
.SetObjectName(aNewName
);
805 aNewName
= aUserSuppliedName
;
809 // user hit cancel or hit OK with nothing in the editbox
816 // open up parent node (which ensures it's loaded)
817 m_xScriptsBox
->expand_row(rEntry
);
819 Sequence
< Any
> args( 1 );
820 args
[ 0 ] <<= aNewName
;
821 Sequence
< Any
> outArgs( 0 );
822 Sequence
< sal_Int16
> outIndex
;
825 Any aResult
= xInv
->invoke( "Creatable", args
, outIndex
, outArgs
);
826 Reference
< browse::XBrowseNode
> newNode( aResult
, UNO_QUERY
);
827 aChildNode
= newNode
;
830 catch( Exception
const & )
832 css::uno::Any
ex( cppu::getCaughtException() );
833 SAL_WARN("cui.dialogs", "Caught exception trying to Create " << exceptionToString(ex
) );
836 if ( aChildNode
.is() )
838 OUString aChildName
= aChildNode
->getName();
840 Reference
<XModel
> xDocumentModel
= getModel( rEntry
);
842 // ISSUE do we need to remove all entries for parent
843 // to achieve sort? Just need to determine position
844 // SvTreeListBox::InsertEntry can take position arg
845 // -- Basic doesn't do this on create.
846 // Suppose we could avoid this too. -> created nodes are
847 // not in alphabetical order
848 if ( aChildNode
->getType() == browse::BrowseNodeTypes::SCRIPT
)
850 insertEntry(aChildName
, RID_CUIBMP_MACRO
, &rEntry
, false,
851 std::make_unique
<SFEntry
>(aChildNode
,xDocumentModel
), true);
855 insertEntry(aChildName
, RID_CUIBMP_LIB
, &rEntry
, false,
856 std::make_unique
<SFEntry
>(aChildNode
,xDocumentModel
), true);
858 // If the Parent is not loaded then set to
859 // loaded, this will prevent RequestingChildren ( called
860 // from vcl via RequestingChildren ) from
861 // creating new ( duplicate ) children
862 SFEntry
* userData
= reinterpret_cast<SFEntry
*>(m_xScriptsBox
->get_id(rEntry
).toInt64());
863 if ( userData
&& !userData
->isLoaded() )
865 userData
->setLoaded();
871 //ISSUE L10N & message from exception?
872 OUString
aError( m_createErrStr
);
873 std::unique_ptr
<weld::MessageDialog
> xErrorBox(Application::CreateMessageDialog(m_xDialog
.get(),
874 VclMessageType::Warning
, VclButtonsType::Ok
, aError
));
875 xErrorBox
->set_title(m_createErrTitleStr
);
880 void SvxScriptOrgDialog::renameEntry(weld::TreeIter
& rEntry
)
883 Reference
< browse::XBrowseNode
> aChildNode
;
884 Reference
< browse::XBrowseNode
> node
= getBrowseNode(rEntry
);
885 Reference
< script::XInvocation
> xInv( node
, UNO_QUERY
);
889 OUString aNewName
= node
->getName();
890 sal_Int32 extnPos
= aNewName
.lastIndexOf( '.' );
893 aNewName
= aNewName
.copy(0,extnPos
);
895 CuiInputDialog
aNewDlg(m_xDialog
.get(), InputDialogMode::RENAME
);
896 aNewDlg
.SetObjectName(aNewName
);
898 if (!aNewDlg
.run() || aNewDlg
.GetObjectName().isEmpty())
899 return; // user hit cancel or hit OK with nothing in the editbox
901 aNewName
= aNewDlg
.GetObjectName();
903 Sequence
< Any
> args( 1 );
904 args
[ 0 ] <<= aNewName
;
905 Sequence
< Any
> outArgs( 0 );
906 Sequence
< sal_Int16
> outIndex
;
909 Any aResult
= xInv
->invoke( "Renamable", args
, outIndex
, outArgs
);
910 Reference
< browse::XBrowseNode
> newNode( aResult
, UNO_QUERY
);
911 aChildNode
= newNode
;
914 catch( Exception
const & )
916 css::uno::Any
ex( cppu::getCaughtException() );
917 SAL_WARN("cui.dialogs", "Caught exception trying to Rename " << exceptionToString(ex
) );
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 css::uno::Any
ex( cppu::getCaughtException() );
966 SAL_WARN("cui.dialogs", "Caught exception trying to delete " << exceptionToString(ex
) );
973 m_xScriptsBox
->remove(rEntry
);
977 //ISSUE L10N & message from exception?
978 std::unique_ptr
<weld::MessageDialog
> xErrorBox(Application::CreateMessageDialog(m_xDialog
.get(),
979 VclMessageType::Warning
, VclButtonsType::Ok
, m_delErrStr
));
980 xErrorBox
->set_title(m_delErrTitleStr
);
986 bool SvxScriptOrgDialog::getBoolProperty( Reference
< beans::XPropertySet
> const & xProps
,
987 OUString
const & propName
)
992 xProps
->getPropertyValue( propName
) >>= result
;
1001 OUString
SvxScriptOrgDialog::getListOfChildren( const Reference
< browse::XBrowseNode
>& node
, int depth
)
1003 OUStringBuffer result
= "\n";
1004 for( int i
=0;i
<=depth
;i
++ )
1006 result
.append("\t");
1008 result
.append(node
->getName());
1012 if ( node
->hasChildNodes() )
1014 Sequence
< Reference
< browse::XBrowseNode
> > children
1015 = node
->getChildNodes();
1016 for ( sal_Int32 n
= 0; n
< children
.getLength(); n
++ )
1018 result
.append( getListOfChildren( children
[ n
] , depth
+1 ) );
1022 catch ( Exception
& )
1024 // ignore, will return an empty string
1027 return result
.makeStringAndClear();
1030 Selection_hash
SvxScriptOrgDialog::m_lastSelection
;
1032 void SvxScriptOrgDialog::StoreCurrentSelection()
1034 std::unique_ptr
<weld::TreeIter
> xIter
= m_xScriptsBox
->make_iterator();
1035 if (!m_xScriptsBox
->get_selected(xIter
.get()))
1037 OUString aDescription
;
1041 aDescription
= m_xScriptsBox
->get_text(*xIter
) + aDescription
;
1042 bEntry
= m_xScriptsBox
->iter_parent(*xIter
);
1044 aDescription
= ";" + aDescription
;
1047 OUString
sDesc( aDescription
);
1048 m_lastSelection
[ m_sLanguage
] = sDesc
;
1051 void SvxScriptOrgDialog::RestorePreviousSelection()
1053 OUString aStoredEntry
= m_lastSelection
[ m_sLanguage
];
1054 if( aStoredEntry
.isEmpty() )
1056 std::unique_ptr
<weld::TreeIter
> xEntry
;
1057 std::unique_ptr
<weld::TreeIter
> xTmpEntry(m_xScriptsBox
->make_iterator());
1058 sal_Int32 nIndex
= 0;
1059 while (nIndex
!= -1)
1061 OUString
aTmp( aStoredEntry
.getToken( 0, ';', nIndex
) );
1066 xEntry
= m_xScriptsBox
->make_iterator();
1067 bTmpEntry
= m_xScriptsBox
->get_iter_first(*xEntry
);
1068 m_xScriptsBox
->copy_iterator(*xEntry
, *xTmpEntry
);
1072 m_xScriptsBox
->copy_iterator(*xEntry
, *xTmpEntry
);
1073 bTmpEntry
= m_xScriptsBox
->iter_children(*xTmpEntry
);
1078 if (m_xScriptsBox
->get_text(*xTmpEntry
) == aTmp
)
1080 m_xScriptsBox
->copy_iterator(*xTmpEntry
, *xEntry
);
1083 bTmpEntry
= m_xScriptsBox
->iter_next_sibling(*xTmpEntry
);
1089 m_xScriptsBox
->expand_row(*xEntry
);
1093 m_xScriptsBox
->set_cursor(*xEntry
);
1098 OUString
ReplaceString(
1099 const OUString
& source
,
1100 const OUString
& token
,
1101 const OUString
& value
)
1103 sal_Int32 pos
= source
.indexOf( token
);
1105 if ( pos
!= -1 && !value
.isEmpty() )
1107 return source
.replaceAt( pos
, token
.getLength(), value
);
1115 OUString
FormatErrorString(
1116 const OUString
& unformatted
,
1117 const OUString
& language
,
1118 const OUString
& script
,
1119 const OUString
& line
,
1120 const OUString
& type
,
1121 const OUString
& message
)
1123 OUString result
= unformatted
.copy( 0 );
1125 result
= ReplaceString(result
, "%LANGUAGENAME", language
);
1126 result
= ReplaceString(result
, "%SCRIPTNAME", script
);
1127 result
= ReplaceString(result
, "%LINENUMBER", line
);
1129 if ( !type
.isEmpty() )
1131 result
+= "\n\n" + CuiResId(RID_SVXSTR_ERROR_TYPE_LABEL
) + " " + type
;
1134 if ( !message
.isEmpty() )
1136 result
+= "\n\n" + CuiResId(RID_SVXSTR_ERROR_MESSAGE_LABEL
) + " " + message
;
1142 OUString
GetErrorMessage(
1143 const provider::ScriptErrorRaisedException
& eScriptError
)
1145 OUString unformatted
= CuiResId( RID_SVXSTR_ERROR_AT_LINE
);
1147 OUString
unknown("UNKNOWN");
1148 OUString language
= unknown
;
1149 OUString script
= unknown
;
1150 OUString line
= unknown
;
1152 OUString message
= eScriptError
.Message
;
1154 if ( !eScriptError
.language
.isEmpty() )
1156 language
= eScriptError
.language
;
1159 if ( !eScriptError
.scriptName
.isEmpty() )
1161 script
= eScriptError
.scriptName
;
1164 if ( !eScriptError
.Message
.isEmpty() )
1166 message
= eScriptError
.Message
;
1168 if ( eScriptError
.lineNum
!= -1 )
1170 line
= OUString::number( eScriptError
.lineNum
);
1171 unformatted
= CuiResId( RID_SVXSTR_ERROR_AT_LINE
);
1175 unformatted
= CuiResId( RID_SVXSTR_ERROR_RUNNING
);
1178 return FormatErrorString(
1179 unformatted
, language
, script
, line
, type
, message
);
1182 OUString
GetErrorMessage(
1183 const provider::ScriptExceptionRaisedException
& eScriptException
)
1185 OUString unformatted
= CuiResId( RID_SVXSTR_EXCEPTION_AT_LINE
);
1187 OUString
unknown("UNKNOWN");
1188 OUString language
= unknown
;
1189 OUString script
= unknown
;
1190 OUString line
= unknown
;
1191 OUString type
= unknown
;
1192 OUString message
= eScriptException
.Message
;
1194 if ( !eScriptException
.language
.isEmpty() )
1196 language
= eScriptException
.language
;
1198 if ( !eScriptException
.scriptName
.isEmpty() )
1200 script
= eScriptException
.scriptName
;
1203 if ( !eScriptException
.Message
.isEmpty() )
1205 message
= eScriptException
.Message
;
1208 if ( eScriptException
.lineNum
!= -1 )
1210 line
= OUString::number( eScriptException
.lineNum
);
1211 unformatted
= CuiResId( RID_SVXSTR_EXCEPTION_AT_LINE
);
1215 unformatted
= CuiResId( RID_SVXSTR_EXCEPTION_RUNNING
);
1218 if ( !eScriptException
.exceptionType
.isEmpty() )
1220 type
= eScriptException
.exceptionType
;
1223 return FormatErrorString(
1224 unformatted
, language
, script
, line
, type
, message
);
1227 OUString
GetErrorMessage(
1228 const provider::ScriptFrameworkErrorException
& sError
)
1230 OUString unformatted
= CuiResId( RID_SVXSTR_FRAMEWORK_ERROR_RUNNING
);
1232 OUString
language("UNKNOWN");
1234 OUString
script("UNKNOWN");
1238 if ( !sError
.scriptName
.isEmpty() )
1240 script
= sError
.scriptName
;
1242 if ( !sError
.language
.isEmpty() )
1244 language
= sError
.language
;
1246 if ( sError
.errorType
== provider::ScriptFrameworkErrorType::NOTSUPPORTED
)
1249 CuiResId( RID_SVXSTR_ERROR_LANG_NOT_SUPPORTED
);
1250 message
= ReplaceString(message
, "%LANGUAGENAME", language
);
1255 message
= sError
.Message
;
1257 return FormatErrorString(
1258 unformatted
, language
, script
, OUString(), OUString(), message
);
1261 OUString
GetErrorMessage( const css::uno::Any
& aException
)
1263 if ( aException
.getValueType() ==
1264 cppu::UnoType
<reflection::InvocationTargetException
>::get())
1266 reflection::InvocationTargetException ite
;
1268 if ( ite
.TargetException
.getValueType() == cppu::UnoType
<provider::ScriptErrorRaisedException
>::get())
1270 // Error raised by script
1271 provider::ScriptErrorRaisedException scriptError
;
1272 ite
.TargetException
>>= scriptError
;
1273 return GetErrorMessage( scriptError
);
1275 else if ( ite
.TargetException
.getValueType() == cppu::UnoType
<provider::ScriptExceptionRaisedException
>::get())
1277 // Exception raised by script
1278 provider::ScriptExceptionRaisedException scriptException
;
1279 ite
.TargetException
>>= scriptException
;
1280 return GetErrorMessage( scriptException
);
1284 // Unknown error, shouldn't happen
1289 else if ( aException
.getValueType() == cppu::UnoType
<provider::ScriptFrameworkErrorException
>::get())
1291 // A Script Framework error has occurred
1292 provider::ScriptFrameworkErrorException sfe
;
1294 return GetErrorMessage( sfe
);
1297 // unknown exception
1298 auto msg
= aException
.getValueTypeName();
1300 if ( (aException
>>= e
) && !e
.Message
.isEmpty() )
1302 msg
+= ": " + e
.Message
;
1309 SvxScriptErrorDialog::SvxScriptErrorDialog( css::uno::Any
const & aException
)
1312 SolarMutexGuard aGuard
;
1313 m_sMessage
= GetErrorMessage( aException
);
1316 SvxScriptErrorDialog::~SvxScriptErrorDialog()
1320 short SvxScriptErrorDialog::Execute()
1322 // Show Error dialog asynchronously
1324 // Pass a copy of the message to the ShowDialog method as the
1325 // SvxScriptErrorDialog may be deleted before ShowDialog is called
1326 Application::PostUserEvent(
1327 LINK( this, SvxScriptErrorDialog
, ShowDialog
),
1328 new OUString( m_sMessage
) );
1333 IMPL_STATIC_LINK( SvxScriptErrorDialog
, ShowDialog
, void*, p
, void )
1335 OUString
* pMessage
= static_cast<OUString
*>(p
);
1338 if ( pMessage
&& !pMessage
->isEmpty() )
1340 message
= *pMessage
;
1344 message
= CuiResId( RID_SVXSTR_ERROR_TITLE
);
1347 std::unique_ptr
<weld::MessageDialog
> xBox(Application::CreateMessageDialog(nullptr,
1348 VclMessageType::Warning
, VclButtonsType::Ok
, message
));
1349 xBox
->set_title(CuiResId(RID_SVXSTR_ERROR_TITLE
));
1355 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */