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 : #include <osl/diagnose.h>
33 :
34 :
35 : namespace svt
36 : {
37 :
38 :
39 : using namespace ::com::sun::star::uno;
40 : using namespace ::com::sun::star::task;
41 : using namespace ::com::sun::star::ucb;
42 : using namespace ::com::sun::star::lang;
43 : using namespace ::com::sun::star::container;
44 :
45 :
46 : //= SmartContent
47 :
48 :
49 0 : SmartContent::SmartContent()
50 : :m_pContent( NULL )
51 : ,m_eState( NOT_BOUND )
52 0 : ,m_pOwnInteraction( NULL )
53 : {
54 0 : }
55 :
56 :
57 0 : SmartContent::SmartContent( const OUString& _rInitialURL )
58 : :m_pContent( NULL )
59 : ,m_eState( NOT_BOUND )
60 0 : ,m_pOwnInteraction( NULL )
61 : {
62 0 : bindTo( _rInitialURL );
63 0 : }
64 :
65 :
66 0 : SmartContent::~SmartContent()
67 : {
68 : /* This destructor originally contained the following blurb: "Do
69 : not delete the content. Because the content will be used by
70 : the cache." This is just plain silly, because it relies on
71 : the provider caching created contents (which is done by
72 : ucbhelper::ContentProviderImplHelper, but we do not actually
73 : expect all providers to use that, right?) Otherwise we are
74 : just leaking memory.
75 :
76 : TODO: If there is real need for caching the content, it must
77 : be done here.
78 : */
79 0 : delete m_pContent;
80 0 : }
81 :
82 :
83 0 : void SmartContent::enableOwnInteractionHandler(::svt::OFilePickerInteractionHandler::EInterceptedInteractions eInterceptions)
84 : {
85 0 : Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
86 : Reference< XInteractionHandler > xGlobalInteractionHandler(
87 0 : InteractionHandler::createWithParent(xContext, 0), UNO_QUERY_THROW );
88 :
89 0 : m_pOwnInteraction = new ::svt::OFilePickerInteractionHandler(xGlobalInteractionHandler);
90 0 : m_pOwnInteraction->enableInterceptions(eInterceptions);
91 0 : m_xOwnInteraction = m_pOwnInteraction;
92 :
93 0 : m_xCmdEnv = new ::ucbhelper::CommandEnvironment( m_xOwnInteraction, Reference< XProgressHandler >() );
94 0 : }
95 :
96 :
97 0 : void SmartContent::enableDefaultInteractionHandler()
98 : {
99 : // Don't free the memory here! It will be done by the next
100 : // call automatically - releasing of the uno reference ...
101 0 : m_pOwnInteraction = NULL;
102 0 : m_xOwnInteraction.clear();
103 :
104 0 : Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
105 : Reference< XInteractionHandler > xGlobalInteractionHandler(
106 0 : InteractionHandler::createWithParent(xContext, 0), UNO_QUERY_THROW );
107 0 : m_xCmdEnv = new ucbhelper::CommandEnvironment( xGlobalInteractionHandler, Reference< XProgressHandler >() );
108 0 : }
109 :
110 :
111 0 : ::svt::OFilePickerInteractionHandler* SmartContent::getOwnInteractionHandler() const
112 : {
113 0 : if (!m_xOwnInteraction.is())
114 0 : return NULL;
115 0 : return m_pOwnInteraction;
116 : }
117 :
118 :
119 0 : SmartContent::InteractionHandlerType SmartContent::queryCurrentInteractionHandler() const
120 : {
121 0 : if (m_xOwnInteraction.is())
122 0 : return IHT_OWN;
123 :
124 0 : if (!m_xCmdEnv.is())
125 0 : return IHT_NONE;
126 :
127 0 : return IHT_DEFAULT;
128 : }
129 :
130 :
131 0 : void SmartContent::disableInteractionHandler()
132 : {
133 : // Don't free the memory here! It will be done by the next
134 : // call automatically - releasing of the uno reference ...
135 0 : m_pOwnInteraction = NULL;
136 0 : m_xOwnInteraction.clear();
137 :
138 0 : m_xCmdEnv.clear();
139 0 : }
140 :
141 :
142 0 : void SmartContent::bindTo( const OUString& _rURL )
143 : {
144 0 : if ( getURL() == _rURL )
145 : // nothing to do, regardless of the state
146 0 : return;
147 :
148 0 : DELETEZ( m_pContent );
149 0 : m_eState = INVALID; // default to INVALID
150 0 : m_sURL = _rURL;
151 :
152 0 : if ( !m_sURL.isEmpty() )
153 : {
154 : try
155 : {
156 0 : m_pContent = new ::ucbhelper::Content( _rURL, m_xCmdEnv, comphelper::getProcessComponentContext() );
157 0 : 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 0 : catch( const ContentCreationException& )
163 : {
164 : }
165 0 : catch( const Exception& )
166 : {
167 : OSL_FAIL( "SmartContent::bindTo: unexpected exception caught!" );
168 : }
169 : }
170 : else
171 : {
172 0 : 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 0 : ::svt::OFilePickerInteractionHandler* pHandler = getOwnInteractionHandler();
179 0 : if (pHandler)
180 : {
181 0 : pHandler->resetUseState();
182 0 : pHandler->forgetRequest();
183 : }
184 : }
185 :
186 :
187 0 : bool SmartContent::implIs( const OUString& _rURL, Type _eType )
188 : {
189 : // bind to this content
190 0 : bindTo( _rURL );
191 :
192 : // did we survive this?
193 0 : if ( isInvalid() || !isBound() )
194 0 : return 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 0 : bool bIs = false;
201 : try
202 : {
203 0 : if ( Folder == _eType )
204 0 : bIs = m_pContent->isFolder();
205 : else
206 0 : bIs = m_pContent->isDocument();
207 :
208 : // from here on, we definitely know that the content is valid
209 0 : m_eState = VALID;
210 : }
211 0 : catch( const Exception& )
212 : {
213 : // now we're definitely invalid
214 0 : m_eState = INVALID;
215 : }
216 0 : return bIs;
217 : }
218 :
219 :
220 0 : void SmartContent::getTitle( OUString& /* [out] */ _rTitle )
221 : {
222 0 : if ( !isBound() || isInvalid() )
223 0 : return;
224 :
225 : try
226 : {
227 0 : OUString sTitle;
228 0 : m_pContent->getPropertyValue("Title") >>= sTitle;
229 0 : _rTitle = sTitle;
230 :
231 : // from here on, we definitely know that the content is valid
232 0 : m_eState = VALID;
233 : }
234 0 : catch( const ::com::sun::star::uno::Exception& )
235 : {
236 : // now we're definitely invalid
237 0 : m_eState = INVALID;
238 : }
239 : }
240 :
241 :
242 0 : bool SmartContent::hasParentFolder( )
243 : {
244 0 : if ( !isBound() || isInvalid() )
245 0 : return false;
246 :
247 0 : bool bRet = false;
248 : try
249 : {
250 0 : Reference< XChild > xChild( m_pContent->get(), UNO_QUERY );
251 0 : if ( xChild.is() )
252 : {
253 0 : Reference< XContent > xParent( xChild->getParent(), UNO_QUERY );
254 0 : if ( xParent.is() )
255 : {
256 0 : const OUString aParentURL( xParent->getIdentifier()->getContentIdentifier() );
257 0 : bRet = ( !aParentURL.isEmpty() && aParentURL != m_pContent->getURL() );
258 :
259 : // now we're definitely valid
260 0 : m_eState = VALID;
261 0 : }
262 0 : }
263 : }
264 0 : catch( const Exception& )
265 : {
266 : // now we're definitely invalid
267 0 : m_eState = INVALID;
268 : }
269 0 : return bRet;
270 : }
271 :
272 :
273 0 : bool SmartContent::canCreateFolder( )
274 : {
275 0 : if ( !isBound() || isInvalid() )
276 0 : return false;
277 :
278 0 : bool bRet = false;
279 : try
280 : {
281 0 : Sequence< ContentInfo > aInfo = m_pContent->queryCreatableContentsInfo();
282 0 : const ContentInfo* pInfo = aInfo.getConstArray();
283 0 : sal_Int32 nCount = aInfo.getLength();
284 0 : for ( sal_Int32 i = 0; i < nCount; ++i, ++pInfo )
285 : {
286 : // Simply look for the first KIND_FOLDER...
287 0 : if ( pInfo->Attributes & ContentInfoAttribute::KIND_FOLDER )
288 : {
289 0 : bRet = true;
290 0 : break;
291 : }
292 : }
293 :
294 : // now we're definitely valid
295 0 : m_eState = VALID;
296 : }
297 0 : catch( const Exception& )
298 : {
299 : // now we're definitely invalid
300 0 : m_eState = INVALID;
301 : }
302 0 : return bRet;
303 : }
304 :
305 0 : OUString SmartContent::createFolder( const OUString& _rTitle )
306 : {
307 0 : OUString aCreatedUrl;
308 : try
309 : {
310 0 : OUString sFolderType;
311 :
312 0 : Sequence< ContentInfo > aInfo = m_pContent->queryCreatableContentsInfo();
313 0 : const ContentInfo* pInfo = aInfo.getConstArray();
314 0 : sal_Int32 nCount = aInfo.getLength();
315 0 : for ( sal_Int32 i = 0; i < nCount; ++i, ++pInfo )
316 : {
317 : // Simply look for the first KIND_FOLDER...
318 0 : if ( pInfo->Attributes & ContentInfoAttribute::KIND_FOLDER )
319 : {
320 0 : sFolderType = pInfo->Type;
321 0 : break;
322 : }
323 : }
324 :
325 0 : if ( !sFolderType.isEmpty() )
326 : {
327 0 : ucbhelper::Content aCreated;
328 0 : Sequence< OUString > aNames( 1 );
329 0 : OUString* pNames = aNames.getArray();
330 0 : pNames[0] = "Title";
331 0 : Sequence< Any > aValues( 1 );
332 0 : Any* pValues = aValues.getArray();
333 0 : pValues[0] = makeAny( _rTitle );
334 0 : m_pContent->insertNewContent( sFolderType, aNames, aValues, aCreated );
335 :
336 0 : aCreatedUrl = aCreated.getURL();
337 0 : }
338 : }
339 0 : catch( const Exception& )
340 : {
341 : }
342 0 : return aCreatedUrl;
343 : }
344 :
345 :
346 : } // namespace svt
347 :
348 :
349 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|