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