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_fpicker.hxx" 26 27 #include "asyncfilepicker.hxx" 28 #include "iodlg.hxx" 29 #include "svtools/fileview.hxx" 30 #include <tools/debug.hxx> 31 32 #include <memory> 33 34 //........................................................................ 35 namespace svt 36 { 37 //........................................................................ 38 39 //==================================================================== 40 //= AsyncPickerAction 41 //==================================================================== DBG_NAME(AsyncPickerAction)42 DBG_NAME( AsyncPickerAction ) 43 //-------------------------------------------------------------------- 44 AsyncPickerAction::AsyncPickerAction( SvtFileDialog* _pDialog, SvtFileView* _pView, const Action _eAction ) 45 :m_refCount ( 0 ) 46 ,m_eAction ( _eAction ) 47 ,m_pView ( _pView ) 48 ,m_pDialog ( _pDialog ) 49 ,m_bRunning ( false ) 50 { 51 DBG_CTOR( AsyncPickerAction, NULL ); 52 DBG_ASSERT( m_pDialog, "AsyncPickerAction::AsyncPickerAction: invalid dialog!" ); 53 DBG_ASSERT( m_pView, "AsyncPickerAction::AsyncPickerAction: invalid view!" ); 54 } 55 56 //-------------------------------------------------------------------- ~AsyncPickerAction()57 AsyncPickerAction::~AsyncPickerAction() 58 { 59 DBG_DTOR( AsyncPickerAction, NULL ); 60 } 61 62 //-------------------------------------------------------------------- acquire()63 oslInterlockedCount SAL_CALL AsyncPickerAction::acquire() 64 { 65 return osl_incrementInterlockedCount( &m_refCount ); 66 } 67 68 //-------------------------------------------------------------------- release()69 oslInterlockedCount SAL_CALL AsyncPickerAction::release() 70 { 71 if ( 0 == osl_decrementInterlockedCount( &m_refCount ) ) 72 { 73 delete this; 74 return 0; 75 } 76 return m_refCount; 77 } 78 79 //-------------------------------------------------------------------- cancel()80 void AsyncPickerAction::cancel() 81 { 82 DBG_TESTSOLARMUTEX(); 83 // if this asserts, we'd need to have an own mutex per instance 84 85 OSL_ENSURE( m_bRunning, "AsyncPickerAction::cancel: not running" ); 86 if ( m_pView ) 87 m_pView->CancelRunningAsyncAction(); 88 } 89 90 //-------------------------------------------------------------------- execute(const String & _rURL,const String & _rFilter,sal_Int32 _nMinTimeout,sal_Int32 _nMaxTimeout,const OUStringList & rBlackList)91 void AsyncPickerAction::execute( 92 const String& _rURL, 93 const String& _rFilter, 94 sal_Int32 _nMinTimeout, 95 sal_Int32 _nMaxTimeout, 96 const OUStringList& rBlackList ) 97 { 98 DBG_TESTSOLARMUTEX(); 99 // if this asserts, we'd need to have an own mutex per instance 100 101 sal_Int32 nMinTimeout = _nMinTimeout; 102 sal_Int32 nMaxTimeout = _nMaxTimeout; 103 // normalizations 104 if ( nMinTimeout < 0 ) 105 // if negative, this is considered as "do it synchronously" 106 nMinTimeout = 0; 107 else if ( nMinTimeout < 1000 ) 108 nMinTimeout = 1000; 109 if ( nMaxTimeout <= nMinTimeout ) 110 nMaxTimeout = nMinTimeout + 30000; 111 112 ::std::auto_ptr< FileViewAsyncAction > pActionDescriptor; 113 if ( nMinTimeout ) 114 { 115 pActionDescriptor.reset( new FileViewAsyncAction ); 116 pActionDescriptor->nMinTimeout = nMinTimeout; 117 pActionDescriptor->nMaxTimeout = nMaxTimeout; 118 pActionDescriptor->aFinishHandler = LINK( this, AsyncPickerAction, OnActionDone ); 119 } 120 121 FileViewResult eResult = eFailure; 122 m_sURL = _rURL; 123 switch ( m_eAction ) 124 { 125 case ePrevLevel: 126 eResult = m_pView->PreviousLevel( pActionDescriptor.get() ); 127 break; 128 129 case eOpenURL: 130 eResult = m_pView->Initialize( _rURL, _rFilter, pActionDescriptor.get(), rBlackList ); 131 break; 132 133 case eExecuteFilter: 134 // preserve the filename (FS: why?) 135 m_sFileName = m_pDialog->getCurrentFileText(); 136 // execute the new filter 137 eResult = m_pView->ExecuteFilter( _rFilter, pActionDescriptor.get() ); 138 break; 139 140 default: 141 DBG_ERROR( "AsyncPickerAction::execute: unknown action!" ); 142 break; 143 } 144 145 acquire(); 146 if ( ( eResult == eSuccess ) || ( eResult == eFailure ) ) 147 { 148 // the handler is only called if the action could not be finished within 149 // the given minimum time period. In case of success, we need to call it 150 // explicitly 151 OnActionDone( reinterpret_cast< void* >( eResult ) ); 152 } 153 else if ( eResult == eStillRunning ) 154 { 155 m_bRunning = true; 156 m_pDialog->onAsyncOperationStarted(); 157 } 158 } 159 160 //-------------------------------------------------------------------- IMPL_LINK(AsyncPickerAction,OnActionDone,void *,pEmptyArg)161 IMPL_LINK( AsyncPickerAction, OnActionDone, void*, pEmptyArg ) 162 { 163 DBG_TESTSOLARMUTEX(); 164 // if this asserts, we'd need to have an own mutex per instance 165 166 FileViewResult eResult = static_cast< FileViewResult >( reinterpret_cast< sal_IntPtr >( pEmptyArg ) ); 167 OSL_ENSURE( eStillRunning != eResult, "AsyncPickerAction::OnActionDone: invalid result!" ); 168 169 // release once (since we acquired in |execute|), but keep alive until the 170 // end of the method 171 ::rtl::Reference< AsyncPickerAction > xKeepAlive( this ); 172 release(); 173 174 m_pDialog->onAsyncOperationFinished(); 175 m_bRunning = true; 176 177 if ( eFailure == eResult ) 178 // TODO: do we need some kind of cleanup here? 179 return 0L; 180 181 if ( eTimeout == eResult ) 182 { 183 m_pDialog->displayIOException( m_sURL, ::com::sun::star::ucb::IOErrorCode_CANT_READ ); 184 return 0L; 185 } 186 187 OSL_ENSURE( eSuccess == eResult, "AsyncPickerAction::OnActionDone: what else valid results are there?" ); 188 189 switch ( m_eAction ) 190 { 191 case ePrevLevel: 192 case eOpenURL: 193 m_pDialog->UpdateControls( m_pView->GetViewURL() ); 194 break; 195 196 case eExecuteFilter: 197 // restore the filename 198 m_pView->SetNoSelection(); 199 m_pDialog->setCurrentFileText( m_sFileName, true ); 200 201 // notify listeners 202 m_pDialog->FilterSelect(); 203 break; 204 205 default: 206 DBG_ERROR( "AsyncPickerAction::OnActionDone: unknown action!" ); 207 break; 208 } 209 210 return 1L; 211 } 212 213 //........................................................................ 214 } // namespace svt 215 //........................................................................ 216 217