xref: /AOO41X/main/sw/source/core/edit/edsect.cxx (revision efeef26f81c84063fb0a91bde3856d4a51172d90)
1*efeef26fSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*efeef26fSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*efeef26fSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*efeef26fSAndrew Rist  * distributed with this work for additional information
6*efeef26fSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*efeef26fSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*efeef26fSAndrew Rist  * "License"); you may not use this file except in compliance
9*efeef26fSAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11*efeef26fSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13*efeef26fSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*efeef26fSAndrew Rist  * software distributed under the License is distributed on an
15*efeef26fSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*efeef26fSAndrew Rist  * KIND, either express or implied.  See the License for the
17*efeef26fSAndrew Rist  * specific language governing permissions and limitations
18*efeef26fSAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20*efeef26fSAndrew Rist  *************************************************************/
21*efeef26fSAndrew Rist 
22*efeef26fSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sw.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <editsh.hxx>
28cdf0e10cSrcweir #include <doc.hxx>
29cdf0e10cSrcweir #include <IDocumentUndoRedo.hxx>
30cdf0e10cSrcweir #include <pam.hxx>
31cdf0e10cSrcweir #include <docary.hxx>
32cdf0e10cSrcweir #include <swundo.hxx>		// fuer die UndoIds
33cdf0e10cSrcweir #include <section.hxx>
34cdf0e10cSrcweir #include <edimp.hxx>
35cdf0e10cSrcweir #include <sectfrm.hxx>		// SwSectionFrm
36cdf0e10cSrcweir #include <cntfrm.hxx>		// SwCntntFrm
37cdf0e10cSrcweir #include <tabfrm.hxx>		// SwTabFrm
38cdf0e10cSrcweir #include <rootfrm.hxx>      // SwRootFrm
39cdf0e10cSrcweir 
40cdf0e10cSrcweir 
41cdf0e10cSrcweir SwSection const*
InsertSection(SwSectionData & rNewData,SfxItemSet const * const pAttr)42cdf0e10cSrcweir SwEditShell::InsertSection(
43cdf0e10cSrcweir         SwSectionData & rNewData, SfxItemSet const*const pAttr)
44cdf0e10cSrcweir {
45cdf0e10cSrcweir 	const SwSection* pRet = 0;
46cdf0e10cSrcweir 	if( !IsTableMode() )
47cdf0e10cSrcweir 	{
48cdf0e10cSrcweir 		StartAllAction();
49cdf0e10cSrcweir         GetDoc()->GetIDocumentUndoRedo().StartUndo( UNDO_INSSECTION, NULL );
50cdf0e10cSrcweir 
51cdf0e10cSrcweir 		FOREACHPAM_START(this)
52cdf0e10cSrcweir             SwSection const*const pNew =
53cdf0e10cSrcweir                 GetDoc()->InsertSwSection( *PCURCRSR, rNewData, 0, pAttr );
54cdf0e10cSrcweir 			if( !pRet )
55cdf0e10cSrcweir 				pRet = pNew;
56cdf0e10cSrcweir 		FOREACHPAM_END()
57cdf0e10cSrcweir 
58cdf0e10cSrcweir         GetDoc()->GetIDocumentUndoRedo().EndUndo( UNDO_INSSECTION, NULL );
59cdf0e10cSrcweir 		EndAllAction();
60cdf0e10cSrcweir 	}
61cdf0e10cSrcweir 	return pRet;
62cdf0e10cSrcweir }
63cdf0e10cSrcweir 
64cdf0e10cSrcweir 
IsInsRegionAvailable() const65cdf0e10cSrcweir sal_Bool SwEditShell::IsInsRegionAvailable() const
66cdf0e10cSrcweir {
67cdf0e10cSrcweir 	if( IsTableMode() )
68cdf0e10cSrcweir 		return sal_False;
69cdf0e10cSrcweir 	SwPaM* pCrsr = GetCrsr();
70cdf0e10cSrcweir 	if( pCrsr->GetNext() != pCrsr )
71cdf0e10cSrcweir 		return sal_False;
72cdf0e10cSrcweir 	if( pCrsr->HasMark() )
73cdf0e10cSrcweir 		return 0 != GetDoc()->IsInsRegionAvailable( *pCrsr );
74cdf0e10cSrcweir 
75cdf0e10cSrcweir 	return sal_True;
76cdf0e10cSrcweir }
77cdf0e10cSrcweir 
78cdf0e10cSrcweir 
GetCurrSection() const79cdf0e10cSrcweir const SwSection* SwEditShell::GetCurrSection() const
80cdf0e10cSrcweir {
81cdf0e10cSrcweir 	if( IsTableMode() )
82cdf0e10cSrcweir 		return 0;
83cdf0e10cSrcweir 
84cdf0e10cSrcweir 	return GetDoc()->GetCurrSection( *GetCrsr()->GetPoint() );
85cdf0e10cSrcweir }
86cdf0e10cSrcweir 
87cdf0e10cSrcweir /*-----------------17.03.99 11:53-------------------
88cdf0e10cSrcweir  * SwEditShell::GetAnySection liefert den fuer Spalten
89cdf0e10cSrcweir  * zustaendigen Bereich, bei Fussnoten kann es nicht der
90cdf0e10cSrcweir  * Bereich innerhalb der Fussnote sein.
91cdf0e10cSrcweir  * --------------------------------------------------*/
92cdf0e10cSrcweir 
GetAnySection(sal_Bool bOutOfTab,const Point * pPt) const93cdf0e10cSrcweir const SwSection* SwEditShell::GetAnySection( sal_Bool bOutOfTab, const Point* pPt ) const
94cdf0e10cSrcweir {
95cdf0e10cSrcweir     SwFrm *pFrm;
96cdf0e10cSrcweir 	if ( pPt )
97cdf0e10cSrcweir 	{
98cdf0e10cSrcweir 		SwPosition aPos( *GetCrsr()->GetPoint() );
99cdf0e10cSrcweir 		Point aPt( *pPt );
100cdf0e10cSrcweir 		GetLayout()->GetCrsrOfst( &aPos, aPt );
101cdf0e10cSrcweir 		SwCntntNode *pNd = aPos.nNode.GetNode().GetCntntNode();
102cdf0e10cSrcweir 		pFrm = pNd->getLayoutFrm( GetLayout(), pPt );
103cdf0e10cSrcweir 	}
104cdf0e10cSrcweir 	else
105cdf0e10cSrcweir 		pFrm = GetCurrFrm( sal_False );
106cdf0e10cSrcweir 
107cdf0e10cSrcweir 	if( bOutOfTab && pFrm )
108cdf0e10cSrcweir 		pFrm = pFrm->FindTabFrm();
109cdf0e10cSrcweir 	if( pFrm && pFrm->IsInSct() )
110cdf0e10cSrcweir 	{
111cdf0e10cSrcweir 		SwSectionFrm* pSect = pFrm->FindSctFrm();
112cdf0e10cSrcweir 		ASSERT( pSect, "GetAnySection: Where's my Sect?" );
113cdf0e10cSrcweir 		if( pSect->IsInFtn() && pSect->GetUpper()->IsInSct() )
114cdf0e10cSrcweir 		{
115cdf0e10cSrcweir 			pSect = pSect->GetUpper()->FindSctFrm();
116cdf0e10cSrcweir 			ASSERT( pSect, "GetAnySection: Where's my SectFrm?" );
117cdf0e10cSrcweir 		}
118cdf0e10cSrcweir 		return pSect->GetSection();
119cdf0e10cSrcweir 	}
120cdf0e10cSrcweir 	return NULL;
121cdf0e10cSrcweir }
122cdf0e10cSrcweir 
GetSectionFmtCount() const123cdf0e10cSrcweir sal_uInt16 SwEditShell::GetSectionFmtCount() const
124cdf0e10cSrcweir {
125cdf0e10cSrcweir 	return GetDoc()->GetSections().Count();
126cdf0e10cSrcweir }
127cdf0e10cSrcweir 
128cdf0e10cSrcweir 
IsAnySectionInDoc(sal_Bool bChkReadOnly,sal_Bool bChkHidden,sal_Bool bChkTOX) const129cdf0e10cSrcweir sal_Bool SwEditShell::IsAnySectionInDoc( sal_Bool bChkReadOnly, sal_Bool bChkHidden, sal_Bool bChkTOX ) const
130cdf0e10cSrcweir {
131cdf0e10cSrcweir 	const SwSectionFmts& rFmts = GetDoc()->GetSections();
132cdf0e10cSrcweir 	sal_uInt16 nCnt = rFmts.Count();
133cdf0e10cSrcweir 	sal_uInt16 n;
134cdf0e10cSrcweir 
135cdf0e10cSrcweir 	for( n = 0; n < nCnt; ++n )
136cdf0e10cSrcweir 	{
137cdf0e10cSrcweir 		SectionType eTmpType;
138cdf0e10cSrcweir 		const SwSectionFmt* pFmt = rFmts[ n ];
139cdf0e10cSrcweir 		if( pFmt->IsInNodesArr() &&
140cdf0e10cSrcweir 			(bChkTOX  ||
141cdf0e10cSrcweir 				( (eTmpType = pFmt->GetSection()->GetType()) != TOX_CONTENT_SECTION
142cdf0e10cSrcweir 				  && TOX_HEADER_SECTION != eTmpType ) ) )
143cdf0e10cSrcweir 		{
144cdf0e10cSrcweir 			const SwSection& rSect = *rFmts[ n ]->GetSection();
145cdf0e10cSrcweir 			if( (!bChkReadOnly && !bChkHidden ) ||
146cdf0e10cSrcweir 				(bChkReadOnly && rSect.IsProtectFlag() ) ||
147cdf0e10cSrcweir 				(bChkHidden && rSect.IsHiddenFlag() ) )
148cdf0e10cSrcweir 				break;
149cdf0e10cSrcweir 		}
150cdf0e10cSrcweir 	}
151cdf0e10cSrcweir 	return n != nCnt;
152cdf0e10cSrcweir }
153cdf0e10cSrcweir 
GetSectionFmtPos(const SwSectionFmt & rFmt) const154cdf0e10cSrcweir sal_uInt16 SwEditShell::GetSectionFmtPos( const SwSectionFmt& rFmt ) const
155cdf0e10cSrcweir {
156cdf0e10cSrcweir 	SwSectionFmt* pFmt = (SwSectionFmt*)&rFmt;
157cdf0e10cSrcweir 	return GetDoc()->GetSections().GetPos( pFmt );
158cdf0e10cSrcweir }
159cdf0e10cSrcweir 
GetSectionFmt(sal_uInt16 nFmt) const160cdf0e10cSrcweir const SwSectionFmt& SwEditShell::GetSectionFmt( sal_uInt16 nFmt ) const
161cdf0e10cSrcweir {
162cdf0e10cSrcweir 	return *GetDoc()->GetSections()[ nFmt ];
163cdf0e10cSrcweir }
164cdf0e10cSrcweir 
165cdf0e10cSrcweir 
DelSectionFmt(sal_uInt16 nFmt)166cdf0e10cSrcweir void SwEditShell::DelSectionFmt( sal_uInt16 nFmt )
167cdf0e10cSrcweir {
168cdf0e10cSrcweir 	StartAllAction();
169cdf0e10cSrcweir 	GetDoc()->DelSectionFmt( GetDoc()->GetSections()[ nFmt ] );
170cdf0e10cSrcweir 	// rufe das AttrChangeNotify auf der UI-Seite.
171cdf0e10cSrcweir 	CallChgLnk();
172cdf0e10cSrcweir 	EndAllAction();
173cdf0e10cSrcweir }
174cdf0e10cSrcweir 
175cdf0e10cSrcweir 
UpdateSection(sal_uInt16 const nSect,SwSectionData & rNewData,SfxItemSet const * const pAttr)176cdf0e10cSrcweir void SwEditShell::UpdateSection(sal_uInt16 const nSect,
177cdf0e10cSrcweir         SwSectionData & rNewData, SfxItemSet const*const pAttr)
178cdf0e10cSrcweir {
179cdf0e10cSrcweir 	StartAllAction();
180cdf0e10cSrcweir     GetDoc()->UpdateSection( nSect, rNewData, pAttr );
181cdf0e10cSrcweir 	// rufe das AttrChangeNotify auf der UI-Seite.
182cdf0e10cSrcweir 	CallChgLnk();
183cdf0e10cSrcweir 	EndAllAction();
184cdf0e10cSrcweir }
185cdf0e10cSrcweir 
GetUniqueSectionName(const String * pChkStr) const186cdf0e10cSrcweir String SwEditShell::GetUniqueSectionName( const String* pChkStr ) const
187cdf0e10cSrcweir {
188cdf0e10cSrcweir 	return GetDoc()->GetUniqueSectionName( pChkStr );
189cdf0e10cSrcweir }
190cdf0e10cSrcweir 
SetSectionAttr(const SfxItemSet & rSet,SwSectionFmt * pSectFmt)191cdf0e10cSrcweir void SwEditShell::SetSectionAttr( const SfxItemSet& rSet,
192cdf0e10cSrcweir 									SwSectionFmt* pSectFmt )
193cdf0e10cSrcweir {
194cdf0e10cSrcweir 	if( pSectFmt )
195cdf0e10cSrcweir 		_SetSectionAttr( *pSectFmt, rSet );
196cdf0e10cSrcweir 	else
197cdf0e10cSrcweir 	{
198cdf0e10cSrcweir 		// for all section in the selection
199cdf0e10cSrcweir 
200cdf0e10cSrcweir 		FOREACHPAM_START(this)
201cdf0e10cSrcweir 
202cdf0e10cSrcweir 			const SwPosition* pStt = PCURCRSR->Start(),
203cdf0e10cSrcweir 							* pEnd = PCURCRSR->End();
204cdf0e10cSrcweir 
205cdf0e10cSrcweir 			const SwSectionNode* pSttSectNd = pStt->nNode.GetNode().FindSectionNode(),
206cdf0e10cSrcweir 							   * pEndSectNd = pEnd->nNode.GetNode().FindSectionNode();
207cdf0e10cSrcweir 
208cdf0e10cSrcweir 			if( pSttSectNd || pEndSectNd )
209cdf0e10cSrcweir 			{
210cdf0e10cSrcweir 				if( pSttSectNd )
211cdf0e10cSrcweir 					_SetSectionAttr( *pSttSectNd->GetSection().GetFmt(),
212cdf0e10cSrcweir 									rSet );
213cdf0e10cSrcweir 				if( pEndSectNd && pSttSectNd != pEndSectNd )
214cdf0e10cSrcweir 					_SetSectionAttr( *pEndSectNd->GetSection().GetFmt(),
215cdf0e10cSrcweir 									rSet );
216cdf0e10cSrcweir 
217cdf0e10cSrcweir 				if( pSttSectNd && pEndSectNd )
218cdf0e10cSrcweir 				{
219cdf0e10cSrcweir 					SwNodeIndex aSIdx( pStt->nNode );
220cdf0e10cSrcweir 					SwNodeIndex aEIdx( pEnd->nNode );
221cdf0e10cSrcweir 					if( pSttSectNd->EndOfSectionIndex() <
222cdf0e10cSrcweir 						pEndSectNd->GetIndex() )
223cdf0e10cSrcweir 					{
224cdf0e10cSrcweir 						aSIdx = pSttSectNd->EndOfSectionIndex() + 1;
225cdf0e10cSrcweir 						aEIdx = *pEndSectNd;
226cdf0e10cSrcweir 					}
227cdf0e10cSrcweir 
228cdf0e10cSrcweir 					while( aSIdx < aEIdx )
229cdf0e10cSrcweir 					{
230cdf0e10cSrcweir 						if( 0 != (pSttSectNd = aSIdx.GetNode().GetSectionNode())
231cdf0e10cSrcweir 							|| ( aSIdx.GetNode().IsEndNode() &&
232cdf0e10cSrcweir 								0 != ( pSttSectNd = aSIdx.GetNode().
233cdf0e10cSrcweir                                     StartOfSectionNode()->GetSectionNode())) )
234cdf0e10cSrcweir 							_SetSectionAttr( *pSttSectNd->GetSection().GetFmt(),
235cdf0e10cSrcweir 											rSet );
236cdf0e10cSrcweir 						aSIdx++;
237cdf0e10cSrcweir 					}
238cdf0e10cSrcweir 				}
239cdf0e10cSrcweir 			}
240cdf0e10cSrcweir 
241cdf0e10cSrcweir 		FOREACHPAM_END()
242cdf0e10cSrcweir 	}
243cdf0e10cSrcweir }
244cdf0e10cSrcweir 
_SetSectionAttr(SwSectionFmt & rSectFmt,const SfxItemSet & rSet)245cdf0e10cSrcweir void SwEditShell::_SetSectionAttr( SwSectionFmt& rSectFmt,
246cdf0e10cSrcweir 									const SfxItemSet& rSet )
247cdf0e10cSrcweir {
248cdf0e10cSrcweir 	StartAllAction();
249cdf0e10cSrcweir 	if(SFX_ITEM_SET == rSet.GetItemState(RES_CNTNT, sal_False))
250cdf0e10cSrcweir 	{
251cdf0e10cSrcweir 		SfxItemSet aSet(rSet);
252cdf0e10cSrcweir 		aSet.ClearItem(RES_CNTNT);
253cdf0e10cSrcweir 		GetDoc()->SetAttr( aSet, rSectFmt );
254cdf0e10cSrcweir 	}
255cdf0e10cSrcweir 	else
256cdf0e10cSrcweir 		GetDoc()->SetAttr( rSet, rSectFmt );
257cdf0e10cSrcweir 
258cdf0e10cSrcweir 	// rufe das AttrChangeNotify auf der UI-Seite.
259cdf0e10cSrcweir 	CallChgLnk();
260cdf0e10cSrcweir 	EndAllAction();
261cdf0e10cSrcweir }
262cdf0e10cSrcweir 
263cdf0e10cSrcweir // search inside the cursor selection for full selected sections.
264cdf0e10cSrcweir // if any part of section in the selection return 0.
265cdf0e10cSrcweir // if more than one in the selection return the count
GetFullSelectedSectionCount() const266cdf0e10cSrcweir sal_uInt16 SwEditShell::GetFullSelectedSectionCount() const
267cdf0e10cSrcweir {
268cdf0e10cSrcweir 	sal_uInt16 nRet = 0;
269cdf0e10cSrcweir 	FOREACHPAM_START(this)
270cdf0e10cSrcweir 
271cdf0e10cSrcweir 		const SwPosition* pStt = PCURCRSR->Start(),
272cdf0e10cSrcweir 						* pEnd = PCURCRSR->End();
273cdf0e10cSrcweir 		const SwCntntNode* pCNd;
274cdf0e10cSrcweir 		// check the selection, if Start at Node begin and End at Node end
275cdf0e10cSrcweir 		if( pStt->nContent.GetIndex() ||
276cdf0e10cSrcweir 			( 0 == ( pCNd = pEnd->nNode.GetNode().GetCntntNode() )) ||
277cdf0e10cSrcweir 			pCNd->Len() != pEnd->nContent.GetIndex() )
278cdf0e10cSrcweir 		{
279cdf0e10cSrcweir 			nRet = 0;
280cdf0e10cSrcweir 			break;
281cdf0e10cSrcweir 		}
282cdf0e10cSrcweir 
283cdf0e10cSrcweir // !!!!!!!!!!!!!!!!!!!!!!!!!!
284cdf0e10cSrcweir // what about table at start or end ?
285cdf0e10cSrcweir //		There is no selection possible!
286cdf0e10cSrcweir // What about only a table inside the section ?
287cdf0e10cSrcweir //		There is only a table selection possible!
288cdf0e10cSrcweir 
289cdf0e10cSrcweir 		SwNodeIndex aSIdx( pStt->nNode, -1 ), aEIdx( pEnd->nNode, +1 );
290cdf0e10cSrcweir 		if( !aSIdx.GetNode().IsSectionNode() ||
291cdf0e10cSrcweir 			!aEIdx.GetNode().IsEndNode() ||
292cdf0e10cSrcweir             !aEIdx.GetNode().StartOfSectionNode()->IsSectionNode() )
293cdf0e10cSrcweir 		{
294cdf0e10cSrcweir 			nRet = 0;
295cdf0e10cSrcweir 			break;
296cdf0e10cSrcweir 		}
297cdf0e10cSrcweir 
298cdf0e10cSrcweir 		++nRet;
299cdf0e10cSrcweir         if( &aSIdx.GetNode() != aEIdx.GetNode().StartOfSectionNode() )
300cdf0e10cSrcweir 			++nRet;
301cdf0e10cSrcweir 
302cdf0e10cSrcweir 	FOREACHPAM_END()
303cdf0e10cSrcweir 	return nRet;
304cdf0e10cSrcweir }
305cdf0e10cSrcweir 
306cdf0e10cSrcweir 
307cdf0e10cSrcweir /**
308cdf0e10cSrcweir  * Find the suitable node for a special insert (alt-enter).
309cdf0e10cSrcweir  * This should enable inserting text before/after sections and tables.
310cdf0e10cSrcweir  *
311cdf0e10cSrcweir  * A node is found if:
312cdf0e10cSrcweir  * 1) the innermost table/section is not in a write-protected area
313cdf0e10cSrcweir  * 2) pCurrentPos is at or just before an end node
314cdf0e10cSrcweir  *    (or at or just after a start node)
315cdf0e10cSrcweir  * 3) there are only start/end nodes between pCurrentPos and the innermost
316cdf0e10cSrcweir  *    table/section
317cdf0e10cSrcweir  *
318cdf0e10cSrcweir  * If a suitable node is found, an SwNode* is returned; else it is NULL.
319cdf0e10cSrcweir  */
lcl_SpecialInsertNode(const SwPosition * pCurrentPos)320cdf0e10cSrcweir const SwNode* lcl_SpecialInsertNode(const SwPosition* pCurrentPos)
321cdf0e10cSrcweir {
322cdf0e10cSrcweir     const SwNode* pReturn = NULL;
323cdf0e10cSrcweir 
324cdf0e10cSrcweir     // the current position
325cdf0e10cSrcweir     //    const SwPosition* pCurrentPos = GetCrsr()->GetPoint();
326cdf0e10cSrcweir     DBG_ASSERT( pCurrentPos != NULL, "Strange, we have no position!" );
327cdf0e10cSrcweir     const SwNode& rCurrentNode = pCurrentPos->nNode.GetNode();
328cdf0e10cSrcweir 
329cdf0e10cSrcweir 
330cdf0e10cSrcweir     // find innermost section or table.  At the end of this scope,
331cdf0e10cSrcweir     // pInntermostNode contain the section/table before/after which we should
332cdf0e10cSrcweir     // insert our empty paragraph, or it will be NULL if none is found.
333cdf0e10cSrcweir     const SwNode* pInnermostNode = NULL;
334cdf0e10cSrcweir     {
335cdf0e10cSrcweir         const SwNode* pTableNode = rCurrentNode.FindTableNode();
336cdf0e10cSrcweir         const SwNode* pSectionNode = rCurrentNode.FindSectionNode();
337cdf0e10cSrcweir 
338cdf0e10cSrcweir         // find the table/section which is close
339cdf0e10cSrcweir         if( pTableNode == NULL )
340cdf0e10cSrcweir             pInnermostNode = pSectionNode;
341cdf0e10cSrcweir         else if ( pSectionNode == NULL )
342cdf0e10cSrcweir             pInnermostNode = pTableNode;
343cdf0e10cSrcweir         else
344cdf0e10cSrcweir         {
345cdf0e10cSrcweir             // compare and choose the larger one
346cdf0e10cSrcweir             pInnermostNode =
347cdf0e10cSrcweir                 ( pSectionNode->GetIndex() > pTableNode->GetIndex() )
348cdf0e10cSrcweir                 ? pSectionNode : pTableNode;
349cdf0e10cSrcweir         }
350cdf0e10cSrcweir     }
351cdf0e10cSrcweir 
352cdf0e10cSrcweir     // The previous version had a check to skip empty read-only sections. Those
353cdf0e10cSrcweir     // shouldn't occur, so we only need to check whether our pInnermostNode is
354cdf0e10cSrcweir     // inside a protected area.
355cdf0e10cSrcweir 
356cdf0e10cSrcweir     // Now, pInnermostNode is NULL or the innermost section or table node.
357cdf0e10cSrcweir     if( (pInnermostNode != NULL) && !pInnermostNode->IsProtect() )
358cdf0e10cSrcweir     {
359cdf0e10cSrcweir         DBG_ASSERT( pInnermostNode->IsTableNode() ||
360cdf0e10cSrcweir                     pInnermostNode->IsSectionNode(), "wrong node found" );
361cdf0e10cSrcweir         DBG_ASSERT( ( pInnermostNode->GetIndex() <= rCurrentNode.GetIndex() )&&
362cdf0e10cSrcweir                     ( pInnermostNode->EndOfSectionNode()->GetIndex() >=
363cdf0e10cSrcweir                       rCurrentNode.GetIndex() ), "wrong node found" );
364cdf0e10cSrcweir 
365cdf0e10cSrcweir         // we now need to find the possible start/end positions
366cdf0e10cSrcweir 
367cdf0e10cSrcweir         // we found a start if
368cdf0e10cSrcweir         // - we're at or just before a start node
369cdf0e10cSrcweir         // - there are only start nodes between the current and pInnermostNode
370cdf0e10cSrcweir         SwNodeIndex aBegin( pCurrentPos->nNode );
371cdf0e10cSrcweir         if( rCurrentNode.IsCntntNode() &&
372cdf0e10cSrcweir             (pCurrentPos->nContent.GetIndex() == 0))
373cdf0e10cSrcweir             aBegin--;
374cdf0e10cSrcweir         while( (aBegin != pInnermostNode->GetIndex()) &&
375cdf0e10cSrcweir                aBegin.GetNode().IsStartNode() )
376cdf0e10cSrcweir             aBegin--;
377cdf0e10cSrcweir         bool bStart = ( aBegin == pInnermostNode->GetIndex() );
378cdf0e10cSrcweir 
379cdf0e10cSrcweir         // we found an end if
380cdf0e10cSrcweir         // - we're at or just before an end node
381cdf0e10cSrcweir         // - there are only end nodes between the current node and
382cdf0e10cSrcweir         //   pInnermostNode's end node
383cdf0e10cSrcweir         SwNodeIndex aEnd( pCurrentPos->nNode );
384cdf0e10cSrcweir         if( rCurrentNode.IsCntntNode() &&
385cdf0e10cSrcweir             ( pCurrentPos->nContent.GetIndex() ==
386cdf0e10cSrcweir               rCurrentNode.GetCntntNode()->Len() ) )
387cdf0e10cSrcweir             aEnd++;
388cdf0e10cSrcweir         while( (aEnd != pInnermostNode->EndOfSectionNode()->GetIndex()) &&
389cdf0e10cSrcweir                aEnd.GetNode().IsEndNode() )
390cdf0e10cSrcweir             aEnd++;
391cdf0e10cSrcweir         bool bEnd = ( aEnd == pInnermostNode->EndOfSectionNode()->GetIndex() );
392cdf0e10cSrcweir 
393cdf0e10cSrcweir         // evalutate result: if both start + end, end is preferred
394cdf0e10cSrcweir         if( bEnd )
395cdf0e10cSrcweir             pReturn = pInnermostNode->EndOfSectionNode();
396cdf0e10cSrcweir         else if ( bStart )
397cdf0e10cSrcweir             pReturn = pInnermostNode;
398cdf0e10cSrcweir         // else pReturn = NULL;
399cdf0e10cSrcweir     }
400cdf0e10cSrcweir     // else: pReturn = NULL
401cdf0e10cSrcweir 
402cdf0e10cSrcweir 
403cdf0e10cSrcweir     DBG_ASSERT( ( pReturn == NULL ) || pReturn->IsStartNode() ||
404cdf0e10cSrcweir                                        pReturn->IsEndNode(),
405cdf0e10cSrcweir                 "SpecialInsertNode failed" );
406cdf0e10cSrcweir     return pReturn;
407cdf0e10cSrcweir }
408cdf0e10cSrcweir 
409cdf0e10cSrcweir 
410cdf0e10cSrcweir /** a node can be special-inserted (alt-Enter) whenever lcl_SpecialInsertNode
411cdf0e10cSrcweir     finds a suitable position
412cdf0e10cSrcweir */
CanSpecialInsert() const413cdf0e10cSrcweir bool SwEditShell::CanSpecialInsert() const
414cdf0e10cSrcweir {
415cdf0e10cSrcweir     return NULL != lcl_SpecialInsertNode( GetCrsr()->GetPoint() );
416cdf0e10cSrcweir }
417cdf0e10cSrcweir 
418cdf0e10cSrcweir 
419cdf0e10cSrcweir /** check whether a node cen be special-inserted (alt-Enter), and do so. Return
420cdf0e10cSrcweir     whether insertion was possible.
421cdf0e10cSrcweir  */
DoSpecialInsert()422cdf0e10cSrcweir bool SwEditShell::DoSpecialInsert()
423cdf0e10cSrcweir {
424cdf0e10cSrcweir     bool bRet = false;
425cdf0e10cSrcweir 
426cdf0e10cSrcweir     // get current node
427cdf0e10cSrcweir     SwPosition* pCursorPos = GetCrsr()->GetPoint();
428cdf0e10cSrcweir     const SwNode* pInsertNode = lcl_SpecialInsertNode( pCursorPos );
429cdf0e10cSrcweir     if( pInsertNode != NULL )
430cdf0e10cSrcweir     {
431cdf0e10cSrcweir 		StartAllAction();
432cdf0e10cSrcweir 
433cdf0e10cSrcweir         // adjust insert position to insert before start nodes and after end
434cdf0e10cSrcweir         // nodes
435cdf0e10cSrcweir         SwNodeIndex aInsertIndex( *pInsertNode,
436cdf0e10cSrcweir                                   pInsertNode->IsStartNode() ? -1 : 0 );
437cdf0e10cSrcweir         SwPosition aInsertPos( aInsertIndex );
438cdf0e10cSrcweir 
439cdf0e10cSrcweir         // insert a new text node, and set the cursor
440cdf0e10cSrcweir 		bRet = GetDoc()->AppendTxtNode( aInsertPos );
441cdf0e10cSrcweir 		*pCursorPos = aInsertPos;
442cdf0e10cSrcweir 
443cdf0e10cSrcweir 		// call AttrChangeNotify for the UI
444cdf0e10cSrcweir 		CallChgLnk();
445cdf0e10cSrcweir 
446cdf0e10cSrcweir 		EndAllAction();
447cdf0e10cSrcweir 	}
448cdf0e10cSrcweir 
449cdf0e10cSrcweir 	return bRet;
450cdf0e10cSrcweir }
451cdf0e10cSrcweir 
452