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