LibreOffice Module cui (master) 1
hldocntp.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <hldocntp.hxx>
21#include <osl/file.hxx>
23#include <sfx2/viewfrm.hxx>
24#include <sfx2/docfilt.hxx>
25#include <svl/stritem.hxx>
26#include <com/sun/star/awt/XTopWindow.hpp>
27#include <com/sun/star/uno/Reference.h>
28#include <com/sun/star/uno/Exception.hpp>
29#include <utility>
30#include <vcl/svapp.hxx>
31#include <vcl/weld.hxx>
32#include <tools/urlobj.hxx>
37
39#include <com/sun/star/ui/dialogs/XFolderPicker2.hpp>
40#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
41
42#include <cuihyperdlg.hxx>
43#include <dialmgr.hxx>
44#include <strings.hrc>
45
46using namespace ::com::sun::star::lang;
47using namespace ::com::sun::star::ui::dialogs;
48using namespace ::com::sun::star::uno;
49
50using namespace ::com::sun::star;
51
52/*************************************************************************
53|*
54|* Data-struct for documenttypes in listbox
55|*
56|************************************************************************/
57
58namespace {
59
60struct DocumentTypeData
61{
62 OUString aStrURL;
63 OUString aStrExt;
64 DocumentTypeData (OUString aURL, OUString aExt) : aStrURL(std::move(aURL)), aStrExt(std::move(aExt))
65 {}
66};
67
68}
69
70bool SvxHyperlinkNewDocTp::ImplGetURLObject( const OUString& rPath, std::u16string_view rBase, INetURLObject& aURLObject ) const
71{
72 bool bIsValidURL = !rPath.isEmpty();
73 if ( bIsValidURL )
74 {
75 aURLObject.SetURL( rPath );
76 if ( aURLObject.GetProtocol() == INetProtocol::NotValid ) // test if the source is already a valid url
77 { // if not we have to create a url from a physical file name
78 bool wasAbs;
79 INetURLObject base(rBase);
80 base.setFinalSlash();
81 aURLObject = base.smartRel2Abs(
82 rPath, wasAbs, true, INetURLObject::EncodeMechanism::All,
83 RTL_TEXTENCODING_UTF8, true);
84 }
85 bIsValidURL = aURLObject.GetProtocol() != INetProtocol::NotValid;
86 if ( bIsValidURL )
87 {
88 OUString aBase( aURLObject.getName( INetURLObject::LAST_SEGMENT, false ) );
89 if ( aBase.isEmpty() || ( aBase[0] == '.' ) )
90 bIsValidURL = false;
91 }
92 if ( bIsValidURL )
93 {
94 sal_Int32 nPos = m_xLbDocTypes->get_selected_index();
95 if (nPos != -1)
96 aURLObject.SetExtension(weld::fromId<DocumentTypeData*>(m_xLbDocTypes->get_id(nPos))->aStrExt);
97 }
98
99 }
100 return bIsValidURL;
101}
102
103/*************************************************************************
104|*
105|* Constructor / Destructor
106|*
107|************************************************************************/
108
110 : SvxHyperlinkTabPageBase(pParent, pDlg, "cui/ui/hyperlinknewdocpage.ui", "HyperlinkNewDocPage", pItemSet)
111 , m_xRbtEditNow(xBuilder->weld_radio_button("editnow"))
112 , m_xRbtEditLater(xBuilder->weld_radio_button("editlater"))
113 , m_xCbbPath(new SvxHyperURLBox(xBuilder->weld_combo_box("path")))
114 , m_xBtCreate(xBuilder->weld_button("create"))
115 , m_xLbDocTypes(xBuilder->weld_tree_view("types"))
116{
117 m_xCbbPath->SetSmartProtocol(INetProtocol::File);
118 m_xLbDocTypes->set_size_request(-1, m_xLbDocTypes->get_height_rows(5));
119
121
123
124 m_xCbbPath->show();
125 m_xCbbPath->SetBaseURL(SvtPathOptions().GetWorkPath());
126
127 // set defaults
128 m_xRbtEditNow->set_active(true);
129
130 m_xBtCreate->connect_clicked(LINK(this, SvxHyperlinkNewDocTp, ClickNewHdl_Impl));
131
133}
134
136{
137 if (m_xLbDocTypes)
138 {
139 for (sal_Int32 n = 0, nEntryCount = m_xLbDocTypes->n_children(); n < nEntryCount; ++n)
140 delete weld::fromId<DocumentTypeData*>(m_xLbDocTypes->get_id(n));
141 m_xLbDocTypes = nullptr;
142 }
143}
144
145/*************************************************************************
146|*
147|* Fill the all dialog-controls except controls in groupbox "more..."
148|*
149|************************************************************************/
150
151
152void SvxHyperlinkNewDocTp::FillDlgFields(const OUString& /*rStrURL*/)
153{
154}
155
157{
158 weld::WaitObject aWaitObj(mpDialog->getDialog());
159
160 std::vector<SvtDynMenuEntry> aDynamicMenuEntries( SvtDynamicMenuOptions::GetMenu( EDynamicMenuType::NewMenu ) );
161
162 for ( const SvtDynMenuEntry & rDynamicMenuEntry : aDynamicMenuEntries )
163 {
164 OUString aDocumentUrl = rDynamicMenuEntry.sURL;
165 OUString aTitle = rDynamicMenuEntry.sTitle;
166
167 //#i96822# business cards, labels and database should not be inserted here
168 if( aDocumentUrl == "private:factory/swriter?slot=21051" ||
169 aDocumentUrl == "private:factory/swriter?slot=21052" ||
170 aDocumentUrl == "private:factory/sdatabase?Interactive" )
171 continue;
172
173 // Insert into listbox
174 if ( !aDocumentUrl.isEmpty() )
175 {
176 if ( aDocumentUrl == "private:factory/simpress?slot=6686" ) // SJ: #106216# do not start
177 aDocumentUrl = "private:factory/simpress"; // the AutoPilot for impress
178
179 // insert private-url and default-extension as user-data
180 std::shared_ptr<const SfxFilter> pFilter = SfxFilter::GetDefaultFilterFromFactory( aDocumentUrl );
181 if ( pFilter )
182 {
183 // insert doc-name and image
184 OUString aTitleName = aTitle.replaceFirst( "~", "" );
185
186 OUString aStrDefExt(pFilter->GetDefaultExtension());
187 DocumentTypeData *pTypeData = new DocumentTypeData(aDocumentUrl, aStrDefExt.copy(2));
188 OUString sId(weld::toId(pTypeData));
189 m_xLbDocTypes->append(sId, aTitleName);
190 }
191 }
192 }
193 m_xLbDocTypes->select(0);
194}
195
196/*************************************************************************
197|*
198|* retrieve and prepare data from dialog-fields
199|*
200|************************************************************************/
201
202void SvxHyperlinkNewDocTp::GetCurentItemData ( OUString& rStrURL, OUString& aStrName,
203 OUString& aStrIntName, OUString& aStrFrame,
204 SvxLinkInsertMode& eMode )
205{
206 // get data from dialog-controls
207 rStrURL = m_xCbbPath->get_active_text();
209 if ( ImplGetURLObject( rStrURL, m_xCbbPath->GetBaseURL(), aURL ) )
210 {
211 rStrURL = aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE );
212 }
213
214 GetDataFromCommonFields( aStrName, aStrIntName, aStrFrame, eMode );
215}
216
217/*************************************************************************
218|*
219|* static method to create Tabpage
220|*
221|************************************************************************/
222
223std::unique_ptr<IconChoicePage> SvxHyperlinkNewDocTp::Create(weld::Container* pWindow, SvxHpLinkDlg* pDlg, const SfxItemSet* pItemSet)
224{
225 return std::make_unique<SvxHyperlinkNewDocTp>(pWindow, pDlg, pItemSet);
226}
227
228/*************************************************************************
229|*
230|* Set initial focus
231|*
232|************************************************************************/
234{
235 m_xCbbPath->grab_focus();
236}
237
238namespace
239{
240 struct ExecuteInfo
241 {
242 bool bRbtEditLater;
243 bool bRbtEditNow;
245 OUString aStrDocName;
246 // current document
247 css::uno::Reference<css::frame::XFrame> xFrame;
248 SfxDispatcher* pDispatcher;
249 };
250}
251
252IMPL_STATIC_LINK(SvxHyperlinkNewDocTp, DispatchDocument, void*, p, void)
253{
254 std::unique_ptr<ExecuteInfo> xExecuteInfo(static_cast<ExecuteInfo*>(p));
255 if (!xExecuteInfo->xFrame.is())
256 return;
257 try
258 {
259 //if it throws dispatcher is invalid
260 css::uno::Reference<css::awt::XTopWindow>(xExecuteInfo->xFrame->getContainerWindow(), css::uno::UNO_QUERY_THROW);
261
262 SfxViewFrame *pViewFrame = nullptr;
263
264 // create items
265 SfxStringItem aName( SID_FILE_NAME, xExecuteInfo->aStrDocName );
266 SfxStringItem aReferer( SID_REFERER, "private:user" );
267 SfxStringItem aFrame( SID_TARGETNAME, "_blank");
268
269 OUString aStrFlags('S');
270 if (xExecuteInfo->bRbtEditLater)
271 {
272 aStrFlags += "H";
273 }
274 SfxStringItem aFlags (SID_OPTIONS, aStrFlags);
275
276 // open url
277 const SfxPoolItem* pReturn = xExecuteInfo->pDispatcher->ExecuteList(
278 SID_OPENDOC, SfxCallMode::SYNCHRON,
279 { &aName, &aFlags, &aFrame, &aReferer });
280
281 // save new doc
282 const SfxViewFrameItem *pItem = dynamic_cast<const SfxViewFrameItem*>( pReturn ); // SJ: pReturn is NULL if the Hyperlink
283 if ( pItem ) // creation is cancelled #106216#
284 {
285 pViewFrame = pItem->GetFrame();
286 if (pViewFrame)
287 {
288 SfxStringItem aNewName( SID_FILE_NAME, xExecuteInfo->aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
289 SfxUnoFrameItem aDocFrame( SID_FILLFRAME, pViewFrame->GetFrame().GetFrameInterface() );
290 fprintf(stderr, "is there a frame int %p\n", pViewFrame->GetFrame().GetFrameInterface().get() );
291 pViewFrame->GetDispatcher()->ExecuteList(
292 SID_SAVEASDOC, SfxCallMode::SYNCHRON,
293 { &aNewName }, { &aDocFrame });
294 }
295 }
296
297 if (xExecuteInfo->bRbtEditNow)
298 {
299 css::uno::Reference<css::awt::XTopWindow> xWindow(xExecuteInfo->xFrame->getContainerWindow(), css::uno::UNO_QUERY);
300 if (xWindow.is()) //will be false if the frame was exited while the document was loading (e.g. we waited for warning dialogs)
301 xWindow->toFront();
302 }
303
304 if (pViewFrame && xExecuteInfo->bRbtEditLater)
305 {
306 SfxObjectShell* pObjShell = pViewFrame->GetObjectShell();
307 pObjShell->DoClose();
308 }
309 }
310 catch (...)
311 {
312 }
313}
314
315/*************************************************************************
316|*
317|* Any action to do after apply-button is pressed
318|*
319\************************************************************************/
321{
322 weld::WaitObject aWait(mpDialog->getDialog());
323
324 // get data from dialog-controls
325 OUString aStrNewName = m_xCbbPath->get_active_text();
326
327 if ( aStrNewName.isEmpty() )
328 aStrNewName = maStrInitURL;
329
330 // create a real URL-String
332 if ( !ImplGetURLObject( aStrNewName, m_xCbbPath->GetBaseURL(), aURL ) )
333 return;
334
335 // create Document
336 aStrNewName = aURL.GetURLPath( INetURLObject::DecodeMechanism::NONE );
337 bool bCreate = true;
338 try
339 {
340 // check if file exists, warn before we overwrite it
341 std::unique_ptr<SvStream> pIStm = ::utl::UcbStreamHelper::CreateStream( aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::READ );
342
343 bool bOk = pIStm && ( pIStm->GetError() == ERRCODE_NONE);
344
345 pIStm.reset();
346
347 if( bOk )
348 {
349 std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(mpDialog->getDialog(),
350 VclMessageType::Warning, VclButtonsType::YesNo,
351 CuiResId(RID_CUISTR_HYPERDLG_QUERYOVERWRITE)));
352 bCreate = xWarn->run() == RET_YES;
353 }
354 }
355 catch (const uno::Exception&)
356 {
357 }
358
359 if (!bCreate || aStrNewName.isEmpty())
360 return;
361
362 ExecuteInfo* pExecuteInfo = new ExecuteInfo;
363
364 pExecuteInfo->bRbtEditLater = m_xRbtEditLater->get_active();
365 pExecuteInfo->bRbtEditNow = m_xRbtEditNow->get_active();
366 // get private-url
367 sal_Int32 nPos = m_xLbDocTypes->get_selected_index();
368 if (nPos == -1)
369 nPos = 0;
370 pExecuteInfo->aURL = aURL;
371 pExecuteInfo->aStrDocName = weld::fromId<DocumentTypeData*>(m_xLbDocTypes->get_id(nPos))->aStrURL;
372
373 // current document
374 pExecuteInfo->xFrame = GetDispatcher()->GetFrame()->GetFrame().GetFrameInterface();
375 pExecuteInfo->pDispatcher = GetDispatcher();
376
377 Application::PostUserEvent(LINK(nullptr, SvxHyperlinkNewDocTp, DispatchDocument), pExecuteInfo);
378}
379
380/*************************************************************************
381|*
382|* Click on imagebutton : new
383|*
384|************************************************************************/
386{
387 DisableClose( true );
388 uno::Reference < XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
389 uno::Reference < XFolderPicker2 > xFolderPicker = sfx2::createFolderPicker(xContext, mpDialog->getDialog());
390
391 OUString aStrURL;
392 OUString aTempStrURL( m_xCbbPath->get_active_text() );
393 osl::FileBase::getFileURLFromSystemPath( aTempStrURL, aStrURL );
394
395 OUString aStrPath = aStrURL;
396 bool bZeroPath = aStrPath.isEmpty();
397 bool bHandleFileName = bZeroPath; // when path has length of 0, then the rest should always be handled
398 // as file name, otherwise we do not yet know
399
400 if( bZeroPath )
401 aStrPath = SvtPathOptions().GetWorkPath();
402 else if( !::utl::UCBContentHelper::IsFolder( aStrURL ) )
403 bHandleFileName = true;
404
405 xFolderPicker->setDisplayDirectory( aStrPath );
406 sal_Int16 nResult = xFolderPicker->execute();
407 DisableClose( false );
408 if( ExecutableDialogResults::OK != nResult )
409 return;
410
411 char const sSlash[] = "/";
412
413 INetURLObject aURL( aStrURL, INetProtocol::File );
414 OUString aStrName;
415 if( bHandleFileName )
416 aStrName = bZeroPath? aTempStrURL : aURL.getName();
417
418 m_xCbbPath->SetBaseURL( xFolderPicker->getDirectory() );
419 OUString aStrTmp( xFolderPicker->getDirectory() );
420
421 if( aStrTmp[ aStrTmp.getLength() - 1 ] != sSlash[0] )
422 aStrTmp += sSlash;
423
424 // append old file name
425 if( bHandleFileName )
426 aStrTmp += aStrName;
427
428 INetURLObject aNewURL( aStrTmp );
429
430 if (!aStrName.isEmpty() && !aNewURL.getExtension().isEmpty() &&
431 m_xLbDocTypes->get_selected_index() != -1)
432 {
433 // get private-url
434 const sal_Int32 nPos = m_xLbDocTypes->get_selected_index();
435 aNewURL.setExtension(weld::fromId<DocumentTypeData*>(m_xLbDocTypes->get_id(nPos))->aStrExt);
436 }
437
438 if( aNewURL.GetProtocol() == INetProtocol::File )
439 {
440 osl::FileBase::getSystemPathFromFileURL(aNewURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), aStrTmp);
441 }
442 else
443 {
445 }
446
447 m_xCbbPath->set_entry_text( aStrTmp );
448}
449
450/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static ImplSVEvent * PostUserEvent(const Link< void *, void > &rLink, void *pCaller=nullptr, bool bReferenceLink=false)
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage, const ILibreOfficeKitNotifier *pNotifier=nullptr)
OUString getName(sal_Int32 nIndex=LAST_SEGMENT, bool bIgnoreFinalSlash=true, DecodeMechanism eMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
void SetExtension(std::u16string_view rTheExtension)
OUString GetMainURL(DecodeMechanism eMechanism, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
OUString getExtension(sal_Int32 nIndex=LAST_SEGMENT, bool bIgnoreFinalSlash=true, DecodeMechanism eMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
INetProtocol GetProtocol() const
bool setExtension(std::u16string_view rTheExtension, sal_Int32 nIndex=LAST_SEGMENT, bool bIgnoreFinalSlash=true, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8)
bool SetURL(std::u16string_view rTheAbsURIRef, EncodeMechanism eMechanism=EncodeMechanism::WasEncoded, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8)
void SetExchangeSupport()
Definition: iconcdlg.hxx:60
const SfxPoolItem * ExecuteList(sal_uInt16 nSlot, SfxCallMode nCall, std::initializer_list< SfxPoolItem const * > args, std::initializer_list< SfxPoolItem const * > internalargs=std::initializer_list< SfxPoolItem const * >())
SfxViewFrame * GetFrame() const
static std::shared_ptr< const SfxFilter > GetDefaultFilterFromFactory(const OUString &rServiceName)
const css::uno::Reference< css::frame::XFrame > & GetFrameInterface() const
SfxViewFrame * GetFrame() const
SfxDispatcher * GetDispatcher()
SfxFrame & GetFrame() const
virtual SfxObjectShell * GetObjectShell() override
const OUString & GetWorkPath() const
ComboBox-Control for URL's with History and Autocompletion.
Definition: hltpbase.hxx:36
SvxHyperlinkNewDocTp(weld::Container *pParent, SvxHpLinkDlg *pDlg, const SfxItemSet *pItemSet)
Definition: hldocntp.cxx:109
std::unique_ptr< weld::Button > m_xBtCreate
Definition: hldocntp.hxx:34
bool ImplGetURLObject(const OUString &rPath, std::u16string_view rBase, INetURLObject &aURLObject) const
Definition: hldocntp.cxx:70
std::unique_ptr< SvxHyperURLBox > m_xCbbPath
Definition: hldocntp.hxx:33
std::unique_ptr< weld::RadioButton > m_xRbtEditLater
Definition: hldocntp.hxx:32
virtual void SetInitFocus() override
Definition: hldocntp.cxx:233
std::unique_ptr< weld::TreeView > m_xLbDocTypes
Definition: hldocntp.hxx:35
virtual void DoApply() override
Definition: hldocntp.cxx:320
virtual ~SvxHyperlinkNewDocTp() override
Definition: hldocntp.cxx:135
void GetCurentItemData(OUString &rStrURL, OUString &aStrName, OUString &aStrIntName, OUString &aStrFrame, SvxLinkInsertMode &eMode) override
Definition: hldocntp.cxx:202
void FillDlgFields(const OUString &rStrURL) override
Definition: hldocntp.cxx:152
static std::unique_ptr< IconChoicePage > Create(weld::Container *pWindow, SvxHpLinkDlg *pDlg, const SfxItemSet *pItemSet)
Definition: hldocntp.cxx:223
std::unique_ptr< weld::RadioButton > m_xRbtEditNow
Definition: hldocntp.hxx:31
Tabpage : Basisclass.
Definition: hltpbase.hxx:47
SfxDispatcher * GetDispatcher() const
Definition: hltpbase.cxx:308
SvxHpLinkDlg * mpDialog
Definition: hltpbase.hxx:63
void GetDataFromCommonFields(OUString &aStrName, OUString &aStrIntName, OUString &aStrFrame, SvxLinkInsertMode &eMode)
Definition: hltpbase.cxx:422
static std::unique_ptr< SvStream > CreateStream(const OUString &rFileName, StreamMode eOpenMode, css::uno::Reference< css::awt::XWindow > xParentWin=nullptr)
OUString CuiResId(TranslateId aKey)
Definition: cuiresmgr.cxx:23
URL aURL
#define ERRCODE_NONE
void const * base
IMPL_STATIC_LINK(SvxHyperlinkNewDocTp, DispatchDocument, void *, p, void)
Definition: hldocntp.cxx:252
IMPL_LINK_NOARG(SvxHyperlinkNewDocTp, ClickNewHdl_Impl, weld::Button &, void)
Definition: hldocntp.cxx:385
SvxLinkInsertMode
OUString aName
Mode eMode
void * p
sal_Int64 n
sal_uInt16 nPos
std::vector< SvtDynMenuEntry > GetMenu(EDynamicMenuType eMenu)
css::uno::Reference< css::ui::dialogs::XFolderPicker2 > createFolderPicker(const css::uno::Reference< css::uno::XComponentContext > &rContext, weld::Window *pPreferredParent)
OUString toId(const void *pValue)
Reference< XFrame > xFrame
OUString sId
RET_YES