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