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