bump product version to 5.0.4.1
[LibreOffice.git] / basctl / source / basicide / basobj3.cxx
blob7de0ab37c50e2c5f22f79beefb8f7bf24621c84b
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <vcl/layout.hxx>
21 #include <basic/basmgr.hxx>
22 #include <basic/sbmeth.hxx>
23 #include <unotools/moduleoptions.hxx>
25 #include <iderdll.hxx>
26 #include <iderdll2.hxx>
27 #include <basdoc.hxx>
28 #include <basidesh.hrc>
30 #include <baside2.hxx>
31 #include <baside3.hxx>
32 #include <localizationmgr.hxx>
33 #include "dlged.hxx"
34 #include <com/sun/star/script/XLibraryContainerPassword.hpp>
35 #include <sfx2/dispatch.hxx>
36 #include <sfx2/request.hxx>
38 namespace basctl
41 using namespace comphelper;
42 using namespace ::com::sun::star;
43 using namespace ::com::sun::star::uno;
44 using namespace ::com::sun::star::container;
46 extern "C" {
47 SAL_DLLPUBLIC_EXPORT long basicide_handle_basic_error( void* pPtr )
49 return HandleBasicError( static_cast<StarBASIC*>(pPtr) );
53 SbMethod* CreateMacro( SbModule* pModule, const OUString& rMacroName )
55 SfxDispatcher* pDispatcher = GetDispatcher();
56 if( pDispatcher )
58 pDispatcher->Execute( SID_BASICIDE_STOREALLMODULESOURCES );
61 if ( pModule->GetMethods()->Find( rMacroName, SbxCLASS_METHOD ) )
62 return 0;
64 OUString aMacroName( rMacroName );
65 if ( aMacroName.isEmpty() )
67 if ( !pModule->GetMethods()->Count() )
68 aMacroName = "Main" ;
69 else
71 bool bValid = false;
72 OUString aStdMacroText( "Macro" );
73 sal_Int32 nMacro = 1;
74 while ( !bValid )
76 aMacroName = aStdMacroText;
77 aMacroName += OUString::number( nMacro );
78 // test whether existing...
79 bValid = pModule->GetMethods()->Find( aMacroName, SbxCLASS_METHOD ) == nullptr;
80 nMacro++;
85 OUString aOUSource( pModule->GetSource32() );
87 // don't produce too many empty lines...
88 sal_Int32 nSourceLen = aOUSource.getLength();
89 if ( nSourceLen > 2 )
91 const sal_Unicode* pStr = aOUSource.getStr();
92 if ( pStr[ nSourceLen - 1 ] != LINE_SEP )
93 aOUSource += "\n\n" ;
94 else if ( pStr[ nSourceLen - 2 ] != LINE_SEP )
95 aOUSource += "\n" ;
96 else if ( pStr[ nSourceLen - 3 ] == LINE_SEP )
97 aOUSource = aOUSource.copy( 0, nSourceLen-1 );
100 OUString aSubStr;
101 aSubStr = "Sub " ;
102 aSubStr += aMacroName;
103 aSubStr += "\n\nEnd Sub" ;
105 aOUSource += aSubStr;
107 // update module in library
108 ScriptDocument aDocument( ScriptDocument::NoDocument );
109 StarBASIC* pBasic = dynamic_cast<StarBASIC*>(pModule->GetParent());
110 DBG_ASSERT(pBasic, "basctl::CreateMacro: No Basic found!");
111 if ( pBasic )
113 BasicManager* pBasMgr = FindBasicManager( pBasic );
114 DBG_ASSERT(pBasMgr, "basctl::CreateMacro: No BasicManager found!");
115 if ( pBasMgr )
117 aDocument = ScriptDocument::getDocumentForBasicManager( pBasMgr );
118 OSL_ENSURE( aDocument.isValid(), "basctl::CreateMacro: no document for the given BasicManager!" );
119 if ( aDocument.isValid() )
121 OUString aLibName = pBasic->GetName();
122 OUString aModName = pModule->GetName();
123 OSL_VERIFY( aDocument.updateModule( aLibName, aModName, aOUSource ) );
128 SbMethod* pMethod = static_cast<SbMethod*>(pModule->GetMethods()->Find( aMacroName, SbxCLASS_METHOD ));
130 if( pDispatcher )
132 pDispatcher->Execute( SID_BASICIDE_UPDATEALLMODULESOURCES );
135 if ( aDocument.isAlive() )
136 MarkDocumentModified( aDocument );
138 return pMethod;
141 bool RenameDialog (
142 vcl::Window* pErrorParent,
143 ScriptDocument const& rDocument,
144 OUString const& rLibName,
145 OUString const& rOldName,
146 OUString const& rNewName
148 throw (ElementExistException, NoSuchElementException, RuntimeException, std::exception)
150 if ( !rDocument.hasDialog( rLibName, rOldName ) )
152 OSL_FAIL( "basctl::RenameDialog: old module name is invalid!" );
153 return false;
156 if ( rDocument.hasDialog( rLibName, rNewName ) )
158 ScopedVclPtrInstance< MessageDialog > aError(pErrorParent, IDE_RESSTR(RID_STR_SBXNAMEALLREADYUSED2));
159 aError->Execute();
160 return false;
163 // #i74440
164 if ( rNewName.isEmpty() )
166 ScopedVclPtrInstance< MessageDialog > aError(pErrorParent, IDE_RESSTR(RID_STR_BADSBXNAME));
167 aError->Execute();
168 return false;
171 Shell* pShell = GetShell();
172 DialogWindow* pWin = pShell ? pShell->FindDlgWin(rDocument, rLibName, rOldName) : 0;
173 Reference< XNameContainer > xExistingDialog;
174 if ( pWin )
175 xExistingDialog = pWin->GetEditor().GetDialog();
177 if ( xExistingDialog.is() )
178 LocalizationMgr::renameStringResourceIDs( rDocument, rLibName, rNewName, xExistingDialog );
180 if ( !rDocument.renameDialog( rLibName, rOldName, rNewName, xExistingDialog ) )
181 return false;
183 if (pWin && pShell)
185 // set new name in window
186 pWin->SetName( rNewName );
188 // update property browser
189 pWin->UpdateBrowser();
191 // update tabwriter
192 sal_uInt16 nId = pShell->GetWindowId( pWin );
193 DBG_ASSERT( nId, "No entry in Tabbar!" );
194 if ( nId )
196 TabBar& rTabBar = pShell->GetTabBar();
197 rTabBar.SetPageText( nId, rNewName );
198 rTabBar.Sort();
199 rTabBar.MakeVisible( rTabBar.GetCurPageId() );
202 return true;
205 bool RemoveDialog( const ScriptDocument& rDocument, const OUString& rLibName, const OUString& rDlgName )
207 if (Shell* pShell = GetShell())
209 if (DialogWindow* pDlgWin = pShell->FindDlgWin(rDocument, rLibName, rDlgName))
211 Reference< container::XNameContainer > xDialogModel = pDlgWin->GetDialog();
212 LocalizationMgr::removeResourceForDialog( rDocument, rLibName, rDlgName, xDialogModel );
216 return rDocument.removeDialog( rLibName, rDlgName );
219 StarBASIC* FindBasic( const SbxVariable* pVar )
221 SbxVariable const* pSbx = pVar;
222 while (pSbx && !dynamic_cast<StarBASIC const*>(pSbx))
223 pSbx = pSbx->GetParent();
224 return const_cast<StarBASIC*>(static_cast<const StarBASIC*>(pSbx));
227 BasicManager* FindBasicManager( StarBASIC* pLib )
229 ScriptDocuments aDocuments( ScriptDocument::getAllScriptDocuments( ScriptDocument::AllWithApplication ) );
230 for ( ScriptDocuments::const_iterator doc = aDocuments.begin();
231 doc != aDocuments.end();
232 ++doc
235 BasicManager* pBasicMgr = doc->getBasicManager();
236 OSL_ENSURE( pBasicMgr, "basctl::FindBasicManager: no basic manager for the document!" );
237 if ( !pBasicMgr )
238 continue;
240 Sequence< OUString > aLibNames( doc->getLibraryNames() );
241 sal_Int32 nLibCount = aLibNames.getLength();
242 const OUString* pLibNames = aLibNames.getConstArray();
244 for ( sal_Int32 i = 0 ; i < nLibCount ; i++ )
246 StarBASIC* pL = pBasicMgr->GetLib( pLibNames[ i ] );
247 if ( pL == pLib )
248 return pBasicMgr;
251 return NULL;
254 void MarkDocumentModified( const ScriptDocument& rDocument )
256 // does not have to come from a document...
257 if ( rDocument.isApplication() )
259 if (Shell* pShell = GetShell())
261 pShell->SetAppBasicModified();
262 pShell->UpdateObjectCatalog();
265 else
267 rDocument.setDocumentModified();
270 if (SfxBindings* pBindings = GetBindingsPtr())
272 pBindings->Invalidate( SID_SIGNATURE );
273 pBindings->Invalidate( SID_SAVEDOC );
274 pBindings->Update( SID_SAVEDOC );
278 void RunMethod( SbMethod* pMethod )
280 SbxValues aRes;
281 aRes.eType = SbxVOID;
282 pMethod->Get( aRes );
285 void StopBasic()
287 StarBASIC::Stop();
288 if (Shell* pShell = GetShell())
290 Shell::WindowTable& rWindows = pShell->GetWindowTable();
291 for (Shell::WindowTableIt it = rWindows.begin(); it != rWindows.end(); ++it )
293 BaseWindow* pWin = it->second;
294 // call BasicStopped manually because the Stop-Notify
295 // might not get through otherwise
296 pWin->BasicStopped();
299 BasicStopped();
302 void BasicStopped(
303 bool* pbAppWindowDisabled,
304 bool* pbDispatcherLocked,
305 sal_uInt16* pnWaitCount,
306 SfxUInt16Item** ppSWActionCount, SfxUInt16Item** ppSWLockViewCount
309 // maybe there are some locks to be removed after an error
310 // or an explicit cancelling of the basic...
311 if ( pbAppWindowDisabled )
312 *pbAppWindowDisabled = false;
313 if ( pbDispatcherLocked )
314 *pbDispatcherLocked = false;
315 if ( pnWaitCount )
316 *pnWaitCount = 0;
317 if ( ppSWActionCount )
318 *ppSWActionCount = 0;
319 if ( ppSWLockViewCount )
320 *ppSWLockViewCount = 0;
322 // AppWait?
323 if (Shell* pShell = GetShell())
325 sal_uInt16 nWait = 0;
326 while ( pShell->GetViewFrame()->GetWindow().IsWait() )
328 pShell->GetViewFrame()->GetWindow().LeaveWait();
329 nWait++;
331 if ( pnWaitCount )
332 *pnWaitCount = nWait;
335 vcl::Window* pDefParent = Application::GetDefDialogParent();
336 if ( pDefParent && !pDefParent->IsEnabled() )
338 pDefParent->Enable(true);
339 if ( pbAppWindowDisabled )
340 *pbAppWindowDisabled = true;
345 void InvalidateDebuggerSlots()
347 if (SfxBindings* pBindings = GetBindingsPtr())
349 pBindings->Invalidate( SID_BASICSTOP );
350 pBindings->Update( SID_BASICSTOP );
351 pBindings->Invalidate( SID_BASICRUN );
352 pBindings->Update( SID_BASICRUN );
353 pBindings->Invalidate( SID_BASICCOMPILE );
354 pBindings->Update( SID_BASICCOMPILE );
355 pBindings->Invalidate( SID_BASICSTEPOVER );
356 pBindings->Update( SID_BASICSTEPOVER );
357 pBindings->Invalidate( SID_BASICSTEPINTO );
358 pBindings->Update( SID_BASICSTEPINTO );
359 pBindings->Invalidate( SID_BASICSTEPOUT );
360 pBindings->Update( SID_BASICSTEPOUT );
361 pBindings->Invalidate( SID_BASICIDE_TOGGLEBRKPNT );
362 pBindings->Update( SID_BASICIDE_TOGGLEBRKPNT );
363 pBindings->Invalidate( SID_BASICIDE_STAT_POS );
364 pBindings->Update( SID_BASICIDE_STAT_POS );
365 pBindings->Invalidate( SID_BASICIDE_STAT_TITLE );
366 pBindings->Update( SID_BASICIDE_STAT_TITLE );
370 long HandleBasicError( StarBASIC* pBasic )
372 EnsureIde();
373 BasicStopped();
375 // no error output during macro choosing
376 if (GetExtraData()->ChoosingMacro())
377 return 1;
378 if (GetExtraData()->ShellInCriticalSection())
379 return 2;
381 long nRet = 0;
382 Shell* pShell = 0;
383 if ( SvtModuleOptions::IsBasicIDE() )
385 BasicManager* pBasMgr = FindBasicManager( pBasic );
386 if ( pBasMgr )
388 bool bProtected = false;
389 ScriptDocument aDocument( ScriptDocument::getDocumentForBasicManager( pBasMgr ) );
390 OSL_ENSURE( aDocument.isValid(), "basctl::HandleBasicError: no document for the given BasicManager!" );
391 if ( aDocument.isValid() )
393 OUString aOULibName( pBasic->GetName() );
394 Reference< script::XLibraryContainer > xModLibContainer( aDocument.getLibraryContainer( E_SCRIPTS ) );
395 if ( xModLibContainer.is() && xModLibContainer->hasByName( aOULibName ) )
397 Reference< script::XLibraryContainerPassword > xPasswd( xModLibContainer, UNO_QUERY );
398 if ( xPasswd.is() && xPasswd->isLibraryPasswordProtected( aOULibName ) && !xPasswd->isLibraryPasswordVerified( aOULibName ) )
400 bProtected = true;
405 if ( !bProtected )
407 pShell = GetShell();
408 if ( !pShell )
410 SfxAllItemSet aArgs( SfxGetpApp()->GetPool() );
411 SfxRequest aRequest( SID_BASICIDE_APPEAR, SfxCallMode::SYNCHRON, aArgs );
412 SfxGetpApp()->ExecuteSlot( aRequest );
413 pShell = GetShell();
419 if ( pShell )
420 nRet = long(pShell->CallBasicErrorHdl( pBasic ));
421 else
422 ErrorHandler::HandleError( StarBASIC::GetErrorCode() );
424 return nRet;
427 SfxBindings* GetBindingsPtr()
429 SfxBindings* pBindings = NULL;
431 SfxViewFrame* pFrame = NULL;
432 if (Shell* pShell = GetShell())
434 pFrame = pShell->GetViewFrame();
436 else
438 SfxViewFrame* pView = SfxViewFrame::GetFirst();
439 while ( pView )
441 if (dynamic_cast<DocShell*>(pView->GetObjectShell()))
443 pFrame = pView;
444 break;
446 pView = SfxViewFrame::GetNext( *pView );
449 if ( pFrame != NULL )
450 pBindings = &pFrame->GetBindings();
452 return pBindings;
455 SfxDispatcher* GetDispatcher ()
457 if (Shell* pShell = GetShell())
458 if (SfxViewFrame* pViewFrame = pShell->GetViewFrame())
459 if (SfxDispatcher* pDispatcher = pViewFrame->GetDispatcher())
460 return pDispatcher;
461 return 0;
463 } // namespace basctl
465 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */