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