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