Many, many updates. Almost perfect.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@2476 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Karsten Ballüder
1999-05-16 23:10:40 +00:00
parent b985763280
commit 47e1663e82
7 changed files with 412 additions and 77 deletions

View File

@@ -16,8 +16,8 @@ BUGS
TODO TODO
===================================================================== =====================================================================
Inserting NL in empty line sometimes doesn't move cursor down. - UNDO!!
Line numbers go a bit berserk, too. :-) - replacement of llist in window
The following two probs can probably be fixed by adding the The following two probs can probably be fixed by adding the
RecalculateLayout() method: RecalculateLayout() method:
@@ -25,11 +25,8 @@ RecalculateLayout() method:
Printing works again, but layout at begin of new page is corrupted. Printing works again, but layout at begin of new page is corrupted.
Selections: - The import of a private data object does not work yet, we need to get
- moving in negative direction doesn't work the objects back from the string.
- selection state not properly reset, only works once
- selecting non-text objects is strange
- Changing default settings in Clear() or changing/inserting/deleting - Changing default settings in Clear() or changing/inserting/deleting
a wxLayoutObject needs to update the m_StyleInfo in all lines, only a wxLayoutObject needs to update the m_StyleInfo in all lines, only
then can we start using that one. then can we start using that one.
@@ -39,8 +36,6 @@ Selections:
some code bits are commented out in wxlwindow.cpp some code bits are commented out in wxlwindow.cpp
offset handling seems a bit dodgy, white shadow to top/left of cursor offset handling seems a bit dodgy, white shadow to top/left of cursor
- replacement of llist in window
- UNDO
- DragNDrop - DragNDrop
- Update docs, do full rtf/html editing. - Update docs, do full rtf/html editing.

View File

@@ -126,7 +126,7 @@ MyFrame::AddSampleText(wxLayoutList *llist)
llist->SetFont(wxROMAN,16,wxNORMAL,wxNORMAL, false); llist->SetFont(wxROMAN,16,wxNORMAL,wxNORMAL, false);
llist->Insert("--"); llist->Insert("--");
llist->LineBreak(); llist->LineBreak();
llist->SetFont(wxROMAN); llist->SetFont(wxROMAN);
llist->Insert("The quick brown fox jumps over the lazy dog."); llist->Insert("The quick brown fox jumps over the lazy dog.");
llist->LineBreak(); llist->LineBreak();

View File

@@ -24,6 +24,7 @@
#ifdef M_BASEDIR #ifdef M_BASEDIR
# include "gui/wxllist.h" # include "gui/wxllist.h"
# include "gui/wxlparser.h"
# define SHOW_SELECTIONS 1 # define SHOW_SELECTIONS 1
#else #else
# include "wxllist.h" # include "wxllist.h"
@@ -37,6 +38,7 @@
# include <wx/dcps.h> # include <wx/dcps.h>
# include <wx/print.h> # include <wx/print.h>
# include <wx/log.h> # include <wx/log.h>
# include <wx/filefn.h>
#endif #endif
#include <ctype.h> #include <ctype.h>
@@ -118,6 +120,45 @@ bool Contains(const wxRect &r, const wxPoint &p)
//@} //@}
void ReadString(wxString &to, wxString &from)
{
to = "";
const char *cptr = from.c_str();
while(*cptr && *cptr != '\n')
to += *cptr++;
if(*cptr) cptr++;
from = cptr;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
wxLayoutObject
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* static */
wxLayoutObject *
wxLayoutObject::Read(wxString &istr)
{
wxString tmp;
ReadString(tmp, istr);
int type = -1;
sscanf(tmp.c_str(),"%d", &type);
switch(type)
{
case WXLO_TYPE_TEXT:
return wxLayoutObjectText::Read(istr);
case WXLO_TYPE_CMD:
return wxLayoutObjectCmd::Read(istr);
case WXLO_TYPE_ICON:
return wxLayoutObjectIcon::Read(istr);
default:
return NULL;
}
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
wxLayoutObjectText wxLayoutObjectText
@@ -145,6 +186,23 @@ wxLayoutObjectText::Copy(void)
return obj; return obj;
} }
void
wxLayoutObjectText::Write(wxString &ostr)
{
ostr << (int) WXLO_TYPE_TEXT << '\n'
<< m_Text << '\n';
}
/* static */
wxLayoutObjectText *
wxLayoutObjectText::Read(wxString &istr)
{
wxString text;
ReadString(text, istr);
return new wxLayoutObjectText(text);
}
wxPoint wxPoint
wxLayoutObjectText::GetSize(CoordType *top, CoordType *bottom) const wxLayoutObjectText::GetSize(CoordType *top, CoordType *bottom) const
{ {
@@ -158,7 +216,7 @@ wxLayoutObjectText::Draw(wxDC &dc, wxPoint const &coords,
wxLayoutList *wxllist, wxLayoutList *wxllist,
CoordType begin, CoordType end) CoordType begin, CoordType end)
{ {
if(begin == -1) if( end <= 0)
dc.DrawText(m_Text, coords.x, coords.y-m_Top); dc.DrawText(m_Text, coords.x, coords.y-m_Top);
else else
{ {
@@ -168,6 +226,10 @@ wxLayoutObjectText::Draw(wxDC &dc, wxPoint const &coords,
xpos = coords.x, xpos = coords.x,
ypos = coords.y-m_Top; ypos = coords.y-m_Top;
long width, height, descent; long width, height, descent;
if(begin < 0) begin = 0;
if(end > m_Text.Length()) end = m_Text.Length();
str = m_Text.Mid(0, begin); str = m_Text.Mid(0, begin);
dc.DrawText(str, xpos, ypos); dc.DrawText(str, xpos, ypos);
@@ -219,6 +281,7 @@ wxLayoutObjectText::Layout(wxDC &dc, class wxLayoutList * )
m_Top = m_Height - m_Bottom; m_Top = m_Height - m_Bottom;
} }
#ifdef WXLAYOUT_DEBUG #ifdef WXLAYOUT_DEBUG
void void
wxLayoutObjectText::Debug(void) wxLayoutObjectText::Debug(void)
@@ -239,6 +302,38 @@ wxLayoutObjectIcon::wxLayoutObjectIcon(wxBitmap const &icon)
m_Icon = new wxBitmap(icon); m_Icon = new wxBitmap(icon);
} }
void
wxLayoutObjectIcon::Write(wxString &ostr)
{
/* Exports icon through a temporary file. */
wxString file = wxGetTempFileName("wxloexport");
ostr << WXLO_TYPE_ICON << '\n'
<< file << '\n';
m_Icon->SaveFile(file, WXLO_BITMAP_FORMAT);
}
/* static */
wxLayoutObjectIcon *
wxLayoutObjectIcon::Read(wxString &istr)
{
wxString file;
ReadString(file, istr);
if(! wxFileExists(file))
return NULL;
wxLayoutObjectIcon *obj = new wxLayoutObjectIcon;
if(!obj->m_Icon->LoadFile(file, WXLO_BITMAP_FORMAT))
{
delete obj;
return NULL;
}
else
return obj;
}
wxLayoutObject * wxLayoutObject *
wxLayoutObjectIcon::Copy(void) wxLayoutObjectIcon::Copy(void)
{ {
@@ -351,6 +446,76 @@ wxLayoutObjectCmd::Copy(void)
return obj; return obj;
} }
void
wxLayoutObjectCmd::Write(wxString &ostr)
{
ostr << WXLO_TYPE_CMD << '\n'
<< m_StyleInfo->size << '\n'
<< m_StyleInfo->family << '\n'
<< m_StyleInfo->style << '\n'
<< m_StyleInfo->weight << '\n'
<< m_StyleInfo->underline << '\n'
<< m_StyleInfo->m_fg_valid << '\n'
<< m_StyleInfo->m_bg_valid << '\n';
if(m_StyleInfo->m_fg_valid)
{
ostr << m_StyleInfo->m_fg.Red() << '\n'
<< m_StyleInfo->m_fg.Green() << '\n'
<< m_StyleInfo->m_fg.Blue() << '\n';
}
if(m_StyleInfo->m_bg_valid)
{
ostr << m_StyleInfo->m_bg.Red() << '\n'
<< m_StyleInfo->m_bg.Green() << '\n'
<< m_StyleInfo->m_bg.Blue() << '\n';
}
}
/* static */
wxLayoutObjectCmd *
wxLayoutObjectCmd::Read(wxString &istr)
{
wxLayoutObjectCmd *obj = new wxLayoutObjectCmd;
wxString tmp;
ReadString(tmp, istr);
sscanf(tmp.c_str(),"%d", &obj->m_StyleInfo->size);
ReadString(tmp, istr);
sscanf(tmp.c_str(),"%d", &obj->m_StyleInfo->family);
ReadString(tmp, istr);
sscanf(tmp.c_str(),"%d", &obj->m_StyleInfo->style);
ReadString(tmp, istr);
sscanf(tmp.c_str(),"%d", &obj->m_StyleInfo->weight);
ReadString(tmp, istr);
sscanf(tmp.c_str(),"%d", &obj->m_StyleInfo->underline);
ReadString(tmp, istr);
sscanf(tmp.c_str(),"%d", &obj->m_StyleInfo->m_fg_valid);
ReadString(tmp, istr);
sscanf(tmp.c_str(),"%d", &obj->m_StyleInfo->m_bg_valid);
if(obj->m_StyleInfo->m_fg_valid)
{
int red, green, blue;
ReadString(tmp, istr);
sscanf(tmp.c_str(),"%d", &red);
ReadString(tmp, istr);
sscanf(tmp.c_str(),"%d", &green);
ReadString(tmp, istr);
sscanf(tmp.c_str(),"%d", &blue);
obj->m_StyleInfo->m_fg = wxColour(red, green, blue);
}
if(obj->m_StyleInfo->m_bg_valid)
{
int red, green, blue;
ReadString(tmp, istr);
sscanf(tmp.c_str(),"%d", &red);
ReadString(tmp, istr);
sscanf(tmp.c_str(),"%d", &green);
ReadString(tmp, istr);
sscanf(tmp.c_str(),"%d", &blue);
obj->m_StyleInfo->m_bg = wxColour(red, green, blue);
}
return obj;
}
wxLayoutObjectCmd::~wxLayoutObjectCmd() wxLayoutObjectCmd::~wxLayoutObjectCmd()
{ {
@@ -765,6 +930,7 @@ wxLayoutLine::Draw(wxDC &dc,
{ {
// parts of the line need highlighting // parts of the line need highlighting
tempto = xpos+(**i).GetLength(); tempto = xpos+(**i).GetLength();
#if 0
if(tempto >= from && xpos <= to) if(tempto >= from && xpos <= to)
{ {
tempto = to-xpos; tempto = to-xpos;
@@ -772,13 +938,16 @@ wxLayoutLine::Draw(wxDC &dc,
tempto = (**i).GetLength(); tempto = (**i).GetLength();
CoordType tmp = from-xpos; CoordType tmp = from-xpos;
if(tmp < 0) tmp = 0; if(tmp < 0) tmp = 0;
(**i).Draw(dc, pos, llist, from-xpos, tempto); #endif
(**i).Draw(dc, pos, llist, from-xpos, to-xpos);
#if 0
} }
else else
{ {
llist->EndHighlighting(dc); // FIXME! inefficient llist->EndHighlighting(dc); // FIXME! inefficient
(**i).Draw(dc, pos, llist); (**i).Draw(dc, pos, llist);
} }
#endif
} }
else else
(**i).Draw(dc, pos, llist); (**i).Draw(dc, pos, llist);
@@ -916,8 +1085,11 @@ wxLayoutLine::Break(CoordType xpos, wxLayoutList *llist)
wxASSERT(xpos >= 0); wxASSERT(xpos >= 0);
//FIXME: this could be optimised, for now be prudent: //FIXME: this could be optimised, for now be prudent:
m_Dirty = true; m_Dirty = true;
if(xpos == 0) /* If we are at the begin of a line, we want to move all other
lines down and stay with the cursor where we are. However, if we
are in an empty line, we want to move down with it. */
if(xpos == 0 && GetLength() > 0)
{ // insert an empty line before this one { // insert an empty line before this one
wxLayoutLine *prev = new wxLayoutLine(m_Previous, llist); wxLayoutLine *prev = new wxLayoutLine(m_Previous, llist);
if(m_Previous == NULL) if(m_Previous == NULL)
@@ -925,12 +1097,11 @@ wxLayoutLine::Break(CoordType xpos, wxLayoutList *llist)
// before this. // before this.
prev->m_Next = this; prev->m_Next = this;
m_Previous = prev; m_Previous = prev;
m_Previous->m_Height = GetHeight(); // this is a wild guess m_Previous->m_Height = 0; // this is a wild guess
} }
MoveLines(+1);
if(m_Next) if(m_Next)
m_Next->RecalculatePositions(1, llist); m_Next->RecalculatePositions(1, llist);
return this; return m_Previous;
} }
CoordType offset; CoordType offset;
@@ -1127,6 +1298,7 @@ wxLayoutLine::Copy(wxLayoutList *llist,
} }
} }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
The wxLayoutList object The wxLayoutList object
@@ -1398,6 +1570,29 @@ wxLayoutList::Insert(wxLayoutObject *obj)
return true; return true;
} }
bool
wxLayoutList::Insert(wxLayoutList *llist)
{
wxASSERT(llist);
bool rc = TRUE;
for(wxLayoutLine *line = llist->GetFirstLine();
line;
line = line->GetNextLine()
)
{
for(wxLOiterator i = line->GetFirstObject();
i != NULLIT;
i++)
rc |= Insert(*i);
LineBreak();
}
return rc;
}
bool bool
wxLayoutList::LineBreak(void) wxLayoutList::LineBreak(void)
{ {
@@ -1408,7 +1603,8 @@ wxLayoutList::LineBreak(void)
m_CursorLine = m_CursorLine->Break(m_CursorPos.x, this); m_CursorLine = m_CursorLine->Break(m_CursorPos.x, this);
if(setFirst) // we were at beginning of first line if(setFirst) // we were at beginning of first line
m_FirstLine = m_CursorLine->GetPreviousLine(); m_FirstLine = m_CursorLine->GetPreviousLine();
m_CursorPos.y++; if(m_CursorPos.x != 0)
m_CursorPos.y++;
m_CursorPos.x = 0; m_CursorPos.x = 0;
// doesn't help m_CursorLine.MarkDirty(); // doesn't help m_CursorLine.MarkDirty();
m_CursorLine->RecalculatePositions(true, this); //FIXME needed? m_CursorLine->RecalculatePositions(true, this); //FIXME needed?
@@ -1560,10 +1756,10 @@ wxLayoutList::Layout(wxDC &dc, CoordType bottom, bool forceAll)
(wxPoint *)&m_CursorSize, m_CursorPos.x); (wxPoint *)&m_CursorSize, m_CursorPos.x);
else else
line->Layout(dc, this); line->Layout(dc, this);
line->RecalculatePosition(this);
// little condition to speed up redrawing: // little condition to speed up redrawing:
if(bottom != -1 && line->GetPosition().y > bottom) break; if(bottom != -1 && line->GetPosition().y > bottom) break;
} }
line->RecalculatePosition(this);
line = line->GetNextLine(); line = line->GetNextLine();
} }
@@ -1596,6 +1792,8 @@ wxLayoutList::Draw(wxDC &dc,
// only draw if between top and bottom: // only draw if between top and bottom:
if((top == -1 || line->GetPosition().y + line->GetHeight() >= top)) if((top == -1 || line->GetPosition().y + line->GetHeight() >= top))
line->Draw(dc, this, offset); line->Draw(dc, this, offset);
else
line->Layout(dc, this);
// little condition to speed up redrawing: // little condition to speed up redrawing:
if(bottom != -1 && line->GetPosition().y > bottom) break; if(bottom != -1 && line->GetPosition().y > bottom) break;
line = line->GetNextLine(); line = line->GetNextLine();
@@ -1720,22 +1918,29 @@ wxLayoutList::SetUpdateRect(CoordType x, CoordType y)
} }
void void
wxLayoutList::StartSelection(void) wxLayoutList::StartSelection(wxPoint cpos)
{ {
WXLO_DEBUG(("Starting selection at %ld/%ld", m_CursorPos.x, m_CursorPos.y)); if(cpos.x == -1)
m_Selection.m_CursorA = m_CursorPos; cpos = m_CursorPos;
m_Selection.m_CursorB = m_CursorPos; WXLO_DEBUG(("Starting selection at %ld/%ld", cpos.x, cpos.y));
m_Selection.m_CursorA = cpos;
m_Selection.m_CursorB = cpos;
m_Selection.m_selecting = true; m_Selection.m_selecting = true;
m_Selection.m_valid = false; m_Selection.m_valid = false;
} }
void void
wxLayoutList::ContinueSelection(void) wxLayoutList::ContinueSelection(wxPoint cpos)
{ {
if(cpos.x == -1)
cpos = m_CursorPos;
wxASSERT(m_Selection.m_selecting == true); wxASSERT(m_Selection.m_selecting == true);
wxASSERT(m_Selection.m_valid == false); wxASSERT(m_Selection.m_valid == false);
WXLO_DEBUG(("Continuing selection at %ld/%ld", m_CursorPos.x, m_CursorPos.y)); WXLO_DEBUG(("Continuing selection at %ld/%ld", cpos.x, cpos.y));
m_Selection.m_CursorB = m_CursorPos; if(m_Selection.m_CursorB <= cpos)
m_Selection.m_CursorB = cpos;
else
m_Selection.m_CursorA = cpos;
// We always want m_CursorA <= m_CursorB! // We always want m_CursorA <= m_CursorB!
if(! (m_Selection.m_CursorA <= m_Selection.m_CursorB)) if(! (m_Selection.m_CursorA <= m_Selection.m_CursorB))
{ {
@@ -1746,10 +1951,12 @@ wxLayoutList::ContinueSelection(void)
} }
void void
wxLayoutList::EndSelection(void) wxLayoutList::EndSelection(wxPoint cpos)
{ {
ContinueSelection(); if(cpos.x == -1)
WXLO_DEBUG(("Ending selection at %ld/%ld", m_CursorPos.x, m_CursorPos.y)); cpos = m_CursorPos;
ContinueSelection(cpos);
WXLO_DEBUG(("Ending selection at %ld/%ld", cpos.x, cpos.y));
m_Selection.m_selecting = false; m_Selection.m_selecting = false;
m_Selection.m_valid = true; m_Selection.m_valid = true;
} }
@@ -1943,7 +2150,7 @@ wxLayoutList::Copy(const wxPoint &from,
} }
wxLayoutList * wxLayoutList *
wxLayoutList::GetSelection(void) wxLayoutList::GetSelection(wxLayoutDataObject *wxlo, bool invalidate)
{ {
if(! m_Selection.m_valid) if(! m_Selection.m_valid)
{ {
@@ -1953,8 +2160,28 @@ wxLayoutList::GetSelection(void)
return NULL; return NULL;
} }
m_Selection.m_valid = false; if(invalidate) m_Selection.m_valid = false;
return Copy( m_Selection.m_CursorA, m_Selection.m_CursorB );
wxLayoutList *llist = Copy( m_Selection.m_CursorA,
m_Selection.m_CursorB );
if(wxlo) // export as data object, too
{
wxString string;
wxLayoutExportObject *export;
wxLayoutExportStatus status(llist);
while((export = wxLayoutExport( &status, WXLO_EXPORT_AS_OBJECTS)) != NULL)
{
if(export->type == WXLO_EXPORT_EMPTYLINE)
; //FIXME missing support for linebreaks in string format
else
export->content.object->Write(string);
delete export;
}
wxlo->SetData(string.c_str(), string.Length()+1);
}
return llist;
} }

View File

@@ -21,6 +21,7 @@
#include "wx/printdlg.h" #include "wx/printdlg.h"
#include "wx/generic/printps.h" #include "wx/generic/printps.h"
#include "wx/generic/prntdlgg.h" #include "wx/generic/prntdlgg.h"
#include "wx/dataobj.h"
// skip the following defines if embedded in M application // skip the following defines if embedded in M application
#ifndef M_BASEDIR #ifndef M_BASEDIR
@@ -46,6 +47,12 @@
# define WXLO_DEFAULTFONTSIZE 12 # define WXLO_DEFAULTFONTSIZE 12
#endif #endif
#ifdef __WXMSW__
# define WXLO_BITMAP_FORMAT wxBITMAP_TYPE_BMP
#else
# define WXLO_BITMAP_FORMAT wxBITMAP_TYPE_PNG
#endif
/// Types of currently supported layout objects. /// Types of currently supported layout objects.
enum wxLayoutObjectType enum wxLayoutObjectType
@@ -160,7 +167,8 @@ public:
if(m_UserData) if(m_UserData)
m_UserData->DecRef(); m_UserData->DecRef();
m_UserData = data; m_UserData = data;
m_UserData->IncRef(); if(m_UserData)
m_UserData->IncRef();
} }
/** Return the user data. */ /** Return the user data. */
@@ -169,6 +177,18 @@ public:
/** Makes a copy of this object. /** Makes a copy of this object.
*/ */
virtual wxLayoutObject *Copy(void) = 0; virtual wxLayoutObject *Copy(void) = 0;
/** Clipboard support function. Read and write objects to
strings. */
//@{
/// Writes the object to the string.
virtual void Write(wxString &ostr) = 0;
/** Reads an object.
@param str stream to read from, will bee changed
@return true on success
*/
static wxLayoutObject *Read(wxString &istr);
//@}
protected: protected:
/// optional data for application's use /// optional data for application's use
UserData *m_UserData; UserData *m_UserData;
@@ -192,8 +212,8 @@ KBLIST_DEFINE(wxLayoutObjectList, wxLayoutObject);
class wxLayoutObjectText : public wxLayoutObject class wxLayoutObjectText : public wxLayoutObject
{ {
public: public:
wxLayoutObjectText(const wxString &txt); wxLayoutObjectText(const wxString &txt = "");
virtual wxLayoutObjectType GetType(void) const { return WXLO_TYPE_TEXT; } virtual wxLayoutObjectType GetType(void) const { return WXLO_TYPE_TEXT; }
virtual void Layout(wxDC &dc, class wxLayoutList *llist); virtual void Layout(wxDC &dc, class wxLayoutList *llist);
virtual void Draw(wxDC &dc, wxPoint const &coords, virtual void Draw(wxDC &dc, wxPoint const &coords,
@@ -216,6 +236,8 @@ public:
*/ */
virtual CoordType GetOffsetScreen(wxDC &dc, CoordType xpos) const; virtual CoordType GetOffsetScreen(wxDC &dc, CoordType xpos) const;
virtual void Write(wxString &ostr);
static wxLayoutObjectText *Read(wxString &istr);
#ifdef WXLAYOUT_DEBUG #ifdef WXLAYOUT_DEBUG
virtual void Debug(void); virtual void Debug(void);
@@ -249,10 +271,10 @@ private:
class wxLayoutObjectIcon : public wxLayoutObject class wxLayoutObjectIcon : public wxLayoutObject
{ {
public: public:
wxLayoutObjectIcon(wxBitmap *icon); wxLayoutObjectIcon(wxBitmap *icon = NULL);
wxLayoutObjectIcon(wxBitmap const &icon); wxLayoutObjectIcon(wxBitmap const &icon);
~wxLayoutObjectIcon() { delete m_Icon; } ~wxLayoutObjectIcon() { if(m_Icon) delete m_Icon; }
virtual wxLayoutObjectType GetType(void) const { return WXLO_TYPE_ICON; } virtual wxLayoutObjectType GetType(void) const { return WXLO_TYPE_ICON; }
virtual void Layout(wxDC &dc, class wxLayoutList *llist); virtual void Layout(wxDC &dc, class wxLayoutList *llist);
@@ -274,6 +296,8 @@ public:
/** Makes a copy of this object. /** Makes a copy of this object.
*/ */
virtual wxLayoutObject *Copy(void); virtual wxLayoutObject *Copy(void);
virtual void Write(wxString &ostr);
static wxLayoutObjectIcon *Read(wxString &istr);
private: private:
wxBitmap *m_Icon; wxBitmap *m_Icon;
}; };
@@ -299,7 +323,7 @@ struct wxLayoutStyleInfo
int size, family, style, weight, underline; int size, family, style, weight, underline;
/// Colours /// Colours
wxColour m_bg, m_fg; wxColour m_bg, m_fg;
bool m_fg_valid, m_bg_valid; int m_fg_valid, m_bg_valid; // bool, but must be int!
}; };
@@ -376,6 +400,8 @@ public:
/** Makes a copy of this object. /** Makes a copy of this object.
*/ */
virtual wxLayoutObject *Copy(void); virtual wxLayoutObject *Copy(void);
virtual void Write(wxString &ostr);
static wxLayoutObjectCmd *Read(wxString &istr);
private: private:
wxLayoutStyleInfo *m_StyleInfo; wxLayoutStyleInfo *m_StyleInfo;
}; };
@@ -732,6 +758,9 @@ public:
bool Insert(wxString const &text); bool Insert(wxString const &text);
/// Insert some other object at current cursor position. /// Insert some other object at current cursor position.
bool Insert(wxLayoutObject *obj); bool Insert(wxLayoutObject *obj);
/// Inserts objects at current cursor positions
bool Insert(wxLayoutList *llist);
/// Inserts a linebreak at current cursor position. /// Inserts a linebreak at current cursor position.
bool LineBreak(void); bool LineBreak(void);
/** Wraps the current line. Searches to the left of the cursor to /** Wraps the current line. Searches to the left of the cursor to
@@ -925,23 +954,26 @@ public:
//@} //@}
/// Begin selecting text. /// Begin selecting text.
void StartSelection(void); void StartSelection(wxPoint cpos = wxPoint(-1,-1));
// Continue selecting text // Continue selecting text
void ContinueSelection(void); void ContinueSelection(wxPoint cpos = wxPoint(-1,-1));
/// End selecting text. /// End selecting text.
void EndSelection(void); void EndSelection(wxPoint cpos = wxPoint(-1,-1));
/// Are we still selecting text? /// Are we still selecting text?
bool IsSelecting(void); bool IsSelecting(void);
bool IsSelected(const wxPoint &cursor); bool IsSelected(const wxPoint &cursor);
/// Return the selection as a wxLayoutList: /** Return the selection as a wxLayoutList.
wxLayoutList *GetSelection(void); @param invalidate if true, the selection will be invalidated after this and can no longer be used.
@return Another layout list object holding the selection, must be freed by caller
*/
wxLayoutList *GetSelection(class wxLayoutDataObject *wxldo = NULL, bool invalidate = TRUE);
/// Delete selected bit /// Delete selected bit
void DeleteSelection(void); void DeleteSelection(void);
wxLayoutList *Copy(const wxPoint &from = wxPoint(0,0), wxLayoutList *Copy(const wxPoint &from = wxPoint(0,0),
const wxPoint &to = wxPoint(-1,-1)); const wxPoint &to = wxPoint(-1,-1));
/// starts highlighting of text for selections /// starts highlighting of text for selections
void StartHighlighting(wxDC &dc); void StartHighlighting(wxDC &dc);
/// ends highlighting of text for selections /// ends highlighting of text for selections
@@ -1007,7 +1039,21 @@ private:
}; };
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
The wxLayoutDataObject for exporting data to the clipboard in our
own format.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
class wxLayoutDataObject : public wxPrivateDataObject
{
public:
wxLayoutDataObject(void)
{
SetId("application/wxlayoutlist");
m_format.SetAtom((GdkAtom) 222222);
}
};
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

View File

@@ -237,11 +237,9 @@ wxLayoutExportObject *wxLayoutExport(wxLayoutExportStatus *status,
*str += ((wxLayoutObjectText *)*status->m_iterator)->GetText(); *str += ((wxLayoutObjectText *)*status->m_iterator)->GetText();
break; break;
case WXLO_TYPE_CMD: case WXLO_TYPE_CMD:
wxASSERT_MSG( mode == WXLO_EXPORT_AS_HTML, if(mode == WXLO_EXPORT_AS_HTML)
"reached cmd object in text mode" ); *str += wxLayoutExportCmdAsHTML(*(wxLayoutObjectCmd const
*)*status->m_iterator, & status->m_si);
*str += wxLayoutExportCmdAsHTML(*(wxLayoutObjectCmd const
*)*status->m_iterator, & status->m_si);
break; break;
default: // ignore icons default: // ignore icons
; ;

View File

@@ -92,6 +92,7 @@ wxLayoutWindow::wxLayoutWindow(wxWindow *parent)
EnableScrolling(true,true); EnableScrolling(true,true);
m_maxx = max.x; m_maxy = max.y; m_maxx = max.x; m_maxy = max.y;
m_Selecting = false; m_Selecting = false;
SetCursorVisibility(-1);
SetCursor(wxCURSOR_IBEAM); SetCursor(wxCURSOR_IBEAM);
SetDirty(); SetDirty();
} }
@@ -177,6 +178,26 @@ wxLayoutWindow::OnMouse(int eventId, wxMouseEvent& event)
SetCursor(wxCURSOR_IBEAM); SetCursor(wxCURSOR_IBEAM);
m_HandCursor = FALSE; m_HandCursor = FALSE;
} }
if(event.LeftIsDown())
{
if(! m_Selecting)
{
m_llist->StartSelection();
m_Selecting = true;
DoPaint(FALSE);
}
else
{
m_llist->ContinueSelection(cursorPos);
DoPaint(FALSE);
}
}
if(m_Selecting && ! event.LeftIsDown())
{
m_llist->EndSelection(cursorPos);
m_Selecting = false;
DoPaint(FALSE);
}
return; return;
} }
@@ -184,8 +205,10 @@ wxLayoutWindow::OnMouse(int eventId, wxMouseEvent& event)
if(obj && eventId == WXLOWIN_MENU_LCLICK) if(obj && eventId == WXLOWIN_MENU_LCLICK)
{ {
m_llist->MoveCursorTo(cursorPos); m_llist->MoveCursorTo(cursorPos);
if(m_CursorVisibility == -1)
m_CursorVisibility = 1;
ScrollToCursor(); ScrollToCursor();
Refresh(FALSE); // DoPaint suppresses flicker under GTK DoPaint(FALSE); // DoPaint suppresses flicker under GTK
} }
if(!m_doSendEvents) // nothing to do if(!m_doSendEvents) // nothing to do
return; return;
@@ -245,6 +268,10 @@ wxLayoutWindow::OnChar(wxKeyEvent& event)
} }
} }
// If needed, make cursor visible:
if(m_CursorVisibility == -1)
m_CursorVisibility = 1;
/* These two nested switches work like this: /* These two nested switches work like this:
The first one processes all non-editing keycodes, to move the The first one processes all non-editing keycodes, to move the
cursor, etc. It's default will process all keycodes causing cursor, etc. It's default will process all keycodes causing
@@ -469,11 +496,14 @@ wxLayoutWindow::InternalPaint(const wxRect *updateRect)
if(x1 > m_maxx) m_maxx = x1; if(x1 > m_maxx) m_maxx = x1;
if(y1 > m_maxy) m_maxy = y1; if(y1 > m_maxy) m_maxy = y1;
WXLO_DEBUG(("Update rect: %ld,%ld / %ld,%ld",
updateRect->x, updateRect->y,
updateRect->x+updateRect->width,
updateRect->y+updateRect->height));
if(updateRect)
{
WXLO_DEBUG(("Update rect: %ld,%ld / %ld,%ld",
updateRect->x, updateRect->y,
updateRect->x+updateRect->width,
updateRect->y+updateRect->height));
}
if(IsDirty()) if(IsDirty())
{ {
m_llist->Layout(dc); m_llist->Layout(dc);
@@ -522,10 +552,13 @@ wxLayoutWindow::InternalPaint(const wxRect *updateRect)
/* This is the important bit: we tell the list to draw itself: */ /* This is the important bit: we tell the list to draw itself: */
#if WXLO_DEBUG_URECT #if WXLO_DEBUG_URECT
WXLO_DEBUG(("Update rect: %ld,%ld / %ld,%ld", if(updateRect)
updateRect->x, updateRect->y, {
updateRect->x+updateRect->width, WXLO_DEBUG(("Update rect: %ld,%ld / %ld,%ld",
updateRect->y+updateRect->height)); updateRect->x, updateRect->y,
updateRect->x+updateRect->width,
updateRect->y+updateRect->height));
}
#endif #endif
// Device origins on the memDC are suspect, we translate manually // Device origins on the memDC are suspect, we translate manually
@@ -538,10 +571,11 @@ wxLayoutWindow::InternalPaint(const wxRect *updateRect)
// update rectangle (although they are drawn on the memDC, this is // update rectangle (although they are drawn on the memDC, this is
// needed to erase it): // needed to erase it):
m_llist->InvalidateUpdateRect(); m_llist->InvalidateUpdateRect();
m_llist->DrawCursor(*m_memDC, if(m_CursorVisibility == 1)
m_HaveFocus && IsEditable(), // draw a thick m_llist->DrawCursor(*m_memDC,
// cursor for editable windows with focus m_HaveFocus && IsEditable(), // draw a thick
offset); // cursor for editable windows with focus
offset);
// Now copy everything to the screen: // Now copy everything to the screen:
#if 0 #if 0
@@ -600,16 +634,29 @@ wxLayoutWindow::ResizeScrollbars(bool exact)
void void
wxLayoutWindow::Paste(void) wxLayoutWindow::Paste(void)
{ {
wxString text;
// Read some text // Read some text
if (wxTheClipboard->Open()) if (wxTheClipboard->Open())
{ {
wxTextDataObject data; #if wxUSE_PRIVATE_CLIPBOARD_FORMAT
if (wxTheClipboard->IsSupported( data.GetFormat() )) wxLayoutDataObject wxldo;
if (wxTheClipboard->IsSupported( wxldo.GetFormat() ))
{ {
wxTheClipboard->GetData(&data); wxTheClipboard->GetData(&wxldo);
text += data.GetText(); {
}
//FIXME: missing functionality m_llist->Insert(wxldo.GetList());
} }
else
#endif
{
wxTextDataObject data;
if (wxTheClipboard->IsSupported( data.GetFormat() ))
{
wxTheClipboard->GetData(&data);
wxString text = data.GetText();
wxLayoutImportText( m_llist, text);
}
}
wxTheClipboard->Close(); wxTheClipboard->Close();
} }
#if 0 #if 0
@@ -622,11 +669,10 @@ wxLayoutWindow::Paste(void)
text += tmp_tctrl.GetValue(); text += tmp_tctrl.GetValue();
} }
#endif #endif
wxLayoutImportText( m_llist, text);
} }
bool bool
wxLayoutWindow::Copy(void) wxLayoutWindow::Copy(bool invalidate)
{ {
// Calling GetSelection() will automatically do an EndSelection() // Calling GetSelection() will automatically do an EndSelection()
// on the list, but we need to take a note of it, too: // on the list, but we need to take a note of it, too:
@@ -635,10 +681,12 @@ wxLayoutWindow::Copy(void)
m_Selecting = false; m_Selecting = false;
m_llist->EndSelection(); m_llist->EndSelection();
} }
wxLayoutList *llist = m_llist->GetSelection();
wxLayoutDataObject wldo;
wxLayoutList *llist = m_llist->GetSelection(&wldo, invalidate);
if(! llist) if(! llist)
return FALSE; return FALSE;
// Export selection as text:
wxString text; wxString text;
wxLayoutExportObject *export; wxLayoutExportObject *export;
wxLayoutExportStatus status(llist); wxLayoutExportStatus status(llist);
@@ -660,11 +708,14 @@ wxLayoutWindow::Copy(void)
text = text.Mid(0,len-1); text = text.Mid(0,len-1);
} }
// Read some text
if (wxTheClipboard->Open()) if (wxTheClipboard->Open())
{ {
wxTextDataObject *data = new wxTextDataObject( text ); wxTextDataObject *data = new wxTextDataObject( text );
bool rc = wxTheClipboard->SetData( data ); bool rc = wxTheClipboard->SetData( data );
#if wxUSE_PRIVATE_CLIPBOARD_FORMAT
rc |= wxTheClipboard->AddData( &wldo );
#endif
wxTheClipboard->Close(); wxTheClipboard->Close();
return rc; return rc;
} }
@@ -674,7 +725,7 @@ wxLayoutWindow::Copy(void)
bool bool
wxLayoutWindow::Cut(void) wxLayoutWindow::Cut(void)
{ {
if(Copy()) if(Copy(false)) // do not invalidate selection after copy
{ {
m_llist->DeleteSelection(); m_llist->DeleteSelection();
return TRUE; return TRUE;

View File

@@ -22,6 +22,9 @@
# define WXLOWIN_MENU_FIRST 12000 # define WXLOWIN_MENU_FIRST 12000
#endif #endif
#define wxUSE_PRIVATE_CLIPBOARD_FORMAT 0
enum enum
{ {
WXLOWIN_MENU_LARGER = WXLOWIN_MENU_FIRST, WXLOWIN_MENU_LARGER = WXLOWIN_MENU_FIRST,
@@ -78,10 +81,21 @@ public:
void SetEditable(bool toggle) { m_Editable = toggle; } void SetEditable(bool toggle) { m_Editable = toggle; }
/// Query whether list can be edited by user. /// Query whether list can be edited by user.
bool IsEditable(void) const { return m_Editable; } bool IsEditable(void) const { return m_Editable; }
/** Sets cursor visibility, visible=1, invisible=0,
visible-on-demand=-1, to hide it until moved.
@param visibility -1,0 or 1
@return the old visibility
*/
inline int SetCursorVisibility(int visibility = -1)
{ int v =m_CursorVisibility;
m_CursorVisibility = visibility; return v;}
/// Pastes text from clipboard. /// Pastes text from clipboard.
void Paste(void); void Paste(void);
/// Copies selection to clipboard. /** Copies selection to clipboard.
bool Copy(void); @param invalidate used internally, see wxllist.h for details
*/
bool Copy(bool invalidate = true);
/// Copies selection to clipboard and deletes it. /// Copies selection to clipboard and deletes it.
bool Cut(void); bool Cut(void);
//@} //@}
@@ -100,7 +114,7 @@ public:
Internally, this stores the parameter and calls a refresh on Internally, this stores the parameter and calls a refresh on
wxMSW, draws directly on wxGTK. wxMSW, draws directly on wxGTK.
*/ */
void DoPaint(const wxRect *updateRect); void DoPaint(const wxRect *updateRect = NULL);
#ifdef __WXMSW__ #ifdef __WXMSW__
virtual long MSWGetDlgCode(); virtual long MSWGetDlgCode();
@@ -177,6 +191,10 @@ protected:
int m_maxx; int m_maxx;
int m_maxy; int m_maxy;
int m_lineHeight; int m_lineHeight;
/** Visibility parameter for cursor. 0/1 as expected, -1: visible
on demand.
*/
int m_CursorVisibility;
private: private:
/// The layout list to be displayed. /// The layout list to be displayed.
wxLayoutList *m_llist; wxLayoutList *m_llist;