|
1 /* |
|
2 * Copyright (c) 1997-2009 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 "FRMTLAY.H" |
|
20 #include "FRMTVIEW.H" |
|
21 #include "FRMCONST.H" |
|
22 |
|
23 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS |
|
24 #include "FRMCONST_INTERNAL.H" |
|
25 #include "FRMCONST_PARTNER.H" |
|
26 #include "TAGMA_INTERNAL.H" |
|
27 #endif |
|
28 |
|
29 /** Reports whether a character is a virama (indic vowel-killer, |
|
30 used for joining syllables together) or not. |
|
31 @param aCharacter The character. |
|
32 @return ETrue if aCharacter is a virama. |
|
33 @internalComponent */ |
|
34 TBool IsVirama(TChar aCharacter) |
|
35 { |
|
36 // Unicode combining class 9 indicates a virama |
|
37 return aCharacter.GetCombiningClass() == 9; |
|
38 } |
|
39 |
|
40 /** |
|
41 Reports whether a character is a graphical spacing character or not. |
|
42 @param aCharacter Unicode UTF32 character to test. |
|
43 @return ETrue if it is both graphical and not a combining mark. |
|
44 @internalComponent |
|
45 */ |
|
46 TBool IsGraphicalSpacing(TChar aCharacter) |
|
47 { |
|
48 TChar::TCategory cat = aCharacter.GetCategory(); |
|
49 switch (cat & 0xF0) |
|
50 { |
|
51 case TChar::EAlphaGroup: |
|
52 case TChar::ELetterOtherGroup: |
|
53 case TChar::ELetterModifierGroup: |
|
54 case TChar::ENumberGroup: |
|
55 case TChar::EPunctuationGroup: |
|
56 case TChar::ESymbolGroup: |
|
57 return ETrue; |
|
58 default: |
|
59 return EFalse; |
|
60 } |
|
61 } |
|
62 |
|
63 TCursor::TCursor(TCursorPosition& aCursorPos,RScreenDisplay& aDisplay): |
|
64 iDisplay(aDisplay), |
|
65 iCursorPos(aCursorPos), |
|
66 iVisible(FALSE), |
|
67 iFlash(TRUE), |
|
68 iLineCursor(EFCursorInvisible), |
|
69 iTextCursor(EFCursorInvisible), |
|
70 iLineCursorBitmap(NULL), |
|
71 iAscent(-1), |
|
72 iDescent(-1), |
|
73 iWeight(ETextCursorWeight), |
|
74 iType(TTextCursor::ETypeRectangle), |
|
75 iXorColor(ETextCursorInvertColor), |
|
76 iPlacement(ECursorVertical) |
|
77 { |
|
78 } |
|
79 |
|
80 void TCursor::SetLineCursorBitmap(const CFbsBitmap* aLineCursorBitmap) |
|
81 { |
|
82 iLineCursorBitmap=aLineCursorBitmap; |
|
83 } |
|
84 |
|
85 /** |
|
86 Sets the selection highlight to have its edges moved by the specified number of pixels. |
|
87 Problems with highlights appearing in the wrong place may be due to incorrect |
|
88 font metrics, and would not be fixed in general with a call to this function. |
|
89 @param aLeftExtension |
|
90 Number of pixels to the left to move the left of the highlight. |
|
91 @param aRightExtension |
|
92 Number of pixels to the right to move the right of the highlight. |
|
93 @param aTopExtension |
|
94 Number of pixels to the up to move the top of the highlight. |
|
95 @param aBottomExtension |
|
96 Number of pixels to the down to move the bottom of the highlight. |
|
97 */ |
|
98 EXPORT_C void CTextView::SetHighlightExtensions(TInt aLeftExtension, |
|
99 TInt aRightExtension, TInt aTopExtension, TInt aBottomExtension) |
|
100 { |
|
101 iLayout->SetHighlightExtensions(aLeftExtension, aRightExtension, |
|
102 aTopExtension, aBottomExtension); |
|
103 } |
|
104 |
|
105 /** |
|
106 Set the delta required to position the baseline so there is enough |
|
107 space for the highset glyph in pixels. This is the height of the highest glyph - |
|
108 CFont::AscentInPixels(). Only used when using TLineSpacingControl::EAttLineSpacingControl. |
|
109 By default zero. |
|
110 @param aExcessHeightRequired |
|
111 Extra height above CFont::AscentInPixels() required for the highest glyph in pixels. |
|
112 */ |
|
113 EXPORT_C void CTextView::SetExcessHeightRequired(TInt aExcessHeightRequired) |
|
114 { |
|
115 iLayout->SetExcessHeightRequired( aExcessHeightRequired ); |
|
116 } |
|
117 |
|
118 void TCursor::SetVisibility(TVisibility aLineCursor,TVisibility aTextCursor) |
|
119 { |
|
120 TUint cursorsToDraw=EFNeitherCursor; |
|
121 |
|
122 if (aLineCursor==EFCursorFlashing) |
|
123 aLineCursor=EFCursorVisible; |
|
124 if (iLineCursor!=aLineCursor) |
|
125 { |
|
126 iLineCursor=aLineCursor; |
|
127 cursorsToDraw|=EFLineCursor; |
|
128 } |
|
129 if (iTextCursor!=aTextCursor) |
|
130 { |
|
131 iTextCursor=aTextCursor; |
|
132 cursorsToDraw|=EFTextCursor; |
|
133 } |
|
134 Draw(cursorsToDraw); |
|
135 } |
|
136 |
|
137 // Change the cursor type and redraw it. |
|
138 void TCursor::SetType(TTextCursor::EType aType) |
|
139 { |
|
140 if (aType != TTextCursor::ETypeNone) |
|
141 { |
|
142 iType = aType; |
|
143 Draw(EFTextCursor); |
|
144 } |
|
145 } |
|
146 |
|
147 // Change the cursor placement and redraw it. |
|
148 void TCursor::SetPlacement(TTmCursorPlacement aPlacement) |
|
149 { |
|
150 iPlacement = aPlacement; |
|
151 Draw(EFTextCursor); |
|
152 } |
|
153 |
|
154 /** Sets the ascent and descent of the text cursor in pixels and redraw it. To |
|
155 use the ascent or descent of the adjacent character pass a value of -1. */ |
|
156 void TCursor::SetAscentAndDescent(TInt aAscent,TInt aDescent) |
|
157 { |
|
158 iAscent = aAscent; |
|
159 iDescent = aDescent; |
|
160 Draw(EFTextCursor); |
|
161 } |
|
162 |
|
163 /** Changes the cursor weight and redraws it.*/ |
|
164 void TCursor::SetWeight(TInt aWeight) |
|
165 { |
|
166 if (aWeight > 0) |
|
167 { |
|
168 iWeight = aWeight; |
|
169 Draw(EFTextCursor); |
|
170 } |
|
171 } |
|
172 |
|
173 /** Sets the flashing state of the cursor and redraws it. */ |
|
174 void TCursor::SetFlash(TBool aEnabled) |
|
175 { |
|
176 iFlash = aEnabled; |
|
177 Draw(EFTextCursor); |
|
178 } |
|
179 |
|
180 /** Sets the XOR colour of the cursor and redraws it. */ |
|
181 void TCursor::SetXorColor(TRgb aColor) |
|
182 { |
|
183 iXorColor = aColor; |
|
184 Draw(EFTextCursor); |
|
185 } |
|
186 |
|
187 /** Sets the cursor so that when it is next drawn its metrics will match those |
|
188 of adjacent text: cancels any overriding metrics. Does not redraw. */ |
|
189 void TCursor::MatchCursorHeightToAdjacentChar() |
|
190 { |
|
191 iAscent = iDescent = -1; |
|
192 } |
|
193 |
|
194 /** Draws the specified cursors. */ |
|
195 void TCursor::Draw(TUint aCursors) |
|
196 { |
|
197 TPoint caret_origin; |
|
198 TInt caret_width, caret_ascent, caret_descent; |
|
199 TBool cursorsVisible = iCursorPos.GetCursor((TTmCursorPlacement)iPlacement, |
|
200 caret_origin,caret_width,caret_ascent,caret_descent); |
|
201 caret_origin += iDisplay.TopLeftTextArea(); |
|
202 |
|
203 if (aCursors & EFTextCursor) |
|
204 { |
|
205 if (cursorsVisible && (iTextCursor != EFCursorInvisible) && !iCursorPos.IsNewPictureFrame()) |
|
206 { |
|
207 if (iTextCursor == EFCursorVisible) |
|
208 RemoveTextCursor(); |
|
209 else |
|
210 { |
|
211 int ascent = 0; |
|
212 int descent = 0; |
|
213 int width = 0; |
|
214 |
|
215 if (iPlacement == ECursorVertical) |
|
216 { |
|
217 if (iAscent >= 0) |
|
218 ascent = iAscent; |
|
219 else |
|
220 ascent = caret_ascent; |
|
221 ascent += iFirstExtension; |
|
222 if (iDescent >= 0) |
|
223 descent = iDescent; |
|
224 else |
|
225 descent = caret_descent; |
|
226 descent += iSecondExtension; |
|
227 width = iWeight; |
|
228 // Adjust which side the cursor hangs around the origin |
|
229 // based on the sign of the 'width' from tagma. |
|
230 if (caret_width<0) |
|
231 caret_origin.iX -= iWeight; |
|
232 |
|
233 } |
|
234 else |
|
235 { |
|
236 ascent = 0; |
|
237 descent = iWeight; |
|
238 // Adjust which side the cursor hangs around the origin |
|
239 // based on the sign of the 'width' from tagma and set the |
|
240 // drawn width to the abs(width) value tagma has given us. |
|
241 if (caret_width < 0) |
|
242 { |
|
243 width = -caret_width; |
|
244 caret_origin.iX -= width; |
|
245 } |
|
246 else |
|
247 width = caret_width; |
|
248 caret_origin.iX -= iFirstExtension; |
|
249 width += (iFirstExtension + iSecondExtension); |
|
250 } |
|
251 DrawTextCursor(caret_origin,width,ascent,descent); |
|
252 } |
|
253 } |
|
254 else |
|
255 RemoveTextCursor(); |
|
256 } |
|
257 if (iDisplay.IsLineCursor() && (aCursors&EFLineCursor)) |
|
258 { |
|
259 if (cursorsVisible && (iLineCursor != EFCursorInvisible)) |
|
260 DrawLineCursor(caret_origin.iY); |
|
261 else |
|
262 RemoveLineCursor(); |
|
263 } |
|
264 } |
|
265 |
|
266 void TCursor::DrawLineCursor(TInt aHeight) |
|
267 { |
|
268 __ASSERT_ALWAYS(iLineCursorBitmap,FormPanic(EFLineCursorBitmapNotSet)); |
|
269 TRect cursorMargin=iDisplay.LineCursorMargin(); |
|
270 TRect bitmapRect; |
|
271 |
|
272 bitmapRect.iTl.iX=cursorMargin.iTl.iX+ELineCursorToLabelGap; |
|
273 bitmapRect.iBr.iX=bitmapRect.iTl.iX+iLineCursorBitmap->SizeInPixels().iWidth; |
|
274 bitmapRect.iBr.iY=aHeight; |
|
275 bitmapRect.iTl.iY=aHeight-iLineCursorBitmap->SizeInPixels().iHeight; |
|
276 |
|
277 iDisplay.SetRects(RScreenDisplay::EFClipLineCursor); |
|
278 iDisplay.ActivateContext(); |
|
279 iDisplay.ResetClippingRect(); |
|
280 |
|
281 if (iDisplay.UseWindowGc() && NULL != iDisplay.Layout()) |
|
282 { |
|
283 iDisplay.Layout()->BeginRedraw(cursorMargin); |
|
284 } |
|
285 |
|
286 TRegionFix<4> clearRegion(cursorMargin); |
|
287 clearRegion.SubRect(bitmapRect); |
|
288 |
|
289 for (TUint ii=0; ii<(TUint)clearRegion.Count(); ii++) |
|
290 { |
|
291 iDisplay.ClearRect(clearRegion.RectangleList()[ii]); |
|
292 } |
|
293 |
|
294 iDisplay.BlastBitmap(bitmapRect.iTl,iLineCursorBitmap,TRect(TPoint(0,0),bitmapRect.Size())); |
|
295 if (iDisplay.UseWindowGc() && NULL != iDisplay.Layout()) |
|
296 { |
|
297 iDisplay.Layout()->EndRedraw(); |
|
298 } |
|
299 |
|
300 iDisplay.DeactivateContext(); |
|
301 } |
|
302 |
|
303 void TCursor::RemoveLineCursor() |
|
304 { |
|
305 TRect cursorMargin=iDisplay.LineCursorMargin(); |
|
306 iDisplay.SetRects(RScreenDisplay::EFClipLineCursor); |
|
307 iDisplay.ActivateContext(); |
|
308 iDisplay.ResetClippingRect(); |
|
309 |
|
310 if (iDisplay.UseWindowGc() && NULL != iDisplay.Layout()) |
|
311 { |
|
312 iDisplay.Layout()->BeginRedraw(cursorMargin); |
|
313 } |
|
314 iDisplay.ClearRect(cursorMargin); |
|
315 if (iDisplay.UseWindowGc() && NULL != iDisplay.Layout()) |
|
316 { |
|
317 iDisplay.Layout()->EndRedraw(); |
|
318 } |
|
319 |
|
320 iDisplay.DeactivateContext(); |
|
321 } |
|
322 |
|
323 /** Draws the text cursor. */ |
|
324 void TCursor::DrawTextCursor(TPoint aOrigin,TInt aWidth,TInt aAscent,TInt aDescent) |
|
325 { |
|
326 TTextCursor cursor; |
|
327 cursor.iType = iType; |
|
328 cursor.iHeight = aAscent + aDescent; |
|
329 cursor.iAscent = aAscent; |
|
330 cursor.iWidth = aWidth; |
|
331 cursor.iFlags = iFlash ? 0 : TTextCursor::EFlagNoFlash; |
|
332 if (iPlacement == ECursorVertical) |
|
333 cursor.iFlags |= TTextCursor::EFlagClipVertical; |
|
334 if (iPlacement == ECursorUnderlineNext || iPlacement == ECursorUnderlinePrev) |
|
335 cursor.iFlags |= TTextCursor::EFlagClipHorizontal; |
|
336 cursor.iColor = iXorColor; |
|
337 iDisplay.SetTextCursor(aOrigin,cursor); |
|
338 iVisible = TRUE; |
|
339 } |
|
340 |
|
341 /** Removes the text cursor only if it is currently visible in this window. */ |
|
342 void TCursor::RemoveTextCursor() |
|
343 { |
|
344 if (iVisible) |
|
345 { |
|
346 iDisplay.RemoveTextCursor(); |
|
347 iVisible = FALSE; |
|
348 } |
|
349 } |
|
350 |
|
351 void TCursor::SetExtensions(TInt aFirstExtension, TInt aSecondExtension) |
|
352 { |
|
353 TBool redraw=EFalse; |
|
354 if (aFirstExtension!=iFirstExtension) |
|
355 { |
|
356 iFirstExtension=aFirstExtension; |
|
357 redraw=ETrue; |
|
358 } |
|
359 if (aSecondExtension!=iSecondExtension) |
|
360 { |
|
361 iSecondExtension=aSecondExtension; |
|
362 redraw=ETrue; |
|
363 } |
|
364 if( redraw) |
|
365 Draw(EFTextCursor); |
|
366 } |
|
367 |
|
368 /** Allocates and constructs a CTextView object. |
|
369 |
|
370 @param aLayout Pointer to the layout object referenced by the text view. Must |
|
371 not be NULL or a panic occurs. |
|
372 @param aDisplay The rectangle in which text is displayed (the "view rectangle"). |
|
373 |
|
374 @param aGd Bitmapped graphics device to draw to, e.g. the screen. |
|
375 @param aDeviceMap The device map used for drawing and formatting. |
|
376 @param aWin The window to draw to. Should not be NULL. |
|
377 @param aGroupWin Window group. Must be provided if a text cursor is to be displayed. |
|
378 It can be NULL if you don't need a text cursor. |
|
379 @param aSession Pointer to the window server session. |
|
380 @return Pointer to the new CTextView object. */ |
|
381 EXPORT_C CTextView *CTextView::NewL(CTextLayout *aLayout,const TRect &aDisplay,CBitmapDevice *aGd, |
|
382 MGraphicsDeviceMap *aDeviceMap,RWindow *aWin,RWindowGroup *aGroupWin, |
|
383 RWsSession *aSession) |
|
384 { |
|
385 CTextView* self = new(ELeave) CTextView(); |
|
386 CleanupStack::PushL(self); |
|
387 self->ConstructL(aLayout,aDisplay,aGd,aDeviceMap,aWin,aGroupWin,aSession); |
|
388 CleanupStack::Pop(); |
|
389 return self; |
|
390 } |
|
391 |
|
392 /** Called when system is idle. Use to do background formatting. Enters OOM |
|
393 state before leaving */ |
|
394 EXPORT_C TInt CTextView::IdleL(TAny *aSelf) |
|
395 { |
|
396 |
|
397 if (((CTextView *) aSelf)->NoMemoryCheckL()) |
|
398 return EFalse; |
|
399 return ((CTextView *) aSelf)->NextLineL(); |
|
400 } |
|
401 |
|
402 EXPORT_C CTextView::CTextView(): |
|
403 iDisplay(&iDrawTextLayoutContext), |
|
404 iCursor(iCursorPos,iDisplay), |
|
405 iCursorPos(), |
|
406 iFlags(EFEverythingVisible | EFFlickerFreeRedraw | EFTextVisible), |
|
407 iHorizontalScroll(EFNoPreviousHorizontalScroll), |
|
408 iContextIsNavigation(ETrue) |
|
409 { |
|
410 __ASSERT_DEBUG(EFMemoryOK != EFRecovering,FormPanic(EFSystemConstantsChanged)); |
|
411 } |
|
412 |
|
413 EXPORT_C void CTextView::ConstructL(CTextLayout *aLayout,const TRect &aDisplay,CBitmapDevice *aGd, |
|
414 MGraphicsDeviceMap *aDeviceMap,RWindow *aWin,RWindowGroup *aGroupWin, |
|
415 RWsSession *aSession) |
|
416 { |
|
417 __ASSERT_ALWAYS(aLayout,FormPanic(EFInvalidLayout)); |
|
418 iHorizontalScrollJump=EFDefaultHorizontalScrollJump; |
|
419 iWrap = CIdle::NewL(EFBackgroundFormattingPriority); |
|
420 SetLayout(aLayout); |
|
421 SetViewRect(aDisplay); |
|
422 SetDisplayContextL(aGd,aWin,aGroupWin,aSession); |
|
423 // Tell the Layout classes about the Graphics Device |
|
424 aLayout->SetImageDeviceMap(aDeviceMap); |
|
425 iDrawTextLayoutContext.SetDrawToEveryPixel(ETrue); |
|
426 } |
|
427 |
|
428 EXPORT_C CTextView::~CTextView() |
|
429 { |
|
430 delete iPictureFrame; |
|
431 delete iWrap; |
|
432 DestroyWindowServerObjects(); |
|
433 } |
|
434 |
|
435 /** Changes the text layout object used by the text view. |
|
436 |
|
437 @param aLayout Pointer to the text layout object used by the text view. Must |
|
438 not be NULL or a panic occurs. */ |
|
439 EXPORT_C void CTextView::SetLayout(CTextLayout *aLayout) |
|
440 { |
|
441 __ASSERT_ALWAYS(aLayout,FormPanic(EFInvalidLayout)); |
|
442 iLayout = aLayout; |
|
443 iCursorPos.SetLayout(aLayout); |
|
444 iDisplay.SetLayout(aLayout); |
|
445 } |
|
446 |
|
447 /** Changes the window server handles which the display uses. Any of the parameters |
|
448 can be NULL in which case they are not changed. |
|
449 |
|
450 @param aGd Pointer to the bitmapped graphics device to draw to. |
|
451 @param aWin Pointer to the view window. |
|
452 @param aGroupWin Pointer to the window group. |
|
453 @param aSession Pointer to the window server session. */ |
|
454 EXPORT_C void CTextView::SetDisplayContextL(CBitmapDevice * aGd,RWindow *aWin,RWindowGroup *aGroupWin,RWsSession *aSession) |
|
455 { |
|
456 if (aSession) |
|
457 iDisplay.SetWindowsServer(aSession); |
|
458 if (aGroupWin) |
|
459 iDisplay.SetWindowGroup(aGroupWin); |
|
460 if (aWin) |
|
461 { |
|
462 iDisplay.SetWindow(aWin); |
|
463 iLayout->SetWindow(aWin); |
|
464 } |
|
465 if (aGd) |
|
466 iDisplay.SetGraphicsDeviceL(aGd); |
|
467 } |
|
468 |
|
469 /** Sets the rectangle in which the text is displayed. |
|
470 |
|
471 |
|
472 Note: |
|
473 |
|
474 A valid band height (>0) must be supplied(i.e. aViewRect.Tl.iY coordinate must be lower than the aViewRect.Br.iY coordinate) or the expected amount of formatting will not take place. This could lead to panics when trying to retrieve formatting information that does not exist. |
|
475 |
|
476 @param aDisplay The view rectangle. */ |
|
477 EXPORT_C void CTextView::SetViewRect(const TRect &aViewRect) |
|
478 { |
|
479 iDrawTextLayoutContext.iViewRect = aViewRect; |
|
480 iLayout->SetBandHeight(aViewRect.Height()); |
|
481 |
|
482 TRect oldViewRect = iDrawTextLayoutContext.iViewRect; |
|
483 |
|
484 iDrawTextLayoutContext.iViewRect = aViewRect; |
|
485 iLayout->SetBandHeight(aViewRect.Height()); |
|
486 |
|
487 if (NULL != iDisplay.Window() && ! oldViewRect.IsEmpty()) |
|
488 { |
|
489 iDisplay.Window()->Invalidate(oldViewRect); |
|
490 } |
|
491 } |
|
492 |
|
493 |
|
494 // deprecated, planning to remove |
|
495 EXPORT_C void CTextView::AlterViewRect(const TRect &aViewRect) |
|
496 { |
|
497 iReducedDrawingAreaRect = aViewRect; |
|
498 } |
|
499 |
|
500 /** Sets the label and line cursor margin widths. |
|
501 |
|
502 Does not redraw. |
|
503 |
|
504 @param aLabels The width in pixels of the label margin. |
|
505 @param aLineCursor The width in pixels of the line cursor margin. */ |
|
506 EXPORT_C void CTextView::SetMarginWidths(TInt aLabels,TInt aLineCursor) |
|
507 { |
|
508 iDrawTextLayoutContext.iLabelMarginWidth = aLabels; |
|
509 iDrawTextLayoutContext.iGutterMarginWidth = aLineCursor; |
|
510 iLayout->SetLabelsMarginWidth(aLabels); |
|
511 } |
|
512 |
|
513 /** Gets the label and line cursor margin widths in pixels. |
|
514 |
|
515 @param aLabels On return contains the width in pixels of the label margin. |
|
516 @param aLineCursor On return contains the width in pixels of the line cursor |
|
517 margin. */ |
|
518 EXPORT_C void CTextView::MarginWidths(TInt& aLabels,TInt& aLineCursor) const |
|
519 { |
|
520 aLineCursor = iDrawTextLayoutContext.iGutterMarginWidth; |
|
521 aLabels = iDrawTextLayoutContext.iLabelMarginWidth; |
|
522 } |
|
523 |
|
524 /** Removes a selection, and redraws the affected part of the screen. |
|
525 |
|
526 Any background formatting is forced to complete first. */ |
|
527 EXPORT_C void CTextView::CancelSelectionL() |
|
528 { |
|
529 TCursorSelection selection; |
|
530 |
|
531 NoMemoryCheckL(); |
|
532 iCursorPos.GetSelection(selection); |
|
533 TBool isPictureFrame=iCursorPos.IsPictureFrame(); |
|
534 if (selection.Length()>0) |
|
535 { |
|
536 iCursorPos.CancelHighlight(); |
|
537 if (!SelectionVisible()) |
|
538 return; |
|
539 iDisplay.SetRects(RScreenDisplay::EFClipExtendedTextArea); |
|
540 iDisplay.ActivateContext(); |
|
541 iDisplay.ResetClippingRect(); |
|
542 if (isPictureFrame) |
|
543 { |
|
544 RedrawPictureFrameRectL(selection.LowerPos()); // iCursorPos.CancelHighlight() was called, so the picture will be redrawn without frame |
|
545 DrawCursor(TCursor::EFTextCursor); |
|
546 } |
|
547 else |
|
548 { |
|
549 CTextLayout::TRangeChange clear_range(selection.iAnchorPos, selection.iCursorPos,CTextLayout::TRangeChange::EClear); |
|
550 CTextLayout::TRangeChange original(selection.iCursorPos,selection.iCursorPos,CTextLayout::TRangeChange::ESet); |
|
551 HighlightUsingExtensions(clear_range, original); |
|
552 } |
|
553 } |
|
554 iDisplay.DeactivateContext(); |
|
555 } |
|
556 |
|
557 /** This function should not be used. This function is used in TTextView to |
|
558 test a fix for a defect. |
|
559 @internalTechnology */ |
|
560 EXPORT_C CBitmapContext* CTextView::BitmapContext() |
|
561 { |
|
562 return iDisplay.BitmapContext(); |
|
563 } |
|
564 |
|
565 /** Calculates which of two document positions would be considered more left or |
|
566 more right, depending on the value of aDirection. |
|
567 |
|
568 @param aStart First document position to compare. |
|
569 @param aEnd Second document position to compare. |
|
570 @param aDirection If EVisualLeft, the function returns the left-most of aStart |
|
571 and aEnd. If EVisualRight, the function returns the right-most. |
|
572 @return The left-most of aStart and aEnd if aDirection was EVisualLeft; |
|
573 otherwise, the right-most. */ |
|
574 EXPORT_C const TTmDocPos& CTextView::VisualEndOfRunL( |
|
575 const TTmDocPos& aStart, const TTmDocPos& aEnd, |
|
576 TCursorPosition::TVisualEnd aDirection) |
|
577 { |
|
578 return iCursorPos.VisualEndOfRunL(aStart, aEnd, aDirection); |
|
579 } |
|
580 |
|
581 /** Gets the cursor position as a TTmDocPos. |
|
582 |
|
583 @param aPos On return, the cursor position. */ |
|
584 EXPORT_C void CTextView::GetCursorPos(TTmDocPos& aPos) const |
|
585 { |
|
586 aPos = iCursorPos.TmDocPos(); |
|
587 } |
|
588 |
|
589 /** Un-draws a selection, redraws the affected part of the screen. The cursor |
|
590 selection remains as before. Analogous to CancelSelectionL(), but leaves the |
|
591 cursor selection untouched. This function should be called before calling |
|
592 CTextView::SetPendingSelection() _and_ SetHighlightExtensions has been used to |
|
593 extend the size of the highlight. Any background formatting is forced to |
|
594 complete first. */ |
|
595 EXPORT_C void CTextView::ClearSelectionL() |
|
596 { |
|
597 TCursorSelection selection; |
|
598 |
|
599 NoMemoryCheckL(); |
|
600 iCursorPos.GetSelection(selection); |
|
601 TBool isPictureFrame=iCursorPos.IsPictureFrame(); |
|
602 if (selection.Length()>0) |
|
603 { |
|
604 iCursorPos.CancelHighlight(); |
|
605 DoClearSelectionL(selection,isPictureFrame); |
|
606 iDisplay.DeactivateContext(); |
|
607 } |
|
608 } |
|
609 |
|
610 void CTextView::DoClearSelectionL(const TCursorSelection& aSelection, TBool aIsPictureFrame) |
|
611 { |
|
612 if (!SelectionVisible()) |
|
613 return; |
|
614 iDisplay.SetRects(RScreenDisplay::EFClipExtendedTextArea); |
|
615 iDisplay.ActivateContext(); |
|
616 iDisplay.ResetClippingRect(); |
|
617 if (aIsPictureFrame) |
|
618 { |
|
619 RedrawPictureFrameRectL(aSelection.LowerPos()); // iCursorPos.CancelHighlight() was called, so the picture will be redrawn without frame |
|
620 DrawCursor(TCursor::EFTextCursor); |
|
621 } |
|
622 else |
|
623 { |
|
624 iDisplay.SetRects(RScreenDisplay::EFClipExtendedTextArea); |
|
625 iDisplay.ResetClippingRect(); |
|
626 CTextLayout::TRangeChange clear_range(aSelection.iAnchorPos, aSelection.iCursorPos,CTextLayout::TRangeChange::EClear); |
|
627 CTextLayout::TRangeChange new_range(aSelection.iCursorPos,aSelection.iCursorPos,CTextLayout::TRangeChange::ESet); |
|
628 HighlightUsingExtensions(clear_range,new_range); |
|
629 } |
|
630 } |
|
631 |
|
632 /** Used to correct the display after a cursor move type call Enters OOM before |
|
633 leaving */ |
|
634 TInt CTextView::DrawAfterCursorMoveL(TInt aVerticalScrollBy) |
|
635 { |
|
636 TInt horizontalScrollBy = CheckHorizontalScroll(iCursorPos.TmDocPos()); |
|
637 |
|
638 DrawWithPreviousHighlight(); |
|
639 |
|
640 if (0 != aVerticalScrollBy || 0 != horizontalScrollBy) |
|
641 { |
|
642 ScrollDisplayL(); |
|
643 } |
|
644 else |
|
645 { |
|
646 DrawCursor(); |
|
647 } |
|
648 |
|
649 DrawWithCurrentHighlight(); |
|
650 |
|
651 return horizontalScrollBy; |
|
652 } |
|
653 |
|
654 /** Sets a selection. The selection is highlighted unless selection visibility |
|
655 has been unset. Any existing selection is cancelled. If necessary, the view is |
|
656 scrolled and redrawn. |
|
657 |
|
658 Any background formatting is forced to complete first. |
|
659 |
|
660 @param aSelection Specifies the start and end positions of the selection. |
|
661 @return The number of pixels scrolled in the x (horizontal) and y (vertical) |
|
662 directions. */ |
|
663 EXPORT_C TPoint CTextView::SetSelectionL(const TCursorSelection& aSelection) |
|
664 { |
|
665 iContextIsNavigation = ETrue; |
|
666 TCursorSelection oldSelection; |
|
667 TBool isPictureFrame=iCursorPos.IsPictureFrame(); |
|
668 TInt scrollBy=0; //To avoid warning |
|
669 |
|
670 NoMemoryCheckL(); |
|
671 FinishBackgroundFormattingL(); |
|
672 iCursorPos.GetSelection(oldSelection); |
|
673 iCursor.MatchCursorHeightToAdjacentChar(); |
|
674 __ASSERT_DEBUG(iLayout->__DbgIsFormattingUpToDate(),FormPanic(EFFormatOutOfDate)); |
|
675 TRAPD(err,scrollBy=iCursorPos.SetSelectionL(aSelection)); |
|
676 if (err) |
|
677 NoMemoryL(err); |
|
678 TInt horizScrollBy=DrawAfterCursorMoveL(scrollBy); |
|
679 iDisplay.SetRects(RScreenDisplay::EFClipTextArea); |
|
680 iDisplay.ActivateContext(); |
|
681 iDisplay.ResetClippingRect(); |
|
682 if (SelectionVisible()) |
|
683 { |
|
684 CTextLayout::TRangeChange old; |
|
685 CTextLayout::TRangeChange select; |
|
686 if (isPictureFrame) |
|
687 { |
|
688 iCursorPos.DontDrawOldPictureFrame(); |
|
689 RedrawPictureFrameRectL(oldSelection.LowerPos()); // this will erase the old picture frame |
|
690 DrawCursor(TCursor::EFTextCursor); |
|
691 } |
|
692 else |
|
693 { |
|
694 old.Set(oldSelection.iAnchorPos, oldSelection.iCursorPos, |
|
695 CTextLayout::TRangeChange::EClear); |
|
696 } |
|
697 |
|
698 if (iCursorPos.IsNewPictureFrame()) |
|
699 { |
|
700 RedrawPictureFrameRectL(aSelection.LowerPos()); // this will draw the new picture frame |
|
701 } |
|
702 else |
|
703 { |
|
704 select.Set(aSelection.iAnchorPos, aSelection.iCursorPos, |
|
705 CTextLayout::TRangeChange::ESet); |
|
706 } |
|
707 |
|
708 CTextLayout::TRangeChange original; |
|
709 original = select; |
|
710 select.OptimizeWith(old); |
|
711 iDisplay.SetRects(RScreenDisplay::EFClipExtendedTextArea); |
|
712 iDisplay.ResetClippingRect(); |
|
713 |
|
714 if (select.IsJoinedTo(old)) |
|
715 { |
|
716 select.Join(old); |
|
717 HighlightUsingExtensions(select,original); |
|
718 } |
|
719 else |
|
720 { |
|
721 HighlightUsingExtensions(old,original); |
|
722 HighlightUsingExtensions(select, original); |
|
723 } |
|
724 } |
|
725 iDisplay.DeactivateContext(); |
|
726 return TPoint(horizScrollBy,scrollBy); |
|
727 } |
|
728 |
|
729 /** Sets the bitmap to be used as a line cursor. This function must be called |
|
730 before attempting to draw the line cursor. Use SetCursorVisibilityL() to make |
|
731 the line cursor visible. |
|
732 @param aLineCursorBitmap The bitmap which represents the line cursor. */ |
|
733 EXPORT_C void CTextView::SetLineCursorBitmap(const CFbsBitmap* aLineCursorBitmap) |
|
734 { |
|
735 iCursor.SetLineCursorBitmap(aLineCursorBitmap); |
|
736 } |
|
737 |
|
738 /** Sets the height and ascent of the text cursor to the values contained in |
|
739 aFontSpec and redraws it. |
|
740 |
|
741 Note: |
|
742 |
|
743 The values set by this function are temporary. If the cursor is subsequently |
|
744 moved, it reverts to being based on the preceding character (unless at the |
|
745 start of a paragraph, in which case, it is based on the following character). |
|
746 |
|
747 @param aFontSpec Specifies a height and ascent to which to set the text cursor. |
|
748 */ |
|
749 EXPORT_C void CTextView::MatchCursorHeightL(const TFontSpec& aFontSpec) |
|
750 { |
|
751 |
|
752 TInt fontHeight = 0; |
|
753 TInt fontAscent = 0; |
|
754 TRAPD(err,iLayout->GetFontHeightAndAscentL(aFontSpec,fontHeight,fontAscent)); |
|
755 if (!err) |
|
756 iCursor.SetAscentAndDescent(fontAscent,fontHeight - fontAscent); |
|
757 User::LeaveIfError(err); |
|
758 } |
|
759 |
|
760 /** Gets the current selection. |
|
761 @return The current selection. */ |
|
762 EXPORT_C TCursorSelection CTextView::Selection() const |
|
763 { |
|
764 TCursorSelection selection; |
|
765 |
|
766 iCursorPos.GetSelection(selection); |
|
767 return selection; |
|
768 } |
|
769 |
|
770 /** Tests whether there is a picture with a picture frame at the current cursor |
|
771 position. If there is, the aPictureFrameRect and aDocPos arguments are set to |
|
772 contain the picture frame rectangle and the document position of the picture, |
|
773 respectively. |
|
774 |
|
775 @param aPictureFrameRect If the function returns true, on return contains the |
|
776 picture frame rectangle. |
|
777 @param aDocPos If the function returns true, on return contains the document |
|
778 position of the picture. |
|
779 @return ETrue if there is a picture with a picture frame at the current cursor |
|
780 position. EFalse if not. */ |
|
781 EXPORT_C TBool CTextView::IsPictureFrameSelected(TRect& aPictureFrameRect,TInt& aDocPos) const |
|
782 { |
|
783 if (iCursorPos.IsPictureFrame()) |
|
784 { |
|
785 __ASSERT_DEBUG(iPictureFrame,FormPanic(EFNoPictureFrame)); |
|
786 aPictureFrameRect=iPictureFrame->Rect(); |
|
787 aDocPos=Selection().LowerPos(); |
|
788 return ETrue; |
|
789 } |
|
790 return EFalse; |
|
791 } |
|
792 |
|
793 /** Gets the bounding rectangle of the picture, if any, located at the document |
|
794 position or x,y coordinates specified, and returns it in aPictureRect. |
|
795 |
|
796 If aCanScaleOrCrop is non-null, sets aCanScaleOrCrop to indicate |
|
797 whether the picture can be scaled or cropped. Returns true if the |
|
798 operation was successful. Returns false otherwise; that is, if there is no |
|
799 picture at the position, or if the position is unformatted. |
|
800 |
|
801 @param aDocPos The document position of interest. |
|
802 @param aXyPos The window coordinates of interest. |
|
803 @param aPictureRect On return, contains the rectangle which encloses the picture |
|
804 located at the position specified. |
|
805 @param aCanScaleOrCrop If non null and the function returns true, indicates |
|
806 whether the picture can be scaled or cropped. By default, null. |
|
807 @return ETrue if the operation was successful, (i.e. there is a picture |
|
808 character at the position, it has been loaded into memory, and the position is |
|
809 formatted). EFalse if any of these conditions are not met. */ |
|
810 EXPORT_C TBool CTextView::GetPictureRectangleL(TInt aDocPos,TRect& aPictureRect,TBool* aCanScaleOrCrop/*=NULL*/) const |
|
811 { |
|
812 TBool isPicture=iLayout->PictureRectangleL(aDocPos,aPictureRect,aCanScaleOrCrop); |
|
813 |
|
814 iDrawTextLayoutContext.TextToWindow(aPictureRect); |
|
815 return isPicture; |
|
816 } |
|
817 |
|
818 /** Returns EFalse if the specified position is not contained within a |
|
819 formatted picture. |
|
820 */ |
|
821 EXPORT_C TBool CTextView::GetPictureRectangleL(TPoint aXyPos,TRect& aPictureRect,TBool* aCanScaleOrCrop/*=NULL*/) |
|
822 { |
|
823 iDrawTextLayoutContext.WindowToText(aXyPos); |
|
824 TBool isPicture=EFalse; |
|
825 TRAPD(err, |
|
826 isPicture = iLayout->PictureRectangleL(aXyPos, aPictureRect, aCanScaleOrCrop)); |
|
827 if (err) |
|
828 NoMemoryL(err); |
|
829 iDrawTextLayoutContext.TextToWindow(aPictureRect); |
|
830 return isPicture; |
|
831 } |
|
832 |
|
833 /** Gets the index of the nearest character in the document to the window coordinates |
|
834 specified. The function first identifies the line which contains, or is nearest |
|
835 to, the vertical coordinate. Then it identifies the character in that line |
|
836 closest to the horizontal coordinate. |
|
837 |
|
838 @param aPoint Window coordinates. On return, contains the window coordinates |
|
839 of the nearest character to the point. |
|
840 @return Index of the nearest character in the document to specified window coordinates. */ |
|
841 EXPORT_C TInt CTextView::XyPosToDocPosL(TPoint& aPoint) |
|
842 { |
|
843 NoMemoryCheckL(); |
|
844 FinishBackgroundFormattingL(); |
|
845 __ASSERT_DEBUG(iLayout->__DbgIsFormattingUpToDate(),FormPanic(EFFormatOutOfDate)); |
|
846 |
|
847 iDrawTextLayoutContext.WindowToText(aPoint); |
|
848 TInt pos = iLayout->XyPosToDocPosL(aPoint); |
|
849 iDrawTextLayoutContext.TextToWindow(aPoint); |
|
850 return pos; |
|
851 } |
|
852 |
|
853 /** Gets the window coordinates of the character located at the specified document |
|
854 position. If the document position specified has not been formatted, the function |
|
855 returns a value of false. |
|
856 |
|
857 @param aDocPos The document position. |
|
858 @param aPoint On return, contains the window coordinates of aDocPos. This value |
|
859 is undefined if the position has not been formatted. |
|
860 @return True if the document position is formatted, false if not. */ |
|
861 EXPORT_C TBool CTextView::DocPosToXyPosL(TInt aDocPos,TPoint& aPoint) |
|
862 { |
|
863 NoMemoryCheckL(); |
|
864 FinishBackgroundFormattingL(); |
|
865 __ASSERT_DEBUG(iLayout->__DbgIsFormattingUpToDate(),FormPanic(EFFormatOutOfDate)); |
|
866 iLayout->ExtendFormattingToCoverPosL(aDocPos); |
|
867 TTmPosInfo2 pos_info; |
|
868 TTmDocPosSpec pos(aDocPos, |
|
869 aDocPos == iLayout->DocumentLength()? |
|
870 TTmDocPosSpec::ETrailing : TTmDocPosSpec::ELeading); |
|
871 TBool in_format = iLayout->FindDocPos(pos, pos_info); |
|
872 aPoint = pos_info.iEdge; |
|
873 iDrawTextLayoutContext.TextToWindow(aPoint); |
|
874 return in_format; |
|
875 } |
|
876 |
|
877 /** Gets the document position of of the nearest character edge to the window coordinates |
|
878 specified. |
|
879 |
|
880 @param aXyPos The window coordinates to investigate. |
|
881 @param aPosInfo If non-null, on return contains information about the position |
|
882 located in the text. |
|
883 @param aLineInfo If non-null, on return contains information on the line that |
|
884 the position is in. |
|
885 @return ETrue if the position was in the text and aPosInfo and aLineInfo have |
|
886 been set. */ |
|
887 EXPORT_C TBool CTextView::FindXyPosL(const TPoint& aXyPos, TTmPosInfo2& aPosInfo, TTmLineInfo* aLineInfo) |
|
888 { |
|
889 TPoint pos = aXyPos; |
|
890 iDrawTextLayoutContext.WindowToText(pos); |
|
891 iLayout->ExtendFormattingToCoverYL(pos.iY); |
|
892 return iLayout->FindXyPos(pos, aPosInfo, aLineInfo); |
|
893 } |
|
894 |
|
895 /** Finds the x-y position of the document position aDocPos. |
|
896 |
|
897 If aDocPos is formatted, TRUE is returned and aPosInfo returns information |
|
898 about the document position and aLineInfo returns information about the line |
|
899 containing the document position, if it is non-null. |
|
900 |
|
901 @param aDocPos The document position to investigate. |
|
902 @param aPosInfo If non-null, on return, contains information about the document |
|
903 position. |
|
904 @param aLineInfo If non-null, on return, contains information on the line that |
|
905 the position is in. |
|
906 @return ETrue if the position was in the text and aPosInfo and aLineInfo have |
|
907 been set; EFalse otherwise. */ |
|
908 EXPORT_C TBool CTextView::FindDocPosL(const TTmDocPosSpec& aDocPos,TTmPosInfo2& aPosInfo,TTmLineInfo* aLineInfo) |
|
909 { |
|
910 TTagmaForwarder forwarder; |
|
911 forwarder.InitL(this); |
|
912 iLayout->ExtendFormattingToCoverPosL(aDocPos.iPos); |
|
913 TTmLineInfo line_info; |
|
914 TBool result = forwarder.FindDocPos(aDocPos,aPosInfo,line_info); |
|
915 if (aLineInfo) |
|
916 *aLineInfo = line_info; |
|
917 return result; |
|
918 } |
|
919 |
|
920 /** |
|
921 Returns a selection for which characters should be deleted in a forwards delete. |
|
922 @return |
|
923 A selection for which characters should be deleted in a forwards delete. |
|
924 */ |
|
925 EXPORT_C TCursorSelection CTextView::GetForwardDeletePositionL() |
|
926 { |
|
927 TCursorSelection selection = Selection(); |
|
928 if (selection.Length() != 0) |
|
929 return selection; |
|
930 iLayout->ExtendFormattingToCoverPosL(Min(selection.iCursorPos + 1, iLayout->DocumentLength())); |
|
931 TInt anchor = iLayout->TagmaTextLayout().FindNextPos(selection.iCursorPos); |
|
932 if (anchor < 0) |
|
933 { |
|
934 selection.iAnchorPos = iLayout->DocumentLength(); |
|
935 return selection; |
|
936 } |
|
937 |
|
938 __ASSERT_DEBUG(selection.iCursorPos < anchor, User::Invariant()); |
|
939 __ASSERT_DEBUG(selection.Length() == 0, User::Invariant()); |
|
940 |
|
941 // Now we have found the next formatted position. However, this |
|
942 // may have skipped a ligature. We should only delete the first character |
|
943 // in any ligature. |
|
944 // However, an indic syllable (glued together with viramas) should be |
|
945 // deleted all in one go. |
|
946 CTextLayout::TUtf32SourceCache sourceCache(*iLayout); |
|
947 TInt graphicalSpacingCharactersFound = 0; |
|
948 TBool ignoreNextSpacingCharacter = EFalse; |
|
949 for (TInt i = selection.iCursorPos; i != anchor; ++i) |
|
950 { |
|
951 __ASSERT_DEBUG(i < anchor, User::Invariant()); |
|
952 TChar c = sourceCache.GetUtf32(i); |
|
953 if ( IsGraphicalSpacing(c) ) |
|
954 { |
|
955 if (!ignoreNextSpacingCharacter) |
|
956 { |
|
957 if (graphicalSpacingCharactersFound != 0) |
|
958 { |
|
959 // Found two graphical spacing characters: don't |
|
960 // include the second |
|
961 selection.iAnchorPos = i; |
|
962 return selection; |
|
963 } |
|
964 ++graphicalSpacingCharactersFound; |
|
965 } |
|
966 else |
|
967 ignoreNextSpacingCharacter = EFalse; |
|
968 } |
|
969 else if (IsVirama(c)) |
|
970 { |
|
971 // virama joins a graphical spacing character to the |
|
972 // previous character, so the second one doesn't count. |
|
973 ignoreNextSpacingCharacter = ETrue; |
|
974 } |
|
975 } |
|
976 selection.iAnchorPos = anchor; |
|
977 return selection; |
|
978 } |
|
979 |
|
980 /** Returns a selection for which characters should be deleted in a backwards |
|
981 delete. |
|
982 @return |
|
983 A selection for which characters should be deleted in a backwards delete. |
|
984 */ |
|
985 |
|
986 EXPORT_C TCursorSelection CTextView::GetBackwardDeletePositionL() |
|
987 { |
|
988 TCursorSelection selection = Selection(); |
|
989 if (selection.Length() != 0) |
|
990 return selection; |
|
991 |
|
992 TInt anchor = KErrNotFound; |
|
993 TTmDocPos docPos; |
|
994 GetCursorPos(docPos); |
|
995 // loop through each previous line in case there are only zero width |
|
996 // chars before the cursor on this line. In practice, the following loop |
|
997 // should only ever iterate twice at most, because you can never have |
|
998 // more than one continuous line of zero-width characters (think about it) |
|
999 while (anchor==KErrNotFound && docPos.iPos > 0) |
|
1000 { |
|
1001 anchor = iLayout->TagmaTextLayout().FindPreviousPos(docPos.iPos); |
|
1002 if (anchor==KErrNotFound) // no non-zero-width character before |
|
1003 { // this position on this line |
|
1004 // get first doc position on line then extend formatting to the one before |
|
1005 TTmPosInfo2 dummy; |
|
1006 TTmLineInfo currentLineInfo; |
|
1007 iLayout->FindDocPos(docPos, dummy, ¤tLineInfo); |
|
1008 docPos.iPos = currentLineInfo.iStart; |
|
1009 iLayout->ExtendFormattingToCoverPosL(Max(docPos.iPos - 1, 0)); |
|
1010 } |
|
1011 } |
|
1012 if (anchor==KErrNotFound) |
|
1013 { |
|
1014 selection.iAnchorPos = 0; |
|
1015 return selection; |
|
1016 } |
|
1017 |
|
1018 __ASSERT_DEBUG(anchor < selection.iCursorPos, User::Invariant()); |
|
1019 __ASSERT_DEBUG(selection.Length() == 0, User::Invariant()); |
|
1020 |
|
1021 // If this cluster is a ligature, it needs to be split. |
|
1022 // Note that an indic syllable (where consonants are glued |
|
1023 // together with viramas) does not count as a ligature. |
|
1024 CTextLayout::TUtf32SourceCache sourceCache(*iLayout); |
|
1025 for (TInt i = selection.iCursorPos - 1; anchor < i; --i) |
|
1026 { |
|
1027 if ( IsGraphicalSpacing(sourceCache.GetUtf32(i)) ) |
|
1028 { |
|
1029 if ( !IsVirama(sourceCache.GetUtf32(i-1)) ) |
|
1030 { |
|
1031 // Found two possible start points: cut to the last. |
|
1032 selection.iAnchorPos = i; |
|
1033 return selection; |
|
1034 } |
|
1035 } |
|
1036 } |
|
1037 // Not a ligature |
|
1038 selection.iAnchorPos = anchor; |
|
1039 return selection; |
|
1040 } |
|
1041 |
|
1042 /** Returns the rectangle enclosing the paragraph containing aDocPos. If the |
|
1043 paragraph is not formatted, returns an empty rectangle. If the paragraph is |
|
1044 partially formatted, returns the rectangle enclosing the formatted part. |
|
1045 |
|
1046 @param aDocPos A document position within the paragraph. |
|
1047 @return The rectangle which encloses the paragraph containing aDocPos. */ |
|
1048 EXPORT_C TRect CTextView::ParagraphRectL(TInt aDocPos) const |
|
1049 { |
|
1050 TRect r; |
|
1051 TTmDocPos pos(aDocPos, |
|
1052 aDocPos == iLayout->DocumentLength()? EFalse : ETrue); |
|
1053 iLayout->GetParagraphRect(pos,r); |
|
1054 iDrawTextLayoutContext.TextToWindow(r); |
|
1055 return r; |
|
1056 } |
|
1057 |
|
1058 /** Formats the next line for background formatting, returns True if more to do |
|
1059 Enters OOM state before leaving */ |
|
1060 TBool CTextView::NextLineL() |
|
1061 { |
|
1062 TBool moreToDo=EFalse; |
|
1063 |
|
1064 if (IsFormatting()) |
|
1065 { |
|
1066 TInt formattedFrom=iFormattedUpTo; |
|
1067 |
|
1068 TRAPD(err,moreToDo=iLayout->FormatNextLineL(iFormattedUpTo)); |
|
1069 if (err) |
|
1070 NoMemoryL(err); |
|
1071 NotifyReformatL(); |
|
1072 TInt displayTo=iDrawTextLayoutContext.DisplayHeight(); |
|
1073 TBool drawAllLines=(iHorizontalScroll==EFPreviousHorizontalScroll && !moreToDo); |
|
1074 if (iFormattedUpTo<displayTo && !drawAllLines) |
|
1075 displayTo=iFormattedUpTo; |
|
1076 DisplayNewLinesL(formattedFrom,displayTo); |
|
1077 if (!moreToDo) |
|
1078 { |
|
1079 if (!drawAllLines) |
|
1080 CheckScrollUpL(); |
|
1081 iHorizontalScroll=EFNoPreviousHorizontalScroll; |
|
1082 } |
|
1083 } |
|
1084 return moreToDo; |
|
1085 } |
|
1086 |
|
1087 /** Draws good parts of the screen that have recently been formatted by |
|
1088 background formatting. Enters OOM before leaving. */ |
|
1089 void CTextView::DisplayNewLinesL(TInt aFrom,TInt aTo) |
|
1090 { |
|
1091 __ASSERT_DEBUG(!iNoMemory,FormPanic(EFNoMemory)); |
|
1092 if (aTo>iGood) |
|
1093 { |
|
1094 ScrollTextL(aTo - iGood,iGood,0,FALSE); |
|
1095 iGood=aTo; |
|
1096 } |
|
1097 iDisplay.SetRects(RScreenDisplay::EFClipViewRect); |
|
1098 DisplayLineRangeL(aFrom,aTo); |
|
1099 DrawCursor(); |
|
1100 } |
|
1101 |
|
1102 void CTextView::DrawCursor(TUint aCursors) |
|
1103 { |
|
1104 iCursor.Draw(aCursors); |
|
1105 } |
|
1106 |
|
1107 /** Scrolls the screen up if necessary following background formatting. Enters |
|
1108 OOM state before leaving */ |
|
1109 void CTextView::CheckScrollUpL() |
|
1110 { |
|
1111 if (iFormattedUpTo<iGood) |
|
1112 { |
|
1113 TInt height=iDrawTextLayoutContext.DisplayHeight(); |
|
1114 |
|
1115 if (height>iGood) |
|
1116 { |
|
1117 TInt scroll=iFormattedUpTo-iGood; |
|
1118 ScrollTextL(scroll,iGood,0,FALSE); |
|
1119 //invalidate the area from the bottom of the last formatted line |
|
1120 //to the bottom of view rect |
|
1121 iDisplay.SetInvalidRect(iFormattedUpTo-height); |
|
1122 iFormattedUpTo+=height-iGood; |
|
1123 iDisplay.SetRects(RScreenDisplay::EFClipViewRect|RScreenDisplay::EFClipInvalid); |
|
1124 DrawTextL(iFormattedUpTo); |
|
1125 } |
|
1126 else if (height>iFormattedUpTo) |
|
1127 { |
|
1128 iDisplay.SetRects(RScreenDisplay::EFClipViewRect); |
|
1129 DrawTextL(iFormattedUpTo); |
|
1130 } |
|
1131 } |
|
1132 } |
|
1133 |
|
1134 /** |
|
1135 CheckHorizontalScroll's job is to take the cursor position in aDocPos and |
|
1136 ensure it is visible in the view. It does this by calculating the horizontal |
|
1137 scroll neccessary and adjusts the iTextStartX (left text margin) attribute of |
|
1138 the view member iDrawTextLayoutContext. This change (if any) would be reflected |
|
1139 in the next re-draw. |
|
1140 |
|
1141 This functionality is required when the layout is in non-screen/window wrapped |
|
1142 mode (ie. wysiwyg mode) and the cursor is out of view to the left or the right |
|
1143 (say if the user has horizontally scrolled) and either a cursor movement |
|
1144 happens or a char is inserted or deleted by the user. The end result is the |
|
1145 view jumps back to the cursor so the user can see when change/movement was |
|
1146 made. |
|
1147 |
|
1148 When the layout format is set to screen mode this functionality may still be |
|
1149 required as paragraphs with wrapping turned off can break the margins. Even |
|
1150 with wrapping turned on, spaces and hanging characters can break margins; |
|
1151 however it is usually considered ugly to allow the screen to scroll to follow |
|
1152 the cursor in these situations. |
|
1153 |
|
1154 @param aDocPos Cusror position to base calculations on |
|
1155 @post Drawing layout context updated with new horizontal scroll position |
|
1156 @return Amount left margin (horizontal scroll) adjusted by or 0 if none |
|
1157 */ |
|
1158 TInt CTextView::CheckHorizontalScroll (const TTmDocPos& aDocPos) |
|
1159 { |
|
1160 /* Here are the requirements for this function: |
|
1161 |
|
1162 (1) Areas beyond the text +10% of the window width +iHorizontalScrollJump |
|
1163 must not be shown if the text edge is beyond its normal bounds, |
|
1164 except that |
|
1165 a distance of (window width - text width) beyond the texts |
|
1166 bounds may be shown if this is positive. |
|
1167 or |
|
1168 If this is not positive then a small amount of padding |
|
1169 (windowWidth - iLayout->WrapWidth) is allowed. |
|
1170 |
|
1171 (2) The cursor must be 10% of the window's width away from the window's |
|
1172 edge if the text is wider than the window. |
|
1173 |
|
1174 (3) In all cases where (1) and (2) do not force otherwise, the scroll |
|
1175 amount must be a multiple of iHorizontalScrollJump. |
|
1176 |
|
1177 (4) The screen must scroll the minimum amount allowed by requirements (1), |
|
1178 (2) and (3). |
|
1179 */ |
|
1180 TInt windowWidth = iDrawTextLayoutContext.TextArea().Width(); |
|
1181 // Scroll position is the position on the screen at which the text |
|
1182 // has its X coordinate |
|
1183 TInt currentScrollPosition = iDrawTextLayoutContext.iTextStartX; |
|
1184 TInt rightTextEdge; |
|
1185 TInt leftTextEdge; |
|
1186 iLayout->CalculateHorizontalExtremes(leftTextEdge, rightTextEdge, ETrue); |
|
1187 |
|
1188 TInt maximumScrollPosition = -leftTextEdge; |
|
1189 TInt minimumScrollPosition = windowWidth - rightTextEdge; |
|
1190 TInt padding = maximumScrollPosition < minimumScrollPosition? |
|
1191 minimumScrollPosition - maximumScrollPosition : |
|
1192 ((windowWidth - iLayout->WrapWidth() > 0) ? windowWidth - iLayout->WrapWidth() : 0); |
|
1193 |
|
1194 TInt buffer = windowWidth / 10; |
|
1195 TInt textWrapWidth = iLayout->WrapWidth(); |
|
1196 // loosen the bounds by 10% of the window width + iHorizontalScrollJump |
|
1197 // if the text is beyond them |
|
1198 TInt leftAllowance = leftTextEdge < 0? |
|
1199 buffer + iHorizontalScrollJump : 0; |
|
1200 TInt rightAllowance = textWrapWidth < rightTextEdge? |
|
1201 buffer + iHorizontalScrollJump : 0; |
|
1202 maximumScrollPosition += Max(leftAllowance, padding); |
|
1203 minimumScrollPosition -= Max(rightAllowance, padding); |
|
1204 |
|
1205 // requirement (2) sets the preferred min and max |
|
1206 TInt preferredMinimumScrollPosition = minimumScrollPosition; |
|
1207 TInt preferredMaximumScrollPosition = maximumScrollPosition; |
|
1208 if (windowWidth < rightTextEdge - leftTextEdge) |
|
1209 { |
|
1210 TTmPosInfo2 posInfo; |
|
1211 iLayout->FindDocPos(aDocPos, posInfo); |
|
1212 TInt cursorWithinTextX = posInfo.iEdge.iX; |
|
1213 |
|
1214 preferredMinimumScrollPosition = buffer - cursorWithinTextX; |
|
1215 preferredMaximumScrollPosition = windowWidth - buffer - cursorWithinTextX; |
|
1216 |
|
1217 // keep the preferred max and min within range |
|
1218 preferredMinimumScrollPosition = Max(preferredMinimumScrollPosition, minimumScrollPosition); |
|
1219 preferredMinimumScrollPosition = Min(preferredMinimumScrollPosition, maximumScrollPosition); |
|
1220 |
|
1221 preferredMaximumScrollPosition = Max(preferredMaximumScrollPosition, minimumScrollPosition); |
|
1222 preferredMaximumScrollPosition = Min(preferredMaximumScrollPosition, maximumScrollPosition); |
|
1223 } |
|
1224 |
|
1225 // Easy out if no scrolling will do |
|
1226 if (preferredMinimumScrollPosition <= currentScrollPosition |
|
1227 && currentScrollPosition <= preferredMaximumScrollPosition) |
|
1228 return 0; |
|
1229 |
|
1230 TInt suggestedPosition = currentScrollPosition; |
|
1231 // Otherwise scrolling is either to just greater than the minimum or |
|
1232 // just greater than the maximum. |
|
1233 if (currentScrollPosition < preferredMinimumScrollPosition) |
|
1234 { |
|
1235 TInt jump = preferredMinimumScrollPosition - currentScrollPosition |
|
1236 + iHorizontalScrollJump - 1; |
|
1237 jump = (jump / iHorizontalScrollJump) * iHorizontalScrollJump; |
|
1238 suggestedPosition = Min(currentScrollPosition + jump, |
|
1239 preferredMaximumScrollPosition); |
|
1240 } |
|
1241 else |
|
1242 { |
|
1243 TInt jump = currentScrollPosition - preferredMaximumScrollPosition |
|
1244 + iHorizontalScrollJump - 1; |
|
1245 jump = (jump / iHorizontalScrollJump) * iHorizontalScrollJump; |
|
1246 suggestedPosition = Max(currentScrollPosition - jump, |
|
1247 preferredMinimumScrollPosition); |
|
1248 } |
|
1249 |
|
1250 TInt delta = suggestedPosition - iDrawTextLayoutContext.iTextStartX; |
|
1251 iDrawTextLayoutContext.iTextStartX = suggestedPosition; |
|
1252 |
|
1253 return delta; |
|
1254 } |
|
1255 |
|
1256 /** Reformats the whole document, or just the visible text, if formatting is |
|
1257 set to the band only (see CTextLayout::SetAmountToFormat()). |
|
1258 |
|
1259 Notes: |
|
1260 |
|
1261 Reformatting the entire document may be time consuming, so only use this |
|
1262 function if necessary. |
|
1263 |
|
1264 This function does not redraw the reformatted text. */ |
|
1265 EXPORT_C void CTextView::FormatTextL() |
|
1266 { |
|
1267 |
|
1268 iCursor.MatchCursorHeightToAdjacentChar(); |
|
1269 iLayout->DiscardFormat(); |
|
1270 if (iNoMemory) |
|
1271 { |
|
1272 iNoMemory=EFRecovering; |
|
1273 RecreateWindowServerObjectsL(); |
|
1274 } |
|
1275 TRAPD(err,iLayout->FormatBandL()); |
|
1276 if (err) |
|
1277 NoMemoryL(err); |
|
1278 NotifyReformatL(); |
|
1279 iNoMemory=EFMemoryOK; |
|
1280 } |
|
1281 |
|
1282 void CTextView::ResetOffScreenBitmapContext(TAny* aTextView) |
|
1283 { |
|
1284 CTextView* that = reinterpret_cast<CTextView*>(aTextView); |
|
1285 that->iOffScreenContext = 0; |
|
1286 } |
|
1287 |
|
1288 void CTextView::ResetExternalDraw(TAny* aTextView) |
|
1289 { |
|
1290 CTextView* that = reinterpret_cast<CTextView*>(aTextView); |
|
1291 that->iLayout->ResetExternalDraw(); |
|
1292 } |
|
1293 |
|
1294 /** Draws the text to a rectangle. |
|
1295 |
|
1296 Draw to a specific GC rather than the stored one. This is essential when |
|
1297 drawing CTextView objects that are embedded inside others, as happens for |
|
1298 editable text controls in WEB (the outermost WEB object is a CTextView, which |
|
1299 has embedded controls that own CEikEdwins, and these own CTextView objects). |
|
1300 @param aRect |
|
1301 Rectangle to which the text is drawn, normally the view rectangle. |
|
1302 @param aGc |
|
1303 Graphics context to be drawn to. Flicker-free redrawing will not be applied, |
|
1304 so this parameter should not be a window gc if flickering is to be avoided. |
|
1305 Notice that the fonts drawn to this context will be taken from the graphics |
|
1306 device map given to the constructor of this object or in subsequent calls to |
|
1307 CTextLayout::SetImageDeviceMap. If such fonts cannot be used with this bitmap |
|
1308 context, the behaviour is undefined. |
|
1309 */ |
|
1310 EXPORT_C void CTextView::DrawL(TRect aRect, CBitmapContext& aGc) |
|
1311 { |
|
1312 NoMemoryCheckL(); |
|
1313 iOffScreenContext = &aGc; |
|
1314 CleanupStack::PushL(TCleanupItem(ResetOffScreenBitmapContext, this)); |
|
1315 DrawL(aRect); |
|
1316 if (!iDisplay.IsLineCursor()) |
|
1317 DrawCursor(); |
|
1318 CleanupStack::PopAndDestroy(); |
|
1319 } |
|
1320 |
|
1321 /** Draws the text to a rectangle. Enters OOM state before leaving. |
|
1322 RWindow::BeginRedraw() should always be called before calling this function, |
|
1323 for the window that the textview draws to. |
|
1324 |
|
1325 @param aRect Rectangle to which the text is drawn, normally the view rectangle. |
|
1326 */ |
|
1327 EXPORT_C void CTextView::DrawL(TRect aRect) |
|
1328 { //make sure exactly the correct bits are drawn ### eg line cursor etc. |
|
1329 TRect rect(iDrawTextLayoutContext.iViewRect); |
|
1330 TInt start=iFormattedUpTo; |
|
1331 |
|
1332 if (NoMemoryCheckL()) |
|
1333 { |
|
1334 iDisplay.Invalidate(rect); |
|
1335 return; |
|
1336 } |
|
1337 |
|
1338 if (!(iFlags & EFTextVisible)) |
|
1339 return; |
|
1340 |
|
1341 TRect drawRect(aRect); |
|
1342 iDrawTextLayoutContext.WindowToText(drawRect); |
|
1343 iLayout->SetReadyToRedraw(); |
|
1344 iLayout->SetExternalDraw(drawRect); // view coordinates |
|
1345 |
|
1346 FinishBackgroundFormattingL(); |
|
1347 if (start<iFormattedUpTo) |
|
1348 { |
|
1349 rect.iTl.iY=start; |
|
1350 rect.iBr.iY=iFormattedUpTo; |
|
1351 iDisplay.Invalidate(rect); |
|
1352 } |
|
1353 __ASSERT_DEBUG(iLayout->__DbgIsFormattingUpToDate(),FormPanic(EFFormatOutOfDate)); |
|
1354 iDisplay.SetInvalidRect(aRect); |
|
1355 iDrawTextLayoutContext.WindowToText(aRect); |
|
1356 iDisplay.SetRects(RScreenDisplay::EFClipViewRect|RScreenDisplay::EFClipInvalid); |
|
1357 |
|
1358 CleanupStack::PushL(TCleanupItem(ResetExternalDraw, this)); |
|
1359 |
|
1360 DrawTextL(aRect.iTl.iY,aRect.iBr.iY); |
|
1361 |
|
1362 CleanupStack::PopAndDestroy(); |
|
1363 } |
|
1364 |
|
1365 /** Clears the specified number of pixels from the bottom of the screen. Enters |
|
1366 OOM state before leaving. */ |
|
1367 void CTextView::ClearRectAtBottom(TInt aHeight) |
|
1368 { |
|
1369 iDisplay.AddRects(RScreenDisplay::EFClipViewRect); |
|
1370 iDisplay.ActivateContext(); |
|
1371 iDisplay.ResetClippingRect(); |
|
1372 TRect rect(ViewRect()); |
|
1373 rect.iTl.iY += aHeight; |
|
1374 |
|
1375 iLayout->BeginRedraw(rect); |
|
1376 iDisplay.ClearRect(rect); |
|
1377 iLayout->EndRedraw(); |
|
1378 |
|
1379 iDisplay.DeactivateContext(); |
|
1380 } |
|
1381 |
|
1382 void CTextView::DrawTextL(TInt aFromHeight,TInt aToHeight) |
|
1383 { |
|
1384 TInt layHeight=iLayout->YBottomLastFormattedLine(); |
|
1385 TInt winHeight=iDrawTextLayoutContext.DisplayHeight(); |
|
1386 |
|
1387 if (layHeight>winHeight) |
|
1388 layHeight=winHeight; |
|
1389 if (layHeight<aToHeight) |
|
1390 aToHeight=layHeight; |
|
1391 DisplayLineRangeL(aFromHeight,aToHeight); |
|
1392 if (layHeight<winHeight && layHeight==aToHeight) //Only last line has been drawn |
|
1393 ClearRectAtBottom(layHeight); //Must be done last as it changes the flags in RScreenDisplay |
|
1394 DrawCursor(); |
|
1395 } |
|
1396 |
|
1397 |
|
1398 |
|
1399 /** Reformats and redraws the view in response to a single key press. The |
|
1400 precise amount of text to be reformatted is controlled by the second parameter. |
|
1401 |
|
1402 @param aType Indicates the type of edit which has taken place. |
|
1403 CTextLayout::EFCharacterInsert (the default) for a character insertion, |
|
1404 CTextLayout::EFParagraphDelimiter for a paragraph delimiter insertion, |
|
1405 CTextLayout::EFLeftDelete or CTextLayout::EFRightDelete for a character or |
|
1406 paragraph delimiter deletion to the left or right of the cursor position. |
|
1407 @param aFormatChanged ETrue if text is to be reformatted from the start of the |
|
1408 paragraph the cursor was on before the edit, EFalse if from the start of the |
|
1409 line the cursor was on before the edit. |
|
1410 @return The number of pixels by which the text had to be scrolled vertically |
|
1411 (positive means text moved down). */ |
|
1412 EXPORT_C TInt CTextView::HandleCharEditL(TUint aType/*=EFCharacterInsert*/ |
|
1413 ,TBool aFormatChanged/*=EFalse*/) |
|
1414 { |
|
1415 iContextIsNavigation = EFalse; |
|
1416 TInt good = 0; |
|
1417 TInt formattedFrom = 0; |
|
1418 TInt from = 0; |
|
1419 TBool formatting = IsFormatting(); |
|
1420 TBool moreToDo = ETrue; |
|
1421 |
|
1422 __ASSERT_DEBUG(!iCursorPos.IsSelection(),FormPanic(EFSelectionCannotCharEdit)); |
|
1423 __ASSERT_DEBUG(aType<=CTextLayout::EFRightDelete,FormPanic(EFBadCharacterEditType)); |
|
1424 __ASSERT_DEBUG(!aFormatChanged || aType==CTextLayout::EFRightDelete |
|
1425 || aType==CTextLayout::EFLeftDelete,FormPanic(EFBadCharacterEditType)); |
|
1426 TBool recovered=NoMemoryCheckL(); |
|
1427 iCursor.MatchCursorHeightToAdjacentChar(); |
|
1428 TPoint dummyPoint; |
|
1429 __ASSERT_DEBUG(iLayout->PosInBand(iCursorPos.TmDocPos(),dummyPoint) |
|
1430 || !formatting, FormPanic(EFBackgroundFormatting)); |
|
1431 TTmDocPos doc_pos = iCursorPos.TmDocPos(); |
|
1432 if ((!formatting && !iLayout->PosInBand(doc_pos,dummyPoint)) || recovered) |
|
1433 { |
|
1434 TInt y=0; |
|
1435 switch (aType) |
|
1436 { |
|
1437 case CTextLayout::EFCharacterInsert: |
|
1438 doc_pos.iLeadingEdge = EFalse; |
|
1439 ++doc_pos.iPos; |
|
1440 break; |
|
1441 case CTextLayout::EFParagraphDelimiter: |
|
1442 ++doc_pos.iPos; |
|
1443 doc_pos.iLeadingEdge = ETrue; |
|
1444 break; |
|
1445 case CTextLayout::EFLeftDelete: |
|
1446 --doc_pos.iPos; |
|
1447 doc_pos.iLeadingEdge = EFalse; |
|
1448 break; |
|
1449 default: |
|
1450 doc_pos.iLeadingEdge = EFalse; |
|
1451 break; |
|
1452 } |
|
1453 iCursorPos.SetDocPos(doc_pos); |
|
1454 |
|
1455 if (recovered) |
|
1456 return 0; |
|
1457 else |
|
1458 return ViewTopOfLineL(iCursorPos.TmDocPos(),y,CTextView::EFViewDiscardAllFormat).iY; |
|
1459 } |
|
1460 TInt scroll = 0; |
|
1461 TRAPD(err,moreToDo = iLayout->HandleCharEditL(aType,doc_pos.iPos,good,iFormattedUpTo,formattedFrom, |
|
1462 scroll,aFormatChanged)); |
|
1463 |
|
1464 doc_pos.iLeadingEdge = |
|
1465 aType == CTextLayout::EFParagraphDelimiter? |
|
1466 ETrue : EFalse; |
|
1467 if (doc_pos.iPos == 0) |
|
1468 doc_pos.iLeadingEdge = EFalse; |
|
1469 |
|
1470 // If this document position will not yield a cursor, try the leading edge |
|
1471 if (!doc_pos.iLeadingEdge) |
|
1472 { |
|
1473 TRect line; |
|
1474 TPoint origin; |
|
1475 TInt width, ascent, descent; |
|
1476 if (!iLayout->GetCursor(doc_pos, ECursorVertical, |
|
1477 line, origin, width, ascent, descent)) |
|
1478 doc_pos.iLeadingEdge = ETrue; |
|
1479 } |
|
1480 iCursorPos.SetDocPos(doc_pos); |
|
1481 if (err) |
|
1482 NoMemoryL(err); |
|
1483 NotifyReformatL(); |
|
1484 if (formatting==EFalse) |
|
1485 { |
|
1486 iGood=good; |
|
1487 if (moreToDo) |
|
1488 StartIdleObject(); |
|
1489 } |
|
1490 formattedFrom=Max(formattedFrom,0); |
|
1491 TInt to=Min(iFormattedUpTo,iDrawTextLayoutContext.DisplayHeight()); |
|
1492 #if defined(_DEBUG) |
|
1493 TInt oldFormattedFrom = formattedFrom; |
|
1494 #endif |
|
1495 if (scroll<0 && formattedFrom>0) |
|
1496 ScrollRect(scroll,from,formattedFrom); |
|
1497 __ASSERT_DEBUG(from==0 && formattedFrom==oldFormattedFrom,FormPanic(EFScrollCurtailed)); |
|
1498 if (to>=formattedFrom) |
|
1499 DisplayNewLinesL(formattedFrom,to); |
|
1500 if (!moreToDo) |
|
1501 CheckScrollUpL(); |
|
1502 iCursorPos.UpdateLatentPosition(); |
|
1503 TInt horizScrollBy=CheckHorizontalScroll(iCursorPos.TmDocPos()); // Have had to put at end, because sometimes format all above |
|
1504 if (horizScrollBy!=0) |
|
1505 { |
|
1506 ScrollDisplayL(); |
|
1507 if (moreToDo) |
|
1508 iHorizontalScroll=EFPreviousHorizontalScroll; |
|
1509 } |
|
1510 return scroll; |
|
1511 } |
|
1512 |
|
1513 /** Reformats after a change to part of the text contents. Enters OOM state |
|
1514 before leaving. */ |
|
1515 TPoint CTextView::HandleBlockChangeL(TCursorSelection aSelection,TInt aOldCharsChanged |
|
1516 ,TBool aFormatChanged) |
|
1517 { |
|
1518 TViewRectChanges viewChanges; |
|
1519 TCursorSelection selection; |
|
1520 |
|
1521 iCursorPos.GetSelection(selection); |
|
1522 TRAPD(err,iLayout->HandleBlockChangeL(aSelection,aOldCharsChanged,viewChanges,aFormatChanged)); |
|
1523 if (err) |
|
1524 NoMemoryL(err); |
|
1525 NotifyReformatL(); |
|
1526 __ASSERT_DEBUG(iLayout->__DbgIsFormattingUpToDate(),FormPanic(EFFormatOutOfDate)); |
|
1527 |
|
1528 TInt from=0; |
|
1529 TInt to=iDrawTextLayoutContext.DisplayHeight(); |
|
1530 TInt horizScrollBy=CheckHorizontalScroll(iCursorPos.TmDocPos()); |
|
1531 if (horizScrollBy!=0) |
|
1532 { |
|
1533 TInt yBot=iLayout->YBottomLastFormattedLine(); |
|
1534 viewChanges.iFormattedFrom=0; |
|
1535 if (yBot<to) |
|
1536 to=yBot; |
|
1537 viewChanges.iFormattedTo=to; |
|
1538 } |
|
1539 else |
|
1540 { |
|
1541 iDisplay.SetRects(RScreenDisplay::EFClipViewRect); |
|
1542 iDisplay.ActivateContext(); |
|
1543 iDisplay.ResetClippingRect(); |
|
1544 if (viewChanges.iScrollAtBottom>0 && viewChanges.iFormattedTo<to) |
|
1545 ScrollRect(viewChanges.iScrollAtBottom,viewChanges.iFormattedTo,to); |
|
1546 if (viewChanges.iScrollAtTop!=0 && viewChanges.iFormattedFrom>0) |
|
1547 ScrollRect(viewChanges.iScrollAtTop,from,viewChanges.iFormattedFrom); |
|
1548 if (viewChanges.iScrollAtBottom<0 && viewChanges.iFormattedTo<to) |
|
1549 ScrollRect(viewChanges.iScrollAtBottom,viewChanges.iFormattedTo,to); |
|
1550 iDisplay.DeactivateContext(); |
|
1551 } |
|
1552 iDisplay.SetRects(RScreenDisplay::EFClipViewRect); |
|
1553 __ASSERT_DEBUG(from<=viewChanges.iFormattedFrom || from<=0,FormPanic(EFScrollError)); |
|
1554 __ASSERT_DEBUG(to>=viewChanges.iFormattedTo || to>=iDrawTextLayoutContext.DisplayHeight(),FormPanic(EFScrollError)); |
|
1555 if (from>0) |
|
1556 DisplayLineRangeL(0,from); |
|
1557 DisplayLineRangeL(viewChanges.iFormattedFrom,viewChanges.iFormattedTo); |
|
1558 if (to<iDrawTextLayoutContext.DisplayHeight()) |
|
1559 DrawTextL(to); |
|
1560 else |
|
1561 DrawCursor(); |
|
1562 iCursorPos.UpdateLatentPosition(); |
|
1563 TInt vertScroll=viewChanges.iScrollAtTop; |
|
1564 if (selection.LowerPos()!=selection.iCursorPos) |
|
1565 vertScroll=viewChanges.iScrollAtBottom; |
|
1566 __ASSERT_DEBUG(iLayout->__DbgIsFormattingUpToDate(),FormPanic(EFFormatOutOfDate)); |
|
1567 return TPoint(horizScrollBy,vertScroll); |
|
1568 } |
|
1569 |
|
1570 /** Makes a selection, but without updating the view. |
|
1571 |
|
1572 This function would only be used before calling CTextView::HandleRangeFormatChangeL() |
|
1573 or HandleInsertDeleteL() to make a selection which will become visible (if |
|
1574 selection visibility is on) after the change handling function has returned. |
|
1575 |
|
1576 @param aSelection The range to be selected after calling CTextView::HandleRangeFormatChangeL() |
|
1577 or HandleInsertDeleteL(). */ |
|
1578 EXPORT_C void CTextView::SetPendingSelection(const TCursorSelection& aSelection) |
|
1579 { |
|
1580 iCursorPos.SetPendingSelection(aSelection); |
|
1581 } |
|
1582 |
|
1583 /** Reformats and redraws the view after changes to the character or paragraph |
|
1584 formatting of a block of text. Reformatting can take place either from the |
|
1585 start of the line or the start of the paragraph containing the cursor position, |
|
1586 depending on aFormatChanged. |
|
1587 |
|
1588 Can be used in combination with SetPendingSelection() to set a selection which |
|
1589 should remain after the function has returned. |
|
1590 |
|
1591 Note: |
|
1592 |
|
1593 A panic occurs if partial lines are excluded from the view (see |
|
1594 CTextLayout::ExcludingPartialLines()). |
|
1595 |
|
1596 Any background formatting is forced to complete first. |
|
1597 |
|
1598 @param aSelection Indicates the text range which has been reformatted. |
|
1599 @param aFormatChanged ETrue if text is to be reformatted from the start of the |
|
1600 paragraph the cursor was on before the edit, EFalse if from the start of the |
|
1601 line the cursor was on before the edit. |
|
1602 @return The number of pixels scrolled horizontally and vertically. */ |
|
1603 EXPORT_C TPoint CTextView::HandleRangeFormatChangeL(TCursorSelection aSelection |
|
1604 ,TBool aFormatChanged/*=EFalse*/) |
|
1605 { |
|
1606 if (NoMemoryCheckL() || (!aFormatChanged && aSelection.Length()==0)) |
|
1607 return TPoint(0,0); |
|
1608 FinishBackgroundFormattingL(); |
|
1609 iCursor.MatchCursorHeightToAdjacentChar(); |
|
1610 if (!iLayout->PosIsFormatted(iCursorPos.DocPos())) |
|
1611 { |
|
1612 TInt y=0; |
|
1613 return ViewTopOfLineL(iCursorPos.TmDocPos(),y,CTextView::EFViewDiscardAllFormat); |
|
1614 } |
|
1615 return HandleBlockChangeL(aSelection,aSelection.Length(),aFormatChanged); |
|
1616 } |
|
1617 |
|
1618 /** Reformats and redraws the view after inserting, deleting or replacing a |
|
1619 block of text. |
|
1620 |
|
1621 Can be used in combination with SetPendingSelection() to set a selection which |
|
1622 should remain after the function has returned. |
|
1623 |
|
1624 Notes: |
|
1625 |
|
1626 If inserting or deleting a single character, use CTextView::HandleCharEditL() |
|
1627 instead. |
|
1628 |
|
1629 A panic occurs if partial lines are excluded from the view (see |
|
1630 CTextLayout::ExcludingPartialLines()). |
|
1631 |
|
1632 @param aSelection The start and new length of the changed block. If this |
|
1633 function is being used to handle deletion only, this argument should be of |
|
1634 length zero and its start position should be the beginning of the deletion. |
|
1635 @param aDeletedChars The number of deleted characters. Specify zero if this |
|
1636 function is being used to handle insertion only. |
|
1637 @param aFormatChanged ETrue if text is to be reformatted from the start of the |
|
1638 paragraph the cursor was on before the edit, EFalse if from the start of the |
|
1639 line the cursor was on before the edit. |
|
1640 @return The number of pixels scrolled horizontally and vertically. */ |
|
1641 EXPORT_C TPoint CTextView::HandleInsertDeleteL(TCursorSelection aSelection,TInt aDeletedChars |
|
1642 ,TBool aFormatChanged/*=EFalse*/) |
|
1643 { |
|
1644 iContextIsNavigation = EFalse; |
|
1645 TInt docPos=aSelection.LowerPos(); |
|
1646 if (NoMemoryCheckL()) |
|
1647 return TPoint(0,CTextLayout::EFScrollRedrawWholeScreen); |
|
1648 if (IsFormatting()) |
|
1649 { |
|
1650 TViewYPosQualifier yPosQualifier; |
|
1651 TPoint scroll; |
|
1652 iCursorPos.SetPendingSelection(aSelection); |
|
1653 scroll=DoHandleGlobalChangeL(yPosQualifier,EFViewDiscardAllFormat); |
|
1654 return scroll; |
|
1655 } |
|
1656 iCursor.MatchCursorHeightToAdjacentChar(); |
|
1657 if (aSelection.iCursorPos!=aSelection.LowerPos()) |
|
1658 docPos+=aDeletedChars; |
|
1659 if (!iLayout->PosIsFormatted(docPos)) |
|
1660 { |
|
1661 TInt y=0; |
|
1662 TTmDocPos pos(aSelection.iCursorPos, EFalse); |
|
1663 if (pos.iPos == 0) |
|
1664 pos.iLeadingEdge = ETrue; |
|
1665 return ViewTopOfLineL(pos,y,CTextView::EFViewDiscardAllFormat); |
|
1666 } |
|
1667 return HandleBlockChangeL(aSelection,aDeletedChars,aFormatChanged); |
|
1668 } |
|
1669 |
|
1670 /** Moves the text cursor to a new document position. The view is scrolled so |
|
1671 that the line containing the new cursor position is at the top, or the bottom, |
|
1672 if the scroll direction was downwards. |
|
1673 |
|
1674 Any background formatting is forced to complete first. |
|
1675 |
|
1676 @param aDocPos |
|
1677 The new document position of the text cursor. |
|
1678 @param aDragSelectOn |
|
1679 ETrue if the region between the old and new cursor positions should be |
|
1680 selected, EFalse if not. If ETrue, any existing selection remains selected, |
|
1681 so that this function can be used to extend or shorten a selected region. |
|
1682 EFalse cancels any existing selection. |
|
1683 @return |
|
1684 The number of pixels scrolled horizontally and vertically. */ |
|
1685 EXPORT_C TPoint CTextView::SetDocPosL(const TTmDocPos& aDocPos,TBool aDragSelectOn) |
|
1686 { |
|
1687 iContextIsNavigation = ETrue; |
|
1688 TInt vertical_scroll = 0; |
|
1689 NoMemoryCheckL(); |
|
1690 FinishBackgroundFormattingL(); |
|
1691 iCursor.MatchCursorHeightToAdjacentChar(); |
|
1692 __ASSERT_DEBUG(iLayout->__DbgIsFormattingUpToDate(),FormPanic(EFFormatOutOfDate)); |
|
1693 TTmDocPos pos(aDocPos); |
|
1694 if (pos.iPos < 0) |
|
1695 { |
|
1696 pos.iPos = 0; |
|
1697 pos.iLeadingEdge = EFalse; |
|
1698 } |
|
1699 else |
|
1700 { |
|
1701 TInt doc_length = iLayout->DocumentLength(); |
|
1702 if (pos.iPos > doc_length) |
|
1703 { |
|
1704 pos.iPos = doc_length; |
|
1705 pos.iLeadingEdge = ETrue; |
|
1706 } |
|
1707 } |
|
1708 TRAPD(error,vertical_scroll = iCursorPos.SetDocPosL(aDragSelectOn,pos)); |
|
1709 if (error) |
|
1710 NoMemoryL(error); |
|
1711 TInt horizontal_scroll = DrawAfterCursorMoveL(vertical_scroll); |
|
1712 if (iCursorPos.IsSelectionToDraw()) |
|
1713 UpdateHighlightL(); |
|
1714 return TPoint(horizontal_scroll,vertical_scroll); |
|
1715 } |
|
1716 |
|
1717 |
|
1718 /** Moves the text cursor to a new document position. The view is scrolled so |
|
1719 that the line containing the new cursor position is at the top, or the bottom, |
|
1720 if the scroll direction was downwards. |
|
1721 |
|
1722 Any background formatting is forced to complete first. |
|
1723 |
|
1724 @param aDocPos |
|
1725 The new document position of the text cursor. |
|
1726 @param aDragSelectOn |
|
1727 ETrue if the region between the old and new cursor positions should be |
|
1728 selected, EFalse if not. If ETrue, any existing selection remains selected, |
|
1729 so that this function can be used to extend or shorten a selected region. |
|
1730 EFalse cancels any existing selection. |
|
1731 @return |
|
1732 The number of pixels scrolled horizontally and vertically. */ |
|
1733 EXPORT_C TPoint CTextView::SetDocPosL(TInt aDocPos,TBool aDragSelectOn) |
|
1734 { |
|
1735 TTmDocPos pos(aDocPos, |
|
1736 aDocPos == iLayout->DocumentLength()? EFalse : ETrue); |
|
1737 return SetDocPosL(pos,aDragSelectOn); |
|
1738 } |
|
1739 |
|
1740 /** Moves the text cursor to a new document position. The view is scrolled so |
|
1741 that the line containing the new cursor position is at the top, or the bottom, |
|
1742 if the scroll direction was downwards. |
|
1743 |
|
1744 Any background formatting is forced to complete first. |
|
1745 |
|
1746 @param aDocPos |
|
1747 The new document position of the text cursor. |
|
1748 @param aDragSelectOn |
|
1749 ETrue if the region between the old and new cursor positions should be |
|
1750 selected, EFalse if not. If ETrue, any existing selection remains selected, |
|
1751 so that this function can be used to extend or shorten a selected region. |
|
1752 EFalse cancels any existing selection. |
|
1753 @return |
|
1754 The number of pixels scrolled horizontally and vertically. */ |
|
1755 EXPORT_C TPoint CTextView::SetDocPosL(const TTmDocPosSpec& aDocPos,TBool aDragSelectOn) |
|
1756 { |
|
1757 TTmDocPos pos(aDocPos.iPos, aDocPos.iType == TTmDocPosSpec::ELeading); |
|
1758 return SetDocPosL(pos, aDragSelectOn); |
|
1759 } |
|
1760 |
|
1761 /** Moves the text cursor to the nearest point on the screen to the x,y coordinates |
|
1762 specified. |
|
1763 |
|
1764 Any background formatting is forced to complete first. |
|
1765 |
|
1766 @param aPos The window coordinates to which to move the text cursor. |
|
1767 @param aDragSelectOn ETrue if the region between the old and new cursor positions |
|
1768 should be selected, EFalse if not. If ETrue, any existing selection remains |
|
1769 selected, so that this function can be used to extend or shorten a selected |
|
1770 region.EFalse cancels any existing selection. |
|
1771 @param aPictureRect On return, a pointer to the rectangle enclosing the picture |
|
1772 at position aPos. If there is no picture at this position, returns NULL. |
|
1773 @param aPictureFrameEdges On return, indicates whether aPos is located within |
|
1774 the active region around a picture edge. The active region is the region inside |
|
1775 which the cursor can be used to resize the picture. A value of zero indicates |
|
1776 that aPos is not within this region. Otherwise, this value indicates which |
|
1777 active region aPos is located in. For more information, see TFrameOverlay::TEdges. |
|
1778 |
|
1779 @return The number of pixels scrolled horizontally and vertically. */ |
|
1780 EXPORT_C TPoint CTextView::SetXyPosL(TPoint aPos,TBool aDragSelectOn,TRect*& aPictureRect,TInt& aPictureFrameEdges) |
|
1781 { |
|
1782 iContextIsNavigation = ETrue; |
|
1783 NoMemoryCheckL(); |
|
1784 FinishBackgroundFormattingL(); |
|
1785 iCursor.MatchCursorHeightToAdjacentChar(); |
|
1786 __ASSERT_DEBUG(iLayout->__DbgIsFormattingUpToDate(),FormPanic(EFFormatOutOfDate)); |
|
1787 aPictureFrameEdges=TFrameOverlay::ENoEdges; |
|
1788 if (iPictureFrame && iCursorPos.IsPictureFrame() && SelectionVisible()) |
|
1789 { |
|
1790 aPictureFrameEdges=iPictureFrame->XyPosToEdges(aPos); |
|
1791 if (aPictureFrameEdges!=TFrameOverlay::ENoEdges && iDrawTextLayoutContext.TextArea().Contains(aPos)) |
|
1792 { |
|
1793 aPos=iPictureFrame->Rect().Center(); |
|
1794 aPictureRect=CONST_CAST(TRect*,&iPictureFrame->RefRect()); |
|
1795 return TPoint(0,0); |
|
1796 } |
|
1797 } |
|
1798 iDrawTextLayoutContext.WindowToText(aPos); |
|
1799 TInt scrollBy=0; //To stop warning |
|
1800 TRAPD(err,scrollBy=iCursorPos.SetXyPosL(aDragSelectOn,aPos,(iFlags & EFPictureFrameEnabled))); |
|
1801 // Have we just moved over a picture? |
|
1802 if(iCursorPos.IsPictureFrame()|| iCursorPos.IsNewPictureFrame()) |
|
1803 UpdatePictureFrameL(); |
|
1804 |
|
1805 if (err) |
|
1806 NoMemoryL(err); |
|
1807 TInt horizScrollBy=DrawAfterCursorMoveL(scrollBy); |
|
1808 if (iCursorPos.IsSelectionToDraw()) |
|
1809 UpdateHighlightL(); |
|
1810 if (iCursorPos.IsPictureFrame() && SelectionVisible()) //Should the rectangle be returned when there is color dimming #JD# The way it is written here it will not be |
|
1811 aPictureRect=CONST_CAST(TRect*,&iPictureFrame->RefRect()); |
|
1812 else |
|
1813 aPictureRect=NULL; |
|
1814 return TPoint(horizScrollBy,scrollBy); |
|
1815 } |
|
1816 |
|
1817 /** Scrolls the view either horizontally or vertically and does a redraw. |
|
1818 |
|
1819 Any background formatting is forced to complete first. |
|
1820 |
|
1821 @param aMovement Controls the direction and the amount of scroll. |
|
1822 @param aScrollBlankSpace CTextLayout::EFAllowScrollingBlankSpace allows blank |
|
1823 space to scroll into the visible area (applies when scrolling horizontally |
|
1824 as well as vertically), CTextLayout::EFDisallowScrollingBlankSpace prevents |
|
1825 blank space from scrolling into the visible area. |
|
1826 @pre aMovement must not scroll the display beyond the formatted range. If aMovement |
|
1827 scrolls beyond the formatted range, this method will leave with the error code |
|
1828 CTextLayout::EPosNotFormatted |
|
1829 @return The number of pixels scrolled */ |
|
1830 EXPORT_C TInt CTextView::ScrollDisplayL(TCursorPosition::TMovementType aMovement |
|
1831 ,CTextLayout::TAllowDisallow aScrollBlankSpace/*=EFDisallowScrollingBlankSpace*/) |
|
1832 { |
|
1833 TInt pixels=0; //To stop warning |
|
1834 |
|
1835 NoMemoryCheckL(); |
|
1836 __ASSERT_DEBUG(iLayout->__DbgIsFormattingUpToDate(),FormPanic(EFFormatOutOfDate)); |
|
1837 FinishBackgroundFormattingL(); |
|
1838 __ASSERT_DEBUG(iLayout->__DbgIsFormattingUpToDate(),FormPanic(EFFormatOutOfDate)); |
|
1839 TRAPD(err,pixels=DoScrollDisplayL(aMovement,aScrollBlankSpace)); |
|
1840 if (err) |
|
1841 { |
|
1842 if (err == CTextLayout::EPosNotFormatted) |
|
1843 User::Leave(err); |
|
1844 else |
|
1845 NoMemoryL(err); |
|
1846 } |
|
1847 return pixels; |
|
1848 } |
|
1849 |
|
1850 TInt CTextView::DoHorizontalScrollDisplayL(TCursorPosition::TMovementType aMovement |
|
1851 ,CTextLayout::TAllowDisallow aScrollBlankSpace) |
|
1852 { |
|
1853 TInt pixels=0; |
|
1854 TInt leftX,rightX; |
|
1855 |
|
1856 CalculateHorizontalExtremes(leftX,rightX,ETrue); |
|
1857 TInt rightEdgeScroll=iDrawTextLayoutContext.TextArea().Width()-rightX; |
|
1858 switch (aMovement) |
|
1859 { |
|
1860 case TCursorPosition::EFLeft: |
|
1861 pixels=iHorizontalScrollJump; |
|
1862 if (aScrollBlankSpace==CTextLayout::EFDisallowScrollingBlankSpace) |
|
1863 pixels=Min(pixels,Max(-leftX,0)); |
|
1864 break; |
|
1865 case TCursorPosition::EFRight: |
|
1866 pixels=-iHorizontalScrollJump; |
|
1867 if (aScrollBlankSpace==CTextLayout::EFDisallowScrollingBlankSpace) |
|
1868 pixels=Max(pixels,Min(rightEdgeScroll,0)); |
|
1869 break; |
|
1870 case TCursorPosition::EFLineBeg: |
|
1871 pixels=-leftX; |
|
1872 break; |
|
1873 case TCursorPosition::EFLineEnd: |
|
1874 pixels=rightEdgeScroll; |
|
1875 break; |
|
1876 default: |
|
1877 #if defined(_DEBUG) |
|
1878 FormPanic(EFInvalidScrollingType) |
|
1879 #endif |
|
1880 ; |
|
1881 } |
|
1882 SetLeftTextMargin(LeftTextMargin()-pixels); |
|
1883 |
|
1884 if (0 != pixels) |
|
1885 { |
|
1886 ScrollDisplayL(); |
|
1887 } |
|
1888 else |
|
1889 { |
|
1890 DrawCursor(); |
|
1891 } |
|
1892 |
|
1893 return pixels; |
|
1894 } |
|
1895 |
|
1896 TInt CTextView::DoScrollDisplayL(TCursorPosition::TMovementType aMovement, |
|
1897 CTextLayout::TAllowDisallow aScrollBlankSpace) |
|
1898 { |
|
1899 TInt pixels = 0; |
|
1900 TInt lines = 0; |
|
1901 TInt cursor_pos = 0; |
|
1902 |
|
1903 switch (aMovement) |
|
1904 { |
|
1905 case TCursorPosition::EFLeft: |
|
1906 case TCursorPosition::EFRight: |
|
1907 case TCursorPosition::EFLineBeg: |
|
1908 case TCursorPosition::EFLineEnd: |
|
1909 return DoHorizontalScrollDisplayL(aMovement,aScrollBlankSpace); |
|
1910 |
|
1911 case TCursorPosition::EFLineUp: |
|
1912 lines = 1; |
|
1913 break; |
|
1914 |
|
1915 case TCursorPosition::EFLineDown: |
|
1916 lines = -1; |
|
1917 break; |
|
1918 |
|
1919 case TCursorPosition::EFPageUp: |
|
1920 iLayout->PageUpL(cursor_pos,pixels); |
|
1921 break; |
|
1922 |
|
1923 case TCursorPosition::EFPageDown: |
|
1924 cursor_pos = iDrawTextLayoutContext.DisplayHeight() - 1; |
|
1925 iLayout->PageDownL(cursor_pos,pixels); |
|
1926 break; |
|
1927 |
|
1928 default: |
|
1929 break; |
|
1930 } |
|
1931 |
|
1932 if (lines) |
|
1933 pixels = iLayout->ScrollLinesL(lines,aScrollBlankSpace); |
|
1934 |
|
1935 if (pixels) |
|
1936 { |
|
1937 iCursorPos.TextMoveVertically(); |
|
1938 ScrollDisplayL(); |
|
1939 } |
|
1940 |
|
1941 return pixels; |
|
1942 } |
|
1943 |
|
1944 /** Moves the text cursor in the direction and manner specified. If necessary, |
|
1945 the view is scrolled so that the line containing the new cursor position is |
|
1946 visible. |
|
1947 |
|
1948 Any background formatting is forced to complete first. |
|
1949 |
|
1950 @param aMovement The direction and manner in which to move the cursor. On |
|
1951 return set to the actual cursor movement. The actual cursor movement may be |
|
1952 different from the one requested if for example the desired cursor movement is |
|
1953 upwards and the cursor is already on the top line. In this case, this argument |
|
1954 will return TCursorPosition::EFLineBeg. A return value of |
|
1955 TCursorPosition::EFNoMovement indicates that no cursor movement took place. |
|
1956 @param aDragSelectOn ETrue if the region between the old and new cursor |
|
1957 positions should be selected, EFalse if not. If ETrue, any existing selection |
|
1958 remains selected, so that this function can be used to extend or shorten a |
|
1959 selected region. EFalse cancels any existing selection. |
|
1960 @return The number of pixels scrolled horizontally and vertically. */ |
|
1961 EXPORT_C TPoint CTextView::MoveCursorL(TCursorPosition::TMovementType& aMovement,TBool aDragSelectOn) |
|
1962 { |
|
1963 iContextIsNavigation = ETrue; |
|
1964 NoMemoryCheckL(); |
|
1965 FinishBackgroundFormattingL(); |
|
1966 __ASSERT_DEBUG(iLayout->__DbgIsFormattingUpToDate(),FormPanic(EFFormatOutOfDate)); |
|
1967 iCursor.MatchCursorHeightToAdjacentChar(); |
|
1968 return DoMoveCursorL(aDragSelectOn, aMovement, |
|
1969 iFlags & EFPictureFrameEnabled); |
|
1970 } |
|
1971 |
|
1972 TPoint CTextView::DoMoveCursorL(TBool aDragSelectOn,TCursorPosition::TMovementType& aMovement |
|
1973 ,TBool aAllowPictureFrame) |
|
1974 { |
|
1975 TInt scrollBy=0; //To avoid complier warning |
|
1976 |
|
1977 TRAPD(err,scrollBy=iCursorPos.MoveL(aDragSelectOn,aMovement,aAllowPictureFrame)); |
|
1978 // Have we just moved over a picture? |
|
1979 if(iCursorPos.IsPictureFrame()|| iCursorPos.IsNewPictureFrame()) |
|
1980 UpdatePictureFrameL(); |
|
1981 |
|
1982 if (err) |
|
1983 NoMemoryL(err); |
|
1984 TInt horizScrollBy=DrawAfterCursorMoveL(scrollBy); |
|
1985 if (iCursorPos.IsSelectionToDraw()) |
|
1986 UpdateHighlightL(); |
|
1987 return TPoint(horizScrollBy,scrollBy); |
|
1988 } |
|
1989 |
|
1990 /** Scrolls the view vertically by a number of pixels, disallowing blank space |
|
1991 from scrolling into the bottom of the visible area. Redraws the newly visible |
|
1992 lines. |
|
1993 |
|
1994 Any background formatting is forced to complete first. |
|
1995 |
|
1996 @param aDeltaY |
|
1997 The number of pixels to scroll; may be a positive or negative value. On |
|
1998 return, contains the number of pixels actually scrolled. Positive values |
|
1999 move the text down, negative move it up. */ |
|
2000 EXPORT_C void CTextView::ScrollDisplayPixelsL(TInt& aDeltaY) |
|
2001 { |
|
2002 |
|
2003 NoMemoryCheckL(); |
|
2004 FinishBackgroundFormattingL(); |
|
2005 TRAPD(err,iLayout->ChangeBandTopL(aDeltaY)); |
|
2006 if (err) |
|
2007 NoMemoryL(err); |
|
2008 |
|
2009 if (0 != aDeltaY) |
|
2010 { |
|
2011 ScrollDisplayL(); |
|
2012 } |
|
2013 else |
|
2014 { |
|
2015 DrawCursor(); |
|
2016 } |
|
2017 } |
|
2018 |
|
2019 /** Scrolls the view vertically by a number of pixels, allowing blank space |
|
2020 from scrolling into both top and bottom of the visible area, which means the |
|
2021 scrolling can go beyond the top or bottom border. Redraws the newly visible |
|
2022 lines. |
|
2023 |
|
2024 Any background formatting is forced to complete first. |
|
2025 |
|
2026 @param aDeltaY |
|
2027 The number of pixels to scroll; may be a positive or negative value. On |
|
2028 return, contains the number of pixels actually scrolled. Positive values |
|
2029 move the text down, negative move it up. */ |
|
2030 EXPORT_C void CTextView::ScrollDisplayPixelsNoLimitBorderL(TInt aDeltaY) |
|
2031 { |
|
2032 NoMemoryCheckL(); |
|
2033 FinishBackgroundFormattingL(); |
|
2034 TRAPD(err,iLayout->ChangeBandTopNoLimitBorderL(aDeltaY)); |
|
2035 if (err) |
|
2036 NoMemoryL(err); |
|
2037 |
|
2038 if (0 != aDeltaY) |
|
2039 { |
|
2040 ScrollDisplayL(); |
|
2041 } |
|
2042 else |
|
2043 { |
|
2044 DrawCursor(); |
|
2045 } |
|
2046 } |
|
2047 |
|
2048 /** Scrolls the view vertically by a number of wholly or partially visible |
|
2049 lines, disallowing blank space at the bottom of the visible area if |
|
2050 aScrollBlankSpace is CTextLayout::EFDisallowScrollingBlankSpace. Redraws the |
|
2051 newly visible lines. |
|
2052 |
|
2053 Any background formatting is forced to complete first. |
|
2054 |
|
2055 @param aDeltaLines |
|
2056 The number of lines to scroll; may be a positive or negative value. |
|
2057 Positive values move the text down, negative move it up. On return, |
|
2058 contains the number of lines not scrolled; that is, the requested number, |
|
2059 minus the number actually scrolled. |
|
2060 @param aScrollBlankSpace |
|
2061 Only relevant when scrolling downwards. |
|
2062 CTextLayout::EFAllowScrollingBlankSpace allows blank space to scroll into |
|
2063 the visible area. CTextLayout::EFDisallowScrollingBlankSpace prevents blank |
|
2064 space from scrolling into the visible area. |
|
2065 @pre aDeltaLines must not scroll the display beyond the formatted range. If aDeltaLines |
|
2066 scrolls beyond the formatted range, this method will leave with the error code |
|
2067 CTextLayout::EPosNotFormatted |
|
2068 @return The number of pixels scrolled. |
|
2069 */ |
|
2070 EXPORT_C TInt CTextView::ScrollDisplayLinesL(TInt& aDeltaLines |
|
2071 ,CTextLayout::TAllowDisallow aScrollBlankSpace/*=EFDisallowScrollingBlankSpace*/) |
|
2072 { |
|
2073 TInt pixels=0; |
|
2074 |
|
2075 NoMemoryCheckL(); |
|
2076 FinishBackgroundFormattingL(); |
|
2077 TRAPD(err,pixels=iLayout->ScrollLinesL(aDeltaLines,aScrollBlankSpace)); |
|
2078 if (err) |
|
2079 { |
|
2080 if (err == CTextLayout::EPosNotFormatted) |
|
2081 User::Leave(err); |
|
2082 else |
|
2083 NoMemoryL(err); |
|
2084 } |
|
2085 |
|
2086 if (0 != pixels) |
|
2087 { |
|
2088 ScrollDisplayL(); |
|
2089 } |
|
2090 else |
|
2091 { |
|
2092 DrawCursor(); |
|
2093 } |
|
2094 |
|
2095 return pixels; |
|
2096 } |
|
2097 |
|
2098 /** Scrolls the view by a number of wholly or partially visible paragraphs |
|
2099 disallowing blank space at the bottom of the visible area if aScrollBlankSpace |
|
2100 is CTextLayout::EFDisallowScrollingBlankSpace. Redraws the newly visible |
|
2101 paragraphs. |
|
2102 |
|
2103 Any background formatting is forced to complete first. |
|
2104 |
|
2105 @param aDeltaParas |
|
2106 The number of paragraphs to scroll; may be a positive or negative value; |
|
2107 positive values move the text down, negative move it up. On return, |
|
2108 contains the number of paragraphs not scrolled; that is the difference |
|
2109 between the requested number and the number of paragraphs actually |
|
2110 scrolled. |
|
2111 @param aScrollBlankSpace |
|
2112 Only relevant when scrolling downwards. |
|
2113 CTextLayout::EFAllowScrollingBlankSpace allows blank space to scroll into |
|
2114 the visible area. CTextLayout::EFDisallowScrollingBlankSpace prevents blank |
|
2115 space from scrolling into the visible area. |
|
2116 @pre aDeltaParas must not scroll the display beyond the formatted range. If aDeltaParas |
|
2117 scrolls beyond the formatted range, this method will leave with the error code |
|
2118 CTextLayout::EPosNotFormatted |
|
2119 @return The number of pixels scrolled. */ |
|
2120 EXPORT_C TInt CTextView::ScrollDisplayParagraphsL(TInt& aDeltaParas |
|
2121 ,CTextLayout::TAllowDisallow aScrollBlankSpace/*=EFDisallowScrollingBlankSpace*/) |
|
2122 { |
|
2123 TInt pixels=0; |
|
2124 |
|
2125 NoMemoryCheckL(); |
|
2126 FinishBackgroundFormattingL(); |
|
2127 TRAPD(err,pixels=iLayout->ScrollParagraphsL(aDeltaParas,aScrollBlankSpace)); |
|
2128 if (err) |
|
2129 { |
|
2130 if (err == CTextLayout::EPosNotFormatted) |
|
2131 User::Leave(err); |
|
2132 else |
|
2133 NoMemoryL(err); |
|
2134 } |
|
2135 |
|
2136 if (0 != pixels) |
|
2137 { |
|
2138 ScrollDisplayL(); |
|
2139 } |
|
2140 else |
|
2141 { |
|
2142 DrawCursor(); |
|
2143 } |
|
2144 |
|
2145 return pixels; |
|
2146 } |
|
2147 |
|
2148 /** Returns the left and right extremes, in window coordinates, of the formatted |
|
2149 text. |
|
2150 |
|
2151 @param aLeftX On return, contains the x coordinate of the leftmost point of |
|
2152 the formatted text. |
|
2153 @param aRightX On return, contains the x coordinate of the rightmost point |
|
2154 of the formatted text. |
|
2155 @param aOnlyVisibleLines If ETrue, only scans partially or fully visible lines. |
|
2156 If EFalse, scans all the formatted text. */ |
|
2157 EXPORT_C void CTextView::CalculateHorizontalExtremesL(TInt& aLeftX,TInt& aRightX,TBool aOnlyVisibleLines) |
|
2158 { |
|
2159 |
|
2160 CalculateHorizontalExtremes(aLeftX,aRightX,aOnlyVisibleLines); |
|
2161 } |
|
2162 |
|
2163 void CTextView::CalculateHorizontalExtremes(TInt& aLeftX,TInt& aRightX,TBool aOnlyVisibleLines) |
|
2164 { |
|
2165 iLayout->CalculateHorizontalExtremes(aLeftX,aRightX,aOnlyVisibleLines); |
|
2166 aLeftX += iDrawTextLayoutContext.iTextStartX; |
|
2167 aRightX += iDrawTextLayoutContext.iTextStartX; |
|
2168 } |
|
2169 |
|
2170 /** Scroll the display below point aFrom by aScrollX. |
|
2171 |
|
2172 aScrollY>0 ==> text moves down. |
|
2173 |
|
2174 aScrollX>0 ==> text moves right. |
|
2175 |
|
2176 aFrom is relative to the text area of the window. |
|
2177 |
|
2178 aScrollBackground determines whether the background can scroll along with the text. |
|
2179 |
|
2180 Enters OOM before leaving */ |
|
2181 void CTextView::ScrollTextL(TInt aScrollY,TInt aFrom,TInt aScrollX,TBool aScrollBackground) |
|
2182 { |
|
2183 TRect rect; |
|
2184 TInt height=iDrawTextLayoutContext.DisplayHeight(); |
|
2185 |
|
2186 __ASSERT_DEBUG(aScrollX!=0 || aScrollY!=0,FormPanic(EFScrollByZero2)); |
|
2187 __ASSERT_DEBUG(aFrom==0 || aScrollX==0,FormPanic(EFScrollError)); //Can only scroll the whole of the ViewRect Horizontally |
|
2188 if (aScrollX==0) |
|
2189 rect=iDrawTextLayoutContext.iViewRect; |
|
2190 else |
|
2191 rect=iDrawTextLayoutContext.TextArea(); |
|
2192 |
|
2193 if (iReducedDrawingAreaRect.Height()) |
|
2194 { |
|
2195 rect.Intersection(iReducedDrawingAreaRect); |
|
2196 } |
|
2197 |
|
2198 if (iReducedDrawingAreaRect.Height()) |
|
2199 rect.Intersection(iReducedDrawingAreaRect); |
|
2200 |
|
2201 if (ExtendedHighlightExists()) |
|
2202 { |
|
2203 AdjustRectForScrolling(rect,aScrollY,aScrollX); |
|
2204 } |
|
2205 |
|
2206 ScrollRect(rect,aScrollY,aFrom,aScrollX,aScrollBackground); |
|
2207 if (aScrollX!=0 && aScrollY!=0) |
|
2208 { |
|
2209 rect=iDrawTextLayoutContext.TotalMargin(); |
|
2210 ScrollRect(rect,aScrollY,0,0,aScrollBackground); |
|
2211 } |
|
2212 |
|
2213 if (iHeightNotDrawn>0 && aScrollY<0 && height+aScrollY>=aFrom) |
|
2214 { |
|
2215 iDisplay.SetRects(RScreenDisplay::EFClipViewRect); |
|
2216 DisplayLineRangeL(aScrollY+height-iHeightNotDrawn,aScrollY+height); |
|
2217 } |
|
2218 } |
|
2219 |
|
2220 |
|
2221 /** Scroll part of the view rect. |
|
2222 @param aScrollY |
|
2223 Number of pixels downwards to scroll |
|
2224 @param aFrom |
|
2225 First line visible after the scroll. |
|
2226 @param aTo |
|
2227 Last line visible after the scroll. |
|
2228 */ |
|
2229 void CTextView::ScrollRect(TInt aScrollY,TInt& aFrom,TInt& aTo) |
|
2230 { |
|
2231 TRect rect=ViewRect(); |
|
2232 |
|
2233 if (ExtendedHighlightExists()) |
|
2234 { |
|
2235 AdjustRectForScrolling(rect,aScrollY,0); |
|
2236 } |
|
2237 |
|
2238 TInt top=rect.iTl.iY; |
|
2239 |
|
2240 __ASSERT_DEBUG(aTo>=0 && aTo>aFrom,FormPanic(EFScrollError)); |
|
2241 aFrom-=aScrollY; |
|
2242 if (aFrom>0) |
|
2243 { |
|
2244 rect.iTl.iY+=aFrom; |
|
2245 if (aFrom>=iDrawTextLayoutContext.DisplayHeight()) |
|
2246 { |
|
2247 aFrom+=aScrollY; |
|
2248 aTo=aFrom; |
|
2249 return; |
|
2250 } |
|
2251 } |
|
2252 aTo+=top-aScrollY; |
|
2253 if (aTo<rect.iBr.iY) |
|
2254 { |
|
2255 rect.iBr.iY=aTo; |
|
2256 if (aTo<=top) |
|
2257 { |
|
2258 aTo-=top-aScrollY; |
|
2259 aFrom=aTo; |
|
2260 return; |
|
2261 } |
|
2262 } |
|
2263 iDisplay.Scroll(rect,TPoint(0,aScrollY),FALSE); |
|
2264 aFrom=rect.iTl.iY+aScrollY-top; |
|
2265 aTo=rect.iBr.iY+aScrollY-top; |
|
2266 } |
|
2267 |
|
2268 /** Scroll part of the view rect */ |
|
2269 void CTextView::ScrollRect(TRect& aRect,TInt aScrollY,TInt aFrom,TInt aScrollX,TBool aScrollBackground) |
|
2270 { |
|
2271 |
|
2272 aFrom=aFrom<0?0:aFrom; |
|
2273 if (aScrollY+aFrom<0) |
|
2274 aRect.iTl.iY-=aScrollY; |
|
2275 else |
|
2276 { |
|
2277 aRect.iTl.iY+=aFrom; |
|
2278 if (aScrollY>0) |
|
2279 aRect.iBr.iY-=aScrollY; |
|
2280 } |
|
2281 if (aScrollX<0) |
|
2282 aRect.iTl.iX-=aScrollX; |
|
2283 else |
|
2284 aRect.iBr.iX-=aScrollX; |
|
2285 iDisplay.SetRects(RScreenDisplay::EFClipViewRect); |
|
2286 iDisplay.ActivateContext(); |
|
2287 iDisplay.ResetClippingRect(); |
|
2288 iDisplay.Scroll(aRect,TPoint(aScrollX,aScrollY),aScrollBackground); |
|
2289 iDisplay.DeactivateContext(); |
|
2290 } |
|
2291 |
|
2292 /** Scroll the display and redraw the missing lines.*/ |
|
2293 void CTextView::ScrollDisplayL() |
|
2294 { |
|
2295 iDisplay.SetRects(RScreenDisplay::EFClipViewRect); |
|
2296 DrawTextL(); |
|
2297 } |
|
2298 |
|
2299 /** Sets the visibility of the line and text cursors. |
|
2300 |
|
2301 Notes: |
|
2302 |
|
2303 A group window must have been provided before a text cursor can be drawn. |
|
2304 |
|
2305 Before making the line cursor visible, a line cursor bitmap must have been |
|
2306 provided (see SetLineCursorBitmap()). |
|
2307 |
|
2308 @param aLineCursor Sets whether the line cursor should be displayed. For possible |
|
2309 values, see the TCursor::TVisibility enumeration. |
|
2310 @param aTextCursor Sets whether the text cursor should be displayed and if |
|
2311 so, whether it should flash. For possible values, see the TCursor::TVisibility |
|
2312 enumeration. */ |
|
2313 EXPORT_C void CTextView::SetCursorVisibilityL(TUint aLineCursor,TUint aTextCursor) |
|
2314 { |
|
2315 __ASSERT_DEBUG(iLayout->__DbgIsFormattingUpToDate() || |
|
2316 (aLineCursor==TCursor::EFCursorInvisible && aTextCursor==TCursor::EFCursorInvisible), |
|
2317 FormPanic(EFFormatOutOfDate)); |
|
2318 NoMemoryCheckL(); |
|
2319 iCursor.SetVisibility((TCursor::TVisibility)aLineCursor,(TCursor::TVisibility)aTextCursor); |
|
2320 } |
|
2321 |
|
2322 /** Sets whether the text and pictures within a selection should be highlighted. |
|
2323 If necessary, the view is redrawn. |
|
2324 |
|
2325 An example of when this function may need to be used is when a control loses |
|
2326 or gains focus. |
|
2327 |
|
2328 @param aSelectionVisible ETrue for highlighted selection. EFalse for unhighlighted |
|
2329 selection. */ |
|
2330 EXPORT_C void CTextView::SetSelectionVisibilityL(TBool aVisible) |
|
2331 { |
|
2332 |
|
2333 NoMemoryCheckL(); |
|
2334 TBool needInverting=((!aVisible)!=(!(iFlags & EFSelectionVisible))); //Extra '!' needed to cope with aVisible>1 |
|
2335 if (needInverting && !iDrawTextLayoutContext.TextOverrideColor() && (iFlags & EFTextVisible)) |
|
2336 { |
|
2337 TCursorSelection selection; |
|
2338 |
|
2339 __ASSERT_DEBUG(iLayout->__DbgIsFormattingUpToDate(),FormPanic(EFFormatOutOfDate)); |
|
2340 iFlags |= EFSelectionVisible; |
|
2341 iCursorPos.GetSelection(selection); |
|
2342 TBool isPictureFrame=iCursorPos.IsPictureFrame(); |
|
2343 iDisplay.SetRects(RScreenDisplay::EFClipTextArea); |
|
2344 iDisplay.ActivateContext(); |
|
2345 iDisplay.ResetClippingRect(); |
|
2346 if (selection.Length()>0) |
|
2347 { |
|
2348 if (isPictureFrame) |
|
2349 { |
|
2350 iCursorPos.DontDrawOldPictureFrame(); |
|
2351 RedrawPictureFrameRectL(selection.LowerPos()); |
|
2352 DrawCursor(TCursor::EFTextCursor); |
|
2353 } |
|
2354 else |
|
2355 { |
|
2356 CTextLayout::TRangeChange select(selection.iAnchorPos, selection.iCursorPos, |
|
2357 aVisible? CTextLayout::TRangeChange::ESet : CTextLayout::TRangeChange::EClear); |
|
2358 iDisplay.SetRects(RScreenDisplay::EFClipExtendedTextArea); |
|
2359 iDisplay.ResetClippingRect(); |
|
2360 HighlightUsingExtensions(select,select); |
|
2361 } |
|
2362 } |
|
2363 iDisplay.DeactivateContext(); |
|
2364 } |
|
2365 if (aVisible) |
|
2366 iFlags |= EFSelectionVisible; |
|
2367 else |
|
2368 iFlags &= ~EFSelectionVisible; |
|
2369 } |
|
2370 |
|
2371 /** Sets whether a picture frame should be displayed when the text cursor is located |
|
2372 at a picture character. |
|
2373 |
|
2374 Note: |
|
2375 |
|
2376 If a picture frame is currently displayed, and aEnabled is EFalse, a redraw |
|
2377 takes place, so that the frame is removed. |
|
2378 |
|
2379 @param aEnabled True to enable picture frames, false to disable them. */ |
|
2380 EXPORT_C void CTextView::EnablePictureFrameL(TBool aEnabled) |
|
2381 { |
|
2382 |
|
2383 NoMemoryCheckL(); |
|
2384 if (aEnabled) |
|
2385 iFlags |= EFPictureFrameEnabled; |
|
2386 else |
|
2387 iFlags &= ~EFPictureFrameEnabled; |
|
2388 if (iCursorPos.IsPictureFrame() && !aEnabled) |
|
2389 CancelSelectionL(); |
|
2390 } |
|
2391 |
|
2392 /** Returns if the selection is currently visible. |
|
2393 |
|
2394 In particular, the selection is invisible if the text color has been |
|
2395 overridden. */ |
|
2396 EXPORT_C TBool CTextView::SelectionVisible() const |
|
2397 { |
|
2398 return ((!iDrawTextLayoutContext.TextOverrideColor()) |
|
2399 && (iFlags & EFSelectionVisible) && (iFlags & EFTextVisible)); |
|
2400 } |
|
2401 |
|
2402 TPoint CTextView::ViewTopOfLineL(const TTmDocPos& aDocPos,TInt& aYPos,CTextView::TDiscard aDiscardFormat, |
|
2403 TDoHorizontalScroll aHorizontalScroll) |
|
2404 { |
|
2405 TViewYPosQualifier yPosQualifier; |
|
2406 yPosQualifier.SetHotSpot(TViewYPosQualifier::EFViewTopOfLine); |
|
2407 return ViewL(aDocPos,aYPos,yPosQualifier,aDiscardFormat,aHorizontalScroll); |
|
2408 } |
|
2409 |
|
2410 TPoint CTextView::ViewL(const TTmDocPos& aDocPos,TInt& aYPos,TViewYPosQualifier aYPosQualifier, |
|
2411 CTextView::TDiscard aDiscardFormat,TDoHorizontalScroll aHorizontalScroll) |
|
2412 { |
|
2413 CTextLayout::TDiscard discardFormat=CTextLayout::EFViewDontDiscardFormat; |
|
2414 TInt scrollBy = 0; |
|
2415 |
|
2416 if (aDiscardFormat==EFViewDiscardAllFormat || aDiscardFormat==EFViewDiscardAllNoRedraw) |
|
2417 discardFormat=CTextLayout::EFViewDiscardAllFormat; |
|
2418 if (IsFormatting()) |
|
2419 { |
|
2420 if (discardFormat==CTextLayout::EFViewDontDiscardFormat) |
|
2421 FinishBackgroundFormattingL(); |
|
2422 else |
|
2423 { |
|
2424 iWrap->Cancel(); |
|
2425 iLayout->NotifyTerminateBackgroundFormatting(); |
|
2426 } |
|
2427 } |
|
2428 TRAPD(err,scrollBy=iLayout->SetViewL(aDocPos,aYPos,aYPosQualifier,discardFormat)); |
|
2429 if (err) |
|
2430 NoMemoryL(err); |
|
2431 NotifyReformatL(); |
|
2432 if (aDiscardFormat==EFViewDontDiscardFullRedraw) |
|
2433 scrollBy=CTextLayout::EFScrollRedrawWholeScreen; |
|
2434 TInt horizScrollBy=0; |
|
2435 if (aHorizontalScroll) |
|
2436 horizScrollBy=CheckHorizontalScroll(aDocPos); |
|
2437 if (aDiscardFormat!=EFViewDiscardAllNoRedraw) |
|
2438 { |
|
2439 if (0 != scrollBy || 0 != horizScrollBy) |
|
2440 { |
|
2441 ScrollDisplayL(); |
|
2442 } |
|
2443 else |
|
2444 { |
|
2445 DrawCursor(); |
|
2446 } |
|
2447 } |
|
2448 iCursorPos.UpdateLatentPosition(); |
|
2449 return TPoint(horizScrollBy,scrollBy); |
|
2450 } |
|
2451 |
|
2452 /** Moves the view vertically and redraws, so that the top of the specified line |
|
2453 is located flush with the top of the view rectangle. |
|
2454 |
|
2455 Note: |
|
2456 |
|
2457 Line numbering is relative to formatted text only and the first formatted |
|
2458 line is numbered one. |
|
2459 |
|
2460 @param aLineNo The number of the line to be displayed at the top of the view |
|
2461 rectangle. |
|
2462 @return The number of pixels the text was scrolled, may be positive or negative. |
|
2463 A value of CTextLayout::EFScrollRedrawWholeScreen indicates that the entire |
|
2464 visible area, at least, was scrolled. */ |
|
2465 EXPORT_C TPoint CTextView::SetViewLineAtTopL(TInt aLineNo) |
|
2466 { |
|
2467 NoMemoryCheckL(); |
|
2468 TTmDocPos pos(iLayout->FirstCharOnLine(aLineNo), ETrue); |
|
2469 TInt pixel = 0; |
|
2470 return ViewTopOfLineL(pos,pixel,CTextView::EFViewDontDiscardFormat,EFNoHorizontalScroll); |
|
2471 } |
|
2472 |
|
2473 /** Sets the vertical position of the view, so that the line containing |
|
2474 aDocPos is located as close as possible to the vertical window coordinate |
|
2475 aYPos. |
|
2476 |
|
2477 Which part of the line is set to appear at aYPos (top, baseline, or bottom) |
|
2478 is controlled by aYPosQualifier, which also specifies whether the visible |
|
2479 area is to be filled and whether the line should be made fully visible if |
|
2480 possible. |
|
2481 |
|
2482 @param aDocPos The document position. Must be valid or a panic occurs. |
|
2483 @param aYPos The y coordinate at which to position the character at aDocPos. |
|
2484 On return, contains the actual vertical window coordinate at which the document |
|
2485 position has been set. |
|
2486 @param aYPosQualifier Controls which part of the line should appear at aYPos. |
|
2487 @param aDiscardFormat If EFViewDiscardAllFormat or EFViewDiscardAllNoRedraw |
|
2488 the text is reformatted to include aDocPos, otherwise text is formatted |
|
2489 only as necessary when bringing new lines into the visible area. |
|
2490 If EFViewDiscardAllNoRedraw, no redraw takes place. |
|
2491 @return The number of pixels scrolled horizontally and vertically. The |
|
2492 vertical coordinate may have a value of CTextLayout::EFScrollRedrawWholeScreen. |
|
2493 This indicates that the entire visible area, at least, was scrolled, and |
|
2494 so a full redraw was needed. */ |
|
2495 EXPORT_C TPoint CTextView::SetViewL(TInt aDocPos,TInt& aYPos,TViewYPosQualifier aYPosQualifier, |
|
2496 TDiscard aDiscardFormat,TDoHorizontalScroll aDoHorizontalScroll) |
|
2497 { |
|
2498 if (NoMemoryCheckL()) |
|
2499 aDiscardFormat = CTextView::EFViewDontDiscardFullRedraw; |
|
2500 __ASSERT_ALWAYS(aDocPos >= 0 && aDocPos <= iLayout->DocumentLength(),FormPanic(EFInvalidDocPos)); |
|
2501 aYPos -= TopViewRect(); |
|
2502 TTmDocPos pos(aDocPos, |
|
2503 aDocPos == iLayout->DocumentLength()? EFalse : ETrue); |
|
2504 TPoint scroll = ViewL(pos,aYPos,aYPosQualifier,aDiscardFormat,aDoHorizontalScroll); |
|
2505 aYPos += TopViewRect(); |
|
2506 return scroll; |
|
2507 } |
|
2508 |
|
2509 /** Finds the base line height of the cursor pos */ |
|
2510 TInt CTextView::CalculateBaseLinePos(TTmDocPos& aDocPos) |
|
2511 { |
|
2512 TInt y=iGood; //The height to put the cursor at to recovery from OOM |
|
2513 |
|
2514 aDocPos = iCursorPos.TmDocPos(); |
|
2515 if (!iNoMemory) |
|
2516 { |
|
2517 TPoint xy(0,0); |
|
2518 if (!iLayout->PosInBand(aDocPos,xy)) |
|
2519 { |
|
2520 xy.SetXY(0,0); |
|
2521 TTmPosInfo2 pos_info; |
|
2522 iLayout->FindXyPos(xy,pos_info); |
|
2523 aDocPos = pos_info.iDocPos; |
|
2524 xy = pos_info.iEdge; |
|
2525 } |
|
2526 y=xy.iY; |
|
2527 } |
|
2528 return y; |
|
2529 } |
|
2530 |
|
2531 /** Discards and reformats keeping the cursor at the same height on the screen |
|
2532 if possible. Enters OOM state before leaving */ |
|
2533 TPoint CTextView::DoHandleGlobalChangeL(TViewYPosQualifier aYPosQualifier,CTextView::TDiscard aDiscard) |
|
2534 { |
|
2535 TTmDocPos docPos; |
|
2536 TInt y = CalculateBaseLinePos(docPos); |
|
2537 TCursorSelection selection; |
|
2538 TTmDocPos docLen(iLayout->DocumentLength(),FALSE); |
|
2539 const TInt visHeight=iDrawTextLayoutContext.iViewRect.Height(); |
|
2540 TRect cursorLine; |
|
2541 |
|
2542 iLayout->GetLineRect(y,cursorLine); |
|
2543 switch (aYPosQualifier.iHotSpot) |
|
2544 { |
|
2545 case TViewYPosQualifier::EFViewTopOfLine: |
|
2546 y=cursorLine.iTl.iY; |
|
2547 break; |
|
2548 case TViewYPosQualifier::EFViewBottomOfLine: |
|
2549 y=cursorLine.iBr.iY-1; |
|
2550 default:; |
|
2551 } |
|
2552 if (aYPosQualifier.iFullyVisible==TViewYPosQualifier::EFViewDontForceLineFullyVisible) |
|
2553 { |
|
2554 if (y<0) |
|
2555 { |
|
2556 UseBottom: |
|
2557 y=(cursorLine.iBr.iY>visHeight ? visHeight:cursorLine.iBr.iY)-1; |
|
2558 aYPosQualifier.iHotSpot=TViewYPosQualifier::EFViewBottomOfLine; |
|
2559 } |
|
2560 else if (y>=visHeight) |
|
2561 { |
|
2562 if (cursorLine.iTl.iY<0) |
|
2563 goto UseBottom; //else UseTop |
|
2564 y=cursorLine.iTl.iY; |
|
2565 aYPosQualifier.iHotSpot=TViewYPosQualifier::EFViewTopOfLine; |
|
2566 } |
|
2567 } |
|
2568 if (docPos > docLen) |
|
2569 docPos = docLen; |
|
2570 iCursorPos.GetSelection(selection); |
|
2571 if (selection.LowerPos() > docLen.iPos) |
|
2572 { |
|
2573 iCursorPos.CancelHighlight(); |
|
2574 iCursorPos.SetDocPos(docLen); |
|
2575 } |
|
2576 else if (selection.HigherPos() > docLen.iPos) |
|
2577 { |
|
2578 iCursorPos.CancelHighlight(); |
|
2579 iCursorPos.SetDocPos(docLen); |
|
2580 } |
|
2581 return ViewL(docPos,y,aYPosQualifier,aDiscard); |
|
2582 } |
|
2583 |
|
2584 /** Reformats and redraws the view after a global change has been made to the |
|
2585 layout. Examples of global layout changes include changing the format mode, the |
|
2586 wrap width, or the visibility of nonprinting characters. |
|
2587 |
|
2588 Forces any background formatting to complete. |
|
2589 |
|
2590 @param aYPosQualifier Specifies whether the visible area is to be filled and |
|
2591 whether the top line should be made fully visible if possible. */ |
|
2592 EXPORT_C void CTextView::HandleGlobalChangeL(TViewYPosQualifier aYPosQualifier) |
|
2593 { |
|
2594 CTextView::TDiscard discard=EFViewDiscardAllFormat; |
|
2595 |
|
2596 if (NoMemoryCheckL()) |
|
2597 discard=EFViewDontDiscardFullRedraw; |
|
2598 DoHandleGlobalChangeL(aYPosQualifier,discard); |
|
2599 } |
|
2600 |
|
2601 /** Reformats the view after a global change has been made to the layout, but |
|
2602 without causing a redraw. Examples of global layout changes include changing |
|
2603 the format mode, the wrap width, or the visibility of nonprinting characters. |
|
2604 |
|
2605 Forces any background formatting to complete. |
|
2606 |
|
2607 @param aYPosQualifier Specifies whether the visible area is to be filled and |
|
2608 whether the top line should be made fully visible if possible. */ |
|
2609 EXPORT_C void CTextView::HandleGlobalChangeNoRedrawL(TViewYPosQualifier aYPosQualifier) |
|
2610 { |
|
2611 CTextView::TDiscard discard=EFViewDiscardAllNoRedraw; |
|
2612 |
|
2613 if (NoMemoryCheckL()) |
|
2614 return; |
|
2615 DoHandleGlobalChangeL(aYPosQualifier,discard); |
|
2616 } |
|
2617 |
|
2618 /** Reformats and redraws to reflect the addition of one or more complete |
|
2619 paragraphs at the end of the text. For instance, it may be used where |
|
2620 information is being found by an active object and appended to a document. |
|
2621 |
|
2622 Note: |
|
2623 |
|
2624 This function should not be used to handle the situation where text is added to |
|
2625 the final paragraph. In this case, use HandleInsertDeleteL() or |
|
2626 HandleCharEditL() instead. */ |
|
2627 EXPORT_C void CTextView::HandleAdditionalCharactersAtEndL() |
|
2628 { |
|
2629 __ASSERT_DEBUG(!IsFormatting(),FormPanic(EFBackgroundFormatting)); |
|
2630 if (!NoMemoryCheckL()) |
|
2631 { |
|
2632 TInt from = 0; |
|
2633 TInt to = 0; |
|
2634 TRAPD(err,iLayout->HandleAdditionalCharactersAtEndL(from,to)); |
|
2635 if (err) |
|
2636 NoMemoryL(err); |
|
2637 NotifyReformatL(); |
|
2638 iDisplay.SetRects(RScreenDisplay::EFClipViewRect); |
|
2639 DisplayLineRangeL(from,to); |
|
2640 } |
|
2641 } |
|
2642 |
|
2643 /** Forces completion of background formatting. |
|
2644 |
|
2645 This is called automatically by all CTextView functions which depend on the |
|
2646 formatting being up to date. */ |
|
2647 EXPORT_C void CTextView::FinishBackgroundFormattingL() |
|
2648 { |
|
2649 while (NextLineL()) {} |
|
2650 } |
|
2651 |
|
2652 void CTextView::UpdateHighlightL() |
|
2653 // |
|
2654 //Correct the highlight after a cursor movement |
|
2655 //Enters OOM before leaving |
|
2656 // |
|
2657 { |
|
2658 if (!SelectionVisible()) |
|
2659 return; |
|
2660 |
|
2661 TCursorSelection oldSelection; |
|
2662 TCursorSelection newSelection; |
|
2663 DrawWithPreviousHighlight(); |
|
2664 iCursorPos.GetSelection(oldSelection); |
|
2665 TBool oldPictureFrame = iCursorPos.IsPictureFrame(); |
|
2666 DrawWithCurrentHighlight(); |
|
2667 iCursorPos.GetSelection(newSelection); |
|
2668 |
|
2669 if (newSelection.LowerPos()==oldSelection.LowerPos() |
|
2670 && iCursorPos.DrawOldPictureFrame() && iCursorPos.DrawNewPictureFrame()) |
|
2671 { |
|
2672 iCursorPos.DontDrawOldPictureFrame(); |
|
2673 return; |
|
2674 } |
|
2675 |
|
2676 iDisplay.SetRects(RScreenDisplay::EFClipTextArea); |
|
2677 iDisplay.ActivateContext(); |
|
2678 iDisplay.ResetClippingRect(); |
|
2679 |
|
2680 if (iCursorPos.DrawOldPictureFrame()) |
|
2681 { |
|
2682 RedrawPictureFrameRectL(oldSelection.LowerPos()); // DrawWithCurrentHighlight() was called, so it will hide the old picture frame |
|
2683 iCursorPos.DontDrawOldPictureFrame(); |
|
2684 } |
|
2685 if (iCursorPos.DrawHighlight()) |
|
2686 { |
|
2687 TCursorSelection select; |
|
2688 iCursorPos.GetOldSelection(select); |
|
2689 CTextLayout::TRangeChange old; |
|
2690 if (!oldPictureFrame) |
|
2691 old.Set(select.iAnchorPos, select.iCursorPos, |
|
2692 CTextLayout::TRangeChange::EClear); |
|
2693 iCursorPos.GetSelection(select); |
|
2694 CTextLayout::TRangeChange now; |
|
2695 if (!iCursorPos.IsNewPictureFrame()) |
|
2696 now.Set(select.iAnchorPos, select.iCursorPos, |
|
2697 CTextLayout::TRangeChange::ESet); |
|
2698 CTextLayout::TRangeChange original; |
|
2699 original=now; |
|
2700 now.OptimizeWith(old); |
|
2701 iDisplay.SetRects(RScreenDisplay::EFClipExtendedTextArea); |
|
2702 iDisplay.ResetClippingRect(); |
|
2703 |
|
2704 if (now.IsJoinedTo(old)) |
|
2705 { |
|
2706 now.Join(old); |
|
2707 HighlightUsingExtensions(now,original); |
|
2708 } |
|
2709 else |
|
2710 { |
|
2711 HighlightUsingExtensions(old,original); |
|
2712 HighlightUsingExtensions(now,original); |
|
2713 } |
|
2714 } |
|
2715 if (iCursorPos.DrawNewPictureFrame()) |
|
2716 { |
|
2717 RedrawPictureFrameRectL(newSelection.LowerPos()); // DrawWithCurrentHighlight() was called, so it will draw the new picture frame |
|
2718 } |
|
2719 iDisplay.DeactivateContext(); |
|
2720 } |
|
2721 |
|
2722 void CTextView::HighlightUsingExtensions(CTextLayout::TRangeChange aOptimizedRange, CTextLayout::TRangeChange aOriginalRange) |
|
2723 { |
|
2724 TInt visPos; |
|
2725 TInt visLen=iLayout->PosRangeInBand(visPos); |
|
2726 |
|
2727 __ASSERT_DEBUG(visLen>=0,FormPanic(EFNoMemory)); // Shouldn't be in OOM here. |
|
2728 __ASSERT_DEBUG(SelectionVisible(),FormPanic(EFSelectionNotVisible)); |
|
2729 |
|
2730 if (!aOptimizedRange.Clip(visPos, visPos + visLen)) |
|
2731 return; |
|
2732 (void)aOriginalRange.Clip(visPos, visPos + visLen); |
|
2733 |
|
2734 // Added to reduce the area drawn to allow layout to work consistently |
|
2735 TRect drawArea = iDisplay.ClippingRect(); |
|
2736 if (iReducedDrawingAreaRect.Height()) |
|
2737 drawArea.Intersection(iReducedDrawingAreaRect); |
|
2738 iLayout->HighlightUsingExtensions(aOptimizedRange,aOriginalRange,drawArea, &iDrawTextLayoutContext); |
|
2739 } |
|
2740 |
|
2741 |
|
2742 /** Gets called after the cursor moved to a picture, creates the picture frame if it has not been created |
|
2743 and updates its state. |
|
2744 */ |
|
2745 void CTextView::UpdatePictureFrameL() |
|
2746 { |
|
2747 TCursorSelection selection; |
|
2748 iCursorPos.GetSelection(selection); |
|
2749 |
|
2750 TInt pos = selection.LowerPos(); |
|
2751 TRect rect; |
|
2752 |
|
2753 TInt err = FALSE; |
|
2754 TBool canScaleOrCrop = FALSE; |
|
2755 |
|
2756 if (!iPictureFrame) |
|
2757 { |
|
2758 TRAP(err,iPictureFrame=new(ELeave) TFrameOverlay()); |
|
2759 } |
|
2760 |
|
2761 TBool isPicture=EFalse; |
|
2762 if (!err) |
|
2763 { |
|
2764 TRAP(err,isPicture=iLayout->PictureRectangleL(pos,rect,&canScaleOrCrop)) |
|
2765 if(!isPicture) |
|
2766 __ASSERT_DEBUG(isPicture,FormPanic(EFNoPictureFrame)); |
|
2767 } |
|
2768 if (err) |
|
2769 NoMemoryL(err); |
|
2770 |
|
2771 iPictureFrame->SetFlags(TFrameOverlay::EFrameOverlayFlagBlobsInternal); |
|
2772 if (canScaleOrCrop) |
|
2773 { |
|
2774 iPictureFrame->SetVisibleBlobWidthInPixels(EFFrameVisibleBlobWidth); |
|
2775 iPictureFrame->SetActiveBlobWidthInPixels(EFFrameActiveBlobWidth); |
|
2776 iPictureFrame->ClearFlags(TFrameOverlay::EFrameOverlayFlagShowBorder); |
|
2777 } |
|
2778 else |
|
2779 { |
|
2780 iPictureFrame->SetVisibleBlobWidthInPixels(0); |
|
2781 iPictureFrame->SetActiveBlobWidthInPixels(0); |
|
2782 iPictureFrame->SetFlags(TFrameOverlay::EFrameOverlayFlagShowBorder); |
|
2783 } |
|
2784 iDrawTextLayoutContext.TextToWindow(rect); |
|
2785 iPictureFrame->SetRect(rect); |
|
2786 |
|
2787 } |
|
2788 |
|
2789 |
|
2790 |
|
2791 /** Shows or hides the picture frame at specified location, redrawing the picture frame rect. |
|
2792 It assumes that: 1)iCursorPos.iFlags has been correctly updated to specify the visibility of |
|
2793 the picture frame. |
|
2794 2)the picture frame object has been created and initialised. |
|
2795 3)Gc has already been activated. |
|
2796 Enters OOM before leaving. |
|
2797 */ |
|
2798 void CTextView::RedrawPictureFrameRectL(TInt aPos) |
|
2799 { |
|
2800 TRect drawRect; |
|
2801 if(iLayout->PictureRectangleL(aPos,drawRect)) |
|
2802 { |
|
2803 iDrawTextLayoutContext.TextToWindow(drawRect); |
|
2804 drawRect.Intersection(iDrawTextLayoutContext.iViewRect); |
|
2805 TBool callBeginEndRedraw = iDrawTextLayoutContext.UseWindowGc() && ! iLayout->BeginRedrawCalled(); |
|
2806 if (callBeginEndRedraw) |
|
2807 { |
|
2808 iLayout->BeginRedraw(drawRect); |
|
2809 } |
|
2810 // since drawRect contains the picture, it calls DrawPictureFrameL() |
|
2811 TRAPD(err,DrawTextSupportL(drawRect,NULL)); |
|
2812 if (callBeginEndRedraw) |
|
2813 { |
|
2814 iLayout->EndRedraw(); |
|
2815 } |
|
2816 |
|
2817 if (err) |
|
2818 { |
|
2819 NoMemoryL(err); //Gc's are deleted |
|
2820 } |
|
2821 } |
|
2822 } |
|
2823 |
|
2824 |
|
2825 |
|
2826 /* |
|
2827 Draws a focus frame around a picture. |
|
2828 It assumes that: 1) cursor is sitting on a picture frame (iCursorPos.IsPictureFrame==ETrue) |
|
2829 2) the picture frame object has been created and initialised |
|
2830 3) BeginRedraw() has already been called |
|
2831 and the background already has been drawn. So we can use the EDrawModePEN |
|
2832 without problems. |
|
2833 */ |
|
2834 void CTextView::DrawPictureFrameL(TRect& aClipRect) |
|
2835 { |
|
2836 __ASSERT_DEBUG(iCursorPos.IsPictureFrame(),FormPanic(EFNoPictureFrame)); |
|
2837 TCursorSelection selection; |
|
2838 iCursorPos.GetSelection(selection); |
|
2839 if(iLayout->PosIsFormatted(selection.LowerPos())) |
|
2840 { |
|
2841 aClipRect.Intersection(iDrawTextLayoutContext.TextArea()); |
|
2842 iDrawTextLayoutContext.PrimaryGc()->SetClippingRect(aClipRect); |
|
2843 TRect rect; |
|
2844 TInt pos = selection.LowerPos(); |
|
2845 rect = iPictureFrame->RefRect(); |
|
2846 TRect lineRect=iLayout->GetLineRectL(pos, pos); |
|
2847 iDrawTextLayoutContext.TextToWindow(lineRect); |
|
2848 lineRect.iTl.iX=iDrawTextLayoutContext.TextArea().iTl.iX; |
|
2849 lineRect.iBr.iX=iDrawTextLayoutContext.TextArea().iBr.iX; |
|
2850 lineRect.Intersection(aClipRect); |
|
2851 if (rect.iTl.iY<iDrawTextLayoutContext.iViewRect.iBr.iY-iHeightNotDrawn) |
|
2852 { |
|
2853 iDisplay.DrawPictureFrame(iPictureFrame, lineRect); |
|
2854 } |
|
2855 } |
|
2856 } |
|
2857 |
|
2858 /** Enters the OOM state. */ |
|
2859 void CTextView::NoMemoryL(TInt aError) |
|
2860 { |
|
2861 __ASSERT_DEBUG(iNoMemory!=EFOutOfMemory,FormPanic(EFNoMemory)); |
|
2862 iLayout->DiscardFormat(); |
|
2863 if (iNoMemory==EFMemoryOK) |
|
2864 { |
|
2865 TTmPosInfo2 pos_info; |
|
2866 if (iLayout->FindDocPos(iCursorPos.TmDocPos(),pos_info)) |
|
2867 iGood = pos_info.iEdge.iY; |
|
2868 if (iGood < 0 || iGood >= ViewRect().Height()) |
|
2869 iGood = 0; |
|
2870 } |
|
2871 iNoMemory=EFOutOfMemory; |
|
2872 DrawWithCurrentHighlight(); |
|
2873 DestroyWindowServerObjects(); |
|
2874 User::Leave(aError); |
|
2875 } |
|
2876 |
|
2877 void CTextView::DestroyWindowServerObjects() |
|
2878 { |
|
2879 iDisplay.Close(); |
|
2880 } |
|
2881 |
|
2882 /** Return True if successfully recovered from being out of memory Enters OOM |
|
2883 before leaving */ |
|
2884 TBool CTextView::NoMemoryCheckL() |
|
2885 { |
|
2886 TBool recovered=iNoMemory; |
|
2887 |
|
2888 __ASSERT_DEBUG(iNoMemory!=EFRecovering,FormPanic(EFRecoverNoMemory)); |
|
2889 if (iNoMemory) |
|
2890 RecoverNoMemoryL(); |
|
2891 return recovered; |
|
2892 } |
|
2893 |
|
2894 /** Make an attempt to recover from no system memory |
|
2895 Enters OOM before leaving */ |
|
2896 void CTextView::RecoverNoMemoryL() |
|
2897 { |
|
2898 |
|
2899 __ASSERT_DEBUG(iNoMemory==EFOutOfMemory,FormPanic(EFRecoverNoMemory)); |
|
2900 iNoMemory=EFRecovering; |
|
2901 RecreateWindowServerObjectsL(); |
|
2902 TTmDocPos end(iLayout->DocumentLength(), EFalse); |
|
2903 TTmDocPos pos = iCursorPos.TmDocPos(); |
|
2904 if (pos.iPos > end.iPos) |
|
2905 iCursorPos.SetDocPos(end); |
|
2906 ViewL(iCursorPos.TmDocPos(),iGood); |
|
2907 __ASSERT_DEBUG(iNoMemory==EFRecovering,FormPanic(EFNoMemory)); |
|
2908 iNoMemory=EFMemoryOK; |
|
2909 iGood=0; |
|
2910 if (iLayout->FormattedHeightInPixels() < iLayout->BandHeight() && iLayout->FirstDocPosFullyInBand()>0) |
|
2911 { |
|
2912 TInt scroll=iLayout->BandHeight()-iLayout->YBottomLastFormattedLine(); |
|
2913 ScrollDisplayPixelsL(scroll); |
|
2914 } |
|
2915 } |
|
2916 |
|
2917 void CTextView::RecreateWindowServerObjectsL() |
|
2918 { |
|
2919 TRAPD(err,iDisplay.CreateContextL()); |
|
2920 if (err) |
|
2921 NoMemoryL(err); |
|
2922 } |
|
2923 |
|
2924 /** Sets the number of pixels by which a horizontal scroll jump will cause the |
|
2925 view to scroll. To carry out a horizontal scroll, use ScrollDisplayL(). |
|
2926 |
|
2927 @param aScrollJump The number of pixels by which a horizontal scroll jump will |
|
2928 cause the view to scroll. Must be a positive value or a panic occurs. */ |
|
2929 EXPORT_C void CTextView::SetHorizontalScrollJump(TInt aScrollJump) |
|
2930 { |
|
2931 __ASSERT_ALWAYS(aScrollJump>=0,FormPanic(EFInvalidJumpValue)); |
|
2932 __ASSERT_DEBUG(aScrollJump<EFUnreasonablyLargeHorizontalScrollJump |
|
2933 ,FormPanic(EFInvalidJumpValue)); |
|
2934 iHorizontalScrollJump=aScrollJump; |
|
2935 } |
|
2936 |
|
2937 /** Sets the left text margin width in pixels. |
|
2938 |
|
2939 The left text margin width is the distance between the text and the left edge |
|
2940 of the page. Increasing the left text margin width causes text to move |
|
2941 leftwards and decreasing the left text margin width causes text to move |
|
2942 rightwards. |
|
2943 |
|
2944 Does not redraw. |
|
2945 |
|
2946 @param aLeftMargin The left text margin width in pixels. */ |
|
2947 EXPORT_C void CTextView::SetLeftTextMargin(TInt aLeftMargin) |
|
2948 { |
|
2949 iDrawTextLayoutContext.iTextStartX=-aLeftMargin; |
|
2950 } |
|
2951 |
|
2952 /** Gets the left text margin width in pixels. |
|
2953 |
|
2954 @return The left text margin width in pixels. */ |
|
2955 EXPORT_C TInt CTextView::LeftTextMargin() const |
|
2956 { |
|
2957 return -iDrawTextLayoutContext.iTextStartX; |
|
2958 } |
|
2959 |
|
2960 /** Sets the pending horizontal text cursor position. This is the horizontal |
|
2961 coordinate to which the text cursor is moved after a scroll up or down by a |
|
2962 line or a page. |
|
2963 |
|
2964 @param aLatentX The horizontal coordinate to which the text cursor should be |
|
2965 moved after a line or page scroll. */ |
|
2966 EXPORT_C void CTextView::SetLatentXPosition(TInt aLatentX) |
|
2967 { |
|
2968 aLatentX-=iDrawTextLayoutContext.TopLeftText().iX; |
|
2969 iCursorPos.UpdateLatentX(aLatentX); |
|
2970 } |
|
2971 |
|
2972 /** Sets the horizontal extent of the view rectangle to fill with paragraph |
|
2973 fill colour (CParaFormat::iFillColor). |
|
2974 |
|
2975 Does not redraw. |
|
2976 |
|
2977 @param aFillTextOnly If true, the region filled with paragraph fill colour is |
|
2978 the area within the paragraph's bounding rectangle only (see ParagraphRectL()). |
|
2979 If false, the filled region includes the left text margin, if one has been set. |
|
2980 By default, false. */ |
|
2981 EXPORT_C void CTextView::SetParagraphFillTextOnly(TBool aFillTextOnly) |
|
2982 { |
|
2983 iDrawTextLayoutContext.SetParagraphFillTextOnly(aFillTextOnly); |
|
2984 } |
|
2985 |
|
2986 /** Sets the text cursor's type and weight and redraws it. If the cursor's |
|
2987 placement is vertical (ECursorVertical), the weight is the width of the cursor. |
|
2988 If the placement is horizontal, the weight is the height of the cursor. |
|
2989 |
|
2990 @param aType The text cursor type. |
|
2991 @param aWidth The weight in pixels of the text cursor. Specify zero (the |
|
2992 default) to leave the current weight unchanged. */ |
|
2993 EXPORT_C void CTextView::SetCursorWidthTypeL(TTextCursor::EType aType,TInt aWidth/*=0*/) |
|
2994 { |
|
2995 iCursor.SetType(aType); |
|
2996 iCursor.SetWeight(aWidth); |
|
2997 } |
|
2998 |
|
2999 /** Sets the text cursor's placement (its shape and position relative to the |
|
3000 insertion position) and redraws it. |
|
3001 |
|
3002 @param aPlacement The text cursor's placement */ |
|
3003 EXPORT_C void CTextView::SetCursorPlacement(TTmCursorPlacement aPlacement) |
|
3004 { |
|
3005 iCursor.SetPlacement(aPlacement); |
|
3006 } |
|
3007 |
|
3008 /** Sets the weight of the text cursor and redraws it. |
|
3009 |
|
3010 If the cursor's placement is vertical (ECursorVertical), the weight is the |
|
3011 width of the cursor. If the placement is horizontal, the weight is the height |
|
3012 of the cursor. Has no effect if the weight value specified is zero or less. |
|
3013 |
|
3014 @param aWeight The weight in pixels of the text cursor. */ |
|
3015 EXPORT_C void CTextView::SetCursorWeight(TInt aWeight) |
|
3016 { |
|
3017 iCursor.SetWeight(aWeight); |
|
3018 } |
|
3019 |
|
3020 |
|
3021 EXPORT_C void CTextView::SetCursorFlash(TBool aEnabled) |
|
3022 /** Sets the flashing state of the text cursor and redraws it. |
|
3023 |
|
3024 @param aEnabled ETrue for a flashing cursor, EFalse for a non-flashing cursor. |
|
3025 */ |
|
3026 { |
|
3027 iCursor.SetFlash(aEnabled); |
|
3028 } |
|
3029 |
|
3030 /** Sets the text cursor's colour and redraws it. The cursor is drawn using an |
|
3031 Exclusive OR draw mode which ensures that the cursor's colour is different from |
|
3032 the background colour. |
|
3033 |
|
3034 @param aColor The text cursor's colour. */ |
|
3035 EXPORT_C void CTextView::SetCursorXorColor(TRgb aColor) |
|
3036 { |
|
3037 iCursor.SetXorColor(aColor); |
|
3038 } |
|
3039 |
|
3040 /** Sets the height and ascent of the text cursor to be the same as an adjacent |
|
3041 character and redraws it. By default, the values are set to be based on the |
|
3042 preceding character. |
|
3043 |
|
3044 @param aBasedOn EFCharacterBefore to base the height and ascent of the text |
|
3045 cursor on the preceding character. EFCharacterAfter to base them on the |
|
3046 following character. */ |
|
3047 EXPORT_C void CTextView::MatchCursorHeightToAdjacentChar(TBeforeAfter /*aBasedOn*/) |
|
3048 { |
|
3049 iCursor.MatchCursorHeightToAdjacentChar(); |
|
3050 } |
|
3051 |
|
3052 /** Overrides the text colour, so that when redrawn, all text has the colour |
|
3053 specified, rather than the colour which is set in the text object. When text is |
|
3054 in this overridden state, no highlighting is visible. To return the text colour |
|
3055 to its original state, call this function again with an argument of NULL. This |
|
3056 also has the effect that if selection visibility is set, any highlighting will |
|
3057 be made visible again. |
|
3058 |
|
3059 Does not do a redraw. |
|
3060 |
|
3061 @param aOverrideColor If not NULL, overrides the text colour. */ |
|
3062 EXPORT_C void CTextView::SetTextColorOverride(const TRgb* aOverrideColor) |
|
3063 { |
|
3064 iDrawTextLayoutContext.SetTextColorOverride(aOverrideColor); |
|
3065 } |
|
3066 |
|
3067 /** Sets the background colour for the view rectangle. |
|
3068 |
|
3069 Does not redraw. |
|
3070 |
|
3071 @param aColor The background colour. */ |
|
3072 EXPORT_C void CTextView::SetBackgroundColor(TRgb aColor) |
|
3073 { |
|
3074 iDrawTextLayoutContext.iBackgroundColor=aColor; |
|
3075 } |
|
3076 |
|
3077 /** Gets the rectangle in which the text is displayed. |
|
3078 |
|
3079 @return The view rectangle. */ |
|
3080 EXPORT_C const TRect& CTextView::ViewRect() const |
|
3081 { |
|
3082 |
|
3083 return iDrawTextLayoutContext.iViewRect; |
|
3084 } |
|
3085 |
|
3086 /** Gets the number of pixels by which a horizontal scroll jump will cause the |
|
3087 view to scroll. On construction, the default horizontal scroll jump value |
|
3088 is set to 20 pixels. |
|
3089 |
|
3090 @return The number of pixels by which a horizontal scroll jump will cause |
|
3091 the view to scroll. */ |
|
3092 EXPORT_C TInt CTextView::HorizontalScrollJump() const |
|
3093 { |
|
3094 |
|
3095 return iHorizontalScrollJump; |
|
3096 } |
|
3097 |
|
3098 /** Starts the Idle Object if not in the middle of drawing para borders. */ |
|
3099 void CTextView::StartIdleObject() |
|
3100 { |
|
3101 |
|
3102 if (!iWrap->IsActive()) |
|
3103 iWrap->Start(TCallBack(CTextView::IdleL,this)); |
|
3104 } |
|
3105 |
|
3106 class RDrawTextSupport |
|
3107 { |
|
3108 public: |
|
3109 /** Constructor. Ownership of aBitmap is passed. |
|
3110 */ |
|
3111 RDrawTextSupport(RScreenDisplay* aScreenDisplay, |
|
3112 TDrawTextLayoutContext* aLayoutContext, |
|
3113 CFbsBitmap* aBitmap) |
|
3114 : iScreenGc(0), iScreenDisplay(aScreenDisplay), |
|
3115 iLayoutContext(aLayoutContext), |
|
3116 iDevice(0), iGc(0), iBitmap(aBitmap) |
|
3117 { |
|
3118 iLayoutContextDrawMode = aLayoutContext->DrawMode(); |
|
3119 iScreenGc = iScreenDisplay->BitmapContext(); |
|
3120 } |
|
3121 void ConstructL(CBitmapContext* aOffScreenContext) |
|
3122 { |
|
3123 if (aOffScreenContext) |
|
3124 { |
|
3125 iScreenDisplay->SetBitmapContext(aOffScreenContext); |
|
3126 } |
|
3127 else |
|
3128 { |
|
3129 // Create the device and graphics context. |
|
3130 iDevice = CFbsBitmapDevice::NewL(iBitmap); |
|
3131 CFbsBitGc* bitGc; |
|
3132 User::LeaveIfError(iDevice->CreateContext(bitGc)); |
|
3133 iGc = bitGc; |
|
3134 iScreenDisplay->SetBitmapContext(iGc); |
|
3135 |
|
3136 // Set the twips size of the bitmap to match the screen so that |
|
3137 // background bitmaps are blitted at the right size. |
|
3138 iBitmap->SetSizeInTwips(iScreenGc->Device()); |
|
3139 } |
|
3140 iLayoutContext->SetBitmapGc(iScreenDisplay->BitmapContext()); |
|
3141 } |
|
3142 void Close() |
|
3143 { |
|
3144 iScreenDisplay->SetBitmapContext(iScreenGc); |
|
3145 iLayoutContext->SetGc(iScreenGc); |
|
3146 iLayoutContext->SetDrawMode(iLayoutContextDrawMode); |
|
3147 delete iGc; iGc = NULL; |
|
3148 delete iDevice; iDevice = NULL; |
|
3149 delete iBitmap; iBitmap = NULL; |
|
3150 } |
|
3151 private: |
|
3152 CBitmapContext* iScreenGc; |
|
3153 RScreenDisplay* iScreenDisplay; |
|
3154 TDrawTextLayoutContext* iLayoutContext; |
|
3155 CFbsBitmapDevice* iDevice; |
|
3156 CBitmapContext* iGc; |
|
3157 CFbsBitmap* iBitmap; |
|
3158 TUint iLayoutContextDrawMode; |
|
3159 }; |
|
3160 |
|
3161 /** |
|
3162 Draws the text. Depending on the opaque mode ("iDrawOpaque" value) and graphics context |
|
3163 type, the method calls either DoDrawTextSupportL() or DoDrawTextSupportOpaqueL(). |
|
3164 The additional graphics context type check has to be done, because currently only |
|
3165 CWindowGc graphics context implementation supports opaque drawing. |
|
3166 |
|
3167 Does not enter OOM state. |
|
3168 */ |
|
3169 void CTextView::DrawTextSupportL(const TRect& aScreenDrawRect, |
|
3170 const TCursorSelection* aHighlight) |
|
3171 { |
|
3172 // Anything to do? |
|
3173 if( aScreenDrawRect.IsEmpty()||!(iFlags & EFTextVisible) ) |
|
3174 return; |
|
3175 |
|
3176 if(iDisplay.Window() && iDrawOpaque |
|
3177 && !iOffScreenContext) |
|
3178 { |
|
3179 // It is a CWindowGc and opaque drawing mode |
|
3180 iLayout->SetOpaqueLC(); |
|
3181 DoDrawTextSupportOpaqueL(aScreenDrawRect, aHighlight); |
|
3182 CleanupStack::PopAndDestroy();//iLayout->SetOpaqueLC() operation |
|
3183 } |
|
3184 else |
|
3185 { |
|
3186 DoDrawTextSupportL(aScreenDrawRect, aHighlight); |
|
3187 } |
|
3188 } |
|
3189 |
|
3190 |
|
3191 /** |
|
3192 Draws the text, using an offscreen bitmap to avoid flicker if possible. |
|
3193 All text drawing is done by this function except in printing. |
|
3194 |
|
3195 Does not enter OOM state. |
|
3196 */ |
|
3197 |
|
3198 void CTextView::DoDrawTextSupportL(const TRect& aScreenDrawRect, |
|
3199 const TCursorSelection* aHighlight) |
|
3200 { |
|
3201 // extend the screen draw rect for any extended highlights |
|
3202 TRect screenDrawRect(aScreenDrawRect); |
|
3203 iLayout->HighlightExtensions().ExtendRect(screenDrawRect); |
|
3204 screenDrawRect.Intersection(iDisplay.ClippingRect()); |
|
3205 |
|
3206 |
|
3207 // Create an offscreen bitmap. Although Window server bitmaps are quicker to bilt, |
|
3208 // but using it need introduce static_cast, which may make code fragile. So we just |
|
3209 // use CFbsBitmaps. |
|
3210 |
|
3211 CFbsBitmap* bitmap = NULL; |
|
3212 int error = 0; |
|
3213 if ((iFlags & EFFlickerFreeRedraw) && !iOffScreenContext) |
|
3214 { |
|
3215 TDisplayMode displayMode = iDisplay.Window()? |
|
3216 iDisplay.Window()->DisplayMode() |
|
3217 : iDisplay.BitmapDevice()->DisplayMode(); |
|
3218 |
|
3219 // We are going to make the bitmap size the size from (0,0) on |
|
3220 // the screen to the bottom right of the drawing area. |
|
3221 // This is because if we only make it exactly the size we need, |
|
3222 // the DrawBackground code does not know how to align the bitmap |
|
3223 // in some cases: |
|
3224 // 1) where the bitmap doesn't scroll with the text |
|
3225 // 2) where the bitmap is to be stretched in a way that depends |
|
3226 // on the co-ordinates it is being stretched to. |
|
3227 TSize bitmapSize(screenDrawRect.iBr.iX, screenDrawRect.iBr.iY); |
|
3228 bitmap = new CFbsBitmap; |
|
3229 if (bitmap) |
|
3230 { |
|
3231 error = bitmap->Create(bitmapSize, displayMode); |
|
3232 } |
|
3233 } |
|
3234 |
|
3235 TBool isDrawingOnABitmap = NULL != bitmap || NULL != iOffScreenContext; |
|
3236 |
|
3237 CBitmapContext* screen_gc = iDisplay.BitmapContext(); |
|
3238 RDrawTextSupport support(&iDisplay, &iDrawTextLayoutContext, bitmap); |
|
3239 CleanupClosePushL(support); |
|
3240 if (error) |
|
3241 User::Leave(error); |
|
3242 |
|
3243 // If we are flicker-free drawing (and there was enough memory for it) or |
|
3244 // drawing to an off screen bitmap for some other reason, set up |
|
3245 // iDrawTextLayoutContext to temporarily point to the appropriate place |
|
3246 if (isDrawingOnABitmap) |
|
3247 { |
|
3248 support.ConstructL(iOffScreenContext); |
|
3249 } |
|
3250 |
|
3251 // Draw the text. |
|
3252 iLayout->DrawL(screenDrawRect, &iDrawTextLayoutContext, aHighlight); |
|
3253 |
|
3254 // Draw picture frame if applicable |
|
3255 TBool pictureFrame = SelectionVisible() && iCursorPos.IsPictureFrame(); |
|
3256 if (pictureFrame) |
|
3257 { |
|
3258 DrawPictureFrameL(screenDrawRect); |
|
3259 } |
|
3260 |
|
3261 if (NULL != bitmap) |
|
3262 { |
|
3263 if (NULL == iOffScreenContext) |
|
3264 { |
|
3265 iLayout->BeginRedraw(screenDrawRect); |
|
3266 } |
|
3267 |
|
3268 // Copy the drawn rectangle from the offscreen bitmap (if present) |
|
3269 // to the screen. |
|
3270 screen_gc->BitBlt(screenDrawRect.iTl, bitmap, screenDrawRect); |
|
3271 |
|
3272 if (NULL == iOffScreenContext) |
|
3273 { |
|
3274 iLayout->EndRedraw(); |
|
3275 } |
|
3276 } |
|
3277 |
|
3278 if (pictureFrame) |
|
3279 { |
|
3280 DrawCursor(TCursor::EFTextCursor); |
|
3281 } |
|
3282 |
|
3283 // Puts iDrawTextLayoutContext back to point to the real screen |
|
3284 CleanupStack::PopAndDestroy(&support); |
|
3285 } |
|
3286 |
|
3287 /* |
|
3288 Draws the text, when opaque drawing mode is "ON" and the used graphics context type is |
|
3289 CWindowGc. |
|
3290 */ |
|
3291 void CTextView::DoDrawTextSupportOpaqueL(const TRect& aScreenDrawRect, |
|
3292 const TCursorSelection* aHighlight) |
|
3293 { |
|
3294 // extend the screen draw rect for any extended highlights |
|
3295 TRect screenDrawRect(aScreenDrawRect); |
|
3296 iLayout->HighlightExtensions().ExtendRect(screenDrawRect); |
|
3297 |
|
3298 iLayout->BeginRedraw(screenDrawRect); |
|
3299 iLayout->DrawL(screenDrawRect, &iDrawTextLayoutContext, aHighlight); |
|
3300 |
|
3301 // Draw picture frame if applicable |
|
3302 TBool pictureFrame = SelectionVisible() && iCursorPos.IsPictureFrame(); |
|
3303 if (pictureFrame) |
|
3304 { |
|
3305 DrawPictureFrameL(screenDrawRect); |
|
3306 DrawCursor(TCursor::EFTextCursor); |
|
3307 } |
|
3308 |
|
3309 iLayout->EndRedraw(); |
|
3310 } |
|
3311 |
|
3312 /** Draws text from aFrom to aTo. |
|
3313 |
|
3314 Enters OOM state before leaving. |
|
3315 @param aFrom Top screen Y co-ordinate to draw (inclusive of aFrom) |
|
3316 @param aTo Bottom screen Y co-ordinate to draw (exclusive of aTo) |
|
3317 */ |
|
3318 void CTextView::DisplayLineRangeL(TInt aFrom,TInt aTo) |
|
3319 { |
|
3320 TCursorSelection* highlight=NULL; |
|
3321 TCursorSelection selection; |
|
3322 |
|
3323 iCursorPos.GetSelection(selection); |
|
3324 TBool pictureFrame=iCursorPos.IsPictureFrame(); |
|
3325 |
|
3326 TRect drawRect=iDisplay.ClippingRect(); |
|
3327 |
|
3328 drawRect.iTl.iY=Max(aFrom+ViewRect().iTl.iY,drawRect.iTl.iY); |
|
3329 drawRect.iBr.iY=Min(aTo+ViewRect().iTl.iY,drawRect.iBr.iY); |
|
3330 |
|
3331 if (SelectionVisible() && selection.Length()>0 && !pictureFrame) |
|
3332 highlight=&selection; |
|
3333 |
|
3334 iDisplay.ActivateContext(iDrawTextLayoutContext.PrimaryGc()); |
|
3335 TRAPD(err,DrawTextSupportL(drawRect,highlight)); |
|
3336 if (err) |
|
3337 NoMemoryL(err); //Gc's are deleted |
|
3338 |
|
3339 iDisplay.DeactivateContext(iDrawTextLayoutContext.PrimaryGc()); |
|
3340 iHeightNotDrawn=0; |
|
3341 } |
|
3342 |
|
3343 EXPORT_C const TRect& CTextView::AlteredViewRect() const |
|
3344 { |
|
3345 return iReducedDrawingAreaRect; |
|
3346 } |
|
3347 |
|
3348 |
|
3349 EXPORT_C void CTextView::SetCursorExtensions(TInt aFirstExtension, TInt aSecondExtension) |
|
3350 { |
|
3351 iCursor.SetExtensions(aFirstExtension,aSecondExtension); |
|
3352 } |
|
3353 |
|
3354 TBool CTextView::ExtendedHighlightExists() const |
|
3355 { |
|
3356 ASSERT(iLayout); |
|
3357 if (SelectionVisible() && iLayout->HighlightExtensions().Extends()) |
|
3358 { |
|
3359 TCursorSelection selection; |
|
3360 iCursorPos.GetSelection(selection); |
|
3361 if (selection.Length()>0) |
|
3362 return ETrue; |
|
3363 } |
|
3364 return EFalse; |
|
3365 } |
|
3366 |
|
3367 |
|
3368 // When scrolling, we also want to include any highlight extensions within the scroll area. |
|
3369 void CTextView::AdjustRectForScrolling(TRect &aRect, TInt aScrollY, TInt aScrollX) const |
|
3370 { |
|
3371 ASSERT(iLayout); |
|
3372 const TTmHighlightExtensions& extensions=iLayout->HighlightExtensions(); |
|
3373 ASSERT(extensions.Extends() && SelectionVisible()); |
|
3374 |
|
3375 if (aScrollY==0) |
|
3376 { |
|
3377 // scrolling horizontally, so we include top and bottom extensions |
|
3378 if (extensions.TopExtension()>0) |
|
3379 aRect.iTl.iY-=extensions.TopExtension(); |
|
3380 if (extensions.BottomExtension()>0) |
|
3381 aRect.iBr.iY+=extensions.BottomExtension(); |
|
3382 } |
|
3383 if (aScrollX==0) |
|
3384 { |
|
3385 // scrolling vertically, so we include left and right extensions |
|
3386 if (extensions.LeftExtension()>0) |
|
3387 aRect.iTl.iX-=extensions.LeftExtension(); |
|
3388 if (extensions.RightExtension()>0) |
|
3389 aRect.iBr.iX+=extensions.RightExtension(); |
|
3390 } |
|
3391 } |
|
3392 |
|
3393 |
|
3394 |
|
3395 /** |
|
3396 Returns whether the two hints passed in are the opposites of each other. |
|
3397 @param aHint1 First hint. |
|
3398 @param aHint2 Second hint. |
|
3399 @return ETrue if the two hints are the reversals of each other. |
|
3400 @internalComponent |
|
3401 */ |
|
3402 TBool PositioningHintsReversed(TCursorPosition::TPosHint aHint1, |
|
3403 TCursorPosition::TPosHint aHint2) |
|
3404 { |
|
3405 if (aHint1 == TCursorPosition::EInsertStrongL2R |
|
3406 && aHint2 == TCursorPosition::EInsertStrongR2L) |
|
3407 return ETrue; |
|
3408 if (aHint1 == TCursorPosition::EInsertStrongR2L |
|
3409 && aHint2 == TCursorPosition::EInsertStrongL2R) |
|
3410 return ETrue; |
|
3411 return EFalse; |
|
3412 } |
|
3413 |
|
3414 /** |
|
3415 This method allows clients of CTextView to provided a cursor positioning hint |
|
3416 (as defined in TCursorPosition::TPosHint) to the Cursor Navigation |
|
3417 Policy object currently in use in this view. |
|
3418 |
|
3419 This information can be used by the CNP object to resolve problems such as |
|
3420 visual cursor positioning ambiguity in bidirectional text. |
|
3421 @param aHint |
|
3422 Cursor position hint provided by client of CTextView. |
|
3423 @post |
|
3424 The hint is stored for use in subsequent cursor movement. |
|
3425 */ |
|
3426 EXPORT_C void CTextView::SetCursorPositioningHintL( |
|
3427 TCursorPosition::TPosHint aHint) |
|
3428 { |
|
3429 if (!PositioningHintsReversed(aHint, iCursorPos.PositioningHint())) |
|
3430 { |
|
3431 iCursorPos.SetPositioningHint(aHint); |
|
3432 return; |
|
3433 } |
|
3434 iCursorPos.SetPositioningHint(aHint); |
|
3435 |
|
3436 const CTmTextLayout& layout = iLayout->TagmaTextLayout(); |
|
3437 TTmPosInfo2 posInfo; |
|
3438 TTmLineInfo lineInfo; |
|
3439 if (!layout.FindDocPos(iCursorPos.TmDocPos(), posInfo, lineInfo)) |
|
3440 return; |
|
3441 TBool preferRightToLeft = |
|
3442 aHint == TCursorPosition::EInsertStrongR2L? |
|
3443 ETrue : EFalse; |
|
3444 if (iContextIsNavigation) |
|
3445 { |
|
3446 // Navigation: keep the visual position the same but maybe change the |
|
3447 // logical position |
|
3448 TTmPosInfo2 posInfoLeft; |
|
3449 TTmPosInfo2 posInfoRight; |
|
3450 if (!layout.FindXyPosWithDisambiguation(posInfo.iEdge, |
|
3451 posInfoLeft, posInfoRight, lineInfo)) |
|
3452 return; |
|
3453 TBool posInfoRightGood = preferRightToLeft? |
|
3454 posInfoRight.iRightToLeft : !posInfoRight.iRightToLeft; |
|
3455 if (posInfoRightGood) |
|
3456 posInfoLeft = posInfoRight; |
|
3457 SetDocPosL(posInfoLeft.iDocPos, EFalse); |
|
3458 } |
|
3459 else |
|
3460 { |
|
3461 // Editing: keep the logical position the same but maybe change the |
|
3462 // visual position |
|
3463 TBool posInfoGood = preferRightToLeft? |
|
3464 posInfo.iRightToLeft : !posInfo.iRightToLeft; |
|
3465 if (posInfoGood) |
|
3466 return; |
|
3467 |
|
3468 // Cursor is not currently attatched to text of the correct |
|
3469 // directionality. We shall try attatching to the one in the other |
|
3470 // direction. |
|
3471 TTmDocPosSpec spec; |
|
3472 spec.iPos = posInfo.iDocPos.iPos; |
|
3473 spec.iType = posInfo.iDocPos.iLeadingEdge? |
|
3474 TTmDocPosSpec::ETrailing : TTmDocPosSpec::ELeading; |
|
3475 if (!layout.FindDocPos(spec, posInfo, lineInfo)) |
|
3476 return; |
|
3477 posInfoGood = preferRightToLeft? |
|
3478 posInfo.iRightToLeft : !posInfo.iRightToLeft; |
|
3479 if (posInfoGood) |
|
3480 SetDocPosL(posInfo.iDocPos, EFalse); |
|
3481 iContextIsNavigation = EFalse; |
|
3482 } |
|
3483 } |
|
3484 |
|
3485 /** |
|
3486 Sets and unsets an opaque flag on the text view's window. |
|
3487 @param aDrawOpaque If true, opaque drawing mode is switched on. |
|
3488 If false, normal drawing will be used. |
|
3489 */ |
|
3490 EXPORT_C void CTextView::SetOpaque(TBool aDrawOpaque) |
|
3491 { |
|
3492 iDrawOpaque = aDrawOpaque; |
|
3493 } |
|
3494 |
|
3495 /** |
|
3496 Stops or allows text to be drawn. Included to allow users to control visibility |
|
3497 if text is part of an invisible control. |
|
3498 |
|
3499 @param aVisible ETrue to make the text visible, EFalse to make it invisible. |
|
3500 @see CCoeControl::MakeVisible() |
|
3501 */ |
|
3502 EXPORT_C void CTextView::MakeVisible(TBool aVisible) |
|
3503 { |
|
3504 if(aVisible) |
|
3505 { |
|
3506 iFlags |= EFTextVisible; |
|
3507 } |
|
3508 else |
|
3509 { |
|
3510 iFlags &= ~EFTextVisible; |
|
3511 } |
|
3512 iLayout->MakeVisible(aVisible); |
|
3513 } |