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 .
21 #include "macrodlg.hxx"
22 #include <basidesh.hxx>
23 #include <strings.hrc>
26 #include <iderdll.hxx>
27 #include "iderdll2.hxx"
29 #include "moduldlg.hxx"
30 #include <basic/basmgr.hxx>
31 #include <basic/sbmeth.hxx>
32 #include <basic/sbmod.hxx>
33 #include <com/sun/star/script/XLibraryContainer2.hpp>
35 #include <sfx2/app.hxx>
36 #include <sfx2/dispatch.hxx>
37 #include <sfx2/frame.hxx>
38 #include <sfx2/minfitem.hxx>
39 #include <sfx2/request.hxx>
40 #include <sfx2/sfxsids.hrc>
41 #include <tools/debug.hxx>
42 #include <vcl/commandevent.hxx>
43 #include <vcl/svapp.hxx>
44 #include <vcl/weld.hxx>
45 #include <osl/diagnose.h>
50 using namespace ::com::sun::star
;
51 using namespace ::com::sun::star::uno
;
53 MacroChooser::MacroChooser(weld::Window
* pParnt
, const Reference
< frame::XFrame
>& xDocFrame
)
54 : SfxDialogController(pParnt
, "modules/BasicIDE/ui/basicmacrodialog.ui", "BasicMacroDialog")
55 , m_xDocumentFrame(xDocFrame
)
56 // the Sfx doesn't ask the BasicManager whether modified or not
57 // => start saving in case of a change without a into the BasicIDE.
58 , bForceStoreBasic(false)
60 , m_xMacroNameEdit(m_xBuilder
->weld_entry("macronameedit"))
61 , m_xMacroFromTxT(m_xBuilder
->weld_label("macrofromft"))
62 , m_xMacrosSaveInTxt(m_xBuilder
->weld_label("macrotoft"))
63 , m_xBasicBox(new SbTreeListBox(m_xBuilder
->weld_tree_view("libraries"), m_xDialog
.get()))
64 , m_xBasicBoxIter(m_xBasicBox
->make_iterator())
65 , m_xMacrosInTxt(m_xBuilder
->weld_label("existingmacrosft"))
66 , m_xMacroBox(m_xBuilder
->weld_tree_view("macros"))
67 , m_xMacroBoxIter(m_xMacroBox
->make_iterator())
68 , m_xRunButton(m_xBuilder
->weld_button("ok"))
69 , m_xCloseButton(m_xBuilder
->weld_button("close"))
70 , m_xAssignButton(m_xBuilder
->weld_button("assign"))
71 , m_xEditButton(m_xBuilder
->weld_button("edit"))
72 , m_xDelButton(m_xBuilder
->weld_button("delete"))
73 , m_xNewButton(m_xBuilder
->weld_button("new"))
74 , m_xOrganizeButton(m_xBuilder
->weld_button("organize"))
75 , m_xNewLibButton(m_xBuilder
->weld_button("newlibrary"))
76 , m_xNewModButton(m_xBuilder
->weld_button("newmodule"))
78 m_xBasicBox
->set_size_request(m_xBasicBox
->get_approximate_digit_width() * 30, m_xBasicBox
->get_height_rows(18));
79 m_xMacroBox
->set_size_request(m_xMacroBox
->get_approximate_digit_width() * 30, m_xMacroBox
->get_height_rows(18));
81 m_aMacrosInTxtBaseStr
= m_xMacrosInTxt
->get_label();
83 m_xRunButton
->connect_clicked( LINK( this, MacroChooser
, ButtonHdl
) );
84 m_xCloseButton
->connect_clicked( LINK( this, MacroChooser
, ButtonHdl
) );
85 m_xAssignButton
->connect_clicked( LINK( this, MacroChooser
, ButtonHdl
) );
86 m_xEditButton
->connect_clicked( LINK( this, MacroChooser
, ButtonHdl
) );
87 m_xDelButton
->connect_clicked( LINK( this, MacroChooser
, ButtonHdl
) );
88 m_xNewButton
->connect_clicked( LINK( this, MacroChooser
, ButtonHdl
) );
89 m_xOrganizeButton
->connect_clicked( LINK( this, MacroChooser
, ButtonHdl
) );
91 // Buttons only for MacroChooser::Recording
92 m_xNewLibButton
->connect_clicked( LINK( this, MacroChooser
, ButtonHdl
) );
93 m_xNewModButton
->connect_clicked( LINK( this, MacroChooser
, ButtonHdl
) );
94 m_xNewLibButton
->hide(); // default
95 m_xNewModButton
->hide(); // default
96 m_xMacrosSaveInTxt
->hide(); // default
98 m_xMacroNameEdit
->connect_changed( LINK( this, MacroChooser
, EditModifyHdl
) );
100 m_xBasicBox
->connect_changed( LINK( this, MacroChooser
, BasicSelectHdl
) );
102 m_xMacroBox
->connect_row_activated( LINK( this, MacroChooser
, MacroDoubleClickHdl
) );
103 m_xMacroBox
->connect_changed( LINK( this, MacroChooser
, MacroSelectHdl
) );
104 m_xMacroBox
->connect_popup_menu( LINK( this, MacroChooser
, ContextMenuHdl
) );
106 m_xBasicBox
->SetMode( BrowseMode::Modules
);
108 if (SfxDispatcher
* pDispatcher
= GetDispatcher())
109 pDispatcher
->Execute( SID_BASICIDE_STOREALLMODULESOURCES
);
111 m_xBasicBox
->ScanAllEntries();
114 MacroChooser::~MacroChooser()
116 if (bForceStoreBasic
)
118 SfxGetpApp()->SaveBasicAndDialogContainer();
119 bForceStoreBasic
= false;
123 void MacroChooser::StoreMacroDescription()
125 m_xBasicBox
->get_selected(m_xBasicBoxIter
.get());
126 EntryDescriptor aDesc
= m_xBasicBox
->GetEntryDescriptor(m_xBasicBoxIter
.get());
127 OUString aMethodName
;
128 if (m_xMacroBox
->get_selected(m_xMacroBoxIter
.get()))
129 aMethodName
= m_xMacroBox
->get_text(*m_xMacroBoxIter
);
131 aMethodName
= m_xMacroNameEdit
->get_text();
132 if ( !aMethodName
.isEmpty() )
134 aDesc
.SetMethodName( aMethodName
);
135 aDesc
.SetType( OBJ_TYPE_METHOD
);
138 if (ExtraData
* pData
= basctl::GetExtraData())
139 pData
->SetLastEntryDescriptor( aDesc
);
142 void MacroChooser::RestoreMacroDescription()
144 EntryDescriptor aDesc
;
145 if (Shell
* pShell
= GetShell())
147 if (BaseWindow
* pCurWin
= pShell
->GetCurWindow())
148 aDesc
= pCurWin
->CreateEntryDescriptor();
152 if (ExtraData
* pData
= basctl::GetExtraData())
153 aDesc
= pData
->GetLastEntryDescriptor();
156 m_xBasicBox
->SetCurrentEntry(aDesc
);
157 BasicSelectHdl(m_xBasicBox
->get_widget());
159 OUString
aLastMacro( aDesc
.GetMethodName() );
160 if (!aLastMacro
.isEmpty())
162 // find entry in macro box
163 auto nIndex
= m_xMacroBox
->find_text(aLastMacro
);
165 m_xMacroBox
->select(nIndex
);
168 m_xMacroNameEdit
->set_text(aLastMacro
);
169 m_xMacroNameEdit
->select_region(0, 0);
174 short MacroChooser::run()
176 RestoreMacroDescription();
178 // #104198 Check if "wrong" document is active
179 bool bSelectedEntry
= m_xBasicBox
->get_cursor(m_xBasicBoxIter
.get());
180 EntryDescriptor
aDesc(m_xBasicBox
->GetEntryDescriptor(bSelectedEntry
? m_xBasicBoxIter
.get() : nullptr));
181 const ScriptDocument
& rSelectedDoc(aDesc
.GetDocument());
183 // App Basic is always ok, so only check if shell was found
184 if( rSelectedDoc
.isDocument() && !rSelectedDoc
.isActive() )
186 // Search for the right entry
187 bool bValidIter
= m_xBasicBox
->get_iter_first(*m_xBasicBoxIter
);
190 EntryDescriptor
aCmpDesc(m_xBasicBox
->GetEntryDescriptor(m_xBasicBoxIter
.get()));
191 const ScriptDocument
& rCmpDoc( aCmpDesc
.GetDocument() );
192 if (rCmpDoc
.isDocument() && rCmpDoc
.isActive())
194 std::unique_ptr
<weld::TreeIter
> xEntry(m_xBasicBox
->make_iterator());
195 m_xBasicBox
->copy_iterator(*m_xBasicBoxIter
, *xEntry
);
196 std::unique_ptr
<weld::TreeIter
> xLastValid(m_xBasicBox
->make_iterator());
197 bool bValidEntryIter
= true;
200 m_xBasicBox
->copy_iterator(*xEntry
, *xLastValid
);
201 bValidEntryIter
= m_xBasicBox
->iter_children(*xEntry
);
203 while (bValidEntryIter
);
204 m_xBasicBox
->set_cursor(*xLastValid
);
206 bValidIter
= m_xBasicBox
->iter_next_sibling(*m_xBasicBoxIter
);
213 // tdf#62955 - Allow searching a name with typing the first letter
214 m_xBasicBox
->get_widget().grab_focus();
216 if ( StarBASIC::IsRunning() )
217 m_xCloseButton
->grab_focus();
219 return SfxDialogController::run();
222 void MacroChooser::EnableButton(weld::Button
& rButton
, bool bEnable
)
226 if (nMode
== ChooseOnly
|| nMode
== Recording
)
227 rButton
.set_sensitive(&rButton
== m_xRunButton
.get());
229 rButton
.set_sensitive(true);
232 rButton
.set_sensitive(false);
235 SbMethod
* MacroChooser::GetMacro()
237 if (!m_xBasicBox
->get_cursor(m_xBasicBoxIter
.get()))
239 SbModule
* pModule
= m_xBasicBox
->FindModule(m_xBasicBoxIter
.get());
242 if (!m_xMacroBox
->get_selected(m_xMacroBoxIter
.get()))
244 OUString
aMacroName(m_xMacroBox
->get_text(*m_xMacroBoxIter
));
245 return pModule
->FindMethod(aMacroName
, SbxClassType::Method
);
248 void MacroChooser::DeleteMacro()
250 SbMethod
* pMethod
= GetMacro();
251 DBG_ASSERT( pMethod
, "DeleteMacro: No Macro !" );
252 if (!(pMethod
&& QueryDelMacro(pMethod
->GetName(), m_xDialog
.get())))
255 if (SfxDispatcher
* pDispatcher
= GetDispatcher())
256 pDispatcher
->Execute( SID_BASICIDE_STOREALLMODULESOURCES
);
258 // mark current doc as modified:
259 StarBASIC
* pBasic
= FindBasic(pMethod
);
260 assert(pBasic
&& "Basic?!");
261 BasicManager
* pBasMgr
= FindBasicManager( pBasic
);
262 DBG_ASSERT( pBasMgr
, "BasMgr?" );
263 ScriptDocument
aDocument( ScriptDocument::getDocumentForBasicManager( pBasMgr
) );
264 if ( aDocument
.isDocument() )
266 aDocument
.setDocumentModified();
267 if (SfxBindings
* pBindings
= GetBindingsPtr())
268 pBindings
->Invalidate( SID_SAVEDOC
);
271 SbModule
* pModule
= pMethod
->GetModule();
272 assert(pModule
&& "DeleteMacro: No Module?!");
273 OUString
aSource( pModule
->GetSource32() );
274 sal_uInt16 nStart
, nEnd
;
275 pMethod
->GetLineRange( nStart
, nEnd
);
276 pModule
->GetMethods()->Remove( pMethod
);
277 CutLines( aSource
, nStart
-1, nEnd
-nStart
+1 );
278 pModule
->SetSource32( aSource
);
280 // update module in library
281 OUString aLibName
= pBasic
->GetName();
282 OUString aModName
= pModule
->GetName();
283 OSL_VERIFY( aDocument
.updateModule( aLibName
, aModName
, aSource
) );
285 bool bSelected
= m_xMacroBox
->get_selected(m_xMacroBoxIter
.get());
286 DBG_ASSERT(bSelected
, "DeleteMacro: Entry ?!");
287 m_xMacroBox
->remove(*m_xMacroBoxIter
);
288 bForceStoreBasic
= true;
291 SbMethod
* MacroChooser::CreateMacro()
293 SbMethod
* pMethod
= nullptr;
294 m_xBasicBox
->get_cursor(m_xBasicBoxIter
.get());
295 EntryDescriptor aDesc
= m_xBasicBox
->GetEntryDescriptor(m_xBasicBoxIter
.get());
296 const ScriptDocument
& aDocument( aDesc
.GetDocument() );
297 OSL_ENSURE( aDocument
.isAlive(), "MacroChooser::CreateMacro: no document!" );
298 if ( !aDocument
.isAlive() )
301 OUString
aLibName( aDesc
.GetLibName() );
303 if ( aLibName
.isEmpty() )
304 aLibName
= "Standard" ;
306 aDocument
.getOrCreateLibrary( E_SCRIPTS
, aLibName
);
308 OUString
aOULibName( aLibName
);
309 Reference
< script::XLibraryContainer
> xModLibContainer( aDocument
.getLibraryContainer( E_SCRIPTS
) );
310 if ( xModLibContainer
.is() && xModLibContainer
->hasByName( aOULibName
) && !xModLibContainer
->isLibraryLoaded( aOULibName
) )
311 xModLibContainer
->loadLibrary( aOULibName
);
312 Reference
< script::XLibraryContainer
> xDlgLibContainer( aDocument
.getLibraryContainer( E_DIALOGS
) );
313 if ( xDlgLibContainer
.is() && xDlgLibContainer
->hasByName( aOULibName
) && !xDlgLibContainer
->isLibraryLoaded( aOULibName
) )
314 xDlgLibContainer
->loadLibrary( aOULibName
);
316 BasicManager
* pBasMgr
= aDocument
.getBasicManager();
317 StarBASIC
* pBasic
= pBasMgr
? pBasMgr
->GetLib( aLibName
) : nullptr;
320 SbModule
* pModule
= nullptr;
321 OUString
aModName( aDesc
.GetName() );
322 if ( !aModName
.isEmpty() )
324 // extract the module name from the string like "Sheet1 (Example1)"
325 if( aDesc
.GetLibSubName() == IDEResId(RID_STR_DOCUMENT_OBJECTS
) )
327 aModName
= aModName
.getToken( 0, ' ' );
329 pModule
= pBasic
->FindModule( aModName
);
331 else if ( !pBasic
->GetModules().empty() )
332 pModule
= pBasic
->GetModules().front().get();
334 // Retain the desired macro name before the macro dialog box is forced to close
335 // by opening the module name dialog window when no module exists in the current library.
336 OUString aSubName
= m_xMacroNameEdit
->get_text();
340 pModule
= createModImpl(m_xDialog
.get(), aDocument
, *m_xBasicBox
, aLibName
, aModName
, false);
343 DBG_ASSERT( !pModule
|| !pModule
->FindMethod( aSubName
, SbxClassType::Method
), "Macro exists already!" );
344 pMethod
= pModule
? basctl::CreateMacro( pModule
, aSubName
) : nullptr;
350 void MacroChooser::SaveSetCurEntry(weld::TreeView
& rBox
, const weld::TreeIter
& rEntry
)
352 // the edit would be killed by the highlight otherwise:
354 OUString
aSaveText(m_xMacroNameEdit
->get_text());
355 int nStartPos
, nEndPos
;
356 m_xMacroNameEdit
->get_selection_bounds(nStartPos
, nEndPos
);
358 rBox
.set_cursor(rEntry
);
360 m_xMacroNameEdit
->set_text(aSaveText
);
361 m_xMacroNameEdit
->select_region(nStartPos
, nEndPos
);
364 void MacroChooser::CheckButtons()
366 const bool bCurEntry
= m_xBasicBox
->get_cursor(m_xBasicBoxIter
.get());
367 EntryDescriptor aDesc
= m_xBasicBox
->GetEntryDescriptor(bCurEntry
? m_xBasicBoxIter
.get() : nullptr);
368 const bool bMacroEntry
= m_xMacroBox
->get_selected(nullptr);
369 SbMethod
* pMethod
= GetMacro();
371 // check, if corresponding libraries are readonly
372 bool bReadOnly
= false;
373 sal_uInt16 nDepth
= bCurEntry
? m_xBasicBox
->get_iter_depth(*m_xBasicBoxIter
) : 0;
374 if ( nDepth
== 1 || nDepth
== 2 )
376 const ScriptDocument
& aDocument( aDesc
.GetDocument() );
377 const OUString
& aOULibName( aDesc
.GetLibName() );
378 Reference
< script::XLibraryContainer2
> xModLibContainer( aDocument
.getLibraryContainer( E_SCRIPTS
), UNO_QUERY
);
379 Reference
< script::XLibraryContainer2
> xDlgLibContainer( aDocument
.getLibraryContainer( E_DIALOGS
), UNO_QUERY
);
380 if ( ( xModLibContainer
.is() && xModLibContainer
->hasByName( aOULibName
) && xModLibContainer
->isLibraryReadOnly( aOULibName
) ) ||
381 ( xDlgLibContainer
.is() && xDlgLibContainer
->hasByName( aOULibName
) && xDlgLibContainer
->isLibraryReadOnly( aOULibName
) ) )
387 if (nMode
!= Recording
)
390 bool bEnable
= pMethod
!= nullptr;
391 if (nMode
!= ChooseOnly
&& StarBASIC::IsRunning())
393 EnableButton(*m_xRunButton
, bEnable
);
396 // organising still possible?
399 EnableButton(*m_xAssignButton
, pMethod
!= nullptr);
402 EnableButton(*m_xEditButton
, bMacroEntry
);
405 EnableButton(*m_xOrganizeButton
, !StarBASIC::IsRunning() && nMode
== All
);
407 // m_xDelButton/m_xNewButton ->...
408 bool bProtected
= bCurEntry
&& m_xBasicBox
->IsEntryProtected(m_xBasicBoxIter
.get());
409 bool bShare
= ( aDesc
.GetLocation() == LIBRARY_LOCATION_SHARE
);
410 bool bEnable
= !StarBASIC::IsRunning() && nMode
== All
&& !bProtected
&& !bReadOnly
&& !bShare
;
411 EnableButton(*m_xDelButton
, bEnable
);
412 EnableButton(*m_xNewButton
, bEnable
);
417 m_xDelButton
->show();
418 m_xNewButton
->hide();
422 m_xNewButton
->show();
423 m_xDelButton
->hide();
427 if (nMode
== Recording
)
430 m_xRunButton
->set_sensitive(!bProtected
&& !bReadOnly
&& !bShare
);
431 // new library button
432 m_xNewLibButton
->set_sensitive(!bShare
);
434 m_xNewModButton
->set_sensitive(!bProtected
&& !bReadOnly
&& !bShare
);
438 IMPL_LINK_NOARG(MacroChooser
, MacroDoubleClickHdl
, weld::TreeView
&, bool)
440 SbMethod
* pMethod
= GetMacro();
441 SbModule
* pModule
= pMethod
? pMethod
->GetModule() : nullptr;
442 StarBASIC
* pBasic
= pModule
? static_cast<StarBASIC
*>(pModule
->GetParent()) : nullptr;
443 BasicManager
* pBasMgr
= pBasic
? FindBasicManager(pBasic
) : nullptr;
444 ScriptDocument
aDocument(ScriptDocument::getDocumentForBasicManager(pBasMgr
));
445 if (aDocument
.isDocument() && !aDocument
.allowMacros())
447 std::unique_ptr
<weld::MessageDialog
> xError(
448 Application::CreateMessageDialog(m_xDialog
.get(), VclMessageType::Warning
,
449 VclButtonsType::Ok
, IDEResId(RID_STR_CANNOTRUNMACRO
)));
454 StoreMacroDescription();
455 if (nMode
== Recording
)
457 if (pMethod
&& !QueryReplaceMacro(pMethod
->GetName(), m_xDialog
.get()))
461 m_xDialog
->response(Macro_OkRun
);
465 IMPL_LINK_NOARG(MacroChooser
, MacroSelectHdl
, weld::TreeView
&, void)
471 IMPL_LINK_NOARG(MacroChooser
, BasicSelectHdl
, weld::TreeView
&, void)
473 m_xBasicBox
->get_cursor(m_xBasicBoxIter
.get());
474 SbModule
* pModule
= m_xBasicBox
->FindModule(m_xBasicBoxIter
.get());
475 m_xMacroBox
->clear();
478 m_xMacrosInTxt
->set_label(m_aMacrosInTxtBaseStr
+ " " + pModule
->GetName());
480 m_xMacroBox
->freeze();
482 sal_uInt32 nMacroCount
= pModule
->GetMethods()->Count32();
483 for ( sal_uInt32 iMeth
= 0; iMeth
< nMacroCount
; iMeth
++ )
485 SbMethod
* pMethod
= static_cast<SbMethod
*>(pModule
->GetMethods()->Get32( iMeth
));
486 assert(pMethod
&& "Method not found!");
487 if (pMethod
->IsHidden())
489 m_xMacroBox
->append_text(pMethod
->GetName());
494 if (m_xMacroBox
->get_iter_first(*m_xMacroBoxIter
))
495 m_xMacroBox
->set_cursor(*m_xMacroBoxIter
);
502 IMPL_LINK_NOARG(MacroChooser
, EditModifyHdl
, weld::Entry
&, void)
504 // select the module in which the macro is put at "new",
505 // if BasicManager or Lib is selecting
506 if (m_xBasicBox
->get_cursor(m_xBasicBoxIter
.get()))
508 sal_uInt16 nDepth
= m_xBasicBox
->get_iter_depth(*m_xBasicBoxIter
);
509 if (nDepth
== 1 && m_xBasicBox
->IsEntryProtected(m_xBasicBoxIter
.get()))
511 // then put to the respective Std-Lib...
512 m_xBasicBox
->iter_parent(*m_xBasicBoxIter
);
513 m_xBasicBox
->iter_children(*m_xBasicBoxIter
);
517 std::unique_ptr
<weld::TreeIter
> xNewEntry(m_xBasicBox
->make_iterator());
518 m_xBasicBox
->copy_iterator(*m_xBasicBoxIter
, *xNewEntry
);
519 bool bCurEntry
= true;
522 bCurEntry
= m_xBasicBox
->iter_children(*m_xBasicBoxIter
);
525 m_xBasicBox
->copy_iterator(*m_xBasicBoxIter
, *xNewEntry
);
526 nDepth
= m_xBasicBox
->get_iter_depth(*m_xBasicBoxIter
);
529 while (bCurEntry
&& (nDepth
< 2));
530 SaveSetCurEntry(m_xBasicBox
->get_widget(), *xNewEntry
);
532 auto nCount
= m_xMacroBox
->n_children();
535 OUString
aEdtText(m_xMacroNameEdit
->get_text());
537 bool bValidIter
= m_xMacroBox
->get_iter_first(*m_xMacroBoxIter
);
540 if (m_xMacroBox
->get_text(*m_xMacroBoxIter
).equalsIgnoreAsciiCase(aEdtText
))
542 SaveSetCurEntry(*m_xMacroBox
, *m_xMacroBoxIter
);
546 bValidIter
= m_xMacroBox
->iter_next_sibling(*m_xMacroBoxIter
);
550 bValidIter
= m_xMacroBox
->get_selected(m_xMacroBoxIter
.get());
551 // if the entry exists ->Select ->Description...
553 m_xMacroBox
->unselect(*m_xMacroBoxIter
);
561 IMPL_LINK(MacroChooser
, ButtonHdl
, weld::Button
&, rButton
, void)
563 // apart from New/Record the Description is done by LoseFocus
564 if (&rButton
== m_xRunButton
.get())
566 StoreMacroDescription();
568 // #116444# check security settings before macro execution
571 SbMethod
* pMethod
= GetMacro();
572 SbModule
* pModule
= pMethod
? pMethod
->GetModule() : nullptr;
573 StarBASIC
* pBasic
= pModule
? static_cast<StarBASIC
*>(pModule
->GetParent()) : nullptr;
574 BasicManager
* pBasMgr
= pBasic
? FindBasicManager(pBasic
) : nullptr;
577 ScriptDocument
aDocument( ScriptDocument::getDocumentForBasicManager( pBasMgr
) );
578 if ( aDocument
.isDocument() && !aDocument
.allowMacros() )
580 std::unique_ptr
<weld::MessageDialog
> xError(Application::CreateMessageDialog(m_xDialog
.get(),
581 VclMessageType::Warning
, VclButtonsType::Ok
, IDEResId(RID_STR_CANNOTRUNMACRO
)));
587 else if (nMode
== Recording
)
589 if ( !IsValidSbxName(m_xMacroNameEdit
->get_text()) )
591 std::unique_ptr
<weld::MessageDialog
> xError(Application::CreateMessageDialog(m_xDialog
.get(),
592 VclMessageType::Warning
, VclButtonsType::Ok
, IDEResId(RID_STR_BADSBXNAME
)));
594 m_xMacroNameEdit
->select_region(0, -1);
595 m_xMacroNameEdit
->grab_focus();
599 SbMethod
* pMethod
= GetMacro();
600 if (pMethod
&& !QueryReplaceMacro(pMethod
->GetName(), m_xDialog
.get()))
604 m_xDialog
->response(Macro_OkRun
);
606 else if (&rButton
== m_xCloseButton
.get())
608 StoreMacroDescription();
609 m_xDialog
->response(Macro_Close
);
611 else if (&rButton
== m_xEditButton
.get() || &rButton
== m_xDelButton
.get() || &rButton
== m_xNewButton
.get())
613 m_xBasicBox
->get_cursor(m_xBasicBoxIter
.get());
614 EntryDescriptor aDesc
= m_xBasicBox
->GetEntryDescriptor(m_xBasicBoxIter
.get());
615 const ScriptDocument
& aDocument( aDesc
.GetDocument() );
616 DBG_ASSERT( aDocument
.isAlive(), "MacroChooser::ButtonHdl: no document, or document is dead!" );
617 if ( !aDocument
.isAlive() )
619 BasicManager
* pBasMgr
= aDocument
.getBasicManager();
620 const OUString
& aLib( aDesc
.GetLibName() );
621 OUString
aMod( aDesc
.GetName() );
622 // extract the module name from the string like "Sheet1 (Example1)"
623 if( aDesc
.GetLibSubName() == IDEResId(RID_STR_DOCUMENT_OBJECTS
) )
625 aMod
= aMod
.getToken( 0, ' ' );
627 const OUString
& aSub( aDesc
.GetMethodName() );
628 SfxMacroInfoItem
aInfoItem( SID_BASICIDE_ARG_MACROINFO
, pBasMgr
, aLib
, aMod
, aSub
, OUString() );
629 if (&rButton
== m_xEditButton
.get())
631 if (m_xMacroBox
->get_selected(m_xMacroBoxIter
.get()))
632 aInfoItem
.SetMethod(m_xMacroBox
->get_text(*m_xMacroBoxIter
));
633 StoreMacroDescription();
634 m_xDialog
->hide(); // tdf#126828 dismiss dialog before opening new window
636 SfxAllItemSet
aArgs( SfxGetpApp()->GetPool() );
637 SfxRequest
aRequest( SID_BASICIDE_APPEAR
, SfxCallMode::SYNCHRON
, aArgs
);
638 SfxGetpApp()->ExecuteSlot( aRequest
);
640 if (SfxDispatcher
* pDispatcher
= GetDispatcher())
642 pDispatcher
->ExecuteList(SID_BASICIDE_EDITMACRO
,
643 SfxCallMode::ASYNCHRON
, { &aInfoItem
});
645 m_xDialog
->response(Macro_Edit
);
649 if (&rButton
== m_xDelButton
.get())
652 if (SfxDispatcher
* pDispatcher
= GetDispatcher())
654 pDispatcher
->ExecuteList( SID_BASICIDE_UPDATEMODULESOURCE
,
655 SfxCallMode::SYNCHRON
, { &aInfoItem
});
659 //if ( m_xMacroBox->GetCurEntry() ) // OV-Bug ?
660 // m_xMacroBox->Select( m_xMacroBox->GetCurEntry() );
664 if ( !IsValidSbxName(m_xMacroNameEdit
->get_text()) )
666 std::unique_ptr
<weld::MessageDialog
> xError(Application::CreateMessageDialog(m_xDialog
.get(),
667 VclMessageType::Warning
, VclButtonsType::Ok
, IDEResId(RID_STR_BADSBXNAME
)));
669 m_xMacroNameEdit
->select_region(0, -1);
670 m_xMacroNameEdit
->grab_focus();
673 SbMethod
* pMethod
= CreateMacro();
676 aInfoItem
.SetMethod( pMethod
->GetName() );
677 aInfoItem
.SetModule( pMethod
->GetModule()->GetName() );
678 aInfoItem
.SetLib( pMethod
->GetModule()->GetParent()->GetName() );
679 SfxAllItemSet
aArgs( SfxGetpApp()->GetPool() );
680 SfxRequest
aRequest( SID_BASICIDE_APPEAR
, SfxCallMode::SYNCHRON
, aArgs
);
681 SfxGetpApp()->ExecuteSlot( aRequest
);
683 if (SfxDispatcher
* pDispatcher
= GetDispatcher())
685 pDispatcher
->ExecuteList(SID_BASICIDE_EDITMACRO
,
686 SfxCallMode::ASYNCHRON
, { &aInfoItem
});
688 StoreMacroDescription();
689 m_xDialog
->response(Macro_New
);
694 else if (&rButton
== m_xAssignButton
.get())
696 m_xBasicBox
->get_cursor(m_xBasicBoxIter
.get());
697 EntryDescriptor aDesc
= m_xBasicBox
->GetEntryDescriptor(m_xBasicBoxIter
.get());
698 const ScriptDocument
& aDocument( aDesc
.GetDocument() );
699 DBG_ASSERT( aDocument
.isAlive(), "MacroChooser::ButtonHdl: no document, or document is dead!" );
700 if ( !aDocument
.isAlive() )
702 BasicManager
* pBasMgr
= aDocument
.getBasicManager();
703 const OUString
& aLib( aDesc
.GetLibName() );
704 const OUString
& aMod( aDesc
.GetName() );
705 OUString
aSub( m_xMacroNameEdit
->get_text() );
706 SbMethod
* pMethod
= GetMacro();
707 DBG_ASSERT( pBasMgr
, "BasMgr?" );
708 DBG_ASSERT( pMethod
, "Method?" );
709 OUString
aComment( GetInfo( pMethod
) );
710 SfxMacroInfoItem
aItem( SID_MACROINFO
, pBasMgr
, aLib
, aMod
, aSub
, aComment
);
711 SfxAllItemSet
Args( SfxGetpApp()->GetPool() );
713 SfxAllItemSet
aInternalSet(SfxGetpApp()->GetPool());
714 if (m_xDocumentFrame
.is())
715 aInternalSet
.Put(SfxUnoFrameItem(SID_FILLFRAME
, m_xDocumentFrame
));
717 SfxRequest
aRequest(SID_CONFIG
, SfxCallMode::SYNCHRON
, Args
, aInternalSet
);
718 aRequest
.AppendItem( aItem
);
719 SfxGetpApp()->ExecuteSlot( aRequest
);
721 else if (&rButton
== m_xNewLibButton
.get())
723 m_xBasicBox
->get_cursor(m_xBasicBoxIter
.get());
724 EntryDescriptor aDesc
= m_xBasicBox
->GetEntryDescriptor(m_xBasicBoxIter
.get());
725 const ScriptDocument
& aDocument( aDesc
.GetDocument() );
726 createLibImpl(m_xDialog
.get(), aDocument
, nullptr, m_xBasicBox
.get());
728 else if (&rButton
== m_xNewModButton
.get())
730 m_xBasicBox
->get_cursor(m_xBasicBoxIter
.get());
731 EntryDescriptor aDesc
= m_xBasicBox
->GetEntryDescriptor(m_xBasicBoxIter
.get());
732 const ScriptDocument
& aDocument( aDesc
.GetDocument() );
733 const OUString
& aLibName( aDesc
.GetLibName() );
734 createModImpl(m_xDialog
.get(), aDocument
, *m_xBasicBox
, aLibName
, OUString(), true);
736 else if (&rButton
== m_xOrganizeButton
.get())
738 StoreMacroDescription();
740 m_xBasicBox
->get_selected(m_xBasicBoxIter
.get());
741 auto xDlg(std::make_shared
<OrganizeDialog
>(m_xDialog
.get(), 0));
742 weld::DialogController::runAsync(xDlg
, [this](sal_Int32 nRet
) {
743 if (nRet
== RET_OK
) // not only closed
745 m_xDialog
->response(Macro_Edit
);
749 Shell
* pShell
= GetShell();
750 if ( pShell
&& pShell
->IsAppBasicModified() )
751 bForceStoreBasic
= true;
753 m_xBasicBox
->UpdateEntries();
758 IMPL_LINK(MacroChooser
, ContextMenuHdl
, const CommandEvent
&, rCEvt
, bool)
760 if (rCEvt
.GetCommand() != CommandEventId::ContextMenu
|| !m_xMacroBox
->n_children())
763 std::unique_ptr
<weld::Builder
> xBuilder(Application::CreateBuilder(m_xMacroBox
.get(), "modules/BasicIDE/ui/sortmenu.ui"));
764 std::unique_ptr
<weld::Menu
> xPopup(xBuilder
->weld_menu("sortmenu"));
765 std::unique_ptr
<weld::Menu
> xDropMenu(xBuilder
->weld_menu("sortsubmenu"));
766 xDropMenu
->set_active("alphabetically", m_xMacroBox
->get_sort_order());
767 xDropMenu
->set_active("properorder", !m_xMacroBox
->get_sort_order());
769 OString
sCommand(xPopup
->popup_at_rect(m_xMacroBox
.get(), tools::Rectangle(rCEvt
.GetMousePosPixel(), Size(1,1))));
770 if (sCommand
== "alphabetically")
772 m_xMacroBox
->make_sorted();
774 else if (sCommand
== "properorder")
776 m_xMacroBox
->make_unsorted();
777 BasicSelectHdl(m_xBasicBox
->get_widget());
779 else if (!sCommand
.isEmpty())
781 SAL_WARN("basctl.basicide", "Unknown context menu action: " << sCommand
);
787 void MacroChooser::UpdateFields()
789 auto nMacroEntry
= m_xMacroBox
->get_selected_index();
790 m_xMacroNameEdit
->set_text("");
791 if (nMacroEntry
!= -1)
792 m_xMacroNameEdit
->set_text(m_xMacroBox
->get_text(nMacroEntry
));
795 void MacroChooser::SetMode (Mode nM
)
802 m_xRunButton
->set_label(IDEResId(RID_STR_RUN
));
803 EnableButton(*m_xDelButton
, true);
804 EnableButton(*m_xNewButton
, true);
805 EnableButton(*m_xOrganizeButton
, true);
811 m_xRunButton
->set_label(IDEResId(RID_STR_CHOOSE
));
812 EnableButton(*m_xDelButton
, false);
813 EnableButton(*m_xNewButton
, false);
814 EnableButton(*m_xOrganizeButton
, false);
820 m_xRunButton
->set_label(IDEResId(RID_STR_RECORD
));
821 EnableButton(*m_xDelButton
, false);
822 EnableButton(*m_xNewButton
, false);
823 EnableButton(*m_xOrganizeButton
, false);
825 m_xAssignButton
->hide();
826 m_xEditButton
->hide();
827 m_xDelButton
->hide();
828 m_xNewButton
->hide();
829 m_xOrganizeButton
->hide();
830 m_xMacroFromTxT
->hide();
832 m_xNewLibButton
->show();
833 m_xNewModButton
->show();
834 m_xMacrosSaveInTxt
->show();
842 OUString
MacroChooser::GetInfo( SbxVariable
* pVar
)
845 SbxInfoRef xInfo
= pVar
->GetInfo();
847 aComment
= xInfo
->GetComment();
852 } // namespace basctl
854 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */