xref: /AOO41X/main/sw/source/core/doc/extinput.cxx (revision efeef26f81c84063fb0a91bde3856d4a51172d90)
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 <com/sun/star/i18n/ScriptType.hpp>
28 
29 #include <editeng/langitem.hxx>
30 #include <editeng/scripttypeitem.hxx>
31 
32 #include <vcl/keycodes.hxx>
33 #include <vcl/cmdevt.hxx>
34 
35 #include <hintids.hxx>
36 #include <extinput.hxx>
37 #include <doc.hxx>
38 #include <IDocumentUndoRedo.hxx>
39 #include <index.hxx>
40 #include <ndtxt.hxx>
41 #include <txtfrm.hxx>
42 #include <swundo.hxx>
43 
44 
45 using namespace ::com::sun::star;
46 
SwExtTextInput(const SwPaM & rPam,Ring * pRing)47 SwExtTextInput::SwExtTextInput( const SwPaM& rPam, Ring* pRing )
48     : SwPaM( *rPam.GetPoint(), (SwPaM*)pRing ),
49     eInputLanguage(LANGUAGE_DONTKNOW)
50 {
51     bIsOverwriteCursor = sal_False;
52     bInsText = sal_True;
53 }
54 
~SwExtTextInput()55 SwExtTextInput::~SwExtTextInput()
56 {
57     SwDoc *const pDoc = GetDoc();
58     if (pDoc->IsInDtor()) { return; /* #i58606# */ }
59 
60     SwTxtNode* pTNd = GetPoint()->nNode.GetNode().GetTxtNode();
61     if( pTNd )
62     {
63         SwIndex& rIdx = GetPoint()->nContent;
64         xub_StrLen nSttCnt = rIdx.GetIndex(),
65                    nEndCnt = GetMark()->nContent.GetIndex();
66         if( nEndCnt != nSttCnt )
67         {
68             if( nEndCnt < nSttCnt )
69             {
70                 xub_StrLen n = nEndCnt; nEndCnt = nSttCnt; nSttCnt = n;
71             }
72 
73             // damit Undo / Redlining usw. richtig funktioniert,
74             // muss ueber die Doc-Schnittstellen gegangen werden !!!
75             if(eInputLanguage != LANGUAGE_DONTKNOW)
76             {
77                 // --> FME 2005-02-11 #i41974# Only set language attribute
78                 // for CJK/CTL scripts.
79                 bool bLang = true;
80                 // <--
81                 sal_uInt16 nWhich = RES_CHRATR_LANGUAGE;
82                 switch(GetI18NScriptTypeOfLanguage(eInputLanguage))
83                 {
84                     case  i18n::ScriptType::ASIAN:     nWhich = RES_CHRATR_CJK_LANGUAGE; break;
85                     case  i18n::ScriptType::COMPLEX:   nWhich = RES_CHRATR_CTL_LANGUAGE; break;
86                     default: bLang = false;
87                 }
88                 if ( bLang )
89                 {
90                     SvxLanguageItem aLangItem( eInputLanguage, nWhich );
91                     pDoc->InsertPoolItem(*this, aLangItem, 0 );
92                 }
93             }
94             rIdx = nSttCnt;
95             String sTxt( pTNd->GetTxt().Copy( nSttCnt, nEndCnt - nSttCnt ));
96             if( bIsOverwriteCursor && sOverwriteText.Len() )
97             {
98                 xub_StrLen nLen = sTxt.Len();
99                 if( nLen > sOverwriteText.Len() )
100                 {
101                     rIdx += sOverwriteText.Len();
102                     pTNd->EraseText( rIdx, nLen - sOverwriteText.Len() );
103                     rIdx = nSttCnt;
104                     pTNd->ReplaceText( rIdx, sOverwriteText.Len(),
105                                             sOverwriteText );
106                     if( bInsText )
107                     {
108                         rIdx = nSttCnt;
109                         pDoc->GetIDocumentUndoRedo().StartUndo(
110                                 UNDO_OVERWRITE, NULL );
111                         pDoc->Overwrite( *this, sTxt.Copy( 0,
112                                                     sOverwriteText.Len() ));
113                         pDoc->InsertString( *this,
114                             sTxt.Copy( sOverwriteText.Len() ) );
115                         pDoc->GetIDocumentUndoRedo().EndUndo(
116                                 UNDO_OVERWRITE, NULL );
117                     }
118                 }
119                 else
120                 {
121                     pTNd->ReplaceText( rIdx, nLen,
122                             sOverwriteText.Copy( 0, nLen ));
123                     if( bInsText )
124                     {
125                         rIdx = nSttCnt;
126                         pDoc->Overwrite( *this, sTxt );
127                     }
128                 }
129             }
130             else
131             {
132                 pTNd->EraseText( rIdx, nEndCnt - nSttCnt );
133 
134                 if( bInsText )
135                 {
136                     pDoc->InsertString( *this, sTxt );
137                 }
138             }
139         }
140     }
141 }
142 
SetInputData(const CommandExtTextInputData & rData)143 void SwExtTextInput::SetInputData( const CommandExtTextInputData& rData )
144 {
145     SwTxtNode* pTNd = GetPoint()->nNode.GetNode().GetTxtNode();
146     if( pTNd )
147     {
148         xub_StrLen nSttCnt = GetPoint()->nContent.GetIndex(),
149                     nEndCnt = GetMark()->nContent.GetIndex();
150         if( nEndCnt < nSttCnt )
151         {
152             xub_StrLen n = nEndCnt; nEndCnt = nSttCnt; nSttCnt = n;
153         }
154 
155         SwIndex aIdx( pTNd, nSttCnt );
156         const String& rNewStr = rData.GetText();
157 
158         if( bIsOverwriteCursor && sOverwriteText.Len() )
159         {
160             xub_StrLen nReplace = nEndCnt - nSttCnt;
161             if( rNewStr.Len() < nReplace )
162             {
163                 // then we must insert from the saved original text
164                 // some characters
165                 nReplace = nReplace - rNewStr.Len();
166                 aIdx += rNewStr.Len();
167                 pTNd->ReplaceText( aIdx, nReplace,
168                             sOverwriteText.Copy( rNewStr.Len(), nReplace ));
169                 aIdx = nSttCnt;
170                 nReplace = rNewStr.Len();
171             }
172             else if( sOverwriteText.Len() < nReplace )
173             {
174                 nReplace = nReplace - sOverwriteText.Len();
175                 aIdx += sOverwriteText.Len();
176                 pTNd->EraseText( aIdx, nReplace );
177                 aIdx = nSttCnt;
178                 nReplace = sOverwriteText.Len();
179             }
180             else if( (nReplace = sOverwriteText.Len()) > rNewStr.Len() )
181                 nReplace = rNewStr.Len();
182 
183             pTNd->ReplaceText( aIdx, nReplace, rNewStr );
184             if( !HasMark() )
185                 SetMark();
186             GetMark()->nContent = aIdx;
187         }
188         else
189         {
190             if( nSttCnt < nEndCnt )
191             {
192                 pTNd->EraseText( aIdx, nEndCnt - nSttCnt );
193             }
194 
195             pTNd->InsertText( rNewStr, aIdx,
196                     IDocumentContentOperations::INS_EMPTYEXPAND );
197             if( !HasMark() )
198                 SetMark();
199         }
200 
201         GetPoint()->nContent = nSttCnt;
202 
203         if( aAttrs.Count() )
204             aAttrs.Remove( 0, aAttrs.Count() );
205         if( rData.GetTextAttr() )
206             aAttrs.Insert( rData.GetTextAttr(), rData.GetText().Len(), 0 );
207     }
208 }
209 
SetOverwriteCursor(sal_Bool bFlag)210 void SwExtTextInput::SetOverwriteCursor( sal_Bool bFlag )
211 {
212     bIsOverwriteCursor = bFlag;
213 
214     SwTxtNode* pTNd;
215     if( bIsOverwriteCursor &&
216         0 != (pTNd = GetPoint()->nNode.GetNode().GetTxtNode()) )
217     {
218         xub_StrLen nSttCnt = GetPoint()->nContent.GetIndex(),
219                     nEndCnt = GetMark()->nContent.GetIndex();
220         sOverwriteText = pTNd->GetTxt().Copy( nEndCnt < nSttCnt ? nEndCnt
221                                                                 : nSttCnt );
222         if( sOverwriteText.Len() )
223         {
224             xub_StrLen nInWrdAttrPos = sOverwriteText.Search( CH_TXTATR_INWORD ),
225                     nWrdAttrPos = sOverwriteText.Search( CH_TXTATR_BREAKWORD );
226             if( nWrdAttrPos < nInWrdAttrPos )
227                 nInWrdAttrPos = nWrdAttrPos;
228             if( STRING_NOTFOUND != nInWrdAttrPos )
229                 sOverwriteText.Erase( nInWrdAttrPos );
230         }
231     }
232 }
233 
234 // die Doc Schnittstellen:
235 
CreateExtTextInput(const SwPaM & rPam)236 SwExtTextInput* SwDoc::CreateExtTextInput( const SwPaM& rPam )
237 {
238     SwExtTextInput* pNew = new SwExtTextInput( rPam, pExtInputRing );
239     if( !pExtInputRing )
240         pExtInputRing = pNew;
241     pNew->SetMark();
242     return pNew;
243 }
244 
DeleteExtTextInput(SwExtTextInput * pDel)245 void SwDoc::DeleteExtTextInput( SwExtTextInput* pDel )
246 {
247     if( pDel == pExtInputRing )
248     {
249         if( pDel->GetNext() != pExtInputRing )
250             pExtInputRing = (SwPaM*)pDel->GetNext();
251         else
252             pExtInputRing = 0;
253     }
254     delete pDel;
255 }
256 
GetExtTextInput(const SwNode & rNd,xub_StrLen nCntntPos) const257 SwExtTextInput* SwDoc::GetExtTextInput( const SwNode& rNd,
258                                         xub_StrLen nCntntPos ) const
259 {
260     SwExtTextInput* pRet = 0;
261     if( pExtInputRing )
262     {
263         sal_uLong nNdIdx = rNd.GetIndex();
264         SwExtTextInput* pTmp = (SwExtTextInput*)pExtInputRing;
265         do {
266             sal_uLong nPt = pTmp->GetPoint()->nNode.GetIndex(),
267                   nMk = pTmp->GetMark()->nNode.GetIndex();
268             xub_StrLen nPtCnt = pTmp->GetPoint()->nContent.GetIndex(),
269                        nMkCnt = pTmp->GetMark()->nContent.GetIndex();
270 
271             if( nPt < nMk || ( nPt == nMk && nPtCnt < nMkCnt ))
272             {
273                 sal_uLong nTmp = nMk; nMk = nPt; nPt = nTmp;
274                 nTmp = nMkCnt; nMkCnt = nPtCnt; nPtCnt = (xub_StrLen)nTmp;
275             }
276 
277             if( nMk <= nNdIdx && nNdIdx <= nPt &&
278                 ( STRING_NOTFOUND == nCntntPos ||
279                     ( nMkCnt <= nCntntPos && nCntntPos <= nPtCnt )))
280             {
281                 pRet = pTmp;
282                 break;
283             }
284         } while( pExtInputRing != (pTmp = (SwExtTextInput*)pExtInputRing ) );
285     }
286     return pRet;
287 }
288 
GetExtTextInput() const289 SwExtTextInput* SwDoc::GetExtTextInput() const
290 {
291     ASSERT( !pExtInputRing || pExtInputRing == pExtInputRing->GetNext(),
292             "more then one InputEngine available" );
293     return (SwExtTextInput*)pExtInputRing;
294 }
295 
296 
297