]> git.saurik.com Git - wxWidgets.git/blobdiff - samples/richedit/wxlwindow.cpp
Couple more Unicode fixes.
[wxWidgets.git] / samples / richedit / wxlwindow.cpp
index 0745527116c6e1a093e9865d14652494cb8bfaf9..7a00a5b0ad64366e29ac9cc16c0ade9fd6c368cf 100644 (file)
@@ -95,6 +95,7 @@ BEGIN_EVENT_TABLE(wxLayoutWindow,wxScrolledWindow)
    EVT_LEFT_UP(wxLayoutWindow::OnLeftMouseUp)
    EVT_RIGHT_DOWN(wxLayoutWindow::OnRightMouseClick)
    EVT_LEFT_DCLICK(wxLayoutWindow::OnMouseDblClick)
+   EVT_MIDDLE_DOWN(wxLayoutWindow::OnMiddleMouseDown)
    EVT_MOTION    (wxLayoutWindow::OnMouseMove)
 
    EVT_UPDATE_UI(WXLOWIN_MENU_UNDERLINE, wxLayoutWindow::OnUpdateMenuUnderline)
@@ -139,7 +140,8 @@ wxLayoutWindow::wxLayoutWindow(wxWindow *parent)
                                  wxDefaultPosition, wxDefaultSize,
                                  wxHSCROLL | wxVSCROLL |
                                  wxBORDER |
-                                 wxWANTS_CHARS)
+                                 wxWANTS_CHARS),
+                m_llist(NULL)
 {
    SetStatusBar(NULL); // don't use statusbar
    m_Editable = false;
@@ -151,18 +153,22 @@ wxLayoutWindow::wxLayoutWindow(wxWindow *parent)
    m_bitmap = new wxBitmap(4,4);
    m_bitmapSize = wxPoint(4,4);
    m_llist = new wxLayoutList();
-
+   SetAutoDeleteSelection(false);
    m_BGbitmap = NULL;
    m_ScrollToCursor = false;
    SetWrapMargin(0);
+
+   // initially the list is empty, so why would we need the scrollbars?
+#if 0
    wxPoint max = m_llist->GetSize();
    SetScrollbars(X_SCROLL_PAGE, Y_SCROLL_PAGE,
                  max.x / X_SCROLL_PAGE + 1, max.y / Y_SCROLL_PAGE + 1);
    EnableScrolling(true, true);
    m_maxx = max.x + X_SCROLL_PAGE;
    m_maxy = max.y + Y_SCROLL_PAGE;
+#endif // 0
 
-   // no scrollbars initially (BTW, why then we do all the stuff above?)
+   // no scrollbars initially
    m_hasHScrollbar =
    m_hasVScrollbar = false;
 
@@ -202,6 +208,7 @@ wxLayoutWindow::Clear(int family,
 {
    GetLayoutList()->Clear(family,size,style,weight,underline,fg,bg);
    SetBackgroundColour(GetLayoutList()->GetDefaultStyleInfo().GetBGColour());
+   wxScrolledWindow::Clear();
    ResizeScrollbars(true);
    SetDirty();
    SetModified(false);
@@ -209,6 +216,14 @@ wxLayoutWindow::Clear(int family,
    DoPaint((wxRect *)NULL);
 }
 
+void wxLayoutWindow::Refresh(bool eraseBackground, const wxRect *rect)
+{
+   wxScrolledWindow::Refresh(eraseBackground, rect);
+
+   ResizeScrollbars();
+   ScrollToCursor();
+}
+
 void
 wxLayoutWindow::OnMouse(int eventId, wxMouseEvent& event)
 {
@@ -287,7 +302,16 @@ wxLayoutWindow::OnMouse(int eventId, wxMouseEvent& event)
       case WXLOWIN_MENU_LDOWN:
          {
              // always move cursor to mouse click:
-             m_llist->MoveCursorTo(cursorPos);
+             if ( obj )
+             {
+                // we have found the real position
+                m_llist->MoveCursorTo(cursorPos);
+             }
+             else
+             {
+                // click beyond the end of the text
+                m_llist->MoveCursorToEnd();
+             }
 
              // clicking a mouse removes the selection
              if ( m_llist->HasSelection() )
@@ -340,8 +364,8 @@ wxLayoutWindow::OnMouse(int eventId, wxMouseEvent& event)
          }
          break;
 
-      case WXLOWIN_MENU_RCLICK:
-         // remove the selection if mouse click is outside it (TODO)
+      case WXLOWIN_MENU_MDOWN:
+         Paste(TRUE);
          break;
 
       case WXLOWIN_MENU_DBLCLICK:
@@ -391,6 +415,7 @@ void
 wxLayoutWindow::OnChar(wxKeyEvent& event)
 {
    int keyCode = event.KeyCode();
+   bool ctrlDown = event.ControlDown();
 
 #ifdef WXLAYOUT_DEBUG
    if(keyCode == WXK_F1)
@@ -400,34 +425,36 @@ wxLayoutWindow::OnChar(wxKeyEvent& event)
    }
 #endif
 
-   wxASSERT_MSG( !m_Selecting || event.ShiftDown(),
-                 "m_Selecting is normally reset in OnKeyUp() when Shift "
-                 "goes up!" );
-
-   if ( !m_Selecting && m_llist->HasSelection() )
-   {
-      // pressing any non-arrow key replaces the selection
-      if ( !IsDirectionKey(keyCode) )
-      {
-         m_llist->DeleteSelection();
-      }
-      else if ( !event.ShiftDown() )
-      {
-         m_llist->DiscardSelection();
-      }
-   }
-
+   // Force m_Selecting to be false if shift is no longer
+   // pressed. OnKeyUp() cannot catch all Shift-Up events.
+   if(!event.ShiftDown())
+      m_Selecting = false;
+   
+   // pressing any non-arrow key optionally replaces the selection:
+   if(m_AutoDeleteSelection
+      && !m_Selecting
+      && m_llist->HasSelection() 
+      && ! IsDirectionKey(keyCode)
+      && ! (event.AltDown() || ctrlDown)
+      )
+      m_llist->DeleteSelection();
+   
    // <Shift>+<arrow> starts selection
-   if ( event.ShiftDown() && IsDirectionKey(keyCode) )
+   if ( IsDirectionKey(keyCode) )
    {
       if ( !m_Selecting )
       {
          m_Selecting = true;
          m_llist->StartSelection();
       }
-      //else: just continue the old selection
+      else
+      {
+         // just continue the old selection
+         if(! event.ShiftDown() )
+            m_llist->DiscardSelection();
+      }
    }
-
+   
    // If needed, make cursor visible:
    if(m_CursorVisibility == -1)
       m_CursorVisibility = 1;
@@ -437,7 +464,6 @@ wxLayoutWindow::OnChar(wxKeyEvent& event)
       cursor, etc. It's default will process all keycodes causing
       modifications to the buffer, but only if editing is allowed.
    */
-   bool ctrlDown = event.ControlDown();
    switch(keyCode)
    {
    case WXK_RIGHT:
@@ -472,7 +498,7 @@ wxLayoutWindow::OnChar(wxKeyEvent& event)
       break;
    case WXK_END:
       if ( ctrlDown )
-         m_llist->MoveCursorTo(m_llist->GetSize());
+         m_llist->MoveCursorToEnd();
       else
          m_llist->MoveCursorToEndOfLine();
       break;
@@ -486,7 +512,7 @@ wxLayoutWindow::OnChar(wxKeyEvent& event)
       else if( IsEditable() )
       {
          /* First, handle control keys */
-         if(event.ControlDown() && ! event.AltDown())
+         if(ctrlDown && ! event.AltDown())
          {
             switch(keyCode)
             {
@@ -561,6 +587,18 @@ wxLayoutWindow::OnChar(wxKeyEvent& event)
                   m_llist->WrapLine(m_WrapMargin);
                m_llist->LineBreak();
                break;
+
+            case WXK_TAB:
+               {
+                   // TODO should be configurable
+                   static const int tabSize = 8;
+
+                   CoordType x = m_llist->GetCursorPos().x;
+                   size_t numSpaces = tabSize - x % tabSize;
+                   m_llist->Insert(wxString(' ', numSpaces));
+               }
+               break;
+
             default:
                if((!(event.ControlDown() || event.AltDown() || event.MetaDown()))
                   && (keyCode < 256 && keyCode >= 32)
@@ -622,19 +660,10 @@ wxLayoutWindow::ScrollToCursor(void)
    WXLO_DEBUG(("ScrollToCursor: ViewStart is %d/%d", x0, y0));
 
    // Get the size of the visible window:
-   GetClientSize(&x1,&y1);
+   GetClientSize(&x1, &y1);
 
-   // notice that the client size may be (0, 0)...
-   wxASSERT(x1 >= 0 && y1 >= 0);
-
-   // VZ: I think this is false - if you do it here, ResizeScrollbars() won't
-   //     call SetScrollbars() later
-#if 0
-   // As we have the values anyway, use them to avoid unnecessary scrollbar
-   // updates.
-   if(x1 > m_maxx) m_maxx = x1;
-   if(y1 > m_maxy) m_maxy = y1;
-#endif // 0
+   // update the cursor screen position
+   m_llist->Layout(dc);
 
    // Make sure that the scrollbars are at a position so that the cursor is
    // visible if we are editing
@@ -842,9 +871,12 @@ wxLayoutWindow::InternalPaint(const wxRect *updateRect)
 void
 wxLayoutWindow::OnSize(wxSizeEvent &event)
 {
-    ResizeScrollbars();
+   if ( m_llist )
+   {
+      ResizeScrollbars();
+   }
 
-    event.Skip();
+   event.Skip();
 }
 
 // change the range and position of scrollbars
@@ -887,6 +919,7 @@ wxLayoutWindow::ResizeScrollbars(bool exact)
       m_maxx = max.x + X_SCROLL_PAGE;
       m_maxy = max.y + Y_SCROLL_PAGE;
    }
+#if 0
    else
    {
       // check if the window hasn't become too big, thus making the scrollbars
@@ -905,18 +938,24 @@ wxLayoutWindow::ResizeScrollbars(bool exact)
          m_hasVScrollbar = false;
       }
    }
+#endif
 }
 
 // ----------------------------------------------------------------------------
 // clipboard operations
+//
 // ----------------------------------------------------------------------------
 
 void
-wxLayoutWindow::Paste(void)
+wxLayoutWindow::Paste(bool primary)
 {
    // Read some text
    if (wxTheClipboard->Open())
    {
+#if __WXGTK__
+      if(primary)
+         wxTheClipboard->UsePrimarySelection();
+#endif
 #if wxUSE_PRIVATE_CLIPBOARD_FORMAT
       wxLayoutDataObject wxldo;
       if (wxTheClipboard->IsSupported( wxldo.GetFormat() ))
@@ -939,17 +978,6 @@ wxLayoutWindow::Paste(void)
       }
       wxTheClipboard->Close();
    }
-
-#if 0
-   /* My attempt to get the primary selection, but it does not
-      work. :-( */
-   if(text.Length() == 0)
-   {
-      wxTextCtrl tmp_tctrl(this,-1);
-      tmp_tctrl.Paste();
-      text += tmp_tctrl.GetValue();
-   }
-#endif
 }
 
 bool
@@ -1087,28 +1115,21 @@ void wxLayoutWindow::OnMenu(wxCommandEvent& event)
    switch (event.GetId())
    {
    case WXLOWIN_MENU_LARGER:
-      m_llist->SetFontLarger();
-      break;
+      m_llist->SetFontLarger(); Refresh(FALSE); break;
    case WXLOWIN_MENU_SMALLER:
-      m_llist->SetFontSmaller();
-      break;
-
+      m_llist->SetFontSmaller(); Refresh(FALSE); break;
    case WXLOWIN_MENU_UNDERLINE:
-      m_llist->ToggleFontUnderline();
-      break;
+      m_llist->ToggleFontUnderline(); Refresh(FALSE); break;
    case WXLOWIN_MENU_BOLD:
-      m_llist->ToggleFontWeight();
-      break;
+      m_llist->ToggleFontWeight(); Refresh(FALSE); break;
    case WXLOWIN_MENU_ITALICS:
-      m_llist->ToggleFontItalics();
-      break;
-
+      m_llist->ToggleFontItalics(); Refresh(FALSE); break;
    case WXLOWIN_MENU_ROMAN:
-      m_llist->SetFontFamily(wxROMAN); break;
+      m_llist->SetFontFamily(wxROMAN); Refresh(FALSE); break;
    case WXLOWIN_MENU_TYPEWRITER:
-      m_llist->SetFontFamily(wxFIXED); break;
+      m_llist->SetFontFamily(wxFIXED); Refresh(FALSE); break;
    case WXLOWIN_MENU_SANSSERIF:
-      m_llist->SetFontFamily(wxSWISS); break;
+      m_llist->SetFontFamily(wxSWISS); Refresh(FALSE); break;
    }
 }