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