Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include <com/sun/star/i18n/ScriptType.hpp>
31 : :
32 : : #include <editeng/langitem.hxx>
33 : : #include <editeng/scripttypeitem.hxx>
34 : :
35 : : #include <vcl/keycodes.hxx>
36 : : #include <vcl/cmdevt.hxx>
37 : :
38 : : #include <hintids.hxx>
39 : : #include <extinput.hxx>
40 : : #include <doc.hxx>
41 : : #include <IDocumentUndoRedo.hxx>
42 : : #include <index.hxx>
43 : : #include <ndtxt.hxx>
44 : : #include <txtfrm.hxx>
45 : : #include <swundo.hxx>
46 : :
47 : :
48 : : using namespace ::com::sun::star;
49 : :
50 : 0 : SwExtTextInput::SwExtTextInput( const SwPaM& rPam, Ring* pRing )
51 : 0 : : SwPaM( *rPam.GetPoint(), (SwPaM*)pRing ),
52 [ # # ][ # # ]: 0 : eInputLanguage(LANGUAGE_DONTKNOW)
53 : : {
54 : 0 : bIsOverwriteCursor = sal_False;
55 : 0 : bInsText = sal_True;
56 : 0 : }
57 : :
58 [ # # ][ # # ]: 0 : SwExtTextInput::~SwExtTextInput()
[ # # ]
59 : : {
60 : 0 : SwDoc *const pDoc = GetDoc();
61 [ # # ]: 0 : if (pDoc->IsInDtor()) { return; /* #i58606# */ }
62 : :
63 : 0 : SwTxtNode* pTNd = GetPoint()->nNode.GetNode().GetTxtNode();
64 [ # # ]: 0 : if( pTNd )
65 : : {
66 : 0 : SwIndex& rIdx = GetPoint()->nContent;
67 : 0 : xub_StrLen nSttCnt = rIdx.GetIndex(),
68 : 0 : nEndCnt = GetMark()->nContent.GetIndex();
69 [ # # ]: 0 : if( nEndCnt != nSttCnt )
70 : : {
71 [ # # ]: 0 : if( nEndCnt < nSttCnt )
72 : : {
73 : 0 : xub_StrLen n = nEndCnt; nEndCnt = nSttCnt; nSttCnt = n;
74 : : }
75 : :
76 : : // In order to get Undo/Redlining etc. working correctly,
77 : : // we need to go through the Doc interface
78 [ # # ]: 0 : if(eInputLanguage != LANGUAGE_DONTKNOW)
79 : : {
80 : : // #i41974# Only set language attribute
81 : : // for CJK/CTL scripts.
82 : 0 : bool bLang = true;
83 : 0 : sal_uInt16 nWhich = RES_CHRATR_LANGUAGE;
84 [ # # ]: 0 : switch(GetI18NScriptTypeOfLanguage(eInputLanguage))
[ # # # ]
85 : : {
86 : 0 : case i18n::ScriptType::ASIAN: nWhich = RES_CHRATR_CJK_LANGUAGE; break;
87 : 0 : case i18n::ScriptType::COMPLEX: nWhich = RES_CHRATR_CTL_LANGUAGE; break;
88 : 0 : default: bLang = false;
89 : : }
90 [ # # ]: 0 : if ( bLang )
91 : : {
92 [ # # ]: 0 : SvxLanguageItem aLangItem( eInputLanguage, nWhich );
93 [ # # ][ # # ]: 0 : pDoc->InsertPoolItem(*this, aLangItem, 0 );
94 : : }
95 : : }
96 [ # # ]: 0 : rIdx = nSttCnt;
97 [ # # ]: 0 : String sTxt( pTNd->GetTxt().Copy( nSttCnt, nEndCnt - nSttCnt ));
98 [ # # ][ # # ]: 0 : if( bIsOverwriteCursor && sOverwriteText.Len() )
[ # # ]
99 : : {
100 : 0 : xub_StrLen nLen = sTxt.Len();
101 [ # # ]: 0 : if( nLen > sOverwriteText.Len() )
102 : : {
103 [ # # ]: 0 : rIdx += sOverwriteText.Len();
104 [ # # ]: 0 : pTNd->EraseText( rIdx, nLen - sOverwriteText.Len() );
105 [ # # ]: 0 : rIdx = nSttCnt;
106 : 0 : pTNd->ReplaceText( rIdx, sOverwriteText.Len(),
107 [ # # ]: 0 : sOverwriteText );
108 [ # # ]: 0 : if( bInsText )
109 : : {
110 [ # # ]: 0 : rIdx = nSttCnt;
111 [ # # ]: 0 : pDoc->GetIDocumentUndoRedo().StartUndo(
112 [ # # ]: 0 : UNDO_OVERWRITE, NULL );
113 : : pDoc->Overwrite( *this, sTxt.Copy( 0,
114 [ # # ][ # # ]: 0 : sOverwriteText.Len() ));
[ # # ]
115 : : pDoc->InsertString( *this,
116 [ # # ][ # # ]: 0 : sTxt.Copy( sOverwriteText.Len() ) );
[ # # ]
117 [ # # ]: 0 : pDoc->GetIDocumentUndoRedo().EndUndo(
118 [ # # ]: 0 : UNDO_OVERWRITE, NULL );
119 : : }
120 : : }
121 : : else
122 : : {
123 : : pTNd->ReplaceText( rIdx, nLen,
124 [ # # ][ # # ]: 0 : sOverwriteText.Copy( 0, nLen ));
[ # # ]
125 [ # # ]: 0 : if( bInsText )
126 : : {
127 [ # # ]: 0 : rIdx = nSttCnt;
128 [ # # ]: 0 : pDoc->Overwrite( *this, sTxt );
129 : : }
130 : : }
131 : : }
132 : : else
133 : : {
134 [ # # ]: 0 : pTNd->EraseText( rIdx, nEndCnt - nSttCnt );
135 : :
136 [ # # ]: 0 : if( bInsText )
137 : : {
138 [ # # ]: 0 : pDoc->InsertString( *this, sTxt );
139 : : }
140 [ # # ]: 0 : }
141 : : }
142 : : }
143 [ # # ]: 0 : }
144 : :
145 : 0 : void SwExtTextInput::SetInputData( const CommandExtTextInputData& rData )
146 : : {
147 : 0 : SwTxtNode* pTNd = GetPoint()->nNode.GetNode().GetTxtNode();
148 [ # # ]: 0 : if( pTNd )
149 : : {
150 : 0 : xub_StrLen nSttCnt = GetPoint()->nContent.GetIndex(),
151 : 0 : nEndCnt = GetMark()->nContent.GetIndex();
152 [ # # ]: 0 : if( nEndCnt < nSttCnt )
153 : : {
154 : 0 : xub_StrLen n = nEndCnt; nEndCnt = nSttCnt; nSttCnt = n;
155 : : }
156 : :
157 [ # # ][ # # ]: 0 : SwIndex aIdx( pTNd, nSttCnt );
158 : 0 : const String& rNewStr = rData.GetText();
159 : :
160 [ # # ][ # # ]: 0 : if( bIsOverwriteCursor && sOverwriteText.Len() )
[ # # ]
161 : : {
162 : 0 : xub_StrLen nReplace = nEndCnt - nSttCnt;
163 [ # # ]: 0 : if( rNewStr.Len() < nReplace )
164 : : {
165 : : // We have to insert some characters from the saved original text
166 : 0 : nReplace = nReplace - rNewStr.Len();
167 [ # # ]: 0 : aIdx += rNewStr.Len();
168 : : pTNd->ReplaceText( aIdx, nReplace,
169 [ # # ][ # # ]: 0 : sOverwriteText.Copy( rNewStr.Len(), nReplace ));
[ # # ]
170 [ # # ]: 0 : aIdx = nSttCnt;
171 : 0 : nReplace = rNewStr.Len();
172 : : }
173 [ # # ]: 0 : else if( sOverwriteText.Len() < nReplace )
174 : : {
175 : 0 : nReplace = nReplace - sOverwriteText.Len();
176 [ # # ]: 0 : aIdx += sOverwriteText.Len();
177 [ # # ]: 0 : pTNd->EraseText( aIdx, nReplace );
178 [ # # ]: 0 : aIdx = nSttCnt;
179 : 0 : nReplace = sOverwriteText.Len();
180 : : }
181 [ # # ]: 0 : else if( (nReplace = sOverwriteText.Len()) > rNewStr.Len() )
182 : 0 : nReplace = rNewStr.Len();
183 : :
184 [ # # ]: 0 : pTNd->ReplaceText( aIdx, nReplace, rNewStr );
185 [ # # ]: 0 : if( !HasMark() )
186 [ # # ]: 0 : SetMark();
187 [ # # ]: 0 : GetMark()->nContent = aIdx;
188 : : }
189 : : else
190 : : {
191 [ # # ]: 0 : if( nSttCnt < nEndCnt )
192 : : {
193 [ # # ]: 0 : pTNd->EraseText( aIdx, nEndCnt - nSttCnt );
194 : : }
195 : :
196 : : pTNd->InsertText( rNewStr, aIdx,
197 [ # # ]: 0 : IDocumentContentOperations::INS_EMPTYEXPAND );
198 [ # # ]: 0 : if( !HasMark() )
199 [ # # ]: 0 : SetMark();
200 : : }
201 : :
202 [ # # ]: 0 : GetPoint()->nContent = nSttCnt;
203 : :
204 : 0 : aAttrs.clear();
205 [ # # ]: 0 : if( rData.GetTextAttr() )
206 : : {
207 : 0 : const sal_uInt16 *pAttrs = rData.GetTextAttr();
208 [ # # ]: 0 : aAttrs.insert( aAttrs.begin(), pAttrs, pAttrs + rData.GetText().Len() );
209 [ # # ]: 0 : }
210 : : }
211 : 0 : }
212 : :
213 : 0 : void SwExtTextInput::SetOverwriteCursor( sal_Bool bFlag )
214 : : {
215 : 0 : bIsOverwriteCursor = bFlag;
216 : :
217 : : SwTxtNode* pTNd;
218 [ # # # # ]: 0 : if( bIsOverwriteCursor &&
[ # # ]
219 : 0 : 0 != (pTNd = GetPoint()->nNode.GetNode().GetTxtNode()) )
220 : : {
221 : 0 : xub_StrLen nSttCnt = GetPoint()->nContent.GetIndex(),
222 : 0 : nEndCnt = GetMark()->nContent.GetIndex();
223 : 0 : sOverwriteText = pTNd->GetTxt().Copy( nEndCnt < nSttCnt ? nEndCnt
224 [ # # ][ # # ]: 0 : : nSttCnt );
225 [ # # ]: 0 : if( sOverwriteText.Len() )
226 : : {
227 : 0 : xub_StrLen nInWrdAttrPos = sOverwriteText.Search( CH_TXTATR_INWORD ),
228 : 0 : nWrdAttrPos = sOverwriteText.Search( CH_TXTATR_BREAKWORD );
229 [ # # ]: 0 : if( nWrdAttrPos < nInWrdAttrPos )
230 : 0 : nInWrdAttrPos = nWrdAttrPos;
231 [ # # ]: 0 : if( STRING_NOTFOUND != nInWrdAttrPos )
232 : 0 : sOverwriteText.Erase( nInWrdAttrPos );
233 : : }
234 : : }
235 : 0 : }
236 : :
237 : : // The Doc interfaces
238 : :
239 : 0 : SwExtTextInput* SwDoc::CreateExtTextInput( const SwPaM& rPam )
240 : : {
241 [ # # ]: 0 : SwExtTextInput* pNew = new SwExtTextInput( rPam, pExtInputRing );
242 [ # # ]: 0 : if( !pExtInputRing )
243 : 0 : pExtInputRing = pNew;
244 : 0 : pNew->SetMark();
245 : 0 : return pNew;
246 : : }
247 : :
248 : 0 : void SwDoc::DeleteExtTextInput( SwExtTextInput* pDel )
249 : : {
250 [ # # ]: 0 : if( pDel == pExtInputRing )
251 : : {
252 [ # # ]: 0 : if( pDel->GetNext() != pExtInputRing )
253 : 0 : pExtInputRing = (SwPaM*)pDel->GetNext();
254 : : else
255 : 0 : pExtInputRing = 0;
256 : : }
257 [ # # ]: 0 : delete pDel;
258 : 0 : }
259 : :
260 : 94706 : SwExtTextInput* SwDoc::GetExtTextInput( const SwNode& rNd,
261 : : xub_StrLen nCntntPos ) const
262 : : {
263 : 94706 : SwExtTextInput* pRet = 0;
264 [ - + ]: 94706 : if( pExtInputRing )
265 : : {
266 : 0 : sal_uLong nNdIdx = rNd.GetIndex();
267 : 0 : SwExtTextInput* pTmp = (SwExtTextInput*)pExtInputRing;
268 [ # # ]: 0 : do {
269 : 0 : sal_uLong nPt = pTmp->GetPoint()->nNode.GetIndex(),
270 : 0 : nMk = pTmp->GetMark()->nNode.GetIndex();
271 : 0 : xub_StrLen nPtCnt = pTmp->GetPoint()->nContent.GetIndex(),
272 : 0 : nMkCnt = pTmp->GetMark()->nContent.GetIndex();
273 : :
274 [ # # ][ # # ]: 0 : if( nPt < nMk || ( nPt == nMk && nPtCnt < nMkCnt ))
[ # # ]
275 : : {
276 : 0 : sal_uLong nTmp = nMk; nMk = nPt; nPt = nTmp;
277 : 0 : nTmp = nMkCnt; nMkCnt = nPtCnt; nPtCnt = (xub_StrLen)nTmp;
278 : : }
279 : :
280 [ # # ][ # # ]: 0 : if( nMk <= nNdIdx && nNdIdx <= nPt &&
[ # # ][ # # ]
[ # # ]
281 : : ( STRING_NOTFOUND == nCntntPos ||
282 : : ( nMkCnt <= nCntntPos && nCntntPos <= nPtCnt )))
283 : : {
284 : 0 : pRet = pTmp;
285 : 0 : break;
286 : : }
287 : : } while( pExtInputRing != (pTmp = (SwExtTextInput*)pExtInputRing ) );
288 : : }
289 : 94706 : return pRet;
290 : : }
291 : :
292 : 0 : SwExtTextInput* SwDoc::GetExtTextInput() const
293 : : {
294 : : OSL_ENSURE( !pExtInputRing || pExtInputRing == pExtInputRing->GetNext(),
295 : : "more then one InputEngine available" );
296 : 0 : return (SwExtTextInput*)pExtInputRing;
297 : : }
298 : :
299 : :
300 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|