1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26
27 #include <hintids.hxx>
28 #include <rtl/logfile.hxx>
29 #include <vcl/outdev.hxx>
30 #include <sfx2/printer.hxx>
31 #include <editeng/eeitem.hxx>
32 #include <editeng/flditem.hxx>
33 #include <editeng/editeng.hxx>
34 #include <svx/svdoutl.hxx>
35 #include <editeng/colritem.hxx>
36 #include <svx/svdpage.hxx>
37 #include <svx/svdogrp.hxx>
38 #include <editeng/langitem.hxx>
39 #include <editeng/unolingu.hxx>
40 #include <editeng/measfld.hxx>
41 #include <svx/svdpool.hxx>
42 #include <fmtanchr.hxx>
43 #include <charatr.hxx>
44 #include <frmfmt.hxx>
45 #include <charfmt.hxx>
46 #include <viewimp.hxx>
47 #include <swhints.hxx>
48 #include <doc.hxx>
49 #include <IDocumentUndoRedo.hxx>
50 #include <docsh.hxx>
51 #include <rootfrm.hxx> //Damit der RootDtor gerufen wird.
52 #include <poolfmt.hxx>
53 #include <viewsh.hxx> // fuer MakeDrawView
54 #include <drawdoc.hxx>
55 #include <UndoDraw.hxx>
56 #include <swundo.hxx> // fuer die UndoIds
57 #include <dcontact.hxx>
58 #include <dview.hxx>
59 #include <mvsave.hxx>
60 #include <flyfrm.hxx>
61 #include <dflyobj.hxx>
62 #include <svx/svdetc.hxx>
63 #include <editeng/fhgtitem.hxx>
64 #include <svx/svdpagv.hxx>
65 #include <dcontact.hxx>
66 #include <txtfrm.hxx>
67 #include <frmfmt.hxx>
68 #include <editeng/frmdiritem.hxx>
69 #include <fmtornt.hxx>
70 #include <svx/svditer.hxx>
71 #include <vector>
72 #include <switerator.hxx>
73
74 using namespace ::com::sun::star;
75 using namespace ::com::sun::star::linguistic2;
76
77
SV_IMPL_VARARR_SORT(_ZSortFlys,_ZSortFly)78 SV_IMPL_VARARR_SORT( _ZSortFlys, _ZSortFly )
79
80 /*************************************************************************
81 |*
82 |* SwDoc::GroupSelection / SwDoc::UnGroupSelection
83 |*
84 |* Ersterstellung JP 21.08.95
85 |* Letzte Aenderung JP 21.08.95
86 |*
87 |*************************************************************************/
88 // OD 2004-04-01 #i26791# - local method to determine positioning and
89 // alignment attributes for a drawing object, which is newly connected to
90 // the layout. Used for a newly formed group object <SwDoc::GroupSelection(..)>
91 // and the members of a destroyed group <SwDoc::UnGroupSelection(..)>
92 void lcl_AdjustPositioningAttr( SwDrawFrmFmt* _pFrmFmt,
93 const SdrObject& _rSdrObj )
94 {
95 const SwContact* pContact = GetUserCall( &_rSdrObj );
96 ASSERT( pContact, "<lcl_AdjustPositioningAttr(..)> - missing contact object." );
97
98 // determine position of new group object relative to its anchor frame position
99 SwTwips nHoriRelPos = 0;
100 SwTwips nVertRelPos = 0;
101 {
102 const SwFrm* pAnchorFrm = pContact->GetAnchoredObj( &_rSdrObj )->GetAnchorFrm();
103 ASSERT( !pAnchorFrm ||
104 !pAnchorFrm->IsTxtFrm() ||
105 !static_cast<const SwTxtFrm*>(pAnchorFrm)->IsFollow(),
106 "<lcl_AdjustPositioningAttr(..)> - anchor frame is a follow. Please inform OD." );
107 bool bVert = false;
108 bool bR2L = false;
109 // --> OD 2005-05-10 #i45952# - use anchor position of
110 // anchor frame, if it exist.
111 Point aAnchorPos;
112 if ( pAnchorFrm )
113 {
114 // --> OD 2005-05-10 #i45952#
115 aAnchorPos = pAnchorFrm->GetFrmAnchorPos( ::HasWrap( &_rSdrObj ) );
116 // <--
117 bVert = pAnchorFrm->IsVertical();
118 bR2L = pAnchorFrm->IsRightToLeft();
119 }
120 else
121 {
122 // --> OD 2005-05-10 #i45952#
123 aAnchorPos = _rSdrObj.GetAnchorPos();
124 // <--
125 // If no anchor frame exist - e.g. because no layout exists - the
126 // default layout direction is taken.
127 const SvxFrameDirectionItem* pDirItem =
128 static_cast<const SvxFrameDirectionItem*>(&(_pFrmFmt->GetAttrSet().GetPool()->GetDefaultItem( RES_FRAMEDIR )));
129 switch ( pDirItem->GetValue() )
130 {
131 case FRMDIR_VERT_TOP_LEFT:
132 {
133 // vertical from left-to-right - Badaa: supported now!
134 bVert = true;
135 bR2L = true;
136 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
137 //ASSERT( false, "<lcl_AdjustPositioningAttr(..)> - vertical from left-to-right not supported." );
138 //End
139 }
140 break;
141 case FRMDIR_VERT_TOP_RIGHT:
142 {
143 // vertical from right-to-left
144 bVert = true;
145 bR2L = false;
146 }
147 break;
148 case FRMDIR_HORI_RIGHT_TOP:
149 {
150 // horizontal from right-to-left
151 bVert = false;
152 bR2L = true;
153 }
154 break;
155 case FRMDIR_HORI_LEFT_TOP:
156 {
157 // horizontal from left-to-right
158 bVert = false;
159 bR2L = false;
160 }
161 break;
162 }
163
164 }
165 // use geometry of drawing object
166 const SwRect aObjRect = _rSdrObj.GetSnapRect();
167
168 if ( bVert )
169 {
170 if ( bR2L ) {
171 //FRMDIR_VERT_TOP_LEFT
172 nHoriRelPos = aObjRect.Left() - aAnchorPos.X();
173 nVertRelPos = aObjRect.Top() - aAnchorPos.Y();
174 } else {
175 //FRMDIR_VERT_TOP_RIGHT
176 nHoriRelPos = aObjRect.Top() - aAnchorPos.Y();
177 nVertRelPos = aAnchorPos.X() - aObjRect.Right();
178 }
179 }
180 else if ( bR2L )
181 {
182 nHoriRelPos = aAnchorPos.X() - aObjRect.Right();
183 nVertRelPos = aObjRect.Top() - aAnchorPos.Y();
184 }
185 else
186 {
187 nHoriRelPos = aObjRect.Left() - aAnchorPos.X();
188 nVertRelPos = aObjRect.Top() - aAnchorPos.Y();
189 }
190 //End of SCMS
191 }
192
193 _pFrmFmt->SetFmtAttr( SwFmtHoriOrient( nHoriRelPos, text::HoriOrientation::NONE, text::RelOrientation::FRAME ) );
194 _pFrmFmt->SetFmtAttr( SwFmtVertOrient( nVertRelPos, text::VertOrientation::NONE, text::RelOrientation::FRAME ) );
195 // --> OD 2005-03-11 #i44334#, #i44681# - positioning attributes already set
196 _pFrmFmt->PosAttrSet();
197 // <--
198 // --> OD 2004-10-01 #i34750# - keep current object rectangle for drawing
199 // objects. The object rectangle is used on events from the drawing layer
200 // to adjust the positioning attributes - see <SwDrawContact::_Changed(..)>.
201 {
202 const SwAnchoredObject* pAnchoredObj = pContact->GetAnchoredObj( &_rSdrObj );
203 if ( pAnchoredObj->ISA(SwAnchoredDrawObject) )
204 {
205 const SwAnchoredDrawObject* pAnchoredDrawObj =
206 static_cast<const SwAnchoredDrawObject*>(pAnchoredObj);
207 const SwRect aObjRect = _rSdrObj.GetSnapRect();
208 const_cast<SwAnchoredDrawObject*>(pAnchoredDrawObj)
209 ->SetLastObjRect( aObjRect.SVRect() );
210 }
211 }
212 // <--
213 }
214
GroupSelection(SdrView & rDrawView)215 SwDrawContact* SwDoc::GroupSelection( SdrView& rDrawView )
216 {
217 // OD 30.06.2003 #108784# - replace marked 'virtual' drawing objects by
218 // the corresponding 'master' drawing objects.
219 SwDrawView::ReplaceMarkedDrawVirtObjs( rDrawView );
220
221 const SdrMarkList &rMrkList = rDrawView.GetMarkedObjectList();
222 SwDrawFrmFmt *pFmt = 0L;
223 SdrObject *pObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj();
224 sal_Bool bNoGroup = ( 0 == pObj->GetUpGroup() );
225 SwDrawContact* pNewContact = 0;
226 if( bNoGroup )
227 {
228 //Ankerattribut aufheben.
229 SwDrawContact *pMyContact = (SwDrawContact*)GetUserCall(pObj);
230 const SwFmtAnchor aAnch( pMyContact->GetFmt()->GetAnchor() );
231
232 SwUndoDrawGroup *const pUndo = (!GetIDocumentUndoRedo().DoesUndo())
233 ? 0
234 : new SwUndoDrawGroup( (sal_uInt16)rMrkList.GetMarkCount() );
235
236 // --> OD 2005-08-16 #i53320#
237 bool bGroupMembersNotPositioned( false );
238 {
239 SwAnchoredDrawObject* pAnchoredDrawObj =
240 static_cast<SwAnchoredDrawObject*>(pMyContact->GetAnchoredObj( pObj ));
241 bGroupMembersNotPositioned = pAnchoredDrawObj->NotYetPositioned();
242 }
243 // <--
244 //ContactObjekte und Formate vernichten.
245 for( sal_uInt16 i = 0; i < rMrkList.GetMarkCount(); ++i )
246 {
247 pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
248 SwDrawContact *pContact = (SwDrawContact*)GetUserCall(pObj);
249
250 // --> OD 2005-08-16 #i53320#
251 #ifdef DBG_UTIL
252 SwAnchoredDrawObject* pAnchoredDrawObj =
253 static_cast<SwAnchoredDrawObject*>(pContact->GetAnchoredObj( pObj ));
254 ASSERT( bGroupMembersNotPositioned == pAnchoredDrawObj->NotYetPositioned(),
255 "<SwDoc::GroupSelection(..)> - group members have different positioning status!" );
256 #endif
257 // <--
258
259 pFmt = (SwDrawFrmFmt*)pContact->GetFmt();
260 //loescht sich selbst!
261 pContact->Changed(*pObj, SDRUSERCALL_DELETE, pObj->GetLastBoundRect() );
262 pObj->SetUserCall( 0 );
263
264 if( pUndo )
265 pUndo->AddObj( i, pFmt, pObj );
266 else
267 DelFrmFmt( pFmt );
268
269 // --> OD 2005-05-10 #i45952# - re-introduce position
270 // normalization of group member objects, because its anchor position
271 // is cleared, when they are grouped.
272 Point aAnchorPos( pObj->GetAnchorPos() );
273 pObj->NbcSetAnchorPos( Point( 0, 0 ) );
274 pObj->NbcMove( Size( aAnchorPos.X(), aAnchorPos.Y() ) );
275 // <--
276 }
277
278 pFmt = MakeDrawFrmFmt( String::CreateFromAscii(
279 RTL_CONSTASCII_STRINGPARAM( "DrawObject" )),
280 GetDfltFrmFmt() );
281 pFmt->SetFmtAttr( aAnch );
282 // --> OD 2004-10-25 #i36010# - set layout direction of the position
283 pFmt->SetPositionLayoutDir(
284 text::PositionLayoutDir::PositionInLayoutDirOfAnchor );
285 // <--
286
287 rDrawView.GroupMarked();
288 ASSERT( rMrkList.GetMarkCount() == 1, "GroupMarked more or none groups." );
289
290 SdrObject* pNewGroupObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj();
291 pNewContact = new SwDrawContact( pFmt, pNewGroupObj );
292 // --> OD 2004-11-22 #i35635#
293 pNewContact->MoveObjToVisibleLayer( pNewGroupObj );
294 // <--
295 pNewContact->ConnectToLayout();
296 // --> OD 2005-08-16 #i53320# - No adjustment of the positioning and
297 // alignment attributes, if group members aren't positioned yet.
298 if ( !bGroupMembersNotPositioned )
299 {
300 // OD 2004-04-01 #i26791# - Adjust positioning and alignment attributes.
301 lcl_AdjustPositioningAttr( pFmt, *pNewGroupObj );
302 }
303 // <--
304
305 if( pUndo )
306 {
307 pUndo->SetGroupFmt( pFmt );
308 GetIDocumentUndoRedo().AppendUndo( pUndo );
309 }
310 }
311 else
312 {
313 if (GetIDocumentUndoRedo().DoesUndo())
314 {
315 GetIDocumentUndoRedo().ClearRedo();
316 }
317
318 rDrawView.GroupMarked();
319 ASSERT( rMrkList.GetMarkCount() == 1, "GroupMarked more or none groups." );
320 }
321
322 return pNewContact;
323 }
324
325
UnGroupSelection(SdrView & rDrawView)326 void SwDoc::UnGroupSelection( SdrView& rDrawView )
327 {
328 bool const bUndo = GetIDocumentUndoRedo().DoesUndo();
329 if( bUndo )
330 {
331 GetIDocumentUndoRedo().ClearRedo();
332 }
333
334 // OD 30.06.2003 #108784# - replace marked 'virtual' drawing objects by
335 // the corresponding 'master' drawing objects.
336 SwDrawView::ReplaceMarkedDrawVirtObjs( rDrawView );
337
338 const SdrMarkList &rMrkList = rDrawView.GetMarkedObjectList();
339 // --> OD 2006-11-01 #130889#
340 std::vector< std::pair< SwDrawFrmFmt*, SdrObject* > >* pFmtsAndObjs( 0L );
341 const sal_uInt32 nMarkCount( rMrkList.GetMarkCount() );
342 // <--
343 if ( nMarkCount )
344 {
345 // --> OD 2006-11-01 #130889#
346 pFmtsAndObjs = new std::vector< std::pair< SwDrawFrmFmt*, SdrObject* > >[nMarkCount];
347 // <--
348 SdrObject *pMyObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj();
349 if( !pMyObj->GetUpGroup() )
350 {
351 String sDrwFmtNm( String::CreateFromAscii(
352 RTL_CONSTASCII_STRINGPARAM("DrawObject" )));
353 for ( sal_uInt16 i = 0; i < nMarkCount; ++i )
354 {
355 SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
356 if ( pObj->IsA( TYPE(SdrObjGroup) ) )
357 {
358 SwDrawContact *pContact = (SwDrawContact*)GetUserCall(pObj);
359 SwFmtAnchor aAnch( pContact->GetFmt()->GetAnchor() );
360 SdrObjList *pLst = ((SdrObjGroup*)pObj)->GetSubList();
361
362 SwUndoDrawUnGroup* pUndo = 0;
363 if( bUndo )
364 {
365 pUndo = new SwUndoDrawUnGroup( (SdrObjGroup*)pObj );
366 GetIDocumentUndoRedo().AppendUndo(pUndo);
367 }
368
369 for ( sal_uInt16 i2 = 0; i2 < pLst->GetObjCount(); ++i2 )
370 {
371 SdrObject* pSubObj = pLst->GetObj( i2 );
372 SwDrawFrmFmt *pFmt = MakeDrawFrmFmt( sDrwFmtNm,
373 GetDfltFrmFmt() );
374 pFmt->SetFmtAttr( aAnch );
375 // --> OD 2004-10-25 #i36010# - set layout direction of the position
376 pFmt->SetPositionLayoutDir(
377 text::PositionLayoutDir::PositionInLayoutDirOfAnchor );
378 // <--
379 // --> OD 2006-11-01 #130889#
380 // creation of <SwDrawContact> instances for the group
381 // members and its connection to the Writer layout is
382 // done after intrinsic ungrouping.
383 // SwDrawContact* pContact = new SwDrawContact( pFmt, pSubObj );
384 // // --> OD 2004-11-22 #i35635#
385 // pContact->MoveObjToVisibleLayer( pSubObj );
386 // // <--
387 // pContact->ConnectToLayout();
388 // // OD 2004-04-07 #i26791# - Adjust positioning and
389 // // alignment attributes.
390 // lcl_AdjustPositioningAttr( pFmt, *pSubObj );
391 pFmtsAndObjs[i].push_back( std::pair< SwDrawFrmFmt*, SdrObject* >( pFmt, pSubObj ) );
392 // <--
393
394 if( bUndo )
395 pUndo->AddObj( i2, pFmt );
396 }
397 }
398 }
399 }
400 }
401 rDrawView.UnGroupMarked();
402 // --> OD 2006-11-01 #130889#
403 // creation of <SwDrawContact> instances for the former group members and
404 // its connection to the Writer layout.
405 for ( sal_uInt32 i = 0; i < nMarkCount; ++i )
406 {
407 SwUndoDrawUnGroupConnectToLayout* pUndo = 0;
408 if( bUndo )
409 {
410 pUndo = new SwUndoDrawUnGroupConnectToLayout();
411 GetIDocumentUndoRedo().AppendUndo(pUndo);
412 }
413
414 while ( pFmtsAndObjs[i].size() > 0 )
415 {
416 SwDrawFrmFmt* pFmt( pFmtsAndObjs[i].back().first );
417 SdrObject* pObj( pFmtsAndObjs[i].back().second );
418 pFmtsAndObjs[i].pop_back();
419
420 SwDrawContact* pContact = new SwDrawContact( pFmt, pObj );
421 pContact->MoveObjToVisibleLayer( pObj );
422 pContact->ConnectToLayout();
423 lcl_AdjustPositioningAttr( pFmt, *pObj );
424
425 if ( bUndo )
426 {
427 pUndo->AddFmtAndObj( pFmt, pObj );
428 }
429 }
430 }
431 delete [] pFmtsAndObjs;
432 // <--
433 }
434
435 /*************************************************************************
436 |*
437 |* SwDoc::DeleteSelection()
438 |*
439 |* Ersterstellung MA 14. Nov. 95
440 |* Letzte Aenderung MA 14. Nov. 95
441 |*
442 |*************************************************************************/
443
DeleteSelection(SwDrawView & rDrawView)444 sal_Bool SwDoc::DeleteSelection( SwDrawView& rDrawView )
445 {
446 sal_Bool bCallBase = sal_False;
447 const SdrMarkList &rMrkList = rDrawView.GetMarkedObjectList();
448 if( rMrkList.GetMarkCount() )
449 {
450 GetIDocumentUndoRedo().StartUndo(UNDO_EMPTY, NULL);
451 sal_uInt16 i;
452 sal_Bool bDelMarked = sal_True;
453
454 if( 1 == rMrkList.GetMarkCount() )
455 {
456 SdrObject *pObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj();
457 if( pObj->ISA(SwVirtFlyDrawObj) )
458 {
459 SwFlyFrmFmt* pFrmFmt = (SwFlyFrmFmt*)
460 ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm()->GetFmt();
461 if( pFrmFmt )
462 {
463 DelLayoutFmt( pFrmFmt );
464 bDelMarked = sal_False;
465 }
466 }
467 }
468
469 for( i = 0; i < rMrkList.GetMarkCount(); ++i )
470 {
471 SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
472 if( !pObj->ISA(SwVirtFlyDrawObj) )
473 {
474 SwDrawContact *pC = (SwDrawContact*)GetUserCall(pObj);
475 SwDrawFrmFmt *pFrmFmt = (SwDrawFrmFmt*)pC->GetFmt();
476 if( pFrmFmt &&
477 FLY_AS_CHAR == pFrmFmt->GetAnchor().GetAnchorId() )
478 {
479 rDrawView.MarkObj( pObj, rDrawView.Imp().GetPageView(), sal_True );
480 --i;
481 DelLayoutFmt( pFrmFmt );
482 }
483 }
484 }
485
486 if( rMrkList.GetMarkCount() && bDelMarked )
487 {
488 SdrObject *pObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj();
489 if( !pObj->GetUpGroup() )
490 {
491 SwUndoDrawDelete *const pUndo =
492 (!GetIDocumentUndoRedo().DoesUndo())
493 ? 0
494 : new SwUndoDrawDelete( (sal_uInt16)rMrkList.GetMarkCount() );
495
496 //ContactObjekte vernichten, Formate sicherstellen.
497 for( i = 0; i < rMrkList.GetMarkCount(); ++i )
498 {
499 const SdrMark& rMark = *rMrkList.GetMark( i );
500 pObj = rMark.GetMarkedSdrObj();
501 SwDrawContact *pContact = (SwDrawContact*)pObj->GetUserCall();
502 if( pContact ) // natuerlich nicht bei gruppierten Objekten
503 {
504 SwDrawFrmFmt *pFmt = (SwDrawFrmFmt*)pContact->GetFmt();
505 // OD 18.06.2003 #108784# - before delete of selection
506 // is performed, marked <SwDrawVirtObj>-objects have to
507 // be replaced by its reference objects.
508 // Thus, assert, if a <SwDrawVirt>-object is found in the mark list.
509 if ( pObj->ISA(SwDrawVirtObj) )
510 {
511 ASSERT( false,
512 "<SwDrawVirtObj> is still marked for delete. application will crash!" );
513 }
514 //loescht sich selbst!
515 pContact->Changed(*pObj, SDRUSERCALL_DELETE, pObj->GetLastBoundRect() );
516 pObj->SetUserCall( 0 );
517
518 if( pUndo )
519 pUndo->AddObj( i, pFmt, rMark );
520 else
521 DelFrmFmt( pFmt );
522 }
523 }
524
525 if( pUndo )
526 {
527 GetIDocumentUndoRedo().AppendUndo( pUndo );
528 }
529 }
530 bCallBase = sal_True;
531 }
532 SetModified();
533
534 GetIDocumentUndoRedo().EndUndo(UNDO_EMPTY, NULL);
535 }
536
537 return bCallBase;
538 }
539
540 /*************************************************************************
541 |*
542 |* SwDoc::DeleteSelection()
543 |*
544 |* Ersterstellung JP 11.01.96
545 |* Letzte Aenderung JP 11.01.96
546 |*
547 |*************************************************************************/
548
_ZSortFly(const SwFrmFmt * pFrmFmt,const SwFmtAnchor * pFlyAn,sal_uInt32 nArrOrdNum)549 _ZSortFly::_ZSortFly( const SwFrmFmt* pFrmFmt, const SwFmtAnchor* pFlyAn,
550 sal_uInt32 nArrOrdNum )
551 : pFmt( pFrmFmt ), pAnchor( pFlyAn ), nOrdNum( nArrOrdNum )
552 {
553 // #i11176#
554 // This also needs to work when no layout exists. Thus, for
555 // FlyFrames an alternative method is used now in that case.
556 if( RES_FLYFRMFMT == pFmt->Which() )
557 {
558 if( pFmt->getIDocumentLayoutAccess()->GetCurrentViewShell() ) //swmod 071107//swmod 071225
559 {
560 // Schauen, ob es ein SdrObject dafuer gibt
561 SwFlyFrm* pFly = SwIterator<SwFlyFrm,SwFmt>::FirstElement( *pFrmFmt );
562 if( pFly )
563 nOrdNum = pFly->GetVirtDrawObj()->GetOrdNum();
564 }
565 else
566 {
567 // Schauen, ob es ein SdrObject dafuer gibt
568 SwFlyDrawContact* pContact = SwIterator<SwFlyDrawContact,SwFmt>::FirstElement( *pFrmFmt );
569 if( pContact )
570 nOrdNum = pContact->GetMaster()->GetOrdNum();
571 }
572 }
573 else if( RES_DRAWFRMFMT == pFmt->Which() )
574 {
575 // Schauen, ob es ein SdrObject dafuer gibt
576 SwDrawContact* pContact = SwIterator<SwDrawContact,SwFmt>::FirstElement( *pFrmFmt );
577 if( pContact )
578 nOrdNum = pContact->GetMaster()->GetOrdNum();
579 }
580 else {
581 ASSERT( !this, "was ist das fuer ein Format?" );
582 }
583 }
584
585 /*************************************************************************/
586 // Wird auch vom Sw3-Reader gerufen, wenn ein Fehler beim Einlesen
587 // des Drawing Layers auftrat. In diesem Fall wird der Layer komplett
588 // neu aufgebaut.
589
590 // #75371#
591 #include <svx/sxenditm.hxx>
592
InitDrawModel()593 void SwDoc::InitDrawModel()
594 {
595 RTL_LOGFILE_CONTEXT_AUTHOR( aLog, "SW", "JP93722", "SwDoc::InitDrawModel" );
596
597 //!!Achtung im sw3-Reader (sw3imp.cxx) gibt es aehnlichen Code, der
598 //mitgepfelgt werden muss.
599 if ( pDrawModel )
600 ReleaseDrawModel();
601
602 //DrawPool und EditEnginePool anlegen, diese gehoeren uns und werden
603 //dem Drawing nur mitgegeben. Im ReleaseDrawModel werden die Pools wieder
604 //zerstoert.
605 // 17.2.99: for Bug 73110 - for loading the drawing items. This must
606 // be loaded without RefCounts!
607 SfxItemPool *pSdrPool = new SdrItemPool( &GetAttrPool() );
608 // #75371# change DefaultItems for the SdrEdgeObj distance items
609 // to TWIPS.
610 if(pSdrPool)
611 {
612 const long nDefEdgeDist = ((500 * 72) / 127); // 1/100th mm in twips
613 pSdrPool->SetPoolDefaultItem(SdrEdgeNode1HorzDistItem(nDefEdgeDist));
614 pSdrPool->SetPoolDefaultItem(SdrEdgeNode1VertDistItem(nDefEdgeDist));
615 pSdrPool->SetPoolDefaultItem(SdrEdgeNode2HorzDistItem(nDefEdgeDist));
616 pSdrPool->SetPoolDefaultItem(SdrEdgeNode2VertDistItem(nDefEdgeDist));
617
618 // #i33700#
619 // Set shadow distance defaults as PoolDefaultItems. Details see bug.
620 pSdrPool->SetPoolDefaultItem(SdrShadowXDistItem((300 * 72) / 127));
621 pSdrPool->SetPoolDefaultItem(SdrShadowYDistItem((300 * 72) / 127));
622 }
623 SfxItemPool *pEEgPool = EditEngine::CreatePool( sal_False );
624 pSdrPool->SetSecondaryPool( pEEgPool );
625 if ( !GetAttrPool().GetFrozenIdRanges () )
626 GetAttrPool().FreezeIdRanges();
627 else
628 pSdrPool->FreezeIdRanges();
629
630 // SJ: #95129# set FontHeight pool defaults without changing static SdrEngineDefaults
631 GetAttrPool().SetPoolDefaultItem(SvxFontHeightItem( 240, 100, EE_CHAR_FONTHEIGHT ));
632
633 RTL_LOGFILE_CONTEXT_TRACE( aLog, "before create DrawDocument" );
634 //Das SdrModel gehoert dem Dokument, wir haben immer zwei Layer und eine
635 //Seite.
636 pDrawModel = new SwDrawDocument( this );
637
638 pDrawModel->EnableUndo( GetIDocumentUndoRedo().DoesUndo() );
639
640 String sLayerNm;
641 sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("Hell" ));
642 nHell = pDrawModel->GetLayerAdmin().NewLayer( sLayerNm )->GetID();
643
644 sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("Heaven" ));
645 nHeaven = pDrawModel->GetLayerAdmin().NewLayer( sLayerNm )->GetID();
646
647 sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("Controls" ));
648 nControls = pDrawModel->GetLayerAdmin().NewLayer( sLayerNm )->GetID();
649
650 // OD 25.06.2003 #108784# - add invisible layers corresponding to the
651 // visible ones.
652 {
653 sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("InvisibleHell" ));
654 nInvisibleHell = pDrawModel->GetLayerAdmin().NewLayer( sLayerNm )->GetID();
655
656 sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("InvisibleHeaven" ));
657 nInvisibleHeaven = pDrawModel->GetLayerAdmin().NewLayer( sLayerNm )->GetID();
658
659 sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("InvisibleControls" ));
660 nInvisibleControls = pDrawModel->GetLayerAdmin().NewLayer( sLayerNm )->GetID();
661 }
662
663 SdrPage* pMasterPage = pDrawModel->AllocPage( sal_False );
664 pDrawModel->InsertPage( pMasterPage );
665 RTL_LOGFILE_CONTEXT_TRACE( aLog, "after create DrawDocument" );
666
667 RTL_LOGFILE_CONTEXT_TRACE( aLog, "before create Spellchecker/Hyphenator" );
668 SdrOutliner& rOutliner = pDrawModel->GetDrawOutliner();
669 uno::Reference< XSpellChecker1 > xSpell = ::GetSpellChecker();
670 rOutliner.SetSpeller( xSpell );
671 uno::Reference<XHyphenator> xHyphenator( ::GetHyphenator() );
672 rOutliner.SetHyphenator( xHyphenator );
673 RTL_LOGFILE_CONTEXT_TRACE( aLog, "after create Spellchecker/Hyphenator" );
674
675 SetCalcFieldValueHdl(&rOutliner);
676 SetCalcFieldValueHdl(&pDrawModel->GetHitTestOutliner());
677
678 //JP 16.07.98: Bug 50193 - Linkmanager am Model setzen, damit
679 // dort ggfs. verlinkte Grafiken eingefuegt werden koennen
680 //JP 28.01.99: der WinWord Import benoetigt ihn auch
681 pDrawModel->SetLinkManager( &GetLinkManager() );
682 pDrawModel->SetAddExtLeading( get(IDocumentSettingAccess::ADD_EXT_LEADING) );
683
684 OutputDevice* pRefDev = getReferenceDevice( false );
685 if ( pRefDev )
686 pDrawModel->SetRefDevice( pRefDev );
687
688 pDrawModel->SetNotifyUndoActionHdl( LINK( this, SwDoc, AddDrawUndo ));
689 if ( pCurrentView )
690 {
691 ViewShell* pViewSh = pCurrentView;
692 do
693 {
694 SwRootFrm* pRoot = pViewSh->GetLayout();
695 if( pRoot && !pRoot->GetDrawPage() )
696 {
697 // Disable "multiple layout" for the moment:
698 // use pMasterPage instead of a new created SdrPage
699 // pDrawModel->AllocPage( FALSE );
700 // pDrawModel->InsertPage( pDrawPage );
701 SdrPage* pDrawPage = pMasterPage;
702 pRoot->SetDrawPage( pDrawPage );
703 pDrawPage->SetSize( pRoot->Frm().SSize() );
704 }
705 pViewSh = (ViewShell*)pViewSh->GetNext();
706 }while( pViewSh != pCurrentView );
707 }
708 }
709
710 /** method to notify drawing page view about the invisible layers
711
712 OD 26.06.2003 #108784#
713
714 @author OD
715 */
NotifyInvisibleLayers(SdrPageView & _rSdrPageView)716 void SwDoc::NotifyInvisibleLayers( SdrPageView& _rSdrPageView )
717 {
718 String sLayerNm;
719 sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("InvisibleHell" ));
720 _rSdrPageView.SetLayerVisible( sLayerNm, sal_False );
721
722 sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("InvisibleHeaven" ));
723 _rSdrPageView.SetLayerVisible( sLayerNm, sal_False );
724
725 sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("InvisibleControls" ));
726 _rSdrPageView.SetLayerVisible( sLayerNm, sal_False );
727 }
728
729 /** method to determine, if a layer ID belongs to the visible ones.
730
731 OD 25.06.2003 #108784#
732 Note: If given layer ID is unknown, method asserts and returns <false>.
733
734 @author OD
735 */
IsVisibleLayerId(const SdrLayerID & _nLayerId) const736 bool SwDoc::IsVisibleLayerId( const SdrLayerID& _nLayerId ) const
737 {
738 bool bRetVal;
739
740 if ( _nLayerId == GetHeavenId() ||
741 _nLayerId == GetHellId() ||
742 _nLayerId == GetControlsId() )
743 {
744 bRetVal = true;
745 }
746 else if ( _nLayerId == GetInvisibleHeavenId() ||
747 _nLayerId == GetInvisibleHellId() ||
748 _nLayerId == GetInvisibleControlsId() )
749 {
750 bRetVal = false;
751 }
752 else
753 {
754 ASSERT( false, "<SwDoc::IsVisibleLayerId(..)> - unknown layer ID." );
755 bRetVal = false;
756 }
757
758 return bRetVal;
759 }
760
761 /** method to determine, if the corresponding visible layer ID for a invisible one.
762
763 OD 25.06.2003 #108784#
764 Note: If given layer ID is a visible one, method returns given layer ID.
765 Note: If given layer ID is unknown, method returns given layer ID.
766
767 @author OD
768 */
GetVisibleLayerIdByInvisibleOne(const SdrLayerID & _nInvisibleLayerId)769 SdrLayerID SwDoc::GetVisibleLayerIdByInvisibleOne( const SdrLayerID& _nInvisibleLayerId )
770 {
771 SdrLayerID nVisibleLayerId;
772
773 if ( _nInvisibleLayerId == GetInvisibleHeavenId() )
774 {
775 nVisibleLayerId = GetHeavenId();
776 }
777 else if ( _nInvisibleLayerId == GetInvisibleHellId() )
778 {
779 nVisibleLayerId = GetHellId();
780 }
781 else if ( _nInvisibleLayerId == GetInvisibleControlsId() )
782 {
783 nVisibleLayerId = GetControlsId();
784 }
785 else if ( _nInvisibleLayerId == GetHeavenId() ||
786 _nInvisibleLayerId == GetHellId() ||
787 _nInvisibleLayerId == GetControlsId() )
788 {
789 ASSERT( false, "<SwDoc::GetVisibleLayerIdByInvisibleOne(..)> - given layer ID already an invisible one." );
790 nVisibleLayerId = _nInvisibleLayerId;
791 }
792 else
793 {
794 ASSERT( false, "<SwDoc::GetVisibleLayerIdByInvisibleOne(..)> - given layer ID is unknown." );
795 nVisibleLayerId = _nInvisibleLayerId;
796 }
797
798 return nVisibleLayerId;
799 }
800
801 /** method to determine, if the corresponding invisible layer ID for a visible one.
802
803 OD 25.06.2003 #108784#
804 Note: If given layer ID is a invisible one, method returns given layer ID.
805 Note: If given layer ID is unknown, method returns given layer ID.
806
807 @author OD
808 */
GetInvisibleLayerIdByVisibleOne(const SdrLayerID & _nVisibleLayerId)809 SdrLayerID SwDoc::GetInvisibleLayerIdByVisibleOne( const SdrLayerID& _nVisibleLayerId )
810 {
811 SdrLayerID nInvisibleLayerId;
812
813 if ( _nVisibleLayerId == GetHeavenId() )
814 {
815 nInvisibleLayerId = GetInvisibleHeavenId();
816 }
817 else if ( _nVisibleLayerId == GetHellId() )
818 {
819 nInvisibleLayerId = GetInvisibleHellId();
820 }
821 else if ( _nVisibleLayerId == GetControlsId() )
822 {
823 nInvisibleLayerId = GetInvisibleControlsId();
824 }
825 else if ( _nVisibleLayerId == GetInvisibleHeavenId() ||
826 _nVisibleLayerId == GetInvisibleHellId() ||
827 _nVisibleLayerId == GetInvisibleControlsId() )
828 {
829 ASSERT( false, "<SwDoc::GetInvisibleLayerIdByVisibleOne(..)> - given layer ID already an invisible one." );
830 nInvisibleLayerId = _nVisibleLayerId;
831 }
832 else
833 {
834 ASSERT( false, "<SwDoc::GetInvisibleLayerIdByVisibleOne(..)> - given layer ID is unknown." );
835 nInvisibleLayerId = _nVisibleLayerId;
836 }
837
838 return nInvisibleLayerId;
839 }
840
841 /*************************************************************************/
842
843
ReleaseDrawModel()844 void SwDoc::ReleaseDrawModel()
845 {
846 if ( pDrawModel )
847 {
848 //!!Den code im sw3io fuer Einfuegen Dokument mitpflegen!!
849
850 delete pDrawModel; pDrawModel = 0;
851 SfxItemPool *pSdrPool = GetAttrPool().GetSecondaryPool();
852
853 ASSERT( pSdrPool, "missing Pool" );
854 SfxItemPool *pEEgPool = pSdrPool->GetSecondaryPool();
855 ASSERT( !pEEgPool->GetSecondaryPool(), "i don't accept additional pools");
856 pSdrPool->Delete(); //Erst die Items vernichten lassen,
857 //dann erst die Verkettung loesen
858 GetAttrPool().SetSecondaryPool( 0 ); //Der ist ein muss!
859 pSdrPool->SetSecondaryPool( 0 ); //Der ist sicherer
860 SfxItemPool::Free(pSdrPool);
861 SfxItemPool::Free(pEEgPool);
862 }
863 }
864
865 /*************************************************************************/
866
867
_MakeDrawModel()868 SdrModel* SwDoc::_MakeDrawModel()
869 {
870 ASSERT( !pDrawModel, "_MakeDrawModel: Why?" );
871 InitDrawModel();
872 if ( pCurrentView )
873 {
874 ViewShell* pTmp = pCurrentView;
875 do
876 {
877 pTmp->MakeDrawView();
878 pTmp = (ViewShell*) pTmp->GetNext();
879 } while ( pTmp != pCurrentView );
880
881 //Broadcast, damit die FormShell mit der DrawView verbunden werden kann
882 if( GetDocShell() )
883 {
884 SfxSimpleHint aHnt( SW_BROADCAST_DRAWVIEWS_CREATED );
885 GetDocShell()->Broadcast( aHnt );
886 }
887 } //swmod 071029//swmod 071225
888 return pDrawModel;
889 }
890
891 /*************************************************************************/
892
DrawNotifyUndoHdl()893 void SwDoc::DrawNotifyUndoHdl()
894 {
895 pDrawModel->SetNotifyUndoActionHdl( Link() );
896 }
897
898 /*************************************************************************
899 *
900 * Am Outliner Link auf Methode fuer Felddarstellung in Editobjekten setzen
901 *
902 *************************************************************************/
903
SetCalcFieldValueHdl(Outliner * pOutliner)904 void SwDoc::SetCalcFieldValueHdl(Outliner* pOutliner)
905 {
906 pOutliner->SetCalcFieldValueHdl(LINK(this, SwDoc, CalcFieldValueHdl));
907 }
908
909 /*************************************************************************
910 |*
911 |* Felder bzw URLs im Outliner erkennen und Darstellung festlegen
912 |*
913 \************************************************************************/
914
IMPL_LINK(SwDoc,CalcFieldValueHdl,EditFieldInfo *,pInfo)915 IMPL_LINK(SwDoc, CalcFieldValueHdl, EditFieldInfo*, pInfo)
916 {
917 if (pInfo)
918 {
919 const SvxFieldItem& rField = pInfo->GetField();
920 const SvxFieldData* pField = rField.GetField();
921
922 if (pField && pField->ISA(SvxDateField))
923 {
924 /******************************************************************
925 * Date-Field
926 ******************************************************************/
927 pInfo->SetRepresentation(
928 ((const SvxDateField*) pField)->GetFormatted(
929 *GetNumberFormatter( sal_True ), LANGUAGE_SYSTEM) );
930 }
931 else if (pField && pField->ISA(SvxURLField))
932 {
933 /******************************************************************
934 * URL-Field
935 ******************************************************************/
936
937 switch ( ((const SvxURLField*) pField)->GetFormat() )
938 {
939 case SVXURLFORMAT_APPDEFAULT: //!!! einstellbar an App???
940 case SVXURLFORMAT_REPR:
941 {
942 pInfo->SetRepresentation(
943 ((const SvxURLField*)pField)->GetRepresentation());
944 }
945 break;
946
947 case SVXURLFORMAT_URL:
948 {
949 pInfo->SetRepresentation(
950 ((const SvxURLField*)pField)->GetURL());
951 }
952 break;
953 }
954
955 sal_uInt16 nChrFmt;
956
957 if (IsVisitedURL(((const SvxURLField*)pField)->GetURL()))
958 nChrFmt = RES_POOLCHR_INET_VISIT;
959 else
960 nChrFmt = RES_POOLCHR_INET_NORMAL;
961
962 SwFmt *pFmt = GetCharFmtFromPool(nChrFmt);
963
964 Color aColor(COL_LIGHTBLUE);
965 if (pFmt)
966 aColor = pFmt->GetColor().GetValue();
967
968 pInfo->SetTxtColor(aColor);
969 }
970 else if (pField && pField->ISA(SdrMeasureField))
971 {
972 /******************************************************************
973 * Measure-Field
974 ******************************************************************/
975 pInfo->ClearFldColor();
976 }
977 else if ( pField && pField->ISA(SvxExtTimeField))
978 {
979 /******************************************************************
980 * Time-Field
981 ******************************************************************/
982 pInfo->SetRepresentation(
983 ((const SvxExtTimeField*) pField)->GetFormatted(
984 *GetNumberFormatter( sal_True ), LANGUAGE_SYSTEM) );
985 }
986 else
987 {
988 DBG_ERROR("unbekannter Feldbefehl");
989 pInfo->SetRepresentation( String( '?' ) );
990 }
991 }
992
993 return(0);
994 }
995
996 /* TFFDI: The functions formerly declared 'inline'
997 */
GetDrawModel() const998 const SdrModel* SwDoc::GetDrawModel() const { return pDrawModel; }
GetDrawModel()999 SdrModel* SwDoc::GetDrawModel() { return pDrawModel; }
GetHeavenId() const1000 SdrLayerID SwDoc::GetHeavenId() const { return nHeaven; }
GetHellId() const1001 SdrLayerID SwDoc::GetHellId() const { return nHell; }
GetControlsId() const1002 SdrLayerID SwDoc::GetControlsId() const { return nControls; }
GetInvisibleHeavenId() const1003 SdrLayerID SwDoc::GetInvisibleHeavenId() const { return nInvisibleHeaven; }
GetInvisibleHellId() const1004 SdrLayerID SwDoc::GetInvisibleHellId() const { return nInvisibleHell; }
GetInvisibleControlsId() const1005 SdrLayerID SwDoc::GetInvisibleControlsId() const { return nInvisibleControls; }
GetOrCreateDrawModel()1006 SdrModel* SwDoc::GetOrCreateDrawModel() { return GetDrawModel() ? GetDrawModel() : _MakeDrawModel(); }
1007
1008 // --> OD 2006-03-14 #i62875#
1009 namespace docfunc
1010 {
ExistsDrawObjs(SwDoc & p_rDoc)1011 bool ExistsDrawObjs( SwDoc& p_rDoc )
1012 {
1013 bool bExistsDrawObjs( false );
1014
1015 if ( p_rDoc.GetDrawModel() &&
1016 p_rDoc.GetDrawModel()->GetPage( 0 ) )
1017 {
1018 const SdrPage& rSdrPage( *(p_rDoc.GetDrawModel()->GetPage( 0 )) );
1019
1020 SdrObjListIter aIter( rSdrPage, IM_FLAT );
1021 while( aIter.IsMore() )
1022 {
1023 SdrObject* pObj( aIter.Next() );
1024 if ( !dynamic_cast<SwVirtFlyDrawObj*>(pObj) &&
1025 !dynamic_cast<SwFlyDrawObj*>(pObj) )
1026 {
1027 bExistsDrawObjs = true;
1028 break;
1029 }
1030 }
1031 }
1032
1033 return bExistsDrawObjs;
1034 }
1035
AllDrawObjsOnPage(SwDoc & p_rDoc)1036 bool AllDrawObjsOnPage( SwDoc& p_rDoc )
1037 {
1038 bool bAllDrawObjsOnPage( true );
1039
1040 if ( p_rDoc.GetDrawModel() &&
1041 p_rDoc.GetDrawModel()->GetPage( 0 ) )
1042 {
1043 const SdrPage& rSdrPage( *(p_rDoc.GetDrawModel()->GetPage( 0 )) );
1044
1045 SdrObjListIter aIter( rSdrPage, IM_FLAT );
1046 while( aIter.IsMore() )
1047 {
1048 SdrObject* pObj( aIter.Next() );
1049 if ( !dynamic_cast<SwVirtFlyDrawObj*>(pObj) &&
1050 !dynamic_cast<SwFlyDrawObj*>(pObj) )
1051 {
1052 SwDrawContact* pDrawContact =
1053 dynamic_cast<SwDrawContact*>(::GetUserCall( pObj ));
1054 if ( pDrawContact )
1055 {
1056 SwAnchoredDrawObject* pAnchoredDrawObj =
1057 dynamic_cast<SwAnchoredDrawObject*>(pDrawContact->GetAnchoredObj( pObj ));
1058
1059 // error handling
1060 {
1061 if ( !pAnchoredDrawObj )
1062 {
1063 ASSERT( false,
1064 "<docfunc::AllDrawObjsOnPage() - missing anchored draw object" );
1065 bAllDrawObjsOnPage = false;
1066 break;
1067 }
1068 }
1069
1070 if ( pAnchoredDrawObj->NotYetPositioned() )
1071 {
1072 // The drawing object isn't yet layouted.
1073 // Thus, it isn't known, if all drawing objects are on page.
1074 bAllDrawObjsOnPage = false;
1075 break;
1076 }
1077 else if ( pAnchoredDrawObj->IsOutsidePage() )
1078 {
1079 bAllDrawObjsOnPage = false;
1080 break;
1081 }
1082 }
1083 else
1084 {
1085 // contact object of drawing object doesn't exists.
1086 // Thus, the drawing object isn't yet positioned.
1087 // Thus, it isn't known, if all drawing objects are on page.
1088 bAllDrawObjsOnPage = false;
1089 break;
1090 }
1091 }
1092 }
1093 }
1094
1095 return bAllDrawObjsOnPage;
1096 }
1097 }
1098 // <--
1099
1100 // eof
1101