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