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 <editeng/unolingu.hxx>
21 :
22 : #include <unobaseclass.hxx>
23 : #include <unoflatpara.hxx>
24 :
25 : #include <osl/mutex.hxx>
26 : #include <vcl/svapp.hxx>
27 : #include <com/sun/star/text/TextMarkupType.hpp>
28 : #include <unotextmarkup.hxx>
29 : #include <ndtxt.hxx>
30 : #include <doc.hxx>
31 : #include <docsh.hxx>
32 : #include <viewsh.hxx>
33 : #include <viewimp.hxx>
34 : #include <breakit.hxx>
35 : #include <pam.hxx>
36 : #include <unotextrange.hxx>
37 : #include <pagefrm.hxx>
38 : #include <cntfrm.hxx>
39 : #include <rootfrm.hxx>
40 : #include <poolfmt.hxx>
41 : #include <pagedesc.hxx>
42 : #include <IGrammarContact.hxx>
43 : #include <viewopt.hxx>
44 : #include <comphelper/servicehelper.hxx>
45 :
46 : #include <com/sun/star/lang/XUnoTunnel.hpp>
47 : #include <com/sun/star/text/XTextRange.hpp>
48 :
49 : using namespace ::com::sun::star;
50 :
51 : namespace SwUnoCursorHelper {
52 :
53 : uno::Reference<text::XFlatParagraphIterator>
54 0 : CreateFlatParagraphIterator(SwDoc & rDoc, sal_Int32 const nTextMarkupType,
55 : bool const bAutomatic)
56 : {
57 0 : return new SwXFlatParagraphIterator(rDoc, nTextMarkupType, bAutomatic);
58 : }
59 :
60 : }
61 :
62 : /******************************************************************************
63 : * SwXFlatParagraph
64 : ******************************************************************************/
65 :
66 0 : SwXFlatParagraph::SwXFlatParagraph( SwTxtNode& rTxtNode, const OUString& aExpandText, const ModelToViewHelper& rMap )
67 : : SwXFlatParagraph_Base(& rTxtNode, rMap)
68 0 : , maExpandText(aExpandText)
69 : {
70 0 : }
71 :
72 0 : SwXFlatParagraph::~SwXFlatParagraph()
73 : {
74 0 : }
75 :
76 0 : const SwTxtNode* SwXFlatParagraph::getTxtNode() const
77 : {
78 0 : return mpTxtNode;
79 : }
80 :
81 : // XPropertySet
82 : uno::Reference< beans::XPropertySetInfo > SAL_CALL
83 0 : SwXFlatParagraph::getPropertySetInfo()
84 : throw (uno::RuntimeException, std::exception)
85 : {
86 : throw uno::RuntimeException("SwXFlatParagraph::getPropertySetInfo(): "
87 0 : "not implemented", static_cast< ::cppu::OWeakObject*>(this));
88 : }
89 :
90 : void SAL_CALL
91 0 : SwXFlatParagraph::setPropertyValue(const OUString&, const uno::Any&)
92 : throw (beans::UnknownPropertyException, beans::PropertyVetoException,
93 : lang::IllegalArgumentException, lang::WrappedTargetException,
94 : uno::RuntimeException, std::exception)
95 : {
96 : throw lang::IllegalArgumentException("no values can be set",
97 0 : static_cast< ::cppu::OWeakObject*>(this), 0);
98 : }
99 :
100 : uno::Any SAL_CALL
101 0 : SwXFlatParagraph::getPropertyValue(const OUString& rPropertyName)
102 : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
103 : uno::RuntimeException, std::exception)
104 : {
105 0 : SolarMutexGuard g;
106 :
107 0 : if (rPropertyName == "FieldPositions")
108 : {
109 0 : uno::Sequence<sal_Int32> ret(maConversionMap.getFieldPositions().size());
110 0 : std::copy(maConversionMap.getFieldPositions().begin(),
111 0 : maConversionMap.getFieldPositions().end(), ret.begin());
112 0 : return uno::makeAny(ret);
113 : }
114 0 : else if (rPropertyName == "FootnotePositions")
115 : {
116 0 : uno::Sequence<sal_Int32> ret(maConversionMap.getFootnotePositions().size());
117 0 : std::copy(maConversionMap.getFootnotePositions().begin(),
118 0 : maConversionMap.getFootnotePositions().end(), ret.begin());
119 0 : return uno::makeAny(ret);
120 : }
121 0 : return uno::Any();
122 : }
123 :
124 : void SAL_CALL
125 0 : SwXFlatParagraph::addPropertyChangeListener(
126 : const OUString& /*rPropertyName*/,
127 : const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
128 : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
129 : uno::RuntimeException, std::exception)
130 : {
131 : SAL_WARN("sw.uno",
132 : "SwXFlatParagraph::addPropertyChangeListener(): not implemented");
133 0 : }
134 :
135 : void SAL_CALL
136 0 : SwXFlatParagraph::removePropertyChangeListener(
137 : const OUString& /*rPropertyName*/,
138 : const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
139 : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
140 : uno::RuntimeException, std::exception)
141 : {
142 : SAL_WARN("sw.uno",
143 : "SwXFlatParagraph::removePropertyChangeListener(): not implemented");
144 0 : }
145 :
146 : void SAL_CALL
147 0 : SwXFlatParagraph::addVetoableChangeListener(
148 : const OUString& /*rPropertyName*/,
149 : const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
150 : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
151 : uno::RuntimeException, std::exception)
152 : {
153 : SAL_WARN("sw.uno",
154 : "SwXFlatParagraph::addVetoableChangeListener(): not implemented");
155 0 : }
156 :
157 : void SAL_CALL
158 0 : SwXFlatParagraph::removeVetoableChangeListener(
159 : const OUString& /*rPropertyName*/,
160 : const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
161 : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
162 : uno::RuntimeException, std::exception)
163 : {
164 : SAL_WARN("sw.uno",
165 : "SwXFlatParagraph::removeVetoableChangeListener(): not implemented");
166 0 : }
167 :
168 :
169 0 : css::uno::Reference< css::container::XStringKeyMap > SAL_CALL SwXFlatParagraph::getMarkupInfoContainer() throw (css::uno::RuntimeException, std::exception)
170 : {
171 0 : return SwXTextMarkup::getMarkupInfoContainer();
172 : }
173 :
174 0 : void SAL_CALL SwXFlatParagraph::commitTextRangeMarkup(::sal_Int32 nType, const OUString & aIdentifier, const uno::Reference< text::XTextRange> & xRange,
175 : const css::uno::Reference< css::container::XStringKeyMap > & xMarkupInfoContainer) throw (uno::RuntimeException, std::exception)
176 : {
177 0 : SolarMutexGuard aGuard;
178 0 : SwXTextMarkup::commitTextRangeMarkup( nType, aIdentifier, xRange, xMarkupInfoContainer );
179 0 : }
180 :
181 0 : void SAL_CALL SwXFlatParagraph::commitStringMarkup(::sal_Int32 nType, const OUString & rIdentifier, ::sal_Int32 nStart, ::sal_Int32 nLength, const css::uno::Reference< css::container::XStringKeyMap > & rxMarkupInfoContainer) throw (css::uno::RuntimeException, std::exception)
182 : {
183 0 : SolarMutexGuard aGuard;
184 0 : SwXTextMarkup::commitStringMarkup( nType, rIdentifier, nStart, nLength, rxMarkupInfoContainer );
185 0 : }
186 :
187 : // text::XFlatParagraph:
188 0 : OUString SAL_CALL SwXFlatParagraph::getText() throw (uno::RuntimeException, std::exception)
189 : {
190 0 : return maExpandText;
191 : }
192 :
193 : // text::XFlatParagraph:
194 0 : void SAL_CALL SwXFlatParagraph::setChecked( ::sal_Int32 nType, sal_Bool bVal ) throw (uno::RuntimeException, std::exception)
195 : {
196 0 : SolarMutexGuard aGuard;
197 :
198 0 : if ( mpTxtNode )
199 : {
200 0 : if ( text::TextMarkupType::SPELLCHECK == nType )
201 0 : mpTxtNode->SetWrongDirty( !bVal );
202 0 : else if ( text::TextMarkupType::SMARTTAG == nType )
203 0 : mpTxtNode->SetSmartTagDirty( !bVal );
204 0 : else if( text::TextMarkupType::PROOFREADING == nType )
205 : {
206 0 : mpTxtNode->SetGrammarCheckDirty( !bVal );
207 0 : if( bVal )
208 0 : ::finishGrammarCheck( *mpTxtNode );
209 : }
210 0 : }
211 0 : }
212 :
213 : // text::XFlatParagraph:
214 0 : sal_Bool SAL_CALL SwXFlatParagraph::isChecked( ::sal_Int32 nType ) throw (uno::RuntimeException, std::exception)
215 : {
216 0 : SolarMutexGuard aGuard;
217 0 : if ( mpTxtNode )
218 : {
219 0 : if ( text::TextMarkupType::SPELLCHECK == nType )
220 0 : return mpTxtNode->IsWrongDirty();
221 0 : else if ( text::TextMarkupType::PROOFREADING == nType )
222 0 : return mpTxtNode->IsGrammarCheckDirty();
223 0 : else if ( text::TextMarkupType::SMARTTAG == nType )
224 0 : return mpTxtNode->IsSmartTagDirty();
225 : }
226 :
227 0 : return sal_False;
228 : }
229 :
230 : // text::XFlatParagraph:
231 0 : sal_Bool SAL_CALL SwXFlatParagraph::isModified() throw (uno::RuntimeException, std::exception)
232 : {
233 0 : SolarMutexGuard aGuard;
234 0 : return 0 == mpTxtNode;
235 : }
236 :
237 : // text::XFlatParagraph:
238 0 : lang::Locale SAL_CALL SwXFlatParagraph::getLanguageOfText(::sal_Int32 nPos, ::sal_Int32 nLen)
239 : throw (uno::RuntimeException, lang::IllegalArgumentException, std::exception)
240 : {
241 0 : SolarMutexGuard aGuard;
242 0 : if (!mpTxtNode)
243 0 : return LanguageTag::convertToLocale( LANGUAGE_NONE );
244 :
245 0 : const lang::Locale aLocale( SW_BREAKITER()->GetLocale( mpTxtNode->GetLang(nPos, nLen) ) );
246 0 : return aLocale;
247 : }
248 :
249 : // text::XFlatParagraph:
250 0 : lang::Locale SAL_CALL SwXFlatParagraph::getPrimaryLanguageOfText(::sal_Int32 nPos, ::sal_Int32 nLen)
251 : throw (uno::RuntimeException, lang::IllegalArgumentException, std::exception)
252 : {
253 0 : SolarMutexGuard aGuard;
254 :
255 0 : if (!mpTxtNode)
256 0 : return LanguageTag::convertToLocale( LANGUAGE_NONE );
257 :
258 0 : const lang::Locale aLocale( SW_BREAKITER()->GetLocale( mpTxtNode->GetLang(nPos, nLen) ) );
259 0 : return aLocale;
260 : }
261 :
262 : // text::XFlatParagraph:
263 0 : void SAL_CALL SwXFlatParagraph::changeText(::sal_Int32 nPos, ::sal_Int32 nLen, const OUString & aNewText, const css::uno::Sequence< css::beans::PropertyValue > & aAttributes) throw (css::uno::RuntimeException, css::lang::IllegalArgumentException, std::exception)
264 : {
265 0 : SolarMutexGuard aGuard;
266 :
267 0 : if ( !mpTxtNode )
268 0 : return;
269 :
270 0 : SwTxtNode* pOldTxtNode = mpTxtNode;
271 :
272 0 : SwPaM aPaM( *mpTxtNode, nPos, *mpTxtNode, nPos+nLen );
273 :
274 0 : UnoActionContext aAction( mpTxtNode->GetDoc() );
275 :
276 : const uno::Reference< text::XTextRange > xRange =
277 : SwXTextRange::CreateXTextRange(
278 0 : *mpTxtNode->GetDoc(), *aPaM.GetPoint(), aPaM.GetMark() );
279 0 : uno::Reference< beans::XPropertySet > xPropSet( xRange, uno::UNO_QUERY );
280 0 : if ( xPropSet.is() )
281 : {
282 0 : for ( sal_uInt16 i = 0; i < aAttributes.getLength(); ++i )
283 0 : xPropSet->setPropertyValue( aAttributes[i].Name, aAttributes[i].Value );
284 : }
285 :
286 0 : mpTxtNode = pOldTxtNode; // setPropertyValue() modifies this. We restore the old state.
287 :
288 0 : IDocumentContentOperations* pIDCO = mpTxtNode->getIDocumentContentOperations();
289 0 : pIDCO->ReplaceRange( aPaM, aNewText, false );
290 :
291 0 : mpTxtNode = 0;
292 : }
293 :
294 : // text::XFlatParagraph:
295 0 : void SAL_CALL SwXFlatParagraph::changeAttributes(::sal_Int32 nPos, ::sal_Int32 nLen, const css::uno::Sequence< css::beans::PropertyValue > & aAttributes) throw (css::uno::RuntimeException, css::lang::IllegalArgumentException, std::exception)
296 : {
297 0 : SolarMutexGuard aGuard;
298 :
299 0 : if ( !mpTxtNode )
300 0 : return;
301 :
302 0 : SwPaM aPaM( *mpTxtNode, nPos, *mpTxtNode, nPos+nLen );
303 :
304 0 : UnoActionContext aAction( mpTxtNode->GetDoc() );
305 :
306 : const uno::Reference< text::XTextRange > xRange =
307 : SwXTextRange::CreateXTextRange(
308 0 : *mpTxtNode->GetDoc(), *aPaM.GetPoint(), aPaM.GetMark() );
309 0 : uno::Reference< beans::XPropertySet > xPropSet( xRange, uno::UNO_QUERY );
310 0 : if ( xPropSet.is() )
311 : {
312 0 : for ( sal_uInt16 i = 0; i < aAttributes.getLength(); ++i )
313 0 : xPropSet->setPropertyValue( aAttributes[i].Name, aAttributes[i].Value );
314 : }
315 :
316 0 : mpTxtNode = 0;
317 : }
318 :
319 : // text::XFlatParagraph:
320 0 : css::uno::Sequence< ::sal_Int32 > SAL_CALL SwXFlatParagraph::getLanguagePortions() throw (css::uno::RuntimeException, std::exception)
321 : {
322 0 : SolarMutexGuard aGuard;
323 0 : return css::uno::Sequence< ::sal_Int32>();
324 : }
325 :
326 : namespace
327 : {
328 : class theSwXFlatParagraphUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXFlatParagraphUnoTunnelId > {};
329 : }
330 :
331 : const uno::Sequence< sal_Int8 >&
332 0 : SwXFlatParagraph::getUnoTunnelId()
333 : {
334 0 : return theSwXFlatParagraphUnoTunnelId::get().getSeq();
335 : }
336 :
337 : sal_Int64 SAL_CALL
338 0 : SwXFlatParagraph::getSomething(
339 : const uno::Sequence< sal_Int8 >& rId)
340 : throw (uno::RuntimeException, std::exception)
341 : {
342 0 : return sw::UnoTunnelImpl(rId, this);
343 : }
344 :
345 : /******************************************************************************
346 : * SwXFlatParagraphIterator
347 : ******************************************************************************/
348 :
349 0 : SwXFlatParagraphIterator::SwXFlatParagraphIterator( SwDoc& rDoc, sal_Int32 nType, sal_Bool bAutomatic )
350 : : mpDoc( &rDoc ),
351 : mnType( nType ),
352 : mbAutomatic( bAutomatic ),
353 : mnCurrentNode( 0 ),
354 : mnStartNode( 0 ),
355 0 : mnEndNode( rDoc.GetNodes().Count() ),
356 0 : mbWrapped( sal_False )
357 : {
358 : //mnStartNode = mnCurrentNode = get node from current cursor TODO!
359 :
360 : // register as listener and get notified when document is closed
361 0 : mpDoc->GetPageDescFromPool( RES_POOLPAGE_STANDARD )->Add(this);
362 0 : }
363 :
364 0 : SwXFlatParagraphIterator::~SwXFlatParagraphIterator()
365 : {
366 0 : }
367 :
368 0 : void SwXFlatParagraphIterator::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew )
369 : {
370 0 : ClientModify( this, pOld, pNew );
371 : // check if document gets closed...
372 0 : if(!GetRegisteredIn())
373 : {
374 0 : SolarMutexGuard aGuard;
375 0 : mpDoc = 0;
376 : }
377 0 : }
378 :
379 0 : uno::Reference< text::XFlatParagraph > SwXFlatParagraphIterator::getFirstPara()
380 : throw( uno::RuntimeException, std::exception )
381 : {
382 0 : return getNextPara(); // TODO
383 : }
384 :
385 0 : uno::Reference< text::XFlatParagraph > SwXFlatParagraphIterator::getNextPara()
386 : throw( uno::RuntimeException, std::exception )
387 : {
388 0 : SolarMutexGuard aGuard;
389 :
390 0 : uno::Reference< text::XFlatParagraph > xRet;
391 0 : if (!mpDoc)
392 0 : return xRet;
393 :
394 0 : SwTxtNode* pRet = 0;
395 0 : if ( mbAutomatic )
396 : {
397 0 : SwViewShell* pViewShell = 0;
398 0 : mpDoc->GetEditShell( &pViewShell );
399 :
400 0 : SwPageFrm* pCurrentPage = pViewShell ? pViewShell->Imp()->GetFirstVisPage() : 0;
401 0 : SwPageFrm* pStartPage = pCurrentPage;
402 0 : SwPageFrm* pStopPage = 0;
403 :
404 0 : while ( pCurrentPage && pCurrentPage != pStopPage )
405 : {
406 0 : if (mnType != text::TextMarkupType::SPELLCHECK || pCurrentPage->IsInvalidSpelling() )
407 : {
408 : // this method is supposed to return an empty paragraph in case Online Checking is disabled
409 0 : if ( ( mnType == text::TextMarkupType::PROOFREADING || mnType == text::TextMarkupType::SPELLCHECK )
410 0 : && !pViewShell->GetViewOptions()->IsOnlineSpell() )
411 0 : return xRet;
412 :
413 : // search for invalid content:
414 0 : SwCntntFrm* pCnt = pCurrentPage->ContainsCntnt();
415 :
416 0 : while( pCnt && pCurrentPage->IsAnLower( pCnt ) )
417 : {
418 0 : SwTxtNode* pTxtNode = dynamic_cast<SwTxtNode*>( pCnt->GetNode()->GetTxtNode() );
419 :
420 0 : if ( pTxtNode &&
421 0 : ((mnType == text::TextMarkupType::SPELLCHECK &&
422 0 : pTxtNode->IsWrongDirty()) ||
423 0 : (mnType == text::TextMarkupType::PROOFREADING &&
424 0 : pTxtNode->IsGrammarCheckDirty())) )
425 : {
426 0 : pRet = pTxtNode;
427 0 : break;
428 : }
429 :
430 0 : pCnt = pCnt->GetNextCntntFrm();
431 : }
432 : }
433 :
434 0 : if ( pRet )
435 0 : break;
436 :
437 : // if there is no invalid text node on the current page,
438 : // we validate the page
439 0 : pCurrentPage->ValidateSpelling();
440 :
441 : // proceed with next page, wrap at end of document if required:
442 0 : pCurrentPage = static_cast<SwPageFrm*>(pCurrentPage->GetNext());
443 :
444 0 : if ( !pCurrentPage && !pStopPage )
445 : {
446 0 : pStopPage = pStartPage;
447 0 : pCurrentPage = static_cast<SwPageFrm*>(pViewShell->GetLayout()->Lower());
448 : }
449 : }
450 : }
451 : else // non-automatic checking
452 : {
453 0 : const SwNodes& rNodes = mpDoc->GetNodes();
454 0 : const sal_uLong nMaxNodes = rNodes.Count();
455 :
456 0 : while ( mnCurrentNode < mnEndNode && mnCurrentNode < nMaxNodes )
457 : {
458 0 : SwNode* pNd = rNodes[ mnCurrentNode ];
459 :
460 0 : ++mnCurrentNode;
461 :
462 0 : pRet = dynamic_cast<SwTxtNode*>(pNd);
463 0 : if ( pRet )
464 0 : break;
465 :
466 0 : if ( mnCurrentNode == mnEndNode && !mbWrapped )
467 : {
468 0 : mnCurrentNode = 0;
469 0 : mnEndNode = mnStartNode;
470 : }
471 : }
472 : }
473 :
474 0 : if ( pRet )
475 : {
476 : // Expand the string:
477 0 : const ModelToViewHelper aConversionMap(*pRet);
478 0 : OUString aExpandText = aConversionMap.getViewText();
479 :
480 0 : xRet = new SwXFlatParagraph( *pRet, aExpandText, aConversionMap );
481 : // keep hard references...
482 0 : m_aFlatParaList.insert( xRet );
483 : }
484 :
485 0 : return xRet;
486 : }
487 :
488 0 : uno::Reference< text::XFlatParagraph > SwXFlatParagraphIterator::getLastPara()
489 : throw( uno::RuntimeException, std::exception )
490 : {
491 0 : return getNextPara();
492 : }
493 :
494 0 : uno::Reference< text::XFlatParagraph > SwXFlatParagraphIterator::getParaAfter(const uno::Reference< text::XFlatParagraph > & xPara)
495 : throw ( uno::RuntimeException, lang::IllegalArgumentException, std::exception )
496 : {
497 0 : SolarMutexGuard aGuard;
498 :
499 0 : uno::Reference< text::XFlatParagraph > xRet;
500 0 : if (!mpDoc)
501 0 : return xRet;
502 :
503 0 : const uno::Reference<lang::XUnoTunnel> xFPTunnel(xPara, uno::UNO_QUERY);
504 : OSL_ASSERT(xFPTunnel.is());
505 0 : SwXFlatParagraph* const pFlatParagraph(sw::UnoTunnelGetImplementation<SwXFlatParagraph>(xFPTunnel));
506 :
507 0 : if ( !pFlatParagraph )
508 0 : return xRet;
509 :
510 0 : const SwTxtNode* pCurrentNode = pFlatParagraph->getTxtNode();
511 :
512 0 : if ( !pCurrentNode )
513 0 : return xRet;
514 :
515 0 : SwTxtNode* pNextTxtNode = 0;
516 0 : const SwNodes& rNodes = pCurrentNode->GetDoc()->GetNodes();
517 :
518 0 : for( sal_uLong nCurrentNode = pCurrentNode->GetIndex() + 1; nCurrentNode < rNodes.Count(); ++nCurrentNode )
519 : {
520 0 : SwNode* pNd = rNodes[ nCurrentNode ];
521 0 : pNextTxtNode = dynamic_cast<SwTxtNode*>(pNd);
522 0 : if ( pNextTxtNode )
523 0 : break;
524 : }
525 :
526 0 : if ( pNextTxtNode )
527 : {
528 : // Expand the string:
529 0 : const ModelToViewHelper aConversionMap(*pNextTxtNode);
530 0 : OUString aExpandText = aConversionMap.getViewText();
531 :
532 0 : xRet = new SwXFlatParagraph( *pNextTxtNode, aExpandText, aConversionMap );
533 : // keep hard references...
534 0 : m_aFlatParaList.insert( xRet );
535 : }
536 :
537 0 : return xRet;
538 : }
539 :
540 0 : uno::Reference< text::XFlatParagraph > SwXFlatParagraphIterator::getParaBefore(const uno::Reference< text::XFlatParagraph > & xPara )
541 : throw ( uno::RuntimeException, lang::IllegalArgumentException, std::exception )
542 : {
543 0 : SolarMutexGuard aGuard;
544 :
545 0 : uno::Reference< text::XFlatParagraph > xRet;
546 0 : if (!mpDoc)
547 0 : return xRet;
548 :
549 0 : const uno::Reference<lang::XUnoTunnel> xFPTunnel(xPara, uno::UNO_QUERY);
550 : OSL_ASSERT(xFPTunnel.is());
551 0 : SwXFlatParagraph* const pFlatParagraph(sw::UnoTunnelGetImplementation<SwXFlatParagraph>(xFPTunnel));
552 :
553 0 : if ( !pFlatParagraph )
554 0 : return xRet;
555 :
556 0 : const SwTxtNode* pCurrentNode = pFlatParagraph->getTxtNode();
557 :
558 0 : if ( !pCurrentNode )
559 0 : return xRet;
560 :
561 0 : SwTxtNode* pPrevTxtNode = 0;
562 0 : const SwNodes& rNodes = pCurrentNode->GetDoc()->GetNodes();
563 :
564 0 : for( sal_uLong nCurrentNode = pCurrentNode->GetIndex() - 1; nCurrentNode > 0; --nCurrentNode )
565 : {
566 0 : SwNode* pNd = rNodes[ nCurrentNode ];
567 0 : pPrevTxtNode = dynamic_cast<SwTxtNode*>(pNd);
568 0 : if ( pPrevTxtNode )
569 0 : break;
570 : }
571 :
572 0 : if ( pPrevTxtNode )
573 : {
574 : // Expand the string:
575 0 : const ModelToViewHelper aConversionMap(*pPrevTxtNode);
576 0 : OUString aExpandText = aConversionMap.getViewText();
577 :
578 0 : xRet = new SwXFlatParagraph( *pPrevTxtNode, aExpandText, aConversionMap );
579 : // keep hard references...
580 0 : m_aFlatParaList.insert( xRet );
581 : }
582 :
583 0 : return xRet;
584 : }
585 :
586 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|