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() == INET_PROT_NOT_VALID ) // 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() != INET_PROT_NOT_VALID;
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( ((DocumentTypeData*)m_pLbDocTypes->GetEntryData( nPos ))->aStrExt );
88 : }
89 :
90 : }
91 0 : return bIsValidURL;
92 : }
93 :
94 : /*************************************************************************
95 : |*
96 : |* Contructor / 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(INET_PROT_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 : for ( sal_uInt16 n=0; n<m_pLbDocTypes->GetEntryCount(); n++ )
133 : {
134 : DocumentTypeData* pTypeData = (DocumentTypeData*)
135 0 : m_pLbDocTypes->GetEntryData ( n );
136 0 : delete pTypeData;
137 : }
138 0 : }
139 :
140 : /*************************************************************************
141 : |*
142 : |* Fill the all dialog-controls except controls in groupbox "more..."
143 : |*
144 : |************************************************************************/
145 :
146 :
147 0 : void SvxHyperlinkNewDocTp::FillDlgFields(const OUString& /*rStrURL*/)
148 : {
149 0 : }
150 :
151 0 : void SvxHyperlinkNewDocTp::FillDocumentList ()
152 : {
153 0 : EnterWait();
154 :
155 : uno::Sequence< uno::Sequence< beans::PropertyValue > >
156 0 : aDynamicMenuEntries( SvtDynamicMenuOptions().GetMenu( E_NEWMENU ) );
157 :
158 0 : sal_uInt32 i, nCount = aDynamicMenuEntries.getLength();
159 0 : for ( i = 0; i < nCount; i++ )
160 : {
161 0 : uno::Sequence< beans::PropertyValue >& rDynamicMenuEntry = aDynamicMenuEntries[ i ];
162 :
163 0 : OUString aDocumentUrl, aTitle, aImageId, aTargetName;
164 :
165 0 : for ( int e = 0; e < rDynamicMenuEntry.getLength(); e++ )
166 : {
167 0 : if ( rDynamicMenuEntry[ e ].Name == DYNAMICMENU_PROPERTYNAME_URL )
168 0 : rDynamicMenuEntry[ e ].Value >>= aDocumentUrl;
169 0 : else if ( rDynamicMenuEntry[e].Name == DYNAMICMENU_PROPERTYNAME_TITLE )
170 0 : rDynamicMenuEntry[e].Value >>= aTitle;
171 0 : else if ( rDynamicMenuEntry[e].Name == DYNAMICMENU_PROPERTYNAME_IMAGEIDENTIFIER )
172 0 : rDynamicMenuEntry[e].Value >>= aImageId;
173 0 : else if ( rDynamicMenuEntry[e].Name == DYNAMICMENU_PROPERTYNAME_TARGETNAME )
174 0 : rDynamicMenuEntry[e].Value >>= aTargetName;
175 : }
176 : //#i96822# business cards, labels and database should not be inserted here
177 0 : if( aDocumentUrl == "private:factory/swriter?slot=21051" ||
178 0 : aDocumentUrl == "private:factory/swriter?slot=21052" ||
179 0 : aDocumentUrl == "private:factory/sdatabase?Interactive" )
180 0 : continue;
181 :
182 : // Insert into listbox
183 0 : if ( !aDocumentUrl.isEmpty() )
184 : {
185 0 : if ( aDocumentUrl == "private:factory/simpress?slot=6686" ) // SJ: #106216# do not start
186 0 : aDocumentUrl = "private:factory/simpress"; // the AutoPilot for impress
187 :
188 : // insert private-url and default-extension as user-data
189 0 : const SfxFilter* pFilter = SfxFilter::GetDefaultFilterFromFactory( aDocumentUrl );
190 0 : if ( pFilter )
191 : {
192 : // insert doc-name and image
193 0 : OUString aTitleName( aTitle );
194 0 : aTitleName = aTitleName.replaceFirst( "~", "" );
195 :
196 0 : sal_Int16 nPos = m_pLbDocTypes->InsertEntry ( aTitleName );
197 0 : OUString aStrDefExt( pFilter->GetDefaultExtension () );
198 0 : DocumentTypeData *pTypeData = new DocumentTypeData ( aDocumentUrl, aStrDefExt.copy( 2 ) );
199 0 : m_pLbDocTypes->SetEntryData ( nPos, pTypeData );
200 : }
201 : }
202 0 : }
203 0 : m_pLbDocTypes->SelectEntryPos ( 0 );
204 :
205 0 : LeaveWait();
206 0 : }
207 :
208 : /*************************************************************************
209 : |*
210 : |* retrieve and prepare data from dialog-fields
211 : |*
212 : |************************************************************************/
213 :
214 0 : void SvxHyperlinkNewDocTp::GetCurentItemData ( OUString& rStrURL, OUString& aStrName,
215 : OUString& aStrIntName, OUString& aStrFrame,
216 : SvxLinkInsertMode& eMode )
217 : {
218 : // get data from dialog-controls
219 0 : rStrURL = m_pCbbPath->GetText();
220 0 : INetURLObject aURL;
221 0 : if ( ImplGetURLObject( rStrURL, m_pCbbPath->GetBaseURL(), aURL ) )
222 : {
223 0 : rStrURL = aURL.GetMainURL( INetURLObject::NO_DECODE );
224 : }
225 :
226 0 : GetDataFromCommonFields( aStrName, aStrIntName, aStrFrame, eMode );
227 0 : }
228 :
229 : /*************************************************************************
230 : |*
231 : |* static method to create Tabpage
232 : |*
233 : |************************************************************************/
234 :
235 0 : IconChoicePage* SvxHyperlinkNewDocTp::Create( vcl::Window* pWindow, IconChoiceDialog* pDlg, const SfxItemSet& rItemSet )
236 : {
237 0 : return( new SvxHyperlinkNewDocTp( pWindow, pDlg, rItemSet ) );
238 : }
239 :
240 : /*************************************************************************
241 : |*
242 : |* Set initial focus
243 : |*
244 : |************************************************************************/
245 :
246 0 : void SvxHyperlinkNewDocTp::SetInitFocus()
247 : {
248 0 : m_pCbbPath->GrabFocus();
249 0 : }
250 :
251 : /*************************************************************************
252 : |*
253 : |* Ask page whether an insert is possible
254 : |*
255 : \************************************************************************/
256 :
257 0 : bool SvxHyperlinkNewDocTp::AskApply()
258 : {
259 0 : INetURLObject aINetURLObject;
260 0 : bool bRet = ImplGetURLObject( m_pCbbPath->GetText(), m_pCbbPath->GetBaseURL(), aINetURLObject );
261 0 : if ( !bRet )
262 : {
263 0 : WarningBox aWarning( this, WB_OK, CUI_RESSTR(RID_SVXSTR_HYPDLG_NOVALIDFILENAME) );
264 0 : aWarning.Execute();
265 : }
266 0 : return bRet;
267 : }
268 :
269 : /*************************************************************************
270 : |*
271 : |* Any action to do after apply-button is pressed
272 : |*
273 : \************************************************************************/
274 :
275 0 : void SvxHyperlinkNewDocTp::DoApply ()
276 : {
277 0 : EnterWait();
278 :
279 : // get data from dialog-controls
280 0 : OUString aStrNewName = m_pCbbPath->GetText();
281 :
282 0 : if ( aStrNewName == aEmptyStr )
283 0 : aStrNewName = maStrInitURL;
284 :
285 :
286 : // create a real URL-String
287 :
288 0 : INetURLObject aURL;
289 0 : if ( ImplGetURLObject( aStrNewName, m_pCbbPath->GetBaseURL(), aURL ) )
290 : {
291 :
292 :
293 : // create Document
294 :
295 0 : aStrNewName = aURL.GetURLPath( INetURLObject::NO_DECODE );
296 0 : SfxViewFrame *pViewFrame = NULL;
297 : try
298 : {
299 0 : bool bCreate = true;
300 :
301 : // check if file exists, warn before we overwrite it
302 : {
303 0 : com::sun::star::uno::Reference < com::sun::star::task::XInteractionHandler > xHandler;
304 0 : SvStream* pIStm = ::utl::UcbStreamHelper::CreateStream( aURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_READ, xHandler );
305 :
306 0 : bool bOk = pIStm && ( pIStm->GetError() == 0);
307 :
308 0 : if( pIStm )
309 0 : delete pIStm;
310 :
311 0 : if( bOk )
312 : {
313 0 : WarningBox aWarning( this, WB_YES_NO, CUI_RESSTR(RID_SVXSTR_HYPERDLG_QUERYOVERWRITE) );
314 0 : bCreate = aWarning.Execute() == BUTTON_YES;
315 0 : }
316 : }
317 :
318 0 : if( bCreate )
319 : {
320 : // current document
321 0 : SfxViewFrame* pCurrentDocFrame = SfxViewFrame::Current();
322 :
323 0 : if ( aStrNewName != aEmptyStr )
324 : {
325 : // get private-url
326 0 : sal_Int32 nPos = m_pLbDocTypes->GetSelectEntryPos();
327 0 : if( nPos == LISTBOX_ENTRY_NOTFOUND )
328 0 : nPos=0;
329 : OUString aStrDocName ( ( ( DocumentTypeData* )
330 0 : m_pLbDocTypes->GetEntryData( nPos ) )->aStrURL );
331 :
332 : // create items
333 0 : SfxStringItem aName( SID_FILE_NAME, aStrDocName );
334 0 : SfxStringItem aReferer( SID_REFERER, OUString("private:user") );
335 0 : SfxStringItem aFrame( SID_TARGETNAME, OUString("_blank") );
336 :
337 0 : OUString aStrFlags('S');
338 0 : if ( m_pRbtEditLater->IsChecked() )
339 : {
340 0 : aStrFlags += OUString('H');
341 : }
342 0 : SfxStringItem aFlags (SID_OPTIONS, aStrFlags);
343 :
344 : // open url
345 : const SfxPoolItem* pReturn = GetDispatcher()->Execute( SID_OPENDOC,
346 : SfxCallMode::SYNCHRON,
347 : &aName, &aFlags,
348 0 : &aFrame, &aReferer, 0L );
349 :
350 : // save new doc
351 0 : const SfxViewFrameItem *pItem = PTR_CAST( SfxViewFrameItem, pReturn ); // SJ: pReturn is NULL if the Hyperlink
352 0 : if ( pItem ) // creation is cancelled #106216#
353 : {
354 0 : pViewFrame = pItem->GetFrame();
355 0 : if (pViewFrame)
356 : {
357 0 : SfxStringItem aNewName( SID_FILE_NAME, aURL.GetMainURL( INetURLObject::NO_DECODE ) );
358 :
359 : pViewFrame->GetDispatcher()->Execute( SID_SAVEASDOC,
360 : SfxCallMode::SYNCHRON,
361 0 : &aNewName, 0L );
362 :
363 : }
364 0 : }
365 : }
366 :
367 0 : if ( m_pRbtEditNow->IsChecked() && pCurrentDocFrame )
368 : {
369 0 : pCurrentDocFrame->ToTop();
370 : }
371 : }
372 : }
373 0 : catch (const uno::Exception&)
374 : {
375 : }
376 :
377 0 : if ( pViewFrame && m_pRbtEditLater->IsChecked() )
378 : {
379 0 : SfxObjectShell* pObjShell = pViewFrame->GetObjectShell();
380 0 : pObjShell->DoClose();
381 : }
382 : }
383 :
384 0 : LeaveWait();
385 0 : }
386 :
387 : /*************************************************************************
388 : |*
389 : |* Click on imagebutton : new
390 : |*
391 : |************************************************************************/
392 :
393 0 : IMPL_LINK_NOARG(SvxHyperlinkNewDocTp, ClickNewHdl_Impl)
394 : {
395 0 : uno::Reference < XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
396 0 : uno::Reference < XFolderPicker2 > xFolderPicker = FolderPicker::create(xContext);
397 :
398 0 : OUString aStrURL;
399 0 : OUString aTempStrURL( m_pCbbPath->GetText() );
400 0 : utl::LocalFileHelper::ConvertSystemPathToURL( aTempStrURL, m_pCbbPath->GetBaseURL(), aStrURL );
401 :
402 0 : OUString aStrPath = aStrURL;
403 0 : bool bZeroPath = aStrPath.isEmpty();
404 0 : bool bHandleFileName = bZeroPath; // when path has length of 0, then the rest should always be handled
405 : // as file name, otherwise we do not yet know
406 :
407 0 : if( bZeroPath )
408 0 : aStrPath = SvtPathOptions().GetWorkPath();
409 0 : else if( !::utl::UCBContentHelper::IsFolder( aStrURL ) )
410 0 : bHandleFileName = true;
411 :
412 0 : xFolderPicker->setDisplayDirectory( aStrPath );
413 0 : DisableClose( true );
414 0 : sal_Int16 nResult = xFolderPicker->execute();
415 0 : DisableClose( false );
416 0 : if( ExecutableDialogResults::OK == nResult )
417 : {
418 0 : sal_Char const sSlash[] = "/";
419 :
420 0 : INetURLObject aURL( aStrURL, INET_PROT_FILE );
421 0 : OUString aStrName;
422 0 : if( bHandleFileName )
423 0 : aStrName = bZeroPath? aTempStrURL : OUString(aURL.getName());
424 :
425 0 : m_pCbbPath->SetBaseURL( xFolderPicker->getDirectory() );
426 0 : OUString aStrTmp( xFolderPicker->getDirectory() );
427 :
428 0 : if( aStrTmp[ aStrTmp.getLength() - 1 ] != sSlash[0] )
429 0 : aStrTmp += OUString( sSlash );
430 :
431 : // append old file name
432 0 : if( bHandleFileName )
433 0 : aStrTmp += aStrName;
434 :
435 0 : INetURLObject aNewURL( aStrTmp );
436 :
437 0 : if( !aStrName.isEmpty() && !aNewURL.getExtension().isEmpty() &&
438 0 : m_pLbDocTypes->GetSelectEntryPos() != LISTBOX_ENTRY_NOTFOUND )
439 : {
440 : // get private-url
441 0 : sal_uInt16 nPos = m_pLbDocTypes->GetSelectEntryPos();
442 0 : aNewURL.setExtension( ( ( DocumentTypeData* ) m_pLbDocTypes->GetEntryData( nPos ) )->aStrExt );
443 : }
444 :
445 0 : if( aNewURL.GetProtocol() == INET_PROT_FILE )
446 : {
447 0 : utl::LocalFileHelper::ConvertURLToSystemPath( aNewURL.GetMainURL( INetURLObject::NO_DECODE ), aStrTmp );
448 : }
449 : else
450 : {
451 0 : aStrTmp = aNewURL.GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS );
452 : }
453 :
454 0 : m_pCbbPath->SetText ( aStrTmp );
455 : }
456 0 : return( 0L );
457 0 : }
458 :
459 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|