Line data Source code
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 <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>
35 :
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>
40 :
41 : using namespace ::com::sun::star::lang;
42 : using namespace ::com::sun::star::ui::dialogs;
43 : using namespace ::com::sun::star::uno;
44 :
45 : using namespace ::com::sun::star;
46 :
47 : /*************************************************************************
48 : |*
49 : |* Data-struct for documenttypes in listbox
50 : |*
51 : |************************************************************************/
52 :
53 0 : struct DocumentTypeData
54 : {
55 : OUString aStrURL;
56 : OUString aStrExt;
57 0 : DocumentTypeData (const OUString& aURL, const OUString& aExt) : aStrURL(aURL), aStrExt(aExt)
58 0 : {}
59 : };
60 :
61 0 : bool SvxHyperlinkNewDocTp::ImplGetURLObject( const OUString& rPath, const OUString& rBase, INetURLObject& aURLObject ) const
62 : {
63 0 : bool bIsValidURL = !rPath.isEmpty();
64 0 : if ( bIsValidURL )
65 : {
66 0 : aURLObject.SetURL( rPath );
67 0 : 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
69 : bool wasAbs;
70 0 : INetURLObject base(rBase);
71 0 : base.setFinalSlash();
72 0 : aURLObject = base.smartRel2Abs(
73 : rPath, wasAbs, true, INetURLObject::ENCODE_ALL,
74 0 : RTL_TEXTENCODING_UTF8, true);
75 : }
76 0 : bIsValidURL = aURLObject.GetProtocol() != INetProtocol::NotValid;
77 0 : if ( bIsValidURL )
78 : {
79 0 : OUString aBase( aURLObject.getName( INetURLObject::LAST_SEGMENT, false ) );
80 0 : if ( aBase.isEmpty() || ( aBase[0] == '.' ) )
81 0 : bIsValidURL = false;
82 : }
83 0 : if ( bIsValidURL )
84 : {
85 0 : sal_Int32 nPos = m_pLbDocTypes->GetSelectEntryPos();
86 0 : if ( nPos != LISTBOX_ENTRY_NOTFOUND )
87 0 : aURLObject.SetExtension( static_cast<DocumentTypeData*>(m_pLbDocTypes->GetEntryData( nPos ))->aStrExt );
88 : }
89 :
90 : }
91 0 : return bIsValidURL;
92 : }
93 :
94 : /*************************************************************************
95 : |*
96 : |* Constructor / Destructor
97 : |*
98 : |************************************************************************/
99 :
100 0 : SvxHyperlinkNewDocTp::SvxHyperlinkNewDocTp ( vcl::Window *pParent, IconChoiceDialog* pDlg, const SfxItemSet& rItemSet)
101 0 : : SvxHyperlinkTabPageBase ( pParent, pDlg, "HyperlinkNewDocPage", "cui/ui/hyperlinknewdocpage.ui", rItemSet )
102 : {
103 0 : get(m_pRbtEditNow, "editnow");
104 0 : get(m_pRbtEditLater, "editlater");
105 0 : get(m_pCbbPath, "path");
106 0 : m_pCbbPath->SetSmartProtocol(INetProtocol::File);
107 0 : get(m_pBtCreate, "create");
108 0 : m_pBtCreate->SetModeImage(Image(CUI_RES(RID_SVXBMP_NEWDOC)));
109 0 : get(m_pLbDocTypes, "types");
110 0 : m_pLbDocTypes->set_height_request(m_pLbDocTypes->GetTextHeight() * 5);
111 :
112 : // Set HC bitmaps and disable display of bitmap names.
113 0 : m_pBtCreate->EnableTextDisplay (false);
114 :
115 0 : InitStdControls();
116 :
117 0 : SetExchangeSupport ();
118 :
119 0 : m_pCbbPath->Show();
120 0 : m_pCbbPath->SetBaseURL(SvtPathOptions().GetWorkPath());
121 :
122 : // set defaults
123 0 : m_pRbtEditNow->Check();
124 :
125 0 : m_pBtCreate->SetClickHdl ( LINK ( this, SvxHyperlinkNewDocTp, ClickNewHdl_Impl ) );
126 :
127 0 : FillDocumentList ();
128 0 : }
129 :
130 0 : SvxHyperlinkNewDocTp::~SvxHyperlinkNewDocTp ()
131 : {
132 0 : disposeOnce();
133 0 : }
134 :
135 0 : void SvxHyperlinkNewDocTp::dispose()
136 : {
137 0 : if (m_pLbDocTypes)
138 : {
139 0 : for ( sal_Int32 n=0; n<m_pLbDocTypes->GetEntryCount(); n++ )
140 0 : delete static_cast<DocumentTypeData*>(m_pLbDocTypes->GetEntryData ( n ));
141 0 : m_pLbDocTypes = NULL;
142 : }
143 0 : m_pRbtEditNow.clear();
144 0 : m_pRbtEditLater.clear();
145 0 : m_pCbbPath.clear();
146 0 : m_pBtCreate.clear();
147 0 : m_pLbDocTypes.clear();
148 0 : SvxHyperlinkTabPageBase::dispose();
149 0 : }
150 :
151 : /*************************************************************************
152 : |*
153 : |* Fill the all dialog-controls except controls in groupbox "more..."
154 : |*
155 : |************************************************************************/
156 :
157 :
158 0 : void SvxHyperlinkNewDocTp::FillDlgFields(const OUString& /*rStrURL*/)
159 : {
160 0 : }
161 :
162 0 : void SvxHyperlinkNewDocTp::FillDocumentList ()
163 : {
164 0 : EnterWait();
165 :
166 : uno::Sequence< uno::Sequence< beans::PropertyValue > >
167 0 : aDynamicMenuEntries( SvtDynamicMenuOptions().GetMenu( E_NEWMENU ) );
168 :
169 0 : sal_uInt32 i, nCount = aDynamicMenuEntries.getLength();
170 0 : for ( i = 0; i < nCount; i++ )
171 : {
172 0 : uno::Sequence< beans::PropertyValue >& rDynamicMenuEntry = aDynamicMenuEntries[ i ];
173 :
174 0 : OUString aDocumentUrl, aTitle, aImageId, aTargetName;
175 :
176 0 : for ( int e = 0; e < rDynamicMenuEntry.getLength(); e++ )
177 : {
178 0 : if ( rDynamicMenuEntry[ e ].Name == DYNAMICMENU_PROPERTYNAME_URL )
179 0 : rDynamicMenuEntry[ e ].Value >>= aDocumentUrl;
180 0 : else if ( rDynamicMenuEntry[e].Name == DYNAMICMENU_PROPERTYNAME_TITLE )
181 0 : rDynamicMenuEntry[e].Value >>= aTitle;
182 0 : else if ( rDynamicMenuEntry[e].Name == DYNAMICMENU_PROPERTYNAME_IMAGEIDENTIFIER )
183 0 : rDynamicMenuEntry[e].Value >>= aImageId;
184 0 : else if ( rDynamicMenuEntry[e].Name == DYNAMICMENU_PROPERTYNAME_TARGETNAME )
185 0 : rDynamicMenuEntry[e].Value >>= aTargetName;
186 : }
187 : //#i96822# business cards, labels and database should not be inserted here
188 0 : if( aDocumentUrl == "private:factory/swriter?slot=21051" ||
189 0 : aDocumentUrl == "private:factory/swriter?slot=21052" ||
190 0 : aDocumentUrl == "private:factory/sdatabase?Interactive" )
191 0 : continue;
192 :
193 : // Insert into listbox
194 0 : if ( !aDocumentUrl.isEmpty() )
195 : {
196 0 : if ( aDocumentUrl == "private:factory/simpress?slot=6686" ) // SJ: #106216# do not start
197 0 : aDocumentUrl = "private:factory/simpress"; // the AutoPilot for impress
198 :
199 : // insert private-url and default-extension as user-data
200 0 : const SfxFilter* pFilter = SfxFilter::GetDefaultFilterFromFactory( aDocumentUrl );
201 0 : if ( pFilter )
202 : {
203 : // insert doc-name and image
204 0 : OUString aTitleName( aTitle );
205 0 : aTitleName = aTitleName.replaceFirst( "~", "" );
206 :
207 0 : sal_Int16 nPos = m_pLbDocTypes->InsertEntry ( aTitleName );
208 0 : OUString aStrDefExt( pFilter->GetDefaultExtension () );
209 0 : DocumentTypeData *pTypeData = new DocumentTypeData ( aDocumentUrl, aStrDefExt.copy( 2 ) );
210 0 : m_pLbDocTypes->SetEntryData ( nPos, pTypeData );
211 : }
212 : }
213 0 : }
214 0 : m_pLbDocTypes->SelectEntryPos ( 0 );
215 :
216 0 : LeaveWait();
217 0 : }
218 :
219 : /*************************************************************************
220 : |*
221 : |* retrieve and prepare data from dialog-fields
222 : |*
223 : |************************************************************************/
224 :
225 0 : void SvxHyperlinkNewDocTp::GetCurentItemData ( OUString& rStrURL, OUString& aStrName,
226 : OUString& aStrIntName, OUString& aStrFrame,
227 : SvxLinkInsertMode& eMode )
228 : {
229 : // get data from dialog-controls
230 0 : rStrURL = m_pCbbPath->GetText();
231 0 : INetURLObject aURL;
232 0 : if ( ImplGetURLObject( rStrURL, m_pCbbPath->GetBaseURL(), aURL ) )
233 : {
234 0 : rStrURL = aURL.GetMainURL( INetURLObject::NO_DECODE );
235 : }
236 :
237 0 : GetDataFromCommonFields( aStrName, aStrIntName, aStrFrame, eMode );
238 0 : }
239 :
240 : /*************************************************************************
241 : |*
242 : |* static method to create Tabpage
243 : |*
244 : |************************************************************************/
245 :
246 0 : VclPtr<IconChoicePage> SvxHyperlinkNewDocTp::Create( vcl::Window* pWindow, IconChoiceDialog* pDlg, const SfxItemSet& rItemSet )
247 : {
248 0 : return VclPtr<SvxHyperlinkNewDocTp>::Create( pWindow, pDlg, rItemSet );
249 : }
250 :
251 : /*************************************************************************
252 : |*
253 : |* Set initial focus
254 : |*
255 : |************************************************************************/
256 :
257 0 : void SvxHyperlinkNewDocTp::SetInitFocus()
258 : {
259 0 : m_pCbbPath->GrabFocus();
260 0 : }
261 :
262 : /*************************************************************************
263 : |*
264 : |* Ask page whether an insert is possible
265 : |*
266 : \************************************************************************/
267 :
268 0 : bool SvxHyperlinkNewDocTp::AskApply()
269 : {
270 0 : INetURLObject aINetURLObject;
271 0 : bool bRet = ImplGetURLObject( m_pCbbPath->GetText(), m_pCbbPath->GetBaseURL(), aINetURLObject );
272 0 : if ( !bRet )
273 : {
274 0 : ScopedVclPtrInstance< WarningBox > aWarning( this, WB_OK, CUI_RESSTR(RID_SVXSTR_HYPDLG_NOVALIDFILENAME) );
275 0 : aWarning->Execute();
276 : }
277 0 : return bRet;
278 : }
279 :
280 : /*************************************************************************
281 : |*
282 : |* Any action to do after apply-button is pressed
283 : |*
284 : \************************************************************************/
285 :
286 0 : void SvxHyperlinkNewDocTp::DoApply ()
287 : {
288 0 : EnterWait();
289 :
290 : // get data from dialog-controls
291 0 : OUString aStrNewName = m_pCbbPath->GetText();
292 :
293 0 : if ( aStrNewName == aEmptyStr )
294 0 : aStrNewName = maStrInitURL;
295 :
296 :
297 : // create a real URL-String
298 :
299 0 : INetURLObject aURL;
300 0 : if ( ImplGetURLObject( aStrNewName, m_pCbbPath->GetBaseURL(), aURL ) )
301 : {
302 :
303 :
304 : // create Document
305 :
306 0 : aStrNewName = aURL.GetURLPath( INetURLObject::NO_DECODE );
307 0 : SfxViewFrame *pViewFrame = NULL;
308 : try
309 : {
310 0 : bool bCreate = true;
311 :
312 : // check if file exists, warn before we overwrite it
313 : {
314 0 : com::sun::star::uno::Reference < com::sun::star::task::XInteractionHandler > xHandler;
315 0 : SvStream* pIStm = ::utl::UcbStreamHelper::CreateStream( aURL.GetMainURL( INetURLObject::NO_DECODE ), StreamMode::READ, xHandler );
316 :
317 0 : bool bOk = pIStm && ( pIStm->GetError() == 0);
318 :
319 0 : if( pIStm )
320 0 : delete pIStm;
321 :
322 0 : if( bOk )
323 : {
324 0 : ScopedVclPtrInstance<WarningBox> aWarning( this, WB_YES_NO, CUI_RESSTR(RID_SVXSTR_HYPERDLG_QUERYOVERWRITE) );
325 0 : bCreate = aWarning->Execute() == RET_YES;
326 0 : }
327 : }
328 :
329 0 : if( bCreate )
330 : {
331 : // current document
332 0 : SfxViewFrame* pCurrentDocFrame = SfxViewFrame::Current();
333 :
334 0 : if ( aStrNewName != aEmptyStr )
335 : {
336 : // get private-url
337 0 : sal_Int32 nPos = m_pLbDocTypes->GetSelectEntryPos();
338 0 : if( nPos == LISTBOX_ENTRY_NOTFOUND )
339 0 : nPos=0;
340 : OUString aStrDocName ( static_cast<DocumentTypeData*>(
341 0 : m_pLbDocTypes->GetEntryData( nPos ))->aStrURL );
342 :
343 : // create items
344 0 : SfxStringItem aName( SID_FILE_NAME, aStrDocName );
345 0 : SfxStringItem aReferer( SID_REFERER, OUString("private:user") );
346 0 : SfxStringItem aFrame( SID_TARGETNAME, OUString("_blank") );
347 :
348 0 : OUString aStrFlags('S');
349 0 : if ( m_pRbtEditLater->IsChecked() )
350 : {
351 0 : aStrFlags += OUString('H');
352 : }
353 0 : SfxStringItem aFlags (SID_OPTIONS, aStrFlags);
354 :
355 : // open url
356 : const SfxPoolItem* pReturn = GetDispatcher()->Execute( SID_OPENDOC,
357 : SfxCallMode::SYNCHRON,
358 : &aName, &aFlags,
359 0 : &aFrame, &aReferer, 0L );
360 :
361 : // save new doc
362 0 : const SfxViewFrameItem *pItem = PTR_CAST( SfxViewFrameItem, pReturn ); // SJ: pReturn is NULL if the Hyperlink
363 0 : if ( pItem ) // creation is cancelled #106216#
364 : {
365 0 : pViewFrame = pItem->GetFrame();
366 0 : if (pViewFrame)
367 : {
368 0 : SfxStringItem aNewName( SID_FILE_NAME, aURL.GetMainURL( INetURLObject::NO_DECODE ) );
369 :
370 : pViewFrame->GetDispatcher()->Execute( SID_SAVEASDOC,
371 : SfxCallMode::SYNCHRON,
372 0 : &aNewName, 0L );
373 :
374 : }
375 0 : }
376 : }
377 :
378 0 : if ( m_pRbtEditNow->IsChecked() && pCurrentDocFrame )
379 : {
380 0 : pCurrentDocFrame->ToTop();
381 : }
382 : }
383 : }
384 0 : catch (const uno::Exception&)
385 : {
386 : }
387 :
388 0 : if ( pViewFrame && m_pRbtEditLater->IsChecked() )
389 : {
390 0 : SfxObjectShell* pObjShell = pViewFrame->GetObjectShell();
391 0 : pObjShell->DoClose();
392 : }
393 : }
394 :
395 0 : LeaveWait();
396 0 : }
397 :
398 : /*************************************************************************
399 : |*
400 : |* Click on imagebutton : new
401 : |*
402 : |************************************************************************/
403 :
404 0 : IMPL_LINK_NOARG(SvxHyperlinkNewDocTp, ClickNewHdl_Impl)
405 : {
406 0 : uno::Reference < XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
407 0 : uno::Reference < XFolderPicker2 > xFolderPicker = FolderPicker::create(xContext);
408 :
409 0 : OUString aStrURL;
410 0 : OUString aTempStrURL( m_pCbbPath->GetText() );
411 0 : utl::LocalFileHelper::ConvertSystemPathToURL( aTempStrURL, m_pCbbPath->GetBaseURL(), aStrURL );
412 :
413 0 : OUString aStrPath = aStrURL;
414 0 : bool bZeroPath = aStrPath.isEmpty();
415 0 : 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
417 :
418 0 : if( bZeroPath )
419 0 : aStrPath = SvtPathOptions().GetWorkPath();
420 0 : else if( !::utl::UCBContentHelper::IsFolder( aStrURL ) )
421 0 : bHandleFileName = true;
422 :
423 0 : xFolderPicker->setDisplayDirectory( aStrPath );
424 0 : DisableClose( true );
425 0 : sal_Int16 nResult = xFolderPicker->execute();
426 0 : DisableClose( false );
427 0 : if( ExecutableDialogResults::OK == nResult )
428 : {
429 0 : sal_Char const sSlash[] = "/";
430 :
431 0 : INetURLObject aURL( aStrURL, INetProtocol::File );
432 0 : OUString aStrName;
433 0 : if( bHandleFileName )
434 0 : aStrName = bZeroPath? aTempStrURL : OUString(aURL.getName());
435 :
436 0 : m_pCbbPath->SetBaseURL( xFolderPicker->getDirectory() );
437 0 : OUString aStrTmp( xFolderPicker->getDirectory() );
438 :
439 0 : if( aStrTmp[ aStrTmp.getLength() - 1 ] != sSlash[0] )
440 0 : aStrTmp += OUString( sSlash );
441 :
442 : // append old file name
443 0 : if( bHandleFileName )
444 0 : aStrTmp += aStrName;
445 :
446 0 : INetURLObject aNewURL( aStrTmp );
447 :
448 0 : if( !aStrName.isEmpty() && !aNewURL.getExtension().isEmpty() &&
449 0 : m_pLbDocTypes->GetSelectEntryPos() != LISTBOX_ENTRY_NOTFOUND )
450 : {
451 : // get private-url
452 0 : sal_uInt16 nPos = m_pLbDocTypes->GetSelectEntryPos();
453 0 : aNewURL.setExtension( static_cast<DocumentTypeData*>(m_pLbDocTypes->GetEntryData( nPos ))->aStrExt );
454 : }
455 :
456 0 : if( aNewURL.GetProtocol() == INetProtocol::File )
457 : {
458 0 : utl::LocalFileHelper::ConvertURLToSystemPath( aNewURL.GetMainURL( INetURLObject::NO_DECODE ), aStrTmp );
459 : }
460 : else
461 : {
462 0 : aStrTmp = aNewURL.GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS );
463 : }
464 :
465 0 : m_pCbbPath->SetText ( aStrTmp );
466 : }
467 0 : return 0L;
468 0 : }
469 :
470 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|