Version 6.1.4.1, tag libreoffice-6.1.4.1
[LibreOffice.git] / basctl / source / basicide / moduldlg.cxx
blob7e28a20ddd175f1ddb29225046be376b6eef6456
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 <sal/config.h>
22 #include <strings.hrc>
23 #include <bitmaps.hlst>
25 #include "moduldlg.hxx"
26 #include <localizationmgr.hxx>
27 #include <basidesh.hxx>
29 #include <basic/basmgr.hxx>
30 #include <com/sun/star/script/XLibraryContainerPassword.hpp>
31 #include <comphelper/processfactory.hxx>
32 #include <o3tl/make_unique.hxx>
33 #include <sfx2/app.hxx>
34 #include <sfx2/dispatch.hxx>
35 #include <sfx2/request.hxx>
36 #include <svl/stritem.hxx>
37 #include <vcl/builderfactory.hxx>
38 #include <vcl/weld.hxx>
39 #include <tools/diagnose_ex.h>
40 #include <xmlscript/xmldlg_imexp.hxx>
41 #include <svtools/treelistentry.hxx>
43 namespace basctl
46 using namespace ::com::sun::star;
47 using namespace ::com::sun::star::uno;
48 using namespace ::com::sun::star::resource;
51 // ExtTreeListBox
53 ExtTreeListBox::ExtTreeListBox(vcl::Window* pParent, WinBits nStyle)
54 : TreeListBox(pParent, nStyle)
58 VCL_BUILDER_FACTORY_CONSTRUCTOR(ExtTreeListBox, WB_TABSTOP)
60 bool ExtTreeListBox::EditingEntry( SvTreeListEntry* pEntry, Selection& )
62 bool bRet = false;
64 if ( pEntry )
66 sal_uInt16 nDepth = GetModel()->GetDepth( pEntry );
67 if ( nDepth >= 2 )
69 EntryDescriptor aDesc = GetEntryDescriptor(pEntry);
70 ScriptDocument aDocument( aDesc.GetDocument() );
71 OUString aLibName( aDesc.GetLibName() );
72 Reference< script::XLibraryContainer2 > xModLibContainer( aDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
73 Reference< script::XLibraryContainer2 > xDlgLibContainer( aDocument.getLibraryContainer( E_DIALOGS ), UNO_QUERY );
74 if ( !( ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) && xModLibContainer->isLibraryReadOnly( aLibName ) ) ||
75 ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) && xDlgLibContainer->isLibraryReadOnly( aLibName ) ) ) )
77 // allow editing only for libraries, which are not readonly
78 bRet = true;
83 return bRet;
86 bool ExtTreeListBox::EditedEntry( SvTreeListEntry* pEntry, const OUString& rNewText )
88 if ( !IsValidSbxName(rNewText) )
90 std::unique_ptr<weld::MessageDialog> xError(Application::CreateMessageDialog(GetFrameWeld(),
91 VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_BADSBXNAME)));
92 xError->run();
93 return false;
96 OUString aCurText( GetEntryText( pEntry ) );
97 if ( aCurText == rNewText )
98 // nothing to do
99 return true;
101 EntryDescriptor aDesc = GetEntryDescriptor(pEntry);
102 ScriptDocument aDocument( aDesc.GetDocument() );
103 DBG_ASSERT( aDocument.isValid(), "ExtTreeListBox::EditedEntry: no document!" );
104 if ( !aDocument.isValid() )
105 return false;
106 OUString aLibName( aDesc.GetLibName() );
107 EntryType eType = aDesc.GetType();
109 bool bSuccess = eType == OBJ_TYPE_MODULE ?
110 RenameModule(GetFrameWeld(), aDocument, aLibName, aCurText, rNewText) :
111 RenameDialog(GetFrameWeld(), aDocument, aLibName, aCurText, rNewText);
113 if ( !bSuccess )
114 return false;
116 MarkDocumentModified( aDocument );
118 if (SfxDispatcher* pDispatcher = GetDispatcher())
120 SbxItem aSbxItem( SID_BASICIDE_ARG_SBX, aDocument, aLibName, rNewText, ConvertType( eType ) );
121 pDispatcher->ExecuteList( SID_BASICIDE_SBXRENAMED,
122 SfxCallMode::SYNCHRON, { &aSbxItem });
125 // OV-Bug?!
126 SetEntryText( pEntry, rNewText );
127 SetCurEntry( pEntry );
128 SetCurEntry( pEntry );
129 Select( pEntry, false );
130 Select( pEntry ); // so that handler is called => update edit
132 return true;
136 DragDropMode ExtTreeListBox::NotifyStartDrag( TransferDataContainer&, SvTreeListEntry* pEntry )
138 DragDropMode nMode_ = DragDropMode::NONE;
140 if ( pEntry )
142 sal_uInt16 nDepth = GetModel()->GetDepth( pEntry );
143 if ( nDepth >= 2 )
145 nMode_ = DragDropMode::CTRL_COPY;
146 EntryDescriptor aDesc = GetEntryDescriptor(pEntry);
147 ScriptDocument aDocument( aDesc.GetDocument() );
148 OUString aLibName( aDesc.GetLibName() );
149 // allow MOVE mode only for libraries, which are not readonly
150 Reference< script::XLibraryContainer2 > xModLibContainer( aDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
151 Reference< script::XLibraryContainer2 > xDlgLibContainer( aDocument.getLibraryContainer( E_DIALOGS ), UNO_QUERY );
152 if ( !( ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) && xModLibContainer->isLibraryReadOnly( aLibName ) ) ||
153 ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) && xDlgLibContainer->isLibraryReadOnly( aLibName ) ) ) )
155 // Only allow copy for localized libraries
156 bool bAllowMove = true;
157 if ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) )
159 // Get StringResourceManager
160 Reference< container::XNameContainer > xDialogLib( aDocument.getLibrary( E_DIALOGS, aLibName, true ) );
161 Reference< XStringResourceManager > xSourceMgr =
162 LocalizationMgr::getStringResourceFromDialogLibrary( xDialogLib );
163 if( xSourceMgr.is() )
164 bAllowMove = ( xSourceMgr->getLocales().getLength() == 0 );
166 if( bAllowMove )
167 nMode_ |= DragDropMode::CTRL_MOVE;
172 return nMode_;
176 bool ExtTreeListBox::NotifyAcceptDrop( SvTreeListEntry* pEntry )
178 // don't drop on a BasicManager (nDepth == 0)
179 sal_uInt16 nDepth = pEntry ? GetModel()->GetDepth( pEntry ) : 0;
180 bool bValid = nDepth != 0;
182 // don't drop in the same library
183 SvTreeListEntry* pSelected = FirstSelected();
184 if (!pSelected)
185 bValid = false;
186 else if ( ( nDepth == 1 ) && ( pEntry == GetParent( pSelected ) ) )
187 bValid = false;
188 else if ( ( nDepth == 2 ) && ( GetParent( pEntry ) == GetParent( pSelected ) ) )
189 bValid = false;
191 // don't drop on a library, which is not loaded, readonly or password protected
192 // or which already has a module/dialog with this name
193 if ( bValid && ( nDepth > 0 ) )
195 // get source module/dialog name
196 EntryDescriptor aSourceDesc = GetEntryDescriptor(pSelected);
197 OUString aSourceName = aSourceDesc.GetName();
198 EntryType eSourceType = aSourceDesc.GetType();
200 // get target shell and target library name
201 EntryDescriptor aDestDesc = GetEntryDescriptor(pEntry);
202 ScriptDocument const& rDestDoc = aDestDesc.GetDocument();
203 OUString aDestLibName = aDestDesc.GetLibName();
205 // check if module library is not loaded, readonly or password protected
206 Reference< script::XLibraryContainer2 > xModLibContainer( rDestDoc.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
207 if ( xModLibContainer.is() && xModLibContainer->hasByName( aDestLibName ) )
209 if ( !xModLibContainer->isLibraryLoaded( aDestLibName ) )
210 bValid = false;
212 if ( xModLibContainer->isLibraryReadOnly( aDestLibName ) )
213 bValid = false;
215 Reference< script::XLibraryContainerPassword > xPasswd( xModLibContainer, UNO_QUERY );
216 if ( xPasswd.is() && xPasswd->isLibraryPasswordProtected( aDestLibName ) && !xPasswd->isLibraryPasswordVerified( aDestLibName ) )
217 bValid = false;
220 // check if dialog library is not loaded or readonly
221 Reference< script::XLibraryContainer2 > xDlgLibContainer( rDestDoc.getLibraryContainer( E_DIALOGS ), UNO_QUERY );
222 if ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aDestLibName ) )
224 if ( !xDlgLibContainer->isLibraryLoaded( aDestLibName ) )
225 bValid = false;
227 if ( xDlgLibContainer->isLibraryReadOnly( aDestLibName ) )
228 bValid = false;
231 // check, if module/dialog with this name is already existing in target library
232 if ( ( eSourceType == OBJ_TYPE_MODULE && rDestDoc.hasModule( aDestLibName, aSourceName ) ) ||
233 ( eSourceType == OBJ_TYPE_DIALOG && rDestDoc.hasDialog( aDestLibName, aSourceName ) ) )
235 bValid = false;
239 return bValid;
242 TriState ExtTreeListBox::NotifyMoving( SvTreeListEntry* pTarget, SvTreeListEntry* pEntry,
243 SvTreeListEntry*& rpNewParent, sal_uLong& rNewChildPos )
245 return NotifyCopyingMoving( pTarget, pEntry,
246 rpNewParent, rNewChildPos, true );
249 TriState ExtTreeListBox::NotifyCopying( SvTreeListEntry* pTarget, SvTreeListEntry* pEntry,
250 SvTreeListEntry*& rpNewParent, sal_uLong& rNewChildPos )
252 return NotifyCopyingMoving( pTarget, pEntry,
253 rpNewParent, rNewChildPos, false );
256 void Shell::CopyDialogResources(
257 Reference< io::XInputStreamProvider >& io_xISP,
258 ScriptDocument const& rSourceDoc,
259 OUString const& rSourceLibName,
260 ScriptDocument const& rDestDoc,
261 OUString const& rDestLibName,
262 OUString const& rDlgName
265 if ( !io_xISP.is() )
266 return;
268 // Get StringResourceManager
269 Reference< container::XNameContainer > xSourceDialogLib( rSourceDoc.getLibrary( E_DIALOGS, rSourceLibName, true ) );
270 Reference< XStringResourceManager > xSourceMgr =
271 LocalizationMgr::getStringResourceFromDialogLibrary( xSourceDialogLib );
272 if( !xSourceMgr.is() )
273 return;
274 bool bSourceLocalized = ( xSourceMgr->getLocales().getLength() > 0 );
276 Reference< container::XNameContainer > xDestDialogLib( rDestDoc.getLibrary( E_DIALOGS, rDestLibName, true ) );
277 Reference< XStringResourceManager > xDestMgr =
278 LocalizationMgr::getStringResourceFromDialogLibrary( xDestDialogLib );
279 if( !xDestMgr.is() )
280 return;
281 bool bDestLocalized = ( xDestMgr->getLocales().getLength() > 0 );
283 if( !bSourceLocalized && !bDestLocalized )
284 return;
286 // create dialog model
287 Reference< XComponentContext > xContext = comphelper::getProcessComponentContext();
288 Reference< container::XNameContainer > xDialogModel( xContext->getServiceManager()->createInstanceWithContext
289 ( "com.sun.star.awt.UnoControlDialogModel", xContext ), UNO_QUERY );
290 Reference< io::XInputStream > xInput( io_xISP->createInputStream() );
291 ::xmlscript::importDialogModel( xInput, xDialogModel, xContext, rSourceDoc.isDocument() ? rSourceDoc.getDocument() : Reference< frame::XModel >() );
293 if( xDialogModel.is() )
295 if( bSourceLocalized && bDestLocalized )
297 Reference< resource::XStringResourceResolver > xSourceStringResolver( xSourceMgr, UNO_QUERY );
298 LocalizationMgr::copyResourceForDroppedDialog( xDialogModel, rDlgName, xDestMgr, xSourceStringResolver );
300 else if( bSourceLocalized )
302 LocalizationMgr::resetResourceForDialog( xDialogModel, xSourceMgr );
304 else if( bDestLocalized )
306 LocalizationMgr::setResourceIDsForDialog( xDialogModel, xDestMgr );
308 io_xISP = ::xmlscript::exportDialogModel( xDialogModel, xContext, rDestDoc.isDocument() ? rDestDoc.getDocument() : Reference< frame::XModel >() );
312 TriState ExtTreeListBox::NotifyCopyingMoving( SvTreeListEntry* pTarget, SvTreeListEntry const * pEntry,
313 SvTreeListEntry*& rpNewParent, sal_uLong& rNewChildPos, bool bMove )
315 DBG_ASSERT( pEntry, "No entry?" ); // ASS is ok here, should not be reached
316 DBG_ASSERT( pTarget, "No target?" ); // with NULL (right at the beginning)
317 sal_uInt16 nDepth = GetModel()->GetDepth( pTarget );
318 DBG_ASSERT( nDepth, "Depth?" );
319 if ( nDepth == 1 )
321 // Target = Basic => put module/dialog under the Basic
322 rpNewParent = pTarget;
323 rNewChildPos = 0;
325 else if ( nDepth >= 2 )
327 // Target = module/dialog => put module/dialog under the superordinate Basic
328 rpNewParent = GetParent( pTarget );
329 rNewChildPos = SvTreeList::GetRelPos( pTarget ) + 1;
332 // get target shell and target library name
333 EntryDescriptor aDestDesc = GetEntryDescriptor(rpNewParent);
334 const ScriptDocument& rDestDoc( aDestDesc.GetDocument() );
335 OUString aDestLibName( aDestDesc.GetLibName() );
337 // get source shell, library name and module/dialog name
338 EntryDescriptor aSourceDesc = GetEntryDescriptor(FirstSelected());
339 const ScriptDocument rSourceDoc( aSourceDesc.GetDocument() );
340 OUString aSourceLibName( aSourceDesc.GetLibName() );
341 OUString aSourceName( aSourceDesc.GetName() );
342 EntryType eType = aSourceDesc.GetType();
344 // get dispatcher
345 SfxDispatcher* pDispatcher = GetDispatcher();
347 if ( bMove ) // move
349 // remove source module/dialog window
350 if ( rSourceDoc != rDestDoc || aSourceLibName != aDestLibName )
352 if( pDispatcher )
354 SbxItem aSbxItem( SID_BASICIDE_ARG_SBX, rSourceDoc, aSourceLibName, aSourceName, ConvertType( eType ) );
355 pDispatcher->ExecuteList( SID_BASICIDE_SBXDELETED,
356 SfxCallMode::SYNCHRON, { &aSbxItem });
362 if ( eType == OBJ_TYPE_MODULE ) // module
364 // get module
365 OUString aModule;
366 if ( rSourceDoc.getModule( aSourceLibName, aSourceName, aModule ) )
368 // remove module from source library
369 if ( rSourceDoc.removeModule( aSourceLibName, aSourceName ) )
371 MarkDocumentModified( rSourceDoc );
373 // insert module into target library
374 if ( rDestDoc.insertModule( aDestLibName, aSourceName, aModule ) )
375 MarkDocumentModified( rDestDoc );
379 else if ( eType == OBJ_TYPE_DIALOG ) // dialog
381 // get dialog
382 Reference< io::XInputStreamProvider > xISP;
383 if ( rSourceDoc.getDialog( aSourceLibName, aSourceName, xISP ) )
385 Shell::CopyDialogResources( xISP, rSourceDoc,
386 aSourceLibName, rDestDoc, aDestLibName, aSourceName );
388 // remove dialog from source library
389 if (RemoveDialog(rSourceDoc, aSourceLibName, aSourceName))
391 MarkDocumentModified(rSourceDoc);
393 // insert dialog into target library
394 if ( rDestDoc.insertDialog( aDestLibName, aSourceName, xISP ) )
395 MarkDocumentModified(rDestDoc);
400 catch (const uno::Exception& )
402 DBG_UNHANDLED_EXCEPTION("basctl.basicide");
405 else // copy
409 if ( eType == OBJ_TYPE_MODULE ) // module
411 // get module
412 OUString aModule;
413 if ( rSourceDoc.getModule( aSourceLibName, aSourceName, aModule ) )
415 // insert module into target library
416 if ( rDestDoc.insertModule( aDestLibName, aSourceName, aModule ) )
417 MarkDocumentModified( rDestDoc );
420 else if ( eType == OBJ_TYPE_DIALOG ) // dialog
422 // get dialog
423 Reference< io::XInputStreamProvider > xISP;
424 if ( rSourceDoc.getDialog( aSourceLibName, aSourceName, xISP ) )
426 Shell::CopyDialogResources( xISP, rSourceDoc,
427 aSourceLibName, rDestDoc, aDestLibName, aSourceName );
429 // insert dialog into target library
430 if ( rDestDoc.insertDialog( aDestLibName, aSourceName, xISP ) )
431 MarkDocumentModified( rDestDoc );
435 catch ( const Exception& )
437 DBG_UNHANDLED_EXCEPTION("basctl.basicide");
441 // create target module/dialog window
442 if ( rSourceDoc != rDestDoc || aSourceLibName != aDestLibName )
444 if( pDispatcher )
446 SbxItem aSbxItem( SID_BASICIDE_ARG_SBX, rDestDoc, aDestLibName, aSourceName, ConvertType( eType ) );
447 pDispatcher->ExecuteList( SID_BASICIDE_SBXINSERTED,
448 SfxCallMode::SYNCHRON, { &aSbxItem });
452 return TRISTATE_INDET; // open...
455 // OrganizeDialog
456 OrganizeDialog::OrganizeDialog(vcl::Window* pParent, sal_Int16 tabId,
457 EntryDescriptor const & rDesc )
458 : TabDialog( pParent, "OrganizeDialog",
459 "modules/BasicIDE/ui/organizedialog.ui" )
460 , m_aCurEntry( rDesc )
462 get(m_pTabCtrl, "tabcontrol");
464 sal_uInt16 nPageCount = m_pTabCtrl->GetPageCount();
465 for (sal_uInt16 nPage = 0; nPage < nPageCount; ++nPage)
467 sal_uInt16 nPageId = m_pTabCtrl->GetPageId(nPage);
468 m_pTabCtrl->SetTabPage(nPageId, nullptr);
471 m_pTabCtrl->SetActivatePageHdl(LINK(this, OrganizeDialog, ActivatePageHdl));
473 if( tabId == 0 )
475 m_pTabCtrl->SetCurPageId(m_pTabCtrl->GetPageId("modules"));
477 else if ( tabId == 1 )
479 m_pTabCtrl->SetCurPageId(m_pTabCtrl->GetPageId("dialogs"));
481 else
483 m_pTabCtrl->SetCurPageId(m_pTabCtrl->GetPageId("libraries"));
486 ActivatePageHdl(m_pTabCtrl);
488 if (SfxDispatcher* pDispatcher = GetDispatcher())
489 pDispatcher->Execute( SID_BASICIDE_STOREALLMODULESOURCES );
492 OrganizeDialog::~OrganizeDialog()
494 disposeOnce();
497 void OrganizeDialog::dispose()
499 if (m_pTabCtrl)
501 for ( sal_uInt16 i = 0; i < m_pTabCtrl->GetPageCount(); i++ )
502 VclPtr<vcl::Window>(m_pTabCtrl->GetTabPage( m_pTabCtrl->GetPageId( i ) )).disposeAndClear();
504 m_pTabCtrl.clear();
506 TabDialog::dispose();
509 IMPL_LINK( OrganizeDialog, ActivatePageHdl, TabControl *, pTabCtrl, void )
511 sal_uInt16 nId = pTabCtrl->GetCurPageId();
513 if ( !pTabCtrl->GetTabPage( nId ) )
515 OString sPageName(pTabCtrl->GetPageName(nId));
516 VclPtr<TabPage> pNewTabPage;
517 if (sPageName == "modules")
519 VclPtrInstance<ObjectPage> pObjectPage(pTabCtrl, "ModulePage", BrowseMode::Modules);
520 pNewTabPage.reset(pObjectPage);
521 pObjectPage->SetTabDlg(this);
522 pObjectPage->SetCurrentEntry(m_aCurEntry);
524 else if (sPageName == "dialogs")
526 VclPtrInstance<ObjectPage> pObjectPage( pTabCtrl, "DialogPage", BrowseMode::Dialogs );
527 pNewTabPage.reset(pObjectPage);
528 pObjectPage->SetTabDlg(this);
529 pObjectPage->SetCurrentEntry(m_aCurEntry);
531 else if (sPageName == "libraries")
533 VclPtrInstance<LibPage> pLibPage( pTabCtrl );
534 pNewTabPage.reset(pLibPage);
535 pLibPage->SetTabDlg( this );
537 else
539 OSL_FAIL( "PageHdl: Unknown ID" );
541 DBG_ASSERT( pNewTabPage, "No page" );
542 pTabCtrl->SetTabPage( nId, pNewTabPage );
547 // ObjectPage
550 ObjectPage::ObjectPage(vcl::Window *pParent, const OString &rName, BrowseMode nMode)
551 : TabPage(pParent, rName, "modules/BasicIDE/ui/" +
552 OStringToOUString(rName, RTL_TEXTENCODING_UTF8).toAsciiLowerCase() +
553 ".ui")
555 get(m_pBasicBox, "library");
556 Size aSize(m_pBasicBox->LogicToPixel(Size(130, 117), MapMode(MapUnit::MapAppFont)));
557 m_pBasicBox->set_height_request(aSize.Height());
558 m_pBasicBox->set_width_request(aSize.Width());
559 get(m_pEditButton, "edit");
560 get(m_pNewModButton, "newmodule");
561 get(m_pNewDlgButton, "newdialog");
562 get(m_pDelButton, "delete");
564 pTabDlg = nullptr;
566 m_pEditButton->SetClickHdl( LINK( this, ObjectPage, ButtonHdl ) );
567 m_pDelButton->SetClickHdl( LINK( this, ObjectPage, ButtonHdl ) );
568 m_pBasicBox->SetSelectHdl( LINK( this, ObjectPage, BasicBoxHighlightHdl ) );
570 if( nMode & BrowseMode::Modules )
572 m_pNewModButton->SetClickHdl( LINK( this, ObjectPage, ButtonHdl ) );
573 m_pNewDlgButton->Hide();
575 else if ( nMode & BrowseMode::Dialogs )
577 m_pNewDlgButton->SetClickHdl( LINK( this, ObjectPage, ButtonHdl ) );
578 m_pNewModButton->Hide();
581 m_pBasicBox->SetDragDropMode( DragDropMode::CTRL_MOVE | DragDropMode::CTRL_COPY );
582 m_pBasicBox->EnableInplaceEditing(true);
583 m_pBasicBox->SetMode( nMode );
584 m_pBasicBox->SetStyle( WB_BORDER | WB_TABSTOP |
585 WB_HASLINES | WB_HASLINESATROOT |
586 WB_HASBUTTONS | WB_HASBUTTONSATROOT |
587 WB_HSCROLL );
588 m_pBasicBox->ScanAllEntries();
590 m_pEditButton->GrabFocus();
591 CheckButtons();
594 ObjectPage::~ObjectPage()
596 disposeOnce();
599 void ObjectPage::dispose()
601 m_pBasicBox.clear();
602 m_pEditButton.clear();
603 m_pNewModButton.clear();
604 m_pNewDlgButton.clear();
605 m_pDelButton.clear();
606 pTabDlg.clear();
607 TabPage::dispose();
610 void ObjectPage::SetCurrentEntry (EntryDescriptor const & rDesc)
612 m_pBasicBox->SetCurrentEntry( rDesc );
615 void ObjectPage::ActivatePage()
617 m_pBasicBox->UpdateEntries();
620 void ObjectPage::DeactivatePage()
624 void ObjectPage::CheckButtons()
626 // enable/disable edit button
627 SvTreeListEntry* pCurEntry = m_pBasicBox->GetCurEntry();
628 EntryDescriptor aDesc = m_pBasicBox->GetEntryDescriptor(pCurEntry);
629 ScriptDocument aDocument( aDesc.GetDocument() );
630 OUString aLibName( aDesc.GetLibName() );
631 OUString aLibSubName( aDesc.GetLibSubName() );
632 bool bVBAEnabled = aDocument.isInVBAMode();
633 BrowseMode nMode = m_pBasicBox->GetMode();
635 sal_uInt16 nDepth = pCurEntry ? m_pBasicBox->GetModel()->GetDepth( pCurEntry ) : 0;
636 if ( nDepth >= 2 )
638 if( bVBAEnabled && ( nMode & BrowseMode::Modules ) && ( nDepth == 2 ) )
639 m_pEditButton->Disable();
640 else
641 m_pEditButton->Enable();
643 else
644 m_pEditButton->Disable();
646 // enable/disable new module/dialog buttons
647 LibraryLocation eLocation( aDesc.GetLocation() );
648 bool bReadOnly = false;
649 if ( nDepth > 0 )
651 Reference< script::XLibraryContainer2 > xModLibContainer( aDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
652 Reference< script::XLibraryContainer2 > xDlgLibContainer( aDocument.getLibraryContainer( E_DIALOGS ), UNO_QUERY );
653 if ( ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) && xModLibContainer->isLibraryReadOnly( aLibName ) ) ||
654 ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) && xDlgLibContainer->isLibraryReadOnly( aLibName ) ) )
656 bReadOnly = true;
659 if ( bReadOnly || eLocation == LIBRARY_LOCATION_SHARE )
661 m_pNewModButton->Disable();
662 m_pNewDlgButton->Disable();
664 else
666 m_pNewModButton->Enable();
667 m_pNewDlgButton->Enable();
670 // enable/disable delete button
671 if ( nDepth >= 2 && !bReadOnly && eLocation != LIBRARY_LOCATION_SHARE )
673 if( bVBAEnabled && ( nMode & BrowseMode::Modules ) && ( ( nDepth == 2 ) || aLibSubName == IDEResId(RID_STR_DOCUMENT_OBJECTS) ) )
674 m_pDelButton->Disable();
675 else
676 m_pDelButton->Enable();
678 else
679 m_pDelButton->Disable();
682 IMPL_LINK( ObjectPage, BasicBoxHighlightHdl, SvTreeListBox*, pBox, void )
684 if ( !pBox->IsSelected( pBox->GetHdlEntry() ) )
685 return;
687 CheckButtons();
690 IMPL_LINK( ObjectPage, ButtonHdl, Button *, pButton, void )
692 if (pButton == m_pEditButton)
694 SfxAllItemSet aArgs( SfxGetpApp()->GetPool() );
695 SfxRequest aRequest( SID_BASICIDE_APPEAR, SfxCallMode::SYNCHRON, aArgs );
696 SfxGetpApp()->ExecuteSlot( aRequest );
698 SfxDispatcher* pDispatcher = GetDispatcher();
699 SvTreeListEntry* pCurEntry = m_pBasicBox->GetCurEntry();
700 DBG_ASSERT( pCurEntry, "Entry?!" );
701 if ( m_pBasicBox->GetModel()->GetDepth( pCurEntry ) >= 2 )
703 EntryDescriptor aDesc = m_pBasicBox->GetEntryDescriptor(pCurEntry);
704 if ( pDispatcher )
706 OUString aModName( aDesc.GetName() );
707 // extract the module name from the string like "Sheet1 (Example1)"
708 if( aDesc.GetLibSubName() == IDEResId(RID_STR_DOCUMENT_OBJECTS) )
710 sal_Int32 nIndex = 0;
711 aModName = aModName.getToken( 0, ' ', nIndex );
713 SbxItem aSbxItem( SID_BASICIDE_ARG_SBX, aDesc.GetDocument(), aDesc.GetLibName(),
714 aModName, TreeListBox::ConvertType( aDesc.GetType() ) );
715 pDispatcher->ExecuteList(SID_BASICIDE_SHOWSBX,
716 SfxCallMode::SYNCHRON, { &aSbxItem });
719 else // only Lib selected
721 DBG_ASSERT( m_pBasicBox->GetModel()->GetDepth( pCurEntry ) == 1, "No LibEntry?!" );
722 ScriptDocument aDocument( ScriptDocument::getApplicationScriptDocument() );
723 SvTreeListEntry* pParentEntry = m_pBasicBox->GetParent( pCurEntry );
724 if ( pParentEntry )
726 DocumentEntry* pDocumentEntry = static_cast<DocumentEntry*>(pParentEntry->GetUserData());
727 if (pDocumentEntry)
728 aDocument = pDocumentEntry->GetDocument();
730 SfxUnoAnyItem aDocItem( SID_BASICIDE_ARG_DOCUMENT_MODEL, Any( aDocument.getDocumentOrNull() ) );
731 OUString aLibName( m_pBasicBox->GetEntryText( pCurEntry ) );
732 SfxStringItem aLibNameItem( SID_BASICIDE_ARG_LIBNAME, aLibName );
733 if ( pDispatcher )
735 pDispatcher->ExecuteList(SID_BASICIDE_LIBSELECTED,
736 SfxCallMode::ASYNCHRON, { &aDocItem, &aLibNameItem });
739 EndTabDialog();
741 else if (pButton == m_pNewModButton)
742 NewModule();
743 else if (pButton == m_pNewDlgButton)
744 NewDialog();
745 else if (pButton == m_pDelButton)
746 DeleteCurrent();
749 bool ObjectPage::GetSelection( ScriptDocument& rDocument, OUString& rLibName )
751 bool bRet = false;
753 SvTreeListEntry* pCurEntry = m_pBasicBox->GetCurEntry();
754 EntryDescriptor aDesc = m_pBasicBox->GetEntryDescriptor(pCurEntry);
755 rDocument = aDesc.GetDocument();
756 rLibName = aDesc.GetLibName();
757 if ( rLibName.isEmpty() )
758 rLibName = "Standard" ;
760 DBG_ASSERT( rDocument.isAlive(), "ObjectPage::GetSelection: no or dead ScriptDocument in the selection!" );
761 if ( !rDocument.isAlive() )
762 return false;
764 // check if the module library is loaded
765 bool bOK = true;
766 OUString aLibName( rLibName );
767 Reference< script::XLibraryContainer > xModLibContainer( rDocument.getLibraryContainer( E_SCRIPTS ) );
768 if ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) && !xModLibContainer->isLibraryLoaded( aLibName ) )
770 // check password
771 Reference< script::XLibraryContainerPassword > xPasswd( xModLibContainer, UNO_QUERY );
772 if ( xPasswd.is() && xPasswd->isLibraryPasswordProtected( aLibName ) && !xPasswd->isLibraryPasswordVerified( aLibName ) )
774 OUString aPassword;
775 bOK = QueryPassword( xModLibContainer, rLibName, aPassword );
778 // load library
779 if ( bOK )
780 xModLibContainer->loadLibrary( aLibName );
783 // check if the dialog library is loaded
784 Reference< script::XLibraryContainer > xDlgLibContainer( rDocument.getLibraryContainer( E_DIALOGS ) );
785 if ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) && !xDlgLibContainer->isLibraryLoaded( aLibName ) )
787 // load library
788 if ( bOK )
789 xDlgLibContainer->loadLibrary( aLibName );
792 if ( bOK )
793 bRet = true;
795 return bRet;
798 void ObjectPage::NewModule()
800 ScriptDocument aDocument( ScriptDocument::getApplicationScriptDocument() );
801 OUString aLibName;
803 if ( GetSelection( aDocument, aLibName ) )
805 createModImpl(GetFrameWeld(), aDocument,
806 *m_pBasicBox, aLibName, OUString(), true);
810 void ObjectPage::NewDialog()
812 ScriptDocument aDocument( ScriptDocument::getApplicationScriptDocument() );
813 OUString aLibName;
815 if ( GetSelection( aDocument, aLibName ) )
817 aDocument.getOrCreateLibrary( E_DIALOGS, aLibName );
819 NewObjectDialog aNewDlg(GetFrameWeld(), ObjectMode::Dialog, true);
820 aNewDlg.SetObjectName(aDocument.createObjectName(E_DIALOGS, aLibName));
822 if (aNewDlg.run() != RET_CANCEL)
824 OUString aDlgName = aNewDlg.GetObjectName();
825 if (aDlgName.isEmpty())
826 aDlgName = aDocument.createObjectName( E_DIALOGS, aLibName);
828 if ( aDocument.hasDialog( aLibName, aDlgName ) )
830 std::unique_ptr<weld::MessageDialog> xError(Application::CreateMessageDialog(GetFrameWeld(),
831 VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_SBXNAMEALLREADYUSED2)));
832 xError->run();
834 else
836 Reference< io::XInputStreamProvider > xISP;
837 if ( !aDocument.createDialog( aLibName, aDlgName, xISP ) )
838 return;
840 SbxItem aSbxItem( SID_BASICIDE_ARG_SBX, aDocument, aLibName, aDlgName, TYPE_DIALOG );
841 if (SfxDispatcher* pDispatcher = GetDispatcher())
843 pDispatcher->ExecuteList( SID_BASICIDE_SBXINSERTED,
844 SfxCallMode::SYNCHRON, { &aSbxItem });
846 LibraryLocation eLocation = aDocument.getLibraryLocation( aLibName );
847 SvTreeListEntry* pRootEntry = m_pBasicBox->FindRootEntry( aDocument, eLocation );
848 if ( pRootEntry )
850 if ( !m_pBasicBox->IsExpanded( pRootEntry ) )
851 m_pBasicBox->Expand( pRootEntry );
852 SvTreeListEntry* pLibEntry = m_pBasicBox->FindEntry( pRootEntry, aLibName, OBJ_TYPE_LIBRARY );
853 DBG_ASSERT( pLibEntry, "LibEntry not found!" );
854 if ( pLibEntry )
856 if ( !m_pBasicBox->IsExpanded( pLibEntry ) )
857 m_pBasicBox->Expand( pLibEntry );
858 SvTreeListEntry* pEntry = m_pBasicBox->FindEntry( pLibEntry, aDlgName, OBJ_TYPE_DIALOG );
859 if ( !pEntry )
861 pEntry = m_pBasicBox->AddEntry(
862 aDlgName,
863 Image(BitmapEx(RID_BMP_DIALOG)),
864 pLibEntry, false,
865 o3tl::make_unique<Entry>(OBJ_TYPE_DIALOG));
866 DBG_ASSERT( pEntry, "Insert entry failed!" );
868 m_pBasicBox->SetCurEntry( pEntry );
869 m_pBasicBox->Select( m_pBasicBox->GetCurEntry() ); // OV-Bug?!
877 void ObjectPage::DeleteCurrent()
879 SvTreeListEntry* pCurEntry = m_pBasicBox->GetCurEntry();
880 DBG_ASSERT( pCurEntry, "No current entry!" );
881 EntryDescriptor aDesc( m_pBasicBox->GetEntryDescriptor( pCurEntry ) );
882 ScriptDocument aDocument( aDesc.GetDocument() );
883 DBG_ASSERT( aDocument.isAlive(), "ObjectPage::DeleteCurrent: no document!" );
884 if ( !aDocument.isAlive() )
885 return;
886 OUString aLibName( aDesc.GetLibName() );
887 OUString aName( aDesc.GetName() );
888 EntryType eType = aDesc.GetType();
890 if ( ( eType == OBJ_TYPE_MODULE && QueryDelModule(aName, GetFrameWeld()) ) ||
891 ( eType == OBJ_TYPE_DIALOG && QueryDelDialog(aName, GetFrameWeld()) ) )
893 m_pBasicBox->GetModel()->Remove( pCurEntry );
894 if ( m_pBasicBox->GetCurEntry() ) // OV-Bug ?
895 m_pBasicBox->Select( m_pBasicBox->GetCurEntry() );
896 if (SfxDispatcher* pDispatcher = GetDispatcher())
898 SbxItem aSbxItem( SID_BASICIDE_ARG_SBX, aDocument, aLibName, aName, TreeListBox::ConvertType( eType ) );
899 pDispatcher->ExecuteList( SID_BASICIDE_SBXDELETED,
900 SfxCallMode::SYNCHRON, { &aSbxItem });
905 bool bSuccess = false;
906 if ( eType == OBJ_TYPE_MODULE )
907 bSuccess = aDocument.removeModule( aLibName, aName );
908 else if ( eType == OBJ_TYPE_DIALOG )
909 bSuccess = RemoveDialog( aDocument, aLibName, aName );
911 if ( bSuccess )
912 MarkDocumentModified( aDocument );
914 catch (const container::NoSuchElementException& )
916 DBG_UNHANDLED_EXCEPTION("basctl.basicide");
922 void ObjectPage::EndTabDialog()
924 DBG_ASSERT( pTabDlg, "TabDlg not set!" );
925 if ( pTabDlg )
926 pTabDlg->EndDialog( 1 );
929 LibDialog::LibDialog( vcl::Window* pParent )
930 : ModalDialog(pParent, "ImportLibDialog", "modules/BasicIDE/ui/importlibdialog.ui")
932 get(m_pStorageFrame, "storageframe");
933 get(m_pReferenceBox, "ref");
934 get(m_pReplaceBox, "replace");
935 get(m_pLibBox, "entries");
936 m_pLibBox->set_height_request(m_pLibBox->GetTextHeight() * 8);
937 m_pLibBox->set_width_request(m_pLibBox->approximate_char_width() * 32);
940 LibDialog::~LibDialog()
942 disposeOnce();
945 void LibDialog::dispose()
947 m_pStorageFrame.clear();
948 m_pLibBox.clear();
949 m_pReferenceBox.clear();
950 m_pReplaceBox.clear();
951 ModalDialog::dispose();
955 void LibDialog::SetStorageName( const OUString& rName )
957 OUString aName = IDEResId(RID_STR_FILENAME) + rName;
958 m_pStorageFrame->set_label(aName);
961 // Helper function
962 SbModule* createModImpl(weld::Window* pWin, const ScriptDocument& rDocument,
963 TreeListBox& rBasicBox, const OUString& rLibName, const OUString& _aModName, bool bMain )
965 OSL_ENSURE( rDocument.isAlive(), "createModImpl: invalid document!" );
966 if ( !rDocument.isAlive() )
967 return nullptr;
969 SbModule* pModule = nullptr;
971 OUString aLibName( rLibName );
972 if ( aLibName.isEmpty() )
973 aLibName = "Standard" ;
974 rDocument.getOrCreateLibrary( E_SCRIPTS, aLibName );
975 OUString aModName = _aModName;
976 if ( aModName.isEmpty() )
977 aModName = rDocument.createObjectName( E_SCRIPTS, aLibName );
979 NewObjectDialog aNewDlg(pWin, ObjectMode::Module, true);
980 aNewDlg.SetObjectName(aModName);
982 if (aNewDlg.run() != RET_CANCEL)
984 if (!aNewDlg.GetObjectName().isEmpty())
985 aModName = aNewDlg.GetObjectName();
989 OUString sModuleCode;
990 // the module has existed
991 if( rDocument.hasModule( aLibName, aModName ) )
992 return nullptr;
993 rDocument.createModule( aLibName, aModName, bMain, sModuleCode );
994 BasicManager* pBasMgr = rDocument.getBasicManager();
995 StarBASIC* pBasic = pBasMgr? pBasMgr->GetLib( aLibName ) : nullptr;
996 if ( pBasic )
997 pModule = pBasic->FindModule( aModName );
998 SbxItem aSbxItem( SID_BASICIDE_ARG_SBX, rDocument, aLibName, aModName, TYPE_MODULE );
999 if (SfxDispatcher* pDispatcher = GetDispatcher())
1001 pDispatcher->ExecuteList( SID_BASICIDE_SBXINSERTED,
1002 SfxCallMode::SYNCHRON, { &aSbxItem });
1004 LibraryLocation eLocation = rDocument.getLibraryLocation( aLibName );
1005 SvTreeListEntry* pRootEntry = rBasicBox.FindRootEntry( rDocument, eLocation );
1006 if ( pRootEntry )
1008 if ( !rBasicBox.IsExpanded( pRootEntry ) )
1009 rBasicBox.Expand( pRootEntry );
1010 SvTreeListEntry* pLibEntry = rBasicBox.FindEntry( pRootEntry, aLibName, OBJ_TYPE_LIBRARY );
1011 DBG_ASSERT( pLibEntry, "LibEntry not found!" );
1012 if ( pLibEntry )
1014 if ( !rBasicBox.IsExpanded( pLibEntry ) )
1015 rBasicBox.Expand( pLibEntry );
1016 SvTreeListEntry* pSubRootEntry = pLibEntry;
1017 if( pBasic && rDocument.isInVBAMode() )
1019 // add the new module in the "Modules" entry
1020 SvTreeListEntry* pLibSubEntry = rBasicBox.FindEntry( pLibEntry, IDEResId(RID_STR_NORMAL_MODULES) , OBJ_TYPE_NORMAL_MODULES );
1021 if( pLibSubEntry )
1023 if( !rBasicBox.IsExpanded( pLibSubEntry ) )
1024 rBasicBox.Expand( pLibSubEntry );
1025 pSubRootEntry = pLibSubEntry;
1029 SvTreeListEntry* pEntry = rBasicBox.FindEntry( pSubRootEntry, aModName, OBJ_TYPE_MODULE );
1030 if ( !pEntry )
1032 pEntry = rBasicBox.AddEntry(
1033 aModName,
1034 Image(BitmapEx(RID_BMP_MODULE)),
1035 pSubRootEntry, false,
1036 o3tl::make_unique<Entry>(OBJ_TYPE_MODULE));
1037 DBG_ASSERT( pEntry, "Insert entry failed!" );
1039 rBasicBox.SetCurEntry( pEntry );
1040 rBasicBox.Select( rBasicBox.GetCurEntry() ); // OV-Bug?!
1044 catch (const container::ElementExistException& )
1046 std::unique_ptr<weld::MessageDialog> xError(Application::CreateMessageDialog(pWin,
1047 VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_SBXNAMEALLREADYUSED2)));
1048 xError->run();
1050 catch (const container::NoSuchElementException& )
1052 DBG_UNHANDLED_EXCEPTION("basctl.basicide");
1055 return pModule;
1058 } // namespace basctl
1060 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */