Index: src/orca/settings.py
===================================================================
--- src/orca/settings.py	(revision 4313)
+++ src/orca/settings.py	(working copy)
@@ -117,6 +117,7 @@
     "brailleRolenameStyle",
     "brailleSelectorIndicator",
     "brailleLinkIndicator",
+    "braillePanningStyle",
     "enableBrailleMonitor",
     "enableMagnifier",
     "enableMagLiveUpdating",
@@ -261,6 +262,11 @@
 BRAILLE_LINK_BOTH = 0xc0 # 11000000
 brailleLinkIndicator = BRAILLE_LINK_BOTH
 
+# braille display panning styles
+PAN_BRAILLE_BY_WORD = 1
+PAN_BRAILLE_AS_BRLTTY = 2
+braillePanningStyle = PAN_BRAILLE_BY_WORD 
+
 # Speech punctuation levels (see verbalizePunctuationStyle).
 #
 PUNCTUATION_STYLE_NONE = 3
@@ -849,7 +855,7 @@
     """
     prefix = "/desktop/gnome/applications/at/visual/"
     try:
-	return ("orca" in gconfClient.get_string(prefix + "exec")) \
+        return ("orca" in gconfClient.get_string(prefix + "exec")) \
            and gconfClient.get_bool(prefix + "startup")
     except:
         return False
Index: src/orca/orca_prefs.py
===================================================================
--- src/orca/orca_prefs.py	(revision 4313)
+++ src/orca/orca_prefs.py	(working copy)
@@ -313,6 +313,14 @@
         else:
             return "orca.settings.BRAILLE_ROLENAME_STYLE_LONG"
 
+    def _getBraillePanningStyleString(self, braillePanningStyle):
+        """Returns a string that represents the braillePanningStyle passed."""
+
+        if braillePanningStyle == settings.PAN_BRAILLE_BY_WORD:
+            return "orca.settings.PAN_BRAILLE_AS_BRLTTY"
+        else:
+            return "orca.settings.PAN_BRAILLE_BY_WORD"
+
     def _getVerbalizePunctuationStyleString(self, punctuationStyle):
         """Returns a string that represents the punctuation style passed in."""
 
@@ -685,6 +693,8 @@
                 value = self._getBrailleSelectionIndicatorString(prefsDict[key])
             elif key == "brailleLinkIndicator":
                 value = self._getBrailleLinkIndicatorString(prefsDict[key])
+            elif key == "braillePanningStyle ":
+                value = self._getBraillePanningStyleString(prefsDict[key])
             elif key == "verbalizePunctuationStyle":
                 value = self._getVerbalizePunctuationStyleString(prefsDict[key])
             elif key == "sayAllStyle":
Index: src/orca/braille.py
===================================================================
--- src/orca/braille.py	(revision 4313)
+++ src/orca/braille.py	(working copy)
@@ -880,7 +880,7 @@
 
     _lines = []
     _regionWithFocus = None
-    viewport = [0, 0]
+    viewport = [viewport[0], 0]
 
 def setLines(lines):
     global _lines
@@ -945,18 +945,45 @@
             break
         else:
             lineNum += 1
+    refresh(panToFocus, 0, getLinkMask)
+    
+def writeBraille(string = "", attributeMask = ""):
+    global monitor
+    if string == "":
+        if useBrlAPIBindings:
+            if brlAPIRunning:
+                brlAPI.writeText("", 0)
+        else:
+            brl.writeText(0, "")
+        return    
+        
+    if useBrlAPIBindings:
+        if brlAPIRunning:
+            writeStruct = brlapi.WriteStruct()
+            writeStruct.regionBegin = 1
+            #writeStruct.regionSize = len(string.decode("UTF-8"))
+            writeStruct.regionSize = _displaySize[0]
+            blankLength = _displaySize[0] - len(string.decode("UTF-8"))
+            string += " " * blankLength
+            if attributeMask:
+                attributeMask += '\x00' * blankLength
+            writeStruct.text = string
+            writeStruct.cursor = cursorCell
+            writeStruct.charset = "UTF-8"
+            if attributeMask:
+                writeStruct.attrOr = attributeMask
+            brlAPI.write(writeStruct) 
+    else:
+        brl.writeText(cursorCell, string)
+    if settings.enableBrailleMonitor:
+        if not monitor:
+            monitor = brlmon.BrlMon(_displaySize[0])
+            monitor.show_all()
+        monitor.writeText(cursorCell, string, attributeMask)
+    elif monitor:
+        monitor.destroy()
+        monitor = None
 
-    line = _lines[viewport[1]]
-    [string, offset, attributeMask] = line.getLineInfo(getLinkMask)
-
-    # If the cursor is too far right, we scroll the viewport
-    # so the cursor will be on the last cell of the display.
-    #
-    if _regionWithFocus.cursorOffset >= _displaySize[0]:
-        offset += _regionWithFocus.cursorOffset - _displaySize[0] + 1
-
-    viewport[0] = max(0, offset)
-
 def refresh(panToCursor=True, targetCursorCell=0, getLinkMask=True):
     """Repaints the Braille on the physical display.  This clips the entire
     logical structure by the viewport and also sets the cursor to the
@@ -980,17 +1007,12 @@
       amount of time (AKA Gecko).
     """
 
+    global cursorCell
     global endIsShowing
     global beginningIsShowing
-    global cursorCell
-    global monitor
 
     if len(_lines) == 0:
-        if useBrlAPIBindings:
-            if brlAPIRunning:
-                brlAPI.writeText("", 0)
-        else:
-            brl.writeText(0, "")
+        writeBraille()
         return
 
     # Now determine the location of the cursor.  First, we'll figure
@@ -1005,37 +1027,32 @@
     # actually is in the string.
     #
     line = _lines[viewport[1]]
-    [string, focusOffset, attributeMask] = line.getLineInfo(getLinkMask)
-    cursorOffset = -1
-    if focusOffset >= 0:
-        cursorOffset = focusOffset + _regionWithFocus.cursorOffset
+    [string, offset, attributeMask] = line.getLineInfo(getLinkMask)
+    # If the cursor is too far right, we scroll the viewport
+    additionalOffset = _regionWithFocus.cursorOffset
+    totalOffset = offset + additionalOffset
 
-    # Now, if desired, we'll automatically pan the viewport to show
-    # the cursor.  If there's no targetCursorCell, then we favor the
-    # left of the display if we need to pan left, or we favor the
-    # right of the display if we need to pan right.
-    #
-    if panToCursor and (cursorOffset >= 0):
-        if len(string) <= _displaySize[0]:
-            viewport[0] = 0
-        elif targetCursorCell:
-            viewport[0] = max(0, cursorOffset - targetCursorCell + 1)
-        elif cursorOffset < viewport[0]:
-            viewport[0] = max(0, cursorOffset)
-        elif cursorOffset >= (viewport[0] + _displaySize[0]):
-            viewport[0] = max(0, cursorOffset - _displaySize[0] + 1)
 
+    if panToCursor:
+        if targetCursorCell:
+            viewport[0] = max(0, totalOffset - targetCursorCell + 1)
+        elif settings.braillePanningStyle == settings.PAN_BRAILLE_AS_BRLTTY:
+            _refreshAsBRLTTY(string, offset, totalOffset)
+        else:
+            _refreshByWords(string, offset, totalOffset)
+
     startPos = viewport[0]
     endPos = startPos + _displaySize[0]
-
     # Now normalize the cursor position to BrlTTY, which uses 1 as
     # the first cursor position as opposed to 0.
     #
-    cursorCell = cursorOffset - startPos
+    cursorCell = totalOffset - startPos
     if (cursorCell < 0) or (cursorCell >= _displaySize[0]):
         cursorCell = 0
     else:
         cursorCell += 1 # Normalize to 1-based offset
+    startPos = viewport[0]
+    endPos = startPos + _displaySize[0]
 
     logLine = "BRAILLE LINE:  '%s'" % string
     debug.println(debug.LEVEL_INFO, logLine)
@@ -1044,59 +1061,68 @@
                     (string[startPos:endPos], cursorCell)
     debug.println(debug.LEVEL_INFO, logLine)
     log.info(logLine.encode("UTF-8"))
-
     substring = string[startPos:endPos]
-    if useBrlAPIBindings:
-        if brlAPIRunning:
-            writeStruct = brlapi.WriteStruct()
-            writeStruct.regionBegin = 1
-            writeStruct.regionSize = len(substring)
-            while writeStruct.regionSize < _displaySize[0]:
-                substring += " "
-                if attributeMask:
-                    attributeMask += '\x00'
-                writeStruct.regionSize += 1
-            writeStruct.text = substring
-            writeStruct.cursor = cursorCell
+    submask = attributeMask[startPos:endPos]
+    writeBraille(substring, submask)
+    beginningIsShowing = startPos == 0
+    endIsShowing = endPos >= len(string)    
 
-            # [[[WDW - if you want to muck around with the dots on the
-            # display to do things such as add underlines, you can use
-            # the attrOr field of the write structure to do so.  The
-            # attrOr field is a string whose length must be the same
-            # length as the display and whose dots will end up showing
-            # up on the display.  Each character represents a bitfield
-            # where each bit corresponds to a dot (i.e., bit 0 = dot 1,
-            # bit 1 = dot 2, and so on).  Here's an example that underlines
-            # all the text.]]]
-            #
-            #myUnderline = ""
-            #for i in range(0, _displaySize[0]):
-            #    myUnderline += '\xc0'
-            #writeStruct.attrOr = myUnderline
+def _refreshByWords(string, offset, totalOffset):
+    """Helper function for refresh()
+    
+    This function positions full words at the edge of the display, if the cursor is within margin of the edge.
+    If the word to be displayed is considered to be too long (larger than maxJump, then we only reposition display by maxJump.
+    """
+    
+    # how close the braille cursor is allowed to the edge of the braille display.
+    margin = 3 
+    # how far we are allowed to look for the next word (beyond the edge of the braille display)
+    maxJump = 8+margin
+    # calculating absolute values:
+    innerLeftMargin  = viewport[0] + margin - 1
+    outerLeftMargin = string[:viewport[0]].rfind(' ')
+    # varifying that we are not jumping the display more than allowed.
+    if outerLeftMargin < viewport[0] - maxJump:
+        outerLeftMargin = viewport[0] - maxJump
 
-            if attributeMask:
-                writeStruct.attrOr = attributeMask[startPos:endPos]
+    rightDisplayEdge = viewport[0] + _displaySize[0]
+    innerRightMargin = rightDisplayEdge  - margin
+    outerRightMargin = string[rightDisplayEdge:].find(' ') \
+      + rightDisplayEdge
+    # varifying that we are not jumping the display more than allowed.
+    if outerRightMargin > rightDisplayEdge + maxJump:
+        outerRightMargin = rightDisplayEdge + maxJump
 
-            brlAPI.write(writeStruct)
-    else:
-        brl.writeText(cursorCell, substring)
-
-    if settings.enableBrailleMonitor:
-        if not monitor:
-            monitor = brlmon.BrlMon(_displaySize[0])
-            monitor.show_all()
-        if attributeMask:
-            subMask = attributeMask[startPos:endPos]
-        else:
-            subMask = None
-        monitor.writeText(cursorCell, substring, subMask)
-    elif monitor:
-        monitor.destroy()
-        monitor = None
-
-    beginningIsShowing = startPos == 0
-    endIsShowing = endPos >= len(string)
-
+    # Working out where to position the display.
+    # Warning, these if blocks are order dependant.
+    if totalOffset >= outerRightMargin:
+        viewport[0] = max(0, totalOffset - _displaySize[0]/2 + 1)
+    elif totalOffset >= innerRightMargin and \
+        outerRightMargin  >= rightDisplayEdge:
+        outerRightMargin = string[outerRightMargin+1:].find(' ') + \
+          outerRightMargin + 1
+        if outerRightMargin  > rightDisplayEdge + maxJump:
+            outerRightMargin  = rightDisplayEdge + maxJump
+        viewport[0] = max(0, (outerRightMargin - _displaySize[0]))
+    elif outerLeftMargin <= offset and totalOffset <= rightDisplayEdge:
+        viewport[0] =  max(0, offset)
+    elif totalOffset <= outerLeftMargin:
+        viewport[0] = max(0, totalOffset)
+    elif totalOffset <= innerLeftMargin:
+        outerLeftMargin = string[:outerLeftMargin-1].rfind(' ') + 1
+        if outerLeftMargin  < viewport[0] - maxJump:
+            outerLeftMargin  = viewport[0] - maxJump
+            viewport[0] = max(0, outerLeftMargin)
+def _refreshAsBRLTTY(string, offset, totalOffset):
+    """Helper function for refresh()
+    
+    This function simulates brlttys method of breaking text.
+    """
+    
+    lineLength = totalOffset - offset
+    fullDisplays = lineLength / _displaySize[0]
+    viewport[0] = offset + fullDisplays * _displaySize[0]
+    
 def displayRegions(regionInfo):
     """Displays a list of regions on a single line, setting focus to the
        specified region.  The regionInfo parameter is something that is
@@ -1117,7 +1143,6 @@
         line.addRegion(item)
     addLine(line)
     setFocus(focusedRegion)
-    refresh()
 
 def displayMessage(message, cursor=-1):
     """Displays a single line, setting the cursor to the given position,
@@ -1132,7 +1157,6 @@
     region = Region(message, cursor)
     addLine(Line(region))
     setFocus(region)
-    refresh(True)
 
 def panLeft(panAmount=0):
     """Pans the display to the left, limiting the pan to the beginning
@@ -1206,8 +1230,6 @@
     """
 
     setFocus(_regionWithFocus)
-    refresh(True)
-
     return True
 
 def _processBrailleEvent(command):
