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 <svx/passwd.hxx>
28 #include <ucbhelper/content.hxx>
29 #include <rtl/uri.hxx>
30 #include <sfx2/app.hxx>
31 #include <sfx2/dinfdlg.hxx>
32 #include <sfx2/dispatch.hxx>
33 #include <sfx2/filedlghelper.hxx>
34 #include <sfx2/request.hxx>
35 #include <sfx2/sfxsids.hrc>
36 #include <sfx2/viewfrm.hxx>
37 #include <tools/debug.hxx>
38 #include <tools/urlobj.hxx>
39 #include <tools/diagnose_ex.h>
40 #include <vcl/svapp.hxx>
41 #include <vcl/weld.hxx>
42
43 #include <com/sun/star/io/Pipe.hpp>
44 #include <com/sun/star/ui/dialogs/FilePicker.hpp>
45 #include <com/sun/star/ui/dialogs/FolderPicker.hpp>
46 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
47 #include <com/sun/star/script/DocumentScriptLibraryContainer.hpp>
48 #include <com/sun/star/script/DocumentDialogLibraryContainer.hpp>
49 #include <com/sun/star/script/XLibraryContainerPassword.hpp>
50 #include <com/sun/star/script/XLibraryContainerExport.hpp>
51 #include <com/sun/star/task/InteractionHandler.hpp>
52 #include <com/sun/star/ucb/SimpleFileAccess.hpp>
53 #include <com/sun/star/ucb/XCommandEnvironment.hpp>
54 #include <com/sun/star/ucb/NameClash.hpp>
55 #include <com/sun/star/packages/manifest/ManifestWriter.hpp>
56 #include <unotools/pathoptions.hxx>
57
58 #include <com/sun/star/util/VetoException.hpp>
59 #include <com/sun/star/script/ModuleSizeExceededRequest.hpp>
60
61 #include <comphelper/processfactory.hxx>
62 #include <comphelper/propertysequence.hxx>
63 #include <cppuhelper/implbase.hxx>
64
65 #include <cassert>
66
67 namespace basctl
68 {
69
70 using namespace ::com::sun::star;
71 using namespace ::com::sun::star::uno;
72 using namespace ::com::sun::star::lang;
73 using namespace ::com::sun::star::ucb;
74 using namespace ::com::sun::star::ui::dialogs;
75
76 namespace
77 {
78
79 class DummyInteractionHandler : public ::cppu::WeakImplHelper< task::XInteractionHandler >
80 {
81 Reference< task::XInteractionHandler2 > m_xHandler;
82 public:
DummyInteractionHandler(const Reference<task::XInteractionHandler2> & xHandler)83 explicit DummyInteractionHandler(const Reference<task::XInteractionHandler2>& xHandler)
84 : m_xHandler(xHandler)
85 {
86 }
87
handle(const Reference<task::XInteractionRequest> & rRequest)88 virtual void SAL_CALL handle( const Reference< task::XInteractionRequest >& rRequest ) override
89 {
90 if ( m_xHandler.is() )
91 {
92 script::ModuleSizeExceededRequest aModSizeException;
93 if ( rRequest->getRequest() >>= aModSizeException )
94 m_xHandler->handle( rRequest );
95 }
96 }
97 };
98
99 } // namespace
100
101 namespace
102 {
FindEntry(const weld::TreeView & rBox,const OUString & rName)103 int FindEntry(const weld::TreeView& rBox, const OUString& rName)
104 {
105 int nCount = rBox.n_children();
106 for (int i = 0; i < nCount; ++i)
107 {
108 if (rName.equalsIgnoreAsciiCase(rBox.get_text(i, 0)))
109 return i;
110 }
111 return -1;
112 }
113 }
114
115 // NewObjectDialog
IMPL_LINK_NOARG(NewObjectDialog,OkButtonHandler,weld::Button &,void)116 IMPL_LINK_NOARG(NewObjectDialog, OkButtonHandler, weld::Button&, void)
117 {
118 if (!m_bCheckName || IsValidSbxName(m_xEdit->get_text()))
119 m_xDialog->response(RET_OK);
120 else
121 {
122 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_xDialog.get(),
123 VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_BADSBXNAME)));
124 xErrorBox->run();
125 m_xEdit->grab_focus();
126 }
127 }
128
NewObjectDialog(weld::Window * pParent,ObjectMode eMode,bool bCheckName)129 NewObjectDialog::NewObjectDialog(weld::Window * pParent, ObjectMode eMode, bool bCheckName)
130 : GenericDialogController(pParent, "modules/BasicIDE/ui/newlibdialog.ui", "NewLibDialog")
131 , m_xEdit(m_xBuilder->weld_entry("entry"))
132 , m_xOKButton(m_xBuilder->weld_button("ok"))
133 , m_bCheckName(bCheckName)
134 {
135 switch (eMode)
136 {
137 case ObjectMode::Library:
138 m_xDialog->set_title(IDEResId(RID_STR_NEWLIB));
139 break;
140 case ObjectMode::Module:
141 m_xDialog->set_title(IDEResId(RID_STR_NEWMOD));
142 break;
143 case ObjectMode::Dialog:
144 m_xDialog->set_title(IDEResId(RID_STR_NEWDLG));
145 break;
146 default:
147 assert(false);
148 }
149 m_xOKButton->connect_clicked(LINK(this, NewObjectDialog, OkButtonHandler));
150 }
151
152 // GotoLineDialog
GotoLineDialog(weld::Window * pParent)153 GotoLineDialog::GotoLineDialog(weld::Window* pParent )
154 : GenericDialogController(pParent, "modules/BasicIDE/ui/gotolinedialog.ui", "GotoLineDialog")
155 , m_xEdit(m_xBuilder->weld_entry("entry"))
156 , m_xOKButton(m_xBuilder->weld_button("ok"))
157 {
158 m_xEdit->grab_focus();
159 m_xOKButton->connect_clicked(LINK(this, GotoLineDialog, OkButtonHandler));
160 }
161
~GotoLineDialog()162 GotoLineDialog::~GotoLineDialog()
163 {
164 }
165
GetLineNumber() const166 sal_Int32 GotoLineDialog::GetLineNumber() const
167 {
168 return m_xEdit->get_text().toInt32();
169 }
170
IMPL_LINK_NOARG(GotoLineDialog,OkButtonHandler,weld::Button &,void)171 IMPL_LINK_NOARG(GotoLineDialog, OkButtonHandler, weld::Button&, void)
172 {
173 if (GetLineNumber())
174 m_xDialog->response(RET_OK);
175 else
176 m_xEdit->select_region(0, -1);
177 }
178
179 // ExportDialog
IMPL_LINK_NOARG(ExportDialog,OkButtonHandler,weld::Button &,void)180 IMPL_LINK_NOARG(ExportDialog, OkButtonHandler, weld::Button&, void)
181 {
182 m_bExportAsPackage = m_xExportAsPackageButton->get_active();
183 m_xDialog->response(RET_OK);
184 }
185
ExportDialog(weld::Window * pParent)186 ExportDialog::ExportDialog(weld::Window * pParent)
187 : GenericDialogController(pParent, "modules/BasicIDE/ui/exportdialog.ui", "ExportDialog")
188 , m_bExportAsPackage(false)
189 , m_xExportAsPackageButton(m_xBuilder->weld_radio_button("extension"))
190 , m_xOKButton(m_xBuilder->weld_button("ok"))
191 {
192 m_xExportAsPackageButton->set_active(true);
193 m_xOKButton->connect_clicked(LINK(this, ExportDialog, OkButtonHandler));
194 }
195
~ExportDialog()196 ExportDialog::~ExportDialog()
197 {
198 }
199
200 // LibPage
LibPage(weld::Container * pParent,OrganizeDialog * pDialog)201 LibPage::LibPage(weld::Container* pParent, OrganizeDialog* pDialog)
202 : OrganizePage(pParent, "modules/BasicIDE/ui/libpage.ui", "LibPage", pDialog)
203 , m_xBasicsBox(m_xBuilder->weld_combo_box("location"))
204 , m_xLibBox(m_xBuilder->weld_tree_view("library"))
205 , m_xEditButton(m_xBuilder->weld_button("edit"))
206 , m_xPasswordButton(m_xBuilder->weld_button("password"))
207 , m_xNewLibButton(m_xBuilder->weld_button("new"))
208 , m_xInsertLibButton(m_xBuilder->weld_button("import"))
209 , m_xExportButton(m_xBuilder->weld_button("export"))
210 , m_xDelButton(m_xBuilder->weld_button("delete"))
211 , m_aCurDocument(ScriptDocument::getApplicationScriptDocument())
212 , m_eCurLocation(LIBRARY_LOCATION_UNKNOWN)
213 {
214 Size aSize(m_xLibBox->get_approximate_digit_width() * 40,
215 m_xLibBox->get_height_rows(10));
216 m_xLibBox->set_size_request(aSize.Width(), aSize.Height());
217
218 // tdf#93476 The libraries should be listed alphabetically
219 m_xLibBox->make_sorted();
220
221 m_xEditButton->connect_clicked( LINK( this, LibPage, ButtonHdl ) );
222 m_xNewLibButton->connect_clicked( LINK( this, LibPage, ButtonHdl ) );
223 m_xPasswordButton->connect_clicked( LINK( this, LibPage, ButtonHdl ) );
224 m_xExportButton->connect_clicked( LINK( this, LibPage, ButtonHdl ) );
225 m_xInsertLibButton->connect_clicked( LINK( this, LibPage, ButtonHdl ) );
226 m_xDelButton->connect_clicked( LINK( this, LibPage, ButtonHdl ) );
227 m_xLibBox->connect_changed( LINK( this, LibPage, TreeListHighlightHdl ) );
228
229 m_xBasicsBox->connect_changed( LINK( this, LibPage, BasicSelectHdl ) );
230
231 m_xLibBox->connect_editing(LINK(this, LibPage, EditingEntryHdl),
232 LINK(this, LibPage, EditedEntryHdl));
233
234 FillListBox();
235 m_xBasicsBox->set_active(0);
236 SetCurLib();
237
238 CheckButtons();
239 }
240
IMPL_LINK(LibPage,EditingEntryHdl,const weld::TreeIter &,rIter,bool)241 IMPL_LINK(LibPage, EditingEntryHdl, const weld::TreeIter&, rIter, bool)
242 {
243 // check, if Standard library
244 OUString aLibName = m_xLibBox->get_text(rIter, 0);
245
246 if ( aLibName.equalsIgnoreAsciiCase( "Standard" ) )
247 {
248 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_pDialog->getDialog(),
249 VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_CANNOTCHANGENAMESTDLIB)));
250 xErrorBox->run();
251 return false;
252 }
253
254 // check, if library is readonly
255 Reference< script::XLibraryContainer2 > xModLibContainer( m_aCurDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
256 Reference< script::XLibraryContainer2 > xDlgLibContainer( m_aCurDocument.getLibraryContainer( E_DIALOGS ), UNO_QUERY );
257 if ( ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) && xModLibContainer->isLibraryReadOnly( aLibName ) && !xModLibContainer->isLibraryLink( aLibName ) ) ||
258 ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) && xDlgLibContainer->isLibraryReadOnly( aLibName ) && !xDlgLibContainer->isLibraryLink( aLibName ) ) )
259 {
260 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_pDialog->getDialog(),
261 VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_LIBISREADONLY)));
262 xErrorBox->run();
263 return false;
264 }
265
266 // i24094: Password verification necessary for renaming
267 if ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) && !xModLibContainer->isLibraryLoaded( aLibName ) )
268 {
269 bool bOK = true;
270 // check password
271 Reference< script::XLibraryContainerPassword > xPasswd( xModLibContainer, UNO_QUERY );
272 if ( xPasswd.is() && xPasswd->isLibraryPasswordProtected( aLibName ) && !xPasswd->isLibraryPasswordVerified( aLibName ) )
273 {
274 OUString aPassword;
275 bOK = QueryPassword(m_pDialog->getDialog(), xModLibContainer, aLibName, aPassword);
276 }
277 if ( !bOK )
278 return false;
279 }
280
281 // TODO: check if library is reference/link
282
283 return true;
284 }
285
IMPL_LINK(LibPage,EditedEntryHdl,const IterString &,rIterString,bool)286 IMPL_LINK(LibPage, EditedEntryHdl, const IterString&, rIterString, bool)
287 {
288 const weld::TreeIter& rIter = rIterString.first;
289 OUString sNewName = rIterString.second;
290
291 bool bValid = sNewName.getLength() <= 30 && IsValidSbxName(sNewName);
292 OUString aOldName(m_xLibBox->get_text(rIter, 0));
293
294 if (bValid && aOldName != sNewName)
295 {
296 try
297 {
298 Reference< script::XLibraryContainer2 > xModLibContainer( m_aCurDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
299 if ( xModLibContainer.is() )
300 xModLibContainer->renameLibrary( aOldName, sNewName );
301
302 Reference< script::XLibraryContainer2 > xDlgLibContainer( m_aCurDocument.getLibraryContainer( E_DIALOGS ), UNO_QUERY );
303 if ( xDlgLibContainer.is() )
304 xDlgLibContainer->renameLibrary( aOldName, sNewName );
305
306 MarkDocumentModified( m_aCurDocument );
307 if (SfxBindings* pBindings = GetBindingsPtr())
308 {
309 pBindings->Invalidate( SID_BASICIDE_LIBSELECTOR );
310 pBindings->Update( SID_BASICIDE_LIBSELECTOR );
311 }
312 }
313 catch (const container::ElementExistException& )
314 {
315 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_pDialog->getDialog(),
316 VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_SBXNAMEALLREADYUSED)));
317 xErrorBox->run();
318 return false;
319 }
320 catch (const container::NoSuchElementException& )
321 {
322 DBG_UNHANDLED_EXCEPTION("basctl.basicide");
323 return false;
324 }
325 }
326
327 if ( !bValid )
328 {
329 OUString sWarning(sNewName.getLength() > 30 ? IDEResId(RID_STR_LIBNAMETOLONG) : IDEResId(RID_STR_BADSBXNAME));
330 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_pDialog->getDialog(),
331 VclMessageType::Warning, VclButtonsType::Ok, sWarning));
332 xErrorBox->run();
333
334 }
335
336 return bValid;
337 }
338
~LibPage()339 LibPage::~LibPage()
340 {
341 if (m_xBasicsBox)
342 {
343 const sal_Int32 nCount = m_xBasicsBox->get_count();
344 for (sal_Int32 i = 0; i < nCount; ++i)
345 {
346 DocumentEntry* pEntry = reinterpret_cast<DocumentEntry*>(m_xBasicsBox->get_id(i).toInt64());
347 delete pEntry;
348 }
349 }
350 }
351
CheckButtons()352 void LibPage::CheckButtons()
353 {
354 std::unique_ptr<weld::TreeIter> xCur(m_xLibBox->make_iterator());
355 if (m_xLibBox->get_cursor(xCur.get()))
356 {
357 OUString aLibName = m_xLibBox->get_text(*xCur, 0);
358 Reference< script::XLibraryContainer2 > xModLibContainer( m_aCurDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
359 Reference< script::XLibraryContainer2 > xDlgLibContainer( m_aCurDocument.getLibraryContainer( E_DIALOGS ), UNO_QUERY );
360
361 if ( m_eCurLocation == LIBRARY_LOCATION_SHARE )
362 {
363 m_xPasswordButton->set_sensitive(false);
364 m_xNewLibButton->set_sensitive(false);
365 m_xInsertLibButton->set_sensitive(false);
366 m_xDelButton->set_sensitive(false);
367 }
368 else if ( aLibName.equalsIgnoreAsciiCase( "Standard" ) )
369 {
370 m_xPasswordButton->set_sensitive(false);
371 m_xNewLibButton->set_sensitive(true);
372 m_xInsertLibButton->set_sensitive(true);
373 m_xExportButton->set_sensitive(false);
374 m_xDelButton->set_sensitive(false);
375 }
376 else if ( ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) && xModLibContainer->isLibraryReadOnly( aLibName ) ) ||
377 ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) && xDlgLibContainer->isLibraryReadOnly( aLibName ) ) )
378 {
379 m_xPasswordButton->set_sensitive(false);
380 m_xNewLibButton->set_sensitive(true);
381 m_xInsertLibButton->set_sensitive(true);
382 if ( ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) && xModLibContainer->isLibraryReadOnly( aLibName ) && !xModLibContainer->isLibraryLink( aLibName ) ) ||
383 ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) && xDlgLibContainer->isLibraryReadOnly( aLibName ) && !xDlgLibContainer->isLibraryLink( aLibName ) ) )
384 m_xDelButton->set_sensitive(false);
385 else
386 m_xDelButton->set_sensitive(true);
387 }
388 else
389 {
390 if ( xModLibContainer.is() && !xModLibContainer->hasByName( aLibName ) )
391 m_xPasswordButton->set_sensitive(false);
392 else
393 m_xPasswordButton->set_sensitive(true);
394
395 m_xNewLibButton->set_sensitive(true);
396 m_xInsertLibButton->set_sensitive(true);
397 m_xExportButton->set_sensitive(true);
398 m_xDelButton->set_sensitive(true);
399 }
400 }
401 }
402
ActivatePage()403 void LibPage::ActivatePage()
404 {
405 SetCurLib();
406 }
407
IMPL_LINK_NOARG(LibPage,TreeListHighlightHdl,weld::TreeView &,void)408 IMPL_LINK_NOARG(LibPage, TreeListHighlightHdl, weld::TreeView&, void)
409 {
410 CheckButtons();
411 }
412
IMPL_LINK_NOARG(LibPage,BasicSelectHdl,weld::ComboBox &,void)413 IMPL_LINK_NOARG( LibPage, BasicSelectHdl, weld::ComboBox&, void )
414 {
415 SetCurLib();
416 CheckButtons();
417 }
418
IMPL_LINK(LibPage,ButtonHdl,weld::Button &,rButton,void)419 IMPL_LINK( LibPage, ButtonHdl, weld::Button&, rButton, void )
420 {
421 if (&rButton == m_xEditButton.get())
422 {
423 SfxAllItemSet aArgs( SfxGetpApp()->GetPool() );
424 SfxRequest aRequest( SID_BASICIDE_APPEAR, SfxCallMode::SYNCHRON, aArgs );
425 SfxGetpApp()->ExecuteSlot( aRequest );
426
427 SfxUnoAnyItem aDocItem( SID_BASICIDE_ARG_DOCUMENT_MODEL, Any( m_aCurDocument.getDocumentOrNull() ) );
428
429 std::unique_ptr<weld::TreeIter> xCurEntry(m_xLibBox->make_iterator());
430 if (!m_xLibBox->get_cursor(xCurEntry.get()))
431 return;
432 OUString aLibName(m_xLibBox->get_text(*xCurEntry, 0));
433 SfxStringItem aLibNameItem( SID_BASICIDE_ARG_LIBNAME, aLibName );
434 if (SfxDispatcher* pDispatcher = GetDispatcher())
435 pDispatcher->ExecuteList( SID_BASICIDE_LIBSELECTED,
436 SfxCallMode::ASYNCHRON, { &aDocItem, &aLibNameItem });
437 EndTabDialog();
438 return;
439 }
440 else if (&rButton == m_xNewLibButton.get())
441 NewLib();
442 else if (&rButton == m_xInsertLibButton.get())
443 InsertLib();
444 else if (&rButton == m_xExportButton.get())
445 Export();
446 else if (&rButton == m_xDelButton.get())
447 DeleteCurrent();
448 else if (&rButton == m_xPasswordButton.get())
449 {
450 std::unique_ptr<weld::TreeIter> xCurEntry(m_xLibBox->make_iterator());
451 if (!m_xLibBox->get_cursor(xCurEntry.get()))
452 return;
453 OUString aLibName(m_xLibBox->get_text(*xCurEntry, 0));
454
455 // load module library (if not loaded)
456 Reference< script::XLibraryContainer > xModLibContainer = m_aCurDocument.getLibraryContainer( E_SCRIPTS );
457 if ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) && !xModLibContainer->isLibraryLoaded( aLibName ) )
458 {
459 Shell* pShell = GetShell();
460 if (pShell)
461 pShell->GetViewFrame()->GetWindow().EnterWait();
462 xModLibContainer->loadLibrary( aLibName );
463 if (pShell)
464 pShell->GetViewFrame()->GetWindow().LeaveWait();
465 }
466
467 // load dialog library (if not loaded)
468 Reference< script::XLibraryContainer > xDlgLibContainer = m_aCurDocument.getLibraryContainer( E_DIALOGS );
469 if ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) && !xDlgLibContainer->isLibraryLoaded( aLibName ) )
470 {
471 Shell* pShell = GetShell();
472 if (pShell)
473 pShell->GetViewFrame()->GetWindow().EnterWait();
474 xDlgLibContainer->loadLibrary( aLibName );
475 if (pShell)
476 pShell->GetViewFrame()->GetWindow().LeaveWait();
477 }
478
479 // check, if library is password protected
480 if ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) )
481 {
482 Reference< script::XLibraryContainerPassword > xPasswd( xModLibContainer, UNO_QUERY );
483 if ( xPasswd.is() )
484 {
485 bool const bProtected = xPasswd->isLibraryPasswordProtected( aLibName );
486
487 // change password dialog
488 SvxPasswordDialog aDlg(m_pDialog->getDialog(), !bProtected);
489 aDlg.SetCheckPasswordHdl(LINK(this, LibPage, CheckPasswordHdl));
490
491 if (aDlg.run() == RET_OK)
492 {
493 bool const bNewProtected = xPasswd->isLibraryPasswordProtected( aLibName );
494
495 if ( bNewProtected != bProtected )
496 {
497 int nPos = m_xLibBox->get_iter_index_in_parent(*xCurEntry);
498 m_xLibBox->remove(*xCurEntry);
499 ImpInsertLibEntry(aLibName, nPos);
500 m_xLibBox->set_cursor(nPos);
501 }
502
503 MarkDocumentModified( m_aCurDocument );
504 }
505 }
506 }
507 }
508 CheckButtons();
509 }
510
IMPL_LINK(LibPage,CheckPasswordHdl,SvxPasswordDialog *,pDlg,bool)511 IMPL_LINK( LibPage, CheckPasswordHdl, SvxPasswordDialog *, pDlg, bool )
512 {
513 bool bRet = false;
514
515 std::unique_ptr<weld::TreeIter> xCurEntry(m_xLibBox->make_iterator());
516 if (!m_xLibBox->get_cursor(xCurEntry.get()))
517 return bRet;
518
519 OUString aLibName(m_xLibBox->get_text(*xCurEntry, 0));
520 Reference< script::XLibraryContainerPassword > xPasswd( m_aCurDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
521
522 if ( xPasswd.is() )
523 {
524 try
525 {
526 OUString aOldPassword( pDlg->GetOldPassword() );
527 OUString aNewPassword( pDlg->GetNewPassword() );
528 xPasswd->changeLibraryPassword( aLibName, aOldPassword, aNewPassword );
529 bRet = true;
530 }
531 catch (...)
532 {
533 }
534 }
535
536 return bRet;
537 }
538
NewLib()539 void LibPage::NewLib()
540 {
541 createLibImpl(m_pDialog->getDialog(), m_aCurDocument, m_xLibBox.get(), nullptr);
542 }
543
InsertLib()544 void LibPage::InsertLib()
545 {
546 Reference< uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
547 // file open dialog
548 sfx2::FileDialogHelper aDlg(ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE, FileDialogFlags::NONE, m_pDialog->getDialog());
549 const Reference <XFilePicker3>& xFP = aDlg.GetFilePicker();
550
551 xFP->setTitle(IDEResId(RID_STR_APPENDLIBS));
552
553 // filter
554 OUString aTitle(IDEResId(RID_STR_BASIC));
555 OUString aFilter = "*.sbl;*.xlc;*.xlb" // library files
556 ";*.sdw;*.sxw;*.odt" // text
557 ";*.vor;*.stw;*.ott" // text template
558 ";*.sgl;*.sxg;*.odm" // master document
559 ";*.oth" // html document template
560 ";*.sdc;*.sxc;*.ods" // spreadsheet
561 ";*.stc;*.ots" // spreadsheet template
562 ";*.sda;*.sxd;*.odg" // drawing
563 ";*.std;*.otg" // drawing template
564 ";*.sdd;*.sxi;*.odp" // presentation
565 ";*.sti;*.otp" // presentation template
566 ";*.sxm;*.odf"; // formula
567 xFP->appendFilter( aTitle, aFilter );
568
569 // set display directory and filter
570 OUString aPath(GetExtraData()->GetAddLibPath());
571 if ( !aPath.isEmpty() )
572 xFP->setDisplayDirectory( aPath );
573 else
574 {
575 // macro path from configuration management
576 xFP->setDisplayDirectory( SvtPathOptions().GetWorkPath() );
577 }
578
579 OUString aLastFilter(GetExtraData()->GetAddLibFilter());
580 if ( !aLastFilter.isEmpty() )
581 xFP->setCurrentFilter( aLastFilter );
582 else
583 xFP->setCurrentFilter( IDEResId(RID_STR_BASIC) );
584
585 if ( xFP->execute() != RET_OK )
586 return;
587
588 GetExtraData()->SetAddLibPath( xFP->getDisplayDirectory() );
589 GetExtraData()->SetAddLibFilter( xFP->getCurrentFilter() );
590
591 // library containers for import
592 Reference< script::XLibraryContainer2 > xModLibContImport;
593 Reference< script::XLibraryContainer2 > xDlgLibContImport;
594
595 // file URLs
596 Sequence< OUString > aFiles = xFP->getSelectedFiles();
597 INetURLObject aURLObj( aFiles[0] );
598 std::shared_ptr<INetURLObject> xModURLObj(new INetURLObject(aURLObj));
599 std::shared_ptr<INetURLObject> xDlgURLObj(new INetURLObject(aURLObj));
600
601 OUString aBase = aURLObj.getBase();
602 OUString aModBase( "script" );
603 OUString aDlgBase( "dialog" );
604
605 if ( aBase == aModBase || aBase == aDlgBase )
606 {
607 xModURLObj->setBase( aModBase );
608 xDlgURLObj->setBase( aDlgBase );
609 }
610
611 Reference< XSimpleFileAccess3 > xSFA( SimpleFileAccess::create(comphelper::getProcessComponentContext()) );
612
613 OUString aModURL( xModURLObj->GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
614 if ( xSFA->exists( aModURL ) )
615 {
616 xModLibContImport = script::DocumentScriptLibraryContainer::createWithURL(xContext, aModURL);
617 }
618
619 OUString aDlgURL( xDlgURLObj->GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
620 if ( xSFA->exists( aDlgURL ) )
621 {
622 xDlgLibContImport = script::DocumentDialogLibraryContainer::createWithURL(xContext, aDlgURL);
623 }
624
625 if ( !xModLibContImport.is() && !xDlgLibContImport.is() )
626 return;
627
628 std::shared_ptr<LibDialog> xLibDlg;
629
630 Sequence< OUString > aLibNames = GetMergedLibraryNames( xModLibContImport, xDlgLibContImport );
631 sal_Int32 nLibCount = aLibNames.getLength();
632 const OUString* pLibNames = aLibNames.getConstArray();
633 for ( sal_Int32 i = 0 ; i < nLibCount ; i++ )
634 {
635 // library import dialog
636 if (!xLibDlg)
637 {
638 xLibDlg.reset(new LibDialog(m_pDialog->getDialog()));
639 xLibDlg->SetStorageName( aURLObj.getName() );
640 }
641
642 // libbox entries
643 OUString aLibName( pLibNames[ i ] );
644 if ( !( ( xModLibContImport.is() && xModLibContImport->hasByName( aLibName ) && xModLibContImport->isLibraryLink( aLibName ) ) ||
645 ( xDlgLibContImport.is() && xDlgLibContImport->hasByName( aLibName ) && xDlgLibContImport->isLibraryLink( aLibName ) ) ) )
646 {
647 weld::TreeView& rView = xLibDlg->GetLibBox();
648 rView.append();
649 const int nRow = rView.n_children() - 1;
650 rView.set_toggle(nRow, TRISTATE_TRUE, 0);
651 rView.set_text(nRow, aLibName, 1);
652 rView.set_cursor(rView.find_text(aLibName));
653 }
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, 0) == TRISTATE_TRUE)
685 {
686 OUString aLibName(rView.get_text(nLib, 1));
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 )
902 MarkDocumentModified( m_aCurDocument );
903 });
904 }
905
Export()906 void 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 {
934 try
935 {
936 bool bExportAsPackage = xNewDlg->isExportAsPackage();
937 //tdf#112063 ensure closing xNewDlg is not selected as
938 //parent of file dialog from ExportAs...
939 xNewDlg.reset();
940 if (bExportAsPackage)
941 ExportAsPackage( aLibName );
942 else
943 ExportAsBasic( aLibName );
944 }
945 catch(const util::VetoException& ) // user canceled operation
946 {
947 }
948 }
949 }
950
implExportLib(const OUString & aLibName,const OUString & aTargetURL,const Reference<task::XInteractionHandler> & Handler)951 void LibPage::implExportLib( const OUString& aLibName, const OUString& aTargetURL,
952 const Reference< task::XInteractionHandler >& Handler )
953 {
954 Reference< script::XLibraryContainerExport > xModLibContainerExport
955 ( m_aCurDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
956 Reference< script::XLibraryContainerExport > xDlgLibContainerExport
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
973 class OLibCommandEnvironment : public cppu::WeakImplHelper< XCommandEnvironment >
974 {
975 Reference< task::XInteractionHandler > mxInteraction;
976
977 public:
OLibCommandEnvironment(const Reference<task::XInteractionHandler> & xInteraction)978 explicit OLibCommandEnvironment(const Reference<task::XInteractionHandler>& xInteraction)
979 : mxInteraction( xInteraction )
980 {}
981
982 // Methods
983 virtual Reference< task::XInteractionHandler > SAL_CALL getInteractionHandler() override;
984 virtual Reference< XProgressHandler > SAL_CALL getProgressHandler() override;
985 };
986
getInteractionHandler()987 Reference< task::XInteractionHandler > OLibCommandEnvironment::getInteractionHandler()
988 {
989 return mxInteraction;
990 }
991
getProgressHandler()992 Reference< XProgressHandler > OLibCommandEnvironment::getProgressHandler()
993 {
994 Reference< XProgressHandler > xRet;
995 return xRet;
996 }
997
ExportAsPackage(const OUString & aLibName)998 void LibPage::ExportAsPackage( const OUString& aLibName )
999 {
1000 // file open dialog
1001 sfx2::FileDialogHelper aDlg(ui::dialogs::TemplateDescription::FILESAVE_SIMPLE, FileDialogFlags::NONE, m_pDialog->getDialog());
1002 const Reference <XFilePicker3>& xFP = aDlg.GetFilePicker();
1003
1004 Reference< uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
1005 Reference< task::XInteractionHandler2 > xHandler( task::InteractionHandler::createWithParent(xContext, nullptr) );
1006 Reference< XSimpleFileAccess3 > xSFA = SimpleFileAccess::create(xContext);
1007
1008 xFP->setTitle(IDEResId(RID_STR_EXPORTPACKAGE));
1009
1010 // filter
1011 OUString aTitle(IDEResId(RID_STR_PACKAGE_BUNDLE));
1012 OUString aFilter = "*.oxt" ; // library files
1013 xFP->appendFilter( aTitle, aFilter );
1014
1015 // set display directory and filter
1016 OUString aPath = GetExtraData()->GetAddLibPath();
1017 if ( !aPath.isEmpty() )
1018 {
1019 xFP->setDisplayDirectory( aPath );
1020 }
1021 else
1022 {
1023 // macro path from configuration management
1024 xFP->setDisplayDirectory( SvtPathOptions().GetWorkPath() );
1025 }
1026 xFP->setCurrentFilter( aTitle );
1027
1028 if ( xFP->execute() == RET_OK )
1029 {
1030 GetExtraData()->SetAddLibPath(xFP->getDisplayDirectory());
1031
1032 Sequence< OUString > aFiles = xFP->getSelectedFiles();
1033 INetURLObject aURL( aFiles[0] );
1034 if( aURL.getExtension().isEmpty() )
1035 aURL.setExtension( "oxt" );
1036
1037 OUString aPackageURL( aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
1038
1039 OUString aTmpPath = SvtPathOptions().GetTempPath();
1040 INetURLObject aInetObj( aTmpPath );
1041 aInetObj.insertName( aLibName, true, INetURLObject::LAST_SEGMENT, INetURLObject::EncodeMechanism::All );
1042 OUString aSourcePath = aInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
1043 if( xSFA->exists( aSourcePath ) )
1044 xSFA->kill( aSourcePath );
1045 Reference< task::XInteractionHandler > xDummyHandler( new DummyInteractionHandler( xHandler ) );
1046 implExportLib( aLibName, aTmpPath, xDummyHandler );
1047
1048 Reference< XCommandEnvironment > xCmdEnv = new OLibCommandEnvironment(xHandler);
1049
1050 ::ucbhelper::Content sourceContent( aSourcePath, xCmdEnv, comphelper::getProcessComponentContext() );
1051
1052 OUString destFolder = "vnd.sun.star.zip://" +
1053 ::rtl::Uri::encode( aPackageURL,
1054 rtl_UriCharClassRegName,
1055 rtl_UriEncodeIgnoreEscapes,
1056 RTL_TEXTENCODING_UTF8 ) +
1057 "/";
1058
1059 if( xSFA->exists( aPackageURL ) )
1060 xSFA->kill( aPackageURL );
1061
1062 ::ucbhelper::Content destFolderContent( destFolder, xCmdEnv, comphelper::getProcessComponentContext() );
1063 destFolderContent.transferContent(
1064 sourceContent, ::ucbhelper::InsertOperation::Copy,
1065 OUString(), NameClash::OVERWRITE );
1066
1067 INetURLObject aMetaInfInetObj( aTmpPath );
1068 aMetaInfInetObj.insertName( "META-INF",
1069 true, INetURLObject::LAST_SEGMENT, INetURLObject::EncodeMechanism::All );
1070 OUString aMetaInfFolder = aMetaInfInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
1071 if( xSFA->exists( aMetaInfFolder ) )
1072 xSFA->kill( aMetaInfFolder );
1073 xSFA->createFolder( aMetaInfFolder );
1074
1075 std::vector< Sequence<beans::PropertyValue> > manifest;
1076 const OUString strMediaType = "MediaType" ;
1077 const OUString strFullPath = "FullPath" ;
1078 const OUString strBasicMediaType = "application/vnd.sun.star.basic-library" ;
1079
1080 OUString fullPath = aLibName
1081 + "/" ;
1082 auto attribs(::comphelper::InitPropertySequence({
1083 { strFullPath, Any(fullPath) },
1084 { strMediaType, Any(strBasicMediaType) }
1085 }));
1086 manifest.push_back( attribs );
1087
1088 // write into pipe:
1089 Reference<packages::manifest::XManifestWriter> xManifestWriter = packages::manifest::ManifestWriter::create( xContext );
1090 Reference<io::XOutputStream> xPipe( io::Pipe::create( xContext ), UNO_QUERY_THROW );
1091 xManifestWriter->writeManifestSequence(
1092 xPipe, Sequence< Sequence<beans::PropertyValue> >(
1093 manifest.data(), manifest.size() ) );
1094
1095 aMetaInfInetObj.insertName( "manifest.xml",
1096 true, INetURLObject::LAST_SEGMENT, INetURLObject::EncodeMechanism::All );
1097
1098 // write buffered pipe data to content:
1099 ::ucbhelper::Content manifestContent( aMetaInfInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ), xCmdEnv, comphelper::getProcessComponentContext() );
1100 manifestContent.writeStream( Reference<io::XInputStream>( xPipe, UNO_QUERY_THROW ), true );
1101
1102 ::ucbhelper::Content MetaInfContent( aMetaInfFolder, xCmdEnv, comphelper::getProcessComponentContext() );
1103 destFolderContent.transferContent(
1104 MetaInfContent, ::ucbhelper::InsertOperation::Copy,
1105 OUString(), NameClash::OVERWRITE );
1106
1107 if( xSFA->exists( aSourcePath ) )
1108 xSFA->kill( aSourcePath );
1109 if( xSFA->exists( aMetaInfFolder ) )
1110 xSFA->kill( aMetaInfFolder );
1111 }
1112 }
1113
ExportAsBasic(const OUString & aLibName)1114 void LibPage::ExportAsBasic( const OUString& aLibName )
1115 {
1116 // Folder picker
1117 Reference< uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
1118 Reference< XFolderPicker2 > xFolderPicker = FolderPicker::create(xContext);
1119 Reference< task::XInteractionHandler2 > xHandler( task::InteractionHandler::createWithParent(xContext, nullptr) );
1120
1121 xFolderPicker->setTitle(IDEResId(RID_STR_EXPORTBASIC));
1122
1123 // set display directory and filter
1124 OUString aPath =GetExtraData()->GetAddLibPath();
1125 if( aPath.isEmpty() )
1126 aPath = SvtPathOptions().GetWorkPath();
1127
1128 // INetURLObject aURL(m_sSavePath, INetProtocol::File);
1129 xFolderPicker->setDisplayDirectory( aPath );
1130 short nRet = xFolderPicker->execute();
1131 if( nRet == RET_OK )
1132 {
1133 OUString aTargetURL = xFolderPicker->getDirectory();
1134 GetExtraData()->SetAddLibPath(aTargetURL);
1135
1136 Reference< task::XInteractionHandler > xDummyHandler( new DummyInteractionHandler( xHandler ) );
1137 implExportLib( aLibName, aTargetURL, xDummyHandler );
1138 }
1139 }
1140
DeleteCurrent()1141 void LibPage::DeleteCurrent()
1142 {
1143 std::unique_ptr<weld::TreeIter> xCurEntry(m_xLibBox->make_iterator());
1144 if (!m_xLibBox->get_cursor(xCurEntry.get()))
1145 return;
1146 OUString aLibName(m_xLibBox->get_text(*xCurEntry, 0));
1147
1148 // check, if library is link
1149 bool bIsLibraryLink = false;
1150 Reference< script::XLibraryContainer2 > xModLibContainer( m_aCurDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
1151 Reference< script::XLibraryContainer2 > xDlgLibContainer( m_aCurDocument.getLibraryContainer( E_DIALOGS ), UNO_QUERY );
1152 if ( ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) && xModLibContainer->isLibraryLink( aLibName ) ) ||
1153 ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) && xDlgLibContainer->isLibraryLink( aLibName ) ) )
1154 {
1155 bIsLibraryLink = true;
1156 }
1157
1158 if (QueryDelLib(aLibName, bIsLibraryLink, m_pDialog->getDialog()))
1159 {
1160 // inform BasicIDE
1161 SfxUnoAnyItem aDocItem( SID_BASICIDE_ARG_DOCUMENT_MODEL, Any( m_aCurDocument.getDocumentOrNull() ) );
1162 SfxStringItem aLibNameItem( SID_BASICIDE_ARG_LIBNAME, aLibName );
1163 if (SfxDispatcher* pDispatcher = GetDispatcher())
1164 pDispatcher->ExecuteList(SID_BASICIDE_LIBREMOVED,
1165 SfxCallMode::SYNCHRON, { &aDocItem, &aLibNameItem });
1166
1167 // remove library from module and dialog library containers
1168 if ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) )
1169 xModLibContainer->removeLibrary( aLibName );
1170 if ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) )
1171 xDlgLibContainer->removeLibrary( aLibName );
1172
1173 m_xLibBox->remove(*xCurEntry);
1174 MarkDocumentModified( m_aCurDocument );
1175 }
1176 }
1177
EndTabDialog()1178 void LibPage::EndTabDialog()
1179 {
1180 m_pDialog->response(RET_OK);
1181 }
1182
FillListBox()1183 void LibPage::FillListBox()
1184 {
1185 InsertListBoxEntry( ScriptDocument::getApplicationScriptDocument(), LIBRARY_LOCATION_USER );
1186 InsertListBoxEntry( ScriptDocument::getApplicationScriptDocument(), LIBRARY_LOCATION_SHARE );
1187
1188 ScriptDocuments aDocuments( ScriptDocument::getAllScriptDocuments( ScriptDocument::DocumentsSorted ) );
1189 for (auto const& doc : aDocuments)
1190 {
1191 InsertListBoxEntry( doc, LIBRARY_LOCATION_DOCUMENT );
1192 }
1193 }
1194
InsertListBoxEntry(const ScriptDocument & rDocument,LibraryLocation eLocation)1195 void LibPage::InsertListBoxEntry( const ScriptDocument& rDocument, LibraryLocation eLocation )
1196 {
1197 OUString aEntryText(rDocument.getTitle(eLocation));
1198 OUString sId(OUString::number(reinterpret_cast<sal_Int64>(new DocumentEntry(rDocument, eLocation))));
1199 m_xBasicsBox->append(sId, aEntryText);
1200 }
1201
SetCurLib()1202 void LibPage::SetCurLib()
1203 {
1204 DocumentEntry* pEntry = reinterpret_cast<DocumentEntry*>(m_xBasicsBox->get_active_id().toInt64());
1205 if (pEntry)
1206 {
1207 const ScriptDocument& aDocument( pEntry->GetDocument() );
1208 DBG_ASSERT( aDocument.isAlive(), "LibPage::SetCurLib: no document, or document is dead!" );
1209 if ( !aDocument.isAlive() )
1210 return;
1211 LibraryLocation eLocation = pEntry->GetLocation();
1212 if ( aDocument != m_aCurDocument || eLocation != m_eCurLocation )
1213 {
1214 m_aCurDocument = aDocument;
1215 m_eCurLocation = eLocation;
1216 m_xLibBox->clear();
1217
1218 // get a sorted list of library names
1219 Sequence< OUString > aLibNames = aDocument.getLibraryNames();
1220 sal_Int32 nLibCount = aLibNames.getLength();
1221 const OUString* pLibNames = aLibNames.getConstArray();
1222
1223 int nEntry = 0;
1224 for (int i = 0 ; i < nLibCount; ++i)
1225 {
1226 OUString aLibName(pLibNames[i]);
1227 if (eLocation == aDocument.getLibraryLocation(aLibName))
1228 ImpInsertLibEntry(aLibName, nEntry++);
1229 }
1230
1231 int nEntry_ = FindEntry(*m_xLibBox, "Standard");
1232 if (nEntry_ == -1 && m_xLibBox->n_children())
1233 nEntry_ = 0;
1234 m_xLibBox->set_cursor(nEntry_);
1235 }
1236 }
1237 }
1238
ImpInsertLibEntry(const OUString & rLibName,sal_uLong nPos)1239 void LibPage::ImpInsertLibEntry( const OUString& rLibName, sal_uLong nPos )
1240 {
1241 // check, if library is password protected
1242 bool bProtected = false;
1243 Reference< script::XLibraryContainer2 > xModLibContainer( m_aCurDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
1244 if ( xModLibContainer.is() && xModLibContainer->hasByName( rLibName ) )
1245 {
1246 Reference< script::XLibraryContainerPassword > xPasswd( xModLibContainer, UNO_QUERY );
1247 if ( xPasswd.is() )
1248 {
1249 bProtected = xPasswd->isLibraryPasswordProtected( rLibName );
1250 }
1251 }
1252
1253 m_xLibBox->insert_text(nPos, rLibName);
1254
1255 if (bProtected)
1256 m_xLibBox->set_image(nPos, RID_BMP_LOCKED);
1257
1258 // check, if library is link
1259 if ( xModLibContainer.is() && xModLibContainer->hasByName( rLibName ) && xModLibContainer->isLibraryLink( rLibName ) )
1260 {
1261 OUString aLinkURL = xModLibContainer->getLibraryLinkURL( rLibName );
1262 m_xLibBox->set_text(nPos, aLinkURL, 1);
1263 }
1264 }
1265
1266 // Helper function
createLibImpl(weld::Window * pWin,const ScriptDocument & rDocument,weld::TreeView * pLibBox,SbTreeListBox * pBasicBox)1267 void createLibImpl(weld::Window* pWin, const ScriptDocument& rDocument,
1268 weld::TreeView* pLibBox, SbTreeListBox* pBasicBox)
1269 {
1270 OSL_ENSURE( rDocument.isAlive(), "createLibImpl: invalid document!" );
1271 if ( !rDocument.isAlive() )
1272 return;
1273
1274 // create library name
1275 OUString aLibName;
1276 bool bValid = false;
1277 sal_Int32 i = 1;
1278 while ( !bValid )
1279 {
1280 aLibName = "Library" + OUString::number( i );
1281 if ( !rDocument.hasLibrary( E_SCRIPTS, aLibName ) && !rDocument.hasLibrary( E_DIALOGS, aLibName ) )
1282 bValid = true;
1283 i++;
1284 }
1285
1286 NewObjectDialog aNewDlg(pWin, ObjectMode::Library);
1287 aNewDlg.SetObjectName(aLibName);
1288
1289 if (aNewDlg.run())
1290 {
1291 if (!aNewDlg.GetObjectName().isEmpty())
1292 aLibName = aNewDlg.GetObjectName();
1293
1294 if ( aLibName.getLength() > 30 )
1295 {
1296 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(pWin,
1297 VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_LIBNAMETOLONG)));
1298 xErrorBox->run();
1299 }
1300 else if ( !IsValidSbxName( aLibName ) )
1301 {
1302 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(pWin,
1303 VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_BADSBXNAME)));
1304 xErrorBox->run();
1305 }
1306 else if ( rDocument.hasLibrary( E_SCRIPTS, aLibName ) || rDocument.hasLibrary( E_DIALOGS, aLibName ) )
1307 {
1308 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(pWin,
1309 VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_SBXNAMEALLREADYUSED2)));
1310 xErrorBox->run();
1311 }
1312 else
1313 {
1314 try
1315 {
1316 // create module and dialog library
1317 Reference< container::XNameContainer > xModLib( rDocument.getOrCreateLibrary( E_SCRIPTS, aLibName ) );
1318 Reference< container::XNameContainer > xDlgLib( rDocument.getOrCreateLibrary( E_DIALOGS, aLibName ) );
1319
1320 if( pLibBox )
1321 {
1322 pLibBox->append_text(aLibName);
1323 pLibBox->set_cursor(pLibBox->find_text(aLibName));
1324 }
1325
1326 // create a module
1327 OUString aModName = rDocument.createObjectName( E_SCRIPTS, aLibName );
1328 OUString sModuleCode;
1329 if ( !rDocument.createModule( aLibName, aModName, true, sModuleCode ) )
1330 throw Exception("could not create module " + aModName, nullptr);
1331
1332 SbxItem aSbxItem( SID_BASICIDE_ARG_SBX, rDocument, aLibName, aModName, TYPE_MODULE );
1333 if (SfxDispatcher* pDispatcher = GetDispatcher())
1334 pDispatcher->ExecuteList(SID_BASICIDE_SBXINSERTED,
1335 SfxCallMode::SYNCHRON, { &aSbxItem });
1336
1337 if( pBasicBox )
1338 {
1339 std::unique_ptr<weld::TreeIter> xIter(pBasicBox->make_iterator(nullptr));
1340 bool bValidIter = pBasicBox->get_cursor(xIter.get());
1341 std::unique_ptr<weld::TreeIter> xRootEntry(pBasicBox->make_iterator(xIter.get()));
1342 while (bValidIter)
1343 {
1344 pBasicBox->copy_iterator(*xIter, *xRootEntry);
1345 bValidIter = pBasicBox->iter_parent(*xIter);
1346 }
1347
1348 BrowseMode nMode = pBasicBox->GetMode();
1349 bool bDlgMode = ( nMode & BrowseMode::Dialogs ) && !( nMode & BrowseMode::Modules );
1350 const OUString sId = bDlgMode ? OUStringLiteral(RID_BMP_DLGLIB) : OUStringLiteral(RID_BMP_MODLIB);
1351 pBasicBox->AddEntry(aLibName, sId, xRootEntry.get(), false, std::make_unique<Entry>(OBJ_TYPE_LIBRARY));
1352 pBasicBox->AddEntry(aModName, RID_BMP_MODULE, xRootEntry.get(), false, std::make_unique<Entry>(OBJ_TYPE_MODULE));
1353 pBasicBox->set_cursor(*xRootEntry);
1354 pBasicBox->select(*xRootEntry);
1355 }
1356 }
1357 catch (const uno::Exception& )
1358 {
1359 DBG_UNHANDLED_EXCEPTION("basctl.basicide");
1360 }
1361 }
1362 }
1363 }
1364
1365 } // namespace basctl
1366
1367 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1368