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