xref: /trunk/main/cui/source/dialogs/hldocntp.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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