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 --------------------------------------------------------------- 32 #include <tools/debug.hxx> 33 #include <tools/urlobj.hxx> 34 #include <vcl/msgbox.hxx> 35 #include <sfx2/filedlghelper.hxx> 36 37 #include "multipat.hxx" 38 #include <dialmgr.hxx> 39 40 #include "multipat.hrc" 41 #include <cuires.hrc> 42 #include <comphelper/processfactory.hxx> 43 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 44 #include <com/sun/star/ui/dialogs/XFolderPicker.hpp> 45 #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp> 46 47 #include <unotools/localfilehelper.hxx> 48 #include <unotools/pathoptions.hxx> 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 // struct MultiPath_Impl ------------------------------------------------- 55 56 struct MultiPath_Impl 57 { 58 sal_Bool bEmptyAllowed; 59 sal_Bool bIsClassPathMode; 60 bool bIsRadioButtonMode; 61 62 MultiPath_Impl( sal_Bool bAllowed ) : 63 bEmptyAllowed( bAllowed ), bIsClassPathMode( sal_False ), bIsRadioButtonMode( false ) {} 64 }; 65 66 // class SvxMultiPathDialog ---------------------------------------------- 67 68 IMPL_LINK( SvxMultiPathDialog, SelectHdl_Impl, void *, EMPTYARG ) 69 { 70 sal_uLong nCount = pImpl->bIsRadioButtonMode ? aRadioLB.GetEntryCount() : aPathLB.GetEntryCount(); 71 bool bIsSelected = pImpl->bIsRadioButtonMode 72 ? aRadioLB.FirstSelected() != NULL 73 : aPathLB.GetSelectEntryPos() != LISTBOX_ENTRY_NOTFOUND; 74 sal_Bool bEnable = ( pImpl->bEmptyAllowed || nCount > 1 ); 75 aDelBtn.Enable( bEnable && bIsSelected ); 76 return 0; 77 } 78 79 // ----------------------------------------------------------------------- 80 81 IMPL_LINK( SvxMultiPathDialog, CheckHdl_Impl, svx::SvxRadioButtonListBox *, pBox ) 82 { 83 SvLBoxEntry* pEntry = 84 pBox ? pBox->GetEntry( pBox->GetCurMousePoint() ) : aRadioLB.FirstSelected(); 85 if ( pEntry ) 86 aRadioLB.HandleEntryChecked( pEntry ); 87 return 0; 88 } 89 90 // ----------------------------------------------------------------------- 91 92 IMPL_LINK( SvxMultiPathDialog, AddHdl_Impl, PushButton *, EMPTYARG ) 93 { 94 rtl::OUString aService( RTL_CONSTASCII_USTRINGPARAM( FOLDER_PICKER_SERVICE_NAME ) ); 95 Reference < XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() ); 96 Reference < XFolderPicker > xFolderPicker( xFactory->createInstance( aService ), UNO_QUERY ); 97 98 if ( xFolderPicker->execute() == ExecutableDialogResults::OK ) 99 { 100 INetURLObject aPath( xFolderPicker->getDirectory() ); 101 aPath.removeFinalSlash(); 102 String aURL = aPath.GetMainURL( INetURLObject::NO_DECODE ); 103 String sInsPath; 104 ::utl::LocalFileHelper::ConvertURLToSystemPath( aURL, sInsPath ); 105 106 if ( pImpl->bIsRadioButtonMode ) 107 { 108 sal_uLong nPos = aRadioLB.GetEntryPos( sInsPath, 1 ); 109 if ( 0xffffffff == nPos ) //See svtools/source/contnr/svtabbx.cxx SvTabListBox::GetEntryPos 110 { 111 String sNewEntry( '\t' ); 112 sNewEntry += sInsPath; 113 SvLBoxEntry* pEntry = aRadioLB.InsertEntry( sNewEntry ); 114 String* pData = new String( aURL ); 115 pEntry->SetUserData( pData ); 116 } 117 else 118 { 119 String sMsg( CUI_RES( RID_MULTIPATH_DBL_ERR ) ); 120 sMsg.SearchAndReplaceAscii( "%1", sInsPath ); 121 InfoBox( this, sMsg ).Execute(); 122 } 123 } 124 else 125 { 126 if ( LISTBOX_ENTRY_NOTFOUND != aPathLB.GetEntryPos( sInsPath ) ) 127 { 128 String sMsg( CUI_RES( RID_MULTIPATH_DBL_ERR ) ); 129 sMsg.SearchAndReplaceAscii( "%1", sInsPath ); 130 InfoBox( this, sMsg ).Execute(); 131 } 132 else 133 { 134 sal_uInt16 nPos = aPathLB.InsertEntry( sInsPath, LISTBOX_APPEND ); 135 aPathLB.SetEntryData( nPos, (void*)new String( aURL ) ); 136 } 137 } 138 SelectHdl_Impl( NULL ); 139 } 140 return 0; 141 } 142 143 // ----------------------------------------------------------------------- 144 145 IMPL_LINK( SvxMultiPathDialog, DelHdl_Impl, PushButton *, EMPTYARG ) 146 { 147 if ( pImpl->bIsRadioButtonMode ) 148 { 149 SvLBoxEntry* pEntry = aRadioLB.FirstSelected(); 150 delete (String*)pEntry->GetUserData(); 151 bool bChecked = aRadioLB.GetCheckButtonState( pEntry ) == SV_BUTTON_CHECKED; 152 sal_uLong nPos = aRadioLB.GetEntryPos( pEntry ); 153 aRadioLB.RemoveEntry( pEntry ); 154 sal_uLong nCnt = aRadioLB.GetEntryCount(); 155 if ( nCnt ) 156 { 157 nCnt--; 158 if ( nPos > nCnt ) 159 nPos = nCnt; 160 pEntry = aRadioLB.GetEntry( nPos ); 161 if ( bChecked ) 162 { 163 aRadioLB.SetCheckButtonState( pEntry, SV_BUTTON_CHECKED ); 164 aRadioLB.HandleEntryChecked( pEntry ); 165 } 166 else 167 aRadioLB.Select( pEntry ); 168 } 169 } 170 else 171 { 172 sal_uInt16 nPos = aPathLB.GetSelectEntryPos(); 173 aPathLB.RemoveEntry( nPos ); 174 sal_uInt16 nCnt = aPathLB.GetEntryCount(); 175 176 if ( nCnt ) 177 { 178 nCnt--; 179 180 if ( nPos > nCnt ) 181 nPos = nCnt; 182 aPathLB.SelectEntryPos( nPos ); 183 } 184 } 185 SelectHdl_Impl( NULL ); 186 return 0; 187 } 188 189 // ----------------------------------------------------------------------- 190 191 SvxMultiPathDialog::SvxMultiPathDialog( Window* pParent, sal_Bool bEmptyAllowed ) : 192 193 ModalDialog( pParent, CUI_RES( RID_SVXDLG_MULTIPATH ) ), 194 195 aPathFL ( this, CUI_RES( FL_MULTIPATH) ), 196 aPathLB ( this, CUI_RES( LB_MULTIPATH ) ), 197 aRadioLB ( this, CUI_RES( LB_RADIOBUTTON ) ), 198 aRadioFT ( this, CUI_RES( FT_RADIOBUTTON ) ), 199 aAddBtn ( this, CUI_RES( BTN_ADD_MULTIPATH ) ), 200 aDelBtn ( this, CUI_RES( BTN_DEL_MULTIPATH ) ), 201 aOKBtn ( this, CUI_RES( BTN_MULTIPATH_OK ) ), 202 aCancelBtn ( this, CUI_RES( BTN_MULTIPATH_CANCEL ) ), 203 aHelpButton ( this, CUI_RES( BTN_MULTIPATH_HELP ) ), 204 pImpl ( new MultiPath_Impl( bEmptyAllowed ) ) 205 206 { 207 static long aStaticTabs[]= { 2, 0, 12 }; 208 aRadioLB.SvxSimpleTable::SetTabs( aStaticTabs ); 209 String sHeader( CUI_RES( STR_HEADER_PATHS ) ); 210 aRadioLB.SetQuickHelpText( sHeader ); 211 sHeader.Insert( '\t', 0 ); 212 aRadioLB.InsertHeaderEntry( sHeader, HEADERBAR_APPEND, HIB_LEFT ); 213 214 FreeResource(); 215 216 aPathLB.SetSelectHdl( LINK( this, SvxMultiPathDialog, SelectHdl_Impl ) ); 217 aRadioLB.SetSelectHdl( LINK( this, SvxMultiPathDialog, SelectHdl_Impl ) ); 218 aRadioLB.SetCheckButtonHdl( LINK( this, SvxMultiPathDialog, CheckHdl_Impl ) ); 219 aAddBtn.SetClickHdl( LINK( this, SvxMultiPathDialog, AddHdl_Impl ) ); 220 aDelBtn.SetClickHdl( LINK( this, SvxMultiPathDialog, DelHdl_Impl ) ); 221 222 SelectHdl_Impl( NULL ); 223 224 aAddBtn.SetAccessibleRelationMemberOf(&aPathLB); 225 aDelBtn.SetAccessibleRelationMemberOf(&aPathLB); 226 } 227 228 // ----------------------------------------------------------------------- 229 230 SvxMultiPathDialog::~SvxMultiPathDialog() 231 { 232 sal_uInt16 nPos = aPathLB.GetEntryCount(); 233 while ( nPos-- ) 234 delete (String*)aPathLB.GetEntryData(nPos); 235 nPos = (sal_uInt16)aRadioLB.GetEntryCount(); 236 while ( nPos-- ) 237 { 238 SvLBoxEntry* pEntry = aRadioLB.GetEntry( nPos ); 239 delete (String*)pEntry->GetUserData(); 240 } 241 delete pImpl; 242 } 243 244 // ----------------------------------------------------------------------- 245 246 String SvxMultiPathDialog::GetPath() const 247 { 248 String sNewPath; 249 sal_Unicode cDelim = pImpl->bIsClassPathMode ? CLASSPATH_DELIMITER : SVT_SEARCHPATH_DELIMITER; 250 251 if ( pImpl->bIsRadioButtonMode ) 252 { 253 String sWritable; 254 for ( sal_uInt16 i = 0; i < aRadioLB.GetEntryCount(); ++i ) 255 { 256 SvLBoxEntry* pEntry = aRadioLB.GetEntry(i); 257 if ( aRadioLB.GetCheckButtonState( pEntry ) == SV_BUTTON_CHECKED ) 258 sWritable = *(String*)pEntry->GetUserData(); 259 else 260 { 261 if ( sNewPath.Len() > 0 ) 262 sNewPath += cDelim; 263 sNewPath += *(String*)pEntry->GetUserData(); 264 } 265 } 266 if ( sNewPath.Len() > 0 ) 267 sNewPath += cDelim; 268 sNewPath += sWritable; 269 } 270 else 271 { 272 for ( sal_uInt16 i = 0; i < aPathLB.GetEntryCount(); ++i ) 273 { 274 if ( sNewPath.Len() > 0 ) 275 sNewPath += cDelim; 276 sNewPath += *(String*)aPathLB.GetEntryData(i); 277 } 278 } 279 return sNewPath; 280 } 281 282 // ----------------------------------------------------------------------- 283 284 void SvxMultiPathDialog::SetPath( const String& rPath ) 285 { 286 sal_Unicode cDelim = pImpl->bIsClassPathMode ? CLASSPATH_DELIMITER : SVT_SEARCHPATH_DELIMITER; 287 sal_uInt16 nPos, nCount = rPath.GetTokenCount( cDelim ); 288 289 for ( sal_uInt16 i = 0; i < nCount; ++i ) 290 { 291 String sPath = rPath.GetToken( i, cDelim ); 292 String sSystemPath; 293 sal_Bool bIsSystemPath = 294 ::utl::LocalFileHelper::ConvertURLToSystemPath( sPath, sSystemPath ); 295 296 if ( pImpl->bIsRadioButtonMode ) 297 { 298 String sEntry( '\t' ); 299 sEntry += bIsSystemPath ? sSystemPath : sPath; 300 SvLBoxEntry* pEntry = aRadioLB.InsertEntry( sEntry ); 301 String* pURL = new String( sPath ); 302 pEntry->SetUserData( pURL ); 303 } 304 else 305 { 306 if ( bIsSystemPath ) 307 nPos = aPathLB.InsertEntry( sSystemPath, LISTBOX_APPEND ); 308 else 309 nPos = aPathLB.InsertEntry( sPath, LISTBOX_APPEND ); 310 aPathLB.SetEntryData( nPos, (void*)new String( sPath ) ); 311 } 312 } 313 314 if ( pImpl->bIsRadioButtonMode && nCount > 0 ) 315 { 316 SvLBoxEntry* pEntry = aRadioLB.GetEntry( nCount - 1 ); 317 if ( pEntry ) 318 { 319 aRadioLB.SetCheckButtonState( pEntry, SV_BUTTON_CHECKED ); 320 aRadioLB.HandleEntryChecked( pEntry ); 321 } 322 } 323 324 SelectHdl_Impl( NULL ); 325 } 326 327 // ----------------------------------------------------------------------- 328 329 void SvxMultiPathDialog::SetClassPathMode() 330 { 331 pImpl->bIsClassPathMode = sal_True; 332 SetText( CUI_RES( RID_SVXSTR_ARCHIVE_TITLE )); 333 aPathFL.SetText( CUI_RES( RID_SVXSTR_ARCHIVE_HEADLINE ) ); 334 } 335 336 // ----------------------------------------------------------------------- 337 338 sal_Bool SvxMultiPathDialog::IsClassPathMode() const 339 { 340 return pImpl->bIsClassPathMode; 341 } 342 343 // ----------------------------------------------------------------------- 344 345 void SvxMultiPathDialog::EnableRadioButtonMode() 346 { 347 pImpl->bIsRadioButtonMode = true; 348 349 aPathFL.Hide(); 350 aPathLB.Hide(); 351 352 aRadioLB.ShowTable(); 353 aRadioFT.Show(); 354 355 Point aNewPos = aAddBtn.GetPosPixel(); 356 long nDelta = aNewPos.Y() - aRadioLB.GetPosPixel().Y(); 357 aNewPos.Y() -= nDelta; 358 aAddBtn.SetPosPixel( aNewPos ); 359 aNewPos = aDelBtn.GetPosPixel(); 360 aNewPos.Y() -= nDelta; 361 aDelBtn.SetPosPixel( aNewPos ); 362 } 363 364