|
1 /* |
|
2 * Copyright (c) 1997-1999 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include <s32mem.h> |
|
20 #include <s32file.h> |
|
21 #include <s32std.h> |
|
22 #include <fldinfo.h> |
|
23 #include <basched.h> |
|
24 #include <baclipb.h> |
|
25 #include <txtglobl.h> |
|
26 #include <eikdef.h> |
|
27 #include <fldbase.h> |
|
28 #ifndef SYMBIAN_ENABLE_SPLIT_HEADERS |
|
29 #include <txtrich.h> |
|
30 #else |
|
31 #include <txtrich.h> |
|
32 #include <txtclipboard.h> |
|
33 #include <uikon/eikdefmacros.h> |
|
34 #include <uikon/eikenvinterface.h> |
|
35 #endif |
|
36 #include <txtfmlyr.h> |
|
37 #include <txtfrmat.h> |
|
38 #include <frmtview.h> |
|
39 #include <barsread.h> |
|
40 #include <coecobs.h> |
|
41 #include <coemain.h> |
|
42 #include <eikedwin.pan> |
|
43 #include <eikpanic.h> |
|
44 #include <uikon.hrh> |
|
45 #include <gulutil.h> |
|
46 #include <eikenv.h> |
|
47 #include <eikedwin.h> |
|
48 #include <eikcoctl.rsg> |
|
49 #include <avkon.rsg> |
|
50 #include <gulcolor.h> |
|
51 #include <eikirfty.h> |
|
52 #include "LAFEDWIN.H" |
|
53 #include <lafmain.h> |
|
54 #include <uiklaf/private/lafenv.h> |
|
55 #include <aknedsts.h> |
|
56 #include <frmtlay.h> |
|
57 #include <tagma.h> |
|
58 #include <eiksvdef.h> |
|
59 #include <AknUtils.h> |
|
60 #include <fepipext.h> |
|
61 #include <aknedformaccessor.h> |
|
62 #include <coemop.h> |
|
63 #include <AknSettingCache.h> |
|
64 #include <aknenv.h> |
|
65 #include <AknDef.h> |
|
66 #include <AknsDrawUtils.h> |
|
67 #include "aknedwincustomdrawprivate.h" |
|
68 #include "aknedwindrawingmodifier.h" |
|
69 #include "FromCursorModifierUtils.h" |
|
70 |
|
71 #include <AknTasHook.h> |
|
72 #include <FormCursorModifier.h> |
|
73 #include <formcursormodifierint.h> |
|
74 #include <biditext.h> |
|
75 #include <bidivisual.h> |
|
76 #include <AknBidiTextUtils.h> |
|
77 |
|
78 #include "aknedwinphysicshandler.h" |
|
79 #include "AknEdwinFormExtendedInterfaceProvider.h" |
|
80 #include "AknNoMatchesIndicatorInlineTextSource.h" |
|
81 #include "AknPhoneNumberInlineTextSource.h" |
|
82 #include "AknRichTextPhoneNumberInlineTextSource.h" |
|
83 #include "AknCompositeInlineTextSource.h" |
|
84 #include <featmgr.h> |
|
85 #include <aknconsts.h> |
|
86 #include <AknPictographInterface.h> |
|
87 #include <aknappui.h> |
|
88 #include <jplangutil.h> |
|
89 #include <AknSgcc.h> |
|
90 #include <AknLayoutFont.h> |
|
91 #include <aknlayoutscalable_avkon.cdl.h> |
|
92 #include <aknextendedinputcapabilities.h> |
|
93 #include <PUAcodes.hrh> |
|
94 #include <AknFepInternalCRKeys.h> // KAknFepHashKeySelection |
|
95 #include <eikrted.h> |
|
96 #include <NumberGroupingCRKeys.h> |
|
97 #include <aknpointereventsuppressor.h> |
|
98 #include <aknnotedialog.h> |
|
99 #include <AknFepGlobalEnums.h> |
|
100 |
|
101 #include "smileymanager.h" |
|
102 #include "smileycustomwrap.h" |
|
103 #include <touchfeedback.h> |
|
104 |
|
105 GLDEF_C void Panic(TEikEdwinPanic aPanic) |
|
106 { |
|
107 _LIT(KPanicCat,"EIKON-EDWIN"); |
|
108 User::Panic(KPanicCat,aPanic); |
|
109 } |
|
110 |
|
111 // For neutral character protection |
|
112 enum |
|
113 { |
|
114 EEikEdwinLeftToRightMark = 0x200E, |
|
115 EEikEdwinRightToLeftMark = 0x200F |
|
116 }; |
|
117 |
|
118 _LIT(KEikEdwinLeftToRightMark, "\x200E" ); // LRM |
|
119 _LIT(KEikEdwinRightToLeftMark, "\x200F" ); // RLM |
|
120 |
|
121 // Used by neutral protection code to extract small chunks of the editor at a time |
|
122 // while searching for strong characters. |
|
123 const TInt KLengthAtATime(3); |
|
124 |
|
125 // Constants for controlling the switching between band and full document formatting |
|
126 const TInt KFullFormattingUpperThreshold=2000; // Default initial value |
|
127 const TInt KPartialFormattingLowerThreshold=1900; // Default initial value |
|
128 // This should be consistent with the difference between the two default limits: |
|
129 const TInt KFormattingThresholdGap=100; |
|
130 // This should be significantly bigger than KFormattingThresholdGap (and certainly > 0): |
|
131 const TInt KMinimumPartialFormattingLength=400; |
|
132 const TInt KMinimumFullFormattingLength=KMinimumPartialFormattingLength+KFormattingThresholdGap; |
|
133 |
|
134 // Unicode sign for S60 "enter" symbol |
|
135 const TInt KDownwardsArrowWithTipLeftwards = 0x21B2; |
|
136 const TInt KDownwardsArrowWithTipRightwards = 0x21B3; |
|
137 |
|
138 // Unicode for euro sign |
|
139 const TInt KEuroSign = 0x20AC; |
|
140 const TInt KSegmSize = 1024; |
|
141 |
|
142 |
|
143 |
|
144 const TInt KNormalAnimPlayTimes = 2; |
|
145 const TInt KInfiniteAnimPlayTimes = 0x7ffff; |
|
146 const TInt KAdditionalPixels = 0x400; |
|
147 |
|
148 const TInt KFullFormatLengthForSmiley = 5000; |
|
149 |
|
150 // |
|
151 // class CEikEdwin::CUndoBuffer |
|
152 // |
|
153 |
|
154 class CEikEdwin::CUndoBuffer : public CBase |
|
155 { |
|
156 public: |
|
157 static CUndoBuffer* NewL(); |
|
158 ~CUndoBuffer(); |
|
159 CBufStore& Store() const; |
|
160 CStreamDictionary& Dictionary() const; |
|
161 TCursorSelection NewText() const; |
|
162 void SetNewText(const TCursorSelection& aSelection); |
|
163 TInt OldCursorPos() const; |
|
164 void SetOldCursorPos(TInt aPos); |
|
165 private: |
|
166 void ConstructL(); |
|
167 private: |
|
168 CBufStore* iStore; |
|
169 CStreamDictionary* iDictionary; |
|
170 TCursorSelection iNewText; |
|
171 TInt iOldCursorPos; |
|
172 }; |
|
173 |
|
174 CEikEdwin::CUndoBuffer* CEikEdwin::CUndoBuffer::NewL() |
|
175 { // static |
|
176 CUndoBuffer* self=new(ELeave) CUndoBuffer; |
|
177 CleanupStack::PushL(self); |
|
178 self->ConstructL(); |
|
179 CleanupStack::Pop(); // self |
|
180 return self; |
|
181 } |
|
182 |
|
183 CEikEdwin::CUndoBuffer::~CUndoBuffer() |
|
184 { |
|
185 delete iStore; |
|
186 delete iDictionary; |
|
187 } |
|
188 |
|
189 void CEikEdwin::CUndoBuffer::ConstructL() |
|
190 { |
|
191 iStore=CBufStore::NewL(512); |
|
192 iDictionary=CStreamDictionary::NewL(); |
|
193 } |
|
194 |
|
195 CBufStore& CEikEdwin::CUndoBuffer::Store() const |
|
196 {return *iStore;} |
|
197 CStreamDictionary& CEikEdwin::CUndoBuffer::Dictionary() const |
|
198 {return *iDictionary;} |
|
199 TCursorSelection CEikEdwin::CUndoBuffer::NewText() const |
|
200 {return iNewText;} |
|
201 void CEikEdwin::CUndoBuffer::SetNewText(const TCursorSelection& aSelection) |
|
202 {iNewText=aSelection;} |
|
203 TInt CEikEdwin::CUndoBuffer::OldCursorPos() const |
|
204 {return iOldCursorPos;} |
|
205 void CEikEdwin::CUndoBuffer::SetOldCursorPos(TInt aPos) |
|
206 {iOldCursorPos=aPos;} |
|
207 |
|
208 void CEikEdwin::CEikEdwinExtension::TAknEdwinPictographDrawer::DrawPictographArea() |
|
209 { |
|
210 } |
|
211 |
|
212 // |
|
213 // class CEikEdwinFepSupport |
|
214 // |
|
215 |
|
216 NONSHARABLE_CLASS(CEikEdwinFepSupport) : public CBase, public MCoeFepAwareTextEditor, public MCoeFepAwareTextEditor_Extension1, public TCoeInputCapabilities::MCoeFepSpecificExtensions |
|
217 { |
|
218 friend class CEikEdwin; |
|
219 public: |
|
220 static CEikEdwinFepSupport* New(CEikEdwin& aEdwin); |
|
221 virtual ~CEikEdwinFepSupport(); |
|
222 TBool IsHandledByFepL(TPointerEvent::TType aType, TUint aModifiers, TInt aDocumentPosition); |
|
223 /** |
|
224 * Set the input capabilities in the edwin fep support object. A copy of the input capabilities |
|
225 * is maintained in and owned by the fep support; |
|
226 * |
|
227 * @param aInputCapabilities Reference to desired input capabilities object |
|
228 */ |
|
229 void SetInputCapabilitiesL(const TCoeInputCapabilities& aInputCapabilities); |
|
230 const TCoeInputCapabilities* InputCapabilities() const; |
|
231 void ConstructStateHolder(); |
|
232 // from MCoeFepAwareTextEditor_Extension1 |
|
233 void SetStateTransferingOwnershipL(CState* aState, TUid aTypeSafetyUid); |
|
234 CState* State(TUid aTypeSafetyUid); // this function does *not* transfer ownership |
|
235 |
|
236 private: |
|
237 enum TPointerState |
|
238 { |
|
239 EPointerIsUp, |
|
240 EPointerIsDownStartingInsideInlineText, |
|
241 EPointerIsDownStartingOutsideInlineText |
|
242 }; |
|
243 struct SPointerEventInInlineText |
|
244 { |
|
245 inline SPointerEventInInlineText(TPointerEvent::TType aType, TUint aModifiers, TInt aPositionInInlineText) :iType(aType), iModifiers(aModifiers), iPositionInInlineText(aPositionInInlineText) {} |
|
246 TPointerEvent::TType iType; |
|
247 TUint iModifiers; |
|
248 TInt iPositionInInlineText; |
|
249 }; |
|
250 private: |
|
251 CEikEdwinFepSupport(CEikEdwin& aEdwin); |
|
252 void UpdateTextViewAfterChangeInInlineTextL(TBool aParagraphContainingStartPositionOfInlineTextHasChangedFormat,TInt aNumberOfCharactersSuccessfullyDeleted,TInt aNumberOfCharactersSuccessfullyInserted,TInt aError); |
|
253 void UpdateTextViewAfterChangeInInlineTextL(TBool aParagraphContainingStartPositionOfInlineTextHasChangedFormat,TInt aNumberOfCharactersSuccessfullyDeleted,TInt aNumberOfCharactersSuccessfullyInserted,TInt aError,TInt aSelectionAnchorPosition); |
|
254 void ResetInternalState(); |
|
255 |
|
256 // from MCoeFepAwareTextEditor |
|
257 virtual void StartFepInlineEditL(const TDesC& aInitialInlineText, TInt aPositionOfInsertionPointInInlineText, TBool aCursorVisibility, const MFormCustomDraw* aCustomDraw, MFepInlineTextFormatRetriever& aInlineTextFormatRetriever, MFepPointerEventHandlerDuringInlineEdit& aPointerEventHandlerDuringInlineEdit); |
|
258 virtual void UpdateFepInlineTextL(const TDesC& aNewInlineText, TInt aPositionOfInsertionPointInInlineText); |
|
259 virtual void SetInlineEditingCursorVisibilityL(TBool aCursorVisibility); |
|
260 virtual void CancelFepInlineEdit(); |
|
261 virtual TInt DocumentLengthForFep() const; |
|
262 virtual TInt DocumentMaximumLengthForFep() const; |
|
263 virtual void SetCursorSelectionForFepL(const TCursorSelection& aCursorSelection); |
|
264 virtual void GetCursorSelectionForFep(TCursorSelection& aCursorSelection) const; |
|
265 virtual void GetEditorContentForFep(TDes& aEditorContent, TInt aDocumentPosition, TInt aLengthToRetrieve) const; // must cope with aDocumentPosition being outside the range 0 to DocumentLengthForFep() |
|
266 virtual void GetFormatForFep(TCharFormat& aFormat, TInt aDocumentPosition) const; |
|
267 virtual void GetScreenCoordinatesForFepL(TPoint& aLeftSideOfBaseLine, TInt& aHeight, TInt& aAscent, TInt aDocumentPosition) const; |
|
268 virtual void DoCommitFepInlineEditL(); |
|
269 virtual MCoeFepAwareTextEditor_Extension1* Extension1(TBool& aSetToTrue); |
|
270 virtual void MCoeFepAwareTextEditor_Reserved_2(); |
|
271 // from MCoeFepAwareTextEditor_Extension1 |
|
272 // virtual void SetStateTransferingOwnershipL(CState* aState, TUid aTypeSafetyUid); |
|
273 // virtual CState* State(TUid aTypeSafetyUid); |
|
274 virtual void StartFepInlineEditL(TBool& aSetToTrue, const TCursorSelection& aCursorSelection, const TDesC& aInitialInlineText, TInt aPositionOfInsertionPointInInlineText, TBool aCursorVisibility, const MFormCustomDraw* aCustomDraw, MFepInlineTextFormatRetriever& aInlineTextFormatRetriever, MFepPointerEventHandlerDuringInlineEdit& aPointerEventHandlerDuringInlineEdit); |
|
275 virtual void SetCursorType(TBool& aSetToTrue, const TTextCursor& aTextCursor); |
|
276 virtual void MCoeFepAwareTextEditor_Extension1_Reserved_3(); |
|
277 virtual void MCoeFepAwareTextEditor_Extension1_Reserved_4(); |
|
278 // from TCoeInputCapabilities::MCoeFepSpecificExtensions |
|
279 virtual TBool IsValidCharacter(TInt aChar); |
|
280 virtual void MCoeFepSpecificExtensions_Reserved_1(); |
|
281 virtual void MCoeFepSpecificExtensions_Reserved_2(); |
|
282 |
|
283 |
|
284 private: |
|
285 CEikEdwin& iEdwin; |
|
286 TCursorSelection iOriginalSelection; |
|
287 TInt iPositionOfInsertionPointInDocument; |
|
288 TInt iPositionOfInlineTextInDocument; |
|
289 TInt iLengthOfInlineText; |
|
290 public: |
|
291 const MFormCustomDraw* iOldCustomDraw; // does not own anything |
|
292 MTouchFeedback* iFeedback; |
|
293 TBool iSelectionIsCancel; |
|
294 TInt iMoveThumbFeedbackNeeded; |
|
295 private: |
|
296 MFepPointerEventHandlerDuringInlineEdit* iPointerEventHandlerDuringInlineEdit; // does not own anything |
|
297 SPointerEventInInlineText iLastPointerEventInInlineText; |
|
298 TPointerState iPointerState; |
|
299 TCoeInputCapabilities* iInputCapabilities; |
|
300 CState* iState; |
|
301 TUid iStateTypeSafetyUid; |
|
302 TInt iCharsDeleted; |
|
303 TInt iCharsInserted; |
|
304 TBool iShowCursor; |
|
305 }; |
|
306 |
|
307 CEikEdwinFepSupport* CEikEdwinFepSupport::New(CEikEdwin& aEdwin) |
|
308 { |
|
309 return new CEikEdwinFepSupport(aEdwin); |
|
310 } |
|
311 |
|
312 CEikEdwinFepSupport::~CEikEdwinFepSupport() |
|
313 { |
|
314 delete iInputCapabilities; |
|
315 delete iState; |
|
316 } |
|
317 |
|
318 TBool CEikEdwinFepSupport::IsHandledByFepL(TPointerEvent::TType aType,TUint aModifiers,TInt aDocumentPosition) |
|
319 { |
|
320 if (iPositionOfInlineTextInDocument>=0) |
|
321 { |
|
322 __ASSERT_DEBUG((iOriginalSelection.iCursorPos>=0) && (iOriginalSelection.iAnchorPos>=0) && (iPositionOfInsertionPointInDocument>=0) && (iPositionOfInlineTextInDocument>=0) && (iLengthOfInlineText>=0) && (iPointerEventHandlerDuringInlineEdit!=NULL),Panic(EEikPanicBadInlineEditingState1)); |
|
323 const TInt positionOfFirstCharacterInDocumentAfterInlineText=iPositionOfInlineTextInDocument+iLengthOfInlineText; |
|
324 switch (aType) |
|
325 { |
|
326 case TPointerEvent::EDrag: |
|
327 case TPointerEvent::EButton1Up: |
|
328 if (iPointerState!=EPointerIsUp) |
|
329 { |
|
330 break; |
|
331 } |
|
332 // fall through (only will do this if no preceding TPointerEvent::EButton1Down occurred, either initially or since the previous TPointerEvent::EButton1Up event) |
|
333 case TPointerEvent::EButton1Down: |
|
334 if ((aDocumentPosition>=iPositionOfInlineTextInDocument) && (aDocumentPosition<=positionOfFirstCharacterInDocumentAfterInlineText)) |
|
335 { |
|
336 iPointerState=EPointerIsDownStartingInsideInlineText; |
|
337 } |
|
338 else |
|
339 { |
|
340 iPointerState=EPointerIsDownStartingOutsideInlineText; |
|
341 } |
|
342 break; |
|
343 #if defined(__GCC32__) |
|
344 default: |
|
345 break; |
|
346 #endif |
|
347 } |
|
348 const TBool pointerIsDownStartingInsideInlineText=(iPointerState==EPointerIsDownStartingInsideInlineText); |
|
349 if (aType==TPointerEvent::EButton1Up) |
|
350 { |
|
351 iPointerState=EPointerIsUp; |
|
352 } |
|
353 if (pointerIsDownStartingInsideInlineText) |
|
354 { |
|
355 if (aDocumentPosition<iPositionOfInlineTextInDocument) |
|
356 { |
|
357 aDocumentPosition=iPositionOfInlineTextInDocument; |
|
358 } |
|
359 if (aDocumentPosition>positionOfFirstCharacterInDocumentAfterInlineText) |
|
360 { |
|
361 aDocumentPosition=positionOfFirstCharacterInDocumentAfterInlineText; |
|
362 } |
|
363 const TInt positionInInlineText=aDocumentPosition-iPositionOfInlineTextInDocument; |
|
364 if ((aType!=iLastPointerEventInInlineText.iType) || (aModifiers!=iLastPointerEventInInlineText.iModifiers) || (positionInInlineText!=iLastPointerEventInInlineText.iPositionInInlineText)) |
|
365 { |
|
366 iLastPointerEventInInlineText.iType=aType; |
|
367 iLastPointerEventInInlineText.iModifiers=aModifiers; |
|
368 iLastPointerEventInInlineText.iPositionInInlineText=positionInInlineText; |
|
369 iPointerEventHandlerDuringInlineEdit->HandlePointerEventInInlineTextL(aType,aModifiers,positionInInlineText); |
|
370 } |
|
371 return ETrue; |
|
372 } |
|
373 } |
|
374 #if defined(_DEBUG) |
|
375 else |
|
376 { |
|
377 __ASSERT_DEBUG((iOriginalSelection.iCursorPos<0) && (iOriginalSelection.iAnchorPos<0) && (iPositionOfInsertionPointInDocument<0) && (iPositionOfInlineTextInDocument<0) && (iLengthOfInlineText<0) && (iOldCustomDraw==NULL) && (iPointerEventHandlerDuringInlineEdit==NULL),Panic(EEikPanicBadInlineEditingState2)); |
|
378 } |
|
379 #endif |
|
380 return EFalse; |
|
381 } |
|
382 |
|
383 // This method treats the input capabilities slightly oddly in order to avoid re-allocation of Heap |
|
384 void CEikEdwinFepSupport::SetInputCapabilitiesL(const TCoeInputCapabilities& aInputCapabilities) |
|
385 { |
|
386 if (iInputCapabilities==NULL) |
|
387 { |
|
388 iInputCapabilities=new(ELeave) TCoeInputCapabilities(aInputCapabilities); // copy constructor |
|
389 } |
|
390 else |
|
391 { |
|
392 *iInputCapabilities=aInputCapabilities; // Structure copy. OK for T class. |
|
393 } |
|
394 } |
|
395 |
|
396 const TCoeInputCapabilities* CEikEdwinFepSupport::InputCapabilities() const |
|
397 { |
|
398 return iInputCapabilities; |
|
399 } |
|
400 |
|
401 void CEikEdwinFepSupport::ConstructStateHolder() |
|
402 { |
|
403 iState = new CAknEdwinState(STATIC_CAST(MEikCcpuEditor*, &iEdwin)); |
|
404 if (iState) |
|
405 static_cast<CAknEdwinState*>(iState)->SetObjectProvider(&iEdwin); |
|
406 } |
|
407 |
|
408 #pragma warning (disable: 4355) // warning disabled: "'this' : used in base member initializer list" |
|
409 CEikEdwinFepSupport::CEikEdwinFepSupport(CEikEdwin& aEdwin) |
|
410 :iEdwin(aEdwin), |
|
411 iOriginalSelection(-1,-1), |
|
412 iPositionOfInsertionPointInDocument(-1), |
|
413 iPositionOfInlineTextInDocument(-1), |
|
414 iLengthOfInlineText(-1), |
|
415 iOldCustomDraw(NULL), |
|
416 iFeedback(MTouchFeedback::Instance()), |
|
417 iSelectionIsCancel(EFalse), |
|
418 iMoveThumbFeedbackNeeded(EFalse), |
|
419 iPointerEventHandlerDuringInlineEdit(NULL), |
|
420 iLastPointerEventInInlineText((TPointerEvent::TType)-1,0,0), |
|
421 iPointerState(EPointerIsUp), |
|
422 iInputCapabilities(NULL) |
|
423 { |
|
424 __DECLARE_NAME(_S("CEikEdwinFepSupport")); |
|
425 } |
|
426 |
|
427 #pragma warning (default: 4355) // warning disabled: "assignment within conditional expression" |
|
428 |
|
429 void CEikEdwinFepSupport::UpdateTextViewAfterChangeInInlineTextL(TBool aParagraphContainingStartPositionOfInlineTextHasChangedFormat,TInt aNumberOfCharactersSuccessfullyDeleted,TInt aNumberOfCharactersSuccessfullyInserted,TInt aError) |
|
430 { |
|
431 UpdateTextViewAfterChangeInInlineTextL(aParagraphContainingStartPositionOfInlineTextHasChangedFormat,aNumberOfCharactersSuccessfullyDeleted,aNumberOfCharactersSuccessfullyInserted,aError,iPositionOfInsertionPointInDocument); |
|
432 } |
|
433 |
|
434 void CEikEdwinFepSupport::UpdateTextViewAfterChangeInInlineTextL(TBool aParagraphContainingStartPositionOfInlineTextHasChangedFormat,TInt aNumberOfCharactersSuccessfullyDeleted,TInt aNumberOfCharactersSuccessfullyInserted,TInt aError,TInt aSelectionAnchorPosition) |
|
435 { |
|
436 TCursorSelection select( iPositionOfInsertionPointInDocument, aSelectionAnchorPosition ); |
|
437 iEdwin.iTextView->SetPendingSelection( select ); |
|
438 |
|
439 select.iAnchorPos = iPositionOfInlineTextInDocument; |
|
440 select.iCursorPos = select.iAnchorPos + aNumberOfCharactersSuccessfullyInserted; |
|
441 if ( iEdwin.iEdwinExtension->iSmiley ) |
|
442 { |
|
443 TInt textChange( aNumberOfCharactersSuccessfullyInserted - aNumberOfCharactersSuccessfullyDeleted ); |
|
444 if ( textChange == 0 ) |
|
445 { |
|
446 if ( iCharsDeleted < aNumberOfCharactersSuccessfullyDeleted ) |
|
447 { |
|
448 iEdwin.iEdwinExtension->iSmiley->HandleDeleteL( iPositionOfInlineTextInDocument, |
|
449 aNumberOfCharactersSuccessfullyDeleted - iCharsDeleted ); |
|
450 iCharsDeleted = aNumberOfCharactersSuccessfullyDeleted; |
|
451 } |
|
452 if ( iCharsInserted < aNumberOfCharactersSuccessfullyInserted ) |
|
453 { |
|
454 iEdwin.iEdwinExtension->iSmiley->HandleInsertL( |
|
455 iPositionOfInlineTextInDocument, |
|
456 ( aNumberOfCharactersSuccessfullyInserted - iCharsInserted ) ); |
|
457 iCharsInserted = aNumberOfCharactersSuccessfullyInserted; |
|
458 } |
|
459 } |
|
460 else |
|
461 { |
|
462 if ( textChange > 0 ) |
|
463 { |
|
464 iEdwin.iEdwinExtension->iSmiley->HandleInsertL( |
|
465 select.iAnchorPos + aNumberOfCharactersSuccessfullyDeleted, |
|
466 textChange ); |
|
467 } |
|
468 else if ( textChange < 0 ) |
|
469 { |
|
470 iEdwin.iEdwinExtension->iSmiley->HandleDeleteL( aSelectionAnchorPosition, |
|
471 textChange * -1 ); |
|
472 } |
|
473 } |
|
474 } |
|
475 iEdwin.iTextView->HandleInsertDeleteL( select, aNumberOfCharactersSuccessfullyDeleted, |
|
476 aParagraphContainingStartPositionOfInlineTextHasChangedFormat ); |
|
477 User::LeaveIfError(aError); |
|
478 iEdwin.SetScrollBarsL(); |
|
479 iEdwin.DoReportEventL(MCoeControlObserver::EEventStateChanged); |
|
480 if (aParagraphContainingStartPositionOfInlineTextHasChangedFormat) |
|
481 { |
|
482 iEdwin.ReportEdwinEventL(MEikEdwinObserver::EEventFormatChanged); |
|
483 } |
|
484 } |
|
485 |
|
486 void CEikEdwinFepSupport::ResetInternalState() |
|
487 { |
|
488 iOriginalSelection.SetSelection(-1,-1); |
|
489 iPositionOfInsertionPointInDocument=-1; |
|
490 iPositionOfInlineTextInDocument=-1; |
|
491 iLengthOfInlineText=-1; |
|
492 iOldCustomDraw=NULL; |
|
493 iPointerEventHandlerDuringInlineEdit=NULL; |
|
494 } |
|
495 |
|
496 |
|
497 void CEikEdwinFepSupport::StartFepInlineEditL( |
|
498 const TDesC& aInitialInlineText, |
|
499 TInt aPositionOfInsertionPointInInlineText, |
|
500 TBool aCursorVisibility, |
|
501 const MFormCustomDraw* aCustomDraw, |
|
502 MFepInlineTextFormatRetriever& aInlineTextFormatRetriever, |
|
503 MFepPointerEventHandlerDuringInlineEdit& aPointerEventHandlerDuringInlineEdit) |
|
504 { |
|
505 __ASSERT_ALWAYS(iPositionOfInlineTextInDocument<0,Panic(EEikPanicBadInlineEditingState3)); // assert that we're not currently inline editing |
|
506 __ASSERT_DEBUG((iOriginalSelection.iCursorPos<0) && (iOriginalSelection.iAnchorPos<0) && (iPositionOfInsertionPointInDocument<0) && (iPositionOfInlineTextInDocument<0) && (iLengthOfInlineText<0) && (iOldCustomDraw==NULL) && (iPointerEventHandlerDuringInlineEdit==NULL),Panic(EEikPanicBadInlineEditingState4)); |
|
507 iEdwin.PerformRecordedOperationL(); |
|
508 CCoeEnv::Static()->ForEachFepObserverCall(FepObserverHandleStartOfTransactionL); |
|
509 iEdwin.SetKeyboardRepeatRate(KAknEditorKeyboardRepeatRate); |
|
510 iEdwin.CheckNotReadOnlyL(); |
|
511 iEdwin.iEdwinExtension->iInlineEditing = ETrue; |
|
512 iShowCursor = aCursorVisibility; |
|
513 CAknEdwinState* state( iEdwin.EditorState() ); |
|
514 state->SetInlineEditSpan( TCursorSelection( 0, 0 ) ); |
|
515 const TCursorSelection selection=iEdwin.Selection(); |
|
516 iOriginalSelection=selection; |
|
517 iPositionOfInsertionPointInDocument=selection.iCursorPos; |
|
518 iPositionOfInlineTextInDocument=selection.LowerPos(); |
|
519 iPointerEventHandlerDuringInlineEdit=&aPointerEventHandlerDuringInlineEdit; |
|
520 TBool paragraphContainingStartPositionOfInlineTextHasChangedFormat=EFalse; |
|
521 TInt numberOfCharactersSuccessfullyDeleted=0; |
|
522 TInt numberOfCharactersSuccessfullyInserted=0; |
|
523 // handle extended highlights |
|
524 |
|
525 /* |
|
526 WARNING. do not insert any leaving function calls after the iEdwin.iText->StartFepInlineEditL unless they are trapped |
|
527 as this will call update-state problems. |
|
528 */ |
|
529 TRAPD(error, |
|
530 { |
|
531 iEdwin.iTextView->ClearSelectionL(); |
|
532 iEdwin.iText->StartFepInlineEditL(paragraphContainingStartPositionOfInlineTextHasChangedFormat,numberOfCharactersSuccessfullyDeleted,numberOfCharactersSuccessfullyInserted,iPositionOfInsertionPointInDocument,iPositionOfInlineTextInDocument+aPositionOfInsertionPointInInlineText,aInitialInlineText,iPositionOfInlineTextInDocument,selection.Length(),aInlineTextFormatRetriever);//); |
|
533 }); |
|
534 if (error != KErrNone) |
|
535 { // cancel inline editing... |
|
536 ResetInternalState(); |
|
537 User::LeaveIfError(error); |
|
538 } |
|
539 iLengthOfInlineText=numberOfCharactersSuccessfullyInserted; |
|
540 iOldCustomDraw=iEdwin.iLayout->CustomDraw(); |
|
541 if (aCustomDraw) |
|
542 iEdwin.iLayout->SetCustomDraw(aCustomDraw); |
|
543 /* |
|
544 The scheme for this component is as follows: |
|
545 There are 3 levels of call to StartFepInlineEdit (from FEP to here, to CEditable) |
|
546 As each level contains its' own state to decide which mode it is in, complex issues arise upon a leave. |
|
547 |
|
548 Basically, if there is a leave, then all three levels must NOT be in inline edit mode. |
|
549 There are a number of possible ways of achieving this, but the simplest and most efficient has been |
|
550 chosen here. The method which changes the state must occur after the last leaving call in that method |
|
551 (NB if the state-changing method itself leaves, then this is ok). That is to say "as soon as the lowest |
|
552 level has entered inline edit mode, all three levels are committed to inline edit mode, as they cannot |
|
553 leave after this point". |
|
554 |
|
555 Therefore, the two calls below are deliberately trapped (as if they leave it does not matter) |
|
556 */ |
|
557 |
|
558 TRAP_IGNORE( |
|
559 { |
|
560 UpdateTextViewAfterChangeInInlineTextL(paragraphContainingStartPositionOfInlineTextHasChangedFormat,numberOfCharactersSuccessfullyDeleted,numberOfCharactersSuccessfullyInserted,error); |
|
561 iEdwin.SetCursorVisibilityL(aCursorVisibility); |
|
562 }); |
|
563 } |
|
564 |
|
565 void CEikEdwinFepSupport::UpdateFepInlineTextL(const TDesC& aNewInlineText,TInt aPositionOfInsertionPointInInlineText) |
|
566 { |
|
567 __ASSERT_ALWAYS(iPositionOfInlineTextInDocument>=0,Panic(EEikPanicBadInlineEditingState5)); // assert that we're currently inline editing |
|
568 __ASSERT_DEBUG((iOriginalSelection.iCursorPos>=0) && (iOriginalSelection.iAnchorPos>=0) && (iPositionOfInsertionPointInDocument>=0) && (iPositionOfInlineTextInDocument>=0) && (iLengthOfInlineText>=0) && (iPointerEventHandlerDuringInlineEdit!=NULL),Panic(EEikPanicBadInlineEditingState6)); |
|
569 TBool paragraphContainingStartPositionOfInlineTextHasChangedFormat=EFalse; |
|
570 TInt numberOfCharactersSuccessfullyDeleted=0; |
|
571 TInt numberOfCharactersSuccessfullyInserted=0; |
|
572 TRAPD(error,iEdwin.iText->UpdateFepInlineTextL(paragraphContainingStartPositionOfInlineTextHasChangedFormat,numberOfCharactersSuccessfullyDeleted,numberOfCharactersSuccessfullyInserted,iPositionOfInsertionPointInDocument,iPositionOfInlineTextInDocument+aPositionOfInsertionPointInInlineText,aNewInlineText)); |
|
573 iLengthOfInlineText=numberOfCharactersSuccessfullyInserted; |
|
574 UpdateTextViewAfterChangeInInlineTextL(paragraphContainingStartPositionOfInlineTextHasChangedFormat,numberOfCharactersSuccessfullyDeleted,numberOfCharactersSuccessfullyInserted,error); |
|
575 iEdwin.ReportEdwinEventL( MEikEdwinObserver::EEventTextUpdate ); |
|
576 } |
|
577 |
|
578 void CEikEdwinFepSupport::SetInlineEditingCursorVisibilityL(TBool aCursorVisibility) |
|
579 { |
|
580 __ASSERT_ALWAYS(iPositionOfInlineTextInDocument>=0,Panic(EEikPanicBadInlineEditingState7)); // assert that we're currently inline editing |
|
581 __ASSERT_DEBUG((iOriginalSelection.iCursorPos>=0) && (iOriginalSelection.iAnchorPos>=0) && (iPositionOfInsertionPointInDocument>=0) && (iPositionOfInlineTextInDocument>=0) && (iLengthOfInlineText>=0) && (iPointerEventHandlerDuringInlineEdit!=NULL),Panic(EEikPanicBadInlineEditingState8)); |
|
582 iEdwin.SetCursorVisibilityL(aCursorVisibility); |
|
583 iShowCursor = aCursorVisibility; |
|
584 } |
|
585 |
|
586 void CEikEdwinFepSupport::CancelFepInlineEdit() |
|
587 { |
|
588 if (iPositionOfInlineTextInDocument>=0) |
|
589 { |
|
590 __ASSERT_DEBUG((iOriginalSelection.iCursorPos>=0) && (iOriginalSelection.iAnchorPos>=0) && (iPositionOfInsertionPointInDocument>=0) && (iPositionOfInlineTextInDocument>=0) && (iLengthOfInlineText>=0) && (iPointerEventHandlerDuringInlineEdit!=NULL),Panic(EEikPanicBadInlineEditingState11)); |
|
591 iEdwin.iEdwinExtension->iInlineEditing = EFalse; |
|
592 iCharsInserted = 0; |
|
593 iCharsDeleted = 0; |
|
594 TBool paragraphContainingStartPositionOfInlineTextHasChangedFormat; |
|
595 TInt numberOfCharactersSuccessfullyDeleted( 0 ); |
|
596 TInt numberOfCharactersSuccessfullyInserted( 0 ); |
|
597 iEdwin.iText->CancelFepInlineEdit(paragraphContainingStartPositionOfInlineTextHasChangedFormat,numberOfCharactersSuccessfullyDeleted,numberOfCharactersSuccessfullyInserted,iPositionOfInsertionPointInDocument,iOriginalSelection.iCursorPos); |
|
598 TRAP_IGNORE( |
|
599 { |
|
600 UpdateTextViewAfterChangeInInlineTextL( |
|
601 paragraphContainingStartPositionOfInlineTextHasChangedFormat, |
|
602 numberOfCharactersSuccessfullyDeleted, |
|
603 numberOfCharactersSuccessfullyInserted, KErrNone, |
|
604 iOriginalSelection.iAnchorPos ); |
|
605 if ( iEdwin.IsFocused() ) |
|
606 { |
|
607 iEdwin.SetCursorVisibilityL( ETrue ); |
|
608 } |
|
609 }); |
|
610 iEdwin.iLayout->SetCustomDraw(iOldCustomDraw); |
|
611 ResetInternalState(); |
|
612 if ( numberOfCharactersSuccessfullyDeleted || numberOfCharactersSuccessfullyInserted ) |
|
613 { |
|
614 TRAP_IGNORE( iEdwin.ReportEdwinEventL( MEikEdwinObserver::EEventTextUpdate ) ); |
|
615 } |
|
616 } |
|
617 #if defined(_DEBUG) |
|
618 else |
|
619 { |
|
620 __ASSERT_DEBUG((iOriginalSelection.iCursorPos<0) && (iOriginalSelection.iAnchorPos<0) && (iPositionOfInsertionPointInDocument<0) && (iPositionOfInlineTextInDocument<0) && (iLengthOfInlineText<0) && (iOldCustomDraw==NULL) && (iPointerEventHandlerDuringInlineEdit==NULL),Panic(EEikPanicBadInlineEditingState12)); |
|
621 } |
|
622 #endif |
|
623 } |
|
624 |
|
625 TInt CEikEdwinFepSupport::DocumentLengthForFep() const |
|
626 { |
|
627 return iEdwin.TextLength(); |
|
628 } |
|
629 |
|
630 TInt CEikEdwinFepSupport::DocumentMaximumLengthForFep() const |
|
631 { |
|
632 return iEdwin.iTextLimit; |
|
633 } |
|
634 |
|
635 void CEikEdwinFepSupport::SetCursorSelectionForFepL(const TCursorSelection& aCursorSelection) |
|
636 { |
|
637 TInt cursorPos( aCursorSelection.iCursorPos ); |
|
638 TInt anchorPos( aCursorSelection.iAnchorPos ); |
|
639 if ( iEdwin.IsSmileyEnabled() ) |
|
640 { |
|
641 CSmileyManager* smiley( iEdwin.iEdwinExtension->iSmiley ); |
|
642 TInt oldPos = ( cursorPos == anchorPos ) ? iEdwin.CursorPos() : anchorPos; |
|
643 smiley->HandleSetCursor( oldPos, cursorPos ); |
|
644 if ( aCursorSelection.iCursorPos == aCursorSelection.iAnchorPos ) |
|
645 { |
|
646 anchorPos = cursorPos; |
|
647 } |
|
648 else |
|
649 { |
|
650 smiley->HandleSetCursor( cursorPos, anchorPos ); |
|
651 } |
|
652 } |
|
653 iEdwin.SetSelectionL( cursorPos, anchorPos ); |
|
654 iEdwin.ReportEdwinEventL(MEikEdwinObserver::EEventNavigation); |
|
655 } |
|
656 |
|
657 void CEikEdwinFepSupport::GetCursorSelectionForFep(TCursorSelection& aCursorSelection) const |
|
658 { |
|
659 aCursorSelection=iEdwin.Selection(); |
|
660 } |
|
661 |
|
662 void CEikEdwinFepSupport::GetEditorContentForFep(TDes& aEditorContent,TInt aDocumentPosition,TInt aLengthToRetrieve) const |
|
663 { |
|
664 TInt length( Min( aLengthToRetrieve, iEdwin.TextLength() - aDocumentPosition ) ); |
|
665 iEdwin.iText->Extract( aEditorContent, aDocumentPosition, length ); |
|
666 if ( iEdwin.IsSmileyEnabled() ) |
|
667 { |
|
668 CSmileyManager* smiley( iEdwin.iEdwinExtension->iSmiley ); |
|
669 CAknEdwinState* state( iEdwin.EditorState() ); |
|
670 if ( state ) |
|
671 { |
|
672 TCursorSelection inlineText( state->CurrentInlineEditSpan() ); |
|
673 if ( aDocumentPosition >= inlineText.LowerPos() && |
|
674 aDocumentPosition + length <= inlineText.HigherPos() ) |
|
675 { |
|
676 iEdwin.iEdwinExtension->iSmiley->ConvertTextForSmileyL( |
|
677 aDocumentPosition, aEditorContent, EFalse ); |
|
678 } |
|
679 } |
|
680 TBool prevIsCode( EFalse ); |
|
681 for ( TInt i( 0 ); i < length; i++ ) |
|
682 { |
|
683 if ( aEditorContent[i] == CSmileyManager::KCompensateChar ) |
|
684 { |
|
685 if ( i == 0 ) |
|
686 { |
|
687 prevIsCode = ( CSmileyManager::IsSmileyCode( |
|
688 smiley->SmileyCodeByPos( aDocumentPosition ) ) ); |
|
689 } |
|
690 if ( prevIsCode ) |
|
691 { |
|
692 aEditorContent[i] = CSmileyManager::KPlaceHolder; |
|
693 } |
|
694 } |
|
695 else |
|
696 { |
|
697 prevIsCode = CSmileyManager::IsSmileyCode( aEditorContent[i] ); |
|
698 } |
|
699 } |
|
700 } |
|
701 } |
|
702 |
|
703 void CEikEdwinFepSupport::GetFormatForFep(TCharFormat& aFormat,TInt aDocumentPosition) const |
|
704 { |
|
705 TCharFormatMask notUsed; |
|
706 STATIC_CAST(CGlobalText*,iEdwin.iText)->GetCharFormat(aFormat,notUsed,aDocumentPosition,(aDocumentPosition==iEdwin.TextLength())? 0: 1); |
|
707 } |
|
708 |
|
709 void CEikEdwinFepSupport::GetScreenCoordinatesForFepL(TPoint& aLeftSideOfBaseLine,TInt& aHeight,TInt& aAscent,TInt aDocumentPosition) const |
|
710 { |
|
711 aDocumentPosition %= ( iEdwin.iText->DocumentLength() + 1 ); |
|
712 iEdwin.iTextView->DocPosToXyPosL(aDocumentPosition,aLeftSideOfBaseLine); |
|
713 aLeftSideOfBaseLine+=iEdwin.DrawableWindow()->InquireOffset(iEdwin.iCoeEnv->RootWin()); // make position "absolute" (i.e. not relative to the window that iEdwin is using) - note that *any* group window can be passed into InquireOffset to return the desired result, it doesn't have to be an ancestor of the window being used by iEdwin (i.e. this line of code does *not* make the assumption that iEdwin is (even indirectly) attached to iCoeEnv->RootWin()) |
|
714 iEdwin.iLayout->GetCharacterHeightAndAscentL(aDocumentPosition,aHeight,aAscent); |
|
715 } |
|
716 |
|
717 MCoeFepAwareTextEditor_Extension1* CEikEdwinFepSupport::Extension1(TBool& aSetToTrue) |
|
718 { |
|
719 aSetToTrue=ETrue; |
|
720 return STATIC_CAST(MCoeFepAwareTextEditor_Extension1*, this); |
|
721 } |
|
722 |
|
723 void CEikEdwinFepSupport::DoCommitFepInlineEditL() |
|
724 { |
|
725 __ASSERT_ALWAYS(iPositionOfInlineTextInDocument>=0,Panic(EEikPanicBadInlineEditingState9)); // assert that we're currently inline editing |
|
726 __ASSERT_DEBUG((iOriginalSelection.iCursorPos>=0) && (iOriginalSelection.iAnchorPos>=0) && (iPositionOfInsertionPointInDocument>=0) && (iPositionOfInlineTextInDocument>=0) && (iLengthOfInlineText>=0) && (iPointerEventHandlerDuringInlineEdit!=NULL),Panic(EEikPanicBadInlineEditingState10)); |
|
727 iEdwin.iEdwinExtension->iInlineEditing = EFalse; |
|
728 iCharsInserted = 0; |
|
729 iCharsDeleted = 0; |
|
730 TBool paragraphContainingStartPositionOfInlineTextHasChangedFormat=EFalse; |
|
731 TInt numberOfCharactersSuccessfullyDeleted=0; |
|
732 TInt numberOfCharactersSuccessfullyInserted=0; |
|
733 TRAPD(error1,iEdwin.iText->CommitFepInlineEditL(paragraphContainingStartPositionOfInlineTextHasChangedFormat,numberOfCharactersSuccessfullyDeleted,numberOfCharactersSuccessfullyInserted,iPositionOfInsertionPointInDocument,iPositionOfInsertionPointInDocument)); |
|
734 TRAPD(error2,UpdateTextViewAfterChangeInInlineTextL(paragraphContainingStartPositionOfInlineTextHasChangedFormat,numberOfCharactersSuccessfullyDeleted,numberOfCharactersSuccessfullyInserted,error1)); |
|
735 TCursorSelection select( iPositionOfInlineTextInDocument + |
|
736 numberOfCharactersSuccessfullyInserted, iPositionOfInlineTextInDocument ); |
|
737 if (iEdwin.iUndoStore!=NULL) |
|
738 { |
|
739 iEdwin.iUndoStore->SetNewText( select ); |
|
740 } |
|
741 if ( iEdwin.IsSmileyEnabled() ) |
|
742 { |
|
743 CAknEdwinState* state( iEdwin.EditorState() ); |
|
744 TCursorSelection inlineSpan( state->CurrentInlineEditSpan() ); |
|
745 if ( inlineSpan.Length() == 0 || iShowCursor ) |
|
746 { |
|
747 iEdwin.ConvertTextForSmileyL( select, ETrue , EFalse ); |
|
748 CSmileyManager* smiley( iEdwin.iEdwinExtension->iSmiley ); |
|
749 TInt docPos( iEdwin.CursorPos() ); |
|
750 smiley->HandleSetCursor( select.iAnchorPos, docPos ); |
|
751 if ( docPos != select.iCursorPos ) |
|
752 { |
|
753 TBool isSelected( iEdwin.SelectionLength() > 0 ); |
|
754 iEdwin.SetCursorPosL( docPos, isSelected ); |
|
755 if ( isSelected ) |
|
756 { |
|
757 iEdwin.HandleSelectionForSmiley( iEdwin.Selection() ); |
|
758 } |
|
759 } |
|
760 iEdwin.SetAmountToFormatL( EFalse, ETrue ); |
|
761 iEdwin.DrawDeferred(); |
|
762 } |
|
763 } |
|
764 iOriginalSelection.SetSelection(-1,-1); |
|
765 iPositionOfInsertionPointInDocument=-1; |
|
766 iPositionOfInlineTextInDocument=-1; |
|
767 iLengthOfInlineText=-1; |
|
768 iEdwin.iLayout->SetCustomDraw(iOldCustomDraw); |
|
769 iOldCustomDraw=NULL; |
|
770 iPointerEventHandlerDuringInlineEdit=NULL; |
|
771 iEdwin.ReportEdwinEventL( MEikEdwinObserver::EEventTextUpdate ); |
|
772 User::LeaveIfError(error2); |
|
773 } |
|
774 |
|
775 /*MCoeFepAwareTextEditor_Extension1* CEikEdwinFepSupport::Extension1(TBool& aSetToTrue) |
|
776 { |
|
777 aSetToTrue=ETrue; |
|
778 return this; |
|
779 } |
|
780 */ |
|
781 void CEikEdwinFepSupport::MCoeFepAwareTextEditor_Reserved_2() |
|
782 { |
|
783 } |
|
784 |
|
785 void CEikEdwinFepSupport::SetStateTransferingOwnershipL(CState* aState, TUid aTypeSafetyUid) |
|
786 { |
|
787 MEikCcpuEditor* currentCcpuState=STATIC_CAST(CAknEdwinState*, State(KNullUid))->CcpuState(); |
|
788 MObjectProvider* currentObjectProvider=STATIC_CAST(CAknEdwinState*, State(KNullUid))->ObjectProvider(); |
|
789 delete iState; |
|
790 iState=aState; |
|
791 STATIC_CAST(CAknEdwinState*, State(KNullUid))->SetCcpuState(currentCcpuState); |
|
792 STATIC_CAST(CAknEdwinState*, State(KNullUid))->SetObjectProvider(currentObjectProvider); |
|
793 iStateTypeSafetyUid.iUid=aTypeSafetyUid.iUid; |
|
794 } |
|
795 |
|
796 MCoeFepAwareTextEditor_Extension1::CState* CEikEdwinFepSupport::State(TUid aTypeSafetyUid) |
|
797 { |
|
798 if (aTypeSafetyUid.iUid==iStateTypeSafetyUid.iUid) |
|
799 { |
|
800 return iState; |
|
801 } |
|
802 return NULL; |
|
803 } |
|
804 |
|
805 void CEikEdwinFepSupport::StartFepInlineEditL( |
|
806 TBool& aSetToTrue, |
|
807 const TCursorSelection& aCursorSelection, |
|
808 const TDesC& aInitialInlineText, |
|
809 TInt aPositionOfInsertionPointInInlineText, |
|
810 TBool aCursorVisibility, |
|
811 const MFormCustomDraw* aCustomDraw, |
|
812 MFepInlineTextFormatRetriever& aInlineTextFormatRetriever, |
|
813 MFepPointerEventHandlerDuringInlineEdit& aPointerEventHandlerDuringInlineEdit) |
|
814 { |
|
815 aSetToTrue=ETrue; |
|
816 iEdwin.PerformRecordedOperationL(); |
|
817 TBool selectionVisible = iEdwin.iTextView->SelectionVisible(); |
|
818 if (selectionVisible) |
|
819 iEdwin.SetSelectionVisibilityL(EFalse); |
|
820 SetCursorSelectionForFepL(aCursorSelection); |
|
821 |
|
822 StartFepInlineEditL(aInitialInlineText, aPositionOfInsertionPointInInlineText, aCursorVisibility, aCustomDraw, aInlineTextFormatRetriever, aPointerEventHandlerDuringInlineEdit); |
|
823 if (selectionVisible) |
|
824 iEdwin.SetSelectionVisibilityL(ETrue); |
|
825 } |
|
826 |
|
827 void CEikEdwinFepSupport::SetCursorType(TBool& /*aSetToTrue*/, const TTextCursor& aTextCursor) |
|
828 { |
|
829 TRAP_IGNORE( iEdwin.iTextView->SetCursorWidthTypeL( aTextCursor.iType ) ); |
|
830 } |
|
831 |
|
832 void CEikEdwinFepSupport::MCoeFepAwareTextEditor_Extension1_Reserved_3() |
|
833 { |
|
834 } |
|
835 |
|
836 void CEikEdwinFepSupport::MCoeFepAwareTextEditor_Extension1_Reserved_4() |
|
837 { |
|
838 } |
|
839 |
|
840 TBool CEikEdwinFepSupport::IsValidCharacter(TInt aChar) |
|
841 { |
|
842 if (aChar == CEditableText::EParagraphDelimiter && |
|
843 (iEdwin.UserFlags() & CEikEdwin::ENoLineOrParaBreaks)) |
|
844 return EFalse; |
|
845 |
|
846 if ((aChar==EKeyEnter || aChar==CEditableText::EParagraphDelimiter) && iEdwin.iEdwinInternalFlags & CEikEdwin::EHasOneLineOnly) |
|
847 return EFalse; |
|
848 /* |
|
849 if (iEdwin.OnlyASCIIChars() && aChar > 0xFF && aChar != KPuaCodeSpaceSymbol) |
|
850 return EFalse; |
|
851 */ |
|
852 |
|
853 if ( !iEdwin.IsValidChar( aChar ) ) |
|
854 { |
|
855 return EFalse; |
|
856 } |
|
857 |
|
858 return ETrue; |
|
859 } |
|
860 |
|
861 |
|
862 void CEikEdwinFepSupport::MCoeFepSpecificExtensions_Reserved_1() |
|
863 { |
|
864 } |
|
865 |
|
866 void CEikEdwinFepSupport::MCoeFepSpecificExtensions_Reserved_2() |
|
867 { |
|
868 } |
|
869 |
|
870 |
|
871 // |
|
872 // CEikEdwinExtension |
|
873 // |
|
874 CEikEdwin::CEikEdwinExtension* CEikEdwin::CEikEdwinExtension::NewL(CEikEdwin* aEdwin) |
|
875 { |
|
876 CEikEdwinExtension* self = new (ELeave) CEikEdwinExtension(); |
|
877 CleanupStack::PushL(self); |
|
878 self->ConstructL(aEdwin); |
|
879 CleanupStack::Pop(); // self |
|
880 return self; |
|
881 } |
|
882 |
|
883 CEikEdwin::CEikEdwinExtension::~CEikEdwinExtension() |
|
884 { |
|
885 delete iPhysicsHandler; |
|
886 |
|
887 // Stop listening CenRep. |
|
888 if (iCenRepNotifyHandler) |
|
889 { |
|
890 iCenRepNotifyHandler->StopListening(); |
|
891 } |
|
892 delete iCenRepNotifyHandler; |
|
893 delete iCenRep; |
|
894 |
|
895 delete iFormAccessor; |
|
896 delete iFormCursorModifier; |
|
897 delete iFormExtendedInterfaceProvider; |
|
898 delete iPictographInterface; |
|
899 delete iExtendedInputCapabilities; |
|
900 delete iPtSuppressor; |
|
901 if( iDestroyedPtr ) |
|
902 { |
|
903 // Mark the object as destroyed. |
|
904 *iDestroyedPtr = ETrue; |
|
905 iDestroyedPtr = NULL; |
|
906 } |
|
907 delete iSmiley; |
|
908 delete iSmileyWrap; |
|
909 } |
|
910 |
|
911 EXPORT_C CAknEdwinFormAccessor* CEikEdwin::CEikEdwinExtension::FormAccessor() const |
|
912 { |
|
913 return iFormAccessor; |
|
914 } |
|
915 |
|
916 EXPORT_C void CEikEdwin::CEikEdwinExtension::SetFormAccessor(CAknEdwinFormAccessor* aFormAccessor) |
|
917 { |
|
918 iFormAccessor = aFormAccessor; |
|
919 } |
|
920 |
|
921 EXPORT_C void CEikEdwin::CEikEdwinExtension::SetScrollBarSetter(CIdle* aScrollBarSetter) |
|
922 { |
|
923 iSetScrollBar=aScrollBarSetter; |
|
924 } |
|
925 |
|
926 EXPORT_C CIdle* CEikEdwin::CEikEdwinExtension::ScrollBarSetter() |
|
927 { |
|
928 return iSetScrollBar; |
|
929 } |
|
930 |
|
931 EXPORT_C const TAvkonEditorCustomWrap& CEikEdwin::CEikEdwinExtension::TextWrapper() |
|
932 { |
|
933 return iTextWrapper; |
|
934 } |
|
935 |
|
936 EXPORT_C CFormCursorModifier* CEikEdwin::CEikEdwinExtension::FormCursorModifier() const |
|
937 { |
|
938 return iFormCursorModifier; |
|
939 } |
|
940 |
|
941 void CEikEdwin::CEikEdwinExtension::SetSkinBackgroundControlContext( MAknsControlContext* aBackgroundControlContext) |
|
942 { |
|
943 iSkinBackgroundControlContext = aBackgroundControlContext; |
|
944 iFlags.Set(ESkinBackgroundControlContextHasBeenSetIndex); |
|
945 } |
|
946 |
|
947 MAknsControlContext* CEikEdwin::CEikEdwinExtension::SkinBackgroundControlContext() const |
|
948 { |
|
949 return iSkinBackgroundControlContext; |
|
950 } |
|
951 |
|
952 TBool CEikEdwin::CEikEdwinExtension::SkinBackgroundControlContextHasBeenSet() const |
|
953 { |
|
954 return iFlags[ESkinBackgroundControlContextHasBeenSetIndex]; |
|
955 } |
|
956 |
|
957 void CEikEdwin::CEikEdwinExtension::SetAlignment(TInt aAlignment) |
|
958 { |
|
959 iAlignment = aAlignment; |
|
960 TUint capabilities = iExtendedInputCapabilities->Capabilities(); |
|
961 capabilities &= ~( CAknExtendedInputCapabilities::KAknEditorAlignMask ); |
|
962 switch( iAlignment ) |
|
963 { |
|
964 case EAknEditorAlignCenter: |
|
965 capabilities |= |
|
966 CAknExtendedInputCapabilities::EInputEditorAlignCenter; |
|
967 break; |
|
968 case EAknEditorAlignLeft: |
|
969 capabilities |= |
|
970 CAknExtendedInputCapabilities::EInputEditorAlignLeft; |
|
971 break; |
|
972 case EAknEditorAlignRight: |
|
973 capabilities |= |
|
974 CAknExtendedInputCapabilities::EInputEditorAlignRight; |
|
975 break; |
|
976 case EAknEditorAlignBidi: |
|
977 capabilities |= |
|
978 CAknExtendedInputCapabilities::EInputEditorAlignBidi; |
|
979 break; |
|
980 default: |
|
981 break; |
|
982 } |
|
983 iExtendedInputCapabilities->SetCapabilities( capabilities ); |
|
984 } |
|
985 |
|
986 TInt CEikEdwin::CEikEdwinExtension::CurrentAlignment() const |
|
987 { |
|
988 return iAlignment; |
|
989 } |
|
990 |
|
991 void CEikEdwin::CEikEdwinExtension::SetSuppressBackgroundDrawing( TBool aSuppress ) |
|
992 { |
|
993 iFlags.Assign( ESuppressBackgroundDrawing, aSuppress ); |
|
994 } |
|
995 |
|
996 TBool CEikEdwin::CEikEdwinExtension::IsBackgroundDrawingSuppressed() const |
|
997 { |
|
998 return iFlags[ESuppressBackgroundDrawing]; |
|
999 } |
|
1000 |
|
1001 void CEikEdwin::CEikEdwinExtension::SetPictoCallBack( TCallBack& aCallBack ) |
|
1002 { |
|
1003 iPictoCallBack = aCallBack; |
|
1004 } |
|
1005 |
|
1006 const TCallBack& CEikEdwin::CEikEdwinExtension::PictoCallBack() const |
|
1007 { |
|
1008 return iPictoCallBack; |
|
1009 } |
|
1010 |
|
1011 CEikEdwin::CEikEdwinExtension::CEikEdwinExtension() : |
|
1012 iAlignment(EAknEditorAlignBidi), |
|
1013 iSkinIdForText(KErrNotFound), |
|
1014 iUpperFullFormattingLength(KFullFormattingUpperThreshold), |
|
1015 iTempCursorPos( KErrNotFound ), |
|
1016 iTempAnchorPos( KErrNotFound ), |
|
1017 iThumbPos( KErrNotFound ), |
|
1018 iEdwin( NULL ), |
|
1019 iPhysicsHandler( NULL ) |
|
1020 { |
|
1021 } |
|
1022 |
|
1023 void CEikEdwin::CEikEdwinExtension::ConstructL(CEikEdwin* aEdwin) |
|
1024 { |
|
1025 iEdwin = aEdwin; |
|
1026 iFormAccessor = new (ELeave) CAknEdwinFormAccessor(aEdwin); |
|
1027 iFormCursorModifier = CFormCursorModifier::NewL(aEdwin->TextView(), aEdwin->TextLayout()); |
|
1028 iPictographInterface = CAknPictographInterface::NewL( *aEdwin, iPictographDrawer ); |
|
1029 iExtendedInputCapabilities = CAknExtendedInputCapabilities::NewL(); |
|
1030 iPtSuppressor = CAknPointerEventSuppressor::NewL(); |
|
1031 |
|
1032 // Start listening a CenRep key indicating whether hash key selection is active. |
|
1033 TRAPD(err, iCenRep = CRepository::NewL(KCRUidAknFep)); |
|
1034 if (err == KErrNone) |
|
1035 { |
|
1036 iCenRepNotifyHandler = CCenRepNotifyHandler::NewL(*this, |
|
1037 *iCenRep, |
|
1038 CCenRepNotifyHandler::EIntKey, |
|
1039 KAknFepClearDirection); |
|
1040 |
|
1041 iCenRepNotifyHandler->StartListeningL(); |
|
1042 iCenRep->Get(KAknFepClearDirection, iClearDirection); |
|
1043 } |
|
1044 iSmileyWrap = new ( ELeave ) CSmileyCustomWrap; |
|
1045 } |
|
1046 |
|
1047 void CEikEdwin::CEikEdwinExtension::CreateFormExtendedInterfaceProviderIfNeededL() |
|
1048 { |
|
1049 if ( !iFormExtendedInterfaceProvider ) |
|
1050 iFormExtendedInterfaceProvider = CAknEdwinFormExtendedInterfaceProvider::NewL(); |
|
1051 } |
|
1052 |
|
1053 CAknEdwinFormExtendedInterfaceProvider* CEikEdwin::CEikEdwinExtension::FormExtendedInferfaceProvider( ) const |
|
1054 { |
|
1055 return iFormExtendedInterfaceProvider; |
|
1056 } |
|
1057 |
|
1058 void CEikEdwin::CEikEdwinExtension::CreatePurePhoneNumberFormatterL( CTextLayout& /*aLayout*/, const CPlainText& aText ) |
|
1059 { |
|
1060 CreateFormExtendedInterfaceProviderIfNeededL(); |
|
1061 |
|
1062 if ( !iPhoneNumberFormatter ) |
|
1063 { |
|
1064 CAknPhoneNumberInlineTextSource* phoneNumberFormatter = |
|
1065 CAknPlainPhoneNumberInlineTextSource::NewL( aText ); |
|
1066 CleanupStack::PushL( phoneNumberFormatter ); |
|
1067 iFormExtendedInterfaceProvider-> |
|
1068 CompositeInlineTextSource().InstallInlineTextSourceL( phoneNumberFormatter ); |
|
1069 CleanupStack::Pop( phoneNumberFormatter ); |
|
1070 iPhoneNumberFormatter = phoneNumberFormatter; |
|
1071 } |
|
1072 } |
|
1073 |
|
1074 |
|
1075 void CEikEdwin::CEikEdwinExtension::CreateNoMatchesIndicatorFormatterL( CTextLayout& aLayout ) |
|
1076 { |
|
1077 CreateFormExtendedInterfaceProviderIfNeededL(); |
|
1078 |
|
1079 if ( !iNoMatchesIndicatorFormatter ) |
|
1080 { |
|
1081 CAknNoMatchesIndicatorInlineTextSource* noMatchesIndicatorFormatter = CAknNoMatchesIndicatorInlineTextSource::NewL( aLayout ); |
|
1082 CleanupStack::PushL( noMatchesIndicatorFormatter ); |
|
1083 iFormExtendedInterfaceProvider->CompositeInlineTextSource().InstallInlineTextSourceL( noMatchesIndicatorFormatter ); |
|
1084 CleanupStack::Pop( noMatchesIndicatorFormatter ); |
|
1085 iNoMatchesIndicatorFormatter = noMatchesIndicatorFormatter; |
|
1086 } |
|
1087 } |
|
1088 |
|
1089 |
|
1090 void CEikEdwin::CEikEdwinExtension::CreateRichTextPhoneNumberFormatterL( CTextLayout& /*aTextLayout*/, const CRichText& aText ) |
|
1091 { |
|
1092 CreateFormExtendedInterfaceProviderIfNeededL(); |
|
1093 |
|
1094 if ( !iPhoneNumberFormatter ) |
|
1095 { |
|
1096 CAknRichTextPhoneNumberInlineTextSource* phoneNumberFormatter = |
|
1097 CAknRichTextPhoneNumberInlineTextSource::NewL( aText ); |
|
1098 CleanupStack::PushL( phoneNumberFormatter ); |
|
1099 iFormExtendedInterfaceProvider-> |
|
1100 CompositeInlineTextSource().InstallInlineTextSourceL( phoneNumberFormatter ); |
|
1101 CleanupStack::Pop( phoneNumberFormatter ); |
|
1102 iPhoneNumberFormatter = phoneNumberFormatter; |
|
1103 } |
|
1104 |
|
1105 } |
|
1106 |
|
1107 CAknInlineTextSource* CEikEdwin::CEikEdwinExtension::InlineTextSource() const |
|
1108 { |
|
1109 CAknEdwinFormExtendedInterfaceProvider* provider = FormExtendedInferfaceProvider(); |
|
1110 if ( provider ) |
|
1111 return &(provider->CompositeInlineTextSource()); |
|
1112 else |
|
1113 return NULL; |
|
1114 } |
|
1115 |
|
1116 CAknPictographInterface* CEikEdwin::CEikEdwinExtension::PictographInterface() const |
|
1117 { |
|
1118 return iPictographInterface; |
|
1119 } |
|
1120 |
|
1121 TInt CEikEdwin::CEikEdwinExtension::ClearDirection() const |
|
1122 { |
|
1123 return iClearDirection; |
|
1124 } |
|
1125 |
|
1126 void CEikEdwin::CEikEdwinExtension::HandleNotifyInt(TUint32 aId, TInt aNewValue) |
|
1127 { |
|
1128 if (aId == KAknFepClearDirection) |
|
1129 { |
|
1130 iClearDirection = (TBool)aNewValue; |
|
1131 } |
|
1132 } |
|
1133 |
|
1134 // --------------------------------------------------------------------------- |
|
1135 // CEikEdwin::CEikEdwinExtension::EnableKineticScrollingL |
|
1136 // --------------------------------------------------------------------------- |
|
1137 // |
|
1138 void CEikEdwin::CEikEdwinExtension::EnableKineticScrollingL() |
|
1139 { |
|
1140 iFlags.Set( EKineticScrollingEnabled ); |
|
1141 EnablePhysicsL(); |
|
1142 } |
|
1143 |
|
1144 // --------------------------------------------------------------------------- |
|
1145 // CEikEdwin::CEikEdwinExtension::EnablePhysicsL |
|
1146 // --------------------------------------------------------------------------- |
|
1147 // |
|
1148 void CEikEdwin::CEikEdwinExtension::EnablePhysicsL() |
|
1149 { |
|
1150 if ( iFlags.IsSet( EKineticScrollingEnabled ) |
|
1151 && !iPhysicsHandler && iEdwin->DrawableWindow() ) |
|
1152 { |
|
1153 iPhysicsHandler = CAknEdwinPhysicsHandler::NewL( *iEdwin ); |
|
1154 |
|
1155 InitPhysicsL(); |
|
1156 if ( iEdwin->iLayout ) |
|
1157 { |
|
1158 iEdwin->iLayout->RestrictScrollToTopsOfLines( EFalse ); |
|
1159 } |
|
1160 } |
|
1161 } |
|
1162 |
|
1163 // --------------------------------------------------------------------------- |
|
1164 // CEikEdwin::CEikEdwinExtension::InitPhysicsL |
|
1165 // --------------------------------------------------------------------------- |
|
1166 // |
|
1167 void CEikEdwin::CEikEdwinExtension::InitPhysicsL() |
|
1168 { |
|
1169 if ( iPhysicsHandler ) |
|
1170 { |
|
1171 if ( iEdwin->iTextView ) |
|
1172 { |
|
1173 iPhysicsHandler->SetViewRect( iEdwin->AdjustedViewRect() ); |
|
1174 } |
|
1175 iPhysicsHandler->InitPhysicsL(); |
|
1176 } |
|
1177 } |
|
1178 |
|
1179 // |
|
1180 // class CEikEdwin |
|
1181 // |
|
1182 |
|
1183 |
|
1184 const TInt KPointerRepeatRate=50000; |
|
1185 // const TInt KBlockDeleteWarningSize=300; // minimum block delete that will elicit a query |
|
1186 |
|
1187 EXPORT_C CEikEdwin::~CEikEdwin() |
|
1188 { |
|
1189 AKNTASHOOK_REMOVE(); |
|
1190 if ( iEdwinFepSupport ) |
|
1191 { |
|
1192 CAknEdwinState* edwinState = STATIC_CAST( CAknEdwinState*, iEdwinFepSupport->State(KNullUid) ); |
|
1193 if ( edwinState ) |
|
1194 { |
|
1195 TRAP_IGNORE( edwinState->ReportAknEdStateEventL( MAknEdStateObserver::EAknEdwinDestroy ) ); |
|
1196 } |
|
1197 } |
|
1198 SetKeyboardRepeatRate(KAknStandardKeyboardRepeatRate); |
|
1199 delete iCcpuSupport; |
|
1200 delete iCustomDrawer; |
|
1201 delete iEdwinFepSupport; |
|
1202 |
|
1203 if (!(iEdwinUserFlags&EKeepDocument)) |
|
1204 delete iText; |
|
1205 delete iTextView; |
|
1206 delete iLayout; |
|
1207 if (iEdwinExtension) |
|
1208 { |
|
1209 delete iEdwinExtension->ScrollBarSetter(); |
|
1210 } |
|
1211 delete iEdwinExtension; |
|
1212 delete iSBFrame; |
|
1213 delete iUndoStore; |
|
1214 delete iObserverArray; |
|
1215 #ifdef _DEBUG |
|
1216 TRAPD(err, SetVirtualCursorStateL(EFalse)); //should never leave |
|
1217 __ASSERT_DEBUG(err==KErrNone,Panic(EEikPanicVirtualCursorLeaveNotExpected)); |
|
1218 #else |
|
1219 TRAP_IGNORE(SetVirtualCursorStateL(EFalse)); //should never leave |
|
1220 #endif // _DEBUG |
|
1221 |
|
1222 delete iCharFormatLayer; |
|
1223 delete iParaFormatLayer; |
|
1224 } |
|
1225 |
|
1226 EXPORT_C CEikEdwin::CEikEdwin() |
|
1227 : iZoomFactor(iEikonEnv->ScreenDevice()), |
|
1228 iAvgCharsPerLine(1) |
|
1229 { |
|
1230 __DECLARE_NAME(_S("CEikEdwin")); |
|
1231 LafEdwin::GetDefaultBorder(iBorder); |
|
1232 iMargins=LafEdwin::Margins(); |
|
1233 BuildEdwinFepSupport(); |
|
1234 iParaFormatLayer = NULL; |
|
1235 iCharFormatLayer = NULL; |
|
1236 |
|
1237 TRAPD(err, iEdwinExtension = CEikEdwinExtension::NewL(this)); |
|
1238 if (err == KErrNone) |
|
1239 { |
|
1240 if (EditorState()) |
|
1241 EditorState()->SetFormAccessor(iEdwinExtension->FormAccessor()); |
|
1242 |
|
1243 iEdwinExtension->iExtendedInputCapabilities->SetEditorType( |
|
1244 CAknExtendedInputCapabilities::EEdwinBased ); |
|
1245 } |
|
1246 AKNTASHOOK_ADD( this, "CEikEdwin" ); |
|
1247 } |
|
1248 |
|
1249 EXPORT_C CEikEdwin::CEikEdwin(const TGulBorder& aBorder) |
|
1250 : CEikBorderedControl(aBorder), |
|
1251 iZoomFactor(iEikonEnv->ScreenDevice()), |
|
1252 iAvgCharsPerLine(1) |
|
1253 { |
|
1254 __DECLARE_NAME(_S("CEikEdwin")); |
|
1255 iMargins=LafEdwin::Margins(); |
|
1256 BuildEdwinFepSupport(); |
|
1257 iParaFormatLayer = NULL; |
|
1258 iCharFormatLayer = NULL; |
|
1259 |
|
1260 TRAPD(err, iEdwinExtension = CEikEdwinExtension::NewL(this)); |
|
1261 if (err == KErrNone) |
|
1262 { |
|
1263 if (EditorState()) |
|
1264 EditorState()->SetFormAccessor(iEdwinExtension->FormAccessor()); |
|
1265 |
|
1266 iEdwinExtension->iExtendedInputCapabilities->SetEditorType( |
|
1267 CAknExtendedInputCapabilities::EEdwinBased ); |
|
1268 } |
|
1269 AKNTASHOOK_ADD( this, "CEikEdwin" ); |
|
1270 } |
|
1271 |
|
1272 void CEikEdwin::BuildEdwinFepSupport() |
|
1273 { |
|
1274 iEdwinFepSupport=CEikEdwinFepSupport::New(*this); // don't leave |
|
1275 if (iEdwinFepSupport) |
|
1276 { |
|
1277 iEdwinFepSupport->ConstructStateHolder(); |
|
1278 if (!iEdwinFepSupport->State(KNullUid)) |
|
1279 { |
|
1280 delete iEdwinFepSupport; |
|
1281 iEdwinFepSupport = NULL; |
|
1282 } |
|
1283 } |
|
1284 } |
|
1285 |
|
1286 EXPORT_C void CEikEdwin::ConstructFromResourceL(TResourceReader& aReader) |
|
1287 { |
|
1288 iEdwinUserFlags=iEdwinUserFlags | aReader.ReadInt32(); |
|
1289 CalculateWidth(aReader.ReadInt16()); |
|
1290 iNumberOfLines=aReader.ReadInt16(); |
|
1291 iTextLimit=aReader.ReadInt16(); |
|
1292 ReadAknResourceL(aReader); |
|
1293 BaseConstructL(); |
|
1294 } |
|
1295 |
|
1296 |
|
1297 EXPORT_C TInt CEikEdwin::AknEdwinFlags() const |
|
1298 { |
|
1299 if (iEdwinFepSupport && iEdwinFepSupport->State(KNullUid)) |
|
1300 return STATIC_CAST(CAknEdwinState*, iEdwinFepSupport->State(KNullUid))->Flags(); |
|
1301 else |
|
1302 return 0; |
|
1303 } |
|
1304 |
|
1305 EXPORT_C void CEikEdwin::BaseConstructL() |
|
1306 { |
|
1307 if (iEdwinUserFlags&EEdwinAlternativeWrapping) |
|
1308 SetAvkonWrap(EFalse); |
|
1309 else |
|
1310 SetAvkonWrap(ETrue); // added to make changes in Edwin spacing work. |
|
1311 if (iEdwinUserFlags&EUserSuppliedText) |
|
1312 { |
|
1313 if (iNumberOfLines) |
|
1314 { |
|
1315 TInt height = iNumberOfLines*iEikonEnv->NormalFont()->HeightInPixels()+iBorder.SizeDelta().iHeight |
|
1316 +iMargins.iTop+iMargins.iBottom; |
|
1317 SetEdwinHeight(height); |
|
1318 } |
|
1319 } |
|
1320 else |
|
1321 { |
|
1322 CheckIfEdwinIsResizable(); |
|
1323 CParaFormatLayer* paraFormatLayer = (iEdwinInternalFlags&EHasOneLineOnly) |
|
1324 ? iEikonEnv->SystemSingleLineParaFormatLayerL() |
|
1325 : iEikonEnv->SystemParaFormatLayerL(); |
|
1326 |
|
1327 SetParaFormatLayer(paraFormatLayer->CloneL()); |
|
1328 SetCharFormatLayer(iEikonEnv->SystemCharFormatLayerL()->CloneL()); |
|
1329 |
|
1330 CreateTextAndLayoutL(iParaFormatLayer,iCharFormatLayer); |
|
1331 } |
|
1332 |
|
1333 EnableCcpuSupportL(ETrue); |
|
1334 if (AknEdwinFlags()&EAknEditorFlagEnableScrollBars) |
|
1335 { |
|
1336 CEikScrollBarFrame* scrollFrame = CreatePreAllocatedScrollBarFrameL(); |
|
1337 scrollFrame->SetScrollBarVisibilityL(CEikScrollBarFrame::EOff, CEikScrollBarFrame::EAuto); |
|
1338 scrollFrame->SetScrollBarFrameFlags(CEikScrollBarFrame::EVVisible); |
|
1339 } |
|
1340 SetVKBStatus(); |
|
1341 } |
|
1342 |
|
1343 EXPORT_C void CEikEdwin::SetCharFormatLayer(CCharFormatLayer* aCharFormatLayer) |
|
1344 { |
|
1345 ASSERT(aCharFormatLayer); |
|
1346 if (iCharFormatLayer) |
|
1347 { |
|
1348 // copy all the format attributes of the new layer, apply to the already |
|
1349 // existing format layer, then delete the one passed in (this function was taking ownership) |
|
1350 // This avoids a problem with ETEXT and CRichText, where CGlobalText::iGlobalCharFormatLayer |
|
1351 // cannot be changed. |
|
1352 if (!(iCharFormatLayer->IsIdentical(aCharFormatLayer,EFalse))) |
|
1353 { |
|
1354 TRAP_IGNORE(MakeCharFormatLayerMatchL(aCharFormatLayer)); |
|
1355 } |
|
1356 delete aCharFormatLayer; |
|
1357 } |
|
1358 else |
|
1359 { |
|
1360 iCharFormatLayer = aCharFormatLayer; |
|
1361 if (STATIC_CAST(CGlobalText*, Text())) |
|
1362 { |
|
1363 STATIC_CAST(CGlobalText*, Text())->SetGlobalCharFormat(iCharFormatLayer); |
|
1364 } |
|
1365 } |
|
1366 } |
|
1367 |
|
1368 EXPORT_C void CEikEdwin::SetParaFormatLayer(CParaFormatLayer* aParaFormatLayer) |
|
1369 { |
|
1370 ASSERT(aParaFormatLayer); |
|
1371 if (iParaFormatLayer) |
|
1372 { |
|
1373 // copy all the format attributes of the new layer, apply to the already |
|
1374 // existing format layer, then delete the one passed in (this function was taking ownership) |
|
1375 // This avoids a problem with ETEXT and CRichText, where CGlobalText::iGlobalCharFormatLayer |
|
1376 // cannot be changed. |
|
1377 if (!(iParaFormatLayer->IsIdentical(aParaFormatLayer,EFalse))) |
|
1378 { |
|
1379 TRAP_IGNORE(MakeParaFormatLayerMatchL(aParaFormatLayer)); |
|
1380 } |
|
1381 delete aParaFormatLayer; |
|
1382 } |
|
1383 else |
|
1384 { |
|
1385 iParaFormatLayer = aParaFormatLayer; |
|
1386 if (STATIC_CAST(CGlobalText*, Text())) |
|
1387 { |
|
1388 STATIC_CAST(CGlobalText*, Text())->SetGlobalParaFormat(iParaFormatLayer); |
|
1389 } |
|
1390 } |
|
1391 } |
|
1392 |
|
1393 void CEikEdwin::MakeCharFormatLayerMatchL(CCharFormatLayer* aCharFormatLayer) |
|
1394 { |
|
1395 ASSERT(aCharFormatLayer); |
|
1396 TCharFormat newCharFormat; |
|
1397 aCharFormatLayer->SenseEffective(newCharFormat); |
|
1398 TCharFormat currentCharFormat; |
|
1399 iCharFormatLayer->SenseEffective(currentCharFormat); |
|
1400 if (!currentCharFormat.IsEqual(newCharFormat)) |
|
1401 { |
|
1402 TCharFormatMask newCharFormatMask; |
|
1403 newCharFormatMask.SetAll(); |
|
1404 iCharFormatLayer->SetL(newCharFormat,newCharFormatMask); |
|
1405 } |
|
1406 } |
|
1407 |
|
1408 void CEikEdwin::MakeParaFormatLayerMatchL(CParaFormatLayer* aParaFormatLayer) |
|
1409 { |
|
1410 ASSERT(aParaFormatLayer); |
|
1411 CParaFormat* newParaFormat=CParaFormat::NewLC(); |
|
1412 CParaFormat* currentParaFormat=CParaFormat::NewLC(); |
|
1413 aParaFormatLayer->SenseEffectiveL(newParaFormat); |
|
1414 iParaFormatLayer->SenseEffectiveL(currentParaFormat); |
|
1415 if (!currentParaFormat->IsEqual(*newParaFormat)) |
|
1416 { |
|
1417 TParaFormatMask newParaFormatMask; |
|
1418 newParaFormatMask.SetAll(); |
|
1419 iParaFormatLayer->SetL(newParaFormat,newParaFormatMask); |
|
1420 } |
|
1421 CleanupStack::PopAndDestroy(2); // currentParaFormat,newParaFormat |
|
1422 } |
|
1423 |
|
1424 EXPORT_C void CEikEdwin::SetSkinBackgroundControlContextL( MAknsControlContext* aBackgroundControlContext ) |
|
1425 { |
|
1426 CheckEdwinExtensionL(); // checks if iEdwinExtension is NULL and constucts it if it is |
|
1427 iEdwinExtension->SetSkinBackgroundControlContext( aBackgroundControlContext ); |
|
1428 } |
|
1429 |
|
1430 MAknsControlContext* CEikEdwin::SkinBackgroundControlContext() const |
|
1431 { |
|
1432 MAknsControlContext* context = NULL; |
|
1433 if ( SkinEnabled() ) // Otherwise null is returned |
|
1434 { |
|
1435 if ( iEdwinExtension ) |
|
1436 context = iEdwinExtension->SkinBackgroundControlContext(); |
|
1437 // if context is still null we still may return a context, but it has to be from env. |
|
1438 if ( !context ) |
|
1439 context = AknsDrawUtils::ControlContext( this ); |
|
1440 } |
|
1441 return context; |
|
1442 } |
|
1443 |
|
1444 TBool CEikEdwin::SkinEnabled() const |
|
1445 { |
|
1446 TBool enabled( ETrue ); |
|
1447 // return EFalse only if the background control context has been set by API |
|
1448 // and the value set is NULL |
|
1449 if ( iEdwinExtension ) |
|
1450 { |
|
1451 if (iEdwinExtension->SkinBackgroundControlContextHasBeenSet() ) |
|
1452 if ( !(iEdwinExtension->SkinBackgroundControlContext()) ) // do not use Edwin method here; would cause recursion |
|
1453 enabled = EFalse; |
|
1454 } |
|
1455 return enabled; |
|
1456 } |
|
1457 |
|
1458 |
|
1459 void CEikEdwin::UpdateCache(TInt aId) |
|
1460 { |
|
1461 CAknSettingCache& cache = CAknEnv::Static()->SettingCache(); |
|
1462 cache.Update(aId); |
|
1463 } |
|
1464 |
|
1465 void CEikEdwin::DrawTextView() const |
|
1466 { |
|
1467 if ( IsReadyToDraw() ) |
|
1468 { |
|
1469 TRect rect = iTextView->ViewRect(); |
|
1470 Window().Invalidate( rect ); |
|
1471 ActivateGc(); |
|
1472 Window().BeginRedraw( rect ); |
|
1473 TrappedDraw( iTextView->ViewRect() ); |
|
1474 Window().EndRedraw(); |
|
1475 DeactivateGc(); |
|
1476 } |
|
1477 } |
|
1478 |
|
1479 /** |
|
1480 * This routine performs draws in the area around the text view. Most of the work is to drive the |
|
1481 * custom drawer if present. |
|
1482 * |
|
1483 */ |
|
1484 void CEikEdwin::DrawBackgroundAroundTextView( CWindowGc& gc, |
|
1485 const TRect& aOuterRect, |
|
1486 const TRect& aInnerRect, |
|
1487 const TRgb& aBackgroundColor ) const |
|
1488 { |
|
1489 // Skins support |
|
1490 if ( iCustomDrawer ) |
|
1491 { |
|
1492 TPoint point(aInnerRect.iTl); // Text layout upper left. |
|
1493 TZoomFactor map(iZoomFactor); |
|
1494 |
|
1495 // This returns the rectangle actually used. Not used here |
|
1496 TRect drawn; |
|
1497 |
|
1498 TRect rect=aOuterRect; |
|
1499 rect.iBr.iY=aInnerRect.iTl.iY; |
|
1500 iCustomDrawer->DrawBackground( |
|
1501 MFormCustomDraw::TParam( gc, map, point, rect ), aBackgroundColor, drawn); |
|
1502 rect.iBr.iY=aOuterRect.iBr.iY; |
|
1503 rect.iTl.iY=aInnerRect.iBr.iY; |
|
1504 iCustomDrawer->DrawBackground( |
|
1505 MFormCustomDraw::TParam( gc, map, point, rect ), aBackgroundColor, drawn); |
|
1506 rect=aInnerRect; |
|
1507 rect.iTl.iX=aOuterRect.iTl.iX; |
|
1508 rect.iBr.iX=aInnerRect.iTl.iX; |
|
1509 iCustomDrawer->DrawBackground( |
|
1510 MFormCustomDraw::TParam( gc, map, point, rect ), aBackgroundColor, drawn); |
|
1511 rect.iTl.iX=aInnerRect.iBr.iX; |
|
1512 rect.iBr.iX=aOuterRect.iBr.iX; |
|
1513 iCustomDrawer->DrawBackground( |
|
1514 MFormCustomDraw::TParam( gc, map, point, rect ), aBackgroundColor, drawn); |
|
1515 } |
|
1516 else |
|
1517 { |
|
1518 // Draws with a null pen but solid brush |
|
1519 DrawUtils::ClearBetweenRects(gc,aOuterRect,aInnerRect); |
|
1520 } |
|
1521 |
|
1522 } |
|
1523 |
|
1524 EXPORT_C CLafEdwinCustomDrawBase* CEikEdwin::CreateCustomDrawL() |
|
1525 { |
|
1526 // If we have a text view, then use the constructor that sets it |
|
1527 CAknEdwinCustomDrawPrivate* customDrawer; |
|
1528 if ( iTextView ) |
|
1529 { |
|
1530 CWindowGc& sysGc = SystemGc(); |
|
1531 customDrawer = CAknEdwinCustomDrawPrivate::NewL(iEikonEnv->LafEnv(),*this, iTextView, &sysGc); |
|
1532 } |
|
1533 else |
|
1534 customDrawer = CAknEdwinCustomDrawPrivate::NewL(iEikonEnv->LafEnv(),*this); |
|
1535 |
|
1536 return customDrawer; |
|
1537 } |
|
1538 |
|
1539 void CEikEdwin::DoCreateCustomDrawL() |
|
1540 { |
|
1541 |
|
1542 if (!(iEdwinUserFlags&ENoCustomDraw)) |
|
1543 { |
|
1544 if (!iCustomDrawer || iTextView ) |
|
1545 { |
|
1546 TBool oldCustomDraw = EFalse; |
|
1547 |
|
1548 if ( iEdwinFepSupport ) |
|
1549 { |
|
1550 oldCustomDraw = ( iEdwinFepSupport->iOldCustomDraw && iEdwinFepSupport->iOldCustomDraw == iCustomDrawer ); |
|
1551 } |
|
1552 |
|
1553 delete iCustomDrawer; |
|
1554 iCustomDrawer = 0; |
|
1555 iLayout->SetCustomDraw(0); |
|
1556 iCustomDrawer=CreateCustomDrawL(); |
|
1557 |
|
1558 if ( oldCustomDraw ) |
|
1559 { |
|
1560 iEdwinFepSupport->iOldCustomDraw = iCustomDrawer; |
|
1561 } |
|
1562 } |
|
1563 } |
|
1564 if (!iCustomDrawer) |
|
1565 { // create a non-Avkon custom drawer that just does colour schemes |
|
1566 iCustomDrawer=CLafEdwinCustomDrawBase::NewL(iEikonEnv->LafEnv(),*this); |
|
1567 } |
|
1568 |
|
1569 iLayout->SetCustomDraw(iCustomDrawer); |
|
1570 } |
|
1571 |
|
1572 /** |
|
1573 * @internal |
|
1574 */ |
|
1575 EXPORT_C void CEikEdwin::CreateTextAndLayoutL(CParaFormatLayer* aParaFormatLayer,CCharFormatLayer* aCharFormatLayer) |
|
1576 { |
|
1577 CancelFepTransaction(); |
|
1578 CEditableText::TDocumentStorage storage=(iEdwinUserFlags&ESegmentedStorage)? |
|
1579 CEditableText::ESegmentedStorage: CEditableText::EFlatStorage; |
|
1580 TInt granularity = (iTextLimit != 0 && iTextLimit+2 < CEditableText::EDefaultTextGranularity) |
|
1581 ? iTextLimit+2 |
|
1582 : CEditableText::EDefaultTextGranularity; |
|
1583 CGlobalText* globalText = (iEdwinInternalFlags&ERichText) |
|
1584 ? CRichText::NewL(aParaFormatLayer,aCharFormatLayer,storage,granularity) |
|
1585 : CGlobalText::NewL(aParaFormatLayer,aCharFormatLayer,storage,granularity); |
|
1586 iText=globalText; |
|
1587 CreateLayoutL(globalText); |
|
1588 SetHeightForNumOfLinesL(); |
|
1589 DoCreateCustomDrawL(); |
|
1590 if ( iEdwinExtension->iSmiley ) |
|
1591 { |
|
1592 TextLayout()->SetCustomWrap( iEdwinExtension->iSmileyWrap ); |
|
1593 } |
|
1594 } |
|
1595 |
|
1596 EXPORT_C void CEikEdwin::CheckEdwinExtensionL() |
|
1597 { |
|
1598 User::LeaveIfNull(EditorState()); |
|
1599 if (!iEdwinExtension) |
|
1600 { |
|
1601 iEdwinExtension = CEikEdwinExtension::NewL(this); |
|
1602 EditorState()->SetFormAccessor(iEdwinExtension->FormAccessor()); |
|
1603 } |
|
1604 } |
|
1605 |
|
1606 |
|
1607 EXPORT_C CEikEdwin::CEikEdwinExtension* CEikEdwin::EdwinExtension() |
|
1608 { |
|
1609 return iEdwinExtension; |
|
1610 } |
|
1611 |
|
1612 |
|
1613 EXPORT_C void CEikEdwin::ConstructL(TInt aEdwinFlags,TInt aWidthInChars,TInt aTextLimit,TInt aNumberOfLines) |
|
1614 { |
|
1615 iEdwinUserFlags |= aEdwinFlags; |
|
1616 CalculateWidth(aWidthInChars); |
|
1617 iTextLimit=aTextLimit; |
|
1618 iNumberOfLines=aNumberOfLines; |
|
1619 BaseConstructL(); |
|
1620 } |
|
1621 |
|
1622 EXPORT_C void CEikEdwin::SetEdwinObserver(MEikEdwinObserver* aEdwinObserver) |
|
1623 { |
|
1624 iEdwinObserver=aEdwinObserver; |
|
1625 } |
|
1626 |
|
1627 /** |
|
1628 * Add an observer of standard edwin events. May be called any number of times and |
|
1629 * is independant of calls to SetEdwinObserver. |
|
1630 */ |
|
1631 EXPORT_C void CEikEdwin::AddEdwinObserverL(MEikEdwinObserver* aEdwinObserver) |
|
1632 { |
|
1633 if (!iObserverArray) |
|
1634 iObserverArray=new(ELeave) CArrayPtrFlat<MEikEdwinObserver>(1); |
|
1635 iObserverArray->AppendL(aEdwinObserver); |
|
1636 } |
|
1637 |
|
1638 /** |
|
1639 * Removes aEdwinObserver form the list of observers. Does nothing if aEdwinObserver isn't an observer. |
|
1640 */ |
|
1641 EXPORT_C void CEikEdwin::RemoveEdwinObserver(MEikEdwinObserver* aEdwinObserver) |
|
1642 { |
|
1643 if (iObserverArray) |
|
1644 { |
|
1645 const TInt count=iObserverArray->Count(); |
|
1646 for (TInt ii=0;ii<count;ii++) |
|
1647 { |
|
1648 if ((*iObserverArray)[ii]==aEdwinObserver) |
|
1649 { |
|
1650 iObserverArray->Delete(ii); |
|
1651 break; |
|
1652 } |
|
1653 } |
|
1654 if (iObserverArray->Count()==0) |
|
1655 { |
|
1656 delete iObserverArray; |
|
1657 iObserverArray=NULL; |
|
1658 } |
|
1659 } |
|
1660 } |
|
1661 |
|
1662 EXPORT_C void CEikEdwin::SetDocumentContentL(CGlobalText& aText,TSetContent aContent) |
|
1663 { |
|
1664 __ASSERT_DEBUG(&aText,Panic(EEikPanicNullPointer)); |
|
1665 CancelFepTransaction(); |
|
1666 if (aContent==ECopyText) |
|
1667 CopyDocumentContentL(aText,*((CGlobalText*)iText)); |
|
1668 else |
|
1669 { |
|
1670 iText=&aText; // relies on any existing iText having been deleted by the caller |
|
1671 if (iEdwinInternalFlags&ERichText) |
|
1672 { |
|
1673 static_cast<CRichText*>(iText)->SetEditObserver(this); |
|
1674 TInt startPos=0; |
|
1675 TInt length=iText->DocumentLength(); |
|
1676 static_cast<CRichText*>(iText)->ParseText(startPos,length,ETrue); |
|
1677 } |
|
1678 if (iLayout) |
|
1679 iLayout->SetLayDoc(&aText); |
|
1680 else |
|
1681 CreateLayoutL(&aText); |
|
1682 DoCreateCustomDrawL(); |
|
1683 } |
|
1684 CheckRemovePictures(0,iText->DocumentLength()); |
|
1685 CheckValidityOfChars(0,iText->DocumentLength()); |
|
1686 SetAmountToFormatL(ETrue); // performs format |
|
1687 } |
|
1688 |
|
1689 EXPORT_C void CEikEdwin::CopyDocumentContentL(CGlobalText& aInText,CGlobalText& aOutText) |
|
1690 { |
|
1691 __ASSERT_DEBUG(&aInText,Panic(EEikPanicNullPointer)); |
|
1692 __ASSERT_DEBUG(&aOutText,Panic(EEikPanicNullPointer)); |
|
1693 aOutText.Reset(); |
|
1694 CBufStore* store=CBufStore::NewLC(1024); |
|
1695 TStreamId streamId=aInText.StoreL(*store); |
|
1696 aOutText.RestoreL(*store,streamId); |
|
1697 RStoreWriteStream paraWriteStream; |
|
1698 TStreamId paraStreamId=paraWriteStream.CreateLC(*store); |
|
1699 (aInText.GlobalParaFormatLayer())->ExternalizeL(paraWriteStream); |
|
1700 CleanupStack::PopAndDestroy(); // paraStreamId |
|
1701 RStoreReadStream paraReadStream; |
|
1702 paraReadStream.OpenLC(*store,paraStreamId); |
|
1703 ((CParaFormatLayer*)(aOutText.GlobalParaFormatLayer()))->InternalizeL(paraReadStream); |
|
1704 CleanupStack::PopAndDestroy(); // paraReadStream |
|
1705 RStoreWriteStream charWriteStream; |
|
1706 TStreamId charStreamId=charWriteStream.CreateLC(*store); |
|
1707 (aInText.GlobalCharFormatLayer())->ExternalizeL(charWriteStream); |
|
1708 CleanupStack::PopAndDestroy(); // charStreamId |
|
1709 RStoreReadStream charReadStream; |
|
1710 charReadStream.OpenLC(*store,charStreamId); |
|
1711 ((CCharFormatLayer*)(aOutText.GlobalCharFormatLayer()))->InternalizeL(charReadStream); |
|
1712 CleanupStack::PopAndDestroy(2); // store and charReadStream |
|
1713 } |
|
1714 |
|
1715 EXPORT_C void CEikEdwin::CalculateWidth(TInt aWidthInChars) |
|
1716 { |
|
1717 const CFont* font=iEikonEnv->NormalFont(); |
|
1718 iSize.iWidth=aWidthInChars; |
|
1719 if (!(iEdwinUserFlags&EWidthInPixels)) |
|
1720 iSize.iWidth*=(iEdwinInternalFlags&ENumericCharacters? font->WidthZeroInPixels(): font->MaxNormalCharWidthInPixels()); |
|
1721 iSize.iWidth+=iBorder.SizeDelta().iWidth+CursorWidth()+LineCursorWidth()+iMargins.iLeft+iMargins.iRight; |
|
1722 } |
|
1723 |
|
1724 void CEikEdwin::SetHeightForNumOfLinesL() |
|
1725 { |
|
1726 if (iNumberOfLines==0) |
|
1727 return; |
|
1728 iLayout->SetImageDeviceMap(iZoomFactor); |
|
1729 iLayout->FormatBandL(); |
|
1730 TInt lineHeight = iLayout->FormattedHeightInPixels(); |
|
1731 TInt edwinHeight = iNumberOfLines*lineHeight; |
|
1732 edwinHeight += iBorder.SizeDelta().iHeight+iMargins.iTop+iMargins.iBottom; |
|
1733 SetEdwinHeight(edwinHeight); |
|
1734 } |
|
1735 |
|
1736 EXPORT_C TKeyResponse CEikEdwin::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType) |
|
1737 { |
|
1738 if (aType!=EEventKey) |
|
1739 return EKeyWasNotConsumed; |
|
1740 TKeyEvent keyEvent = aKeyEvent; |
|
1741 LafEdwin::MapKeyEvent(keyEvent, aType); |
|
1742 return DoOfferKeyEventL(keyEvent, aType); |
|
1743 } |
|
1744 |
|
1745 TKeyResponse CEikEdwin::DoOfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode /*aType*/) |
|
1746 { |
|
1747 TInt code=aKeyEvent.iCode; |
|
1748 if ( code == EKeyLeftUpArrow || code == EKeyRightUpArrow) |
|
1749 { |
|
1750 code = EKeyUpArrow; |
|
1751 } |
|
1752 else if ( code == EKeyLeftDownArrow || code == EKeyRightDownArrow) |
|
1753 { |
|
1754 code = EKeyDownArrow; |
|
1755 } |
|
1756 const TCursorSelection selection=Selection(); |
|
1757 const TInt selectionLength=selection.Length(); |
|
1758 TInt cursorPos=CursorPos(); |
|
1759 const TInt docLength=iText->DocumentLength(); |
|
1760 |
|
1761 /* |
|
1762 if a 1 line editor, |
|
1763 and the key is an up/down |
|
1764 and not holding shift, |
|
1765 => ignore the key. |
|
1766 */ |
|
1767 if ( |
|
1768 (iEdwinInternalFlags&EHasOneLineOnly)&& |
|
1769 (code==EKeyUpArrow || code==EKeyDownArrow) && |
|
1770 (!(aKeyEvent.iModifiers&EModifierShift)) |
|
1771 ) |
|
1772 { |
|
1773 SetVirtualCursorStateL(EFalse); |
|
1774 return EKeyWasNotConsumed; |
|
1775 } |
|
1776 if (selectionLength==0) |
|
1777 { |
|
1778 if (code==EKeyLeftArrow || code==EKeyRightArrow || code==EKeyBackspace) |
|
1779 SetKeyboardRepeatRate(KAknEditorKeyboardRepeatRate); |
|
1780 else |
|
1781 SetKeyboardRepeatRate(KAknStandardKeyboardRepeatRate); |
|
1782 |
|
1783 TBool consume=ETrue; |
|
1784 TPoint cursorPoint; |
|
1785 if (iLayout->PosInBand(cursorPos,cursorPoint)) |
|
1786 { |
|
1787 TPoint pos; |
|
1788 /* |
|
1789 The following cases were added to stop Up/Down cursors moving the insert point to the |
|
1790 start/end of lines in the case of first/last line. |
|
1791 However, we should only do this if there is not a shift held down, as otherwise it |
|
1792 is a selection operation |
|
1793 */ |
|
1794 if (!(aKeyEvent.iModifiers&EModifierShift)) |
|
1795 { |
|
1796 if ( |
|
1797 code==EKeyUpArrow && |
|
1798 iLayout->FirstDocPosFullyInBand()==0 && |
|
1799 iLayout->PosInBand(0,pos) && |
|
1800 pos.iY == cursorPoint.iY |
|
1801 ) |
|
1802 { |
|
1803 if (cursorPos == 0 || iNumberOfLines == 1) |
|
1804 { |
|
1805 consume = EFalse; |
|
1806 } |
|
1807 } |
|
1808 if (consume && code==EKeyDownArrow) |
|
1809 { |
|
1810 if (iLayout->PosInBand(docLength,pos)) |
|
1811 { |
|
1812 if (pos.iY == cursorPoint.iY) |
|
1813 { |
|
1814 if (cursorPos == TextLength() || iNumberOfLines == 1) |
|
1815 { |
|
1816 consume = EFalse; |
|
1817 } |
|
1818 } |
|
1819 } |
|
1820 } |
|
1821 } |
|
1822 } |
|
1823 if (!consume) |
|
1824 { |
|
1825 SetVirtualCursorStateL(EFalse); |
|
1826 return EKeyWasNotConsumed; |
|
1827 } |
|
1828 } |
|
1829 if (iEdwinUserFlags&EDisplayOnly) |
|
1830 return EKeyWasConsumed; |
|
1831 if ( iEdwinExtension->iDrawInvoked == CEikEdwinExtension::ENotDraw ) |
|
1832 { |
|
1833 PerformRecordedOperationL(); |
|
1834 } |
|
1835 const TInt modifiers=aKeyEvent.iModifiers; |
|
1836 TBool navigation=EFalse; |
|
1837 TBool formatChange=EFalse; |
|
1838 TBool select=modifiers&EModifierShift; |
|
1839 if ( select ) |
|
1840 { |
|
1841 CEikButtonGroupContainer* cba( CEikButtonGroupContainer::Current() ); |
|
1842 if ( cba ) |
|
1843 { |
|
1844 TInt copyPos( cba->PositionById( EAknFepSoftkeyStartCopy ) ); |
|
1845 TInt cutPos( cba->PositionById( EAknFepSoftkeyStartCut ) ); |
|
1846 if ( copyPos != KErrNotFound || cutPos != KErrNotFound ) |
|
1847 { |
|
1848 select = EFalse; |
|
1849 } |
|
1850 } |
|
1851 } |
|
1852 TBool magnify=modifiers&EModifierCtrl; |
|
1853 const TInt oldLength=iText->DocumentLength(); |
|
1854 if (magnify && ( code == EKeyF18 || ( code<100 && code!=' ' ) ) )////!!! magic number |
|
1855 { |
|
1856 TClipboardFunc clipboardFunc=ENoClipboard; |
|
1857 TBuf<24> buf; |
|
1858 if (select) |
|
1859 iCoeEnv->ReadResourceL(buf,R_EIK_EDWIN_SHIFT_CTRL_HOTKEYS); |
|
1860 else |
|
1861 iCoeEnv->ReadResourceL(buf,R_EIK_EDWIN_CTRL_HOTKEYS); |
|
1862 TInt ret=buf.Locate(TChar(code+'a'-1)); |
|
1863 if ( code == EKeyF18 ) |
|
1864 { |
|
1865 ret = aKeyEvent.iScanCode; |
|
1866 } |
|
1867 switch (ret) |
|
1868 { |
|
1869 case EHotKeyCut: |
|
1870 case EEikCmdEditCut: |
|
1871 CheckNotReadOnlyL(); |
|
1872 clipboardFunc=ECut; |
|
1873 formatChange=ETrue; |
|
1874 break; |
|
1875 case EHotKeyCopy: |
|
1876 case EEikCmdEditCopy: |
|
1877 clipboardFunc=ECopy; |
|
1878 break; |
|
1879 case EHotKeyPaste: |
|
1880 CheckNotReadOnlyL(); |
|
1881 clipboardFunc=EPaste; |
|
1882 formatChange=ETrue; |
|
1883 break; |
|
1884 case EHotKeyUndo: |
|
1885 UndoL(); |
|
1886 return EKeyWasConsumed; |
|
1887 case EHotKeyFind: |
|
1888 if (iEdwinInternalFlags&EHasOneLineOnly) |
|
1889 return EKeyWasConsumed; |
|
1890 if (!TextLength()) |
|
1891 iEikonEnv->InfoMsg(R_EIK_TBUF_NO_TEXT); |
|
1892 else if (!FindL(NULL)) |
|
1893 iEikonEnv->InfoMsg(R_EIK_TBUF_TEXT_NOT_FOUND); |
|
1894 else |
|
1895 navigation=ETrue; |
|
1896 break; |
|
1897 case EHotKeyInsertChar: |
|
1898 RunCharMapDialogL(); |
|
1899 return EKeyWasConsumed; |
|
1900 default: |
|
1901 ; |
|
1902 } |
|
1903 if (clipboardFunc>ENoClipboard) |
|
1904 { |
|
1905 ClipboardL(clipboardFunc); |
|
1906 return EKeyWasConsumed; |
|
1907 } |
|
1908 |
|
1909 // Select all |
|
1910 TChar ctrlStripped( code + 'a' - 1 ); |
|
1911 if ( ctrlStripped == TChar('a') ) // ctrl-a is 0x01 |
|
1912 { |
|
1913 SelectAllL(); |
|
1914 return EKeyWasConsumed; |
|
1915 } |
|
1916 } |
|
1917 TKeyResponse ret=EKeyWasConsumed; |
|
1918 TBool reportChange=EFalse; |
|
1919 TBool formatHasChanged; |
|
1920 TInt charEditType=CTextLayout::EFCharacterInsert; |
|
1921 switch (code) |
|
1922 { |
|
1923 case EKeyPageUp: |
|
1924 case EKeyPageDown: |
|
1925 if (magnify) |
|
1926 SetCursorPosL((code==EKeyPageUp)? 0: TextLength(),select); |
|
1927 else |
|
1928 MoveCursorL((code==EKeyPageUp)? TCursorPosition::EFPageUp: TCursorPosition::EFPageDown, select); |
|
1929 if(CursorPos()==cursorPos && ((cursorPos==0 && code==EKeyPageUp) || |
|
1930 (cursorPos==TextLength() && code==EKeyPageDown))) |
|
1931 SetVirtualCursorStateL(EFalse); |
|
1932 CancelInsertCharFormat(); |
|
1933 navigation=ETrue; |
|
1934 break; |
|
1935 case EKeyHome: |
|
1936 case EKeyEnd: |
|
1937 { |
|
1938 const TBool cancelFormat=!((code==EKeyHome && selection.iCursorPos==0) || |
|
1939 (code==EKeyEnd && selection.iCursorPos==docLength)); |
|
1940 if (magnify) |
|
1941 SetCursorPosL((code==EKeyHome? 0 : docLength),select); |
|
1942 else |
|
1943 MoveCursorL((code==EKeyHome)? TCursorPosition::EFLineBeg: TCursorPosition::EFLineEnd, select); |
|
1944 if (cancelFormat) |
|
1945 { |
|
1946 CancelInsertCharFormat(); |
|
1947 navigation=ETrue; |
|
1948 } |
|
1949 else if(selection.Length()==0) |
|
1950 SetVirtualCursorStateL(EFalse); |
|
1951 break; |
|
1952 } |
|
1953 case EKeyUpArrow: |
|
1954 case EKeyDownArrow: |
|
1955 { |
|
1956 // Cancelformat should be true unless the key is stuck at the maximum/minimum position. |
|
1957 // Unfortunately the following code is not bidi: |
|
1958 const TBool cancelFormat=!((code==EKeyUpArrow && selection.iCursorPos==0) || |
|
1959 (code==EKeyDownArrow && selection.iCursorPos==docLength)); |
|
1960 if (selectionLength && !select) |
|
1961 CancelSelectionL(code==EKeyUpArrow? EStart: EEnd); |
|
1962 else |
|
1963 { |
|
1964 if (magnify) |
|
1965 MoveCursorToChunkStartL(select,EChunkPara,(code==EKeyUpArrow)? EStart: EEnd); |
|
1966 else if (IsReadOnly() && (iEdwinUserFlags&EAvkonDisableCursor)) |
|
1967 ret = ScrollReadOnlyNoCursorDisplayL(code); |
|
1968 else |
|
1969 MoveCursorL((code==EKeyUpArrow)? TCursorPosition::EFLineUp: TCursorPosition::EFLineDown, select); |
|
1970 } |
|
1971 if (cancelFormat) |
|
1972 { |
|
1973 CancelInsertCharFormat(); |
|
1974 navigation=ETrue; |
|
1975 } |
|
1976 else if(selectionLength==0 && ((cursorPos==0 && code==EKeyUpArrow) || |
|
1977 (cursorPos==TextLength() && code==EKeyDownArrow))) |
|
1978 SetVirtualCursorStateL(EFalse); // This logic not Bidi either...in |
|
1979 break; |
|
1980 } |
|
1981 case EKeyLeftArrow: |
|
1982 case EKeyRightArrow: |
|
1983 { |
|
1984 if (iEdwinFepSupport && iEdwinFepSupport->State(KNullUid)) |
|
1985 if (STATIC_CAST(CAknEdwinState*, iEdwinFepSupport->State(KNullUid))->Flags()&EAknEditorFlagNoLRNavigation) |
|
1986 return EKeyWasNotConsumed; |
|
1987 |
|
1988 // This logic is to determine key/position situations that are not causing navigation. |
|
1989 // All REAL navigation should set the cancelFormat flag. |
|
1990 // However, In Series 60, all left/right keys navigate somewhere because of end-start looping. |
|
1991 // (In fact the right left keys causing document end to start looping do not even get here. Done in FEP) |
|
1992 TBool cancelFormat(ETrue); |
|
1993 |
|
1994 if (selectionLength && !select) |
|
1995 CancelSelectionL(code==EKeyLeftArrow? EStart: EEnd); |
|
1996 else |
|
1997 { |
|
1998 if (magnify) |
|
1999 MoveCursorToChunkStartL(select,EChunkWord,(code==EKeyLeftArrow)? EStart: EEnd); |
|
2000 else |
|
2001 MoveCursorL((code==EKeyLeftArrow)? TCursorPosition::EFLeft: TCursorPosition::EFRight, select); |
|
2002 } |
|
2003 if (cancelFormat) |
|
2004 { |
|
2005 CancelInsertCharFormat(); |
|
2006 navigation=ETrue; |
|
2007 } |
|
2008 else if(selectionLength==0 && ((cursorPos==0 && code==EKeyLeftArrow) || |
|
2009 (cursorPos==TextLength() && code==EKeyRightArrow))) |
|
2010 SetVirtualCursorStateL(EFalse); |
|
2011 break; |
|
2012 } |
|
2013 case EKeyEscape: |
|
2014 if (selectionLength) |
|
2015 iTextView->CancelSelectionL(); |
|
2016 break; |
|
2017 case EKeyBackspace: |
|
2018 if (magnify && !(modifiers&EModifierPureKeycode)) |
|
2019 break; // prevent Ctrl-H deleting |
|
2020 case EKeyDelete: |
|
2021 { |
|
2022 if (iEdwinExtension) |
|
2023 { |
|
2024 if (iEdwinExtension->ClearDirection() > 0) |
|
2025 { |
|
2026 if (code == EKeyBackspace) |
|
2027 { |
|
2028 if (!selectionLength |
|
2029 && cursorPos != docLength) |
|
2030 { |
|
2031 code = EKeyDelete; |
|
2032 } |
|
2033 } |
|
2034 else if (code == EKeyDelete && !select) |
|
2035 { |
|
2036 code = EKeyBackspace; |
|
2037 } |
|
2038 } |
|
2039 } |
|
2040 |
|
2041 // In case of pressing BS-key or Delete-key with shift-key, |
|
2042 // Change from BS(or Delete) to Delete(or BS) |
|
2043 if (select) |
|
2044 { |
|
2045 code = (code==EKeyBackspace)? EKeyDelete : EKeyBackspace; |
|
2046 } |
|
2047 |
|
2048 TBuf<2> newText; // Used for neutral protection |
|
2049 CheckNotReadOnlyL(); |
|
2050 |
|
2051 TCursorSelection toDelete; |
|
2052 TBool deleteSelection = EFalse; |
|
2053 TBool replaceSelection = EFalse; |
|
2054 TBool forwardProtectionNeeded = EFalse; |
|
2055 |
|
2056 if (selectionLength) |
|
2057 { |
|
2058 toDelete = selection; |
|
2059 deleteSelection = ETrue; |
|
2060 SetSelectionL(toDelete.iCursorPos, toDelete.iAnchorPos); |
|
2061 } |
|
2062 else // no selection |
|
2063 { |
|
2064 //convert visible codes to original text strings. |
|
2065 if ( ConvertSmileyForDeleteL( cursorPos, ( code == EKeyBackspace ) ) ) |
|
2066 { |
|
2067 return EKeyWasConsumed; |
|
2068 } |
|
2069 if (code==EKeyDelete) |
|
2070 toDelete = iTextView->GetForwardDeletePositionL(); |
|
2071 else if (code==EKeyBackspace) |
|
2072 { |
|
2073 TInt cursorPos = CursorPos(); |
|
2074 if ( cursorPos > 0 ) |
|
2075 { |
|
2076 TPtrC ptr(iText->Read(cursorPos-1)); |
|
2077 TInt glyphToDelete = ptr[0]; |
|
2078 if ( (glyphToDelete >= 0x0E01) && (glyphToDelete <= 0x0E5B) |
|
2079 // #ifdef RD_HINDI |
|
2080 || (glyphToDelete >= 0x0900) && (glyphToDelete <= 0x097F) //unicode code range for Devanagari. |
|
2081 // #endif //RD_HINDI |
|
2082 ) |
|
2083 { |
|
2084 toDelete = TCursorSelection(cursorPos, cursorPos-1); |
|
2085 } |
|
2086 else |
|
2087 { |
|
2088 toDelete = iTextView->GetBackwardDeletePositionL(); |
|
2089 } |
|
2090 } |
|
2091 else |
|
2092 toDelete = iTextView->GetBackwardDeletePositionL(); |
|
2093 } |
|
2094 |
|
2095 if (toDelete.Length() > 1 ) |
|
2096 { // => we have some invisible characters to delete |
|
2097 SetSelectionL(toDelete.iCursorPos, toDelete.iAnchorPos); |
|
2098 deleteSelection = ETrue; |
|
2099 } |
|
2100 // Neutral charcter protection |
|
2101 // Copy selection to descriptor |
|
2102 if ( EditorSupportsNeutralProtection() ) |
|
2103 { |
|
2104 if ( NeedsNeutralProtection( toDelete.LowerPos(), toDelete.Length(), newText, forwardProtectionNeeded ) ) |
|
2105 replaceSelection = ETrue; |
|
2106 } |
|
2107 } |
|
2108 |
|
2109 if (deleteSelection && !replaceSelection ) // delete select, but no neutral protection |
|
2110 { |
|
2111 DeleteHighlightL(formatHasChanged,code==EKeyBackspace); |
|
2112 const TInt lower=toDelete.LowerPos(); |
|
2113 const TCursorSelection sel(lower,lower); |
|
2114 iTextView->SetPendingSelection(sel); |
|
2115 iTextView->HandleInsertDeleteL(sel,toDelete.Length(),formatHasChanged); |
|
2116 reportChange=ETrue; |
|
2117 } |
|
2118 else if ( replaceSelection ) // All neutral protection cases |
|
2119 { |
|
2120 if ( !deleteSelection ) // selection has not been set yet |
|
2121 SetSelectionL(toDelete.iCursorPos, toDelete.iAnchorPos); |
|
2122 TInt cursorPosInNewText = newText.Length(); // after neutral protection character(s) |
|
2123 if (forwardProtectionNeeded) // back it up if one was forward protecting |
|
2124 cursorPosInNewText--; |
|
2125 ReplaceSelectionWithTextL( newText, cursorPosInNewText, formatHasChanged ); |
|
2126 reportChange=ETrue; |
|
2127 formatChange=formatHasChanged; |
|
2128 } |
|
2129 else // !deleteSelection and !replaceSelection => Legacy single character delete |
|
2130 { |
|
2131 TInt pos=-1; |
|
2132 if (code==EKeyDelete) |
|
2133 pos=cursorPos; |
|
2134 else if (code==EKeyBackspace) |
|
2135 { |
|
2136 pos=cursorPos; |
|
2137 --pos; |
|
2138 } |
|
2139 TBool isPicture=EFalse; |
|
2140 if (pos>=0) |
|
2141 { |
|
2142 TPtrC text=iText->Read(pos,1); // look at the single character |
|
2143 if (text[0]==CEditableText::EPictureCharacter) |
|
2144 { |
|
2145 if (!iEikonEnv->QueryWinL(R_EIK_CONFIRM_DELETE_OBJECT_TITLE)) |
|
2146 return EKeyWasConsumed; |
|
2147 isPicture=ETrue; |
|
2148 } |
|
2149 } |
|
2150 |
|
2151 TBool doDelete=EFalse; |
|
2152 if (code==EKeyBackspace) |
|
2153 { |
|
2154 charEditType=CTextLayout::EFLeftDelete; |
|
2155 if (cursorPos>0) |
|
2156 { |
|
2157 doDelete=ETrue; |
|
2158 --cursorPos; |
|
2159 } |
|
2160 } |
|
2161 else |
|
2162 { |
|
2163 charEditType=CTextLayout::EFRightDelete; |
|
2164 if (cursorPos<TextLength()) |
|
2165 doDelete=ETrue; |
|
2166 } |
|
2167 if (doDelete) |
|
2168 { |
|
2169 TCursorSelection selection=(isPicture? TCursorSelection(cursorPos,cursorPos+1) : TCursorSelection(cursorPos,cursorPos)); |
|
2170 DeleteL(formatHasChanged,selection,code==EKeyBackspace,isPicture); |
|
2171 if (!isPicture) |
|
2172 ClearUndo(); |
|
2173 iTextView->HandleCharEditL(charEditType,formatHasChanged); |
|
2174 reportChange=ETrue; |
|
2175 formatChange=formatHasChanged; |
|
2176 } |
|
2177 } |
|
2178 if ( reportChange && iEdwinExtension->iSmiley ) |
|
2179 { |
|
2180 ConvertTextForSmileyL( TCursorSelection( cursorPos, cursorPos ), |
|
2181 ETrue ); |
|
2182 if ( deleteSelection || replaceSelection ) |
|
2183 { |
|
2184 SetCursorPosL( cursorPos, EFalse ); |
|
2185 } |
|
2186 } |
|
2187 } |
|
2188 break; |
|
2189 case '-': |
|
2190 if (select|magnify) |
|
2191 code=CEditableText::ENonBreakingHyphen; |
|
2192 goto InChar; |
|
2193 case EKeySpace: |
|
2194 if (select) |
|
2195 code=CEditableText::ENonBreakingSpace; |
|
2196 goto InChar; |
|
2197 case EKeyEnter: |
|
2198 if ( iEdwinUserFlags & ENoLineOrParaBreaks ) |
|
2199 { |
|
2200 return EKeyWasConsumed; |
|
2201 } |
|
2202 CheckNotReadOnlyL(); |
|
2203 if (iEdwinInternalFlags&EHasOneLineOnly) |
|
2204 break; |
|
2205 code=(select? CEditableText::ELineBreak : CEditableText::EParagraphDelimiter); |
|
2206 if (code == CEditableText::EParagraphDelimiter) |
|
2207 NewParagraphL(); |
|
2208 charEditType=(select? CTextLayout::EFCharacterInsert : CTextLayout::EFParagraphDelimiter); |
|
2209 goto TestMagnify; |
|
2210 case EKeyTab: |
|
2211 code=CEditableText::ETabCharacter; |
|
2212 // Tab characters are disabled in all editors |
|
2213 // because copy/paste and column/formattedcell listboxes |
|
2214 // do not work well and any tab characters in the |
|
2215 // strings will cause crashes in _all_ applications. |
|
2216 // (implements tabulator section in default event |
|
2217 // actions spec which says tab is inactive.) |
|
2218 if (!(iEdwinUserFlags&EAvkonTabsEnabled)) |
|
2219 break; |
|
2220 TestMagnify: |
|
2221 if (magnify && !(modifiers&EModifierPureKeycode)) |
|
2222 break; // prevent eg Ctrl-I inserting a tab |
|
2223 goto InChar; |
|
2224 default: |
|
2225 if (code>=ENonCharacterKeyBase || !TChar(code).IsPrint() || (!IsValidChar(code))) |
|
2226 { |
|
2227 ret=EKeyWasNotConsumed; |
|
2228 break; |
|
2229 } |
|
2230 InChar: CheckNotReadOnlyL(); |
|
2231 TChar character(code); |
|
2232 if ( selectionLength && IsValidNumericCharL(character) ) |
|
2233 { |
|
2234 TInt pos=DeleteHighlightL(formatHasChanged); |
|
2235 TRAPD(err,iText->InsertL(pos,character)); |
|
2236 if ( iEdwinExtension->iSmiley ) |
|
2237 { |
|
2238 iEdwinExtension->iSmiley->HandleInsertL( pos, 1 ); |
|
2239 ConvertTextForSmileyL( TCursorSelection( pos, pos ), ETrue ); |
|
2240 } |
|
2241 TCursorSelection selection=iTextView->Selection(); |
|
2242 if (err==KErrNone && iUndoStore) |
|
2243 iUndoStore->SetNewText(TCursorSelection(selection.LowerPos(),selection.LowerPos()+1)); |
|
2244 TCursorSelection pending; |
|
2245 pending.iCursorPos=selection.LowerPos()+1; |
|
2246 pending.iAnchorPos=pending.iCursorPos; |
|
2247 iTextView->SetPendingSelection(pending); |
|
2248 selection=pending; |
|
2249 --selection.iAnchorPos; |
|
2250 iTextView->HandleInsertDeleteL(selection,selectionLength,formatHasChanged); |
|
2251 User::LeaveIfError(err); |
|
2252 reportChange=ETrue; |
|
2253 formatChange=formatHasChanged; |
|
2254 break; |
|
2255 } |
|
2256 if ( (!iTextLimit || TextLength()<iTextLimit) && IsValidNumericCharL(character) ) |
|
2257 { |
|
2258 iText->InsertL(CursorPos(),character); |
|
2259 ClearUndo(); |
|
2260 if ( iEdwinExtension->iSmiley ) |
|
2261 { |
|
2262 TInt cursorPos( CursorPos() ); |
|
2263 iEdwinExtension->iSmiley->HandleInsertL( cursorPos, 1 ); |
|
2264 ConvertTextForSmileyL( TCursorSelection( cursorPos, cursorPos ), |
|
2265 ETrue ); |
|
2266 } |
|
2267 iTextView->HandleCharEditL(charEditType); |
|
2268 reportChange=ETrue; |
|
2269 } |
|
2270 else |
|
2271 { |
|
2272 ClearUndo(); |
|
2273 CEikonEnv::Beep(); |
|
2274 iEikonEnv->InfoMsg(R_EIK_TBUF_MAX_CHARACTERS_REACHED); |
|
2275 } |
|
2276 } |
|
2277 if (reportChange) |
|
2278 { |
|
2279 ReportEdwinEventL( MEikEdwinObserver::EEventTextUpdate ); |
|
2280 DoReportEventL( MCoeControlObserver::EEventStateChanged ); |
|
2281 if ( iEdwinExtension->iSmiley ) |
|
2282 { |
|
2283 TInt docPos( CursorPos() ); |
|
2284 iEdwinExtension->iSmiley->HandleSetCursor( docPos, |
|
2285 docPos ); |
|
2286 if ( docPos != CursorPos() ) |
|
2287 { |
|
2288 SetCursorPosL( docPos, SelectionLength() > 0 ); |
|
2289 } |
|
2290 } |
|
2291 } |
|
2292 if (navigation) |
|
2293 { |
|
2294 iEdwinExtension->iThumbPos = KErrNotFound; |
|
2295 ReportEdwinEventL(MEikEdwinObserver::EEventNavigation); |
|
2296 } |
|
2297 if (formatChange) |
|
2298 ReportEdwinEventL(MEikEdwinObserver::EEventFormatChanged); |
|
2299 if (NeedToChangeFormattingModeL()) |
|
2300 SetAmountToFormatL(); |
|
2301 UpdateScrollBarsL(); |
|
2302 return ret; |
|
2303 } |
|
2304 |
|
2305 TKeyResponse CEikEdwin::ScrollReadOnlyNoCursorDisplayL(TUint aKeyCode) |
|
2306 { |
|
2307 __ASSERT_DEBUG(iTextView,Panic(EEikPanicEdwinNoView)); |
|
2308 TCursorPosition::TMovementType move = (aKeyCode==EKeyUpArrow)? TCursorPosition::EFLineUp: TCursorPosition::EFLineDown; |
|
2309 // attempt to scroll the display, but prevent blank lines being added to the end |
|
2310 if (iTextView->ScrollDisplayL(move, CTextLayout::EFDisallowScrollingBlankSpace)) |
|
2311 { |
|
2312 // make the cursor stay on the screen by matching its movement to the scrolling |
|
2313 MoveCursorL(move, EFalse); |
|
2314 return EKeyWasConsumed; |
|
2315 } |
|
2316 return EKeyWasNotConsumed; |
|
2317 } |
|
2318 |
|
2319 |
|
2320 void CEikEdwin::ReplaceSelectionWithTextL( const TDesC& aNewText, |
|
2321 TInt aPositionOfCursorInNewText, |
|
2322 TBool& aFormatHasChanged ) |
|
2323 { |
|
2324 CheckNotReadOnlyL(); // leaves if readonly |
|
2325 |
|
2326 // The selection length is preserved as it is used in the HandleInsertDeleteL at the bottom |
|
2327 TInt deletedChars = iTextView->Selection().Length(); |
|
2328 |
|
2329 // Just return if the new text minus the old text does not fit |
|
2330 if (iTextLimit && (TextLength() - deletedChars + aNewText.Length() > iTextLimit ) ) |
|
2331 return; |
|
2332 |
|
2333 // Delete the selected text from the buffer; |
|
2334 TCursorSelection selToDelete = iTextView->Selection(); |
|
2335 TInt pos = selToDelete.iAnchorPos; |
|
2336 if ( selToDelete.Length() ) |
|
2337 { |
|
2338 pos=DeleteHighlightL(aFormatHasChanged); |
|
2339 } |
|
2340 |
|
2341 // Insert new text. |
|
2342 // This is trapped so that we can get by with one call to HandleInsertDeleteL. |
|
2343 // However, we need to ensure that HandleInsertDeleteL is called at least after |
|
2344 // a non-leaving DeleteHighlightL. |
|
2345 TInt newTextLength = 0; // if the following leaves, handling will be as if newText has length 0 |
|
2346 TRAPD(err,iText->InsertL(pos,aNewText) ); |
|
2347 if ( err == KErrNone ) |
|
2348 newTextLength = aNewText.Length(); |
|
2349 |
|
2350 // New selection to be passed to HandleInsertDeleteL. Span the new text |
|
2351 TCursorSelection selection(pos + newTextLength, pos); // Note, cursor pos is first parameter |
|
2352 |
|
2353 // Some undo stuff; unused in S60 |
|
2354 if (err==KErrNone && iUndoStore) |
|
2355 iUndoStore->SetNewText(selection); |
|
2356 |
|
2357 // Following code is to set up for SetPendingSelection which dictates where the selection/cursor |
|
2358 // will be after the operation. Zero length selection dictated by aPositionOfCursorInNewText |
|
2359 TCursorSelection pending; |
|
2360 pending.iAnchorPos = selection.LowerPos() + Min( newTextLength, aPositionOfCursorInNewText); |
|
2361 pending.iCursorPos = pending.iAnchorPos; |
|
2362 |
|
2363 iTextView->SetPendingSelection(pending); |
|
2364 /* |
|
2365 Set up for the call for textview to handle the changed content |
|
2366 @param aSelection The start and new length of the changed block. |
|
2367 @param aDeletedChars The number of deleted characters. |
|
2368 @param aFormatChanged ETrue if text is to be reformatted from the start of the |
|
2369 paragraph the cursor was on before the edit, EFalse if from the start of the |
|
2370 line the cursor was on before the edit. |
|
2371 @return The number of pixels scrolled horizontally and vertically. ( Ignored ) |
|
2372 */ |
|
2373 (void)iTextView->HandleInsertDeleteL( selection, deletedChars, aFormatHasChanged); |
|
2374 User::LeaveIfError(err); |
|
2375 } |
|
2376 |
|
2377 EXPORT_C void* CEikEdwin::ExtensionInterface( TUid /*aInterface*/ ) |
|
2378 { |
|
2379 return NULL; |
|
2380 } |
|
2381 |
|
2382 EXPORT_C void CEikEdwin::HandlePointerEventL(const TPointerEvent& aPointerEvent) |
|
2383 { |
|
2384 if ( iEdwinFepSupport ) |
|
2385 { |
|
2386 CAknEdwinState* edwinState = |
|
2387 STATIC_CAST( CAknEdwinState*, |
|
2388 iEdwinFepSupport->State(KNullUid) ); |
|
2389 |
|
2390 if ( edwinState && ( edwinState->Flags() & EAknEditorFlagChinesePopup ) ) |
|
2391 { |
|
2392 return; |
|
2393 } |
|
2394 } |
|
2395 |
|
2396 if ( iEdwinExtension->iDrawInvoked == CEikEdwinExtension::ENotDraw ) |
|
2397 { |
|
2398 PerformRecordedOperationL(); |
|
2399 } |
|
2400 TCursorSelection selectionBefore = iTextView->Selection(); |
|
2401 if (IsDimmed()) |
|
2402 { |
|
2403 // IMHO, dimmed editor should not handle events |
|
2404 return; |
|
2405 } |
|
2406 |
|
2407 TBool kineticScrollingEnabled( KineticScrollingEnabled() ); |
|
2408 if ( iEdwinExtension ) |
|
2409 { |
|
2410 TPoint pos = aPointerEvent.iPosition; |
|
2411 |
|
2412 CAknExtendedInputCapabilities:: |
|
2413 MAknEventObserver::TPointerEventReceivedParams params; |
|
2414 |
|
2415 if ( kineticScrollingEnabled && |
|
2416 aPointerEvent.iType == TPointerEvent::EButton1Down ) |
|
2417 { |
|
2418 iEdwinExtension->iPhysicsHandler->InitKineticScrolling( |
|
2419 aPointerEvent.iPosition ); |
|
2420 } |
|
2421 |
|
2422 params.iPointerEvent = aPointerEvent; |
|
2423 TTmPosInfo2 posInfo; |
|
2424 if(iTextView->FindXyPosL(pos, posInfo, NULL)) // not interested in the line |
|
2425 { |
|
2426 params.iDocPos = posInfo.iDocPos.iPos; |
|
2427 } |
|
2428 else // Need to call this method for the case where the pen is beyond the last line of text |
|
2429 { |
|
2430 params.iDocPos = iTextView->XyPosToDocPosL( pos ); |
|
2431 } |
|
2432 |
|
2433 /** The local @c destroyed variable keeps track of the object destroyed state. */ |
|
2434 TBool destroyed = EFalse; |
|
2435 iEdwinExtension->iDestroyedPtr = &destroyed; |
|
2436 TRAP_IGNORE ( |
|
2437 iEdwinExtension->iExtendedInputCapabilities->ReportEventL( |
|
2438 CAknExtendedInputCapabilities::MAknEventObserver::EPointerEventReceived, |
|
2439 ¶ms ); |
|
2440 ) |
|
2441 if ( !destroyed ) |
|
2442 { |
|
2443 iEdwinExtension->iDestroyedPtr = NULL; |
|
2444 } |
|
2445 else |
|
2446 { |
|
2447 return; |
|
2448 } |
|
2449 } |
|
2450 |
|
2451 // Kinetic scrolling related code begins |
|
2452 |
|
2453 if ( kineticScrollingEnabled ) |
|
2454 { |
|
2455 // This FEP related code block needs to perform only if EDisplayOnly |
|
2456 // flag was NOT SET to match to old functionality. |
|
2457 // In original code we returned here if EDisplayOnly was set. |
|
2458 // Now we have to continue (but skip this block of code) |
|
2459 // because kinetic scrolling is supported also in editors |
|
2460 // with EDisplayOnly flag and this is handled later in the code. |
|
2461 |
|
2462 const TCursorSelection selection( iTextView->Selection() ); |
|
2463 const TPoint pointerPos( aPointerEvent.iPosition ); |
|
2464 |
|
2465 if ( !( iEdwinUserFlags & EDisplayOnly ) ) |
|
2466 { |
|
2467 if ( IsFocused() ) |
|
2468 { |
|
2469 CancelFepTransaction(); |
|
2470 } |
|
2471 if ( iEdwinFepSupport && iCoeEnv->Fep() ) |
|
2472 { |
|
2473 TPoint tempPos( pointerPos ); |
|
2474 const TInt documentPosition = |
|
2475 iTextView->XyPosToDocPosL( tempPos ); |
|
2476 |
|
2477 if ( iEdwinFepSupport->IsHandledByFepL( aPointerEvent.iType, |
|
2478 aPointerEvent.iModifiers, documentPosition ) ) |
|
2479 { |
|
2480 return; |
|
2481 } |
|
2482 } |
|
2483 } |
|
2484 |
|
2485 TBool shouldReturn( EFalse ); |
|
2486 iEdwinExtension->iPhysicsHandler->HandleKineticScrolling( |
|
2487 aPointerEvent, shouldReturn ); |
|
2488 |
|
2489 if ( shouldReturn ) |
|
2490 { |
|
2491 return; |
|
2492 } |
|
2493 |
|
2494 } // physics enabled |
|
2495 |
|
2496 // Kinetic scrolling related code ends |
|
2497 |
|
2498 // Display only mode, don't handle selection but return here. |
|
2499 if ( iEdwinUserFlags & EDisplayOnly ) |
|
2500 { |
|
2501 return; |
|
2502 } |
|
2503 |
|
2504 const TCursorSelection selection( iTextView->Selection() ); |
|
2505 const TPoint pointerPos( aPointerEvent.iPosition ); |
|
2506 |
|
2507 // Kinetic scrolling not enabled |
|
2508 if ( !kineticScrollingEnabled ) |
|
2509 { |
|
2510 if ( IsFocused() ) |
|
2511 { |
|
2512 CancelFepTransaction(); |
|
2513 } |
|
2514 if ( iEdwinFepSupport != NULL ) |
|
2515 { |
|
2516 if ( iEdwinFepSupport != NULL ) |
|
2517 { |
|
2518 // an optimization so that iTextView->XyPosToDocPosL is not |
|
2519 // called unnecessarily, since it needs to be called again, |
|
2520 // after CancelFepTransaction has been called |
|
2521 if (iCoeEnv->Fep()!=NULL) |
|
2522 { |
|
2523 TPoint tempPos( pointerPos ); |
|
2524 const TInt documentPosition = |
|
2525 iTextView->XyPosToDocPosL( tempPos ); |
|
2526 if ( iEdwinFepSupport->IsHandledByFepL( aPointerEvent.iType, |
|
2527 aPointerEvent.iModifiers, documentPosition)) |
|
2528 { |
|
2529 return; |
|
2530 } |
|
2531 } |
|
2532 } |
|
2533 } |
|
2534 } // Kinetic scrolling not enabled |
|
2535 |
|
2536 if ( iEdwinExtension->iPtSuppressor->SuppressPointerEvent( aPointerEvent ) ) |
|
2537 { |
|
2538 return; |
|
2539 } |
|
2540 if ( IsFocused() ) |
|
2541 { |
|
2542 CancelFepTransaction(); |
|
2543 } |
|
2544 TInt newCursorPos; // initialized a couple of lines below |
|
2545 { |
|
2546 TPoint tempPos(pointerPos); // the parameter to iTextView->XyPosToDocPosL gets stomped over, so copy pointerPos into a temporary TPoint object - the curly braces give this object a short lifetime |
|
2547 TTmPosInfo2 posInfo; |
|
2548 // newCursorPos needs to be initialised *after* CancelFepTransaction has been called, as CancelFepTransaction |
|
2549 // may have changed the contents of the document by cancelling an inline edit, and in particular it may have made |
|
2550 // the document shorter |
|
2551 if(iTextView->FindXyPosL(tempPos, posInfo, NULL)) // not interested in the line |
|
2552 { |
|
2553 newCursorPos = posInfo.iDocPos.iPos; // Gives correct value when pen is on right hand part of the character |
|
2554 } |
|
2555 else // Need to call this method for the case where the pen is beyond the last line of text |
|
2556 { |
|
2557 newCursorPos=iTextView->XyPosToDocPosL(tempPos); |
|
2558 } |
|
2559 } |
|
2560 TBool select=(aPointerEvent.iModifiers&EModifierShift); |
|
2561 TBool navigation=EFalse; |
|
2562 switch (aPointerEvent.iType) |
|
2563 { |
|
2564 case TPointerEvent::EButton1Down: |
|
2565 { |
|
2566 SetVirtualCursorStateL(ETrue); |
|
2567 iLastPointerDocPos=CursorPos(); |
|
2568 iLastPointerAnchorPos=selection.iAnchorPos; |
|
2569 if (iTextView->ViewRect().Contains(pointerPos)) |
|
2570 iEdwinInternalFlags|=ELeftDownInViewRect; |
|
2571 else |
|
2572 return; |
|
2573 if (aPointerEvent.iModifiers&EModifierCtrl) |
|
2574 iEdwinInternalFlags|=EDragDouble; |
|
2575 else |
|
2576 iEdwinInternalFlags&=(~EDragDouble); |
|
2577 |
|
2578 if (iEdwinInternalFlags&EDragDouble) |
|
2579 { |
|
2580 TInt startPos,length; |
|
2581 GetWordInfo(newCursorPos,startPos,length); |
|
2582 SetSelectionL(startPos+length,startPos); |
|
2583 } |
|
2584 else |
|
2585 { |
|
2586 if ( iEdwinUserFlags & CEikEdwin::EAvkonDisableCursor ) |
|
2587 { |
|
2588 iEdwinExtension->iTempCursorPos = newCursorPos; |
|
2589 iEdwinExtension->iTempSelect = select; |
|
2590 if ( selection.Length() > 0 && !select ) |
|
2591 { |
|
2592 ClearSelectionL(); |
|
2593 iEdwinFepSupport->iSelectionIsCancel = ETrue; |
|
2594 } |
|
2595 } |
|
2596 else |
|
2597 { |
|
2598 CAknEdwinState* edwinState = STATIC_CAST( CAknEdwinState*, iEdwinFepSupport->State( KNullUid ) ); |
|
2599 iEdwinExtension->iRecordCursor = newCursorPos; |
|
2600 // If touch input opened or no selection, set the new position. Otherwise record current position. |
|
2601 if ( !( selection.iCursorPos != selection.iAnchorPos |
|
2602 && !( edwinState->Flags() & EAknEditorFlagTouchInputModeOpened ) ) |
|
2603 || (iEdwinUserFlags & EAvkonDisableVKB ) || |
|
2604 ( iEdwinExtension->iExtendedInputCapabilities->Capabilities() & CAknExtendedInputCapabilities::EInputEditorQwertyInputActive ) ) |
|
2605 { |
|
2606 EnableRateScrolling( ETrue ); |
|
2607 SetCursorPosL( newCursorPos, select ); |
|
2608 EnableRateScrolling( EFalse ); |
|
2609 |
|
2610 // when point at the bottom line ,if it is not the last line CTextview will scroll up |
|
2611 // one line. So we record if it scroll and record current point DocPos |
|
2612 TPoint testPos = aPointerEvent.iPosition; |
|
2613 if ( newCursorPos != iTextView->XyPosToDocPosL( testPos ) ) |
|
2614 { |
|
2615 iEdwinExtension->iRecordScroll = ETrue; |
|
2616 iEdwinExtension->iRecordCursor = iTextView->XyPosToDocPosL( testPos ); |
|
2617 } |
|
2618 else |
|
2619 { |
|
2620 iEdwinExtension->iRecordScroll = EFalse; |
|
2621 } |
|
2622 } |
|
2623 } |
|
2624 } |
|
2625 break; |
|
2626 } |
|
2627 case TPointerEvent::EButtonRepeat: |
|
2628 case TPointerEvent::EDrag: |
|
2629 case TPointerEvent::EButton1Up: |
|
2630 { |
|
2631 iEdwinFepSupport->iMoveThumbFeedbackNeeded = ETrue; |
|
2632 if (!(iEdwinInternalFlags&ELeftDownInViewRect)) |
|
2633 return; |
|
2634 if ( aPointerEvent.iType == TPointerEvent::EDrag && |
|
2635 ( iEdwinUserFlags & CEikEdwin::EAvkonDisableCursor ) && |
|
2636 ( iEdwinExtension->iTempCursorPos != KErrNotFound ) ) |
|
2637 { |
|
2638 SetCursorPosL( iEdwinExtension->iTempCursorPos, |
|
2639 iEdwinExtension->iTempSelect ); |
|
2640 iEdwinExtension->iTempCursorPos = KErrNotFound; |
|
2641 } |
|
2642 if ( aPointerEvent.iType == TPointerEvent::EButton1Up ) |
|
2643 { |
|
2644 if (!iEdwinExtension->iScrollRect.IsEmpty()) |
|
2645 { |
|
2646 TPoint point; |
|
2647 TextLayout()->PosInBand(newCursorPos, point); |
|
2648 TInt yPos = point.iY; |
|
2649 TRect lineRect; |
|
2650 TextLayout()->GetLineRect(yPos, lineRect); |
|
2651 lineRect.iTl += Position(); |
|
2652 lineRect.iBr += Position(); |
|
2653 |
|
2654 |
|
2655 if (!(iEdwinExtension->iScrollRect.Contains(lineRect.iTl) || iEdwinExtension->iScrollRect.Contains(lineRect.iBr))) |
|
2656 { |
|
2657 TInt y = (iEdwinExtension->iScrollRect.iTl.iY + iEdwinExtension->iScrollRect.iBr.iY) / 2; |
|
2658 if (lineRect.iTl.iY > y) |
|
2659 { // Scroll up (cursor is down) |
|
2660 TInt num = -1; |
|
2661 TRAP_IGNORE( iTextView->ScrollDisplayLinesL(num)); |
|
2662 } |
|
2663 else |
|
2664 { // Scroll down (cursor is up) |
|
2665 TInt num = 1; |
|
2666 TRAP_IGNORE( iTextView->ScrollDisplayLinesL(num)); |
|
2667 } |
|
2668 } |
|
2669 } |
|
2670 |
|
2671 const TInt newAnchorPos=selection.iAnchorPos; |
|
2672 if (newCursorPos!=iLastPointerDocPos || newAnchorPos!=iLastPointerAnchorPos) |
|
2673 navigation=ETrue; |
|
2674 iLastPointerDocPos=newCursorPos; |
|
2675 iLastPointerAnchorPos=newAnchorPos; |
|
2676 iEdwinInternalFlags&=(~ELeftDownInViewRect); |
|
2677 |
|
2678 // We can't open cut-copy-paste menu if dragging started |
|
2679 if ( IsReadOnly() && IsSelectionVisible() && !( kineticScrollingEnabled |
|
2680 && iEdwinExtension->iPhysicsHandler->DraggingStarted() ) ) |
|
2681 { |
|
2682 iEdwinFepSupport->iFeedback->InstantFeedback( |
|
2683 this, |
|
2684 ETouchFeedbackPopUp, |
|
2685 ETouchFeedbackVibra, |
|
2686 aPointerEvent ); |
|
2687 TRAP_IGNORE ( |
|
2688 iEdwinExtension->iExtendedInputCapabilities->ReportEventL( |
|
2689 CAknExtendedInputCapabilities::MAknEventObserver::EOpenStylusMenuCcpu, |
|
2690 NULL ); |
|
2691 ) |
|
2692 } |
|
2693 |
|
2694 if ( iEdwinFepSupport && |
|
2695 iTextView->ViewRect().Contains( pointerPos ) ) |
|
2696 { |
|
2697 CAknEdwinState* edwinState = |
|
2698 STATIC_CAST( CAknEdwinState*, |
|
2699 iEdwinFepSupport->State(KNullUid) ); |
|
2700 |
|
2701 if ( kineticScrollingEnabled ) |
|
2702 { |
|
2703 if ( !IsReadOnly() && !iEdwinExtension->iDragging && |
|
2704 !iEdwinExtension->iPhysicsHandler->DraggingStarted() |
|
2705 ) |
|
2706 { |
|
2707 iEdwinFepSupport->iFeedback->InstantFeedback( this, |
|
2708 ETouchFeedbackEdit, ETouchFeedbackVibra, |
|
2709 aPointerEvent ); |
|
2710 } |
|
2711 } |
|
2712 else // Kinetic scrolling not enabled |
|
2713 { |
|
2714 if ( aPointerEvent.iType == TPointerEvent::EButton1Up && IsFocused() && |
|
2715 ( iEdwinFepSupport->iSelectionIsCancel || |
|
2716 !( iEdwinUserFlags & ( CEikEdwin::EAvkonDisableCursor | |
|
2717 iEdwinUserFlags & CEikEdwin::EDisplayOnly | |
|
2718 iEdwinUserFlags & CEikEdwin::EReadOnly | |
|
2719 iEdwinUserFlags & CEikEdwin::EAvkonNotEditable ) ) ) ) |
|
2720 { |
|
2721 iEdwinFepSupport->iFeedback->InstantFeedback( |
|
2722 this, |
|
2723 ETouchFeedbackEdit, |
|
2724 ETouchFeedbackVibra, |
|
2725 aPointerEvent ); |
|
2726 iEdwinFepSupport->iSelectionIsCancel = EFalse; |
|
2727 } |
|
2728 } |
|
2729 |
|
2730 TBool kineticDragging = kineticScrollingEnabled && |
|
2731 ( iEdwinExtension->iPhysicsHandler->DraggingStarted() || |
|
2732 iEdwinExtension->iPhysicsHandler-> |
|
2733 DragThresholdExceeded( aPointerEvent.iPosition ) ); |
|
2734 |
|
2735 if ( edwinState && !IsReadOnly() && |
|
2736 !iEdwinExtension->iDragging && |
|
2737 !kineticDragging ) |
|
2738 { |
|
2739 TRAP_IGNORE( |
|
2740 edwinState->ReportAknEdStateEventL( |
|
2741 MAknEdStateObserver::EAknActivatePenInputRequest ) |
|
2742 ); |
|
2743 } |
|
2744 } |
|
2745 } |
|
2746 TInt origWordStartPos, origWordLength; |
|
2747 GetWordInfo(selection.iAnchorPos,origWordStartPos,origWordLength); |
|
2748 TRect pictRect; |
|
2749 if (aPointerEvent.iType==TPointerEvent::EButton1Up && |
|
2750 iTextView->GetPictureRectangleL(selection.LowerPos(),pictRect)) |
|
2751 { |
|
2752 iEdwinFepSupport->iMoveThumbFeedbackNeeded = EFalse; |
|
2753 break; |
|
2754 } |
|
2755 select=ETrue; |
|
2756 |
|
2757 TRect viewRect( AdjustedViewRect() ); |
|
2758 |
|
2759 if ( aPointerEvent.iType != TPointerEvent::EButton1Up && |
|
2760 ( ( pointerPos.iY >= viewRect.iBr.iY ) || |
|
2761 ( pointerPos.iY < viewRect.iTl.iY ) ) ) |
|
2762 { |
|
2763 TRect rect(TPoint(viewRect.iTl.iX-1000,viewRect.iBr.iY),TSize(viewRect.Width()+2000,2000)); |
|
2764 if ( pointerPos.iY >= viewRect.iBr.iY ) |
|
2765 { |
|
2766 MoveCursorL(TCursorPosition::EFLineDown,select); |
|
2767 } |
|
2768 else |
|
2769 { |
|
2770 MoveCursorL(TCursorPosition::EFLineUp,select); |
|
2771 rect.Move(0,-(viewRect.Height()+2000)); |
|
2772 } |
|
2773 Window().RequestPointerRepeatEvent(KPointerRepeatRate,rect); |
|
2774 navigation = ETrue; |
|
2775 iEdwinExtension->iThumbPos = KErrNotFound; |
|
2776 } |
|
2777 else if (iEdwinInternalFlags&EDragDouble) |
|
2778 { |
|
2779 TInt newWordStartPos,newWordLength; |
|
2780 GetWordInfo(newCursorPos,newWordStartPos,newWordLength); |
|
2781 if (selection.iCursorPos>selection.iAnchorPos) |
|
2782 { |
|
2783 if (newCursorPos<selection.iAnchorPos) |
|
2784 SetSelectionL(newWordStartPos,origWordStartPos+origWordLength); |
|
2785 else |
|
2786 SetCursorPosL(newWordStartPos+newWordLength,select); |
|
2787 } |
|
2788 else |
|
2789 { |
|
2790 if (newCursorPos>selection.iAnchorPos) |
|
2791 SetSelectionL(newWordStartPos+newWordLength,origWordStartPos); |
|
2792 else |
|
2793 SetCursorPosL(newWordStartPos,select); |
|
2794 } |
|
2795 } |
|
2796 else if ( aPointerEvent.iType != TPointerEvent::EButton1Up ) |
|
2797 { |
|
2798 CAknEdwinState* edwinState = STATIC_CAST( CAknEdwinState*, iEdwinFepSupport->State(KNullUid) ); |
|
2799 // Deal with second selection |
|
2800 if ( selection.iCursorPos != selection.iAnchorPos && |
|
2801 ( ! ( edwinState->Flags() & EAknEditorFlagTouchInputModeOpened ) )&& |
|
2802 !iEdwinExtension->iDragging |
|
2803 ) |
|
2804 { |
|
2805 if ( newCursorPos != iEdwinExtension->iRecordCursor ) |
|
2806 { |
|
2807 SetCursorPosL( iEdwinExtension->iRecordCursor, EFalse ); |
|
2808 iEdwinExtension->iDragging = EFalse; |
|
2809 iEdwinExtension->iRecordScroll = EFalse; |
|
2810 } |
|
2811 } |
|
2812 // If CTextView scroll at the bottom line and there is a little drag, |
|
2813 // we should ignore the little drag. |
|
2814 else if ( newCursorPos == iEdwinExtension->iRecordCursor |
|
2815 && iEdwinExtension->iRecordScroll |
|
2816 && !iEdwinExtension->iDragging ) |
|
2817 { |
|
2818 break; |
|
2819 } |
|
2820 else |
|
2821 { |
|
2822 // Deal with little drag in hardware |
|
2823 if ( newCursorPos != iEdwinExtension->iRecordCursor ) |
|
2824 { |
|
2825 iEdwinExtension->iDragging = ETrue; |
|
2826 } |
|
2827 else |
|
2828 { |
|
2829 iEdwinExtension->iDragging = EFalse; |
|
2830 } |
|
2831 SetCursorPosL( newCursorPos, select ); |
|
2832 iEdwinExtension->iRecordScroll = EFalse; |
|
2833 } |
|
2834 } |
|
2835 iEdwinFepSupport->iMoveThumbFeedbackNeeded = EFalse; |
|
2836 break; |
|
2837 } |
|
2838 default: |
|
2839 break; |
|
2840 } |
|
2841 if (aPointerEvent.iType == TPointerEvent::EButton1Down |
|
2842 || aPointerEvent.iType == TPointerEvent::EDrag |
|
2843 || aPointerEvent.iType == TPointerEvent::EButtonRepeat ) |
|
2844 { |
|
2845 const TCursorSelection selectionAfter = iTextView->Selection(); |
|
2846 TBool selectionVisible = iTextView->SelectionVisible(); |
|
2847 TBool paintingPossible = selectionVisible; |
|
2848 TBool selectionChanged = |
|
2849 paintingPossible |
|
2850 && ( ( selectionAfter.iCursorPos != selectionBefore.iCursorPos ) |
|
2851 || ( selectionAfter.iAnchorPos != selectionBefore.iAnchorPos ) ); |
|
2852 const TBool focused=IsFocused(); |
|
2853 const TBool readOnly = IsReadOnly(); |
|
2854 // editor got event, can be focused -> will be focused? |
|
2855 TBool editorWillGetFocus = !focused && |
|
2856 !IsNonFocusing() && |
|
2857 aPointerEvent.iType == TPointerEvent::EButton1Down; |
|
2858 |
|
2859 TBool editingEnabled = !readOnly; |
|
2860 if ( iEdwinFepSupport && |
|
2861 iEdwinFepSupport->iFeedback && |
|
2862 ( paintingPossible || editorWillGetFocus ) ) |
|
2863 { |
|
2864 if ( aPointerEvent.iType == TPointerEvent::EButton1Down && editingEnabled ) |
|
2865 { |
|
2866 // on down event feedback is given if cursor/selection changes |
|
2867 if ( paintingPossible && !readOnly || editorWillGetFocus ) |
|
2868 { |
|
2869 iEdwinFepSupport->iFeedback->InstantFeedback( this, ETouchFeedbackBasic ); |
|
2870 } |
|
2871 } |
|
2872 else if ( selectionChanged && |
|
2873 ( ( aPointerEvent.iType == TPointerEvent::EDrag ) || |
|
2874 ( aPointerEvent.iType == TPointerEvent::EButtonRepeat ) ) ) |
|
2875 { |
|
2876 |
|
2877 // selectionAfter.iCursorPos-1 below is because we need to select the previous char |
|
2878 TBool ltr = ( selectionAfter.iCursorPos >= selectionBefore.iCursorPos ); |
|
2879 TInt readPos = selectionAfter.iCursorPos; |
|
2880 if (ltr && readPos > 0) |
|
2881 { |
|
2882 readPos -= 1; // read previous char |
|
2883 } |
|
2884 TChar currentSelectedChar = Text()->Read( readPos, 1 )[0]; |
|
2885 TBool isSpace = currentSelectedChar.IsSpace(); |
|
2886 TBool isText = currentSelectedChar.IsAlpha() |
|
2887 || currentSelectedChar.IsDigit(); |
|
2888 |
|
2889 // case line |
|
2890 TInt prevLineNr = TextLayout()->GetLineNumber(selectionBefore.iCursorPos); |
|
2891 TInt lineNr = TextLayout()->GetLineNumber(selectionAfter.iCursorPos); |
|
2892 if ( prevLineNr != lineNr && ( selection.Length() != 0 ) ) |
|
2893 { |
|
2894 TInt group = ( currentSelectedChar.GetCategory() & 0xF0 ); |
|
2895 TBool isEmptyLine = ( group == TChar::ESeparatorGroup ); |
|
2896 TTouchLogicalFeedback fType = ( isEmptyLine ? |
|
2897 ETouchFeedbackEmptyLineSelection : ETouchFeedbackLineSelection ); |
|
2898 iEdwinFepSupport->iFeedback->InstantFeedback( this, fType ); |
|
2899 } |
|
2900 // case space |
|
2901 else if (isSpace) |
|
2902 { |
|
2903 iEdwinFepSupport->iFeedback->InstantFeedback( this, ETouchFeedbackBlankSelection ); |
|
2904 } |
|
2905 // case text |
|
2906 else if (isText) |
|
2907 { |
|
2908 iEdwinFepSupport->iFeedback->InstantFeedback( this, ETouchFeedbackTextSelection ); |
|
2909 } |
|
2910 } |
|
2911 } |
|
2912 } |
|
2913 if ( aPointerEvent.iType == TPointerEvent::EButton1Up && iEdwinExtension->iDragging ) |
|
2914 { |
|
2915 iEdwinExtension->iDragging = EFalse; |
|
2916 } |
|
2917 if ( aPointerEvent.iType == TPointerEvent::EButton1Up && iEdwinExtension->iRecordScroll ) |
|
2918 { |
|
2919 iEdwinExtension->iRecordScroll = EFalse; |
|
2920 } |
|
2921 if ( aPointerEvent.iType == TPointerEvent::EButton1Up ) |
|
2922 { |
|
2923 iEdwinExtension->iRecordCursor = -1; |
|
2924 } |
|
2925 if (navigation) |
|
2926 { |
|
2927 ReportEdwinEventL(MEikEdwinObserver::EEventNavigation); |
|
2928 CancelInsertCharFormat(); |
|
2929 } |
|
2930 } |
|
2931 |
|
2932 EXPORT_C void CEikEdwin::FocusChanged(TDrawNow /*aDrawNow*/) |
|
2933 { |
|
2934 if (!iTextView) |
|
2935 return; |
|
2936 const TBool focused=IsFocused(); |
|
2937 TRAP_IGNORE(SetCursorVisibilityL(focused)); |
|
2938 if (!focused && iEdwinUserFlags&EAlwaysShowSelection) |
|
2939 ; |
|
2940 else |
|
2941 { |
|
2942 TRAP_IGNORE( SetSelectionVisibilityL( focused ) );// !! inefficient |
|
2943 } |
|
2944 if (focused) |
|
2945 SetCursorSizeAndType(); |
|
2946 else |
|
2947 SetKeyboardRepeatRate(KAknStandardKeyboardRepeatRate); |
|
2948 |
|
2949 TRAP_IGNORE(SetVirtualCursorStateL(focused)); |
|
2950 if (iCcpuSupport) |
|
2951 { |
|
2952 TRAP_IGNORE(iCcpuSupport->HandleFocusChangeL()); |
|
2953 } |
|
2954 |
|
2955 if ( iEdwinFepSupport ) |
|
2956 { |
|
2957 CAknEdwinState* edwinState = STATIC_CAST( CAknEdwinState*, |
|
2958 iEdwinFepSupport->State(KNullUid) ); |
|
2959 if ( edwinState ) |
|
2960 { |
|
2961 if ( !focused ) |
|
2962 { |
|
2963 TRAP_IGNORE( edwinState->ReportAknEdStateEventL( |
|
2964 MAknEdStateObserver::EAknSyncEdwinState ) ); |
|
2965 } |
|
2966 else |
|
2967 { |
|
2968 if ( edwinState->Flags() & EAknEditorFlagLaunchPenInputAutomatic && |
|
2969 !IsReadOnly() && !IsDimmed() && !( iEdwinUserFlags & EDisplayOnly ) ) |
|
2970 { |
|
2971 edwinState->ReportAknEdStateEventL( |
|
2972 MAknEdStateObserver::EAknActivatePenInputRequest ); |
|
2973 } |
|
2974 } |
|
2975 } |
|
2976 } |
|
2977 } |
|
2978 |
|
2979 void CEikEdwin::SetCursorSizeAndType() |
|
2980 { |
|
2981 TInt first,second; |
|
2982 AknLayoutUtils::CursorExtensionsFromFont(CursorFontSpec(),first,second); |
|
2983 iTextView->SetCursorExtensions(first,second); |
|
2984 iTextView->SetCursorWeight(CursorWidth()); |
|
2985 } |
|
2986 |
|
2987 TFontSpec CEikEdwin::CursorFontSpec() const |
|
2988 { |
|
2989 if ( iText && iTextView ) |
|
2990 { |
|
2991 TCharFormat charFormat; |
|
2992 TCharFormatMask notUsed; |
|
2993 TInt cursorPos = CursorPos(); |
|
2994 if ( cursorPos > iText->DocumentLength() ) |
|
2995 { |
|
2996 cursorPos = iText->DocumentLength(); |
|
2997 } |
|
2998 STATIC_CAST( CGlobalText*, iText )->GetCharFormat( charFormat, notUsed, |
|
2999 cursorPos, 0 ); |
|
3000 return charFormat.iFontSpec; |
|
3001 } |
|
3002 else |
|
3003 { |
|
3004 return iEikonEnv->NormalFont()->FontSpecInTwips(); |
|
3005 } |
|
3006 } |
|
3007 |
|
3008 TInt CEikEdwin::CursorWidth() const |
|
3009 { |
|
3010 return AknLayoutUtils::CursorWidthFromFont( CursorFontSpec() ); |
|
3011 } |
|
3012 |
|
3013 void CEikEdwin::SetVirtualCursorStateL(TBool aSetSuspended) const |
|
3014 { |
|
3015 if(!(iEdwinUserFlags&EIgnoreVirtualCursor)) |
|
3016 { |
|
3017 TEikVirtualCursor& cursor=iEikonEnv->VirtualCursor(); |
|
3018 if(aSetSuspended && cursor.CursorState(*iEikonEnv)==TEikVirtualCursor::EOn) |
|
3019 cursor.SetCursorStateL(TEikVirtualCursor::ESuspended,*iEikonEnv); |
|
3020 else if(!aSetSuspended && cursor.CursorState(*iEikonEnv)==TEikVirtualCursor::ESuspended) |
|
3021 cursor.SetCursorStateL(TEikVirtualCursor::EOn,*iEikonEnv); |
|
3022 } |
|
3023 } |
|
3024 |
|
3025 EXPORT_C void CEikEdwin::ActivateL() |
|
3026 { |
|
3027 User::LeaveIfNull(iEdwinFepSupport); |
|
3028 User::LeaveIfNull(iEdwinFepSupport->State(KNullUid)); |
|
3029 __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText)); |
|
3030 |
|
3031 CRepository* repository = NULL; |
|
3032 TInt phoneNumberGroupingSupported = 0; |
|
3033 TRAPD(ret, repository = CRepository::NewL(KCRUidNumberGrouping)); |
|
3034 if (ret == KErrNone) |
|
3035 { |
|
3036 ret = repository->Get(KNumberGrouping, phoneNumberGroupingSupported); |
|
3037 } |
|
3038 delete repository; |
|
3039 |
|
3040 EnableDragEvents(); |
|
3041 Window().SetPointerGrab(ETrue); |
|
3042 |
|
3043 TBool suppressNotifyDraw = iEdwinInternalFlags & ESuppressNotifyDraw; |
|
3044 |
|
3045 SetSuppressNotifyDraw( ETrue ); |
|
3046 |
|
3047 if (!iTextView) |
|
3048 { |
|
3049 CreateTextViewL(); |
|
3050 } |
|
3051 |
|
3052 if (IsFocused()) |
|
3053 { |
|
3054 SetCursorVisibilityL(ETrue); |
|
3055 } |
|
3056 else |
|
3057 { |
|
3058 SetSelectionVisibilityL( EFalse ); |
|
3059 } |
|
3060 |
|
3061 DoCreateCustomDrawL(); // Done after TextView is created so that optimized drawer is constructed |
|
3062 |
|
3063 // Create the required formatters according to the editor set-up |
|
3064 if ( IsPurePhoneNumberEditor() ) |
|
3065 { |
|
3066 if ( phoneNumberGroupingSupported ) |
|
3067 { |
|
3068 CAknEdwinState* edwinState = STATIC_CAST( CAknEdwinState*, iEdwinFepSupport->State(KNullUid) ); |
|
3069 edwinState->SetFlags( edwinState->Flags() | EAknEditorFlagNumberGrouping ); |
|
3070 iEdwinExtension->CreatePurePhoneNumberFormatterL( *iLayout, *iText ); |
|
3071 } |
|
3072 } |
|
3073 else // Make approximation that all other editors have no matches indicator functionality |
|
3074 { |
|
3075 iEdwinExtension->CreateNoMatchesIndicatorFormatterL( *iLayout ); |
|
3076 } |
|
3077 |
|
3078 // Rich text editors that have been configured for phone number grouping |
|
3079 if (iEdwinInternalFlags&ERichText && iEdwinInternalFlags&EPhoneNumberGrouping && |
|
3080 phoneNumberGroupingSupported ) |
|
3081 { |
|
3082 CAknEdwinState* edwinState = STATIC_CAST( CAknEdwinState*, iEdwinFepSupport->State(KNullUid) ); |
|
3083 edwinState->SetFlags( edwinState->Flags() | EAknEditorFlagNumberGrouping ); |
|
3084 iEdwinExtension->CreateRichTextPhoneNumberFormatterL( *iLayout, *(static_cast<CRichText*>(iText)) ); |
|
3085 } |
|
3086 |
|
3087 // Install the custom formatter system if needed |
|
3088 if ( iEdwinExtension->FormExtendedInferfaceProvider() ) |
|
3089 TextLayout()->SetInterfaceProvider( iEdwinExtension->FormExtendedInferfaceProvider() ); |
|
3090 |
|
3091 UpdateScrollBarsL(); |
|
3092 ForceScrollBarUpdateL(); |
|
3093 |
|
3094 DoAlignment(); |
|
3095 |
|
3096 ApplyAutoSelectionL(); |
|
3097 |
|
3098 CCoeControl::ActivateL(); |
|
3099 |
|
3100 SetSuppressNotifyDraw( suppressNotifyDraw ); |
|
3101 } |
|
3102 |
|
3103 /** |
|
3104 * @internal |
|
3105 */ |
|
3106 EXPORT_C void CEikEdwin::CreateTextViewL() |
|
3107 { |
|
3108 if (iTextView) |
|
3109 return; |
|
3110 __ASSERT_DEBUG(iLayout,Panic(EEikPanicEdwinNoLayout)); |
|
3111 if (iEdwinInternalFlags&EHasOneLineOnly && !(iEdwinUserFlags&ENoHorizScrolling)) |
|
3112 iEdwinUserFlags|=ENoWrap; |
|
3113 if (iEdwinUserFlags&ENoWrap) |
|
3114 iLayout->ForceNoWrapping(); |
|
3115 |
|
3116 TRect innerRect = iBorder.InnerRect( Rect() ); |
|
3117 |
|
3118 if ( innerRect.Height() < 0 ) |
|
3119 { |
|
3120 innerRect.SetHeight( 0 ); |
|
3121 } |
|
3122 |
|
3123 iTextView=CTextView::NewL(iLayout,innerRect,iEikonEnv->ScreenDevice(), |
|
3124 iZoomFactor,&Window(),&iEikonEnv->RootWin(),&iEikonEnv->WsSession()); |
|
3125 // AVKON CHANGE to make less flicker!!! |
|
3126 // (Need to do here instead of LayoutEdwin, because not everyone |
|
3127 // seem to use layoutedwin :( ) |
|
3128 iTextView->DisableFlickerFreeRedraw(); |
|
3129 // END |
|
3130 |
|
3131 if (LineCursorWidth()) |
|
3132 SetLineCursorDetailsL(); |
|
3133 if (iText->DocumentLength()>UpperFullFormattingLength()) |
|
3134 SetAmountToFormatL(ETrue); |
|
3135 FormatTextL(); |
|
3136 iTextView->SetObserver(this); |
|
3137 |
|
3138 CheckEdwinExtensionL(); // checks if iEdwinExtension is non-NULL |
|
3139 iEdwinExtension->FormCursorModifier()->SetTextView(iTextView); |
|
3140 DoCreateCustomDrawL(); |
|
3141 } |
|
3142 |
|
3143 EXPORT_C void CEikEdwin::SizeChanged() |
|
3144 { |
|
3145 __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText)); |
|
3146 CheckEdwinHeight(); |
|
3147 TrappedSizeChanged(); |
|
3148 } |
|
3149 |
|
3150 EXPORT_C void CEikEdwin::TrappedSizeChanged() |
|
3151 { |
|
3152 TRAPD(err,HandleSizeChangedL()); |
|
3153 if (err) |
|
3154 { |
|
3155 CWindowGc& gc=SystemGc(); |
|
3156 gc.Activate(Window()); |
|
3157 TRect rect; |
|
3158 if (iTextView) |
|
3159 rect=iTextView->ViewRect(); |
|
3160 else |
|
3161 { |
|
3162 rect=Rect(); |
|
3163 rect=iBorder.InnerRect(rect); |
|
3164 } |
|
3165 gc.Clear(rect); |
|
3166 gc.Deactivate(); |
|
3167 iEikonEnv->NotifyIdleErrorWhileRedrawing(err); |
|
3168 } |
|
3169 } |
|
3170 |
|
3171 EXPORT_C void CEikEdwin::HandleSizeChangedL() |
|
3172 { |
|
3173 if (!iTextView) |
|
3174 CreateTextViewL(); |
|
3175 #ifdef _DEBUG |
|
3176 if (iMaximumHeight) |
|
3177 __ASSERT_DEBUG(iSize.iHeight<=iMaximumHeight, Panic(EEikPanicEdwinHeightGreaterThanMaximum)); |
|
3178 #endif |
|
3179 TBool condition( IsFocused() ); |
|
3180 CAknEdwinState* state( EditorState() ); |
|
3181 TBool noInlineEditSpan( !state || |
|
3182 state->CurrentInlineEditSpan().Length() <= 0 ); |
|
3183 condition = ( condition && noInlineEditSpan ); |
|
3184 condition = ( condition && ( iEdwinFepSupport->iLengthOfInlineText <= 0 ) ); |
|
3185 if ( condition ) |
|
3186 { |
|
3187 SetCursorVisibilityL( EFalse ); |
|
3188 } |
|
3189 TRect displayRect=iBorder.InnerRect(Rect()); |
|
3190 displayRect=iMargins.InnerRect(displayRect); |
|
3191 |
|
3192 // Negative width (and possibly height) seem to break iTextView |
|
3193 // This can happen if editor's width is less than the margins |
|
3194 |
|
3195 // if width equals to zero, will cause the cursor doesn't display in the right-to-left directionality |
|
3196 // so we set the width and height to smallest value 1. |
|
3197 const TInt displayRectWith = 1; |
|
3198 const TInt displayRectHeight = 1; |
|
3199 if ( displayRect.Width() <= 0 ) |
|
3200 { |
|
3201 displayRect.iBr.iX = displayRect.iTl.iX + displayRectWith; |
|
3202 } |
|
3203 |
|
3204 if ( displayRect.Height() <= 0 ) |
|
3205 { |
|
3206 displayRect.iBr.iY = displayRect.iTl.iY + displayRectHeight; |
|
3207 } |
|
3208 |
|
3209 |
|
3210 iTextView->SetViewRect(displayRect); |
|
3211 iLayout->SetWrapWidth(LayoutWidth()); |
|
3212 TViewYPosQualifier yPosQualifier; |
|
3213 yPosQualifier.SetFillScreen(); |
|
3214 yPosQualifier.SetMakeLineFullyVisible(); |
|
3215 SetAmountToFormatL( EFalse, EFalse ); // Not a new doc; Do not reformat |
|
3216 if (!(iEdwinInternalFlags & ESuppressFormatting)) |
|
3217 iTextView->HandleGlobalChangeNoRedrawL(yPosQualifier); // This does the reformat |
|
3218 CalculateLineMetricsForBandFormattingL(); |
|
3219 SetScrollBarsL(); |
|
3220 UpdateScrollBarsL(); |
|
3221 if ( condition ) |
|
3222 { |
|
3223 SetCursorVisibilityL( ETrue ); |
|
3224 } |
|
3225 // View size changed, Initialize physics here |
|
3226 iEdwinExtension->InitPhysicsL(); |
|
3227 } |
|
3228 |
|
3229 EXPORT_C TInt CEikEdwin::CountComponentControls() const |
|
3230 { |
|
3231 TInt count=CEikBorderedControl::CountComponentControls(); |
|
3232 if (iSBFrame) |
|
3233 count+=iSBFrame->CountComponentControls(); |
|
3234 return count; |
|
3235 } |
|
3236 |
|
3237 EXPORT_C CCoeControl* CEikEdwin::ComponentControl(TInt aIndex) const |
|
3238 { |
|
3239 TInt baseCount=CEikBorderedControl::CountComponentControls(); |
|
3240 if (aIndex<baseCount) |
|
3241 return CEikBorderedControl::ComponentControl(aIndex); |
|
3242 aIndex-=baseCount; |
|
3243 return iSBFrame->ComponentControl(aIndex); |
|
3244 } |
|
3245 |
|
3246 EXPORT_C void CEikEdwin::SetAmountToFormatL(TBool aIsNewDoc) |
|
3247 { |
|
3248 if (!iTextView) |
|
3249 return; |
|
3250 const TInt chars=iText->DocumentLength(); |
|
3251 if ( iEdwinExtension->iSmiley && !iEdwinExtension->iDisableConvertInFormat ) |
|
3252 { |
|
3253 if ( chars > KFullFormatLengthForSmiley ) |
|
3254 { |
|
3255 ConvertVisibleTextForSmileyL( ETrue ); |
|
3256 } |
|
3257 else if ( chars > 0 ) |
|
3258 { |
|
3259 ConvertTextForSmileyL( TCursorSelection( 0, chars ), ETrue ); |
|
3260 } |
|
3261 } |
|
3262 if (chars>UpperFullFormattingLength()) |
|
3263 { |
|
3264 if (aIsNewDoc) |
|
3265 { |
|
3266 iLayout->SetAmountToFormat(); |
|
3267 iTextView->FormatTextL(); |
|
3268 const TInt formattedLines=iLayout->NumFormattedLines(); |
|
3269 const TInt formattedHeight=iLayout->FormattedHeightInPixels(); |
|
3270 iAvgCharsPerLine=iLayout->FormattedLength()/formattedLines; |
|
3271 iAvgLinesInViewRect=Max(1,(iTextView->ViewRect().Height()*formattedLines)/formattedHeight); |
|
3272 } |
|
3273 else |
|
3274 { |
|
3275 const TInt numLines=iLayout->NumFormattedLines(); |
|
3276 const TInt docHeight=iLayout->FormattedHeightInPixels(); |
|
3277 iAvgCharsPerLine=iLayout->FormattedLength()/numLines; |
|
3278 iAvgLinesInViewRect=Max(1,(iTextView->ViewRect().Height()*numLines)/docHeight); |
|
3279 iLayout->SetAmountToFormat(); |
|
3280 iTextView->HandleGlobalChangeNoRedrawL(); |
|
3281 } |
|
3282 if (IsReadyToDraw() && iSBFrame && iSBFrame->VScrollBarVisibility()!=CEikScrollBarFrame::EOff) |
|
3283 UpdateScrollBarsL(); |
|
3284 } |
|
3285 else |
|
3286 { |
|
3287 iAvgCharsPerLine=1; |
|
3288 iAvgLinesInViewRect=0; |
|
3289 iLayout->SetAmountToFormat(CTextLayout::EFFormatAllText); |
|
3290 if (aIsNewDoc) |
|
3291 iTextView->FormatTextL(); |
|
3292 else |
|
3293 iTextView->HandleGlobalChangeNoRedrawL(); |
|
3294 } |
|
3295 } |
|
3296 |
|
3297 EXPORT_C void CEikEdwin::SetAmountToFormatL( TBool aIsNewDoc, TBool aReFormat ) |
|
3298 { |
|
3299 if (aReFormat) |
|
3300 { |
|
3301 SetAmountToFormatL( aIsNewDoc ); |
|
3302 return; |
|
3303 } |
|
3304 |
|
3305 if (!iTextView) |
|
3306 return; |
|
3307 const TInt chars=iText->DocumentLength(); |
|
3308 if ( iEdwinExtension->iSmiley && !iEdwinExtension->iDisableConvertInFormat ) |
|
3309 { |
|
3310 if ( chars > KFullFormatLengthForSmiley ) |
|
3311 { |
|
3312 ConvertVisibleTextForSmileyL( ETrue ); |
|
3313 } |
|
3314 else if ( chars > 0 ) |
|
3315 { |
|
3316 ConvertTextForSmileyL( TCursorSelection( 0, chars ), ETrue ); |
|
3317 } |
|
3318 } |
|
3319 if (chars>UpperFullFormattingLength()) |
|
3320 { |
|
3321 iLayout->SetAmountToFormat(CTextLayout::EFFormatBand); |
|
3322 } |
|
3323 else |
|
3324 { |
|
3325 iLayout->SetAmountToFormat(CTextLayout::EFFormatAllText); |
|
3326 } |
|
3327 } |
|
3328 |
|
3329 void CEikEdwin::CalculateLineMetricsForBandFormattingL() |
|
3330 { |
|
3331 if ( iLayout) |
|
3332 { |
|
3333 if (iLayout->IsFormattingBand()) |
|
3334 { |
|
3335 const TInt numLines=iLayout->NumFormattedLines(); |
|
3336 const TInt docHeight=iLayout->FormattedHeightInPixels(); |
|
3337 |
|
3338 // To make sure that division by 0 does not happen in any situation. |
|
3339 if (numLines > 0) |
|
3340 { |
|
3341 iAvgCharsPerLine=iLayout->FormattedLength()/numLines; |
|
3342 } |
|
3343 else |
|
3344 { |
|
3345 iAvgCharsPerLine = 1; |
|
3346 } |
|
3347 |
|
3348 // To make sure that division by 0 does not happen in any situation. |
|
3349 if (docHeight > 0) |
|
3350 { |
|
3351 iAvgLinesInViewRect=Max(1,(iTextView->ViewRect().Height()*numLines)/docHeight); |
|
3352 } |
|
3353 else |
|
3354 { |
|
3355 iAvgLinesInViewRect=0; |
|
3356 } |
|
3357 } |
|
3358 else |
|
3359 { |
|
3360 iAvgCharsPerLine=1; |
|
3361 iAvgLinesInViewRect=0; |
|
3362 } |
|
3363 if (IsReadyToDraw() && iSBFrame && iSBFrame->VScrollBarVisibility()!=CEikScrollBarFrame::EOff) |
|
3364 UpdateScrollBarsL(); |
|
3365 } |
|
3366 } |
|
3367 |
|
3368 EXPORT_C void CEikEdwin::ReportEdwinEventL(MEikEdwinObserver::TEdwinEvent aEventType) |
|
3369 { |
|
3370 if(iCustomDrawer && aEventType==MEikEdwinObserver::EEventFormatChanged) |
|
3371 iCustomDrawer->LineSpacingChanged(); |
|
3372 if (iEdwinObserver!=NULL) |
|
3373 iEdwinObserver->HandleEdwinEventL(this,aEventType); |
|
3374 if (iCcpuSupport) |
|
3375 iCcpuSupport->HandleSelectionChangeL(); |
|
3376 if (iObserverArray) |
|
3377 { |
|
3378 const TInt count=iObserverArray->Count(); |
|
3379 for (TInt ii=0;ii<count;ii++) |
|
3380 (*iObserverArray)[ii]->HandleEdwinEventL(this,aEventType); |
|
3381 } |
|
3382 if ( aEventType == MEikEdwinObserver::EEventScroll || |
|
3383 aEventType == MEikEdwinObserver::EEventNavigation |
|
3384 ) |
|
3385 { |
|
3386 HandleScrollForSmileyL(); |
|
3387 } |
|
3388 if ( aEventType == MEikEdwinObserver::EEventTextUpdate ) |
|
3389 { |
|
3390 iEdwinExtension->iExtendedInputCapabilities->ReportEventL( |
|
3391 CAknExtendedInputCapabilities:: |
|
3392 MAknEventObserver::EControlContentUpdatedInternally, |
|
3393 NULL ); |
|
3394 } |
|
3395 } |
|
3396 |
|
3397 |
|
3398 |
|
3399 EXPORT_C void CEikEdwin::NotifyNewDocumentL() |
|
3400 { |
|
3401 __ASSERT_DEBUG(iTextView,Panic(EEikPanicEdwinNoView)); |
|
3402 __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText)); |
|
3403 TViewYPosQualifier yPosQ; |
|
3404 yPosQ.SetMakeLineFullyVisible(); |
|
3405 yPosQ.SetFillScreen(); // ??? |
|
3406 iTextView->HandleGlobalChangeL(yPosQ); |
|
3407 TInt topLeftYPos=iTextView->ViewRect().iTl.iY; |
|
3408 iTextView->SetViewL(0,topLeftYPos,yPosQ); |
|
3409 iTextView->SetDocPosL(0); |
|
3410 SetAmountToFormatL(ETrue); // performs formatting |
|
3411 UpdateScrollBarsL(); |
|
3412 } |
|
3413 |
|
3414 EXPORT_C void CEikEdwin::NotifyNewFormatL() |
|
3415 { |
|
3416 if(iCustomDrawer) |
|
3417 iCustomDrawer->LineSpacingChanged(); |
|
3418 __ASSERT_DEBUG(iTextView,Panic(EEikPanicEdwinNoView)); |
|
3419 TViewYPosQualifier yPosQualifier; |
|
3420 yPosQualifier.SetMakeLineFullyVisible(); |
|
3421 yPosQualifier.SetFillScreen(); |
|
3422 if( !(iEdwinInternalFlags & ESuppressFormatting)) |
|
3423 { |
|
3424 iTextView->HandleGlobalChangeNoRedrawL(yPosQualifier); |
|
3425 ForceScrollBarUpdateL(); |
|
3426 // Drawing here is controlled by an internal mechanism |
|
3427 CAknEdwinDrawingModifier* modifier = AknEdwinDrawingModifier(); |
|
3428 if ( ! (iEdwinInternalFlags & ESuppressNotifyDraw) ) |
|
3429 { |
|
3430 if ( !(modifier && modifier->InhibitNotifyNewFormatDrawing()) ) |
|
3431 { |
|
3432 DrawDeferred(); |
|
3433 } |
|
3434 } |
|
3435 |
|
3436 } |
|
3437 } |
|
3438 |
|
3439 EXPORT_C void CEikEdwin::SetCursorPosL(TInt aDocPos,TBool aSelect) |
|
3440 { |
|
3441 // CTextView::SetDocPosL will cause textview to be drawn. This could happen |
|
3442 // before the drawing of editor. So adding following codes to postpone the action to |
|
3443 // first drawing of editor. |
|
3444 if ( iEdwinExtension->iDrawInvoked == CEikEdwinExtension::ENotDraw ) |
|
3445 { |
|
3446 iEdwinExtension->iTempCursorPos = aDocPos; |
|
3447 iEdwinExtension->iTempSelect = aSelect; |
|
3448 if ( !aSelect ) |
|
3449 { |
|
3450 iEdwinExtension->iTempAnchorPos = KErrNotFound; |
|
3451 } |
|
3452 return; |
|
3453 } |
|
3454 |
|
3455 if ( IsFocused() ) |
|
3456 { |
|
3457 CancelFepTransaction(); |
|
3458 } |
|
3459 |
|
3460 if (!iTextView) |
|
3461 CreateTextViewL(); |
|
3462 TInt oldPos( CursorPos() ); |
|
3463 TInt docPos( aDocPos ); |
|
3464 if ( iEdwinExtension->iSmiley ) |
|
3465 { |
|
3466 iEdwinExtension->iSmiley->HandleSetCursor( oldPos, docPos ); |
|
3467 } |
|
3468 TCursorSelection select( Selection() ); |
|
3469 select.iCursorPos = docPos; |
|
3470 if ( !aSelect ) |
|
3471 { |
|
3472 select.iAnchorPos = docPos; |
|
3473 } |
|
3474 HandleSelectionForSmiley( select ); |
|
3475 iTextView->SetDocPosL( docPos, aSelect ); |
|
3476 ScrollIfAtTopOrBottomL(); |
|
3477 |
|
3478 if ( iEdwinFepSupport && |
|
3479 ( aDocPos != oldPos || ( select.Length() > 0 && !aSelect ) ) ) |
|
3480 { |
|
3481 CAknEdwinState* edwinState = static_cast<CAknEdwinState*>( iEdwinFepSupport->State(KNullUid) ); |
|
3482 if ( edwinState ) |
|
3483 { |
|
3484 TRAP_IGNORE( edwinState->ReportAknEdStateEventL( MAknEdStateObserver::EAknCursorPositionChanged ) ); |
|
3485 } |
|
3486 } |
|
3487 |
|
3488 UpdateVertScrollBarThumbL(); |
|
3489 UpdateHorizScrollBarThumb(); |
|
3490 } |
|
3491 |
|
3492 EXPORT_C void CEikEdwin::SetDocumentOwnership(TOwnershipType aOwner) |
|
3493 { |
|
3494 if (aOwner==EOwnsText) |
|
3495 iEdwinUserFlags&=~EKeepDocument; |
|
3496 else |
|
3497 iEdwinUserFlags|=EKeepDocument; |
|
3498 } |
|
3499 |
|
3500 EXPORT_C void CEikEdwin::SetSelectionL(TInt aCursorPos,TInt aAnchorPos) |
|
3501 { |
|
3502 if( IsFocused() ) |
|
3503 { |
|
3504 CancelFepTransaction(); |
|
3505 } |
|
3506 if (!iTextView) |
|
3507 CreateTextViewL(); |
|
3508 if ( iEdwinExtension->iDrawInvoked == CEikEdwinExtension::ENotDraw ) |
|
3509 { |
|
3510 iEdwinExtension->iTempCursorPos = aCursorPos; |
|
3511 iEdwinExtension->iTempAnchorPos = aAnchorPos; |
|
3512 return; |
|
3513 } |
|
3514 if ( IsSmileyEnabled() ) |
|
3515 { |
|
3516 iEdwinExtension->iSmiley->HandleSetCursor( aAnchorPos, aCursorPos ); |
|
3517 iEdwinExtension->iSmiley->HandleSetCursor( aCursorPos, aAnchorPos ); |
|
3518 } |
|
3519 TCursorSelection select( aCursorPos, aAnchorPos ); |
|
3520 HandleSelectionForSmiley( select ); |
|
3521 iTextView->SetSelectionL( select ); |
|
3522 iEdwinExtension->iThumbPos = KErrNotFound; |
|
3523 |
|
3524 if ( iEdwinFepSupport ) |
|
3525 { |
|
3526 CAknEdwinState* edwinState = static_cast<CAknEdwinState*>( iEdwinFepSupport->State(KNullUid) ); |
|
3527 if ( edwinState ) |
|
3528 { |
|
3529 TRAP_IGNORE( edwinState->ReportAknEdStateEventL( MAknEdStateObserver::EAknCursorPositionChanged ) ); |
|
3530 } |
|
3531 } |
|
3532 CancelInsertCharFormat(); |
|
3533 UpdateVertScrollBarThumbL(); |
|
3534 UpdateHorizScrollBarThumb(); |
|
3535 } |
|
3536 |
|
3537 EXPORT_C void CEikEdwin::SelectAllL() |
|
3538 { |
|
3539 CancelFepTransaction(); |
|
3540 SetSelectionL( TextLength(), 0 ); |
|
3541 } |
|
3542 |
|
3543 TBool CEikEdwin::OwnsScrollBars() const |
|
3544 { |
|
3545 if (!iSBFrame) |
|
3546 return EFalse; |
|
3547 return ((iSBFrame->ScrollBarVisibility(CEikScrollBar::EHorizontal)!=CEikScrollBarFrame::EOff)||(iSBFrame->VScrollBarVisibility()!=CEikScrollBarFrame::EOff)); |
|
3548 } |
|
3549 |
|
3550 EXPORT_C void CEikEdwin::SetWordWrapL(TBool aWrapIsOn) |
|
3551 { |
|
3552 __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText)); |
|
3553 __ASSERT_DEBUG(iLayout,Panic(EEikPanicEdwinNoLayout)); |
|
3554 if (aWrapIsOn) |
|
3555 { |
|
3556 iEdwinUserFlags&=~ENoWrap; |
|
3557 iLayout->ForceNoWrapping(EFalse); |
|
3558 iLayout->SetWrapWidth(LayoutWidth()); |
|
3559 } |
|
3560 else |
|
3561 { |
|
3562 iEdwinUserFlags|=ENoWrap; |
|
3563 iLayout->ForceNoWrapping(); |
|
3564 } |
|
3565 NotifyNewFormatL(); |
|
3566 } |
|
3567 |
|
3568 EXPORT_C TInt CEikEdwin::LineCursorWidth() const |
|
3569 { |
|
3570 return 0; |
|
3571 } |
|
3572 |
|
3573 EXPORT_C void CEikEdwin::SetLineCursorDetailsL() |
|
3574 { |
|
3575 __ASSERT_DEBUG(iTextView,Panic(EEikPanicEdwinNoView)); |
|
3576 iTextView->SetMarginWidths(0,LineCursorWidth()); |
|
3577 } |
|
3578 |
|
3579 EXPORT_C void CEikEdwin::SetTextLimit(TInt aLimit) |
|
3580 { |
|
3581 #if defined(_DEBUG) |
|
3582 if (aLimit<iText->DocumentLength()) |
|
3583 Panic(EEikPanicEdwinInvalidTextLimit); |
|
3584 #endif |
|
3585 iTextLimit=aLimit; |
|
3586 } |
|
3587 |
|
3588 EXPORT_C TMargins8 CEikEdwin::Margins() const |
|
3589 { |
|
3590 return iMargins; |
|
3591 } |
|
3592 |
|
3593 void CEikEdwin::ApplyAutoSelectionL() |
|
3594 { |
|
3595 if ( iEdwinUserFlags & EAvkonNotEditable ) |
|
3596 return; |
|
3597 const TInt length=TextLength(); |
|
3598 if (iEdwinUserFlags&EJustAutoCurEnd) |
|
3599 { |
|
3600 SetCursorPosL(length,EFalse); |
|
3601 } |
|
3602 else if (!(iEdwinUserFlags&ENoAutoSelection)) |
|
3603 { |
|
3604 SetSelectionL(length,0); |
|
3605 } |
|
3606 else |
|
3607 { |
|
3608 SetCursorPosL(0,EFalse); |
|
3609 } |
|
3610 } |
|
3611 |
|
3612 EXPORT_C TSize CEikEdwin::MinimumSize() |
|
3613 { |
|
3614 TSize edwinSize = iSize; |
|
3615 if ((iEdwinUserFlags&EResizable) && (edwinSize.iHeight == 0)) |
|
3616 { |
|
3617 if ((iMinimumHeight > 0) && (edwinSize.iHeight < iMinimumHeight)) |
|
3618 edwinSize.iHeight = iMinimumHeight; |
|
3619 } |
|
3620 return edwinSize; |
|
3621 } |
|
3622 |
|
3623 EXPORT_C void CEikEdwin::SetContainerWindowL(const CCoeControl& aParent) |
|
3624 { |
|
3625 if (iEdwinUserFlags&EOwnsWindow && !OwnsWindow()) |
|
3626 CreateWindowL(&aParent); |
|
3627 else |
|
3628 CCoeControl::SetContainerWindowL(aParent); |
|
3629 |
|
3630 iEdwinExtension->EnablePhysicsL(); |
|
3631 } |
|
3632 |
|
3633 EXPORT_C void CEikEdwin::SetContainerWindowL() |
|
3634 { |
|
3635 __ASSERT_DEBUG(iEdwinUserFlags&EOwnsWindow, Panic(EEikPanicEdwinNoWindow)); |
|
3636 if (!OwnsWindow()) |
|
3637 CreateWindowL(); |
|
3638 |
|
3639 iEdwinExtension->EnablePhysicsL(); |
|
3640 } |
|
3641 |
|
3642 EXPORT_C TCoeInputCapabilities CEikEdwin::InputCapabilities() const |
|
3643 { |
|
3644 if (IsReadOnly()) |
|
3645 { |
|
3646 TCoeInputCapabilities readOnlyInputCaps( TCoeInputCapabilities::ENavigation ); |
|
3647 readOnlyInputCaps.SetObjectProvider( const_cast<CEikEdwin*>( this ) ); |
|
3648 return readOnlyInputCaps; |
|
3649 } |
|
3650 |
|
3651 TCoeInputCapabilities inputCaps( LafEdwin::InputCapabilities(),iEdwinFepSupport,NULL,TUid::Uid(0x100056de),iEdwinFepSupport ); |
|
3652 inputCaps.SetObjectProvider( const_cast<CEikEdwin*>( this ) ); |
|
3653 |
|
3654 if (iEdwinFepSupport!=NULL) |
|
3655 { |
|
3656 const TCoeInputCapabilities* inputCapabilities=iEdwinFepSupport->InputCapabilities(); |
|
3657 |
|
3658 if (inputCapabilities!=NULL) |
|
3659 { |
|
3660 return *inputCapabilities; |
|
3661 } |
|
3662 |
|
3663 // This tries to sense that this is a numeric-only edwin, and |
|
3664 // set the input caps so that FEP would use the _digit mode_ instead |
|
3665 // of input language mode when choosing input type and indicator |
|
3666 CAknEdwinState* state = static_cast<CAknEdwinState*>( iEdwinFepSupport->State( KNullUid ) ); |
|
3667 if ( state ) |
|
3668 { |
|
3669 if ( state->PermittedInputModes() == EAknEditorNumericInputMode ) |
|
3670 { |
|
3671 inputCaps.SetCapabilities( inputCaps.Capabilities() | |
|
3672 TCoeInputCapabilities::EWesternNumericIntegerPositive | |
|
3673 TCoeInputCapabilities::EWesternNumericIntegerNegative ); |
|
3674 } |
|
3675 } |
|
3676 } |
|
3677 |
|
3678 return inputCaps; |
|
3679 } |
|
3680 |
|
3681 EXPORT_C void CEikEdwin::SetInputCapabilitiesL(const TCoeInputCapabilities& aInputCapabilities) |
|
3682 { |
|
3683 User::LeaveIfNull(iEdwinFepSupport); |
|
3684 iEdwinFepSupport->SetInputCapabilitiesL(aInputCapabilities); |
|
3685 } |
|
3686 |
|
3687 EXPORT_C void CEikEdwin::FormatTextL() |
|
3688 { |
|
3689 if (iTextView) // else FormatTextL() will get called later, in ActivateL() |
|
3690 iTextView->FormatTextL(); |
|
3691 } |
|
3692 |
|
3693 /** |
|
3694 * @internal |
|
3695 */ |
|
3696 EXPORT_C void CEikEdwin::CreateLayoutL(MLayDoc* aLayDoc) |
|
3697 { |
|
3698 __ASSERT_DEBUG(aLayDoc,Panic(EEikPanicEdwinNoText)); |
|
3699 |
|
3700 if ((iEdwinUserFlags&EAvkonEditor)) |
|
3701 { |
|
3702 iLayout=CTextLayout::NewL(aLayDoc,KMaxTInt); // supply real wrapping width later |
|
3703 iLayout->SetCustomWrap(&(iEdwinExtension->TextWrapper())); |
|
3704 |
|
3705 // This WAS ETrue, then fixed to EFalse, caused regression and now back to |
|
3706 // ETrue. In case it is true the editor scrolls _always_ |
|
3707 // so that the topmost line is visible, and the baselines are nicely |
|
3708 // aligned. This had a side effect which sometimes caused editors to |
|
3709 // display only partial lines in the bottom, even if the cursor was in that |
|
3710 // line. Setting this to false makes sure that the line where cursor is |
|
3711 // is always displayed properly, but causes small less-than-linespacing |
|
3712 // scrolls in some occasions where the editor's size doesn't match the |
|
3713 // multiple of font and its highlights and line spacing. |
|
3714 //iLayout->RestrictScrollToTopsOfLines( EFalse ); |
|
3715 |
|
3716 if ( KineticScrollingEnabled() ) |
|
3717 { |
|
3718 // With kinetic scrolling this is set to EFalse. |
|
3719 // ScrollDisplayPixelsL and ScrollDisplayPixelsNoLimitBorderL |
|
3720 // won't move content pixel by pixel (but line by line) |
|
3721 // if this is not EFalse. |
|
3722 iLayout->RestrictScrollToTopsOfLines( EFalse ); |
|
3723 } |
|
3724 else |
|
3725 { |
|
3726 iLayout->RestrictScrollToTopsOfLines( ETrue ); |
|
3727 } |
|
3728 |
|
3729 // the default FontHeightIncreaseFactor in FORM is EDefaultFontHeightIncreaseFactor==7, |
|
3730 // but the Avkon modified FORM change this to 6 |
|
3731 // Moved this modification out and using the provided interface instead |
|
3732 iLayout->SetFontHeightIncreaseFactor(6); |
|
3733 // not originally merged in |
|
3734 //iLayout->SetMinimumLineDescent(0); |
|
3735 } |
|
3736 else |
|
3737 { |
|
3738 iLayout=CTextLayout::NewL(aLayDoc,KMaxTInt); // supply real wrapping width later |
|
3739 // Was ETrue, see above. |
|
3740 iLayout->RestrictScrollToTopsOfLines( EFalse ); |
|
3741 //iLayout->RestrictScrollToTopsOfLines(ETrue); |
|
3742 // not originally merged in |
|
3743 //iLayout->SetMinimumLineDescent(0); |
|
3744 } |
|
3745 |
|
3746 CheckEdwinExtensionL(); // checks if iEdwinExtension is non-NULL |
|
3747 iEdwinExtension->FormCursorModifier()->SetTextLayout(iLayout); |
|
3748 } |
|
3749 |
|
3750 EXPORT_C void CEikEdwin::SetAvkonWrap(TBool aAvkonWrapIsOn) |
|
3751 { |
|
3752 if (aAvkonWrapIsOn) |
|
3753 iEdwinUserFlags|=EAvkonEditor; |
|
3754 else |
|
3755 iEdwinUserFlags&=~EAvkonEditor; |
|
3756 } |
|
3757 |
|
3758 EXPORT_C void CEikEdwin::Draw(const TRect& /*aRect*/) const |
|
3759 { |
|
3760 CEikEdwin* me = const_cast< CEikEdwin* > ( this ); |
|
3761 me->iEdwinInternalFlags |= ESkipBackgroundDrawer; |
|
3762 |
|
3763 if ( iTextView ) |
|
3764 { |
|
3765 const TRect rect=Rect(); |
|
3766 CWindowGc& gc=SystemGc(); |
|
3767 |
|
3768 const TRect viewRect=iTextView->ViewRect(); |
|
3769 |
|
3770 TRgb dummyColor; |
|
3771 TRgb backgroundColor = EditorBackgroundColor(dummyColor); |
|
3772 gc.SetBrushColor( backgroundColor ); |
|
3773 |
|
3774 if ( !IsBackgroundDrawingSuppressed() ) |
|
3775 { |
|
3776 // Text view may not occupy the whole control area. So we need to draw in the gaps |
|
3777 DrawBackgroundAroundTextView( gc, rect, viewRect, backgroundColor ); |
|
3778 } |
|
3779 |
|
3780 TrappedDraw(viewRect); |
|
3781 |
|
3782 #ifdef RD_UI_TRANSITION_EFFECTS_POPUPS |
|
3783 // Workaround for clipping rect problem in multiline queries with text |
|
3784 // entries. Because of differences between CRemoteGc and CWindowGc, |
|
3785 // parts of the query wouldn't be drawn by CRemoteGc. The Reset() call |
|
3786 // is to cancel the clipping rect. For some reason, CancelClippingRect() |
|
3787 // and CancelClippingRegion() don't work. |
|
3788 gc.Reset(); |
|
3789 #endif |
|
3790 } |
|
3791 |
|
3792 me->iEdwinInternalFlags &= ~ESkipBackgroundDrawer; |
|
3793 } |
|
3794 |
|
3795 void CleanupReleaseFont(TAny* aFont) |
|
3796 { |
|
3797 CFont** fontPtr = (CFont**)aFont; |
|
3798 CEikonEnv::Static()->ScreenDevice()->ReleaseFont(*fontPtr); |
|
3799 } |
|
3800 |
|
3801 void CEikEdwin::DrawFirstLineTextL() const |
|
3802 { |
|
3803 |
|
3804 HBufC* clipbuf = GetTextInHBufL(); |
|
3805 CleanupStack::PushL(clipbuf); |
|
3806 |
|
3807 TPtrC clipbufPtr = clipbuf->Des(); |
|
3808 TMargins8 margins = Margins(); |
|
3809 const TRect rect(Rect()); |
|
3810 TInt cursorWidth = CursorWidth(); // need to add cursor width to right hand margin |
|
3811 TRect edwinRect = AknLayoutUtils::RectFromCoords(rect, margins.iLeft, margins.iTop, margins.iRight+cursorWidth, margins.iBottom, ELayoutEmpty, ELayoutEmpty); |
|
3812 |
|
3813 TAknTextLineLayout textLayout = AknLayoutScalable_Avkon::data_form_wide_pane_t1(0).LayoutLine(); |
|
3814 const CAknLayoutFont* font = AknLayoutUtils::LayoutFontFromId( textLayout.FontId()); |
|
3815 |
|
3816 // reorder the text |
|
3817 AknBidiTextUtils::PrepareRunInfoArray(clipbufPtr); |
|
3818 |
|
3819 HBufC* reorderedText = HBufC::NewLC(clipbufPtr.Length() + TBidiLogicalToVisual::KMinCharAvailable); |
|
3820 TPtr reorderedTextPtr = reorderedText->Des(); |
|
3821 TInt width = edwinRect.Size().iWidth; |
|
3822 AknBidiTextUtils::ConvertToVisualAndClip(clipbufPtr, reorderedTextPtr, *font, width, width); |
|
3823 AknTextUtils::ReplaceCharacters( reorderedTextPtr, _L("\x2029"), TChar(' ') ); |
|
3824 CleanupStack::Pop(reorderedText); |
|
3825 CleanupStack::PopAndDestroy(clipbuf); |
|
3826 CleanupStack::PushL(reorderedText); |
|
3827 |
|
3828 CGraphicsContext::TTextAlign alignment = CGraphicsContext::ELeft; |
|
3829 switch(CurrentAlignment()) |
|
3830 { |
|
3831 case EAknEditorAlignLeft: |
|
3832 alignment = CGraphicsContext::ELeft; |
|
3833 break; |
|
3834 case EAknEditorAlignCenter: |
|
3835 alignment = CGraphicsContext::ECenter; |
|
3836 break; |
|
3837 case EAknEditorAlignRight: |
|
3838 alignment = CGraphicsContext::ERight; |
|
3839 break; |
|
3840 case EAknEditorAlignNone: // drop through to default |
|
3841 case EAknEditorAlignBidi: // drop through to default |
|
3842 default: |
|
3843 { |
|
3844 if (TBidiText::TextDirectionality(reorderedTextPtr) == TBidiText::ELeftToRight) |
|
3845 alignment = CGraphicsContext::ELeft; |
|
3846 else |
|
3847 alignment = CGraphicsContext::ERight; |
|
3848 } |
|
3849 break; |
|
3850 } |
|
3851 |
|
3852 CWindowGc& gc=SystemGc(); |
|
3853 gc.UseFont(font); |
|
3854 |
|
3855 // Following patching up of the GC are now necessary after calling LafCustomDrawerfor background |
|
3856 gc.SetBrushStyle(CGraphicsContext::ENullBrush); |
|
3857 gc.SetPenStyle(CGraphicsContext::ESolidPen); |
|
3858 TRgb textColor=iEikonEnv->ControlColor(EColorControlText,*this); |
|
3859 |
|
3860 gc.SetPenColor(textColor); // Text color |
|
3861 |
|
3862 // Edwin is assumed to be laid out already with LayoutEdwin. In that case |
|
3863 // the textpane top is the top of the edwin |
|
3864 TInt ascent = font->TextPaneTopToBaseline(); |
|
3865 |
|
3866 gc.DrawText(reorderedTextPtr, edwinRect, ascent, alignment); |
|
3867 |
|
3868 CleanupStack::PopAndDestroy(reorderedText); |
|
3869 |
|
3870 gc.DiscardFont(); // So the GC will not try to use the font. |
|
3871 } |
|
3872 |
|
3873 EXPORT_C void CEikEdwin::TrappedDraw(const TRect& aViewRect) const |
|
3874 { |
|
3875 if ( iEdwinExtension->iDrawInvoked == CEikEdwinExtension::ENotDraw ) |
|
3876 { |
|
3877 CEikEdwin* edwin( const_cast<CEikEdwin*>( this ) ); |
|
3878 edwin->iEdwinExtension->iDrawInvoked = CEikEdwinExtension::EDrawing; |
|
3879 TRAP_IGNORE( edwin->PerformRecordedOperationL(); ); |
|
3880 } |
|
3881 if (!(iEdwinUserFlags & EAvkonNotEditable)) |
|
3882 { |
|
3883 TRAPD(err, iTextView->DrawL(aViewRect,SystemGc()) ); |
|
3884 if (err) |
|
3885 { |
|
3886 SystemGc().Clear(aViewRect); |
|
3887 iEikonEnv->NotifyIdleErrorWhileRedrawing(err); |
|
3888 } |
|
3889 } |
|
3890 else |
|
3891 { |
|
3892 if(TextLength() == 0) // no text, so nothing to draw. |
|
3893 return; |
|
3894 |
|
3895 // If a non-editable edwin does not vertically fit to the parent window, |
|
3896 // do not draw the text |
|
3897 // TODO: commented code below should be flagged run-time |
|
3898 /* TRect parentRect = DrawableWindow()->GetDrawRect(); |
|
3899 if( aViewRect.iTl.iY < parentRect.iTl.iY || |
|
3900 aViewRect.iBr.iY > parentRect.iBr.iY ) |
|
3901 return;*/ |
|
3902 |
|
3903 TRAP_IGNORE(DrawFirstLineTextL()); |
|
3904 } |
|
3905 } |
|
3906 |
|
3907 EXPORT_C void CEikEdwin::SetDimmed(TBool aDimmed) |
|
3908 { |
|
3909 CCoeControl::SetDimmed(aDimmed); |
|
3910 TRgb dimmedColor=iEikonEnv->ControlColor(EColorControlDimmedText,*this); // KEikEdwinDimmedTextColor |
|
3911 TRgb* pointer=(&dimmedColor); |
|
3912 if (!aDimmed) |
|
3913 pointer=NULL; |
|
3914 if (!iTextView) |
|
3915 { |
|
3916 TRAPD(err,CreateTextViewL()); |
|
3917 if (err) |
|
3918 { |
|
3919 SystemGc().Clear(iTextView->ViewRect()); |
|
3920 iEikonEnv->NotifyIdleErrorWhileRedrawing(err); |
|
3921 } |
|
3922 } |
|
3923 iTextView->SetTextColorOverride(pointer); |
|
3924 |
|
3925 // make scrollbar also dimmed |
|
3926 if (iSBFrame && iSBFrame->ScrollBarVisibility(CEikScrollBar::EHorizontal)!=CEikScrollBarFrame::EOff) |
|
3927 { |
|
3928 CEikScrollBar* sb = iSBFrame-> CEikScrollBarFrame::HorizontalScrollBar(); |
|
3929 sb->SetDimmed(aDimmed); |
|
3930 } |
|
3931 if (iSBFrame && iSBFrame->ScrollBarVisibility(CEikScrollBar::EVertical)!=CEikScrollBarFrame::EOff) |
|
3932 { |
|
3933 CEikScrollBar* sb = iSBFrame-> CEikScrollBarFrame::VerticalScrollBar(); |
|
3934 sb->SetDimmed(aDimmed); |
|
3935 } |
|
3936 } |
|
3937 |
|
3938 EXPORT_C void CEikEdwin::DrawContents() |
|
3939 { |
|
3940 if ( CAknEnv::Static()->TransparencyEnabled() ) |
|
3941 { |
|
3942 if ( IsReadyToDraw() ) |
|
3943 { |
|
3944 // Note that rect may be larger than iTextView->ViewRect(), |
|
3945 // so we have to make sure the whole area is drawn. The |
|
3946 // easiest way to achieve this is to call DrawNow. |
|
3947 |
|
3948 const TRect rect=iBorder.InnerRect(Rect()); |
|
3949 DrawNow( rect ); |
|
3950 } |
|
3951 } |
|
3952 else |
|
3953 { |
|
3954 if ( IsReadyToDraw() ) |
|
3955 { |
|
3956 const TRect rect=iBorder.InnerRect(Rect()); |
|
3957 CWindowGc& gc=iEikonEnv->SystemGc(); |
|
3958 |
|
3959 gc.Activate(Window()); |
|
3960 TrappedDraw(rect); //assumes the SystemGc is active |
|
3961 gc.Deactivate(); |
|
3962 } |
|
3963 } |
|
3964 } |
|
3965 |
|
3966 EXPORT_C void CEikEdwin::EditObserver(TInt aStartEdit,TInt aEditLength ) |
|
3967 { |
|
3968 if( EdwinExtension() ) |
|
3969 { |
|
3970 if ( EdwinExtension()->InlineTextSource() ) |
|
3971 EdwinExtension()->InlineTextSource()->EditObserver( aStartEdit, aEditLength ); |
|
3972 } |
|
3973 } |
|
3974 |
|
3975 EXPORT_C void CEikEdwin::CancelSelectionL(TEnd aEndOfSelectionToLeaveCursor) |
|
3976 { |
|
3977 CancelFepTransaction(); |
|
3978 __ASSERT_DEBUG(iTextView,Panic(EEikPanicEdwinNoView)); |
|
3979 TCursorSelection cursorSelection=iTextView->Selection(); |
|
3980 SetCursorPosL((aEndOfSelectionToLeaveCursor==EStart)? cursorSelection.LowerPos(): cursorSelection.HigherPos(),EFalse); |
|
3981 } |
|
3982 |
|
3983 EXPORT_C void CEikEdwin::MoveCursorL(TCursorPosition::TMovementType aMovement,TBool aSelect) |
|
3984 { |
|
3985 CancelFepTransaction(); |
|
3986 __ASSERT_DEBUG(iTextView,Panic(EEikPanicEdwinNoView)); |
|
3987 if ( aMovement == TCursorPosition::EFLeft || aMovement == TCursorPosition::EFRight ) |
|
3988 { |
|
3989 if ( AdjustCursorPosByMovementL( aMovement, aSelect ) ) |
|
3990 { |
|
3991 return; |
|
3992 } |
|
3993 } |
|
3994 TInt oldCursor( CursorPos() ); |
|
3995 TPoint movePoint=iTextView->MoveCursorL( aMovement, aSelect ); |
|
3996 if ( iEdwinExtension->iSmiley ) |
|
3997 { |
|
3998 TCursorSelection select( 0, 0 ); |
|
3999 if ( AdjustCursorForSmileyL( oldCursor, select ) ) |
|
4000 { |
|
4001 SetSelectionL( select.iCursorPos, select.iAnchorPos ); |
|
4002 } |
|
4003 else |
|
4004 { |
|
4005 HandleSelectionForSmiley( select ); |
|
4006 } |
|
4007 DrawDeferred(); |
|
4008 } |
|
4009 if ( movePoint.iX ) |
|
4010 UpdateHorizScrollBarThumb(); |
|
4011 if ( movePoint.iY ) |
|
4012 UpdateVertScrollBarThumbL(); |
|
4013 |
|
4014 if ( iEdwinFepSupport ) |
|
4015 { |
|
4016 CAknEdwinState* edwinState = static_cast<CAknEdwinState*>( |
|
4017 iEdwinFepSupport->State( KNullUid ) ); |
|
4018 if ( edwinState ) |
|
4019 { |
|
4020 TRAP_IGNORE( edwinState->ReportAknEdStateEventL( |
|
4021 MAknEdStateObserver::EAknCursorPositionChanged ) ); |
|
4022 } |
|
4023 } |
|
4024 } |
|
4025 |
|
4026 EXPORT_C void CEikEdwin::MoveDisplayL(TCursorPosition::TMovementType aMovement) |
|
4027 { |
|
4028 __ASSERT_DEBUG(iTextView,Panic(EEikPanicEdwinNoView)); |
|
4029 |
|
4030 // Before scrolling into blank space was allowed, but this eventually |
|
4031 // causes a panic at CTextView::ScrollDisplayL(). |
|
4032 const TInt move=iTextView->ScrollDisplayL(aMovement,CTextLayout::EFDisallowScrollingBlankSpace); |
|
4033 if (move) |
|
4034 { |
|
4035 iEdwinExtension->iThumbPos = KErrNotFound; |
|
4036 switch (aMovement) |
|
4037 { |
|
4038 case TCursorPosition::EFLeft: |
|
4039 case TCursorPosition::EFRight: |
|
4040 case TCursorPosition::EFLineBeg: |
|
4041 case TCursorPosition::EFLineEnd: |
|
4042 UpdateHorizScrollBarThumb(); |
|
4043 break; |
|
4044 case TCursorPosition::EFLineUp: |
|
4045 case TCursorPosition::EFLineDown: |
|
4046 case TCursorPosition::EFPageUp: |
|
4047 case TCursorPosition::EFPageDown: |
|
4048 UpdateVertScrollBarThumbL(); |
|
4049 break; |
|
4050 default: |
|
4051 break; |
|
4052 } |
|
4053 } |
|
4054 } |
|
4055 |
|
4056 EXPORT_C void CEikEdwin::CancelInsertCharFormat() |
|
4057 { |
|
4058 __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText)); |
|
4059 if (iEdwinInternalFlags&ERichText) |
|
4060 STATIC_CAST(CRichText*,iText)->CancelInsertCharFormat(); |
|
4061 } |
|
4062 |
|
4063 EXPORT_C void CEikEdwin::MoveCursorToChunkStartL(TBool aSelect,TChunkSize aChunkSize,TEnd aEndScanningTowards) |
|
4064 { |
|
4065 CancelFepTransaction(); |
|
4066 __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText)); |
|
4067 TInt cursorPos=CursorPos(); |
|
4068 TUint flags=CPlainText::EScanToUnitStart|CPlainText::EScanJoinDelimiters; |
|
4069 if (aEndScanningTowards==EStart) |
|
4070 flags|=CPlainText::EScanBackwards; |
|
4071 switch (aChunkSize) |
|
4072 { |
|
4073 case EChunkWord: |
|
4074 iText->ScanWords(cursorPos,flags); |
|
4075 break; |
|
4076 case EChunkPara: |
|
4077 iText->ScanParas(cursorPos,flags); |
|
4078 break; |
|
4079 } |
|
4080 if (cursorPos==CPlainText::EScanEndOfData) |
|
4081 cursorPos=TextLength(); |
|
4082 SetCursorPosL(cursorPos,aSelect); |
|
4083 } |
|
4084 |
|
4085 EXPORT_C TInt CEikEdwin::CursorPos() const |
|
4086 { |
|
4087 __ASSERT_DEBUG(iTextView,Panic(EEikPanicEdwinNoView)); |
|
4088 if ( iEdwinExtension->iDrawInvoked == CEikEdwinExtension::ENotDraw && |
|
4089 iEdwinExtension->iTempCursorPos != KErrNotFound ) |
|
4090 { |
|
4091 return iEdwinExtension->iTempCursorPos; |
|
4092 } |
|
4093 else |
|
4094 { |
|
4095 TCursorSelection selection=iTextView->Selection(); |
|
4096 return(selection.iCursorPos); |
|
4097 } |
|
4098 } |
|
4099 |
|
4100 EXPORT_C TInt CEikEdwin::SelectionLength() const |
|
4101 { |
|
4102 __ASSERT_DEBUG(iTextView,Panic(EEikPanicEdwinNoView)); |
|
4103 TCursorSelection selection( 0, 0 ); |
|
4104 if ( iEdwinExtension->iDrawInvoked == CEikEdwinExtension::ENotDraw && |
|
4105 iEdwinExtension->iTempCursorPos != KErrNotFound && |
|
4106 iEdwinExtension->iTempAnchorPos != KErrNotFound ) |
|
4107 { |
|
4108 selection.iCursorPos = iEdwinExtension->iTempCursorPos; |
|
4109 selection.iAnchorPos = iEdwinExtension->iTempAnchorPos; |
|
4110 } |
|
4111 else |
|
4112 { |
|
4113 selection = iTextView->Selection(); |
|
4114 } |
|
4115 return(selection.Length()); |
|
4116 } |
|
4117 |
|
4118 EXPORT_C TInt CEikEdwin::DeleteHighlightL(TBool& aChanged,TBool aIsBackSpace,TBool aPromptConfirmation) |
|
4119 { |
|
4120 __ASSERT_DEBUG(iTextView,Panic(EEikPanicEdwinNoView)); |
|
4121 CancelFepTransaction(); |
|
4122 const TCursorSelection selection=iTextView->Selection(); |
|
4123 if (aPromptConfirmation) |
|
4124 { |
|
4125 if (!OkToDeleteSelectionL()) |
|
4126 CBaActiveScheduler::LeaveNoAlert(); |
|
4127 } |
|
4128 iTextView->CancelSelectionL(); |
|
4129 SetCursorPosL(selection.LowerPos(),EFalse); |
|
4130 DeleteL(aChanged,selection,aIsBackSpace); |
|
4131 return(selection.LowerPos()); |
|
4132 } |
|
4133 |
|
4134 EXPORT_C TBool CEikEdwin::OkToDeleteSelectionL() |
|
4135 { |
|
4136 // Avkon behaviour is always to allow deletion of selection, including |
|
4137 // pictures. |
|
4138 return ETrue; |
|
4139 } |
|
4140 |
|
4141 struct STempCleanup { CEikEdwin* iEdwin; }; |
|
4142 |
|
4143 LOCAL_C void DeleteTemp(TAny* aPtr) |
|
4144 { STATIC_CAST(STempCleanup*,aPtr)->iEdwin->ClearUndo(); } |
|
4145 |
|
4146 EXPORT_C void CEikEdwin::DeleteL(TBool& aChanged,const TCursorSelection& aSelection,TBool aIsBackSpace,TBool aAllowUndo) |
|
4147 { |
|
4148 __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText)); |
|
4149 CancelFepTransaction(); |
|
4150 if (aAllowUndo && !SetUndoBufferL(aSelection)) |
|
4151 CBaActiveScheduler::LeaveNoAlert(); |
|
4152 STempCleanup tempCleanup; |
|
4153 tempCleanup.iEdwin=this; |
|
4154 CleanupStack::PushL(TCleanupItem(DeleteTemp,&tempCleanup)); |
|
4155 const TInt length=Max(1,aSelection.Length()); |
|
4156 if ((iEdwinInternalFlags&ERichText) && aIsBackSpace) |
|
4157 aChanged=STATIC_CAST(CRichText*,iText)->DelSetInsertCharFormatL(aSelection.LowerPos(),length); |
|
4158 else |
|
4159 { |
|
4160 if (iEdwinInternalFlags&ERichText) |
|
4161 STATIC_CAST(CRichText*,iText)->CancelInsertCharFormat(); |
|
4162 aChanged=iText->DeleteL(aSelection.LowerPos(),length); |
|
4163 } |
|
4164 if ( iEdwinExtension->iSmiley ) |
|
4165 { |
|
4166 iEdwinExtension->iSmiley->HandleDeleteL( aSelection.LowerPos(), length ); |
|
4167 } |
|
4168 CleanupStack::Pop(); |
|
4169 } |
|
4170 |
|
4171 EXPORT_C TInt CEikEdwin::TextLength() const |
|
4172 { |
|
4173 __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText)); |
|
4174 return(iText->DocumentLength()); |
|
4175 } |
|
4176 |
|
4177 void CEikEdwin::SetCursorVisibilityL(TBool aEmphasis) |
|
4178 { |
|
4179 TCursor::TVisibility textCursor=(aEmphasis? TCursor::EFCursorFlashing : TCursor::EFCursorInvisible); |
|
4180 TCursor::TVisibility lineCursor=((iEdwinUserFlags&ELineCursor && aEmphasis)? |
|
4181 TCursor::EFCursorVisible : TCursor::EFCursorInvisible); |
|
4182 if (iEdwinUserFlags&EAvkonDisableCursor) |
|
4183 { |
|
4184 textCursor = TCursor::EFCursorInvisible; |
|
4185 lineCursor = TCursor::EFCursorInvisible; |
|
4186 } |
|
4187 |
|
4188 iTextView->SetCursorVisibilityL(lineCursor,textCursor); |
|
4189 CAknEdwinState*edwinState = EditorState(); |
|
4190 if( !edwinState ) |
|
4191 return; |
|
4192 if( textCursor != TCursor::EFCursorInvisible ) |
|
4193 { |
|
4194 SetAknEditorFlags( edwinState->Flags() | EAknEditorFlagTextCursorVisible ); |
|
4195 } |
|
4196 else |
|
4197 { |
|
4198 SetAknEditorFlags( edwinState->Flags() & ~EAknEditorFlagTextCursorVisible ); |
|
4199 |
|
4200 // If cursor is disabled during kinetic scrolling |
|
4201 // by other party (for any reason), reset flag so that we don't show it again |
|
4202 // when kinetic scrolling stops |
|
4203 iEdwinExtension->iCursorWasVisible = EFalse; |
|
4204 } |
|
4205 } |
|
4206 |
|
4207 EXPORT_C CPlainText* CEikEdwin::Text() const |
|
4208 { |
|
4209 return iText; |
|
4210 } |
|
4211 |
|
4212 /** |
|
4213 * @internal |
|
4214 * @deprecated |
|
4215 */ |
|
4216 EXPORT_C CTextView* CEikEdwin::TextView() const |
|
4217 { |
|
4218 return iTextView; |
|
4219 } |
|
4220 |
|
4221 /** |
|
4222 * @internal |
|
4223 * @deprecated |
|
4224 */ |
|
4225 EXPORT_C CTextLayout* CEikEdwin::TextLayout() const |
|
4226 { |
|
4227 return iLayout; |
|
4228 } |
|
4229 |
|
4230 EXPORT_C void CEikEdwin::SetZoomFactorL(TZoomFactor* aZoomFactor) |
|
4231 { |
|
4232 iZoomFactor=aZoomFactor; |
|
4233 SetAmountToFormatL(ETrue); // isn't new doc at all !!! |
|
4234 } |
|
4235 |
|
4236 EXPORT_C void CEikEdwin::SetBorderViewMargins(TMargins8 aMargins) |
|
4237 { |
|
4238 iMargins=aMargins; |
|
4239 } |
|
4240 |
|
4241 EXPORT_C void CEikEdwin::SetBackgroundColorL(TRgb aBackground) |
|
4242 { |
|
4243 if (!iTextView) |
|
4244 CreateTextViewL(); |
|
4245 |
|
4246 if (iEdwinExtension) |
|
4247 { |
|
4248 iEdwinExtension->iEditorBackgroundColor = aBackground; |
|
4249 } |
|
4250 |
|
4251 // for legacy reasons |
|
4252 AknLayoutUtils::OverrideControlColorL(*this, EColorControlBackground, aBackground); |
|
4253 } |
|
4254 |
|
4255 EXPORT_C void CEikEdwin::SetWysiwygModeOn(TInt aLayoutWidth,MGraphicsDeviceMap* aDevice) |
|
4256 { |
|
4257 __ASSERT_DEBUG(iLayout,Panic(EEikPanicEdwinNoLayout)); |
|
4258 iLayoutWidth=aLayoutWidth; |
|
4259 iEdwinInternalFlags|=EWysiwygOn; |
|
4260 iLayout->SetFormatMode(CLayoutData::EFWysiwygMode,aLayoutWidth,aDevice); |
|
4261 } |
|
4262 |
|
4263 EXPORT_C void CEikEdwin::SetWysiwygModeOff() |
|
4264 { |
|
4265 __ASSERT_DEBUG(iLayout,Panic(EEikPanicEdwinNoLayout)); |
|
4266 iLayoutWidth=0; |
|
4267 iEdwinInternalFlags&=~EWysiwygOn; |
|
4268 iLayout->SetFormatMode(CLayoutData::EFScreenMode,LayoutWidth(),NULL); |
|
4269 } |
|
4270 |
|
4271 EXPORT_C void CEikEdwin::UpdateLayoutWidth(TInt aLayoutWidth) |
|
4272 { |
|
4273 __ASSERT_DEBUG(iLayout,Panic(EEikPanicEdwinNoLayout)); |
|
4274 iLayoutWidth=aLayoutWidth; |
|
4275 iLayout->SetWrapWidth(aLayoutWidth); |
|
4276 } |
|
4277 |
|
4278 EXPORT_C TInt CEikEdwin::UpperFullFormattingLength() const |
|
4279 { |
|
4280 if (iEdwinExtension) |
|
4281 return iEdwinExtension->iUpperFullFormattingLength; |
|
4282 else |
|
4283 return KFullFormattingUpperThreshold; |
|
4284 } |
|
4285 |
|
4286 EXPORT_C TInt CEikEdwin::LowerPartialFormattingLength() const |
|
4287 { |
|
4288 if (iEdwinExtension) |
|
4289 return iEdwinExtension->iUpperFullFormattingLength - KFormattingThresholdGap; |
|
4290 else |
|
4291 return KPartialFormattingLowerThreshold; |
|
4292 } |
|
4293 |
|
4294 EXPORT_C void CEikEdwin::SetSuppressNotifyDraw( TBool aEnabled ) |
|
4295 { |
|
4296 if (aEnabled) |
|
4297 iEdwinInternalFlags |= ESuppressNotifyDraw; |
|
4298 else |
|
4299 iEdwinInternalFlags &= ~ESuppressNotifyDraw; |
|
4300 } |
|
4301 |
|
4302 EXPORT_C void CEikEdwin::SetSuppressFormatting( TBool aSuppress ) |
|
4303 { |
|
4304 if (aSuppress) |
|
4305 iEdwinInternalFlags |= ESuppressFormatting; |
|
4306 else |
|
4307 iEdwinInternalFlags &= ~ESuppressFormatting; |
|
4308 } |
|
4309 |
|
4310 EXPORT_C void CEikEdwin::SetReadOnly(TBool aReadOnly) |
|
4311 { |
|
4312 if (aReadOnly) |
|
4313 iEdwinUserFlags|=EReadOnly; |
|
4314 else |
|
4315 iEdwinUserFlags&=~EReadOnly; |
|
4316 } |
|
4317 |
|
4318 EXPORT_C TBool CEikEdwin::IsReadOnly() const |
|
4319 { |
|
4320 return iEdwinUserFlags&EReadOnly; |
|
4321 } |
|
4322 |
|
4323 EXPORT_C TInt CEikEdwin::AknEditorFlags() |
|
4324 { |
|
4325 if (EditorState()) |
|
4326 { |
|
4327 return EditorState()->Flags(); |
|
4328 } |
|
4329 return KErrNotFound; |
|
4330 } |
|
4331 |
|
4332 EXPORT_C void CEikEdwin::SetOnlyASCIIChars(TBool aASCIIOnly) |
|
4333 { |
|
4334 if (aASCIIOnly) |
|
4335 iEdwinUserFlags|=EOnlyASCIIChars; |
|
4336 else |
|
4337 iEdwinUserFlags&=~EOnlyASCIIChars; |
|
4338 } |
|
4339 |
|
4340 EXPORT_C TBool CEikEdwin::OnlyASCIIChars() const |
|
4341 { |
|
4342 return (iEdwinUserFlags&EOnlyASCIIChars) || |
|
4343 (AknEdwinFlags() & EAknEditorFlagLatinInputModesOnly); |
|
4344 } |
|
4345 |
|
4346 TBool CEikEdwin::IsValidChar(TInt aChar) const |
|
4347 { |
|
4348 TBool ret( ETrue ); |
|
4349 |
|
4350 if ( OnlyASCIIChars() && aChar >= 255 ) |
|
4351 { |
|
4352 if ( aChar == KPuaCodeSpaceSymbol |
|
4353 || aChar == KEuroSign |
|
4354 ) |
|
4355 { |
|
4356 ret = ETrue; |
|
4357 } |
|
4358 else if ( ( aChar == KDownwardsArrowWithTipLeftwards || |
|
4359 aChar == KDownwardsArrowWithTipRightwards || |
|
4360 aChar == CEditableText::EParagraphDelimiter || |
|
4361 aChar == CEditableText::ELineBreak ) && |
|
4362 !( iEdwinUserFlags & ENoLineOrParaBreaks || |
|
4363 iEdwinInternalFlags & EHasOneLineOnly ) ) |
|
4364 { |
|
4365 ret = ETrue; |
|
4366 } |
|
4367 else |
|
4368 { |
|
4369 ret = EFalse; |
|
4370 } |
|
4371 } |
|
4372 |
|
4373 return ret; |
|
4374 } |
|
4375 |
|
4376 EXPORT_C void CEikEdwin::CheckNotReadOnlyL() |
|
4377 { |
|
4378 if (IsReadOnly()) |
|
4379 { |
|
4380 NotifyInvalidOperationOnReadOnlyL(); |
|
4381 CBaActiveScheduler::LeaveNoAlert(); |
|
4382 } |
|
4383 } |
|
4384 |
|
4385 EXPORT_C void CEikEdwin::NotifyInvalidOperationOnReadOnlyL() |
|
4386 { |
|
4387 iEikonEnv->InfoMsg(R_EIK_TBUF_READONLYFILE); |
|
4388 } |
|
4389 |
|
4390 EXPORT_C void CEikEdwin::SetRightWrapGutter(TInt aGap) |
|
4391 { |
|
4392 iRightWrapGutter=aGap; |
|
4393 } |
|
4394 |
|
4395 EXPORT_C void CEikEdwin::GetText(TDes& aDes) const |
|
4396 { |
|
4397 __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText)); |
|
4398 |
|
4399 // Uncommitted text in inline editing might temporarily exceed the maximum |
|
4400 // allowed number of characters in editor. |
|
4401 // So, truncate the text to the max allowed number of characters to prevent |
|
4402 // any buffer overflows in caller code. |
|
4403 if ( iTextLimit && TextLength() > iTextLimit ) |
|
4404 { |
|
4405 iText->Extract( aDes, 0, iTextLimit ); |
|
4406 } |
|
4407 else |
|
4408 { |
|
4409 iText->Extract(aDes); // caller's responsibility to provide long enough buffer |
|
4410 } |
|
4411 TCursorSelection select( TextLength(), 0 ); |
|
4412 if ( iTextLimit && TextLength() > iTextLimit ) |
|
4413 { |
|
4414 select.iCursorPos = iTextLimit; |
|
4415 } |
|
4416 TBool hasSmiley( EFalse ); |
|
4417 if ( iEdwinExtension->iSmiley ) |
|
4418 { |
|
4419 hasSmiley = iEdwinExtension->iSmiley->HasSmileyIconsInText(); |
|
4420 } |
|
4421 if ( hasSmiley ) |
|
4422 { |
|
4423 // ensure conversion happens |
|
4424 iEdwinExtension->iSmiley->ConvertTextForSmileyL( select.LowerPos(), aDes, EFalse ); |
|
4425 } |
|
4426 } |
|
4427 |
|
4428 EXPORT_C HBufC* CEikEdwin::GetTextInHBufL() const |
|
4429 { |
|
4430 HBufC* ret=NULL; |
|
4431 TInt textLength=TextLength(); |
|
4432 if (textLength) |
|
4433 { |
|
4434 ret=HBufC::NewL(textLength); |
|
4435 TPtr ptr=ret->Des(); |
|
4436 GetText(ptr); |
|
4437 } |
|
4438 return(ret); |
|
4439 } |
|
4440 |
|
4441 EXPORT_C void CEikEdwin::ClearSelectionL() |
|
4442 { // !! must ensure with CTextView that this never leaves |
|
4443 if( IsFocused() ) |
|
4444 { |
|
4445 CancelFepTransaction(); |
|
4446 } |
|
4447 HandleSelectionForSmiley( TCursorSelection( 0, 0 ) ); |
|
4448 if (iTextView) |
|
4449 { |
|
4450 iTextView->CancelSelectionL(); |
|
4451 if ( iEdwinFepSupport ) |
|
4452 { |
|
4453 CAknEdwinState* edwinState = static_cast<CAknEdwinState*>( iEdwinFepSupport->State(KNullUid) ); |
|
4454 if ( edwinState ) |
|
4455 { |
|
4456 TRAP_IGNORE( edwinState->ReportAknEdStateEventL( MAknEdStateObserver::EAknCursorPositionChanged ) ); |
|
4457 } |
|
4458 } |
|
4459 } |
|
4460 } |
|
4461 |
|
4462 EXPORT_C void CEikEdwin::SetTextL(const TDesC* aDes) |
|
4463 { |
|
4464 __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText)); |
|
4465 if( IsFocused() ) |
|
4466 { |
|
4467 CancelFepTransaction(); |
|
4468 } |
|
4469 if (iEdwinFepSupport && iEdwinFepSupport->State(KNullUid)) |
|
4470 STATIC_CAST(CAknEdwinState*, iEdwinFepSupport->State(KNullUid))->SetInlineEditSpan(TCursorSelection(0,0)); |
|
4471 |
|
4472 ClearSelectionL(); |
|
4473 |
|
4474 TInt err=0; |
|
4475 if (aDes && aDes->Length()) |
|
4476 { |
|
4477 _LIT(KLineBreakCharacter, "\n"); |
|
4478 TInt oldLength=iText->DocumentLength(); |
|
4479 HBufC* segmBuf = HBufC::NewL(KSegmSize); |
|
4480 CleanupStack::PushL(segmBuf); |
|
4481 TPtr segmBufPtr = segmBuf->Des(); |
|
4482 TInt strLength = aDes->Length(); |
|
4483 TInt strEnd = strLength - 1; |
|
4484 TInt segmStart = 0; |
|
4485 TInt segmEnd = 0; |
|
4486 TInt insertLength =0; |
|
4487 while ( strLength > 0 && segmStart <= strEnd && segmEnd <= strEnd) |
|
4488 { |
|
4489 if ( strEnd - segmEnd < KSegmSize) |
|
4490 { |
|
4491 segmEnd = strEnd; |
|
4492 insertLength = segmEnd - segmStart + 1; |
|
4493 } |
|
4494 else |
|
4495 { |
|
4496 segmEnd = segmEnd + KSegmSize; |
|
4497 insertLength = KSegmSize; |
|
4498 } |
|
4499 segmBufPtr = aDes->Mid( segmStart, insertLength); |
|
4500 AknTextUtils::ReplaceCharacters(segmBufPtr, KLineBreakCharacter, |
|
4501 TChar(CEditableText::EParagraphDelimiter)); |
|
4502 iText->InsertL(oldLength+segmStart,*segmBuf); |
|
4503 if ( iEdwinExtension->iSmiley ) |
|
4504 { |
|
4505 iEdwinExtension->iSmiley->HandleInsertL( oldLength+segmStart, |
|
4506 insertLength ); |
|
4507 } |
|
4508 segmStart = segmEnd; |
|
4509 if ( insertLength < KSegmSize && insertLength > 0) |
|
4510 { |
|
4511 segmEnd++; |
|
4512 } |
|
4513 } |
|
4514 |
|
4515 CleanupStack::PopAndDestroy(segmBuf); |
|
4516 TRAP(err,iText->DeleteL(0,oldLength)); |
|
4517 if ( iEdwinExtension->iSmiley ) |
|
4518 { |
|
4519 iEdwinExtension->iSmiley->HandleDeleteL( 0, oldLength ); |
|
4520 ConvertTextForSmileyL( TCursorSelection( 0, |
|
4521 iText->DocumentLength() ), ETrue ); |
|
4522 } |
|
4523 } |
|
4524 else |
|
4525 { |
|
4526 iText->Reset(); // Duplicates previous behaviour where null pointer argument reset text object |
|
4527 if ( iEdwinExtension->iSmiley ) |
|
4528 { |
|
4529 iEdwinExtension->iSmiley->HandleDeleteL( 0, |
|
4530 iText->DocumentLength() ); |
|
4531 } |
|
4532 } |
|
4533 |
|
4534 CheckRemovePictures(0,iText->DocumentLength()); |
|
4535 CheckValidityOfChars(0,iText->DocumentLength()); |
|
4536 iEdwinExtension->iDisableConvertInFormat = ETrue; |
|
4537 SetAmountToFormatL(ETrue); // performs formatting |
|
4538 iEdwinExtension->iDisableConvertInFormat = EFalse; |
|
4539 // Update cursor position as CursorWidth() needs that. |
|
4540 if (IsReadyToDraw()) |
|
4541 { |
|
4542 ApplyAutoSelectionL(); |
|
4543 } |
|
4544 |
|
4545 TInt left, right=0; |
|
4546 if (iLayout && iLayout->CalculateHorizontalExtremesL(left,right,ETrue) && iTextView) |
|
4547 { |
|
4548 TInt width=iTextView->ViewRect().Width(); |
|
4549 TInt labels=0, cursor=0; |
|
4550 iTextView->MarginWidths(labels,cursor); |
|
4551 width-=labels+cursor+labels+cursor+CursorWidth()+iRightWrapGutter; |
|
4552 if (left+right<width) |
|
4553 iTextView->SetLeftTextMargin(0); |
|
4554 |
|
4555 if ( iEdwinExtension ) |
|
4556 { |
|
4557 iEdwinExtension->iExtendedInputCapabilities->ReportEventL( |
|
4558 CAknExtendedInputCapabilities:: |
|
4559 MAknEventObserver::EControlContentUpdatedInternally, |
|
4560 NULL ); |
|
4561 } |
|
4562 ReportEdwinEventL( MEikEdwinObserver::EEventTextUpdateAPI ); |
|
4563 if ( iCcpuSupport ) |
|
4564 { |
|
4565 iCcpuSupport->HandleSelectionChangeL(); |
|
4566 } |
|
4567 } |
|
4568 if (IsReadyToDraw()) |
|
4569 { |
|
4570 UpdateScrollBarsL(); |
|
4571 } |
|
4572 |
|
4573 User::LeaveIfError(err); |
|
4574 } |
|
4575 |
|
4576 EXPORT_C TCursorSelection CEikEdwin::Selection() const |
|
4577 { |
|
4578 if ( iEdwinExtension->iDrawInvoked == CEikEdwinExtension::ENotDraw && |
|
4579 iEdwinExtension->iTempCursorPos != KErrNotFound && |
|
4580 iEdwinExtension->iTempAnchorPos != KErrNotFound ) |
|
4581 { |
|
4582 return TCursorSelection( iEdwinExtension->iTempCursorPos, |
|
4583 iEdwinExtension->iTempAnchorPos ); |
|
4584 } |
|
4585 if (iTextView) |
|
4586 return(iTextView->Selection()); |
|
4587 return TCursorSelection(0,0); |
|
4588 } |
|
4589 |
|
4590 EXPORT_C TInt CEikEdwin::CountWords() |
|
4591 { |
|
4592 __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText)); |
|
4593 return(iText->WordCount()); |
|
4594 } |
|
4595 |
|
4596 EXPORT_C void CEikEdwin::SetAllowUndo(TBool aAllow) |
|
4597 { |
|
4598 if (aAllow) |
|
4599 iEdwinUserFlags|=EAllowUndo; |
|
4600 else |
|
4601 iEdwinUserFlags&=~EAllowUndo; |
|
4602 } |
|
4603 |
|
4604 EXPORT_C TBool CEikEdwin::SupportsUndo() const |
|
4605 { |
|
4606 return iEdwinUserFlags&EAllowUndo; |
|
4607 } |
|
4608 |
|
4609 EXPORT_C TBool CEikEdwin::CanUndo() const |
|
4610 { |
|
4611 return (iUndoStore!=NULL); |
|
4612 } |
|
4613 |
|
4614 EXPORT_C void CEikEdwin::UndoL() |
|
4615 { |
|
4616 CancelFepTransaction(); |
|
4617 if (!SupportsUndo()) |
|
4618 return; |
|
4619 if (!iUndoStore) |
|
4620 iEikonEnv->InfoMsg(R_EIK_TBUF_NOTHING_TO_UNDO); |
|
4621 else |
|
4622 { |
|
4623 TBool changed=EFalse; |
|
4624 TCursorSelection newText=iUndoStore->NewText(); |
|
4625 const TInt oldLength=TextLength(); |
|
4626 if (newText.Length()) |
|
4627 DeleteL(changed,newText,EFalse,EFalse); |
|
4628 const TInt lower=newText.LowerPos(); |
|
4629 TInt undoneLength=0; |
|
4630 TRAPD(err,undoneLength=iText->PasteFromStoreL(iUndoStore->Store(),iUndoStore->Dictionary(),lower)) |
|
4631 const TInt cursorPos=iUndoStore->OldCursorPos(); |
|
4632 iTextView->SetPendingSelection(TCursorSelection(cursorPos,cursorPos)); |
|
4633 if ( iEdwinExtension->iSmiley ) |
|
4634 { |
|
4635 iEdwinExtension->iSmiley->HandleInsertL( lower, undoneLength ); |
|
4636 ConvertTextForSmileyL( TCursorSelection( lower, undoneLength ), ETrue ); |
|
4637 } |
|
4638 TRAPD(err2,iTextView->HandleInsertDeleteL(TCursorSelection(lower,lower+undoneLength),newText.Length(),changed)); |
|
4639 ClearUndo(); |
|
4640 if (NeedToChangeFormattingModeL()) |
|
4641 SetAmountToFormatL(); |
|
4642 ForceScrollBarUpdateL(); |
|
4643 User::LeaveIfError(err); |
|
4644 User::LeaveIfError(err2); |
|
4645 ReportEdwinEventL( MEikEdwinObserver::EEventTextUpdate ); |
|
4646 DoReportEventL( MCoeControlObserver::EEventStateChanged ); |
|
4647 } |
|
4648 } |
|
4649 |
|
4650 EXPORT_C void CEikEdwin::ClearUndo() |
|
4651 { |
|
4652 delete iUndoStore; |
|
4653 iUndoStore=NULL; |
|
4654 } |
|
4655 |
|
4656 /** |
|
4657 * @internal |
|
4658 */ |
|
4659 EXPORT_C TBool CEikEdwin::SetUndoBufferL(const TCursorSelection& aSelection) |
|
4660 { |
|
4661 if (iEdwinUserFlags&EAllowUndo) |
|
4662 { |
|
4663 TRAPD(err,DoSetUndoBufferL(aSelection)); |
|
4664 if (err!=KErrNone && iUndoStore!=NULL) |
|
4665 ClearUndo(); |
|
4666 if (err==KErrNoMemory) |
|
4667 return iEikonEnv->QueryWinL(R_EIK_TBUF_CANNOT_UNDO_CONFIRM_1,R_EIK_TBUF_CANNOT_UNDO_CONFIRM_2); |
|
4668 User::LeaveIfError(err); |
|
4669 } |
|
4670 return ETrue; |
|
4671 } |
|
4672 |
|
4673 void CEikEdwin::DoSetUndoBufferL(const TCursorSelection& aSelection) |
|
4674 { |
|
4675 if (iUndoStore) |
|
4676 ClearUndo(); |
|
4677 iUndoStore=CUndoBuffer::NewL(); |
|
4678 iText->CopyToStoreL(iUndoStore->Store(),iUndoStore->Dictionary(),aSelection.LowerPos(),aSelection.Length()); |
|
4679 const TInt lowerPos=aSelection.LowerPos(); |
|
4680 iUndoStore->SetNewText(TCursorSelection(lowerPos,lowerPos)); |
|
4681 iUndoStore->SetOldCursorPos(aSelection.iCursorPos); |
|
4682 } |
|
4683 |
|
4684 /** |
|
4685 * @internal |
|
4686 */ |
|
4687 EXPORT_C void CEikEdwin::SetUndoableText(const TCursorSelection& aSelection) |
|
4688 { |
|
4689 iUndoStore->SetNewText(aSelection); |
|
4690 } |
|
4691 |
|
4692 |
|
4693 CAknEdwinState* CEikEdwin::EditorState() const |
|
4694 { |
|
4695 if (iEdwinFepSupport) |
|
4696 return static_cast<CAknEdwinState*>(iEdwinFepSupport->State(KNullUid)); |
|
4697 else |
|
4698 return NULL; |
|
4699 } |
|
4700 |
|
4701 EXPORT_C void CEikEdwin::InsertFromTextFileL(const TFileName& aFileName,const CPlainText::TTextOrganisation aTextOrganisation) |
|
4702 { |
|
4703 __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText)); |
|
4704 CancelFepTransaction(); |
|
4705 const TInt oldLength = iText->DocumentLength(); |
|
4706 const TInt cursorPos=CursorPos(); |
|
4707 iEikonEnv->BusyMsgL(R_EIK_TBUF_IMPORTING,500000); // after 0.5 seconds |
|
4708 iText->ImportTextFileL(cursorPos,aFileName,aTextOrganisation); |
|
4709 TInt insertLength( iText->DocumentLength() - oldLength ); |
|
4710 CheckValidityOfChars( oldLength, insertLength ); |
|
4711 if ( iEdwinExtension->iSmiley ) |
|
4712 { |
|
4713 iEdwinExtension->iSmiley->HandleInsertL( cursorPos, insertLength ); |
|
4714 ConvertTextForSmileyL( TCursorSelection( cursorPos, |
|
4715 cursorPos + insertLength ), ETrue ); |
|
4716 } |
|
4717 const TInt newLength=iText->DocumentLength(); |
|
4718 const TInt newCursorPos=cursorPos+newLength-oldLength; |
|
4719 iTextView->SetPendingSelection(TCursorSelection(newCursorPos,newCursorPos)); |
|
4720 if (NeedToChangeFormattingModeL()) |
|
4721 SetAmountToFormatL(); |
|
4722 else |
|
4723 iTextView->HandleInsertDeleteL(TCursorSelection(newCursorPos,cursorPos),0,ETrue); |
|
4724 DrawContents(); |
|
4725 UpdateScrollBarsL(); |
|
4726 ReportEdwinEventL( MEikEdwinObserver::EEventTextUpdate ); |
|
4727 DoReportEventL( MCoeControlObserver::EEventStateChanged ); |
|
4728 iEikonEnv->BusyMsgCancel(); |
|
4729 } |
|
4730 |
|
4731 EXPORT_C void CEikEdwin::ClipboardL(TClipboardFunc aClipboardFunc) |
|
4732 { |
|
4733 __ASSERT_DEBUG(iTextView,Panic(EEikPanicEdwinNoView)); |
|
4734 |
|
4735 TInt prevEndPosition( 0 ); |
|
4736 if ( KineticScrollingEnabled() ) |
|
4737 { |
|
4738 prevEndPosition = |
|
4739 iLayout->PixelsAboveBand() + AdjustedViewRect().Height(); |
|
4740 } |
|
4741 |
|
4742 TBool commitInline( aClipboardFunc == EPaste ); |
|
4743 TCursorSelection selection( 0, 0 ); |
|
4744 CAknEdwinState* state( EditorState() ); |
|
4745 if ( !commitInline && aClipboardFunc == ECut ) |
|
4746 { |
|
4747 selection = iTextView->Selection(); |
|
4748 TInt startOfInline( iEdwinFepSupport->iPositionOfInlineTextInDocument ); |
|
4749 TInt endOfInline( iEdwinFepSupport->iPositionOfInlineTextInDocument + |
|
4750 iEdwinFepSupport->iLengthOfInlineText ); |
|
4751 if ( iEdwinFepSupport->iLengthOfInlineText < 0 ) |
|
4752 { |
|
4753 if ( state && state->CurrentInlineEditSpan().Length() > 0 ) |
|
4754 { |
|
4755 startOfInline = state->CurrentInlineEditSpan().LowerPos(); |
|
4756 endOfInline = state->CurrentInlineEditSpan().HigherPos(); |
|
4757 } |
|
4758 } |
|
4759 commitInline = ( selection.LowerPos() < endOfInline && |
|
4760 selection.HigherPos() > startOfInline ); |
|
4761 } |
|
4762 if ( commitInline ) |
|
4763 { |
|
4764 if ( iEdwinFepSupport->iLengthOfInlineText > 0 ) |
|
4765 { |
|
4766 iEdwinFepSupport->DoCommitFepInlineEditL(); |
|
4767 SetCursorVisibilityL( ETrue ); |
|
4768 } |
|
4769 if ( state && state->CurrentInlineEditSpan().Length() > 0 ) |
|
4770 { |
|
4771 state->SetInlineEditSpan( TCursorSelection( 0, 0 ) ); |
|
4772 } |
|
4773 } |
|
4774 CancelFepTransaction(); |
|
4775 TBool reportChange=EFalse; |
|
4776 switch (aClipboardFunc) |
|
4777 { |
|
4778 case ECut: |
|
4779 case ECopy: |
|
4780 { |
|
4781 TCursorSelection selection=iTextView->Selection(); |
|
4782 const TInt selLength=SelectionLength(); |
|
4783 if (!selLength) |
|
4784 iEikonEnv->InfoMsg(aClipboardFunc==ECut? R_EIK_TBUF_NOTHING_TO_CUT: R_EIK_TBUF_NOTHING_TO_COPY); |
|
4785 else |
|
4786 { |
|
4787 PlaceDataOnClipboardL(); |
|
4788 if (aClipboardFunc==ECopy) |
|
4789 { |
|
4790 iEikonEnv->InfoMsg(R_EIK_TBUF_COPIED); |
|
4791 if (iCcpuSupport) |
|
4792 iCcpuSupport->HandleSelectionChangeL(); |
|
4793 } |
|
4794 else |
|
4795 { |
|
4796 TBool formatHasChanged; |
|
4797 DeleteHighlightL(formatHasChanged,EFalse,EFalse); |
|
4798 const TInt lower=selection.LowerPos(); |
|
4799 const TCursorSelection pending(lower,lower); |
|
4800 iTextView->SetPendingSelection(pending); |
|
4801 selection.iAnchorPos=lower; |
|
4802 selection.iCursorPos=lower; |
|
4803 iTextView->HandleInsertDeleteL(selection,selLength,formatHasChanged); |
|
4804 reportChange=ETrue; |
|
4805 } |
|
4806 CAknNoteDialog* dlg = new (ELeave) CAknNoteDialog(); |
|
4807 dlg->SetTimeout( CAknNoteDialog::EShortTimeout ); |
|
4808 dlg->SetTone( CAknNoteDialog::ENoTone ); |
|
4809 dlg->ExecuteLD( R_AVKON_NOTE_CONF_COPIED ); |
|
4810 } |
|
4811 break; |
|
4812 } |
|
4813 case EPaste: |
|
4814 RetrieveDataFromClipboardL(); |
|
4815 reportChange=ETrue; |
|
4816 break; |
|
4817 default: |
|
4818 #if defined(_DEBUG) |
|
4819 Panic(EEikPanicEdwinBadClipboardFunc); |
|
4820 #endif |
|
4821 break; |
|
4822 } |
|
4823 |
|
4824 if ( KineticScrollingEnabled() ) |
|
4825 { |
|
4826 // If we have deleted some text and previous position (before delete) is |
|
4827 // out of current editor content, we must move back to inside content. |
|
4828 TInt formattedHeight( iLayout->FormattedHeightInPixels() ); |
|
4829 if ( prevEndPosition > formattedHeight ) |
|
4830 { |
|
4831 TInt movement( prevEndPosition - formattedHeight ); |
|
4832 iEdwinExtension->iPhysicsHandler->MoveScrollIndex( movement ); |
|
4833 } |
|
4834 } |
|
4835 |
|
4836 if (reportChange) |
|
4837 { |
|
4838 ReportEdwinEventL( MEikEdwinObserver::EEventTextUpdate ); |
|
4839 DoReportEventL( MCoeControlObserver::EEventStateChanged ); |
|
4840 NotifyEditorStateObserverOfStateChangeL(); |
|
4841 UpdateScrollBarsL(); |
|
4842 } |
|
4843 } |
|
4844 |
|
4845 EXPORT_C void CEikEdwin::PlaceDataOnClipboardL() |
|
4846 { |
|
4847 __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText)); |
|
4848 CancelFepTransaction(); |
|
4849 CClipboard* cb=CClipboard::NewForWritingLC(iCoeEnv->FsSession()); |
|
4850 CopyToStoreL(cb->Store(),cb->StreamDictionary()); |
|
4851 cb->CommitL(); |
|
4852 CleanupStack::PopAndDestroy(); |
|
4853 } |
|
4854 |
|
4855 void CEikEdwin::RetrieveDataFromClipboardL() |
|
4856 { |
|
4857 CancelFepTransaction(); |
|
4858 CClipboard* cb=NULL; |
|
4859 TRAPD(err,cb=CClipboard::NewForReadingL(iCoeEnv->FsSession())); |
|
4860 CleanupStack::PushL(cb); |
|
4861 if (err==KErrPathNotFound || err==KErrNotFound) |
|
4862 iEikonEnv->LeaveWithInfoMsg(R_EIK_TBUF_NOTHING_TO_PASTE); |
|
4863 User::LeaveIfError(err); |
|
4864 PasteFromStoreL(cb->Store(), cb->StreamDictionary()); |
|
4865 CleanupStack::PopAndDestroy(); // cb |
|
4866 } |
|
4867 |
|
4868 EXPORT_C void CEikEdwin::SendDataOverIrL() |
|
4869 { |
|
4870 __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText)); |
|
4871 iEikonEnv->IrFactory()->SendDataOverIrL(this); |
|
4872 } |
|
4873 |
|
4874 EXPORT_C void CEikEdwin::ReceiveDataOverIrL() |
|
4875 { |
|
4876 iEikonEnv->IrFactory()->ReceiveDataOverIrL(this); |
|
4877 } |
|
4878 |
|
4879 EXPORT_C void CEikEdwin::CopyToStoreL(CStreamStore& aStore,CStreamDictionary& aDict) |
|
4880 { |
|
4881 CancelFepTransaction(); |
|
4882 TCursorSelection selection=Selection(); |
|
4883 CPlainText* text( iText ); |
|
4884 TInt start( selection.LowerPos() ); |
|
4885 HBufC* buf( NULL ); |
|
4886 if ( iEdwinExtension->iSmiley ) |
|
4887 { |
|
4888 buf = ExtractTextLC( selection ); |
|
4889 text = CPlainText::NewL(); |
|
4890 CleanupStack::PushL( text ); |
|
4891 TPtr ptr( buf->Des() ); |
|
4892 iEdwinExtension->iSmiley->ConvertTextForSmileyL( selection.LowerPos(), |
|
4893 ptr, EFalse ); |
|
4894 start = 0; |
|
4895 text->InsertL( start, *buf ); |
|
4896 } |
|
4897 text->CopyToStoreL(aStore, aDict, start, selection.Length() ); |
|
4898 if ( iEdwinExtension->iSmiley ) |
|
4899 { |
|
4900 CleanupStack::PopAndDestroy( text ); |
|
4901 CleanupStack::PopAndDestroy( buf ); |
|
4902 } |
|
4903 } |
|
4904 |
|
4905 EXPORT_C void CEikEdwin::PasteFromStoreL(CStreamStore& aStore,CStreamDictionary& aDict) |
|
4906 { |
|
4907 CancelFepTransaction(); |
|
4908 TStreamId streamId=aDict.At(KClipboardUidTypeRichText); |
|
4909 if (streamId==KNullStreamId) |
|
4910 streamId=aDict.At(KClipboardUidTypePlainText); |
|
4911 TInt nothingResId=(iEdwinInternalFlags&EPasteFromIrStore)? R_EIK_TBUF_UNSUITABLE_IR_TYPE : R_EIK_TBUF_NOTHING_TO_PASTE; |
|
4912 SetPasteFromIrStore(EFalse); // nothing to leave before this line |
|
4913 if (streamId==KNullStreamId) |
|
4914 iEikonEnv->LeaveWithInfoMsg(nothingResId); |
|
4915 iEikonEnv->BusyMsgL(R_EIK_TBUF_PASTING,500000); |
|
4916 TCursorSelection selection=iTextView->Selection(); |
|
4917 const TInt oldTextLength=TextLength(); |
|
4918 const TInt selLength=selection.Length(); |
|
4919 TBool formatHasChanged=EFalse; |
|
4920 if (selLength) |
|
4921 DeleteHighlightL(formatHasChanged); |
|
4922 else |
|
4923 ClearUndo(); |
|
4924 const TInt lengthBeforePaste=TextLength(); |
|
4925 TRAPD(err,DoPasteFromStoreL(aStore,aDict)); |
|
4926 TInt newLength=iText->DocumentLength(); |
|
4927 TInt pastedLength=newLength-lengthBeforePaste; |
|
4928 if (err!=KErrNone && pastedLength==0) |
|
4929 { |
|
4930 ClearUndo(); |
|
4931 User::Leave(err); |
|
4932 } |
|
4933 const TInt higher=selection.HigherPos()+newLength-oldTextLength; |
|
4934 iTextView->SetPendingSelection(TCursorSelection(higher,higher)); |
|
4935 selection.iAnchorPos=selection.LowerPos(); |
|
4936 selection.iCursorPos=selection.iAnchorPos+pastedLength; |
|
4937 if ( iEdwinExtension->iSmiley ) |
|
4938 { |
|
4939 iEdwinExtension->iSmiley->HandleInsertL( selection.LowerPos(), |
|
4940 selection.Length() ); |
|
4941 ConvertTextForSmileyL( selection, ETrue ); |
|
4942 } |
|
4943 if (iUndoStore) |
|
4944 iUndoStore->SetNewText(selection); |
|
4945 if ( NeedToChangeFormattingModeL()) |
|
4946 { |
|
4947 SetAmountToFormatL(); |
|
4948 DrawContents(); |
|
4949 } |
|
4950 else |
|
4951 iTextView->HandleInsertDeleteL(selection,selLength,formatHasChanged); |
|
4952 iEikonEnv->BusyMsgCancel(); |
|
4953 User::LeaveIfError(err); |
|
4954 } |
|
4955 |
|
4956 void CEikEdwin::DoPasteFromStoreL(const CStreamStore& aStore,const CStreamDictionary& aDict) |
|
4957 { |
|
4958 const TInt lengthBeforePaste=iText->DocumentLength(); |
|
4959 const TInt cursorPos=CursorPos(); |
|
4960 |
|
4961 TBool pasteAsPlainText = iEdwinUserFlags & CEikRichTextEditor::EPasteAsPlainText; |
|
4962 |
|
4963 CAknEdwinState* state = static_cast<CAknEdwinState*>( iEdwinFepSupport->State( KNullUid ) ); |
|
4964 if (state && state->PermittedInputModes() == EAknEditorNumericInputMode ) |
|
4965 { |
|
4966 TBool isDigit(ETrue); |
|
4967 CPlainText* txtStore = CPlainText::NewL(); |
|
4968 CleanupStack::PushL(txtStore); |
|
4969 TInt bufferLength = txtStore->PasteFromStoreL(aStore, aDict, 0); |
|
4970 |
|
4971 HBufC* txtStoreBuf = txtStore->Read(0).AllocL(); |
|
4972 CleanupStack::PushL( txtStoreBuf ); |
|
4973 TPtr text = txtStoreBuf->Des(); |
|
4974 TInt textLength = text.Length(); |
|
4975 |
|
4976 HBufC* allowedChars = GetAllowedCharsLC(); |
|
4977 for ( TInt ii = 0; ii < textLength; ii++ ) |
|
4978 { |
|
4979 TChar chr(text[ii]); |
|
4980 if ((*allowedChars).Locate(chr) == KErrNotFound && text[ii] != 0x2029) |
|
4981 { |
|
4982 isDigit = EFalse; |
|
4983 break; |
|
4984 } |
|
4985 } |
|
4986 CleanupStack::PopAndDestroy(3);//texStore, txtStoreBuf, allowedChars |
|
4987 |
|
4988 if (!isDigit) |
|
4989 return; |
|
4990 } |
|
4991 if ( (iEdwinInternalFlags & ERichText) && pasteAsPlainText ) |
|
4992 { |
|
4993 static_cast<CRichText*>(iText)->PasteFromStoreL( aStore, aDict, cursorPos, CParagraphStyle::EIgnoreNewStyles ); |
|
4994 } |
|
4995 else |
|
4996 { |
|
4997 iText->PasteFromStoreL(aStore,aDict,cursorPos); |
|
4998 } |
|
4999 |
|
5000 // Remove tabulators from text if found |
|
5001 TInt length = iText->DocumentLength(); |
|
5002 |
|
5003 TPtrC ptr= iText->Read(0); |
|
5004 TInt position = ptr.Mid(0).LocateReverse('\t'); |
|
5005 while (position != KErrNotFound ) |
|
5006 { |
|
5007 iText->DeleteL( position, 1 ); |
|
5008 position = ptr.Left(position).LocateReverse('\t'); |
|
5009 } |
|
5010 |
|
5011 TInt newLength=iText->DocumentLength(); |
|
5012 TInt pastedLength=newLength-lengthBeforePaste; |
|
5013 CheckRemovePictures(cursorPos,pastedLength); |
|
5014 const TInt tmp=iText->DocumentLength(); |
|
5015 if (tmp<newLength) |
|
5016 iEikonEnv->InfoMsg(R_EIK_TBUF_CANNOT_PASTE_OBJECTS); |
|
5017 CheckValidityOfChars(cursorPos,pastedLength); |
|
5018 newLength = iText->DocumentLength(); |
|
5019 pastedLength=newLength-lengthBeforePaste; |
|
5020 if ( iEdwinInternalFlags&EHasOneLineOnly || iEdwinUserFlags&ENoLineOrParaBreaks ) |
|
5021 { |
|
5022 ReplaceParaDelimitersL( cursorPos, pastedLength ); |
|
5023 newLength=iText->DocumentLength(); |
|
5024 pastedLength=newLength-lengthBeforePaste; |
|
5025 } |
|
5026 const TInt extraChars=newLength-iTextLimit; |
|
5027 if (iTextLimit && extraChars>0) |
|
5028 { |
|
5029 const TInt pos=cursorPos+pastedLength-extraChars; |
|
5030 DeleteExtraParasL(pos,extraChars); |
|
5031 const TInt length=iText->DocumentLength()-iTextLimit; |
|
5032 if (iEdwinInternalFlags&ERichText && length>0) |
|
5033 STATIC_CAST(CRichText*,iText)->DeleteFromParagraph(pos,length); |
|
5034 else |
|
5035 iText->DeleteL(pos,iText->DocumentLength()-iTextLimit); // won't leave |
|
5036 CEikonEnv::Beep(); |
|
5037 iEikonEnv->InfoMsg(R_EIK_TBUF_MAX_CHARACTERS_REACHED); |
|
5038 } |
|
5039 pastedLength=iText->DocumentLength()-lengthBeforePaste; |
|
5040 |
|
5041 // The CParagraphStyle::EIgnoreNewStyles doesn't remove italics, |
|
5042 // bold or underline. We'll try to hack it here. |
|
5043 if ( (iEdwinInternalFlags & ERichText) && pasteAsPlainText ) |
|
5044 { |
|
5045 TCharFormat charFormat; |
|
5046 TCharFormatMask charFormatMask; |
|
5047 |
|
5048 CRichText* text = static_cast<CRichText*>(iText); |
|
5049 text->CGlobalText::GetCharFormat( charFormat, charFormatMask, 0, 0 ); |
|
5050 charFormatMask.SetAll(); |
|
5051 text->ApplyCharFormatL( charFormat, charFormatMask, cursorPos, pastedLength ); |
|
5052 |
|
5053 // To make sure that no parts of the text are left formatted with |
|
5054 // something else than the globalcharformat. |
|
5055 text->RemoveSpecificCharFormatL( cursorPos, pastedLength ); |
|
5056 } |
|
5057 |
|
5058 HandleTextPastedL(cursorPos,pastedLength); |
|
5059 } |
|
5060 |
|
5061 void CEikEdwin::ReplaceParaDelimitersL( TInt aStartPos, TInt aLength ) |
|
5062 { |
|
5063 TPtrC ptr = iText->Read( aStartPos, aLength ); |
|
5064 TInt delimiter[2] = { 0 }; |
|
5065 _LIT( KSpace, " " ); |
|
5066 while( delimiter[0] >= 0 || delimiter[1] >= 0 ) |
|
5067 { |
|
5068 delimiter[0] = ptr.Locate( TChar(CEditableText::EParagraphDelimiter) ); |
|
5069 delimiter[1] = ptr.Locate( TChar(CEditableText::ELineBreak) ); |
|
5070 for( TInt i = 0; i < 2; i++ ) |
|
5071 { |
|
5072 if ( delimiter[i] >= 0 ) |
|
5073 { |
|
5074 iText->DeleteL( aStartPos + delimiter[i], 1 ); |
|
5075 iText->InsertL( aStartPos + delimiter[i], KSpace ); |
|
5076 } |
|
5077 } |
|
5078 } |
|
5079 } |
|
5080 |
|
5081 void CEikEdwin::DeleteExtraParasL(TInt aStartPos,TInt aLength) |
|
5082 { |
|
5083 TInt pos=aStartPos; |
|
5084 TInt charsRead=0; |
|
5085 const TBool pastedAtEnd=(aStartPos+aLength==iText->DocumentLength()); |
|
5086 while (charsRead<aLength) |
|
5087 { |
|
5088 TPtrC ptr=iText->Read(pos,Min(aLength-charsRead,10)); |
|
5089 const TInt paraDelimiter=ptr.Locate(TChar(CEditableText::EParagraphDelimiter)); |
|
5090 const TInt lineDelimiter=ptr.Locate(TChar(CEditableText::ELineBreak)); |
|
5091 if (!(iEdwinInternalFlags&ERichText)) |
|
5092 { |
|
5093 const TInt delimiter=(paraDelimiter==-1? lineDelimiter : (lineDelimiter==-1? |
|
5094 paraDelimiter : Min(lineDelimiter,paraDelimiter))); |
|
5095 if (delimiter!=-1) |
|
5096 { |
|
5097 iText->DeleteL(pos+delimiter,aLength-(charsRead+delimiter)); // won't leave |
|
5098 break; |
|
5099 } |
|
5100 } |
|
5101 else |
|
5102 { |
|
5103 if (paraDelimiter!=-1) |
|
5104 { |
|
5105 if (pastedAtEnd) |
|
5106 STATIC_CAST(CRichText*,iText)->DeleteParagraph(pos+paraDelimiter+1,aLength-(charsRead+paraDelimiter)); |
|
5107 else |
|
5108 { |
|
5109 TChar delimiter(CEditableText::EParagraphDelimiter); |
|
5110 TInt startPos=pos+paraDelimiter+1; |
|
5111 TInt length=aLength-(charsRead+paraDelimiter)-1; |
|
5112 TInt lastParaDelimiter=KErrNotFound; |
|
5113 TInt charPos=LocateChar(delimiter,startPos,length); |
|
5114 while (charPos!=KErrNotFound) |
|
5115 { |
|
5116 lastParaDelimiter=startPos+charPos; |
|
5117 startPos+=(charPos+1); |
|
5118 length-=(charPos+1); |
|
5119 charPos=LocateChar(delimiter,startPos,length); |
|
5120 } |
|
5121 TInt len=aLength-(startPos-aStartPos); |
|
5122 if (len>0) |
|
5123 STATIC_CAST(CRichText*,iText)->DeleteFromParagraph(startPos,len); |
|
5124 if (lastParaDelimiter!=KErrNotFound) |
|
5125 { |
|
5126 const TInt start=pos+paraDelimiter+1; |
|
5127 length=lastParaDelimiter-start+1; |
|
5128 STATIC_CAST(CRichText*,iText)->DeleteParagraph(start,length); |
|
5129 } |
|
5130 } |
|
5131 } |
|
5132 if (lineDelimiter!=-1 && (paraDelimiter==-1 || lineDelimiter<paraDelimiter)) |
|
5133 { |
|
5134 TInt length=aLength-(charsRead+lineDelimiter); |
|
5135 if (paraDelimiter!=-1) |
|
5136 length=paraDelimiter-lineDelimiter; |
|
5137 STATIC_CAST(CRichText*,iText)->DeleteFromParagraph(pos+lineDelimiter,length); |
|
5138 break; |
|
5139 } |
|
5140 if (paraDelimiter!=-1) |
|
5141 { |
|
5142 if (!pastedAtEnd) |
|
5143 iText->DeleteL(pos+paraDelimiter,1); |
|
5144 break; |
|
5145 } |
|
5146 } |
|
5147 const TInt ptrLen=ptr.Length(); |
|
5148 pos+=ptrLen; |
|
5149 charsRead+=ptrLen; |
|
5150 } |
|
5151 } |
|
5152 |
|
5153 TInt CEikEdwin::LocateChar(TChar aChar,TInt aStartPos,TInt aLength) |
|
5154 { |
|
5155 TInt pos=aStartPos; |
|
5156 TInt charsRead=0; |
|
5157 while (charsRead<aLength) |
|
5158 { |
|
5159 TPtrC ptr=iText->Read(pos,Min(aLength-charsRead,10)); |
|
5160 const TInt charPos=ptr.Locate(aChar); |
|
5161 if (charPos!=KErrNotFound) |
|
5162 return (charsRead+charPos); |
|
5163 const TInt ptrLen=ptr.Length(); |
|
5164 pos+=ptrLen; |
|
5165 charsRead+=ptrLen; |
|
5166 } |
|
5167 return KErrNotFound; |
|
5168 } |
|
5169 |
|
5170 EXPORT_C void CEikEdwin::SetPasteFromIrStore(TBool aPasteFromIrStore) |
|
5171 { |
|
5172 if (aPasteFromIrStore) |
|
5173 iEdwinInternalFlags|=EPasteFromIrStore; |
|
5174 else |
|
5175 iEdwinInternalFlags&=(~EPasteFromIrStore); |
|
5176 } |
|
5177 |
|
5178 EXPORT_C void CEikEdwin::HandleTextPastedL(TInt /*aStartPos*/,TInt& /*aLength*/) |
|
5179 { |
|
5180 } |
|
5181 |
|
5182 EXPORT_C void CEikEdwin::CancelFepTransaction() |
|
5183 { |
|
5184 CCoeFep* fep=iCoeEnv->Fep(); |
|
5185 if ( fep!=NULL ) |
|
5186 { |
|
5187 fep->CancelTransaction(); |
|
5188 } |
|
5189 } |
|
5190 |
|
5191 EXPORT_C void CEikEdwin::HandleTextChangedL() |
|
5192 { |
|
5193 ClearSelectionL(); // ?? maybe too late here!! |
|
5194 |
|
5195 // clear inline edit state info |
|
5196 if (iEdwinFepSupport) |
|
5197 STATIC_CAST(CAknEdwinState*, iEdwinFepSupport->State(KNullUid))->SetInlineEditSpan(TCursorSelection(0,0)); |
|
5198 |
|
5199 SetAmountToFormatL( ETrue ); |
|
5200 |
|
5201 if (IsReadyToDraw()) |
|
5202 { |
|
5203 DrawContents(); |
|
5204 UpdateScrollBarsL(); |
|
5205 } |
|
5206 } |
|
5207 |
|
5208 EXPORT_C void CEikEdwin::RunCharMapDialogL() |
|
5209 { |
|
5210 CancelFepTransaction(); |
|
5211 ASSERT(iEikonEnv->CDlgDialogFactory()); |
|
5212 iEikonEnv->CDlgDialogFactory()->RunCharMapDlgLD(this); |
|
5213 } |
|
5214 |
|
5215 EXPORT_C void CEikEdwin::ForceScrollBarUpdateL() |
|
5216 { |
|
5217 SetScrollBarsL(); |
|
5218 } |
|
5219 |
|
5220 EXPORT_C void CEikEdwin::UpdateScrollBarsL() |
|
5221 { |
|
5222 CheckEdwinExtensionL(); // checks if iEdwinExtension is non-NULL |
|
5223 |
|
5224 // Updating via CIdle is needed only if kinetic scrolling is not in use |
|
5225 if ( !KineticScrollingEnabled() ) |
|
5226 { |
|
5227 if ( !iEdwinExtension->ScrollBarSetter() && OwnsScrollBars() ) |
|
5228 { |
|
5229 iEdwinExtension->SetScrollBarSetter( CIdle::NewL( |
|
5230 CTextView::EFBackgroundFormattingPriority - 1 ) ); |
|
5231 } |
|
5232 if ( iEdwinExtension->ScrollBarSetter() |
|
5233 && !iEdwinExtension->ScrollBarSetter()->IsActive() ) |
|
5234 { |
|
5235 iEdwinExtension->ScrollBarSetter()->Start( TCallBack( |
|
5236 CEikEdwin::IdleL, this ) ); |
|
5237 } |
|
5238 } |
|
5239 else |
|
5240 { |
|
5241 SetScrollBarsL(); |
|
5242 } |
|
5243 } |
|
5244 |
|
5245 void CEikEdwin::UpdateHorizScrollBarThumb() |
|
5246 { |
|
5247 __ASSERT_DEBUG(iTextView,Panic(EEikPanicEdwinNoView)); |
|
5248 if (iSBFrame) |
|
5249 { |
|
5250 iSBFrame->MoveHorizThumbTo(iTextView->LeftTextMargin()); |
|
5251 } |
|
5252 } |
|
5253 |
|
5254 void CEikEdwin::UpdateVertScrollBarThumbL() |
|
5255 { |
|
5256 __ASSERT_DEBUG(iTextView,Panic(EEikPanicEdwinNoView)); |
|
5257 __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoLayout)); |
|
5258 if (iSBFrame) |
|
5259 { |
|
5260 if ( KineticScrollingEnabled() ) |
|
5261 { |
|
5262 if ( iEdwinExtension && iEdwinExtension->iScrolledByScrollBar ) |
|
5263 { |
|
5264 CEikScrollBar* sb = |
|
5265 iSBFrame-> CEikScrollBarFrame::VerticalScrollBar(); |
|
5266 iEdwinExtension->iScrollbarPosition = sb->ThumbPosition(); |
|
5267 return; |
|
5268 } |
|
5269 } |
|
5270 |
|
5271 CEikScrollBar* sb = iSBFrame-> CEikScrollBarFrame::VerticalScrollBar(); |
|
5272 TInt prevSBPos = sb->ThumbPosition(); |
|
5273 |
|
5274 TEikScrollBarModel vertModel; |
|
5275 SetVertScrollBarModelByCharactersL(vertModel); |
|
5276 if ( iSBFrame->TypeOfVScrollBar() == CEikScrollBarFrame::EDoubleSpan ) |
|
5277 { |
|
5278 TAknDoubleSpanScrollBarModel doubleModel( vertModel ); |
|
5279 sb->SetModel( &doubleModel ); |
|
5280 } |
|
5281 else |
|
5282 { |
|
5283 sb->SetModel( &vertModel ); |
|
5284 } |
|
5285 |
|
5286 TInt newSBPos = sb->ThumbPosition(); |
|
5287 TBool paintingEnabled = !(iEdwinUserFlags&EDisplayOnly) |
|
5288 && !(iEdwinUserFlags&EAvkonDisableCursor) |
|
5289 && iTextView->SelectionVisible(); |
|
5290 if (iEdwinFepSupport->iFeedback |
|
5291 && iEdwinFepSupport->iMoveThumbFeedbackNeeded |
|
5292 && (prevSBPos != newSBPos) |
|
5293 && !paintingEnabled) |
|
5294 { |
|
5295 iEdwinFepSupport->iFeedback->InstantFeedback( this, ETouchFeedbackSensitive ); |
|
5296 } |
|
5297 } |
|
5298 } |
|
5299 |
|
5300 EXPORT_C CEikScrollBarFrame* CEikEdwin::CreateScrollBarFrameL() |
|
5301 { |
|
5302 return CreateScrollBarFrameL(EFalse); |
|
5303 } |
|
5304 |
|
5305 EXPORT_C CEikScrollBarFrame* CEikEdwin::CreateScrollBarFrameL(TBool aPreAlloc) |
|
5306 { |
|
5307 if(!iSBFrame) |
|
5308 { |
|
5309 iSBFrame=new(ELeave) CEikScrollBarFrame(this, this, aPreAlloc, ETrue); |
|
5310 |
|
5311 // Check which type of scrollbar is to be shown |
|
5312 |
|
5313 if (AknLayoutUtils::DefaultScrollBarType(iAvkonAppUi) == CEikScrollBarFrame::EDoubleSpan) |
|
5314 { |
|
5315 iSBFrame->CreateDoubleSpanScrollBarsL(ETrue, EFalse); |
|
5316 } |
|
5317 } |
|
5318 return iSBFrame; |
|
5319 } |
|
5320 void CEikEdwin::CreateScrollBarFrameLayout(TEikScrollBarFrameLayout& aLayout) const |
|
5321 { |
|
5322 aLayout.iInclusiveMargin=iBorder.Margins(); |
|
5323 const TRect inner=iBorder.InnerRect(Rect()); |
|
5324 const TRect& viewRect=iTextView->ViewRect(); |
|
5325 aLayout.iClientMargin.iLeft=viewRect.iTl.iX-inner.iTl.iX; |
|
5326 aLayout.iClientMargin.iRight=inner.iBr.iX-viewRect.iBr.iX; |
|
5327 aLayout.iClientMargin.iTop=viewRect.iTl.iY-inner.iTl.iY; |
|
5328 aLayout.iClientMargin.iBottom=inner.iBr.iY-viewRect.iBr.iY; |
|
5329 aLayout.iTilingMode=TEikScrollBarFrameLayout::EInclusiveRectConstant; |
|
5330 } |
|
5331 |
|
5332 EXPORT_C TInt CEikEdwin::IdleL(TAny *anObj) |
|
5333 { |
|
5334 CEikEdwin* edwin = static_cast<CEikEdwin*>( anObj ); |
|
5335 if ( edwin && !edwin->KineticScrollingEnabled() ) |
|
5336 { |
|
5337 edwin->SetScrollBarsL(); |
|
5338 } |
|
5339 return EFalse; |
|
5340 } |
|
5341 |
|
5342 void CEikEdwin::SetScrollBarsL() |
|
5343 { |
|
5344 __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText)); |
|
5345 if (!iSBFrame) |
|
5346 return; |
|
5347 CheckEdwinExtensionL(); // checks if iEdwinExtension is non-NULL |
|
5348 |
|
5349 if ( KineticScrollingEnabled() ) |
|
5350 { |
|
5351 SetKineticScrollingScrollBarsL(); |
|
5352 return; |
|
5353 } |
|
5354 |
|
5355 if (iEdwinExtension->ScrollBarSetter() && iEdwinExtension->ScrollBarSetter()->IsActive()) |
|
5356 iEdwinExtension->ScrollBarSetter()->Cancel(); |
|
5357 TEikScrollBarModel hSbarModel(0,0,0); |
|
5358 TEikScrollBarModel vSbarModel(0,0,0); |
|
5359 TRect rect = AdjustedViewRect(); |
|
5360 |
|
5361 rect=iMargins.OuterRect(rect); |
|
5362 // Ignore scrollbars presence to set the model, Scrollbar Frame will change it as required |
|
5363 if (iSBFrame->VScrollBarVisibility()!=CEikScrollBarFrame::EOff) |
|
5364 { |
|
5365 SetVertScrollBarModelByCharactersL(vSbarModel); |
|
5366 // Examine the model to see how the "under one screen" flag is to be set: |
|
5367 if ( vSbarModel.iThumbSpan >= vSbarModel.iScrollSpan ) |
|
5368 { |
|
5369 iEdwinInternalFlags|=EUnderOneScreenFormattedText; |
|
5370 } |
|
5371 else |
|
5372 { |
|
5373 iEdwinInternalFlags&=~EUnderOneScreenFormattedText; |
|
5374 } |
|
5375 } |
|
5376 if (iSBFrame->ScrollBarVisibility(CEikScrollBar::EHorizontal)!=CEikScrollBarFrame::EOff) |
|
5377 { |
|
5378 if (iEdwinInternalFlags&EWysiwygOn) |
|
5379 { |
|
5380 hSbarModel.iScrollSpan=iZoomFactor->HorizontalTwipsToPixels(LayoutWidth()); |
|
5381 TInt labels=0, cursor=0; |
|
5382 iTextView->MarginWidths(labels,cursor); |
|
5383 hSbarModel.iScrollSpan+=labels+cursor+LineCursorWidth(); |
|
5384 } |
|
5385 else |
|
5386 hSbarModel.iScrollSpan=LayoutWidth(); |
|
5387 hSbarModel.iThumbSpan=rect.Width(); |
|
5388 hSbarModel.iThumbPosition=iTextView->LeftTextMargin(); |
|
5389 } |
|
5390 TRect inclusiveRect=Rect(); |
|
5391 TRect clientRect=rect; // claim client is as large as possible |
|
5392 TEikScrollBarFrameLayout layout; |
|
5393 CreateScrollBarFrameLayout(layout); |
|
5394 if (vSbarModel.iThumbSpan) |
|
5395 { |
|
5396 const TInt granularityHeight = AdjustedViewRect().Height()/vSbarModel.iThumbSpan; |
|
5397 if (granularityHeight) |
|
5398 layout.iClientAreaGranularity.iHeight=granularityHeight; |
|
5399 } |
|
5400 |
|
5401 TBool sizeChanged = EFalse; |
|
5402 if (iSBFrame && iSBFrame->TypeOfVScrollBar() == CEikScrollBarFrame::EDoubleSpan) |
|
5403 { |
|
5404 // For EDoubleSpan type scrollbar |
|
5405 TAknDoubleSpanScrollBarModel hDsSbarModel(hSbarModel); |
|
5406 TAknDoubleSpanScrollBarModel vDsSbarModel(vSbarModel); |
|
5407 |
|
5408 TRect inclusiveRectForDoubleSpan = Rect(); |
|
5409 TRect clientRectForDoubleSpan = Rect(); |
|
5410 TEikScrollBarFrameLayout layout; |
|
5411 layout.iTilingMode = TEikScrollBarFrameLayout::EClientRectConstant; |
|
5412 TInt focusPostion = 0; |
|
5413 if (!(iLayout->IsFormattingBand())) |
|
5414 { |
|
5415 TInt numLines = iLayout->NumFormattedLines(); |
|
5416 if (numLines > 1) |
|
5417 numLines--; |
|
5418 else |
|
5419 numLines = 1; |
|
5420 |
|
5421 TInt height = iLayout->FormattedHeightInPixels(); |
|
5422 TInt lineNo = 0; |
|
5423 lineNo = iLayout->FirstLineInBand(); |
|
5424 focusPostion = (height*lineNo)/numLines; |
|
5425 } |
|
5426 else |
|
5427 { |
|
5428 TEikScrollBarModel vertModel; |
|
5429 SetVertScrollBarModelByCharactersL(vertModel); |
|
5430 |
|
5431 focusPostion = vertModel.iThumbPosition; |
|
5432 } |
|
5433 |
|
5434 vDsSbarModel.SetFocusPosition(focusPostion); |
|
5435 iSBFrame->TileL(&hDsSbarModel, &vDsSbarModel, clientRectForDoubleSpan, inclusiveRectForDoubleSpan, layout); |
|
5436 } |
|
5437 else |
|
5438 { |
|
5439 // For EArrowHead type scrollbar |
|
5440 sizeChanged=iSBFrame->TileL(&hSbarModel, &vSbarModel, clientRect, inclusiveRect, layout); |
|
5441 } |
|
5442 |
|
5443 if (!OwnsScrollBars()) |
|
5444 { |
|
5445 delete iSBFrame; |
|
5446 iSBFrame=NULL; |
|
5447 } |
|
5448 UpdateVertScrollBarThumbL(); |
|
5449 if (!sizeChanged) |
|
5450 return; |
|
5451 // else size of client/inclusive rect has changed |
|
5452 if (layout.iTilingMode==TEikScrollBarFrameLayout::EClientRectConstant) |
|
5453 { |
|
5454 iSize=inclusiveRect.Size(); |
|
5455 DrawNow(); |
|
5456 } |
|
5457 else |
|
5458 { |
|
5459 clientRect=iMargins.InnerRect(clientRect); |
|
5460 iTextView->SetViewRect(clientRect); |
|
5461 if (!(iEdwinUserFlags&ENoWrap)) |
|
5462 iLayout->SetWrapWidth(LayoutWidth()); |
|
5463 TViewYPosQualifier yPosQualifier; |
|
5464 yPosQualifier.SetMakeLineFullyVisible(); |
|
5465 iTextView->HandleGlobalChangeNoRedrawL(yPosQualifier); |
|
5466 CWindowGc& gc=SystemGc(); |
|
5467 ActivateGc(); |
|
5468 gc.SetBrushColor(iEikonEnv->ControlColor(EColorControlBackground,*this)); |
|
5469 DrawUtils::ClearBetweenRects(gc,iBorder.InnerRect(Rect()),clientRect); |
|
5470 DeactivateGc(); |
|
5471 if (iEdwinInternalFlags&ELockScrollBarState) |
|
5472 { |
|
5473 iTextView->HandleGlobalChangeNoRedrawL(yPosQualifier); |
|
5474 CEikScrollBarFrame::TScrollBarVisibility vis=iSBFrame->VScrollBarVisibility(); |
|
5475 CEikScrollBarFrame::TScrollBarVisibility vVis=(vis==CEikScrollBarFrame::EAuto? CEikScrollBarFrame::EOn : vis); |
|
5476 vis=iSBFrame->ScrollBarVisibility(CEikScrollBar::EHorizontal); |
|
5477 CEikScrollBarFrame::TScrollBarVisibility hVis=(vis==CEikScrollBarFrame::EAuto? CEikScrollBarFrame::EOn : vis); |
|
5478 iSBFrame->SetScrollBarVisibilityL(hVis,vVis); |
|
5479 } |
|
5480 else |
|
5481 iEdwinInternalFlags|=ELockScrollBarState; |
|
5482 SetAmountToFormatL(); // will call SetScrollBarsL() again if need be |
|
5483 if (!iLayout->IsFormattingBand()) |
|
5484 SetScrollBarsL(); |
|
5485 iEdwinInternalFlags&=~ELockScrollBarState; |
|
5486 if (iEdwinInternalFlags&EWysiwygOn && iSBFrame->ScrollBarVisibility(CEikScrollBar::EHorizontal)==CEikScrollBarFrame::EAuto) |
|
5487 { |
|
5488 CEikScrollBar* hSBar=iSBFrame->GetScrollBarHandle(CEikScrollBar::EHorizontal); |
|
5489 if (!hSBar || !hSBar->IsVisible()) |
|
5490 iTextView->SetLeftTextMargin(0); |
|
5491 } |
|
5492 iTextView->DrawL(clientRect); |
|
5493 } |
|
5494 } |
|
5495 |
|
5496 void CEikEdwin::SetKineticScrollingScrollBarsL() |
|
5497 { |
|
5498 TEikScrollBarModel hSbarModel( 0, 0, 0 ); |
|
5499 TEikScrollBarModel vSbarModel( 0, 0, 0 ); |
|
5500 TRect rect( AdjustedViewRect() ); |
|
5501 |
|
5502 rect = iMargins.OuterRect( rect ); |
|
5503 // Ignore scrollbars presence to set the model, |
|
5504 // Scrollbar Frame will change it as required |
|
5505 if ( iSBFrame->VScrollBarVisibility() != CEikScrollBarFrame::EOff ) |
|
5506 { |
|
5507 if ( iLayout->IsFormattingBand() ) |
|
5508 { |
|
5509 SetVertScrollBarModelByCharactersL( vSbarModel ); |
|
5510 // Examine the model to see how the "under one screen" |
|
5511 // flag is to be set: |
|
5512 if ( vSbarModel.iThumbSpan >= vSbarModel.iScrollSpan ) |
|
5513 { |
|
5514 iEdwinInternalFlags |= EUnderOneScreenFormattedText; |
|
5515 } |
|
5516 else |
|
5517 { |
|
5518 iEdwinInternalFlags &= ~EUnderOneScreenFormattedText; |
|
5519 } |
|
5520 } |
|
5521 else |
|
5522 { |
|
5523 vSbarModel.iScrollSpan = iLayout->FormattedHeightInPixels(); |
|
5524 vSbarModel.iThumbSpan = AdjustedViewRect().Height(); |
|
5525 if ( vSbarModel.iScrollSpan < vSbarModel.iThumbSpan |
|
5526 && vSbarModel.iThumbPosition ) |
|
5527 { |
|
5528 vSbarModel.iScrollSpan = vSbarModel.iThumbSpan |
|
5529 + vSbarModel.iThumbPosition; |
|
5530 iEdwinInternalFlags |= EUnderOneScreenFormattedText; |
|
5531 } |
|
5532 else |
|
5533 { |
|
5534 iEdwinInternalFlags &= ~EUnderOneScreenFormattedText; |
|
5535 } |
|
5536 } |
|
5537 } |
|
5538 |
|
5539 if ( iSBFrame->ScrollBarVisibility( CEikScrollBar::EHorizontal ) |
|
5540 != CEikScrollBarFrame::EOff ) |
|
5541 { |
|
5542 if ( iEdwinInternalFlags & EWysiwygOn ) |
|
5543 { |
|
5544 hSbarModel.iScrollSpan = iZoomFactor->HorizontalTwipsToPixels( |
|
5545 LayoutWidth() ); |
|
5546 TInt labels = 0, cursor = 0; |
|
5547 iTextView->MarginWidths( labels, cursor ); |
|
5548 hSbarModel.iScrollSpan += labels + cursor + LineCursorWidth(); |
|
5549 } |
|
5550 else |
|
5551 { |
|
5552 hSbarModel.iScrollSpan = LayoutWidth(); |
|
5553 } |
|
5554 hSbarModel.iThumbSpan = rect.Width(); |
|
5555 hSbarModel.iThumbPosition = iTextView->LeftTextMargin(); |
|
5556 } |
|
5557 |
|
5558 TRect inclusiveRect( Rect() ); |
|
5559 TEikScrollBarFrameLayout layout; |
|
5560 CreateScrollBarFrameLayout( layout ); |
|
5561 |
|
5562 if ( vSbarModel.iThumbSpan ) |
|
5563 { |
|
5564 TInt granularityHeight = AdjustedViewRect().Height() |
|
5565 / vSbarModel.iThumbSpan; |
|
5566 if ( granularityHeight ) |
|
5567 layout.iClientAreaGranularity.iHeight = granularityHeight; |
|
5568 } |
|
5569 |
|
5570 // For EDoubleSpan type scrollbar |
|
5571 TAknDoubleSpanScrollBarModel hDsSbarModel( hSbarModel ); |
|
5572 TAknDoubleSpanScrollBarModel vDsSbarModel( vSbarModel ); |
|
5573 |
|
5574 TRect inclusiveRectForDoubleSpan( Rect() ); |
|
5575 TRect clientRectForDoubleSpan ( Rect() ); |
|
5576 |
|
5577 TEikScrollBarFrameLayout layout2; |
|
5578 layout2.iTilingMode = TEikScrollBarFrameLayout::EClientRectConstant; |
|
5579 |
|
5580 TInt focusPosition = 0; |
|
5581 if ( !( iLayout->IsFormattingBand() ) ) |
|
5582 { |
|
5583 TInt numLines = iLayout->NumFormattedLines(); |
|
5584 if ( numLines > 1 ) |
|
5585 { |
|
5586 numLines--; |
|
5587 } |
|
5588 else |
|
5589 { |
|
5590 numLines = 1; |
|
5591 } |
|
5592 |
|
5593 TInt height = iLayout->FormattedHeightInPixels(); |
|
5594 TInt lineNo = 0; |
|
5595 lineNo = iLayout->FirstLineInBand(); |
|
5596 focusPosition = ( height * lineNo ) / numLines; |
|
5597 } |
|
5598 else |
|
5599 { |
|
5600 TEikScrollBarModel vertModel; |
|
5601 SetVertScrollBarModelByCharactersL( vertModel ); |
|
5602 |
|
5603 focusPosition = vertModel.iThumbPosition; |
|
5604 } |
|
5605 |
|
5606 vDsSbarModel.SetFocusPosition( focusPosition ); |
|
5607 iSBFrame->TileL( &hDsSbarModel, &vDsSbarModel, clientRectForDoubleSpan, |
|
5608 inclusiveRectForDoubleSpan, layout2 ); |
|
5609 |
|
5610 if ( !OwnsScrollBars() ) |
|
5611 { |
|
5612 delete iSBFrame; |
|
5613 iSBFrame = NULL; |
|
5614 } |
|
5615 UpdateVertScrollBarThumbL(); |
|
5616 } |
|
5617 |
|
5618 void CEikEdwin::SetVertScrollBarModelByCharactersL(TEikScrollBarModel& aVertModel) const |
|
5619 { |
|
5620 __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText)); |
|
5621 __ASSERT_DEBUG(iLayout,Panic(EEikPanicEdwinNoLayout)); |
|
5622 |
|
5623 if ( KineticScrollingEnabled() ) |
|
5624 { |
|
5625 SetKineticScrollingScrollBarModel( aVertModel ); |
|
5626 return; |
|
5627 } |
|
5628 |
|
5629 TRect viewRect( AdjustedViewRect() ); |
|
5630 const TInt formattedLines = Max(1, iLayout->NumFormattedLines()); |
|
5631 const TInt formattedHeight = iLayout->FormattedHeightInPixels(); |
|
5632 const TInt viewRectHeight = viewRect.Height(); |
|
5633 const TInt totalChars = iText->DocumentLength(); |
|
5634 const TInt formattedLength = Min( totalChars, iLayout->FormattedLength() ); |
|
5635 const TInt topLeftDocPos=iLayout->FirstDocPosFullyInBand(); |
|
5636 const TInt avgCharsPerLine = iAvgCharsPerLine ? iAvgCharsPerLine : |
|
5637 Max( 1, formattedLength / formattedLines ); |
|
5638 const TInt avgLineHeight = formattedHeight/formattedLines; |
|
5639 TInt posRange( 0 ); |
|
5640 TInt topPos( iTextView->XyPosToDocPosL( viewRect.iTl ) ); |
|
5641 TInt bottomPos( iTextView->XyPosToDocPosL( viewRect.iBr ) ); |
|
5642 if( AknLayoutUtils::PenEnabled() ) |
|
5643 { |
|
5644 if ( !iLayout->IsFormattingBand() ) |
|
5645 { |
|
5646 aVertModel.iThumbSpan = viewRectHeight; |
|
5647 aVertModel.iScrollSpan = formattedHeight; |
|
5648 aVertModel.iThumbPosition = iEdwinExtension->iThumbPos; |
|
5649 if ( aVertModel.iThumbPosition == KErrNotFound ) |
|
5650 { |
|
5651 if ( bottomPos == totalChars ) |
|
5652 { |
|
5653 aVertModel.iThumbPosition = aVertModel.iScrollSpan - |
|
5654 aVertModel.iThumbSpan; |
|
5655 TPoint bottomPoint(0,0); |
|
5656 iTextView->DocPosToXyPosL(bottomPos,bottomPoint); |
|
5657 if ( topPos == 0 && bottomPoint.iY == viewRect.iBr.iY ) |
|
5658 { |
|
5659 aVertModel.iThumbPosition = 0; |
|
5660 TInt gapFhAndVh = formattedHeight-viewRectHeight; |
|
5661 if (gapFhAndVh < avgLineHeight/2) |
|
5662 { |
|
5663 aVertModel.iThumbSpan = viewRectHeight; |
|
5664 aVertModel.iScrollSpan = viewRectHeight; |
|
5665 } |
|
5666 } |
|
5667 } |
|
5668 else |
|
5669 { |
|
5670 TInt topLine( iLayout->GetLineNumber( topPos ) ); |
|
5671 aVertModel.iThumbPosition = topLine * formattedHeight / |
|
5672 formattedLines; |
|
5673 } |
|
5674 } |
|
5675 } |
|
5676 else |
|
5677 { |
|
5678 aVertModel.iThumbSpan = bottomPos - topPos; |
|
5679 aVertModel.iScrollSpan = totalChars; |
|
5680 aVertModel.iThumbPosition = topPos; |
|
5681 } |
|
5682 return; |
|
5683 } |
|
5684 else |
|
5685 { |
|
5686 // - units for all elements of the model are numbers of characters, not pixels. |
|
5687 // - character positions refer to the VISIBLE band (not the total formatted text), |
|
5688 // - scrollspan is the total no. of characters, not pixels, to avoid "bounce" on the |
|
5689 // fractional position (this is because thumb info is sent separately from the whole model at times) |
|
5690 // - take advantage of form APIs as well as we can |
|
5691 aVertModel.iScrollSpan = Max(1,totalChars); |
|
5692 TInt docPos; |
|
5693 posRange = iLayout->PosRangeInBand( docPos ); // gives number of characters in visible range |
|
5694 } |
|
5695 |
|
5696 if (iSBFrame && iSBFrame->TypeOfVScrollBar() == CEikScrollBarFrame::EDoubleSpan) |
|
5697 { |
|
5698 // For EDoubleSpan type scrollbar |
|
5699 // Normally, the thumbspan is just the size of the range of visible characters, and the top of the thumb is |
|
5700 // index of first character in the view. |
|
5701 aVertModel.iThumbSpan = Max(1,posRange); |
|
5702 aVertModel.iThumbPosition = topLeftDocPos; // Simply the top left character |
|
5703 |
|
5704 // A situation can arise when cursor is near the end of text, and the user is deleting. This can leave empty lines. |
|
5705 // Thumbspan must try to measure the whole view - even if there are no characters in some of it. |
|
5706 // (Note that this problem does not arise when there is very little text in the document and the screen is only half |
|
5707 // full. In that case thumb and scroll span are equal.) |
|
5708 // The approach is to invent ficticious characters. Estimate how many characters there would be if the text were as dense |
|
5709 // as the average formatted line. |
|
5710 // It is biased against by a factor, so that it does not trigger unless we are in the above situation. |
|
5711 #define KSparseCharactersNumerator 8 |
|
5712 #define KSparseCharactersDenominator 10 |
|
5713 // Note deliberate ordering of multiplies and divides to avoid chance of overflow |
|
5714 TInt estimatedCharsToFillVisibleArea = |
|
5715 ( KSparseCharactersNumerator * viewRectHeight / KSparseCharactersDenominator * formattedLength ) |
|
5716 / Max(1,formattedHeight); |
|
5717 TInt excessChars = estimatedCharsToFillVisibleArea - posRange; |
|
5718 if ( excessChars > 0 && (posRange < totalChars/2 ) ) // Additional cond. that most of text is not showing |
|
5719 { |
|
5720 aVertModel.iThumbSpan += excessChars; |
|
5721 // Also have to increase the span, as these ficticious characters are (sort of) included in the whole document. |
|
5722 aVertModel.iScrollSpan += excessChars; |
|
5723 } |
|
5724 } |
|
5725 else |
|
5726 { |
|
5727 // For scroll-indicator functionality (EArrowHead) |
|
5728 // - quantize thumb position according to a "line model" to avoid changing values each time the cursor |
|
5729 // moves 1 character. |
|
5730 // Divide the visible band into a number of lines to get a "line" quantized value. |
|
5731 // (This leads to less drawing of the arrowheads, or at least stops that notification earlier) |
|
5732 // Number of lines is calculated with approximation that the last line is half filled. |
|
5733 // This is chosen because the correct behaviour is most important when at the (top line is usually filled) |
|
5734 // and at the bottom (Sometimes full, sometimes just one character). |
|
5735 const TInt nLines = ( posRange - avgCharsPerLine/2 ) / avgCharsPerLine + 1; |
|
5736 const TInt currentPos = CursorPos(); |
|
5737 const TInt line = Max(0,currentPos - topLeftDocPos) / avgCharsPerLine; // zero-based line number; bigger because of rounding down above. |
|
5738 if ( line >= (nLines - 1) ) // last line or too high because of rounding? |
|
5739 { |
|
5740 aVertModel.iThumbPosition = topLeftDocPos + posRange - 1; //Clamp to max value |
|
5741 } |
|
5742 else |
|
5743 { |
|
5744 aVertModel.iThumbPosition = topLeftDocPos + line * avgCharsPerLine; |
|
5745 } |
|
5746 // Although arrowhead implementations probably ignore the thumb span, just ensure its bottom end does not go below |
|
5747 // the scrollspan. |
|
5748 aVertModel.iThumbSpan = Min( aVertModel.iThumbSpan, aVertModel.iScrollSpan - aVertModel.iThumbPosition ); |
|
5749 } |
|
5750 } |
|
5751 |
|
5752 void CEikEdwin::SetKineticScrollingScrollBarModel( |
|
5753 TEikScrollBarModel& aVertModel ) const |
|
5754 { |
|
5755 // This function is related to Rate scrolling implementation. |
|
5756 // |
|
5757 // When kinetic scrolling is not enabled, original way |
|
5758 // (named here as Position Scrolling) is used. When kinetic |
|
5759 // scrolling is enabled, new way (named here as Rate Scrolling) is used. |
|
5760 // |
|
5761 // In Position Scrolling there is always a one-to-one mapping relationship |
|
5762 // of position between text view and scrollbar. When you scroll one of |
|
5763 // them, the other one will always be moved to follow the new position of |
|
5764 // its friend. |
|
5765 // |
|
5766 // But there is one issue, the height of the whole document is not accurate |
|
5767 // but a approximate value according to current band |
|
5768 // (Band: current formatted text area, including current shown view and |
|
5769 // some text leading and following it). So the mapping is somehow |
|
5770 // irregular, that when you scroll the view regularly, the scrollbar will |
|
5771 // change its position not regularly. |
|
5772 // |
|
5773 // When you move text view from Pos1 to Pos2, the scrollbar will be moved |
|
5774 // from Pos3 to Pos4, and here the Pos4 is only related to Pos2. |
|
5775 // |
|
5776 // |
|
5777 // Rate Scrolling is designed to make regular scrolling for both text view |
|
5778 // and scrollbar. The “regular?here is not absolutely regular but more |
|
5779 // regular than before, or regular to end users. It is also impacted by |
|
5780 // the Band area changing, but the impact is much smaller than before. |
|
5781 // |
|
5782 // When you move text view from Pos1 to Pos2, the scrollbar will be moved |
|
5783 // from Pos3 to Pos4. Here the Pos4 is related to all Pos1, Pos2 and Pos3. |
|
5784 // The relationship between them is the Rate. |
|
5785 // |
|
5786 // The Rate means how many percentage it has moved to the end boundary. |
|
5787 // If you move downwards, expected whole text view height is H, remaining |
|
5788 // way to the end boundary is (H - Pos1), the Percentage you have moved is |
|
5789 // offset/(H - Pos1) = (Pos2 - Pos1)/(H - Pos1) |
|
5790 // |
|
5791 // So the scrollbar should also move for the same percentage of the |
|
5792 // remaining way. |
|
5793 // |
|
5794 // This moving behavior is more regular than before, and the visible result |
|
5795 // proves it. |
|
5796 // |
|
5797 // With this way, It can be proved that when text view is scrolled to the |
|
5798 // end, the scrollbar will also be in the end, and vice versa. |
|
5799 // |
|
5800 // In Rate scrolling way, scrollbar will have different position values |
|
5801 // if you scroll text view same to X but from different starting position. |
|
5802 |
|
5803 TInt formattedLines = Max( 1, iLayout->NumFormattedLines() ); |
|
5804 TInt formattedHeight = iLayout->FormattedHeightInPixels(); |
|
5805 TInt viewRectHeight = AdjustedViewRect().Height(); |
|
5806 TInt totalChars = iText->DocumentLength(); |
|
5807 TInt formattedLength = iLayout->FormattedLength(); |
|
5808 TInt topLeftDocPos = iLayout->FirstDocPosFullyInBand(); |
|
5809 TInt avgCharsPerLine = Max( 1, formattedLength / formattedLines ); |
|
5810 |
|
5811 TInt formattedHeightAboveView = iLayout->PixelsAboveBand(); |
|
5812 TInt formattedHeightBelowView = formattedHeight - viewRectHeight |
|
5813 - formattedHeightAboveView; |
|
5814 |
|
5815 TInt anchorThumbPos = 0; |
|
5816 TInt avgLineHeight = 0; |
|
5817 |
|
5818 // Approximate top visible line from bottom if we are over half of text, |
|
5819 // otherwise from top of text. |
|
5820 TInt approxTopVisibleLine = 0; |
|
5821 |
|
5822 // Variables only used in this block |
|
5823 TInt firstFormattedPos = iLayout->FirstFormattedPos(); |
|
5824 TInt lastFormattedPos = firstFormattedPos + formattedLength; |
|
5825 |
|
5826 avgLineHeight = formattedHeight / formattedLines; |
|
5827 |
|
5828 TInt lineNo = iLayout->GetLineNumber( CursorPos() ); |
|
5829 TInt heightBeforeFormat = ( avgLineHeight * firstFormattedPos ) |
|
5830 / avgCharsPerLine; |
|
5831 TInt heightAfterFormat = ( avgLineHeight * ( totalChars |
|
5832 - lastFormattedPos ) ) / avgCharsPerLine; |
|
5833 |
|
5834 const TAknDoubleSpanScrollBarModel* doubleModel = |
|
5835 static_cast< const TAknDoubleSpanScrollBarModel* > |
|
5836 ( iSBFrame->CEikScrollBarFrame::VerticalScrollBar()->Model() ); |
|
5837 |
|
5838 if ( !iEdwinExtension->iUseRateScroll ) |
|
5839 { |
|
5840 aVertModel.iScrollSpan = heightBeforeFormat + formattedHeight |
|
5841 + heightAfterFormat; |
|
5842 aVertModel.iThumbSpan = viewRectHeight; |
|
5843 } |
|
5844 |
|
5845 // Rate scrolling |
|
5846 |
|
5847 if ( iEdwinExtension->iUseRateScroll ) |
|
5848 { |
|
5849 TInt heightAboveView = formattedHeightAboveView + heightBeforeFormat; |
|
5850 TInt heightBelowView = formattedHeightBelowView + heightAfterFormat; |
|
5851 |
|
5852 TInt curScrollSpan = aVertModel.iScrollSpan |
|
5853 = doubleModel->ScrollSpan(); |
|
5854 TInt curThumbSpan = aVertModel.iThumbSpan |
|
5855 = doubleModel->WindowSize(); |
|
5856 |
|
5857 TInt thumbSpaceAbove = aVertModel.iThumbPosition |
|
5858 = iSBFrame-> CEikScrollBarFrame::VerticalScrollBar()->ThumbPosition(); |
|
5859 |
|
5860 TInt thumbSpaceBelow = curScrollSpan - curThumbSpan - thumbSpaceAbove; |
|
5861 |
|
5862 // We have moved above |
|
5863 if ( iEdwinExtension->iScrolledDelta > 0 )//Move above |
|
5864 { |
|
5865 TInt prePosition = heightAboveView + iEdwinExtension->iScrolledDelta; |
|
5866 if ( prePosition == 0 ) |
|
5867 { |
|
5868 return; |
|
5869 } |
|
5870 anchorThumbPos = thumbSpaceAbove |
|
5871 - iEdwinExtension->iScrolledDelta * thumbSpaceAbove |
|
5872 / prePosition; |
|
5873 } |
|
5874 // We have moved below |
|
5875 else if ( iEdwinExtension->iScrolledDelta < 0 )//Move below |
|
5876 { |
|
5877 TInt postPosition = heightBelowView - iEdwinExtension->iScrolledDelta; |
|
5878 if ( postPosition == 0 ) |
|
5879 { |
|
5880 return; |
|
5881 } |
|
5882 anchorThumbPos = thumbSpaceAbove |
|
5883 - iEdwinExtension->iScrolledDelta * thumbSpaceBelow |
|
5884 / postPosition; |
|
5885 } |
|
5886 else |
|
5887 { |
|
5888 return; |
|
5889 } |
|
5890 } |
|
5891 else // Original way, no rate scrolling |
|
5892 { |
|
5893 approxTopVisibleLine = topLeftDocPos / avgCharsPerLine; |
|
5894 if ( approxTopVisibleLine == 0 && topLeftDocPos > 0 ) |
|
5895 { |
|
5896 approxTopVisibleLine = 1; |
|
5897 } |
|
5898 } |
|
5899 |
|
5900 if ( iEdwinExtension->iUseRateScroll ) |
|
5901 { |
|
5902 aVertModel.iThumbPosition = anchorThumbPos; |
|
5903 } |
|
5904 else |
|
5905 { |
|
5906 aVertModel.iThumbPosition = approxTopVisibleLine * avgLineHeight; |
|
5907 } |
|
5908 iEdwinExtension->iScrollbarPosition = aVertModel.iThumbPosition; |
|
5909 } |
|
5910 |
|
5911 // --------------------------------------------------------------------------- |
|
5912 // CEikEdwin::HandleScrollEventWithPhysicsL |
|
5913 // --------------------------------------------------------------------------- |
|
5914 // |
|
5915 void CEikEdwin::HandleScrollEventWithPhysics( CEikScrollBar* aScrollBar ) |
|
5916 { |
|
5917 // Scroll view based on scrollbar thumb position |
|
5918 |
|
5919 const TAknDoubleSpanScrollBarModel * doubleModel = |
|
5920 static_cast< const TAknDoubleSpanScrollBarModel* > |
|
5921 ( aScrollBar->Model() ); |
|
5922 |
|
5923 TInt curScrollSpan = doubleModel->ScrollSpan(); |
|
5924 TInt curThumbSpan = doubleModel->WindowSize(); |
|
5925 TInt thumbSpaceAbove = aScrollBar->ThumbPosition(); |
|
5926 TInt thumbSpaceBelow = curScrollSpan - curThumbSpan - thumbSpaceAbove; |
|
5927 |
|
5928 TInt moveOffset = thumbSpaceAbove - iEdwinExtension->iScrollbarPosition; |
|
5929 |
|
5930 const TInt formattedLines = Max( 1, iLayout->NumFormattedLines() ); |
|
5931 const TInt formattedHeight = iLayout->FormattedHeightInPixels(); |
|
5932 const TInt viewRectHeight = AdjustedViewRect().Height(); |
|
5933 const TInt totalChars = iText->DocumentLength(); |
|
5934 const TInt formattedLength = iLayout->FormattedLength(); |
|
5935 const TInt avgCharsPerLine = Max( 1, formattedLength / formattedLines ); |
|
5936 |
|
5937 const TInt formattedHeightAboveView = iLayout->PixelsAboveBand(); |
|
5938 const TInt formattedHeightBelowView = formattedHeight - viewRectHeight |
|
5939 - formattedHeightAboveView; |
|
5940 |
|
5941 const TInt firstFormattedPos = iLayout->FirstFormattedPos(); |
|
5942 const TInt lastFormattedPos = firstFormattedPos + formattedLength; |
|
5943 const TInt heightBeforeFormat = ( formattedHeight * firstFormattedPos ) |
|
5944 / avgCharsPerLine / formattedLines; |
|
5945 const TInt heightAfterFormat = ( formattedHeight * ( totalChars |
|
5946 - lastFormattedPos ) ) / avgCharsPerLine / formattedLines; |
|
5947 |
|
5948 const TInt heightAboveView = formattedHeightAboveView + heightBeforeFormat; |
|
5949 const TInt heightBelowView = formattedHeightBelowView + heightAfterFormat; |
|
5950 |
|
5951 TInt textMovePixels = 0; |
|
5952 if ( moveOffset > 0 ) |
|
5953 { |
|
5954 textMovePixels = heightBelowView * moveOffset / ( 0 - thumbSpaceBelow |
|
5955 - moveOffset ); |
|
5956 } |
|
5957 else if ( moveOffset < 0 ) |
|
5958 { |
|
5959 textMovePixels = heightAboveView * moveOffset / ( moveOffset |
|
5960 - thumbSpaceAbove ); |
|
5961 } |
|
5962 else |
|
5963 { |
|
5964 return; |
|
5965 } |
|
5966 iEdwinExtension->iScrollbarPosition = thumbSpaceAbove; |
|
5967 |
|
5968 // If scrollbar thumb is moved to the beginning or end of scrollbar, |
|
5969 // ensure that also editor content is moved also exactly to the beginning |
|
5970 // or end. This is needed because otherwise in some situations editor |
|
5971 // content is not moved enough. We can't move too much because moving is |
|
5972 // limited to begin and end of actual editor content. |
|
5973 if ( thumbSpaceAbove <= 0 ) |
|
5974 { |
|
5975 textMovePixels += KAdditionalPixels; |
|
5976 } |
|
5977 else if ( thumbSpaceAbove >= curScrollSpan - curThumbSpan ) |
|
5978 { |
|
5979 textMovePixels -= KAdditionalPixels; |
|
5980 } |
|
5981 |
|
5982 iEdwinExtension->iScrolledByScrollBar = ETrue; |
|
5983 |
|
5984 // Actual scrolling is done by calling MoveScrollIndex |
|
5985 iEdwinExtension->iPhysicsHandler->MoveScrollIndex( -textMovePixels ); |
|
5986 |
|
5987 iEdwinExtension->iScrolledByScrollBar = EFalse; |
|
5988 } |
|
5989 |
|
5990 EXPORT_C void CEikEdwin::HandleScrollEventL(CEikScrollBar* aScrollBar,TEikScrollEvent aEventType) |
|
5991 { |
|
5992 __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText)); |
|
5993 __ASSERT_DEBUG(iLayout,Panic(EEikPanicEdwinNoLayout)); |
|
5994 |
|
5995 TInt thumbPosition=aScrollBar->ThumbPosition(); |
|
5996 TInt thumbSpan = 0; |
|
5997 if ( aScrollBar->Model()->ScrollBarModelType() == |
|
5998 TEikScrollBarModel::EAknDoubleSpanScrollBarModel) |
|
5999 { |
|
6000 const TAknDoubleSpanScrollBarModel* doubleModel = |
|
6001 static_cast<const TAknDoubleSpanScrollBarModel*>( aScrollBar->Model() ); |
|
6002 thumbSpan = doubleModel->ScrollSpan(); |
|
6003 thumbSpan -= doubleModel->WindowSize(); |
|
6004 } |
|
6005 else |
|
6006 { |
|
6007 thumbSpan = aScrollBar->Model()->MaxThumbPos(); |
|
6008 } |
|
6009 switch (aEventType&KEikScrollEventBarMask) |
|
6010 { |
|
6011 case KEikScrollEventFromHBar: |
|
6012 switch (aEventType) |
|
6013 { |
|
6014 case EEikScrollLeft: |
|
6015 case EEikScrollRight: |
|
6016 MoveDisplayL((aEventType==EEikScrollLeft)? TCursorPosition::EFLeft: TCursorPosition::EFRight); |
|
6017 break; |
|
6018 case EEikScrollPageLeft: |
|
6019 case EEikScrollPageRight: |
|
6020 { |
|
6021 TInt singleScrollJump=iTextView->HorizontalScrollJump(); |
|
6022 if (aEventType==EEikScrollPageLeft) |
|
6023 singleScrollJump=-singleScrollJump; |
|
6024 const TInt leftTextViewMargin=iTextView->LeftTextMargin(); |
|
6025 const TInt layoutWidth = LayoutWidth(); |
|
6026 const TInt textViewWidth = iTextView->ViewRect().Width(); |
|
6027 |
|
6028 TInt leftMargin = (5*singleScrollJump) + leftTextViewMargin; // ?? scroll how far!! |
|
6029 if (leftMargin < 0) |
|
6030 leftMargin=0; |
|
6031 else if (leftMargin>layoutWidth) |
|
6032 leftMargin=leftTextViewMargin + layoutWidth - textViewWidth; |
|
6033 iTextView->SetLeftTextMargin(leftMargin); // !! this doesn't actually scroll anything so... |
|
6034 TRect rect=iBorder.InnerRect(Rect()); |
|
6035 iMargins.InnerRect(rect); |
|
6036 iTextView->DrawL(rect); |
|
6037 UpdateScrollBarsL(); |
|
6038 UpdateHorizScrollBarThumb(); |
|
6039 } |
|
6040 break; |
|
6041 case EEikScrollThumbDragHoriz: |
|
6042 // case EEikScrollThumbReleaseHoriz: |
|
6043 { |
|
6044 iTextView->SetLeftTextMargin(thumbPosition); |
|
6045 TRect rect=iBorder.InnerRect(Rect()); |
|
6046 iMargins.InnerRect(rect); |
|
6047 iTextView->DrawL(rect); |
|
6048 } |
|
6049 break; |
|
6050 default: |
|
6051 break; |
|
6052 } |
|
6053 break; |
|
6054 case KEikScrollEventFromVBar: |
|
6055 switch (aEventType) |
|
6056 { |
|
6057 default: |
|
6058 break; |
|
6059 case EEikScrollTop: |
|
6060 case EEikScrollBottom: |
|
6061 { |
|
6062 TInt docPos=(aEventType==EEikScrollTop)? 0 : iText->DocumentLength(); |
|
6063 TInt yPos=iPosition.iY+iBorder.Margins().iLeft; |
|
6064 TViewYPosQualifier yPosQ; |
|
6065 yPosQ.SetMakeLineFullyVisible(); |
|
6066 yPosQ.SetFillScreen(); |
|
6067 iTextView->SetViewL(docPos, yPos, yPosQ); |
|
6068 UpdateVertScrollBarThumbL(); |
|
6069 UpdateHorizScrollBarThumb();// can also change horizontally |
|
6070 } |
|
6071 break; |
|
6072 case EEikScrollThumbReleaseVert: |
|
6073 { |
|
6074 if ( KineticScrollingEnabled() ) |
|
6075 { |
|
6076 RestoreCursorState(); |
|
6077 } |
|
6078 } |
|
6079 break; |
|
6080 case EEikScrollUp: |
|
6081 case EEikScrollDown: |
|
6082 case EEikScrollPageUp: |
|
6083 case EEikScrollPageDown: |
|
6084 case EEikScrollThumbDragVert: |
|
6085 { |
|
6086 if ( KineticScrollingEnabled() ) |
|
6087 { |
|
6088 StoreCursorState(); |
|
6089 HandleScrollEventWithPhysics( aScrollBar ); |
|
6090 break; |
|
6091 } |
|
6092 |
|
6093 TRect viewRect( AdjustedViewRect() ); |
|
6094 TInt docPos( 0 ); |
|
6095 TInt yPos = viewRect.iTl.iY; |
|
6096 TInt totalChars( iText->DocumentLength() ); |
|
6097 if ( !iLayout->IsFormattingBand() ) |
|
6098 { |
|
6099 TInt topLine( thumbPosition * iLayout->NumFormattedLines() / |
|
6100 iLayout->FormattedHeightInPixels() + 1 ); |
|
6101 docPos = iLayout->FirstCharOnLine( topLine ); |
|
6102 } |
|
6103 else |
|
6104 { |
|
6105 TInt topPos( iTextView->XyPosToDocPosL( viewRect.iTl ) ); |
|
6106 TInt bottomPos( iTextView->XyPosToDocPosL( viewRect.iBr ) ); |
|
6107 TInt visibleRange( bottomPos - topPos ); |
|
6108 |
|
6109 if ( thumbPosition != thumbSpan ) |
|
6110 { |
|
6111 TInt scrollRange( totalChars - visibleRange ); |
|
6112 docPos = ( TInt )( ( TInt64 )( thumbPosition ) * scrollRange |
|
6113 / thumbSpan ); |
|
6114 if ( iEdwinExtension->iThumbPos > thumbPosition && |
|
6115 docPos >= topPos && topPos != 0) |
|
6116 { |
|
6117 docPos = (TInt)( topPos - ( TInt64 )( thumbPosition - |
|
6118 iEdwinExtension->iThumbPos ) * scrollRange / thumbSpan ); |
|
6119 docPos = docPos < 0 ? 0 : docPos; |
|
6120 } |
|
6121 else if ( iEdwinExtension->iThumbPos < thumbPosition && |
|
6122 docPos <= topPos && bottomPos != totalChars ) |
|
6123 { |
|
6124 docPos = (TInt)( topPos + ( TInt64 )( thumbPosition - |
|
6125 iEdwinExtension->iThumbPos ) * scrollRange / thumbSpan ); |
|
6126 docPos = docPos > totalChars ? totalChars : docPos; |
|
6127 } |
|
6128 } |
|
6129 } |
|
6130 if ( thumbPosition == thumbSpan ) |
|
6131 { |
|
6132 docPos = totalChars; |
|
6133 yPos = viewRect.iBr.iY; |
|
6134 } |
|
6135 iEdwinExtension->iThumbPos = thumbPosition; |
|
6136 TViewYPosQualifier yPosQ; |
|
6137 yPosQ.SetMakeLineFullyVisible(); |
|
6138 iTextView->SetViewL( docPos, yPos, yPosQ, |
|
6139 CTextView::EFViewDontDiscardFormat, |
|
6140 CTextView::EFNoHorizontalScroll); |
|
6141 UpdateVertScrollBarThumbL(); |
|
6142 } |
|
6143 break; |
|
6144 } |
|
6145 if (aEventType!=EEikScrollThumbDragVert && iEdwinInternalFlags&EUnderOneScreenFormattedText) |
|
6146 UpdateScrollBarsL(); |
|
6147 break; |
|
6148 } |
|
6149 ReportEdwinEventL( MEikEdwinObserver::EEventScroll ); |
|
6150 } |
|
6151 |
|
6152 EXPORT_C TInt CEikEdwin::LayoutWidth() const |
|
6153 { |
|
6154 if (iLayoutWidth) |
|
6155 return iLayoutWidth; |
|
6156 TMargins margins=iBorder.Margins(); |
|
6157 TInt labels=0, cursor=0; |
|
6158 if (iTextView) |
|
6159 iTextView->MarginWidths(labels,cursor); |
|
6160 |
|
6161 TInt width; |
|
6162 |
|
6163 if ( iTextView ) |
|
6164 { |
|
6165 width = iTextView->ViewRect().Width(); |
|
6166 } |
|
6167 else |
|
6168 { |
|
6169 width = iSize.iWidth - ( margins.iLeft + margins.iRight ); |
|
6170 } |
|
6171 |
|
6172 return width - ( labels + cursor + CursorWidth() + iRightWrapGutter ); |
|
6173 } |
|
6174 |
|
6175 void CEikEdwin::DoReplaceAllL(SEdwinFindModel* aModel,TBool& aTextFound,TBool& aReplaced) |
|
6176 { |
|
6177 aReplaced=EFalse; |
|
6178 aTextFound=EFalse; |
|
6179 TInt flags=aModel->iFlags; |
|
6180 //text is found when called from replace dialog. |
|
6181 if (SelectionLength()) |
|
6182 ClearSelectionL(); |
|
6183 TInt startPos=CursorPos(); |
|
6184 if (flags&EFindDirectionUp) |
|
6185 startPos+=aModel->iText.Length(); |
|
6186 else |
|
6187 startPos-=aModel->iText.Length(); |
|
6188 TInt count=-1; |
|
6189 FindAgain: |
|
6190 count=FindTextL(&aModel->iText,startPos,aModel->iFlags); |
|
6191 if (count!=KErrNotFound) |
|
6192 { |
|
6193 aReplaced=ETrue; |
|
6194 aTextFound=ETrue; |
|
6195 iText->InsertL(count,aModel->iReplaceText); |
|
6196 iText->DeleteL(count+aModel->iReplaceText.Length(),aModel->iText.Length()); |
|
6197 if (!(flags&EFindDirectionUp)) |
|
6198 startPos=count+aModel->iReplaceText.Length(); |
|
6199 else |
|
6200 startPos=count; |
|
6201 goto FindAgain; |
|
6202 } |
|
6203 } |
|
6204 |
|
6205 EXPORT_C void CEikEdwin::ReplaceAllL(SEdwinFindModel* aModel) |
|
6206 { |
|
6207 __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText)); |
|
6208 __ASSERT_DEBUG(iTextView,Panic(EEikPanicEdwinNoView)); |
|
6209 CancelFepTransaction(); |
|
6210 TBool textFound=EFalse; |
|
6211 TBool replaced=EFalse; |
|
6212 const TBool undoEnabled=SupportsUndo(); |
|
6213 if (undoEnabled) |
|
6214 SetAllowUndo(EFalse); |
|
6215 TRAPD(ret,DoReplaceAllL(aModel,textFound,replaced)); |
|
6216 if (undoEnabled) |
|
6217 SetAllowUndo(ETrue); |
|
6218 if (ret==KErrNone) |
|
6219 { |
|
6220 if (!textFound) |
|
6221 DisplayFindTextNotFound(aModel->iText); |
|
6222 if (replaced) |
|
6223 { |
|
6224 ReportEdwinEventL( MEikEdwinObserver::EEventTextUpdate ); |
|
6225 DoReportEventL( MCoeControlObserver::EEventStateChanged ); |
|
6226 NotifyNewFormatL(); //do global format |
|
6227 } |
|
6228 if (SelectionLength()) |
|
6229 ClearSelectionL(); |
|
6230 } |
|
6231 else |
|
6232 { |
|
6233 iEikonEnv->BusyMsgCancel(); |
|
6234 ReportEdwinEventL( MEikEdwinObserver::EEventTextUpdate ); |
|
6235 DoReportEventL( MCoeControlObserver::EEventStateChanged ); |
|
6236 NotifyNewFormatL();//this will fail too if oom. |
|
6237 User::Leave(ret); |
|
6238 } |
|
6239 } |
|
6240 |
|
6241 EXPORT_C void CEikEdwin::ReplaceL(SEdwinFindModel* aModel) |
|
6242 { |
|
6243 __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText)); |
|
6244 __ASSERT_DEBUG(iTextView,Panic(EEikPanicEdwinNoView)); |
|
6245 |
|
6246 CancelFepTransaction(); |
|
6247 const TInt oldLength=iText->DocumentLength(); |
|
6248 TBool formatHasChanged; |
|
6249 TCursorSelection selection=iTextView->Selection(); |
|
6250 const TBool undoEnabled=SupportsUndo(); |
|
6251 if (undoEnabled) |
|
6252 SetAllowUndo(EFalse); |
|
6253 TInt startPos=DeleteHighlightL(formatHasChanged,EFalse,EFalse); |
|
6254 if (undoEnabled) |
|
6255 SetAllowUndo(ETrue); |
|
6256 TRAPD(err,iText->InsertL(startPos,aModel->iReplaceText)); |
|
6257 if (aModel->iFlags&EFindDirectionUp) |
|
6258 { |
|
6259 selection.iCursorPos=selection.LowerPos(); |
|
6260 selection.iAnchorPos=selection.iCursorPos+aModel->iReplaceText.Length(); |
|
6261 } |
|
6262 else |
|
6263 { |
|
6264 selection.iAnchorPos=selection.LowerPos(); |
|
6265 selection.iCursorPos=selection.iAnchorPos+aModel->iReplaceText.Length(); |
|
6266 } |
|
6267 const TCursorSelection pending(selection.iCursorPos,selection.iCursorPos); |
|
6268 iTextView->SetPendingSelection(pending); |
|
6269 iTextView->HandleInsertDeleteL(selection,aModel->iText.Length(),formatHasChanged); |
|
6270 if ( NeedToChangeFormattingModeL()) |
|
6271 SetAmountToFormatL(); |
|
6272 ReportEdwinEventL( MEikEdwinObserver::EEventTextUpdate ); |
|
6273 DoReportEventL( MCoeControlObserver::EEventStateChanged ); |
|
6274 User::LeaveIfError(err); |
|
6275 } |
|
6276 |
|
6277 EXPORT_C TBool CEikEdwin::FindL(const TDesC* aFindText,TInt aFindFlags) |
|
6278 { |
|
6279 TBuf<EEikEdwinFindStringMaxLen>* findText=new(ELeave) TBuf<EEikEdwinFindStringMaxLen>; |
|
6280 CleanupStack::PushL(findText); |
|
6281 if (!aFindText) |
|
6282 { |
|
6283 GetFindText(findText); |
|
6284 if (!findText->Length()) |
|
6285 { |
|
6286 CleanupStack::PopAndDestroy(); |
|
6287 if (SelectionLength()) |
|
6288 ClearSelectionL(); |
|
6289 return EFalse; |
|
6290 } |
|
6291 } |
|
6292 else |
|
6293 *findText=*aFindText; |
|
6294 TBool noBusyMessage=(aFindFlags&ENoBusyMessage); |
|
6295 if(!noBusyMessage) |
|
6296 iEikonEnv->BusyMsgL(R_EIK_TBUF_SEARCHING,500000); // 0.5s delay |
|
6297 TInt startPos=CursorPos(); |
|
6298 TBool isUp=(aFindFlags&EFindDirectionUp); |
|
6299 TBool findAgain=(aFindFlags&EFindAgain); |
|
6300 if ((isUp==EFalse) != (findAgain==EFalse)) |
|
6301 startPos=Selection().HigherPos(); |
|
6302 else |
|
6303 startPos=Selection().LowerPos(); |
|
6304 TInt pos=FindTextL(findText,startPos,aFindFlags); |
|
6305 if (pos==KErrNotFound) //ie not found |
|
6306 { |
|
6307 CleanupStack::PopAndDestroy(); // findText |
|
6308 if (SelectionLength()) |
|
6309 ClearSelectionL(); |
|
6310 if(!noBusyMessage) |
|
6311 iEikonEnv->BusyMsgCancel(); |
|
6312 return EFalse; |
|
6313 } |
|
6314 if (aFindFlags&EFindDirectionUp) |
|
6315 SetSelectionL(pos,pos+findText->Length()); |
|
6316 else |
|
6317 SetSelectionL(pos+findText->Length(),pos); |
|
6318 CleanupStack::PopAndDestroy(); // findText |
|
6319 if(!noBusyMessage) |
|
6320 iEikonEnv->BusyMsgCancel(); |
|
6321 return ETrue; |
|
6322 } |
|
6323 |
|
6324 EXPORT_C TInt CEikEdwin::FindTextL(const TDesC* aFindText,TInt aPos,TInt aFindFlags) |
|
6325 { |
|
6326 __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText)); |
|
6327 const TInt docLength=TextLength(); |
|
6328 if (docLength<aPos) |
|
6329 return KErrNotFound; |
|
6330 TInt findParams=aFindFlags; |
|
6331 TBuf<EEikEdwinFindStringMaxLen>* findText=new(ELeave) TBuf<EEikEdwinFindStringMaxLen>; |
|
6332 CleanupStack::PushL(findText); |
|
6333 if (aFindText) |
|
6334 *findText=*aFindText; |
|
6335 else |
|
6336 { |
|
6337 GetFindText(findText); |
|
6338 findParams&=(~EFindCaseSensitive); |
|
6339 } |
|
6340 const TInt findLen=findText->Length(); |
|
6341 if (!findLen || docLength<findLen) |
|
6342 { |
|
6343 CleanupStack::PopAndDestroy(); // findText |
|
6344 return KErrNotFound; |
|
6345 } |
|
6346 if (!(findParams&EFindCaseSensitive)) |
|
6347 findText->LowerCase(); |
|
6348 TBuf<EEikEdwinFindStringMaxLen>* docText=new(ELeave) TBuf<EEikEdwinFindStringMaxLen>; |
|
6349 CleanupStack::PushL(docText); |
|
6350 TInt count=aPos; |
|
6351 if (findParams&EFindDirectionUp) |
|
6352 { |
|
6353 if (aPos<findText->Length()) |
|
6354 { |
|
6355 CleanupStack::PopAndDestroy(2); // findText, docText |
|
6356 return KErrNotFound; |
|
6357 } |
|
6358 count=aPos-findLen; |
|
6359 } |
|
6360 FOREVER |
|
6361 { |
|
6362 if (count<0 || (count>(docLength-findLen) && !(findParams&EFindDirectionUp))) |
|
6363 { |
|
6364 CleanupStack::PopAndDestroy(2); // findText, docText |
|
6365 return KErrNotFound; |
|
6366 } |
|
6367 *docText=iText->Read(count,findLen); |
|
6368 TInt docLen=docText->Length(); |
|
6369 while (docLen<findLen) // tried to read across a segment boundary |
|
6370 { |
|
6371 docText->Append(iText->Read(count+docLen,findLen-docLen)); |
|
6372 docLen=docText->Length(); |
|
6373 } |
|
6374 if (!(findParams&EFindCaseSensitive)) |
|
6375 docText->LowerCase(); |
|
6376 if (*findText==*docText) |
|
6377 { |
|
6378 if (findParams&EFindWholeWord) |
|
6379 { |
|
6380 if ((count==0 || !TCharF(*((iText->Read(count-1,1)).Ptr())).IsAlphaDigit()) && |
|
6381 (count+findLen==docLength || !TCharF(*((iText->Read(count+findLen,1)).Ptr())).IsAlphaDigit())) |
|
6382 { |
|
6383 break; |
|
6384 } |
|
6385 } |
|
6386 else |
|
6387 { |
|
6388 break; |
|
6389 } |
|
6390 } |
|
6391 if (findParams&EFindDirectionUp) |
|
6392 count--; |
|
6393 else |
|
6394 count++; |
|
6395 } |
|
6396 CleanupStack::PopAndDestroy(2); // findText, docText |
|
6397 return count; |
|
6398 } |
|
6399 |
|
6400 EXPORT_C void CEikEdwin::DisplayFindTextNotFound(TDes& aFindText) |
|
6401 { |
|
6402 TBuf<80> tmp; |
|
6403 TRAPD( err, iCoeEnv->ReadResourceL( tmp,R_EIK_TBUF_CANNOT_FIND_TEXT ) ); |
|
6404 if ( err == KErrNone ) |
|
6405 { |
|
6406 TInt rem = tmp.MaxLength() - tmp.Length() - 1; |
|
6407 if ( aFindText.Length() > rem ) |
|
6408 { |
|
6409 TextUtils::TruncateToNumChars( aFindText, rem ); |
|
6410 } |
|
6411 TBuf<80> buf; |
|
6412 buf.Format( tmp, &aFindText ); |
|
6413 TextUtils::ClipToFit( buf, *iCoeEnv->NormalFont(), |
|
6414 iAvkonAppUi->ApplicationRect().Width() - 20 ); // -20 allows for borders on infomsg |
|
6415 iEikonEnv->InfoMsg( buf ); |
|
6416 } |
|
6417 } |
|
6418 |
|
6419 EXPORT_C void CEikEdwin::GetFindText(TDes* aSearchText) |
|
6420 { |
|
6421 CancelFepTransaction(); |
|
6422 TInt startPos=0; |
|
6423 TInt length=0; |
|
6424 if (SelectionLength()) |
|
6425 { |
|
6426 TCursorSelection selection=Selection(); |
|
6427 startPos=selection.LowerPos(); |
|
6428 length=SelectionLength(); |
|
6429 if (length>EEikEdwinFindStringMaxLen) |
|
6430 goto GetWord; |
|
6431 } |
|
6432 else |
|
6433 { |
|
6434 GetWord: |
|
6435 GetWordInfo(CursorPos(),startPos,length); |
|
6436 } |
|
6437 if (!length) |
|
6438 return; |
|
6439 length=Min(length,EEikEdwinFindStringMaxLen); |
|
6440 *aSearchText=iText->Read(startPos,length); |
|
6441 TInt searchLen=aSearchText->Length(); |
|
6442 while (searchLen<length) // tried to read across a segment boundary |
|
6443 { |
|
6444 aSearchText->Append(iText->Read(startPos+searchLen,length-searchLen)); |
|
6445 searchLen=aSearchText->Length(); |
|
6446 } |
|
6447 } |
|
6448 |
|
6449 EXPORT_C void CEikEdwin::SetAllowPictures(TBool aAllow) |
|
6450 { |
|
6451 if (aAllow) |
|
6452 iEdwinUserFlags|=EAllowPictures; |
|
6453 else |
|
6454 iEdwinUserFlags&=~EAllowPictures; |
|
6455 } |
|
6456 |
|
6457 EXPORT_C void CEikEdwin::CheckRemovePictures(TInt aStartPos,TInt aLength) |
|
6458 { |
|
6459 if (iEdwinUserFlags&EAllowPictures) |
|
6460 return; |
|
6461 TInt charsRead=0; |
|
6462 while (charsRead<aLength) |
|
6463 { |
|
6464 TPtrC ptr=iText->Read(aStartPos,Min(aLength-charsRead,10)); |
|
6465 const TInt ptrLength=ptr.Length(); |
|
6466 TInt located=0; |
|
6467 TInt pos=ptr.Locate(TChar(CEditableText::EPictureCharacter)); |
|
6468 while(pos!=-1) |
|
6469 { |
|
6470 if (iEdwinInternalFlags&ERichText) |
|
6471 STATIC_CAST(CRichText*,iText)->DeleteFromParagraph(aStartPos+pos,1); |
|
6472 else |
|
6473 { |
|
6474 TRAP_IGNORE( iText->DeleteL(aStartPos+pos,1)); |
|
6475 } |
|
6476 ++located; |
|
6477 ptr.Set(ptr.Ptr(),ptr.Length()-1); |
|
6478 pos=ptr.Locate(TChar(CEditableText::EPictureCharacter)); |
|
6479 } |
|
6480 aStartPos+=(ptrLength-located); |
|
6481 charsRead+=ptrLength; |
|
6482 } |
|
6483 } |
|
6484 |
|
6485 /* |
|
6486 * This function will remove the non Ascii character when the UNICODE |
|
6487 * charaters are not allowed |
|
6488 */ |
|
6489 EXPORT_C void CEikEdwin::CheckValidityOfChars(TInt aStartPos,TInt aLength) |
|
6490 { |
|
6491 if (!OnlyASCIIChars()) |
|
6492 return; |
|
6493 TInt charsRead=0; |
|
6494 while (charsRead<aLength) |
|
6495 { |
|
6496 TBuf<1> buf; |
|
6497 iText->Extract(buf, aStartPos, 1); |
|
6498 if (!IsValidChar(buf[0])) |
|
6499 { |
|
6500 if (iEdwinInternalFlags&ERichText) |
|
6501 STATIC_CAST(CRichText*,iText)->DeleteFromParagraph(aStartPos,1); |
|
6502 else |
|
6503 { |
|
6504 TRAP_IGNORE( iText->DeleteL(aStartPos,1)); |
|
6505 } |
|
6506 if ( iEdwinExtension->iSmiley ) |
|
6507 { |
|
6508 iEdwinExtension->iSmiley->HandleDeleteL( aStartPos, 1 ); |
|
6509 } |
|
6510 } |
|
6511 else |
|
6512 aStartPos++;//=(ptrLength-located); |
|
6513 charsRead++;//=ptrLength; |
|
6514 } |
|
6515 |
|
6516 } |
|
6517 |
|
6518 EXPORT_C void CEikEdwin::SetWordDelimiters(TBool aPicture,TBool aPunctuation) |
|
6519 { |
|
6520 if (aPicture) |
|
6521 iEdwinInternalFlags|=EPictureDelimits; |
|
6522 else |
|
6523 iEdwinInternalFlags&=~EPictureDelimits; |
|
6524 if (aPunctuation) |
|
6525 iEdwinInternalFlags|=EPunctuationDelimits; |
|
6526 else |
|
6527 iEdwinInternalFlags&=~EPunctuationDelimits; |
|
6528 } |
|
6529 |
|
6530 EXPORT_C void CEikEdwin::GetWordInfo(TInt aCurrentPos,TInt& aStartPos,TInt& aLength) const |
|
6531 { |
|
6532 __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText)); |
|
6533 iText->GetWordInfo(aCurrentPos,aStartPos,aLength,iEdwinInternalFlags&EPictureDelimits,iEdwinInternalFlags&EPunctuationDelimits); |
|
6534 } |
|
6535 |
|
6536 EXPORT_C void CEikEdwin::InsertFieldL(CTextField* aField,TUid aFieldType) |
|
6537 // Takes ownership of aField |
|
6538 // Inserts if there is space for the insert |
|
6539 // |
|
6540 { |
|
6541 __ASSERT_DEBUG(aField,Panic(EEikPanicFieldDoesNotExist)); |
|
6542 __ASSERT_DEBUG(iTextView,Panic(EEikPanicEdwinNoView)); |
|
6543 __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText)); |
|
6544 |
|
6545 CancelFepTransaction(); |
|
6546 TPtr ptr(NULL,0); // a null TPtr |
|
6547 TInt fieldLength=aField->Value(ptr); |
|
6548 CleanupStack::PushL(aField); |
|
6549 if (!((iTextLimit>(TextLength()+fieldLength)) || !iTextLimit)) |
|
6550 { |
|
6551 iEikonEnv->InfoMsg(R_EIK_TBUF_MAX_CHARACTERS_REACHED); |
|
6552 CleanupStack::PopAndDestroy(); // aField |
|
6553 } |
|
6554 else |
|
6555 { |
|
6556 TCursorSelection selection=iTextView->Selection(); |
|
6557 const TInt selectionLength=selection.Length(); |
|
6558 TBool formatHasChanged=EFalse; |
|
6559 if (selectionLength) |
|
6560 DeleteHighlightL(formatHasChanged); |
|
6561 const TInt oldLength=TextLength(); |
|
6562 const TInt cursorPos=CursorPos(); |
|
6563 CleanupStack::Pop(); // InsertFieldL takes ownership of aField |
|
6564 TRAPD(err,iText->InsertFieldL(cursorPos,aField,aFieldType)); |
|
6565 TRAP(err,iText->UpdateFieldL(cursorPos)); |
|
6566 if (NeedToChangeFormattingModeL()) |
|
6567 TRAP(err,SetAmountToFormatL()); |
|
6568 const TInt fieldLength=TextLength()-oldLength; |
|
6569 const TInt newCursorPos=selection.LowerPos()+fieldLength; |
|
6570 iTextView->SetPendingSelection(TCursorSelection(newCursorPos,newCursorPos)); |
|
6571 const TInt anchor=selection.LowerPos(); |
|
6572 selection.iAnchorPos=anchor; |
|
6573 selection.iCursorPos=anchor+fieldLength; |
|
6574 if (iUndoStore) |
|
6575 iUndoStore->SetNewText(selection); |
|
6576 iTextView->HandleInsertDeleteL(selection,selectionLength,formatHasChanged); |
|
6577 ReportEdwinEventL( MEikEdwinObserver::EEventTextUpdate ); |
|
6578 DoReportEventL( MCoeControlObserver::EEventStateChanged ); |
|
6579 User::LeaveIfError(err); |
|
6580 } |
|
6581 } |
|
6582 |
|
6583 EXPORT_C void CEikEdwin::UpdateAllFieldsL() |
|
6584 // move to the start of the document then update all fields |
|
6585 // (must move to the start first because doc may get much shorter) |
|
6586 // |
|
6587 { |
|
6588 __ASSERT_DEBUG(iTextView,Panic(EEikPanicEdwinNoView)); |
|
6589 __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText)); |
|
6590 |
|
6591 CancelFepTransaction(); |
|
6592 SetCursorPosL(0,EFalse); |
|
6593 const TInt oldLength=iText->DocumentLength(); |
|
6594 iText->UpdateAllFieldsL(); |
|
6595 if (NeedToChangeFormattingModeL()) |
|
6596 SetAmountToFormatL(); |
|
6597 TViewYPosQualifier yPosQualifier; |
|
6598 yPosQualifier.SetMakeLineFullyVisible(); |
|
6599 iTextView->HandleGlobalChangeL(yPosQualifier); |
|
6600 ReportEdwinEventL( MEikEdwinObserver::EEventTextUpdate ); |
|
6601 DoReportEventL( MCoeControlObserver::EEventStateChanged ); |
|
6602 } |
|
6603 |
|
6604 EXPORT_C void CEikEdwin::UpdateCurrentFieldL() |
|
6605 // if we're in a field move to the start of it and update it, else do nothing |
|
6606 // |
|
6607 { |
|
6608 __ASSERT_DEBUG(iTextView,Panic(EEikPanicEdwinNoView)); |
|
6609 __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText)); |
|
6610 |
|
6611 CancelFepTransaction(); |
|
6612 TInt pos = CursorPos(); |
|
6613 TFindFieldInfo info; |
|
6614 if (iText->FindFields(info,pos)) |
|
6615 {// we are in a field |
|
6616 // move cursor to start of field |
|
6617 SetCursorPosL(info.iFirstFieldPos,EFalse); |
|
6618 const TInt oldLength=iText->DocumentLength(); |
|
6619 // update the field |
|
6620 iText->UpdateFieldL(pos); |
|
6621 if (NeedToChangeFormattingModeL()) |
|
6622 SetAmountToFormatL(); |
|
6623 iTextView->HandleRangeFormatChangeL(TCursorSelection(info.iFirstFieldPos,info.iFirstFieldLen),EFalse); |
|
6624 ReportEdwinEventL( MEikEdwinObserver::EEventTextUpdate ); |
|
6625 DoReportEventL( MCoeControlObserver::EEventStateChanged ); |
|
6626 } |
|
6627 } |
|
6628 |
|
6629 /** |
|
6630 * Gets the list of logical colors employed in the drawing of the control, |
|
6631 * paired with an explanation of how they are used. Appends the list to aColorUseList. |
|
6632 * |
|
6633 * @since ER5U |
|
6634 */ |
|
6635 EXPORT_C void CEikEdwin::GetColorUseListL(CArrayFix<TCoeColorUse>& aColorUseList) const |
|
6636 { |
|
6637 CEikBorderedControl::GetColorUseListL(aColorUseList); |
|
6638 LafEdwin::GetColorUseListL(aColorUseList); |
|
6639 } |
|
6640 |
|
6641 /** |
|
6642 * Handles a change to the control's resources of type aType |
|
6643 * which are shared across the environment, e.g. colors or fonts. |
|
6644 * For this particular control aType can be a request of handling either the caps lock |
|
6645 * modifier or the virtual cursor state. |
|
6646 * |
|
6647 * @since ER5U |
|
6648 */ |
|
6649 EXPORT_C void CEikEdwin::HandleResourceChange(TInt aType) |
|
6650 { |
|
6651 CEikBorderedControl::HandleResourceChange(aType); |
|
6652 |
|
6653 switch (aType) |
|
6654 { |
|
6655 case KEikDynamicLayoutVariantSwitch: |
|
6656 { |
|
6657 iEdwinExtension->iThumbPos = KErrNotFound; |
|
6658 SizeChanged(); |
|
6659 if ( !IsReadOnly() && !IsNonFocusing() |
|
6660 && !( iEdwinUserFlags & EDisplayOnly ) ) |
|
6661 { |
|
6662 TInt docPos = CursorPos(); |
|
6663 TRect viewRect( AdjustedViewRect() ); |
|
6664 TViewYPosQualifier yPosQ; |
|
6665 TInt yPos = ( viewRect.iBr.iY + viewRect.iTl.iY )/2; |
|
6666 yPosQ.SetMakeLineFullyVisible(); |
|
6667 yPosQ.SetFillScreen(); |
|
6668 TRAP_IGNORE( iTextView->SetViewL( docPos, yPos, yPosQ ) ); |
|
6669 } |
|
6670 } |
|
6671 break; |
|
6672 case KEikMessageVirtualCursorStateChange: |
|
6673 { |
|
6674 TEikVirtualCursor& cursor=iEikonEnv->VirtualCursor(); |
|
6675 |
|
6676 if(!(iEdwinUserFlags&EIgnoreVirtualCursor) && IsFocused() |
|
6677 && cursor.CursorState(*iEikonEnv)==TEikVirtualCursor::EOn) |
|
6678 { |
|
6679 TRAP_IGNORE( cursor.SetCursorStateL(TEikVirtualCursor::ESuspended,*iEikonEnv)); |
|
6680 } |
|
6681 } |
|
6682 break; |
|
6683 case KEikMessageCaptionedControlEditableStateChange: |
|
6684 { |
|
6685 iEdwinUserFlags &= ~EAvkonNotEditable; |
|
6686 } |
|
6687 break; |
|
6688 case KEikMessageCaptionedControlNotEditableStateChange: |
|
6689 { |
|
6690 iEdwinUserFlags |= EAvkonNotEditable; |
|
6691 } |
|
6692 break; |
|
6693 case KEikInputLanguageChange: |
|
6694 { |
|
6695 UpdateCache(KEikInputLanguageChange); |
|
6696 DoAlignment(); |
|
6697 } |
|
6698 break; |
|
6699 default: |
|
6700 break; |
|
6701 } |
|
6702 } |
|
6703 |
|
6704 |
|
6705 /** |
|
6706 * Sets the edwin size observer to aObserver. Does not imply transfer of ownership. |
|
6707 */ |
|
6708 EXPORT_C void CEikEdwin::SetEdwinSizeObserver(MEikEdwinSizeObserver* aEdwinSizeObserver) |
|
6709 { |
|
6710 iEdwinSizeObserver = aEdwinSizeObserver; |
|
6711 CheckIfEdwinIsResizable(); |
|
6712 } |
|
6713 |
|
6714 void CEikEdwin::CheckIfEdwinIsResizable() |
|
6715 { |
|
6716 if (iEdwinSizeObserver!=NULL && iEdwinUserFlags&EResizable) |
|
6717 { |
|
6718 iEdwinInternalFlags &= ~EHasOneLineOnly; |
|
6719 } |
|
6720 |
|
6721 if ((iEdwinSizeObserver==NULL || !(iEdwinUserFlags&EResizable)) && |
|
6722 (iNumberOfLines==1)) |
|
6723 { |
|
6724 iEdwinInternalFlags |= EHasOneLineOnly; |
|
6725 } |
|
6726 } |
|
6727 |
|
6728 TBool CEikEdwin::IsNewHeightWithinMinimumAndMaximum(TInt aNewHeight) const |
|
6729 // Checks if the new height is within the minimum and maximum edwin height. |
|
6730 { |
|
6731 const TInt edwinHeight = iSize.iHeight; |
|
6732 TBool validHeight = ETrue; |
|
6733 if (aNewHeight < edwinHeight) |
|
6734 { |
|
6735 if ( ((iMinimumHeight > 0) && (iMinimumHeight > aNewHeight) ) || |
|
6736 (iMinimumHeight == 0) ) |
|
6737 validHeight = EFalse; |
|
6738 } |
|
6739 else if (aNewHeight > edwinHeight) |
|
6740 { |
|
6741 if ((iMaximumHeight > 0) && (iMaximumHeight < aNewHeight)) |
|
6742 validHeight = EFalse; |
|
6743 } |
|
6744 return validHeight; |
|
6745 } |
|
6746 |
|
6747 /** |
|
6748 * Reports the event EEventSizeChanging to the observer every time the text view height changes. |
|
6749 * |
|
6750 * This routine has been significantly changed for AVKON: (TimW Aug 2000) |
|
6751 * - It deals in numbers of lines rather than pixels for height. |
|
6752 * - It is triggers the oberver when the height reduces as well as when it increases. |
|
6753 * - It updates iNumberOfLInes |
|
6754 * |
|
6755 */ |
|
6756 EXPORT_C void CEikEdwin::OnReformatL(const CTextView* /*aTextView*/) |
|
6757 { |
|
6758 if (iEdwinInternalFlags&EOnReformatting) |
|
6759 return; |
|
6760 |
|
6761 CheckIfEdwinIsResizable(); |
|
6762 if ( (iEdwinSizeObserver) && (iEdwinUserFlags&EResizable) ) |
|
6763 { |
|
6764 const TInt extraHeight = iBorder.SizeDelta().iHeight+iMargins.iTop+iMargins.iBottom; |
|
6765 #ifdef _DEBUG |
|
6766 TInt edwinHeightWithBorgersAndMargins = iSize.iHeight; |
|
6767 #endif |
|
6768 |
|
6769 TInt newHeight = TextLayout()->FormattedHeightInPixels() + extraHeight; |
|
6770 |
|
6771 TInt lines = TextLayout()->NumFormattedLines() ; |
|
6772 |
|
6773 |
|
6774 iEdwinInternalFlags |= EOnReformatting; |
|
6775 // if (newHeight!=edwinHeightWithBorgersAndMargins) |
|
6776 if ( lines != iNumberOfLines ) |
|
6777 { |
|
6778 #ifdef _DEBUG |
|
6779 RDebug::Print(_L("Resizing edwin: newlines = %d, oldlines = %d, newHeight = %d. ehwbm = %d"), lines, iNumberOfLines, newHeight, edwinHeightWithBorgersAndMargins ) ; |
|
6780 #endif |
|
6781 iNumberOfLines = lines ; |
|
6782 |
|
6783 TInt minimumHeight = CalcMinimumHeightFromNumOfLinesL(); |
|
6784 // if ( IsEdwinHeightWithinMinimumAndMaximum(newHeight) || |
|
6785 // ((edwinHeightWithBorgersAndMargins > newHeight) && (newHeight == minimumHeight)) || |
|
6786 // (minimumHeight > newHeight) && (minimumHeight != edwinHeightWithBorgersAndMargins) ) |
|
6787 // if (ETrue) |
|
6788 // { |
|
6789 // if ((minimumHeight > newHeight) && (minimumHeight != edwinHeightWithBorgersAndMargins)) |
|
6790 newHeight = minimumHeight; |
|
6791 TSize desirableEdwinSize(iSize.iWidth, newHeight); |
|
6792 if (iEdwinSizeObserver->HandleEdwinSizeEventL(this, MEikEdwinSizeObserver::EEventSizeChanging, desirableEdwinSize)) |
|
6793 { |
|
6794 DrawDeferred(); |
|
6795 } |
|
6796 // } |
|
6797 } |
|
6798 iEdwinInternalFlags &= ~EOnReformatting; |
|
6799 } |
|
6800 } |
|
6801 |
|
6802 TInt CEikEdwin::CalcMinimumHeightFromNumOfLinesL() const |
|
6803 { |
|
6804 TInt minimumHeight = iSize.iHeight; |
|
6805 if (iNumberOfLines == 0) |
|
6806 { |
|
6807 if (iMinimumHeight > 0 ) |
|
6808 minimumHeight = iMinimumHeight; |
|
6809 } |
|
6810 else |
|
6811 { |
|
6812 __ASSERT_DEBUG(iLayout,Panic(EEikPanicEdwinNoLayout)); |
|
6813 TInt lineHeight = iLayout->FormattedHeightInPixels(); |
|
6814 const TInt docLength = iLayout->DocumentLength(); |
|
6815 if (docLength > 0) |
|
6816 { |
|
6817 const TInt numFormattedLines = iLayout->NumFormattedLines(); |
|
6818 lineHeight = lineHeight / numFormattedLines; |
|
6819 } |
|
6820 minimumHeight = (lineHeight * iNumberOfLines) + iBorder.SizeDelta().iHeight+iMargins.iTop+iMargins.iBottom; |
|
6821 } |
|
6822 return minimumHeight; |
|
6823 } |
|
6824 |
|
6825 void CEikEdwin::CheckEdwinHeight() |
|
6826 { |
|
6827 const TInt height = iSize.iHeight; |
|
6828 if ( (height >= iMaximumHeight) && (iMaximumHeight > 0) ) |
|
6829 iSize.iHeight = iMaximumHeight; |
|
6830 else if ( (height < iMinimumHeight) && (iMinimumHeight > 0) ) |
|
6831 iSize.iHeight = iMinimumHeight; |
|
6832 } |
|
6833 |
|
6834 void CEikEdwin::SetEdwinHeight(TInt aHeight) |
|
6835 { |
|
6836 if ( (aHeight > iMaximumHeight) && (iMaximumHeight > 0) ) |
|
6837 iSize.iHeight = iMaximumHeight; |
|
6838 else if ( (aHeight < iMinimumHeight) && (iMinimumHeight > 0) ) |
|
6839 iSize.iHeight = iMinimumHeight; |
|
6840 else |
|
6841 iSize.iHeight = aHeight; |
|
6842 } |
|
6843 |
|
6844 /** |
|
6845 * Returns the minimum edwin height. |
|
6846 * |
|
6847 */ |
|
6848 EXPORT_C TInt CEikEdwin::MinimumHeight() const |
|
6849 { |
|
6850 return iMinimumHeight; |
|
6851 } |
|
6852 |
|
6853 /** |
|
6854 * Returns the maximum edwin height. |
|
6855 */ |
|
6856 EXPORT_C TInt CEikEdwin::MaximumHeight() const |
|
6857 { |
|
6858 return iMaximumHeight; |
|
6859 } |
|
6860 |
|
6861 |
|
6862 /** |
|
6863 * Sets the minimum edwin height to be aHeight. It also adjustes the maximum edwin height when |
|
6864 * its values is smaller than aHeight. |
|
6865 */ |
|
6866 EXPORT_C void CEikEdwin::SetMinimumHeight(TInt aHeight) |
|
6867 { |
|
6868 if (aHeight > iMaximumHeight) |
|
6869 iMaximumHeight = aHeight; |
|
6870 iMinimumHeight = aHeight; |
|
6871 } |
|
6872 |
|
6873 /** |
|
6874 * Sets the maximum edwin height to be aHeight. It also adjustes the minimum edwin height when |
|
6875 * its values is bigger than aHeight. |
|
6876 */ |
|
6877 EXPORT_C void CEikEdwin::SetMaximumHeight(TInt aHeight) |
|
6878 { |
|
6879 if (iMinimumHeight > aHeight) |
|
6880 iMinimumHeight = aHeight; |
|
6881 iMaximumHeight = aHeight; |
|
6882 } |
|
6883 |
|
6884 EXPORT_C void CEikEdwin::InsertDeleteCharsL(TInt aInsertPos,const TDesC& aText,const TCursorSelection& aSelection) |
|
6885 { |
|
6886 __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText)); |
|
6887 __ASSERT_DEBUG(iTextView,Panic(EEikPanicEdwinNoView)); |
|
6888 const TInt lowerPos=aSelection.LowerPos(); |
|
6889 TBool formatChanged=EFalse; |
|
6890 const TInt length=aSelection.Length(); |
|
6891 if (iEdwinInternalFlags&ERichText) |
|
6892 { |
|
6893 STATIC_CAST(CRichText*,iText)->CancelInsertCharFormat(); |
|
6894 formatChanged=STATIC_CAST(CRichText*,iText)->DelSetInsertCharFormatL(lowerPos,length); |
|
6895 } |
|
6896 else |
|
6897 { |
|
6898 formatChanged=iText->DeleteL(lowerPos,length); |
|
6899 if ( iEdwinExtension->iSmiley ) |
|
6900 { |
|
6901 iEdwinExtension->iSmiley->HandleDeleteL( lowerPos, length ); |
|
6902 } |
|
6903 } |
|
6904 iText->InsertL(aInsertPos,aText); |
|
6905 if ( iEdwinExtension->iSmiley ) |
|
6906 { |
|
6907 iEdwinExtension->iSmiley->HandleInsertL( aInsertPos, aText.Length() ); |
|
6908 ConvertTextForSmileyL( TCursorSelection( aInsertPos, |
|
6909 aInsertPos + aText.Length() ), ETrue ); |
|
6910 } |
|
6911 iTextView->HandleInsertDeleteL(TCursorSelection(aInsertPos,aInsertPos+aText.Length()),length,formatChanged); |
|
6912 } |
|
6913 |
|
6914 EXPORT_C void CEikEdwin::SetNonPrintingCharsVisibility(TNonPrintingCharVisibility aVisibility) |
|
6915 { |
|
6916 __ASSERT_DEBUG(iLayout,Panic(EEikPanicEdwinNoLayout)); |
|
6917 iLayout->SetNonPrintingCharsVisibility(aVisibility); |
|
6918 } |
|
6919 |
|
6920 EXPORT_C TNonPrintingCharVisibility CEikEdwin::NonPrintingCharsVisibility() const |
|
6921 { |
|
6922 __ASSERT_DEBUG(iLayout,Panic(EEikPanicEdwinNoLayout)); |
|
6923 return iLayout->NonPrintingCharsVisibility(); |
|
6924 } |
|
6925 |
|
6926 /** |
|
6927 * Writes the internal state of the control and its components to aStream. |
|
6928 * Does nothing in release mode. |
|
6929 * Designed to be overidden and base called by subclasses. |
|
6930 * |
|
6931 * @internal |
|
6932 * @since App-Framework_6.1 |
|
6933 */ |
|
6934 #ifndef _DEBUG |
|
6935 EXPORT_C void CEikEdwin::WriteInternalStateL(RWriteStream&) const |
|
6936 {} |
|
6937 #else |
|
6938 EXPORT_C void CEikEdwin::WriteInternalStateL(RWriteStream& aWriteStream) const |
|
6939 { |
|
6940 _LIT(KEikLitEdWnCtlStart,"<CEikEdwin>"); |
|
6941 _LIT(KEikLitEdWnCtlEnd,"<\\CEikEdwin>"); |
|
6942 _LIT(KEikLitEdWnUsFlgs,"<iEdwinUserFlags>"); |
|
6943 _LIT(KEikLitEdWnUsFlgsEnd,"<\\iEdwinUserFlags>"); |
|
6944 _LIT(KEikLitEdWnIntFlgs,"<iEdwinInternalFlags>"); |
|
6945 _LIT(KEikLitEdWnIntFlgsEnd,"<\\iEdwinInternalFlags>"); |
|
6946 _LIT(KEikLitEdWnPlnTxt,"<iText>"); |
|
6947 _LIT(KEikLitEdWnPlnTxtEnd,"<\\iText>"); |
|
6948 _LIT(KEikLitEdWnTxtLmt,"<iTextLimit>"); |
|
6949 _LIT(KEikLitEdWnTxtLmtEnd,"<\\iTextLimit>"); |
|
6950 _LIT(KEikLitEdWnNoLns,"<iNumberOfLines>"); |
|
6951 _LIT(KEikLitEdWnNoLnsEnd,"<\\iNumberOfLines>"); |
|
6952 _LIT(KEikLitEdWnLstPtrDPs,"<iLastPointerDocPos>"); |
|
6953 _LIT(KEikLitEdWnLstPtrDPsEnd,"<\\iLastPointerDocPos>"); |
|
6954 _LIT(KEikLitEdWnMrgns, "<iMargins>"); |
|
6955 _LIT(KEikLitEdWnMrgnsEnd, "<\\iMargins>"); |
|
6956 _LIT(KEikLitEdWnAvLnsVwRct,"<iAvgLinesInViewRect>"); |
|
6957 _LIT(KEikLitEdWnAvLnsVwRctEnd,"<\\iAvgLinesInViewRect>"); |
|
6958 _LIT(KEikLitEdWnAvChPrLn,"<iAvgCharsPerLine>"); |
|
6959 _LIT(KEikLitEdWnAvChPrLnEnd,"<\\iAvgCharsPerLine>"); |
|
6960 _LIT(KEikLitEdWnRgWrpGtr,"<iRightWrapGutter>"); |
|
6961 _LIT(KEikLitEdWnRgWrpGtrEnd,"<\\iRightWrapGutter>"); |
|
6962 _LIT(KEikLitEdWnLyWdth,"<iLayoutWidth>"); |
|
6963 _LIT(KEikLitEdWnLyWdthEnd,"<\\iLayoutWidth>"); |
|
6964 _LIT(KEikLitEdWnMinH,"<iMinimumHeight>"); |
|
6965 _LIT(KEikLitEdWnMinHEnd,"<\\iMinimumHeight>"); |
|
6966 _LIT(KEikLitEdWnMaxH,"<iMaximumHeight>"); |
|
6967 _LIT(KEikLitEdWnMaxHEnd,"<\\iMaximumHeight>"); |
|
6968 _LIT(KEikLitEdWnLstPrtAPs,"<iLastPointerAnchorPosition>"); |
|
6969 _LIT(KEikLitEdWnLstPrtAPsEnd,"<\\iLastPointerAnchorPosition>"); |
|
6970 |
|
6971 aWriteStream << KEikLitEdWnCtlStart; |
|
6972 aWriteStream << KEikLitEdWnUsFlgs; |
|
6973 aWriteStream.WriteInt32L(iEdwinUserFlags); |
|
6974 aWriteStream << KEikLitEdWnUsFlgsEnd; |
|
6975 aWriteStream << KEikLitEdWnIntFlgs; |
|
6976 aWriteStream.WriteInt32L(iEdwinInternalFlags); |
|
6977 aWriteStream << KEikLitEdWnIntFlgsEnd; |
|
6978 aWriteStream << KEikLitEdWnPlnTxt; |
|
6979 if(iText->DocumentLength()) |
|
6980 aWriteStream << *iText; |
|
6981 aWriteStream << KEikLitEdWnPlnTxtEnd; |
|
6982 aWriteStream << KEikLitEdWnTxtLmt; |
|
6983 aWriteStream.WriteInt32L(iTextLimit); |
|
6984 aWriteStream << KEikLitEdWnTxtLmtEnd; |
|
6985 aWriteStream << KEikLitEdWnNoLns; |
|
6986 aWriteStream.WriteInt32L(iNumberOfLines); |
|
6987 aWriteStream << KEikLitEdWnNoLnsEnd; |
|
6988 aWriteStream << KEikLitEdWnLstPtrDPs; |
|
6989 aWriteStream.WriteInt32L(iLastPointerDocPos); |
|
6990 aWriteStream << KEikLitEdWnLstPtrDPsEnd; |
|
6991 aWriteStream << KEikLitEdWnMrgns; |
|
6992 aWriteStream.WriteInt8L(iMargins.iLeft); |
|
6993 aWriteStream.WriteInt8L(iMargins.iRight); |
|
6994 aWriteStream.WriteInt8L(iMargins.iTop); |
|
6995 aWriteStream.WriteInt8L(iMargins.iBottom); |
|
6996 aWriteStream << KEikLitEdWnMrgnsEnd; |
|
6997 aWriteStream << KEikLitEdWnAvLnsVwRct; |
|
6998 aWriteStream.WriteInt32L(iAvgLinesInViewRect); |
|
6999 aWriteStream << KEikLitEdWnAvLnsVwRctEnd; |
|
7000 aWriteStream << KEikLitEdWnAvChPrLn; |
|
7001 aWriteStream.WriteInt32L(iAvgCharsPerLine); |
|
7002 aWriteStream << KEikLitEdWnAvChPrLnEnd; |
|
7003 aWriteStream << KEikLitEdWnRgWrpGtr; |
|
7004 aWriteStream.WriteInt32L(iRightWrapGutter); |
|
7005 aWriteStream << KEikLitEdWnRgWrpGtrEnd; |
|
7006 aWriteStream << KEikLitEdWnLyWdth; |
|
7007 aWriteStream.WriteInt32L(iLayoutWidth); |
|
7008 aWriteStream << KEikLitEdWnLyWdthEnd; |
|
7009 aWriteStream << KEikLitEdWnMinH; |
|
7010 aWriteStream.WriteInt32L(iMinimumHeight); |
|
7011 aWriteStream << KEikLitEdWnMinHEnd; |
|
7012 aWriteStream << KEikLitEdWnMaxH; |
|
7013 aWriteStream.WriteInt32L(iMaximumHeight); |
|
7014 aWriteStream << KEikLitEdWnMaxHEnd; |
|
7015 aWriteStream << KEikLitEdWnLstPrtAPs; |
|
7016 aWriteStream.WriteInt32L(iLastPointerAnchorPos); |
|
7017 aWriteStream << KEikLitEdWnLstPrtAPsEnd; |
|
7018 CEikBorderedControl::WriteInternalStateL(aWriteStream); |
|
7019 aWriteStream << KEikLitEdWnCtlEnd; |
|
7020 } |
|
7021 #endif |
|
7022 |
|
7023 EXPORT_C void CEikEdwin::Reserved_2() |
|
7024 {} |
|
7025 |
|
7026 EXPORT_C void CEikEdwin::Reserved_3() |
|
7027 {} |
|
7028 |
|
7029 // Avkon editor extensions |
|
7030 EXPORT_C void CEikEdwin::SetAknEditorCase(TInt aCase) |
|
7031 { |
|
7032 if (iEdwinFepSupport && iEdwinFepSupport->State(KNullUid)) |
|
7033 STATIC_CAST(CAknEdwinState*, iEdwinFepSupport->State(KNullUid))->SetDefaultCase(aCase); |
|
7034 } |
|
7035 |
|
7036 EXPORT_C void CEikEdwin::SetAknEditorPermittedCaseModes(TInt aPermittedCaseModes) |
|
7037 { |
|
7038 if (iEdwinFepSupport && iEdwinFepSupport->State(KNullUid)) |
|
7039 STATIC_CAST(CAknEdwinState*, iEdwinFepSupport->State(KNullUid))->SetPermittedCases(aPermittedCaseModes); |
|
7040 } |
|
7041 |
|
7042 EXPORT_C void CEikEdwin::SetAknEditorNumericKeymap(TAknEditorNumericKeymap aNumericKeymap) |
|
7043 { |
|
7044 if (iEdwinFepSupport && iEdwinFepSupport->State(KNullUid)) |
|
7045 STATIC_CAST(CAknEdwinState*, iEdwinFepSupport->State(KNullUid))->SetNumericKeymap(aNumericKeymap); |
|
7046 } |
|
7047 |
|
7048 EXPORT_C void CEikEdwin::SetAknEditorInputMode(TInt aInputMode) |
|
7049 { |
|
7050 if (iEdwinFepSupport && iEdwinFepSupport->State(KNullUid)) |
|
7051 STATIC_CAST(CAknEdwinState*, iEdwinFepSupport->State(KNullUid))->SetDefaultInputMode(aInputMode); |
|
7052 } |
|
7053 |
|
7054 EXPORT_C void CEikEdwin::SetAknEditorAllowedInputModes(TInt aInputModes) |
|
7055 { |
|
7056 if (iEdwinFepSupport && iEdwinFepSupport->State(KNullUid)) |
|
7057 STATIC_CAST(CAknEdwinState*, iEdwinFepSupport->State(KNullUid))->SetPermittedInputModes(aInputModes); |
|
7058 } |
|
7059 |
|
7060 EXPORT_C void CEikEdwin::SetAknEditorSpecialCharacterTable(TInt aSCTResId) |
|
7061 { |
|
7062 if (iEdwinFepSupport && iEdwinFepSupport->State(KNullUid)) |
|
7063 STATIC_CAST(CAknEdwinState*, iEdwinFepSupport->State(KNullUid))->SetSpecialCharacterTableResourceId(aSCTResId); |
|
7064 } |
|
7065 |
|
7066 EXPORT_C void CEikEdwin::SetAknEditorFlags(TInt aFlags) |
|
7067 { |
|
7068 if (iEdwinFepSupport) |
|
7069 { |
|
7070 CAknEdwinState* edwinState = STATIC_CAST(CAknEdwinState*, iEdwinFepSupport->State(KNullUid)); |
|
7071 if (edwinState) |
|
7072 { |
|
7073 edwinState->SetFlags(aFlags); |
|
7074 TRAP_IGNORE( edwinState->ReportAknEdStateEventL(MAknEdStateObserver::EAknEdwinStateFlagsUpdate)); |
|
7075 } |
|
7076 } |
|
7077 } |
|
7078 |
|
7079 EXPORT_C void CEikEdwin::SetAknEditorCurrentInputMode(TInt aInputMode) |
|
7080 { |
|
7081 if (iEdwinFepSupport) |
|
7082 { |
|
7083 CAknEdwinState* edwinState = STATIC_CAST(CAknEdwinState*, iEdwinFepSupport->State(KNullUid)); |
|
7084 if (edwinState) |
|
7085 { |
|
7086 edwinState->SetCurrentInputMode(aInputMode); |
|
7087 TRAP_IGNORE(edwinState->ReportAknEdStateEventL(MAknEdStateObserver::EAknEdwinStateInputModeUpdate)); |
|
7088 } |
|
7089 } |
|
7090 } |
|
7091 |
|
7092 EXPORT_C TInt CEikEdwin::AknEditorCurrentInputMode() |
|
7093 { |
|
7094 TInt inputMode = EAknEditorNullInputMode; |
|
7095 if (iEdwinFepSupport) |
|
7096 { |
|
7097 CAknEdwinState* edwinState = STATIC_CAST(CAknEdwinState*, iEdwinFepSupport->State(KNullUid)); |
|
7098 if (edwinState) |
|
7099 { |
|
7100 inputMode = edwinState->CurrentInputMode(); |
|
7101 } |
|
7102 } |
|
7103 return inputMode; |
|
7104 } |
|
7105 |
|
7106 EXPORT_C void CEikEdwin::SetAknEditorCurrentCase(TInt aCase) |
|
7107 { |
|
7108 if (iEdwinFepSupport) |
|
7109 { |
|
7110 CAknEdwinState* edwinState = STATIC_CAST(CAknEdwinState*, iEdwinFepSupport->State(KNullUid)); |
|
7111 if (edwinState) |
|
7112 { |
|
7113 edwinState->SetCurrentCase(aCase); |
|
7114 TRAP_IGNORE( edwinState->ReportAknEdStateEventL(MAknEdStateObserver::EAknEdwinStateCaseModeUpdate)); |
|
7115 } |
|
7116 } |
|
7117 } |
|
7118 |
|
7119 EXPORT_C void CEikEdwin::SetAknEditorLocalLanguage(TLanguage aLanguage) |
|
7120 { |
|
7121 if (iEdwinFepSupport) |
|
7122 { |
|
7123 CAknEdwinState* edwinState = STATIC_CAST(CAknEdwinState*, iEdwinFepSupport->State(KNullUid)); |
|
7124 if (edwinState) |
|
7125 { |
|
7126 edwinState->SetLocalLanguage(aLanguage); |
|
7127 TRAP_IGNORE( edwinState->ReportAknEdStateEventL(MAknEdStateObserver::EAknEdwinStateLocalLanguageUpdate)); |
|
7128 } |
|
7129 } |
|
7130 } |
|
7131 |
|
7132 EXPORT_C void CEikEdwin::NotifyEditorStateObserverOfStateChangeL() |
|
7133 { |
|
7134 if (iEdwinFepSupport && iEdwinFepSupport->State(KNullUid)) |
|
7135 { |
|
7136 STATIC_CAST(CAknEdwinState*, iEdwinFepSupport->State(KNullUid))->ReportAknEdStateEventL(MAknEdStateObserver::EAknEdwinStateEventStateUpdate); |
|
7137 } |
|
7138 } |
|
7139 |
|
7140 EXPORT_C void CEikEdwin::ReadAknResourceL(TResourceReader& aReader) |
|
7141 { |
|
7142 SetAknEditorCase(aReader.ReadInt16()); |
|
7143 SetAknEditorPermittedCaseModes(aReader.ReadInt16()); |
|
7144 SetAknEditorNumericKeymap(static_cast<TAknEditorNumericKeymap>(aReader.ReadInt16())); |
|
7145 SetAknEditorAllowedInputModes(aReader.ReadInt16()); |
|
7146 SetAknEditorInputMode(aReader.ReadInt16()); |
|
7147 SetAknEditorSpecialCharacterTable(aReader.ReadInt32()); |
|
7148 |
|
7149 SetAknEditorFlags(aReader.ReadInt16() | AknEdwinFlags()); |
|
7150 |
|
7151 // added to have a max height |
|
7152 SetMaximumHeightInLines(aReader.ReadInt16()); |
|
7153 |
|
7154 aReader.ReadInt16(); // ignore baseline |
|
7155 aReader.ReadInt16(); // spare |
|
7156 |
|
7157 // The following tries to ensure that those unfortunate number editors that |
|
7158 // trust the default resource keymapping value don't break. |
|
7159 if ( iEdwinFepSupport && iEdwinFepSupport->State( KNullUid ) ) |
|
7160 { |
|
7161 CAknEdwinState* state = static_cast<CAknEdwinState*>( iEdwinFepSupport->State( KNullUid ) ); |
|
7162 |
|
7163 if ( !( state->PermittedInputModes() & EAknEditorTextInputMode ) && |
|
7164 state->NumericKeymap() == EAknEditorAlphanumericNumberModeKeymap ) |
|
7165 { |
|
7166 // The OLD default value of the resource. This is safe, since alphanumeric is |
|
7167 // invalid anyway if the editor doesn't allow text input. |
|
7168 SetAknEditorNumericKeymap( EAknEditorStandardNumberModeKeymap ); |
|
7169 } |
|
7170 } |
|
7171 } |
|
7172 |
|
7173 |
|
7174 EXPORT_C void CEikEdwin::SetSuppressBackgroundDrawing( TBool aSuppress ) |
|
7175 { |
|
7176 if ( iEdwinExtension ) |
|
7177 { |
|
7178 iEdwinExtension->SetSuppressBackgroundDrawing( aSuppress ); |
|
7179 } |
|
7180 } |
|
7181 |
|
7182 EXPORT_C TBool CEikEdwin::IsBackgroundDrawingSuppressed() const |
|
7183 { |
|
7184 TBool ret( EFalse ); |
|
7185 |
|
7186 if ( iEdwinExtension ) |
|
7187 { |
|
7188 ret = iEdwinExtension->IsBackgroundDrawingSuppressed(); |
|
7189 } |
|
7190 |
|
7191 return ret; |
|
7192 } |
|
7193 |
|
7194 EXPORT_C void CEikEdwin::SetTextLinesRect( const TRect& aRect ) |
|
7195 { |
|
7196 if ( iEdwinExtension ) |
|
7197 { |
|
7198 iEdwinExtension->iTextLinesRect = aRect; |
|
7199 } |
|
7200 } |
|
7201 |
|
7202 EXPORT_C void CEikEdwin::SetScrollRect( const TRect & aRect ) |
|
7203 { |
|
7204 if ( iEdwinExtension ) |
|
7205 { |
|
7206 iEdwinExtension->iScrollRect = aRect; |
|
7207 } |
|
7208 } |
|
7209 |
|
7210 EXPORT_C TRect CEikEdwin::GetTextLinesRect() const |
|
7211 { |
|
7212 if ( iEdwinExtension ) |
|
7213 { |
|
7214 return iEdwinExtension->iTextLinesRect; |
|
7215 } |
|
7216 else |
|
7217 { |
|
7218 return TRect(); // Should initialize to empty |
|
7219 } |
|
7220 } |
|
7221 |
|
7222 EXPORT_C TBool CEikEdwin::CcpuIsFocused() const |
|
7223 { |
|
7224 return IsFocused(); |
|
7225 } |
|
7226 |
|
7227 EXPORT_C TBool CEikEdwin::CcpuCanCut() const |
|
7228 { |
|
7229 CAknEdwinState* state( EditorState() ); |
|
7230 if( state && state->Flags() & EAknEditorFlagFindPane ) |
|
7231 { |
|
7232 return EFalse; |
|
7233 } |
|
7234 return iCcpuSupport && !IsReadOnly() && SelectionLength() != 0; |
|
7235 } |
|
7236 |
|
7237 EXPORT_C void CEikEdwin::CcpuCutL() |
|
7238 { |
|
7239 ClipboardL(ECut); |
|
7240 } |
|
7241 |
|
7242 EXPORT_C TBool CEikEdwin::CcpuCanCopy() const |
|
7243 { |
|
7244 CAknEdwinState* state( EditorState() ); |
|
7245 if( state && state->Flags() & EAknEditorFlagFindPane ) |
|
7246 { |
|
7247 return EFalse; |
|
7248 } |
|
7249 return iCcpuSupport && SelectionLength() != 0; |
|
7250 } |
|
7251 |
|
7252 EXPORT_C void CEikEdwin::CcpuCopyL() |
|
7253 { |
|
7254 ClipboardL(ECopy); |
|
7255 } |
|
7256 |
|
7257 EXPORT_C TBool CEikEdwin::CcpuCanPaste() const |
|
7258 { |
|
7259 CAknEdwinState* state( EditorState() ); |
|
7260 if( state && state->Flags() & EAknEditorFlagFindPane ) |
|
7261 { |
|
7262 return EFalse; |
|
7263 } |
|
7264 if (!iCcpuSupport || IsReadOnly()) |
|
7265 return EFalse; |
|
7266 |
|
7267 TRAPD(err, DoCcpuCanPasteL()); |
|
7268 return err == KErrNone; |
|
7269 } |
|
7270 |
|
7271 EXPORT_C void CEikEdwin::CcpuPasteL() |
|
7272 { |
|
7273 ClipboardL(EPaste); |
|
7274 } |
|
7275 |
|
7276 EXPORT_C TBool CEikEdwin::CcpuCanUndo() const |
|
7277 { |
|
7278 return CanUndo(); |
|
7279 } |
|
7280 |
|
7281 EXPORT_C void CEikEdwin::CcpuUndoL() |
|
7282 { |
|
7283 UndoL(); |
|
7284 } |
|
7285 |
|
7286 void CEikEdwin::DoCcpuCanPasteL() const |
|
7287 { |
|
7288 if (!SelectionLength() && (iTextLimit && (TextLength() >= iTextLimit))) |
|
7289 User::Leave(KErrNotFound); |
|
7290 |
|
7291 CClipboard* cb=CClipboard::NewForReadingL(iCoeEnv->FsSession()); |
|
7292 CleanupStack::PushL(cb); |
|
7293 |
|
7294 TBool richText = ETrue; |
|
7295 TStreamId streamId=cb->StreamDictionary().At(KClipboardUidTypeRichText); |
|
7296 if (streamId==KNullStreamId) |
|
7297 { |
|
7298 streamId=cb->StreamDictionary().At(KClipboardUidTypePlainText); |
|
7299 richText = EFalse; |
|
7300 } |
|
7301 if (streamId==KNullStreamId) |
|
7302 User::Leave(KErrNotFound); |
|
7303 |
|
7304 HBufC* allowedChars = GetAllowedCharsLC(); |
|
7305 User::LeaveIfError(CheckAllowedCharsL(*allowedChars, *cb, richText)); |
|
7306 |
|
7307 CleanupStack::PopAndDestroy(2); // allowedChars, cb |
|
7308 } |
|
7309 |
|
7310 HBufC* CEikEdwin::GetAllowedCharsLC() const |
|
7311 { |
|
7312 if (iEdwinFepSupport && iEdwinFepSupport->State(KNullUid)) |
|
7313 { |
|
7314 CAknEdwinState* state = STATIC_CAST(CAknEdwinState*, iEdwinFepSupport->State(KNullUid)); |
|
7315 TInt permittedModes = state->PermittedInputModes(); |
|
7316 |
|
7317 if ( permittedModes & |
|
7318 ~(EAknEditorNumericInputMode | EAknEditorFullWidthNumericInputMode)) |
|
7319 { |
|
7320 if ( OnlyASCIIChars() ) |
|
7321 { |
|
7322 // While the specification for what characters actually are |
|
7323 // allowed in "latin only" editor is underway, we'll do this. Once |
|
7324 // the spec is set, a more efficient solution with constant |
|
7325 // unicode ranges is in order.. |
|
7326 const TInt asciiLimit( 256 ); |
|
7327 HBufC* buf = HBufC::NewLC( asciiLimit ); |
|
7328 TPtr ptr( buf->Des() ); |
|
7329 |
|
7330 for ( TInt i = 1; i < asciiLimit; ++i ) |
|
7331 { |
|
7332 ptr.Append( TChar( i ) ); |
|
7333 } |
|
7334 |
|
7335 return buf; |
|
7336 } |
|
7337 else |
|
7338 { |
|
7339 return KNullDesC().AllocLC(); |
|
7340 } |
|
7341 } |
|
7342 |
|
7343 // EAknEditorNumericInputMode and EAknEditorFullWidthNumericInputMode are only left. |
|
7344 TInt resId = 0; |
|
7345 switch (state->NumericKeymap()) |
|
7346 { |
|
7347 case EAknEditorStandardNumberModeKeymap: |
|
7348 resId = R_EIK_ALLOWED_STANDARDNUMBERMODEKEYMAP; |
|
7349 break; |
|
7350 case EAknEditorPlainNumberModeKeymap: |
|
7351 resId = R_EIK_ALLOWED_PLAINNUMBERMODEKEYMAP; |
|
7352 break; |
|
7353 case EAknEditorCalculatorNumberModeKeymap: |
|
7354 resId = R_EIK_ALLOWED_CALCULATORNUMBERMODEKEYMAP; |
|
7355 break; |
|
7356 case EAknEditorConverterNumberModeKeymap: |
|
7357 resId = R_EIK_ALLOWED_CONVERTERNUMBERMODEKEYMAP; |
|
7358 break; |
|
7359 case EAknEditorToFieldNumberModeKeymap: |
|
7360 resId = R_EIK_ALLOWED_TOFIELDNUMBERMODEKEYMAP; |
|
7361 break; |
|
7362 case EAknEditorFixedDiallingNumberModeKeymap: |
|
7363 default: |
|
7364 resId = R_EIK_ALLOWED_FIXEDDIALLINGNUMBERMODEKEYMAP; |
|
7365 break; |
|
7366 } |
|
7367 |
|
7368 return iEikonEnv->AllocReadResourceLC(resId); |
|
7369 } |
|
7370 else |
|
7371 { |
|
7372 User::Leave(KErrNoMemory); |
|
7373 return NULL; |
|
7374 } |
|
7375 } |
|
7376 |
|
7377 TInt CEikEdwin::CheckAllowedCharsL(const TDesC& aChars, CClipboard& aClipboard, TBool aRichText) const |
|
7378 { |
|
7379 TBool pictographsEnabled = EFalse; |
|
7380 TBool fullWidthCharactersAllowed = ETrue; |
|
7381 |
|
7382 CAknEdwinState* edwinState = NULL; |
|
7383 if (iEdwinFepSupport) |
|
7384 { |
|
7385 edwinState = STATIC_CAST(CAknEdwinState*, iEdwinFepSupport->State(KNullUid)); |
|
7386 } |
|
7387 |
|
7388 CAknPictographInterface* pictographInterface = iEdwinExtension->PictographInterface(); |
|
7389 if (edwinState) |
|
7390 { |
|
7391 if (FeatureManager::FeatureSupported(KFeatureIdJapanese)) |
|
7392 { |
|
7393 fullWidthCharactersAllowed = edwinState->PermittedInputModes() & ( |
|
7394 EAknEditorFullWidthTextInputMode | |
|
7395 EAknEditorFullWidthNumericInputMode | |
|
7396 EAknEditorFullWidthKatakanaInputMode | |
|
7397 EAknEditorHiraganaKanjiInputMode | |
|
7398 EAknEditorHiraganaInputMode | |
|
7399 EAknEditorTextInputMode |
|
7400 ); |
|
7401 } |
|
7402 if (pictographInterface) |
|
7403 { |
|
7404 pictographsEnabled = edwinState->Flags() & EAknEditorFlagEnablePictographInput; |
|
7405 } |
|
7406 } |
|
7407 |
|
7408 if (aChars.Length() == 0 && (pictographsEnabled || !pictographInterface) && fullWidthCharactersAllowed) |
|
7409 { |
|
7410 // All characters are allowed to paste. |
|
7411 return KErrNone; |
|
7412 } |
|
7413 |
|
7414 CPlainText* txtStore; |
|
7415 CRichText* richText = STATIC_CAST(CRichText*, Text()); |
|
7416 if (aRichText && richText) |
|
7417 { |
|
7418 const CParaFormatLayer* paraFormatLayer=richText->GlobalParaFormatLayer(); |
|
7419 const CCharFormatLayer* charFormatLayer=richText->GlobalCharFormatLayer(); |
|
7420 txtStore = CRichText::NewL(paraFormatLayer, charFormatLayer); |
|
7421 } |
|
7422 else |
|
7423 { |
|
7424 txtStore = CPlainText::NewL(); |
|
7425 } |
|
7426 CleanupStack::PushL(txtStore); |
|
7427 TInt bufferLength = txtStore->PasteFromStoreL(aClipboard.Store(), aClipboard.StreamDictionary(), 0); |
|
7428 TInt textLength = 0; |
|
7429 TInt textIndex = 0; |
|
7430 TBool finished = EFalse; |
|
7431 TInt err = KErrNone; |
|
7432 do |
|
7433 { |
|
7434 // EAknEditorNumericInputMode and EAknEditorFullWidthNumericInputMode are the only ones |
|
7435 // that get this far, so we convert the input to latin if non-ascii chars |
|
7436 // are allowed in the editor. This can leave if the text in the clipboard is huge. |
|
7437 HBufC* txtStoreBuf = txtStore->Read( textIndex ).AllocL(); |
|
7438 CleanupStack::PushL( txtStoreBuf ); // in case something leavable is added later |
|
7439 TPtr text = txtStoreBuf->Des(); |
|
7440 textLength = text.Length(); |
|
7441 |
|
7442 if (aChars.Length() == 0) |
|
7443 { |
|
7444 if (pictographInterface && !pictographsEnabled && |
|
7445 pictographInterface->Interface()->ContainsPictographs(text)) |
|
7446 { |
|
7447 // The clipboard contains pictographs but those are not allowed by the editor. |
|
7448 finished = ETrue; |
|
7449 err = KErrNotFound; |
|
7450 } |
|
7451 if ( err == KErrNone && !fullWidthCharactersAllowed ) |
|
7452 { |
|
7453 // Go through clipboard context and check if full-width characters exist. |
|
7454 for ( TInt ii = 0; ii < textLength; ii++ ) |
|
7455 { |
|
7456 if (JPLangUtil::IsFullWidth(text[ii]) && text[ii] != 0x2029) |
|
7457 { |
|
7458 // The clipboard contains full-width character(s) but those are not allowed by the editor. |
|
7459 err = KErrNotFound; |
|
7460 finished = ETrue; |
|
7461 break; |
|
7462 } |
|
7463 } |
|
7464 } |
|
7465 } |
|
7466 else |
|
7467 { |
|
7468 if ( !OnlyASCIIChars() ) |
|
7469 { |
|
7470 AknTextUtils::ConvertDigitsTo( text, EDigitTypeWestern ); |
|
7471 } |
|
7472 |
|
7473 // Go through all allowed characters and check if the clipboard contains unallowed characters. |
|
7474 for (TInt ii=0; ii < textLength; ii++) |
|
7475 { |
|
7476 TChar ch = text[ii]; |
|
7477 if (ch.IsPrint() && aChars.Locate(ch) == KErrNotFound) |
|
7478 { |
|
7479 err = KErrNotFound; |
|
7480 finished = ETrue; |
|
7481 break; |
|
7482 } |
|
7483 } |
|
7484 } |
|
7485 CleanupStack::PopAndDestroy(); // txtStoreBuf |
|
7486 textIndex += textLength; |
|
7487 } |
|
7488 while (!finished && textIndex < bufferLength); |
|
7489 |
|
7490 CleanupStack::PopAndDestroy(txtStore); |
|
7491 return err; |
|
7492 } |
|
7493 |
|
7494 EXPORT_C void CEikEdwin::EnableCcpuSupportL(TBool aSupport) |
|
7495 { |
|
7496 CAknCcpuSupport* ccpu = NULL; |
|
7497 CAknEdwinState* edwinState = EditorState(); |
|
7498 |
|
7499 if (aSupport) |
|
7500 { |
|
7501 ccpu = new(ELeave) CAknCcpuSupport(this); |
|
7502 ccpu->SetMopParent(this); |
|
7503 CleanupStack::PushL(ccpu); |
|
7504 ccpu->ConstructL(); |
|
7505 CleanupStack::Pop(ccpu); |
|
7506 if (edwinState) |
|
7507 { |
|
7508 edwinState->SetCcpuState(this); |
|
7509 } |
|
7510 } |
|
7511 else |
|
7512 { |
|
7513 if (edwinState) |
|
7514 { |
|
7515 edwinState->SetCcpuState(NULL); |
|
7516 } |
|
7517 } |
|
7518 |
|
7519 delete iCcpuSupport; |
|
7520 iCcpuSupport = ccpu; |
|
7521 } |
|
7522 |
|
7523 void CEikEdwin::DoReportEventL(MCoeControlObserver::TCoeEvent aEvent) |
|
7524 { |
|
7525 if (iCcpuSupport && aEvent == MCoeControlObserver::EEventStateChanged) |
|
7526 iCcpuSupport->HandleSelectionChangeL(); |
|
7527 ReportEventL(aEvent); |
|
7528 } |
|
7529 |
|
7530 void CEikEdwin::SetKeyboardRepeatRate(TTimeIntervalMicroSeconds32 aKeyRepeatRate) const |
|
7531 { |
|
7532 // test for fixed timeouts (do not require capabilities) |
|
7533 if (aKeyRepeatRate == TTimeIntervalMicroSeconds32(KAknStandardKeyboardRepeatRate)) |
|
7534 { |
|
7535 CAknSgcClient::SetKeyboardRepeatRate(EAknApplicationDefaulRepeatRate); |
|
7536 return; |
|
7537 } |
|
7538 else if (aKeyRepeatRate == TTimeIntervalMicroSeconds32(KAknEditorKeyboardRepeatRate)) |
|
7539 { |
|
7540 CAknSgcClient::SetKeyboardRepeatRate(EAknEditorDefaulRepeatRate); |
|
7541 return; |
|
7542 } |
|
7543 |
|
7544 // fall through, this requires capability WriteDeviceData |
|
7545 TTimeIntervalMicroSeconds32 currentRepeatDelay; |
|
7546 TTimeIntervalMicroSeconds32 currentRepeatRate; |
|
7547 iCoeEnv->WsSession().GetKeyboardRepeatRate(currentRepeatDelay, currentRepeatRate); |
|
7548 if (aKeyRepeatRate!=currentRepeatRate) |
|
7549 iCoeEnv->WsSession().SetKeyboardRepeatRate(currentRepeatDelay, aKeyRepeatRate); |
|
7550 } |
|
7551 |
|
7552 |
|
7553 EXPORT_C void CEikEdwin::SetMaximumHeightInLines(TInt aLines) |
|
7554 { |
|
7555 iMaximumHeightInLines=aLines; |
|
7556 }; |
|
7557 |
|
7558 EXPORT_C TInt CEikEdwin::MaximumHeightInLines() const |
|
7559 { |
|
7560 return iMaximumHeightInLines; |
|
7561 }; |
|
7562 |
|
7563 EXPORT_C void CEikEdwin::AddFlagToUserFlags(TUint32 aFlag) |
|
7564 { |
|
7565 iEdwinUserFlags|=aFlag; |
|
7566 SetVKBStatus(); |
|
7567 if ( aFlag & EAvkonEnableSmileySupport ) |
|
7568 { |
|
7569 EnableSmileySupportL( ETrue ); |
|
7570 } |
|
7571 } |
|
7572 |
|
7573 EXPORT_C void CEikEdwin::RemoveFlagFromUserFlags(TUint32 aFlag) |
|
7574 { |
|
7575 iEdwinUserFlags&=~aFlag; |
|
7576 SetVKBStatus(); |
|
7577 if ( aFlag & EAvkonEnableSmileySupport ) |
|
7578 { |
|
7579 EnableSmileySupportL( EFalse ); |
|
7580 } |
|
7581 } |
|
7582 |
|
7583 EXPORT_C TUint32 CEikEdwin::UserFlags() const |
|
7584 { |
|
7585 return iEdwinUserFlags; |
|
7586 } |
|
7587 |
|
7588 EXPORT_C TTypeUid::Ptr CEikEdwin::MopSupplyObject(TTypeUid aId) |
|
7589 { |
|
7590 TRAPD(err, CheckEdwinExtensionL()); |
|
7591 if (err==KErrNone) |
|
7592 { |
|
7593 if (iEdwinExtension->FormAccessor() && aId.iUid == MAknFormAccessor::ETypeId) |
|
7594 { |
|
7595 return aId.MakePtr(iEdwinExtension->FormAccessor()); |
|
7596 } |
|
7597 else if ( aId.iUid == CAknExtendedInputCapabilities::ETypeId ) |
|
7598 { |
|
7599 return aId.MakePtr( iEdwinExtension->iExtendedInputCapabilities ); |
|
7600 } |
|
7601 } |
|
7602 return TTypeUid::Null(); |
|
7603 } |
|
7604 |
|
7605 EXPORT_C void CEikEdwin::SetAlignment(TInt aAlignment) |
|
7606 { |
|
7607 if (iEdwinExtension) |
|
7608 iEdwinExtension->SetAlignment(aAlignment); |
|
7609 DoAlignment(); |
|
7610 } |
|
7611 |
|
7612 void CEikEdwin::NewParagraphL() |
|
7613 { |
|
7614 CheckEdwinExtensionL(); // checks if iEdwinExtension is NULL and constucts it if necessary |
|
7615 DoAlignment(); |
|
7616 } |
|
7617 |
|
7618 TInt CEikEdwin::CurrentAlignment() const |
|
7619 { |
|
7620 if (iEdwinExtension) |
|
7621 return iEdwinExtension->CurrentAlignment(); |
|
7622 return EAknEditorAlignBidi; |
|
7623 } |
|
7624 |
|
7625 void CEikEdwin::DoAlignment() |
|
7626 { |
|
7627 CParaFormat paraFormat; |
|
7628 TParaFormatMask paraFormatMask; |
|
7629 |
|
7630 // Get para format information from existing para format - else it gets overwritten. |
|
7631 if (iParaFormatLayer) |
|
7632 { |
|
7633 TRAPD( err, iParaFormatLayer->SenseL( ¶Format, paraFormatMask ) ) ; |
|
7634 if (err) |
|
7635 { |
|
7636 #ifdef _DEBUG |
|
7637 RDebug::Print(_L("CEikEdwin: Error in sensing format\n")); |
|
7638 #endif |
|
7639 return; |
|
7640 } |
|
7641 } |
|
7642 |
|
7643 CAknSettingCache& cache = CAknEnv::Static()->SettingCache(); |
|
7644 paraFormat.iLanguage = ELangEnglish; |
|
7645 TLanguage currentLanguage = cache.InputLanguage(); |
|
7646 |
|
7647 switch (CurrentAlignment()) |
|
7648 { |
|
7649 case EAknEditorAlignLeft: paraFormat.iHorizontalAlignment = CParaFormat::EAbsoluteLeftAlign; break; |
|
7650 case EAknEditorAlignRight: paraFormat.iHorizontalAlignment = CParaFormat::EAbsoluteRightAlign; break; |
|
7651 case EAknEditorAlignCenter: paraFormat.iHorizontalAlignment = CParaFormat::ECenterAlign; break; |
|
7652 case EAknEditorAlignBidi: |
|
7653 { |
|
7654 paraFormat.iHorizontalAlignment = CParaFormat::ELeftAlign; |
|
7655 paraFormat.iLanguage = currentLanguage; |
|
7656 break; |
|
7657 } |
|
7658 default: paraFormat.iHorizontalAlignment = CParaFormat::ELeftAlign; break; |
|
7659 } |
|
7660 paraFormatMask.SetAttrib(EAttParaLanguage); |
|
7661 paraFormatMask.SetAttrib(EAttAlignment); |
|
7662 |
|
7663 CParaFormatLayer* paraFormatLayer = NULL; |
|
7664 TBool alignNull = EFalse; |
|
7665 TRAPD(error, |
|
7666 { |
|
7667 paraFormatLayer = CParaFormatLayer::NewL(¶Format,paraFormatMask); |
|
7668 SetParaFormatLayer(paraFormatLayer); |
|
7669 if (iTextView) |
|
7670 { |
|
7671 NotifyNewFormatL(); |
|
7672 } |
|
7673 else |
|
7674 { |
|
7675 alignNull = ETrue; |
|
7676 } |
|
7677 }); |
|
7678 |
|
7679 if ( alignNull ) |
|
7680 { |
|
7681 #ifdef _DEBUG |
|
7682 RDebug::Print(_L("CEikEdwin: Alignment found null CEikEdwin::iTextView\n")); |
|
7683 #endif |
|
7684 } |
|
7685 |
|
7686 if (error) |
|
7687 { |
|
7688 #ifdef _DEBUG |
|
7689 RDebug::Print(_L("Error in applying formatting\n")); |
|
7690 #endif |
|
7691 } |
|
7692 } |
|
7693 |
|
7694 CAknEdwinDrawingModifier* CEikEdwin::AknEdwinDrawingModifier() |
|
7695 { |
|
7696 CAknEdwinDrawingModifier* modifier = NULL; |
|
7697 MopGetObject( modifier ); |
|
7698 return modifier; |
|
7699 } |
|
7700 |
|
7701 TBool CEikEdwin::EditorSupportsNeutralProtection() const |
|
7702 { |
|
7703 TBool ret = ETrue; |
|
7704 if (!InputCapabilities().FepAwareTextEditor()) |
|
7705 ret = EFalse; |
|
7706 |
|
7707 else if (InputCapabilities().SupportsSecretText()) |
|
7708 ret = EFalse; |
|
7709 |
|
7710 else if ( AknEdwinFlags() & EAknEditorFlagLatinInputModesOnly ) |
|
7711 ret = EFalse; |
|
7712 |
|
7713 else if (iEdwinFepSupport && iEdwinFepSupport->State(KNullUid)) |
|
7714 { |
|
7715 if ( static_cast<CAknEdwinState*>(iEdwinFepSupport->State(KNullUid))->PermittedInputModes() == EAknEditorNumericInputMode) |
|
7716 ret = EFalse; |
|
7717 } |
|
7718 else if ( !IsValidChar( EEikEdwinLeftToRightMark ) ) |
|
7719 ret = EFalse; |
|
7720 |
|
7721 return ret; |
|
7722 } |
|
7723 |
|
7724 |
|
7725 TBool CEikEdwin::NeedsNeutralProtection( TInt aPosOfLowEndOfDelete, TInt aLengthToDelete, TDes& aNewText, TBool& aForwardProtection ) |
|
7726 { |
|
7727 TBool protect(ETrue); |
|
7728 if (!EditorSupportsNeutralProtection() || ( aLengthToDelete == 0) ) |
|
7729 protect = EFalse; |
|
7730 |
|
7731 // Perform no neutral protection if the beginning of the text is deleted. |
|
7732 // Note that there MAY be protection occuring if the delete is from the end so there is |
|
7733 // no corresponding text on DocLength |
|
7734 if ( aPosOfLowEndOfDelete <= 0 ) |
|
7735 protect = EFalse; |
|
7736 |
|
7737 TInt posOfNextCharHigherThanDelete = aPosOfLowEndOfDelete + aLengthToDelete; |
|
7738 |
|
7739 TInt docLen = Text()->DocumentLength(); |
|
7740 |
|
7741 // Length to delete should not exceed the document length |
|
7742 if ( posOfNextCharHigherThanDelete > docLen) |
|
7743 protect = EFalse; |
|
7744 |
|
7745 TBool adjacentPrecedingIsNeutral(EFalse); |
|
7746 TBool adjacentTrailingIsNeutral(EFalse); |
|
7747 |
|
7748 if ( protect ) |
|
7749 { |
|
7750 adjacentPrecedingIsNeutral = CharIsNeutral( aPosOfLowEndOfDelete - 1); |
|
7751 if ( posOfNextCharHigherThanDelete < Text()->DocumentLength() ) |
|
7752 adjacentTrailingIsNeutral = CharIsNeutral( posOfNextCharHigherThanDelete); |
|
7753 |
|
7754 if ( !adjacentPrecedingIsNeutral && !adjacentTrailingIsNeutral ) |
|
7755 protect = EFalse; |
|
7756 } |
|
7757 |
|
7758 // Inits actually correspond to LTR, but they are only used if the bools indicating |
|
7759 // strong directionality found get set |
|
7760 TBool directionPrecedingDeleteIsRTL(EFalse); |
|
7761 TBool directionTrailingDeleteIsRTL(EFalse); |
|
7762 if ( protect ) |
|
7763 { |
|
7764 TBool strongPreceding = GetExposedDirectionOfText( aPosOfLowEndOfDelete - 1, EFalse, directionPrecedingDeleteIsRTL ); |
|
7765 TBool strongTrailing = GetExposedDirectionOfText( posOfNextCharHigherThanDelete, ETrue, directionTrailingDeleteIsRTL ); |
|
7766 if (!strongTrailing) |
|
7767 { |
|
7768 TFormCursorModifierUtils cursorModifierUtils( *TextView(), *TextLayout() ); |
|
7769 TTmDocPosSpec pos = cursorModifierUtils.DocPos(); |
|
7770 TBool isRTLPara = cursorModifierUtils.IsRightToLeftParagraph(pos); |
|
7771 directionTrailingDeleteIsRTL = isRTLPara; |
|
7772 strongTrailing = ETrue; |
|
7773 } |
|
7774 if ( !strongPreceding || !strongTrailing) |
|
7775 protect = EFalse; |
|
7776 else if ( COMPARE_BOOLS( directionPrecedingDeleteIsRTL, directionTrailingDeleteIsRTL ) ) |
|
7777 protect = EFalse; |
|
7778 } |
|
7779 |
|
7780 // Obtain ptr to text being deleted |
|
7781 TPtrC deletedText = Text()->Read( aPosOfLowEndOfDelete, aLengthToDelete) ; |
|
7782 |
|
7783 if ( protect ) |
|
7784 { |
|
7785 protect = EFalse; |
|
7786 TBool deletedWasRTL; |
|
7787 |
|
7788 // Check for and do reverse protection |
|
7789 if ( adjacentPrecedingIsNeutral ) |
|
7790 { |
|
7791 TBool deletedTextIsStrong = GetExposedDirectionOfTextInDescriptor( deletedText, ETrue, deletedWasRTL ); // search forward into deleted stuff |
|
7792 if ( deletedTextIsStrong && (directionPrecedingDeleteIsRTL == deletedWasRTL)) |
|
7793 { |
|
7794 protect = ETrue; |
|
7795 aForwardProtection = EFalse; |
|
7796 if ( deletedWasRTL ) |
|
7797 aNewText.Append( KEikEdwinRightToLeftMark ); |
|
7798 else |
|
7799 aNewText.Append( KEikEdwinLeftToRightMark ); |
|
7800 } |
|
7801 } |
|
7802 |
|
7803 // Check for and do forward protection |
|
7804 // Note it is possible to have both forward and reverse redecoration. |
|
7805 if ( adjacentTrailingIsNeutral ) |
|
7806 { |
|
7807 TBool deletedTextIsStrong = GetExposedDirectionOfTextInDescriptor( deletedText, EFalse, deletedWasRTL ); // search backward in deleted stuff |
|
7808 if (deletedTextIsStrong && (directionTrailingDeleteIsRTL == deletedWasRTL) ) |
|
7809 { |
|
7810 protect = ETrue; |
|
7811 aForwardProtection = ETrue; |
|
7812 if ( deletedWasRTL ) |
|
7813 aNewText.Append( KEikEdwinRightToLeftMark ); |
|
7814 else |
|
7815 aNewText.Append( KEikEdwinLeftToRightMark ); |
|
7816 } |
|
7817 } |
|
7818 } |
|
7819 |
|
7820 return protect; |
|
7821 } |
|
7822 |
|
7823 TBool CEikEdwin::GetStrongDirectionality(TChar aChar, TBool& aRightToLeft ) const |
|
7824 { |
|
7825 TBool hasStrongDirectionality(EFalse); |
|
7826 TChar::TBdCategory bdcat = aChar.GetBdCategory(); |
|
7827 |
|
7828 if ( (bdcat == TChar::ERightToLeft) || |
|
7829 (bdcat == TChar::ERightToLeftArabic) |
|
7830 ) |
|
7831 { |
|
7832 hasStrongDirectionality = ETrue; |
|
7833 aRightToLeft = ETrue; |
|
7834 } |
|
7835 else if (bdcat == TChar::ELeftToRight) |
|
7836 { |
|
7837 hasStrongDirectionality = ETrue; |
|
7838 aRightToLeft = EFalse; |
|
7839 } |
|
7840 |
|
7841 return hasStrongDirectionality; |
|
7842 } |
|
7843 |
|
7844 TBool CEikEdwin::CharIsNeutral( TInt aPos ) const |
|
7845 { |
|
7846 TChar ch = Text()->Read( aPos, 1 )[0]; |
|
7847 TChar::TBdCategory bdcat = ch.GetBdCategory(); |
|
7848 return ( bdcat == TChar::EWhitespace || |
|
7849 bdcat == TChar::EOtherNeutral ); |
|
7850 } |
|
7851 |
|
7852 TBool CEikEdwin::GetExposedDirectionOfTextInDescriptor( const TDesC& aText, TBool aForward, TBool& aIsRightToLeft ) const |
|
7853 { |
|
7854 TBool hasStrongCharacter(EFalse); |
|
7855 |
|
7856 TInt length = aText.Length(); |
|
7857 |
|
7858 // bail out if there is zero length, 'cos it would add a lot of tests in the rest of the source |
|
7859 if ( length <= 0 ) |
|
7860 return EFalse; |
|
7861 |
|
7862 TInt start = 0; |
|
7863 TInt increment = 1; |
|
7864 TInt limit = length; |
|
7865 |
|
7866 if ( !aForward ) |
|
7867 { |
|
7868 start = length - 1; |
|
7869 increment = -1; |
|
7870 limit = -1; // Limit is one beyond that last executed in the loop |
|
7871 } |
|
7872 |
|
7873 for ( TInt index = start; index != limit; index += increment ) |
|
7874 { |
|
7875 TBool isRTL; |
|
7876 if ( GetStrongDirectionality( aText[ index ], isRTL ) ) |
|
7877 { |
|
7878 hasStrongCharacter = ETrue; |
|
7879 aIsRightToLeft = isRTL; |
|
7880 break; |
|
7881 } |
|
7882 } |
|
7883 |
|
7884 return hasStrongCharacter; |
|
7885 } |
|
7886 |
|
7887 /** |
|
7888 * Start at pos and scan for strong characters. |
|
7889 * Stop at paragraph boundaries. |
|
7890 * Maximum of KMaxSearch of about 1 line... |
|
7891 */ |
|
7892 TBool CEikEdwin::GetExposedDirectionOfText( TInt aPos, TBool aForward, TBool& aIsRightToLeft ) const |
|
7893 { |
|
7894 TBool hasStrongCharacter(EFalse); |
|
7895 |
|
7896 // Access the plain text from the editor, getting a little bit at a time. |
|
7897 TBool done(EFalse); |
|
7898 TBool dataLeft(ETrue); |
|
7899 |
|
7900 TInt docLen = Text()->DocumentLength(); |
|
7901 if ( aPos < 0 || aPos >= docLen) |
|
7902 dataLeft = EFalse; |
|
7903 |
|
7904 // These are the inclusive start and end positions of the chunk of text to look at in the |
|
7905 // loop. |
|
7906 TInt start = aPos; |
|
7907 TInt end = aPos; |
|
7908 TInt len; |
|
7909 |
|
7910 while ( !done && dataLeft ) |
|
7911 { |
|
7912 // Get new end/start position - constrained |
|
7913 if ( aForward ) |
|
7914 { |
|
7915 end = start + KLengthAtATime - 1; |
|
7916 if ( end >= docLen ) |
|
7917 end = docLen - 1; |
|
7918 } |
|
7919 else |
|
7920 { |
|
7921 start = end - KLengthAtATime + 1; |
|
7922 if ( start < 0 ) |
|
7923 start = 0; |
|
7924 } |
|
7925 |
|
7926 len = end - start + 1; |
|
7927 |
|
7928 if ( len > 0 ) |
|
7929 { |
|
7930 TPtrC ptr = Text()->Read( start, len ); |
|
7931 TBool isRightToLeft; |
|
7932 if ( GetExposedDirectionOfTextInDescriptor( ptr, aForward, isRightToLeft ) ) |
|
7933 { |
|
7934 done = ETrue; |
|
7935 hasStrongCharacter = ETrue; |
|
7936 aIsRightToLeft = isRightToLeft; |
|
7937 } |
|
7938 else |
|
7939 { |
|
7940 // Get new start/end position - constrained |
|
7941 if (aForward) |
|
7942 { |
|
7943 start = end + 1; |
|
7944 if ( start >= docLen ) |
|
7945 dataLeft = EFalse; |
|
7946 } |
|
7947 else |
|
7948 { |
|
7949 end = start - 1; |
|
7950 if ( end <= -1 ) |
|
7951 dataLeft = EFalse; |
|
7952 } |
|
7953 } |
|
7954 } |
|
7955 else |
|
7956 dataLeft = EFalse; |
|
7957 |
|
7958 } |
|
7959 return hasStrongCharacter; |
|
7960 } |
|
7961 |
|
7962 EXPORT_C void CEikEdwin::SetPictographAnimationCallBack( TCallBack& aCallBack ) |
|
7963 { |
|
7964 iEdwinExtension->SetPictoCallBack( aCallBack ); |
|
7965 } |
|
7966 |
|
7967 const TCallBack& CEikEdwin::PictographAnimationCallBack() const |
|
7968 { |
|
7969 return iEdwinExtension->PictoCallBack(); |
|
7970 } |
|
7971 |
|
7972 TBool CEikEdwin::IsPurePhoneNumberEditor() const |
|
7973 { |
|
7974 TBool retVal(EFalse); |
|
7975 |
|
7976 if (iEdwinFepSupport && iEdwinFepSupport->State(KNullUid)) |
|
7977 { |
|
7978 CAknEdwinState* state = STATIC_CAST(CAknEdwinState*, iEdwinFepSupport->State(KNullUid) ); |
|
7979 if ( state->PermittedInputModes() == EAknEditorNumericInputMode && |
|
7980 ( state->NumericKeymap() == EAknEditorStandardNumberModeKeymap |
|
7981 || state->NumericKeymap() == EAknEditorFixedDiallingNumberModeKeymap |
|
7982 || state->NumericKeymap() == EAknEditorSATHiddenNumberModeKeymap |
|
7983 || state->NumericKeymap() == EAknEditorSATNumberModeKeymap ) |
|
7984 ) |
|
7985 retVal = ETrue; |
|
7986 } |
|
7987 return retVal; |
|
7988 } |
|
7989 |
|
7990 EXPORT_C void CEikEdwin::SetTextSkinColorIdL(TInt aAknSkinIdForTextColor) |
|
7991 { |
|
7992 CheckEdwinExtensionL(); |
|
7993 iEdwinExtension->iSkinIdForText = aAknSkinIdForTextColor; |
|
7994 } |
|
7995 |
|
7996 EXPORT_C void CEikEdwin::SetHighlightStyleL(TAknsHighlightStyle aStyle) |
|
7997 { |
|
7998 CheckEdwinExtensionL(); |
|
7999 iEdwinExtension->iSkinHighlightStyle = aStyle; |
|
8000 } |
|
8001 |
|
8002 // for custom drawer, not exported |
|
8003 TInt CEikEdwin::SkinColorId() const |
|
8004 { |
|
8005 if (iEdwinExtension) |
|
8006 { |
|
8007 return iEdwinExtension->iSkinIdForText; |
|
8008 } |
|
8009 return KErrNotFound; |
|
8010 } |
|
8011 |
|
8012 TAknsHighlightStyle CEikEdwin::HighlightStyle() const |
|
8013 { |
|
8014 if (iEdwinExtension) |
|
8015 { |
|
8016 return iEdwinExtension->iSkinHighlightStyle; |
|
8017 } |
|
8018 return EEikEdwinHighlightNormal; |
|
8019 } |
|
8020 |
|
8021 TRgb CEikEdwin::EditorBackgroundColor(TRgb& aConditionalColor) const |
|
8022 { |
|
8023 TRgb color; |
|
8024 if (iEdwinExtension && iEdwinExtension->iEditorBackgroundColor.IsSet() ) |
|
8025 { |
|
8026 aConditionalColor = iEdwinExtension->iEditorBackgroundColor.Value(); |
|
8027 color = aConditionalColor; |
|
8028 } |
|
8029 else |
|
8030 { |
|
8031 color = CEikonEnv::Static()->ControlColor(EColorControlBackground, *this); |
|
8032 } |
|
8033 return color; |
|
8034 } |
|
8035 |
|
8036 EXPORT_C void CEikEdwin::SetUpperFullFormattingLength( TInt aUpperFullFormattingLimit ) |
|
8037 { |
|
8038 if ( iEdwinExtension ) |
|
8039 { |
|
8040 iEdwinExtension->iUpperFullFormattingLength = Max( KMinimumFullFormattingLength, aUpperFullFormattingLimit ); |
|
8041 } |
|
8042 } |
|
8043 |
|
8044 EXPORT_C void CEikEdwin::EnableKineticScrollingL( TBool aEnable ) |
|
8045 { |
|
8046 if ( iEdwinExtension && aEnable ) |
|
8047 { |
|
8048 iEdwinExtension->EnableKineticScrollingL(); |
|
8049 } |
|
8050 } |
|
8051 |
|
8052 TBool CEikEdwin::NeedToChangeFormattingModeL() const |
|
8053 { |
|
8054 if ( TextLayout() && iText ) |
|
8055 { |
|
8056 const TInt docLength = iText->DocumentLength(); |
|
8057 TBool bandFormatting = TextLayout()->IsFormattingBand(); |
|
8058 if ( ( !bandFormatting && docLength > UpperFullFormattingLength() ) |
|
8059 || ( bandFormatting && docLength <= LowerPartialFormattingLength() ) ) |
|
8060 { |
|
8061 return ETrue; |
|
8062 } |
|
8063 } |
|
8064 return EFalse; |
|
8065 } |
|
8066 |
|
8067 TRect CEikEdwin::AdjustedViewRect() const |
|
8068 { |
|
8069 TRect mainPaneRect( 0, 0, 0, 0 ); |
|
8070 AknLayoutUtils::LayoutMetricsRect (AknLayoutUtils::EMainPane, |
|
8071 mainPaneRect ); |
|
8072 TInt mainPaneHeight = mainPaneRect.Height(); |
|
8073 |
|
8074 TRect rect( iTextView->ViewRect() ); |
|
8075 if ( rect.iTl.iY < 0 ) |
|
8076 { |
|
8077 rect.iTl.iY = 0; |
|
8078 } |
|
8079 if ( rect.iBr.iY > mainPaneHeight ) |
|
8080 { |
|
8081 rect.iBr.iY = mainPaneHeight; |
|
8082 } |
|
8083 return rect; |
|
8084 } |
|
8085 |
|
8086 void CEikEdwin::SetVKBStatus() |
|
8087 { |
|
8088 TUint cap = iEdwinExtension->iExtendedInputCapabilities->Capabilities(); |
|
8089 if ( iEdwinUserFlags & EAvkonDisableVKB ) |
|
8090 { |
|
8091 cap |= CAknExtendedInputCapabilities::EInputEditorDisableVKB; |
|
8092 } |
|
8093 else |
|
8094 { |
|
8095 cap &= ~CAknExtendedInputCapabilities::EInputEditorDisableVKB; |
|
8096 } |
|
8097 iEdwinExtension->iExtendedInputCapabilities->SetCapabilities( cap ); |
|
8098 } |
|
8099 |
|
8100 void CEikEdwin::ScrollViewToCursorLineL() |
|
8101 { |
|
8102 TInt cursorPos = CursorPos(); |
|
8103 TRect viewRect( AdjustedViewRect() ); |
|
8104 TInt pixels = -1; |
|
8105 TBool scroll = EFalse; |
|
8106 TInt endPos = iTextView->XyPosToDocPosL( viewRect.iBr ); |
|
8107 while ( cursorPos > endPos && pixels != 0 ) |
|
8108 { |
|
8109 pixels = iTextView->ScrollDisplayL( TCursorPosition::EFLineDown ); |
|
8110 if ( pixels != 0 ) |
|
8111 { |
|
8112 scroll = ETrue; |
|
8113 } |
|
8114 endPos = iTextView->XyPosToDocPosL( viewRect.iBr ); |
|
8115 } |
|
8116 if ( scroll ) |
|
8117 { |
|
8118 UpdateScrollBarsL(); |
|
8119 } |
|
8120 } |
|
8121 |
|
8122 EXPORT_C void CEikEdwin::SetCursorVisible(TBool aVisible) |
|
8123 { |
|
8124 TRAP_IGNORE( SetCursorVisibilityL( aVisible ) ); |
|
8125 } |
|
8126 |
|
8127 void CEikEdwin::PerformRecordedOperationL() |
|
8128 { |
|
8129 if ( iEdwinExtension->iDrawInvoked == CEikEdwinExtension::ENotDraw || |
|
8130 iEdwinExtension->iDrawInvoked == CEikEdwinExtension::EDrawing ) |
|
8131 { |
|
8132 if ( iEdwinExtension->iDrawInvoked == CEikEdwinExtension::ENotDraw ) |
|
8133 { |
|
8134 iEdwinExtension->iDrawInvoked = CEikEdwinExtension::EDrawn; |
|
8135 } |
|
8136 if ( iEdwinExtension->iTempCursorPos != KErrNotFound ) |
|
8137 { |
|
8138 if ( iEdwinExtension->iTempAnchorPos == KErrNotFound ) |
|
8139 { |
|
8140 SetCursorPosL( iEdwinExtension->iTempCursorPos, |
|
8141 iEdwinExtension->iTempSelect ); |
|
8142 } |
|
8143 else |
|
8144 { |
|
8145 SetSelectionL( iEdwinExtension->iTempCursorPos, |
|
8146 iEdwinExtension->iTempAnchorPos ); |
|
8147 } |
|
8148 } |
|
8149 iEdwinExtension->iTempCursorPos = KErrNotFound; |
|
8150 iEdwinExtension->iTempAnchorPos = KErrNotFound; |
|
8151 if ( iEdwinExtension->iDrawInvoked == CEikEdwinExtension::EDrawing ) |
|
8152 { |
|
8153 iEdwinExtension->iDrawInvoked = CEikEdwinExtension::EDrawn; |
|
8154 } |
|
8155 } |
|
8156 } |
|
8157 |
|
8158 void CEikEdwin::ScrollIfAtTopOrBottomL() |
|
8159 { |
|
8160 TInt cursorPos = CursorPos(); |
|
8161 TRect viewRect( AdjustedViewRect() ); |
|
8162 TPoint cursorPoint; |
|
8163 if ( ! iTextView->DocPosToXyPosL(cursorPos, cursorPoint) ) |
|
8164 { |
|
8165 return; |
|
8166 } |
|
8167 |
|
8168 TInt topPos = iTextView->XyPosToDocPosL( viewRect.iTl ); |
|
8169 TInt bottomPos = iTextView->XyPosToDocPosL( viewRect.iBr ); |
|
8170 TPoint cursorLineLeftPiont(viewRect.iTl.iX,cursorPoint.iY ); |
|
8171 TPoint cursorLineRightPiont(viewRect.iBr.iX,cursorPoint.iY ); |
|
8172 TInt cursorLineLeftPos = iTextView->XyPosToDocPosL( cursorLineLeftPiont ); |
|
8173 TInt cursorLineRightPos = iTextView->XyPosToDocPosL( cursorLineRightPiont ); |
|
8174 const TInt totalChars = iText->DocumentLength(); |
|
8175 TBool scroll( EFalse ); |
|
8176 if (topPos >= 0 && topPos == cursorLineLeftPos) |
|
8177 { |
|
8178 iTextView->ScrollDisplayL( TCursorPosition::EFLineUp ); |
|
8179 UpdateScrollBarsL(); |
|
8180 scroll = ETrue ; |
|
8181 } |
|
8182 if (bottomPos < totalChars && bottomPos == cursorLineRightPos) |
|
8183 { |
|
8184 iTextView->ScrollDisplayL( TCursorPosition::EFLineDown ); |
|
8185 UpdateScrollBarsL(); |
|
8186 scroll = ETrue ; |
|
8187 } |
|
8188 if ( scroll && iEdwinExtension->iDrawInvoked != |
|
8189 CEikEdwinExtension::EDrawing ) |
|
8190 { |
|
8191 ReportEdwinEventL( MEikEdwinObserver::EEventNavigation ); |
|
8192 } |
|
8193 } |
|
8194 |
|
8195 void CEikEdwin::OnEditorStateFlagChange( TInt aOldFlags, TInt aNewFlags ) |
|
8196 { |
|
8197 // for chinese popup flag |
|
8198 TInt chinesePopup( aOldFlags & EAknEditorFlagChinesePopup ); |
|
8199 if ( chinesePopup != ( aNewFlags & EAknEditorFlagChinesePopup ) ) |
|
8200 { |
|
8201 TRAP_IGNORE( ReportChinesePopupEventL( chinesePopup == 0 ) ); |
|
8202 } |
|
8203 } |
|
8204 |
|
8205 void CEikEdwin::ReportChinesePopupEventL( TBool aChinesePopupOpen ) |
|
8206 { |
|
8207 if ( aChinesePopupOpen ) |
|
8208 { |
|
8209 ReportEdwinEventL( MEikEdwinObserver::EEventChinesePopupOpen ); |
|
8210 } |
|
8211 else |
|
8212 { |
|
8213 ReportEdwinEventL( MEikEdwinObserver::EEventChinesePopupClose ); |
|
8214 } |
|
8215 } |
|
8216 |
|
8217 // for smiley support |
|
8218 void CEikEdwin::EnableSmileySupportL( TBool aEnableSmiley ) |
|
8219 { |
|
8220 if ( aEnableSmiley && !AknLayoutUtils::LayoutMirrored() ) |
|
8221 { |
|
8222 if ( !iEdwinExtension->iSmiley ) |
|
8223 { |
|
8224 iEdwinExtension->iSmiley = CSmileyManager::NewL( *this ); |
|
8225 iEdwinExtension->iSmiley->SetAnimationPlayTimes( KNormalAnimPlayTimes ); |
|
8226 if ( IsReadOnly() || iEdwinUserFlags & EDisplayOnly ) |
|
8227 { |
|
8228 iEdwinExtension->iSmiley->SetAnimationPlayTimes( |
|
8229 KInfiniteAnimPlayTimes ); |
|
8230 } |
|
8231 } |
|
8232 if ( TextLayout() ) |
|
8233 { |
|
8234 TextLayout()->SetCustomWrap( iEdwinExtension->iSmileyWrap ); |
|
8235 } |
|
8236 } |
|
8237 else |
|
8238 { |
|
8239 delete iEdwinExtension->iSmiley; |
|
8240 iEdwinExtension->iSmiley = NULL; |
|
8241 if ( TextLayout() ) |
|
8242 { |
|
8243 TextLayout()->SetCustomWrap( NULL ); |
|
8244 } |
|
8245 } |
|
8246 } |
|
8247 |
|
8248 TBool CEikEdwin::IsSmileyEnabled() const |
|
8249 { |
|
8250 return ( iEdwinExtension->iSmiley != NULL ); |
|
8251 } |
|
8252 |
|
8253 void CEikEdwin::DrawSmileyInTextL( CBitmapContext& aGc, CFont& aFont, |
|
8254 const TDesC& aText, const TPoint& aPt ) |
|
8255 { |
|
8256 TRect viewRect( AdjustedViewRect() ); |
|
8257 TInt topY( aPt.iY - aFont.AscentInPixels() ); |
|
8258 TInt bottomY( aPt.iY + aFont.DescentInPixels() ); |
|
8259 const TInt KThreshold = 10; |
|
8260 if ( topY < viewRect.iTl.iY - KThreshold || |
|
8261 bottomY > viewRect.iBr.iY + KThreshold ) |
|
8262 { |
|
8263 return; |
|
8264 } |
|
8265 TInt pos( 0 ); |
|
8266 TPoint pt( aPt ); |
|
8267 HBufC* buf( NULL ); |
|
8268 TRAPD( err, |
|
8269 { |
|
8270 pos = iTextView->XyPosToDocPosL( pt ); |
|
8271 buf = HBufC::NewL( aText.Length() ); |
|
8272 }); |
|
8273 if ( err == KErrNone ) |
|
8274 { |
|
8275 TPtr text( buf->Des() ); |
|
8276 text.Copy( aText ); |
|
8277 TrimText( text ); |
|
8278 TInt smileyWidth( aFont.TextWidthInPixels( KSmileyString ) ); |
|
8279 for ( TInt i( 0 ); i < text.Length(); i++ ) |
|
8280 { |
|
8281 if ( CSmileyManager::IsSmileyCode( text[i] ) ) |
|
8282 { |
|
8283 TInt x( pt.iX + aFont.TextWidthInPixels( text.Left( i ) ) ); |
|
8284 TRect rect( x, topY, x + smileyWidth, bottomY ); |
|
8285 iEdwinExtension->iSmiley->DrawIconL( aGc, rect, i + pos ); |
|
8286 } |
|
8287 } |
|
8288 } |
|
8289 delete buf; |
|
8290 } |
|
8291 |
|
8292 void CEikEdwin::ConvertVisibleTextForSmileyL( TBool aTextToCode ) |
|
8293 { |
|
8294 if ( !iEdwinExtension->iSmiley && !iTextView ) |
|
8295 { |
|
8296 return; |
|
8297 } |
|
8298 TCursorSelection visibleRange( GetVisibleTextRangeL() ); |
|
8299 ConvertTextForSmileyL( visibleRange, aTextToCode ); |
|
8300 } |
|
8301 |
|
8302 void CEikEdwin::ConvertTextForSmileyL( TCursorSelection aSelect, |
|
8303 TBool aTextToCode, TBool aRedraw ) |
|
8304 { |
|
8305 if ( iEdwinExtension->iSmiley && !iEdwinExtension->iInlineEditing ) |
|
8306 { |
|
8307 if ( aTextToCode ) |
|
8308 { |
|
8309 ExtendedRangeForSmiley( aSelect ); |
|
8310 } |
|
8311 TInt start( aSelect.LowerPos() ); |
|
8312 TInt length( aSelect.Length() ); |
|
8313 HBufC* buf( ExtractTextLC( aSelect ) ); |
|
8314 TPtr ptr( buf->Des() ); |
|
8315 if ( ptr.Length() > 0 && |
|
8316 iEdwinExtension->iSmiley->ConvertTextForSmileyL( aSelect.LowerPos(), |
|
8317 ptr, aTextToCode ) ) |
|
8318 { |
|
8319 iText->DeleteL( start, length ); |
|
8320 iText->InsertL( start, ptr ); |
|
8321 } |
|
8322 CleanupStack::PopAndDestroy( buf ); |
|
8323 if ( aRedraw ) |
|
8324 { |
|
8325 DrawDeferred(); |
|
8326 } |
|
8327 } |
|
8328 } |
|
8329 |
|
8330 void CEikEdwin::TrimText( TDes& aText ) |
|
8331 { |
|
8332 TInt index( -1 ); |
|
8333 const TText KTrimChar = 0xffff; |
|
8334 for ( TInt i( 0 ); i < aText.Length() && aText[i] == KTrimChar; i++ ) |
|
8335 { |
|
8336 index = i; |
|
8337 } |
|
8338 if ( index != -1 ) |
|
8339 { |
|
8340 aText.Delete( 0, index + 1 ); |
|
8341 } |
|
8342 index = -1; |
|
8343 for ( TInt i( aText.Length() - 1 ); i >= 0 && aText[i] == KTrimChar; i-- ) |
|
8344 { |
|
8345 index = i; |
|
8346 } |
|
8347 if ( index != -1 ) |
|
8348 { |
|
8349 aText.Delete( index, aText.Length() - index ); |
|
8350 } |
|
8351 } |
|
8352 |
|
8353 TCursorSelection CEikEdwin::GetVisibleTextRangeL() |
|
8354 { |
|
8355 if ( iTextView ) |
|
8356 { |
|
8357 TRect viewRect( AdjustedViewRect() ); |
|
8358 TInt start( iTextView->XyPosToDocPosL( viewRect.iTl ) ); |
|
8359 TInt end( iTextView->XyPosToDocPosL( viewRect.iBr ) ); |
|
8360 return TCursorSelection( start, end ); |
|
8361 } |
|
8362 return TCursorSelection( 0, 0 ); |
|
8363 } |
|
8364 |
|
8365 HBufC* CEikEdwin::ExtractTextLC( TCursorSelection aSelect ) |
|
8366 { |
|
8367 TInt length( aSelect.Length() ); |
|
8368 HBufC* buf( HBufC::NewL( length ) ); |
|
8369 CleanupStack::PushL( buf ); |
|
8370 TPtr ptr( buf->Des() ); |
|
8371 iText->Extract( ptr, aSelect.LowerPos(), length ); |
|
8372 return buf; |
|
8373 } |
|
8374 |
|
8375 void CEikEdwin::ConvertSmileyIconToTextL( TInt aStartPos, TDes& aText ) |
|
8376 { |
|
8377 if ( iEdwinExtension->iSmiley ) |
|
8378 { |
|
8379 iEdwinExtension->iSmiley->ConvertTextForSmileyL( aStartPos, |
|
8380 aText, EFalse ); |
|
8381 } |
|
8382 } |
|
8383 |
|
8384 void CEikEdwin::ExtendedRangeForSmiley( TCursorSelection& aSelect ) |
|
8385 { |
|
8386 if ( iEdwinExtension->iSmiley ) |
|
8387 { |
|
8388 TInt textLength( TextLength() ); |
|
8389 TInt start = aSelect.LowerPos() - CSmileyManager::KMaxLength; |
|
8390 if ( start < 0 ) |
|
8391 { |
|
8392 start = 0; |
|
8393 } |
|
8394 TInt end = aSelect.HigherPos() + CSmileyManager::KMaxLength; |
|
8395 if ( end > textLength ) |
|
8396 { |
|
8397 end = textLength; |
|
8398 } |
|
8399 aSelect.iAnchorPos = start; |
|
8400 aSelect.iCursorPos = end; |
|
8401 } |
|
8402 } |
|
8403 |
|
8404 TBool CEikEdwin::ConvertSmileyForDeleteL( TInt aDocPos, TBool aBackSpace ) |
|
8405 { |
|
8406 if ( !iEdwinExtension->iSmiley || ( aDocPos == 0 && aBackSpace ) || |
|
8407 ( aDocPos == TextLength() && !aBackSpace ) ) |
|
8408 { |
|
8409 return EFalse; |
|
8410 } |
|
8411 TInt checkPos( aDocPos ); |
|
8412 if ( aBackSpace ) |
|
8413 { |
|
8414 checkPos--; |
|
8415 checkPos = checkPos >= 0 ? checkPos : 0; |
|
8416 } |
|
8417 if ( CSmileyManager::IsSmileyCode( iEdwinExtension->iSmiley-> |
|
8418 SmileyCodeByPos( checkPos ) ) && |
|
8419 !iEdwinExtension->iSmiley->IsDisabledSmileyIcon( checkPos ) ) |
|
8420 { |
|
8421 TInt codeLength( iEdwinExtension->iSmiley->SmileyLength( checkPos ) ); |
|
8422 iEdwinExtension->iSmiley->DisableSmileyIcon( checkPos ); |
|
8423 TCursorSelection select( aDocPos, aDocPos ); |
|
8424 if ( aBackSpace ) |
|
8425 { |
|
8426 select.iAnchorPos -= codeLength; |
|
8427 } |
|
8428 else |
|
8429 { |
|
8430 select.iCursorPos += codeLength; |
|
8431 } |
|
8432 ConvertTextForSmileyL( select, EFalse ); |
|
8433 iEdwinExtension->iExtendedInputCapabilities->ReportEventL( |
|
8434 CAknExtendedInputCapabilities:: |
|
8435 MAknEventObserver::EControlContentUpdatedInternally, |
|
8436 NULL ); |
|
8437 return ETrue; |
|
8438 } |
|
8439 return EFalse; |
|
8440 } |
|
8441 |
|
8442 void CEikEdwin::ConvertSmileyForDeleteL( const TCursorSelection &aSelect ) |
|
8443 { |
|
8444 if ( !iEdwinExtension->iSmiley ) |
|
8445 { |
|
8446 return; |
|
8447 } |
|
8448 |
|
8449 TInt lowerPos( aSelect.LowerPos() ); |
|
8450 TInt higherPos( aSelect.HigherPos() ); |
|
8451 |
|
8452 // Extend the lowerPos to the edge of a smiley |
|
8453 iEdwinExtension->iSmiley->HandleSetCursor( lowerPos + 1, lowerPos ); |
|
8454 // Extend the higherPos to the edge of a smiley |
|
8455 iEdwinExtension->iSmiley->HandleSetCursor( higherPos - 1, higherPos ); |
|
8456 |
|
8457 TCursorSelection select( lowerPos, higherPos ); |
|
8458 HBufC* buf( ExtractTextLC( select ) ); |
|
8459 TPtr ptr( buf->Des() ); |
|
8460 if ( ptr.Length() > 0 && |
|
8461 iEdwinExtension->iSmiley->ConvertTextForSmileyL( lowerPos, |
|
8462 ptr, EFalse ) ) |
|
8463 { |
|
8464 iText->DeleteL( lowerPos, higherPos - lowerPos ); |
|
8465 iText->InsertL( lowerPos, ptr ); |
|
8466 } |
|
8467 CleanupStack::PopAndDestroy( buf ); |
|
8468 } |
|
8469 |
|
8470 void CEikEdwin::HandleScrollForSmileyL() |
|
8471 { |
|
8472 if ( !iEdwinExtension->iSmiley ) |
|
8473 { |
|
8474 return; |
|
8475 } |
|
8476 TCursorSelection select( GetVisibleTextRangeL() ); |
|
8477 if ( select.LowerPos() != iEdwinExtension->iVisibleRange.LowerPos() || |
|
8478 select.HigherPos() != iEdwinExtension->iVisibleRange.HigherPos() ) |
|
8479 { |
|
8480 iEdwinExtension->iVisibleRange.iCursorPos = select.iCursorPos; |
|
8481 iEdwinExtension->iVisibleRange.iAnchorPos = select.iAnchorPos; |
|
8482 } |
|
8483 iEdwinExtension->iSmiley->SetVisibleRange( select.LowerPos(), |
|
8484 select.Length() ); |
|
8485 } |
|
8486 |
|
8487 TBool CEikEdwin::AdjustCursorForSmileyL( TInt aOldCursor, TCursorSelection& aSelect ) |
|
8488 { |
|
8489 TBool ret( EFalse ); |
|
8490 TCursorSelection select( Selection() ); |
|
8491 TInt cursor( select.iCursorPos ); |
|
8492 iEdwinExtension->iSmiley->HandleSetCursor( aOldCursor, cursor ); |
|
8493 if ( cursor != select.iCursorPos ) |
|
8494 { |
|
8495 if ( select.iAnchorPos == select.iCursorPos ) |
|
8496 { |
|
8497 select.iAnchorPos = cursor; |
|
8498 } |
|
8499 select.iCursorPos = cursor; |
|
8500 ret = ETrue; |
|
8501 } |
|
8502 aSelect = select; |
|
8503 return ret; |
|
8504 } |
|
8505 |
|
8506 TRect CEikEdwin::AdjustDrawRectForSmiley( const TRect& aRect ) const |
|
8507 { |
|
8508 TRect viewRect( AdjustedViewRect() ); |
|
8509 return TRect( viewRect.iTl.iX, aRect.iTl.iY, viewRect.iBr.iX, aRect.iBr.iY ); |
|
8510 } |
|
8511 |
|
8512 void CEikEdwin::GetClipRegionForSmiley( RRegion& rgn, CFont& aFont, |
|
8513 const TDesC& aText, const TPoint& aPt, const TRect& aDrawRect ) const |
|
8514 { |
|
8515 TInt smileyWidth( aFont.TextWidthInPixels( KSmileyString ) ); |
|
8516 TInt topY( aDrawRect.iTl.iY ); |
|
8517 TInt bottomY( aDrawRect.iBr.iY ); |
|
8518 for ( TInt i( 0 ); i < aText.Length(); i++ ) |
|
8519 { |
|
8520 if ( CSmileyManager::IsSmileyCode( aText[i] ) ) |
|
8521 { |
|
8522 TInt x( aPt.iX + aFont.TextWidthInPixels( aText.Left( i ) ) ); |
|
8523 TRect rect( x, topY, x + smileyWidth, bottomY ); |
|
8524 rgn.SubRect( rect, NULL ); |
|
8525 } |
|
8526 } |
|
8527 } |
|
8528 |
|
8529 TBool CEikEdwin::AdjustCursorPosByMovementL( TCursorPosition::TMovementType aMovement, |
|
8530 TBool aSelect ) |
|
8531 { |
|
8532 TBool ret( EFalse ); |
|
8533 if ( iEdwinExtension->iSmiley ) |
|
8534 { |
|
8535 TInt oldPos( CursorPos() ); |
|
8536 TInt curPos( oldPos ); |
|
8537 if ( aMovement == TCursorPosition::EFLeft ) |
|
8538 { |
|
8539 curPos--; |
|
8540 } |
|
8541 else if ( aMovement == TCursorPosition::EFRight ) |
|
8542 { |
|
8543 curPos++; |
|
8544 } |
|
8545 iEdwinExtension->iSmiley->HandleSetCursor( oldPos, curPos ); |
|
8546 if ( oldPos != curPos ) |
|
8547 { |
|
8548 SetCursorPosL( curPos, aSelect ); |
|
8549 ret = ETrue; |
|
8550 } |
|
8551 } |
|
8552 return ret; |
|
8553 } |
|
8554 |
|
8555 void CEikEdwin::SetSelectionVisibilityL( TBool isVisable ) |
|
8556 { |
|
8557 iTextView->SetSelectionVisibilityL(isVisable); |
|
8558 CAknEdwinState*edwinState = EditorState(); |
|
8559 if( !edwinState ) |
|
8560 return; |
|
8561 if(isVisable) |
|
8562 { |
|
8563 SetAknEditorFlags( edwinState->Flags() | EAknEditorFlagSelectionVisible ); |
|
8564 } |
|
8565 else |
|
8566 { |
|
8567 SetAknEditorFlags( edwinState->Flags() & ~EAknEditorFlagSelectionVisible ); |
|
8568 } |
|
8569 return; |
|
8570 } |
|
8571 TBool CEikEdwin::IsSelectionVisible() |
|
8572 { |
|
8573 TBool ret = EFalse; |
|
8574 const TCursorSelection selection=iTextView->Selection(); |
|
8575 if (selection.Length() == 0) |
|
8576 return ret; |
|
8577 TPtrC text = iText->Read( selection.LowerPos(), selection.Length() ); |
|
8578 for (TInt i = 0; i < text.Length(); i++) |
|
8579 { |
|
8580 TChar character(text[i]); |
|
8581 if (text[i] == ' ') |
|
8582 return ETrue; |
|
8583 |
|
8584 TChar::TCategory category = character.GetCategory(); |
|
8585 |
|
8586 if ( !((category&TChar::ESeparatorGroup == TChar::ESeparatorGroup) || |
|
8587 (text[i]>=0x200B && text[i]<=0xFFFC)) ) |
|
8588 { |
|
8589 ret = ETrue; |
|
8590 break; |
|
8591 } |
|
8592 } |
|
8593 return ret; |
|
8594 } |
|
8595 |
|
8596 // --------------------------------------------------------------------------- |
|
8597 // CEikEdwin::ScrollView |
|
8598 // --------------------------------------------------------------------------- |
|
8599 // |
|
8600 TInt CEikEdwin::ScrollView( TInt aPixelsToScroll, TBool& aBorderExceeded, TInt& aRestOfPixels ) |
|
8601 { |
|
8602 EnableRateScrolling( ETrue ); |
|
8603 TInt scrolledPixels( aPixelsToScroll ); |
|
8604 |
|
8605 // Normal scrolling, we need to use old function because |
|
8606 // we know from return value if border has been exceeded |
|
8607 // This function call updates scrolledPixels to number |
|
8608 // of actually scrolled pixels. |
|
8609 |
|
8610 TRAP_IGNORE( iTextView->ScrollDisplayPixelsL( scrolledPixels ) ); |
|
8611 |
|
8612 if ( scrolledPixels != aPixelsToScroll ) |
|
8613 { |
|
8614 // We can't move enough, we have exceeded the border |
|
8615 // (at the beginning or end of the document) |
|
8616 if ( aPixelsToScroll != 0 ) |
|
8617 { |
|
8618 if ( aPixelsToScroll < 0 ) |
|
8619 { |
|
8620 // End of document. Set flag to tell about that |
|
8621 iEdwinExtension->iEndBorderExceeded = ETrue; |
|
8622 aBorderExceeded = ETrue; |
|
8623 } |
|
8624 else |
|
8625 { |
|
8626 // Beginning of document. Set flag to tell about that |
|
8627 iEdwinExtension->iStartBorderExceeded = ETrue; |
|
8628 aBorderExceeded = ETrue; |
|
8629 } |
|
8630 |
|
8631 // Calculate how many pixels more we should scroll and |
|
8632 // return it in variable |
|
8633 aRestOfPixels = aPixelsToScroll - scrolledPixels; |
|
8634 |
|
8635 // Set variable how many pixels we are out of border |
|
8636 iEdwinExtension->iPixelsOutOfBorder = 0; |
|
8637 } |
|
8638 } |
|
8639 |
|
8640 if ( scrolledPixels != 0 ) |
|
8641 { |
|
8642 iEdwinExtension->iScrolledDelta = scrolledPixels; |
|
8643 TRAP_IGNORE( UpdateVertScrollBarThumbL() ); |
|
8644 iEdwinExtension->iScrolledDelta = 0; |
|
8645 } |
|
8646 |
|
8647 EnableRateScrolling( EFalse ); |
|
8648 return scrolledPixels; |
|
8649 } |
|
8650 |
|
8651 // --------------------------------------------------------------------------- |
|
8652 // CEikEdwin::ScrollViewWithBounce |
|
8653 // --------------------------------------------------------------------------- |
|
8654 // |
|
8655 TInt CEikEdwin::ScrollViewWithBounce( TInt aPixelsToScroll, |
|
8656 TBool& aEndOfBounce, TInt& aRestOfPixels ) |
|
8657 { |
|
8658 aEndOfBounce = EFalse; |
|
8659 aRestOfPixels = 0; |
|
8660 EnableRateScrolling( ETrue ); |
|
8661 |
|
8662 // We have to check here if we are moving enough so that bounce |
|
8663 // ends (scrolling over the border toward content). In this case we |
|
8664 // can use ScrollDisplayPixelsNoLimitBorderL to scroll only to border. |
|
8665 // After that we have to move to mode where we use ScrollDisplayPixelsL |
|
8666 // to detect if we exceed border again. |
|
8667 TBool adjustScrolling( EFalse ); |
|
8668 if ( aPixelsToScroll > 0 && iEdwinExtension->iEndBorderExceeded ) |
|
8669 { |
|
8670 if ( aPixelsToScroll > - iEdwinExtension->iPixelsOutOfBorder ) |
|
8671 { |
|
8672 adjustScrolling = ETrue; |
|
8673 } |
|
8674 } |
|
8675 else if ( aPixelsToScroll < 0 && iEdwinExtension->iStartBorderExceeded ) |
|
8676 { |
|
8677 if ( aPixelsToScroll < - iEdwinExtension->iPixelsOutOfBorder ) |
|
8678 { |
|
8679 adjustScrolling = ETrue; |
|
8680 } |
|
8681 } |
|
8682 |
|
8683 if ( adjustScrolling ) |
|
8684 { |
|
8685 // we are scrolling over the border, calculate how many |
|
8686 // pixels we can scroll and how many pixels there is rest |
|
8687 // after movement |
|
8688 aRestOfPixels = aPixelsToScroll + iEdwinExtension->iPixelsOutOfBorder; |
|
8689 aPixelsToScroll = -iEdwinExtension->iPixelsOutOfBorder; |
|
8690 } |
|
8691 |
|
8692 // We are out of borders. Call scrolling function that supports bounce-effect |
|
8693 TRAP_IGNORE( iTextView->ScrollDisplayPixelsNoLimitBorderL( aPixelsToScroll ) ); |
|
8694 |
|
8695 // Update variable that tells how near the border we are. |
|
8696 iEdwinExtension->iPixelsOutOfBorder += aPixelsToScroll; |
|
8697 |
|
8698 if ( iEdwinExtension->iStartBorderExceeded |
|
8699 && iEdwinExtension->iPixelsOutOfBorder <= 0 ) |
|
8700 { |
|
8701 // We are inside borders, reset flag and tell to caller |
|
8702 iEdwinExtension->iStartBorderExceeded = EFalse; |
|
8703 aEndOfBounce = ETrue; |
|
8704 } |
|
8705 else if ( iEdwinExtension->iEndBorderExceeded |
|
8706 && iEdwinExtension->iPixelsOutOfBorder >= 0 ) |
|
8707 { |
|
8708 // we are inside borders, reset flag and tell to caller |
|
8709 iEdwinExtension->iEndBorderExceeded = EFalse; |
|
8710 aEndOfBounce = ETrue; |
|
8711 } |
|
8712 |
|
8713 if ( aPixelsToScroll != 0 ) |
|
8714 { |
|
8715 TRAP_IGNORE( UpdateVertScrollBarThumbL() ); |
|
8716 } |
|
8717 EnableRateScrolling( EFalse ); |
|
8718 // Return how many pixels we actually moved. It can be different to |
|
8719 // value what user requested |
|
8720 return aPixelsToScroll; |
|
8721 } |
|
8722 |
|
8723 // --------------------------------------------------------------------------- |
|
8724 // CEikEdwin::PixelsOutOfBorder |
|
8725 // --------------------------------------------------------------------------- |
|
8726 // |
|
8727 TInt CEikEdwin::PixelsOutOfBorder() const |
|
8728 { |
|
8729 return iEdwinExtension->iPixelsOutOfBorder; |
|
8730 } |
|
8731 |
|
8732 // --------------------------------------------------------------------------- |
|
8733 // CEikEdwin::EnableRateScrolling |
|
8734 // --------------------------------------------------------------------------- |
|
8735 // |
|
8736 void CEikEdwin::EnableRateScrolling( TBool aEnable ) |
|
8737 { |
|
8738 // This function is related to Rate scrolling implementation. |
|
8739 // See comments in function SetKineticScrollingScrollbarModelL |
|
8740 // for more information about Rate scrolling. |
|
8741 |
|
8742 // Use this function to change scrolling mode. |
|
8743 // If aEnable is EFalse, Position scrolling mode is in use. |
|
8744 // If aEnable is ETrue, Rate scrolling mode is in use. |
|
8745 |
|
8746 iEdwinExtension->iUseRateScroll = aEnable; |
|
8747 } |
|
8748 |
|
8749 // --------------------------------------------------------------------------- |
|
8750 // CEikEdwin::StoreCursorState |
|
8751 // --------------------------------------------------------------------------- |
|
8752 // |
|
8753 void CEikEdwin::StoreCursorState() |
|
8754 { |
|
8755 CAknEdwinState* state( EditorState() ); |
|
8756 if ( state && state->Flags() & EAknEditorFlagTextCursorVisible ) |
|
8757 { |
|
8758 TRAP_IGNORE( SetCursorVisibilityL( EFalse ) ); |
|
8759 iEdwinExtension->iCursorWasVisible = ETrue; |
|
8760 } |
|
8761 } |
|
8762 |
|
8763 // --------------------------------------------------------------------------- |
|
8764 // CEikEdwin::RestoreCursorState |
|
8765 // --------------------------------------------------------------------------- |
|
8766 // |
|
8767 void CEikEdwin::RestoreCursorState() |
|
8768 { |
|
8769 if ( iEdwinExtension->iCursorWasVisible ) |
|
8770 { |
|
8771 TRAP_IGNORE( SetCursorVisibilityL( ETrue ) ); |
|
8772 iEdwinExtension->iCursorWasVisible = EFalse; |
|
8773 } |
|
8774 } |
|
8775 |
|
8776 // --------------------------------------------------------------------------- |
|
8777 // CEikEdwin::KineticScrollingEnabled |
|
8778 // --------------------------------------------------------------------------- |
|
8779 // |
|
8780 TBool CEikEdwin::KineticScrollingEnabled() const |
|
8781 { |
|
8782 return iEdwinExtension && iEdwinExtension->iPhysicsHandler; |
|
8783 } |
|
8784 |
|
8785 |
|
8786 void CEikEdwin::HandleSelectionForSmiley( TCursorSelection aSelect ) |
|
8787 { |
|
8788 if ( !iEdwinExtension->iSmiley ) |
|
8789 { |
|
8790 return; |
|
8791 } |
|
8792 if ( iCustomDrawer ) |
|
8793 { |
|
8794 iEdwinExtension->iSmiley->SetHighlightColor( |
|
8795 iCustomDrawer->SystemColor( TLogicalRgb::ESystemSelectionBackgroundIndex, |
|
8796 KRgbWhite ) ); |
|
8797 } |
|
8798 iEdwinExtension->iSmiley->HandleSelection( aSelect.LowerPos(), |
|
8799 aSelect.Length() ); |
|
8800 } |
|
8801 |
|
8802 // --------------------------------------------------------------------------- |
|
8803 // CEikEdwin::SkipBackgroundDrawer |
|
8804 // --------------------------------------------------------------------------- |
|
8805 // |
|
8806 TBool CEikEdwin::SkipBackgroundDrawer() const |
|
8807 { |
|
8808 return iEdwinInternalFlags & ESkipBackgroundDrawer; |
|
8809 } |
|
8810 |
|
8811 TBool CEikEdwin::IsValidNumericCharL( TChar aChar ) |
|
8812 { |
|
8813 TBool ret(ETrue); |
|
8814 CAknEdwinState* state = static_cast<CAknEdwinState*>( iEdwinFepSupport->State( KNullUid ) ); |
|
8815 if (state && state->CurrentInputMode() == EAknEditorNumericInputMode ) |
|
8816 { |
|
8817 HBufC* allowedChars = GetAllowedCharsLC(); |
|
8818 if ( (*allowedChars).Length() > 0 && (*allowedChars).Locate( aChar ) == KErrNotFound ) |
|
8819 { |
|
8820 ret = EFalse; |
|
8821 } |
|
8822 CleanupStack::PopAndDestroy(1);//allowedChars |
|
8823 } |
|
8824 return ret; |
|
8825 } |
|
8826 |
|
8827 // End of File |
|
8828 |