Version 6.1.0.2, tag libreoffice-6.1.0.2
[LibreOffice.git] / basctl / source / basicide / basobj3.cxx
blob8f3c0d5627824b33ba0b443deb351d48851e885e
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/weld.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 <strings.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 const * pPtr )
49 return HandleBasicError( static_cast<StarBASIC const *>(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->FindMethod( rMacroName, SbxClassType::Method ) )
62 return nullptr;
64 OUString aMacroName( rMacroName );
65 if ( aMacroName.isEmpty() )
67 if ( !pModule->GetMethods()->Count() )
68 aMacroName = "Main" ;
69 else
71 bool bValid = false;
72 sal_Int32 nMacro = 1;
73 while ( !bValid )
75 aMacroName = "Macro" + OUString::number( nMacro );
76 // test whether existing...
77 bValid = pModule->FindMethod( aMacroName, SbxClassType::Method ) == nullptr;
78 nMacro++;
83 OUString aOUSource( pModule->GetSource32() );
85 // don't produce too many empty lines...
86 sal_Int32 nSourceLen = aOUSource.getLength();
87 if ( nSourceLen > 2 )
89 const sal_Unicode* pStr = aOUSource.getStr();
90 if ( pStr[ nSourceLen - 1 ] != LINE_SEP )
91 aOUSource += "\n\n" ;
92 else if ( pStr[ nSourceLen - 2 ] != LINE_SEP )
93 aOUSource += "\n" ;
94 else if ( pStr[ nSourceLen - 3 ] == LINE_SEP )
95 aOUSource = aOUSource.copy( 0, nSourceLen-1 );
98 OUString aSubStr = "Sub " + aMacroName + "\n\nEnd Sub";
100 aOUSource += aSubStr;
102 // update module in library
103 StarBASIC* pBasic = dynamic_cast<StarBASIC*>(pModule->GetParent());
104 BasicManager* pBasMgr = pBasic ? FindBasicManager(pBasic) : nullptr;
105 SAL_WARN_IF(!pBasMgr, "basctl.basicide", "No BasicManager found!");
106 ScriptDocument aDocument = pBasMgr
107 ? ScriptDocument::getDocumentForBasicManager(pBasMgr)
108 : ScriptDocument(ScriptDocument::NoDocument);
110 if (aDocument.isValid())
112 OUString aLibName = pBasic->GetName();
113 OUString aModName = pModule->GetName();
114 OSL_VERIFY( aDocument.updateModule( aLibName, aModName, aOUSource ) );
117 SbMethod* pMethod = pModule->FindMethod( aMacroName, SbxClassType::Method );
119 if( pDispatcher )
121 pDispatcher->Execute( SID_BASICIDE_UPDATEALLMODULESOURCES );
124 if (aDocument.isAlive())
125 MarkDocumentModified(aDocument);
127 return pMethod;
130 bool RenameDialog (
131 weld::Widget* pErrorParent,
132 ScriptDocument const& rDocument,
133 OUString const& rLibName,
134 OUString const& rOldName,
135 OUString const& rNewName
138 if ( !rDocument.hasDialog( rLibName, rOldName ) )
140 OSL_FAIL( "basctl::RenameDialog: old module name is invalid!" );
141 return false;
144 if ( rDocument.hasDialog( rLibName, rNewName ) )
146 std::unique_ptr<weld::MessageDialog> xError(Application::CreateMessageDialog(pErrorParent,
147 VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_SBXNAMEALLREADYUSED2)));
148 xError->run();
149 return false;
152 // #i74440
153 if ( rNewName.isEmpty() )
155 std::unique_ptr<weld::MessageDialog> xError(Application::CreateMessageDialog(pErrorParent,
156 VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_BADSBXNAME)));
157 xError->run();
158 return false;
161 Shell* pShell = GetShell();
162 VclPtr<DialogWindow> pWin = pShell ? pShell->FindDlgWin(rDocument, rLibName, rOldName) : nullptr;
163 Reference< XNameContainer > xExistingDialog;
164 if ( pWin )
165 xExistingDialog = pWin->GetEditor().GetDialog();
167 if ( xExistingDialog.is() )
168 LocalizationMgr::renameStringResourceIDs( rDocument, rLibName, rNewName, xExistingDialog );
170 if ( !rDocument.renameDialog( rLibName, rOldName, rNewName, xExistingDialog ) )
171 return false;
173 if (pWin && pShell)
175 // set new name in window
176 pWin->SetName( rNewName );
178 // update property browser
179 pWin->UpdateBrowser();
181 // update tabwriter
182 sal_uInt16 nId = pShell->GetWindowId( pWin );
183 DBG_ASSERT( nId, "No entry in Tabbar!" );
184 if ( nId )
186 TabBar& rTabBar = pShell->GetTabBar();
187 rTabBar.SetPageText( nId, rNewName );
188 rTabBar.Sort();
189 rTabBar.MakeVisible( rTabBar.GetCurPageId() );
192 return true;
195 bool RemoveDialog( const ScriptDocument& rDocument, const OUString& rLibName, const OUString& rDlgName )
197 if (Shell* pShell = GetShell())
199 if (VclPtr<DialogWindow> pDlgWin = pShell->FindDlgWin(rDocument, rLibName, rDlgName))
201 Reference< container::XNameContainer > xDialogModel = pDlgWin->GetDialog();
202 LocalizationMgr::removeResourceForDialog( rDocument, rLibName, rDlgName, xDialogModel );
206 return rDocument.removeDialog( rLibName, rDlgName );
209 StarBASIC* FindBasic( const SbxVariable* pVar )
211 SbxVariable const* pSbx = pVar;
212 while (pSbx && !dynamic_cast<StarBASIC const*>(pSbx))
213 pSbx = pSbx->GetParent();
214 return const_cast<StarBASIC*>(static_cast<const StarBASIC*>(pSbx));
217 BasicManager* FindBasicManager( StarBASIC const * pLib )
219 ScriptDocuments aDocuments( ScriptDocument::getAllScriptDocuments( ScriptDocument::AllWithApplication ) );
220 for (auto const& doc : aDocuments)
222 BasicManager* pBasicMgr = doc.getBasicManager();
223 OSL_ENSURE( pBasicMgr, "basctl::FindBasicManager: no basic manager for the document!" );
224 if ( !pBasicMgr )
225 continue;
227 Sequence< OUString > aLibNames( doc.getLibraryNames() );
228 sal_Int32 nLibCount = aLibNames.getLength();
229 const OUString* pLibNames = aLibNames.getConstArray();
231 for ( sal_Int32 i = 0 ; i < nLibCount ; i++ )
233 StarBASIC* pL = pBasicMgr->GetLib( pLibNames[ i ] );
234 if ( pL == pLib )
235 return pBasicMgr;
238 return nullptr;
241 void MarkDocumentModified( const ScriptDocument& rDocument )
243 // does not have to come from a document...
244 if ( rDocument.isApplication() )
246 if (Shell* pShell = GetShell())
248 pShell->SetAppBasicModified(true);
249 pShell->UpdateObjectCatalog();
252 else
254 rDocument.setDocumentModified();
257 if (SfxBindings* pBindings = GetBindingsPtr())
259 pBindings->Invalidate( SID_SIGNATURE );
260 pBindings->Invalidate( SID_SAVEDOC );
261 pBindings->Update( SID_SAVEDOC );
265 void RunMethod( SbMethod const * pMethod )
267 SbxValues aRes;
268 aRes.eType = SbxVOID;
269 pMethod->Get( aRes );
272 void StopBasic()
274 StarBASIC::Stop();
275 if (Shell* pShell = GetShell())
277 Shell::WindowTable& rWindows = pShell->GetWindowTable();
278 for (auto const& window : rWindows)
280 BaseWindow* pWin = window.second;
281 // call BasicStopped manually because the Stop-Notify
282 // might not get through otherwise
283 pWin->BasicStopped();
286 BasicStopped();
289 void BasicStopped(
290 bool* pbAppWindowDisabled,
291 bool* pbDispatcherLocked,
292 sal_uInt16* pnWaitCount,
293 SfxUInt16Item** ppSWActionCount, SfxUInt16Item** ppSWLockViewCount
296 // maybe there are some locks to be removed after an error
297 // or an explicit cancelling of the basic...
298 if ( pbAppWindowDisabled )
299 *pbAppWindowDisabled = false;
300 if ( pbDispatcherLocked )
301 *pbDispatcherLocked = false;
302 if ( pnWaitCount )
303 *pnWaitCount = 0;
304 if ( ppSWActionCount )
305 *ppSWActionCount = nullptr;
306 if ( ppSWLockViewCount )
307 *ppSWLockViewCount = nullptr;
309 // AppWait?
310 if (Shell* pShell = GetShell())
312 sal_uInt16 nWait = 0;
313 while ( pShell->GetViewFrame()->GetWindow().IsWait() )
315 pShell->GetViewFrame()->GetWindow().LeaveWait();
316 nWait++;
318 if ( pnWaitCount )
319 *pnWaitCount = nWait;
322 vcl::Window* pDefParent = Application::GetDefDialogParent();
323 if ( pDefParent && !pDefParent->IsEnabled() )
325 pDefParent->Enable();
326 if ( pbAppWindowDisabled )
327 *pbAppWindowDisabled = true;
332 void InvalidateDebuggerSlots()
334 if (SfxBindings* pBindings = GetBindingsPtr())
336 pBindings->Invalidate( SID_BASICSTOP );
337 pBindings->Update( SID_BASICSTOP );
338 pBindings->Invalidate( SID_BASICRUN );
339 pBindings->Update( SID_BASICRUN );
340 pBindings->Invalidate( SID_BASICCOMPILE );
341 pBindings->Update( SID_BASICCOMPILE );
342 pBindings->Invalidate( SID_BASICSTEPOVER );
343 pBindings->Update( SID_BASICSTEPOVER );
344 pBindings->Invalidate( SID_BASICSTEPINTO );
345 pBindings->Update( SID_BASICSTEPINTO );
346 pBindings->Invalidate( SID_BASICSTEPOUT );
347 pBindings->Update( SID_BASICSTEPOUT );
348 pBindings->Invalidate( SID_BASICIDE_TOGGLEBRKPNT );
349 pBindings->Update( SID_BASICIDE_TOGGLEBRKPNT );
350 pBindings->Invalidate( SID_BASICIDE_STAT_POS );
351 pBindings->Update( SID_BASICIDE_STAT_POS );
352 pBindings->Invalidate( SID_BASICIDE_STAT_TITLE );
353 pBindings->Update( SID_BASICIDE_STAT_TITLE );
357 long HandleBasicError( StarBASIC const * pBasic )
359 EnsureIde();
360 BasicStopped();
362 // no error output during macro choosing
363 if (GetExtraData()->ChoosingMacro())
364 return 1;
365 if (GetExtraData()->ShellInCriticalSection())
366 return 2;
368 long nRet = 0;
369 Shell* pShell = nullptr;
370 if ( SvtModuleOptions::IsBasicIDE() )
372 BasicManager* pBasMgr = FindBasicManager( pBasic );
373 if ( pBasMgr )
375 bool bProtected = false;
376 ScriptDocument aDocument( ScriptDocument::getDocumentForBasicManager( pBasMgr ) );
377 OSL_ENSURE( aDocument.isValid(), "basctl::HandleBasicError: no document for the given BasicManager!" );
378 if ( aDocument.isValid() )
380 OUString aOULibName( pBasic->GetName() );
381 Reference< script::XLibraryContainer > xModLibContainer( aDocument.getLibraryContainer( E_SCRIPTS ) );
382 if ( xModLibContainer.is() && xModLibContainer->hasByName( aOULibName ) )
384 Reference< script::XLibraryContainerPassword > xPasswd( xModLibContainer, UNO_QUERY );
385 if ( xPasswd.is() && xPasswd->isLibraryPasswordProtected( aOULibName ) && !xPasswd->isLibraryPasswordVerified( aOULibName ) )
387 bProtected = true;
392 if ( !bProtected )
394 pShell = GetShell();
395 if ( !pShell )
397 SfxAllItemSet aArgs( SfxGetpApp()->GetPool() );
398 SfxRequest aRequest( SID_BASICIDE_APPEAR, SfxCallMode::SYNCHRON, aArgs );
399 SfxGetpApp()->ExecuteSlot( aRequest );
400 pShell = GetShell();
406 if ( pShell )
407 nRet = long(pShell->CallBasicErrorHdl( pBasic ));
408 else
409 ErrorHandler::HandleError( StarBASIC::GetErrorCode() );
411 return nRet;
414 SfxBindings* GetBindingsPtr()
416 SfxBindings* pBindings = nullptr;
418 SfxViewFrame* pFrame = nullptr;
419 if (Shell* pShell = GetShell())
421 pFrame = pShell->GetViewFrame();
423 else
425 SfxViewFrame* pView = SfxViewFrame::GetFirst();
426 while ( pView )
428 if (dynamic_cast<DocShell*>(pView->GetObjectShell()))
430 pFrame = pView;
431 break;
433 pView = SfxViewFrame::GetNext( *pView );
436 if ( pFrame != nullptr )
437 pBindings = &pFrame->GetBindings();
439 return pBindings;
442 SfxDispatcher* GetDispatcher ()
444 if (Shell* pShell = GetShell())
445 if (SfxViewFrame* pViewFrame = pShell->GetViewFrame())
446 if (SfxDispatcher* pDispatcher = pViewFrame->GetDispatcher())
447 return pDispatcher;
448 return nullptr;
450 } // namespace basctl
452 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */