bump product version to 5.0.4.1
[LibreOffice.git] / cui / source / dialogs / scriptdlg.cxx
blob4bddaae613f92ee06582b179951034d2e66591fd
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
20 #include <memory>
21 #include <utility>
23 #include <sfx2/objsh.hxx>
24 #include <vcl/svapp.hxx>
25 #include <vcl/layout.hxx>
26 #include <vcl/builderfactory.hxx>
27 #include <osl/mutex.hxx>
29 #include <cuires.hrc>
30 #include "scriptdlg.hrc"
31 #include "scriptdlg.hxx"
32 #include <dialmgr.hxx>
33 #include "selector.hxx"
35 #include <com/sun/star/uno/XComponentContext.hpp>
36 #include <com/sun/star/frame/XDesktop.hpp>
37 #include <com/sun/star/script/provider/XScriptProviderSupplier.hpp>
38 #include <com/sun/star/script/provider/XScriptProvider.hpp>
39 #include <com/sun/star/script/browse/BrowseNodeTypes.hpp>
40 #include <com/sun/star/script/browse/XBrowseNodeFactory.hpp>
41 #include <com/sun/star/script/browse/BrowseNodeFactoryViewTypes.hpp>
42 #include <com/sun/star/script/browse/theBrowseNodeFactory.hpp>
43 #include <com/sun/star/script/provider/ScriptErrorRaisedException.hpp>
44 #include <com/sun/star/script/provider/ScriptExceptionRaisedException.hpp>
45 #include <com/sun/star/script/provider/ScriptFrameworkErrorType.hpp>
46 #include <com/sun/star/frame/Desktop.hpp>
47 #include <com/sun/star/frame/ModuleManager.hpp>
48 #include <com/sun/star/script/XInvocation.hpp>
49 #include <com/sun/star/document/XEmbeddedScripts.hpp>
51 #include <cppuhelper/implbase1.hxx>
52 #include <comphelper/documentinfo.hxx>
53 #include <comphelper/uno3.hxx>
54 #include <comphelper/processfactory.hxx>
55 #include <comphelper/broadcasthelper.hxx>
56 #include <comphelper/propertycontainer.hxx>
57 #include <comphelper/proparrhlp.hxx>
59 #include <basic/sbx.hxx>
60 #include <svtools/imagemgr.hxx>
61 #include "svtools/treelistentry.hxx"
62 #include <tools/urlobj.hxx>
63 #include <vector>
64 #include <algorithm>
65 #include <boost/scoped_ptr.hpp>
67 using namespace ::com::sun::star;
68 using namespace ::com::sun::star::uno;
69 using namespace ::com::sun::star::script;
70 using namespace ::com::sun::star::frame;
71 using namespace ::com::sun::star::document;
73 void ShowErrorDialog( const Any& aException )
75 boost::scoped_ptr<SvxScriptErrorDialog> pDlg(new SvxScriptErrorDialog( NULL, aException ));
76 pDlg->Execute();
79 SFTreeListBox::SFTreeListBox(vcl::Window* pParent)
80 : SvTreeListBox(pParent)
81 , m_hdImage(CUI_RES(RID_CUIIMG_HARDDISK))
82 , m_libImage(CUI_RES(RID_CUIIMG_LIB))
83 , m_macImage(CUI_RES(RID_CUIIMG_MACRO))
84 , m_docImage(CUI_RES(RID_CUIIMG_DOC))
85 , m_sMyMacros(CUI_RESSTR(RID_SVXSTR_MYMACROS))
86 , m_sProdMacros(CUI_RESSTR(RID_SVXSTR_PRODMACROS))
88 SetSelectionMode( SINGLE_SELECTION );
90 SetStyle( GetStyle() | WB_CLIPCHILDREN | WB_HSCROLL |
91 WB_HASBUTTONS | WB_HASBUTTONSATROOT | WB_HIDESELECTION |
92 WB_HASLINES | WB_HASLINESATROOT | WB_TABSTOP );
93 SetNodeDefaultImages();
95 nMode = 0xFF; // everything
98 VCL_BUILDER_FACTORY(SFTreeListBox)
100 SFTreeListBox::~SFTreeListBox()
102 disposeOnce();
105 void SFTreeListBox::dispose()
107 deleteAllTree();
108 SvTreeListBox::dispose();
111 void SFTreeListBox::delUserData( SvTreeListEntry* pEntry )
113 if ( pEntry )
115 SFEntry* pUserData = static_cast<SFEntry*>(pEntry->GetUserData());
116 if ( pUserData )
118 delete pUserData;
119 // TBD seem to get a Select event on node that is remove ( below )
120 // so need to be able to detect that this node is not to be
121 // processed in order to do this, setting userData to NULL ( must
122 // be a better way to do this )
123 pUserData = 0;
124 pEntry->SetUserData( pUserData );
129 void SFTreeListBox::deleteTree( SvTreeListEntry* pEntry )
132 delUserData( pEntry );
133 pEntry = FirstChild( pEntry );
134 while ( pEntry )
136 SvTreeListEntry* pNextEntry = NextSibling( pEntry );
137 deleteTree( pEntry );
138 GetModel()->Remove( pEntry );
139 pEntry = pNextEntry;
143 void SFTreeListBox::deleteAllTree()
145 SvTreeListEntry* pEntry = GetEntry( 0 );
147 // TBD - below is a candidate for a destroyAllTrees method
148 if ( pEntry )
150 while ( pEntry )
152 SvTreeListEntry* pNextEntry = NextSibling( pEntry ) ;
153 deleteTree( pEntry );
154 GetModel()->Remove( pEntry );
155 pEntry = pNextEntry;
160 void SFTreeListBox::Init( const OUString& language )
162 SetUpdateMode( false );
164 deleteAllTree();
166 Reference< browse::XBrowseNode > rootNode;
167 Reference< XComponentContext > xCtx(
168 comphelper::getProcessComponentContext() );
170 Sequence< Reference< browse::XBrowseNode > > children;
172 OUString userStr("user");
173 OUString shareStr("share");
177 Reference< browse::XBrowseNodeFactory > xFac = browse::theBrowseNodeFactory::get(xCtx);
179 rootNode.set( xFac->createView(
180 browse::BrowseNodeFactoryViewTypes::MACROORGANIZER ) );
182 if ( rootNode.is() && rootNode->hasChildNodes() == sal_True )
184 children = rootNode->getChildNodes();
187 catch( Exception& e )
189 OSL_TRACE("Exception getting root browse node from factory: %s",
190 OUStringToOString(
191 e.Message , RTL_TEXTENCODING_ASCII_US ).pData->buffer );
192 // TODO exception handling
195 Reference<XModel> xDocumentModel;
196 for ( sal_Int32 n = 0; n < children.getLength(); n++ )
198 bool app = false;
199 OUString uiName = children[ n ]->getName();
200 OUString factoryURL;
201 if ( uiName.equals( userStr ) || uiName.equals( shareStr ) )
203 app = true;
204 if ( uiName.equals( userStr ) )
206 uiName = m_sMyMacros;
208 else
210 uiName = m_sProdMacros;
213 else
215 xDocumentModel.set(getDocumentModel(xCtx, uiName ), UNO_QUERY);
217 if ( xDocumentModel.is() )
219 Reference< frame::XModuleManager2 > xModuleManager( frame::ModuleManager::create(xCtx) );
221 // get the long name of the document:
222 Sequence<beans::PropertyValue> moduleDescr;
223 try{
224 OUString appModule = xModuleManager->identify( xDocumentModel );
225 xModuleManager->getByName(appModule) >>= moduleDescr;
226 } catch(const uno::Exception&)
229 beans::PropertyValue const * pmoduleDescr =
230 moduleDescr.getConstArray();
231 for ( sal_Int32 pos = moduleDescr.getLength(); pos--; )
233 if ( pmoduleDescr[ pos ].Name == "ooSetupFactoryEmptyDocumentURL" )
235 pmoduleDescr[ pos ].Value >>= factoryURL;
236 break;
242 OUString lang( language );
243 Reference< browse::XBrowseNode > langEntries =
244 getLangNodeFromRootNode( children[ n ], lang );
246 insertEntry( uiName, app ? RID_CUIIMG_HARDDISK : RID_CUIIMG_DOC,
247 0, true, std::unique_ptr< SFEntry >(new SFEntry( OBJTYPE_SFROOT, langEntries, xDocumentModel )), factoryURL );
250 SetUpdateMode( true );
253 Reference< XInterface >
254 SFTreeListBox::getDocumentModel( Reference< XComponentContext >& xCtx, OUString& docName )
256 Reference< XInterface > xModel;
257 Reference< frame::XDesktop2 > desktop = frame::Desktop::create(xCtx);
259 Reference< container::XEnumerationAccess > componentsAccess =
260 desktop->getComponents();
261 Reference< container::XEnumeration > components =
262 componentsAccess->createEnumeration();
263 while (components->hasMoreElements())
265 Reference< frame::XModel > model(
266 components->nextElement(), UNO_QUERY );
267 if ( model.is() )
269 OUString sTdocUrl = ::comphelper::DocumentInfo::getDocumentTitle( model );
270 if( sTdocUrl.equals( docName ) )
272 xModel = model;
273 break;
277 return xModel;
280 Reference< browse::XBrowseNode >
281 SFTreeListBox::getLangNodeFromRootNode( Reference< browse::XBrowseNode >& rootNode, OUString& language )
283 Reference< browse::XBrowseNode > langNode;
287 Sequence < Reference< browse::XBrowseNode > > children = rootNode->getChildNodes();
288 for ( sal_Int32 n = 0; n < children.getLength(); n++ )
290 if ( children[ n ]->getName().equals( language ) )
292 langNode = children[ n ];
293 break;
297 catch ( Exception& )
299 // if getChildNodes() throws an exception we just return
300 // the empty Reference
302 return langNode;
305 void SFTreeListBox:: RequestSubEntries( SvTreeListEntry* pRootEntry, Reference< ::com::sun::star::script::browse::XBrowseNode >& node,
306 Reference< XModel >& model )
308 if (! node.is() )
310 return;
313 Sequence< Reference< browse::XBrowseNode > > children;
316 children = node->getChildNodes();
318 catch ( Exception& )
320 // if we catch an exception in getChildNodes then no entries are added
323 for ( sal_Int32 n = 0; n < children.getLength(); n++ )
325 OUString name( children[ n ]->getName() );
326 if ( children[ n ]->getType() != browse::BrowseNodeTypes::SCRIPT)
328 insertEntry( name, RID_CUIIMG_LIB, pRootEntry, true, std::unique_ptr< SFEntry >(new SFEntry( OBJTYPE_SCRIPTCONTAINER, children[ n ],model )));
330 else
332 if ( children[ n ]->getType() == browse::BrowseNodeTypes::SCRIPT )
334 insertEntry( name, RID_CUIIMG_MACRO, pRootEntry, false, std::unique_ptr< SFEntry >(new SFEntry( OBJTYPE_METHOD, children[ n ],model )));
341 bool SFTreeListBox::ExpandingHdl()
343 return true;
346 SvTreeListEntry * SFTreeListBox::insertEntry(
347 OUString const & rText, sal_uInt16 nBitmap, SvTreeListEntry * pParent,
348 bool bChildrenOnDemand, std::unique_ptr< SFEntry > && aUserData, const OUString& factoryURL )
350 SvTreeListEntry * p;
351 if( nBitmap == RID_CUIIMG_DOC && !factoryURL.isEmpty() )
353 Image aImage = SvFileInformationManager::GetFileImage( INetURLObject(factoryURL), false );
354 p = InsertEntry(
355 rText, aImage, aImage, pParent, bChildrenOnDemand, TREELIST_APPEND,
356 aUserData.release()); // XXX possible leak
358 else
360 p = insertEntry( rText, nBitmap, pParent, bChildrenOnDemand, std::move(aUserData) );
362 return p;
365 SvTreeListEntry * SFTreeListBox::insertEntry(
366 OUString const & rText, sal_uInt16 nBitmap, SvTreeListEntry * pParent,
367 bool bChildrenOnDemand, std::unique_ptr< SFEntry > && aUserData )
369 Image aImage;
370 if( nBitmap == RID_CUIIMG_HARDDISK )
372 aImage = m_hdImage;
374 else if( nBitmap == RID_CUIIMG_LIB )
376 aImage = m_libImage;
378 else if( nBitmap == RID_CUIIMG_MACRO )
380 aImage = m_macImage;
382 else if( nBitmap == RID_CUIIMG_DOC )
384 aImage = m_docImage;
386 SvTreeListEntry * p = InsertEntry(
387 rText, aImage, aImage, pParent, bChildrenOnDemand, TREELIST_APPEND,
388 aUserData.release()); // XXX possible leak
389 return p;
392 void SFTreeListBox::RequestingChildren( SvTreeListEntry* pEntry )
394 SFEntry* userData = 0;
395 if ( !pEntry )
397 return;
399 userData = static_cast<SFEntry*>(pEntry->GetUserData());
401 Reference< browse::XBrowseNode > node;
402 Reference< XModel > model;
403 if ( userData && !userData->isLoaded() )
405 node = userData->GetNode();
406 model = userData->GetModel();
407 RequestSubEntries( pEntry, node, model );
408 userData->setLoaded();
412 void SFTreeListBox::ExpandedHdl()
417 // CuiInputDialog ------------------------------------------------------------
419 CuiInputDialog::CuiInputDialog(vcl::Window * pParent, sal_uInt16 nMode )
420 : ModalDialog(pParent, "NewLibDialog",
421 "cui/ui/newlibdialog.ui")
423 get(m_pEdit, "entry");
424 m_pEdit->GrabFocus();
426 FixedText *pNewLibFT = get<FixedText>("newlibft");
428 if ( nMode == INPUTMODE_NEWMACRO )
430 pNewLibFT->Hide();
431 FixedText *pNewMacroFT = get<FixedText>("newmacroft");
432 pNewMacroFT->Show();
433 SetText(get<FixedText>("altmacrotitle")->GetText());
435 else if ( nMode == INPUTMODE_RENAME )
437 pNewLibFT->Hide();
438 FixedText *pRenameFT = get<FixedText>("renameft");
439 pRenameFT->Show();
440 SetText(get<FixedText>("altrenametitle")->GetText());
444 CuiInputDialog::~CuiInputDialog()
446 disposeOnce();
449 void CuiInputDialog::dispose()
451 m_pEdit.clear();
452 ModalDialog::dispose();
456 // ScriptOrgDialog ------------------------------------------------------------
458 SvxScriptOrgDialog::SvxScriptOrgDialog( vcl::Window* pParent, const OUString& language )
459 : SfxModalDialog(pParent, "ScriptOrganizerDialog",
460 "cui/ui/scriptorganizer.ui")
461 , m_sLanguage(language)
462 , m_delErrStr(CUI_RESSTR(RID_SVXSTR_DELFAILED))
463 , m_delErrTitleStr(CUI_RESSTR(RID_SVXSTR_DELFAILED_TITLE))
464 , m_delQueryStr(CUI_RES(RID_SVXSTR_DELQUERY))
465 , m_delQueryTitleStr(CUI_RESSTR(RID_SVXSTR_DELQUERY_TITLE))
466 , m_createErrStr(CUI_RESSTR(RID_SVXSTR_CREATEFAILED))
467 , m_createDupStr(CUI_RESSTR(RID_SVXSTR_CREATEFAILEDDUP))
468 , m_createErrTitleStr(CUI_RESSTR(RID_SVXSTR_CREATEFAILED_TITLE))
469 , m_renameErrStr(CUI_RESSTR(RID_SVXSTR_RENAMEFAILED))
470 , m_renameErrTitleStr(CUI_RESSTR(RID_SVXSTR_RENAMEFAILED_TITLE))
472 get(m_pScriptsBox, "scripts");
473 get(m_pRunButton, "run");
474 get(m_pCloseButton, "close");
475 get(m_pCreateButton, "create");
476 get(m_pEditButton, "edit");
477 get(m_pRenameButton, "rename");
478 get(m_pDelButton, "delete");
479 // must be a neater way to deal with the strings than as above
480 // append the language to the dialog title
481 OUString winTitle( GetText() );
482 winTitle = winTitle.replaceFirst( "%MACROLANG", m_sLanguage );
483 SetText( winTitle );
485 m_pScriptsBox->SetSelectHdl( LINK( this, SvxScriptOrgDialog, ScriptSelectHdl ) );
486 m_pRunButton->SetClickHdl( LINK( this, SvxScriptOrgDialog, ButtonHdl ) );
487 m_pCloseButton->SetClickHdl( LINK( this, SvxScriptOrgDialog, ButtonHdl ) );
488 m_pRenameButton->SetClickHdl( LINK( this, SvxScriptOrgDialog, ButtonHdl ) );
489 m_pEditButton->SetClickHdl( LINK( this, SvxScriptOrgDialog, ButtonHdl ) );
490 m_pDelButton->SetClickHdl( LINK( this, SvxScriptOrgDialog, ButtonHdl ) );
491 m_pCreateButton->SetClickHdl( LINK( this, SvxScriptOrgDialog, ButtonHdl ) );
493 m_pRunButton->Disable();
494 m_pRenameButton->Disable();
495 m_pEditButton->Disable();
496 m_pDelButton->Disable();
497 m_pCreateButton->Disable();
499 m_pScriptsBox->Init( m_sLanguage );
500 RestorePreviousSelection();
503 SvxScriptOrgDialog::~SvxScriptOrgDialog()
505 disposeOnce();
508 void SvxScriptOrgDialog::dispose()
510 // clear the SelectHdl so that it isn't called during the dtor
511 m_pScriptsBox->SetSelectHdl( Link<>() );
512 m_pScriptsBox.clear();
513 m_pRunButton.clear();
514 m_pCloseButton.clear();
515 m_pCreateButton.clear();
516 m_pEditButton.clear();
517 m_pRenameButton.clear();
518 m_pDelButton.clear();
519 SfxModalDialog::dispose();
522 short SvxScriptOrgDialog::Execute()
525 SfxObjectShell *pDoc = SfxObjectShell::GetFirst();
527 // force load of MSPs for all documents
528 while ( pDoc )
530 Reference< provider::XScriptProviderSupplier > xSPS =
531 Reference< provider::XScriptProviderSupplier >
532 ( pDoc->GetModel(), UNO_QUERY );
533 if ( xSPS.is() )
535 Reference< provider::XScriptProvider > ScriptProvider =
536 xSPS->getScriptProvider();
539 pDoc = SfxObjectShell::GetNext(*pDoc);
542 vcl::Window* pPrevDlgParent = Application::GetDefDialogParent();
543 Application::SetDefDialogParent( this );
544 short nRet = ModalDialog::Execute();
545 Application::SetDefDialogParent( pPrevDlgParent );
546 return nRet;
549 void SvxScriptOrgDialog::CheckButtons( Reference< browse::XBrowseNode >& node )
551 if ( node.is() )
553 if ( node->getType() == browse::BrowseNodeTypes::SCRIPT)
555 m_pRunButton->Enable();
557 else
559 m_pRunButton->Disable();
561 Reference< beans::XPropertySet > xProps( node, UNO_QUERY );
563 if ( !xProps.is() )
565 m_pEditButton->Disable();
566 m_pDelButton->Disable();
567 m_pCreateButton->Disable();
568 m_pRunButton->Disable();
569 return;
572 OUString sName("Editable");
574 if ( getBoolProperty( xProps, sName ) )
576 m_pEditButton->Enable();
578 else
580 m_pEditButton->Disable();
583 sName = "Deletable";
585 if ( getBoolProperty( xProps, sName ) )
587 m_pDelButton->Enable();
589 else
591 m_pDelButton->Disable();
594 sName = "Creatable";
596 if ( getBoolProperty( xProps, sName ) )
598 m_pCreateButton->Enable();
600 else
602 m_pCreateButton->Disable();
605 sName = "Renamable";
607 if ( getBoolProperty( xProps, sName ) )
609 m_pRenameButton->Enable();
611 else
613 m_pRenameButton->Disable();
616 else
618 // no node info available, disable all configurable actions
619 m_pDelButton->Disable();
620 m_pCreateButton->Disable();
621 m_pEditButton->Disable();
622 m_pRunButton->Disable();
623 m_pRenameButton->Disable();
627 IMPL_LINK( SvxScriptOrgDialog, ScriptSelectHdl, SvTreeListBox *, pBox )
629 if ( !pBox->IsSelected( pBox->GetHdlEntry() ) )
631 return 0;
634 SvTreeListEntry* pEntry = pBox->GetHdlEntry();
636 SFEntry* userData = 0;
637 if ( !pEntry )
639 return 0;
641 userData = static_cast<SFEntry*>(pEntry->GetUserData());
643 Reference< browse::XBrowseNode > node;
644 if ( userData )
646 node = userData->GetNode();
647 CheckButtons( node );
650 return 0;
653 IMPL_LINK( SvxScriptOrgDialog, ButtonHdl, Button *, pButton )
655 if ( pButton == m_pCloseButton )
657 StoreCurrentSelection();
658 EndDialog( 0 );
660 if ( pButton == m_pEditButton ||
661 pButton == m_pCreateButton ||
662 pButton == m_pDelButton ||
663 pButton == m_pRunButton ||
664 pButton == m_pRenameButton )
667 if ( m_pScriptsBox->IsSelected( m_pScriptsBox->GetHdlEntry() ) )
669 SvTreeListEntry* pEntry = m_pScriptsBox->GetHdlEntry();
670 SFEntry* userData = 0;
671 if ( !pEntry )
673 return 0;
675 userData = static_cast<SFEntry*>(pEntry->GetUserData());
676 if ( userData )
678 Reference< browse::XBrowseNode > node;
679 Reference< XModel > xModel;
681 node = userData->GetNode();
682 xModel = userData->GetModel();
684 if ( !node.is() )
686 return 0;
689 if ( pButton == m_pRunButton )
691 OUString tmpString;
692 Reference< beans::XPropertySet > xProp( node, UNO_QUERY );
693 Reference< provider::XScriptProvider > mspNode;
694 if( !xProp.is() )
696 return 0;
699 if ( xModel.is() )
701 Reference< XEmbeddedScripts > xEmbeddedScripts( xModel, UNO_QUERY);
702 if( !xEmbeddedScripts.is() )
704 return 0;
707 if (!xEmbeddedScripts->getAllowMacroExecution())
709 // Please FIXME: Show a message box if AllowMacroExecution is false
710 return 0;
715 SvTreeListEntry* pParent = m_pScriptsBox->GetParent( pEntry );
716 while ( pParent && !mspNode.is() )
718 SFEntry* mspUserData = static_cast<SFEntry*>(pParent->GetUserData());
719 mspNode.set( mspUserData->GetNode() , UNO_QUERY );
720 pParent = m_pScriptsBox->GetParent( pParent );
722 xProp->getPropertyValue("URI") >>= tmpString;
723 const OUString scriptURL( tmpString );
725 if ( mspNode.is() )
729 Reference< provider::XScript > xScript(
730 mspNode->getScript( scriptURL ), UNO_QUERY_THROW );
732 const Sequence< Any > args(0);
733 Any aRet;
734 Sequence< sal_Int16 > outIndex;
735 Sequence< Any > outArgs( 0 );
736 aRet = xScript->invoke( args, outIndex, outArgs );
738 catch ( reflection::InvocationTargetException& ite )
740 ::com::sun::star::uno::Any a = makeAny(ite);
741 ShowErrorDialog(a);
743 catch ( provider::ScriptFrameworkErrorException& ite )
745 ::com::sun::star::uno::Any a = makeAny(ite);
746 ShowErrorDialog(a);
748 catch ( RuntimeException& re )
750 ::com::sun::star::uno::Any a = makeAny(re);
751 ShowErrorDialog(a);
753 catch ( Exception& e )
755 ::com::sun::star::uno::Any a = makeAny(e);
756 ShowErrorDialog(a);
759 StoreCurrentSelection();
760 EndDialog( 0 );
762 else if ( pButton == m_pEditButton )
764 Reference< script::XInvocation > xInv( node, UNO_QUERY );
765 if ( xInv.is() )
767 StoreCurrentSelection();
768 EndDialog( 0 );
769 Sequence< Any > args(0);
770 Sequence< Any > outArgs( 0 );
771 Sequence< sal_Int16 > outIndex;
774 // ISSUE need code to run script here
775 xInv->invoke( "Editable", args, outIndex, outArgs );
777 catch( Exception& e )
779 OSL_TRACE("Caught exception trying to invoke %s", OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).pData->buffer );
784 else if ( pButton == m_pCreateButton )
786 createEntry( pEntry );
788 else if ( pButton == m_pDelButton )
790 deleteEntry( pEntry );
792 else if ( pButton == m_pRenameButton )
794 renameEntry( pEntry );
799 return 0;
802 Reference< browse::XBrowseNode > SvxScriptOrgDialog::getBrowseNode( SvTreeListEntry* pEntry )
804 Reference< browse::XBrowseNode > node;
805 if ( pEntry )
807 SFEntry* userData = static_cast<SFEntry*>(pEntry->GetUserData());
808 if ( userData )
810 node = userData->GetNode();
814 return node;
817 Reference< XModel > SvxScriptOrgDialog::getModel( SvTreeListEntry* pEntry )
819 Reference< XModel > model;
820 if ( pEntry )
822 SFEntry* userData = static_cast<SFEntry*>(pEntry->GetUserData());
823 if ( userData )
825 model = userData->GetModel();
829 return model;
832 void SvxScriptOrgDialog::createEntry( SvTreeListEntry* pEntry )
835 Reference< browse::XBrowseNode > aChildNode;
836 Reference< browse::XBrowseNode > node = getBrowseNode( pEntry );
837 Reference< script::XInvocation > xInv( node, UNO_QUERY );
839 if ( xInv.is() )
841 OUString aNewName;
842 OUString aNewStdName;
843 sal_uInt16 nMode = INPUTMODE_NEWLIB;
844 if( m_pScriptsBox->GetModel()->GetDepth( pEntry ) == 0 )
846 aNewStdName = "Library" ;
848 else
850 aNewStdName = "Macro" ;
851 nMode = INPUTMODE_NEWMACRO;
853 //do we need L10N for this? ie something like:
854 //String aNewStdName( ResId( STR_STDMODULENAME ) );
855 bool bValid = false;
856 sal_Int32 i = 1;
858 Sequence< Reference< browse::XBrowseNode > > childNodes;
859 // no children => ok to create Parcel1 or Script1 without checking
862 if( node->hasChildNodes() == sal_False )
864 aNewName = aNewStdName + OUString::number(i);
865 bValid = true;
867 else
869 childNodes = node->getChildNodes();
872 catch ( Exception& )
874 // ignore, will continue on with empty sequence
877 OUString extn;
878 while ( !bValid )
880 aNewName = aNewStdName + OUString::number(i);
881 bool bFound = false;
882 if(childNodes.getLength() > 0 )
884 OUString nodeName = childNodes[0]->getName();
885 sal_Int32 extnPos = nodeName.lastIndexOf( '.' );
886 if(extnPos>0)
887 extn = nodeName.copy(extnPos);
889 for( sal_Int32 index = 0; index < childNodes.getLength(); index++ )
891 if (aNewName+extn == childNodes[index]->getName())
893 bFound = true;
894 break;
897 if( bFound )
899 i++;
901 else
903 bValid = true;
907 ScopedVclPtrInstance< CuiInputDialog > xNewDlg( static_cast<vcl::Window*>(this), nMode );
908 xNewDlg->SetObjectName( aNewName );
912 if ( xNewDlg->Execute() && !xNewDlg->GetObjectName().isEmpty() )
914 OUString aUserSuppliedName = xNewDlg->GetObjectName();
915 bValid = true;
916 for( sal_Int32 index = 0; index < childNodes.getLength(); index++ )
918 if (aUserSuppliedName+extn == childNodes[index]->getName())
920 bValid = false;
921 OUString aError( m_createErrStr );
922 aError += m_createDupStr;
923 ScopedVclPtrInstance< MessageDialog > aErrorBox(static_cast<vcl::Window*>(this), aError);
924 aErrorBox->SetText( m_createErrTitleStr );
925 aErrorBox->Execute();
926 xNewDlg->SetObjectName( aNewName );
927 break;
930 if( bValid )
931 aNewName = aUserSuppliedName;
933 else
935 // user hit cancel or hit OK with nothing in the editbox
937 return;
940 while ( !bValid );
942 // open up parent node (which ensures it's loaded)
943 m_pScriptsBox->RequestingChildren( pEntry );
945 Sequence< Any > args( 1 );
946 args[ 0 ] <<= aNewName;
947 Sequence< Any > outArgs( 0 );
948 Sequence< sal_Int16 > outIndex;
951 Any aResult;
952 aResult = xInv->invoke( "Creatable", args, outIndex, outArgs );
953 Reference< browse::XBrowseNode > newNode( aResult, UNO_QUERY );
954 aChildNode = newNode;
957 catch( Exception& e )
959 OSL_TRACE("Caught exception trying to Create %s",
960 OUStringToOString(
961 e.Message, RTL_TEXTENCODING_ASCII_US ).pData->buffer );
964 if ( aChildNode.is() )
966 OUString aChildName = aChildNode->getName();
967 SvTreeListEntry* pNewEntry = NULL;
969 Reference<XModel> xDocumentModel = getModel( pEntry );
971 // ISSUE do we need to remove all entries for parent
972 // to achieve sort? Just need to determine position
973 // SvTreeListBox::InsertEntry can take position arg
974 // -- Basic doesn't do this on create.
975 // Suppose we could avoid this too. -> created nodes are
976 // not in alphabetical order
977 if ( aChildNode->getType() == browse::BrowseNodeTypes::SCRIPT )
979 pNewEntry = m_pScriptsBox->insertEntry( aChildName,
980 RID_CUIIMG_MACRO, pEntry, false, std::unique_ptr< SFEntry >(new SFEntry( OBJTYPE_METHOD, aChildNode,xDocumentModel ) ) );
982 else
984 pNewEntry = m_pScriptsBox->insertEntry( aChildName,
985 RID_CUIIMG_LIB, pEntry, false, std::unique_ptr< SFEntry >(new SFEntry( OBJTYPE_SCRIPTCONTAINER, aChildNode,xDocumentModel ) ) );
987 // If the Parent is not loaded then set to
988 // loaded, this will prevent RequestingChildren ( called
989 // from vcl via RequestingChildren ) from
990 // creating new ( duplicate ) children
991 SFEntry* userData = static_cast<SFEntry*>(pEntry->GetUserData());
992 if ( userData && !userData->isLoaded() )
994 userData->setLoaded();
997 m_pScriptsBox->SetCurEntry( pNewEntry );
998 m_pScriptsBox->Select( m_pScriptsBox->GetCurEntry() );
1001 else
1003 //ISSUE L10N & message from exception?
1004 OUString aError( m_createErrStr );
1005 ScopedVclPtrInstance< MessageDialog > aErrorBox(static_cast<vcl::Window*>(this), aError);
1006 aErrorBox->SetText( m_createErrTitleStr );
1007 aErrorBox->Execute();
1011 void SvxScriptOrgDialog::renameEntry( SvTreeListEntry* pEntry )
1014 Reference< browse::XBrowseNode > aChildNode;
1015 Reference< browse::XBrowseNode > node = getBrowseNode( pEntry );
1016 Reference< script::XInvocation > xInv( node, UNO_QUERY );
1018 if ( xInv.is() )
1020 OUString aNewName = node->getName();
1021 sal_Int32 extnPos = aNewName.lastIndexOf( '.' );
1022 OUString extn;
1023 if(extnPos>0)
1025 extn = aNewName.copy(extnPos);
1026 aNewName = aNewName.copy(0,extnPos);
1028 sal_uInt16 nMode = INPUTMODE_RENAME;
1030 ScopedVclPtrInstance< CuiInputDialog > xNewDlg( static_cast<vcl::Window*>(this), nMode );
1031 xNewDlg->SetObjectName( aNewName );
1033 bool bValid;
1036 if ( xNewDlg->Execute() && !xNewDlg->GetObjectName().isEmpty() )
1038 OUString aUserSuppliedName = xNewDlg->GetObjectName();
1039 bValid = true;
1040 if( bValid )
1041 aNewName = aUserSuppliedName;
1043 else
1045 // user hit cancel or hit OK with nothing in the editbox
1046 return;
1049 while ( !bValid );
1051 Sequence< Any > args( 1 );
1052 args[ 0 ] <<= aNewName;
1053 Sequence< Any > outArgs( 0 );
1054 Sequence< sal_Int16 > outIndex;
1057 Any aResult;
1058 aResult = xInv->invoke( "Renamable", args, outIndex, outArgs );
1059 Reference< browse::XBrowseNode > newNode( aResult, UNO_QUERY );
1060 aChildNode = newNode;
1063 catch( Exception& e )
1065 OSL_TRACE("Caught exception trying to Rename %s",
1066 OUStringToOString(
1067 e.Message, RTL_TEXTENCODING_ASCII_US ).pData->buffer );
1070 if ( aChildNode.is() )
1072 m_pScriptsBox->SetEntryText( pEntry, aChildNode->getName() );
1073 m_pScriptsBox->SetCurEntry( pEntry );
1074 m_pScriptsBox->Select( m_pScriptsBox->GetCurEntry() );
1077 else
1079 //ISSUE L10N & message from exception?
1080 OUString aError( m_renameErrStr );
1081 ScopedVclPtrInstance< MessageDialog > aErrorBox(static_cast<vcl::Window*>(this), aError);
1082 aErrorBox->SetText( m_renameErrTitleStr );
1083 aErrorBox->Execute();
1086 void SvxScriptOrgDialog::deleteEntry( SvTreeListEntry* pEntry )
1088 bool result = false;
1089 Reference< browse::XBrowseNode > node = getBrowseNode( pEntry );
1090 // ISSUE L10N string & can we centre list?
1091 OUString aQuery = m_delQueryStr + getListOfChildren( node, 0 );
1092 VclPtrInstance< MessageDialog > aQueryBox(static_cast<vcl::Window*>(this), aQuery, VCL_MESSAGE_QUESTION, VCL_BUTTONS_YES_NO);
1093 aQueryBox->SetText( m_delQueryTitleStr );
1094 if ( aQueryBox->Execute() == RET_NO )
1096 return;
1099 Reference< script::XInvocation > xInv( node, UNO_QUERY );
1100 if ( xInv.is() )
1102 Sequence< Any > args( 0 );
1103 Sequence< Any > outArgs( 0 );
1104 Sequence< sal_Int16 > outIndex;
1107 Any aResult;
1108 aResult = xInv->invoke( "Deletable", args, outIndex, outArgs );
1109 aResult >>= result; // or do we just assume true if no exception ?
1111 catch( Exception& e )
1113 OSL_TRACE("Caught exception trying to delete %s",
1114 OUStringToOString(
1115 e.Message, RTL_TEXTENCODING_ASCII_US ).pData->buffer );
1119 if ( result )
1121 m_pScriptsBox->deleteTree( pEntry );
1122 m_pScriptsBox->GetModel()->Remove( pEntry );
1124 else
1126 //ISSUE L10N & message from exception?
1127 ScopedVclPtrInstance< MessageDialog > aErrorBox(static_cast<vcl::Window*>(this), m_delErrStr);
1128 aErrorBox->SetText( m_delErrTitleStr );
1129 aErrorBox->Execute();
1134 bool SvxScriptOrgDialog::getBoolProperty( Reference< beans::XPropertySet >& xProps,
1135 OUString& propName )
1137 bool result = false;
1140 xProps->getPropertyValue( propName ) >>= result;
1142 catch ( Exception& )
1144 return result;
1146 return result;
1149 OUString SvxScriptOrgDialog::getListOfChildren( Reference< browse::XBrowseNode > node, int depth )
1151 OUString result = "\n";
1152 for( int i=0;i<=depth;i++ )
1154 result += "\t";
1156 result += node->getName();
1160 if ( node->hasChildNodes() == sal_True )
1162 Sequence< Reference< browse::XBrowseNode > > children
1163 = node->getChildNodes();
1164 for ( sal_Int32 n = 0; n < children.getLength(); n++ )
1166 result += getListOfChildren( children[ n ] , depth+1 );
1170 catch ( Exception& )
1172 // ignore, will return an empty string
1175 return result;
1178 Selection_hash SvxScriptOrgDialog::m_lastSelection;
1180 void SvxScriptOrgDialog::StoreCurrentSelection()
1182 OUString aDescription;
1183 if ( m_pScriptsBox->IsSelected( m_pScriptsBox->GetHdlEntry() ) )
1185 SvTreeListEntry* pEntry = m_pScriptsBox->GetHdlEntry();
1186 while( pEntry )
1188 aDescription = m_pScriptsBox->GetEntryText( pEntry ) + aDescription;
1189 pEntry = m_pScriptsBox->GetParent( pEntry );
1190 if ( pEntry )
1191 aDescription = ";" + aDescription;
1193 OUString sDesc( aDescription );
1194 m_lastSelection[ m_sLanguage ] = sDesc;
1198 void SvxScriptOrgDialog::RestorePreviousSelection()
1200 OUString aStoredEntry = m_lastSelection[ m_sLanguage ];
1201 if( aStoredEntry.isEmpty() )
1202 return;
1203 SvTreeListEntry* pEntry = 0;
1204 sal_Int32 nIndex = 0;
1205 while ( nIndex != -1 )
1207 OUString aTmp( aStoredEntry.getToken( 0, ';', nIndex ) );
1208 SvTreeListEntry* pTmpEntry = m_pScriptsBox->FirstChild( pEntry );
1209 while ( pTmpEntry )
1211 if ( m_pScriptsBox->GetEntryText( pTmpEntry ) == aTmp )
1213 pEntry = pTmpEntry;
1214 break;
1216 pTmpEntry = SvTreeListBox::NextSibling( pTmpEntry );
1218 if ( !pTmpEntry )
1219 break;
1220 m_pScriptsBox->RequestingChildren( pEntry );
1222 m_pScriptsBox->SetCurEntry( pEntry );
1225 OUString ReplaceString(
1226 const OUString& source,
1227 const OUString& token,
1228 const OUString& value )
1230 sal_Int32 pos = source.indexOf( token );
1232 if ( pos != -1 && !value.isEmpty() )
1234 return source.replaceAt( pos, token.getLength(), value );
1236 else
1238 return source;
1242 OUString FormatErrorString(
1243 const OUString& unformatted,
1244 const OUString& language,
1245 const OUString& script,
1246 const OUString& line,
1247 const OUString& type,
1248 const OUString& message )
1250 OUString result = unformatted.copy( 0 );
1252 result = ReplaceString(result, "%LANGUAGENAME", language );
1253 result = ReplaceString(result, "%SCRIPTNAME", script );
1254 result = ReplaceString(result, "%LINENUMBER", line );
1256 if ( !type.isEmpty() )
1258 result += "\n\n" +
1259 OUString(CUI_RES(RID_SVXSTR_ERROR_TYPE_LABEL)) +
1260 " " +
1261 type;
1264 if ( !message.isEmpty() )
1266 result += "\n\n" +
1267 OUString(CUI_RES(RID_SVXSTR_ERROR_MESSAGE_LABEL)) +
1268 " " +
1269 message;
1272 return result;
1275 OUString GetErrorMessage(
1276 const provider::ScriptErrorRaisedException& eScriptError )
1278 OUString unformatted = CUI_RES( RID_SVXSTR_ERROR_AT_LINE );
1280 OUString unknown("UNKNOWN");
1281 OUString language = unknown;
1282 OUString script = unknown;
1283 OUString line = unknown;
1284 OUString type = "";
1285 OUString message = eScriptError.Message;
1287 if ( !eScriptError.language.isEmpty() )
1289 language = eScriptError.language;
1292 if ( !eScriptError.scriptName.isEmpty() )
1294 script = eScriptError.scriptName;
1297 if ( !eScriptError.Message.isEmpty() )
1299 message = eScriptError.Message;
1301 if ( eScriptError.lineNum != -1 )
1303 line = OUString::number( eScriptError.lineNum );
1304 unformatted = CUI_RES( RID_SVXSTR_ERROR_AT_LINE );
1306 else
1308 unformatted = CUI_RES( RID_SVXSTR_ERROR_RUNNING );
1311 return FormatErrorString(
1312 unformatted, language, script, line, type, message );
1315 OUString GetErrorMessage(
1316 const provider::ScriptExceptionRaisedException& eScriptException )
1318 OUString unformatted = CUI_RES( RID_SVXSTR_EXCEPTION_AT_LINE );
1320 OUString unknown("UNKNOWN");
1321 OUString language = unknown;
1322 OUString script = unknown;
1323 OUString line = unknown;
1324 OUString type = unknown;
1325 OUString message = eScriptException.Message;
1327 if ( !eScriptException.language.isEmpty() )
1329 language = eScriptException.language;
1331 if ( !eScriptException.scriptName.isEmpty() )
1333 script = eScriptException.scriptName;
1336 if ( !eScriptException.Message.isEmpty() )
1338 message = eScriptException.Message;
1341 if ( eScriptException.lineNum != -1 )
1343 line = OUString::number( eScriptException.lineNum );
1344 unformatted = CUI_RES( RID_SVXSTR_EXCEPTION_AT_LINE );
1346 else
1348 unformatted = CUI_RES( RID_SVXSTR_EXCEPTION_RUNNING );
1351 if ( !eScriptException.exceptionType.isEmpty() )
1353 type = eScriptException.exceptionType;
1356 return FormatErrorString(
1357 unformatted, language, script, line, type, message );
1360 OUString GetErrorMessage(
1361 const provider::ScriptFrameworkErrorException& sError )
1363 OUString unformatted = CUI_RES( RID_SVXSTR_FRAMEWORK_ERROR_RUNNING );
1365 OUString language("UNKNOWN");
1367 OUString script("UNKNOWN");
1369 OUString message;
1371 if ( !sError.scriptName.isEmpty() )
1373 script = sError.scriptName;
1375 if ( !sError.language.isEmpty() )
1377 language = sError.language;
1379 if ( sError.errorType == provider::ScriptFrameworkErrorType::NOTSUPPORTED )
1381 message = OUString(
1382 CUI_RES( RID_SVXSTR_ERROR_LANG_NOT_SUPPORTED ) );
1383 message = ReplaceString(message, "%LANGUAGENAME", language );
1386 else
1388 message = sError.Message;
1390 return FormatErrorString(
1391 unformatted, language, script, OUString(), OUString(), message );
1394 OUString GetErrorMessage( const RuntimeException& re )
1396 Type t = cppu::UnoType<decltype(re)>::get();
1397 OUString message = t.getTypeName();
1398 message += re.Message;
1400 return message;
1403 OUString GetErrorMessage( const Exception& e )
1405 Type t = cppu::UnoType<decltype(e)>::get();
1406 OUString message = t.getTypeName();
1407 message += e.Message;
1409 return message;
1412 OUString GetErrorMessage( const com::sun::star::uno::Any& aException )
1414 if ( aException.getValueType() ==
1415 cppu::UnoType<reflection::InvocationTargetException>::get())
1417 reflection::InvocationTargetException ite;
1418 aException >>= ite;
1419 if ( ite.TargetException.getValueType() == cppu::UnoType<provider::ScriptErrorRaisedException>::get())
1421 // Error raised by script
1422 provider::ScriptErrorRaisedException scriptError;
1423 ite.TargetException >>= scriptError;
1424 return GetErrorMessage( scriptError );
1426 else if ( ite.TargetException.getValueType() == cppu::UnoType<provider::ScriptExceptionRaisedException>::get())
1428 // Exception raised by script
1429 provider::ScriptExceptionRaisedException scriptException;
1430 ite.TargetException >>= scriptException;
1431 return GetErrorMessage( scriptException );
1433 else
1435 // Unknown error, shouldn't happen
1436 // OSL_ASSERT(...)
1440 else if ( aException.getValueType() == cppu::UnoType<provider::ScriptFrameworkErrorException>::get())
1442 // A Script Framework error has occurred
1443 provider::ScriptFrameworkErrorException sfe;
1444 aException >>= sfe;
1445 return GetErrorMessage( sfe );
1448 // unknown exception
1449 Exception e;
1450 RuntimeException rte;
1451 if ( aException >>= rte )
1453 return GetErrorMessage( rte );
1456 aException >>= e;
1457 return GetErrorMessage( e );
1461 SvxScriptErrorDialog::SvxScriptErrorDialog(
1462 vcl::Window* , ::com::sun::star::uno::Any aException )
1463 : m_sMessage()
1465 SolarMutexGuard aGuard;
1466 m_sMessage = GetErrorMessage( aException );
1469 SvxScriptErrorDialog::~SvxScriptErrorDialog()
1473 short SvxScriptErrorDialog::Execute()
1475 // Show Error dialog asynchronously
1477 // Pass a copy of the message to the ShowDialog method as the
1478 // SvxScriptErrorDialog may be deleted before ShowDialog is called
1479 Application::PostUserEvent(
1480 LINK( this, SvxScriptErrorDialog, ShowDialog ),
1481 new OUString( m_sMessage ) );
1483 return 0;
1486 IMPL_STATIC_LINK(
1487 SvxScriptErrorDialog, ShowDialog, OUString*, pMessage )
1489 OUString message;
1491 if ( pMessage && !pMessage->isEmpty() )
1493 message = *pMessage;
1495 else
1497 message = OUString( CUI_RES( RID_SVXSTR_ERROR_TITLE ) );
1500 ScopedVclPtrInstance<MessageDialog> pBox( nullptr, message, VCL_MESSAGE_WARNING );
1501 pBox->SetText( CUI_RES( RID_SVXSTR_ERROR_TITLE ) );
1502 pBox->Execute();
1504 delete pMessage;
1506 return 0;
1509 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */