Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
5 : : * This Source Code Form is subject to the terms of the Mozilla Public
6 : : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
11 : : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : : * contributor license agreements. See the NOTICE file distributed
13 : : * with this work for additional information regarding copyright
14 : : * ownership. The ASF licenses this file to you under the Apache
15 : : * License, Version 2.0 (the "License"); you may not use this file
16 : : * except in compliance with the License. You may obtain a copy of
17 : : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : : */
19 : :
20 : : #include <vcl/msgbox.hxx>
21 : : #include <vector>
22 : : #include <algorithm>
23 : : #include <basic/basmgr.hxx>
24 : : #include <basic/sbmeth.hxx>
25 : : #include <basic/sbx.hxx>
26 : : #include <unotools/moduleoptions.hxx>
27 : :
28 : : #include <iderdll.hxx>
29 : : #include <iderdll2.hxx>
30 : : #include <basobj.hxx>
31 : : #include <basidesh.hxx>
32 : : #include <objdlg.hxx>
33 : : #include <bastypes.hxx>
34 : : #include <basdoc.hxx>
35 : : #include <basidesh.hrc>
36 : :
37 : : #include <baside2.hxx>
38 : : #include <baside3.hxx>
39 : : #include <basicmod.hxx>
40 : : #include <localizationmgr.hxx>
41 : : #include "dlged.hxx"
42 : : #include <dlgeddef.hxx>
43 : : #include <comphelper/processfactory.hxx>
44 : : #include <com/sun/star/script/XLibraryContainer.hpp>
45 : : #include <com/sun/star/script/XLibraryContainerPassword.hpp>
46 : : #include <com/sun/star/container/XNameContainer.hpp>
47 : : #include <xmlscript/xmldlg_imexp.hxx>
48 : : #include <sfx2/app.hxx>
49 : : #include <sfx2/dispatch.hxx>
50 : : #include <sfx2/request.hxx>
51 : : #include <rtl/uri.hxx>
52 : : #include <osl/process.h>
53 : : #include <osl/file.hxx>
54 : :
55 : : using namespace comphelper;
56 : : using namespace ::com::sun::star;
57 : : using namespace ::com::sun::star::uno;
58 : : using namespace ::com::sun::star::container;
59 : :
60 : :
61 : : //----------------------------------------------------------------------------
62 : :
63 : : extern "C" {
64 : 0 : SAL_DLLPUBLIC_EXPORT long basicide_handle_basic_error( void* pPtr )
65 : : {
66 : 0 : return BasicIDE::HandleBasicError( (StarBASIC*)pPtr );
67 : : }
68 : : }
69 : :
70 : : namespace BasicIDE
71 : : {
72 : : //----------------------------------------------------------------------------
73 : :
74 : 0 : SbMethod* CreateMacro( SbModule* pModule, const String& rMacroName )
75 : : {
76 : 0 : BasicIDEShell* pIDEShell = BasicIDEGlobals::GetShell();
77 : 0 : SfxViewFrame* pViewFrame = pIDEShell ? pIDEShell->GetViewFrame() : NULL;
78 : 0 : SfxDispatcher* pDispatcher = pViewFrame ? pViewFrame->GetDispatcher() : NULL;
79 : :
80 : 0 : if( pDispatcher )
81 : : {
82 : 0 : pDispatcher->Execute( SID_BASICIDE_STOREALLMODULESOURCES );
83 : : }
84 : :
85 : 0 : if ( pModule->GetMethods()->Find( rMacroName, SbxCLASS_METHOD ) )
86 : 0 : return 0;
87 : :
88 : 0 : String aMacroName( rMacroName );
89 : 0 : if ( aMacroName.Len() == 0 )
90 : : {
91 : 0 : if ( !pModule->GetMethods()->Count() )
92 : 0 : aMacroName = String( RTL_CONSTASCII_USTRINGPARAM( "Main" ) );
93 : : else
94 : : {
95 : 0 : bool bValid = false;
96 : 0 : String aStdMacroText( RTL_CONSTASCII_USTRINGPARAM( "Macro" ) );
97 : 0 : sal_uInt16 nMacro = 1;
98 : 0 : while ( !bValid )
99 : : {
100 : 0 : aMacroName = aStdMacroText;
101 : 0 : aMacroName += String::CreateFromInt32( nMacro );
102 : : // test whether existing...
103 : 0 : bValid = pModule->GetMethods()->Find( aMacroName, SbxCLASS_METHOD ) ? false : true;
104 : 0 : nMacro++;
105 : 0 : }
106 : : }
107 : : }
108 : :
109 : 0 : ::rtl::OUString aOUSource( pModule->GetSource32() );
110 : :
111 : : // don't produce too many empty lines...
112 : 0 : sal_Int32 nSourceLen = aOUSource.getLength();
113 : 0 : if ( nSourceLen > 2 )
114 : : {
115 : 0 : const sal_Unicode* pStr = aOUSource.getStr();
116 : 0 : if ( pStr[ nSourceLen - 1 ] != LINE_SEP )
117 : 0 : aOUSource += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "\n\n" ) );
118 : 0 : else if ( pStr[ nSourceLen - 2 ] != LINE_SEP )
119 : 0 : aOUSource += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "\n" ) );
120 : 0 : else if ( pStr[ nSourceLen - 3 ] == LINE_SEP )
121 : 0 : aOUSource = aOUSource.copy( 0, nSourceLen-1 );
122 : : }
123 : :
124 : 0 : ::rtl::OUString aSubStr;
125 : 0 : aSubStr = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Sub " ) );
126 : 0 : aSubStr += aMacroName;
127 : 0 : aSubStr += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "\n\nEnd Sub" ) );
128 : :
129 : 0 : aOUSource += aSubStr;
130 : :
131 : : // update module in library
132 : 0 : ScriptDocument aDocument( ScriptDocument::NoDocument );
133 : 0 : StarBASIC* pBasic = dynamic_cast<StarBASIC*>(pModule->GetParent());
134 : : DBG_ASSERT(pBasic, "BasicIDE::CreateMacro: No Basic found!");
135 : 0 : if ( pBasic )
136 : : {
137 : 0 : BasicManager* pBasMgr = BasicIDE::FindBasicManager( pBasic );
138 : : DBG_ASSERT(pBasMgr, "BasicIDE::CreateMacro: No BasicManager found!");
139 : 0 : if ( pBasMgr )
140 : : {
141 : 0 : aDocument = ScriptDocument::getDocumentForBasicManager( pBasMgr );
142 : : OSL_ENSURE( aDocument.isValid(), "BasicIDE::CreateMacro: no document for the given BasicManager!" );
143 : 0 : if ( aDocument.isValid() )
144 : : {
145 : 0 : String aLibName = pBasic->GetName();
146 : 0 : String aModName = pModule->GetName();
147 : 0 : OSL_VERIFY( aDocument.updateModule( aLibName, aModName, aOUSource ) );
148 : : }
149 : : }
150 : : }
151 : :
152 : 0 : SbMethod* pMethod = (SbMethod*)pModule->GetMethods()->Find( aMacroName, SbxCLASS_METHOD );
153 : :
154 : 0 : if( pDispatcher )
155 : : {
156 : 0 : pDispatcher->Execute( SID_BASICIDE_UPDATEALLMODULESOURCES );
157 : : }
158 : :
159 : 0 : if ( aDocument.isAlive() )
160 : 0 : BasicIDE::MarkDocumentModified( aDocument );
161 : :
162 : 0 : return pMethod;
163 : : }
164 : :
165 : : //----------------------------------------------------------------------------
166 : :
167 : 0 : bool RenameDialog( Window* pErrorParent, const ScriptDocument& rDocument, const ::rtl::OUString& rLibName, const ::rtl::OUString& rOldName, const ::rtl::OUString& rNewName )
168 : : throw(ElementExistException, NoSuchElementException)
169 : : {
170 : 0 : if ( !rDocument.hasDialog( rLibName, rOldName ) )
171 : : {
172 : : OSL_FAIL( "BasicIDE::RenameDialog: old module name is invalid!" );
173 : 0 : return false;
174 : : }
175 : :
176 : 0 : if ( rDocument.hasDialog( rLibName, rNewName ) )
177 : : {
178 : 0 : ErrorBox aError( pErrorParent, WB_OK | WB_DEF_OK, IDE_RESSTR(RID_STR_SBXNAMEALLREADYUSED2) );
179 : 0 : aError.Execute();
180 : 0 : return false;
181 : : }
182 : :
183 : : // #i74440
184 : 0 : if ( rNewName.isEmpty() )
185 : : {
186 : 0 : ErrorBox aError( pErrorParent, WB_OK | WB_DEF_OK, IDE_RESSTR(RID_STR_BADSBXNAME) );
187 : 0 : aError.Execute();
188 : 0 : return false;
189 : : }
190 : :
191 : 0 : BasicIDEShell* pIDEShell = BasicIDEGlobals::GetShell();
192 : 0 : basctl::DialogWindow* pWin = pIDEShell ? pIDEShell->FindDlgWin(rDocument, rLibName, rOldName) : 0;
193 : 0 : Reference< XNameContainer > xExistingDialog;
194 : 0 : if ( pWin )
195 : 0 : xExistingDialog = pWin->GetEditor()->GetDialog();
196 : :
197 : 0 : if ( xExistingDialog.is() )
198 : 0 : LocalizationMgr::renameStringResourceIDs( rDocument, rLibName, rNewName, xExistingDialog );
199 : :
200 : 0 : if ( !rDocument.renameDialog( rLibName, rOldName, rNewName, xExistingDialog ) )
201 : 0 : return false;
202 : :
203 : 0 : if ( pWin )
204 : : {
205 : : // set new name in window
206 : 0 : pWin->SetName( rNewName );
207 : :
208 : : // update property browser
209 : 0 : pWin->UpdateBrowser();
210 : :
211 : : // update tabwriter
212 : 0 : sal_uInt16 nId = pIDEShell->GetIDEWindowId( pWin );
213 : : DBG_ASSERT( nId, "No entry in Tabbar!" );
214 : 0 : if ( nId )
215 : : {
216 : 0 : BasicIDETabBar* pTabBar = (BasicIDETabBar*)pIDEShell->GetTabBar();
217 : 0 : pTabBar->SetPageText( nId, rNewName );
218 : 0 : pTabBar->Sort();
219 : 0 : pTabBar->MakeVisible( pTabBar->GetCurPageId() );
220 : : }
221 : : }
222 : 0 : return true;
223 : : }
224 : :
225 : : //----------------------------------------------------------------------------
226 : :
227 : 0 : bool RemoveDialog( const ScriptDocument& rDocument, const ::rtl::OUString& rLibName, const ::rtl::OUString& rDlgName )
228 : : {
229 : 0 : BasicIDEShell* pIDEShell = BasicIDEGlobals::GetShell();
230 : 0 : if ( pIDEShell )
231 : : {
232 : 0 : if (basctl::DialogWindow* pDlgWin = pIDEShell->FindDlgWin(rDocument, rLibName, rDlgName))
233 : : {
234 : 0 : Reference< container::XNameContainer > xDialogModel = pDlgWin->GetDialog();
235 : 0 : LocalizationMgr::removeResourceForDialog( rDocument, rLibName, rDlgName, xDialogModel );
236 : : }
237 : : }
238 : :
239 : 0 : return rDocument.removeDialog( rLibName, rDlgName );
240 : : }
241 : :
242 : : //----------------------------------------------------------------------------
243 : :
244 : 0 : StarBASIC* FindBasic( const SbxVariable* pVar )
245 : : {
246 : 0 : SbxVariable const* pSbx = pVar;
247 : 0 : while (pSbx && !dynamic_cast<StarBASIC const*>(pSbx))
248 : 0 : pSbx = pSbx->GetParent();
249 : 0 : return (StarBASIC*)pSbx;
250 : : }
251 : :
252 : : //----------------------------------------------------------------------------
253 : :
254 : 0 : BasicManager* FindBasicManager( StarBASIC* pLib )
255 : : {
256 : 0 : ScriptDocuments aDocuments( ScriptDocument::getAllScriptDocuments( ScriptDocument::AllWithApplication ) );
257 : 0 : for ( ScriptDocuments::const_iterator doc = aDocuments.begin();
258 : 0 : doc != aDocuments.end();
259 : : ++doc
260 : : )
261 : : {
262 : 0 : BasicManager* pBasicMgr = doc->getBasicManager();
263 : : OSL_ENSURE( pBasicMgr, "BasicIDE::FindBasicManager: no basic manager for the document!" );
264 : 0 : if ( !pBasicMgr )
265 : 0 : continue;
266 : :
267 : 0 : Sequence< ::rtl::OUString > aLibNames( doc->getLibraryNames() );
268 : 0 : sal_Int32 nLibCount = aLibNames.getLength();
269 : 0 : const ::rtl::OUString* pLibNames = aLibNames.getConstArray();
270 : :
271 : 0 : for ( sal_Int32 i = 0 ; i < nLibCount ; i++ )
272 : : {
273 : 0 : StarBASIC* pL = pBasicMgr->GetLib( pLibNames[ i ] );
274 : 0 : if ( pL == pLib )
275 : 0 : return pBasicMgr;
276 : : }
277 : 0 : }
278 : 0 : return NULL;
279 : : }
280 : :
281 : : //----------------------------------------------------------------------------
282 : :
283 : 0 : void MarkDocumentModified( const ScriptDocument& rDocument )
284 : : {
285 : : // does not have to come from a document...
286 : 0 : if ( rDocument.isApplication() )
287 : : {
288 : 0 : if (BasicIDEShell* pIDEShell = BasicIDEGlobals::GetShell())
289 : : {
290 : 0 : pIDEShell->SetAppBasicModified();
291 : 0 : pIDEShell->UpdateObjectCatalog();
292 : : }
293 : : }
294 : : else
295 : : {
296 : 0 : rDocument.setDocumentModified();
297 : : }
298 : :
299 : 0 : SfxBindings* pBindings = BasicIDE::GetBindingsPtr();
300 : 0 : if ( pBindings )
301 : : {
302 : 0 : pBindings->Invalidate( SID_SIGNATURE );
303 : 0 : pBindings->Invalidate( SID_SAVEDOC );
304 : 0 : pBindings->Update( SID_SAVEDOC );
305 : : }
306 : 0 : }
307 : :
308 : : //----------------------------------------------------------------------------
309 : :
310 : 0 : void RunMethod( SbMethod* pMethod )
311 : : {
312 : 0 : SbxValues aRes;
313 : 0 : aRes.eType = SbxVOID;
314 : 0 : pMethod->Get( aRes );
315 : 0 : }
316 : :
317 : : //----------------------------------------------------------------------------
318 : :
319 : 0 : void StopBasic()
320 : : {
321 : 0 : StarBASIC::Stop();
322 : 0 : BasicIDEShell* pShell = BasicIDEGlobals::GetShell();
323 : 0 : if ( pShell )
324 : : {
325 : 0 : IDEWindowTable& rWindows = pShell->GetIDEWindowTable();
326 : 0 : for( IDEWindowTable::const_iterator it = rWindows.begin(); it != rWindows.end(); ++it )
327 : : {
328 : 0 : IDEBaseWindow* pWin = it->second;
329 : : // call BasicStopped manually because the Stop-Notify
330 : : // might not get through otherwise
331 : 0 : pWin->BasicStopped();
332 : : }
333 : : }
334 : 0 : BasicIDE::BasicStopped();
335 : 0 : }
336 : :
337 : : //----------------------------------------------------------------------------
338 : :
339 : 0 : void BasicStopped( bool* pbAppWindowDisabled,
340 : : bool* pbDispatcherLocked, sal_uInt16* pnWaitCount,
341 : : SfxUInt16Item** ppSWActionCount, SfxUInt16Item** ppSWLockViewCount )
342 : : {
343 : : // maybe there are some locks to be removed after an error
344 : : // or an explicit cancelling of the basic...
345 : :
346 : 0 : if ( pbAppWindowDisabled )
347 : 0 : *pbAppWindowDisabled = false;
348 : 0 : if ( pbDispatcherLocked )
349 : 0 : *pbDispatcherLocked = false;
350 : 0 : if ( pnWaitCount )
351 : 0 : *pnWaitCount = 0;
352 : 0 : if ( ppSWActionCount )
353 : 0 : *ppSWActionCount = 0;
354 : 0 : if ( ppSWLockViewCount )
355 : 0 : *ppSWLockViewCount = 0;
356 : :
357 : : // AppWait ?
358 : 0 : BasicIDEShell* pIDEShell = BasicIDEGlobals::GetShell();
359 : 0 : if( pIDEShell )
360 : : {
361 : 0 : sal_uInt16 nWait = 0;
362 : 0 : while ( pIDEShell->GetViewFrame()->GetWindow().IsWait() )
363 : : {
364 : 0 : pIDEShell->GetViewFrame()->GetWindow().LeaveWait();
365 : 0 : nWait++;
366 : : }
367 : 0 : if ( pnWaitCount )
368 : 0 : *pnWaitCount = nWait;
369 : : }
370 : :
371 : 0 : Window* pDefParent = Application::GetDefDialogParent();
372 : 0 : if ( pDefParent && !pDefParent->IsEnabled() )
373 : : {
374 : 0 : pDefParent->Enable(true);
375 : 0 : if ( pbAppWindowDisabled )
376 : 0 : *pbAppWindowDisabled = true;
377 : : }
378 : :
379 : 0 : }
380 : :
381 : : //----------------------------------------------------------------------------
382 : :
383 : 0 : void InvalidateDebuggerSlots()
384 : : {
385 : 0 : SfxBindings* pBindings = BasicIDE::GetBindingsPtr();
386 : 0 : if ( pBindings )
387 : : {
388 : 0 : pBindings->Invalidate( SID_BASICSTOP );
389 : 0 : pBindings->Update( SID_BASICSTOP );
390 : 0 : pBindings->Invalidate( SID_BASICRUN );
391 : 0 : pBindings->Update( SID_BASICRUN );
392 : 0 : pBindings->Invalidate( SID_BASICCOMPILE );
393 : 0 : pBindings->Update( SID_BASICCOMPILE );
394 : 0 : pBindings->Invalidate( SID_BASICSTEPOVER );
395 : 0 : pBindings->Update( SID_BASICSTEPOVER );
396 : 0 : pBindings->Invalidate( SID_BASICSTEPINTO );
397 : 0 : pBindings->Update( SID_BASICSTEPINTO );
398 : 0 : pBindings->Invalidate( SID_BASICSTEPOUT );
399 : 0 : pBindings->Update( SID_BASICSTEPOUT );
400 : 0 : pBindings->Invalidate( SID_BASICIDE_TOGGLEBRKPNT );
401 : 0 : pBindings->Update( SID_BASICIDE_TOGGLEBRKPNT );
402 : 0 : pBindings->Invalidate( SID_BASICIDE_STAT_POS );
403 : 0 : pBindings->Update( SID_BASICIDE_STAT_POS );
404 : : }
405 : 0 : }
406 : :
407 : : //----------------------------------------------------------------------------
408 : :
409 : 0 : long HandleBasicError( StarBASIC* pBasic )
410 : : {
411 : 0 : BasicIDEGlobals::ensure();
412 : 0 : BasicIDE::BasicStopped();
413 : :
414 : : // no error output during macro choosing
415 : 0 : if ( BasicIDEGlobals::GetExtraData()->ChoosingMacro() )
416 : 0 : return 1;
417 : 0 : if ( BasicIDEGlobals::GetExtraData()->ShellInCriticalSection() )
418 : 0 : return 2;
419 : :
420 : 0 : long nRet = 0;
421 : 0 : BasicIDEShell* pIDEShell = 0;
422 : 0 : if ( SvtModuleOptions().IsBasicIDE() )
423 : : {
424 : 0 : BasicManager* pBasMgr = BasicIDE::FindBasicManager( pBasic );
425 : 0 : if ( pBasMgr )
426 : : {
427 : 0 : bool bProtected = false;
428 : 0 : ScriptDocument aDocument( ScriptDocument::getDocumentForBasicManager( pBasMgr ) );
429 : : OSL_ENSURE( aDocument.isValid(), "BasicIDE::HandleBasicError: no document for the given BasicManager!" );
430 : 0 : if ( aDocument.isValid() )
431 : : {
432 : 0 : ::rtl::OUString aOULibName( pBasic->GetName() );
433 : 0 : Reference< script::XLibraryContainer > xModLibContainer( aDocument.getLibraryContainer( E_SCRIPTS ) );
434 : 0 : if ( xModLibContainer.is() && xModLibContainer->hasByName( aOULibName ) )
435 : : {
436 : 0 : Reference< script::XLibraryContainerPassword > xPasswd( xModLibContainer, UNO_QUERY );
437 : 0 : if ( xPasswd.is() && xPasswd->isLibraryPasswordProtected( aOULibName ) && !xPasswd->isLibraryPasswordVerified( aOULibName ) )
438 : : {
439 : 0 : bProtected = true;
440 : 0 : }
441 : 0 : }
442 : : }
443 : :
444 : 0 : if ( !bProtected )
445 : : {
446 : 0 : pIDEShell = BasicIDEGlobals::GetShell();
447 : 0 : if ( !pIDEShell )
448 : : {
449 : 0 : SfxAllItemSet aArgs( SFX_APP()->GetPool() );
450 : 0 : SfxRequest aRequest( SID_BASICIDE_APPEAR, SFX_CALLMODE_SYNCHRON, aArgs );
451 : 0 : SFX_APP()->ExecuteSlot( aRequest );
452 : 0 : pIDEShell = BasicIDEGlobals::GetShell();
453 : : }
454 : 0 : }
455 : : }
456 : : }
457 : :
458 : 0 : if ( pIDEShell )
459 : 0 : nRet = pIDEShell->CallBasicErrorHdl( pBasic );
460 : : else
461 : 0 : ErrorHandler::HandleError( StarBASIC::GetErrorCode() );
462 : :
463 : 0 : return nRet;
464 : : }
465 : :
466 : : //----------------------------------------------------------------------------
467 : :
468 : 0 : SfxBindings* GetBindingsPtr()
469 : : {
470 : 0 : SfxBindings* pBindings = NULL;
471 : :
472 : 0 : SfxViewFrame* pFrame = NULL;
473 : 0 : if ( BasicIDEGlobals::GetShell() )
474 : : {
475 : 0 : pFrame = BasicIDEGlobals::GetShell()->GetViewFrame();
476 : : }
477 : : else
478 : : {
479 : 0 : SfxViewFrame* pView = SfxViewFrame::GetFirst();
480 : 0 : while ( pView )
481 : : {
482 : 0 : SfxObjectShell* pObjShell = pView->GetObjectShell();
483 : 0 : if (dynamic_cast<BasicDocShell*>(pObjShell))
484 : : {
485 : 0 : pFrame = pView;
486 : 0 : break;
487 : : }
488 : 0 : pView = SfxViewFrame::GetNext( *pView );
489 : : }
490 : : }
491 : 0 : if ( pFrame != NULL )
492 : 0 : pBindings = &pFrame->GetBindings();
493 : :
494 : 0 : return pBindings;
495 : : }
496 : :
497 : : } //namespace BasicIDE
498 : :
499 : :
500 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|