LibreOffice Module basctl (master) 1
moduldl2.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20
21#include "moduldlg.hxx"
22#include <basidesh.hxx>
23#include <strings.hrc>
24#include <bitmaps.hlst>
25#include <iderdll.hxx>
26#include "iderdll2.hxx"
27#include <iderid.hxx>
28#include <basobj.hxx>
29#include <svx/passwd.hxx>
30#include <ucbhelper/content.hxx>
31#include <rtl/uri.hxx>
32#include <sfx2/app.hxx>
33#include <sfx2/dispatch.hxx>
35#include <sfx2/request.hxx>
36#include <sfx2/sfxsids.hrc>
37#include <sfx2/viewfrm.hxx>
38#include <svl/stritem.hxx>
39#include <tools/debug.hxx>
40#include <tools/urlobj.hxx>
42#include <vcl/svapp.hxx>
43#include <vcl/weld.hxx>
44
45#include <com/sun/star/io/Pipe.hpp>
46#include <com/sun/star/ui/dialogs/XFilePicker3.hpp>
47#include <com/sun/star/ui/dialogs/XFolderPicker2.hpp>
48#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
49#include <com/sun/star/script/DocumentScriptLibraryContainer.hpp>
50#include <com/sun/star/script/DocumentDialogLibraryContainer.hpp>
51#include <com/sun/star/script/XLibraryContainerPassword.hpp>
52#include <com/sun/star/script/XLibraryContainerExport.hpp>
53#include <com/sun/star/task/InteractionHandler.hpp>
54#include <com/sun/star/ucb/SimpleFileAccess.hpp>
55#include <com/sun/star/ucb/XCommandEnvironment.hpp>
56#include <com/sun/star/ucb/NameClash.hpp>
57#include <com/sun/star/packages/manifest/ManifestWriter.hpp>
59
60#include <com/sun/star/util/VetoException.hpp>
61#include <com/sun/star/script/ModuleSizeExceededRequest.hpp>
62
66#include <o3tl/string_view.hxx>
67
68#include <cassert>
69
70namespace basctl
71{
72
73using namespace ::com::sun::star;
74using namespace ::com::sun::star::uno;
75using namespace ::com::sun::star::lang;
76using namespace ::com::sun::star::ucb;
77using namespace ::com::sun::star::ui::dialogs;
78
79namespace
80{
81
82class DummyInteractionHandler : public ::cppu::WeakImplHelper< task::XInteractionHandler >
83{
84 Reference< task::XInteractionHandler2 > m_xHandler;
85public:
86 explicit DummyInteractionHandler(const Reference<task::XInteractionHandler2>& xHandler)
87 : m_xHandler(xHandler)
88 {
89 }
90
91 virtual void SAL_CALL handle( const Reference< task::XInteractionRequest >& rRequest ) override
92 {
93 if ( m_xHandler.is() )
94 {
95 script::ModuleSizeExceededRequest aModSizeException;
96 if ( rRequest->getRequest() >>= aModSizeException )
97 m_xHandler->handle( rRequest );
98 }
99 }
100};
101
102} // namespace
103
104namespace
105{
106 int FindEntry(const weld::TreeView& rBox, std::u16string_view rName)
107 {
108 int nCount = rBox.n_children();
109 for (int i = 0; i < nCount; ++i)
110 {
111 if (o3tl::equalsIgnoreAsciiCase(rName, rBox.get_text(i, 0)))
112 return i;
113 }
114 return -1;
115 }
116}
117
118// NewObjectDialog
120{
121 if (!m_bCheckName || IsValidSbxName(m_xEdit->get_text()))
122 m_xDialog->response(RET_OK);
123 else
124 {
125 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_xDialog.get(),
126 VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_BADSBXNAME)));
127 xErrorBox->run();
128 m_xEdit->grab_focus();
129 }
130}
131
133 : GenericDialogController(pParent, "modules/BasicIDE/ui/newlibdialog.ui", "NewLibDialog")
134 , m_xEdit(m_xBuilder->weld_entry("entry"))
135 , m_xOKButton(m_xBuilder->weld_button("ok"))
136 , m_bCheckName(bCheckName)
137{
138 switch (eMode)
139 {
141 m_xDialog->set_title(IDEResId(RID_STR_NEWLIB));
142 break;
144 m_xDialog->set_title(IDEResId(RID_STR_NEWMOD));
145 break;
147 m_xDialog->set_title(IDEResId(RID_STR_NEWDLG));
148 break;
149 default:
150 assert(false);
151 }
152 m_xOKButton->connect_clicked(LINK(this, NewObjectDialog, OkButtonHandler));
153}
154
155// GotoLineDialog
157 : GenericDialogController(pParent, "modules/BasicIDE/ui/gotolinedialog.ui", "GotoLineDialog")
158 , m_xEdit(m_xBuilder->weld_entry("entry"))
159 , m_xOKButton(m_xBuilder->weld_button("ok"))
160{
161 m_xEdit->grab_focus();
162 m_xOKButton->connect_clicked(LINK(this, GotoLineDialog, OkButtonHandler));
163}
164
166{
167}
168
170{
171 return m_xEdit->get_text().toInt32();
172}
173
175{
176 if (GetLineNumber())
177 m_xDialog->response(RET_OK);
178 else
179 m_xEdit->select_region(0, -1);
180}
181
182// ExportDialog
184{
185 m_bExportAsPackage = m_xExportAsPackageButton->get_active();
186 m_xDialog->response(RET_OK);
187}
188
190 : GenericDialogController(pParent, "modules/BasicIDE/ui/exportdialog.ui", "ExportDialog")
191 , m_bExportAsPackage(false)
192 , m_xExportAsPackageButton(m_xBuilder->weld_radio_button("extension"))
193 , m_xOKButton(m_xBuilder->weld_button("ok"))
194{
195 m_xExportAsPackageButton->set_active(true);
196 m_xOKButton->connect_clicked(LINK(this, ExportDialog, OkButtonHandler));
197}
198
200{
201}
202
203// LibPage
205 : OrganizePage(pParent, "modules/BasicIDE/ui/libpage.ui", "LibPage", pDialog)
206 , m_xBasicsBox(m_xBuilder->weld_combo_box("location"))
207 , m_xLibBox(m_xBuilder->weld_tree_view("library"))
208 , m_xEditButton(m_xBuilder->weld_button("edit"))
209 , m_xPasswordButton(m_xBuilder->weld_button("password"))
210 , m_xNewLibButton(m_xBuilder->weld_button("new"))
211 , m_xInsertLibButton(m_xBuilder->weld_button("import"))
212 , m_xExportButton(m_xBuilder->weld_button("export"))
213 , m_xDelButton(m_xBuilder->weld_button("delete"))
214 , m_aCurDocument(ScriptDocument::getApplicationScriptDocument())
215 , m_eCurLocation(LIBRARY_LOCATION_UNKNOWN)
216{
217 Size aSize(m_xLibBox->get_approximate_digit_width() * 40,
218 m_xLibBox->get_height_rows(10));
219 m_xLibBox->set_size_request(aSize.Width(), aSize.Height());
220
221 // tdf#93476 The libraries should be listed alphabetically
222 m_xLibBox->make_sorted();
223
224 m_xEditButton->connect_clicked( LINK( this, LibPage, ButtonHdl ) );
225 m_xNewLibButton->connect_clicked( LINK( this, LibPage, ButtonHdl ) );
226 m_xPasswordButton->connect_clicked( LINK( this, LibPage, ButtonHdl ) );
227 m_xExportButton->connect_clicked( LINK( this, LibPage, ButtonHdl ) );
228 m_xInsertLibButton->connect_clicked( LINK( this, LibPage, ButtonHdl ) );
229 m_xDelButton->connect_clicked( LINK( this, LibPage, ButtonHdl ) );
230 m_xLibBox->connect_changed( LINK( this, LibPage, TreeListHighlightHdl ) );
231
232 m_xBasicsBox->connect_changed( LINK( this, LibPage, BasicSelectHdl ) );
233
234 m_xLibBox->connect_editing(LINK(this, LibPage, EditingEntryHdl),
235 LINK(this, LibPage, EditedEntryHdl));
236
237 FillListBox();
238 m_xBasicsBox->set_active(0);
239 SetCurLib();
240
241 CheckButtons();
242}
243
244IMPL_LINK(LibPage, EditingEntryHdl, const weld::TreeIter&, rIter, bool)
245{
246 // check, if Standard library
247 OUString aLibName = m_xLibBox->get_text(rIter, 0);
248
249 if ( aLibName.equalsIgnoreAsciiCase( "Standard" ) )
250 {
251 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_pDialog->getDialog(),
252 VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_CANNOTCHANGENAMESTDLIB)));
253 xErrorBox->run();
254 return false;
255 }
256
257 // check, if library is readonly
258 Reference< script::XLibraryContainer2 > xModLibContainer( m_aCurDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
259 Reference< script::XLibraryContainer2 > xDlgLibContainer( m_aCurDocument.getLibraryContainer( E_DIALOGS ), UNO_QUERY );
260 if ( ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) && xModLibContainer->isLibraryReadOnly( aLibName ) && !xModLibContainer->isLibraryLink( aLibName ) ) ||
261 ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) && xDlgLibContainer->isLibraryReadOnly( aLibName ) && !xDlgLibContainer->isLibraryLink( aLibName ) ) )
262 {
263 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_pDialog->getDialog(),
264 VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_LIBISREADONLY)));
265 xErrorBox->run();
266 return false;
267 }
268
269 // i24094: Password verification necessary for renaming
270 if ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) && !xModLibContainer->isLibraryLoaded( aLibName ) )
271 {
272 bool bOK = true;
273 // check password
274 Reference< script::XLibraryContainerPassword > xPasswd( xModLibContainer, UNO_QUERY );
275 if ( xPasswd.is() && xPasswd->isLibraryPasswordProtected( aLibName ) && !xPasswd->isLibraryPasswordVerified( aLibName ) )
276 {
277 OUString aPassword;
278 bOK = QueryPassword(m_pDialog->getDialog(), xModLibContainer, aLibName, aPassword);
279 }
280 if ( !bOK )
281 return false;
282 }
283
284 // TODO: check if library is reference/link
285
286 return true;
287}
288
289IMPL_LINK(LibPage, EditedEntryHdl, const IterString&, rIterString, bool)
290{
291 const weld::TreeIter& rIter = rIterString.first;
292 OUString sNewName = rIterString.second;
293
294 bool bValid = sNewName.getLength() <= 30 && IsValidSbxName(sNewName);
295 OUString aOldName(m_xLibBox->get_text(rIter, 0));
296
297 if (bValid && aOldName != sNewName)
298 {
299 try
300 {
301 Reference< script::XLibraryContainer2 > xModLibContainer( m_aCurDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
302 if ( xModLibContainer.is() )
303 xModLibContainer->renameLibrary( aOldName, sNewName );
304
305 Reference< script::XLibraryContainer2 > xDlgLibContainer( m_aCurDocument.getLibraryContainer( E_DIALOGS ), UNO_QUERY );
306 if ( xDlgLibContainer.is() )
307 xDlgLibContainer->renameLibrary( aOldName, sNewName );
308
309 MarkDocumentModified( m_aCurDocument );
310 if (SfxBindings* pBindings = GetBindingsPtr())
311 {
312 pBindings->Invalidate( SID_BASICIDE_LIBSELECTOR );
313 pBindings->Update( SID_BASICIDE_LIBSELECTOR );
314 }
315 }
316 catch (const container::ElementExistException& )
317 {
318 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_pDialog->getDialog(),
319 VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_SBXNAMEALLREADYUSED)));
320 xErrorBox->run();
321 return false;
322 }
323 catch (const container::NoSuchElementException& )
324 {
325 DBG_UNHANDLED_EXCEPTION("basctl.basicide");
326 return false;
327 }
328 }
329
330 if ( !bValid )
331 {
332 OUString sWarning(sNewName.getLength() > 30 ? IDEResId(RID_STR_LIBNAMETOLONG) : IDEResId(RID_STR_BADSBXNAME));
333 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_pDialog->getDialog(),
334 VclMessageType::Warning, VclButtonsType::Ok, sWarning));
335 xErrorBox->run();
336
337 }
338
339 return bValid;
340}
341
343{
344 if (m_xBasicsBox)
345 {
346 const sal_Int32 nCount = m_xBasicsBox->get_count();
347 for (sal_Int32 i = 0; i < nCount; ++i)
348 {
349 DocumentEntry* pEntry = weld::fromId<DocumentEntry*>(m_xBasicsBox->get_id(i));
350 delete pEntry;
351 }
352 }
353}
354
356{
357 std::unique_ptr<weld::TreeIter> xCur(m_xLibBox->make_iterator());
358 if (!m_xLibBox->get_cursor(xCur.get()))
359 return;
360
361 OUString aLibName = m_xLibBox->get_text(*xCur, 0);
364
366 {
367 m_xPasswordButton->set_sensitive(false);
368 m_xNewLibButton->set_sensitive(false);
369 m_xInsertLibButton->set_sensitive(false);
370 m_xDelButton->set_sensitive(false);
371 }
372 else if ( aLibName.equalsIgnoreAsciiCase( "Standard" ) )
373 {
374 m_xPasswordButton->set_sensitive(false);
375 m_xNewLibButton->set_sensitive(true);
376 m_xInsertLibButton->set_sensitive(true);
377 m_xExportButton->set_sensitive(false);
378 m_xDelButton->set_sensitive(false);
379 }
380 else if ( ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) && xModLibContainer->isLibraryReadOnly( aLibName ) ) ||
381 ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) && xDlgLibContainer->isLibraryReadOnly( aLibName ) ) )
382 {
383 m_xPasswordButton->set_sensitive(false);
384 m_xNewLibButton->set_sensitive(true);
385 m_xInsertLibButton->set_sensitive(true);
386 if ( ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) && xModLibContainer->isLibraryReadOnly( aLibName ) && !xModLibContainer->isLibraryLink( aLibName ) ) ||
387 ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) && xDlgLibContainer->isLibraryReadOnly( aLibName ) && !xDlgLibContainer->isLibraryLink( aLibName ) ) )
388 m_xDelButton->set_sensitive(false);
389 else
390 m_xDelButton->set_sensitive(true);
391 }
392 else
393 {
394 if ( xModLibContainer.is() && !xModLibContainer->hasByName( aLibName ) )
395 m_xPasswordButton->set_sensitive(false);
396 else
397 m_xPasswordButton->set_sensitive(true);
398
399 m_xNewLibButton->set_sensitive(true);
400 m_xInsertLibButton->set_sensitive(true);
401 m_xExportButton->set_sensitive(true);
402 m_xDelButton->set_sensitive(true);
403 }
404}
405
407{
408 SetCurLib();
409}
410
411IMPL_LINK_NOARG(LibPage, TreeListHighlightHdl, weld::TreeView&, void)
412{
413 CheckButtons();
414}
415
416IMPL_LINK_NOARG( LibPage, BasicSelectHdl, weld::ComboBox&, void )
417{
418 SetCurLib();
419 CheckButtons();
420}
421
422IMPL_LINK( LibPage, ButtonHdl, weld::Button&, rButton, void )
423{
424 if (&rButton == m_xEditButton.get())
425 {
426 SfxAllItemSet aArgs( SfxGetpApp()->GetPool() );
427 SfxRequest aRequest( SID_BASICIDE_APPEAR, SfxCallMode::SYNCHRON, aArgs );
428 SfxGetpApp()->ExecuteSlot( aRequest );
429
430 SfxUnoAnyItem aDocItem( SID_BASICIDE_ARG_DOCUMENT_MODEL, Any( m_aCurDocument.getDocumentOrNull() ) );
431
432 std::unique_ptr<weld::TreeIter> xCurEntry(m_xLibBox->make_iterator());
433 if (!m_xLibBox->get_cursor(xCurEntry.get()))
434 return;
435 OUString aLibName(m_xLibBox->get_text(*xCurEntry, 0));
436 SfxStringItem aLibNameItem( SID_BASICIDE_ARG_LIBNAME, aLibName );
437 if (SfxDispatcher* pDispatcher = GetDispatcher())
438 pDispatcher->ExecuteList( SID_BASICIDE_LIBSELECTED,
439 SfxCallMode::ASYNCHRON, { &aDocItem, &aLibNameItem });
440 EndTabDialog();
441 return;
442 }
443 else if (&rButton == m_xNewLibButton.get())
444 NewLib();
445 else if (&rButton == m_xInsertLibButton.get())
446 InsertLib();
447 else if (&rButton == m_xExportButton.get())
448 Export();
449 else if (&rButton == m_xDelButton.get())
450 DeleteCurrent();
451 else if (&rButton == m_xPasswordButton.get())
452 {
453 std::unique_ptr<weld::TreeIter> xCurEntry(m_xLibBox->make_iterator());
454 if (!m_xLibBox->get_cursor(xCurEntry.get()))
455 return;
456 OUString aLibName(m_xLibBox->get_text(*xCurEntry, 0));
457
458 // load module library (if not loaded)
459 Reference< script::XLibraryContainer > xModLibContainer = m_aCurDocument.getLibraryContainer( E_SCRIPTS );
460 if ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) && !xModLibContainer->isLibraryLoaded( aLibName ) )
461 {
462 Shell* pShell = GetShell();
463 if (pShell)
464 pShell->GetViewFrame().GetWindow().EnterWait();
465 xModLibContainer->loadLibrary( aLibName );
466 if (pShell)
467 pShell->GetViewFrame().GetWindow().LeaveWait();
468 }
469
470 // load dialog library (if not loaded)
471 Reference< script::XLibraryContainer > xDlgLibContainer = m_aCurDocument.getLibraryContainer( E_DIALOGS );
472 if ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) && !xDlgLibContainer->isLibraryLoaded( aLibName ) )
473 {
474 Shell* pShell = GetShell();
475 if (pShell)
476 pShell->GetViewFrame().GetWindow().EnterWait();
477 xDlgLibContainer->loadLibrary( aLibName );
478 if (pShell)
479 pShell->GetViewFrame().GetWindow().LeaveWait();
480 }
481
482 // check, if library is password protected
483 if ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) )
484 {
485 Reference< script::XLibraryContainerPassword > xPasswd( xModLibContainer, UNO_QUERY );
486 if ( xPasswd.is() )
487 {
488 bool const bProtected = xPasswd->isLibraryPasswordProtected( aLibName );
489
490 // change password dialog
491 SvxPasswordDialog aDlg(m_pDialog->getDialog(), !bProtected);
492 aDlg.SetCheckPasswordHdl(LINK(this, LibPage, CheckPasswordHdl));
493
494 if (aDlg.run() == RET_OK)
495 {
496 bool const bNewProtected = xPasswd->isLibraryPasswordProtected( aLibName );
497
498 if ( bNewProtected != bProtected )
499 {
500 int nPos = m_xLibBox->get_iter_index_in_parent(*xCurEntry);
501 m_xLibBox->remove(*xCurEntry);
502 ImpInsertLibEntry(aLibName, nPos);
503 m_xLibBox->set_cursor(nPos);
504 }
505
506 MarkDocumentModified( m_aCurDocument );
507 }
508 }
509 }
510 }
511 CheckButtons();
512}
513
514IMPL_LINK( LibPage, CheckPasswordHdl, SvxPasswordDialog *, pDlg, bool )
515{
516 bool bRet = false;
517
518 std::unique_ptr<weld::TreeIter> xCurEntry(m_xLibBox->make_iterator());
519 if (!m_xLibBox->get_cursor(xCurEntry.get()))
520 return bRet;
521
522 OUString aLibName(m_xLibBox->get_text(*xCurEntry, 0));
523 Reference< script::XLibraryContainerPassword > xPasswd( m_aCurDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
524
525 if ( xPasswd.is() )
526 {
527 try
528 {
529 OUString aOldPassword( pDlg->GetOldPassword() );
530 OUString aNewPassword( pDlg->GetNewPassword() );
531 xPasswd->changeLibraryPassword( aLibName, aOldPassword, aNewPassword );
532 bRet = true;
533 }
534 catch (...)
535 {
536 }
537 }
538
539 return bRet;
540}
541
543{
545}
546
548{
549 Reference< uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
550 // file open dialog
551 sfx2::FileDialogHelper aDlg(ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE, FileDialogFlags::NONE, m_pDialog->getDialog());
553 const Reference <XFilePicker3>& xFP = aDlg.GetFilePicker();
554
555 xFP->setTitle(IDEResId(RID_STR_APPENDLIBS));
556
557 // filter
558 OUString aTitle(IDEResId(RID_STR_BASIC));
559 xFP->appendFilter( aTitle, "*.sbl;*.xlc;*.xlb" // library files
560 ";*.sdw;*.sxw;*.odt" // text
561 ";*.vor;*.stw;*.ott" // text template
562 ";*.sgl;*.sxg;*.odm" // master document
563 ";*.oth" // html document template
564 ";*.sdc;*.sxc;*.ods" // spreadsheet
565 ";*.stc;*.ots" // spreadsheet template
566 ";*.sda;*.sxd;*.odg" // drawing
567 ";*.std;*.otg" // drawing template
568 ";*.sdd;*.sxi;*.odp" // presentation
569 ";*.sti;*.otp" // presentation template
570 ";*.sxm;*.odf" ); // formula
571
572 OUString aLastFilter(GetExtraData()->GetAddLibFilter());
573 if ( !aLastFilter.isEmpty() )
574 xFP->setCurrentFilter( aLastFilter );
575 else
576 xFP->setCurrentFilter( IDEResId(RID_STR_BASIC) );
577
578 if ( xFP->execute() != RET_OK )
579 return;
580
581 GetExtraData()->SetAddLibPath( xFP->getDisplayDirectory() );
582 GetExtraData()->SetAddLibFilter( xFP->getCurrentFilter() );
583
584 // library containers for import
587
588 // file URLs
589 Sequence< OUString > aFiles = xFP->getSelectedFiles();
590 INetURLObject aURLObj( aFiles[0] );
591 auto xModURLObj = std::make_shared<INetURLObject>(aURLObj);
592 auto xDlgURLObj = std::make_shared<INetURLObject>(aURLObj);
593
594 OUString aBase = aURLObj.getBase();
595 OUString aModBase( "script" );
596 OUString aDlgBase( "dialog" );
597
598 if ( aBase == aModBase || aBase == aDlgBase )
599 {
600 xModURLObj->setBase( aModBase );
601 xDlgURLObj->setBase( aDlgBase );
602 }
603
605
606 OUString aModURL( xModURLObj->GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
607 if ( xSFA->exists( aModURL ) )
608 {
609 xModLibContImport = script::DocumentScriptLibraryContainer::createWithURL(xContext, aModURL);
610 }
611
612 OUString aDlgURL( xDlgURLObj->GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
613 if ( xSFA->exists( aDlgURL ) )
614 {
615 xDlgLibContImport = script::DocumentDialogLibraryContainer::createWithURL(xContext, aDlgURL);
616 }
617
618 if ( !xModLibContImport.is() && !xDlgLibContImport.is() )
619 return;
620
621 std::shared_ptr<LibDialog> xLibDlg;
622
623 Sequence< OUString > aLibNames = GetMergedLibraryNames( xModLibContImport, xDlgLibContImport );
624 sal_Int32 nLibCount = aLibNames.getLength();
625 if (nLibCount)
626 {
627 // library import dialog
628 xLibDlg = std::make_shared<LibDialog>(m_pDialog->getDialog());
629 xLibDlg->SetStorageName(aURLObj.getName());
630 weld::TreeView& rView = xLibDlg->GetLibBox();
631 rView.make_unsorted();
632 rView.freeze();
633
634 const OUString* pLibNames = aLibNames.getConstArray();
635 for (sal_Int32 i = 0 ; i < nLibCount; ++i)
636 {
637 // libbox entries
638 OUString aLibName( pLibNames[ i ] );
639 if ( !( ( xModLibContImport.is() && xModLibContImport->hasByName( aLibName ) && xModLibContImport->isLibraryLink( aLibName ) ) ||
640 ( xDlgLibContImport.is() && xDlgLibContImport->hasByName( aLibName ) && xDlgLibContImport->isLibraryLink( aLibName ) ) ) )
641 {
642 rView.append();
643 const int nRow = rView.n_children() - 1;
644 rView.set_toggle(nRow, TRISTATE_TRUE);
645 rView.set_text(nRow, aLibName, 0);
646 }
647 }
648
649 rView.thaw();
650 rView.make_sorted();
651
652 if (rView.n_children())
653 rView.set_cursor(0);
654 }
655
656 if (!xLibDlg)
657 {
658 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_pDialog->getDialog(),
659 VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_NOLIBINSTORAGE)));
660 xErrorBox->run();
661 return;
662 }
663
664 OUString aExtension( aURLObj.getExtension() );
665 OUString aLibExtension( "xlb" );
666 OUString aContExtension( "xlc" );
667
668 // disable reference checkbox for documents and sbls
669 if ( aExtension != aLibExtension && aExtension != aContExtension )
670 xLibDlg->EnableReference(false);
671
672 weld::DialogController::runAsync(xLibDlg, [aContExtension, xDlgURLObj, aExtension, aLibExtension, xModURLObj, xLibDlg, xDlgLibContImport, xModLibContImport, this](sal_Int32 nResult)
673 {
674 if (!nResult )
675 return;
676
677 bool bChanges = false;
678 bool bRemove = false;
679 bool bReplace = xLibDlg->IsReplace();
680 bool bReference = xLibDlg->IsReference();
681 weld::TreeView& rView = xLibDlg->GetLibBox();
682 for (int nLib = 0, nChildren = rView.n_children(); nLib < nChildren; ++nLib)
683 {
684 if (rView.get_toggle(nLib) == TRISTATE_TRUE)
685 {
686 OUString aLibName(rView.get_text(nLib));
687 Reference< script::XLibraryContainer2 > xModLibContainer( m_aCurDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
688 Reference< script::XLibraryContainer2 > xDlgLibContainer( m_aCurDocument.getLibraryContainer( E_DIALOGS ), UNO_QUERY );
689
690 // check, if the library is already existing
691 if ( ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) ) ||
692 ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) ) )
693 {
694 if ( bReplace )
695 {
696 // check, if the library is the Standard library
697 if ( aLibName == "Standard" )
698 {
699 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_pDialog->getDialog(),
700 VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_REPLACESTDLIB)));
701 xErrorBox->run();
702 continue;
703 }
704
705 // check, if the library is readonly and not a link
706 if ( ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) && xModLibContainer->isLibraryReadOnly( aLibName ) && !xModLibContainer->isLibraryLink( aLibName ) ) ||
707 ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) && xDlgLibContainer->isLibraryReadOnly( aLibName ) && !xDlgLibContainer->isLibraryLink( aLibName ) ) )
708 {
709 OUString aErrStr( IDEResId(RID_STR_REPLACELIB) );
710 aErrStr = aErrStr.replaceAll("XX", aLibName) + "\n" + IDEResId(RID_STR_LIBISREADONLY);
711 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_pDialog->getDialog(),
712 VclMessageType::Warning, VclButtonsType::Ok, aErrStr));
713 xErrorBox->run();
714 continue;
715 }
716
717 // remove existing libraries
718 bRemove = true;
719 }
720 else
721 {
722 OUString aErrStr;
723 if ( bReference )
724 aErrStr = IDEResId(RID_STR_REFNOTPOSSIBLE);
725 else
726 aErrStr = IDEResId(RID_STR_IMPORTNOTPOSSIBLE);
727 aErrStr = aErrStr.replaceAll("XX", aLibName) + "\n" +IDEResId(RID_STR_SBXNAMEALLREADYUSED);
728 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_pDialog->getDialog(),
729 VclMessageType::Warning, VclButtonsType::Ok, aErrStr));
730 xErrorBox->run();
731 continue;
732 }
733 }
734
735 // check, if the library is password protected
736 bool bOK = false;
737 OUString aPassword;
738 if ( xModLibContImport.is() && xModLibContImport->hasByName( aLibName ) )
739 {
740 Reference< script::XLibraryContainerPassword > xPasswd( xModLibContImport, UNO_QUERY );
741 if ( xPasswd.is() && xPasswd->isLibraryPasswordProtected( aLibName ) && !xPasswd->isLibraryPasswordVerified( aLibName ) && !bReference )
742 {
743 bOK = QueryPassword(m_pDialog->getDialog(), xModLibContImport, aLibName, aPassword, true, true);
744
745 if ( !bOK )
746 {
747 OUString aErrStr( IDEResId(RID_STR_NOIMPORT) );
748 aErrStr = aErrStr.replaceAll("XX", aLibName);
749 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_pDialog->getDialog(),
750 VclMessageType::Warning, VclButtonsType::Ok, aErrStr));
751 xErrorBox->run();
752 continue;
753 }
754 }
755 }
756
757 // remove existing libraries
758 if ( bRemove )
759 {
760 // remove listbox entry
761 int nEntry_ = FindEntry(*m_xLibBox, aLibName);
762 if (nEntry_ != -1)
763 m_xLibBox->remove(nEntry_);
764
765 // remove module library
766 if ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) )
767 xModLibContainer->removeLibrary( aLibName );
768
769 // remove dialog library
770 if ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) )
771 xDlgLibContainer->removeLibrary( aLibName );
772 }
773
774 // copy module library
775 if ( xModLibContImport.is() && xModLibContImport->hasByName( aLibName ) && xModLibContainer.is() && !xModLibContainer->hasByName( aLibName ) )
776 {
777 Reference< container::XNameContainer > xModLib;
778 if ( bReference )
779 {
780 // storage URL
781 INetURLObject aModStorageURLObj(*xModURLObj);
782 if ( aExtension == aContExtension )
783 {
784 sal_Int32 nCount = aModStorageURLObj.getSegmentCount();
785 aModStorageURLObj.insertName( aLibName, false, nCount-1 );
786 aModStorageURLObj.setExtension( aLibExtension );
787 aModStorageURLObj.setFinalSlash();
788 }
789 OUString aModStorageURL( aModStorageURLObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
790
791 // create library link
792 xModLib.set( xModLibContainer->createLibraryLink( aLibName, aModStorageURL, true ), UNO_QUERY);
793 }
794 else
795 {
796 // create library
797 xModLib = xModLibContainer->createLibrary( aLibName );
798 if ( xModLib.is() )
799 {
800 // get import library
801 Reference< container::XNameContainer > xModLibImport;
802 Any aElement = xModLibContImport->getByName( aLibName );
803 aElement >>= xModLibImport;
804
805 if ( xModLibImport.is() )
806 {
807 // load library
808 if ( !xModLibContImport->isLibraryLoaded( aLibName ) )
809 xModLibContImport->loadLibrary( aLibName );
810
811 // copy all modules
812 Sequence< OUString > aModNames = xModLibImport->getElementNames();
813 sal_Int32 nModCount = aModNames.getLength();
814 const OUString* pModNames = aModNames.getConstArray();
815 for ( sal_Int32 i = 0 ; i < nModCount ; i++ )
816 {
817 OUString aModName( pModNames[ i ] );
818 Any aElement_ = xModLibImport->getByName( aModName );
819 xModLib->insertByName( aModName, aElement_ );
820 }
821
822 // set password
823 if ( bOK )
824 {
825 Reference< script::XLibraryContainerPassword > xPasswd( xModLibContainer, UNO_QUERY );
826 if ( xPasswd.is() )
827 {
828 try
829 {
830 xPasswd->changeLibraryPassword( aLibName, OUString(), aPassword );
831 }
832 catch (...)
833 {
834 }
835 }
836 }
837 }
838 }
839 }
840 }
841
842 // copy dialog library
843 if ( xDlgLibContImport.is() && xDlgLibContImport->hasByName( aLibName ) && xDlgLibContainer.is() && !xDlgLibContainer->hasByName( aLibName ) )
844 {
845 Reference< container::XNameContainer > xDlgLib;
846 if ( bReference )
847 {
848 // storage URL
849 INetURLObject aDlgStorageURLObj( *xDlgURLObj );
850 if ( aExtension == aContExtension )
851 {
852 sal_Int32 nCount = aDlgStorageURLObj.getSegmentCount();
853 aDlgStorageURLObj.insertName( aLibName, false, nCount - 1 );
854 aDlgStorageURLObj.setExtension( aLibExtension );
855 aDlgStorageURLObj.setFinalSlash();
856 }
857 OUString aDlgStorageURL( aDlgStorageURLObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
858
859 // create library link
860 xDlgLib.set( xDlgLibContainer->createLibraryLink( aLibName, aDlgStorageURL, true ), UNO_QUERY);
861 }
862 else
863 {
864 // create library
865 xDlgLib = xDlgLibContainer->createLibrary( aLibName );
866 if ( xDlgLib.is() )
867 {
868 // get import library
869 Reference< container::XNameContainer > xDlgLibImport;
870 Any aElement = xDlgLibContImport->getByName( aLibName );
871 aElement >>= xDlgLibImport;
872
873 if ( xDlgLibImport.is() )
874 {
875 // load library
876 if ( !xDlgLibContImport->isLibraryLoaded( aLibName ) )
877 xDlgLibContImport->loadLibrary( aLibName );
878
879 // copy all dialogs
880 Sequence< OUString > aDlgNames = xDlgLibImport->getElementNames();
881 sal_Int32 nDlgCount = aDlgNames.getLength();
882 const OUString* pDlgNames = aDlgNames.getConstArray();
883 for ( sal_Int32 i = 0 ; i < nDlgCount ; i++ )
884 {
885 OUString aDlgName( pDlgNames[ i ] );
886 Any aElement_ = xDlgLibImport->getByName( aDlgName );
887 xDlgLib->insertByName( aDlgName, aElement_ );
888 }
889 }
890 }
891 }
892 }
893
894 // insert listbox entry
895 ImpInsertLibEntry( aLibName, m_xLibBox->n_children() );
896 m_xLibBox->set_cursor( m_xLibBox->find_text(aLibName) );
897 bChanges = true;
898 }
899 }
900
901 if ( bChanges )
903 });
904}
905
906void LibPage::Export()
907{
908 std::unique_ptr<weld::TreeIter> xCurEntry(m_xLibBox->make_iterator());
909 if (!m_xLibBox->get_cursor(xCurEntry.get()))
910 return;
911 OUString aLibName(m_xLibBox->get_text(*xCurEntry, 0));
912
913 // Password verification
914 Reference< script::XLibraryContainer2 > xModLibContainer( m_aCurDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
915
916 if ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) && !xModLibContainer->isLibraryLoaded( aLibName ) )
917 {
918 bool bOK = true;
919
920 // check password
921 Reference< script::XLibraryContainerPassword > xPasswd( xModLibContainer, UNO_QUERY );
922 if ( xPasswd.is() && xPasswd->isLibraryPasswordProtected( aLibName ) && !xPasswd->isLibraryPasswordVerified( aLibName ) )
923 {
924 OUString aPassword;
925 bOK = QueryPassword(m_pDialog->getDialog(), xModLibContainer, aLibName, aPassword);
926 }
927 if ( !bOK )
928 return;
929 }
930
931 std::unique_ptr<ExportDialog> xNewDlg(new ExportDialog(m_pDialog->getDialog()));
932 if (xNewDlg->run() != RET_OK)
933 return;
934
935 try
936 {
937 bool bExportAsPackage = xNewDlg->isExportAsPackage();
938 //tdf#112063 ensure closing xNewDlg is not selected as
939 //parent of file dialog from ExportAs...
940 xNewDlg.reset();
941 if (bExportAsPackage)
942 ExportAsPackage( aLibName );
943 else
944 ExportAsBasic( aLibName );
945 }
946 catch(const util::VetoException& ) // user canceled operation
947 {
948 }
949}
950
951void LibPage::implExportLib( const OUString& aLibName, const OUString& aTargetURL,
953{
955 ( m_aCurDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
957 ( m_aCurDocument.getLibraryContainer( E_DIALOGS ), UNO_QUERY );
958 if ( xModLibContainerExport.is() )
959 xModLibContainerExport->exportLibrary( aLibName, aTargetURL, Handler );
960
961 if (!xDlgLibContainerExport.is())
962 return;
963 Reference<container::XNameAccess> xNameAcc(xDlgLibContainerExport, UNO_QUERY);
964 if (!xNameAcc.is())
965 return;
966 if (!xNameAcc->hasByName(aLibName))
967 return;
968 xDlgLibContainerExport->exportLibrary(aLibName, aTargetURL, Handler);
969}
970
971// Implementation XCommandEnvironment
972
973namespace {
974
975class OLibCommandEnvironment : public cppu::WeakImplHelper< XCommandEnvironment >
976{
977 Reference< task::XInteractionHandler > mxInteraction;
978
979public:
980 explicit OLibCommandEnvironment(const Reference<task::XInteractionHandler>& xInteraction)
981 : mxInteraction( xInteraction )
982 {}
983
984 // Methods
985 virtual Reference< task::XInteractionHandler > SAL_CALL getInteractionHandler() override;
986 virtual Reference< XProgressHandler > SAL_CALL getProgressHandler() override;
987};
988
989}
990
991Reference< task::XInteractionHandler > OLibCommandEnvironment::getInteractionHandler()
992{
993 return mxInteraction;
994}
995
996Reference< XProgressHandler > OLibCommandEnvironment::getProgressHandler()
997{
998 Reference< XProgressHandler > xRet;
999 return xRet;
1000}
1001
1002void LibPage::ExportAsPackage( const OUString& aLibName )
1003{
1004 // file open dialog
1005 sfx2::FileDialogHelper aDlg(ui::dialogs::TemplateDescription::FILESAVE_SIMPLE, FileDialogFlags::NONE, m_pDialog->getDialog());
1007 const Reference <XFilePicker3>& xFP = aDlg.GetFilePicker();
1008
1009 Reference< uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
1010 Reference< task::XInteractionHandler2 > xHandler( task::InteractionHandler::createWithParent(xContext, nullptr) );
1011 Reference< XSimpleFileAccess3 > xSFA = SimpleFileAccess::create(xContext);
1012
1013 xFP->setTitle(IDEResId(RID_STR_EXPORTPACKAGE));
1014
1015 // filter
1016 OUString aTitle(IDEResId(RID_STR_PACKAGE_BUNDLE));
1017 xFP->appendFilter( aTitle, "*.oxt" ); // library files
1018
1019 xFP->setCurrentFilter( aTitle );
1020
1021 if ( xFP->execute() != RET_OK )
1022 return;
1023
1024 GetExtraData()->SetAddLibPath(xFP->getDisplayDirectory());
1025
1026 Sequence< OUString > aFiles = xFP->getSelectedFiles();
1027 INetURLObject aURL( aFiles[0] );
1028 if( aURL.getExtension().isEmpty() )
1029 aURL.setExtension( u"oxt" );
1030
1031 OUString aPackageURL( aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
1032
1033 OUString aTmpPath = SvtPathOptions().GetTempPath();
1034 INetURLObject aInetObj( aTmpPath );
1036 OUString aSourcePath = aInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
1037 if( xSFA->exists( aSourcePath ) )
1038 xSFA->kill( aSourcePath );
1039 Reference< task::XInteractionHandler > xDummyHandler( new DummyInteractionHandler( xHandler ) );
1040 implExportLib( aLibName, aTmpPath, xDummyHandler );
1041
1042 Reference< XCommandEnvironment > xCmdEnv = new OLibCommandEnvironment(xHandler);
1043
1044 ::ucbhelper::Content sourceContent( aSourcePath, xCmdEnv, comphelper::getProcessComponentContext() );
1045
1046 OUString destFolder = "vnd.sun.star.zip://" +
1047 ::rtl::Uri::encode( aPackageURL,
1048 rtl_UriCharClassRegName,
1049 rtl_UriEncodeIgnoreEscapes,
1050 RTL_TEXTENCODING_UTF8 ) +
1051 "/";
1052
1053 if( xSFA->exists( aPackageURL ) )
1054 xSFA->kill( aPackageURL );
1055
1056 ::ucbhelper::Content destFolderContent( destFolder, xCmdEnv, comphelper::getProcessComponentContext() );
1057 destFolderContent.transferContent(
1059 OUString(), NameClash::OVERWRITE );
1060
1061 INetURLObject aMetaInfInetObj( aTmpPath );
1062 aMetaInfInetObj.insertName( u"META-INF",
1064 OUString aMetaInfFolder = aMetaInfInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
1065 if( xSFA->exists( aMetaInfFolder ) )
1066 xSFA->kill( aMetaInfFolder );
1067 xSFA->createFolder( aMetaInfFolder );
1068
1069 std::vector< Sequence<beans::PropertyValue> > manifest;
1070
1071 OUString fullPath = aLibName
1072 + "/" ;
1073 auto attribs(::comphelper::InitPropertySequence({
1074 { "FullPath", Any(fullPath) },
1075 { "MediaType", Any(OUString("application/vnd.sun.star.basic-library")) }
1076 }));
1077 manifest.push_back( attribs );
1078
1079 // write into pipe:
1080 Reference<packages::manifest::XManifestWriter> xManifestWriter = packages::manifest::ManifestWriter::create( xContext );
1081 Reference<io::XOutputStream> xPipe( io::Pipe::create( xContext ), UNO_QUERY_THROW );
1082 xManifestWriter->writeManifestSequence(
1084 manifest.data(), manifest.size() ) );
1085
1086 aMetaInfInetObj.insertName( u"manifest.xml",
1088
1089 // write buffered pipe data to content:
1091 manifestContent.writeStream( Reference<io::XInputStream>( xPipe, UNO_QUERY_THROW ), true );
1092
1093 ::ucbhelper::Content MetaInfContent( aMetaInfFolder, xCmdEnv, comphelper::getProcessComponentContext() );
1094 destFolderContent.transferContent(
1095 MetaInfContent, ::ucbhelper::InsertOperation::Copy,
1096 OUString(), NameClash::OVERWRITE );
1097
1098 if( xSFA->exists( aSourcePath ) )
1099 xSFA->kill( aSourcePath );
1100 if( xSFA->exists( aMetaInfFolder ) )
1101 xSFA->kill( aMetaInfFolder );
1102}
1103
1104void LibPage::ExportAsBasic( const OUString& aLibName )
1105{
1106 // Folder picker
1107 Reference< uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
1108 Reference< XFolderPicker2 > xFolderPicker = sfx2::createFolderPicker(xContext, m_pDialog->getDialog());
1109 Reference< task::XInteractionHandler2 > xHandler( task::InteractionHandler::createWithParent(xContext, nullptr) );
1110
1111 xFolderPicker->setTitle(IDEResId(RID_STR_EXPORTBASIC));
1112
1113 // set display directory and filter
1114 OUString aPath =GetExtraData()->GetAddLibPath();
1115 if( aPath.isEmpty() )
1116 aPath = SvtPathOptions().GetWorkPath();
1117
1118 // INetURLObject aURL(m_sSavePath, INetProtocol::File);
1119 xFolderPicker->setDisplayDirectory( aPath );
1120 short nRet = xFolderPicker->execute();
1121 if( nRet == RET_OK )
1122 {
1123 OUString aTargetURL = xFolderPicker->getDirectory();
1125
1126 Reference< task::XInteractionHandler > xDummyHandler( new DummyInteractionHandler( xHandler ) );
1127 implExportLib( aLibName, aTargetURL, xDummyHandler );
1128 }
1129}
1130
1131void LibPage::DeleteCurrent()
1132{
1133 std::unique_ptr<weld::TreeIter> xCurEntry(m_xLibBox->make_iterator());
1134 if (!m_xLibBox->get_cursor(xCurEntry.get()))
1135 return;
1136 OUString aLibName(m_xLibBox->get_text(*xCurEntry, 0));
1137
1138 // check, if library is link
1139 bool bIsLibraryLink = false;
1140 Reference< script::XLibraryContainer2 > xModLibContainer( m_aCurDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
1141 Reference< script::XLibraryContainer2 > xDlgLibContainer( m_aCurDocument.getLibraryContainer( E_DIALOGS ), UNO_QUERY );
1142 if ( ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) && xModLibContainer->isLibraryLink( aLibName ) ) ||
1143 ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) && xDlgLibContainer->isLibraryLink( aLibName ) ) )
1144 {
1145 bIsLibraryLink = true;
1146 }
1147
1148 if (!QueryDelLib(aLibName, bIsLibraryLink, m_pDialog->getDialog()))
1149 return;
1150
1151 // inform BasicIDE
1152 SfxUnoAnyItem aDocItem( SID_BASICIDE_ARG_DOCUMENT_MODEL, Any( m_aCurDocument.getDocumentOrNull() ) );
1153 SfxStringItem aLibNameItem( SID_BASICIDE_ARG_LIBNAME, aLibName );
1154 if (SfxDispatcher* pDispatcher = GetDispatcher())
1155 pDispatcher->ExecuteList(SID_BASICIDE_LIBREMOVED,
1156 SfxCallMode::SYNCHRON, { &aDocItem, &aLibNameItem });
1157
1158 // remove library from module and dialog library containers
1159 if ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) )
1160 xModLibContainer->removeLibrary( aLibName );
1161 if ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) )
1162 xDlgLibContainer->removeLibrary( aLibName );
1163
1164 m_xLibBox->remove(*xCurEntry);
1165 MarkDocumentModified( m_aCurDocument );
1166}
1167
1168void LibPage::EndTabDialog()
1169{
1170 m_pDialog->response(RET_OK);
1171}
1172
1173void LibPage::FillListBox()
1174{
1175 InsertListBoxEntry( ScriptDocument::getApplicationScriptDocument(), LIBRARY_LOCATION_USER );
1176 InsertListBoxEntry( ScriptDocument::getApplicationScriptDocument(), LIBRARY_LOCATION_SHARE );
1177
1178 ScriptDocuments aDocuments( ScriptDocument::getAllScriptDocuments( ScriptDocument::DocumentsSorted ) );
1179 for (auto const& doc : aDocuments)
1180 {
1181 InsertListBoxEntry( doc, LIBRARY_LOCATION_DOCUMENT );
1182 }
1183}
1184
1185void LibPage::InsertListBoxEntry( const ScriptDocument& rDocument, LibraryLocation eLocation )
1186{
1187 OUString aEntryText(rDocument.getTitle(eLocation));
1188 OUString sId(weld::toId(new DocumentEntry(rDocument, eLocation)));
1189 m_xBasicsBox->append(sId, aEntryText);
1190}
1191
1192void LibPage::SetCurLib()
1193{
1194 DocumentEntry* pEntry = weld::fromId<DocumentEntry*>(m_xBasicsBox->get_active_id());
1195 if (!pEntry)
1196 return;
1197
1198 const ScriptDocument& aDocument( pEntry->GetDocument() );
1199 DBG_ASSERT( aDocument.isAlive(), "LibPage::SetCurLib: no document, or document is dead!" );
1200 if ( !aDocument.isAlive() )
1201 return;
1202 LibraryLocation eLocation = pEntry->GetLocation();
1203 if ( aDocument == m_aCurDocument && eLocation == m_eCurLocation )
1204 return;
1205
1206 m_aCurDocument = aDocument;
1207 m_eCurLocation = eLocation;
1208 m_xLibBox->clear();
1209
1210 // get a sorted list of library names
1211 Sequence< OUString > aLibNames = aDocument.getLibraryNames();
1212 sal_Int32 nLibCount = aLibNames.getLength();
1213 const OUString* pLibNames = aLibNames.getConstArray();
1214
1215 int nEntry = 0;
1216 for (int i = 0 ; i < nLibCount; ++i)
1217 {
1218 OUString aLibName(pLibNames[i]);
1219 if (eLocation == aDocument.getLibraryLocation(aLibName))
1220 ImpInsertLibEntry(aLibName, nEntry++);
1221 }
1222
1223 int nEntry_ = FindEntry(*m_xLibBox, u"Standard");
1224 if (nEntry_ == -1 && m_xLibBox->n_children())
1225 nEntry_ = 0;
1226 m_xLibBox->set_cursor(nEntry_);
1227}
1228
1229void LibPage::ImpInsertLibEntry( const OUString& rLibName, int nPos )
1230{
1231 // check, if library is password protected
1232 bool bProtected = false;
1233 Reference< script::XLibraryContainer2 > xModLibContainer( m_aCurDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
1234 if ( xModLibContainer.is() && xModLibContainer->hasByName( rLibName ) )
1235 {
1236 Reference< script::XLibraryContainerPassword > xPasswd( xModLibContainer, UNO_QUERY );
1237 if ( xPasswd.is() )
1238 {
1239 bProtected = xPasswd->isLibraryPasswordProtected( rLibName );
1240 }
1241 }
1242
1243 m_xLibBox->insert_text(nPos, rLibName);
1244
1245 if (bProtected)
1246 m_xLibBox->set_image(nPos, RID_BMP_LOCKED);
1247
1248 // check, if library is link
1249 if ( xModLibContainer.is() && xModLibContainer->hasByName( rLibName ) && xModLibContainer->isLibraryLink( rLibName ) )
1250 {
1251 OUString aLinkURL = xModLibContainer->getLibraryLinkURL( rLibName );
1252 m_xLibBox->set_text(nPos, aLinkURL, 1);
1253 }
1254}
1255
1256// Helper function
1257void createLibImpl(weld::Window* pWin, const ScriptDocument& rDocument,
1258 weld::TreeView* pLibBox, SbTreeListBox* pBasicBox)
1259{
1260 OSL_ENSURE( rDocument.isAlive(), "createLibImpl: invalid document!" );
1261 if ( !rDocument.isAlive() )
1262 return;
1263
1264 // create library name
1265 OUString aLibName;
1266 bool bValid = false;
1267 sal_Int32 i = 1;
1268 while ( !bValid )
1269 {
1270 aLibName = "Library" + OUString::number( i );
1271 if ( !rDocument.hasLibrary( E_SCRIPTS, aLibName ) && !rDocument.hasLibrary( E_DIALOGS, aLibName ) )
1272 bValid = true;
1273 i++;
1274 }
1275
1276 NewObjectDialog aNewDlg(pWin, ObjectMode::Library);
1277 aNewDlg.SetObjectName(aLibName);
1278
1279 if (!aNewDlg.run())
1280 return;
1281
1282 if (!aNewDlg.GetObjectName().isEmpty())
1283 aLibName = aNewDlg.GetObjectName();
1284
1285 if ( aLibName.getLength() > 30 )
1286 {
1287 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(pWin,
1288 VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_LIBNAMETOLONG)));
1289 xErrorBox->run();
1290 }
1291 else if ( !IsValidSbxName( aLibName ) )
1292 {
1293 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(pWin,
1294 VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_BADSBXNAME)));
1295 xErrorBox->run();
1296 }
1297 else if ( rDocument.hasLibrary( E_SCRIPTS, aLibName ) || rDocument.hasLibrary( E_DIALOGS, aLibName ) )
1298 {
1299 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(pWin,
1300 VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_SBXNAMEALLREADYUSED2)));
1301 xErrorBox->run();
1302 }
1303 else
1304 {
1305 try
1306 {
1307 // create module and dialog library
1308 rDocument.getOrCreateLibrary( E_SCRIPTS, aLibName );
1309 rDocument.getOrCreateLibrary( E_DIALOGS, aLibName );
1310
1311 if( pLibBox )
1312 {
1313 pLibBox->append_text(aLibName);
1314 pLibBox->set_cursor(pLibBox->find_text(aLibName));
1315 }
1316
1317 // create a module
1318 OUString aModName = rDocument.createObjectName( E_SCRIPTS, aLibName );
1319 OUString sModuleCode;
1320 if ( !rDocument.createModule( aLibName, aModName, true, sModuleCode ) )
1321 throw Exception("could not create module " + aModName, nullptr);
1322
1323 // tdf#151741 - store all libraries to the file system, otherwise they
1324 // cannot be renamed/moved since the SfxLibraryContainer::renameLibrary
1325 // moves the folders/files on the file system
1327 rDocument.getLibraryContainer(E_SCRIPTS), UNO_QUERY);
1329 rDocument.getLibraryContainer(E_DIALOGS), UNO_QUERY);
1330 Reference<script::XPersistentLibraryContainer> xModPersLibContainer(xModLibContainer,
1331 UNO_QUERY);
1332 if (xModPersLibContainer.is())
1333 xModPersLibContainer->storeLibraries();
1334 Reference<script::XPersistentLibraryContainer> xDlgPersLibContainer(xDlgLibContainer,
1335 UNO_QUERY);
1336 if (xDlgPersLibContainer.is())
1337 xDlgPersLibContainer->storeLibraries();
1338
1339 SbxItem aSbxItem( SID_BASICIDE_ARG_SBX, rDocument, aLibName, aModName, TYPE_MODULE );
1340 if (SfxDispatcher* pDispatcher = GetDispatcher())
1341 pDispatcher->ExecuteList(SID_BASICIDE_SBXINSERTED,
1342 SfxCallMode::SYNCHRON, { &aSbxItem });
1343
1344 if( pBasicBox )
1345 {
1346 std::unique_ptr<weld::TreeIter> xIter(pBasicBox->make_iterator(nullptr));
1347 bool bValidIter = pBasicBox->get_cursor(xIter.get());
1348 std::unique_ptr<weld::TreeIter> xRootEntry(pBasicBox->make_iterator(xIter.get()));
1349 while (bValidIter)
1350 {
1351 pBasicBox->copy_iterator(*xIter, *xRootEntry);
1352 bValidIter = pBasicBox->iter_parent(*xIter);
1353 }
1354
1355 BrowseMode nMode = pBasicBox->GetMode();
1356 bool bDlgMode = ( nMode & BrowseMode::Dialogs ) && !( nMode & BrowseMode::Modules );
1357 const auto sId = bDlgMode ? OUString(RID_BMP_DLGLIB) : OUString(RID_BMP_MODLIB);
1358 pBasicBox->AddEntry(aLibName, sId, xRootEntry.get(), false, std::make_unique<Entry>(OBJ_TYPE_LIBRARY));
1359 pBasicBox->AddEntry(aModName, RID_BMP_MODULE, xRootEntry.get(), false, std::make_unique<Entry>(OBJ_TYPE_MODULE));
1360 pBasicBox->set_cursor(*xRootEntry);
1361 pBasicBox->select(*xRootEntry);
1362 }
1363 }
1364 catch (const uno::Exception& )
1365 {
1366 DBG_UNHANDLED_EXCEPTION("basctl.basicide");
1367 }
1368 }
1369}
1370
1371} // namespace basctl
1372
1373/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SfxApplication * SfxGetpApp()
Reference< XExecutableDialog > m_xDialog
ScriptDocument aDocument
Definition: basobj2.cxx:194
BrowseMode
Definition: bastype2.hxx:36
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage, const ILibreOfficeKitNotifier *pNotifier=nullptr)
OUString getName(sal_Int32 nIndex=LAST_SEGMENT, bool bIgnoreFinalSlash=true, DecodeMechanism eMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
OUString GetMainURL(DecodeMechanism eMechanism, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
OUString getExtension(sal_Int32 nIndex=LAST_SEGMENT, bool bIgnoreFinalSlash=true, DecodeMechanism eMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
OUString getBase(sal_Int32 nIndex=LAST_SEGMENT, bool bIgnoreFinalSlash=true, DecodeMechanism eMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
bool insertName(std::u16string_view rTheName, bool bAppendFinalSlash=false, sal_Int32 nIndex=LAST_SEGMENT, EncodeMechanism eMechanism=EncodeMechanism::WasEncoded, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8)
const SfxPoolItem * ExecuteSlot(SfxRequest &rReq, const SfxInterface *pIF=nullptr)
vcl::Window & GetWindow() const
SfxViewFrame & GetViewFrame() const
constexpr tools::Long Height() const
constexpr tools::Long Width() const
const OUString & GetWorkPath() const
const OUString & GetTempPath() const
LibraryLocation GetLocation() const
Definition: bastype2.hxx:100
ScriptDocument const & GetDocument() const
Definition: bastype2.hxx:99
virtual ~ExportDialog() override
Definition: moduldl2.cxx:199
ExportDialog(weld::Window *pParent)
Definition: moduldl2.cxx:189
std::unique_ptr< weld::RadioButton > m_xExportAsPackageButton
Definition: moduldlg.hxx:76
std::unique_ptr< weld::Button > m_xOKButton
Definition: moduldlg.hxx:77
void SetAddLibFilter(const OUString &rFilter)
Definition: iderdll2.hxx:62
const OUString & GetAddLibPath() const
Definition: iderdll2.hxx:58
void SetAddLibPath(const OUString &rPath)
Definition: iderdll2.hxx:59
virtual ~GotoLineDialog() override
Definition: moduldl2.cxx:165
sal_Int32 GetLineNumber() const
Definition: moduldl2.cxx:169
std::unique_ptr< weld::Button > m_xOKButton
Definition: moduldlg.hxx:63
std::unique_ptr< weld::Entry > m_xEdit
Definition: moduldlg.hxx:62
GotoLineDialog(weld::Window *pParent)
Definition: moduldl2.cxx:156
void InsertLib()
Definition: moduldl2.cxx:547
LibPage(weld::Container *pParent, OrganizeDialog *pDialog)
Definition: moduldl2.cxx:204
std::unique_ptr< weld::TreeView > m_xLibBox
Definition: moduldlg.hxx:161
std::unique_ptr< weld::Button > m_xInsertLibButton
Definition: moduldlg.hxx:165
virtual void ActivatePage() override
Definition: moduldl2.cxx:406
virtual ~LibPage() override
Definition: moduldl2.cxx:342
void CheckButtons()
Definition: moduldl2.cxx:355
std::unique_ptr< weld::Button > m_xEditButton
Definition: moduldlg.hxx:162
std::unique_ptr< weld::ComboBox > m_xBasicsBox
Definition: moduldlg.hxx:160
void FillListBox()
Definition: moduldl2.cxx:1173
std::unique_ptr< weld::Button > m_xNewLibButton
Definition: moduldlg.hxx:164
std::unique_ptr< weld::Button > m_xPasswordButton
Definition: moduldlg.hxx:163
std::unique_ptr< weld::Button > m_xExportButton
Definition: moduldlg.hxx:166
ScriptDocument m_aCurDocument
Definition: moduldlg.hxx:169
LibraryLocation m_eCurLocation
Definition: moduldlg.hxx:170
std::unique_ptr< weld::Button > m_xDelButton
Definition: moduldlg.hxx:167
std::unique_ptr< weld::Button > m_xOKButton
Definition: moduldlg.hxx:46
OUString GetObjectName() const
Definition: moduldlg.hxx:52
NewObjectDialog(weld::Window *pParent, ObjectMode, bool bCheckName=false)
Definition: moduldl2.cxx:132
void SetObjectName(const OUString &rName)
Definition: moduldlg.hxx:53
OrganizeDialog * m_pDialog
Definition: moduldlg.hxx:114
bool get_cursor(weld::TreeIter *pIter) const
Definition: bastype2.hxx:238
void set_cursor(const weld::TreeIter &rIter)
Definition: bastype2.hxx:239
std::unique_ptr< weld::TreeIter > make_iterator(const weld::TreeIter *pIter=nullptr) const
Definition: bastype2.hxx:232
void select(const weld::TreeIter &rIter)
Definition: bastype2.hxx:235
void AddEntry(const OUString &rText, const OUString &rImage, const weld::TreeIter *pParent, bool bChildrenOnDemand, std::unique_ptr< Entry > &&rUserData, weld::TreeIter *pRet=nullptr)
Definition: bastype2.cxx:642
BrowseMode GetMode() const
Definition: bastype2.hxx:216
bool iter_parent(weld::TreeIter &rIter) const
Definition: bastype2.hxx:246
void copy_iterator(const weld::TreeIter &rSource, weld::TreeIter &rDest) const
Definition: bastype2.hxx:233
encapsulates a document which contains Basic scripts and dialogs
css::uno::Reference< css::container::XNameContainer > getOrCreateLibrary(LibraryContainerType _eType, const OUString &_rLibName) const
creates a script or dialog library in the document, or returns an existing one
OUString getTitle(LibraryLocation _eLocation, LibraryType _eType=LibraryType::All) const
returns the title for the document
bool hasLibrary(LibraryContainerType _eType, const OUString &_rLibName) const
determines whether there exists a library of the given type, with the given name
css::uno::Reference< css::script::XLibraryContainer > getLibraryContainer(LibraryContainerType _eType) const
returns the Basic or Dialog library container of the document
bool createModule(const OUString &_rLibName, const OUString &_rModName, bool _bCreateMain, OUString &_out_rNewModuleCode) const
creates a module with the given name in the given library
bool isAlive() const
determines whether the document instance is alive
OUString createObjectName(LibraryContainerType _eType, const OUString &_rLibName) const
retrieves a name for a newly to be created module or dialog
const css::uno::Reference< css::ui::dialogs::XFilePicker3 > & GetFilePicker() const
void SetContext(Context _eNewContext)
void transferContent(const Content &rSourceContent, InsertOperation eOperation, const OUString &rTitle, const sal_Int32 nNameClashAction, const OUString &rMimeType=OUString(), bool bMajorVersion=false, const OUString &rCommentVersion=OUString(), OUString *pResultURL=nullptr, const OUString &rDocumentId=OUString()) const
void writeStream(const css::uno::Reference< css::io::XInputStream > &rStream, bool bReplaceExisting)
void LeaveWait()
void EnterWait()
virtual short run()
static bool runAsync(const std::shared_ptr< DialogController > &rController, const std::function< void(sal_Int32)> &)
virtual Dialog * getDialog() override
std::shared_ptr< weld::Dialog > m_xDialog
virtual void make_sorted()=0
virtual void set_text(int row, const OUString &rText, int col=-1)=0
virtual int find_text(const OUString &rText) const=0
virtual OUString get_text(int row, int col=-1) const=0
void append_text(const OUString &rStr)
virtual void set_toggle(int row, TriState eState, int col=-1)=0
virtual int n_children() const=0
void append(TreeIter *pRet=nullptr)
virtual void set_cursor(int pos)=0
virtual void make_unsorted()=0
virtual void freeze()=0
virtual void thaw()=0
int nCount
#define DBG_ASSERT(sCon, aError)
#define DBG_UNHANDLED_EXCEPTION(...)
URL aURL
float u
TRISTATE_TRUE
std::unique_ptr< weld::Button > m_xOKButton
Mode eMode
sal_uInt16 nPos
Reference< task::XInteractionHandler2 > m_xHandler
Definition: moduldl2.cxx:84
Reference< task::XInteractionHandler > mxInteraction
Definition: moduldl2.cxx:977
SfxBindings * GetBindingsPtr()
Definition: basobj3.cxx:426
bool QueryDelLib(std::u16string_view rName, bool bRef, weld::Widget *pParent)
Definition: bastypes.cxx:769
bool IsValidSbxName(std::u16string_view rName)
Definition: basobj2.cxx:81
void createLibImpl(weld::Window *pWin, const ScriptDocument &rDocument, weld::TreeView *pLibBox, SbTreeListBox *pBasicBox)
Definition: moduldl2.cxx:1257
bool QueryPassword(weld::Widget *pDialogParent, const Reference< script::XLibraryContainer > &xLibContainer, const OUString &rLibName, OUString &rPassword, bool bRepeat, bool bNewTitle)
Definition: bastypes.cxx:779
@ LIBRARY_LOCATION_USER
@ LIBRARY_LOCATION_UNKNOWN
@ LIBRARY_LOCATION_SHARE
@ LIBRARY_LOCATION_DOCUMENT
ExtraData * GetExtraData()
Definition: iderdll.cxx:101
Shell * GetShell()
Definition: iderdll.cxx:80
SfxDispatcher * GetDispatcher()
Definition: basobj3.cxx:454
void MarkDocumentModified(const ScriptDocument &rDocument)
Definition: basobj3.cxx:249
IMPL_LINK(AccessibleDialogWindow, WindowEventListener, VclWindowEvent &, rEvent, void)
std::vector< ScriptDocument > ScriptDocuments
ObjectMode
Definition: moduldlg.hxx:36
Sequence< OUString > GetMergedLibraryNames(const Reference< script::XLibraryContainer > &xModLibContainer, const Reference< script::XLibraryContainer > &xDlgLibContainer)
Definition: basobj2.cxx:98
@ OBJ_TYPE_LIBRARY
Definition: bastype2.hxx:54
@ OBJ_TYPE_MODULE
Definition: bastype2.hxx:55
IMPL_LINK_NOARG(EditorWindow, SetSourceInBasicHdl, void *, void)
Definition: baside2b.cxx:987
@ TYPE_MODULE
Definition: sbxitem.hxx:32
OUString IDEResId(TranslateId aId)
Definition: iderdll.cxx:108
@ Exception
Reference< XComponentContext > getProcessComponentContext()
int i
bool equalsIgnoreAsciiCase(std::u16string_view s1, std::u16string_view s2)
css::uno::Reference< css::ui::dialogs::XFolderPicker2 > createFolderPicker(const css::uno::Reference< css::uno::XComponentContext > &rContext, weld::Window *pPreferredParent)
OUString toId(const void *pValue)
OUString aTargetURL
OUString sId
RET_OK