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_svx.hxx" 30 31 #include "svx/databaselocationinput.hxx" 32 #include "svx/dialmgr.hxx" 33 34 #include "svx/fmresids.hrc" 35 36 /** === begin UNO includes === **/ 37 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp> 38 /** === end UNO includes === **/ 39 40 #include <comphelper/componentcontext.hxx> 41 #include <comphelper/namedvaluecollection.hxx> 42 #include <rtl/ustrbuf.hxx> 43 #include <sfx2/filedlghelper.hxx> 44 #include <svtools/urlcontrol.hxx> 45 #include <svl/filenotation.hxx> 46 #include <tools/diagnose_ex.h> 47 #include <unotools/confignode.hxx> 48 #include <unotools/ucbhelper.hxx> 49 #include <vcl/button.hxx> 50 #include <vcl/msgbox.hxx> 51 52 //........................................................................ 53 namespace svx 54 { 55 //........................................................................ 56 57 /** === begin UNO using === **/ 58 using ::com::sun::star::uno::Sequence; 59 using ::com::sun::star::uno::Reference; 60 using ::com::sun::star::container::XNameAccess; 61 using ::com::sun::star::uno::UNO_QUERY_THROW; 62 using ::com::sun::star::uno::Exception; 63 /** === end UNO using === **/ 64 namespace TemplateDescription = ::com::sun::star::ui::dialogs::TemplateDescription; 65 66 //==================================================================== 67 //= DatabaseLocationInputController_Impl 68 //==================================================================== 69 class DatabaseLocationInputController_Impl 70 { 71 public: 72 DatabaseLocationInputController_Impl( 73 const ::comphelper::ComponentContext& _rContext, 74 ::svt::OFileURLControl& _rLocationInput, 75 PushButton& _rBrowseButton 76 ); 77 ~DatabaseLocationInputController_Impl(); 78 79 bool prepareCommit(); 80 void setURL( const String& _rURL ); 81 String getURL() const; 82 83 private: 84 void impl_initFilterProperties_nothrow(); 85 void impl_onBrowseButtonClicked(); 86 void impl_onLocationModified(); 87 String impl_getCurrentURL() const; 88 89 DECL_LINK( OnControlAction, VclWindowEvent* ); 90 91 private: 92 const ::comphelper::ComponentContext m_aContext; 93 ::svt::OFileURLControl& m_rLocationInput; 94 PushButton& m_rBrowseButton; 95 Sequence< ::rtl::OUString > m_aFilterExtensions; 96 ::rtl::OUString m_sFilterUIName; 97 bool m_bNeedExistenceCheck; 98 }; 99 100 //-------------------------------------------------------------------- 101 DatabaseLocationInputController_Impl::DatabaseLocationInputController_Impl( const ::comphelper::ComponentContext& _rContext, 102 ::svt::OFileURLControl& _rLocationInput, PushButton& _rBrowseButton ) 103 :m_aContext( _rContext ) 104 ,m_rLocationInput( _rLocationInput ) 105 ,m_rBrowseButton( _rBrowseButton ) 106 ,m_aFilterExtensions() 107 ,m_sFilterUIName() 108 ,m_bNeedExistenceCheck( true ) 109 { 110 impl_initFilterProperties_nothrow(); 111 112 // forward the allowed extensions to the input control 113 ::rtl::OUStringBuffer aExtensionList; 114 for ( const ::rtl::OUString* pExtension = m_aFilterExtensions.getConstArray(); 115 pExtension != m_aFilterExtensions.getConstArray() + m_aFilterExtensions.getLength(); 116 ++pExtension 117 ) 118 { 119 aExtensionList.append( *pExtension ); 120 aExtensionList.append( (sal_Unicode)';' ); 121 } 122 m_rLocationInput.SetFilter( aExtensionList.makeStringAndClear() ); 123 124 m_rBrowseButton.AddEventListener( LINK( this, DatabaseLocationInputController_Impl, OnControlAction ) ); 125 m_rLocationInput.AddEventListener( LINK( this, DatabaseLocationInputController_Impl, OnControlAction ) ); 126 } 127 128 //-------------------------------------------------------------------- 129 DatabaseLocationInputController_Impl::~DatabaseLocationInputController_Impl() 130 { 131 m_rBrowseButton.RemoveEventListener( LINK( this, DatabaseLocationInputController_Impl, OnControlAction ) ); 132 m_rLocationInput.RemoveEventListener( LINK( this, DatabaseLocationInputController_Impl, OnControlAction ) ); 133 } 134 135 //-------------------------------------------------------------------- 136 bool DatabaseLocationInputController_Impl::prepareCommit() 137 { 138 ::rtl::OUString sURL( impl_getCurrentURL() ); 139 if ( !sURL.getLength() ) 140 return false; 141 142 // check if the name exists 143 if ( m_bNeedExistenceCheck ) 144 { 145 if ( ::utl::UCBContentHelper::Exists( sURL ) ) 146 { 147 QueryBox aBox( m_rLocationInput.GetSystemWindow(), WB_YES_NO, SVX_RES( RID_STR_ALREADYEXISTOVERWRITE ) ); 148 if ( aBox.Execute() != RET_YES ) 149 return false; 150 } 151 } 152 153 return true; 154 } 155 156 //-------------------------------------------------------------------- 157 void DatabaseLocationInputController_Impl::setURL( const String& _rURL ) 158 { 159 ::svt::OFileNotation aTransformer( _rURL ); 160 m_rLocationInput.SetText( aTransformer.get( ::svt::OFileNotation::N_SYSTEM ) ); 161 } 162 163 //-------------------------------------------------------------------- 164 String DatabaseLocationInputController_Impl::getURL() const 165 { 166 return impl_getCurrentURL(); 167 } 168 169 //-------------------------------------------------------------------- 170 void DatabaseLocationInputController_Impl::impl_initFilterProperties_nothrow() 171 { 172 try 173 { 174 // get the name of the default filter for database documents 175 ::utl::OConfigurationTreeRoot aConfig( 176 ::utl::OConfigurationTreeRoot::createWithServiceFactory( 177 m_aContext.getLegacyServiceFactory(), 178 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Setup/Office/Factories/com.sun.star.sdb.OfficeDatabaseDocument" ) ) 179 ) ); 180 ::rtl::OUString sDatabaseFilter; 181 OSL_VERIFY( aConfig.getNodeValue( "ooSetupFactoryActualFilter" ) >>= sDatabaseFilter ); 182 183 // get the type this filter is responsible for 184 Reference< XNameAccess > xFilterFactory( 185 m_aContext.createComponent( "com.sun.star.document.FilterFactory" ), 186 UNO_QUERY_THROW ); 187 ::comphelper::NamedValueCollection aFilterProperties( xFilterFactory->getByName( sDatabaseFilter ) ); 188 ::rtl::OUString sDocumentType = aFilterProperties.getOrDefault( "Type", ::rtl::OUString() ); 189 190 // get the extension(s) for this type 191 Reference< XNameAccess > xTypeDetection( 192 m_aContext.createComponent( "com.sun.star.document.TypeDetection" ), 193 UNO_QUERY_THROW ); 194 195 ::comphelper::NamedValueCollection aTypeProperties( xTypeDetection->getByName( sDocumentType ) ); 196 m_aFilterExtensions = aTypeProperties.getOrDefault( "Extensions", m_aFilterExtensions ); 197 m_sFilterUIName = aTypeProperties.getOrDefault( "UIName", m_sFilterUIName ); 198 } 199 catch( const Exception& ) 200 { 201 DBG_UNHANDLED_EXCEPTION(); 202 } 203 204 // ensure we have at least one extension 205 OSL_ENSURE( m_aFilterExtensions.getLength(), 206 "DatabaseLocationInputController_Impl::impl_initFilterProperties_nothrow: unable to determine the file extension(s)!" ); 207 if ( m_aFilterExtensions.getLength() == 0 ) 208 { 209 m_aFilterExtensions.realloc(1); 210 m_aFilterExtensions[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "*.odb" ) ); 211 } 212 } 213 214 // ----------------------------------------------------------------------------- 215 IMPL_LINK( DatabaseLocationInputController_Impl, OnControlAction, VclWindowEvent*, _pEvent ) 216 { 217 if ( ( _pEvent->GetWindow() == &m_rBrowseButton ) 218 && ( _pEvent->GetId() == VCLEVENT_BUTTON_CLICK ) 219 ) 220 { 221 impl_onBrowseButtonClicked(); 222 } 223 224 if ( ( _pEvent->GetWindow() == &m_rLocationInput ) 225 && ( _pEvent->GetId() == VCLEVENT_EDIT_MODIFY ) 226 ) 227 { 228 impl_onLocationModified(); 229 } 230 231 return 0L; 232 } 233 234 // ----------------------------------------------------------------------------- 235 String DatabaseLocationInputController_Impl::impl_getCurrentURL() const 236 { 237 String sCurrentFile( m_rLocationInput.GetText() ); 238 if ( sCurrentFile.Len() ) 239 { 240 ::svt::OFileNotation aCurrentFile( sCurrentFile ); 241 sCurrentFile = aCurrentFile.get( ::svt::OFileNotation::N_URL ); 242 } 243 return sCurrentFile; 244 } 245 246 // ----------------------------------------------------------------------------- 247 void DatabaseLocationInputController_Impl::impl_onBrowseButtonClicked() 248 { 249 ::sfx2::FileDialogHelper aFileDlg( 250 TemplateDescription::FILESAVE_AUTOEXTENSION, 251 WB_STDMODAL | WB_SAVEAS, 252 m_rLocationInput.GetSystemWindow() 253 ); 254 aFileDlg.SetDisplayDirectory( impl_getCurrentURL() ); 255 256 aFileDlg.AddFilter( m_sFilterUIName, ::rtl::OUStringBuffer().appendAscii( "*." ).append( m_aFilterExtensions[0] ).makeStringAndClear() ); 257 aFileDlg.SetCurrentFilter( m_sFilterUIName ); 258 259 if ( aFileDlg.Execute() == ERRCODE_NONE ) 260 { 261 INetURLObject aURL( aFileDlg.GetPath() ); 262 if( aURL.GetProtocol() != INET_PROT_NOT_VALID ) 263 { 264 ::svt::OFileNotation aFileNotation( aURL.GetMainURL( INetURLObject::NO_DECODE ) ); 265 m_rLocationInput.SetText( aFileNotation.get( ::svt::OFileNotation::N_SYSTEM ) ); 266 m_rLocationInput.GetModifyHdl().Call( &m_rLocationInput ); 267 // the dialog already checked for the file's existence, so we don't need to, again 268 m_bNeedExistenceCheck = false; 269 } 270 } 271 } 272 273 // ----------------------------------------------------------------------------- 274 void DatabaseLocationInputController_Impl::impl_onLocationModified() 275 { 276 m_bNeedExistenceCheck = true; 277 } 278 279 //==================================================================== 280 //= DatabaseLocationInputController 281 //==================================================================== 282 //-------------------------------------------------------------------- 283 DatabaseLocationInputController::DatabaseLocationInputController( const ::comphelper::ComponentContext& _rContext, 284 ::svt::OFileURLControl& _rLocationInput, PushButton& _rBrowseButton ) 285 :m_pImpl( new DatabaseLocationInputController_Impl( _rContext, _rLocationInput, _rBrowseButton ) ) 286 { 287 } 288 289 //-------------------------------------------------------------------- 290 DatabaseLocationInputController::~DatabaseLocationInputController() 291 { 292 } 293 294 //-------------------------------------------------------------------- 295 bool DatabaseLocationInputController::prepareCommit() 296 { 297 return m_pImpl->prepareCommit(); 298 } 299 300 //-------------------------------------------------------------------- 301 void DatabaseLocationInputController::setURL( const String& _rURL ) 302 { 303 m_pImpl->setURL( _rURL ); 304 } 305 306 //-------------------------------------------------------------------- 307 String DatabaseLocationInputController::getURL() const 308 { 309 return m_pImpl->getURL(); 310 } 311 312 //........................................................................ 313 } // namespace svx 314 //........................................................................ 315