Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "fpsmartcontent.hxx"
21 :
22 : #include <com/sun/star/container/XChild.hpp>
23 : #include <com/sun/star/task/InteractionHandler.hpp>
24 : #include <com/sun/star/ucb/ContentInfo.hpp>
25 : #include <com/sun/star/ucb/ContentInfoAttribute.hpp>
26 : #include <com/sun/star/ucb/XContent.hpp>
27 :
28 : #include <comphelper/processfactory.hxx>
29 : #include <ucbhelper/commandenvironment.hxx>
30 : #include <tools/solar.h>
31 : #include <tools/debug.hxx>
32 :
33 : //........................................................................
34 : namespace svt
35 : {
36 : //........................................................................
37 :
38 : using namespace ::com::sun::star::uno;
39 : using namespace ::com::sun::star::task;
40 : using namespace ::com::sun::star::ucb;
41 : using namespace ::com::sun::star::lang;
42 : using namespace ::com::sun::star::container;
43 :
44 : //====================================================================
45 : //= SmartContent
46 : //====================================================================
47 : //--------------------------------------------------------------------
48 0 : SmartContent::SmartContent()
49 : :m_pContent( NULL )
50 : ,m_eState( NOT_BOUND )
51 0 : ,m_pOwnInteraction( NULL )
52 : {
53 0 : }
54 :
55 : //--------------------------------------------------------------------
56 0 : SmartContent::SmartContent( const OUString& _rInitialURL )
57 : :m_pContent( NULL )
58 0 : ,m_eState( NOT_BOUND )
59 : {
60 0 : bindTo( _rInitialURL );
61 0 : }
62 :
63 : //--------------------------------------------------------------------
64 0 : SmartContent::~SmartContent()
65 : {
66 : /* This destructor originally contained the following blurb: "Do
67 : not delete the content. Because the content will be used by
68 : the cache." This is just plain silly, because it relies on
69 : the provider caching created contents (which is done by
70 : ucbhelper::ContentProviderImplHelper, but we do not actually
71 : expect all providers to use that, right?) Otherwise we are
72 : just leaking memory.
73 :
74 : TODO: If there is real need for caching the content, it must
75 : be done here.
76 : */
77 0 : delete m_pContent;
78 0 : }
79 :
80 : //--------------------------------------------------------------------
81 0 : void SmartContent::enableOwnInteractionHandler(::svt::OFilePickerInteractionHandler::EInterceptedInteractions eInterceptions)
82 : {
83 0 : Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
84 : Reference< XInteractionHandler > xGlobalInteractionHandler(
85 0 : InteractionHandler::createWithParent(xContext, 0), UNO_QUERY_THROW );
86 :
87 0 : m_pOwnInteraction = new ::svt::OFilePickerInteractionHandler(xGlobalInteractionHandler);
88 0 : m_pOwnInteraction->enableInterceptions(eInterceptions);
89 0 : m_xOwnInteraction = m_pOwnInteraction;
90 :
91 0 : m_xCmdEnv = new ::ucbhelper::CommandEnvironment( m_xOwnInteraction, Reference< XProgressHandler >() );
92 0 : }
93 :
94 : //--------------------------------------------------------------------
95 0 : void SmartContent::enableDefaultInteractionHandler()
96 : {
97 : // Don't free the memory here! It will be done by the next
98 : // call automaticly - releasing of the uno reference ...
99 0 : m_pOwnInteraction = NULL;
100 0 : m_xOwnInteraction = Reference< XInteractionHandler >();
101 :
102 0 : Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
103 : Reference< XInteractionHandler > xGlobalInteractionHandler(
104 0 : InteractionHandler::createWithParent(xContext, 0), UNO_QUERY_THROW );
105 0 : m_xCmdEnv = new ucbhelper::CommandEnvironment( xGlobalInteractionHandler, Reference< XProgressHandler >() );
106 0 : }
107 :
108 : //--------------------------------------------------------------------
109 0 : ::svt::OFilePickerInteractionHandler* SmartContent::getOwnInteractionHandler() const
110 : {
111 0 : if (!m_xOwnInteraction.is())
112 0 : return NULL;
113 0 : return m_pOwnInteraction;
114 : }
115 :
116 : //--------------------------------------------------------------------
117 0 : SmartContent::InteractionHandlerType SmartContent::queryCurrentInteractionHandler() const
118 : {
119 0 : if (m_xOwnInteraction.is())
120 0 : return IHT_OWN;
121 :
122 0 : if (!m_xCmdEnv.is())
123 0 : return IHT_NONE;
124 :
125 0 : return IHT_DEFAULT;
126 : }
127 :
128 : //--------------------------------------------------------------------
129 0 : void SmartContent::disableInteractionHandler()
130 : {
131 : // Don't free the memory here! It will be done by the next
132 : // call automaticly - releasing of the uno reference ...
133 0 : m_pOwnInteraction = NULL;
134 0 : m_xOwnInteraction.clear();
135 :
136 0 : m_xCmdEnv.clear();
137 0 : }
138 :
139 : //--------------------------------------------------------------------
140 0 : void SmartContent::bindTo( const OUString& _rURL )
141 : {
142 0 : if ( getURL() == _rURL )
143 : // nothing to do, regardless of the state
144 0 : return;
145 :
146 0 : DELETEZ( m_pContent );
147 0 : m_eState = INVALID; // default to INVALID
148 0 : m_sURL = _rURL;
149 :
150 0 : if ( !m_sURL.isEmpty() )
151 : {
152 : try
153 : {
154 0 : m_pContent = new ::ucbhelper::Content( _rURL, m_xCmdEnv, comphelper::getProcessComponentContext() );
155 0 : m_eState = UNKNOWN;
156 : // from now on, the state is unknown -> we cannot know for sure if the content
157 : // is really valid (some UCP's only tell this when asking for properties, not upon
158 : // creation)
159 : }
160 0 : catch( const ContentCreationException& )
161 : {
162 : }
163 0 : catch( const Exception& )
164 : {
165 : OSL_FAIL( "SmartContent::bindTo: unexpected exception caught!" );
166 : }
167 : }
168 : else
169 : {
170 0 : m_eState = NOT_BOUND;
171 : }
172 :
173 :
174 : // don't forget to reset the may internal used interaction handler ...
175 : // But do it only for our own specialized interaction helper!
176 0 : ::svt::OFilePickerInteractionHandler* pHandler = getOwnInteractionHandler();
177 0 : if (pHandler)
178 : {
179 0 : pHandler->resetUseState();
180 0 : pHandler->forgetRequest();
181 : }
182 : }
183 :
184 : //--------------------------------------------------------------------
185 0 : sal_Bool SmartContent::implIs( const OUString& _rURL, Type _eType )
186 : {
187 : // bind to this content
188 0 : bindTo( _rURL );
189 :
190 : // did we survive this?
191 0 : if ( isInvalid() || !isBound() )
192 0 : return sal_False;
193 :
194 : DBG_ASSERT( m_pContent, "SmartContent::implIs: inconsistence!" );
195 : // if, after an bindTo, we don't have a content, then we should be INVALID, or at least
196 : // NOT_BOUND (the latter happens, for example, if somebody tries to ask for an empty URL)
197 :
198 0 : sal_Bool bIs = sal_False;
199 : try
200 : {
201 0 : if ( Folder == _eType )
202 0 : bIs = m_pContent->isFolder();
203 : else
204 0 : bIs = m_pContent->isDocument();
205 :
206 : // from here on, we definately know that the content is valid
207 0 : m_eState = VALID;
208 : }
209 0 : catch( const Exception& )
210 : {
211 : // now we're definately invalid
212 0 : m_eState = INVALID;
213 : }
214 0 : return bIs;
215 : }
216 :
217 : //--------------------------------------------------------------------
218 0 : void SmartContent::getTitle( OUString& /* [out] */ _rTitle )
219 : {
220 0 : if ( !isBound() || isInvalid() )
221 0 : return;
222 :
223 : try
224 : {
225 0 : OUString sTitle;
226 0 : m_pContent->getPropertyValue( OUString( "Title" ) ) >>= sTitle;
227 0 : _rTitle = sTitle;
228 :
229 : // from here on, we definately know that the content is valid
230 0 : m_eState = VALID;
231 : }
232 0 : catch( const ::com::sun::star::uno::Exception& )
233 : {
234 : // now we're definately invalid
235 0 : m_eState = INVALID;
236 : }
237 : }
238 :
239 : //--------------------------------------------------------------------
240 0 : sal_Bool SmartContent::hasParentFolder( )
241 : {
242 0 : if ( !isBound() || isInvalid() )
243 0 : return sal_False;
244 :
245 0 : sal_Bool bRet = sal_False;
246 : try
247 : {
248 0 : Reference< XChild > xChild( m_pContent->get(), UNO_QUERY );
249 0 : if ( xChild.is() )
250 : {
251 0 : Reference< XContent > xParent( xChild->getParent(), UNO_QUERY );
252 0 : if ( xParent.is() )
253 : {
254 0 : const OUString aParentURL( xParent->getIdentifier()->getContentIdentifier() );
255 0 : bRet = ( !aParentURL.isEmpty() && aParentURL != m_pContent->getURL() );
256 :
257 : // now we're definately valid
258 0 : m_eState = VALID;
259 0 : }
260 0 : }
261 : }
262 0 : catch( const Exception& )
263 : {
264 : // now we're definately invalid
265 0 : m_eState = INVALID;
266 : }
267 0 : return bRet;
268 : }
269 :
270 : //--------------------------------------------------------------------
271 0 : sal_Bool SmartContent::canCreateFolder( )
272 : {
273 0 : if ( !isBound() || isInvalid() )
274 0 : return sal_False;
275 :
276 0 : sal_Bool bRet = sal_False;
277 : try
278 : {
279 0 : Sequence< ContentInfo > aInfo = m_pContent->queryCreatableContentsInfo();
280 0 : const ContentInfo* pInfo = aInfo.getConstArray();
281 0 : sal_Int32 nCount = aInfo.getLength();
282 0 : for ( sal_Int32 i = 0; i < nCount; ++i, ++pInfo )
283 : {
284 : // Simply look for the first KIND_FOLDER...
285 0 : if ( pInfo->Attributes & ContentInfoAttribute::KIND_FOLDER )
286 : {
287 0 : bRet = sal_True;
288 0 : break;
289 : }
290 : }
291 :
292 : // now we're definately valid
293 0 : m_eState = VALID;
294 : }
295 0 : catch( const Exception& )
296 : {
297 : // now we're definately invalid
298 0 : m_eState = INVALID;
299 : }
300 0 : return bRet;
301 : }
302 :
303 0 : OUString SmartContent::createFolder( const OUString& _rTitle )
304 : {
305 0 : OUString aCreatedUrl;
306 : try
307 : {
308 0 : OUString sFolderType;
309 :
310 0 : Sequence< ContentInfo > aInfo = m_pContent->queryCreatableContentsInfo();
311 0 : const ContentInfo* pInfo = aInfo.getConstArray();
312 0 : sal_Int32 nCount = aInfo.getLength();
313 0 : for ( sal_Int32 i = 0; i < nCount; ++i, ++pInfo )
314 : {
315 : // Simply look for the first KIND_FOLDER...
316 0 : if ( pInfo->Attributes & ContentInfoAttribute::KIND_FOLDER )
317 : {
318 0 : sFolderType = pInfo->Type;
319 0 : break;
320 : }
321 : }
322 :
323 0 : if ( !sFolderType.isEmpty() )
324 : {
325 0 : ucbhelper::Content aCreated;
326 0 : Sequence< OUString > aNames( 1 );
327 0 : OUString* pNames = aNames.getArray();
328 0 : pNames[0] = OUString( "Title" );
329 0 : Sequence< Any > aValues( 1 );
330 0 : Any* pValues = aValues.getArray();
331 0 : pValues[0] = makeAny( _rTitle );
332 0 : m_pContent->insertNewContent( sFolderType, aNames, aValues, aCreated );
333 :
334 0 : aCreatedUrl = aCreated.getURL();
335 0 : }
336 : }
337 0 : catch( const Exception& )
338 : {
339 : }
340 0 : return aCreatedUrl;
341 : }
342 :
343 : //........................................................................
344 : } // namespace svt
345 : //........................................................................
346 :
347 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|