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