2. FindObjectScreen() applies the line style - corrects "mouse click mis
   positions the cursor" bug
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@2762 
c3d73ce0-8a6f-49c7-b76d-
6d57e0e08775
    }
 
    m_StyleInfo = llist->GetDefaultStyleInfo();
    }
 
    m_StyleInfo = llist->GetDefaultStyleInfo();
+
+   llist->IncNumLines();
 }
 
 wxLayoutLine::~wxLayoutLine()
 }
 
 wxLayoutLine::~wxLayoutLine()
 wxLayoutLine *
 wxLayoutLine::DeleteLine(bool update, wxLayoutList *llist)
 {
 wxLayoutLine *
 wxLayoutLine::DeleteLine(bool update, wxLayoutList *llist)
 {
-   if(m_Next) m_Next->m_Previous = m_Previous;
-   if(m_Previous) m_Previous->m_Next = m_Next;
+   // maintain linked list integrity
+   if(m_Next)
+       m_Next->m_Previous = m_Previous;
+   if(m_Previous)
+       m_Previous->m_Next = m_Next;
+
    if(update)
    {
       m_Next->MoveLines(-1);
    if(update)
    {
       m_Next->MoveLines(-1);
    }
    wxLayoutLine *next = m_Next;
    delete this;
    }
    wxLayoutLine *next = m_Next;
    delete this;
+
+   llist->DecNumLines();
+
    m_caret = NULL;
 #endif // WXLAYOUT_USE_CARET
 
    m_caret = NULL;
 #endif // WXLAYOUT_USE_CARET
 
    m_FirstLine = NULL;
    InvalidateUpdateRect();
    Clear();
    m_FirstLine = NULL;
    InvalidateUpdateRect();
    Clear();
 {
    InternalClear();
    m_FirstLine->DeleteLine(false, this);
 {
    InternalClear();
    m_FirstLine->DeleteLine(false, this);
+
+   wxASSERT_MSG( m_numLines == 0, "line count calculation broken" );
 #endif
       line = line->GetNextLine();
    }
 #endif
       line = line->GetNextLine();
    }
-      if(found) *found = false;
+      if ( found )
+          *found = false;
+
       return NULL; // not found
    }
       return NULL; // not found
    }
-   if(cursorPos) cursorPos->y = line->GetLineNumber();
+
+   if ( cursorPos )
+       cursorPos->y = line->GetLineNumber();
+
    // Now, find the object in the line:
    // Now, find the object in the line:
+   ApplyStyle(line->GetStyleInfo(), dc);
    wxLOiterator i = line->FindObjectScreen(dc, pos.x,
    wxLOiterator i = line->FindObjectScreen(dc, pos.x,
-                                           cursorPos ? & cursorPos->x : NULL ,
+                                           cursorPos ? &cursorPos->x : NULL,
                                            found);
    return (i == NULLIT) ? NULL : *i;
 
                                            found);
    return (i == NULLIT) ? NULL : *i;
 
 
          MoveCursorHorizontally(m_CursorLine->GetLength()-m_CursorPos.x);
       }
 
          MoveCursorHorizontally(m_CursorLine->GetLength()-m_CursorPos.x);
       }
 
-   /// Move cursor to begin of line.
+   /// Move cursor to the start of line.
    void MoveCursorToBeginOfLine(void)
       { MoveCursorHorizontally(-m_CursorPos.x); }
 
    void MoveCursorToBeginOfLine(void)
       { MoveCursorHorizontally(-m_CursorPos.x); }
 
+   /// get the number of lines in the list
+   size_t GetNumLines() const { return m_numLines; }
+
    /// Returns current cursor position.
    const wxPoint &GetCursorPos(wxDC &dc) const { return m_CursorPos; }
    const wxPoint &GetCursorPos() const { return m_CursorPos; }
 
    /// Returns current cursor position.
    const wxPoint &GetCursorPos(wxDC &dc) const { return m_CursorPos; }
    const wxPoint &GetCursorPos() const { return m_CursorPos; }
 
+   /// move cursor to the end of text
+   void MoveCursorToEnd(void)
+   {
+      MoveCursorTo(wxPoint(0, GetNumLines() - 1));
+      MoveCursorToEndOfLine();
+   }
+
    //@}
 
    /**@name Editing functions.
    //@}
 
    /**@name Editing functions.
+   // for wxLayoutLine usage only
+   void IncNumLines() { m_numLines++; }
+   void DecNumLines() { m_numLines--; }
+
 private:
    /// Clear the list.
    void InternalClear(void);
 
    /// The list of lines.
    wxLayoutLine *m_FirstLine;
 private:
    /// Clear the list.
    void InternalClear(void);
 
    /// The list of lines.
    wxLayoutLine *m_FirstLine;
+   /// The number of lines in the list (store instead recalculating for speed)
+   size_t m_numLines;
+
    /// The update rectangle which needs to be refreshed:
    wxRect  m_UpdateRect;
    /// Is the update rectangle valid?
    bool    m_UpdateRectValid;
    /// The update rectangle which needs to be refreshed:
    wxRect  m_UpdateRect;
    /// Is the update rectangle valid?
    bool    m_UpdateRectValid;
    /**@name Cursor Management */
    //@{
    /// Where the text cursor (column,line) is.
    /**@name Cursor Management */
    //@{
    /// Where the text cursor (column,line) is.
 
              else
              {
                 // click beyond the end of the text
              else
              {
                 // click beyond the end of the text
-                m_llist->MoveCursorTo(m_llist->GetSize());
+                m_llist->MoveCursorToEnd();
              }
 
              // clicking a mouse removes the selection
              }
 
              // clicking a mouse removes the selection
       break;
    case WXK_END:
       if ( ctrlDown )
       break;
    case WXK_END:
       if ( ctrlDown )
-         m_llist->MoveCursorTo(m_llist->GetSize());
+         m_llist->MoveCursorToEnd();
       else
          m_llist->MoveCursorToEndOfLine();
       break;
       else
          m_llist->MoveCursorToEndOfLine();
       break;