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 <unocrsrhelper.hxx>
21 :
22 : #include <map>
23 : #include <algorithm>
24 :
25 : #include <com/sun/star/beans/PropertyState.hpp>
26 : #include <com/sun/star/embed/ElementModes.hpp>
27 : #include <com/sun/star/embed/XStorage.hpp>
28 : #include <com/sun/star/text/XTextSection.hpp>
29 :
30 : #include <svx/svxids.hrc>
31 : #include <svx/unoshape.hxx>
32 :
33 : #include <cmdid.h>
34 : #include <unotextrange.hxx>
35 : #include <unodraw.hxx>
36 : #include <unofootnote.hxx>
37 : #include <unobookmark.hxx>
38 : #include <unorefmark.hxx>
39 : #include <unostyle.hxx>
40 : #include <unoidx.hxx>
41 : #include <unofield.hxx>
42 : #include <unotbl.hxx>
43 : #include <unosett.hxx>
44 : #include <unoframe.hxx>
45 : #include <unocrsr.hxx>
46 : #include <doc.hxx>
47 : #include <IDocumentUndoRedo.hxx>
48 : #include <IDocumentRedlineAccess.hxx>
49 : #include <IDocumentLayoutAccess.hxx>
50 : #include <fmtftn.hxx>
51 : #include <fmtpdsc.hxx>
52 : #include <charfmt.hxx>
53 : #include <pagedesc.hxx>
54 : #include <docstyle.hxx>
55 : #include <ndtxt.hxx>
56 : #include <txtrfmrk.hxx>
57 : #include <fmtfld.hxx>
58 : #include <docsh.hxx>
59 : #include <section.hxx>
60 : #include <shellio.hxx>
61 : #include <edimp.hxx>
62 : #include <swundo.hxx>
63 : #include <cntfrm.hxx>
64 : #include <pagefrm.hxx>
65 : #include <svl/eitem.hxx>
66 : #include <docary.hxx>
67 : #include <swtable.hxx>
68 : #include <tox.hxx>
69 : #include <doctxm.hxx>
70 : #include <fchrfmt.hxx>
71 : #include <editeng/flstitem.hxx>
72 : #include <vcl/metric.hxx>
73 : #include <svtools/ctrltool.hxx>
74 : #include <sfx2/docfilt.hxx>
75 : #include <sfx2/docfile.hxx>
76 : #include <sfx2/fcontnr.hxx>
77 : #include <svl/stritem.hxx>
78 : #include <SwStyleNameMapper.hxx>
79 : #include <redline.hxx>
80 : #include <numrule.hxx>
81 : #include <comphelper/storagehelper.hxx>
82 : #include <unotools/mediadescriptor.hxx>
83 : #include <comphelper/sequenceashashmap.hxx>
84 : #include <SwNodeNum.hxx>
85 : #include <fmtmeta.hxx>
86 : #include <txtfld.hxx>
87 :
88 : using namespace ::com::sun::star;
89 : using namespace ::com::sun::star::uno;
90 : using namespace ::com::sun::star::beans;
91 : using namespace ::com::sun::star::text;
92 : using namespace ::com::sun::star::table;
93 : using namespace ::com::sun::star::container;
94 : using namespace ::com::sun::star::lang;
95 :
96 : namespace SwUnoCursorHelper
97 : {
98 :
99 0 : static SwPaM* lcl_createPamCopy(const SwPaM& rPam)
100 : {
101 0 : SwPaM *const pRet = new SwPaM(*rPam.GetPoint());
102 0 : ::sw::DeepCopyPaM(rPam, *pRet);
103 0 : return pRet;
104 : }
105 :
106 8 : void GetSelectableFromAny(uno::Reference<uno::XInterface> const& xIfc,
107 : SwDoc & rTargetDoc,
108 : SwPaM *& o_rpPaM, std::pair<OUString, FlyCntType> & o_rFrame,
109 : OUString & o_rTableName, SwUnoTableCrsr const*& o_rpTableCursor,
110 : ::sw::mark::IMark const*& o_rpMark,
111 : std::vector<SdrObject *> & o_rSdrObjects)
112 : {
113 8 : uno::Reference<drawing::XShapes> const xShapes(xIfc, UNO_QUERY);
114 8 : if (xShapes.is())
115 : {
116 0 : sal_Int32 nShapes(xShapes->getCount());
117 0 : for (sal_Int32 i = 0; i < nShapes; ++i)
118 : {
119 0 : uno::Reference<lang::XUnoTunnel> xShape;
120 0 : xShapes->getByIndex(i) >>= xShape;
121 0 : if (xShape.is())
122 : {
123 : SvxShape *const pSvxShape(
124 0 : ::sw::UnoTunnelGetImplementation<SvxShape>(xShape));
125 0 : if (pSvxShape)
126 : {
127 0 : SdrObject *const pSdrObject = pSvxShape->GetSdrObject();
128 0 : if (pSdrObject)
129 : { // hmm... needs view to verify it's in right doc...
130 0 : o_rSdrObjects.push_back(pSdrObject);
131 : }
132 : }
133 : }
134 0 : }
135 0 : return;
136 : }
137 :
138 8 : uno::Reference<lang::XUnoTunnel> const xTunnel(xIfc, UNO_QUERY);
139 8 : if (!xTunnel.is()) // everything below needs tunnel
140 : {
141 0 : return;
142 : }
143 :
144 8 : SwXShape *const pShape(::sw::UnoTunnelGetImplementation<SwXShape>(xTunnel));
145 8 : if (pShape)
146 : {
147 : uno::Reference<uno::XAggregation> const xAgg(
148 0 : pShape->GetAggregationInterface());
149 0 : if (xAgg.is())
150 : {
151 : SvxShape *const pSvxShape(
152 0 : ::sw::UnoTunnelGetImplementation<SvxShape>(xTunnel));
153 0 : if (pSvxShape)
154 : {
155 0 : SdrObject *const pSdrObject = pSvxShape->GetSdrObject();
156 0 : if (pSdrObject)
157 : { // hmm... needs view to verify it's in right doc...
158 0 : o_rSdrObjects.push_back(pSdrObject);
159 : }
160 : }
161 : }
162 0 : return;
163 : }
164 :
165 : OTextCursorHelper *const pCursor(
166 8 : ::sw::UnoTunnelGetImplementation<OTextCursorHelper>(xTunnel));
167 8 : if (pCursor)
168 : {
169 0 : if (pCursor->GetDoc() == &rTargetDoc)
170 : {
171 0 : o_rpPaM = lcl_createPamCopy(*pCursor->GetPaM());
172 : }
173 0 : return;
174 : }
175 :
176 : SwXTextRanges* const pRanges(
177 8 : ::sw::UnoTunnelGetImplementation<SwXTextRanges>(xTunnel));
178 8 : if (pRanges)
179 : {
180 0 : SwUnoCrsr const* pUnoCrsr = pRanges->GetCursor();
181 0 : if (pUnoCrsr && pUnoCrsr->GetDoc() == &rTargetDoc)
182 : {
183 0 : o_rpPaM = lcl_createPamCopy(*pUnoCrsr);
184 : }
185 0 : return;
186 : }
187 :
188 : // check these before Range to prevent misinterpretation of text frames
189 : // and cells also implement XTextRange
190 : SwXFrame *const pFrame(
191 8 : ::sw::UnoTunnelGetImplementation<SwXFrame>(xTunnel));
192 8 : if (pFrame)
193 : {
194 0 : const SwFrameFormat *const pFrameFormat(pFrame->GetFrameFormat());
195 0 : if (pFrameFormat && pFrameFormat->GetDoc() == &rTargetDoc)
196 : {
197 0 : o_rFrame = std::make_pair(pFrameFormat->GetName(), pFrame->GetFlyCntType());
198 : }
199 0 : return;
200 : }
201 :
202 : SwXTextTable *const pTextTable(
203 8 : ::sw::UnoTunnelGetImplementation<SwXTextTable>(xTunnel));
204 8 : if (pTextTable)
205 : {
206 8 : SwFrameFormat *const pFrameFormat(pTextTable->GetFrameFormat());
207 8 : if (pFrameFormat && pFrameFormat->GetDoc() == &rTargetDoc)
208 : {
209 8 : o_rTableName = pFrameFormat->GetName();
210 : }
211 8 : return;
212 : }
213 :
214 : SwXCell *const pCell(
215 0 : ::sw::UnoTunnelGetImplementation<SwXCell>(xTunnel));
216 0 : if (pCell)
217 : {
218 0 : SwFrameFormat *const pFrameFormat(pCell->GetFrameFormat());
219 0 : if (pFrameFormat && pFrameFormat->GetDoc() == &rTargetDoc)
220 : {
221 0 : SwTableBox * pBox = pCell->GetTableBox();
222 0 : SwTable *const pTable = SwTable::FindTable(pFrameFormat);
223 : // ??? what's the benefit of setting pBox in this convoluted way?
224 0 : pBox = pCell->FindBox(pTable, pBox);
225 0 : if (pBox)
226 : {
227 0 : SwPosition const aPos(*pBox->GetSttNd());
228 0 : SwPaM aPam(aPos);
229 0 : aPam.Move(fnMoveForward, fnGoNode);
230 0 : o_rpPaM = lcl_createPamCopy(aPam);
231 : }
232 : }
233 0 : return;
234 : }
235 :
236 0 : uno::Reference<text::XTextRange> const xTextRange(xTunnel, UNO_QUERY);
237 0 : if (xTextRange.is())
238 : {
239 0 : SwUnoInternalPaM aPam(rTargetDoc);
240 0 : if (::sw::XTextRangeToSwPaM(aPam, xTextRange))
241 : {
242 0 : o_rpPaM = lcl_createPamCopy(aPam);
243 : }
244 0 : return;
245 : }
246 :
247 : SwXCellRange *const pCellRange(
248 0 : ::sw::UnoTunnelGetImplementation<SwXCellRange>(xTunnel));
249 0 : if (pCellRange)
250 : {
251 0 : SwUnoCrsr const*const pUnoCrsr(pCellRange->GetTableCrsr());
252 0 : if (pUnoCrsr && pUnoCrsr->GetDoc() == &rTargetDoc)
253 : {
254 : // probably can't copy it to o_rpPaM for this since it's
255 : // a SwTableCursor
256 0 : o_rpTableCursor = dynamic_cast<SwUnoTableCrsr const*>(pUnoCrsr);
257 : }
258 0 : return;
259 : }
260 :
261 : ::sw::mark::IMark const*const pMark(
262 0 : SwXBookmark::GetBookmarkInDoc(& rTargetDoc, xTunnel));
263 0 : if (pMark)
264 : {
265 0 : o_rpMark = pMark;
266 0 : return;
267 0 : }
268 : }
269 :
270 : uno::Reference<text::XTextContent>
271 22 : GetNestedTextContent(SwTextNode & rTextNode, sal_Int32 const nIndex,
272 : bool const bParent)
273 : {
274 : // these should be unambiguous because of the dummy character
275 : SwTextNode::GetTextAttrMode const eMode( (bParent)
276 22 : ? SwTextNode::PARENT : SwTextNode::EXPAND );
277 : SwTextAttr *const pMetaTextAttr =
278 22 : rTextNode.GetTextAttrAt(nIndex, RES_TXTATR_META, eMode);
279 : SwTextAttr *const pMetaFieldTextAttr =
280 22 : rTextNode.GetTextAttrAt(nIndex, RES_TXTATR_METAFIELD, eMode);
281 : // which is innermost?
282 : SwTextAttr *const pTextAttr = (pMetaTextAttr)
283 : ? ((pMetaFieldTextAttr)
284 20 : ? ((pMetaFieldTextAttr->GetStart() >
285 10 : pMetaTextAttr->GetStart())
286 : ? pMetaFieldTextAttr : pMetaTextAttr)
287 : : pMetaTextAttr)
288 32 : : pMetaFieldTextAttr;
289 22 : uno::Reference<XTextContent> xRet;
290 22 : if (pTextAttr)
291 : {
292 : ::sw::Meta *const pMeta(
293 16 : static_cast<SwFormatMeta &>(pTextAttr->GetAttr()).GetMeta());
294 : OSL_ASSERT(pMeta);
295 16 : xRet.set(pMeta->MakeUnoObject(), uno::UNO_QUERY);
296 : }
297 22 : return xRet;
298 : }
299 :
300 : // Read the special properties of the cursor
301 25207 : bool getCrsrPropertyValue(const SfxItemPropertySimpleEntry& rEntry
302 : , SwPaM& rPam
303 : , Any *pAny
304 : , PropertyState& eState
305 : , const SwTextNode* pNode )
306 : {
307 25207 : PropertyState eNewState = PropertyState_DIRECT_VALUE;
308 25207 : bool bDone = true;
309 25207 : switch(rEntry.nWID)
310 : {
311 : case FN_UNO_PARA_CONT_PREV_SUBTREE:
312 36 : if (pAny)
313 : {
314 36 : const SwTextNode * pTmpNode = pNode;
315 :
316 36 : if (!pTmpNode)
317 2 : pTmpNode = rPam.GetNode().GetTextNode();
318 :
319 36 : bool bRet = false;
320 :
321 70 : if ( pTmpNode &&
322 70 : pTmpNode->GetNum() &&
323 34 : pTmpNode->GetNum()->IsContinueingPreviousSubTree() )
324 : {
325 0 : bRet = true;
326 : }
327 :
328 36 : *pAny <<= bRet;
329 : }
330 36 : break;
331 : case FN_UNO_PARA_NUM_STRING:
332 2 : if (pAny)
333 : {
334 2 : const SwTextNode * pTmpNode = pNode;
335 :
336 2 : if (!pTmpNode)
337 2 : pTmpNode = rPam.GetNode().GetTextNode();
338 :
339 2 : OUString sRet;
340 2 : if ( pTmpNode && pTmpNode->GetNum() )
341 : {
342 0 : sRet = pTmpNode->GetNumString();
343 : }
344 :
345 2 : *pAny <<= sRet;
346 : }
347 2 : break;
348 : case RES_PARATR_OUTLINELEVEL:
349 6632 : if (pAny)
350 : {
351 6632 : const SwTextNode * pTmpNode = pNode;
352 :
353 6632 : if (!pTmpNode)
354 5700 : pTmpNode = rPam.GetNode().GetTextNode();
355 :
356 6632 : sal_Int16 nRet = -1;
357 6632 : if ( pTmpNode )
358 6630 : nRet = sal::static_int_cast< sal_Int16 >( pTmpNode->GetAttrOutlineLevel() );
359 :
360 6632 : *pAny <<= nRet;
361 : }
362 6632 : break;
363 : case FN_UNO_PARA_CONDITIONAL_STYLE_NAME:
364 : case FN_UNO_PARA_STYLE :
365 : {
366 2065 : SwFormatColl* pFormat = 0;
367 2065 : if(pNode)
368 1982 : pFormat = FN_UNO_PARA_CONDITIONAL_STYLE_NAME == rEntry.nWID
369 1982 : ? pNode->GetFormatColl() : &pNode->GetAnyFormatColl();
370 : else
371 : {
372 : pFormat = SwUnoCursorHelper::GetCurTextFormatColl(rPam,
373 83 : FN_UNO_PARA_CONDITIONAL_STYLE_NAME == rEntry.nWID);
374 : }
375 2065 : if(pFormat)
376 : {
377 2061 : if( pAny )
378 : {
379 2061 : OUString sVal;
380 2061 : SwStyleNameMapper::FillProgName(pFormat->GetName(), sVal, nsSwGetPoolIdFromName::GET_POOLID_TXTCOLL, true );
381 2061 : *pAny <<= sVal;
382 : }
383 : }
384 : else
385 4 : eNewState = PropertyState_AMBIGUOUS_VALUE;
386 : }
387 2065 : break;
388 : case FN_UNO_PAGE_STYLE :
389 : {
390 164 : OUString sVal;
391 164 : GetCurPageStyle(rPam, sVal);
392 164 : if( pAny )
393 164 : *pAny <<= sVal;
394 164 : if(sVal.isEmpty())
395 107 : eNewState = PropertyState_AMBIGUOUS_VALUE;
396 : }
397 164 : break;
398 : case FN_UNO_NUM_START_VALUE :
399 36 : if( pAny )
400 : {
401 36 : sal_Int16 nValue = IsNodeNumStart(rPam, eNewState);
402 36 : *pAny <<= nValue;
403 : }
404 36 : break;
405 : case FN_UNO_NUM_LEVEL :
406 : case FN_UNO_IS_NUMBER :
407 : // #i91601#
408 : case FN_UNO_LIST_ID:
409 : case FN_NUMBER_NEWSTART:
410 : {
411 : // a multi selection is not considered
412 2098 : const SwTextNode* pTextNd = rPam.GetNode().GetTextNode();
413 2098 : if ( pTextNd && pTextNd->IsInList() )
414 : {
415 281 : if( pAny )
416 : {
417 281 : if(rEntry.nWID == FN_UNO_NUM_LEVEL)
418 104 : *pAny <<= (sal_Int16)(pTextNd->GetActualListLevel());
419 177 : else if(rEntry.nWID == FN_UNO_IS_NUMBER)
420 : {
421 108 : *pAny <<= pTextNd->IsCountedInList();
422 : }
423 : // #i91601#
424 69 : else if ( rEntry.nWID == FN_UNO_LIST_ID )
425 : {
426 35 : *pAny <<= pTextNd->GetListId();
427 : }
428 : else
429 : {
430 34 : *pAny <<= pTextNd->IsListRestart();
431 : }
432 : }
433 : }
434 : else
435 : {
436 1817 : eNewState = PropertyState_DEFAULT_VALUE;
437 :
438 1817 : if( pAny )
439 : {
440 : // #i30838# set default values for default properties
441 1817 : if(rEntry.nWID == FN_UNO_NUM_LEVEL)
442 900 : *pAny <<= static_cast<sal_Int16>( 0 );
443 917 : else if(rEntry.nWID == FN_UNO_IS_NUMBER)
444 900 : *pAny <<= false;
445 : // #i91601#
446 17 : else if ( rEntry.nWID == FN_UNO_LIST_ID )
447 : {
448 2 : *pAny <<= OUString();
449 : }
450 : else
451 15 : *pAny <<= false;
452 : }
453 : }
454 : //PROPERTY_MAYBEVOID!
455 : }
456 2098 : break;
457 : case FN_UNO_NUM_RULES :
458 5854 : if( pAny )
459 5854 : getNumberingProperty(rPam, eNewState, pAny);
460 : else
461 : {
462 0 : if( !SwDoc::GetNumRuleAtPos( *rPam.GetPoint() ) )
463 0 : eNewState = PropertyState_DEFAULT_VALUE;
464 : }
465 5854 : break;
466 : case FN_UNO_DOCUMENT_INDEX_MARK:
467 : {
468 2 : ::std::vector<SwTextAttr *> marks;
469 2 : if (rPam.GetNode().IsTextNode())
470 : {
471 0 : marks = rPam.GetNode().GetTextNode()->GetTextAttrsAt(
472 0 : rPam.GetPoint()->nContent.GetIndex(), RES_TXTATR_TOXMARK);
473 : }
474 2 : if (marks.size())
475 : {
476 0 : if( pAny )
477 : { // hmm... can only return 1 here
478 : SwTOXMark & rMark =
479 0 : static_cast<SwTOXMark &>((*marks.begin())->GetAttr());
480 : const uno::Reference< text::XDocumentIndexMark > xRef =
481 : SwXDocumentIndexMark::CreateXDocumentIndexMark(
482 0 : *rPam.GetDoc(), &rMark);
483 0 : (*pAny) <<= xRef;
484 : }
485 : }
486 : else
487 : //also here - indistinguishable
488 2 : eNewState = PropertyState_DEFAULT_VALUE;
489 : }
490 2 : break;
491 : case FN_UNO_DOCUMENT_INDEX:
492 : {
493 : SwTOXBase* pBase = SwDoc::GetCurTOX(
494 2 : *rPam.Start() );
495 2 : if( pBase )
496 : {
497 0 : if( pAny )
498 : {
499 : const uno::Reference< text::XDocumentIndex > xRef =
500 0 : SwXDocumentIndex::CreateXDocumentIndex(*rPam.GetDoc(),
501 0 : static_cast<SwTOXBaseSection *>(pBase));
502 0 : (*pAny) <<= xRef;
503 : }
504 : }
505 : else
506 2 : eNewState = PropertyState_DEFAULT_VALUE;
507 : }
508 2 : break;
509 : case FN_UNO_TEXT_FIELD:
510 : {
511 2 : const SwPosition *pPos = rPam.Start();
512 : const SwTextNode *pTextNd =
513 2 : rPam.GetDoc()->GetNodes()[pPos->nNode.GetIndex()]->GetTextNode();
514 : const SwTextAttr* pTextAttr = (pTextNd)
515 0 : ? pTextNd->GetFieldTextAttrAt( pPos->nContent.GetIndex(), true )
516 2 : : 0;
517 2 : if ( pTextAttr != NULL )
518 : {
519 0 : if( pAny )
520 : {
521 : uno::Reference<text::XTextField> const xField(
522 : SwXTextField::CreateXTextField(rPam.GetDoc(),
523 0 : &pTextAttr->GetFormatField()));
524 0 : *pAny <<= xField;
525 : }
526 : }
527 : else
528 2 : eNewState = PropertyState_DEFAULT_VALUE;
529 : }
530 2 : break;
531 : case FN_UNO_TEXT_TABLE:
532 : case FN_UNO_CELL:
533 : {
534 4 : SwStartNode* pSttNode = rPam.GetNode().StartOfSectionNode();
535 4 : SwStartNodeType eType = pSttNode->GetStartNodeType();
536 4 : if(SwTableBoxStartNode == eType)
537 : {
538 0 : if( pAny )
539 : {
540 0 : const SwTableNode* pTableNode = pSttNode->FindTableNode();
541 0 : SwFrameFormat* pTableFormat = static_cast<SwFrameFormat*>(pTableNode->GetTable().GetFrameFormat());
542 : //SwTable& rTable = static_cast<SwTableNode*>(pSttNode)->GetTable();
543 0 : if(FN_UNO_TEXT_TABLE == rEntry.nWID)
544 : {
545 0 : uno::Reference< XTextTable > xTable = SwXTextTables::GetObject(*pTableFormat);
546 0 : pAny->setValue(&xTable, cppu::UnoType<XTextTable>::get());
547 : }
548 : else
549 : {
550 0 : SwTableBox* pBox = pSttNode->GetTableBox();
551 0 : uno::Reference< XCell > xCell = SwXCell::CreateXCell(pTableFormat, pBox);
552 0 : pAny->setValue(&xCell, cppu::UnoType<XCell>::get());
553 : }
554 : }
555 : }
556 : else
557 4 : eNewState = PropertyState_DEFAULT_VALUE;
558 : }
559 4 : break;
560 : case FN_UNO_TEXT_FRAME:
561 : {
562 26 : SwStartNode* pSttNode = rPam.GetNode().StartOfSectionNode();
563 26 : SwStartNodeType eType = pSttNode->GetStartNodeType();
564 :
565 : SwFrameFormat* pFormat;
566 26 : if(eType == SwFlyStartNode && 0 != (pFormat = pSttNode->GetFlyFormat()))
567 : {
568 1 : if( pAny )
569 : {
570 : uno::Reference<XTextFrame> const xFrame(
571 1 : SwXTextFrame::CreateXTextFrame(*pFormat->GetDoc(), pFormat));
572 1 : (*pAny) <<= xFrame;
573 : }
574 : }
575 : else
576 25 : eNewState = PropertyState_DEFAULT_VALUE;
577 : }
578 26 : break;
579 : case FN_UNO_TEXT_SECTION:
580 : {
581 998 : SwSection* pSect = SwDoc::GetCurrSection(*rPam.GetPoint());
582 998 : if(pSect)
583 : {
584 90 : if( pAny )
585 : {
586 90 : uno::Reference< XTextSection > xSect = SwXTextSections::GetObject( *pSect->GetFormat() );
587 90 : pAny->setValue(&xSect, cppu::UnoType<XTextSection>::get());
588 : }
589 : }
590 : else
591 908 : eNewState = PropertyState_DEFAULT_VALUE;
592 : }
593 998 : break;
594 : case FN_UNO_ENDNOTE:
595 : case FN_UNO_FOOTNOTE:
596 : {
597 4 : SwTextAttr *const pTextAttr = rPam.GetNode().IsTextNode() ?
598 0 : rPam.GetNode().GetTextNode()->GetTextAttrForCharAt(
599 4 : rPam.GetPoint()->nContent.GetIndex(), RES_TXTATR_FTN) : 0;
600 4 : if(pTextAttr)
601 : {
602 0 : const SwFormatFootnote& rFootnote = pTextAttr->GetFootnote();
603 0 : if(rFootnote.IsEndNote() == (FN_UNO_ENDNOTE == rEntry.nWID))
604 : {
605 0 : if( pAny )
606 : {
607 : const uno::Reference< text::XFootnote > xFootnote =
608 0 : SwXFootnote::CreateXFootnote(*rPam.GetDoc(),
609 0 : &const_cast<SwFormatFootnote&>(rFootnote));
610 0 : *pAny <<= xFootnote;
611 : }
612 : }
613 : else
614 0 : eNewState = PropertyState_DEFAULT_VALUE;
615 : }
616 : else
617 4 : eNewState = PropertyState_DEFAULT_VALUE;
618 : }
619 4 : break;
620 : case FN_UNO_REFERENCE_MARK:
621 : {
622 2 : ::std::vector<SwTextAttr *> marks;
623 2 : if (rPam.GetNode().IsTextNode())
624 : {
625 0 : marks = (
626 0 : rPam.GetNode().GetTextNode()->GetTextAttrsAt(
627 0 : rPam.GetPoint()->nContent.GetIndex(), RES_TXTATR_REFMARK));
628 : }
629 2 : if (marks.size())
630 : {
631 0 : if( pAny )
632 : { // hmm... can only return 1 here
633 0 : const SwFormatRefMark& rRef = (*marks.begin())->GetRefMark();
634 : uno::Reference<XTextContent> const xRef =
635 0 : SwXReferenceMark::CreateXReferenceMark(*rPam.GetDoc(),
636 0 : const_cast<SwFormatRefMark*>(&rRef));
637 0 : pAny->setValue(&xRef, cppu::UnoType<XTextContent>::get());
638 : }
639 : }
640 : else
641 2 : eNewState = PropertyState_DEFAULT_VALUE;
642 : }
643 2 : break;
644 : case FN_UNO_NESTED_TEXT_CONTENT:
645 : {
646 18 : uno::Reference<XTextContent> const xRet(rPam.GetNode().IsTextNode()
647 16 : ? GetNestedTextContent(*rPam.GetNode().GetTextNode(),
648 16 : rPam.GetPoint()->nContent.GetIndex(), false)
649 50 : : 0);
650 18 : if (xRet.is())
651 : {
652 13 : if (pAny)
653 : {
654 13 : (*pAny) <<= xRet;
655 : }
656 : }
657 : else
658 : {
659 5 : eNewState = PropertyState_DEFAULT_VALUE;
660 18 : }
661 : }
662 18 : break;
663 : case FN_UNO_CHARFMT_SEQUENCE:
664 : {
665 :
666 24 : SwTextNode *const pTextNode = rPam.GetNode().GetTextNode();
667 48 : if (&rPam.GetNode(true) == &rPam.GetNode(false)
668 24 : && pTextNode && pTextNode->GetpSwpHints())
669 : {
670 22 : sal_Int32 nPaMStart = rPam.GetPoint()->nContent.GetIndex();
671 22 : sal_Int32 nPaMEnd = rPam.GetMark() ? rPam.GetMark()->nContent.GetIndex() : nPaMStart;
672 22 : if(nPaMStart > nPaMEnd)
673 : {
674 20 : std::swap(nPaMStart, nPaMEnd);
675 : }
676 22 : Sequence< OUString> aCharStyles;
677 22 : SwpHints* pHints = pTextNode->GetpSwpHints();
678 101 : for( size_t nAttr = 0; nAttr < pHints->GetStartCount(); ++nAttr )
679 : {
680 79 : SwTextAttr* pAttr = pHints->GetStart( nAttr );
681 79 : if(pAttr->Which() != RES_TXTATR_CHARFMT)
682 47 : continue;
683 32 : const sal_Int32 nAttrStart = pAttr->GetStart();
684 32 : const sal_Int32 nAttrEnd = *pAttr->GetEnd();
685 : //check if the attribute touches the selection
686 32 : if( ( nAttrEnd > nPaMStart && nAttrStart < nPaMEnd ) ||
687 5 : ( !nAttrStart && !nAttrEnd && !nPaMStart && !nPaMEnd ) )
688 : {
689 : //check for overlapping
690 44 : if(nAttrStart > nPaMStart ||
691 22 : nAttrEnd < nPaMEnd)
692 : {
693 0 : aCharStyles.realloc(0);
694 0 : eNewState = PropertyState_AMBIGUOUS_VALUE;
695 0 : break;
696 : }
697 : else
698 : {
699 : //now the attribute should start before or at the selection
700 : //and it should end at the end of the selection or behind
701 : OSL_ENSURE(nAttrStart <= nPaMStart && nAttrEnd >=nPaMEnd,
702 : "attribute overlaps or is outside");
703 : //now the name of the style has to be added to the sequence
704 22 : aCharStyles.realloc(aCharStyles.getLength() + 1);
705 : OSL_ENSURE(pAttr->GetCharFormat().GetCharFormat(), "no character format set");
706 22 : aCharStyles.getArray()[aCharStyles.getLength() - 1] =
707 : SwStyleNameMapper::GetProgName(
708 44 : pAttr->GetCharFormat().GetCharFormat()->GetName(), nsSwGetPoolIdFromName::GET_POOLID_CHRFMT);
709 : }
710 : }
711 :
712 : }
713 : eNewState =
714 22 : aCharStyles.getLength() ?
715 22 : PropertyState_DIRECT_VALUE : PropertyState_DEFAULT_VALUE;
716 22 : if(pAny)
717 22 : (*pAny) <<= aCharStyles;
718 : }
719 : else
720 2 : eNewState = PropertyState_DEFAULT_VALUE;
721 : }
722 24 : break;
723 : case RES_TXTATR_CHARFMT:
724 : // no break here!
725 7238 : default: bDone = false;
726 : }
727 25207 : if( bDone )
728 17969 : eState = eNewState;
729 25207 : return bDone;
730 : };
731 :
732 36 : sal_Int16 IsNodeNumStart(SwPaM& rPam, PropertyState& eState)
733 : {
734 36 : const SwTextNode* pTextNd = rPam.GetNode().GetTextNode();
735 : // correction: check, if restart value is set at the text node and use
736 : // new method <SwTextNode::GetAttrListRestartValue()> to retrieve the value
737 36 : if ( pTextNd && pTextNd->GetNumRule() && pTextNd->IsListRestart() &&
738 0 : pTextNd->HasAttrListRestartValue() )
739 : {
740 0 : eState = PropertyState_DIRECT_VALUE;
741 0 : sal_Int16 nTmp = sal::static_int_cast< sal_Int16 >(pTextNd->GetAttrListRestartValue());
742 0 : return nTmp;
743 : }
744 36 : eState = PropertyState_DEFAULT_VALUE;
745 36 : return -1;
746 : }
747 :
748 2641 : void setNumberingProperty(const Any& rValue, SwPaM& rPam)
749 : {
750 2641 : uno::Reference<XIndexReplace> xIndexReplace;
751 2641 : if(rValue >>= xIndexReplace)
752 : {
753 2641 : SwXNumberingRules* pSwNum = 0;
754 :
755 2641 : uno::Reference<XUnoTunnel> xNumTunnel(xIndexReplace, UNO_QUERY);
756 2641 : if(xNumTunnel.is())
757 : {
758 : pSwNum = reinterpret_cast< SwXNumberingRules * >(
759 2641 : sal::static_int_cast< sal_IntPtr >( xNumTunnel->getSomething( SwXNumberingRules::getUnoTunnelId() )));
760 : }
761 :
762 2641 : if(pSwNum)
763 : {
764 2641 : SwDoc* pDoc = rPam.GetDoc();
765 2641 : if(pSwNum->GetNumRule())
766 : {
767 2469 : SwNumRule aRule(*pSwNum->GetNumRule());
768 2469 : const OUString* pNewCharStyles = pSwNum->GetNewCharStyleNames();
769 2469 : const OUString* pBulletFontNames = pSwNum->GetBulletFontNames();
770 27159 : for(sal_uInt16 i = 0; i < MAXLEVEL; i++)
771 : {
772 24690 : SwNumFormat aFormat(aRule.Get( i ));
773 109383 : if (!pNewCharStyles[i].isEmpty() &&
774 49380 : !SwXNumberingRules::isInvalidStyle(pNewCharStyles[i]) &&
775 24690 : (!aFormat.GetCharFormat() || pNewCharStyles[i] != aFormat.GetCharFormat()->GetName()))
776 : {
777 0 : if (pNewCharStyles[i].isEmpty())
778 : {
779 : // FIXME
780 : // Is something missing/wrong here?
781 : // if condition is always false due to outer check!
782 0 : aFormat.SetCharFormat(0);
783 : }
784 : else
785 : {
786 :
787 : // get CharStyle and set the rule
788 0 : const size_t nChCount = pDoc->GetCharFormats()->size();
789 0 : SwCharFormat* pCharFormat = 0;
790 0 : for(size_t nCharFormat = 0; nCharFormat < nChCount; ++nCharFormat)
791 : {
792 0 : SwCharFormat& rChFormat = *((*(pDoc->GetCharFormats()))[nCharFormat]);
793 0 : if(rChFormat.GetName() == pNewCharStyles[i])
794 : {
795 0 : pCharFormat = &rChFormat;
796 0 : break;
797 : }
798 : }
799 :
800 0 : if(!pCharFormat)
801 : {
802 0 : SfxStyleSheetBasePool* pPool = pDoc->GetDocShell()->GetStyleSheetPool();
803 : SfxStyleSheetBase* pBase;
804 0 : pBase = pPool->Find(pNewCharStyles[i], SFX_STYLE_FAMILY_CHAR);
805 : // shall it really be created?
806 0 : if(!pBase)
807 0 : pBase = &pPool->Make(pNewCharStyles[i], SFX_STYLE_FAMILY_PAGE);
808 0 : pCharFormat = static_cast<SwDocStyleSheet*>(pBase)->GetCharFormat();
809 : }
810 0 : if(pCharFormat)
811 0 : aFormat.SetCharFormat(pCharFormat);
812 : }
813 : }
814 : //Now again for fonts
815 24690 : if(
816 49380 : !pBulletFontNames[i].isEmpty() &&
817 24690 : !SwXNumberingRules::isInvalidStyle(pBulletFontNames[i]) &&
818 0 : (!aFormat.GetBulletFont() || aFormat.GetBulletFont()->GetName() != pBulletFontNames[i])
819 : )
820 : {
821 : const SvxFontListItem* pFontListItem =
822 0 : static_cast<const SvxFontListItem* >(pDoc->GetDocShell()
823 0 : ->GetItem( SID_ATTR_CHAR_FONTLIST ));
824 0 : const FontList* pList = pFontListItem->GetFontList();
825 :
826 : vcl::FontInfo aInfo = pList->Get(
827 0 : pBulletFontNames[i],WEIGHT_NORMAL, ITALIC_NONE);
828 0 : vcl::Font aFont(aInfo);
829 0 : aFormat.SetBulletFont(&aFont);
830 : }
831 24690 : aRule.Set( i, aFormat );
832 24690 : }
833 4938 : UnoActionContext aAction(pDoc);
834 :
835 2469 : if( rPam.GetNext() != &rPam ) // Multiple selection?
836 : {
837 0 : pDoc->GetIDocumentUndoRedo().StartUndo( UNDO_START, NULL );
838 0 : SwPamRanges aRangeArr( rPam );
839 0 : SwPaM aPam( *rPam.GetPoint() );
840 0 : for ( SwPamRanges::size_type n = 0; n < aRangeArr.Count(); ++n )
841 : {
842 : // no start of a new list
843 0 : pDoc->SetNumRule( aRangeArr.SetPam( n, aPam ), aRule, false );
844 : }
845 0 : pDoc->GetIDocumentUndoRedo().EndUndo( UNDO_END, NULL );
846 : }
847 : else
848 : {
849 : // no start of a new list
850 2469 : pDoc->SetNumRule( rPam, aRule, false );
851 2469 : }
852 :
853 : }
854 172 : else if(!pSwNum->GetCreatedNumRuleName().isEmpty())
855 : {
856 168 : UnoActionContext aAction( pDoc );
857 168 : SwNumRule* pRule = pDoc->FindNumRulePtr( pSwNum->GetCreatedNumRuleName() );
858 168 : if ( !pRule )
859 0 : throw RuntimeException();
860 : // no start of a new list
861 168 : pDoc->SetNumRule( rPam, *pRule, false );
862 : }
863 : else
864 : {
865 : // #i103817#
866 : // outline numbering
867 4 : UnoActionContext aAction(pDoc);
868 4 : SwNumRule* pRule = pDoc->GetOutlineNumRule();
869 4 : if(!pRule)
870 0 : throw RuntimeException();
871 4 : pDoc->SetNumRule( rPam, *pRule, false );
872 : }
873 2641 : }
874 : }
875 0 : else if ( rValue.getValueType() == cppu::UnoType<void>::get() )
876 : {
877 0 : rPam.GetDoc()->DelNumRules(rPam);
878 2641 : }
879 2641 : }
880 :
881 5854 : void getNumberingProperty(SwPaM& rPam, PropertyState& eState, Any * pAny )
882 : {
883 5854 : const SwNumRule* pNumRule = SwDoc::GetNumRuleAtPos( *rPam.GetPoint() );
884 5854 : if(pNumRule)
885 : {
886 151 : uno::Reference< XIndexReplace > xNum = new SwXNumberingRules(*pNumRule);
887 151 : if ( pAny )
888 151 : pAny->setValue(&xNum, cppu::UnoType<XIndexReplace>::get());
889 151 : eState = PropertyState_DIRECT_VALUE;
890 : }
891 : else
892 5703 : eState = PropertyState_DEFAULT_VALUE;
893 5854 : }
894 :
895 164 : void GetCurPageStyle(SwPaM& rPaM, OUString &rString)
896 : {
897 164 : if (!rPaM.GetContentNode())
898 166 : return; // TODO: is there an easy way to get it for tables/sections?
899 162 : SwContentFrm* pFrame = rPaM.GetContentNode()->getLayoutFrm(rPaM.GetDoc()->getIDocumentLayoutAccess().GetCurrentLayout());
900 162 : if(pFrame)
901 : {
902 57 : const SwPageFrm* pPage = pFrame->FindPageFrm();
903 57 : if(pPage)
904 : {
905 : SwStyleNameMapper::FillProgName(pPage->GetPageDesc()->GetName(),
906 57 : rString, nsSwGetPoolIdFromName::GET_POOLID_PAGEDESC, true);
907 : }
908 : }
909 : }
910 :
911 : // reset special properties of the cursor
912 0 : void resetCrsrPropertyValue(const SfxItemPropertySimpleEntry& rEntry, SwPaM& rPam)
913 : {
914 0 : SwDoc* pDoc = rPam.GetDoc();
915 0 : switch(rEntry.nWID)
916 : {
917 : case FN_UNO_PARA_STYLE :
918 0 : break;
919 : case FN_UNO_PAGE_STYLE :
920 0 : break;
921 : case FN_UNO_NUM_START_VALUE :
922 : {
923 0 : UnoActionContext aAction(pDoc);
924 :
925 0 : if( rPam.GetNext() != &rPam ) // Multiple selection?
926 : {
927 0 : pDoc->GetIDocumentUndoRedo().StartUndo( UNDO_START, NULL );
928 0 : SwPamRanges aRangeArr( rPam );
929 0 : SwPaM aPam( *rPam.GetPoint() );
930 0 : for( SwPamRanges::size_type n = 0; n < aRangeArr.Count(); ++n )
931 0 : pDoc->SetNodeNumStart( *aRangeArr.SetPam( n, aPam ).GetPoint(), 1 );
932 0 : pDoc->GetIDocumentUndoRedo().EndUndo( UNDO_END, NULL );
933 : }
934 : else
935 0 : pDoc->SetNodeNumStart( *rPam.GetPoint(), 0 );
936 : }
937 :
938 0 : break;
939 : case FN_UNO_NUM_LEVEL :
940 0 : break;
941 : case FN_UNO_NUM_RULES:
942 0 : break;
943 : case FN_UNO_CHARFMT_SEQUENCE:
944 : {
945 0 : std::set<sal_uInt16> aWhichIds;
946 0 : aWhichIds.insert( RES_TXTATR_CHARFMT);
947 0 : pDoc->ResetAttrs(rPam, true, aWhichIds);
948 : }
949 0 : break;
950 : }
951 0 : }
952 :
953 0 : void InsertFile(SwUnoCrsr* pUnoCrsr, const OUString& rURL,
954 : const uno::Sequence< beans::PropertyValue >& rOptions)
955 : throw (lang::IllegalArgumentException, io::IOException,
956 : uno::RuntimeException, std::exception)
957 : {
958 0 : SfxMedium* pMed = 0;
959 0 : SwDoc* pDoc = pUnoCrsr->GetDoc();
960 0 : SwDocShell* pDocSh = pDoc->GetDocShell();
961 0 : utl::MediaDescriptor aMediaDescriptor( rOptions );
962 0 : OUString sFileName = rURL;
963 0 : OUString sFilterName, sFilterOptions, sPassword, sBaseURL;
964 0 : uno::Reference < io::XStream > xStream;
965 0 : uno::Reference < io::XInputStream > xInputStream;
966 :
967 0 : if( sFileName.isEmpty() )
968 0 : aMediaDescriptor[utl::MediaDescriptor::PROP_URL()] >>= sFileName;
969 0 : if( sFileName.isEmpty() )
970 0 : aMediaDescriptor[utl::MediaDescriptor::PROP_FILENAME()] >>= sFileName;
971 0 : aMediaDescriptor[utl::MediaDescriptor::PROP_INPUTSTREAM()] >>= xInputStream;
972 0 : aMediaDescriptor[utl::MediaDescriptor::PROP_STREAM()] >>= xStream;
973 0 : aMediaDescriptor[utl::MediaDescriptor::PROP_INPUTSTREAM()] >>= xInputStream;
974 0 : aMediaDescriptor[utl::MediaDescriptor::PROP_FILTERNAME()] >>= sFilterName;
975 0 : aMediaDescriptor[utl::MediaDescriptor::PROP_FILTEROPTIONS()] >>= sFilterOptions;
976 0 : aMediaDescriptor[utl::MediaDescriptor::PROP_PASSWORD()] >>= sPassword;
977 0 : aMediaDescriptor[utl::MediaDescriptor::PROP_DOCUMENTBASEURL() ] >>= sBaseURL;
978 0 : if ( !xInputStream.is() && xStream.is() )
979 0 : xInputStream = xStream->getInputStream();
980 :
981 0 : if(!pDocSh || (sFileName.isEmpty() && !xInputStream.is()))
982 0 : return;
983 :
984 0 : SfxObjectFactory& rFact = pDocSh->GetFactory();
985 0 : const SfxFilter* pFilter = rFact.GetFilterContainer()->GetFilter4FilterName( sFilterName );
986 0 : uno::Reference < embed::XStorage > xReadStorage;
987 0 : if( xInputStream.is() )
988 : {
989 0 : uno::Sequence< uno::Any > aArgs( 2 );
990 0 : aArgs[0] <<= xInputStream;
991 0 : aArgs[1] <<= embed::ElementModes::READ;
992 : try
993 : {
994 0 : xReadStorage = uno::Reference< embed::XStorage >(
995 0 : ::comphelper::OStorageHelper::GetStorageFactory()->createInstanceWithArguments( aArgs ),
996 0 : uno::UNO_QUERY );
997 : }
998 0 : catch( const io::IOException& rEx)
999 : {
1000 : (void)rEx;
1001 0 : }
1002 : }
1003 0 : if ( !pFilter )
1004 : {
1005 0 : if( xInputStream.is() && !xReadStorage.is())
1006 : {
1007 0 : pMed = new SfxMedium;
1008 0 : pMed->setStreamToLoadFrom(xInputStream, true );
1009 : }
1010 : else
1011 0 : pMed = xReadStorage.is() ?
1012 0 : new SfxMedium(xReadStorage, sBaseURL, 0 ) :
1013 0 : new SfxMedium(sFileName, StreamMode::READ, 0, 0 );
1014 0 : if( !sBaseURL.isEmpty() )
1015 0 : pMed->GetItemSet()->Put( SfxStringItem( SID_DOC_BASEURL, sBaseURL ) );
1016 :
1017 0 : SfxFilterMatcher aMatcher( rFact.GetFilterContainer()->GetName() );
1018 0 : ErrCode nErr = aMatcher.GuessFilter(*pMed, &pFilter, SfxFilterFlags::NONE);
1019 0 : if ( nErr || !pFilter)
1020 0 : DELETEZ(pMed);
1021 : else
1022 0 : pMed->SetFilter( pFilter );
1023 : }
1024 : else
1025 : {
1026 0 : if(!pMed)
1027 : {
1028 0 : if( xInputStream.is() && !xReadStorage.is())
1029 : {
1030 0 : pMed = new SfxMedium;
1031 0 : pMed->setStreamToLoadFrom(xInputStream, true );
1032 0 : pMed->SetFilter( pFilter );
1033 : }
1034 : else
1035 : {
1036 0 : if( xReadStorage.is() )
1037 : {
1038 0 : pMed = new SfxMedium(xReadStorage, sBaseURL, 0 );
1039 0 : pMed->SetFilter( pFilter );
1040 : }
1041 : else
1042 0 : pMed = new SfxMedium(sFileName, StreamMode::READ, pFilter, 0);
1043 : }
1044 : }
1045 0 : if(!sFilterOptions.isEmpty())
1046 0 : pMed->GetItemSet()->Put( SfxStringItem( SID_FILE_FILTEROPTIONS, sFilterOptions ) );
1047 0 : if(!sBaseURL.isEmpty())
1048 0 : pMed->GetItemSet()->Put( SfxStringItem( SID_DOC_BASEURL, sBaseURL ) );
1049 : }
1050 :
1051 0 : if( !pMed )
1052 0 : return;
1053 :
1054 : // this sourcecode is not responsible for the lifetime of the shell, SfxObjectShellLock should not be used
1055 0 : SfxObjectShellRef aRef( pDocSh );
1056 :
1057 0 : pMed->Download(); // if necessary: start the download
1058 0 : if( aRef.Is() && 1 < aRef->GetRefCount() ) // Ref still valid?
1059 : {
1060 : SwReader* pRdr;
1061 0 : SfxItemSet* pSet = pMed->GetItemSet();
1062 0 : pSet->Put(SfxBoolItem(FN_API_CALL, true));
1063 0 : if(!sPassword.isEmpty())
1064 0 : pSet->Put(SfxStringItem(SID_PASSWORD, sPassword));
1065 0 : Reader *pRead = pDocSh->StartConvertFrom( *pMed, &pRdr, 0, pUnoCrsr);
1066 0 : if( pRead )
1067 : {
1068 :
1069 0 : UnoActionContext aContext(pDoc);
1070 :
1071 0 : if(pUnoCrsr->HasMark())
1072 0 : pDoc->getIDocumentContentOperations().DeleteAndJoin(*pUnoCrsr);
1073 :
1074 0 : SwNodeIndex aSave( pUnoCrsr->GetPoint()->nNode, -1 );
1075 0 : sal_Int32 nContent = pUnoCrsr->GetPoint()->nContent.GetIndex();
1076 :
1077 0 : sal_uInt32 nErrno = pRdr->Read( *pRead ); // and paste the document
1078 :
1079 0 : if(!nErrno)
1080 : {
1081 0 : ++aSave;
1082 0 : pUnoCrsr->SetMark();
1083 0 : pUnoCrsr->GetMark()->nNode = aSave;
1084 :
1085 0 : SwContentNode* pCntNode = aSave.GetNode().GetContentNode();
1086 0 : if( !pCntNode )
1087 0 : nContent = 0;
1088 0 : pUnoCrsr->GetMark()->nContent.Assign( pCntNode, nContent );
1089 : }
1090 :
1091 0 : delete pRdr;
1092 :
1093 : }
1094 : }
1095 0 : delete pMed;
1096 : }
1097 :
1098 : // insert text and scan for CR characters in order to insert
1099 : // paragraph breaks at those positions by calling SplitNode
1100 83808 : bool DocInsertStringSplitCR(
1101 : SwDoc &rDoc,
1102 : const SwPaM &rNewCursor,
1103 : const OUString &rText,
1104 : const bool bForceExpandHints )
1105 : {
1106 83808 : bool bOK = true;
1107 :
1108 : const SwInsertFlags nInsertFlags =
1109 : bForceExpandHints
1110 83860 : ? ( SwInsertFlags::FORCEHINTEXPAND | SwInsertFlags::EMPTYEXPAND)
1111 167616 : : SwInsertFlags::EMPTYEXPAND;
1112 :
1113 : // grouping done in InsertString is intended for typing, not API calls
1114 83808 : ::sw::GroupUndoGuard const undoGuard(rDoc.GetIDocumentUndoRedo());
1115 : SwTextNode* const pTextNd =
1116 83808 : rNewCursor.GetPoint()->nNode.GetNode().GetTextNode();
1117 83808 : if (!pTextNd)
1118 : {
1119 : SAL_INFO("sw.uno", "DocInsertStringSplitCR: need a text node");
1120 0 : return false;
1121 : }
1122 167616 : OUString aText;
1123 83808 : sal_Int32 nStartIdx = 0;
1124 83808 : const sal_Int32 nMaxLength = COMPLETE_STRING - pTextNd->GetText().getLength();
1125 :
1126 83808 : sal_Int32 nIdx = rText.indexOf( '\r', nStartIdx );
1127 83808 : if( ( nIdx == -1 && nMaxLength < rText.getLength() ) ||
1128 0 : ( nIdx != -1 && nMaxLength < nIdx ) )
1129 : {
1130 0 : nIdx = nMaxLength;
1131 : }
1132 167616 : while (nIdx != -1 )
1133 : {
1134 : OSL_ENSURE( nIdx - nStartIdx >= 0, "index negative!" );
1135 0 : aText = rText.copy( nStartIdx, nIdx - nStartIdx );
1136 0 : if (!aText.isEmpty() &&
1137 0 : !rDoc.getIDocumentContentOperations().InsertString( rNewCursor, aText, nInsertFlags ))
1138 : {
1139 : OSL_FAIL( "Doc->Insert(Str) failed." );
1140 0 : bOK = false;
1141 : }
1142 0 : if (!rDoc.getIDocumentContentOperations().SplitNode( *rNewCursor.GetPoint(), false ) )
1143 : {
1144 : OSL_FAIL( "SplitNode failed" );
1145 0 : bOK = false;
1146 : }
1147 0 : nStartIdx = nIdx + 1;
1148 0 : nIdx = rText.indexOf( '\r', nStartIdx );
1149 : }
1150 83808 : aText = rText.copy( nStartIdx );
1151 167101 : if (!aText.isEmpty() &&
1152 83293 : !rDoc.getIDocumentContentOperations().InsertString( rNewCursor, aText, nInsertFlags ))
1153 : {
1154 : OSL_FAIL( "Doc->Insert(Str) failed." );
1155 0 : bOK = false;
1156 : }
1157 :
1158 167616 : return bOK;
1159 : }
1160 :
1161 1447 : void makeRedline( SwPaM& rPaM,
1162 : const OUString& rRedlineType,
1163 : const uno::Sequence< beans::PropertyValue >& rRedlineProperties )
1164 : throw (lang::IllegalArgumentException, uno::RuntimeException)
1165 : {
1166 1447 : IDocumentRedlineAccess* pRedlineAccess = &rPaM.GetDoc()->getIDocumentRedlineAccess();
1167 :
1168 : RedlineType_t eType;
1169 1447 : if ( rRedlineType == "Insert" )
1170 73 : eType = nsRedlineType_t::REDLINE_INSERT;
1171 1374 : else if ( rRedlineType == "Delete" )
1172 432 : eType = nsRedlineType_t::REDLINE_DELETE;
1173 942 : else if ( rRedlineType == "Format" )
1174 461 : eType = nsRedlineType_t::REDLINE_FORMAT;
1175 481 : else if ( rRedlineType == "TextTable" )
1176 0 : eType = nsRedlineType_t::REDLINE_TABLE;
1177 481 : else if ( rRedlineType == "ParagraphFormat" )
1178 481 : eType = nsRedlineType_t::REDLINE_PARAGRAPH_FORMAT;
1179 : else
1180 0 : throw lang::IllegalArgumentException();
1181 :
1182 : //todo: what about REDLINE_FMTCOLL?
1183 1447 : comphelper::SequenceAsHashMap aPropMap( rRedlineProperties );
1184 2894 : uno::Any aAuthorValue;
1185 1447 : aAuthorValue = aPropMap.getUnpackedValueOrDefault("RedlineAuthor", aAuthorValue);
1186 1447 : sal_uInt16 nAuthor = 0;
1187 2894 : OUString sAuthor;
1188 1447 : if( aAuthorValue >>= sAuthor )
1189 1447 : nAuthor = pRedlineAccess->InsertRedlineAuthor(sAuthor);
1190 :
1191 2894 : OUString sComment;
1192 2894 : uno::Any aCommentValue;
1193 1447 : aCommentValue = aPropMap.getUnpackedValueOrDefault("RedlineComment", aCommentValue);
1194 :
1195 2894 : SwRedlineData aRedlineData( eType, nAuthor );
1196 1447 : if( aCommentValue >>= sComment )
1197 0 : aRedlineData.SetComment( sComment );
1198 :
1199 1447 : ::util::DateTime aStamp;
1200 2894 : uno::Any aDateTimeValue;
1201 1447 : aDateTimeValue = aPropMap.getUnpackedValueOrDefault("RedlineDateTime", aDateTimeValue);
1202 1447 : if( aDateTimeValue >>= aStamp )
1203 : {
1204 : aRedlineData.SetTimeStamp(
1205 1447 : DateTime( Date( aStamp.Day, aStamp.Month, aStamp.Year ), tools::Time( aStamp.Hours, aStamp.Minutes, aStamp.Seconds ) ) );
1206 : }
1207 :
1208 1447 : SwRedlineExtraData_FormattingChanges* pRedlineExtraData = NULL;
1209 :
1210 : // Read the 'Redline Revert Properties' from the parameters
1211 2894 : uno::Sequence< beans::PropertyValue > aRevertProperties;
1212 2894 : uno::Any aRevertPropertiesValue;
1213 1447 : aRevertPropertiesValue = aPropMap.getUnpackedValueOrDefault("RedlineRevertProperties", aRevertPropertiesValue);
1214 :
1215 : // Check if the value exists
1216 1447 : if ( aRevertPropertiesValue >>= aRevertProperties )
1217 : {
1218 1447 : int nMap = 0;
1219 : // Make sure that paragraph format gets its own map, otherwise e.g. fill attributes are not preserved.
1220 1447 : if (eType == nsRedlineType_t::REDLINE_PARAGRAPH_FORMAT)
1221 481 : nMap = PROPERTY_MAP_PARAGRAPH;
1222 : else
1223 966 : nMap = PROPERTY_MAP_TEXTPORTION_EXTENSIONS;
1224 1447 : SfxItemPropertySet const& rPropSet = (*aSwMapProvider.GetPropertySet(nMap));
1225 :
1226 : // Check if there are any properties
1227 1447 : if (aRevertProperties.getLength())
1228 : {
1229 803 : SwDoc *const pDoc = rPaM.GetDoc();
1230 1606 : OUString aUnknownExMsg, aPropertyVetoExMsg;
1231 :
1232 : // Build set of attributes we want to fetch
1233 1606 : std::vector<sal_uInt16> aWhichPairs;
1234 1606 : std::vector<SfxItemPropertySimpleEntry const*> aEntries;
1235 803 : aEntries.reserve(aRevertProperties.getLength());
1236 7750 : for (sal_Int32 i = 0; i < aRevertProperties.getLength(); ++i)
1237 : {
1238 3072 : const OUString &rPropertyName = aRevertProperties[i].Name;
1239 3072 : SfxItemPropertySimpleEntry const* pEntry = rPropSet.getPropertyMap().getByName(rPropertyName);
1240 :
1241 : // Queue up any exceptions until the end ...
1242 3072 : if (!pEntry)
1243 : {
1244 0 : aUnknownExMsg += "Unknown property: '" + rPropertyName + "' ";
1245 0 : break;
1246 : }
1247 3072 : else if (pEntry->nFlags & beans::PropertyAttribute::READONLY)
1248 : {
1249 0 : aPropertyVetoExMsg += "Property is read-only: '" + rPropertyName + "' ";
1250 0 : break;
1251 : }
1252 : else
1253 : {
1254 : // FIXME: we should have some nice way of merging ranges surely ?
1255 3072 : aWhichPairs.push_back(pEntry->nWID);
1256 3072 : aWhichPairs.push_back(pEntry->nWID);
1257 : }
1258 3072 : aEntries.push_back(pEntry);
1259 : }
1260 :
1261 803 : if (!aWhichPairs.empty())
1262 : {
1263 803 : aWhichPairs.push_back(0); // terminate
1264 803 : SfxItemSet aItemSet(pDoc->GetAttrPool(), &aWhichPairs[0]);
1265 :
1266 3875 : for (size_t i = 0; i < aEntries.size(); ++i)
1267 : {
1268 3072 : SfxItemPropertySimpleEntry const*const pEntry = aEntries[i];
1269 3072 : const uno::Any &rValue = aRevertProperties[i].Value;
1270 3072 : rPropSet.setPropertyValue(*pEntry, rValue, aItemSet);
1271 : }
1272 803 : pRedlineExtraData = new SwRedlineExtraData_FormattingChanges( &aItemSet );
1273 803 : }
1274 : }
1275 : }
1276 :
1277 1447 : SwRangeRedline* pRedline = new SwRangeRedline( aRedlineData, rPaM );
1278 1447 : RedlineMode_t nPrevMode = pRedlineAccess->GetRedlineMode( );
1279 1447 : pRedline->SetExtraData( pRedlineExtraData );
1280 :
1281 1447 : pRedlineAccess->SetRedlineMode_intern(nsRedlineMode_t::REDLINE_ON);
1282 1447 : bool bRet = pRedlineAccess->AppendRedline( pRedline, false );
1283 1447 : pRedlineAccess->SetRedlineMode_intern( nPrevMode );
1284 1447 : if( !bRet )
1285 1449 : throw lang::IllegalArgumentException();
1286 1445 : }
1287 :
1288 28 : void makeTableRowRedline( SwTableLine& rTableLine,
1289 : const OUString& rRedlineType,
1290 : const uno::Sequence< beans::PropertyValue >& rRedlineProperties )
1291 : throw (lang::IllegalArgumentException, uno::RuntimeException)
1292 : {
1293 28 : IDocumentRedlineAccess* pRedlineAccess = &rTableLine.GetFrameFormat()->GetDoc()->getIDocumentRedlineAccess();
1294 :
1295 : RedlineType_t eType;
1296 28 : if ( rRedlineType == "TableRowInsert" )
1297 : {
1298 3 : eType = nsRedlineType_t::REDLINE_TABLE_ROW_INSERT;
1299 : }
1300 25 : else if ( rRedlineType == "TableRowDelete" )
1301 : {
1302 25 : eType = nsRedlineType_t::REDLINE_TABLE_ROW_DELETE;
1303 : }
1304 : else
1305 : {
1306 0 : throw lang::IllegalArgumentException();
1307 : }
1308 :
1309 28 : comphelper::SequenceAsHashMap aPropMap( rRedlineProperties );
1310 56 : uno::Any aAuthorValue;
1311 28 : aAuthorValue = aPropMap.getUnpackedValueOrDefault("RedlineAuthor", aAuthorValue);
1312 28 : sal_uInt16 nAuthor = 0;
1313 56 : OUString sAuthor;
1314 28 : if( aAuthorValue >>= sAuthor )
1315 28 : nAuthor = pRedlineAccess->InsertRedlineAuthor(sAuthor);
1316 :
1317 56 : OUString sComment;
1318 56 : uno::Any aCommentValue;
1319 28 : aCommentValue = aPropMap.getUnpackedValueOrDefault("RedlineComment", aCommentValue);
1320 :
1321 56 : SwRedlineData aRedlineData( eType, nAuthor );
1322 28 : if( aCommentValue >>= sComment )
1323 0 : aRedlineData.SetComment( sComment );
1324 :
1325 28 : ::util::DateTime aStamp;
1326 56 : uno::Any aDateTimeValue;
1327 28 : aDateTimeValue = aPropMap.getUnpackedValueOrDefault("RedlineDateTime", aDateTimeValue);
1328 28 : if( aDateTimeValue >>= aStamp )
1329 : {
1330 : aRedlineData.SetTimeStamp(
1331 28 : DateTime( Date( aStamp.Day, aStamp.Month, aStamp.Year ), tools::Time( aStamp.Hours, aStamp.Minutes, aStamp.Seconds ) ) );
1332 : }
1333 :
1334 28 : SwTableRowRedline* pRedline = new SwTableRowRedline( aRedlineData, rTableLine );
1335 28 : RedlineMode_t nPrevMode = pRedlineAccess->GetRedlineMode( );
1336 28 : pRedline->SetExtraData( NULL );
1337 :
1338 28 : pRedlineAccess->SetRedlineMode_intern(nsRedlineMode_t::REDLINE_ON);
1339 28 : bool bRet = pRedlineAccess->AppendTableRowRedline( pRedline, false );
1340 28 : pRedlineAccess->SetRedlineMode_intern( nPrevMode );
1341 28 : if( !bRet )
1342 28 : throw lang::IllegalArgumentException();
1343 28 : }
1344 :
1345 6 : void makeTableCellRedline( SwTableBox& rTableBox,
1346 : const OUString& rRedlineType,
1347 : const uno::Sequence< beans::PropertyValue >& rRedlineProperties )
1348 : throw (lang::IllegalArgumentException, uno::RuntimeException)
1349 : {
1350 6 : IDocumentRedlineAccess* pRedlineAccess = &rTableBox.GetFrameFormat()->GetDoc()->getIDocumentRedlineAccess();
1351 :
1352 : RedlineType_t eType;
1353 6 : if ( rRedlineType == "TableCellInsert" )
1354 : {
1355 3 : eType = nsRedlineType_t::REDLINE_TABLE_CELL_INSERT;
1356 : }
1357 3 : else if ( rRedlineType == "TableCellDelete" )
1358 : {
1359 3 : eType = nsRedlineType_t::REDLINE_TABLE_CELL_DELETE;
1360 : }
1361 : else
1362 : {
1363 0 : throw lang::IllegalArgumentException();
1364 : }
1365 :
1366 6 : comphelper::SequenceAsHashMap aPropMap( rRedlineProperties );
1367 12 : uno::Any aAuthorValue;
1368 6 : aAuthorValue = aPropMap.getUnpackedValueOrDefault("RedlineAuthor", aAuthorValue);
1369 6 : sal_uInt16 nAuthor = 0;
1370 12 : OUString sAuthor;
1371 6 : if( aAuthorValue >>= sAuthor )
1372 6 : nAuthor = pRedlineAccess->InsertRedlineAuthor(sAuthor);
1373 :
1374 12 : OUString sComment;
1375 12 : uno::Any aCommentValue;
1376 6 : aCommentValue = aPropMap.getUnpackedValueOrDefault("RedlineComment", aCommentValue);
1377 :
1378 12 : SwRedlineData aRedlineData( eType, nAuthor );
1379 6 : if( aCommentValue >>= sComment )
1380 0 : aRedlineData.SetComment( sComment );
1381 :
1382 6 : ::util::DateTime aStamp;
1383 12 : uno::Any aDateTimeValue;
1384 6 : aDateTimeValue = aPropMap.getUnpackedValueOrDefault("RedlineDateTime", aDateTimeValue);
1385 6 : if( aDateTimeValue >>= aStamp )
1386 : {
1387 : aRedlineData.SetTimeStamp(
1388 6 : DateTime( Date( aStamp.Day, aStamp.Month, aStamp.Year ), tools::Time( aStamp.Hours, aStamp.Minutes, aStamp.Seconds ) ) );
1389 : }
1390 :
1391 6 : SwTableCellRedline* pRedline = new SwTableCellRedline( aRedlineData, rTableBox );
1392 6 : RedlineMode_t nPrevMode = pRedlineAccess->GetRedlineMode( );
1393 6 : pRedline->SetExtraData( NULL );
1394 :
1395 6 : pRedlineAccess->SetRedlineMode_intern(nsRedlineMode_t::REDLINE_ON);
1396 6 : bool bRet = pRedlineAccess->AppendTableCellRedline( pRedline, false );
1397 6 : pRedlineAccess->SetRedlineMode_intern( nPrevMode );
1398 6 : if( !bRet )
1399 6 : throw lang::IllegalArgumentException();
1400 6 : }
1401 :
1402 22994 : void SwAnyMapHelper::SetValue( sal_uInt16 nWhichId, sal_uInt16 nMemberId, const uno::Any& rAny )
1403 : {
1404 22994 : sal_uInt32 nKey = (nWhichId << 16) + nMemberId;
1405 22994 : auto aIt = maMap.find( nKey );
1406 22994 : if( aIt != maMap.end() )
1407 1088 : *(aIt->second) = rAny;
1408 : else
1409 21906 : maMap.insert( nKey, new uno::Any(rAny) );
1410 22994 : }
1411 :
1412 180833 : bool SwAnyMapHelper::FillValue( sal_uInt16 nWhichId, sal_uInt16 nMemberId, const uno::Any*& pAny )
1413 : {
1414 180833 : bool bRet = false;
1415 180833 : sal_uInt32 nKey = (nWhichId << 16) + nMemberId;
1416 180833 : auto aIt = maMap.find( nKey );
1417 180833 : if( aIt != maMap.end() )
1418 : {
1419 23180 : pAny = aIt->second;
1420 23180 : bRet = true;
1421 : }
1422 180833 : return bRet;
1423 : }
1424 :
1425 177 : }//namespace SwUnoCursorHelper
1426 :
1427 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|