xref: /trunk/main/cui/source/dialogs/hldocntp.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_cui.hxx"
30 
31 #include "hldocntp.hxx"
32 #include <sfx2/viewfrm.hxx>
33 #include <sfx2/docfac.hxx>
34 #include <com/sun/star/uno/Reference.h>
35 #include <com/sun/star/uno/Sequence.h>
36 #include <com/sun/star/beans/PropertyValue.hpp>
37 #include <com/sun/star/uno/Exception.hpp>
38 #include <unotools/localfilehelper.hxx>
39 #include <tools/config.hxx>
40 #include <vcl/image.hxx>
41 #include <tools/urlobj.hxx>
42 #include <unotools/pathoptions.hxx>
43 #include <unotools/dynamicmenuoptions.hxx>
44 #include <sfx2/filedlghelper.hxx>
45 #include <unotools/ucbstreamhelper.hxx>
46 #include <unotools/ucbhelper.hxx>
47 
48 #include "hyperdlg.hrc"
49 #include <comphelper/processfactory.hxx>
50 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
51 #include <com/sun/star/ui/dialogs/XFolderPicker.hpp>
52 #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
53 
54 using namespace ::com::sun::star::lang;
55 using namespace ::com::sun::star::ui::dialogs;
56 using namespace ::com::sun::star::uno;
57 
58 using namespace ::rtl;
59 using namespace ::com::sun::star;
60 
61 /*************************************************************************
62 |*
63 |* Data-struct for documenttypes in listbox
64 |*
65 |************************************************************************/
66 
67 struct DocumentTypeData
68 {
69 	String aStrURL;
70 	String aStrExt;
71 	DocumentTypeData (String aURL, String aExt) : aStrURL(aURL), aStrExt(aExt)
72 	{}
73 };
74 
75 sal_Bool SvxHyperlinkNewDocTp::ImplGetURLObject( const String& rPath, const String& rBase, INetURLObject& aURLObject ) const
76 {
77     sal_Bool bIsValidURL = rPath.Len() != 0;
78     if ( bIsValidURL )
79     {
80         aURLObject.SetURL( rPath );
81         if ( aURLObject.GetProtocol() == INET_PROT_NOT_VALID )      // test if the source is already a valid url
82         {                                                           // if not we have to create a url from a physical file name
83             bool wasAbs;
84             INetURLObject base(rBase);
85             base.setFinalSlash();
86             aURLObject = base.smartRel2Abs(
87                 rPath, wasAbs, true, INetURLObject::ENCODE_ALL,
88                 RTL_TEXTENCODING_UTF8, true);
89         }
90         bIsValidURL = aURLObject.GetProtocol() != INET_PROT_NOT_VALID;
91         if ( bIsValidURL )
92         {
93             String aBase( aURLObject.getName( INetURLObject::LAST_SEGMENT, sal_False ) );
94             if ( ( aBase.Len() == 0 ) || ( aBase.GetChar( 0 ) == '.' ) )
95                 bIsValidURL = sal_False;
96         }
97         if ( bIsValidURL )
98         {
99         	sal_uInt16 nPos = maLbDocTypes.GetSelectEntryPos();
100 	        if ( nPos != LISTBOX_ENTRY_NOTFOUND )
101                 aURLObject.SetExtension( ((DocumentTypeData*)maLbDocTypes.GetEntryData( nPos ))->aStrExt );
102         }
103 
104     }
105     return bIsValidURL;
106 }
107 
108 /*************************************************************************
109 |*
110 |* Contructor / Destructor
111 |*
112 |************************************************************************/
113 
114 SvxHyperlinkNewDocTp::SvxHyperlinkNewDocTp ( Window *pParent, const SfxItemSet& rItemSet)
115 :	SvxHyperlinkTabPageBase ( pParent, CUI_RES( RID_SVXPAGE_HYPERLINK_NEWDOCUMENT ), rItemSet ),
116 	maGrpNewDoc		( this, CUI_RES (GRP_NEWDOCUMENT) ),
117 	maRbtEditNow	( this, CUI_RES (RB_EDITNOW) ),
118 	maRbtEditLater	( this, CUI_RES (RB_EDITLATER) ),
119 	maFtPath		( this, CUI_RES (FT_PATH_NEWDOC) ),
120 	maCbbPath		( this, INET_PROT_FILE ),
121 	maBtCreate		( this, CUI_RES (BTN_CREATE) ),
122 	maFtDocTypes	( this, CUI_RES (FT_DOCUMENT_TYPES) ),
123 	maLbDocTypes	( this, CUI_RES (LB_DOCUMENT_TYPES) )
124 {
125 	// Set HC bitmaps and disable display of bitmap names.
126 	maBtCreate.SetModeImage( Image( CUI_RES( IMG_CREATE_HC ) ), BMP_COLOR_HIGHCONTRAST );
127     maBtCreate.EnableTextDisplay (sal_False);
128 
129 	InitStdControls();
130 	FreeResource();
131 
132 	SetExchangeSupport ();
133 
134 	maCbbPath.SetPosSizePixel ( LogicToPixel( Point( COL_2 , 25 ), MAP_APPFONT ),
135 		                        LogicToPixel( Size ( 176 - COL_DIFF, 60), MAP_APPFONT ) );
136 	maCbbPath.Show();
137 	maCbbPath.SetBaseURL(SvtPathOptions().GetWorkPath());
138 //	maCbbPath.SetHelpId( HID_HYPERDLG_DOC_PATH );
139 
140 	// set defaults
141 	maRbtEditNow.Check();
142 
143 	maBtCreate.SetClickHdl		  ( LINK ( this, SvxHyperlinkNewDocTp, ClickNewHdl_Impl ) );
144 
145 	maBtCreate.SetAccessibleRelationMemberOf( &maGrpNewDoc );
146 	maBtCreate.SetAccessibleRelationLabeledBy( &maFtPath );
147 
148 	FillDocumentList ();
149 }
150 
151 SvxHyperlinkNewDocTp::~SvxHyperlinkNewDocTp ()
152 {
153 	for ( sal_uInt16 n=0; n<maLbDocTypes.GetEntryCount(); n++ )
154 	{
155 		DocumentTypeData* pTypeData = (DocumentTypeData*)
156 			                          maLbDocTypes.GetEntryData ( n );
157 		delete pTypeData;
158 	}
159 }
160 
161 /*************************************************************************
162 |*
163 |* Fill the all dialog-controls except controls in groupbox "more..."
164 |*
165 |************************************************************************/
166 
167 
168 void SvxHyperlinkNewDocTp::FillDlgFields ( String& /*aStrURL*/ )
169 {
170 }
171 
172 #define INTERNETSHORTCUT_ID_TAG       "InternetShortcut"
173 #define INTERNETSHORTCUT_TITLE_TAG    "Title"
174 #define INTERNETSHORTCUT_TARGET_TAG   "Target"
175 #define INTERNETSHORTCUT_FOLDER_TAG   "Folder"
176 #define INTERNETSHORTCUT_URL_TAG      "URL"
177 #define INTERNETSHORTCUT_ICONID_TAG	  "IconIndex"
178 
179 void SvxHyperlinkNewDocTp::FillDocumentList ()
180 {
181 	EnterWait();
182 
183     uno::Sequence< uno::Sequence< beans::PropertyValue > >
184         aDynamicMenuEntries( SvtDynamicMenuOptions().GetMenu( E_NEWMENU ) );
185 
186 	sal_uInt32 i, nCount = aDynamicMenuEntries.getLength();
187     for ( i = 0; i < nCount; i++ )
188     {
189         uno::Sequence< beans::PropertyValue >& rDynamicMenuEntry = aDynamicMenuEntries[ i ];
190 
191         rtl::OUString aDocumentUrl, aTitle, aImageId, aTargetName;
192 
193    	    for ( int e = 0; e < rDynamicMenuEntry.getLength(); e++ )
194 	    {
195 		    if ( rDynamicMenuEntry[ e ].Name == DYNAMICMENU_PROPERTYNAME_URL )
196                 rDynamicMenuEntry[ e ].Value >>= aDocumentUrl;
197 		    else if ( rDynamicMenuEntry[e].Name == DYNAMICMENU_PROPERTYNAME_TITLE )
198                 rDynamicMenuEntry[e].Value >>= aTitle;
199 		    else if ( rDynamicMenuEntry[e].Name == DYNAMICMENU_PROPERTYNAME_IMAGEIDENTIFIER )
200 			    rDynamicMenuEntry[e].Value >>= aImageId;
201 		    else if ( rDynamicMenuEntry[e].Name == DYNAMICMENU_PROPERTYNAME_TARGETNAME )
202 			    rDynamicMenuEntry[e].Value >>= aTargetName;
203 	    }
204         //#i96822# business cards, labels and database should not be inserted here
205         if( aDocumentUrl.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "private:factory/swriter?slot=21051" ) ) ||
206                 aDocumentUrl.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "private:factory/swriter?slot=21052" )) ||
207                 aDocumentUrl.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "private:factory/sdatabase?Interactive" )))
208             continue;
209 
210 		// Insert into listbox
211         if ( aDocumentUrl.getLength() )
212         {
213 			if ( aDocumentUrl.equalsAscii( "private:factory/simpress?slot=6686" ) )				// SJ: #106216# do not start
214 				aDocumentUrl = String( RTL_CONSTASCII_USTRINGPARAM( "private:factory/simpress" ) );	// the AutoPilot for impress
215 
216 			// insert private-url and default-extension as user-data
217 			const SfxFilter* pFilter = SfxFilter::GetDefaultFilterFromFactory( aDocumentUrl );
218 			if ( pFilter )
219 			{
220 				// insert doc-name and image
221 	            String aTitleName( aTitle );
222 				aTitleName.Erase( aTitleName.Search( (sal_Unicode)'~' ), 1 );
223 
224 				sal_Int16 nPos = maLbDocTypes.InsertEntry ( aTitleName );
225 				String aStrDefExt( pFilter->GetDefaultExtension () );
226 				DocumentTypeData *pTypeData = new DocumentTypeData ( aDocumentUrl, aStrDefExt.Copy( 2, aStrDefExt.Len() ) );
227 				maLbDocTypes.SetEntryData ( nPos, pTypeData );
228 			}
229         }
230     }
231 	maLbDocTypes.SelectEntryPos ( 0 );
232 
233 	LeaveWait();
234 }
235 
236 /*************************************************************************
237 |*
238 |* retrieve and prepare data from dialog-fields
239 |*
240 |************************************************************************/
241 
242 void SvxHyperlinkNewDocTp::GetCurentItemData ( String& aStrURL, String& aStrName,
243 											   String& aStrIntName, String& aStrFrame,
244 											   SvxLinkInsertMode& eMode )
245 {
246 	// get data from dialog-controls
247 	aStrURL = maCbbPath.GetText();
248     INetURLObject aURL;
249     if ( ImplGetURLObject( aStrURL, maCbbPath.GetBaseURL(), aURL ) )
250     {
251         aStrURL     = aURL.GetMainURL( INetURLObject::NO_DECODE );
252     }
253 
254 	GetDataFromCommonFields( aStrName, aStrIntName, aStrFrame, eMode );
255 }
256 
257 /*************************************************************************
258 |*
259 |* static method to create Tabpage
260 |*
261 |************************************************************************/
262 
263 IconChoicePage* SvxHyperlinkNewDocTp::Create( Window* pWindow, const SfxItemSet& rItemSet )
264 {
265 	return( new SvxHyperlinkNewDocTp( pWindow, rItemSet ) );
266 }
267 
268 /*************************************************************************
269 |*
270 |* Set initial focus
271 |*
272 |************************************************************************/
273 
274 void SvxHyperlinkNewDocTp::SetInitFocus()
275 {
276 	maCbbPath.GrabFocus();
277 }
278 
279 /*************************************************************************
280 |*
281 |* Ask page whether an insert is possible
282 |*
283 \************************************************************************/
284 
285 sal_Bool SvxHyperlinkNewDocTp::AskApply()
286 {
287     INetURLObject aINetURLObject;
288     sal_Bool bRet = ImplGetURLObject( maCbbPath.GetText(), maCbbPath.GetBaseURL(), aINetURLObject );
289     if ( !bRet )
290     {
291 	    WarningBox aWarning( this, WB_OK, CUI_RESSTR(RID_SVXSTR_HYPDLG_NOVALIDFILENAME) );
292 	    aWarning.Execute();
293     }
294     return bRet;
295 }
296 
297 /*************************************************************************
298 |*
299 |* Any action to do after apply-button is pressed
300 |*
301 \************************************************************************/
302 
303 void SvxHyperlinkNewDocTp::DoApply ()
304 {
305 	EnterWait();
306 
307 	// get data from dialog-controls
308 	String aStrNewName = maCbbPath.GetText();
309 
310 	if ( aStrNewName == aEmptyStr )
311 		aStrNewName = maStrInitURL;
312 
313 	///////////////////////////////////////////////////////
314 	// create a real URL-String
315 
316     INetURLObject aURL;
317     if ( ImplGetURLObject( aStrNewName, maCbbPath.GetBaseURL(), aURL ) )
318     {
319 
320 	    ///////////////////////////////////////////////////////
321 	    // create Document
322 
323 	    aStrNewName = aURL.GetURLPath( INetURLObject::NO_DECODE );
324 	    SfxViewFrame *pViewFrame = NULL;
325 	    try
326 	    {
327 			bool bCreate = true;
328 
329 			// check if file exists, warn before we overwrite it
330 			{
331 				com::sun::star::uno::Reference < com::sun::star::task::XInteractionHandler > xHandler;
332 				SvStream* pIStm = ::utl::UcbStreamHelper::CreateStream( aURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_READ, xHandler );
333 
334 				sal_Bool bOk = pIStm && ( pIStm->GetError() == 0);
335 
336 				if( pIStm )
337 					delete pIStm;
338 
339 				if( bOk )
340 				{
341 					WarningBox aWarning( this, WB_YES_NO, CUI_RESSTR(RID_SVXSTR_HYPERDLG_QUERYOVERWRITE) );
342 					bCreate = aWarning.Execute() == BUTTON_YES;
343 				}
344 			}
345 
346 			if( bCreate )
347 			{
348 				// current document
349                 SfxViewFrame* pCurrentDocFrame = SfxViewFrame::Current();
350 
351 				if ( aStrNewName != aEmptyStr )
352 				{
353 					// get private-url
354 					sal_uInt16 nPos = maLbDocTypes.GetSelectEntryPos();
355 					if( nPos == LISTBOX_ENTRY_NOTFOUND )
356 						nPos=0;
357 					String aStrDocName ( ( ( DocumentTypeData* )
358 										 maLbDocTypes.GetEntryData( nPos ) )->aStrURL );
359 
360 					// create items
361 					SfxStringItem aName( SID_FILE_NAME, aStrDocName );
362 					SfxStringItem aReferer( SID_REFERER, UniString::CreateFromAscii(
363 												RTL_CONSTASCII_STRINGPARAM( "private:user" ) ) );
364 					SfxStringItem aFrame( SID_TARGETNAME, UniString::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "_blank" ) ) );
365 					//SfxBoolItem aFrame( SID_OPEN_NEW_VIEW, sal_True );
366 
367 					String aStrFlags ( sal_Unicode('S') );
368 					if ( maRbtEditLater.IsChecked() )
369 					{
370 						aStrFlags += sal_Unicode('H');
371 					}
372 					SfxStringItem aFlags (SID_OPTIONS, aStrFlags);
373 
374 					// open url
375 					const SfxPoolItem* pReturn = GetDispatcher()->Execute( SID_OPENDOC,
376 																		   SFX_CALLMODE_SYNCHRON,
377 																		   &aName, &aFlags,
378 																		   &aFrame, &aReferer, 0L );
379 
380 					// save new doc
381 					const SfxViewFrameItem *pItem = PTR_CAST( SfxViewFrameItem, pReturn );	// SJ: pReturn is NULL if the Hyperlink
382 					if ( pItem )															// creation is cancelled #106216#
383 					{
384 						pViewFrame = pItem->GetFrame();
385 						if (pViewFrame)
386 						{
387 							//SfxViewFrame *pViewFrame = pFrame->GetCurrentViewFrame();
388 							SfxStringItem aNewName( SID_FILE_NAME, aURL.GetMainURL( INetURLObject::NO_DECODE ) );
389 
390 							pViewFrame->GetDispatcher()->Execute( SID_SAVEASDOC,
391 																  SFX_CALLMODE_SYNCHRON,
392 																  &aNewName, 0L );
393 
394 						}
395 					}
396 				}
397 
398                 if ( maRbtEditNow.IsChecked() && pCurrentDocFrame )
399 				{
400 					pCurrentDocFrame->ToTop();
401 				}
402 			}
403 	    }
404 	    catch( uno::Exception )
405 	    {
406 	    }
407 
408 	    if ( pViewFrame && maRbtEditLater.IsChecked() )
409 	    {
410 		    SfxObjectShell* pObjShell = pViewFrame->GetObjectShell();
411 		    pObjShell->DoClose();
412 	    }
413     }
414 
415 	LeaveWait();
416 }
417 
418 /*************************************************************************
419 |*
420 |* Click on imagebutton : new
421 |*
422 |************************************************************************/
423 
424 IMPL_LINK ( SvxHyperlinkNewDocTp, ClickNewHdl_Impl, void *, EMPTYARG )
425 {
426     rtl::OUString						aService( RTL_CONSTASCII_USTRINGPARAM( FOLDER_PICKER_SERVICE_NAME ) );
427     uno::Reference < XMultiServiceFactory >	xFactory( ::comphelper::getProcessServiceFactory() );
428 	uno::Reference < XFolderPicker >			xFolderPicker( xFactory->createInstance( aService ), UNO_QUERY );
429 
430 	String				aStrURL;
431 	String				aTempStrURL( maCbbPath.GetText() );
432 	utl::LocalFileHelper::ConvertSystemPathToURL( aTempStrURL, maCbbPath.GetBaseURL(), aStrURL );
433 
434 	String				aStrPath = aStrURL;
435 	sal_Bool				bZeroPath = ( aStrPath.Len() == 0 );
436 	sal_Bool				bHandleFileName = bZeroPath;	// when path has length of 0, then the rest should always be handled
437 														//	as file name, otherwise we do not yet know
438 
439 	if( bZeroPath )
440 		aStrPath = SvtPathOptions().GetWorkPath();
441 	else if( !::utl::UCBContentHelper::IsFolder( aStrURL ) )
442 		bHandleFileName = sal_True;
443 
444     xFolderPicker->setDisplayDirectory( aStrPath );
445     DisableClose( sal_True );
446     sal_Int16 nResult = xFolderPicker->execute();
447     DisableClose( sal_False );
448     if( ExecutableDialogResults::OK == nResult )
449 	{
450 		sal_Char const	sSlash[] = "/";
451 
452 		INetURLObject	aURL( aStrURL, INET_PROT_FILE );
453 		String			aStrName;
454 		if( bHandleFileName )
455 			aStrName = bZeroPath? aTempStrURL : String(aURL.getName());
456 
457 		maCbbPath.SetBaseURL( xFolderPicker->getDirectory() );
458 		String			aStrTmp( xFolderPicker->getDirectory() );
459 
460 		if( aStrTmp.GetChar( aStrTmp.Len() - 1 ) != sSlash[0] )
461 			aStrTmp.AppendAscii( sSlash );
462 
463 		// append old file name
464 		if( bHandleFileName )
465 			aStrTmp += aStrName;
466 
467 		INetURLObject	aNewURL( aStrTmp );
468 
469 		if( aStrName.Len() > 0 && aNewURL.getExtension().getLength() > 0 &&
470 			maLbDocTypes.GetSelectEntryPos() != LISTBOX_ENTRY_NOTFOUND )
471 		{
472 			// get private-url
473 			sal_uInt16 nPos = maLbDocTypes.GetSelectEntryPos();
474 			aNewURL.setExtension( ( ( DocumentTypeData* ) maLbDocTypes.GetEntryData( nPos ) )->aStrExt );
475 		}
476 
477         if( aNewURL.GetProtocol() == INET_PROT_FILE )
478         {
479             utl::LocalFileHelper::ConvertURLToSystemPath( aNewURL.GetMainURL( INetURLObject::NO_DECODE ), aStrTmp );
480         }
481         else
482         {
483             aStrTmp = aNewURL.GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS );
484         }
485 
486 		maCbbPath.SetText ( aStrTmp );
487 	}
488 	return( 0L );
489 }
490 
491