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