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 #include "fpsmartcontent.hxx"
27 
28 /** === begin UNO includes === **/
29 #include <com/sun/star/container/XChild.hpp>
30 #include <com/sun/star/ucb/ContentInfo.hpp>
31 #include <com/sun/star/ucb/ContentInfoAttribute.hpp>
32 #include <com/sun/star/ucb/XContent.hpp>
33 /** === end UNO includes === **/
34 
35 #include <comphelper/processfactory.hxx>
36 #include <ucbhelper/commandenvironment.hxx>
37 #include <tools/solar.h>
38 #include <tools/debug.hxx>
39 #include <tools/string.hxx>
40 
41 //........................................................................
42 namespace svt
43 {
44 //........................................................................
45 
46     using namespace ::com::sun::star::uno;
47     using namespace ::com::sun::star::task;
48     using namespace ::com::sun::star::ucb;
49     using namespace ::com::sun::star::lang;
50     using namespace ::com::sun::star::container;
51 
52     //====================================================================
53     //= SmartContent
54     //====================================================================
55     //--------------------------------------------------------------------
56     SmartContent::SmartContent()
57         :m_pContent( NULL )
58         ,m_eState( NOT_BOUND )
59         ,m_pOwnInteraction( NULL )
60     {
61     }
62 
63     //--------------------------------------------------------------------
64     SmartContent::SmartContent( const ::rtl::OUString& _rInitialURL )
65         :m_pContent( NULL )
66         ,m_eState( NOT_BOUND )
67     {
68         bindTo( _rInitialURL );
69     }
70 
71     //--------------------------------------------------------------------
72     SmartContent::~SmartContent()
73     {
74         //Do not delete the content. Because the content will be used by the cache.
75         //DELETEZ( m_pContent );
76     }
77 
78     //--------------------------------------------------------------------
79     void SmartContent::enableOwnInteractionHandler(::svt::OFilePickerInteractionHandler::EInterceptedInteractions eInterceptions)
80     {
81         Reference< XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
82         Reference< XInteractionHandler >  xGlobalInteractionHandler = Reference< XInteractionHandler >(
83             xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.task.InteractionHandler") ) ), UNO_QUERY );
84 
85         m_pOwnInteraction = new ::svt::OFilePickerInteractionHandler(xGlobalInteractionHandler);
86         m_pOwnInteraction->enableInterceptions(eInterceptions);
87         m_xOwnInteraction = m_pOwnInteraction;
88 
89         m_xCmdEnv = new ::ucbhelper::CommandEnvironment( m_xOwnInteraction, Reference< XProgressHandler >() );
90     }
91 
92     //--------------------------------------------------------------------
93     void SmartContent::enableDefaultInteractionHandler()
94     {
95         // Don't free the memory here! It will be done by the next
96         // call automaticly - releasing of the uno reference ...
97         m_pOwnInteraction = NULL;
98         m_xOwnInteraction = Reference< XInteractionHandler >();
99 
100         Reference< XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
101         Reference< XInteractionHandler >  xGlobalInteractionHandler = Reference< XInteractionHandler >(
102             xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.task.InteractionHandler") ) ), UNO_QUERY );
103         m_xCmdEnv = new ucbhelper::CommandEnvironment( xGlobalInteractionHandler, Reference< XProgressHandler >() );
104     }
105 
106     //--------------------------------------------------------------------
107     ::svt::OFilePickerInteractionHandler* SmartContent::getOwnInteractionHandler() const
108     {
109         if (!m_xOwnInteraction.is())
110             return NULL;
111         return m_pOwnInteraction;
112     }
113 
114     //--------------------------------------------------------------------
115     SmartContent::InteractionHandlerType SmartContent::queryCurrentInteractionHandler() const
116     {
117         if (m_xOwnInteraction.is())
118             return IHT_OWN;
119 
120         if (!m_xCmdEnv.is())
121             return IHT_NONE;
122 
123         return IHT_DEFAULT;
124     }
125 
126     //--------------------------------------------------------------------
127     void SmartContent::disableInteractionHandler()
128     {
129         // Don't free the memory here! It will be done by the next
130         // call automaticly - releasing of the uno reference ...
131         m_pOwnInteraction = NULL;
132         m_xOwnInteraction.clear();
133 
134         m_xCmdEnv.clear();
135     }
136 
137     //--------------------------------------------------------------------
138     void SmartContent::bindTo( const ::rtl::OUString& _rURL )
139     {
140         if ( getURL() == _rURL )
141             // nothing to do, regardless of the state
142             return;
143 
144         DELETEZ( m_pContent );
145         m_eState = INVALID; // default to INVALID
146         m_sURL = _rURL;
147 
148         if ( m_sURL.getLength() )
149         {
150             try
151             {
152                 m_pContent = new ::ucbhelper::Content( _rURL, m_xCmdEnv );
153                 m_eState = UNKNOWN;
154                     // from now on, the state is unknown -> we cannot know for sure if the content
155                     // is really valid (some UCP's only tell this when asking for properties, not upon
156                     // creation)
157             }
158             catch( ContentCreationException& )
159             {
160             }
161             catch( Exception& )
162             {
163                 DBG_ERROR( "SmartContent::bindTo: unexpected exception caught!" );
164             }
165         }
166         else
167         {
168             m_eState = NOT_BOUND;
169         }
170 
171 
172         // don't forget to reset the may internal used interaction handler ...
173         // But do it only for our own specialized interaction helper!
174         ::svt::OFilePickerInteractionHandler* pHandler = getOwnInteractionHandler();
175         if (pHandler)
176         {
177             pHandler->resetUseState();
178             pHandler->forgetRequest();
179         }
180     }
181 
182     //--------------------------------------------------------------------
183     sal_Bool SmartContent::implIs( const ::rtl::OUString& _rURL, Type _eType )
184     {
185         // bind to this content
186         bindTo( _rURL );
187 
188         // did we survive this?
189         if ( isInvalid() || !isBound() )
190             return sal_False;
191 
192         DBG_ASSERT( m_pContent, "SmartContent::implIs: inconsistence!" );
193             // if, after an bindTo, we don't have a content, then we should be INVALID, or at least
194             // NOT_BOUND (the latter happens, for example, if somebody tries to ask for an empty URL)
195 
196         sal_Bool bIs = sal_False;
197         try
198         {
199             if ( Folder == _eType )
200                 bIs = m_pContent->isFolder();
201             else
202                 bIs = m_pContent->isDocument();
203 
204             // from here on, we definately know that the content is valid
205             m_eState = VALID;
206         }
207         catch( Exception& )
208         {
209             // now we're definately invalid
210             m_eState = INVALID;
211         }
212         return bIs;
213     }
214 
215     //--------------------------------------------------------------------
216     void SmartContent::getTitle( ::rtl::OUString& /* [out] */ _rTitle )
217     {
218         if ( !isBound() || isInvalid() )
219             return;
220 
221         try
222         {
223             ::rtl::OUString sTitle;
224             m_pContent->getPropertyValue( ::rtl::OUString::createFromAscii( "Title" ) ) >>= sTitle;
225             _rTitle =  sTitle;
226 
227             // from here on, we definately know that the content is valid
228             m_eState = VALID;
229         }
230         catch( ::com::sun::star::uno::Exception& )
231         {
232             // now we're definately invalid
233             m_eState = INVALID;
234         }
235     }
236 
237     //--------------------------------------------------------------------
238     sal_Bool SmartContent::hasParentFolder( )
239     {
240         if ( !isBound() || isInvalid() )
241             return sal_False;
242 
243         sal_Bool bRet = sal_False;
244         try
245         {
246             Reference< XChild > xChild( m_pContent->get(), UNO_QUERY );
247             if ( xChild.is() )
248             {
249                 Reference< XContent > xParent( xChild->getParent(), UNO_QUERY );
250                 if ( xParent.is() )
251                 {
252                     String aParentURL = String( xParent->getIdentifier()->getContentIdentifier() );
253                     bRet = ( aParentURL.Len() > 0 && aParentURL != (String)(m_pContent->getURL()) );
254 
255                     // now we're definately valid
256                     m_eState = VALID;
257                 }
258             }
259         }
260         catch( const Exception& )
261         {
262             // now we're definately invalid
263             m_eState = INVALID;
264         }
265         return bRet;
266     }
267 
268     //--------------------------------------------------------------------
269     sal_Bool SmartContent::canCreateFolder( )
270     {
271         if ( !isBound() || isInvalid() )
272             return sal_False;
273 
274         sal_Bool bRet = sal_False;
275         try
276         {
277             Sequence< ContentInfo > aInfo = m_pContent->queryCreatableContentsInfo();
278             const ContentInfo* pInfo = aInfo.getConstArray();
279             sal_Int32 nCount = aInfo.getLength();
280             for ( sal_Int32 i = 0; i < nCount; ++i, ++pInfo )
281             {
282                 // Simply look for the first KIND_FOLDER...
283                 if ( pInfo->Attributes & ContentInfoAttribute::KIND_FOLDER )
284                 {
285                     bRet = sal_True;
286                     break;
287                 }
288             }
289 
290             // now we're definately valid
291             m_eState = VALID;
292         }
293         catch( Exception& )
294         {
295             // now we're definately invalid
296             m_eState = INVALID;
297         }
298         return bRet;
299     }
300 
301 //........................................................................
302 } // namespace svt
303 //........................................................................
304 
305