comparison dwt/custom/StyledText.d @ 246:fd9c62a2998e

Updater SWT 3.4M7 to 3.4
author Frank Benoit <benoit@tionex.de>
date Tue, 01 Jul 2008 10:15:59 +0200
parents a59d51c12b42
children dffb802cad03
comparison
equal deleted inserted replaced
245:d8c3d4a4f2b0 246:fd9c62a2998e
1 /******************************************************************************* 1 /*******************************************************************************
2 * Copyright (c) 2000, 2007 IBM Corporation and others. 2 * Copyright (c) 2000, 2008 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials 3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0 4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at 5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html 6 * http://www.eclipse.org/legal/epl-v10.html
7 * 7 *
141 * <dt><b>Events:</b><dd>ExtendedModify, LineGetBackground, LineGetSegments, LineGetStyle, Modify, Selection, Verify, VerifyKey 141 * <dt><b>Events:</b><dd>ExtendedModify, LineGetBackground, LineGetSegments, LineGetStyle, Modify, Selection, Verify, VerifyKey
142 * </dl> 142 * </dl>
143 * </p><p> 143 * </p><p>
144 * IMPORTANT: This class is <em>not</em> intended to be subclassed. 144 * IMPORTANT: This class is <em>not</em> intended to be subclassed.
145 * </p> 145 * </p>
146 *
147 * @see <a href="http://www.eclipse.org/swt/snippets/#styledtext">StyledText snippets</a>
148 * @see <a href="http://www.eclipse.org/swt/examples.php">DWT Examples: CustomControlExample, TextEditor</a>
149 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
146 */ 150 */
147 public class StyledText : Canvas { 151 public class StyledText : Canvas {
148 152
149 alias Canvas.computeSize computeSize; 153 alias Canvas.computeSize computeSize;
150 154
195 Point clipboardSelection; // x and y are start and end caret offsets of previous selection 199 Point clipboardSelection; // x and y are start and end caret offsets of previous selection
196 int selectionAnchor; // position of selection anchor. 0 based offset from beginning of text 200 int selectionAnchor; // position of selection anchor. 0 based offset from beginning of text
197 Point doubleClickSelection; // selection after last mouse double click 201 Point doubleClickSelection; // selection after last mouse double click
198 bool editable = true; 202 bool editable = true;
199 bool wordWrap = false; 203 bool wordWrap = false;
200 bool doubleClickEnabled = true; // see getDoubleClickEnabled 204 bool doubleClickEnabled = true; // see getDoubleClickEnabled
201 bool overwrite = false; // insert/overwrite edit mode 205 bool overwrite = false; // insert/overwrite edit mode
202 int textLimit = -1; // limits the number of characters the user can type in the widget. Unlimited by default. 206 int textLimit = -1; // limits the number of characters the user can type in the widget. Unlimited by default.
203 int[int] keyActionMap; 207 int[int] keyActionMap;
204 Color background = null; // workaround for bug 4791 208 Color background = null; // workaround for bug 4791
205 Color foreground = null; // 209 Color foreground = null; //
206 Clipboard clipboard; 210 Clipboard clipboard;
212 int lastTextChangeNewCharCount; // event for use in the 216 int lastTextChangeNewCharCount; // event for use in the
213 int lastTextChangeReplaceLineCount; // text changed handler 217 int lastTextChangeReplaceLineCount; // text changed handler
214 int lastTextChangeReplaceCharCount; 218 int lastTextChangeReplaceCharCount;
215 int lastLineBottom; // the bottom pixel of the last line been replaced 219 int lastLineBottom; // the bottom pixel of the last line been replaced
216 bool isMirrored_; 220 bool isMirrored_;
217 bool bidiColoring = false; // apply the BIDI algorithm on text segments of the same color 221 bool bidiColoring = false; // apply the BIDI algorithm on text segments of the same color
218 Image leftCaretBitmap = null; 222 Image leftCaretBitmap = null;
219 Image rightCaretBitmap = null; 223 Image rightCaretBitmap = null;
220 int caretDirection = DWT.NULL; 224 int caretDirection = DWT.NULL;
221 int caretWidth = 0; 225 int caretWidth = 0;
222 Caret defaultCaret = null; 226 Caret defaultCaret = null;
261 int pageWidth; // width of a printer page in pixels 265 int pageWidth; // width of a printer page in pixels
262 int startPage; // first page to print 266 int startPage; // first page to print
263 int endPage; // last page to print 267 int endPage; // last page to print
264 int startLine; // first (wrapped) line to print 268 int startLine; // first (wrapped) line to print
265 int endLine; // last (wrapped) line to print 269 int endLine; // last (wrapped) line to print
266 bool singleLine; // widget single line mode 270 bool singleLine; // widget single line mode
267 Point selection = null; // selected text 271 Point selection = null; // selected text
268 bool mirrored; // indicates the printing gc should be mirrored 272 bool mirrored; // indicates the printing gc should be mirrored
269 int lineSpacing; 273 int lineSpacing;
270 int printMargin; 274 int printMargin;
271 275
272 /** 276 /**
273 * Creates an instance of <code>Printing</code>. 277 * Creates an instance of <code>Printing</code>.
3822 * 3826 *
3823 * @param lineIndex the line index, the max value is lineCount. If 3827 * @param lineIndex the line index, the max value is lineCount. If
3824 * lineIndex is lineCount it returns the bottom pixel of the last line. 3828 * lineIndex is lineCount it returns the bottom pixel of the last line.
3825 * It means this function can be used to retrieve the bottom pixel of any line. 3829 * It means this function can be used to retrieve the bottom pixel of any line.
3826 * 3830 *
3831 * @return the top pixel of a given line index
3832 *
3827 * @since 3.2 3833 * @since 3.2
3828 */ 3834 */
3829 public int getLinePixel(int lineIndex) { 3835 public int getLinePixel(int lineIndex) {
3830 checkWidget(); 3836 checkWidget();
3831 int lineCount = content.getLineCount(); 3837 int lineCount = content.getLineCount();
3848 return height + topMargin; 3854 return height + topMargin;
3849 } 3855 }
3850 /** 3856 /**
3851 * Returns the line index for a y, relative to the client area. 3857 * Returns the line index for a y, relative to the client area.
3852 * The line index returned is always in the range 0..lineCount - 1. 3858 * The line index returned is always in the range 0..lineCount - 1.
3859 *
3860 * @param y the y-coordinate pixel
3861 *
3862 * @return the line index for a given y-coordinate pixel
3853 * 3863 *
3854 * @since 3.2 3864 * @since 3.2
3855 */ 3865 */
3856 public int getLineIndex(int y) { 3866 public int getLineIndex(int y) {
3857 checkWidget(); 3867 checkWidget();
5125 int start = event.start; 5135 int start = event.start;
5126 int end = event.end; 5136 int end = event.end;
5127 int length = text.length; 5137 int length = text.length;
5128 if (length is ime.getCommitCount()) { 5138 if (length is ime.getCommitCount()) {
5129 content.replaceTextRange(start, end - start, ""); 5139 content.replaceTextRange(start, end - start, "");
5130 caretOffset = start; 5140 caretOffset = ime.getCompositionOffset();
5131 caretWidth = 0; 5141 caretWidth = 0;
5132 caretDirection = DWT.NULL; 5142 caretDirection = DWT.NULL;
5133 } else { 5143 } else {
5134 content.replaceTextRange(start, end - start, text); 5144 content.replaceTextRange(start, end - start, text);
5135 caretOffset = ime.getCaretOffset(); 5145 caretOffset = ime.getCaretOffset();
5136 if (ime.getWideCaret()) { 5146 if (ime.getWideCaret()) {
5147 start = ime.getCompositionOffset();
5137 int lineIndex = getCaretLine(); 5148 int lineIndex = getCaretLine();
5138 int lineOffset = content.getOffsetAtLine(lineIndex); 5149 int lineOffset = content.getOffsetAtLine(lineIndex);
5139 TextLayout layout = renderer.getTextLayout(lineIndex); 5150 TextLayout layout = renderer.getTextLayout(lineIndex);
5140 caretWidth = layout.getBounds(start - lineOffset, start + length - 1 - lineOffset).width; 5151 caretWidth = layout.getBounds(start - lineOffset, start + length - 1 - lineOffset).width;
5141 renderer.disposeTextLayout(layout); 5152 renderer.disposeTextLayout(layout);
5515 int lastLine = firstLine + lastTextChangeNewLineCount; 5526 int lastLine = firstLine + lastTextChangeNewLineCount;
5516 int firstLineTop = getLinePixel(firstLine); 5527 int firstLineTop = getLinePixel(firstLine);
5517 int newLastLineBottom = getLinePixel(lastLine + 1); 5528 int newLastLineBottom = getLinePixel(lastLine + 1);
5518 if (lastLineBottom !is newLastLineBottom) { 5529 if (lastLineBottom !is newLastLineBottom) {
5519 super.redraw(); 5530 super.redraw();
5520 if (wordWrap) setCaretLocation();
5521 } else { 5531 } else {
5522 super.redraw(0, firstLineTop, clientAreaWidth, newLastLineBottom - firstLineTop, false); 5532 super.redraw(0, firstLineTop, clientAreaWidth, newLastLineBottom - firstLineTop, false);
5523 redrawLinesBullet(renderer.redrawLines); 5533 redrawLinesBullet(renderer.redrawLines);
5524 } 5534 }
5525 } 5535 }
6062 * <p> 6072 * <p>
6063 * The runnable may be run in a non-UI thread. 6073 * The runnable may be run in a non-UI thread.
6064 * </p> 6074 * </p>
6065 * 6075 *
6066 * @param printer the printer to print to 6076 * @param printer the printer to print to
6077 *
6078 * @return a <code>Runnable</code> for printing the receiver's text
6079 *
6067 * @exception DWTException <ul> 6080 * @exception DWTException <ul>
6068 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 6081 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
6069 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 6082 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
6070 * </ul> 6083 * </ul>
6071 * @exception IllegalArgumentException <ul> 6084 * @exception IllegalArgumentException <ul>
6091 * The runnable may be run in a non-UI thread. 6104 * The runnable may be run in a non-UI thread.
6092 * </p> 6105 * </p>
6093 * 6106 *
6094 * @param printer the printer to print to 6107 * @param printer the printer to print to
6095 * @param options print options to use during printing 6108 * @param options print options to use during printing
6109 *
6110 * @return a <code>Runnable</code> for printing the receiver's text
6111 *
6096 * @exception DWTException <ul> 6112 * @exception DWTException <ul>
6097 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 6113 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
6098 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 6114 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
6099 * </ul> 6115 * </ul>
6100 * @exception IllegalArgumentException <ul> 6116 * @exception IllegalArgumentException <ul>
6249 internalRedrawRange(start, length); 6265 internalRedrawRange(start, length);
6250 } 6266 }
6251 /** 6267 /**
6252 * Removes the specified bidirectional segment listener. 6268 * Removes the specified bidirectional segment listener.
6253 * 6269 *
6254 * @param listener the listener 6270 * @param listener the listener which should no longer be notified
6271 *
6255 * @exception DWTException <ul> 6272 * @exception DWTException <ul>
6256 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 6273 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
6257 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 6274 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
6258 * </ul> 6275 * </ul>
6259 * @exception IllegalArgumentException <ul> 6276 * @exception IllegalArgumentException <ul>
6260 * <li>ERROR_NULL_ARGUMENT when listener is null</li> 6277 * <li>ERROR_NULL_ARGUMENT when listener is null</li>
6261 * </ul> 6278 * </ul>
6279 *
6262 * @since 2.0 6280 * @since 2.0
6263 */ 6281 */
6264 public void removeBidiSegmentListener(BidiSegmentListener listener) { 6282 public void removeBidiSegmentListener(BidiSegmentListener listener) {
6265 checkWidget(); 6283 checkWidget();
6266 if (listener is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); 6284 if (listener is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
6267 removeListener(LineGetSegments, listener); 6285 removeListener(LineGetSegments, listener);
6268 } 6286 }
6269 /** 6287 /**
6270 * Removes the specified extended modify listener. 6288 * Removes the specified extended modify listener.
6271 * 6289 *
6272 * @param extendedModifyListener the listener 6290 * @param extendedModifyListener the listener which should no longer be notified
6291 *
6273 * @exception DWTException <ul> 6292 * @exception DWTException <ul>
6274 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 6293 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
6275 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 6294 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
6276 * </ul> 6295 * </ul>
6277 * @exception IllegalArgumentException <ul> 6296 * @exception IllegalArgumentException <ul>
6284 removeListener(ExtendedModify, extendedModifyListener); 6303 removeListener(ExtendedModify, extendedModifyListener);
6285 } 6304 }
6286 /** 6305 /**
6287 * Removes the specified line background listener. 6306 * Removes the specified line background listener.
6288 * 6307 *
6289 * @param listener the listener 6308 * @param listener the listener which should no longer be notified
6309 *
6290 * @exception DWTException <ul> 6310 * @exception DWTException <ul>
6291 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 6311 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
6292 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 6312 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
6293 * </ul> 6313 * </ul>
6294 * @exception IllegalArgumentException <ul> 6314 * @exception IllegalArgumentException <ul>
6301 removeListener(LineGetBackground, listener); 6321 removeListener(LineGetBackground, listener);
6302 } 6322 }
6303 /** 6323 /**
6304 * Removes the specified line style listener. 6324 * Removes the specified line style listener.
6305 * 6325 *
6306 * @param listener the listener 6326 * @param listener the listener which should no longer be notified
6327 *
6307 * @exception DWTException <ul> 6328 * @exception DWTException <ul>
6308 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 6329 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
6309 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 6330 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
6310 * </ul> 6331 * </ul>
6311 * @exception IllegalArgumentException <ul> 6332 * @exception IllegalArgumentException <ul>
6318 removeListener(LineGetStyle, listener); 6339 removeListener(LineGetStyle, listener);
6319 } 6340 }
6320 /** 6341 /**
6321 * Removes the specified modify listener. 6342 * Removes the specified modify listener.
6322 * 6343 *
6323 * @param modifyListener the listener 6344 * @param modifyListener the listener which should no longer be notified
6345 *
6324 * @exception DWTException <ul> 6346 * @exception DWTException <ul>
6325 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 6347 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
6326 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 6348 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
6327 * </ul> 6349 * </ul>
6328 * @exception IllegalArgumentException <ul> 6350 * @exception IllegalArgumentException <ul>
6335 removeListener(DWT.Modify, modifyListener); 6357 removeListener(DWT.Modify, modifyListener);
6336 } 6358 }
6337 /** 6359 /**
6338 * Removes the specified listener. 6360 * Removes the specified listener.
6339 * 6361 *
6340 * @param listener the listener 6362 * @param listener the listener which should no longer be notified
6363 *
6341 * @exception DWTException <ul> 6364 * @exception DWTException <ul>
6342 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 6365 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
6343 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 6366 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
6344 * </ul> 6367 * </ul>
6345 * @exception IllegalArgumentException <ul> 6368 * @exception IllegalArgumentException <ul>
6375 removeListener(DWT.Selection, listener); 6398 removeListener(DWT.Selection, listener);
6376 } 6399 }
6377 /** 6400 /**
6378 * Removes the specified verify listener. 6401 * Removes the specified verify listener.
6379 * 6402 *
6380 * @param verifyListener the listener 6403 * @param verifyListener the listener which should no longer be notified
6404 *
6381 * @exception DWTException <ul> 6405 * @exception DWTException <ul>
6382 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 6406 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
6383 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 6407 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
6384 * </ul> 6408 * </ul>
6385 * @exception IllegalArgumentException <ul> 6409 * @exception IllegalArgumentException <ul>
6392 removeListener(DWT.Verify, verifyListener); 6416 removeListener(DWT.Verify, verifyListener);
6393 } 6417 }
6394 /** 6418 /**
6395 * Removes the specified key verify listener. 6419 * Removes the specified key verify listener.
6396 * 6420 *
6397 * @param listener the listener 6421 * @param listener the listener which should no longer be notified
6422 *
6398 * @exception DWTException <ul> 6423 * @exception DWTException <ul>
6399 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 6424 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
6400 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 6425 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
6401 * </ul> 6426 * </ul>
6402 * @exception IllegalArgumentException <ul> 6427 * @exception IllegalArgumentException <ul>
6408 removeListener(VerifyKey, listener); 6433 removeListener(VerifyKey, listener);
6409 } 6434 }
6410 /** 6435 /**
6411 * Removes the specified word movement listener. 6436 * Removes the specified word movement listener.
6412 * 6437 *
6413 * @param listener the listener 6438 * @param listener the listener which should no longer be notified
6439 *
6414 * @exception DWTException <ul> 6440 * @exception DWTException <ul>
6415 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 6441 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
6416 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 6442 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
6417 * </ul> 6443 * </ul>
6418 * @exception IllegalArgumentException <ul> 6444 * @exception IllegalArgumentException <ul>
7106 if (isBidiCaret()) createCaretBitmaps(); 7132 if (isBidiCaret()) createCaretBitmaps();
7107 caretDirection = DWT.NULL; 7133 caretDirection = DWT.NULL;
7108 setCaretLocation(); 7134 setCaretLocation();
7109 super.redraw(); 7135 super.redraw();
7110 } 7136 }
7111 /**
7112 * @see dwt.widgets.Control#setForeground
7113 */
7114 public override void setForeground(Color color) { 7137 public override void setForeground(Color color) {
7115 checkWidget(); 7138 checkWidget();
7116 foreground = color; 7139 foreground = color;
7117 super.setForeground(getForeground()); 7140 super.setForeground(getForeground());
7118 super.redraw(); 7141 super.redraw();
8397 * @param newLength length of new text 8420 * @param newLength length of new text
8398 */ 8421 */
8399 void updateSelection(int startOffset, int replacedLength, int newLength) { 8422 void updateSelection(int startOffset, int replacedLength, int newLength) {
8400 if (selection.y <= startOffset) { 8423 if (selection.y <= startOffset) {
8401 // selection ends before text change 8424 // selection ends before text change
8425 if (wordWrap) setCaretLocation();
8402 return; 8426 return;
8403 } 8427 }
8404 if (selection.x < startOffset) { 8428 if (selection.x < startOffset) {
8405 // clear selection fragment before text change 8429 // clear selection fragment before text change
8406 internalRedrawRange(selection.x, startOffset - selection.x); 8430 internalRedrawRange(selection.x, startOffset - selection.x);