update credits
[LibreOffice.git] / cui / source / dialogs / scriptdlg.cxx
blob672ff5e3e29723ab2ca174a0e5e7f0282fe84486
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>
22 #include <sfx2/objsh.hxx>
23 #include <vcl/svapp.hxx>
24 #include <vcl/msgbox.hxx>
25 #include <osl/mutex.hxx>
27 #include <cuires.hrc>
28 #include "scriptdlg.hrc"
29 #include "scriptdlg.hxx"
30 #include <dialmgr.hxx>
31 #include "selector.hxx"
33 #include <com/sun/star/uno/XComponentContext.hpp>
34 #include <com/sun/star/frame/XDesktop.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 <cppuhelper/implbase1.hxx>
50 #include <comphelper/documentinfo.hxx>
51 #include <comphelper/uno3.hxx>
52 #include <comphelper/processfactory.hxx>
53 #include <comphelper/broadcasthelper.hxx>
54 #include <comphelper/propertycontainer.hxx>
55 #include <comphelper/proparrhlp.hxx>
57 #include <basic/sbx.hxx>
58 #include <svtools/imagemgr.hxx>
59 #include "svtools/treelistentry.hxx"
60 #include <tools/urlobj.hxx>
61 #include <vector>
62 #include <algorithm>
64 using namespace ::com::sun::star;
65 using namespace ::com::sun::star::uno;
66 using namespace ::com::sun::star::script;
67 using namespace ::com::sun::star::frame;
68 using namespace ::com::sun::star::document;
70 void ShowErrorDialog( const Any& aException )
72 SvxScriptErrorDialog* pDlg = new SvxScriptErrorDialog( NULL, aException );
73 pDlg->Execute();
74 delete pDlg;
77 SFTreeListBox::SFTreeListBox(Window* pParent)
78 : SvTreeListBox(pParent)
79 , m_hdImage(CUI_RES(RID_CUIIMG_HARDDISK))
80 , m_libImage(CUI_RES(RID_CUIIMG_LIB))
81 , m_macImage(CUI_RES(RID_CUIIMG_MACRO))
82 , m_docImage(CUI_RES(RID_CUIIMG_DOC))
83 , m_sMyMacros(CUI_RESSTR(RID_SVXSTR_MYMACROS))
84 , m_sProdMacros(CUI_RESSTR(RID_SVXSTR_PRODMACROS))
86 SetSelectionMode( SINGLE_SELECTION );
88 SetStyle( GetStyle() | WB_CLIPCHILDREN | WB_HSCROLL |
89 WB_HASBUTTONS | WB_HASBUTTONSATROOT | WB_HIDESELECTION |
90 WB_HASLINES | WB_HASLINESATROOT | WB_TABSTOP );
91 SetNodeDefaultImages();
93 nMode = 0xFF; // everything
96 extern "C" SAL_DLLPUBLIC_EXPORT Window* SAL_CALL makeSFTreeListBox(Window *pParent, VclBuilder::stringmap &)
98 return new SFTreeListBox(pParent);
101 SFTreeListBox::~SFTreeListBox()
103 deleteAllTree();
106 void SFTreeListBox::delUserData( SvTreeListEntry* pEntry )
108 if ( pEntry )
110 SFEntry* pUserData = (SFEntry*)pEntry->GetUserData();
111 if ( pUserData )
113 delete pUserData;
114 // TBD seem to get a Select event on node that is remove ( below )
115 // so need to be able to detect that this node is not to be
116 // processed in order to do this, setting userData to NULL ( must
117 // be a better way to do this )
118 pUserData = 0;
119 pEntry->SetUserData( pUserData );
124 void SFTreeListBox::deleteTree( SvTreeListEntry* pEntry )
127 delUserData( pEntry );
128 pEntry = FirstChild( pEntry );
129 while ( pEntry )
131 SvTreeListEntry* pNextEntry = NextSibling( pEntry );
132 deleteTree( pEntry );
133 GetModel()->Remove( pEntry );
134 pEntry = pNextEntry;
138 void SFTreeListBox::deleteAllTree()
140 SvTreeListEntry* pEntry = GetEntry( 0 );
142 // TBD - below is a candidate for a destroyAllTrees method
143 if ( pEntry )
145 while ( pEntry )
147 SvTreeListEntry* pNextEntry = NextSibling( pEntry ) ;
148 deleteTree( pEntry );
149 GetModel()->Remove( pEntry );
150 pEntry = pNextEntry;
155 void SFTreeListBox::Init( const OUString& language )
157 SetUpdateMode( sal_False );
159 deleteAllTree();
161 Reference< browse::XBrowseNode > rootNode;
162 Reference< XComponentContext > xCtx(
163 comphelper::getProcessComponentContext() );
165 Sequence< Reference< browse::XBrowseNode > > children;
167 OUString userStr("user");
168 OUString shareStr("share");
172 Reference< browse::XBrowseNodeFactory > xFac = browse::theBrowseNodeFactory::get(xCtx);
174 rootNode.set( xFac->createView(
175 browse::BrowseNodeFactoryViewTypes::MACROORGANIZER ) );
177 if ( rootNode.is() && rootNode->hasChildNodes() == sal_True )
179 children = rootNode->getChildNodes();
182 catch( Exception& e )
184 OSL_TRACE("Exception getting root browse node from factory: %s",
185 OUStringToOString(
186 e.Message , RTL_TEXTENCODING_ASCII_US ).pData->buffer );
187 // TODO exception handling
190 Reference<XModel> xDocumentModel;
191 for ( sal_Int32 n = 0; n < children.getLength(); n++ )
193 bool app = false;
194 OUString uiName = children[ n ]->getName();
195 OUString factoryURL;
196 if ( uiName.equals( userStr ) || uiName.equals( shareStr ) )
198 app = true;
199 if ( uiName.equals( userStr ) )
201 uiName = m_sMyMacros;
203 else
205 uiName = m_sProdMacros;
208 else
210 xDocumentModel.set(getDocumentModel(xCtx, uiName ), UNO_QUERY);
212 if ( xDocumentModel.is() )
214 Reference< frame::XModuleManager2 > xModuleManager( frame::ModuleManager::create(xCtx) );
216 // get the long name of the document:
217 Sequence<beans::PropertyValue> moduleDescr;
218 try{
219 OUString appModule = xModuleManager->identify( xDocumentModel );
220 xModuleManager->getByName(appModule) >>= moduleDescr;
221 } catch(const uno::Exception&)
224 beans::PropertyValue const * pmoduleDescr =
225 moduleDescr.getConstArray();
226 for ( sal_Int32 pos = moduleDescr.getLength(); pos--; )
228 if ( pmoduleDescr[ pos ].Name == "ooSetupFactoryEmptyDocumentURL" )
230 pmoduleDescr[ pos ].Value >>= factoryURL;
231 break;
237 OUString lang( language );
238 Reference< browse::XBrowseNode > langEntries =
239 getLangNodeFromRootNode( children[ n ], lang );
241 SAL_WNODEPRECATED_DECLARATIONS_PUSH
242 insertEntry( uiName, app ? RID_CUIIMG_HARDDISK : RID_CUIIMG_DOC,
243 0, true, std::auto_ptr< SFEntry >(new SFEntry( OBJTYPE_SFROOT, langEntries, xDocumentModel )), factoryURL );
244 SAL_WNODEPRECATED_DECLARATIONS_POP
247 SetUpdateMode( sal_True );
250 Reference< XInterface >
251 SFTreeListBox::getDocumentModel( Reference< XComponentContext >& xCtx, OUString& docName )
253 Reference< XInterface > xModel;
254 Reference< frame::XDesktop2 > desktop = frame::Desktop::create(xCtx);
256 Reference< container::XEnumerationAccess > componentsAccess =
257 desktop->getComponents();
258 Reference< container::XEnumeration > components =
259 componentsAccess->createEnumeration();
260 while (components->hasMoreElements())
262 Reference< frame::XModel > model(
263 components->nextElement(), UNO_QUERY );
264 if ( model.is() )
266 OUString sTdocUrl = ::comphelper::DocumentInfo::getDocumentTitle( model );
267 if( sTdocUrl.equals( docName ) )
269 xModel = model;
270 break;
274 return xModel;
277 Reference< browse::XBrowseNode >
278 SFTreeListBox::getLangNodeFromRootNode( Reference< browse::XBrowseNode >& rootNode, OUString& language )
280 Reference< browse::XBrowseNode > langNode;
284 Sequence < Reference< browse::XBrowseNode > > children = rootNode->getChildNodes();
285 for ( sal_Int32 n = 0; n < children.getLength(); n++ )
287 if ( children[ n ]->getName().equals( language ) )
289 langNode = children[ n ];
290 break;
294 catch ( Exception& )
296 // if getChildNodes() throws an exception we just return
297 // the empty Reference
299 return langNode;
302 void SFTreeListBox:: RequestSubEntries( SvTreeListEntry* pRootEntry, Reference< ::com::sun::star::script::browse::XBrowseNode >& node,
303 Reference< XModel >& model )
305 if (! node.is() )
307 return;
310 Sequence< Reference< browse::XBrowseNode > > children;
313 children = node->getChildNodes();
315 catch ( Exception& )
317 // if we catch an exception in getChildNodes then no entries are added
320 for ( sal_Int32 n = 0; n < children.getLength(); n++ )
322 OUString name( children[ n ]->getName() );
323 if ( children[ n ]->getType() != browse::BrowseNodeTypes::SCRIPT)
325 SAL_WNODEPRECATED_DECLARATIONS_PUSH
326 insertEntry( name, RID_CUIIMG_LIB, pRootEntry, true, std::auto_ptr< SFEntry >(new SFEntry( OBJTYPE_SCRIPTCONTAINER, children[ n ],model )));
327 SAL_WNODEPRECATED_DECLARATIONS_POP
329 else
331 if ( children[ n ]->getType() == browse::BrowseNodeTypes::SCRIPT )
333 SAL_WNODEPRECATED_DECLARATIONS_PUSH
334 insertEntry( name, RID_CUIIMG_MACRO, pRootEntry, false, std::auto_ptr< SFEntry >(new SFEntry( OBJTYPE_METHOD, children[ n ],model )));
335 SAL_WNODEPRECATED_DECLARATIONS_POP
342 long SFTreeListBox::ExpandingHdl()
344 return sal_True;
347 void SFTreeListBox::ExpandAllTrees()
351 SAL_WNODEPRECATED_DECLARATIONS_PUSH
352 SvTreeListEntry * SFTreeListBox::insertEntry(
353 String const & rText, sal_uInt16 nBitmap, SvTreeListEntry * pParent,
354 bool bChildrenOnDemand, std::auto_ptr< SFEntry > aUserData, OUString factoryURL )
356 SvTreeListEntry * p;
357 if( nBitmap == RID_CUIIMG_DOC && !factoryURL.isEmpty() )
359 Image aImage = SvFileInformationManager::GetFileImage( INetURLObject(factoryURL), false );
360 p = InsertEntry(
361 rText, aImage, aImage, pParent, bChildrenOnDemand, LIST_APPEND,
362 aUserData.release()); // XXX possible leak
364 else
366 p = insertEntry( rText, nBitmap, pParent, bChildrenOnDemand, aUserData );
368 return p;
370 SAL_WNODEPRECATED_DECLARATIONS_POP
372 SAL_WNODEPRECATED_DECLARATIONS_PUSH
373 SvTreeListEntry * SFTreeListBox::insertEntry(
374 String const & rText, sal_uInt16 nBitmap, SvTreeListEntry * pParent,
375 bool bChildrenOnDemand, std::auto_ptr< SFEntry > aUserData )
377 Image aImage;
378 if( nBitmap == RID_CUIIMG_HARDDISK )
380 aImage = m_hdImage;
382 else if( nBitmap == RID_CUIIMG_LIB )
384 aImage = m_libImage;
386 else if( nBitmap == RID_CUIIMG_MACRO )
388 aImage = m_macImage;
390 else if( nBitmap == RID_CUIIMG_DOC )
392 aImage = m_docImage;
394 SvTreeListEntry * p = InsertEntry(
395 rText, aImage, aImage, pParent, bChildrenOnDemand, LIST_APPEND,
396 aUserData.release()); // XXX possible leak
397 return p;
399 SAL_WNODEPRECATED_DECLARATIONS_POP
401 void SFTreeListBox::RequestingChildren( SvTreeListEntry* pEntry )
403 SFEntry* userData = 0;
404 if ( !pEntry )
406 return;
408 userData = (SFEntry*)pEntry->GetUserData();
410 Reference< browse::XBrowseNode > node;
411 Reference< XModel > model;
412 if ( userData && !userData->isLoaded() )
414 node = userData->GetNode();
415 model = userData->GetModel();
416 RequestSubEntries( pEntry, node, model );
417 userData->setLoaded();
421 void SFTreeListBox::ExpandedHdl()
425 // ----------------------------------------------------------------------------
426 // CuiInputDialog ------------------------------------------------------------
427 // ----------------------------------------------------------------------------
428 CuiInputDialog::CuiInputDialog(Window * pParent, sal_uInt16 nMode )
429 : ModalDialog( pParent, CUI_RES( RID_DLG_NEWLIB ) ),
430 aText( this, CUI_RES( FT_NEWLIB ) ),
431 aEdit( this, CUI_RES( ED_LIBNAME ) ),
432 aOKButton( this, CUI_RES( PB_OK ) ),
433 aCancelButton( this, CUI_RES( PB_CANCEL ) )
435 aEdit.GrabFocus();
436 if ( nMode == INPUTMODE_NEWLIB )
438 SetText( String( CUI_RES( STR_NEWLIB ) ) );
440 else if ( nMode == INPUTMODE_NEWMACRO )
442 SetText( String( CUI_RES( STR_NEWMACRO ) ) );
443 aText.SetText( String( CUI_RES( STR_FT_NEWMACRO ) ) );
445 else if ( nMode == INPUTMODE_RENAME )
447 SetText( String( CUI_RES( STR_RENAME ) ) );
448 aText.SetText( String( CUI_RES( STR_FT_RENAME ) ) );
450 FreeResource();
452 // some resizing so that the text fits
453 Point point, newPoint;
454 Size siz, newSiz;
455 long gap;
457 sal_uInt16 style = TEXT_DRAW_MULTILINE | TEXT_DRAW_TOP |
458 TEXT_DRAW_LEFT | TEXT_DRAW_WORDBREAK;
460 // get dimensions of dialog instructions control
461 point = aText.GetPosPixel();
462 siz = aText.GetSizePixel();
464 // get dimensions occupied by text in the control
465 Rectangle rect =
466 GetTextRect( Rectangle( point, siz ), aText.GetText(), style );
467 newSiz = rect.GetSize();
469 // the gap is the difference between the text width and its control width
470 gap = siz.Height() - newSiz.Height();
472 //resize the text field
473 newSiz = Size( siz.Width(), siz.Height() - gap );
474 aText.SetSizePixel( newSiz );
476 //move the OK & cancel buttons
477 point = aEdit.GetPosPixel();
478 newPoint = Point( point.X(), point.Y() - gap );
479 aEdit.SetPosPixel( newPoint );
483 CuiInputDialog::~CuiInputDialog()
486 // ----------------------------------------------------------------------------
487 // ScriptOrgDialog ------------------------------------------------------------
488 // ----------------------------------------------------------------------------
489 SvxScriptOrgDialog::SvxScriptOrgDialog( Window* pParent, OUString language )
490 : SfxModalDialog(pParent, "ScriptOrganizerDialog", "cui/ui/scriptorganizer.ui")
491 , m_sLanguage(language)
492 , m_delErrStr(CUI_RESSTR(RID_SVXSTR_DELFAILED))
493 , m_delErrTitleStr(CUI_RESSTR(RID_SVXSTR_DELFAILED_TITLE))
494 , m_delQueryStr(CUI_RES(RID_SVXSTR_DELQUERY))
495 , m_delQueryTitleStr(CUI_RESSTR(RID_SVXSTR_DELQUERY_TITLE))
496 , m_createErrStr(CUI_RESSTR(RID_SVXSTR_CREATEFAILED))
497 , m_createDupStr(CUI_RESSTR(RID_SVXSTR_CREATEFAILEDDUP))
498 , m_createErrTitleStr(CUI_RESSTR(RID_SVXSTR_CREATEFAILED_TITLE))
499 , m_renameErrStr(CUI_RESSTR(RID_SVXSTR_RENAMEFAILED))
500 , m_renameErrTitleStr(CUI_RESSTR(RID_SVXSTR_RENAMEFAILED_TITLE))
502 get(m_pScriptsBox, "scripts");
503 get(m_pRunButton, "run");
504 get(m_pCloseButton, "close");
505 get(m_pCreateButton, "create");
506 get(m_pEditButton, "edit");
507 get(m_pRenameButton, "rename");
508 get(m_pDelButton, "delete");
509 // must be a neater way to deal with the strings than as above
510 // append the language to the dialog title
511 String winTitle( GetText() );
512 winTitle.SearchAndReplace( OUString( "%MACROLANG" ), m_sLanguage );
513 SetText( winTitle );
515 m_pScriptsBox->SetSelectHdl( LINK( this, SvxScriptOrgDialog, ScriptSelectHdl ) );
516 m_pRunButton->SetClickHdl( LINK( this, SvxScriptOrgDialog, ButtonHdl ) );
517 m_pCloseButton->SetClickHdl( LINK( this, SvxScriptOrgDialog, ButtonHdl ) );
518 m_pRenameButton->SetClickHdl( LINK( this, SvxScriptOrgDialog, ButtonHdl ) );
519 m_pEditButton->SetClickHdl( LINK( this, SvxScriptOrgDialog, ButtonHdl ) );
520 m_pDelButton->SetClickHdl( LINK( this, SvxScriptOrgDialog, ButtonHdl ) );
521 m_pCreateButton->SetClickHdl( LINK( this, SvxScriptOrgDialog, ButtonHdl ) );
523 m_pRunButton->Disable();
524 m_pRenameButton->Disable();
525 m_pEditButton->Disable();
526 m_pDelButton->Disable();
527 m_pCreateButton->Disable();
529 m_pScriptsBox->Init( m_sLanguage );
530 RestorePreviousSelection();
533 SvxScriptOrgDialog::~SvxScriptOrgDialog()
535 // clear the SelectHdl so that it isn't called during the dtor
536 m_pScriptsBox->SetSelectHdl( Link() );
539 short SvxScriptOrgDialog::Execute()
542 SfxObjectShell *pDoc = SfxObjectShell::GetFirst();
544 // force load of MSPs for all documents
545 while ( pDoc )
547 Reference< provider::XScriptProviderSupplier > xSPS =
548 Reference< provider::XScriptProviderSupplier >
549 ( pDoc->GetModel(), UNO_QUERY );
550 if ( xSPS.is() )
552 Reference< provider::XScriptProvider > ScriptProvider =
553 xSPS->getScriptProvider();
556 pDoc = SfxObjectShell::GetNext(*pDoc);
558 m_pScriptsBox->ExpandAllTrees();
560 Window* pPrevDlgParent = Application::GetDefDialogParent();
561 Application::SetDefDialogParent( this );
562 short nRet = ModalDialog::Execute();
563 Application::SetDefDialogParent( pPrevDlgParent );
564 return nRet;
567 void SvxScriptOrgDialog::CheckButtons( Reference< browse::XBrowseNode >& node )
569 if ( node.is() )
571 if ( node->getType() == browse::BrowseNodeTypes::SCRIPT)
573 m_pRunButton->Enable();
575 else
577 m_pRunButton->Disable();
579 Reference< beans::XPropertySet > xProps( node, UNO_QUERY );
581 if ( !xProps.is() )
583 m_pEditButton->Disable();
584 m_pDelButton->Disable();
585 m_pCreateButton->Disable();
586 m_pRunButton->Disable();
587 return;
590 OUString sName("Editable") ;
592 if ( getBoolProperty( xProps, sName ) )
594 m_pEditButton->Enable();
596 else
598 m_pEditButton->Disable();
601 sName = OUString("Deletable") ;
603 if ( getBoolProperty( xProps, sName ) )
605 m_pDelButton->Enable();
607 else
609 m_pDelButton->Disable();
612 sName = OUString("Creatable") ;
614 if ( getBoolProperty( xProps, sName ) )
616 m_pCreateButton->Enable();
618 else
620 m_pCreateButton->Disable();
623 sName = OUString("Renamable") ;
625 if ( getBoolProperty( xProps, sName ) )
627 m_pRenameButton->Enable();
629 else
631 m_pRenameButton->Disable();
634 else
636 // no node info available, disable all configurable actions
637 m_pDelButton->Disable();
638 m_pCreateButton->Disable();
639 m_pEditButton->Disable();
640 m_pRunButton->Disable();
641 m_pRenameButton->Disable();
645 IMPL_LINK( SvxScriptOrgDialog, ScriptSelectHdl, SvTreeListBox *, pBox )
647 if ( !pBox->IsSelected( pBox->GetHdlEntry() ) )
649 return 0;
652 SvTreeListEntry* pEntry = pBox->GetHdlEntry();
654 SFEntry* userData = 0;
655 if ( !pEntry )
657 return 0;
659 userData = (SFEntry*)pEntry->GetUserData();
661 Reference< browse::XBrowseNode > node;
662 if ( userData )
664 node = userData->GetNode();
665 CheckButtons( node );
668 return 0;
671 IMPL_LINK( SvxScriptOrgDialog, ButtonHdl, Button *, pButton )
673 if ( pButton == m_pCloseButton )
675 StoreCurrentSelection();
676 EndDialog( 0 );
678 if ( pButton == m_pEditButton ||
679 pButton == m_pCreateButton ||
680 pButton == m_pDelButton ||
681 pButton == m_pRunButton ||
682 pButton == m_pRenameButton )
685 if ( m_pScriptsBox->IsSelected( m_pScriptsBox->GetHdlEntry() ) )
687 SvTreeListEntry* pEntry = m_pScriptsBox->GetHdlEntry();
688 SFEntry* userData = 0;
689 if ( !pEntry )
691 return 0;
693 userData = (SFEntry*)pEntry->GetUserData();
694 if ( userData )
696 Reference< browse::XBrowseNode > node;
697 Reference< XModel > xModel;
699 node = userData->GetNode();
700 xModel = userData->GetModel();
702 if ( !node.is() )
704 return 0;
707 if ( pButton == m_pRunButton )
709 OUString tmpString;
710 Reference< beans::XPropertySet > xProp( node, UNO_QUERY );
711 Reference< provider::XScriptProvider > mspNode;
712 if( !xProp.is() )
714 return 0;
717 if ( xModel.is() )
719 Reference< XEmbeddedScripts > xEmbeddedScripts( xModel, UNO_QUERY);
720 if( !xEmbeddedScripts.is() )
722 return 0;
725 if (!xEmbeddedScripts->getAllowMacroExecution())
727 // Please FIXME: Show a message box if AllowMacroExecution is false
728 return 0;
733 SvTreeListEntry* pParent = m_pScriptsBox->GetParent( pEntry );
734 while ( pParent && !mspNode.is() )
736 SFEntry* mspUserData = (SFEntry*)pParent->GetUserData();
737 mspNode.set( mspUserData->GetNode() , UNO_QUERY );
738 pParent = m_pScriptsBox->GetParent( pParent );
740 xProp->getPropertyValue( OUString("URI" ) ) >>= tmpString;
741 const String scriptURL( tmpString );
743 if ( mspNode.is() )
747 Reference< provider::XScript > xScript(
748 mspNode->getScript( scriptURL ), UNO_QUERY_THROW );
750 const Sequence< Any > args(0);
751 Any aRet;
752 Sequence< sal_Int16 > outIndex;
753 Sequence< Any > outArgs( 0 );
754 aRet = xScript->invoke( args, outIndex, outArgs );
756 catch ( reflection::InvocationTargetException& ite )
758 ::com::sun::star::uno::Any a = makeAny(ite);
759 ShowErrorDialog(a);
761 catch ( provider::ScriptFrameworkErrorException& ite )
763 ::com::sun::star::uno::Any a = makeAny(ite);
764 ShowErrorDialog(a);
766 catch ( RuntimeException& re )
768 ::com::sun::star::uno::Any a = makeAny(re);
769 ShowErrorDialog(a);
771 catch ( Exception& e )
773 ::com::sun::star::uno::Any a = makeAny(e);
774 ShowErrorDialog(a);
777 StoreCurrentSelection();
778 EndDialog( 0 );
780 else if ( pButton == m_pEditButton )
782 Reference< script::XInvocation > xInv( node, UNO_QUERY );
783 if ( xInv.is() )
785 StoreCurrentSelection();
786 EndDialog( 0 );
787 Sequence< Any > args(0);
788 Sequence< Any > outArgs( 0 );
789 Sequence< sal_Int16 > outIndex;
792 // ISSUE need code to run script here
793 xInv->invoke( "Editable", args, outIndex, outArgs );
795 catch( Exception& e )
797 OSL_TRACE("Caught exception trying to invoke %s", OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).pData->buffer );
802 else if ( pButton == m_pCreateButton )
804 createEntry( pEntry );
806 else if ( pButton == m_pDelButton )
808 deleteEntry( pEntry );
810 else if ( pButton == m_pRenameButton )
812 renameEntry( pEntry );
817 return 0;
820 Reference< browse::XBrowseNode > SvxScriptOrgDialog::getBrowseNode( SvTreeListEntry* pEntry )
822 Reference< browse::XBrowseNode > node;
823 if ( pEntry )
825 SFEntry* userData = (SFEntry*)pEntry->GetUserData();
826 if ( userData )
828 node = userData->GetNode();
832 return node;
835 Reference< XModel > SvxScriptOrgDialog::getModel( SvTreeListEntry* pEntry )
837 Reference< XModel > model;
838 if ( pEntry )
840 SFEntry* userData = (SFEntry*)pEntry->GetUserData();
841 if ( userData )
843 model = userData->GetModel();
847 return model;
850 void SvxScriptOrgDialog::createEntry( SvTreeListEntry* pEntry )
853 Reference< browse::XBrowseNode > aChildNode;
854 Reference< browse::XBrowseNode > node = getBrowseNode( pEntry );
855 Reference< script::XInvocation > xInv( node, UNO_QUERY );
857 if ( xInv.is() )
859 OUString aNewName;
860 OUString aNewStdName;
861 sal_uInt16 nMode = INPUTMODE_NEWLIB;
862 if( m_pScriptsBox->GetModel()->GetDepth( pEntry ) == 0 )
864 aNewStdName = "Library" ;
866 else
868 aNewStdName = "Macro" ;
869 nMode = INPUTMODE_NEWMACRO;
871 //do we need L10N for this? ie somethng like:
872 //String aNewStdName( ResId( STR_STDMODULENAME ) );
873 sal_Bool bValid = sal_False;
874 sal_uInt16 i = 1;
876 Sequence< Reference< browse::XBrowseNode > > childNodes;
877 // no children => ok to create Parcel1 or Script1 without checking
880 if( node->hasChildNodes() == sal_False )
882 aNewName = aNewStdName + OUString::number(i);
883 bValid = sal_True;
885 else
887 childNodes = node->getChildNodes();
890 catch ( Exception& )
892 // ignore, will continue on with empty sequence
895 OUString extn;
896 while ( !bValid )
898 aNewName = aNewStdName + OUString::number(i);
899 sal_Bool bFound = sal_False;
900 if(childNodes.getLength() > 0 )
902 OUString nodeName = childNodes[0]->getName();
903 sal_Int32 extnPos = nodeName.lastIndexOf( '.' );
904 if(extnPos>0)
905 extn = nodeName.copy(extnPos);
907 for( sal_Int32 index = 0; index < childNodes.getLength(); index++ )
909 if (aNewName+extn == childNodes[index]->getName())
911 bFound = sal_True;
912 break;
915 if( bFound )
917 i++;
919 else
921 bValid = sal_True;
925 SAL_WNODEPRECATED_DECLARATIONS_PUSH
926 std::auto_ptr< CuiInputDialog > xNewDlg( new CuiInputDialog( static_cast<Window*>(this), nMode ) );
927 SAL_WNODEPRECATED_DECLARATIONS_POP
928 xNewDlg->SetObjectName( aNewName );
932 if ( xNewDlg->Execute() && xNewDlg->GetObjectName().Len() )
934 OUString aUserSuppliedName = xNewDlg->GetObjectName();
935 bValid = sal_True;
936 for( sal_Int32 index = 0; index < childNodes.getLength(); index++ )
938 if (aUserSuppliedName+extn == childNodes[index]->getName())
940 bValid = sal_False;
941 String aError( m_createErrStr );
942 aError.Append( m_createDupStr );
943 ErrorBox aErrorBox( static_cast<Window*>(this), WB_OK | RET_OK, aError );
944 aErrorBox.SetText( m_createErrTitleStr );
945 aErrorBox.Execute();
946 xNewDlg->SetObjectName( aNewName );
947 break;
950 if( bValid )
951 aNewName = aUserSuppliedName;
953 else
955 // user hit cancel or hit OK with nothing in the editbox
957 return;
960 while ( !bValid );
962 // open up parent node (which ensures it's loaded)
963 m_pScriptsBox->RequestingChildren( pEntry );
965 Sequence< Any > args( 1 );
966 args[ 0 ] <<= aNewName;
967 Sequence< Any > outArgs( 0 );
968 Sequence< sal_Int16 > outIndex;
971 Any aResult;
972 aResult = xInv->invoke( "Creatable", args, outIndex, outArgs );
973 Reference< browse::XBrowseNode > newNode( aResult, UNO_QUERY );
974 aChildNode = newNode;
977 catch( Exception& e )
979 OSL_TRACE("Caught exception trying to Create %s",
980 OUStringToOString(
981 e.Message, RTL_TEXTENCODING_ASCII_US ).pData->buffer );
984 if ( aChildNode.is() )
986 String aChildName = aChildNode->getName();
987 SvTreeListEntry* pNewEntry = NULL;
989 Reference<XModel> xDocumentModel = getModel( pEntry );
991 // ISSUE do we need to remove all entries for parent
992 // to achieve sort? Just need to determine position
993 // SvTreeListBox::InsertEntry can take position arg
994 // -- Basic doesn't do this on create.
995 // Suppose we could avoid this too. -> created nodes are
996 // not in alphabetical order
997 if ( aChildNode->getType() == browse::BrowseNodeTypes::SCRIPT )
999 SAL_WNODEPRECATED_DECLARATIONS_PUSH
1000 pNewEntry = m_pScriptsBox->insertEntry( aChildName,
1001 RID_CUIIMG_MACRO, pEntry, false, std::auto_ptr< SFEntry >(new SFEntry( OBJTYPE_METHOD, aChildNode,xDocumentModel ) ) );
1002 SAL_WNODEPRECATED_DECLARATIONS_POP
1005 else
1007 SAL_WNODEPRECATED_DECLARATIONS_PUSH
1008 pNewEntry = m_pScriptsBox->insertEntry( aChildName,
1009 RID_CUIIMG_LIB, pEntry, false, std::auto_ptr< SFEntry >(new SFEntry( OBJTYPE_SCRIPTCONTAINER, aChildNode,xDocumentModel ) ) );
1010 SAL_WNODEPRECATED_DECLARATIONS_POP
1012 // If the Parent is not loaded then set to
1013 // loaded, this will prevent RequestingChildren ( called
1014 // from vcl via RequestingChildren ) from
1015 // creating new ( duplicate ) children
1016 SFEntry* userData = (SFEntry*)pEntry->GetUserData();
1017 if ( userData && !userData->isLoaded() )
1019 userData->setLoaded();
1022 m_pScriptsBox->SetCurEntry( pNewEntry );
1023 m_pScriptsBox->Select( m_pScriptsBox->GetCurEntry() );
1026 else
1028 //ISSUE L10N & message from exception?
1029 OUString aError( m_createErrStr );
1030 ErrorBox aErrorBox( static_cast<Window*>(this), WB_OK | RET_OK, aError );
1031 aErrorBox.SetText( m_createErrTitleStr );
1032 aErrorBox.Execute();
1036 void SvxScriptOrgDialog::renameEntry( SvTreeListEntry* pEntry )
1039 Reference< browse::XBrowseNode > aChildNode;
1040 Reference< browse::XBrowseNode > node = getBrowseNode( pEntry );
1041 Reference< script::XInvocation > xInv( node, UNO_QUERY );
1043 if ( xInv.is() )
1045 OUString aNewName = node->getName();
1046 sal_Int32 extnPos = aNewName.lastIndexOf( '.' );
1047 OUString extn;
1048 if(extnPos>0)
1050 extn = aNewName.copy(extnPos);
1051 aNewName = aNewName.copy(0,extnPos);
1053 sal_uInt16 nMode = INPUTMODE_RENAME;
1055 SAL_WNODEPRECATED_DECLARATIONS_PUSH
1056 std::auto_ptr< CuiInputDialog > xNewDlg( new CuiInputDialog( static_cast<Window*>(this), nMode ) );
1057 SAL_WNODEPRECATED_DECLARATIONS_POP
1058 xNewDlg->SetObjectName( aNewName );
1060 sal_Bool bValid;
1063 if ( xNewDlg->Execute() && xNewDlg->GetObjectName().Len() )
1065 OUString aUserSuppliedName = xNewDlg->GetObjectName();
1066 bValid = sal_True;
1067 if( bValid )
1068 aNewName = aUserSuppliedName;
1070 else
1072 // user hit cancel or hit OK with nothing in the editbox
1073 return;
1076 while ( !bValid );
1078 Sequence< Any > args( 1 );
1079 args[ 0 ] <<= aNewName;
1080 Sequence< Any > outArgs( 0 );
1081 Sequence< sal_Int16 > outIndex;
1084 Any aResult;
1085 aResult = xInv->invoke( "Renamable", args, outIndex, outArgs );
1086 Reference< browse::XBrowseNode > newNode( aResult, UNO_QUERY );
1087 aChildNode = newNode;
1090 catch( Exception& e )
1092 OSL_TRACE("Caught exception trying to Rename %s",
1093 OUStringToOString(
1094 e.Message, RTL_TEXTENCODING_ASCII_US ).pData->buffer );
1097 if ( aChildNode.is() )
1099 m_pScriptsBox->SetEntryText( pEntry, aChildNode->getName() );
1100 m_pScriptsBox->SetCurEntry( pEntry );
1101 m_pScriptsBox->Select( m_pScriptsBox->GetCurEntry() );
1104 else
1106 //ISSUE L10N & message from exception?
1107 String aError( m_renameErrStr );
1108 ErrorBox aErrorBox( static_cast<Window*>(this), WB_OK | RET_OK, aError );
1109 aErrorBox.SetText( m_renameErrTitleStr );
1110 aErrorBox.Execute();
1113 void SvxScriptOrgDialog::deleteEntry( SvTreeListEntry* pEntry )
1115 sal_Bool result = sal_False;
1116 Reference< browse::XBrowseNode > node = getBrowseNode( pEntry );
1117 // ISSUE L10N string & can we centre list?
1118 OUString aQuery = m_delQueryStr + getListOfChildren( node, 0 );
1119 QueryBox aQueryBox( static_cast<Window*>(this), WB_YES_NO | WB_DEF_YES, aQuery );
1120 aQueryBox.SetText( m_delQueryTitleStr );
1121 if ( aQueryBox.Execute() == RET_NO )
1123 return;
1126 Reference< script::XInvocation > xInv( node, UNO_QUERY );
1127 if ( xInv.is() )
1129 Sequence< Any > args( 0 );
1130 Sequence< Any > outArgs( 0 );
1131 Sequence< sal_Int16 > outIndex;
1134 Any aResult;
1135 aResult = xInv->invoke( "Deletable", args, outIndex, outArgs );
1136 aResult >>= result; // or do we just assume true if no exception ?
1138 catch( Exception& e )
1140 OSL_TRACE("Caught exception trying to delete %s",
1141 OUStringToOString(
1142 e.Message, RTL_TEXTENCODING_ASCII_US ).pData->buffer );
1146 if ( result == sal_True )
1148 m_pScriptsBox->deleteTree( pEntry );
1149 m_pScriptsBox->GetModel()->Remove( pEntry );
1151 else
1153 //ISSUE L10N & message from exception?
1154 ErrorBox aErrorBox( static_cast<Window*>(this), WB_OK | RET_OK, m_delErrStr );
1155 aErrorBox.SetText( m_delErrTitleStr );
1156 aErrorBox.Execute();
1161 sal_Bool SvxScriptOrgDialog::getBoolProperty( Reference< beans::XPropertySet >& xProps,
1162 OUString& propName )
1164 sal_Bool result = false;
1167 sal_Bool bTemp = sal_False;
1168 xProps->getPropertyValue( propName ) >>= bTemp;
1169 result = ( bTemp == sal_True );
1171 catch ( Exception& )
1173 return result;
1175 return result;
1178 OUString SvxScriptOrgDialog::getListOfChildren( Reference< browse::XBrowseNode > node, int depth )
1180 OUString result = "\n";
1181 for( int i=0;i<=depth;i++ )
1183 result += "\t";
1185 result += node->getName();
1189 if ( node->hasChildNodes() == sal_True )
1191 Sequence< Reference< browse::XBrowseNode > > children
1192 = node->getChildNodes();
1193 for ( sal_Int32 n = 0; n < children.getLength(); n++ )
1195 result += getListOfChildren( children[ n ] , depth+1 );
1199 catch ( Exception& )
1201 // ignore, will return an empty string
1204 return result;
1207 Selection_hash SvxScriptOrgDialog::m_lastSelection;
1209 void SvxScriptOrgDialog::StoreCurrentSelection()
1211 OUString aDescription;
1212 if ( m_pScriptsBox->IsSelected( m_pScriptsBox->GetHdlEntry() ) )
1214 SvTreeListEntry* pEntry = m_pScriptsBox->GetHdlEntry();
1215 while( pEntry )
1217 aDescription = m_pScriptsBox->GetEntryText( pEntry ) + aDescription;
1218 pEntry = m_pScriptsBox->GetParent( pEntry );
1219 if ( pEntry )
1220 aDescription = ";" + aDescription;
1222 OUString sDesc( aDescription );
1223 m_lastSelection[ m_sLanguage ] = sDesc;
1227 void SvxScriptOrgDialog::RestorePreviousSelection()
1229 String aStoredEntry = String( m_lastSelection[ m_sLanguage ] );
1230 if( aStoredEntry.Len() <= 0 )
1231 return;
1232 SvTreeListEntry* pEntry = 0;
1233 sal_Int32 nIndex = 0;
1234 while ( nIndex != -1 )
1236 String aTmp( aStoredEntry.GetToken( 0, ';', nIndex ) );
1237 SvTreeListEntry* pTmpEntry = m_pScriptsBox->FirstChild( pEntry );
1238 while ( pTmpEntry )
1240 if ( m_pScriptsBox->GetEntryText( pTmpEntry ) == aTmp )
1242 pEntry = pTmpEntry;
1243 break;
1245 pTmpEntry = m_pScriptsBox->NextSibling( pTmpEntry );
1247 if ( !pTmpEntry )
1248 break;
1249 m_pScriptsBox->RequestingChildren( pEntry );
1251 m_pScriptsBox->SetCurEntry( pEntry );
1254 OUString ReplaceString(
1255 const OUString& source,
1256 const OUString& token,
1257 const OUString& value )
1259 sal_Int32 pos = source.indexOf( token );
1261 if ( pos != -1 && !value.isEmpty() )
1263 return source.replaceAt( pos, token.getLength(), value );
1265 else
1267 return source;
1271 OUString FormatErrorString(
1272 const OUString& unformatted,
1273 const OUString& language,
1274 const OUString& script,
1275 const OUString& line,
1276 const OUString& type,
1277 const OUString& message )
1279 OUString result = unformatted.copy( 0 );
1281 result = ReplaceString(result, "%LANGUAGENAME", language );
1282 result = ReplaceString(result, "%SCRIPTNAME", script );
1283 result = ReplaceString(result, "%LINENUMBER", line );
1285 if ( !type.isEmpty() )
1287 result += "\n\n" +
1288 OUString(CUI_RES(RID_SVXSTR_ERROR_TYPE_LABEL)) +
1289 " " +
1290 type;
1293 if ( !message.isEmpty() )
1295 result += "\n\n" +
1296 OUString(CUI_RES(RID_SVXSTR_ERROR_MESSAGE_LABEL)) +
1297 " " +
1298 message;
1301 return result;
1304 OUString GetErrorMessage(
1305 const provider::ScriptErrorRaisedException& eScriptError )
1307 OUString unformatted = CUI_RES( RID_SVXSTR_ERROR_AT_LINE );
1309 OUString unknown("UNKNOWN");
1310 OUString language = unknown;
1311 OUString script = unknown;
1312 OUString line = unknown;
1313 OUString type = OUString();
1314 OUString message = eScriptError.Message;
1316 if ( !eScriptError.language.isEmpty() )
1318 language = eScriptError.language;
1321 if ( !eScriptError.scriptName.isEmpty() )
1323 script = eScriptError.scriptName;
1326 if ( !eScriptError.Message.isEmpty() )
1328 message = eScriptError.Message;
1330 if ( eScriptError.lineNum != -1 )
1332 line = OUString::valueOf( eScriptError.lineNum );
1333 unformatted = CUI_RES( RID_SVXSTR_ERROR_AT_LINE );
1335 else
1337 unformatted = CUI_RES( RID_SVXSTR_ERROR_RUNNING );
1340 return FormatErrorString(
1341 unformatted, language, script, line, type, message );
1344 OUString GetErrorMessage(
1345 const provider::ScriptExceptionRaisedException& eScriptException )
1347 OUString unformatted = CUI_RES( RID_SVXSTR_EXCEPTION_AT_LINE );
1349 OUString unknown("UNKNOWN");
1350 OUString language = unknown;
1351 OUString script = unknown;
1352 OUString line = unknown;
1353 OUString type = unknown;
1354 OUString message = eScriptException.Message;
1356 if ( !eScriptException.language.isEmpty() )
1358 language = eScriptException.language;
1360 if ( !eScriptException.scriptName.isEmpty() )
1362 script = eScriptException.scriptName;
1365 if ( !eScriptException.Message.isEmpty() )
1367 message = eScriptException.Message;
1370 if ( eScriptException.lineNum != -1 )
1372 line = OUString::valueOf( eScriptException.lineNum );
1373 unformatted = CUI_RES( RID_SVXSTR_EXCEPTION_AT_LINE );
1375 else
1377 unformatted = CUI_RES( RID_SVXSTR_EXCEPTION_RUNNING );
1380 if ( !eScriptException.exceptionType.isEmpty() )
1382 type = eScriptException.exceptionType;
1385 return FormatErrorString(
1386 unformatted, language, script, line, type, message );
1389 OUString GetErrorMessage(
1390 const provider::ScriptFrameworkErrorException& sError )
1392 OUString unformatted = CUI_RES( RID_SVXSTR_FRAMEWORK_ERROR_RUNNING );
1394 OUString language("UNKNOWN");
1396 OUString script("UNKNOWN");
1398 OUString message;
1400 if ( !sError.scriptName.isEmpty() )
1402 script = sError.scriptName;
1404 if ( !sError.language.isEmpty() )
1406 language = sError.language;
1408 if ( sError.errorType == provider::ScriptFrameworkErrorType::NOTSUPPORTED )
1410 message = OUString(
1411 CUI_RES( RID_SVXSTR_ERROR_LANG_NOT_SUPPORTED ) );
1412 message = ReplaceString(message, "%LANGUAGENAME", language );
1415 else
1417 message = sError.Message;
1419 return FormatErrorString(
1420 unformatted, language, script, OUString(), OUString(), message );
1423 OUString GetErrorMessage( const RuntimeException& re )
1425 Type t = ::getCppuType( &re );
1426 OUString message = t.getTypeName();
1427 message += re.Message;
1429 return message;
1432 OUString GetErrorMessage( const Exception& e )
1434 Type t = ::getCppuType( &e );
1435 OUString message = t.getTypeName();
1436 message += e.Message;
1438 return message;
1441 OUString GetErrorMessage( const com::sun::star::uno::Any& aException )
1443 if ( aException.getValueType() ==
1444 ::getCppuType( (const reflection::InvocationTargetException* ) NULL ) )
1446 reflection::InvocationTargetException ite;
1447 aException >>= ite;
1448 if ( ite.TargetException.getValueType() == ::getCppuType( ( const provider::ScriptErrorRaisedException* ) NULL ) )
1450 // Error raised by script
1451 provider::ScriptErrorRaisedException scriptError;
1452 ite.TargetException >>= scriptError;
1453 return GetErrorMessage( scriptError );
1455 else if ( ite.TargetException.getValueType() == ::getCppuType( ( const provider::ScriptExceptionRaisedException* ) NULL ) )
1457 // Exception raised by script
1458 provider::ScriptExceptionRaisedException scriptException;
1459 ite.TargetException >>= scriptException;
1460 return GetErrorMessage( scriptException );
1462 else
1464 // Unknown error, shouldn't happen
1465 // OSL_ASSERT(...)
1469 else if ( aException.getValueType() == ::getCppuType( ( const provider::ScriptFrameworkErrorException* ) NULL ) )
1471 // A Script Framework error has occurred
1472 provider::ScriptFrameworkErrorException sfe;
1473 aException >>= sfe;
1474 return GetErrorMessage( sfe );
1477 // unknown exception
1478 Exception e;
1479 RuntimeException rte;
1480 if ( aException >>= rte )
1482 return GetErrorMessage( rte );
1485 aException >>= e;
1486 return GetErrorMessage( e );
1490 SvxScriptErrorDialog::SvxScriptErrorDialog(
1491 Window* , ::com::sun::star::uno::Any aException )
1492 : m_sMessage()
1494 SolarMutexGuard aGuard;
1495 m_sMessage = GetErrorMessage( aException );
1498 SvxScriptErrorDialog::~SvxScriptErrorDialog()
1502 short SvxScriptErrorDialog::Execute()
1504 // Show Error dialog asynchronously
1506 // Pass a copy of the message to the ShowDialog method as the
1507 // SvxScriptErrorDialog may be deleted before ShowDialog is called
1508 Application::PostUserEvent(
1509 LINK( this, SvxScriptErrorDialog, ShowDialog ),
1510 new OUString( m_sMessage ) );
1512 return 0;
1515 IMPL_LINK( SvxScriptErrorDialog, ShowDialog, OUString*, pMessage )
1517 OUString message;
1519 if ( pMessage && !pMessage->isEmpty() )
1521 message = *pMessage;
1523 else
1525 message = OUString( CUI_RES( RID_SVXSTR_ERROR_TITLE ) );
1528 MessBox* pBox = new WarningBox( NULL, WB_OK, message );
1529 pBox->SetText( CUI_RES( RID_SVXSTR_ERROR_TITLE ) );
1530 pBox->Execute();
1532 delete pBox;
1533 delete pMessage;
1535 return 0;
1538 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */