1*b557fc96SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*b557fc96SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*b557fc96SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*b557fc96SAndrew Rist  * distributed with this work for additional information
6*b557fc96SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*b557fc96SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*b557fc96SAndrew Rist  * "License"); you may not use this file except in compliance
9*b557fc96SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*b557fc96SAndrew Rist  *
11*b557fc96SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*b557fc96SAndrew Rist  *
13*b557fc96SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*b557fc96SAndrew Rist  * software distributed under the License is distributed on an
15*b557fc96SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b557fc96SAndrew Rist  * KIND, either express or implied.  See the License for the
17*b557fc96SAndrew Rist  * specific language governing permissions and limitations
18*b557fc96SAndrew Rist  * under the License.
19*b557fc96SAndrew Rist  *
20*b557fc96SAndrew Rist  *************************************************************/
21*b557fc96SAndrew Rist 
22*b557fc96SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_fpicker.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include "asyncfilepicker.hxx"
28cdf0e10cSrcweir #include "iodlg.hxx"
29cdf0e10cSrcweir #include "svtools/fileview.hxx"
30cdf0e10cSrcweir #include <tools/debug.hxx>
31cdf0e10cSrcweir 
32cdf0e10cSrcweir #include <memory>
33cdf0e10cSrcweir 
34cdf0e10cSrcweir //........................................................................
35cdf0e10cSrcweir namespace svt
36cdf0e10cSrcweir {
37cdf0e10cSrcweir //........................................................................
38cdf0e10cSrcweir 
39cdf0e10cSrcweir 	//====================================================================
40cdf0e10cSrcweir 	//= AsyncPickerAction
41cdf0e10cSrcweir 	//====================================================================
DBG_NAME(AsyncPickerAction)42cdf0e10cSrcweir     DBG_NAME( AsyncPickerAction )
43cdf0e10cSrcweir 	//--------------------------------------------------------------------
44cdf0e10cSrcweir     AsyncPickerAction::AsyncPickerAction( SvtFileDialog* _pDialog, SvtFileView* _pView, const Action _eAction )
45cdf0e10cSrcweir         :m_refCount ( 0        )
46cdf0e10cSrcweir         ,m_eAction  ( _eAction )
47cdf0e10cSrcweir         ,m_pView    ( _pView   )
48cdf0e10cSrcweir         ,m_pDialog  ( _pDialog )
49cdf0e10cSrcweir         ,m_bRunning ( false    )
50cdf0e10cSrcweir     {
51cdf0e10cSrcweir         DBG_CTOR( AsyncPickerAction, NULL );
52cdf0e10cSrcweir         DBG_ASSERT( m_pDialog, "AsyncPickerAction::AsyncPickerAction: invalid dialog!" );
53cdf0e10cSrcweir         DBG_ASSERT( m_pView, "AsyncPickerAction::AsyncPickerAction: invalid view!" );
54cdf0e10cSrcweir     }
55cdf0e10cSrcweir 
56cdf0e10cSrcweir     //--------------------------------------------------------------------
~AsyncPickerAction()57cdf0e10cSrcweir     AsyncPickerAction::~AsyncPickerAction()
58cdf0e10cSrcweir     {
59cdf0e10cSrcweir         DBG_DTOR( AsyncPickerAction, NULL );
60cdf0e10cSrcweir     }
61cdf0e10cSrcweir 
62cdf0e10cSrcweir     //--------------------------------------------------------------------
acquire()63cdf0e10cSrcweir     oslInterlockedCount SAL_CALL AsyncPickerAction::acquire()
64cdf0e10cSrcweir     {
65cdf0e10cSrcweir         return osl_incrementInterlockedCount( &m_refCount );
66cdf0e10cSrcweir     }
67cdf0e10cSrcweir 
68cdf0e10cSrcweir     //--------------------------------------------------------------------
release()69cdf0e10cSrcweir     oslInterlockedCount SAL_CALL AsyncPickerAction::release()
70cdf0e10cSrcweir     {
71cdf0e10cSrcweir         if ( 0 == osl_decrementInterlockedCount( &m_refCount ) )
72cdf0e10cSrcweir         {
73cdf0e10cSrcweir             delete this;
74cdf0e10cSrcweir             return 0;
75cdf0e10cSrcweir         }
76cdf0e10cSrcweir         return m_refCount;
77cdf0e10cSrcweir     }
78cdf0e10cSrcweir 
79cdf0e10cSrcweir 	//--------------------------------------------------------------------
cancel()80cdf0e10cSrcweir     void AsyncPickerAction::cancel()
81cdf0e10cSrcweir     {
82cdf0e10cSrcweir         DBG_TESTSOLARMUTEX();
83cdf0e10cSrcweir             // if this asserts, we'd need to have an own mutex per instance
84cdf0e10cSrcweir 
85cdf0e10cSrcweir         OSL_ENSURE( m_bRunning, "AsyncPickerAction::cancel: not running" );
86cdf0e10cSrcweir         if ( m_pView )
87cdf0e10cSrcweir             m_pView->CancelRunningAsyncAction();
88cdf0e10cSrcweir     }
89cdf0e10cSrcweir 
90cdf0e10cSrcweir 	//--------------------------------------------------------------------
execute(const String & _rURL,const String & _rFilter,sal_Int32 _nMinTimeout,sal_Int32 _nMaxTimeout,const OUStringList & rBlackList)91cdf0e10cSrcweir     void AsyncPickerAction::execute(
92cdf0e10cSrcweir 		const String& _rURL,
93cdf0e10cSrcweir 		const String& _rFilter,
94cdf0e10cSrcweir 		sal_Int32 _nMinTimeout,
95cdf0e10cSrcweir 		sal_Int32 _nMaxTimeout,
96cdf0e10cSrcweir 		const OUStringList& rBlackList )
97cdf0e10cSrcweir     {
98cdf0e10cSrcweir         DBG_TESTSOLARMUTEX();
99cdf0e10cSrcweir             // if this asserts, we'd need to have an own mutex per instance
100cdf0e10cSrcweir 
101cdf0e10cSrcweir         sal_Int32 nMinTimeout = _nMinTimeout;
102cdf0e10cSrcweir         sal_Int32 nMaxTimeout = _nMaxTimeout;
103cdf0e10cSrcweir         // normalizations
104cdf0e10cSrcweir         if ( nMinTimeout < 0 )
105cdf0e10cSrcweir             // if negative, this is considered as "do it synchronously"
106cdf0e10cSrcweir             nMinTimeout = 0;
107cdf0e10cSrcweir         else if ( nMinTimeout < 1000 )
108cdf0e10cSrcweir             nMinTimeout = 1000;
109cdf0e10cSrcweir         if ( nMaxTimeout <= nMinTimeout )
110cdf0e10cSrcweir             nMaxTimeout = nMinTimeout + 30000;
111cdf0e10cSrcweir 
112cdf0e10cSrcweir         ::std::auto_ptr< FileViewAsyncAction > pActionDescriptor;
113cdf0e10cSrcweir         if ( nMinTimeout )
114cdf0e10cSrcweir         {
115cdf0e10cSrcweir             pActionDescriptor.reset( new FileViewAsyncAction );
116cdf0e10cSrcweir             pActionDescriptor->nMinTimeout = nMinTimeout;
117cdf0e10cSrcweir             pActionDescriptor->nMaxTimeout = nMaxTimeout;
118cdf0e10cSrcweir             pActionDescriptor->aFinishHandler = LINK( this, AsyncPickerAction, OnActionDone );
119cdf0e10cSrcweir         }
120cdf0e10cSrcweir 
121cdf0e10cSrcweir         FileViewResult eResult = eFailure;
122cdf0e10cSrcweir         m_sURL = _rURL;
123cdf0e10cSrcweir         switch ( m_eAction )
124cdf0e10cSrcweir         {
125cdf0e10cSrcweir         case ePrevLevel:
126cdf0e10cSrcweir             eResult = m_pView->PreviousLevel( pActionDescriptor.get() );
127cdf0e10cSrcweir             break;
128cdf0e10cSrcweir 
129cdf0e10cSrcweir         case eOpenURL:
130cdf0e10cSrcweir             eResult = m_pView->Initialize( _rURL, _rFilter, pActionDescriptor.get(), rBlackList );
131cdf0e10cSrcweir             break;
132cdf0e10cSrcweir 
133cdf0e10cSrcweir         case eExecuteFilter:
134cdf0e10cSrcweir             // preserve the filename (FS: why?)
135cdf0e10cSrcweir             m_sFileName = m_pDialog->getCurrentFileText();
136cdf0e10cSrcweir             // execute the new filter
137cdf0e10cSrcweir             eResult = m_pView->ExecuteFilter( _rFilter, pActionDescriptor.get() );
138cdf0e10cSrcweir             break;
139cdf0e10cSrcweir 
140cdf0e10cSrcweir         default:
141cdf0e10cSrcweir             DBG_ERROR( "AsyncPickerAction::execute: unknown action!" );
142cdf0e10cSrcweir             break;
143cdf0e10cSrcweir         }
144cdf0e10cSrcweir 
145cdf0e10cSrcweir         acquire();
146cdf0e10cSrcweir         if ( ( eResult == eSuccess ) || ( eResult == eFailure ) )
147cdf0e10cSrcweir         {
148cdf0e10cSrcweir             // the handler is only called if the action could not be finished within
149cdf0e10cSrcweir             // the given minimum time period. In case of success, we need to call it
150cdf0e10cSrcweir             // explicitly
151cdf0e10cSrcweir             OnActionDone( reinterpret_cast< void* >( eResult ) );
152cdf0e10cSrcweir         }
153cdf0e10cSrcweir         else if ( eResult == eStillRunning )
154cdf0e10cSrcweir         {
155cdf0e10cSrcweir             m_bRunning = true;
156cdf0e10cSrcweir             m_pDialog->onAsyncOperationStarted();
157cdf0e10cSrcweir         }
158cdf0e10cSrcweir     }
159cdf0e10cSrcweir 
160cdf0e10cSrcweir 	//--------------------------------------------------------------------
IMPL_LINK(AsyncPickerAction,OnActionDone,void *,pEmptyArg)161cdf0e10cSrcweir 	IMPL_LINK( AsyncPickerAction, OnActionDone, void*, pEmptyArg )
162cdf0e10cSrcweir     {
163cdf0e10cSrcweir         DBG_TESTSOLARMUTEX();
164cdf0e10cSrcweir             // if this asserts, we'd need to have an own mutex per instance
165cdf0e10cSrcweir 
166cdf0e10cSrcweir         FileViewResult eResult = static_cast< FileViewResult >( reinterpret_cast< sal_IntPtr >( pEmptyArg ) );
167cdf0e10cSrcweir         OSL_ENSURE( eStillRunning != eResult, "AsyncPickerAction::OnActionDone: invalid result!" );
168cdf0e10cSrcweir 
169cdf0e10cSrcweir         // release once (since we acquired in |execute|), but keep alive until the
170cdf0e10cSrcweir         // end of the method
171cdf0e10cSrcweir         ::rtl::Reference< AsyncPickerAction > xKeepAlive( this );
172cdf0e10cSrcweir         release();
173cdf0e10cSrcweir 
174cdf0e10cSrcweir         m_pDialog->onAsyncOperationFinished();
175cdf0e10cSrcweir         m_bRunning = true;
176cdf0e10cSrcweir 
177cdf0e10cSrcweir         if ( eFailure == eResult )
178cdf0e10cSrcweir             // TODO: do we need some kind of cleanup here?
179cdf0e10cSrcweir             return 0L;
180cdf0e10cSrcweir 
181cdf0e10cSrcweir         if ( eTimeout == eResult )
182cdf0e10cSrcweir         {
183cdf0e10cSrcweir             m_pDialog->displayIOException( m_sURL, ::com::sun::star::ucb::IOErrorCode_CANT_READ );
184cdf0e10cSrcweir             return 0L;
185cdf0e10cSrcweir         }
186cdf0e10cSrcweir 
187cdf0e10cSrcweir         OSL_ENSURE( eSuccess == eResult, "AsyncPickerAction::OnActionDone: what else valid results are there?" );
188cdf0e10cSrcweir 
189cdf0e10cSrcweir         switch ( m_eAction )
190cdf0e10cSrcweir         {
191cdf0e10cSrcweir         case ePrevLevel:
192cdf0e10cSrcweir         case eOpenURL:
193cdf0e10cSrcweir             m_pDialog->UpdateControls( m_pView->GetViewURL() );
194cdf0e10cSrcweir             break;
195cdf0e10cSrcweir 
196cdf0e10cSrcweir         case eExecuteFilter:
197cdf0e10cSrcweir 	        // restore the filename
198cdf0e10cSrcweir 	        m_pView->SetNoSelection();
199cdf0e10cSrcweir             m_pDialog->setCurrentFileText( m_sFileName, true );
200cdf0e10cSrcweir 
201cdf0e10cSrcweir 	        // notify listeners
202cdf0e10cSrcweir 	        m_pDialog->FilterSelect();
203cdf0e10cSrcweir             break;
204cdf0e10cSrcweir 
205cdf0e10cSrcweir         default:
206cdf0e10cSrcweir             DBG_ERROR( "AsyncPickerAction::OnActionDone: unknown action!" );
207cdf0e10cSrcweir             break;
208cdf0e10cSrcweir         }
209cdf0e10cSrcweir 
210cdf0e10cSrcweir         return 1L;
211cdf0e10cSrcweir     }
212cdf0e10cSrcweir 
213cdf0e10cSrcweir //........................................................................
214cdf0e10cSrcweir } // namespace svt
215cdf0e10cSrcweir //........................................................................
216cdf0e10cSrcweir 
217