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 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 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 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 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 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 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 257 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 289 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