xref: /AOO41X/main/basctl/source/basicide/basobj3.cxx (revision 31598a226906602f93ad246cbee896e3caca5f8f)
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 <ide_pch.hxx>
28 
29 #include <vector>
30 #include <algorithm>
31 #include <basic/sbx.hxx>
32 #include <unotools/moduleoptions.hxx>
33 
34 #include <iderdll.hxx>
35 #include <iderdll2.hxx>
36 #include <basobj.hxx>
37 #include <basidesh.hxx>
38 #include <objdlg.hxx>
39 #include <bastypes.hxx>
40 #include <basdoc.hxx>
41 #include <basidesh.hrc>
42 
43 #include <baside2.hxx>
44 #include <baside3.hxx>
45 #include <basicmod.hxx>
46 #include <localizationmgr.hxx>
47 #include "dlged.hxx"
48 #include <dlgeddef.hxx>
49 #include <comphelper/processfactory.hxx>
50 #ifndef _COM_SUN_STAR_SCRIPT_XLIBRYARYCONTAINER_HPP_
51 #include <com/sun/star/script/XLibraryContainer.hpp>
52 #endif
53 #include <com/sun/star/script/XLibraryContainerPassword.hpp>
54 #include <com/sun/star/container/XNameContainer.hpp>
55 #include <xmlscript/xmldlg_imexp.hxx>
56 #include <rtl/uri.hxx>
57 #include <osl/process.h>
58 #include <osl/file.hxx>
59 
60 using namespace comphelper;
61 using namespace ::com::sun::star;
62 using namespace ::com::sun::star::uno;
63 using namespace ::com::sun::star::container;
64 
65 
66 //----------------------------------------------------------------------------
67 
68 extern "C" {
basicide_handle_basic_error(void * pPtr)69     SAL_DLLPUBLIC_EXPORT long basicide_handle_basic_error( void* pPtr )
70     {
71         return BasicIDE::HandleBasicError( (StarBASIC*)pPtr );
72     }
73 }
74 
75 namespace BasicIDE
76 {
77 //----------------------------------------------------------------------------
78 
CreateMacro(SbModule * pModule,const String & rMacroName)79 SbMethod* CreateMacro( SbModule* pModule, const String& rMacroName )
80 {
81     BasicIDEShell* pIDEShell = IDE_DLL()->GetShell();
82     SfxViewFrame* pViewFrame = pIDEShell ? pIDEShell->GetViewFrame() : NULL;
83     SfxDispatcher* pDispatcher = pViewFrame ? pViewFrame->GetDispatcher() : NULL;
84 
85     if( pDispatcher )
86     {
87         pDispatcher->Execute( SID_BASICIDE_STOREALLMODULESOURCES );
88     }
89 
90     if ( pModule->GetMethods()->Find( rMacroName, SbxCLASS_METHOD ) )
91         return 0;
92 
93     String aMacroName( rMacroName );
94     if ( aMacroName.Len() == 0 )
95     {
96         if ( !pModule->GetMethods()->Count() )
97             aMacroName = String( RTL_CONSTASCII_USTRINGPARAM( "Main" ) );
98         else
99         {
100             sal_Bool bValid = sal_False;
101             String aStdMacroText( RTL_CONSTASCII_USTRINGPARAM( "Macro" ) );
102             //String aStdMacroText( IDEResId( RID_STR_STDMACRONAME ) );
103             sal_uInt16 nMacro = 1;
104             while ( !bValid )
105             {
106                 aMacroName = aStdMacroText;
107                 aMacroName += String::CreateFromInt32( nMacro );
108                 // Pruefen, ob vorhanden...
109                 bValid = pModule->GetMethods()->Find( aMacroName, SbxCLASS_METHOD ) ? sal_False : sal_True;
110                 nMacro++;
111             }
112         }
113     }
114 
115     ::rtl::OUString aOUSource( pModule->GetSource32() );
116 
117     // Nicht zu viele Leerzeilen erzeugen...
118     sal_Int32 nSourceLen = aOUSource.getLength();
119     if ( nSourceLen > 2 )
120     {
121         const sal_Unicode* pStr = aOUSource.getStr();
122         if ( pStr[ nSourceLen - 1 ]  != LINE_SEP )
123             aOUSource += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "\n\n" ) );
124         else if ( pStr[ nSourceLen - 2 ] != LINE_SEP )
125             aOUSource += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "\n" ) );
126         else if ( pStr[ nSourceLen - 3 ] == LINE_SEP )
127             aOUSource = aOUSource.copy( 0, nSourceLen-1 );
128     }
129 
130     ::rtl::OUString aSubStr;
131     aSubStr = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Sub " ) );
132     aSubStr += aMacroName;
133     aSubStr += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "\n\nEnd Sub" ) );
134 
135     aOUSource += aSubStr;
136 
137     // update module in library
138     ScriptDocument aDocument( ScriptDocument::NoDocument );
139     SbxObject* pParent = pModule->GetParent();
140     StarBASIC* pBasic = PTR_CAST(StarBASIC,pParent);
141     DBG_ASSERT(pBasic, "BasicIDE::CreateMacro: No Basic found!");
142     if ( pBasic )
143     {
144         BasicManager* pBasMgr = BasicIDE::FindBasicManager( pBasic );
145         DBG_ASSERT(pBasMgr, "BasicIDE::CreateMacro: No BasicManager found!");
146         if ( pBasMgr )
147         {
148             aDocument = ScriptDocument::getDocumentForBasicManager( pBasMgr );
149             OSL_ENSURE( aDocument.isValid(), "BasicIDE::CreateMacro: no document for the given BasicManager!" );
150             if ( aDocument.isValid() )
151             {
152                 String aLibName = pBasic->GetName();
153                 String aModName = pModule->GetName();
154                 OSL_VERIFY( aDocument.updateModule( aLibName, aModName, aOUSource ) );
155             }
156         }
157     }
158 
159     SbMethod* pMethod = (SbMethod*)pModule->GetMethods()->Find( aMacroName, SbxCLASS_METHOD );
160 
161     if( pDispatcher )
162     {
163         pDispatcher->Execute( SID_BASICIDE_UPDATEALLMODULESOURCES );
164     }
165 
166     if ( aDocument.isAlive() )
167         BasicIDE::MarkDocumentModified( aDocument );
168 
169     return pMethod;
170 }
171 
172 //----------------------------------------------------------------------------
173 
RenameDialog(Window * pErrorParent,const ScriptDocument & rDocument,const String & rLibName,const String & rOldName,const String & rNewName)174 bool RenameDialog( Window* pErrorParent, const ScriptDocument& rDocument, const String& rLibName, const String& rOldName, const String& rNewName )
175     throw(ElementExistException, NoSuchElementException)
176 {
177     if ( !rDocument.hasDialog( rLibName, rOldName ) )
178     {
179         OSL_ENSURE( false, "BasicIDE::RenameDialog: old module name is invalid!" );
180         return false;
181     }
182 
183     if ( rDocument.hasDialog( rLibName, rNewName ) )
184     {
185         ErrorBox aError( pErrorParent, WB_OK | WB_DEF_OK, String( IDEResId( RID_STR_SBXNAMEALLREADYUSED2 ) ) );
186         aError.Execute();
187         return false;
188     }
189 
190     // #i74440
191     if ( rNewName.Len() == 0 )
192     {
193         ErrorBox aError( pErrorParent, WB_OK | WB_DEF_OK, String( IDEResId( RID_STR_BADSBXNAME ) ) );
194         aError.Execute();
195         return false;
196     }
197 
198     BasicIDEShell* pIDEShell = IDE_DLL()->GetShell();
199     IDEBaseWindow* pWin = pIDEShell ? pIDEShell->FindWindow( rDocument, rLibName, rOldName, BASICIDE_TYPE_DIALOG, sal_False ) : NULL;
200     Reference< XNameContainer > xExistingDialog;
201     if ( pWin )
202         xExistingDialog = ((DialogWindow*)pWin)->GetEditor()->GetDialog();
203 
204     if ( xExistingDialog.is() )
205         LocalizationMgr::renameStringResourceIDs( rDocument, rLibName, rNewName, xExistingDialog );
206 
207     if ( !rDocument.renameDialog( rLibName, rOldName, rNewName, xExistingDialog ) )
208         return false;
209 
210     if ( pWin )
211     {
212         // set new name in window
213         pWin->SetName( rNewName );
214 
215         // update property browser
216         ((DialogWindow*)pWin)->UpdateBrowser();
217 
218         // update tabwriter
219         sal_uInt16 nId = (sal_uInt16)(pIDEShell->GetIDEWindowTable()).GetKey( pWin );
220         DBG_ASSERT( nId, "No entry in Tabbar!" );
221         if ( nId )
222         {
223             BasicIDETabBar* pTabBar = (BasicIDETabBar*)pIDEShell->GetTabBar();
224             pTabBar->SetPageText( nId, rNewName );
225             pTabBar->Sort();
226             pTabBar->MakeVisible( pTabBar->GetCurPageId() );
227         }
228     }
229     return true;
230 }
231 
232 //----------------------------------------------------------------------------
233 
RemoveDialog(const ScriptDocument & rDocument,const String & rLibName,const String & rDlgName)234 bool RemoveDialog( const ScriptDocument& rDocument, const String& rLibName, const String& rDlgName )
235 {
236     BasicIDEShell* pIDEShell = IDE_DLL()->GetShell();
237     if ( pIDEShell )
238     {
239         DialogWindow* pDlgWin = pIDEShell->FindDlgWin( rDocument, rLibName, rDlgName, sal_False );
240         if( pDlgWin )
241         {
242             Reference< container::XNameContainer > xDialogModel = pDlgWin->GetDialog();
243             LocalizationMgr::removeResourceForDialog( rDocument, rLibName, rDlgName, xDialogModel );
244         }
245     }
246 
247     return rDocument.removeDialog( rLibName, rDlgName );
248 }
249 
250 //----------------------------------------------------------------------------
251 
FindBasic(const SbxVariable * pVar)252 StarBASIC* FindBasic( const SbxVariable* pVar )
253 {
254     const SbxVariable* pSbx = pVar;
255     while ( pSbx && !pSbx->ISA( StarBASIC ) )
256         pSbx = pSbx->GetParent();
257 
258     DBG_ASSERT( !pSbx || pSbx->ISA( StarBASIC ), "Find Basic: Kein Basic!" );
259     return (StarBASIC*)pSbx;
260 }
261 
262 //----------------------------------------------------------------------------
263 
FindBasicManager(StarBASIC * pLib)264 BasicManager* FindBasicManager( StarBASIC* pLib )
265 {
266     ScriptDocuments aDocuments( ScriptDocument::getAllScriptDocuments( ScriptDocument::AllWithApplication ) );
267     for (   ScriptDocuments::const_iterator doc = aDocuments.begin();
268             doc != aDocuments.end();
269             ++doc
270         )
271     {
272         BasicManager* pBasicMgr = doc->getBasicManager();
273         OSL_ENSURE( pBasicMgr, "BasicIDE::FindBasicManager: no basic manager for the document!" );
274         if ( !pBasicMgr )
275             continue;
276 
277         Sequence< ::rtl::OUString > aLibNames( doc->getLibraryNames() );
278         sal_Int32 nLibCount = aLibNames.getLength();
279         const ::rtl::OUString* pLibNames = aLibNames.getConstArray();
280 
281         for ( sal_Int32 i = 0 ; i < nLibCount ; i++ )
282         {
283             StarBASIC* pL = pBasicMgr->GetLib( pLibNames[ i ] );
284             if ( pL == pLib )
285                 return pBasicMgr;
286         }
287     }
288     return NULL;
289 }
290 
291 //----------------------------------------------------------------------------
292 
MarkDocumentModified(const ScriptDocument & rDocument)293 void MarkDocumentModified( const ScriptDocument& rDocument )
294 {
295     // Muss ja nicht aus einem Document kommen...
296     if ( rDocument.isApplication() )
297     {
298         BasicIDEShell* pIDEShell = IDE_DLL()->GetShell();
299         if ( pIDEShell )
300             pIDEShell->SetAppBasicModified();
301     }
302     else
303     {
304         rDocument.setDocumentModified();
305     }
306 
307     SfxBindings* pBindings = BasicIDE::GetBindingsPtr();
308     if ( pBindings )
309     {
310         pBindings->Invalidate( SID_SIGNATURE );
311         pBindings->Invalidate( SID_SAVEDOC );
312         pBindings->Update( SID_SAVEDOC );
313     }
314 
315     // Objectcatalog updaten...
316     BasicIDEShell* pIDEShell = IDE_DLL()->GetShell();
317     ObjectCatalog* pObjCatalog = pIDEShell ? pIDEShell->GetObjectCatalog() : 0;
318     if ( pObjCatalog )
319         pObjCatalog->UpdateEntries();
320 }
321 
322 //----------------------------------------------------------------------------
323 
RunMethod(SbMethod * pMethod)324 void RunMethod( SbMethod* pMethod )
325 {
326     SbxValues aRes;
327     aRes.eType = SbxVOID;
328     pMethod->Get( aRes );
329 }
330 
331 //----------------------------------------------------------------------------
332 
StopBasic()333 void StopBasic()
334 {
335     StarBASIC::Stop();
336     BasicIDEShell* pShell = IDE_DLL()->GetShell();
337     if ( pShell )
338     {
339         IDEWindowTable& rWindows = pShell->GetIDEWindowTable();
340         IDEBaseWindow* pWin = rWindows.First();
341         while ( pWin )
342         {
343             // BasicStopped von Hand rufen, da das Stop-Notify ggf. sonst nicht
344             // durchkommen kann.
345             pWin->BasicStopped();
346             pWin = rWindows.Next();
347         }
348     }
349     BasicIDE::BasicStopped();
350 }
351 
352 //----------------------------------------------------------------------------
353 
BasicStopped(sal_Bool * pbAppWindowDisabled,sal_Bool * pbDispatcherLocked,sal_uInt16 * pnWaitCount,SfxUInt16Item ** ppSWActionCount,SfxUInt16Item ** ppSWLockViewCount)354 void BasicStopped( sal_Bool* pbAppWindowDisabled,
355         sal_Bool* pbDispatcherLocked, sal_uInt16* pnWaitCount,
356         SfxUInt16Item** ppSWActionCount, SfxUInt16Item** ppSWLockViewCount )
357 {
358     // Nach einem Error oder dem expliziten abbrechen des Basics muessen
359     // ggf. einige Locks entfernt werden...
360 
361     if ( pbAppWindowDisabled )
362         *pbAppWindowDisabled = sal_False;
363     if ( pbDispatcherLocked )
364         *pbDispatcherLocked = sal_False;
365     if ( pnWaitCount )
366         *pnWaitCount = 0;
367     if ( ppSWActionCount )
368         *ppSWActionCount = 0;
369     if ( ppSWLockViewCount )
370         *ppSWLockViewCount = 0;
371 
372     // AppWait ?
373     sal_uInt16 nWait = 0;
374     BasicIDEShell* pIDEShell = IDE_DLL()->GetShell();
375     if( pIDEShell )
376     {
377         while ( pIDEShell->GetViewFrame()->GetWindow().IsWait() )
378         {
379             pIDEShell->GetViewFrame()->GetWindow().LeaveWait();
380             nWait++;
381         }
382         if ( pnWaitCount )
383             *pnWaitCount = nWait;
384     }
385 
386     /*
387     // Interactive = sal_False ?
388     if ( SFX_APP()->IsDispatcherLocked() )
389     {
390         SFX_APP()->LockDispatcher( sal_False );
391         if ( pbDispatcherLocked )
392             *pbDispatcherLocked = sal_True;
393     } */
394 
395     Window* pDefParent = Application::GetDefDialogParent();
396     if ( pDefParent && !pDefParent->IsEnabled() )
397     {
398         pDefParent->Enable( sal_True );
399         if ( pbAppWindowDisabled )
400             *pbAppWindowDisabled = sal_True;
401     }
402 
403 }
404 
405 //----------------------------------------------------------------------------
406 
InvalidateDebuggerSlots()407 void InvalidateDebuggerSlots()
408 {
409     SfxBindings* pBindings = BasicIDE::GetBindingsPtr();
410     if ( pBindings )
411     {
412         pBindings->Invalidate( SID_BASICSTOP );
413         pBindings->Update( SID_BASICSTOP );
414         pBindings->Invalidate( SID_BASICRUN );
415         pBindings->Update( SID_BASICRUN );
416         pBindings->Invalidate( SID_BASICCOMPILE );
417         pBindings->Update( SID_BASICCOMPILE );
418         pBindings->Invalidate( SID_BASICSTEPOVER );
419         pBindings->Update( SID_BASICSTEPOVER );
420         pBindings->Invalidate( SID_BASICSTEPINTO );
421         pBindings->Update( SID_BASICSTEPINTO );
422         pBindings->Invalidate( SID_BASICSTEPOUT );
423         pBindings->Update( SID_BASICSTEPOUT );
424         pBindings->Invalidate( SID_BASICIDE_TOGGLEBRKPNT );
425         pBindings->Update( SID_BASICIDE_TOGGLEBRKPNT );
426         pBindings->Invalidate( SID_BASICIDE_STAT_POS );
427         pBindings->Update( SID_BASICIDE_STAT_POS );
428     }
429 }
430 
431 //----------------------------------------------------------------------------
432 
HandleBasicError(StarBASIC * pBasic)433 long HandleBasicError( StarBASIC* pBasic )
434 {
435     BasicIDEDLL::Init();
436     BasicIDE::BasicStopped();
437 
438     // no error output during macro choosing
439     if ( IDE_DLL()->GetExtraData()->ChoosingMacro() )
440         return 1;
441     if ( IDE_DLL()->GetExtraData()->ShellInCriticalSection() )
442         return 2;
443 
444     long nRet = 0;
445     BasicIDEShell* pIDEShell = 0;
446     if ( SvtModuleOptions().IsBasicIDE() )
447     {
448         BasicManager* pBasMgr = BasicIDE::FindBasicManager( pBasic );
449         if ( pBasMgr )
450         {
451             sal_Bool bProtected = sal_False;
452             ScriptDocument aDocument( ScriptDocument::getDocumentForBasicManager( pBasMgr ) );
453             OSL_ENSURE( aDocument.isValid(), "BasicIDE::HandleBasicError: no document for the given BasicManager!" );
454             if ( aDocument.isValid() )
455             {
456                 ::rtl::OUString aOULibName( pBasic->GetName() );
457                 Reference< script::XLibraryContainer > xModLibContainer( aDocument.getLibraryContainer( E_SCRIPTS ) );
458                 if ( xModLibContainer.is() && xModLibContainer->hasByName( aOULibName ) )
459                 {
460                     Reference< script::XLibraryContainerPassword > xPasswd( xModLibContainer, UNO_QUERY );
461                     if ( xPasswd.is() && xPasswd->isLibraryPasswordProtected( aOULibName ) && !xPasswd->isLibraryPasswordVerified( aOULibName ) )
462                     {
463                         bProtected = sal_True;
464                     }
465                 }
466             }
467 
468             if ( !bProtected )
469             {
470                 pIDEShell = IDE_DLL()->GetShell();
471                 if ( !pIDEShell )
472                 {
473                     SfxAllItemSet aArgs( SFX_APP()->GetPool() );
474                     SfxRequest aRequest( SID_BASICIDE_APPEAR, SFX_CALLMODE_SYNCHRON, aArgs );
475                     SFX_APP()->ExecuteSlot( aRequest );
476                     pIDEShell = IDE_DLL()->GetShell();
477                 }
478             }
479         }
480     }
481 
482     if ( pIDEShell )
483         nRet = pIDEShell->CallBasicErrorHdl( pBasic );
484     else
485         ErrorHandler::HandleError( StarBASIC::GetErrorCode() );
486 
487     return nRet;
488 }
489 
490 //----------------------------------------------------------------------------
491 
GetBindingsPtr()492 SfxBindings* GetBindingsPtr()
493 {
494     SfxBindings* pBindings = NULL;
495 
496     SfxViewFrame* pFrame = NULL;
497     BasicIDEDLL* pIDEDLL = IDE_DLL();
498     if ( pIDEDLL && pIDEDLL->GetShell() )
499     {
500         pFrame = pIDEDLL->GetShell()->GetViewFrame();
501     }
502     else
503     {
504         SfxViewFrame* pView = SfxViewFrame::GetFirst();
505         while ( pView )
506         {
507             SfxObjectShell* pObjShell = pView->GetObjectShell();
508             if ( pObjShell && pObjShell->ISA( BasicDocShell ) )
509             {
510                 pFrame = pView;
511                 break;
512             }
513             pView = SfxViewFrame::GetNext( *pView );
514         }
515     }
516     if ( pFrame != NULL )
517         pBindings = &pFrame->GetBindings();
518 
519     return pBindings;
520 }
521 
522 } //namespace BasicIDE
523 
524 //----------------------------------------------------------------------------
525