From: Karsten Ballüder Date: Tue, 11 May 1999 20:43:12 +0000 (+0000) Subject: COPY works, cut still missing, highlighting buggy. X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/c3ed79361965073ad96e235ca53b93ab55acd511 COPY works, cut still missing, highlighting buggy. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@2419 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/user/wxLayout/wxLayout.cpp b/user/wxLayout/wxLayout.cpp index 74163afbef..4d8d9baf90 100644 --- a/user/wxLayout/wxLayout.cpp +++ b/user/wxLayout/wxLayout.cpp @@ -36,7 +36,7 @@ IMPLEMENT_APP(MyApp) enum ids{ ID_ADD_SAMPLE = 1, ID_CLEAR, ID_PRINT, ID_PRINT_SETUP, ID_PAGE_SETUP, ID_PREVIEW, ID_PRINT_PS, ID_PRINT_SETUP_PS, ID_PAGE_SETUP_PS,ID_PREVIEW_PS, - ID_WRAP, ID_NOWRAP, ID_PASTE, + ID_WRAP, ID_NOWRAP, ID_PASTE, ID_COPY, ID_WXLAYOUT_DEBUG, ID_QUIT, ID_CLICK, ID_HTML, ID_TEXT, ID_TEST, ID_LONG_TEST }; @@ -93,7 +93,8 @@ MyFrame::MyFrame(void) : edit_menu->Append(ID_WRAP, "Wrap mode", "Activate wrapping at pixel 200."); edit_menu->Append(ID_NOWRAP, "No-wrap mode", "Deactivate wrapping."); edit_menu->AppendSeparator(); - edit_menu->Append(ID_PASTE, "Paste", "Paste text from clipboard."); + edit_menu->Append(ID_COPY, "Copy", "Copy text to clipboard."); + edit_menu->Append(ID_PASTE,"Paste", "Paste text from clipboard."); menu_bar->Append(edit_menu, "Edit" ); #ifndef __WXMSW__ @@ -231,6 +232,9 @@ void MyFrame::OnCommand( wxCommandEvent &event ) case ID_PASTE: m_lwin->Paste(); break; + case ID_COPY: + m_lwin->Copy(); + break; case ID_HTML: { wxLayoutExportObject *export; diff --git a/user/wxLayout/wxllist.cpp b/user/wxLayout/wxllist.cpp index 29c0edef54..ed081e8af0 100644 --- a/user/wxLayout/wxllist.cpp +++ b/user/wxLayout/wxllist.cpp @@ -24,10 +24,10 @@ #ifdef M_BASEDIR # include "gui/wxllist.h" -# undef SHOW_SELECTIONS +# define SHOW_SELECTIONS 0 #else # include "wxllist.h" -# define SHOW_SELECTIONS +# define SHOW_SELECTIONS 1 #endif #ifndef USE_PCH @@ -104,12 +104,15 @@ void GrowRect(wxRect &r, CoordType x, CoordType y) r.height = y - r.y; } +#if 0 +// unused /// returns true if the point is in the rectangle static bool Contains(const wxRect &r, const wxPoint &p) { return r.x <= p.x && r.y <= p.y && (r.x+r.width) >= p.x && (r.y + r.height) >= p.y; } +#endif //@} @@ -334,6 +337,8 @@ wxLayoutObjectCmd::Draw(wxDC &dc, wxPoint const & /* coords */, dc.SetFont(*m_font); dc.SetTextForeground(m_ColourFG); dc.SetTextBackground(m_ColourBG); + if(wxllist) + wxllist->SetColour_Internal(&m_ColourFG,& m_ColourBG); } void @@ -456,7 +461,7 @@ wxLayoutLine::FindObjectScreen(wxDC &dc, if( x <= xpos && xpos <= x + width ) { *cxpos = cx + (**i).GetOffsetScreen(dc, xpos-x); - wxLogDebug("wxLayoutLine::FindObjectScreen: cursor xpos = %ld", *cxpos); + WXLO_DEBUG(("wxLayoutLine::FindObjectScreen: cursor xpos = %ld", *cxpos)); if(found) *found = true; return i; } @@ -691,7 +696,7 @@ wxLayoutLine::Draw(wxDC &dc, tempto = (**i).GetLength(); CoordType tmp = from-xpos; if(tmp < 0) tmp = 0; - (**i).Draw(dc, pos, llist, from-xpos, to); + (**i).Draw(dc, pos, llist, from-xpos, tempto); } else { @@ -971,15 +976,76 @@ wxLayoutLine::Debug(void) { wxString tmp; wxPoint pos = GetPosition(); - tmp.Printf("Line %ld, Pos (%ld,%ld), Height %ld", + WXLO_DEBUG(("Line %ld, Pos (%ld,%ld), Height %ld", (long int) GetLineNumber(), (long int) pos.x, (long int) pos.y, - (long int) GetHeight()); - - wxLogDebug(tmp); + (long int) GetHeight())); } #endif +void +wxLayoutLine::Copy(wxLayoutList *llist, + CoordType from, + CoordType to) +{ + CoordType firstOffset, lastOffset; + + if(to == -1) to = GetLength(); + + wxLOiterator first = FindObject(from, &firstOffset); + wxLOiterator last = FindObject(to, &lastOffset); + + // Common special case: only one object + if( *first == *last ) + { + if( (**first).GetType() == WXLO_TYPE_TEXT ) + { + llist->Insert(new wxLayoutObjectText( + ((wxLayoutObjectText + *)*first)->GetText().substr(firstOffset, + lastOffset-firstOffset)) + ); + return; + } + else // what can we do? + { + if(lastOffset > firstOffset) // i.e. +1 :-) + llist->Insert( (**first).Copy() ); + return; + } + } + + // If we reach here, we can safely copy the whole first object from + // the firstOffset position on: + if((**first).GetType() == WXLO_TYPE_TEXT && firstOffset != 0) + { + llist->Insert(new wxLayoutObjectText( + ((wxLayoutObjectText *)*first)->GetText().substr(firstOffset)) + ); + } + else if(firstOffset == 0) + llist->Insert( (**first).Copy() ); + // else nothing to copy :-( + + // Now we copy all objects before the last one: + wxLOiterator i = first; i++; + for( ; i != last; i++) + llist->Insert( (**i).Copy() ); + + // And now the last object: + if(lastOffset != 0) + { + if( (**last).GetType() == WXLO_TYPE_TEXT ) + { + llist->Insert(new wxLayoutObjectText( + ((wxLayoutObjectText *)*last)->GetText().substr(0,lastOffset)) + ); + } + else + llist->Insert( (**last).Copy() ); + } +} + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * The wxLayoutList object @@ -1076,12 +1142,15 @@ wxLayoutList::Clear(int family, int size, int style, int weight, m_FontFamily = family; m_FontStyle = style; m_FontWeight = weight; - if(fg) m_ColourFG = *fg; - if(bg) m_ColourBG = *bg; - - m_ColourFG = *wxBLACK; - m_ColourBG = *wxWHITE; - + if(fg) + m_ColourFG = *fg; + else + m_ColourFG = *wxBLACK; + if(bg) + m_ColourBG = *bg; + else + m_ColourBG = *wxWHITE; + if(m_DefaultSetting) delete m_DefaultSetting; @@ -1429,10 +1498,10 @@ wxLayoutList::Draw(wxDC &dc, m_CursorLine == m_FirstLine)); InvalidateUpdateRect(); - wxLogDebug("Selection is %s : l%d,%ld/%ld,%ld", - m_Selection.m_valid ? "valid" : "invalid", - m_Selection.m_CursorA.x, m_Selection.m_CursorA.y, - m_Selection.m_CursorB.x, m_Selection.m_CursorB.y); + WXLO_DEBUG(("Selection is %s : l%d,%ld/%ld,%ld", + m_Selection.m_valid ? "valid" : "invalid", + m_Selection.m_CursorA.x, m_Selection.m_CursorA.y, + m_Selection.m_CursorB.x, m_Selection.m_CursorB.y)); } wxLayoutObject * @@ -1548,8 +1617,9 @@ wxLayoutList::SetUpdateRect(CoordType x, CoordType y) void wxLayoutList::StartSelection(void) { - wxLogDebug("Starting selection at %ld/%ld", m_CursorPos.x, m_CursorPos.y); + WXLO_DEBUG(("Starting selection at %ld/%ld", m_CursorPos.x, m_CursorPos.y)); m_Selection.m_CursorA = m_CursorPos; + m_Selection.m_CursorB = m_CursorPos; m_Selection.m_selecting = true; m_Selection.m_valid = false; } @@ -1559,7 +1629,7 @@ wxLayoutList::ContinueSelection(void) { wxASSERT(m_Selection.m_selecting == true); wxASSERT(m_Selection.m_valid == false); - wxLogDebug("Continuing selection at %ld/%ld", m_CursorPos.x, m_CursorPos.y); + WXLO_DEBUG(("Continuing selection at %ld/%ld", m_CursorPos.x, m_CursorPos.y)); m_Selection.m_CursorB = m_CursorPos; // We always want m_CursorA <= m_CursorB! if(! (m_Selection.m_CursorA <= m_Selection.m_CursorB)) @@ -1574,7 +1644,7 @@ void wxLayoutList::EndSelection(void) { ContinueSelection(); - wxLogDebug("Ending selection at %ld/%ld", m_CursorPos.x, m_CursorPos.y); + WXLO_DEBUG(("Ending selection at %ld/%ld", m_CursorPos.x, m_CursorPos.y)); m_Selection.m_selecting = false; m_Selection.m_valid = true; } @@ -1641,7 +1711,7 @@ wxLayoutList::IsSelected(const wxLayoutLine *line, CoordType *from, void wxLayoutList::StartHighlighting(wxDC &dc) { -#ifdef SHOW_SELECTIONS +#if SHOW_SELECTIONS dc.SetTextForeground(m_ColourBG); dc.SetTextBackground(m_ColourFG); #endif @@ -1651,17 +1721,76 @@ wxLayoutList::StartHighlighting(wxDC &dc) void wxLayoutList::EndHighlighting(wxDC &dc) { -#ifdef SHOW_SELECTIONS +#if SHOW_SELECTIONS dc.SetTextForeground(m_ColourFG); dc.SetTextBackground(m_ColourBG); #endif } +wxLayoutList * +wxLayoutList::Copy(const wxPoint &from, + const wxPoint &to) +{ + wxLayoutLine + * firstLine = NULL, + * lastLine = NULL; + + for(firstLine = m_FirstLine; + firstLine && firstLine->GetLineNumber() < from.y; + firstLine=firstLine->GetNextLine()) + ; + if(!firstLine || firstLine->GetLineNumber() != from.y) + return NULL; + + for(lastLine = m_FirstLine; + lastLine && lastLine->GetLineNumber() < to.y; + lastLine=lastLine->GetNextLine()) + ; + if(!lastLine || lastLine->GetLineNumber() != to.y) + return NULL; + + if(to <= from) + { + wxLayoutLine *tmp = firstLine; + firstLine = lastLine; + lastLine = tmp; + } + + wxLayoutList *llist = new wxLayoutList(); + + if(firstLine == lastLine) + { + firstLine->Copy(llist, from.x, to.x); + } + else + { + // Extract objects from first line + firstLine->Copy(llist, from.x); + // Extract all lines between + for(wxLayoutLine *line = firstLine->GetNextLine(); + line != lastLine; + line = line->GetNextLine()) + line->Copy(llist); + // Extract objects from last line + lastLine->Copy(llist, 0, to.x); + } + return llist; +} + +wxLayoutList * +wxLayoutList::GetSelection(void) +{ + if(! m_Selection.m_valid) + return NULL; + + return Copy( m_Selection.m_CursorA, m_Selection.m_CursorB ); +} + #ifdef WXLAYOUT_DEBUG void -wxLayoutList::Debug(void) +wxLayoutList::Debug(void) { wxLayoutLine *line; diff --git a/user/wxLayout/wxllist.h b/user/wxLayout/wxllist.h index 03e302cd6c..a3e4cb438f 100644 --- a/user/wxLayout/wxllist.h +++ b/user/wxLayout/wxllist.h @@ -29,7 +29,8 @@ # define WXMENU_LAYOUT_DBLCLICK 1113 #endif -#ifdef __WXDEBUG__ +// do not enable debug mode within Mahogany +#if defined(__WXDEBUG__) && ! defined(M_BASEDIR) # define WXLAYOUT_DEBUG #endif @@ -527,6 +528,15 @@ public: /// Recalculates the position of this line on the canvas. wxPoint RecalculatePosition(wxLayoutList *llist); + /** Copies the contents of this line to another wxLayoutList + @param llist the wxLayoutList destination + @param from x cursor coordinate where to start + @param to x cursor coordinate where to stop, -1 for end of line + */ + void Copy(wxLayoutList *llist, + CoordType from = 0, + CoordType to = -1); + #ifdef WXLAYOUT_DEBUG void Debug(void); #endif @@ -731,9 +741,16 @@ public: /// toggle underline flag inline void SetFontUnderline(bool ul) { SetFont(-1,-1,-1,-1,(int)ul); } /// set font colours by name - inline void SetFontColour(char const *fg, char const *bg = NULL) { SetFont(-1,-1,-1,-1,-1,fg,bg); } + inline void SetFontColour(char const *fg, char const *bg = NULL) + { SetFont(-1,-1,-1,-1,-1,fg,bg); } /// set font colours by colour - inline void SetFontColour(wxColour *fg, wxColour *bg = NULL) { SetFont(-1,-1,-1,-1,-1,fg,bg); } + inline void SetFontColour(wxColour *fg, wxColour *bg = NULL) + { SetFont(-1,-1,-1,-1,-1,fg,bg); } + + + /// Used by wxLayoutObjectCmd only: + void SetColour_Internal(wxColour *fg, wxColour *bg) + { if(fg) m_ColourFG = *fg; if(bg) m_ColourBG = *bg; } /** Returns a pointer to the default settings. This is only valid temporarily and should not be stored @@ -840,6 +857,12 @@ public: bool IsSelecting(void); bool IsSelected(const wxPoint &cursor); + /// Return the selection as a wxLayoutList: + wxLayoutList *GetSelection(void); + + wxLayoutList *Copy(const wxPoint &from = wxPoint(0,0), + const wxPoint &to = wxPoint(-1,-1)); + /// starts highlighting of text for selections void StartHighlighting(wxDC &dc); /// ends highlighting of text for selections diff --git a/user/wxLayout/wxlparser.cpp b/user/wxLayout/wxlparser.cpp index 95268ef08c..eac7dfcb3b 100644 --- a/user/wxLayout/wxlparser.cpp +++ b/user/wxLayout/wxlparser.cpp @@ -148,24 +148,11 @@ wxString wxLayoutExportCmdAsHTML(wxLayoutObjectCmd const & cmd, -wxLayoutExportStatus::wxLayoutExportStatus(wxLayoutList *list, - wxPoint fromPos, - wxPoint toPos) +wxLayoutExportStatus::wxLayoutExportStatus(wxLayoutList *list) { list->GetDefaults()->GetStyle(&m_si); m_line = list->GetFirstLine(); m_iterator = m_line->GetFirstObject(); - m_fromPos = fromPos; - m_toPos = toPos; - - if(m_fromPos.x != -1) - { - while(m_line && m_line->GetLineNumber() != m_fromPos.y) - m_line = m_line->GetNextLine(); - wxASSERT(m_line); - CoordType dummy; - m_iterator = m_line->FindObject(fromPos.x, &dummy); - } } @@ -176,9 +163,6 @@ wxLayoutExportStatus::wxLayoutExportStatus(wxLayoutList *list, && mode == WXLO_EXPORT_AS_HTML)) - -extern const wxPoint wxLayoutExportNoPosition = wxPoint(-1,-1); - wxLayoutExportObject *wxLayoutExport(wxLayoutExportStatus *status, int mode, int flags) { diff --git a/user/wxLayout/wxlparser.h b/user/wxLayout/wxlparser.h index 338dad1b7b..571a8749d9 100644 --- a/user/wxLayout/wxlparser.h +++ b/user/wxLayout/wxlparser.h @@ -53,18 +53,12 @@ struct wxLayoutExportObject }; -extern const wxPoint wxLayoutExportNoPosition; - struct wxLayoutExportStatus { - wxLayoutExportStatus(wxLayoutList *list, - wxPoint fromPos = wxLayoutExportNoPosition, - wxPoint toPos = wxLayoutExportNoPosition); + wxLayoutExportStatus(wxLayoutList *list); wxLayoutLine * m_line; wxLOiterator m_iterator; wxLayoutStyleInfo m_si; - wxPoint m_fromPos; - wxPoint m_toPos; }; #ifdef OS_WIN diff --git a/user/wxLayout/wxlwindow.cpp b/user/wxLayout/wxlwindow.cpp index 001baa5e6f..a0b37cb1c4 100644 --- a/user/wxLayout/wxlwindow.cpp +++ b/user/wxLayout/wxlwindow.cpp @@ -43,6 +43,12 @@ #include +#ifdef WXLAYOUT_DEBUG +# define WXLO_DEBUG(x) wxLogDebug x +#else +# define WXLO_DEBUG(x) +#endif + /// offsets to put a nice frame around text #define WXLO_XOFFSET 4 #define WXLO_YOFFSET 4 @@ -364,7 +370,50 @@ wxLayoutWindow::OnKeyUp(wxKeyEvent& event) m_llist->EndSelection(); event.Skip(); } - + + +void +wxLayoutWindow::ScrollToCursor(void) +{ + wxClientDC dc( this ); + PrepareDC( dc ); + + int x0,y0,x1,y1, dx, dy; + + // Calculate where the top of the visible area is: + ViewStart(&x0,&y0); + GetScrollPixelsPerUnit(&dx, &dy); + x0 *= dx; y0 *= dy; + + // Get the size of the visible window: + GetClientSize(&x1,&y1); + wxASSERT(x1 > 0); + wxASSERT(y1 > 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; + /* Make sure that the scrollbars are at a position so that the + cursor is visible if we are editing. */ + /** Scroll so that cursor is visible! */ + WXLO_DEBUG(("m_ScrollToCursor = %d", (int) m_ScrollToCursor)); + if(IsEditable() && m_ScrollToCursor) + { + wxPoint cc = m_llist->GetCursorScreenPos(*m_memDC); + if(cc.x < x0 || cc.y < y0 + || cc.x >= x0+(9*x1)/10 || cc.y >= y0+(9*y1/10)) // (9*x)/10 == 90% + { + int nx, ny; + nx = cc.x - x1/2; if(nx < 0) nx = 0; + ny = cc.y - y1/2; if(ny < 0) ny = 0; + Scroll(nx/dx,ny/dy); // new view start + x0 = nx; y0 = ny; + m_ScrollToCursor = false; // avoid recursion + Refresh(FALSE); /// Re-entering this function! + } + } +} + void wxLayoutWindow::OnPaint( wxPaintEvent &WXUNUSED(event)) // or: OnDraw(wxDC& dc) { @@ -407,8 +456,10 @@ wxLayoutWindow::InternalPaint(const wxRect *updateRect) //m_llist->InvalidateUpdateRect(); //const wxRect *r = m_llist->GetUpdateRect(); - wxLogDebug("Update rect: %ld,%ld / %ld,%ld", - updateRect->x, updateRect->y, updateRect->x+updateRect->width, updateRect->y+updateRect->height); + WXLO_DEBUG(("Update rect: %ld,%ld / %ld,%ld", + updateRect->x, updateRect->y, + updateRect->x+updateRect->width, + updateRect->y+updateRect->height)); #if 0 //FIXME: we should never need to call Layout at all because the @@ -428,25 +479,6 @@ wxLayoutWindow::InternalPaint(const wxRect *updateRect) if(IsDirty()) ResizeScrollbars(); - /* Make sure that the scrollbars are at a position so that the - cursor is visible if we are editing. */ - /** Scroll so that cursor is visible! */ - wxLogDebug("m_ScrollToCursor = %d", (int) m_ScrollToCursor); - if(IsEditable() && m_ScrollToCursor) - { - wxPoint cc = m_llist->GetCursorScreenPos(*m_memDC); - if(cc.x < x0 || cc.y < y0 - || cc.x >= x0+(9*x1)/10 || cc.y >= y0+(9*y1/10)) // (9*x)/10 == 90% - { - int nx, ny; - nx = cc.x - x1/2; if(nx < 0) nx = 0; - ny = cc.y - y1/2; if(ny < 0) ny = 0; - Scroll(nx/dx,ny/dy); // new view start - x0 = nx; y0 = ny; - m_ScrollToCursor = false; // avoid recursion - Refresh(FALSE); /// Re-entering this function! - } - } /* Check whether the window has grown, if so, we need to reallocate the bitmap to be larger. */ @@ -492,8 +524,10 @@ wxLayoutWindow::InternalPaint(const wxRect *updateRect) /* This is the important bit: we tell the list to draw itself: */ - wxLogDebug("Update rect: %ld,%ld / %ld,%ld", - updateRect->x, updateRect->y, updateRect->x+updateRect->width, updateRect->y+updateRect->height); + WXLO_DEBUG(("Update rect: %ld,%ld / %ld,%ld", + updateRect->x, updateRect->y, + updateRect->x+updateRect->width, + updateRect->y+updateRect->height)); wxPoint offset(-x0+WXLO_XOFFSET,-y0+WXLO_YOFFSET); m_llist->Draw(*m_memDC,offset, y0, y0+y1); @@ -512,8 +546,8 @@ wxLayoutWindow::InternalPaint(const wxRect *updateRect) if(ri) while(ri) { - wxLogDebug("UpdateRegion: %ld,%ld, %ld,%ld", - ri.GetX(),ri.GetY(),ri.GetW(),ri.GetH()); + WXLO_DEBUG(("UpdateRegion: %ld,%ld, %ld,%ld", + ri.GetX(),ri.GetY(),ri.GetW(),ri.GetH())); dc.Blit(x0+ri.GetX(),y0+ri.GetY(),ri.GetW(),ri.GetH(), m_memDC,ri.GetX(),ri.GetY(),wxCOPY,FALSE); ri++; @@ -584,6 +618,34 @@ wxLayoutWindow::Paste(void) wxLayoutImportText( m_llist, text); } +bool +wxLayoutWindow::Copy(void) +{ + wxLayoutList *llist = m_llist->GetSelection(); + if(! llist) + return FALSE; + + wxString text; + wxLayoutExportObject *export; + wxLayoutExportStatus status(llist); + while((export = wxLayoutExport( &status, WXLO_EXPORT_AS_TEXT)) != NULL) + { + if(export->type == WXLO_EXPORT_TEXT) + text << *(export->content.text); + delete export; + } + delete llist; + + // Read some text + if (wxTheClipboard->Open()) + { + wxTextDataObject *data = new wxTextDataObject( text ); + bool rc = wxTheClipboard->SetData( data ); + wxTheClipboard->Close(); + return rc; + } + return FALSE; +} wxMenu * wxLayoutWindow::MakeFormatMenu() diff --git a/user/wxLayout/wxlwindow.h b/user/wxLayout/wxlwindow.h index ff019ed254..e8cb71b4d8 100644 --- a/user/wxLayout/wxlwindow.h +++ b/user/wxLayout/wxlwindow.h @@ -93,6 +93,8 @@ public: bool IsEditable(void) const { return m_Editable; } /// Pastes text from clipboard. void Paste(void); + /// Copies selection to clipboard. + bool Copy(void); //@} @@ -160,7 +162,8 @@ public: protected: /// generic function for mouse events processing void OnMouse(int eventId, wxMouseEvent& event); - + /// as the name says + void ScrollToCursor(void); /// for sending events wxWindow *m_Parent; /// Shall we send events?