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