EditTextView.st
branchtext-view-selection-refactoring
changeset 4841 4fca96a61d42
parent 4674 935f7e07003b
child 4843 7cd827899263
--- a/EditTextView.st	Tue Aug 27 03:25:37 2013 +0000
+++ b/EditTextView.st	Wed Aug 28 01:41:15 2013 +0100
@@ -4559,6 +4559,7 @@
         (shifted and:[selectionStartLine isNil]) ifTrue:[
             selectionStartLine := selectionEndLine := clickStartLine := cursorLine.
             selectionStartCol := selectionEndCol := clickStartCol := cursorCol.
+            cursorCol := cursorCol + 1.
             expandingTop := false.
             self validateNewSelection.
             self setPrimarySelection.
@@ -4567,34 +4568,25 @@
             ^ self.
         ].
 
-        selectionStartLine notNil ifTrue:[
-            self cursorMovementAllowed ifTrue:[
-                "/
-                "/ treat the whole selection as cursor
-                "/
-                self setCursorLine:(selectionEndLine ? selectionStartLine).
-                selectionEndCol == 0 ifTrue:[
-                    selectionEndCol := 1.
-                ].
-                self setCursorCol:selectionEndCol.
-                shifted ifTrue:[
-                    self expandSelectionRight.
-                    ^ self
-                ].
+        self cursorMovementAllowed ifTrue:[
+            shifted ifTrue:[
+                self addToSelectionAfter:[ self cursorRight ]
+            ] ifFalse:[
                 self unselect; makeCursorVisible.
-                cursorCol == 1 ifTrue:[^ self].
+                self cursorRight.
             ].
         ].
-        self cursorRight.
         ^ self
     ].
     (key == #CursorDown) ifTrue:[
         (shifted and:[selectionStartLine isNil]) ifTrue:[
             selectionStartLine := clickStartLine := cursorLine. selectionEndLine := cursorLine + 1.
-            selectionStartCol := clickStartCol := selectionEndCol := cursorCol.
+            selectionStartCol := clickStartCol := cursorCol.
+            selectionEndCol := cursorCol - 1.
             selectionEndCol == 1 ifTrue:[
                 selectionEndCol := 0.
             ].
+            self setCursorLine: cursorLine + 1.
             self validateNewSelection.
             self selectionChanged.
             self redrawLine:selectionStartLine.
@@ -4608,30 +4600,37 @@
                 "/
                 "/ treat the whole selection as cursor
                 "/
-                self setCursorLine:(selectionEndLine ? selectionStartLine).
-                self setCursorCol:selectionStartCol.
-                (cursorCol == 0 or:[selectionEndCol == 0]) ifTrue:[
-                    self setCursorCol:1.
-                    self setCursorLine:(cursorLine - 1).
-                ].
-                self makeCursorVisible.
-
-                shifted ifTrue:[
-                    clickLine := cursorLine.
-                    clickCol := cursorCol.
-                    self expandSelectionDown.
-                    ^ self
-                ].
-                self unselect.
+"/                self setCursorLine:(selectionEndLine ? selectionStartLine).
+"/                self setCursorCol:selectionStartCol.
+"/                (cursorCol == 0 or:[selectionEndCol == 0]) ifTrue:[
+"/                    self setCursorCol:1.
+"/                    self setCursorLine:(cursorLine - 1).
+"/                ].
+"/                self makeCursorVisible.
+"/
+"/                shifted ifTrue:[
+"/                    clickLine := cursorLine.
+"/                    clickCol := cursorCol.
+"/                    self setCursorLine: cursorLine + 1.
+"/                    self expandSelectionDown.
+"/                    ^ self
+"/                ].
+"/                self unselect.
             ].
         ].
-
-        n := 1 + (self sensor compressKeyPressEventsWithKey:#CursorDown).
-        self cursorDown:n.
-        "/
-        "/ flush keyboard to avoid runaway cursor
-        "/
-        self sensor flushKeyboardFor:self.
+        self cursorMovementAllowed ifTrue:[
+            n := 1 + (self sensor compressKeyPressEventsWithKey:#CursorDown).
+            shifted ifTrue:[
+                self addToSelectionAfter:[ self cursorDown:n ]
+            ] ifFalse:[
+                self unselect; makeCursorVisible.
+                self cursorDown:n.
+            ].  
+            "/
+            "/ flush keyboard to avoid runaway cursor
+            "/
+            self sensor flushKeyboardFor:self.
+        ].
         ^ self
     ].
     (key == #CursorLeft or:[key == #CursorUp]) ifTrue:[
@@ -4642,6 +4641,7 @@
                     selectionStartLine := selectionEndLine := clickStartLine := cursorLine.
                     selectionEndCol := clickStartCol := cursorCol-1.
                     selectionStartCol := cursorCol-1.
+                    self setCursorCol: cursorCol-1.
                     self validateNewSelection.
                     self selectionChanged.
                     self redrawLine:selectionStartLine.
@@ -4650,7 +4650,8 @@
             ] ifFalse:[
                 cursorLine > 1 ifTrue:[
                     selectionEndLine := clickStartLine := cursorLine.
-                    selectionEndCol := selectionStartCol := clickStartCol := cursorCol.
+                    selectionStartCol := clickStartCol := cursorCol.
+                    selectionEndCol := cursorCol - 1.
                     selectionStartLine := cursorLine - 1.
                     selectionEndCol == 1 ifTrue:[
                         selectionEndCol := 0.
@@ -4658,41 +4659,43 @@
                     self validateNewSelection.
                     self selectionChanged.
                     self redrawFromLine:selectionStartLine to:cursorLine.
+                    self setCursorLine: cursorLine - 1.  
                     ^ self
                 ]
             ]
         ].
 
-        selectionStartLine notNil ifTrue:[
+        self hasSelection ifTrue:[
             self cursorMovementAllowed ifTrue:[
                 "/
                 "/ treat the whole selection as cursor
                 "/
-                self setCursorLine:selectionStartLine.
-                self setCursorCol:selectionStartCol.
-                (key == #CursorLeft) ifTrue:[
-                    self setCursorCol:(cursorCol+1).  "/ compensate for followup crsr-left
-                ].
+"/                self setCursorLine:selectionStartLine.
+"/                self setCursorCol:selectionStartCol.
                 self makeCursorVisible.
 
-                shifted ifTrue:[
-                    (key == #CursorUp) ifTrue:[
-                        clickLine := cursorLine.
-                        self expandSelectionUp.
-                    ] ifFalse:[
-                        self expandSelectionLeft.
-                    ].
-                    ^ self
-                ].
-                self unselect.
+"/                shifted ifFalse:[
+"/                    self unselect.
+"/                ]
             ].
         ].
         (key == #CursorLeft) ifTrue:[
-            self cursorLeft. ^self
+            shifted ifTrue:[
+                self addToSelectionAfter:[self cursorLeft].
+            ] ifFalse:[
+                self unselect; makeCursorVisible.
+                self cursorLeft. 
+            ].
+            ^self
         ].
-        (key == #CursorUp)        ifTrue:[
+        (key == #CursorUp) ifTrue:[
             n := 1 + (self sensor compressKeyPressEventsWithKey:#CursorUp).
-            self cursorUp:n.
+            shifted ifTrue:[
+                self addToSelectionAfter: [ self cursorUp:n ]
+            ] ifFalse:[
+                self unselect; makeCursorVisible.
+                self cursorUp:n.
+            ].
             "/
             "/ flush keyboard to avoid runaway cursor
             "/
@@ -4701,7 +4704,7 @@
         ].
     ].
 
-    "Modified: / 17-04-2012 / 21:01:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 28-08-2013 / 01:08:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 doKeyPress:key x:x y:y
@@ -4884,9 +4887,10 @@
             "/ self unselect.
             "/ self cursorHome.
             "Jan's modification"
-            "/ self addToSelectionAfter:[ self cursorToBeginOfLine ].
+            self addToSelectionAfter:[ self cursorToBeginOfLine ].
             "/ Jan's modification modified by his own request ;-))
-            self selectFromBeginOfLine.
+            "/ JV: Well, does not work correctly. Better to fix addToSelectionAfter: 
+            "/ self selectFromBeginOfLine.
         ] ifFalse: [
             self unselect.
             ctrlPressed ifTrue:[
@@ -4903,9 +4907,10 @@
             "/ self unselect.
             "/ self cursorToBottom
             " Jan's modification"
-            "/ self addToSelectionAfter:[ self cursorToEndOfLine ] .
+            self addToSelectionAfter:[ self cursorToEndOfLine ] .
             "/ Jan's modification modified by his own request ;-))
-            self selectToEndOfLine.
+            "/ JV: Well, does not work correctly. Better to fix addToSelectionAfter:
+            "/  self selectToEndOfLine.
         ] ifFalse:[
             self unselect.
             ctrlPressed ifTrue:[
@@ -5089,6 +5094,7 @@
 
     "Modified: / 06-02-1998 / 11:59:59 / stefan"
     "Modified: / 14-07-2011 / 12:08:28 / cg"
+    "Modified: / 26-08-2013 / 17:50:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 executeKeyboardMacro:cmdMacro
@@ -7313,36 +7319,84 @@
 !EditTextView methodsFor:'selections'!
 
 addToSelectionAfter:aBlock
+    "Extends the selection accroding to cursor position
+     after evaluation of `aBlock`. Used to implement
+     Shift-Home & Shift-End. "
+
+    "/ Following comment is in czech and thus now very useful.
+    "/ However I (JV) keep it here as this is one of the very
+    "/ first fix/hack we made to Smalltalk/X ages ago, if not
+    "/ the very first one. Actually, this method and comment was 
+    "/ written by Martin Dvorak. Yeah, being bit nostalgic...
+
     "Pokud existuje selekce, upravi ji
      podle aktualni pozice kurzoru a pozice
      po provedeni blocku.
      Urceno k implementaci Shift-Home a Shift-End
      Nejak nevim, jak to presneji popsat :-)"
 
-    |startLine startCol endLine endCol |
+    | startLine startCol endLine endCol curLine curCol cursorAtTheBeginning cursorAtTheEnd cursorWasShown |
+
+    curLine := cursorLine.
+    curCol := cursorCol.
 
     self hasSelection ifTrue: [
-	startLine := selectionStartLine .
-	startCol := selectionStartCol .
-	endLine := selectionEndLine .
-	endCol := selectionEndCol .
-    ] ifFalse: [
-	startLine := endLine :=  cursorLine .
-	startCol := endCol := cursorCol .
-    ].
-
-    "deselectim a provedu presun kurzoru..."
-    self unselect .
-    aBlock value .
-
-    "funguje dost mizerne, jen na jednom radku..."
-    (startCol - cursorCol) abs <= (endCol - cursorCol) abs
-	ifTrue: [
-	    startCol := cursorCol.
-	] ifFalse: [
-	    endCol := cursorCol - 1.
-	].
+        startLine := selectionStartLine .
+        startCol := selectionStartCol .
+        endLine := selectionEndLine .
+        endCol := selectionEndCol .
+    ] ifFalse:[
+        startLine := endLine := curLine.
+        startCol := curCol.
+        endCol := curCol - 1.
+    ].
+
+
+    cursorAtTheBeginning := (startLine == curLine) and:[startCol == curCol].
+    cursorAtTheEnd := (endLine == curLine) and:[endCol == (curCol - 1)]. 
+
+    self assert: cursorAtTheBeginning | cursorAtTheEnd.
+
+
+    cursorWasShown := self hideCursor.
+    aBlock value.
+
+    cursorAtTheBeginning ifTrue:[
+        (cursorCol == (endCol + 1) and:[cursorLine == endLine]) ifTrue:[
+                self unselect; showCursor.
+                ^self
+        ].
+
+        (cursorLine > endLine or:[cursorLine == endLine and:[cursorCol > endCol]]) ifTrue:[
+            startLine := endLine.
+            startCol := endCol + 1.
+            endLine := cursorLine.
+            endCol := cursorCol - 1
+        ] ifFalse:[
+            startLine := cursorLine.
+            startCol := cursorCol.
+        ]
+    ] ifFalse:[
+        cursorAtTheEnd ifTrue:[
+            (cursorCol == startCol and:[cursorLine == startLine]) ifTrue:[
+                self unselect; showCursor.
+                ^self
+            ].
+            (cursorLine < startLine or:[cursorLine == startLine and:[cursorCol < startCol]]) ifTrue:[
+                endLine := startLine.
+                endCol := startCol - 1.
+                startLine := cursorLine.
+                startCol := cursorCol
+            ] ifFalse:[
+                endLine := cursorLine.
+                endCol := cursorCol - 1.
+            ]
+        ].
+    ].
     self selectFromLine:startLine col:startCol toLine: endLine col:endCol .
+    cursorWasShown ifTrue:[self showCursor].
+
+    "Modified: / 28-08-2013 / 01:23:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 autoMoveCursorToEndOfSelection
@@ -7496,14 +7550,18 @@
 !
 
 selectFromLine:startLine col:startCol toLine:endLine col:endCol
-    "when a range is selected, position the cursor behind the selection
-     for easier editing. Also typeOfSelection is nilled here."
 
     super selectFromLine:startLine col:startCol toLine:endLine col:endCol.
-    (selectionEndLine notNil and:[self autoMoveCursorToEndOfSelection]) ifTrue:[
-	self cursorLine:selectionEndLine col:(selectionEndCol + 1).
-    ].
+    "JV: That's atctuall rubbish as then you loose the original positon
+     and if user wants to extend/shring the selection further, you don't know
+     from which end to do it!!"
+"/    (selectionEndLine notNil and:[self autoMoveCursorToEndOfSelection]) ifTrue:[
+"/        self cursorLine:selectionEndLine col:(selectionEndCol + 1).
+"/    ].
     typeOfSelection := nil
+
+    "Modified: / 27-08-2013 / 13:28:12 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (comment): / 27-08-2013 / 15:58:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 selectToEndOfLine