COPY works, cut still missing, highlighting buggy.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@2419 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Karsten Ballüder 1999-05-11 20:43:12 +00:00
parent f924129679
commit c3ed793619
7 changed files with 279 additions and 80 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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)
{

View File

@ -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

View File

@ -43,6 +43,12 @@
#include <ctype.h>
#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()

View File

@ -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?