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