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>
34 #include <sfx2/filedlghelper.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>
41 #include <tools/diagnose_ex.h>
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/FolderPicker.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>
58 #include <unotools/pathoptions.hxx>
59
60 #include <com/sun/star/util/VetoException.hpp>
61 #include <com/sun/star/script/ModuleSizeExceededRequest.hpp>
62
63 #include <comphelper/processfactory.hxx>
64 #include <comphelper/propertysequence.hxx>
65 #include <cppuhelper/implbase.hxx>
66
67 #include <cassert>
68 #include <string_view>
69
70 namespace basctl
71 {
72
73 using namespace ::com::sun::star;
74 using namespace ::com::sun::star::uno;
75 using namespace ::com::sun::star::lang;
76 using namespace ::com::sun::star::ucb;
77 using namespace ::com::sun::star::ui::dialogs;
78
79 namespace
80 {
81
82 class DummyInteractionHandler : public ::cppu::WeakImplHelper< task::XInteractionHandler >
83 {
84 Reference< task::XInteractionHandler2 > m_xHandler;
85 public:
DummyInteractionHandler(const Reference<task::XInteractionHandler2> & xHandler)86 explicit DummyInteractionHandler(const Reference<task::XInteractionHandler2>& xHandler)
87 : m_xHandler(xHandler)
88 {
89 }
90
handle(const Reference<task::XInteractionRequest> & rRequest)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
104 namespace
105 {
FindEntry(const weld::TreeView & rBox,const OUString & rName)106 int FindEntry(const weld::TreeView& rBox, const OUString& rName)
107 {
108 int nCount = rBox.n_children();
109 for (int i = 0; i < nCount; ++i)
110 {
111 if (rName.equalsIgnoreAsciiCase(rBox.get_text(i, 0)))
112 return i;
113 }
114 return -1;
115 }
116 }
117
118 // NewObjectDialog
IMPL_LINK_NOARG(NewObjectDialog,OkButtonHandler,weld::Button &,void)119 IMPL_LINK_NOARG(NewObjectDialog, OkButtonHandler, weld::Button&, void)
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
NewObjectDialog(weld::Window * pParent,ObjectMode eMode,bool bCheckName)132 NewObjectDialog::NewObjectDialog(weld::Window * pParent, ObjectMode eMode, bool bCheckName)
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 {
140 case ObjectMode::Library:
141 m_xDialog->set_title(IDEResId(RID_STR_NEWLIB));
142 break;
143 case ObjectMode::Module:
144 m_xDialog->set_title(IDEResId(RID_STR_NEWMOD));
145 break;
146 case ObjectMode::Dialog:
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
GotoLineDialog(weld::Window * pParent)156 GotoLineDialog::GotoLineDialog(weld::Window* pParent )
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
~GotoLineDialog()165 GotoLineDialog::~GotoLineDialog()
166 {
167 }
168
GetLineNumber() const169 sal_Int32 GotoLineDialog::GetLineNumber() const
170 {
171 return m_xEdit->get_text().toInt32();
172 }
173
IMPL_LINK_NOARG(GotoLineDialog,OkButtonHandler,weld::Button &,void)174 IMPL_LINK_NOARG(GotoLineDialog, OkButtonHandler, weld::Button&, void)
175 {
176 if (GetLineNumber())
177 m_xDialog->response(RET_OK);
178 else
179 m_xEdit->select_region(0, -1);
180 }
181
182 // ExportDialog
IMPL_LINK_NOARG(ExportDialog,OkButtonHandler,weld::Button &,void)183 IMPL_LINK_NOARG(ExportDialog, OkButtonHandler, weld::Button&, void)
184 {
185 m_bExportAsPackage = m_xExportAsPackageButton->get_active();
186 m_xDialog->response(RET_OK);
187 }
188
ExportDialog(weld::Window * pParent)189 ExportDialog::ExportDialog(weld::Window * pParent)
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
~ExportDialog()199 ExportDialog::~ExportDialog()
200 {
201 }
202
203 // LibPage
LibPage(weld::Container * pParent,OrganizeDialog * pDialog)204 LibPage::LibPage(weld::Container* pParent, OrganizeDialog* pDialog)
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
IMPL_LINK(LibPage,EditingEntryHdl,const weld::TreeIter &,rIter,bool)244 IMPL_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
IMPL_LINK(LibPage,EditedEntryHdl,const IterString &,rIterString,bool)289 IMPL_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
~LibPage()342 LibPage::~LibPage()
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 = reinterpret_cast<DocumentEntry*>(m_xBasicsBox->get_id(i).toInt64());
350 delete pEntry;
351 }
352 }
353 }
354
CheckButtons()355 void LibPage::CheckButtons()
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);
362 Reference< script::XLibraryContainer2 > xModLibContainer( m_aCurDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
363 Reference< script::XLibraryContainer2 > xDlgLibContainer( m_aCurDocument.getLibraryContainer( E_DIALOGS ), UNO_QUERY );
364
365 if ( m_eCurLocation == LIBRARY_LOCATION_SHARE )
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
ActivatePage()406 void LibPage::ActivatePage()
407 {
408 SetCurLib();
409 }
410
IMPL_LINK_NOARG(LibPage,TreeListHighlightHdl,weld::TreeView &,void)411 IMPL_LINK_NOARG(LibPage, TreeListHighlightHdl, weld::TreeView&, void)
412 {
413 CheckButtons();
414 }
415
IMPL_LINK_NOARG(LibPage,BasicSelectHdl,weld::ComboBox &,void)416 IMPL_LINK_NOARG( LibPage, BasicSelectHdl, weld::ComboBox&, void )
417 {
418 SetCurLib();
419 CheckButtons();
420 }
421
IMPL_LINK(LibPage,ButtonHdl,weld::Button &,rButton,void)422 IMPL_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
IMPL_LINK(LibPage,CheckPasswordHdl,SvxPasswordDialog *,pDlg,bool)514 IMPL_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
NewLib()542 void LibPage::NewLib()
543 {
544 createLibImpl(m_pDialog->getDialog(), m_aCurDocument, m_xLibBox.get(), nullptr);
545 }
546
InsertLib()547 void LibPage::InsertLib()
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());
552 const Reference <XFilePicker3>& xFP = aDlg.GetFilePicker();
553
554 xFP->setTitle(IDEResId(RID_STR_APPENDLIBS));
555
556 // filter
557 OUString aTitle(IDEResId(RID_STR_BASIC));
558 xFP->appendFilter( aTitle, "*.sbl;*.xlc;*.xlb" // library files
559 ";*.sdw;*.sxw;*.odt" // text
560 ";*.vor;*.stw;*.ott" // text template
561 ";*.sgl;*.sxg;*.odm" // master document
562 ";*.oth" // html document template
563 ";*.sdc;*.sxc;*.ods" // spreadsheet
564 ";*.stc;*.ots" // spreadsheet template
565 ";*.sda;*.sxd;*.odg" // drawing
566 ";*.std;*.otg" // drawing template
567 ";*.sdd;*.sxi;*.odp" // presentation
568 ";*.sti;*.otp" // presentation template
569 ";*.sxm;*.odf" ); // formula
570
571 // set display directory and filter
572 OUString aPath(GetExtraData()->GetAddLibPath());
573 if ( !aPath.isEmpty() )
574 xFP->setDisplayDirectory( aPath );
575 else
576 {
577 // macro path from configuration management
578 xFP->setDisplayDirectory( SvtPathOptions().GetWorkPath() );
579 }
580
581 OUString aLastFilter(GetExtraData()->GetAddLibFilter());
582 if ( !aLastFilter.isEmpty() )
583 xFP->setCurrentFilter( aLastFilter );
584 else
585 xFP->setCurrentFilter( IDEResId(RID_STR_BASIC) );
586
587 if ( xFP->execute() != RET_OK )
588 return;
589
590 GetExtraData()->SetAddLibPath( xFP->getDisplayDirectory() );
591 GetExtraData()->SetAddLibFilter( xFP->getCurrentFilter() );
592
593 // library containers for import
594 Reference< script::XLibraryContainer2 > xModLibContImport;
595 Reference< script::XLibraryContainer2 > xDlgLibContImport;
596
597 // file URLs
598 Sequence< OUString > aFiles = xFP->getSelectedFiles();
599 INetURLObject aURLObj( aFiles[0] );
600 auto xModURLObj = std::make_shared<INetURLObject>(aURLObj);
601 auto xDlgURLObj = std::make_shared<INetURLObject>(aURLObj);
602
603 OUString aBase = aURLObj.getBase();
604 OUString aModBase( "script" );
605 OUString aDlgBase( "dialog" );
606
607 if ( aBase == aModBase || aBase == aDlgBase )
608 {
609 xModURLObj->setBase( aModBase );
610 xDlgURLObj->setBase( aDlgBase );
611 }
612
613 Reference< XSimpleFileAccess3 > xSFA( SimpleFileAccess::create(comphelper::getProcessComponentContext()) );
614
615 OUString aModURL( xModURLObj->GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
616 if ( xSFA->exists( aModURL ) )
617 {
618 xModLibContImport = script::DocumentScriptLibraryContainer::createWithURL(xContext, aModURL);
619 }
620
621 OUString aDlgURL( xDlgURLObj->GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
622 if ( xSFA->exists( aDlgURL ) )
623 {
624 xDlgLibContImport = script::DocumentDialogLibraryContainer::createWithURL(xContext, aDlgURL);
625 }
626
627 if ( !xModLibContImport.is() && !xDlgLibContImport.is() )
628 return;
629
630 std::shared_ptr<LibDialog> xLibDlg;
631
632 Sequence< OUString > aLibNames = GetMergedLibraryNames( xModLibContImport, xDlgLibContImport );
633 sal_Int32 nLibCount = aLibNames.getLength();
634 if (nLibCount)
635 {
636 // library import dialog
637 xLibDlg = std::make_shared<LibDialog>(m_pDialog->getDialog());
638 xLibDlg->SetStorageName(aURLObj.getName());
639 weld::TreeView& rView = xLibDlg->GetLibBox();
640 rView.make_unsorted();
641
642 const OUString* pLibNames = aLibNames.getConstArray();
643 for (sal_Int32 i = 0 ; i < nLibCount; ++i)
644 {
645 // libbox entries
646 OUString aLibName( pLibNames[ i ] );
647 if ( !( ( xModLibContImport.is() && xModLibContImport->hasByName( aLibName ) && xModLibContImport->isLibraryLink( aLibName ) ) ||
648 ( xDlgLibContImport.is() && xDlgLibContImport->hasByName( aLibName ) && xDlgLibContImport->isLibraryLink( aLibName ) ) ) )
649 {
650 rView.append();
651 const int nRow = rView.n_children() - 1;
652 rView.set_toggle(nRow, TRISTATE_TRUE);
653 rView.set_text(nRow, aLibName, 0);
654 }
655 }
656
657 rView.make_sorted();
658
659 if (rView.n_children())
660 rView.set_cursor(0);
661 }
662
663 if (!xLibDlg)
664 {
665 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_pDialog->getDialog(),
666 VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_NOLIBINSTORAGE)));
667 xErrorBox->run();
668 return;
669 }
670
671 OUString aExtension( aURLObj.getExtension() );
672 OUString aLibExtension( "xlb" );
673 OUString aContExtension( "xlc" );
674
675 // disable reference checkbox for documents and sbls
676 if ( aExtension != aLibExtension && aExtension != aContExtension )
677 xLibDlg->EnableReference(false);
678
679 weld::DialogController::runAsync(xLibDlg, [aContExtension, xDlgURLObj, aExtension, aLibExtension, xModURLObj, xLibDlg, xDlgLibContImport, xModLibContImport, this](sal_Int32 nResult)
680 {
681 if (!nResult )
682 return;
683
684 bool bChanges = false;
685 bool bRemove = false;
686 bool bReplace = xLibDlg->IsReplace();
687 bool bReference = xLibDlg->IsReference();
688 weld::TreeView& rView = xLibDlg->GetLibBox();
689 for (int nLib = 0, nChildren = rView.n_children(); nLib < nChildren; ++nLib)
690 {
691 if (rView.get_toggle(nLib) == TRISTATE_TRUE)
692 {
693 OUString aLibName(rView.get_text(nLib));
694 Reference< script::XLibraryContainer2 > xModLibContainer( m_aCurDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
695 Reference< script::XLibraryContainer2 > xDlgLibContainer( m_aCurDocument.getLibraryContainer( E_DIALOGS ), UNO_QUERY );
696
697 // check, if the library is already existing
698 if ( ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) ) ||
699 ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) ) )
700 {
701 if ( bReplace )
702 {
703 // check, if the library is the Standard library
704 if ( aLibName == "Standard" )
705 {
706 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_pDialog->getDialog(),
707 VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_REPLACESTDLIB)));
708 xErrorBox->run();
709 continue;
710 }
711
712 // check, if the library is readonly and not a link
713 if ( ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) && xModLibContainer->isLibraryReadOnly( aLibName ) && !xModLibContainer->isLibraryLink( aLibName ) ) ||
714 ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) && xDlgLibContainer->isLibraryReadOnly( aLibName ) && !xDlgLibContainer->isLibraryLink( aLibName ) ) )
715 {
716 OUString aErrStr( IDEResId(RID_STR_REPLACELIB) );
717 aErrStr = aErrStr.replaceAll("XX", aLibName) + "\n" + IDEResId(RID_STR_LIBISREADONLY);
718 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_pDialog->getDialog(),
719 VclMessageType::Warning, VclButtonsType::Ok, aErrStr));
720 xErrorBox->run();
721 continue;
722 }
723
724 // remove existing libraries
725 bRemove = true;
726 }
727 else
728 {
729 OUString aErrStr;
730 if ( bReference )
731 aErrStr = IDEResId(RID_STR_REFNOTPOSSIBLE);
732 else
733 aErrStr = IDEResId(RID_STR_IMPORTNOTPOSSIBLE);
734 aErrStr = aErrStr.replaceAll("XX", aLibName) + "\n" +IDEResId(RID_STR_SBXNAMEALLREADYUSED);
735 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_pDialog->getDialog(),
736 VclMessageType::Warning, VclButtonsType::Ok, aErrStr));
737 xErrorBox->run();
738 continue;
739 }
740 }
741
742 // check, if the library is password protected
743 bool bOK = false;
744 OUString aPassword;
745 if ( xModLibContImport.is() && xModLibContImport->hasByName( aLibName ) )
746 {
747 Reference< script::XLibraryContainerPassword > xPasswd( xModLibContImport, UNO_QUERY );
748 if ( xPasswd.is() && xPasswd->isLibraryPasswordProtected( aLibName ) && !xPasswd->isLibraryPasswordVerified( aLibName ) && !bReference )
749 {
750 bOK = QueryPassword(m_pDialog->getDialog(), xModLibContImport, aLibName, aPassword, true, true);
751
752 if ( !bOK )
753 {
754 OUString aErrStr( IDEResId(RID_STR_NOIMPORT) );
755 aErrStr = aErrStr.replaceAll("XX", aLibName);
756 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_pDialog->getDialog(),
757 VclMessageType::Warning, VclButtonsType::Ok, aErrStr));
758 xErrorBox->run();
759 continue;
760 }
761 }
762 }
763
764 // remove existing libraries
765 if ( bRemove )
766 {
767 // remove listbox entry
768 int nEntry_ = FindEntry(*m_xLibBox, aLibName);
769 if (nEntry_ != -1)
770 m_xLibBox->remove(nEntry_);
771
772 // remove module library
773 if ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) )
774 xModLibContainer->removeLibrary( aLibName );
775
776 // remove dialog library
777 if ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) )
778 xDlgLibContainer->removeLibrary( aLibName );
779 }
780
781 // copy module library
782 if ( xModLibContImport.is() && xModLibContImport->hasByName( aLibName ) && xModLibContainer.is() && !xModLibContainer->hasByName( aLibName ) )
783 {
784 Reference< container::XNameContainer > xModLib;
785 if ( bReference )
786 {
787 // storage URL
788 INetURLObject aModStorageURLObj(*xModURLObj);
789 if ( aExtension == aContExtension )
790 {
791 sal_Int32 nCount = aModStorageURLObj.getSegmentCount();
792 aModStorageURLObj.insertName( aLibName, false, nCount-1 );
793 aModStorageURLObj.setExtension( aLibExtension );
794 aModStorageURLObj.setFinalSlash();
795 }
796 OUString aModStorageURL( aModStorageURLObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
797
798 // create library link
799 xModLib.set( xModLibContainer->createLibraryLink( aLibName, aModStorageURL, true ), UNO_QUERY);
800 }
801 else
802 {
803 // create library
804 xModLib = xModLibContainer->createLibrary( aLibName );
805 if ( xModLib.is() )
806 {
807 // get import library
808 Reference< container::XNameContainer > xModLibImport;
809 Any aElement = xModLibContImport->getByName( aLibName );
810 aElement >>= xModLibImport;
811
812 if ( xModLibImport.is() )
813 {
814 // load library
815 if ( !xModLibContImport->isLibraryLoaded( aLibName ) )
816 xModLibContImport->loadLibrary( aLibName );
817
818 // copy all modules
819 Sequence< OUString > aModNames = xModLibImport->getElementNames();
820 sal_Int32 nModCount = aModNames.getLength();
821 const OUString* pModNames = aModNames.getConstArray();
822 for ( sal_Int32 i = 0 ; i < nModCount ; i++ )
823 {
824 OUString aModName( pModNames[ i ] );
825 Any aElement_ = xModLibImport->getByName( aModName );
826 xModLib->insertByName( aModName, aElement_ );
827 }
828
829 // set password
830 if ( bOK )
831 {
832 Reference< script::XLibraryContainerPassword > xPasswd( xModLibContainer, UNO_QUERY );
833 if ( xPasswd.is() )
834 {
835 try
836 {
837 xPasswd->changeLibraryPassword( aLibName, OUString(), aPassword );
838 }
839 catch (...)
840 {
841 }
842 }
843 }
844 }
845 }
846 }
847 }
848
849 // copy dialog library
850 if ( xDlgLibContImport.is() && xDlgLibContImport->hasByName( aLibName ) && xDlgLibContainer.is() && !xDlgLibContainer->hasByName( aLibName ) )
851 {
852 Reference< container::XNameContainer > xDlgLib;
853 if ( bReference )
854 {
855 // storage URL
856 INetURLObject aDlgStorageURLObj( *xDlgURLObj );
857 if ( aExtension == aContExtension )
858 {
859 sal_Int32 nCount = aDlgStorageURLObj.getSegmentCount();
860 aDlgStorageURLObj.insertName( aLibName, false, nCount - 1 );
861 aDlgStorageURLObj.setExtension( aLibExtension );
862 aDlgStorageURLObj.setFinalSlash();
863 }
864 OUString aDlgStorageURL( aDlgStorageURLObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
865
866 // create library link
867 xDlgLib.set( xDlgLibContainer->createLibraryLink( aLibName, aDlgStorageURL, true ), UNO_QUERY);
868 }
869 else
870 {
871 // create library
872 xDlgLib = xDlgLibContainer->createLibrary( aLibName );
873 if ( xDlgLib.is() )
874 {
875 // get import library
876 Reference< container::XNameContainer > xDlgLibImport;
877 Any aElement = xDlgLibContImport->getByName( aLibName );
878 aElement >>= xDlgLibImport;
879
880 if ( xDlgLibImport.is() )
881 {
882 // load library
883 if ( !xDlgLibContImport->isLibraryLoaded( aLibName ) )
884 xDlgLibContImport->loadLibrary( aLibName );
885
886 // copy all dialogs
887 Sequence< OUString > aDlgNames = xDlgLibImport->getElementNames();
888 sal_Int32 nDlgCount = aDlgNames.getLength();
889 const OUString* pDlgNames = aDlgNames.getConstArray();
890 for ( sal_Int32 i = 0 ; i < nDlgCount ; i++ )
891 {
892 OUString aDlgName( pDlgNames[ i ] );
893 Any aElement_ = xDlgLibImport->getByName( aDlgName );
894 xDlgLib->insertByName( aDlgName, aElement_ );
895 }
896 }
897 }
898 }
899 }
900
901 // insert listbox entry
902 ImpInsertLibEntry( aLibName, m_xLibBox->n_children() );
903 m_xLibBox->set_cursor( m_xLibBox->find_text(aLibName) );
904 bChanges = true;
905 }
906 }
907
908 if ( bChanges )
909 MarkDocumentModified( m_aCurDocument );
910 });
911 }
912
Export()913 void LibPage::Export()
914 {
915 std::unique_ptr<weld::TreeIter> xCurEntry(m_xLibBox->make_iterator());
916 if (!m_xLibBox->get_cursor(xCurEntry.get()))
917 return;
918 OUString aLibName(m_xLibBox->get_text(*xCurEntry, 0));
919
920 // Password verification
921 Reference< script::XLibraryContainer2 > xModLibContainer( m_aCurDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
922
923 if ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) && !xModLibContainer->isLibraryLoaded( aLibName ) )
924 {
925 bool bOK = true;
926
927 // check password
928 Reference< script::XLibraryContainerPassword > xPasswd( xModLibContainer, UNO_QUERY );
929 if ( xPasswd.is() && xPasswd->isLibraryPasswordProtected( aLibName ) && !xPasswd->isLibraryPasswordVerified( aLibName ) )
930 {
931 OUString aPassword;
932 bOK = QueryPassword(m_pDialog->getDialog(), xModLibContainer, aLibName, aPassword);
933 }
934 if ( !bOK )
935 return;
936 }
937
938 std::unique_ptr<ExportDialog> xNewDlg(new ExportDialog(m_pDialog->getDialog()));
939 if (xNewDlg->run() != RET_OK)
940 return;
941
942 try
943 {
944 bool bExportAsPackage = xNewDlg->isExportAsPackage();
945 //tdf#112063 ensure closing xNewDlg is not selected as
946 //parent of file dialog from ExportAs...
947 xNewDlg.reset();
948 if (bExportAsPackage)
949 ExportAsPackage( aLibName );
950 else
951 ExportAsBasic( aLibName );
952 }
953 catch(const util::VetoException& ) // user canceled operation
954 {
955 }
956 }
957
implExportLib(const OUString & aLibName,const OUString & aTargetURL,const Reference<task::XInteractionHandler> & Handler)958 void LibPage::implExportLib( const OUString& aLibName, const OUString& aTargetURL,
959 const Reference< task::XInteractionHandler >& Handler )
960 {
961 Reference< script::XLibraryContainerExport > xModLibContainerExport
962 ( m_aCurDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
963 Reference< script::XLibraryContainerExport > xDlgLibContainerExport
964 ( m_aCurDocument.getLibraryContainer( E_DIALOGS ), UNO_QUERY );
965 if ( xModLibContainerExport.is() )
966 xModLibContainerExport->exportLibrary( aLibName, aTargetURL, Handler );
967
968 if (!xDlgLibContainerExport.is())
969 return;
970 Reference<container::XNameAccess> xNameAcc(xDlgLibContainerExport, UNO_QUERY);
971 if (!xNameAcc.is())
972 return;
973 if (!xNameAcc->hasByName(aLibName))
974 return;
975 xDlgLibContainerExport->exportLibrary(aLibName, aTargetURL, Handler);
976 }
977
978 // Implementation XCommandEnvironment
979
980 namespace {
981
982 class OLibCommandEnvironment : public cppu::WeakImplHelper< XCommandEnvironment >
983 {
984 Reference< task::XInteractionHandler > mxInteraction;
985
986 public:
OLibCommandEnvironment(const Reference<task::XInteractionHandler> & xInteraction)987 explicit OLibCommandEnvironment(const Reference<task::XInteractionHandler>& xInteraction)
988 : mxInteraction( xInteraction )
989 {}
990
991 // Methods
992 virtual Reference< task::XInteractionHandler > SAL_CALL getInteractionHandler() override;
993 virtual Reference< XProgressHandler > SAL_CALL getProgressHandler() override;
994 };
995
996 }
997
getInteractionHandler()998 Reference< task::XInteractionHandler > OLibCommandEnvironment::getInteractionHandler()
999 {
1000 return mxInteraction;
1001 }
1002
getProgressHandler()1003 Reference< XProgressHandler > OLibCommandEnvironment::getProgressHandler()
1004 {
1005 Reference< XProgressHandler > xRet;
1006 return xRet;
1007 }
1008
ExportAsPackage(const OUString & aLibName)1009 void LibPage::ExportAsPackage( const OUString& aLibName )
1010 {
1011 // file open dialog
1012 sfx2::FileDialogHelper aDlg(ui::dialogs::TemplateDescription::FILESAVE_SIMPLE, FileDialogFlags::NONE, m_pDialog->getDialog());
1013 const Reference <XFilePicker3>& xFP = aDlg.GetFilePicker();
1014
1015 Reference< uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
1016 Reference< task::XInteractionHandler2 > xHandler( task::InteractionHandler::createWithParent(xContext, nullptr) );
1017 Reference< XSimpleFileAccess3 > xSFA = SimpleFileAccess::create(xContext);
1018
1019 xFP->setTitle(IDEResId(RID_STR_EXPORTPACKAGE));
1020
1021 // filter
1022 OUString aTitle(IDEResId(RID_STR_PACKAGE_BUNDLE));
1023 xFP->appendFilter( aTitle, "*.oxt" ); // library files
1024
1025 // set display directory and filter
1026 OUString aPath = GetExtraData()->GetAddLibPath();
1027 if ( !aPath.isEmpty() )
1028 {
1029 xFP->setDisplayDirectory( aPath );
1030 }
1031 else
1032 {
1033 // macro path from configuration management
1034 xFP->setDisplayDirectory( SvtPathOptions().GetWorkPath() );
1035 }
1036 xFP->setCurrentFilter( aTitle );
1037
1038 if ( xFP->execute() != RET_OK )
1039 return;
1040
1041 GetExtraData()->SetAddLibPath(xFP->getDisplayDirectory());
1042
1043 Sequence< OUString > aFiles = xFP->getSelectedFiles();
1044 INetURLObject aURL( aFiles[0] );
1045 if( aURL.getExtension().isEmpty() )
1046 aURL.setExtension( u"oxt" );
1047
1048 OUString aPackageURL( aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
1049
1050 OUString aTmpPath = SvtPathOptions().GetTempPath();
1051 INetURLObject aInetObj( aTmpPath );
1052 aInetObj.insertName( aLibName, true, INetURLObject::LAST_SEGMENT, INetURLObject::EncodeMechanism::All );
1053 OUString aSourcePath = aInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
1054 if( xSFA->exists( aSourcePath ) )
1055 xSFA->kill( aSourcePath );
1056 Reference< task::XInteractionHandler > xDummyHandler( new DummyInteractionHandler( xHandler ) );
1057 implExportLib( aLibName, aTmpPath, xDummyHandler );
1058
1059 Reference< XCommandEnvironment > xCmdEnv = new OLibCommandEnvironment(xHandler);
1060
1061 ::ucbhelper::Content sourceContent( aSourcePath, xCmdEnv, comphelper::getProcessComponentContext() );
1062
1063 OUString destFolder = "vnd.sun.star.zip://" +
1064 ::rtl::Uri::encode( aPackageURL,
1065 rtl_UriCharClassRegName,
1066 rtl_UriEncodeIgnoreEscapes,
1067 RTL_TEXTENCODING_UTF8 ) +
1068 "/";
1069
1070 if( xSFA->exists( aPackageURL ) )
1071 xSFA->kill( aPackageURL );
1072
1073 ::ucbhelper::Content destFolderContent( destFolder, xCmdEnv, comphelper::getProcessComponentContext() );
1074 destFolderContent.transferContent(
1075 sourceContent, ::ucbhelper::InsertOperation::Copy,
1076 OUString(), NameClash::OVERWRITE );
1077
1078 INetURLObject aMetaInfInetObj( aTmpPath );
1079 aMetaInfInetObj.insertName( u"META-INF",
1080 true, INetURLObject::LAST_SEGMENT, INetURLObject::EncodeMechanism::All );
1081 OUString aMetaInfFolder = aMetaInfInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
1082 if( xSFA->exists( aMetaInfFolder ) )
1083 xSFA->kill( aMetaInfFolder );
1084 xSFA->createFolder( aMetaInfFolder );
1085
1086 std::vector< Sequence<beans::PropertyValue> > manifest;
1087
1088 OUString fullPath = aLibName
1089 + "/" ;
1090 auto attribs(::comphelper::InitPropertySequence({
1091 { "FullPath", Any(fullPath) },
1092 { "MediaType", Any(OUString("application/vnd.sun.star.basic-library")) }
1093 }));
1094 manifest.push_back( attribs );
1095
1096 // write into pipe:
1097 Reference<packages::manifest::XManifestWriter> xManifestWriter = packages::manifest::ManifestWriter::create( xContext );
1098 Reference<io::XOutputStream> xPipe( io::Pipe::create( xContext ), UNO_QUERY_THROW );
1099 xManifestWriter->writeManifestSequence(
1100 xPipe, Sequence< Sequence<beans::PropertyValue> >(
1101 manifest.data(), manifest.size() ) );
1102
1103 aMetaInfInetObj.insertName( u"manifest.xml",
1104 true, INetURLObject::LAST_SEGMENT, INetURLObject::EncodeMechanism::All );
1105
1106 // write buffered pipe data to content:
1107 ::ucbhelper::Content manifestContent( aMetaInfInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ), xCmdEnv, comphelper::getProcessComponentContext() );
1108 manifestContent.writeStream( Reference<io::XInputStream>( xPipe, UNO_QUERY_THROW ), true );
1109
1110 ::ucbhelper::Content MetaInfContent( aMetaInfFolder, xCmdEnv, comphelper::getProcessComponentContext() );
1111 destFolderContent.transferContent(
1112 MetaInfContent, ::ucbhelper::InsertOperation::Copy,
1113 OUString(), NameClash::OVERWRITE );
1114
1115 if( xSFA->exists( aSourcePath ) )
1116 xSFA->kill( aSourcePath );
1117 if( xSFA->exists( aMetaInfFolder ) )
1118 xSFA->kill( aMetaInfFolder );
1119 }
1120
ExportAsBasic(const OUString & aLibName)1121 void LibPage::ExportAsBasic( const OUString& aLibName )
1122 {
1123 // Folder picker
1124 Reference< uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
1125 Reference< XFolderPicker2 > xFolderPicker = FolderPicker::create(xContext);
1126 Reference< task::XInteractionHandler2 > xHandler( task::InteractionHandler::createWithParent(xContext, nullptr) );
1127
1128 xFolderPicker->setTitle(IDEResId(RID_STR_EXPORTBASIC));
1129
1130 // set display directory and filter
1131 OUString aPath =GetExtraData()->GetAddLibPath();
1132 if( aPath.isEmpty() )
1133 aPath = SvtPathOptions().GetWorkPath();
1134
1135 // INetURLObject aURL(m_sSavePath, INetProtocol::File);
1136 xFolderPicker->setDisplayDirectory( aPath );
1137 short nRet = xFolderPicker->execute();
1138 if( nRet == RET_OK )
1139 {
1140 OUString aTargetURL = xFolderPicker->getDirectory();
1141 GetExtraData()->SetAddLibPath(aTargetURL);
1142
1143 Reference< task::XInteractionHandler > xDummyHandler( new DummyInteractionHandler( xHandler ) );
1144 implExportLib( aLibName, aTargetURL, xDummyHandler );
1145 }
1146 }
1147
DeleteCurrent()1148 void LibPage::DeleteCurrent()
1149 {
1150 std::unique_ptr<weld::TreeIter> xCurEntry(m_xLibBox->make_iterator());
1151 if (!m_xLibBox->get_cursor(xCurEntry.get()))
1152 return;
1153 OUString aLibName(m_xLibBox->get_text(*xCurEntry, 0));
1154
1155 // check, if library is link
1156 bool bIsLibraryLink = false;
1157 Reference< script::XLibraryContainer2 > xModLibContainer( m_aCurDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
1158 Reference< script::XLibraryContainer2 > xDlgLibContainer( m_aCurDocument.getLibraryContainer( E_DIALOGS ), UNO_QUERY );
1159 if ( ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) && xModLibContainer->isLibraryLink( aLibName ) ) ||
1160 ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) && xDlgLibContainer->isLibraryLink( aLibName ) ) )
1161 {
1162 bIsLibraryLink = true;
1163 }
1164
1165 if (!QueryDelLib(aLibName, bIsLibraryLink, m_pDialog->getDialog()))
1166 return;
1167
1168 // inform BasicIDE
1169 SfxUnoAnyItem aDocItem( SID_BASICIDE_ARG_DOCUMENT_MODEL, Any( m_aCurDocument.getDocumentOrNull() ) );
1170 SfxStringItem aLibNameItem( SID_BASICIDE_ARG_LIBNAME, aLibName );
1171 if (SfxDispatcher* pDispatcher = GetDispatcher())
1172 pDispatcher->ExecuteList(SID_BASICIDE_LIBREMOVED,
1173 SfxCallMode::SYNCHRON, { &aDocItem, &aLibNameItem });
1174
1175 // remove library from module and dialog library containers
1176 if ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) )
1177 xModLibContainer->removeLibrary( aLibName );
1178 if ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) )
1179 xDlgLibContainer->removeLibrary( aLibName );
1180
1181 m_xLibBox->remove(*xCurEntry);
1182 MarkDocumentModified( m_aCurDocument );
1183 }
1184
EndTabDialog()1185 void LibPage::EndTabDialog()
1186 {
1187 m_pDialog->response(RET_OK);
1188 }
1189
FillListBox()1190 void LibPage::FillListBox()
1191 {
1192 InsertListBoxEntry( ScriptDocument::getApplicationScriptDocument(), LIBRARY_LOCATION_USER );
1193 InsertListBoxEntry( ScriptDocument::getApplicationScriptDocument(), LIBRARY_LOCATION_SHARE );
1194
1195 ScriptDocuments aDocuments( ScriptDocument::getAllScriptDocuments( ScriptDocument::DocumentsSorted ) );
1196 for (auto const& doc : aDocuments)
1197 {
1198 InsertListBoxEntry( doc, LIBRARY_LOCATION_DOCUMENT );
1199 }
1200 }
1201
InsertListBoxEntry(const ScriptDocument & rDocument,LibraryLocation eLocation)1202 void LibPage::InsertListBoxEntry( const ScriptDocument& rDocument, LibraryLocation eLocation )
1203 {
1204 OUString aEntryText(rDocument.getTitle(eLocation));
1205 OUString sId(OUString::number(reinterpret_cast<sal_Int64>(new DocumentEntry(rDocument, eLocation))));
1206 m_xBasicsBox->append(sId, aEntryText);
1207 }
1208
SetCurLib()1209 void LibPage::SetCurLib()
1210 {
1211 DocumentEntry* pEntry = reinterpret_cast<DocumentEntry*>(m_xBasicsBox->get_active_id().toInt64());
1212 if (!pEntry)
1213 return;
1214
1215 const ScriptDocument& aDocument( pEntry->GetDocument() );
1216 DBG_ASSERT( aDocument.isAlive(), "LibPage::SetCurLib: no document, or document is dead!" );
1217 if ( !aDocument.isAlive() )
1218 return;
1219 LibraryLocation eLocation = pEntry->GetLocation();
1220 if ( aDocument == m_aCurDocument && eLocation == m_eCurLocation )
1221 return;
1222
1223 m_aCurDocument = aDocument;
1224 m_eCurLocation = eLocation;
1225 m_xLibBox->clear();
1226
1227 // get a sorted list of library names
1228 Sequence< OUString > aLibNames = aDocument.getLibraryNames();
1229 sal_Int32 nLibCount = aLibNames.getLength();
1230 const OUString* pLibNames = aLibNames.getConstArray();
1231
1232 int nEntry = 0;
1233 for (int i = 0 ; i < nLibCount; ++i)
1234 {
1235 OUString aLibName(pLibNames[i]);
1236 if (eLocation == aDocument.getLibraryLocation(aLibName))
1237 ImpInsertLibEntry(aLibName, nEntry++);
1238 }
1239
1240 int nEntry_ = FindEntry(*m_xLibBox, "Standard");
1241 if (nEntry_ == -1 && m_xLibBox->n_children())
1242 nEntry_ = 0;
1243 m_xLibBox->set_cursor(nEntry_);
1244 }
1245
ImpInsertLibEntry(const OUString & rLibName,sal_uLong nPos)1246 void LibPage::ImpInsertLibEntry( const OUString& rLibName, sal_uLong nPos )
1247 {
1248 // check, if library is password protected
1249 bool bProtected = false;
1250 Reference< script::XLibraryContainer2 > xModLibContainer( m_aCurDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
1251 if ( xModLibContainer.is() && xModLibContainer->hasByName( rLibName ) )
1252 {
1253 Reference< script::XLibraryContainerPassword > xPasswd( xModLibContainer, UNO_QUERY );
1254 if ( xPasswd.is() )
1255 {
1256 bProtected = xPasswd->isLibraryPasswordProtected( rLibName );
1257 }
1258 }
1259
1260 m_xLibBox->insert_text(nPos, rLibName);
1261
1262 if (bProtected)
1263 m_xLibBox->set_image(nPos, RID_BMP_LOCKED);
1264
1265 // check, if library is link
1266 if ( xModLibContainer.is() && xModLibContainer->hasByName( rLibName ) && xModLibContainer->isLibraryLink( rLibName ) )
1267 {
1268 OUString aLinkURL = xModLibContainer->getLibraryLinkURL( rLibName );
1269 m_xLibBox->set_text(nPos, aLinkURL, 1);
1270 }
1271 }
1272
1273 // Helper function
createLibImpl(weld::Window * pWin,const ScriptDocument & rDocument,weld::TreeView * pLibBox,SbTreeListBox * pBasicBox)1274 void createLibImpl(weld::Window* pWin, const ScriptDocument& rDocument,
1275 weld::TreeView* pLibBox, SbTreeListBox* pBasicBox)
1276 {
1277 OSL_ENSURE( rDocument.isAlive(), "createLibImpl: invalid document!" );
1278 if ( !rDocument.isAlive() )
1279 return;
1280
1281 // create library name
1282 OUString aLibName;
1283 bool bValid = false;
1284 sal_Int32 i = 1;
1285 while ( !bValid )
1286 {
1287 aLibName = "Library" + OUString::number( i );
1288 if ( !rDocument.hasLibrary( E_SCRIPTS, aLibName ) && !rDocument.hasLibrary( E_DIALOGS, aLibName ) )
1289 bValid = true;
1290 i++;
1291 }
1292
1293 NewObjectDialog aNewDlg(pWin, ObjectMode::Library);
1294 aNewDlg.SetObjectName(aLibName);
1295
1296 if (!aNewDlg.run())
1297 return;
1298
1299 if (!aNewDlg.GetObjectName().isEmpty())
1300 aLibName = aNewDlg.GetObjectName();
1301
1302 if ( aLibName.getLength() > 30 )
1303 {
1304 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(pWin,
1305 VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_LIBNAMETOLONG)));
1306 xErrorBox->run();
1307 }
1308 else if ( !IsValidSbxName( aLibName ) )
1309 {
1310 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(pWin,
1311 VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_BADSBXNAME)));
1312 xErrorBox->run();
1313 }
1314 else if ( rDocument.hasLibrary( E_SCRIPTS, aLibName ) || rDocument.hasLibrary( E_DIALOGS, aLibName ) )
1315 {
1316 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(pWin,
1317 VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_SBXNAMEALLREADYUSED2)));
1318 xErrorBox->run();
1319 }
1320 else
1321 {
1322 try
1323 {
1324 // create module and dialog library
1325 rDocument.getOrCreateLibrary( E_SCRIPTS, aLibName );
1326 rDocument.getOrCreateLibrary( E_DIALOGS, aLibName );
1327
1328 if( pLibBox )
1329 {
1330 pLibBox->append_text(aLibName);
1331 pLibBox->set_cursor(pLibBox->find_text(aLibName));
1332 }
1333
1334 // create a module
1335 OUString aModName = rDocument.createObjectName( E_SCRIPTS, aLibName );
1336 OUString sModuleCode;
1337 if ( !rDocument.createModule( aLibName, aModName, true, sModuleCode ) )
1338 throw Exception("could not create module " + aModName, nullptr);
1339
1340 SbxItem aSbxItem( SID_BASICIDE_ARG_SBX, rDocument, aLibName, aModName, TYPE_MODULE );
1341 if (SfxDispatcher* pDispatcher = GetDispatcher())
1342 pDispatcher->ExecuteList(SID_BASICIDE_SBXINSERTED,
1343 SfxCallMode::SYNCHRON, { &aSbxItem });
1344
1345 if( pBasicBox )
1346 {
1347 std::unique_ptr<weld::TreeIter> xIter(pBasicBox->make_iterator(nullptr));
1348 bool bValidIter = pBasicBox->get_cursor(xIter.get());
1349 std::unique_ptr<weld::TreeIter> xRootEntry(pBasicBox->make_iterator(xIter.get()));
1350 while (bValidIter)
1351 {
1352 pBasicBox->copy_iterator(*xIter, *xRootEntry);
1353 bValidIter = pBasicBox->iter_parent(*xIter);
1354 }
1355
1356 BrowseMode nMode = pBasicBox->GetMode();
1357 bool bDlgMode = ( nMode & BrowseMode::Dialogs ) && !( nMode & BrowseMode::Modules );
1358 const auto sId = bDlgMode ? std::u16string_view(u"" RID_BMP_DLGLIB) : std::u16string_view(u"" RID_BMP_MODLIB);
1359 pBasicBox->AddEntry(aLibName, OUString(sId), xRootEntry.get(), false, std::make_unique<Entry>(OBJ_TYPE_LIBRARY));
1360 pBasicBox->AddEntry(aModName, RID_BMP_MODULE, xRootEntry.get(), false, std::make_unique<Entry>(OBJ_TYPE_MODULE));
1361 pBasicBox->set_cursor(*xRootEntry);
1362 pBasicBox->select(*xRootEntry);
1363 }
1364 }
1365 catch (const uno::Exception& )
1366 {
1367 DBG_UNHANDLED_EXCEPTION("basctl.basicide");
1368 }
1369 }
1370 }
1371
1372 } // namespace basctl
1373
1374 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1375