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