1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "hldocntp.hxx"
21 #include <sfx2/viewfrm.hxx>
22 #include <sfx2/docfac.hxx>
23 #include <com/sun/star/uno/Reference.h>
24 #include <com/sun/star/uno/Sequence.h>
25 #include <com/sun/star/beans/PropertyValue.hpp>
26 #include <com/sun/star/uno/Exception.hpp>
27 #include <unotools/localfilehelper.hxx>
28 #include <vcl/image.hxx>
29 #include <tools/urlobj.hxx>
30 #include <unotools/pathoptions.hxx>
31 #include <unotools/dynamicmenuoptions.hxx>
32 #include <sfx2/filedlghelper.hxx>
33 #include <unotools/ucbstreamhelper.hxx>
34 #include <unotools/ucbhelper.hxx>
36 #include <comphelper/processfactory.hxx>
37 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
38 #include <com/sun/star/ui/dialogs/FolderPicker.hpp>
39 #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
41 using namespace ::com::sun::star::lang
;
42 using namespace ::com::sun::star::ui::dialogs
;
43 using namespace ::com::sun::star::uno
;
45 using namespace ::com::sun::star
;
47 /*************************************************************************
49 |* Data-struct for documenttypes in listbox
51 |************************************************************************/
53 struct DocumentTypeData
57 DocumentTypeData (const OUString
& aURL
, const OUString
& aExt
) : aStrURL(aURL
), aStrExt(aExt
)
61 bool SvxHyperlinkNewDocTp::ImplGetURLObject( const OUString
& rPath
, const OUString
& rBase
, INetURLObject
& aURLObject
) const
63 bool bIsValidURL
= !rPath
.isEmpty();
66 aURLObject
.SetURL( rPath
);
67 if ( aURLObject
.GetProtocol() == INetProtocol::NotValid
) // test if the source is already a valid url
68 { // if not we have to create a url from a physical file name
70 INetURLObject
base(rBase
);
72 aURLObject
= base
.smartRel2Abs(
73 rPath
, wasAbs
, true, INetURLObject::ENCODE_ALL
,
74 RTL_TEXTENCODING_UTF8
, true);
76 bIsValidURL
= aURLObject
.GetProtocol() != INetProtocol::NotValid
;
79 OUString
aBase( aURLObject
.getName( INetURLObject::LAST_SEGMENT
, false ) );
80 if ( aBase
.isEmpty() || ( aBase
[0] == '.' ) )
85 sal_Int32 nPos
= m_pLbDocTypes
->GetSelectEntryPos();
86 if ( nPos
!= LISTBOX_ENTRY_NOTFOUND
)
87 aURLObject
.SetExtension( static_cast<DocumentTypeData
*>(m_pLbDocTypes
->GetEntryData( nPos
))->aStrExt
);
94 /*************************************************************************
96 |* Constructor / Destructor
98 |************************************************************************/
100 SvxHyperlinkNewDocTp::SvxHyperlinkNewDocTp ( vcl::Window
*pParent
, IconChoiceDialog
* pDlg
, const SfxItemSet
& rItemSet
)
101 : SvxHyperlinkTabPageBase ( pParent
, pDlg
, "HyperlinkNewDocPage", "cui/ui/hyperlinknewdocpage.ui", rItemSet
)
103 get(m_pRbtEditNow
, "editnow");
104 get(m_pRbtEditLater
, "editlater");
105 get(m_pCbbPath
, "path");
106 m_pCbbPath
->SetSmartProtocol(INetProtocol::File
);
107 get(m_pBtCreate
, "create");
108 m_pBtCreate
->SetModeImage(Image(CUI_RES(RID_SVXBMP_NEWDOC
)));
109 get(m_pLbDocTypes
, "types");
110 m_pLbDocTypes
->set_height_request(m_pLbDocTypes
->GetTextHeight() * 5);
112 // Set HC bitmaps and disable display of bitmap names.
113 m_pBtCreate
->EnableTextDisplay (false);
117 SetExchangeSupport ();
120 m_pCbbPath
->SetBaseURL(SvtPathOptions().GetWorkPath());
123 m_pRbtEditNow
->Check();
125 m_pBtCreate
->SetClickHdl ( LINK ( this, SvxHyperlinkNewDocTp
, ClickNewHdl_Impl
) );
130 SvxHyperlinkNewDocTp::~SvxHyperlinkNewDocTp ()
135 void SvxHyperlinkNewDocTp::dispose()
139 for ( sal_uInt16 n
=0; n
<m_pLbDocTypes
->GetEntryCount(); n
++ )
140 delete static_cast<DocumentTypeData
*>(m_pLbDocTypes
->GetEntryData ( n
));
141 m_pLbDocTypes
= NULL
;
143 m_pRbtEditNow
.clear();
144 m_pRbtEditLater
.clear();
147 m_pLbDocTypes
.clear();
148 SvxHyperlinkTabPageBase::dispose();
151 /*************************************************************************
153 |* Fill the all dialog-controls except controls in groupbox "more..."
155 |************************************************************************/
158 void SvxHyperlinkNewDocTp::FillDlgFields(const OUString
& /*rStrURL*/)
162 void SvxHyperlinkNewDocTp::FillDocumentList ()
166 uno::Sequence
< uno::Sequence
< beans::PropertyValue
> >
167 aDynamicMenuEntries( SvtDynamicMenuOptions().GetMenu( E_NEWMENU
) );
169 sal_uInt32 i
, nCount
= aDynamicMenuEntries
.getLength();
170 for ( i
= 0; i
< nCount
; i
++ )
172 uno::Sequence
< beans::PropertyValue
>& rDynamicMenuEntry
= aDynamicMenuEntries
[ i
];
174 OUString aDocumentUrl
, aTitle
, aImageId
, aTargetName
;
176 for ( int e
= 0; e
< rDynamicMenuEntry
.getLength(); e
++ )
178 if ( rDynamicMenuEntry
[ e
].Name
== DYNAMICMENU_PROPERTYNAME_URL
)
179 rDynamicMenuEntry
[ e
].Value
>>= aDocumentUrl
;
180 else if ( rDynamicMenuEntry
[e
].Name
== DYNAMICMENU_PROPERTYNAME_TITLE
)
181 rDynamicMenuEntry
[e
].Value
>>= aTitle
;
182 else if ( rDynamicMenuEntry
[e
].Name
== DYNAMICMENU_PROPERTYNAME_IMAGEIDENTIFIER
)
183 rDynamicMenuEntry
[e
].Value
>>= aImageId
;
184 else if ( rDynamicMenuEntry
[e
].Name
== DYNAMICMENU_PROPERTYNAME_TARGETNAME
)
185 rDynamicMenuEntry
[e
].Value
>>= aTargetName
;
187 //#i96822# business cards, labels and database should not be inserted here
188 if( aDocumentUrl
== "private:factory/swriter?slot=21051" ||
189 aDocumentUrl
== "private:factory/swriter?slot=21052" ||
190 aDocumentUrl
== "private:factory/sdatabase?Interactive" )
193 // Insert into listbox
194 if ( !aDocumentUrl
.isEmpty() )
196 if ( aDocumentUrl
== "private:factory/simpress?slot=6686" ) // SJ: #106216# do not start
197 aDocumentUrl
= "private:factory/simpress"; // the AutoPilot for impress
199 // insert private-url and default-extension as user-data
200 const SfxFilter
* pFilter
= SfxFilter::GetDefaultFilterFromFactory( aDocumentUrl
);
203 // insert doc-name and image
204 OUString
aTitleName( aTitle
);
205 aTitleName
= aTitleName
.replaceFirst( "~", "" );
207 sal_Int16 nPos
= m_pLbDocTypes
->InsertEntry ( aTitleName
);
208 OUString
aStrDefExt( pFilter
->GetDefaultExtension () );
209 DocumentTypeData
*pTypeData
= new DocumentTypeData ( aDocumentUrl
, aStrDefExt
.copy( 2 ) );
210 m_pLbDocTypes
->SetEntryData ( nPos
, pTypeData
);
214 m_pLbDocTypes
->SelectEntryPos ( 0 );
219 /*************************************************************************
221 |* retrieve and prepare data from dialog-fields
223 |************************************************************************/
225 void SvxHyperlinkNewDocTp::GetCurentItemData ( OUString
& rStrURL
, OUString
& aStrName
,
226 OUString
& aStrIntName
, OUString
& aStrFrame
,
227 SvxLinkInsertMode
& eMode
)
229 // get data from dialog-controls
230 rStrURL
= m_pCbbPath
->GetText();
232 if ( ImplGetURLObject( rStrURL
, m_pCbbPath
->GetBaseURL(), aURL
) )
234 rStrURL
= aURL
.GetMainURL( INetURLObject::NO_DECODE
);
237 GetDataFromCommonFields( aStrName
, aStrIntName
, aStrFrame
, eMode
);
240 /*************************************************************************
242 |* static method to create Tabpage
244 |************************************************************************/
246 VclPtr
<IconChoicePage
> SvxHyperlinkNewDocTp::Create( vcl::Window
* pWindow
, IconChoiceDialog
* pDlg
, const SfxItemSet
& rItemSet
)
248 return VclPtr
<SvxHyperlinkNewDocTp
>::Create( pWindow
, pDlg
, rItemSet
);
251 /*************************************************************************
255 |************************************************************************/
257 void SvxHyperlinkNewDocTp::SetInitFocus()
259 m_pCbbPath
->GrabFocus();
262 /*************************************************************************
264 |* Ask page whether an insert is possible
266 \************************************************************************/
268 bool SvxHyperlinkNewDocTp::AskApply()
270 INetURLObject aINetURLObject
;
271 bool bRet
= ImplGetURLObject( m_pCbbPath
->GetText(), m_pCbbPath
->GetBaseURL(), aINetURLObject
);
274 ScopedVclPtrInstance
< WarningBox
> aWarning( this, WB_OK
, CUI_RESSTR(RID_SVXSTR_HYPDLG_NOVALIDFILENAME
) );
280 /*************************************************************************
282 |* Any action to do after apply-button is pressed
284 \************************************************************************/
286 void SvxHyperlinkNewDocTp::DoApply ()
290 // get data from dialog-controls
291 OUString aStrNewName
= m_pCbbPath
->GetText();
293 if ( aStrNewName
== aEmptyStr
)
294 aStrNewName
= maStrInitURL
;
297 // create a real URL-String
300 if ( ImplGetURLObject( aStrNewName
, m_pCbbPath
->GetBaseURL(), aURL
) )
306 aStrNewName
= aURL
.GetURLPath( INetURLObject::NO_DECODE
);
307 SfxViewFrame
*pViewFrame
= NULL
;
312 // check if file exists, warn before we overwrite it
314 com::sun::star::uno::Reference
< com::sun::star::task::XInteractionHandler
> xHandler
;
315 SvStream
* pIStm
= ::utl::UcbStreamHelper::CreateStream( aURL
.GetMainURL( INetURLObject::NO_DECODE
), StreamMode::READ
, xHandler
);
317 bool bOk
= pIStm
&& ( pIStm
->GetError() == 0);
324 ScopedVclPtrInstance
<WarningBox
> aWarning( this, WB_YES_NO
, CUI_RESSTR(RID_SVXSTR_HYPERDLG_QUERYOVERWRITE
) );
325 bCreate
= aWarning
->Execute() == RET_YES
;
332 SfxViewFrame
* pCurrentDocFrame
= SfxViewFrame::Current();
334 if ( aStrNewName
!= aEmptyStr
)
337 sal_Int32 nPos
= m_pLbDocTypes
->GetSelectEntryPos();
338 if( nPos
== LISTBOX_ENTRY_NOTFOUND
)
340 OUString
aStrDocName ( static_cast<DocumentTypeData
*>(
341 m_pLbDocTypes
->GetEntryData( nPos
))->aStrURL
);
344 SfxStringItem
aName( SID_FILE_NAME
, aStrDocName
);
345 SfxStringItem
aReferer( SID_REFERER
, OUString("private:user") );
346 SfxStringItem
aFrame( SID_TARGETNAME
, OUString("_blank") );
348 OUString
aStrFlags('S');
349 if ( m_pRbtEditLater
->IsChecked() )
351 aStrFlags
+= OUString('H');
353 SfxStringItem
aFlags (SID_OPTIONS
, aStrFlags
);
356 const SfxPoolItem
* pReturn
= GetDispatcher()->Execute( SID_OPENDOC
,
357 SfxCallMode::SYNCHRON
,
359 &aFrame
, &aReferer
, 0L );
362 const SfxViewFrameItem
*pItem
= PTR_CAST( SfxViewFrameItem
, pReturn
); // SJ: pReturn is NULL if the Hyperlink
363 if ( pItem
) // creation is cancelled #106216#
365 pViewFrame
= pItem
->GetFrame();
368 SfxStringItem
aNewName( SID_FILE_NAME
, aURL
.GetMainURL( INetURLObject::NO_DECODE
) );
370 pViewFrame
->GetDispatcher()->Execute( SID_SAVEASDOC
,
371 SfxCallMode::SYNCHRON
,
378 if ( m_pRbtEditNow
->IsChecked() && pCurrentDocFrame
)
380 pCurrentDocFrame
->ToTop();
384 catch (const uno::Exception
&)
388 if ( pViewFrame
&& m_pRbtEditLater
->IsChecked() )
390 SfxObjectShell
* pObjShell
= pViewFrame
->GetObjectShell();
391 pObjShell
->DoClose();
398 /*************************************************************************
400 |* Click on imagebutton : new
402 |************************************************************************/
404 IMPL_LINK_NOARG(SvxHyperlinkNewDocTp
, ClickNewHdl_Impl
)
406 uno::Reference
< XComponentContext
> xContext( ::comphelper::getProcessComponentContext() );
407 uno::Reference
< XFolderPicker2
> xFolderPicker
= FolderPicker::create(xContext
);
410 OUString
aTempStrURL( m_pCbbPath
->GetText() );
411 utl::LocalFileHelper::ConvertSystemPathToURL( aTempStrURL
, m_pCbbPath
->GetBaseURL(), aStrURL
);
413 OUString aStrPath
= aStrURL
;
414 bool bZeroPath
= aStrPath
.isEmpty();
415 bool bHandleFileName
= bZeroPath
; // when path has length of 0, then the rest should always be handled
416 // as file name, otherwise we do not yet know
419 aStrPath
= SvtPathOptions().GetWorkPath();
420 else if( !::utl::UCBContentHelper::IsFolder( aStrURL
) )
421 bHandleFileName
= true;
423 xFolderPicker
->setDisplayDirectory( aStrPath
);
424 DisableClose( true );
425 sal_Int16 nResult
= xFolderPicker
->execute();
426 DisableClose( false );
427 if( ExecutableDialogResults::OK
== nResult
)
429 sal_Char
const sSlash
[] = "/";
431 INetURLObject
aURL( aStrURL
, INetProtocol::File
);
433 if( bHandleFileName
)
434 aStrName
= bZeroPath
? aTempStrURL
: OUString(aURL
.getName());
436 m_pCbbPath
->SetBaseURL( xFolderPicker
->getDirectory() );
437 OUString
aStrTmp( xFolderPicker
->getDirectory() );
439 if( aStrTmp
[ aStrTmp
.getLength() - 1 ] != sSlash
[0] )
440 aStrTmp
+= OUString( sSlash
);
442 // append old file name
443 if( bHandleFileName
)
446 INetURLObject
aNewURL( aStrTmp
);
448 if( !aStrName
.isEmpty() && !aNewURL
.getExtension().isEmpty() &&
449 m_pLbDocTypes
->GetSelectEntryPos() != LISTBOX_ENTRY_NOTFOUND
)
452 sal_uInt16 nPos
= m_pLbDocTypes
->GetSelectEntryPos();
453 aNewURL
.setExtension( static_cast<DocumentTypeData
*>(m_pLbDocTypes
->GetEntryData( nPos
))->aStrExt
);
456 if( aNewURL
.GetProtocol() == INetProtocol::File
)
458 utl::LocalFileHelper::ConvertURLToSystemPath( aNewURL
.GetMainURL( INetURLObject::NO_DECODE
), aStrTmp
);
462 aStrTmp
= aNewURL
.GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS
);
465 m_pCbbPath
->SetText ( aStrTmp
);
470 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */