From: Karsten Ballüder Date: Sun, 14 Mar 1999 21:22:10 +0000 (+0000) Subject: Fixes and more functionality. X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/6ba4e8acebbb8fd6a255bf78c8833b8378d9dd01?ds=inline Fixes and more functionality. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@1929 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/user/wxLayout/TODO b/user/wxLayout/TODO index 1bffa8dd99..63008b8ed9 100644 --- a/user/wxLayout/TODO +++ b/user/wxLayout/TODO @@ -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 diff --git a/user/wxLayout/wxLayout.cpp b/user/wxLayout/wxLayout.cpp index 441580e3a5..fe8fa471ee 100644 --- a/user/wxLayout/wxLayout.cpp +++ b/user/wxLayout/wxLayout.cpp @@ -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; diff --git a/user/wxLayout/wxllist.cpp b/user/wxLayout/wxllist.cpp index 246fbb98e1..5357810c50 100644 --- a/user/wxLayout/wxllist.cpp +++ b/user/wxLayout/wxllist.cpp @@ -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; diff --git a/user/wxLayout/wxllist.h b/user/wxLayout/wxllist.h index fab769d6f9..03f979732e 100644 --- a/user/wxLayout/wxllist.h +++ b/user/wxLayout/wxllist.h @@ -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. diff --git a/user/wxLayout/wxlparser.cpp b/user/wxLayout/wxlparser.cpp index 6ebe3a5ce3..08c2c61fb2 100644 --- a/user/wxLayout/wxlparser.cpp +++ b/user/wxLayout/wxlparser.cpp @@ -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) diff --git a/user/wxLayout/wxlparser.h b/user/wxLayout/wxlparser.h index 7aba804790..2a65688cb0 100644 --- a/user/wxLayout/wxlparser.h +++ b/user/wxLayout/wxlparser.h @@ -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 diff --git a/user/wxLayout/wxlwindow.cpp b/user/wxLayout/wxlwindow.cpp index 5fa7a63325..90cf075e50 100644 --- a/user/wxLayout/wxlwindow.cpp +++ b/user/wxLayout/wxlwindow.cpp @@ -27,10 +27,11 @@ # undef StartDoc # endif # include "wxlwindow.h" +# include "wxlparser.h" #endif #include - +#include #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() diff --git a/user/wxLayout/wxlwindow.h b/user/wxLayout/wxlwindow.h index 89d709a728..22df9e617b 100644 --- a/user/wxLayout/wxlwindow.h +++ b/user/wxLayout/wxlwindow.h @@ -16,7 +16,7 @@ # include #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