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 21 #include "macrodlg.hxx" 22 #include <basidesh.hxx> 23 #include <strings.hrc> 24 25 #include <iderdll.hxx> 26 #include "iderdll2.hxx" 27 28 #include "moduldlg.hxx" 29 #include <basic/basmgr.hxx> 30 #include <basic/sbmeth.hxx> 31 #include <basic/sbmod.hxx> 32 33 #include <sfx2/dispatch.hxx> 34 #include <sfx2/minfitem.hxx> 35 #include <sfx2/request.hxx> 36 #include <vcl/weld.hxx> 37 38 #include <map> 39 40 namespace basctl 41 { 42 43 using std::map; 44 45 using namespace ::com::sun::star; 46 using namespace ::com::sun::star::uno; 47 48 MacroChooser::MacroChooser( vcl::Window* pParnt, const Reference< frame::XFrame >& xDocFrame, bool bCreateEntries ) 49 : SfxModalDialog(pParnt, "BasicMacroDialog", "modules/BasicIDE/ui/basicmacrodialog.ui") 50 , m_xDocumentFrame(xDocFrame) 51 , bNewDelIsDel(true) 52 // the Sfx doesn't ask the BasicManager whether modified or not 53 // => start saving in case of a change without a into the BasicIDE. 54 , bForceStoreBasic(false) 55 , nMode(All) 56 { 57 get(m_pMacroNameEdit, "macronameedit"); 58 get(m_pMacroFromTxT, "macrofromft"); 59 get(m_pMacrosSaveInTxt, "macrotoft"); 60 get(m_pBasicBox, "libraries"); 61 get(m_pMacrosInTxt, "existingmacrosft"); 62 m_aMacrosInTxtBaseStr = m_pMacrosInTxt->GetText(); 63 get(m_pMacroBox, "macros"); 64 get(m_pRunButton, "run"); 65 get(m_pCloseButton, "close"); 66 get(m_pAssignButton, "assign"); 67 get(m_pEditButton, "edit"); 68 get(m_pDelButton, "delete"); 69 get(m_pOrganizeButton, "organize"); 70 get(m_pNewLibButton, "newlibrary"); 71 get(m_pNewModButton, "newmodule"); 72 73 m_pMacroBox->SetSelectionMode( SelectionMode::Single ); 74 m_pMacroBox->SetHighlightRange(); // select over the whole width 75 76 m_pRunButton->SetClickHdl( LINK( this, MacroChooser, ButtonHdl ) ); 77 m_pCloseButton->SetClickHdl( LINK( this, MacroChooser, ButtonHdl ) ); 78 m_pAssignButton->SetClickHdl( LINK( this, MacroChooser, ButtonHdl ) ); 79 m_pEditButton->SetClickHdl( LINK( this, MacroChooser, ButtonHdl ) ); 80 m_pDelButton->SetClickHdl( LINK( this, MacroChooser, ButtonHdl ) ); 81 m_pOrganizeButton->SetClickHdl( LINK( this, MacroChooser, ButtonHdl ) ); 82 83 // Buttons only for MacroChooser::Recording 84 m_pNewLibButton->SetClickHdl( LINK( this, MacroChooser, ButtonHdl ) ); 85 m_pNewModButton->SetClickHdl( LINK( this, MacroChooser, ButtonHdl ) ); 86 m_pNewLibButton->Hide(); // default 87 m_pNewModButton->Hide(); // default 88 m_pMacrosSaveInTxt->Hide(); // default 89 90 m_pMacrosInTxt->SetStyle( WB_NOMULTILINE | WB_PATHELLIPSIS ); 91 92 m_pMacroNameEdit->SetModifyHdl( LINK( this, MacroChooser, EditModifyHdl ) ); 93 94 m_pBasicBox->SetSelectHdl( LINK( this, MacroChooser, BasicSelectHdl ) ); 95 96 m_pMacroBox->SetDoubleClickHdl( LINK( this, MacroChooser, MacroDoubleClickHdl ) ); 97 m_pMacroBox->SetSelectHdl( LINK( this, MacroChooser, MacroSelectHdl ) ); 98 99 m_pBasicBox->SetMode( BrowseMode::Modules ); 100 m_pBasicBox->SetStyle( WB_TABSTOP | WB_BORDER | 101 WB_HASLINES | WB_HASLINESATROOT | 102 WB_HASBUTTONS | WB_HASBUTTONSATROOT | 103 WB_HSCROLL ); 104 105 if (SfxDispatcher* pDispatcher = GetDispatcher()) 106 pDispatcher->Execute( SID_BASICIDE_STOREALLMODULESOURCES ); 107 108 if ( bCreateEntries ) 109 m_pBasicBox->ScanAllEntries(); 110 } 111 112 MacroChooser::~MacroChooser() 113 { 114 disposeOnce(); 115 } 116 117 void MacroChooser::dispose() 118 { 119 if ( bForceStoreBasic ) 120 { 121 SfxGetpApp()->SaveBasicAndDialogContainer(); 122 bForceStoreBasic = false; 123 } 124 m_pMacroNameEdit.clear(); 125 m_pMacroFromTxT.clear(); 126 m_pMacrosSaveInTxt.clear(); 127 m_pBasicBox.clear(); 128 m_pMacrosInTxt.clear(); 129 m_pMacroBox.clear(); 130 m_pRunButton.clear(); 131 m_pCloseButton.clear(); 132 m_pAssignButton.clear(); 133 m_pEditButton.clear(); 134 m_pDelButton.clear(); 135 m_pOrganizeButton.clear(); 136 m_pNewLibButton.clear(); 137 m_pNewModButton.clear(); 138 SfxModalDialog::dispose(); 139 } 140 141 void MacroChooser::StoreMacroDescription() 142 { 143 EntryDescriptor aDesc = m_pBasicBox->GetEntryDescriptor(m_pBasicBox->FirstSelected()); 144 OUString aMethodName; 145 SvTreeListEntry* pEntry = m_pMacroBox->FirstSelected(); 146 if ( pEntry ) 147 aMethodName = m_pMacroBox->GetEntryText( pEntry ); 148 else 149 aMethodName = m_pMacroNameEdit->GetText(); 150 if ( !aMethodName.isEmpty() ) 151 { 152 aDesc.SetMethodName( aMethodName ); 153 aDesc.SetType( OBJ_TYPE_METHOD ); 154 } 155 156 if (ExtraData* pData = basctl::GetExtraData()) 157 pData->SetLastEntryDescriptor( aDesc ); 158 } 159 160 void MacroChooser::RestoreMacroDescription() 161 { 162 EntryDescriptor aDesc; 163 if (Shell* pShell = GetShell()) 164 { 165 if (BaseWindow* pCurWin = pShell->GetCurWindow()) 166 aDesc = pCurWin->CreateEntryDescriptor(); 167 } 168 else 169 { 170 if (ExtraData* pData = basctl::GetExtraData()) 171 aDesc = pData->GetLastEntryDescriptor(); 172 } 173 174 m_pBasicBox->SetCurrentEntry( aDesc ); 175 176 OUString aLastMacro( aDesc.GetMethodName() ); 177 if ( !aLastMacro.isEmpty() ) 178 { 179 // find entry in macro box 180 SvTreeListEntry* pEntry = nullptr; 181 sal_uLong nPos = 0; 182 SvTreeListEntry* pE = m_pMacroBox->GetEntry( nPos ); 183 while ( pE ) 184 { 185 if ( m_pMacroBox->GetEntryText( pE ) == aLastMacro ) 186 { 187 pEntry = pE; 188 break; 189 } 190 pE = m_pMacroBox->GetEntry( ++nPos ); 191 } 192 193 if ( pEntry ) 194 m_pMacroBox->SetCurEntry( pEntry ); 195 else 196 { 197 m_pMacroNameEdit->SetText( aLastMacro ); 198 m_pMacroNameEdit->SetSelection( Selection( 0, 0 ) ); 199 } 200 } 201 } 202 203 short MacroChooser::Execute() 204 { 205 RestoreMacroDescription(); 206 m_pRunButton->GrabFocus(); 207 208 // #104198 Check if "wrong" document is active 209 SvTreeListEntry* pSelectedEntry = m_pBasicBox->GetCurEntry(); 210 EntryDescriptor aDesc( m_pBasicBox->GetEntryDescriptor( pSelectedEntry ) ); 211 const ScriptDocument& rSelectedDoc( aDesc.GetDocument() ); 212 213 // App Basic is always ok, so only check if shell was found 214 if( rSelectedDoc.isDocument() && !rSelectedDoc.isActive() ) 215 { 216 // Search for the right entry 217 sal_uLong nRootPos = 0; 218 SvTreeListEntry* pRootEntry = m_pBasicBox->GetEntry( nRootPos ); 219 while( pRootEntry ) 220 { 221 EntryDescriptor aCmpDesc( m_pBasicBox->GetEntryDescriptor( pRootEntry ) ); 222 const ScriptDocument& rCmpDoc( aCmpDesc.GetDocument() ); 223 if ( rCmpDoc.isDocument() && rCmpDoc.isActive() ) 224 { 225 SvTreeListEntry* pEntry = pRootEntry; 226 SvTreeListEntry* pLastValid = pEntry; 227 while ( pEntry ) 228 { 229 pLastValid = pEntry; 230 pEntry = m_pBasicBox->FirstChild( pEntry ); 231 } 232 if( pLastValid ) 233 m_pBasicBox->SetCurEntry( pLastValid ); 234 } 235 pRootEntry = m_pBasicBox->GetEntry( ++nRootPos ); 236 } 237 } 238 239 CheckButtons(); 240 UpdateFields(); 241 242 if ( StarBASIC::IsRunning() ) 243 m_pCloseButton->GrabFocus(); 244 245 return ModalDialog::Execute(); 246 } 247 248 void MacroChooser::EnableButton( Button& rButton, bool bEnable ) 249 { 250 if ( bEnable ) 251 { 252 if (nMode == ChooseOnly || nMode == Recording) 253 rButton.Enable(&rButton == m_pRunButton); 254 else 255 rButton.Enable(); 256 } 257 else 258 rButton.Disable(); 259 } 260 261 262 SbMethod* MacroChooser::GetMacro() 263 { 264 SbMethod* pMethod = nullptr; 265 SbModule* pModule = m_pBasicBox->FindModule( m_pBasicBox->GetCurEntry() ); 266 if ( pModule ) 267 { 268 SvTreeListEntry* pEntry = m_pMacroBox->FirstSelected(); 269 if ( pEntry ) 270 { 271 OUString aMacroName( m_pMacroBox->GetEntryText( pEntry ) ); 272 pMethod = pModule->FindMethod( aMacroName, SbxClassType::Method ); 273 } 274 } 275 return pMethod; 276 } 277 278 279 void MacroChooser::DeleteMacro() 280 { 281 SbMethod* pMethod = GetMacro(); 282 DBG_ASSERT( pMethod, "DeleteMacro: No Macro !" ); 283 if (pMethod && QueryDelMacro(pMethod->GetName(), GetFrameWeld())) 284 { 285 if (SfxDispatcher* pDispatcher = GetDispatcher()) 286 pDispatcher->Execute( SID_BASICIDE_STOREALLMODULESOURCES ); 287 288 // mark current doc as modified: 289 StarBASIC* pBasic = FindBasic(pMethod); 290 assert(pBasic && "Basic?!"); 291 BasicManager* pBasMgr = FindBasicManager( pBasic ); 292 DBG_ASSERT( pBasMgr, "BasMgr?" ); 293 ScriptDocument aDocument( ScriptDocument::getDocumentForBasicManager( pBasMgr ) ); 294 if ( aDocument.isDocument() ) 295 { 296 aDocument.setDocumentModified(); 297 if (SfxBindings* pBindings = GetBindingsPtr()) 298 pBindings->Invalidate( SID_SAVEDOC ); 299 } 300 301 SbModule* pModule = pMethod->GetModule(); 302 assert(pModule && "DeleteMacro: No Module?!"); 303 OUString aSource( pModule->GetSource32() ); 304 sal_uInt16 nStart, nEnd; 305 pMethod->GetLineRange( nStart, nEnd ); 306 pModule->GetMethods()->Remove( pMethod ); 307 CutLines( aSource, nStart-1, nEnd-nStart+1 ); 308 pModule->SetSource32( aSource ); 309 310 // update module in library 311 OUString aLibName = pBasic->GetName(); 312 OUString aModName = pModule->GetName(); 313 OSL_VERIFY( aDocument.updateModule( aLibName, aModName, aSource ) ); 314 315 SvTreeListEntry* pEntry = m_pMacroBox->FirstSelected(); 316 DBG_ASSERT( pEntry, "DeleteMacro: Entry ?!" ); 317 m_pMacroBox->GetModel()->Remove( pEntry ); 318 bForceStoreBasic = true; 319 } 320 } 321 322 SbMethod* MacroChooser::CreateMacro() 323 { 324 SbMethod* pMethod = nullptr; 325 SvTreeListEntry* pCurEntry = m_pBasicBox->GetCurEntry(); 326 EntryDescriptor aDesc = m_pBasicBox->GetEntryDescriptor(pCurEntry); 327 const ScriptDocument& aDocument( aDesc.GetDocument() ); 328 OSL_ENSURE( aDocument.isAlive(), "MacroChooser::CreateMacro: no document!" ); 329 if ( !aDocument.isAlive() ) 330 return nullptr; 331 332 OUString aLibName( aDesc.GetLibName() ); 333 334 if ( aLibName.isEmpty() ) 335 aLibName = "Standard" ; 336 337 aDocument.getOrCreateLibrary( E_SCRIPTS, aLibName ); 338 339 OUString aOULibName( aLibName ); 340 Reference< script::XLibraryContainer > xModLibContainer( aDocument.getLibraryContainer( E_SCRIPTS ) ); 341 if ( xModLibContainer.is() && xModLibContainer->hasByName( aOULibName ) && !xModLibContainer->isLibraryLoaded( aOULibName ) ) 342 xModLibContainer->loadLibrary( aOULibName ); 343 Reference< script::XLibraryContainer > xDlgLibContainer( aDocument.getLibraryContainer( E_DIALOGS ) ); 344 if ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aOULibName ) && !xDlgLibContainer->isLibraryLoaded( aOULibName ) ) 345 xDlgLibContainer->loadLibrary( aOULibName ); 346 347 BasicManager* pBasMgr = aDocument.getBasicManager(); 348 StarBASIC* pBasic = pBasMgr ? pBasMgr->GetLib( aLibName ) : nullptr; 349 if ( pBasic ) 350 { 351 SbModule* pModule = nullptr; 352 OUString aModName( aDesc.GetName() ); 353 if ( !aModName.isEmpty() ) 354 { 355 // extract the module name from the string like "Sheet1 (Example1)" 356 if( aDesc.GetLibSubName() == IDEResId(RID_STR_DOCUMENT_OBJECTS) ) 357 { 358 sal_Int32 nIndex = 0; 359 aModName = aModName.getToken( 0, ' ', nIndex ); 360 } 361 pModule = pBasic->FindModule( aModName ); 362 } 363 else if ( !pBasic->GetModules().empty() ) 364 pModule = pBasic->GetModules().front().get(); 365 366 // Retain the desired macro name before the macro dialog box is forced to close 367 // by opening the module name dialog window when no module exists in the current library. 368 OUString aSubName = m_pMacroNameEdit->GetText(); 369 370 if ( !pModule ) 371 { 372 pModule = createModImpl(GetFrameWeld(), aDocument, *m_pBasicBox, aLibName, aModName, false); 373 } 374 375 DBG_ASSERT( !pModule || !pModule->FindMethod( aSubName, SbxClassType::Method ), "Macro exists already!" ); 376 pMethod = pModule ? basctl::CreateMacro( pModule, aSubName ) : nullptr; 377 } 378 379 return pMethod; 380 } 381 382 void MacroChooser::SaveSetCurEntry( SvTreeListBox& rBox, SvTreeListEntry* pEntry ) 383 { 384 // the edit would be killed by the highlight otherwise: 385 386 OUString aSaveText( m_pMacroNameEdit->GetText() ); 387 Selection aCurSel( m_pMacroNameEdit->GetSelection() ); 388 389 rBox.SetCurEntry( pEntry ); 390 m_pMacroNameEdit->SetText( aSaveText ); 391 m_pMacroNameEdit->SetSelection( aCurSel ); 392 } 393 394 void MacroChooser::CheckButtons() 395 { 396 SvTreeListEntry* pCurEntry = m_pBasicBox->GetCurEntry(); 397 EntryDescriptor aDesc = m_pBasicBox->GetEntryDescriptor(pCurEntry); 398 SvTreeListEntry* pMacroEntry = m_pMacroBox->FirstSelected(); 399 SbMethod* pMethod = GetMacro(); 400 401 // check, if corresponding libraries are readonly 402 bool bReadOnly = false; 403 sal_uInt16 nDepth = pCurEntry ? m_pBasicBox->GetModel()->GetDepth( pCurEntry ) : 0; 404 if ( nDepth == 1 || nDepth == 2 ) 405 { 406 const ScriptDocument& aDocument( aDesc.GetDocument() ); 407 const OUString& aOULibName( aDesc.GetLibName() ); 408 Reference< script::XLibraryContainer2 > xModLibContainer( aDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY ); 409 Reference< script::XLibraryContainer2 > xDlgLibContainer( aDocument.getLibraryContainer( E_DIALOGS ), UNO_QUERY ); 410 if ( ( xModLibContainer.is() && xModLibContainer->hasByName( aOULibName ) && xModLibContainer->isLibraryReadOnly( aOULibName ) ) || 411 ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aOULibName ) && xDlgLibContainer->isLibraryReadOnly( aOULibName ) ) ) 412 { 413 bReadOnly = true; 414 } 415 } 416 417 if (nMode != Recording) 418 { 419 // Run... 420 bool bEnable = pMethod != nullptr; 421 if (nMode != ChooseOnly && StarBASIC::IsRunning()) 422 bEnable = false; 423 EnableButton(*m_pRunButton, bEnable); 424 } 425 426 // organising still possible? 427 428 // Assign... 429 EnableButton(*m_pAssignButton, pMethod != nullptr); 430 431 // Edit... 432 EnableButton(*m_pEditButton, pMacroEntry != nullptr); 433 434 // Organizer... 435 EnableButton(*m_pOrganizeButton, !StarBASIC::IsRunning() && nMode == All); 436 437 // m_pDelButton->... 438 bool bProtected = m_pBasicBox->IsEntryProtected( pCurEntry ); 439 bool bShare = ( aDesc.GetLocation() == LIBRARY_LOCATION_SHARE ); 440 EnableButton(*m_pDelButton, !StarBASIC::IsRunning() && nMode == All && !bProtected && !bReadOnly && !bShare); 441 bool bPrev = bNewDelIsDel; 442 bNewDelIsDel = pMethod != nullptr; 443 if (bPrev != bNewDelIsDel && nMode == All) 444 { 445 OUString aBtnText( bNewDelIsDel ? IDEResId(RID_STR_BTNDEL) : IDEResId(RID_STR_BTNNEW) ); 446 m_pDelButton->SetText( aBtnText ); 447 } 448 449 if (nMode == Recording) 450 { 451 // save button 452 m_pRunButton->Enable(!bProtected && !bReadOnly && !bShare); 453 // new library button 454 m_pNewLibButton->Enable(!bShare); 455 // new module button 456 m_pNewModButton->Enable(!bProtected && !bReadOnly && !bShare); 457 } 458 } 459 460 461 IMPL_LINK_NOARG(MacroChooser, MacroDoubleClickHdl, SvTreeListBox*, bool) 462 { 463 SbMethod* pMethod = GetMacro(); 464 SbModule* pModule = pMethod ? pMethod->GetModule() : nullptr; 465 StarBASIC* pBasic = pModule ? static_cast<StarBASIC*>(pModule->GetParent()) : nullptr; 466 BasicManager* pBasMgr = pBasic ? FindBasicManager(pBasic) : nullptr; 467 ScriptDocument aDocument(ScriptDocument::getDocumentForBasicManager(pBasMgr)); 468 if (aDocument.isDocument() && !aDocument.allowMacros()) 469 { 470 std::unique_ptr<weld::MessageDialog> xError( 471 Application::CreateMessageDialog(GetFrameWeld(), VclMessageType::Warning, 472 VclButtonsType::Ok, IDEResId(RID_STR_CANNOTRUNMACRO))); 473 xError->run(); 474 return false; 475 } 476 477 StoreMacroDescription(); 478 if (nMode == Recording) 479 { 480 if (pMethod && !QueryReplaceMacro(pMethod->GetName(), GetFrameWeld())) 481 return false; 482 } 483 484 EndDialog(Macro_OkRun); 485 return false; 486 } 487 488 IMPL_LINK( MacroChooser, MacroSelectHdl, SvTreeListBox *, pBox, void ) 489 { 490 // Is also called if deselected! 491 // Two function calls in every SelectHdl because 492 // there's no separate DeselectHDL. 493 // So find out if select or deselect: 494 if ( pBox->IsSelected( pBox->GetHdlEntry() ) ) 495 { 496 UpdateFields(); 497 CheckButtons(); 498 } 499 } 500 501 IMPL_LINK( MacroChooser, BasicSelectHdl, SvTreeListBox *, pBox, void ) 502 { 503 // Is also called if deselected! 504 // Two function calls in every SelectHdl because 505 // there's no separate DeselectHDL. 506 // So find out if select or deselect: 507 if ( !pBox->IsSelected( pBox->GetHdlEntry() ) ) 508 return; 509 510 SbModule* pModule = m_pBasicBox->FindModule( m_pBasicBox->GetCurEntry() ); 511 512 m_pMacroBox->Clear(); 513 if ( pModule ) 514 { 515 m_pMacrosInTxt->SetText( m_aMacrosInTxtBaseStr + " " + pModule->GetName() ); 516 517 // The macros should be called in the same order that they 518 // are written down in the module. 519 520 map< sal_uInt16, SbMethod* > aMacros; 521 size_t nMacroCount = pModule->GetMethods()->Count(); 522 for ( size_t iMeth = 0; iMeth < nMacroCount; iMeth++ ) 523 { 524 SbMethod* pMethod = static_cast<SbMethod*>(pModule->GetMethods()->Get( iMeth )); 525 if( pMethod->IsHidden() ) 526 continue; 527 DBG_ASSERT( pMethod, "Method not found! (NULL)" ); 528 sal_uInt16 nStart, nEnd; 529 pMethod->GetLineRange( nStart, nEnd ); 530 aMacros.emplace( nStart, pMethod ); 531 } 532 533 m_pMacroBox->SetUpdateMode(false); 534 for (auto const& macro : aMacros) 535 m_pMacroBox->InsertEntry( macro.second->GetName() ); 536 m_pMacroBox->SetUpdateMode(true); 537 538 if ( m_pMacroBox->GetEntryCount() ) 539 { 540 SvTreeListEntry* pEntry = m_pMacroBox->GetEntry( 0 ); 541 DBG_ASSERT( pEntry, "Entry ?!" ); 542 m_pMacroBox->SetCurEntry( pEntry ); 543 } 544 } 545 546 UpdateFields(); 547 CheckButtons(); 548 } 549 550 551 IMPL_LINK_NOARG( MacroChooser, EditModifyHdl, Edit&, void ) 552 { 553 // select the module in which the macro is put at "new", 554 // if BasicManager or Lib is selecting 555 SvTreeListEntry* pCurEntry = m_pBasicBox->GetCurEntry(); 556 if ( pCurEntry ) 557 { 558 sal_uInt16 nDepth = m_pBasicBox->GetModel()->GetDepth( pCurEntry ); 559 if ( ( nDepth == 1 ) && ( m_pBasicBox->IsEntryProtected( pCurEntry ) ) ) 560 { 561 // then put to the respective Std-Lib... 562 SvTreeListEntry* pManagerEntry = m_pBasicBox->GetModel()->GetParent( pCurEntry ); 563 pCurEntry = m_pBasicBox->GetModel()->FirstChild( pManagerEntry ); 564 } 565 if ( nDepth < 2 ) 566 { 567 SvTreeListEntry* pNewEntry = pCurEntry; 568 while ( pCurEntry && ( nDepth < 2 ) ) 569 { 570 pCurEntry = m_pBasicBox->FirstChild( pCurEntry ); 571 if ( pCurEntry ) 572 { 573 pNewEntry = pCurEntry; 574 nDepth = m_pBasicBox->GetModel()->GetDepth( pCurEntry ); 575 } 576 } 577 SaveSetCurEntry( *m_pBasicBox, pNewEntry ); 578 } 579 if ( m_pMacroBox->GetEntryCount() ) 580 { 581 OUString aEdtText( m_pMacroNameEdit->GetText() ); 582 bool bFound = false; 583 for ( sal_uLong n = 0; n < m_pMacroBox->GetEntryCount(); n++ ) 584 { 585 SvTreeListEntry* pEntry = m_pMacroBox->GetEntry( n ); 586 DBG_ASSERT( pEntry, "Entry ?!" ); 587 if ( m_pMacroBox->GetEntryText( pEntry ).equalsIgnoreAsciiCase( aEdtText ) ) 588 { 589 SaveSetCurEntry(*m_pMacroBox, pEntry); 590 bFound = true; 591 break; 592 } 593 } 594 if ( !bFound ) 595 { 596 SvTreeListEntry* pEntry = m_pMacroBox->FirstSelected(); 597 // if the entry exists ->Select ->Description... 598 if ( pEntry ) 599 m_pMacroBox->Select( pEntry, false ); 600 } 601 } 602 } 603 604 CheckButtons(); 605 } 606 607 608 IMPL_LINK( MacroChooser, ButtonHdl, Button *, pButton, void ) 609 { 610 // apart from New/Record the Description is done by LoseFocus 611 if (pButton == m_pRunButton) 612 { 613 StoreMacroDescription(); 614 615 // #116444# check security settings before macro execution 616 if (nMode == All) 617 { 618 SbMethod* pMethod = GetMacro(); 619 SbModule* pModule = pMethod ? pMethod->GetModule() : nullptr; 620 StarBASIC* pBasic = pModule ? static_cast<StarBASIC*>(pModule->GetParent()) : nullptr; 621 BasicManager* pBasMgr = pBasic ? FindBasicManager(pBasic) : nullptr; 622 if ( pBasMgr ) 623 { 624 ScriptDocument aDocument( ScriptDocument::getDocumentForBasicManager( pBasMgr ) ); 625 if ( aDocument.isDocument() && !aDocument.allowMacros() ) 626 { 627 std::unique_ptr<weld::MessageDialog> xError(Application::CreateMessageDialog(GetFrameWeld(), 628 VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_CANNOTRUNMACRO))); 629 xError->run(); 630 return; 631 } 632 } 633 } 634 else if (nMode == Recording ) 635 { 636 if ( !IsValidSbxName(m_pMacroNameEdit->GetText()) ) 637 { 638 std::unique_ptr<weld::MessageDialog> xError(Application::CreateMessageDialog(GetFrameWeld(), 639 VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_BADSBXNAME))); 640 xError->run(); 641 m_pMacroNameEdit->SetSelection( Selection( 0, m_pMacroNameEdit->GetText().getLength() ) ); 642 m_pMacroNameEdit->GrabFocus(); 643 return; 644 } 645 646 SbMethod* pMethod = GetMacro(); 647 if (pMethod && !QueryReplaceMacro(pMethod->GetName(), GetFrameWeld())) 648 return; 649 } 650 651 EndDialog(Macro_OkRun); 652 } 653 else if (pButton == m_pCloseButton) 654 { 655 StoreMacroDescription(); 656 EndDialog(Macro_Close); 657 } 658 else if ((pButton == m_pEditButton) || (pButton == m_pDelButton)) 659 { 660 SvTreeListEntry* pCurEntry = m_pBasicBox->GetCurEntry(); 661 EntryDescriptor aDesc = m_pBasicBox->GetEntryDescriptor(pCurEntry); 662 const ScriptDocument& aDocument( aDesc.GetDocument() ); 663 DBG_ASSERT( aDocument.isAlive(), "MacroChooser::ButtonHdl: no document, or document is dead!" ); 664 if ( !aDocument.isAlive() ) 665 return; 666 BasicManager* pBasMgr = aDocument.getBasicManager(); 667 const OUString& aLib( aDesc.GetLibName() ); 668 OUString aMod( aDesc.GetName() ); 669 // extract the module name from the string like "Sheet1 (Example1)" 670 if( aDesc.GetLibSubName() == IDEResId(RID_STR_DOCUMENT_OBJECTS) ) 671 { 672 sal_Int32 nIndex = 0; 673 aMod = aMod.getToken( 0, ' ', nIndex ); 674 } 675 const OUString& aSub( aDesc.GetMethodName() ); 676 SfxMacroInfoItem aInfoItem( SID_BASICIDE_ARG_MACROINFO, pBasMgr, aLib, aMod, aSub, OUString() ); 677 if (pButton == m_pEditButton) 678 { 679 SvTreeListEntry* pEntry = m_pMacroBox->FirstSelected(); 680 if ( pEntry ) 681 aInfoItem.SetMethod( m_pMacroBox->GetEntryText( pEntry ) ); 682 StoreMacroDescription(); 683 SfxAllItemSet aArgs( SfxGetpApp()->GetPool() ); 684 SfxRequest aRequest( SID_BASICIDE_APPEAR, SfxCallMode::SYNCHRON, aArgs ); 685 SfxGetpApp()->ExecuteSlot( aRequest ); 686 687 if (SfxDispatcher* pDispatcher = GetDispatcher()) 688 { 689 pDispatcher->ExecuteList(SID_BASICIDE_EDITMACRO, 690 SfxCallMode::ASYNCHRON, { &aInfoItem }); 691 } 692 EndDialog(Macro_Edit); 693 } 694 else 695 { 696 if ( bNewDelIsDel ) 697 { 698 DeleteMacro(); 699 if (SfxDispatcher* pDispatcher = GetDispatcher()) 700 { 701 pDispatcher->ExecuteList( SID_BASICIDE_UPDATEMODULESOURCE, 702 SfxCallMode::SYNCHRON, { &aInfoItem }); 703 } 704 CheckButtons(); 705 UpdateFields(); 706 //if ( m_pMacroBox->GetCurEntry() ) // OV-Bug ? 707 // m_pMacroBox->Select( m_pMacroBox->GetCurEntry() ); 708 } 709 else 710 { 711 if ( !IsValidSbxName(m_pMacroNameEdit->GetText()) ) 712 { 713 std::unique_ptr<weld::MessageDialog> xError(Application::CreateMessageDialog(GetFrameWeld(), 714 VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_BADSBXNAME))); 715 xError->run(); 716 m_pMacroNameEdit->SetSelection( Selection( 0, m_pMacroNameEdit->GetText().getLength() ) ); 717 m_pMacroNameEdit->GrabFocus(); 718 return; 719 } 720 SbMethod* pMethod = CreateMacro(); 721 if ( pMethod ) 722 { 723 aInfoItem.SetMethod( pMethod->GetName() ); 724 aInfoItem.SetModule( pMethod->GetModule()->GetName() ); 725 aInfoItem.SetLib( pMethod->GetModule()->GetParent()->GetName() ); 726 SfxAllItemSet aArgs( SfxGetpApp()->GetPool() ); 727 SfxRequest aRequest( SID_BASICIDE_APPEAR, SfxCallMode::SYNCHRON, aArgs ); 728 SfxGetpApp()->ExecuteSlot( aRequest ); 729 730 if (SfxDispatcher* pDispatcher = GetDispatcher()) 731 { 732 pDispatcher->ExecuteList(SID_BASICIDE_EDITMACRO, 733 SfxCallMode::ASYNCHRON, { &aInfoItem }); 734 } 735 StoreMacroDescription(); 736 EndDialog(Macro_New); 737 } 738 } 739 } 740 } 741 else if (pButton == m_pAssignButton) 742 { 743 SvTreeListEntry* pCurEntry = m_pBasicBox->GetCurEntry(); 744 EntryDescriptor aDesc = m_pBasicBox->GetEntryDescriptor(pCurEntry); 745 const ScriptDocument& aDocument( aDesc.GetDocument() ); 746 DBG_ASSERT( aDocument.isAlive(), "MacroChooser::ButtonHdl: no document, or document is dead!" ); 747 if ( !aDocument.isAlive() ) 748 return; 749 BasicManager* pBasMgr = aDocument.getBasicManager(); 750 const OUString& aLib( aDesc.GetLibName() ); 751 const OUString& aMod( aDesc.GetName() ); 752 OUString aSub( m_pMacroNameEdit->GetText() ); 753 SbMethod* pMethod = GetMacro(); 754 DBG_ASSERT( pBasMgr, "BasMgr?" ); 755 DBG_ASSERT( pMethod, "Method?" ); 756 OUString aComment( GetInfo( pMethod ) ); 757 SfxMacroInfoItem aItem( SID_MACROINFO, pBasMgr, aLib, aMod, aSub, aComment ); 758 SfxAllItemSet Args( SfxGetpApp()->GetPool() ); 759 760 SfxAllItemSet aInternalSet(SfxGetpApp()->GetPool()); 761 if (m_xDocumentFrame.is()) 762 aInternalSet.Put(SfxUnoFrameItem(SID_FILLFRAME, m_xDocumentFrame)); 763 764 SfxRequest aRequest(SID_CONFIG, SfxCallMode::SYNCHRON, Args, aInternalSet); 765 aRequest.AppendItem( aItem ); 766 SfxGetpApp()->ExecuteSlot( aRequest ); 767 } 768 else if (pButton == m_pNewLibButton) 769 { 770 SvTreeListEntry* pCurEntry = m_pBasicBox->GetCurEntry(); 771 EntryDescriptor aDesc = m_pBasicBox->GetEntryDescriptor(pCurEntry); 772 const ScriptDocument& aDocument( aDesc.GetDocument() ); 773 createLibImpl(GetFrameWeld(), aDocument, nullptr, m_pBasicBox); 774 } 775 else if (pButton == m_pNewModButton) 776 { 777 SvTreeListEntry* pCurEntry = m_pBasicBox->GetCurEntry(); 778 EntryDescriptor aDesc = m_pBasicBox->GetEntryDescriptor(pCurEntry); 779 const ScriptDocument& aDocument( aDesc.GetDocument() ); 780 const OUString& aLibName( aDesc.GetLibName() ); 781 createModImpl(GetFrameWeld(), aDocument, *m_pBasicBox, aLibName, OUString(), true); 782 } 783 else if (pButton == m_pOrganizeButton) 784 { 785 StoreMacroDescription(); 786 787 EntryDescriptor aDesc = m_pBasicBox->GetEntryDescriptor(m_pBasicBox->FirstSelected()); 788 VclPtrInstance< OrganizeDialog > pDlg( this, 0, aDesc ); 789 sal_uInt16 nRet = pDlg->Execute(); 790 pDlg.reset(); 791 792 if ( nRet ) // not only closed 793 { 794 EndDialog(Macro_Edit); 795 return; 796 } 797 798 Shell* pShell = GetShell(); 799 if ( pShell && pShell->IsAppBasicModified() ) 800 bForceStoreBasic = true; 801 802 m_pBasicBox->UpdateEntries(); 803 } 804 } 805 806 807 void MacroChooser::UpdateFields() 808 { 809 SvTreeListEntry* pMacroEntry = m_pMacroBox->GetCurEntry(); 810 811 m_pMacroNameEdit->SetText( "" ); 812 if ( pMacroEntry ) 813 m_pMacroNameEdit->SetText( m_pMacroBox->GetEntryText( pMacroEntry ) ); 814 } 815 816 void MacroChooser::SetMode (Mode nM) 817 { 818 nMode = nM; 819 switch (nMode) 820 { 821 case All: 822 { 823 m_pRunButton->SetText(IDEResId(RID_STR_RUN)); 824 EnableButton(*m_pDelButton, true); 825 EnableButton(*m_pOrganizeButton, true); 826 break; 827 } 828 829 case ChooseOnly: 830 { 831 m_pRunButton->SetText(IDEResId(RID_STR_CHOOSE)); 832 EnableButton(*m_pDelButton, false); 833 EnableButton(*m_pOrganizeButton, false); 834 break; 835 } 836 837 case Recording: 838 { 839 m_pRunButton->SetText(IDEResId(RID_STR_RECORD)); 840 EnableButton(*m_pDelButton, false); 841 EnableButton(*m_pOrganizeButton, false); 842 843 m_pAssignButton->Hide(); 844 m_pEditButton->Hide(); 845 m_pDelButton->Hide(); 846 m_pOrganizeButton->Hide(); 847 m_pMacroFromTxT->Hide(); 848 849 m_pNewLibButton->Show(); 850 m_pNewModButton->Show(); 851 m_pMacrosSaveInTxt->Show(); 852 853 break; 854 } 855 } 856 CheckButtons(); 857 } 858 859 OUString MacroChooser::GetInfo( SbxVariable* pVar ) 860 { 861 OUString aComment; 862 SbxInfoRef xInfo = pVar->GetInfo(); 863 if ( xInfo.is() ) 864 aComment = xInfo->GetComment(); 865 return aComment; 866 } 867 868 869 } // namespace basctl 870 871 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 872
