1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: callnk.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
35 #include <hintids.hxx>
37 #ifndef _COM_SUN_STAR_I18N_SCRIPTTYPE_HDL_
38 #include <com/sun/star/i18n/ScriptType.hdl>
40 #include <fmtcntnt.hxx>
41 #include <txatbase.hxx>
51 #include <fmtfsize.hxx>
54 #include <breakit.hxx>
56 #include<vcl/window.hxx>
59 SwCallLink::SwCallLink( SwCrsrShell
& rSh
, ULONG nAktNode
, xub_StrLen nAktCntnt
,
60 BYTE nAktNdTyp
, long nLRPos
, bool bAktSelection
)
61 : rShell( rSh
), nNode( nAktNode
), nCntnt( nAktCntnt
),
62 nNdTyp( nAktNdTyp
), nLeftFrmPos( nLRPos
),
63 bHasSelection( bAktSelection
)
68 SwCallLink::SwCallLink( SwCrsrShell
& rSh
)
71 // SPoint-Werte vom aktuellen Cursor merken
72 SwPaM
* pCrsr
= rShell
.IsTableMode() ? rShell
.GetTblCrs() : rShell
.GetCrsr();
73 SwNode
& rNd
= pCrsr
->GetPoint()->nNode
.GetNode();
74 nNode
= rNd
.GetIndex();
75 nCntnt
= pCrsr
->GetPoint()->nContent
.GetIndex();
76 nNdTyp
= rNd
.GetNodeType();
77 bHasSelection
= ( *pCrsr
->GetPoint() != *pCrsr
->GetMark() );
79 if( ND_TEXTNODE
& nNdTyp
)
80 nLeftFrmPos
= SwCallLink::GetFrm( (SwTxtNode
&)rNd
, nCntnt
,
81 !rShell
.ActionPend() );
86 // eine Sonderbehandlung fuer die SwFeShell: diese setzt beim Loeschen
87 // der Kopf-/Fusszeile, Fussnoten den Cursor auf NULL (Node + Content)
88 // steht der Cursor auf keinem CntntNode, wird sich das im NdType
90 if( ND_CONTENTNODE
& nNdTyp
)
96 SwCallLink::~SwCallLink()
98 if( !nNdTyp
|| !rShell
.bCallChgLnk
) // siehe ctor
101 // wird ueber Nodes getravellt, Formate ueberpruefen und im neuen
102 // Node wieder anmelden
103 SwPaM
* pCurCrsr
= rShell
.IsTableMode() ? rShell
.GetTblCrs() : rShell
.GetCrsr();
104 SwCntntNode
* pCNd
= pCurCrsr
->GetCntntNode();
108 bool bUpdatedTable
= false;
109 SwFrm
*myFrm
=pCNd
->GetFrm();
112 // We need to emulated a change of the row height in order
113 // to have the complete row redrawn
114 SwRowFrm
* pRow
= myFrm
->FindRowFrm( );
117 const SwTableLine
* pLine
= pRow
->GetTabLine( );
118 SwFmtFrmSize pSize
= pLine
->GetFrmFmt( )->GetFrmSize( );
119 pRow
->Modify( NULL
, &pSize
);
121 bUpdatedTable
= true;
125 const SwDoc
*pDoc
=rShell
.GetDoc();
126 const SwCntntNode
*pNode
=(pDoc
!=NULL
?pDoc
->GetNodes()[nNode
]->GetCntntNode():NULL
);
129 SwFrm
*myFrm2
=pNode
->GetFrm();
132 // We need to emulated a change of the row height in order
133 // to have the complete row redrawn
134 SwRowFrm
* pRow
= myFrm2
->FindRowFrm();
137 const SwTableLine
* pLine
= pRow
->GetTabLine( );
138 SwFmtFrmSize pSize
= pLine
->GetFrmFmt( )->GetFrmSize( );
139 pRow
->Modify( NULL
, &pSize
);
141 bUpdatedTable
= true;
147 rShell
.GetWin( )->Invalidate( 0 );
149 xub_StrLen nCmp
, nAktCntnt
= pCurCrsr
->GetPoint()->nContent
.GetIndex();
150 USHORT nNdWhich
= pCNd
->GetNodeType();
151 ULONG nAktNode
= pCurCrsr
->GetPoint()->nNode
.GetIndex();
153 // melde die Shell beim akt. Node als abhaengig an, dadurch koennen
154 // alle Attribut-Aenderungen ueber den Link weiter gemeldet werden.
155 pCNd
->Add( &rShell
);
157 if( nNdTyp
!= nNdWhich
|| nNode
!= nAktNode
)
159 /* immer, wenn zwischen Nodes gesprungen wird, kann es
160 * vorkommen, das neue Attribute gelten; die Text-Attribute.
161 * Es muesste also festgestellt werden, welche Attribute
162 * jetzt gelten; das kann auch gleich der Handler machen
166 else if( !bHasSelection
!= !(*pCurCrsr
->GetPoint() != *pCurCrsr
->GetMark()) )
168 // always call change link when selection changes
171 else if( rShell
.aChgLnk
.IsSet() && ND_TEXTNODE
== nNdWhich
&&
172 nCntnt
!= nAktCntnt
)
174 // nur wenn mit Left/right getravellt, dann Text-Hints pruefen
175 // und sich nicht der Frame geaendert hat (Spalten!)
176 if( nLeftFrmPos
== SwCallLink::GetFrm( (SwTxtNode
&)*pCNd
, nAktCntnt
,
177 !rShell
.ActionPend() ) &&
178 (( nCmp
= nCntnt
) + 1 == nAktCntnt
|| // Right
179 nCntnt
-1 == ( nCmp
= nAktCntnt
)) ) // Left
181 if( nCmp
== nAktCntnt
&& pCurCrsr
->HasMark() ) // left & Sele
183 if ( ((SwTxtNode
*)pCNd
)->HasHints() )
186 const SwpHints
&rHts
= ((SwTxtNode
*)pCNd
)->GetSwpHints();
189 const xub_StrLen
*pEnd
;
191 for( n
= 0; n
< rHts
.Count(); n
++ )
193 const SwTxtAttr
* pHt
= rHts
[ n
];
194 pEnd
= pHt
->GetEnd();
195 nStart
= *pHt
->GetStart();
197 // nur Start oder Start und Ende gleich, dann immer
198 // beim Ueberlaufen von Start callen
199 if( ( !pEnd
|| ( nStart
== *pEnd
) ) &&
200 ( nStart
== nCntnt
|| nStart
== nAktCntnt
) )
206 // hat das Attribut einen Bereich und dieser nicht leer
207 else if( pEnd
&& nStart
< *pEnd
&&
208 // dann teste, ob ueber Start/Ende getravellt wurde
210 ( pHt
->DontExpand() ? nCmp
== *pEnd
-1
220 if( pBreakIt
->GetBreakIter().is() )
222 const String
& rTxt
= ((SwTxtNode
*)pCNd
)->GetTxt();
224 pBreakIt
->GetBreakIter()->getScriptType( rTxt
, nCmp
)
225 != pBreakIt
->GetBreakIter()->getScriptType( rTxt
, nCmp
- 1 ))
233 /* wenn mit Home/End/.. mehr als 1 Zeichen getravellt, dann
234 * immer den ChgLnk rufen, denn es kann hier nicht
235 * festgestellt werden, was sich geaendert; etwas kann
242 const SwFlyFrm
*pFlyFrm
;
243 if( !rShell
.ActionPend() && 0 != ( pFrm
= pCNd
->GetFrm(0,0,FALSE
) ) &&
244 0 != ( pFlyFrm
= pFrm
->FindFlyFrm() ) && !rShell
.IsTableMode() )
246 const SwNodeIndex
* pIndex
= pFlyFrm
->GetFmt()->GetCntnt().GetCntntIdx();
247 ASSERT( pIndex
, "Fly ohne Cntnt" );
248 const SwNode
& rStNd
= pIndex
->GetNode();
250 if( rStNd
.EndOfSectionNode()->StartOfSectionIndex() > nNode
||
251 nNode
> rStNd
.EndOfSectionIndex() )
252 rShell
.GetFlyMacroLnk().Call( (void*)pFlyFrm
->GetFmt() );
256 long SwCallLink::GetFrm( SwTxtNode
& rNd
, xub_StrLen nCntPos
, BOOL bCalcFrm
)
258 SwTxtFrm
* pFrm
= (SwTxtFrm
*)rNd
.GetFrm(0,0,bCalcFrm
), *pNext
= pFrm
;
259 if ( pFrm
&& !pFrm
->IsHiddenNow() )
261 if( pFrm
->HasFollow() )
262 while( 0 != ( pNext
= (SwTxtFrm
*)pFrm
->GetFollow() ) &&
263 nCntPos
>= pNext
->GetOfst() )
266 return pFrm
->Frm().Left();