1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/errinf.hxx>
21 #include <vcl/svapp.hxx>
22 #include <vcl/weld.hxx>
23 #include <basic/basmgr.hxx>
24 #include <basic/sbmeth.hxx>
25 #include <unotools/moduleoptions.hxx>
27 #include <iderdll.hxx>
28 #include "iderdll2.hxx"
31 #include <strings.hrc>
33 #include <baside3.hxx>
34 #include <basidesh.hxx>
36 #include <localizationmgr.hxx>
38 #include <com/sun/star/script/XLibraryContainerPassword.hpp>
39 #include <sfx2/app.hxx>
40 #include <sfx2/dispatch.hxx>
41 #include <sfx2/sfxsids.hrc>
42 #include <sfx2/request.hxx>
43 #include <sfx2/viewfrm.hxx>
44 #include <sal/log.hxx>
45 #include <osl/diagnose.h>
46 #include <tools/debug.hxx>
51 using namespace comphelper
;
52 using namespace ::com::sun::star
;
53 using namespace ::com::sun::star::uno
;
54 using namespace ::com::sun::star::container
;
57 SAL_DLLPUBLIC_EXPORT
tools::Long
basicide_handle_basic_error( void const * pPtr
)
59 return HandleBasicError( static_cast<StarBASIC
const *>(pPtr
) );
63 SbMethod
* CreateMacro( SbModule
* pModule
, const OUString
& rMacroName
)
65 SfxDispatcher
* pDispatcher
= GetDispatcher();
68 pDispatcher
->Execute( SID_BASICIDE_STOREALLMODULESOURCES
);
71 if ( pModule
->FindMethod( rMacroName
, SbxClassType::Method
) )
74 OUString
aMacroName( rMacroName
);
75 if ( aMacroName
.isEmpty() )
77 if (!pModule
->GetMethods()->Count())
85 aMacroName
= "Macro" + OUString::number( nMacro
);
86 // test whether existing...
87 bValid
= pModule
->FindMethod( aMacroName
, SbxClassType::Method
) == nullptr;
93 OUString
aOUSource( pModule
->GetSource32() );
95 // don't produce too many empty lines...
96 sal_Int32 nSourceLen
= aOUSource
.getLength();
99 const sal_Unicode
* pStr
= aOUSource
.getStr();
100 if ( pStr
[ nSourceLen
- 1 ] != LINE_SEP
)
101 aOUSource
+= "\n\n" ;
102 else if ( pStr
[ nSourceLen
- 2 ] != LINE_SEP
)
104 else if ( pStr
[ nSourceLen
- 3 ] == LINE_SEP
)
105 aOUSource
= aOUSource
.copy( 0, nSourceLen
-1 );
108 aOUSource
+= "Sub " + aMacroName
+ "\n\nEnd Sub";
110 // update module in library
111 StarBASIC
* pBasic
= dynamic_cast<StarBASIC
*>(pModule
->GetParent());
112 BasicManager
* pBasMgr
= pBasic
? FindBasicManager(pBasic
) : nullptr;
113 SAL_WARN_IF(!pBasMgr
, "basctl.basicide", "No BasicManager found!");
114 ScriptDocument aDocument
= pBasMgr
115 ? ScriptDocument::getDocumentForBasicManager(pBasMgr
)
116 : ScriptDocument(ScriptDocument::NoDocument
);
118 if (aDocument
.isValid())
120 const OUString
& aLibName
= pBasic
->GetName();
121 const OUString
& aModName
= pModule
->GetName();
122 OSL_VERIFY( aDocument
.updateModule( aLibName
, aModName
, aOUSource
) );
125 SbMethod
* pMethod
= pModule
->FindMethod( aMacroName
, SbxClassType::Method
);
129 pDispatcher
->Execute( SID_BASICIDE_UPDATEALLMODULESOURCES
);
132 if (aDocument
.isAlive())
133 MarkDocumentModified(aDocument
);
139 weld::Widget
* pErrorParent
,
140 ScriptDocument
const& rDocument
,
141 OUString
const& rLibName
,
142 OUString
const& rOldName
,
143 OUString
const& rNewName
146 if ( !rDocument
.hasDialog( rLibName
, rOldName
) )
148 OSL_FAIL( "basctl::RenameDialog: old module name is invalid!" );
152 if ( rDocument
.hasDialog( rLibName
, rNewName
) )
154 std::unique_ptr
<weld::MessageDialog
> xError(Application::CreateMessageDialog(pErrorParent
,
155 VclMessageType::Warning
, VclButtonsType::Ok
, IDEResId(RID_STR_SBXNAMEALLREADYUSED2
)));
161 if ( rNewName
.isEmpty() )
163 std::unique_ptr
<weld::MessageDialog
> xError(Application::CreateMessageDialog(pErrorParent
,
164 VclMessageType::Warning
, VclButtonsType::Ok
, IDEResId(RID_STR_BADSBXNAME
)));
169 Shell
* pShell
= GetShell();
170 VclPtr
<DialogWindow
> pWin
= pShell
? pShell
->FindDlgWin(rDocument
, rLibName
, rOldName
) : nullptr;
171 Reference
< XNameContainer
> xExistingDialog
;
173 xExistingDialog
= pWin
->GetEditor().GetDialog();
175 if ( xExistingDialog
.is() )
176 LocalizationMgr::renameStringResourceIDs( rDocument
, rLibName
, rNewName
, xExistingDialog
);
178 if ( !rDocument
.renameDialog( rLibName
, rOldName
, rNewName
, xExistingDialog
) )
181 if (!pWin
|| !pShell
)
184 // set new name in window
185 pWin
->SetName( rNewName
);
187 // update property browser
188 pWin
->UpdateBrowser();
191 sal_uInt16 nId
= pShell
->GetWindowId( pWin
);
192 DBG_ASSERT( nId
, "No entry in Tabbar!" );
195 TabBar
& rTabBar
= pShell
->GetTabBar();
196 rTabBar
.SetPageText( nId
, rNewName
);
198 rTabBar
.MakeVisible( rTabBar
.GetCurPageId() );
203 bool RemoveDialog( const ScriptDocument
& rDocument
, const OUString
& rLibName
, const OUString
& rDlgName
)
205 if (Shell
* pShell
= GetShell())
207 if (VclPtr
<DialogWindow
> pDlgWin
= pShell
->FindDlgWin(rDocument
, rLibName
, rDlgName
))
209 Reference
< container::XNameContainer
> xDialogModel
= pDlgWin
->GetDialog();
210 LocalizationMgr::removeResourceForDialog( rDocument
, rLibName
, rDlgName
, xDialogModel
);
214 return rDocument
.removeDialog( rLibName
, rDlgName
);
217 StarBASIC
* FindBasic( const SbxVariable
* pVar
)
219 SbxVariable
const* pSbx
= pVar
;
220 while (pSbx
&& !dynamic_cast<StarBASIC
const*>(pSbx
))
221 pSbx
= pSbx
->GetParent();
222 return const_cast<StarBASIC
*>(static_cast<const StarBASIC
*>(pSbx
));
225 BasicManager
* FindBasicManager( StarBASIC
const * pLib
)
227 ScriptDocuments
aDocuments( ScriptDocument::getAllScriptDocuments( ScriptDocument::AllWithApplication
) );
228 for (auto const& doc
: aDocuments
)
230 BasicManager
* pBasicMgr
= doc
.getBasicManager();
231 OSL_ENSURE( pBasicMgr
, "basctl::FindBasicManager: no basic manager for the document!" );
235 Sequence
< OUString
> aLibNames( doc
.getLibraryNames() );
236 sal_Int32 nLibCount
= aLibNames
.getLength();
237 const OUString
* pLibNames
= aLibNames
.getConstArray();
239 for ( sal_Int32 i
= 0 ; i
< nLibCount
; i
++ )
241 StarBASIC
* pL
= pBasicMgr
->GetLib( pLibNames
[ i
] );
249 void MarkDocumentModified( const ScriptDocument
& rDocument
)
251 Shell
* pShell
= GetShell();
253 // does not have to come from a document...
254 if ( rDocument
.isApplication() )
257 pShell
->SetAppBasicModified(true);
261 rDocument
.setDocumentModified();
264 // tdf#130161 in all cases call UpdateObjectCatalog
266 pShell
->UpdateObjectCatalog();
268 if (SfxBindings
* pBindings
= GetBindingsPtr())
270 pBindings
->Invalidate( SID_SIGNATURE
);
271 pBindings
->Invalidate( SID_SAVEDOC
);
272 pBindings
->Update( SID_SAVEDOC
);
276 void RunMethod( SbMethod
const * pMethod
)
279 aRes
.eType
= SbxVOID
;
280 pMethod
->Get( aRes
);
286 if (Shell
* pShell
= GetShell())
288 Shell::WindowTable
& rWindows
= pShell
->GetWindowTable();
289 for (auto const& window
: rWindows
)
291 BaseWindow
* pWin
= window
.second
;
292 // call BasicStopped manually because the Stop-Notify
293 // might not get through otherwise
294 pWin
->BasicStopped();
301 bool* pbAppWindowDisabled
,
302 bool* pbDispatcherLocked
,
303 sal_uInt16
* pnWaitCount
,
304 SfxUInt16Item
** ppSWActionCount
, SfxUInt16Item
** ppSWLockViewCount
307 // maybe there are some locks to be removed after an error
308 // or an explicit cancelling of the basic...
309 if ( pbAppWindowDisabled
)
310 *pbAppWindowDisabled
= false;
311 if ( pbDispatcherLocked
)
312 *pbDispatcherLocked
= false;
315 if ( ppSWActionCount
)
316 *ppSWActionCount
= nullptr;
317 if ( ppSWLockViewCount
)
318 *ppSWLockViewCount
= nullptr;
321 if (Shell
* pShell
= GetShell())
323 sal_uInt16 nWait
= 0;
324 while ( pShell
->GetViewFrame().GetWindow().IsWait() )
326 pShell
->GetViewFrame().GetWindow().LeaveWait();
330 *pnWaitCount
= nWait
;
333 weld::Window
* pDefParent
= Application::GetDefDialogParent();
334 if (pDefParent
&& !pDefParent
->get_sensitive())
336 pDefParent
->set_sensitive(true);
337 if ( pbAppWindowDisabled
)
338 *pbAppWindowDisabled
= true;
343 void InvalidateDebuggerSlots()
345 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
);
369 tools::Long
HandleBasicError( StarBASIC
const * pBasic
)
374 // no error output during macro choosing
375 if (GetExtraData()->ChoosingMacro())
377 if (GetExtraData()->ShellInCriticalSection())
380 tools::Long nRet
= 0;
381 Shell
* pShell
= nullptr;
382 if ( SvtModuleOptions::IsBasicIDE() )
384 BasicManager
* pBasMgr
= FindBasicManager( pBasic
);
387 bool bProtected
= false;
388 ScriptDocument
aDocument( ScriptDocument::getDocumentForBasicManager( pBasMgr
) );
389 OSL_ENSURE( aDocument
.isValid(), "basctl::HandleBasicError: no document for the given BasicManager!" );
390 if ( aDocument
.isValid() )
392 const OUString
& aOULibName( pBasic
->GetName() );
393 Reference
< script::XLibraryContainer
> xModLibContainer( aDocument
.getLibraryContainer( E_SCRIPTS
) );
394 if ( xModLibContainer
.is() && xModLibContainer
->hasByName( aOULibName
) )
396 Reference
< script::XLibraryContainerPassword
> xPasswd( xModLibContainer
, UNO_QUERY
);
397 if ( xPasswd
.is() && xPasswd
->isLibraryPasswordProtected( aOULibName
) && !xPasswd
->isLibraryPasswordVerified( aOULibName
) )
409 SfxAllItemSet
aArgs( SfxGetpApp()->GetPool() );
410 SfxRequest
aRequest( SID_BASICIDE_APPEAR
, SfxCallMode::SYNCHRON
, aArgs
);
411 SfxGetpApp()->ExecuteSlot( aRequest
);
419 nRet
= tools::Long(pShell
->CallBasicErrorHdl( pBasic
));
421 ErrorHandler::HandleError( StarBASIC::GetErrorCode() );
426 SfxBindings
* GetBindingsPtr()
428 SfxBindings
* pBindings
= nullptr;
430 SfxViewFrame
* pFrame
= nullptr;
431 if (Shell
* pShell
= GetShell())
433 pFrame
= &pShell
->GetViewFrame();
437 SfxViewFrame
* pView
= SfxViewFrame::GetFirst();
440 if (dynamic_cast<DocShell
*>(pView
->GetObjectShell()))
445 pView
= SfxViewFrame::GetNext( *pView
);
448 if ( pFrame
!= nullptr )
449 pBindings
= &pFrame
->GetBindings();
454 SfxDispatcher
* GetDispatcher ()
456 if (Shell
* pShell
= GetShell())
458 SfxViewFrame
& rViewFrame
= pShell
->GetViewFrame();
459 if (SfxDispatcher
* pDispatcher
= rViewFrame
.GetDispatcher())
464 } // namespace basctl
466 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */