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( sal_False, "what is that 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 // SJ: #95129# set FontHeight pool defaults without changing static SdrEngineDefaults
603 GetAttrPool().SetPoolDefaultItem(SvxFontHeightItem( 240, 100, EE_CHAR_FONTHEIGHT ));
604
605 RTL_LOGFILE_CONTEXT_TRACE( aLog, "before create DrawDocument" );
606 //Das SdrModel gehoert dem Dokument, wir haben immer zwei Layer und eine
607 //Seite.
608 pDrawModel = new SwDrawModel( this );
609
610 pDrawModel->EnableUndo( GetIDocumentUndoRedo().DoesUndo() );
611
612 String sLayerNm;
613 sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("Hell" ));
614 nHell = pDrawModel->GetLayerAdmin().NewLayer( sLayerNm )->GetID();
615
616 sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("Heaven" ));
617 nHeaven = pDrawModel->GetLayerAdmin().NewLayer( sLayerNm )->GetID();
618
619 sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("Controls" ));
620 nControls = pDrawModel->GetLayerAdmin().NewLayer( sLayerNm )->GetID();
621
622 // OD 25.06.2003 #108784# - add invisible layers corresponding to the
623 // visible ones.
624 {
625 sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("InvisibleHell" ));
626 nInvisibleHell = pDrawModel->GetLayerAdmin().NewLayer( sLayerNm )->GetID();
627
628 sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("InvisibleHeaven" ));
629 nInvisibleHeaven = pDrawModel->GetLayerAdmin().NewLayer( sLayerNm )->GetID();
630
631 sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("InvisibleControls" ));
632 nInvisibleControls = pDrawModel->GetLayerAdmin().NewLayer( sLayerNm )->GetID();
633 }
634
635 SdrPage* pMasterPage = pDrawModel->AllocPage( sal_False );
636 pDrawModel->InsertPage( pMasterPage );
637 RTL_LOGFILE_CONTEXT_TRACE( aLog, "after create DrawDocument" );
638
639 RTL_LOGFILE_CONTEXT_TRACE( aLog, "before create Spellchecker/Hyphenator" );
640 SdrOutliner& rOutliner = pDrawModel->GetDrawOutliner();
641 uno::Reference< XSpellChecker1 > xSpell = ::GetSpellChecker();
642 rOutliner.SetSpeller( xSpell );
643 uno::Reference<XHyphenator> xHyphenator( ::GetHyphenator() );
644 rOutliner.SetHyphenator( xHyphenator );
645 RTL_LOGFILE_CONTEXT_TRACE( aLog, "after create Spellchecker/Hyphenator" );
646
647 SetCalcFieldValueHdl(&rOutliner);
648 SetCalcFieldValueHdl(&pDrawModel->GetHitTestOutliner());
649
650 //JP 16.07.98: Bug 50193 - Linkmanager am Model setzen, damit
651 // dort ggfs. verlinkte Grafiken eingefuegt werden koennen
652 //JP 28.01.99: der WinWord Import benoetigt ihn auch
653 pDrawModel->SetLinkManager( &GetLinkManager() );
654 pDrawModel->SetAddExtLeading( get(IDocumentSettingAccess::ADD_EXT_LEADING) );
655
656 OutputDevice* pRefDev = getReferenceDevice( false );
657 if ( pRefDev )
658 pDrawModel->SetRefDevice( pRefDev );
659
660 pDrawModel->SetNotifyUndoActionHdl( LINK( this, SwDoc, AddDrawUndo ));
661 if ( pCurrentView )
662 {
663 ViewShell* pViewSh = pCurrentView;
664 do
665 {
666 SwRootFrm* pRoot = pViewSh->GetLayout();
667 if( pRoot && !pRoot->GetDrawPage() )
668 {
669 // Disable "multiple layout" for the moment:
670 // use pMasterPage instead of a new created SdrPage
671 // pDrawModel->AllocPage( FALSE );
672 // pDrawModel->InsertPage( pDrawPage );
673 SdrPage* pDrawPage = pMasterPage;
674 pRoot->SetDrawPage( pDrawPage );
675 pDrawPage->SetSize( pRoot->Frm().SSize() );
676 }
677 pViewSh = (ViewShell*)pViewSh->GetNext();
678 }while( pViewSh != pCurrentView );
679 }
680 }
681
682 /** method to notify drawing page view about the invisible layers
683
684 OD 26.06.2003 #108784#
685
686 @author OD
687 */
NotifyInvisibleLayers(SdrPageView & _rSdrPageView)688 void SwDoc::NotifyInvisibleLayers( SdrPageView& _rSdrPageView )
689 {
690 String sLayerNm;
691 sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("InvisibleHell" ));
692 _rSdrPageView.SetLayerVisible( sLayerNm, sal_False );
693
694 sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("InvisibleHeaven" ));
695 _rSdrPageView.SetLayerVisible( sLayerNm, sal_False );
696
697 sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("InvisibleControls" ));
698 _rSdrPageView.SetLayerVisible( sLayerNm, sal_False );
699 }
700
701 /** method to determine, if a layer ID belongs to the visible ones.
702
703 OD 25.06.2003 #108784#
704 Note: If given layer ID is unknown, method asserts and returns <false>.
705
706 @author OD
707 */
IsVisibleLayerId(const SdrLayerID & _nLayerId) const708 bool SwDoc::IsVisibleLayerId( const SdrLayerID& _nLayerId ) const
709 {
710 bool bRetVal;
711
712 if ( _nLayerId == GetHeavenId() ||
713 _nLayerId == GetHellId() ||
714 _nLayerId == GetControlsId() )
715 {
716 bRetVal = true;
717 }
718 else if ( _nLayerId == GetInvisibleHeavenId() ||
719 _nLayerId == GetInvisibleHellId() ||
720 _nLayerId == GetInvisibleControlsId() )
721 {
722 bRetVal = false;
723 }
724 else
725 {
726 ASSERT( false, "<SwDoc::IsVisibleLayerId(..)> - unknown layer ID." );
727 bRetVal = false;
728 }
729
730 return bRetVal;
731 }
732
733 /** method to determine, if the corresponding visible layer ID for a invisible one.
734
735 OD 25.06.2003 #108784#
736 Note: If given layer ID is a visible one, method returns given layer ID.
737 Note: If given layer ID is unknown, method returns given layer ID.
738
739 @author OD
740 */
GetVisibleLayerIdByInvisibleOne(const SdrLayerID & _nInvisibleLayerId)741 SdrLayerID SwDoc::GetVisibleLayerIdByInvisibleOne( const SdrLayerID& _nInvisibleLayerId )
742 {
743 SdrLayerID nVisibleLayerId;
744
745 if ( _nInvisibleLayerId == GetInvisibleHeavenId() )
746 {
747 nVisibleLayerId = GetHeavenId();
748 }
749 else if ( _nInvisibleLayerId == GetInvisibleHellId() )
750 {
751 nVisibleLayerId = GetHellId();
752 }
753 else if ( _nInvisibleLayerId == GetInvisibleControlsId() )
754 {
755 nVisibleLayerId = GetControlsId();
756 }
757 else if ( _nInvisibleLayerId == GetHeavenId() ||
758 _nInvisibleLayerId == GetHellId() ||
759 _nInvisibleLayerId == GetControlsId() )
760 {
761 ASSERT( false, "<SwDoc::GetVisibleLayerIdByInvisibleOne(..)> - given layer ID already an invisible one." );
762 nVisibleLayerId = _nInvisibleLayerId;
763 }
764 else
765 {
766 ASSERT( false, "<SwDoc::GetVisibleLayerIdByInvisibleOne(..)> - given layer ID is unknown." );
767 nVisibleLayerId = _nInvisibleLayerId;
768 }
769
770 return nVisibleLayerId;
771 }
772
773 /** method to determine, if the corresponding invisible layer ID for a visible one.
774
775 OD 25.06.2003 #108784#
776 Note: If given layer ID is a invisible one, method returns given layer ID.
777 Note: If given layer ID is unknown, method returns given layer ID.
778
779 @author OD
780 */
GetInvisibleLayerIdByVisibleOne(const SdrLayerID & _nVisibleLayerId)781 SdrLayerID SwDoc::GetInvisibleLayerIdByVisibleOne( const SdrLayerID& _nVisibleLayerId )
782 {
783 SdrLayerID nInvisibleLayerId;
784
785 if ( _nVisibleLayerId == GetHeavenId() )
786 {
787 nInvisibleLayerId = GetInvisibleHeavenId();
788 }
789 else if ( _nVisibleLayerId == GetHellId() )
790 {
791 nInvisibleLayerId = GetInvisibleHellId();
792 }
793 else if ( _nVisibleLayerId == GetControlsId() )
794 {
795 nInvisibleLayerId = GetInvisibleControlsId();
796 }
797 else if ( _nVisibleLayerId == GetInvisibleHeavenId() ||
798 _nVisibleLayerId == GetInvisibleHellId() ||
799 _nVisibleLayerId == GetInvisibleControlsId() )
800 {
801 ASSERT( false, "<SwDoc::GetInvisibleLayerIdByVisibleOne(..)> - given layer ID already an invisible one." );
802 nInvisibleLayerId = _nVisibleLayerId;
803 }
804 else
805 {
806 ASSERT( false, "<SwDoc::GetInvisibleLayerIdByVisibleOne(..)> - given layer ID is unknown." );
807 nInvisibleLayerId = _nVisibleLayerId;
808 }
809
810 return nInvisibleLayerId;
811 }
812
813 /*************************************************************************/
814
815
ReleaseDrawModel()816 void SwDoc::ReleaseDrawModel()
817 {
818 if ( pDrawModel )
819 {
820 //!!Den code im sw3io fuer Einfuegen Dokument mitpflegen!!
821 delete pDrawModel; pDrawModel = 0;
822 }
823 }
824
825 /*************************************************************************/
826
827
_MakeDrawModel()828 SwDrawModel* SwDoc::_MakeDrawModel()
829 {
830 ASSERT( !pDrawModel, "_MakeDrawModel: Why?" );
831 InitDrawModel();
832 if ( pCurrentView )
833 {
834 ViewShell* pTmp = pCurrentView;
835 do
836 {
837 pTmp->MakeDrawView();
838 pTmp = (ViewShell*) pTmp->GetNext();
839 } while ( pTmp != pCurrentView );
840
841 //Broadcast, damit die FormShell mit der DrawView verbunden werden kann
842 if( GetDocShell() )
843 {
844 SfxSimpleHint aHnt( SW_BROADCAST_DRAWVIEWS_CREATED );
845 GetDocShell()->Broadcast( aHnt );
846 }
847 } //swmod 071029//swmod 071225
848 return pDrawModel;
849 }
850
851 /*************************************************************************/
852
DrawNotifyUndoHdl()853 void SwDoc::DrawNotifyUndoHdl()
854 {
855 pDrawModel->SetNotifyUndoActionHdl( Link() );
856 }
857
858 /*************************************************************************
859 *
860 * Am Outliner Link auf Methode fuer Felddarstellung in Editobjekten setzen
861 *
862 *************************************************************************/
863
SetCalcFieldValueHdl(Outliner * pOutliner)864 void SwDoc::SetCalcFieldValueHdl(Outliner* pOutliner)
865 {
866 pOutliner->SetCalcFieldValueHdl(LINK(this, SwDoc, CalcFieldValueHdl));
867 }
868
869 /*************************************************************************
870 |*
871 |* Felder bzw URLs im Outliner erkennen und Darstellung festlegen
872 |*
873 \************************************************************************/
874
IMPL_LINK(SwDoc,CalcFieldValueHdl,EditFieldInfo *,pInfo)875 IMPL_LINK(SwDoc, CalcFieldValueHdl, EditFieldInfo*, pInfo)
876 {
877 if (pInfo)
878 {
879 const SvxFieldItem& rField = pInfo->GetField();
880 const SvxFieldData* pField = rField.GetField();
881
882 if (pField && pField->ISA(SvxDateField))
883 {
884 /******************************************************************
885 * Date-Field
886 ******************************************************************/
887 pInfo->SetRepresentation(
888 ((const SvxDateField*) pField)->GetFormatted(
889 *GetNumberFormatter( sal_True ), LANGUAGE_SYSTEM) );
890 }
891 else if (pField && pField->ISA(SvxURLField))
892 {
893 /******************************************************************
894 * URL-Field
895 ******************************************************************/
896
897 switch ( ((const SvxURLField*) pField)->GetFormat() )
898 {
899 case SVXURLFORMAT_APPDEFAULT: //!!! einstellbar an App???
900 case SVXURLFORMAT_REPR:
901 {
902 pInfo->SetRepresentation(
903 ((const SvxURLField*)pField)->GetRepresentation());
904 }
905 break;
906
907 case SVXURLFORMAT_URL:
908 {
909 pInfo->SetRepresentation(
910 ((const SvxURLField*)pField)->GetURL());
911 }
912 break;
913 }
914
915 sal_uInt16 nChrFmt;
916
917 if (IsVisitedURL(((const SvxURLField*)pField)->GetURL()))
918 nChrFmt = RES_POOLCHR_INET_VISIT;
919 else
920 nChrFmt = RES_POOLCHR_INET_NORMAL;
921
922 SwFmt *pFmt = GetCharFmtFromPool(nChrFmt);
923
924 Color aColor(COL_LIGHTBLUE);
925 if (pFmt)
926 aColor = pFmt->GetColor().GetValue();
927
928 pInfo->SetTxtColor(aColor);
929 }
930 else if (pField && pField->ISA(SdrMeasureField))
931 {
932 /******************************************************************
933 * Measure-Field
934 ******************************************************************/
935 pInfo->ClearFldColor();
936 }
937 else if ( pField && pField->ISA(SvxExtTimeField))
938 {
939 /******************************************************************
940 * Time-Field
941 ******************************************************************/
942 pInfo->SetRepresentation(
943 ((const SvxExtTimeField*) pField)->GetFormatted(
944 *GetNumberFormatter( sal_True ), LANGUAGE_SYSTEM) );
945 }
946 else
947 {
948 DBG_ERROR("unbekannter Feldbefehl");
949 pInfo->SetRepresentation( String( '?' ) );
950 }
951 }
952
953 return(0);
954 }
955
956 /* TFFDI: The functions formerly declared 'inline'
957 */
GetDrawModel() const958 const SwDrawModel* SwDoc::GetDrawModel() const { return pDrawModel; }
GetDrawModel()959 SwDrawModel* SwDoc::GetDrawModel() { return pDrawModel; }
GetHeavenId() const960 SdrLayerID SwDoc::GetHeavenId() const { return nHeaven; }
GetHellId() const961 SdrLayerID SwDoc::GetHellId() const { return nHell; }
GetControlsId() const962 SdrLayerID SwDoc::GetControlsId() const { return nControls; }
GetInvisibleHeavenId() const963 SdrLayerID SwDoc::GetInvisibleHeavenId() const { return nInvisibleHeaven; }
GetInvisibleHellId() const964 SdrLayerID SwDoc::GetInvisibleHellId() const { return nInvisibleHell; }
GetInvisibleControlsId() const965 SdrLayerID SwDoc::GetInvisibleControlsId() const { return nInvisibleControls; }
GetOrCreateDrawModel()966 SwDrawModel* SwDoc::GetOrCreateDrawModel() { return GetDrawModel() ? GetDrawModel() : _MakeDrawModel(); }
967
968 // --> OD 2006-03-14 #i62875#
969 namespace docfunc
970 {
ExistsDrawObjs(SwDoc & p_rDoc)971 bool ExistsDrawObjs( SwDoc& p_rDoc )
972 {
973 bool bExistsDrawObjs( false );
974
975 if ( p_rDoc.GetDrawModel() &&
976 p_rDoc.GetDrawModel()->GetPage( 0 ) )
977 {
978 const SdrPage& rSdrPage( *(p_rDoc.GetDrawModel()->GetPage( 0 )) );
979
980 SdrObjListIter aIter( rSdrPage, IM_FLAT );
981 while( aIter.IsMore() )
982 {
983 SdrObject* pObj( aIter.Next() );
984 if ( !dynamic_cast<SwVirtFlyDrawObj*>(pObj) &&
985 !dynamic_cast<SwFlyDrawObj*>(pObj) )
986 {
987 bExistsDrawObjs = true;
988 break;
989 }
990 }
991 }
992
993 return bExistsDrawObjs;
994 }
995
AllDrawObjsOnPage(SwDoc & p_rDoc)996 bool AllDrawObjsOnPage( SwDoc& p_rDoc )
997 {
998 bool bAllDrawObjsOnPage( true );
999
1000 if ( p_rDoc.GetDrawModel() &&
1001 p_rDoc.GetDrawModel()->GetPage( 0 ) )
1002 {
1003 const SdrPage& rSdrPage( *(p_rDoc.GetDrawModel()->GetPage( 0 )) );
1004
1005 SdrObjListIter aIter( rSdrPage, IM_FLAT );
1006 while( aIter.IsMore() )
1007 {
1008 SdrObject* pObj( aIter.Next() );
1009 if ( !dynamic_cast<SwVirtFlyDrawObj*>(pObj) &&
1010 !dynamic_cast<SwFlyDrawObj*>(pObj) )
1011 {
1012 SwDrawContact* pDrawContact =
1013 dynamic_cast<SwDrawContact*>(::GetUserCall( pObj ));
1014 if ( pDrawContact )
1015 {
1016 SwAnchoredDrawObject* pAnchoredDrawObj =
1017 dynamic_cast<SwAnchoredDrawObject*>(pDrawContact->GetAnchoredObj( pObj ));
1018
1019 // error handling
1020 {
1021 if ( !pAnchoredDrawObj )
1022 {
1023 ASSERT( false,
1024 "<docfunc::AllDrawObjsOnPage() - missing anchored draw object" );
1025 bAllDrawObjsOnPage = false;
1026 break;
1027 }
1028 }
1029
1030 if ( pAnchoredDrawObj->NotYetPositioned() )
1031 {
1032 // The drawing object isn't yet layouted.
1033 // Thus, it isn't known, if all drawing objects are on page.
1034 bAllDrawObjsOnPage = false;
1035 break;
1036 }
1037 else if ( pAnchoredDrawObj->IsOutsidePage() )
1038 {
1039 bAllDrawObjsOnPage = false;
1040 break;
1041 }
1042 }
1043 else
1044 {
1045 // contact object of drawing object doesn't exists.
1046 // Thus, the drawing object isn't yet positioned.
1047 // Thus, it isn't known, if all drawing objects are on page.
1048 bAllDrawObjsOnPage = false;
1049 break;
1050 }
1051 }
1052 }
1053 }
1054
1055 return bAllDrawObjsOnPage;
1056 }
1057 }
1058 // <--
1059
1060 // eof
1061