Fixes and more functionality.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@1929 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Karsten Ballüder 1999-03-14 21:22:10 +00:00
parent 77c630ca85
commit 6ba4e8aceb
8 changed files with 200 additions and 48 deletions

View File

@ -5,9 +5,14 @@ BUGS
- dmalloc shows duplicate deletion after merging two lines and
deleting the second half
- printout page calculation still a bit wrong
- word wrap for objects with lots of non-space needs to search in positive
direction if begin of first object is reached
TODO
=====================================================================
- replacement of llist in window
- undo
- Selections
- More optimisations

View File

@ -33,7 +33,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_WRAP, ID_NOWRAP, ID_PASTE,
ID_WXLAYOUT_DEBUG, ID_QUIT, ID_CLICK, ID_HTML, ID_TEXT, ID_TEST };
@ -63,10 +63,9 @@ MyFrame::MyFrame(void) :
SetStatusText( "wxLayout by Karsten Ballüder." );
wxMenuBar *menu_bar = new wxMenuBar();
wxMenu *file_menu = new wxMenu;
file_menu->Append( ID_CLEAR, "Clear");
file_menu->Append( ID_ADD_SAMPLE, "Example");
file_menu->Append(ID_PRINT, "&Print...", "Print");
file_menu->Append(ID_PRINT_SETUP, "Print &Setup...","Setup printer properties");
file_menu->Append(ID_PAGE_SETUP, "Page Set&up...", "Page setup");
@ -78,18 +77,22 @@ MyFrame::MyFrame(void) :
file_menu->Append(ID_PAGE_SETUP_PS, "Page Setup PostScript...", "Page setup (PostScript)");
file_menu->Append(ID_PREVIEW_PS, "Print Preview PostScript", "Preview (PostScript)");
#endif
file_menu->AppendSeparator();
file_menu->Append(ID_WRAP, "Wrap mode", "Activate wrapping at pixel 200.");
file_menu->Append(ID_NOWRAP, "No-wrap mode", "Deactivate wrapping.");
file_menu->AppendSeparator();
file_menu->Append( ID_TEXT, "Export Text");
file_menu->Append( ID_HTML, "Export HTML");
file_menu->Append( ID_QUIT, "Exit");
wxMenuBar *menu_bar = new wxMenuBar();
menu_bar->Append(file_menu, "File" );
wxMenu *edit_menu = new wxMenu;
edit_menu->Append( ID_CLEAR, "Clear");
edit_menu->Append( ID_ADD_SAMPLE, "Example");
edit_menu->AppendSeparator();
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.");
menu_bar->Append(edit_menu, "Edit" );
#ifndef __WXMSW__
menu_bar->Show( TRUE );
#endif // MSW
@ -222,6 +225,9 @@ void MyFrame::OnCommand( wxCommandEvent &event )
case ID_CLICK:
cerr << "Received click event." << endl;
break;
case ID_PASTE:
m_lwin->Paste();
break;
case ID_HTML:
{
wxLayoutExportObject *export;

View File

@ -72,6 +72,7 @@ bool operator !=(wxPoint const &p1, wxPoint const &p2)
return p1.x != p2.x || p1.y != p2.y;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
wxLayoutObjectText
@ -87,6 +88,17 @@ wxLayoutObjectText::wxLayoutObjectText(const wxString &txt)
m_Bottom = 0;
}
wxLayoutObject *
wxLayoutObjectText::Copy(void)
{
wxLayoutObjectText *obj = new wxLayoutObjectText(m_Text);
obj->m_Width = m_Width;
obj->m_Height = m_Height;
obj->m_Top = m_Top;
obj->m_Bottom = m_Bottom;
obj->SetUserData(m_UserData);
return obj;
}
wxPoint
wxLayoutObjectText::GetSize(CoordType *top, CoordType *bottom) const
@ -157,6 +169,15 @@ wxLayoutObjectIcon::wxLayoutObjectIcon(wxBitmap const &icon)
m_Icon = new wxBitmap(icon);
}
wxLayoutObject *
wxLayoutObjectIcon::Copy(void)
{
wxLayoutObjectIcon *obj = new wxLayoutObjectIcon(new
wxBitmap(*m_Icon));
obj->SetUserData(m_UserData);
return obj;
}
wxLayoutObjectIcon::wxLayoutObjectIcon(wxBitmap *icon)
{
m_Icon = icon;
@ -199,6 +220,20 @@ wxLayoutObjectCmd::wxLayoutObjectCmd(int size, int family, int style, int
m_ColourBG = bg;
}
wxLayoutObject *
wxLayoutObjectCmd::Copy(void)
{
wxLayoutStyleInfo si;
GetStyle(&si);
wxLayoutObjectCmd *obj = new wxLayoutObjectCmd(
si.size, si.family, si.style, si.weight, si.underline,
m_ColourFG, m_ColourBG);
obj->SetUserData(m_UserData);
return obj;
}
wxLayoutObjectCmd::~wxLayoutObjectCmd()
{
delete m_font;
@ -787,15 +822,38 @@ wxLayoutLine::GetWrapPosition(CoordType column)
column--;
}
}while(offset != -1);
i--; // move on to previous object
}
else
{
column -= (**i).GetLength();
// This is both "else" and what has to be done after checking
// all positions of the text object:
i--;
offset = (**i).GetLength();
i--;
}
if( i != NULLIT)
offset = (**i).GetLength();
}while(i != NULLIT);
return -1;
/* If we reached the begin of the list and have more than one
object, that one is longer than the margin, so break behind
it. */
CoordType pos = 0;
i = m_ObjectList.begin();
while(i != NULLIT && (**i).GetType() != WXLO_TYPE_TEXT)
{
pos += (**i).GetLength();
i++;
}
if(i == NULLIT) return -1; //why should this happen?
pos += (**i).GetLength();
i++;
while(i != NULLIT && (**i).GetType() != WXLO_TYPE_TEXT)
{
pos += (**i).GetLength();
i++;
}
if(i == NULLIT) return -1; //this is possible, if there is only one text object
// now we are at the second text object:
pos -= (**i).GetLength();
return pos; // in front of it
}
@ -809,7 +867,7 @@ wxLayoutList::wxLayoutList()
{
m_DefaultSetting = NULL;
m_FirstLine = NULL;
InternalClear();
Clear();
}
wxLayoutList::~wxLayoutList()
@ -818,17 +876,11 @@ wxLayoutList::~wxLayoutList()
}
void
wxLayoutList::InternalClear(void)
wxLayoutList::Empty(void)
{
while(m_FirstLine)
m_FirstLine = m_FirstLine->DeleteLine(false);
if(m_DefaultSetting)
{
delete m_DefaultSetting;
m_DefaultSetting = NULL;
}
m_CursorPos = wxPoint(0,0);
m_CursorScreenPos = wxPoint(0,0);
m_CursorSize = wxPoint(0,0);
@ -836,6 +888,18 @@ wxLayoutList::InternalClear(void)
m_CursorLine = m_FirstLine;
}
void
wxLayoutList::InternalClear(void)
{
Empty();
if(m_DefaultSetting)
{
delete m_DefaultSetting;
m_DefaultSetting = NULL;
}
}
void
wxLayoutList::SetFont(int family, int size, int style, int weight,
int underline, wxColour const *fg,
@ -906,7 +970,7 @@ wxLayoutList::MoveCursorTo(wxPoint const &p)
{
wxLayoutLine *line = m_FirstLine;
while(line && line->GetLineNumber() != p.y)
;
line = line->GetNextLine();
if(line && line->GetLineNumber() == p.y) // found it
{
m_CursorPos.y = p.y;

View File

@ -83,10 +83,22 @@ class wxFont;
class wxLayoutObject
{
public:
/// This structure can be used to contain data associated with the object.
/** This structure can be used to contain data associated with the
object.
It is refcounted, so the caller has to do a DecRef() on it
instead of a delete.
*/
struct UserData
{
virtual ~UserData() { }
UserData() { m_refcount = 1; }
void IncRef(void) { m_refcount++; }
void DecRef(void) { m_refcount--; if(m_refcount == 0) delete this;}
private:
int m_refcount;
protected:
virtual ~UserData() { wxASSERT(m_refcount == 0); }
/// prevents gcc from generating stupid warnings
friend class dummy_UserData;
};
/// return the type of this object
@ -125,7 +137,7 @@ public:
/// constructor
wxLayoutObject() { m_UserData = NULL; }
/// delete the user data
virtual ~wxLayoutObject() { if(m_UserData) delete m_UserData; }
virtual ~wxLayoutObject() { if(m_UserData) m_UserData->DecRef(); }
#ifdef WXLAYOUT_DEBUG
virtual void Debug(void);
@ -134,10 +146,20 @@ public:
/** Tells the object about some user data. This data is associated
with the object and will be deleted at destruction time.
*/
void SetUserData(UserData *data) { m_UserData = data; }
/** Return the user data. */
void * GetUserData(void) const { return m_UserData; }
void SetUserData(UserData *data)
{
if(m_UserData)
m_UserData->DecRef();
m_UserData = data;
m_UserData->IncRef();
}
/** Return the user data. */
void * GetUserData(void) const { if(m_UserData) m_UserData->IncRef(); return m_UserData; }
/** Makes a copy of this object.
*/
virtual wxLayoutObject *Copy(void) = 0;
private:
/// optional data for application's use
UserData *m_UserData;
@ -192,7 +214,9 @@ public:
// for editing:
wxString & GetText(void) { return m_Text; }
void SetText(wxString const &text) { m_Text = text; }
/** Makes a copy of this object.
*/
virtual wxLayoutObject *Copy(void);
private:
wxString m_Text;
/// size of the box containing text
@ -230,7 +254,11 @@ public:
virtual wxPoint GetSize(CoordType * top, CoordType *bottom) const;
/// Return just the width of the object on the screen.
virtual CoordType GetWidth(void) const { return m_Icon->GetWidth(); }
// return a pointer to the icon
wxBitmap *GetIcon(void) const { return m_Icon; }
/** Makes a copy of this object.
*/
virtual wxLayoutObject *Copy(void);
private:
wxBitmap *m_Icon;
};
@ -269,6 +297,9 @@ public:
void GetStyle(wxLayoutStyleInfo *si) const;
/// return the background colour for setting colour of window
wxColour const *GetBGColour(void) const { return m_ColourBG; }
/** Makes a copy of this object.
*/
virtual wxLayoutObject *Copy(void);
private:
/// the font to use
wxFont *m_font;
@ -539,7 +570,9 @@ public:
int underline=0,
char const *fg="black",
char const *bg="white");
/// Empty: clear the list but leave font settings.
void Empty(void);
/**@name Cursor Management */
//@{
/** Set new cursor position.

View File

@ -32,7 +32,7 @@ inline static bool IsEndOfLine(const char *p, int mode)
(((*p == '\r') && (*(p + 1) == '\n'))||(*p == '\n'));
}
void wxLayoutImportText(wxLayoutList &list, wxString const &str, int withflag)
void wxLayoutImportText(wxLayoutList *list, wxString const &str, int withflag)
{
char * cptr = (char *)str.c_str(); // string gets changed only temporarily
const char * begin = cptr;
@ -45,7 +45,7 @@ void wxLayoutImportText(wxLayoutList &list, wxString const &str, int withflag)
cptr++;
backup = *cptr;
*cptr = '\0';
list.Insert(begin);
list->Insert(begin);
*cptr = backup;
// check if it's the end of this line
@ -54,7 +54,7 @@ void wxLayoutImportText(wxLayoutList &list, wxString const &str, int withflag)
// if it was "\r\n", skip the following '\n'
if ( *cptr == '\r' )
cptr++;
list.LineBreak();
list->LineBreak();
}
else if(backup == '\0') // reached end of string
break;
@ -158,7 +158,7 @@ wxLayoutExportObject *wxLayoutExport(wxLayoutExportStatus *status,
{
wxASSERT(status);
wxLayoutExportObject * export;
if(status->m_iterator == NULLIT) // end of line
{
if(!status->m_line || status->m_line->GetNextLine() == NULL) // reached end of list
@ -168,6 +168,14 @@ wxLayoutExportObject *wxLayoutExport(wxLayoutExportStatus *status,
status->m_line = status->m_line->GetNextLine();
status->m_iterator = status->m_line->GetFirstObject();
export = new wxLayoutExportObject();;
if( (mode & WXLO_EXPORT_AS_MASK) == WXLO_EXPORT_AS_OBJECTS) // simple case
{
export->type = WXLO_EXPORT_OBJECT;
export->content.object = *status->m_iterator;
status->m_iterator++;
return export;
}
//else: text object:
export->type = ((mode & WXLO_EXPORT_AS_MASK) == WXLO_EXPORT_AS_HTML)
? WXLO_EXPORT_HTML : WXLO_EXPORT_TEXT;
if((mode & WXLO_EXPORT_WITH_CRLF) == WXLO_EXPORT_WITH_CRLF)

View File

@ -68,14 +68,14 @@ struct wxLayoutExportStatus
#ifdef OS_WIN
/// import text into a wxLayoutList (including linefeeds):
void wxLayoutImportText(wxLayoutList &list, wxString const &str,
void wxLayoutImportText(wxLayoutList *list, wxString const &str,
int withflag = WXLO_EXPORT_WITH_CRLF);
wxLayoutExportObject *wxLayoutExport(wxLayoutExportStatus *status,
int mode = WXLO_EXPORT_AS_TEXT|WXLO_EXPORT_WITH_CRLF);
#else
/// import text into a wxLayoutList (including linefeeds):
void wxLayoutImportText(wxLayoutList &list, wxString const &str,
void wxLayoutImportText(wxLayoutList *list, wxString const &str,
int withflag = WXLO_EXPORT_WITH_LF_ONLY);
/// export text in a given format FIXME-MT: not thread safe, uses static variable

View File

@ -27,10 +27,11 @@
# undef StartDoc
# endif
# include "wxlwindow.h"
# include "wxlparser.h"
#endif
#include <ctype.h>
#include <wx/clipbrd.h>
#define WXLO_XOFFSET 4
#define WXLO_YOFFSET 4
@ -266,11 +267,23 @@ wxLayoutWindow::OnChar(wxKeyEvent& event)
void
wxLayoutWindow::OnPaint( wxPaintEvent &WXUNUSED(event)) // or: OnDraw(wxDC& dc)
{
DoPaint();
m_ScrollToCursor = false;
InternalPaint();
}
void
wxLayoutWindow::DoPaint(bool scrollToCursor)
{
m_ScrollToCursor = scrollToCursor;
#ifdef __WXGTK__
InternalPaint();
#else
Refresh();
#endif
}
void
wxLayoutWindow::InternalPaint(void)
{
wxPaintDC dc( this );
PrepareDC( dc );
@ -301,7 +314,7 @@ wxLayoutWindow::DoPaint(bool scrollToCursor)
/* 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! */
if(IsEditable() && scrollToCursor)
if(IsEditable() && m_ScrollToCursor)
{
wxPoint cc = m_llist->GetCursorScreenPos();
if(cc.x < x0 || cc.y < y0
@ -366,6 +379,22 @@ wxLayoutWindow::ResizeScrollbars(bool exact)
}
}
void
wxLayoutWindow::Paste(void)
{
// Read some text
if (wxTheClipboard->Open())
{
wxTextDataObject data;
if (wxTheClipboard->IsSupported(wxDF_TEXT))
{
wxTheClipboard->GetData(&data);
wxLayoutImportText( m_llist, data.GetText());
}
wxTheClipboard->Close();
}
}
wxMenu *
wxLayoutWindow::MakeFormatMenu()

View File

@ -16,7 +16,7 @@
# include <wx/wx.h>
#endif
#include "wxllist.h"
#include "wxllist.h"
#ifndef WXLOWIN_MENU_FIRST
# define WXLOWIN_MENU_FIRST 12000
@ -76,7 +76,9 @@ public:
void SetEditable(bool toggle) { m_Editable = toggle; }
/// Query whether list can be edited by user.
bool IsEditable(void) const { return m_Editable; }
/// Pastes text from clipboard.
void Paste(void);
//@}
void EnablePopup(bool enable = true) { m_DoPopupMenu = enable; }
@ -87,6 +89,8 @@ public:
void SetWrapMargin(CoordType margin) { m_WrapMargin = margin; }
/** Redraws the window.
Internally, this stores the parameter and calls a refresh on
wxMSW, draws directly on wxGTK.
@param scrollToCursor if true, scroll the window so that the
cursor becomes visible
*/
@ -121,16 +125,17 @@ public:
/// Creates a wxMenu for use as a format popup.
static wxMenu * MakeFormatMenu(void);
/// Set dirty flag.
void SetDirty(void) { m_Dirty = true; }
protected:
/**@name Dirty flag handling for optimisations. */
//@{
/// Set dirty flag.
void SetDirty(void) { m_Dirty = true; }
/// Query whether window needs redrawing.
bool IsDirty(void) const { return m_Dirty; }
/// Reset dirty flag.
void ResetDirty(void) { m_Dirty = false; }
//@}
/// Redraws the window, used by DoPaint() or OnPaint().
void InternalPaint(void);
protected:
/// generic function for mouse events processing
void OnMouse(int eventId, wxMouseEvent& event);
@ -145,6 +150,8 @@ protected:
bool m_HaveFocus;
/// do we handle clicks of the right mouse button?
bool m_DoPopupMenu;
/// Should InternalPaint() scroll to cursor.
bool m_ScrollToCursor;
/// the menu
wxMenu * m_PopupMenu;
/// for derived classes, set when mouse is clicked