Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 138579

Summary: StyledText: Support for custom double-click (+drag) behavior
Product: [Eclipse Project] Platform Reporter: Dani Megert <daniel_megert>
Component: SWTAssignee: Felipe Heidrich <eclipse.felipe>
Status: VERIFIED FIXED QA Contact:
Severity: normal    
Priority: P3 CC: bogofilter+eclipse.org, Mike_Wilson, snorthov
Version: 3.2   
Target Milestone: 3.3 M6   
Hardware: PC   
OS: Windows XP   
Whiteboard:
Bug Depends on:    
Bug Blocks: 5138    
Attachments:
Description Flags
Snippet showing bug
none
patch for wordboundary listener none

Description Dani Megert CLA 2006-04-26 05:13:56 EDT
N20060426-0010.

In order to correctly fix bug 135056 and provider the feature from bug 5138 we need more support from StyledText to prevent the UI from flickering since there is no API in StyledText to disable it's selection behavior and hence we setting the selection compete against the StyledText behavior. 

Even better than API to temporarily disable the selection behavior would be to allow to set a double-click strategy or word detector that is used for double-click and double-click drag.
Comment 1 Steve Northover CLA 2006-04-26 09:08:26 EDT
You are already using setDoubleClickEnabled(false) to disable the default action of the widget when the user double clicks, right?
Comment 2 Dani Megert CLA 2006-04-26 09:10:50 EDT
Correct, but the selection (while mouse is down during double-click) is still be done by StyledText. We could stop using setDoubleClickEnabled(false) if we can set a strategy.
Comment 3 Steve Northover CLA 2006-06-21 10:29:35 EDT
> ... but the selection (while mouse is down during double-click) is still
> be done

Isn't this just a bug.
Comment 4 Dani Megert CLA 2006-06-21 10:46:18 EDT
Yes, either we consider setting the selection on 1 1/2 click + drag when setDoubleClickEnabled(false) as a bug or we add new API that allows to control how the next/previous word is selected when setDoubleClickEnabled(true).
Comment 5 Felipe Heidrich CLA 2006-07-06 14:51:05 EDT
We (SN and FH) don't understand the problem.  Can you give us a set of steps that shows the bad thing?
Comment 6 Dani Megert CLA 2006-07-18 11:43:51 EDT
Created attachment 46449 [details]
Snippet showing bug

Start the attached snippet then 1 1/2 click (i.e. don't release mouse button after second down) + drag
==> StyledText sets the selection while moving the mouse
Comment 7 Dani Megert CLA 2006-09-21 10:31:40 EDT
Bug 5138 is on the 3.3 plan but can't be done without this one. Can you commit to this bug for 3.3 and give an ETA (e.g. target milestone)? Thanks.
Comment 8 Bogdan Gheorghe CLA 2007-01-31 17:03:11 EST
Dani, here's our understanding of what you're asking: 

Currently, StyledText has the ability to do word select during double click drag if doubleClickEnabled is true(see bug 15610). 

We believe that you want to be able to specify the boundaries of the word selection (ex. for camel case) on a double click + drag. 

As you said there are two options:

a) We don't select any text during a double click drag.

b) We allow for a word boundary listener which we would consult to get the start and end of the next/previous word given the current caret offset. In this case, doubleClickEnabled would have to set to true.

Is this correct?
Comment 9 Dani Megert CLA 2007-02-01 02:40:30 EST
Exactly. Of course I'd prefer to get b) ;-)
Comment 10 Dani Megert CLA 2007-02-27 06:33:57 EST
ping.
Comment 11 Felipe Heidrich CLA 2007-02-28 15:02:51 EST
Hey Dani, this is what I come up this morning, let me know if I'm in the right track. Suggestion are welcome.

	styledText.addWordBoundaryListener(new WordBoundaryListener() {
		/* Called when the StyledText needs to know the word start of the next 
		 * word relative to current caretOffset.
		 * This method is called:
		 *   word next (control right-arrow)
		 *   select word next (control shift right-arrow)
		 *   delete next word (control delete)
		 */
		public void getWordNext(WordBoundaryEvent event) {
			event.caretOffset += 4;//this is a input/output field
		}
		
		/* Called when the StyledText needs to know the word start of the previous 
		 * word relative to current caretOffset.
		 * This method is called:
		 *   word previous (control left-arrow) 
		 *   select word previous (control shift left-arrow)
		 *   select word on mouse double click
		 *   select word on mouse double-click+drag
		 *   delete previous word (control backspace)
		 */
		public void getWordPrevious(WordBoundaryEvent event) {
			event.caretOffset -= 3;
			
		}
		
		/* Called when the StyledText needs to know the word end of the next 
		 * word relative to current caretOffset.
		 * This method is called:
		 *   select word on mouse double click
		 *   select word on mouse double-click+drag
		 */
		public void getWordNextNoSpaces(WordBoundaryEvent event) {
			event.caretOffset = SWT.DEFAULT;//teels styledtext to do the default behaviour
		}
	});
Comment 12 Felipe Heidrich CLA 2007-02-28 15:06:10 EST
Created attachment 60014 [details]
patch for wordboundary listener

(this patch also has the printing line number fix, you can ignore that).
Comment 13 Dani Megert CLA 2007-03-01 10:34:30 EST
Looks good.
Comment 14 Dani Megert CLA 2007-03-12 06:54:30 EDT
API freeze is in a few days. I need this asap in an official build so that I can adopt this and ask for new API on the PMC mailing list.
Comment 15 Felipe Heidrich CLA 2007-03-16 12:00:10 EDT
I got the API verified by SSQ and Steve.
I have it ready to release. How do we procede ?
Comment 16 Felipe Heidrich CLA 2007-03-16 12:01:07 EDT
This is a sample on how to use the API:

text.addWordMovementListener(new MovementListener() {
	public void getNextOffset (MovementEvent event) {
		switch (event.movement) {
			/* This method is called:
			 *   word next (control right-arrow)
			 *   select word next (control shift right-arrow)
			 *   delete next word (control delete)
			 */
			case SWT.MOVEMENT_WORD:
				event.newOffset = event.offset + 3; break;
				
			/* This method is called:
			 *   double click select word
			 *   double click drag select word
			 */	
			case SWT.MOVEMENT_WORD_END:
				event.newOffset = event.offset + 6; break;
		}
	}
	
	public void getPreviousOffset(MovementEvent event) {
		switch (event.movement) {
			/* This method is called:
			 *   word previous (control right-arrow)
			 *   select word previous (control shift right-arrow)
			 *   delete previous word (control delete)
			 */
			case SWT.MOVEMENT_WORD:
				event.newOffset = event.offset - 3; break;
			
			/* This method is called:
			 *   double click select word
			 *   double click drag select word
			 */	
			case SWT.MOVEMENT_WORD_START:
				event.newOffset = event.offset - 6; break;
		}
	}
});
Comment 17 Dani Megert CLA 2007-03-16 12:08:52 EDT
>How do we procede ?
File an API change request on eclipse-pmc@eclipse.org and once it is approved commit it to HEAD. Best would be if it's in the warm up build.
Comment 18 Felipe Heidrich CLA 2007-03-16 12:10:57 EDT
MOVEMENT_WORD is platform specific. For example, during word next on windows the caret stops at each word start in the line. In gtk or carbon the caret stops at each word end in the line.

MOVEMENT_WORD_START and MOVEMENT_WORD_END are absolute, the API has to respond the next word start or word end relative to the current offset.
StyledText uses this API to determine word boundary during mouse double click (+drag). It will call previous word start and next word end to determine which word to select. Note: StyledText doesn't need to ask for previous word end and next word start for any of its current functionalists.

The event has two int fields, the offset and the newOffset. offset is the current offset (input only). newOffset is filled if the offset StyledText computed using TextLayout, this is the field the application should change to override the behaviour.

Comment 19 Felipe Heidrich CLA 2007-03-16 13:23:01 EDT
The request has been sent to the PMC.
Comment 20 Mike Wilson CLA 2007-03-16 16:15:46 EDT
+1
Comment 21 Felipe Heidrich CLA 2007-03-16 18:02:51 EDT
fixed in HEAD.
Comment 22 Dani Megert CLA 2007-03-21 10:41:59 EDT
First, thanks Felipe for this - I will be able to use that during M7 to fix bug 5138.

There are three remaining issues:
1) the MOVEMENT constants are pretty vague formulated i.e. what you describe in
   your sample in comment 16 is not backed through official API. This however is
   needed as I need to know whether we are in keyboard or mouse mode (see next
   item).

2) we can/want currently only adopt this support for mouse events and hence I 
   wonder whether we could add the listener depending on that. It would save 
   performance in keyboard mode.

3) now that I added line selection on triple-click I basically run into the
   same problem there i.e. I'm back at comment 0 in this case. Hence I would
   either need to disable the SWT's selection mechanism or (better) extend the
   MovementListener to also get called on triple-click + drag and to add the
   'clickCount' field to it.

And finally a question: when I use this API I don't have to manually call getTextWidget().copy(DND.SELECTION_CLIPBOARD), right?
Comment 23 Dani Megert CLA 2007-03-21 11:28:28 EDT
In the triple-click + drag case the problem is even worse as I have to adjust the selection all the time, not just when I'm inside the first (line) selection.
Comment 24 Felipe Heidrich CLA 2007-03-21 12:30:34 EDT
1) Sorry Dany, we don't have time to write JavaDoc this week.

2) As far as I understood this question the answer is:
You can add the listener and only change the value of newOffset for the movements type: MOVEMENT_WORD_START and MOVEMENT_WORD_END. That will only affect the mouse. No performance penalty for the keyboard.

3) Triple click select line: Did you test it - does it flash ?

4) Triple click + drag doesn not exist. To start a drag operation the click count has to be one. Do you get a drag start in triple or double click drag ?
Please, we change this very recently so use latest code from HEAD to test.
(note, I didn't understand the problem in comment #23)

5) setSelection does not copy the selection to the clipboard for you.
Comment 25 Dani Megert CLA 2007-03-21 12:50:32 EDT
1) fine with me as long as it will say the same as in your snippet ;-)

2) yep, but each keyboard next/prev will now fire to my listener and will
   then be ignored by it. If I could add the listener and tell to be fired
   only for the mouse case it would be a little bit faster.

3) Triple click to select one line works perfect but when the user starts to 
   move the mouse while still down, he expects that next/prev lines are fully 
   selected. This I have to do manually and hence I'm back to comnent 0 as SWT 
   also tries to update the selection during mouseDown+Shift+mouseMove.

5) I know that setSelection doesn't do this but what about StyledText's double 
   click (+ select via mouse move) support? Does it feed the 
   SELECTION_CLIPBOARD?

>4) Triple click + drag doesn not exist. 
>(note, I didn't understand the problem in comment #23)
Sorry for the confusion. "drag" was the wrong word. It's all about triple-click and + mouseMove to select multiple lines.
Comment 26 Felipe Heidrich CLA 2007-03-21 14:34:48 EDT
1. okay

2. You are right, the listener will be called. 
I think you should use the listener to implement the camel case word next/previous for keyboard too.
How is that implement right now? Do you remove the binding from StyledText ? If so then the listener won't get called anyway, right ?

3. Triple click - move. It is bad. I guess I could change StyledText to ignore triple click, but then I would never be able to implement this feature in StyledText.

5. After every mouse up (button==1) the text selection is set in the clipboard. So yes for your question.
Comment 27 Dani Megert CLA 2007-03-21 15:29:20 EDT
re 2) the text editor does nothing special hence StyledText handles word-based operations and hence the listener is fired and handled without use. In the Java editor we take the control and nothing gets fired.

>I guess I could change StyledText to ignore triple click, 
What do you mean by that exactly?
Comment 28 Felipe Heidrich CLA 2007-03-21 15:44:48 EDT
> >I guess I could change StyledText to ignore triple click, 
> What do you mean by that exactly?

Steve thinks StyledText should implement triple click and triple click move.
Since, we believe, line boundary never needs to be customized by the application this feautre won't required new API.
We can add this after M6.
If you agree please go ahead and open a new bug report.

Comment 29 Dani Megert CLA 2007-03-21 15:51:35 EDT
>Steve thinks StyledText should implement triple click and triple click move.
That sounds great. If you can commit to this for 3.3 I will file a PMC request right now asking for permission to remove the API that I added recently for triple-click.
Comment 30 Dani Megert CLA 2007-03-22 07:03:55 EDT
I looked at the new API and verified that Platform Text can use it to fix bug 5138 during M7.

Filed bug 178758 to track the incomplete Javadoc.