Version 6.1.4.1, tag libreoffice-6.1.4.1
[LibreOffice.git] / basctl / source / basicide / moduldl2.cxx
blob020e2f4488cff89b99a1cbb4f3085199f8015e9b
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 .
21 #include "moduldlg.hxx"
22 #include <basidesh.hxx>
23 #include <strings.hrc>
24 #include <bitmaps.hlst>
25 #include <iderdll.hxx>
26 #include "iderdll2.hxx"
27 #include <o3tl/make_unique.hxx>
28 #include <svx/passwd.hxx>
29 #include <ucbhelper/content.hxx>
30 #include <rtl/uri.hxx>
31 #include <sfx2/dinfdlg.hxx>
32 #include <sfx2/dispatch.hxx>
33 #include <sfx2/filedlghelper.hxx>
34 #include <sfx2/request.hxx>
35 #include <tools/urlobj.hxx>
36 #include <tools/diagnose_ex.h>
37 #include <svtools/svlbitm.hxx>
38 #include <svtools/treelistentry.hxx>
39 #include <vcl/builderfactory.hxx>
40 #include <vcl/weld.hxx>
42 #include <com/sun/star/io/Pipe.hpp>
43 #include <com/sun/star/ui/dialogs/FilePicker.hpp>
44 #include <com/sun/star/ui/dialogs/FolderPicker.hpp>
45 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
46 #include <com/sun/star/script/DocumentScriptLibraryContainer.hpp>
47 #include <com/sun/star/script/DocumentDialogLibraryContainer.hpp>
48 #include <com/sun/star/script/XLibraryContainerPassword.hpp>
49 #include <com/sun/star/script/XLibraryContainerExport.hpp>
50 #include <com/sun/star/task/InteractionHandler.hpp>
51 #include <com/sun/star/ucb/SimpleFileAccess.hpp>
52 #include <com/sun/star/ucb/XCommandEnvironment.hpp>
53 #include <com/sun/star/ucb/NameClash.hpp>
54 #include <com/sun/star/packages/manifest/ManifestWriter.hpp>
55 #include <unotools/pathoptions.hxx>
57 #include <com/sun/star/util/VetoException.hpp>
58 #include <com/sun/star/script/ModuleSizeExceededRequest.hpp>
60 #include <comphelper/propertysequence.hxx>
61 #include <cppuhelper/implbase.hxx>
63 #include <cassert>
65 namespace basctl
68 using namespace ::com::sun::star;
69 using namespace ::com::sun::star::uno;
70 using namespace ::com::sun::star::lang;
71 using namespace ::com::sun::star::ucb;
72 using namespace ::com::sun::star::ui::dialogs;
74 namespace
77 class DummyInteractionHandler : public ::cppu::WeakImplHelper< task::XInteractionHandler >
79 Reference< task::XInteractionHandler2 > m_xHandler;
80 public:
81 explicit DummyInteractionHandler(const Reference<task::XInteractionHandler2>& xHandler)
82 : m_xHandler(xHandler)
86 virtual void SAL_CALL handle( const Reference< task::XInteractionRequest >& rRequest ) override
88 if ( m_xHandler.is() )
90 script::ModuleSizeExceededRequest aModSizeException;
91 if ( rRequest->getRequest() >>= aModSizeException )
92 m_xHandler->handle( rRequest );
97 // LibUserData
98 class LibUserData final
100 private:
101 ScriptDocument m_aDocument;
103 public:
104 explicit LibUserData(ScriptDocument const& rDocument)
105 : m_aDocument(rDocument)
109 const ScriptDocument& GetDocument() const { return m_aDocument; }
112 // LibLBoxString
113 class LibLBoxString : public SvLBoxString
115 public:
116 explicit LibLBoxString(const OUString& rTxt)
117 : SvLBoxString(rTxt)
121 virtual void Paint(const Point& rPos, SvTreeListBox& rDev, vcl::RenderContext& rRenderContext,
122 const SvViewDataEntry* pView, const SvTreeListEntry& rEntry) override;
125 void LibLBoxString::Paint(const Point& rPos, SvTreeListBox& /*rDev*/, vcl::RenderContext& rRenderContext,
126 const SvViewDataEntry* /*pView*/, const SvTreeListEntry& rEntry)
128 // Change text color if library is read only:
129 bool bReadOnly = false;
130 if (rEntry.GetUserData())
132 ScriptDocument aDocument(static_cast<LibUserData*>(rEntry.GetUserData())->GetDocument());
134 OUString aLibName = static_cast<const SvLBoxString&>(rEntry.GetItem(1)).GetText();
135 Reference<script::XLibraryContainer2> xModLibContainer(aDocument.getLibraryContainer(E_SCRIPTS), UNO_QUERY);
136 Reference<script::XLibraryContainer2 > xDlgLibContainer(aDocument.getLibraryContainer(E_DIALOGS), UNO_QUERY);
137 bReadOnly = (xModLibContainer.is() && xModLibContainer->hasByName(aLibName) && xModLibContainer->isLibraryReadOnly(aLibName))
138 || (xDlgLibContainer.is() && xDlgLibContainer->hasByName(aLibName) && xDlgLibContainer->isLibraryReadOnly(aLibName));
140 if (bReadOnly)
141 rRenderContext.DrawCtrlText(rPos, GetText(), 0, -1, DrawTextFlags::Disable);
142 else
143 rRenderContext.DrawText(rPos, GetText());
146 } // namespace
148 // basctl::CheckBox
149 CheckBox::CheckBox(vcl::Window* pParent, WinBits nStyle)
150 : SvTabListBox(pParent, nStyle)
151 , eMode(ObjectMode::Module)
152 , m_aDocument(ScriptDocument::getApplicationScriptDocument())
154 long const aTabPositions[] = { 12 }; // TabPos needs at least one...
155 // 12 because of the CheckBox
156 SetTabs( SAL_N_ELEMENTS(aTabPositions), aTabPositions );
157 Init();
160 VCL_BUILDER_FACTORY_CONSTRUCTOR(CheckBox, WB_TABSTOP)
162 CheckBox::~CheckBox()
164 disposeOnce();
167 void CheckBox::dispose()
169 delete pCheckButton;
170 pCheckButton = nullptr;
172 // delete user data
173 SvTreeListEntry* pEntry = First();
174 while ( pEntry )
176 delete static_cast<LibUserData*>( pEntry->GetUserData() );
177 pEntry->SetUserData( nullptr );
178 pEntry = Next( pEntry );
180 SvTabListBox::dispose();
183 void CheckBox::Init()
185 pCheckButton = new SvLBoxButtonData(this);
187 if (eMode == ObjectMode::Library)
188 EnableCheckButton( pCheckButton );
189 else
190 EnableCheckButton( nullptr );
192 SetHighlightRange();
195 void CheckBox::SetMode (ObjectMode e)
197 eMode = e;
199 if (eMode == ObjectMode::Library)
200 EnableCheckButton( pCheckButton );
201 else
202 EnableCheckButton( nullptr );
205 SvTreeListEntry* CheckBox::DoInsertEntry( const OUString& rStr, sal_uLong nPos )
207 return SvTabListBox::InsertEntryToColumn( rStr, nPos, 0 );
210 SvTreeListEntry* CheckBox::FindEntry( const OUString& rName )
212 sal_uLong nCount = GetEntryCount();
213 for ( sal_uLong i = 0; i < nCount; i++ )
215 SvTreeListEntry* pEntry = GetEntry( i );
216 DBG_ASSERT( pEntry, "pEntry?!" );
217 if ( rName.equalsIgnoreAsciiCase( GetEntryText( pEntry, 0 ) ) )
218 return pEntry;
220 return nullptr;
223 void CheckBox::CheckEntryPos( sal_uLong nPos )
225 if ( nPos < GetEntryCount() )
227 SvTreeListEntry* pEntry = GetEntry( nPos );
229 if ( GetCheckButtonState( pEntry ) != SvButtonState::Checked )
230 SetCheckButtonState( pEntry, SvButtonState::Checked );
234 bool CheckBox::IsChecked( sal_uLong nPos ) const
236 if ( nPos < GetEntryCount() )
237 return GetCheckButtonState(GetEntry(nPos)) == SvButtonState::Checked;
238 return false;
241 void CheckBox::InitEntry(SvTreeListEntry* pEntry, const OUString& rTxt,
242 const Image& rImg1, const Image& rImg2, SvLBoxButtonKind eButtonKind )
244 SvTabListBox::InitEntry(pEntry, rTxt, rImg1, rImg2, eButtonKind);
246 if (eMode == ObjectMode::Module)
248 // initialize all columns with own string class (column 0 == bitmap)
249 sal_uInt16 nCount = pEntry->ItemCount();
250 for ( sal_uInt16 nCol = 1; nCol < nCount; ++nCol )
252 SvLBoxString& rCol = static_cast<SvLBoxString&>(pEntry->GetItem( nCol ));
253 pEntry->ReplaceItem(o3tl::make_unique<LibLBoxString>( rCol.GetText() ), nCol);
258 bool CheckBox::EditingEntry( SvTreeListEntry* pEntry, Selection& )
260 if (eMode != ObjectMode::Module)
261 return false;
263 DBG_ASSERT( pEntry, "No entry?" );
265 // check, if Standard library
266 OUString aLibName = GetEntryText( pEntry, 0 );
267 if ( aLibName.equalsIgnoreAsciiCase( "Standard" ) )
269 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(GetFrameWeld(),
270 VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_CANNOTCHANGENAMESTDLIB)));
271 xErrorBox->run();
272 return false;
275 // check, if library is readonly
276 Reference< script::XLibraryContainer2 > xModLibContainer( m_aDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
277 Reference< script::XLibraryContainer2 > xDlgLibContainer( m_aDocument.getLibraryContainer( E_DIALOGS ), UNO_QUERY );
278 if ( ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) && xModLibContainer->isLibraryReadOnly( aLibName ) && !xModLibContainer->isLibraryLink( aLibName ) ) ||
279 ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) && xDlgLibContainer->isLibraryReadOnly( aLibName ) && !xDlgLibContainer->isLibraryLink( aLibName ) ) )
281 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(GetFrameWeld(),
282 VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_LIBISREADONLY)));
283 xErrorBox->run();
284 return false;
287 // i24094: Password verification necessary for renaming
288 if ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) && !xModLibContainer->isLibraryLoaded( aLibName ) )
290 bool bOK = true;
291 // check password
292 Reference< script::XLibraryContainerPassword > xPasswd( xModLibContainer, UNO_QUERY );
293 if ( xPasswd.is() && xPasswd->isLibraryPasswordProtected( aLibName ) && !xPasswd->isLibraryPasswordVerified( aLibName ) )
295 OUString aPassword;
296 Reference< script::XLibraryContainer > xModLibContainer1( xModLibContainer, UNO_QUERY );
297 bOK = QueryPassword( xModLibContainer1, aLibName, aPassword );
299 if ( !bOK )
300 return false;
303 // TODO: check if library is reference/link
305 return true;
308 bool CheckBox::EditedEntry( SvTreeListEntry* pEntry, const OUString& rNewName )
310 bool bValid = rNewName.getLength() <= 30 && IsValidSbxName(rNewName);
311 OUString aOldName( GetEntryText( pEntry, 0 ) );
312 if ( bValid && ( aOldName != rNewName ) )
316 Reference< script::XLibraryContainer2 > xModLibContainer( m_aDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
317 if ( xModLibContainer.is() )
318 xModLibContainer->renameLibrary( aOldName, rNewName );
320 Reference< script::XLibraryContainer2 > xDlgLibContainer( m_aDocument.getLibraryContainer( E_DIALOGS ), UNO_QUERY );
321 if ( xDlgLibContainer.is() )
322 xDlgLibContainer->renameLibrary( aOldName, rNewName );
324 MarkDocumentModified( m_aDocument );
325 if (SfxBindings* pBindings = GetBindingsPtr())
327 pBindings->Invalidate( SID_BASICIDE_LIBSELECTOR );
328 pBindings->Update( SID_BASICIDE_LIBSELECTOR );
331 catch (const container::ElementExistException& )
333 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(GetFrameWeld(),
334 VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_SBXNAMEALLREADYUSED)));
335 xErrorBox->run();
336 return false;
338 catch (const container::NoSuchElementException& )
340 DBG_UNHANDLED_EXCEPTION("basctl.basicide");
341 return false;
345 if ( !bValid )
347 OUString sWarning(rNewName.getLength() > 30 ? IDEResId(RID_STR_LIBNAMETOLONG) : IDEResId(RID_STR_BADSBXNAME));
348 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(GetFrameWeld(),
349 VclMessageType::Warning, VclButtonsType::Ok, sWarning));
350 xErrorBox->run();
354 return bValid;
357 // NewObjectDialog
358 IMPL_LINK_NOARG(NewObjectDialog, OkButtonHandler, weld::Button&, void)
360 if (!m_bCheckName || IsValidSbxName(m_xEdit->get_text()))
361 m_xDialog->response(RET_OK);
362 else
364 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_xDialog.get(),
365 VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_BADSBXNAME)));
366 xErrorBox->run();
367 m_xEdit->grab_focus();
371 NewObjectDialog::NewObjectDialog(weld::Window * pParent, ObjectMode eMode, bool bCheckName)
372 : GenericDialogController(pParent, "modules/BasicIDE/ui/newlibdialog.ui", "NewLibDialog")
373 , m_xEdit(m_xBuilder->weld_entry("entry"))
374 , m_xOKButton(m_xBuilder->weld_button("ok"))
375 , m_bCheckName(bCheckName)
377 switch (eMode)
379 case ObjectMode::Library:
380 m_xDialog->set_title(IDEResId(RID_STR_NEWLIB));
381 break;
382 case ObjectMode::Module:
383 m_xDialog->set_title(IDEResId(RID_STR_NEWMOD));
384 break;
385 case ObjectMode::Dialog:
386 m_xDialog->set_title(IDEResId(RID_STR_NEWDLG));
387 break;
388 default:
389 assert(false);
391 m_xOKButton->connect_clicked(LINK(this, NewObjectDialog, OkButtonHandler));
394 // GotoLineDialog
395 GotoLineDialog::GotoLineDialog(weld::Window* pParent )
396 : GenericDialogController(pParent, "modules/BasicIDE/ui/gotolinedialog.ui", "GotoLineDialog")
397 , m_xEdit(m_xBuilder->weld_entry("entry"))
398 , m_xOKButton(m_xBuilder->weld_button("ok"))
400 m_xEdit->grab_focus();
401 m_xOKButton->connect_clicked(LINK(this, GotoLineDialog, OkButtonHandler));
404 GotoLineDialog::~GotoLineDialog()
408 sal_Int32 GotoLineDialog::GetLineNumber() const
410 return m_xEdit->get_text().toInt32();
413 IMPL_LINK_NOARG(GotoLineDialog, OkButtonHandler, weld::Button&, void)
415 if (GetLineNumber())
416 m_xDialog->response(RET_OK);
417 else
418 m_xEdit->select_region(0, -1);
421 // ExportDialog
422 IMPL_LINK_NOARG(ExportDialog, OkButtonHandler, weld::Button&, void)
424 m_bExportAsPackage = m_xExportAsPackageButton->get_active();
425 m_xDialog->response(RET_OK);
428 ExportDialog::ExportDialog(weld::Window * pParent)
429 : GenericDialogController(pParent, "modules/BasicIDE/ui/exportdialog.ui", "ExportDialog")
430 , m_bExportAsPackage(false)
431 , m_xExportAsPackageButton(m_xBuilder->weld_radio_button("extension"))
432 , m_xOKButton(m_xBuilder->weld_button("ok"))
434 m_xExportAsPackageButton->set_active(true);
435 m_xOKButton->connect_clicked(LINK(this, ExportDialog, OkButtonHandler));
438 ExportDialog::~ExportDialog()
442 // LibPage
443 LibPage::LibPage(vcl::Window * pParent)
444 : TabPage(pParent, "LibPage",
445 "modules/BasicIDE/ui/libpage.ui")
446 , m_aCurDocument(ScriptDocument::getApplicationScriptDocument())
447 , m_eCurLocation(LIBRARY_LOCATION_UNKNOWN)
449 get(m_pBasicsBox, "location");
450 get(m_pLibBox, "library");
451 Size aSize(m_pLibBox->LogicToPixel(Size(130, 87), MapMode(MapUnit::MapAppFont)));
452 m_pLibBox->set_height_request(aSize.Height());
453 m_pLibBox->set_width_request(aSize.Width());
454 get(m_pEditButton, "edit");
455 get(m_pPasswordButton, "password");
456 get(m_pNewLibButton, "new");
457 get(m_pInsertLibButton, "import");
458 get(m_pExportButton, "export");
459 get(m_pDelButton, "delete");
461 pTabDlg = nullptr;
463 m_pEditButton->SetClickHdl( LINK( this, LibPage, ButtonHdl ) );
464 m_pNewLibButton->SetClickHdl( LINK( this, LibPage, ButtonHdl ) );
465 m_pPasswordButton->SetClickHdl( LINK( this, LibPage, ButtonHdl ) );
466 m_pExportButton->SetClickHdl( LINK( this, LibPage, ButtonHdl ) );
467 m_pInsertLibButton->SetClickHdl( LINK( this, LibPage, ButtonHdl ) );
468 m_pDelButton->SetClickHdl( LINK( this, LibPage, ButtonHdl ) );
469 m_pLibBox->SetSelectHdl( LINK( this, LibPage, TreeListHighlightHdl ) );
471 m_pBasicsBox->SetSelectHdl( LINK( this, LibPage, BasicSelectHdl ) );
473 m_pLibBox->SetMode(ObjectMode::Module);
474 m_pLibBox->EnableInplaceEditing(true);
475 m_pLibBox->SetStyle( WB_HSCROLL | WB_BORDER | WB_TABSTOP );
477 long const aTabPositions[] = { 30, 120 };
478 m_pLibBox->SetTabs( SAL_N_ELEMENTS(aTabPositions), aTabPositions, MapUnit::MapPixel );
480 FillListBox();
481 m_pBasicsBox->SelectEntryPos( 0 );
482 SetCurLib();
484 CheckButtons();
487 LibPage::~LibPage()
489 disposeOnce();
492 void LibPage::dispose()
494 if (m_pBasicsBox)
496 const sal_Int32 nCount = m_pBasicsBox->GetEntryCount();
497 for ( sal_Int32 i = 0; i < nCount; ++i )
499 DocumentEntry* pEntry = static_cast<DocumentEntry*>(m_pBasicsBox->GetEntryData( i ));
500 delete pEntry;
503 m_pBasicsBox.clear();
504 m_pLibBox.clear();
505 m_pEditButton.clear();
506 m_pPasswordButton.clear();
507 m_pNewLibButton.clear();
508 m_pInsertLibButton.clear();
509 m_pExportButton.clear();
510 m_pDelButton.clear();
511 pTabDlg.clear();
512 TabPage::dispose();
515 void LibPage::CheckButtons()
517 SvTreeListEntry* pCur = m_pLibBox->GetCurEntry();
518 if ( pCur )
520 OUString aLibName = SvTabListBox::GetEntryText( pCur, 0 );
521 Reference< script::XLibraryContainer2 > xModLibContainer( m_aCurDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
522 Reference< script::XLibraryContainer2 > xDlgLibContainer( m_aCurDocument.getLibraryContainer( E_DIALOGS ), UNO_QUERY );
524 if ( m_eCurLocation == LIBRARY_LOCATION_SHARE )
526 m_pPasswordButton->Disable();
527 m_pNewLibButton->Disable();
528 m_pInsertLibButton->Disable();
529 m_pDelButton->Disable();
531 else if ( aLibName.equalsIgnoreAsciiCase( "Standard" ) )
533 m_pPasswordButton->Disable();
534 m_pNewLibButton->Enable();
535 m_pInsertLibButton->Enable();
536 m_pExportButton->Disable();
537 m_pDelButton->Disable();
539 else if ( ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) && xModLibContainer->isLibraryReadOnly( aLibName ) ) ||
540 ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) && xDlgLibContainer->isLibraryReadOnly( aLibName ) ) )
542 m_pPasswordButton->Disable();
543 m_pNewLibButton->Enable();
544 m_pInsertLibButton->Enable();
545 if ( ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) && xModLibContainer->isLibraryReadOnly( aLibName ) && !xModLibContainer->isLibraryLink( aLibName ) ) ||
546 ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) && xDlgLibContainer->isLibraryReadOnly( aLibName ) && !xDlgLibContainer->isLibraryLink( aLibName ) ) )
547 m_pDelButton->Disable();
548 else
549 m_pDelButton->Enable();
551 else
553 if ( xModLibContainer.is() && !xModLibContainer->hasByName( aLibName ) )
554 m_pPasswordButton->Disable();
555 else
556 m_pPasswordButton->Enable();
558 m_pNewLibButton->Enable();
559 m_pInsertLibButton->Enable();
560 m_pExportButton->Enable();
561 m_pDelButton->Enable();
566 void LibPage::ActivatePage()
568 SetCurLib();
571 void LibPage::DeactivatePage()
575 IMPL_LINK( LibPage, TreeListHighlightHdl, SvTreeListBox *, pBox, void )
577 if ( pBox->IsSelected( pBox->GetHdlEntry() ) )
578 CheckButtons();
581 IMPL_LINK_NOARG( LibPage, BasicSelectHdl, ListBox&, void )
583 SetCurLib();
584 CheckButtons();
587 IMPL_LINK( LibPage, ButtonHdl, Button *, pButton, void )
589 if (pButton == m_pEditButton)
591 SfxAllItemSet aArgs( SfxGetpApp()->GetPool() );
592 SfxRequest aRequest( SID_BASICIDE_APPEAR, SfxCallMode::SYNCHRON, aArgs );
593 SfxGetpApp()->ExecuteSlot( aRequest );
595 SfxUnoAnyItem aDocItem( SID_BASICIDE_ARG_DOCUMENT_MODEL, Any( m_aCurDocument.getDocumentOrNull() ) );
596 SvTreeListEntry* pCurEntry = m_pLibBox->GetCurEntry();
597 DBG_ASSERT( pCurEntry, "Entry?!" );
598 OUString aLibName( SvTabListBox::GetEntryText( pCurEntry, 0 ) );
599 SfxStringItem aLibNameItem( SID_BASICIDE_ARG_LIBNAME, aLibName );
600 if (SfxDispatcher* pDispatcher = GetDispatcher())
601 pDispatcher->ExecuteList( SID_BASICIDE_LIBSELECTED,
602 SfxCallMode::ASYNCHRON, { &aDocItem, &aLibNameItem });
603 EndTabDialog();
604 return;
606 else if (pButton == m_pNewLibButton)
607 NewLib();
608 else if (pButton == m_pInsertLibButton)
609 InsertLib();
610 else if (pButton == m_pExportButton)
611 Export();
612 else if (pButton == m_pDelButton)
613 DeleteCurrent();
614 else if (pButton == m_pPasswordButton)
616 SvTreeListEntry* pCurEntry = m_pLibBox->GetCurEntry();
617 OUString aLibName( SvTabListBox::GetEntryText( pCurEntry, 0 ) );
619 // load module library (if not loaded)
620 Reference< script::XLibraryContainer > xModLibContainer = m_aCurDocument.getLibraryContainer( E_SCRIPTS );
621 if ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) && !xModLibContainer->isLibraryLoaded( aLibName ) )
623 Shell* pShell = GetShell();
624 if (pShell)
625 pShell->GetViewFrame()->GetWindow().EnterWait();
626 xModLibContainer->loadLibrary( aLibName );
627 if (pShell)
628 pShell->GetViewFrame()->GetWindow().LeaveWait();
631 // load dialog library (if not loaded)
632 Reference< script::XLibraryContainer > xDlgLibContainer = m_aCurDocument.getLibraryContainer( E_DIALOGS );
633 if ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) && !xDlgLibContainer->isLibraryLoaded( aLibName ) )
635 Shell* pShell = GetShell();
636 if (pShell)
637 pShell->GetViewFrame()->GetWindow().EnterWait();
638 xDlgLibContainer->loadLibrary( aLibName );
639 if (pShell)
640 pShell->GetViewFrame()->GetWindow().LeaveWait();
643 // check, if library is password protected
644 if ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) )
646 Reference< script::XLibraryContainerPassword > xPasswd( xModLibContainer, UNO_QUERY );
647 if ( xPasswd.is() )
649 bool const bProtected = xPasswd->isLibraryPasswordProtected( aLibName );
651 // change password dialog
652 SvxPasswordDialog aDlg(GetFrameWeld(), !bProtected);
653 aDlg.SetCheckPasswordHdl(LINK(this, LibPage, CheckPasswordHdl));
655 if (aDlg.run() == RET_OK)
657 bool const bNewProtected = xPasswd->isLibraryPasswordProtected( aLibName );
659 if ( bNewProtected != bProtected )
661 sal_uLong nPos = m_pLibBox->GetModel()->GetAbsPos( pCurEntry );
662 m_pLibBox->GetModel()->Remove( pCurEntry );
663 ImpInsertLibEntry( aLibName, nPos );
664 m_pLibBox->SetCurEntry( m_pLibBox->GetEntry( nPos ) );
667 MarkDocumentModified( m_aCurDocument );
672 CheckButtons();
675 IMPL_LINK( LibPage, CheckPasswordHdl, SvxPasswordDialog *, pDlg, bool )
677 bool bRet = false;
679 SvTreeListEntry* pCurEntry = m_pLibBox->GetCurEntry();
680 OUString aLibName( SvTabListBox::GetEntryText( pCurEntry, 0 ) );
681 Reference< script::XLibraryContainerPassword > xPasswd( m_aCurDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
683 if ( xPasswd.is() )
687 OUString aOldPassword( pDlg->GetOldPassword() );
688 OUString aNewPassword( pDlg->GetNewPassword() );
689 xPasswd->changeLibraryPassword( aLibName, aOldPassword, aNewPassword );
690 bRet = true;
692 catch (...)
697 return bRet;
700 void LibPage::NewLib()
702 createLibImpl(GetFrameWeld(), m_aCurDocument, m_pLibBox, nullptr);
705 void LibPage::InsertLib()
707 Reference< uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
708 // file open dialog
709 sfx2::FileDialogHelper aDlg(ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE, FileDialogFlags::NONE, pTabDlg ? pTabDlg->GetFrameWeld() : nullptr);
710 Reference <XFilePicker3> xFP = aDlg.GetFilePicker();
712 xFP->setTitle(IDEResId(RID_STR_APPENDLIBS));
714 // filter
715 OUString aTitle(IDEResId(RID_STR_BASIC));
716 OUString aFilter;
717 aFilter = "*.sbl;*.xlc;*.xlb" // library files
718 ";*.sdw;*.sxw;*.odt" // text
719 ";*.vor;*.stw;*.ott" // text template
720 ";*.sgl;*.sxg;*.odm" // master document
721 ";*.oth" // html document template
722 ";*.sdc;*.sxc;*.ods" // spreadsheet
723 ";*.stc;*.ots" // spreadsheet template
724 ";*.sda;*.sxd;*.odg" // drawing
725 ";*.std;*.otg" // drawing template
726 ";*.sdd;*.sxi;*.odp" // presentation
727 ";*.sti;*.otp" // presentation template
728 ";*.sxm;*.odf"; // formula
729 xFP->appendFilter( aTitle, aFilter );
731 // set display directory and filter
732 OUString aPath(GetExtraData()->GetAddLibPath());
733 if ( !aPath.isEmpty() )
734 xFP->setDisplayDirectory( aPath );
735 else
737 // macro path from configuration management
738 xFP->setDisplayDirectory( SvtPathOptions().GetWorkPath() );
741 OUString aLastFilter(GetExtraData()->GetAddLibFilter());
742 if ( !aLastFilter.isEmpty() )
743 xFP->setCurrentFilter( aLastFilter );
744 else
745 xFP->setCurrentFilter( IDEResId(RID_STR_BASIC) );
747 if ( xFP->execute() == RET_OK )
749 GetExtraData()->SetAddLibPath( xFP->getDisplayDirectory() );
750 GetExtraData()->SetAddLibFilter( xFP->getCurrentFilter() );
752 // library containers for import
753 Reference< script::XLibraryContainer2 > xModLibContImport;
754 Reference< script::XLibraryContainer2 > xDlgLibContImport;
756 // file URLs
757 Sequence< OUString > aFiles = xFP->getSelectedFiles();
758 INetURLObject aURLObj( aFiles[0] );
759 INetURLObject aModURLObj( aURLObj );
760 INetURLObject aDlgURLObj( aURLObj );
762 OUString aBase = aURLObj.getBase();
763 OUString aModBase( "script" );
764 OUString aDlgBase( "dialog" );
766 if ( aBase == aModBase || aBase == aDlgBase )
768 aModURLObj.setBase( aModBase );
769 aDlgURLObj.setBase( aDlgBase );
772 Reference< XSimpleFileAccess3 > xSFA( SimpleFileAccess::create(comphelper::getProcessComponentContext()) );
774 OUString aModURL( aModURLObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
775 if ( xSFA->exists( aModURL ) )
777 xModLibContImport.set( script::DocumentScriptLibraryContainer::createWithURL(xContext, aModURL), UNO_QUERY );
780 OUString aDlgURL( aDlgURLObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
781 if ( xSFA->exists( aDlgURL ) )
783 xDlgLibContImport.set( script::DocumentDialogLibraryContainer::createWithURL(xContext, aDlgURL), UNO_QUERY );
786 if ( xModLibContImport.is() || xDlgLibContImport.is() )
788 VclPtr<LibDialog> pLibDlg;
790 Reference< script::XLibraryContainer > xModLibContImp( xModLibContImport, UNO_QUERY );
791 Reference< script::XLibraryContainer > xDlgLibContImp( xDlgLibContImport, UNO_QUERY );
792 Sequence< OUString > aLibNames = GetMergedLibraryNames( xModLibContImp, xDlgLibContImp );
793 sal_Int32 nLibCount = aLibNames.getLength();
794 const OUString* pLibNames = aLibNames.getConstArray();
795 for ( sal_Int32 i = 0 ; i < nLibCount ; i++ )
797 // library import dialog
798 if ( !pLibDlg )
800 pLibDlg.reset(VclPtr<LibDialog>::Create( this ));
801 pLibDlg->SetStorageName( aURLObj.getName() );
802 pLibDlg->GetLibBox().SetMode(ObjectMode::Library);
805 // libbox entries
806 OUString aLibName( pLibNames[ i ] );
807 if ( !( ( xModLibContImport.is() && xModLibContImport->hasByName( aLibName ) && xModLibContImport->isLibraryLink( aLibName ) ) ||
808 ( xDlgLibContImport.is() && xDlgLibContImport->hasByName( aLibName ) && xDlgLibContImport->isLibraryLink( aLibName ) ) ) )
810 SvTreeListEntry* pEntry = pLibDlg->GetLibBox().DoInsertEntry( aLibName );
811 sal_uInt16 nPos = static_cast<sal_uInt16>(pLibDlg->GetLibBox().GetModel()->GetAbsPos( pEntry ));
812 pLibDlg->GetLibBox().CheckEntryPos(nPos);
816 if ( !pLibDlg )
818 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(GetFrameWeld(),
819 VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_NOLIBINSTORAGE)));
820 xErrorBox->run();
822 else
824 bool bChanges = false;
825 OUString aExtension( aURLObj.getExtension() );
826 OUString aLibExtension( "xlb" );
827 OUString aContExtension( "xlc" );
829 // disable reference checkbox for documents and sbls
830 if ( aExtension != aLibExtension && aExtension != aContExtension )
831 pLibDlg->EnableReference(false);
833 if ( pLibDlg->Execute() )
835 sal_uLong nNewPos = m_pLibBox->GetEntryCount();
836 bool bRemove = false;
837 bool bReplace = pLibDlg->IsReplace();
838 bool bReference = pLibDlg->IsReference();
839 for ( sal_uLong nLib = 0; nLib < pLibDlg->GetLibBox().GetEntryCount(); nLib++ )
841 if ( pLibDlg->GetLibBox().IsChecked( nLib ) )
843 SvTreeListEntry* pEntry = pLibDlg->GetLibBox().GetEntry( nLib );
844 DBG_ASSERT( pEntry, "Entry?!" );
845 OUString aLibName( SvTabListBox::GetEntryText( pEntry, 0 ) );
846 Reference< script::XLibraryContainer2 > xModLibContainer( m_aCurDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
847 Reference< script::XLibraryContainer2 > xDlgLibContainer( m_aCurDocument.getLibraryContainer( E_DIALOGS ), UNO_QUERY );
849 // check, if the library is already existing
850 if ( ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) ) ||
851 ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) ) )
853 if ( bReplace )
855 // check, if the library is the Standard library
856 if ( aLibName == "Standard" )
858 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(GetFrameWeld(),
859 VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_REPLACESTDLIB)));
860 xErrorBox->run();
861 continue;
864 // check, if the library is readonly and not a link
865 if ( ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) && xModLibContainer->isLibraryReadOnly( aLibName ) && !xModLibContainer->isLibraryLink( aLibName ) ) ||
866 ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) && xDlgLibContainer->isLibraryReadOnly( aLibName ) && !xDlgLibContainer->isLibraryLink( aLibName ) ) )
868 OUString aErrStr( IDEResId(RID_STR_REPLACELIB) );
869 aErrStr = aErrStr.replaceAll("XX", aLibName) + "\n" + IDEResId(RID_STR_LIBISREADONLY);
870 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(GetFrameWeld(),
871 VclMessageType::Warning, VclButtonsType::Ok, aErrStr));
872 xErrorBox->run();
873 continue;
876 // remove existing libraries
877 bRemove = true;
879 else
881 OUString aErrStr;
882 if ( bReference )
883 aErrStr = IDEResId(RID_STR_REFNOTPOSSIBLE);
884 else
885 aErrStr = IDEResId(RID_STR_IMPORTNOTPOSSIBLE);
886 aErrStr = aErrStr.replaceAll("XX", aLibName) + "\n" +IDEResId(RID_STR_SBXNAMEALLREADYUSED);
887 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(GetFrameWeld(),
888 VclMessageType::Warning, VclButtonsType::Ok, aErrStr));
889 xErrorBox->run();
890 continue;
894 // check, if the library is password protected
895 bool bOK = false;
896 OUString aPassword;
897 if ( xModLibContImport.is() && xModLibContImport->hasByName( aLibName ) )
899 Reference< script::XLibraryContainerPassword > xPasswd( xModLibContImport, UNO_QUERY );
900 if ( xPasswd.is() && xPasswd->isLibraryPasswordProtected( aLibName ) && !xPasswd->isLibraryPasswordVerified( aLibName ) && !bReference )
902 bOK = QueryPassword( xModLibContImp, aLibName, aPassword, true, true );
904 if ( !bOK )
906 OUString aErrStr( IDEResId(RID_STR_NOIMPORT) );
907 aErrStr = aErrStr.replaceAll("XX", aLibName);
908 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(GetFrameWeld(),
909 VclMessageType::Warning, VclButtonsType::Ok, aErrStr));
910 xErrorBox->run();
911 continue;
916 // remove existing libraries
917 if ( bRemove )
919 // remove listbox entry
920 SvTreeListEntry* pEntry_ = m_pLibBox->FindEntry( aLibName );
921 if ( pEntry_ )
922 m_pLibBox->SvTreeListBox::GetModel()->Remove( pEntry_ );
924 // remove module library
925 if ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) )
926 xModLibContainer->removeLibrary( aLibName );
928 // remove dialog library
929 if ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) )
930 xDlgLibContainer->removeLibrary( aLibName );
933 // copy module library
934 if ( xModLibContImport.is() && xModLibContImport->hasByName( aLibName ) && xModLibContainer.is() && !xModLibContainer->hasByName( aLibName ) )
936 Reference< container::XNameContainer > xModLib;
937 if ( bReference )
939 // storage URL
940 INetURLObject aModStorageURLObj( aModURLObj );
941 if ( aExtension == aContExtension )
943 sal_Int32 nCount = aModStorageURLObj.getSegmentCount();
944 aModStorageURLObj.insertName( aLibName, false, nCount-1 );
945 aModStorageURLObj.setExtension( aLibExtension );
946 aModStorageURLObj.setFinalSlash();
948 OUString aModStorageURL( aModStorageURLObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
950 // create library link
951 xModLib.set( xModLibContainer->createLibraryLink( aLibName, aModStorageURL, true ), UNO_QUERY);
953 else
955 // create library
956 xModLib = xModLibContainer->createLibrary( aLibName );
957 if ( xModLib.is() )
959 // get import library
960 Reference< container::XNameContainer > xModLibImport;
961 Any aElement = xModLibContImport->getByName( aLibName );
962 aElement >>= xModLibImport;
964 if ( xModLibImport.is() )
966 // load library
967 if ( !xModLibContImport->isLibraryLoaded( aLibName ) )
968 xModLibContImport->loadLibrary( aLibName );
970 // copy all modules
971 Sequence< OUString > aModNames = xModLibImport->getElementNames();
972 sal_Int32 nModCount = aModNames.getLength();
973 const OUString* pModNames = aModNames.getConstArray();
974 for ( sal_Int32 i = 0 ; i < nModCount ; i++ )
976 OUString aModName( pModNames[ i ] );
977 Any aElement_ = xModLibImport->getByName( aModName );
978 xModLib->insertByName( aModName, aElement_ );
981 // set password
982 if ( bOK )
984 Reference< script::XLibraryContainerPassword > xPasswd( xModLibContainer, UNO_QUERY );
985 if ( xPasswd.is() )
989 xPasswd->changeLibraryPassword( aLibName, OUString(), aPassword );
991 catch (...)
1001 // copy dialog library
1002 if ( xDlgLibContImport.is() && xDlgLibContImport->hasByName( aLibName ) && xDlgLibContainer.is() && !xDlgLibContainer->hasByName( aLibName ) )
1004 Reference< container::XNameContainer > xDlgLib;
1005 if ( bReference )
1007 // storage URL
1008 INetURLObject aDlgStorageURLObj( aDlgURLObj );
1009 if ( aExtension == aContExtension )
1011 sal_Int32 nCount = aDlgStorageURLObj.getSegmentCount();
1012 aDlgStorageURLObj.insertName( aLibName, false, nCount - 1 );
1013 aDlgStorageURLObj.setExtension( aLibExtension );
1014 aDlgStorageURLObj.setFinalSlash();
1016 OUString aDlgStorageURL( aDlgStorageURLObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
1018 // create library link
1019 xDlgLib.set( xDlgLibContainer->createLibraryLink( aLibName, aDlgStorageURL, true ), UNO_QUERY);
1021 else
1023 // create library
1024 xDlgLib = xDlgLibContainer->createLibrary( aLibName );
1025 if ( xDlgLib.is() )
1027 // get import library
1028 Reference< container::XNameContainer > xDlgLibImport;
1029 Any aElement = xDlgLibContImport->getByName( aLibName );
1030 aElement >>= xDlgLibImport;
1032 if ( xDlgLibImport.is() )
1034 // load library
1035 if ( !xDlgLibContImport->isLibraryLoaded( aLibName ) )
1036 xDlgLibContImport->loadLibrary( aLibName );
1038 // copy all dialogs
1039 Sequence< OUString > aDlgNames = xDlgLibImport->getElementNames();
1040 sal_Int32 nDlgCount = aDlgNames.getLength();
1041 const OUString* pDlgNames = aDlgNames.getConstArray();
1042 for ( sal_Int32 i = 0 ; i < nDlgCount ; i++ )
1044 OUString aDlgName( pDlgNames[ i ] );
1045 Any aElement_ = xDlgLibImport->getByName( aDlgName );
1046 xDlgLib->insertByName( aDlgName, aElement_ );
1053 // insert listbox entry
1054 ImpInsertLibEntry( aLibName, m_pLibBox->GetEntryCount() );
1055 bChanges = true;
1059 SvTreeListEntry* pFirstNew = m_pLibBox->GetEntry( nNewPos );
1060 if ( pFirstNew )
1061 m_pLibBox->SetCurEntry( pFirstNew );
1064 pLibDlg.reset();
1065 if ( bChanges )
1066 MarkDocumentModified( m_aCurDocument );
1072 void LibPage::Export()
1074 SvTreeListEntry* pCurEntry = m_pLibBox->GetCurEntry();
1075 OUString aLibName( SvTabListBox::GetEntryText( pCurEntry, 0 ) );
1077 // Password verification
1078 Reference< script::XLibraryContainer2 > xModLibContainer( m_aCurDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
1080 if ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) && !xModLibContainer->isLibraryLoaded( aLibName ) )
1082 bool bOK = true;
1084 // check password
1085 Reference< script::XLibraryContainerPassword > xPasswd( xModLibContainer, UNO_QUERY );
1086 if ( xPasswd.is() && xPasswd->isLibraryPasswordProtected( aLibName ) && !xPasswd->isLibraryPasswordVerified( aLibName ) )
1088 OUString aPassword;
1089 Reference< script::XLibraryContainer > xModLibContainer1( xModLibContainer, UNO_QUERY );
1090 bOK = QueryPassword( xModLibContainer1, aLibName, aPassword );
1092 if ( !bOK )
1093 return;
1096 std::unique_ptr<ExportDialog> xNewDlg(new ExportDialog(GetFrameWeld()));
1097 if (xNewDlg->run() == RET_OK)
1101 bool bExportAsPackage = xNewDlg->isExportAsPackage();
1102 //tdf#112063 ensure closing xNewDlg is not selected as
1103 //parent of file dialog from ExportAs...
1104 xNewDlg.reset();
1105 if (bExportAsPackage)
1106 ExportAsPackage( aLibName );
1107 else
1108 ExportAsBasic( aLibName );
1110 catch(const util::VetoException& ) // user canceled operation
1116 void LibPage::implExportLib( const OUString& aLibName, const OUString& aTargetURL,
1117 const Reference< task::XInteractionHandler >& Handler )
1119 Reference< script::XLibraryContainerExport > xModLibContainerExport
1120 ( m_aCurDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
1121 Reference< script::XLibraryContainerExport > xDlgLibContainerExport
1122 ( m_aCurDocument.getLibraryContainer( E_DIALOGS ), UNO_QUERY );
1123 if ( xModLibContainerExport.is() )
1124 xModLibContainerExport->exportLibrary( aLibName, aTargetURL, Handler );
1126 if (!xDlgLibContainerExport.is())
1127 return;
1128 Reference<container::XNameAccess> xNameAcc(xDlgLibContainerExport, UNO_QUERY);
1129 if (!xNameAcc.is())
1130 return;
1131 if (!xNameAcc->hasByName(aLibName))
1132 return;
1133 xDlgLibContainerExport->exportLibrary(aLibName, aTargetURL, Handler);
1136 // Implementation XCommandEnvironment
1138 class OLibCommandEnvironment : public cppu::WeakImplHelper< XCommandEnvironment >
1140 Reference< task::XInteractionHandler > mxInteraction;
1142 public:
1143 explicit OLibCommandEnvironment(const Reference<task::XInteractionHandler>& xInteraction)
1144 : mxInteraction( xInteraction )
1147 // Methods
1148 virtual Reference< task::XInteractionHandler > SAL_CALL getInteractionHandler() override;
1149 virtual Reference< XProgressHandler > SAL_CALL getProgressHandler() override;
1152 Reference< task::XInteractionHandler > OLibCommandEnvironment::getInteractionHandler()
1154 return mxInteraction;
1157 Reference< XProgressHandler > OLibCommandEnvironment::getProgressHandler()
1159 Reference< XProgressHandler > xRet;
1160 return xRet;
1163 void LibPage::ExportAsPackage( const OUString& aLibName )
1165 // file open dialog
1166 sfx2::FileDialogHelper aDlg(ui::dialogs::TemplateDescription::FILESAVE_SIMPLE, FileDialogFlags::NONE, pTabDlg ? pTabDlg->GetFrameWeld() : nullptr);
1167 Reference <XFilePicker3> xFP = aDlg.GetFilePicker();
1169 Reference< uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
1170 Reference< task::XInteractionHandler2 > xHandler( task::InteractionHandler::createWithParent(xContext, nullptr) );
1171 Reference< XSimpleFileAccess3 > xSFA = SimpleFileAccess::create(xContext);
1173 xFP->setTitle(IDEResId(RID_STR_EXPORTPACKAGE));
1175 // filter
1176 OUString aTitle(IDEResId(RID_STR_PACKAGE_BUNDLE));
1177 OUString aFilter;
1178 aFilter = "*.oxt" ; // library files
1179 xFP->appendFilter( aTitle, aFilter );
1181 // set display directory and filter
1182 OUString aPath = GetExtraData()->GetAddLibPath();
1183 if ( !aPath.isEmpty() )
1185 xFP->setDisplayDirectory( aPath );
1187 else
1189 // macro path from configuration management
1190 xFP->setDisplayDirectory( SvtPathOptions().GetWorkPath() );
1192 xFP->setCurrentFilter( aTitle );
1194 if ( xFP->execute() == RET_OK )
1196 GetExtraData()->SetAddLibPath(xFP->getDisplayDirectory());
1198 Sequence< OUString > aFiles = xFP->getSelectedFiles();
1199 INetURLObject aURL( aFiles[0] );
1200 if( aURL.getExtension().isEmpty() )
1201 aURL.setExtension( "oxt" );
1203 OUString aPackageURL( aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
1205 OUString aTmpPath = SvtPathOptions().GetTempPath();
1206 INetURLObject aInetObj( aTmpPath );
1207 aInetObj.insertName( aLibName, true, INetURLObject::LAST_SEGMENT, INetURLObject::EncodeMechanism::All );
1208 OUString aSourcePath = aInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
1209 if( xSFA->exists( aSourcePath ) )
1210 xSFA->kill( aSourcePath );
1211 Reference< task::XInteractionHandler > xDummyHandler( new DummyInteractionHandler( xHandler ) );
1212 implExportLib( aLibName, aTmpPath, xDummyHandler );
1214 Reference< XCommandEnvironment > xCmdEnv =
1215 static_cast<XCommandEnvironment*>(
1216 new OLibCommandEnvironment(
1217 Reference< task::XInteractionHandler >(
1218 xHandler, UNO_QUERY ) ) );
1220 ::ucbhelper::Content sourceContent( aSourcePath, xCmdEnv, comphelper::getProcessComponentContext() );
1222 OUString destFolder = "vnd.sun.star.zip://" +
1223 ::rtl::Uri::encode( aPackageURL,
1224 rtl_UriCharClassRegName,
1225 rtl_UriEncodeIgnoreEscapes,
1226 RTL_TEXTENCODING_UTF8 ) +
1227 "/";
1229 if( xSFA->exists( aPackageURL ) )
1230 xSFA->kill( aPackageURL );
1232 ::ucbhelper::Content destFolderContent( destFolder, xCmdEnv, comphelper::getProcessComponentContext() );
1233 destFolderContent.transferContent(
1234 sourceContent, ::ucbhelper::InsertOperation::Copy,
1235 OUString(), NameClash::OVERWRITE );
1237 INetURLObject aMetaInfInetObj( aTmpPath );
1238 aMetaInfInetObj.insertName( "META-INF",
1239 true, INetURLObject::LAST_SEGMENT, INetURLObject::EncodeMechanism::All );
1240 OUString aMetaInfFolder = aMetaInfInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
1241 if( xSFA->exists( aMetaInfFolder ) )
1242 xSFA->kill( aMetaInfFolder );
1243 xSFA->createFolder( aMetaInfFolder );
1245 std::vector< Sequence<beans::PropertyValue> > manifest;
1246 const OUString strMediaType = "MediaType" ;
1247 const OUString strFullPath = "FullPath" ;
1248 const OUString strBasicMediaType = "application/vnd.sun.star.basic-library" ;
1250 OUString fullPath = aLibName
1251 + "/" ;
1252 auto attribs(::comphelper::InitPropertySequence({
1253 { strFullPath, Any(fullPath) },
1254 { strMediaType, Any(strBasicMediaType) }
1255 }));
1256 manifest.push_back( attribs );
1258 // write into pipe:
1259 Reference<packages::manifest::XManifestWriter> xManifestWriter = packages::manifest::ManifestWriter::create( xContext );
1260 Reference<io::XOutputStream> xPipe( io::Pipe::create( xContext ), UNO_QUERY_THROW );
1261 xManifestWriter->writeManifestSequence(
1262 xPipe, Sequence< Sequence<beans::PropertyValue> >(
1263 &manifest[ 0 ], manifest.size() ) );
1265 aMetaInfInetObj.insertName( "manifest.xml",
1266 true, INetURLObject::LAST_SEGMENT, INetURLObject::EncodeMechanism::All );
1268 // write buffered pipe data to content:
1269 ::ucbhelper::Content manifestContent( aMetaInfInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ), xCmdEnv, comphelper::getProcessComponentContext() );
1270 manifestContent.writeStream( Reference<io::XInputStream>( xPipe, UNO_QUERY_THROW ), true );
1272 ::ucbhelper::Content MetaInfContent( aMetaInfFolder, xCmdEnv, comphelper::getProcessComponentContext() );
1273 destFolderContent.transferContent(
1274 MetaInfContent, ::ucbhelper::InsertOperation::Copy,
1275 OUString(), NameClash::OVERWRITE );
1277 if( xSFA->exists( aSourcePath ) )
1278 xSFA->kill( aSourcePath );
1279 if( xSFA->exists( aMetaInfFolder ) )
1280 xSFA->kill( aMetaInfFolder );
1284 void LibPage::ExportAsBasic( const OUString& aLibName )
1286 // Folder picker
1287 Reference< uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
1288 Reference< XFolderPicker2 > xFolderPicker = FolderPicker::create(xContext);
1289 Reference< task::XInteractionHandler2 > xHandler( task::InteractionHandler::createWithParent(xContext, nullptr) );
1291 xFolderPicker->setTitle(IDEResId(RID_STR_EXPORTBASIC));
1293 // set display directory and filter
1294 OUString aPath =GetExtraData()->GetAddLibPath();
1295 if( aPath.isEmpty() )
1296 aPath = SvtPathOptions().GetWorkPath();
1298 // INetURLObject aURL(m_sSavePath, INetProtocol::File);
1299 xFolderPicker->setDisplayDirectory( aPath );
1300 short nRet = xFolderPicker->execute();
1301 if( nRet == RET_OK )
1303 OUString aTargetURL = xFolderPicker->getDirectory();
1304 GetExtraData()->SetAddLibPath(aTargetURL);
1306 Reference< task::XInteractionHandler > xDummyHandler( new DummyInteractionHandler( xHandler ) );
1307 implExportLib( aLibName, aTargetURL, xDummyHandler );
1311 void LibPage::DeleteCurrent()
1313 SvTreeListEntry* pCurEntry = m_pLibBox->GetCurEntry();
1314 OUString aLibName( SvTabListBox::GetEntryText( pCurEntry, 0 ) );
1316 // check, if library is link
1317 bool bIsLibraryLink = false;
1318 Reference< script::XLibraryContainer2 > xModLibContainer( m_aCurDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
1319 Reference< script::XLibraryContainer2 > xDlgLibContainer( m_aCurDocument.getLibraryContainer( E_DIALOGS ), UNO_QUERY );
1320 if ( ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) && xModLibContainer->isLibraryLink( aLibName ) ) ||
1321 ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) && xDlgLibContainer->isLibraryLink( aLibName ) ) )
1323 bIsLibraryLink = true;
1326 if (QueryDelLib(aLibName, bIsLibraryLink, GetFrameWeld()))
1328 // inform BasicIDE
1329 SfxUnoAnyItem aDocItem( SID_BASICIDE_ARG_DOCUMENT_MODEL, Any( m_aCurDocument.getDocumentOrNull() ) );
1330 SfxStringItem aLibNameItem( SID_BASICIDE_ARG_LIBNAME, aLibName );
1331 if (SfxDispatcher* pDispatcher = GetDispatcher())
1332 pDispatcher->ExecuteList(SID_BASICIDE_LIBREMOVED,
1333 SfxCallMode::SYNCHRON, { &aDocItem, &aLibNameItem });
1335 // remove library from module and dialog library containers
1336 if ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) )
1337 xModLibContainer->removeLibrary( aLibName );
1338 if ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) )
1339 xDlgLibContainer->removeLibrary( aLibName );
1341 static_cast<SvTreeListBox&>(*m_pLibBox).GetModel()->Remove( pCurEntry );
1342 MarkDocumentModified( m_aCurDocument );
1346 void LibPage::EndTabDialog()
1348 DBG_ASSERT( pTabDlg, "TabDlg not set!" );
1349 if ( pTabDlg )
1350 pTabDlg->EndDialog( 1 );
1353 void LibPage::FillListBox()
1355 InsertListBoxEntry( ScriptDocument::getApplicationScriptDocument(), LIBRARY_LOCATION_USER );
1356 InsertListBoxEntry( ScriptDocument::getApplicationScriptDocument(), LIBRARY_LOCATION_SHARE );
1358 ScriptDocuments aDocuments( ScriptDocument::getAllScriptDocuments( ScriptDocument::DocumentsSorted ) );
1359 for (auto const& doc : aDocuments)
1361 InsertListBoxEntry( doc, LIBRARY_LOCATION_DOCUMENT );
1365 void LibPage::InsertListBoxEntry( const ScriptDocument& rDocument, LibraryLocation eLocation )
1367 OUString aEntryText( rDocument.getTitle( eLocation ) );
1368 const sal_Int32 nPos = m_pBasicsBox->InsertEntry( aEntryText );
1369 m_pBasicsBox->SetEntryData( nPos, new DocumentEntry(rDocument, eLocation) );
1372 void LibPage::SetCurLib()
1374 const sal_Int32 nSelPos = m_pBasicsBox->GetSelectedEntryPos();
1375 DocumentEntry* pEntry = static_cast<DocumentEntry*>(m_pBasicsBox->GetEntryData( nSelPos ));
1376 if ( pEntry )
1378 ScriptDocument aDocument( pEntry->GetDocument() );
1379 DBG_ASSERT( aDocument.isAlive(), "LibPage::SetCurLib: no document, or document is dead!" );
1380 if ( !aDocument.isAlive() )
1381 return;
1382 LibraryLocation eLocation = pEntry->GetLocation();
1383 if ( aDocument != m_aCurDocument || eLocation != m_eCurLocation )
1385 m_aCurDocument = aDocument;
1386 m_eCurLocation = eLocation;
1387 m_pLibBox->SetDocument( aDocument );
1388 m_pLibBox->Clear();
1390 // get a sorted list of library names
1391 Sequence< OUString > aLibNames = aDocument.getLibraryNames();
1392 sal_Int32 nLibCount = aLibNames.getLength();
1393 const OUString* pLibNames = aLibNames.getConstArray();
1395 for ( sal_Int32 i = 0 ; i < nLibCount ; i++ )
1397 OUString aLibName( pLibNames[ i ] );
1398 if ( eLocation == aDocument.getLibraryLocation( aLibName ) )
1399 ImpInsertLibEntry( aLibName, i );
1402 SvTreeListEntry* pEntry_ = m_pLibBox->FindEntry( "Standard" );
1403 if ( !pEntry_ )
1404 pEntry_ = m_pLibBox->GetEntry( 0 );
1405 m_pLibBox->SetCurEntry( pEntry_ );
1410 SvTreeListEntry* LibPage::ImpInsertLibEntry( const OUString& rLibName, sal_uLong nPos )
1412 // check, if library is password protected
1413 bool bProtected = false;
1414 Reference< script::XLibraryContainer2 > xModLibContainer( m_aCurDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
1415 if ( xModLibContainer.is() && xModLibContainer->hasByName( rLibName ) )
1417 Reference< script::XLibraryContainerPassword > xPasswd( xModLibContainer, UNO_QUERY );
1418 if ( xPasswd.is() )
1420 bProtected = xPasswd->isLibraryPasswordProtected( rLibName );
1424 SvTreeListEntry* pNewEntry = m_pLibBox->DoInsertEntry( rLibName, nPos );
1425 pNewEntry->SetUserData( new LibUserData(m_aCurDocument) );
1427 if (bProtected)
1429 Image aImage(BitmapEx(RID_BMP_LOCKED));
1430 m_pLibBox->SetExpandedEntryBmp(pNewEntry, aImage);
1431 m_pLibBox->SetCollapsedEntryBmp(pNewEntry, aImage);
1434 // check, if library is link
1435 if ( xModLibContainer.is() && xModLibContainer->hasByName( rLibName ) && xModLibContainer->isLibraryLink( rLibName ) )
1437 OUString aLinkURL = xModLibContainer->getLibraryLinkURL( rLibName );
1438 m_pLibBox->SetEntryText( aLinkURL, pNewEntry, 1 );
1441 return pNewEntry;
1444 // Helper function
1445 void createLibImpl(weld::Window* pWin, const ScriptDocument& rDocument,
1446 CheckBox* pLibBox, TreeListBox* pBasicBox)
1448 OSL_ENSURE( rDocument.isAlive(), "createLibImpl: invalid document!" );
1449 if ( !rDocument.isAlive() )
1450 return;
1452 // create library name
1453 OUString aLibName;
1454 bool bValid = false;
1455 sal_Int32 i = 1;
1456 while ( !bValid )
1458 aLibName = "Library" + OUString::number( i );
1459 if ( !rDocument.hasLibrary( E_SCRIPTS, aLibName ) && !rDocument.hasLibrary( E_DIALOGS, aLibName ) )
1460 bValid = true;
1461 i++;
1464 NewObjectDialog aNewDlg(pWin, ObjectMode::Library);
1465 aNewDlg.SetObjectName(aLibName);
1467 if (aNewDlg.run())
1469 if (!aNewDlg.GetObjectName().isEmpty())
1470 aLibName = aNewDlg.GetObjectName();
1472 if ( aLibName.getLength() > 30 )
1474 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(pWin,
1475 VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_LIBNAMETOLONG)));
1476 xErrorBox->run();
1478 else if ( !IsValidSbxName( aLibName ) )
1480 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(pWin,
1481 VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_BADSBXNAME)));
1482 xErrorBox->run();
1484 else if ( rDocument.hasLibrary( E_SCRIPTS, aLibName ) || rDocument.hasLibrary( E_DIALOGS, aLibName ) )
1486 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(pWin,
1487 VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_SBXNAMEALLREADYUSED2)));
1488 xErrorBox->run();
1490 else
1494 // create module and dialog library
1495 Reference< container::XNameContainer > xModLib( rDocument.getOrCreateLibrary( E_SCRIPTS, aLibName ) );
1496 Reference< container::XNameContainer > xDlgLib( rDocument.getOrCreateLibrary( E_DIALOGS, aLibName ) );
1498 if( pLibBox )
1500 SvTreeListEntry* pEntry = pLibBox->DoInsertEntry( aLibName );
1501 pEntry->SetUserData( new LibUserData( rDocument ) );
1502 pLibBox->SetCurEntry( pEntry );
1505 // create a module
1506 OUString aModName = rDocument.createObjectName( E_SCRIPTS, aLibName );
1507 OUString sModuleCode;
1508 if ( !rDocument.createModule( aLibName, aModName, true, sModuleCode ) )
1509 throw Exception("could not create module " + aModName, nullptr);
1511 SbxItem aSbxItem( SID_BASICIDE_ARG_SBX, rDocument, aLibName, aModName, TYPE_MODULE );
1512 if (SfxDispatcher* pDispatcher = GetDispatcher())
1513 pDispatcher->ExecuteList(SID_BASICIDE_SBXINSERTED,
1514 SfxCallMode::SYNCHRON, { &aSbxItem });
1516 if( pBasicBox )
1518 SvTreeListEntry* pEntry = pBasicBox->GetCurEntry();
1519 SvTreeListEntry* pRootEntry = nullptr;
1520 while( pEntry )
1522 pRootEntry = pEntry;
1523 pEntry = pBasicBox->GetParent( pEntry );
1526 BrowseMode nMode = pBasicBox->GetMode();
1527 bool bDlgMode = ( nMode & BrowseMode::Dialogs ) && !( nMode & BrowseMode::Modules );
1528 const OUString sId = bDlgMode ? OUStringLiteral(RID_BMP_DLGLIB) : OUStringLiteral(RID_BMP_MODLIB);
1529 SvTreeListEntry* pNewLibEntry = pBasicBox->AddEntry(
1530 aLibName,
1531 Image(BitmapEx(sId)),
1532 pRootEntry, false,
1533 o3tl::make_unique<Entry>(OBJ_TYPE_LIBRARY));
1534 DBG_ASSERT( pNewLibEntry, "Insert entry failed!" );
1536 if( pNewLibEntry )
1538 SvTreeListEntry* pEntry_ = pBasicBox->AddEntry(
1539 aModName,
1540 Image(BitmapEx(RID_BMP_MODULE)),
1541 pNewLibEntry, false,
1542 o3tl::make_unique<Entry>(OBJ_TYPE_MODULE));
1543 DBG_ASSERT( pEntry_, "Insert entry failed!" );
1544 pBasicBox->SetCurEntry( pEntry_ );
1545 pBasicBox->Select( pBasicBox->GetCurEntry() ); // OV-Bug?!
1549 catch (const uno::Exception& )
1551 DBG_UNHANDLED_EXCEPTION("basctl.basicide");
1556 } // namespace basctl
1558 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */