xref: /trunk/main/basctl/source/basicide/macrodlg.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_basctl.hxx"
30 
31 #include <memory>
32 
33 #include <ide_pch.hxx>
34 
35 
36 #include <macrodlg.hxx>
37 #include <macrodlg.hrc>
38 #include <basidesh.hrc>
39 #include <basidesh.hxx>
40 #include <baside2.hrc>      // ID's fuer Imagese
41 #include <basobj.hxx>
42 #include <baside3.hxx>
43 
44 #include <iderdll.hxx>
45 #include <iderdll2.hxx>
46 #include <iderid.hxx>
47 
48 #include <moduldlg.hxx>
49 #include <basic/sbx.hxx>
50 
51 #include <bastypes.hxx>
52 #include <sbxitem.hxx>
53 #include <sfx2/minfitem.hxx>
54 
55 #ifndef _COM_SUN_STAR_SCRIPT_XLIBRYARYCONTAINER2_HPP_
56 #include <com/sun/star/script/XLibraryContainer2.hpp>
57 #endif
58 #include <com/sun/star/document/MacroExecMode.hpp>
59 
60 using namespace ::com::sun::star;
61 using namespace ::com::sun::star::uno;
62 
63 
64 DECLARE_LIST( MacroList, SbMethod* )
65 
66 MacroChooser::MacroChooser( Window* pParnt, sal_Bool bCreateEntries ) :
67         SfxModalDialog(     pParnt, IDEResId( RID_MACROCHOOSER ) ),
68         aMacroNameTxt(      this,   IDEResId( RID_TXT_MACRONAME ) ),
69         aMacroNameEdit(     this,   IDEResId( RID_ED_MACRONAME ) ),
70         aMacroFromTxT(      this,   IDEResId( RID_TXT_MACROFROM ) ),
71         aMacrosSaveInTxt(   this,   IDEResId( RID_TXT_SAVEMACRO ) ),
72         aBasicBox(          this,   IDEResId( RID_CTRL_LIB ) ),
73         aMacrosInTxt(       this,   IDEResId( RID_TXT_MACROSIN ) ),
74         aMacroBox(          this,   IDEResId( RID_CTRL_MACRO ) ),
75         aRunButton(         this,   IDEResId( RID_PB_RUN ) ),
76         aCloseButton(       this,   IDEResId( RID_PB_CLOSE ) ),
77         aAssignButton(      this,   IDEResId( RID_PB_ASSIGN ) ),
78         aEditButton(        this,   IDEResId( RID_PB_EDIT ) ),
79         aNewDelButton(      this,   IDEResId( RID_PB_DEL ) ),
80         aOrganizeButton(    this,   IDEResId( RID_PB_ORG ) ),
81         aHelpButton(        this,   IDEResId( RID_PB_HELP ) ),
82         aNewLibButton(      this,   IDEResId( RID_PB_NEWLIB ) ),
83         aNewModButton(      this,   IDEResId( RID_PB_NEWMOD ) )
84 {
85     FreeResource();
86 
87     nMode = MACROCHOOSER_ALL;
88     bNewDelIsDel = sal_True;
89 
90     // Der Sfx fragt den BasicManager nicht, ob modified
91     // => Speichern anschmeissen, wenn Aenderung, aber kein Sprung in
92     // die BasicIDE.
93     bForceStoreBasic = sal_False;
94 
95     aMacrosInTxtBaseStr = aMacrosInTxt.GetText();
96 
97     aMacroBox.SetSelectionMode( SINGLE_SELECTION );
98     aMacroBox.SetHighlightRange(); // ueber ganze Breite selektieren
99 
100     aRunButton.SetClickHdl( LINK( this, MacroChooser, ButtonHdl ) );
101     aCloseButton.SetClickHdl( LINK( this, MacroChooser, ButtonHdl ) );
102     aAssignButton.SetClickHdl( LINK( this, MacroChooser, ButtonHdl ) );
103     aEditButton.SetClickHdl( LINK( this, MacroChooser, ButtonHdl ) );
104     aNewDelButton.SetClickHdl( LINK( this, MacroChooser, ButtonHdl ) );
105     aOrganizeButton.SetClickHdl( LINK( this, MacroChooser, ButtonHdl ) );
106 
107     // Buttons only for MACROCHOOSER_RECORDING
108     aNewLibButton.SetClickHdl( LINK( this, MacroChooser, ButtonHdl ) );
109     aNewModButton.SetClickHdl( LINK( this, MacroChooser, ButtonHdl ) );
110     aNewLibButton.Hide();       // default
111     aNewModButton.Hide();       // default
112     aMacrosSaveInTxt.Hide();    // default
113 
114     aMacrosInTxt.SetStyle( WB_NOMULTILINE | WB_PATHELLIPSIS );
115 
116     aMacroNameEdit.SetModifyHdl( LINK( this, MacroChooser, EditModifyHdl ) );
117 
118     aBasicBox.SetSelectHdl( LINK( this, MacroChooser, BasicSelectHdl ) );
119 
120     aMacroBox.SetDoubleClickHdl( LINK( this, MacroChooser, MacroDoubleClickHdl ) );
121     aMacroBox.SetSelectHdl( LINK( this, MacroChooser, MacroSelectHdl ) );
122 
123     aBasicBox.SetMode( BROWSEMODE_MODULES );
124     aBasicBox.SetStyle( WB_TABSTOP | WB_BORDER |
125                         WB_HASLINES | WB_HASLINESATROOT |
126                         WB_HASBUTTONS | WB_HASBUTTONSATROOT |
127                         WB_HSCROLL );
128 
129     BasicIDEShell* pIDEShell = IDE_DLL()->GetShell();
130     SfxViewFrame* pViewFrame = pIDEShell ? pIDEShell->GetViewFrame() : NULL;
131     SfxDispatcher* pDispatcher = pViewFrame ? pViewFrame->GetDispatcher() : NULL;
132     if( pDispatcher )
133     {
134         pDispatcher->Execute( SID_BASICIDE_STOREALLMODULESOURCES );
135     }
136 
137     if ( bCreateEntries )
138         aBasicBox.ScanAllEntries();
139 }
140 
141 MacroChooser::~MacroChooser()
142 {
143     if ( bForceStoreBasic )
144         SFX_APP()->SaveBasicAndDialogContainer();
145 }
146 
147 void MacroChooser::StoreMacroDescription()
148 {
149     BasicEntryDescriptor aDesc( aBasicBox.GetEntryDescriptor( aBasicBox.FirstSelected() ) );
150     String aMethodName;
151     SvLBoxEntry* pEntry = aMacroBox.FirstSelected();
152     if ( pEntry )
153         aMethodName = aMacroBox.GetEntryText( pEntry );
154     else
155         aMethodName = aMacroNameEdit.GetText();
156     if ( aMethodName.Len() )
157     {
158         aDesc.SetMethodName( aMethodName );
159         aDesc.SetType( OBJ_TYPE_METHOD );
160     }
161 
162     BasicIDEData* pData = IDE_DLL()->GetExtraData();
163     if ( pData )
164         pData->SetLastEntryDescriptor( aDesc );
165 }
166 
167 void MacroChooser::RestoreMacroDescription()
168 {
169     BasicEntryDescriptor aDesc;
170     BasicIDEShell* pIDEShell = IDE_DLL()->GetShell();
171     if ( pIDEShell )
172     {
173         IDEBaseWindow* pCurWin = pIDEShell->GetCurWindow();
174         if ( pCurWin )
175             aDesc = pCurWin->CreateEntryDescriptor();
176     }
177     else
178     {
179         BasicIDEData* pData = IDE_DLL()->GetExtraData();
180         if ( pData )
181             aDesc = pData->GetLastEntryDescriptor();
182     }
183 
184     aBasicBox.SetCurrentEntry( aDesc );
185 
186     String aLastMacro( aDesc.GetMethodName() );
187     if ( aLastMacro.Len() )
188     {
189         // find entry in macro box
190         SvLBoxEntry* pEntry = 0;
191         sal_uLong nPos = 0;
192         SvLBoxEntry* pE = aMacroBox.GetEntry( nPos );
193         while ( pE )
194         {
195             if ( aMacroBox.GetEntryText( pE ) == aLastMacro )
196             {
197                 pEntry = pE;
198                 break;
199             }
200             pE = aMacroBox.GetEntry( ++nPos );
201         }
202 
203         if ( pEntry )
204             aMacroBox.SetCurEntry( pEntry );
205         else
206         {
207             aMacroNameEdit.SetText( aLastMacro );
208             aMacroNameEdit.SetSelection( Selection( 0, 0 ) );
209         }
210     }
211 }
212 
213 short __EXPORT MacroChooser::Execute()
214 {
215     RestoreMacroDescription();
216     aRunButton.GrabFocus();
217 
218     // #104198 Check if "wrong" document is active
219     SvLBoxEntry* pSelectedEntry = aBasicBox.GetCurEntry();
220     BasicEntryDescriptor aDesc( aBasicBox.GetEntryDescriptor( pSelectedEntry ) );
221     const ScriptDocument& rSelectedDoc( aDesc.GetDocument() );
222 
223     // App Basic is always ok, so only check if shell was found
224     if( rSelectedDoc.isDocument() && !rSelectedDoc.isActive() )
225     {
226         // Search for the right entry
227         sal_uLong nRootPos = 0;
228         SvLBoxEntry* pRootEntry = aBasicBox.GetEntry( nRootPos );
229         while( pRootEntry )
230         {
231             BasicEntryDescriptor aCmpDesc( aBasicBox.GetEntryDescriptor( pRootEntry ) );
232             const ScriptDocument& rCmpDoc( aCmpDesc.GetDocument() );
233             if ( rCmpDoc.isDocument() && rCmpDoc.isActive() )
234             {
235                 SvLBoxEntry* pEntry = pRootEntry;
236                 SvLBoxEntry* pLastValid = pEntry;
237                 while ( pEntry )
238                 {
239                     pLastValid = pEntry;
240                     pEntry = aBasicBox.FirstChild( pEntry );
241                 }
242                 if( pLastValid )
243                     aBasicBox.SetCurEntry( pLastValid );
244             }
245             pRootEntry = aBasicBox.GetEntry( ++nRootPos );
246         }
247     }
248 
249     CheckButtons();
250     UpdateFields();
251 
252     if ( StarBASIC::IsRunning() )
253         aCloseButton.GrabFocus();
254 
255     Window* pPrevDlgParent = Application::GetDefDialogParent();
256     Application::SetDefDialogParent( this );
257     short nRet = ModalDialog::Execute();
258     // #57314# Wenn die BasicIDE aktiviert wurde, dann nicht den DefModalDialogParent auf das inaktive Dokument zuruecksetzen.
259     if ( Application::GetDefDialogParent() == this )
260         Application::SetDefDialogParent( pPrevDlgParent );
261     return nRet;
262 }
263 
264 
265 void MacroChooser::EnableButton( Button& rButton, sal_Bool bEnable )
266 {
267     if ( bEnable )
268     {
269         if ( nMode == MACROCHOOSER_CHOOSEONLY || nMode == MACROCHOOSER_RECORDING )
270         {
271             // Nur der RunButton kann enabled werden
272             if ( &rButton == &aRunButton )
273                 rButton.Enable();
274             else
275                 rButton.Disable();
276         }
277         else
278             rButton.Enable();
279     }
280     else
281         rButton.Disable();
282 }
283 
284 
285 
286 
287 SbMethod* MacroChooser::GetMacro()
288 {
289     SbMethod* pMethod = 0;
290     SbModule* pModule = aBasicBox.FindModule( aBasicBox.GetCurEntry() );
291     if ( pModule )
292     {
293         SvLBoxEntry* pEntry = aMacroBox.FirstSelected();
294         if ( pEntry )
295         {
296             String aMacroName( aMacroBox.GetEntryText( pEntry ) );
297             pMethod = (SbMethod*)pModule->GetMethods()->Find( aMacroName, SbxCLASS_METHOD );
298         }
299     }
300     return pMethod;
301 }
302 
303 
304 
305 void MacroChooser::DeleteMacro()
306 {
307     SbMethod* pMethod = GetMacro();
308     DBG_ASSERT( pMethod, "DeleteMacro: Kein Macro !" );
309     if ( pMethod && QueryDelMacro( pMethod->GetName(), this ) )
310     {
311         BasicIDEShell* pIDEShell = IDE_DLL()->GetShell();
312         SfxViewFrame* pViewFrame = pIDEShell ? pIDEShell->GetViewFrame() : NULL;
313         SfxDispatcher* pDispatcher = pViewFrame ? pViewFrame->GetDispatcher() : NULL;
314         if( pDispatcher )
315         {
316             pDispatcher->Execute( SID_BASICIDE_STOREALLMODULESOURCES );
317         }
318 
319         // Aktuelles Doc als geaendert markieren:
320         StarBASIC* pBasic = BasicIDE::FindBasic( pMethod );
321         DBG_ASSERT( pBasic, "Basic?!" );
322         BasicManager* pBasMgr = BasicIDE::FindBasicManager( pBasic );
323         DBG_ASSERT( pBasMgr, "BasMgr?" );
324         ScriptDocument aDocument( ScriptDocument::getDocumentForBasicManager( pBasMgr ) );
325         if ( aDocument.isDocument() )    // Muss ja nicht aus einem Document kommen...
326         {
327             aDocument.setDocumentModified();
328             SfxBindings* pBindings = BasicIDE::GetBindingsPtr();
329             if ( pBindings )
330                 pBindings->Invalidate( SID_SAVEDOC );
331         }
332 
333         SbModule* pModule = pMethod->GetModule();
334         DBG_ASSERT( pModule, "DeleteMacro: Kein Modul?!" );
335         ::rtl::OUString aSource( pModule->GetSource32() );
336         sal_uInt16 nStart, nEnd;
337         pMethod->GetLineRange( nStart, nEnd );
338         pModule->GetMethods()->Remove( pMethod );
339         CutLines( aSource, nStart-1, nEnd-nStart+1, sal_True );
340         pModule->SetSource32( aSource );
341 
342         // update module in library
343         String aLibName = pBasic->GetName();
344         String aModName = pModule->GetName();
345         OSL_VERIFY( aDocument.updateModule( aLibName, aModName, aSource ) );
346 
347         SvLBoxEntry* pEntry = aMacroBox.FirstSelected();
348         DBG_ASSERT( pEntry, "DeleteMacro: Entry ?!" );
349         aMacroBox.GetModel()->Remove( pEntry );
350         bForceStoreBasic = sal_True;
351     }
352 }
353 
354 SbMethod* MacroChooser::CreateMacro()
355 {
356     SbMethod* pMethod = 0;
357     SvLBoxEntry* pCurEntry = aBasicBox.GetCurEntry();
358     BasicEntryDescriptor aDesc( aBasicBox.GetEntryDescriptor( pCurEntry ) );
359     ScriptDocument aDocument( aDesc.GetDocument() );
360     OSL_ENSURE( aDocument.isAlive(), "MacroChooser::CreateMacro: no document!" );
361     if ( !aDocument.isAlive() )
362         return NULL;
363 
364     String aLibName( aDesc.GetLibName() );
365 
366     if ( !aLibName.Len() )
367         aLibName = String::CreateFromAscii( "Standard" );
368 
369     aDocument.getOrCreateLibrary( E_SCRIPTS, aLibName );
370 
371     ::rtl::OUString aOULibName( aLibName );
372     Reference< script::XLibraryContainer > xModLibContainer( aDocument.getLibraryContainer( E_SCRIPTS ) );
373     if ( xModLibContainer.is() && xModLibContainer->hasByName( aOULibName ) && !xModLibContainer->isLibraryLoaded( aOULibName ) )
374         xModLibContainer->loadLibrary( aOULibName );
375     Reference< script::XLibraryContainer > xDlgLibContainer( aDocument.getLibraryContainer( E_DIALOGS ) );
376     if ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aOULibName ) && !xDlgLibContainer->isLibraryLoaded( aOULibName ) )
377         xDlgLibContainer->loadLibrary( aOULibName );
378 
379     BasicManager* pBasMgr = aDocument.getBasicManager();
380     StarBASIC* pBasic = pBasMgr ? pBasMgr->GetLib( aLibName ) : 0;
381     if ( pBasic )
382     {
383         SbModule* pModule = 0;
384         String aModName( aDesc.GetName() );
385         if ( aModName.Len() )
386         {
387             // extract the module name from the string like "Sheet1 (Example1)"
388             if( aDesc.GetLibSubName().Equals( String( IDEResId( RID_STR_DOCUMENT_OBJECTS ) ) ) )
389             {
390                 sal_uInt16 nIndex = 0;
391                 aModName = aModName.GetToken( 0, ' ', nIndex );
392             }
393             pModule = pBasic->FindModule( aModName );
394         }
395         else if ( pBasic->GetModules()->Count() )
396             pModule = (SbModule*)pBasic->GetModules()->Get( 0 );
397 
398         if ( !pModule )
399         {
400             pModule = createModImpl( static_cast<Window*>( this ),
401                 aDocument, aBasicBox, aLibName, aModName );
402         }
403 
404         String aSubName = aMacroNameEdit.GetText();
405         DBG_ASSERT( !pModule || !pModule->GetMethods()->Find( aSubName, SbxCLASS_METHOD ), "Macro existiert schon!" );
406         pMethod = pModule ? BasicIDE::CreateMacro( pModule, aSubName ) : NULL;
407     }
408 
409     return pMethod;
410 }
411 
412 void MacroChooser::SaveSetCurEntry( SvTreeListBox& rBox, SvLBoxEntry* pEntry )
413 {
414     // Durch das Highlight wird das Edit sonst platt gemacht:
415 
416     String aSaveText( aMacroNameEdit.GetText() );
417     Selection aCurSel( aMacroNameEdit.GetSelection() );
418 
419     rBox.SetCurEntry( pEntry );
420     aMacroNameEdit.SetText( aSaveText );
421     aMacroNameEdit.SetSelection( aCurSel );
422 }
423 
424 void MacroChooser::CheckButtons()
425 {
426     SvLBoxEntry* pCurEntry = aBasicBox.GetCurEntry();
427     BasicEntryDescriptor aDesc( aBasicBox.GetEntryDescriptor( pCurEntry ) );
428     SvLBoxEntry* pMacroEntry = aMacroBox.FirstSelected();
429     SbMethod* pMethod = GetMacro();
430 
431     // check, if corresponding libraries are readonly
432     sal_Bool bReadOnly = sal_False;
433     sal_uInt16 nDepth = pCurEntry ? aBasicBox.GetModel()->GetDepth( pCurEntry ) : 0;
434     if ( nDepth == 1 || nDepth == 2 )
435     {
436         ScriptDocument aDocument( aDesc.GetDocument() );
437         ::rtl::OUString aOULibName( aDesc.GetLibName() );
438         Reference< script::XLibraryContainer2 > xModLibContainer( aDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
439         Reference< script::XLibraryContainer2 > xDlgLibContainer( aDocument.getLibraryContainer( E_DIALOGS ), UNO_QUERY );
440         if ( ( xModLibContainer.is() && xModLibContainer->hasByName( aOULibName ) && xModLibContainer->isLibraryReadOnly( aOULibName ) ) ||
441                 ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aOULibName ) && xDlgLibContainer->isLibraryReadOnly( aOULibName ) ) )
442         {
443             bReadOnly = sal_True;
444         }
445     }
446 
447     if ( nMode != MACROCHOOSER_RECORDING )
448     {
449         // Run...
450         sal_Bool bEnable = pMethod ? sal_True : sal_False;
451         if ( ( nMode != MACROCHOOSER_CHOOSEONLY ) && StarBASIC::IsRunning() )
452             bEnable = sal_False;
453         EnableButton( aRunButton, bEnable );
454     }
455 
456     // Organisieren immer moeglich ?
457 
458     // Assign...
459     EnableButton( aAssignButton, pMethod ? sal_True : sal_False );
460 
461     // Edit...
462     EnableButton( aEditButton, pMacroEntry ? sal_True : sal_False );
463 
464     // aOrganizeButton
465     EnableButton( aOrganizeButton, !StarBASIC::IsRunning() && ( nMode == MACROCHOOSER_ALL ));
466 
467     // aNewDelButton....
468     bool bProtected = aBasicBox.IsEntryProtected( pCurEntry );
469     bool bShare = ( aDesc.GetLocation() == LIBRARY_LOCATION_SHARE );
470     EnableButton( aNewDelButton,
471         !StarBASIC::IsRunning() && ( nMode == MACROCHOOSER_ALL ) && !bProtected && !bReadOnly && !bShare );
472     sal_Bool bPrev = bNewDelIsDel;
473     bNewDelIsDel = pMethod ? sal_True : sal_False;
474     if ( ( bPrev != bNewDelIsDel ) && ( nMode == MACROCHOOSER_ALL ) )
475     {
476         String aBtnText( bNewDelIsDel ? IDEResId( RID_STR_BTNDEL) : IDEResId( RID_STR_BTNNEW ) );
477         aNewDelButton.SetText( aBtnText );
478     }
479 
480     if ( nMode == MACROCHOOSER_RECORDING )
481     {
482         // save button
483         if ( !bProtected && !bReadOnly && !bShare )
484             aRunButton.Enable();
485         else
486             aRunButton.Disable();
487 
488         // new library button
489         if ( !bShare )
490             aNewLibButton.Enable();
491         else
492             aNewLibButton.Disable();
493 
494         // new module button
495         if ( !bProtected && !bReadOnly && !bShare )
496             aNewModButton.Enable();
497         else
498             aNewModButton.Disable();
499     }
500 }
501 
502 
503 
504 IMPL_LINK_INLINE_START( MacroChooser, MacroDoubleClickHdl, SvTreeListBox *, EMPTYARG )
505 {
506     StoreMacroDescription();
507     if ( nMode == MACROCHOOSER_RECORDING )
508     {
509         SbMethod* pMethod = GetMacro();
510         if ( pMethod && !QueryReplaceMacro( pMethod->GetName(), this ) )
511             return 0;
512     }
513 
514     EndDialog( MACRO_OK_RUN );
515     return 0;
516 }
517 IMPL_LINK_INLINE_END( MacroChooser, MacroDoubleClickHdl, SvTreeListBox *, EMPTYARG )
518 
519 IMPL_LINK( MacroChooser, MacroSelectHdl, SvTreeListBox *, pBox )
520 {
521     // Wird auch gerufen, wenn Deselektiert!
522     // 2 Funktionsaufrufe in jedem SelectHdl, nur weil Olli
523     // keinen separatren DeselctHdl einfuehren wollte:
524     // Also: Feststellen, ob Select oder Deselect:
525     if ( pBox->IsSelected( pBox->GetHdlEntry() ) )
526     {
527         UpdateFields();
528         CheckButtons();
529     }
530     return 0;
531 }
532 
533 IMPL_LINK( MacroChooser, BasicSelectHdl, SvTreeListBox *, pBox )
534 {
535     static String aSpaceStr = String::CreateFromAscii(" ");
536 
537     // Wird auch gerufen, wenn Deselektiert!
538     // 2 Funktionsaufrufe in jedem SelectHdl, nur weil Olli
539     // keinen separatren DeselctHdl einfuehren wollte:
540     // Also: Feststellen, ob Select oder Deselect:
541     if ( !pBox->IsSelected( pBox->GetHdlEntry() ) )
542         return 0;
543 
544     SbModule* pModule = aBasicBox.FindModule( aBasicBox.GetCurEntry() );
545 
546     aMacroBox.Clear();
547     if ( pModule )
548     {
549         String aStr = aMacrosInTxtBaseStr;
550         aStr += aSpaceStr;
551         aStr += pModule->GetName();
552 
553         aMacrosInTxt.SetText( aStr );
554 
555         // Die Macros sollen in der Reihenfolge angezeigt werden,
556         // wie sie im Modul stehen.
557         MacroList aMacros;
558         sal_uInt16 nMacroCount = pModule->GetMethods()->Count();
559         sal_uInt16 nRealMacroCount = 0;
560         sal_uInt16 iMeth;
561         for ( iMeth = 0; iMeth  < nMacroCount; iMeth++ )
562         {
563             SbMethod* pMethod = (SbMethod*)pModule->GetMethods()->Get( iMeth );
564             if( pMethod->IsHidden() )
565                 continue;
566             ++nRealMacroCount;
567             DBG_ASSERT( pMethod, "Methode nicht gefunden! (NULL)" );
568             sal_uLong nPos = LIST_APPEND;
569             // Eventuell weiter vorne ?
570             sal_uInt16 nStart, nEnd;
571             pMethod->GetLineRange( nStart, nEnd );
572             for ( sal_uLong n = 0; n < aMacros.Count(); n++ )
573             {
574                 sal_uInt16 nS, nE;
575                 SbMethod* pM = aMacros.GetObject( n );
576                 DBG_ASSERT( pM, "Macro nicht in Liste ?!" );
577                 pM->GetLineRange( nS, nE );
578                 if ( nS > nStart )
579                 {
580                     nPos = n;
581                     break;
582                 }
583             }
584             aMacros.Insert( pMethod, nPos );
585         }
586 
587         aMacroBox.SetUpdateMode( sal_False );
588         for ( iMeth = 0; iMeth < nRealMacroCount; iMeth++ )
589             aMacroBox.InsertEntry( aMacros.GetObject( iMeth )->GetName() );
590         aMacroBox.SetUpdateMode( sal_True );
591 
592         if ( aMacroBox.GetEntryCount() )
593         {
594             SvLBoxEntry* pEntry = aMacroBox.GetEntry( 0 );
595             DBG_ASSERT( pEntry, "Entry ?!" );
596             aMacroBox.SetCurEntry( pEntry );
597         }
598     }
599 
600     UpdateFields();
601     CheckButtons();
602     return 0;
603 }
604 
605 
606 
607 IMPL_LINK( MacroChooser, EditModifyHdl, Edit *, pEdit )
608 {
609     (void)pEdit;
610 
611     // Das Modul, in dem bei Neu das Macro landet, selektieren,
612     // wenn BasicManager oder Lib selektiert.
613     SvLBoxEntry* pCurEntry = aBasicBox.GetCurEntry();
614     if ( pCurEntry )
615     {
616         sal_uInt16 nDepth = aBasicBox.GetModel()->GetDepth( pCurEntry );
617         if ( ( nDepth == 1 ) && ( aBasicBox.IsEntryProtected( pCurEntry ) ) )
618         {
619             // Dann auf die entsprechende Std-Lib stellen...
620             SvLBoxEntry* pManagerEntry = aBasicBox.GetModel()->GetParent( pCurEntry );
621             pCurEntry = aBasicBox.GetModel()->FirstChild( pManagerEntry );
622         }
623         if ( nDepth < 2 )
624         {
625             SvLBoxEntry* pNewEntry = pCurEntry;
626             while ( pCurEntry && ( nDepth < 2 ) )
627             {
628                 pCurEntry = aBasicBox.FirstChild( pCurEntry );
629                 if ( pCurEntry )
630                 {
631                     pNewEntry = pCurEntry;
632                     nDepth = aBasicBox.GetModel()->GetDepth( pCurEntry );
633                 }
634             }
635             SaveSetCurEntry( aBasicBox, pNewEntry );
636         }
637         if ( aMacroBox.GetEntryCount() )
638         {
639             String aEdtText( aMacroNameEdit.GetText() );
640             sal_Bool bFound = sal_False;
641             for ( sal_uInt16 n = 0; n < aMacroBox.GetEntryCount(); n++ )
642             {
643                 SvLBoxEntry* pEntry = aMacroBox.GetEntry( n );
644                 DBG_ASSERT( pEntry, "Entry ?!" );
645                 if ( aMacroBox.GetEntryText( pEntry ).CompareIgnoreCaseToAscii( aEdtText ) == COMPARE_EQUAL )
646                 {
647                     SaveSetCurEntry( aMacroBox, pEntry );
648                     bFound = sal_True;
649                     break;
650                 }
651             }
652             if ( !bFound )
653             {
654                 SvLBoxEntry* pEntry = aMacroBox.FirstSelected();
655                 // Wenn es den Eintrag gibt ->Select ->Desription...
656                 if ( pEntry )
657                     aMacroBox.Select( pEntry, sal_False );
658             }
659         }
660     }
661 
662     CheckButtons();
663     return 0;
664 }
665 
666 
667 
668 IMPL_LINK( MacroChooser, ButtonHdl, Button *, pButton )
669 {
670     // ausser bei New/Record wird die Description durch LoseFocus uebernommen.
671     if ( pButton == &aRunButton )
672     {
673         StoreMacroDescription();
674 
675         // #116444# check security settings before macro execution
676         if ( nMode == MACROCHOOSER_ALL )
677         {
678             SbMethod* pMethod = GetMacro();
679             SbModule* pModule = pMethod ? pMethod->GetModule() : NULL;
680             StarBASIC* pBasic = pModule ? (StarBASIC*)pModule->GetParent() : NULL;
681             BasicManager* pBasMgr = pBasic ? BasicIDE::FindBasicManager( pBasic ) : NULL;
682             if ( pBasMgr )
683             {
684                 ScriptDocument aDocument( ScriptDocument::getDocumentForBasicManager( pBasMgr ) );
685                 if ( aDocument.isDocument() && !aDocument.allowMacros() )
686                 {
687                     WarningBox( this, WB_OK, String( IDEResId( RID_STR_CANNOTRUNMACRO ) ) ).Execute();
688                     return 0;
689                 }
690             }
691         }
692         else if ( nMode == MACROCHOOSER_RECORDING )
693         {
694             sal_Bool bValid = BasicIDE::IsValidSbxName( aMacroNameEdit.GetText() );
695             if ( !bValid )
696             {
697                 ErrorBox( this, WB_OK | WB_DEF_OK, String( IDEResId( RID_STR_BADSBXNAME ) ) ).Execute();
698                 aMacroNameEdit.SetSelection( Selection( 0, aMacroNameEdit.GetText().Len() ) );
699                 aMacroNameEdit.GrabFocus();
700                 return 0;
701             }
702 
703             SbMethod* pMethod = GetMacro();
704             if ( pMethod && !QueryReplaceMacro( pMethod->GetName(), this ) )
705                 return 0;
706         }
707 
708         EndDialog( MACRO_OK_RUN );
709     }
710     else if ( pButton == &aCloseButton )
711     {
712         StoreMacroDescription();
713         EndDialog( MACRO_CLOSE );
714     }
715     else if ( ( pButton == &aEditButton ) || ( pButton == &aNewDelButton ) )
716     {
717         SvLBoxEntry* pCurEntry = aBasicBox.GetCurEntry();
718         BasicEntryDescriptor aDesc( aBasicBox.GetEntryDescriptor( pCurEntry ) );
719         ScriptDocument aDocument( aDesc.GetDocument() );
720         DBG_ASSERT( aDocument.isAlive(), "MacroChooser::ButtonHdl: no document, or document is dead!" );
721         if ( !aDocument.isAlive() )
722             return 0;
723         BasicManager* pBasMgr = aDocument.getBasicManager();
724         String aLib( aDesc.GetLibName() );
725         String aMod( aDesc.GetName() );
726         // extract the module name from the string like "Sheet1 (Example1)"
727         if( aDesc.GetLibSubName().Equals( String( IDEResId( RID_STR_DOCUMENT_OBJECTS ) ) ) )
728         {
729             sal_uInt16 nIndex = 0;
730             aMod = aMod.GetToken( 0, ' ', nIndex );
731         }
732         String aSub( aDesc.GetMethodName() );
733         SfxMacroInfoItem aInfoItem( SID_BASICIDE_ARG_MACROINFO, pBasMgr, aLib, aMod, aSub, String() );
734         if ( pButton == &aEditButton )
735         {
736             SvLBoxEntry* pEntry = aMacroBox.FirstSelected();
737             if ( pEntry )
738                 aInfoItem.SetMethod( aMacroBox.GetEntryText( pEntry ) );
739             StoreMacroDescription();
740             SfxAllItemSet aArgs( SFX_APP()->GetPool() );
741             SfxRequest aRequest( SID_BASICIDE_APPEAR, SFX_CALLMODE_SYNCHRON, aArgs );
742             SFX_APP()->ExecuteSlot( aRequest );
743 
744             BasicIDEShell* pIDEShell = IDE_DLL()->GetShell();
745             SfxViewFrame* pViewFrame = pIDEShell ? pIDEShell->GetViewFrame() : NULL;
746             SfxDispatcher* pDispatcher = pViewFrame ? pViewFrame->GetDispatcher() : NULL;
747             if( pDispatcher )
748                 pDispatcher->Execute( SID_BASICIDE_EDITMACRO, SFX_CALLMODE_ASYNCHRON, &aInfoItem, 0L );
749             EndDialog( MACRO_EDIT );
750         }
751         else
752         {
753             if ( bNewDelIsDel )
754             {
755                 DeleteMacro();
756                 BasicIDEShell* pIDEShell = IDE_DLL()->GetShell();
757                 SfxViewFrame* pViewFrame = pIDEShell ? pIDEShell->GetViewFrame() : NULL;
758                 SfxDispatcher* pDispatcher = pViewFrame ? pViewFrame->GetDispatcher() : NULL;
759                 if( pDispatcher )
760                 {
761                     pDispatcher->Execute( SID_BASICIDE_UPDATEMODULESOURCE,
762                                           SFX_CALLMODE_SYNCHRON, &aInfoItem, 0L );
763                 }
764                 CheckButtons();
765                 UpdateFields();
766                 //if ( aMacroBox.GetCurEntry() )    // OV-Bug ?
767                 //  aMacroBox.Select( aMacroBox.GetCurEntry() );
768             }
769             else
770             {
771                 sal_Bool bValid = BasicIDE::IsValidSbxName( aMacroNameEdit.GetText() );
772                 if ( !bValid )
773                 {
774                     ErrorBox( this, WB_OK | WB_DEF_OK, String( IDEResId( RID_STR_BADSBXNAME ) ) ).Execute();
775                     aMacroNameEdit.SetSelection( Selection( 0, aMacroNameEdit.GetText().Len() ) );
776                     aMacroNameEdit.GrabFocus();
777                     return 1;
778                 }
779                 SbMethod* pMethod = CreateMacro();
780                 if ( pMethod )
781                 {
782                     aInfoItem.SetMethod( pMethod->GetName() );
783                     aInfoItem.SetModule( pMethod->GetModule()->GetName() );
784                     aInfoItem.SetLib( pMethod->GetModule()->GetParent()->GetName() );
785                     SfxAllItemSet aArgs( SFX_APP()->GetPool() );
786                     SfxRequest aRequest( SID_BASICIDE_APPEAR, SFX_CALLMODE_SYNCHRON, aArgs );
787                     SFX_APP()->ExecuteSlot( aRequest );
788 
789                     BasicIDEShell* pIDEShell = IDE_DLL()->GetShell();
790                     SfxViewFrame* pViewFrame = pIDEShell ? pIDEShell->GetViewFrame() : NULL;
791                     SfxDispatcher* pDispatcher = pViewFrame ? pViewFrame->GetDispatcher() : NULL;
792                     if ( pDispatcher )
793                         pDispatcher->Execute( SID_BASICIDE_EDITMACRO, SFX_CALLMODE_ASYNCHRON, &aInfoItem, 0L );
794                     StoreMacroDescription();
795                     EndDialog( MACRO_NEW );
796                 }
797             }
798         }
799     }
800 
801     else if ( pButton == &aAssignButton )
802     {
803         SvLBoxEntry* pCurEntry = aBasicBox.GetCurEntry();
804         BasicEntryDescriptor aDesc( aBasicBox.GetEntryDescriptor( pCurEntry ) );
805         ScriptDocument aDocument( aDesc.GetDocument() );
806         DBG_ASSERT( aDocument.isAlive(), "MacroChooser::ButtonHdl: no document, or document is dead!" );
807         if ( !aDocument.isAlive() )
808             return 0;
809         BasicManager* pBasMgr = aDocument.getBasicManager();
810         String aLib( aDesc.GetLibName() );
811         String aMod( aDesc.GetName() );
812         String aSub( aMacroNameEdit.GetText() );
813         SbMethod* pMethod = GetMacro();
814         DBG_ASSERT( pBasMgr, "BasMgr?" );
815         DBG_ASSERT( pMethod, "Method?" );
816         String aComment( GetInfo( pMethod ) );
817         SfxMacroInfoItem aItem( SID_MACROINFO, pBasMgr, aLib, aMod, aSub, aComment );
818         SfxAllItemSet Args( SFX_APP()->GetPool() );
819         SfxRequest aRequest( SID_CONFIG, SFX_CALLMODE_SYNCHRON, Args );
820         aRequest.AppendItem( aItem );
821         SFX_APP()->ExecuteSlot( aRequest );
822     }
823     else if ( pButton == &aNewLibButton )
824     {
825         SvLBoxEntry* pCurEntry = aBasicBox.GetCurEntry();
826         BasicEntryDescriptor aDesc( aBasicBox.GetEntryDescriptor( pCurEntry ) );
827         ScriptDocument aDocument( aDesc.GetDocument() );
828         createLibImpl( static_cast<Window*>( this ), aDocument, NULL, &aBasicBox );
829     }
830     else if ( pButton == &aNewModButton )
831     {
832         SvLBoxEntry* pCurEntry = aBasicBox.GetCurEntry();
833         BasicEntryDescriptor aDesc( aBasicBox.GetEntryDescriptor( pCurEntry ) );
834         ScriptDocument aDocument( aDesc.GetDocument() );
835         String aLibName( aDesc.GetLibName() );
836         String aModName;
837         createModImpl( static_cast<Window*>( this ), aDocument,
838             aBasicBox, aLibName, aModName, true );
839     }
840     else if ( pButton == &aOrganizeButton )
841     {
842         StoreMacroDescription();
843 
844         BasicEntryDescriptor aDesc( aBasicBox.GetEntryDescriptor( aBasicBox.FirstSelected() ) );
845         OrganizeDialog* pDlg = new OrganizeDialog( this, 0, aDesc );
846         sal_uInt16 nRet = pDlg->Execute();
847         delete pDlg;
848 
849         if ( nRet ) // Nicht einfach nur geschlossen
850         {
851             EndDialog( MACRO_EDIT );
852             return 0;
853         }
854 
855         BasicIDEShell* pIDEShell = IDE_DLL()->GetShell();
856         if ( pIDEShell && pIDEShell->IsAppBasicModified() )
857             bForceStoreBasic = sal_True;
858 
859         aBasicBox.UpdateEntries();
860     }
861     return 0;
862 }
863 
864 
865 
866 void MacroChooser::UpdateFields()
867 {
868     SvLBoxEntry*    pMacroEntry = aMacroBox.GetCurEntry();
869     String          aEmptyStr;
870 
871     aMacroNameEdit.SetText( aEmptyStr );
872     if ( pMacroEntry )
873         aMacroNameEdit.SetText( aMacroBox.GetEntryText( pMacroEntry ) );
874 }
875 
876 void MacroChooser::SetMode( sal_uInt16 nM )
877 {
878     nMode = nM;
879     if ( nMode == MACROCHOOSER_ALL )
880     {
881         aRunButton.SetText( String( IDEResId( RID_STR_RUN ) ) );
882         EnableButton( aNewDelButton, sal_True );
883         EnableButton( aOrganizeButton, sal_True );
884     }
885     else if ( nMode == MACROCHOOSER_CHOOSEONLY )
886     {
887         aRunButton.SetText( String( IDEResId( RID_STR_CHOOSE ) ) );
888         EnableButton( aNewDelButton, sal_False );
889         EnableButton( aOrganizeButton, sal_False );
890     }
891     else if ( nMode == MACROCHOOSER_RECORDING )
892     {
893         aRunButton.SetText( String( IDEResId( RID_STR_RECORD ) ) );
894         EnableButton( aNewDelButton, sal_False );
895         EnableButton( aOrganizeButton, sal_False );
896 
897         aAssignButton.Hide();
898         aEditButton.Hide();
899         aNewDelButton.Hide();
900         aOrganizeButton.Hide();
901         aMacroFromTxT.Hide();
902 
903         aNewLibButton.Show();
904         aNewModButton.Show();
905         aMacrosSaveInTxt.Show();
906 
907         Point aHelpPos = aHelpButton.GetPosPixel();
908         Point aHelpPosLogic = PixelToLogic( aHelpPos, MapMode(MAP_APPFONT) );
909         aHelpPosLogic.Y() -= 34;
910         aHelpPos = LogicToPixel( aHelpPosLogic, MapMode(MAP_APPFONT) );
911         aHelpButton.SetPosPixel( aHelpPos );
912     }
913     CheckButtons();
914 }
915 
916 String MacroChooser::GetInfo( SbxVariable* pVar )
917 {
918     String aComment;
919     SbxInfoRef xInfo = pVar->GetInfo();
920     if ( xInfo.Is() )
921         aComment = xInfo->GetComment();
922     return aComment;
923 }
924 
925