From 47e1663e822c3bce607dfae81a5bdd9f69c71ad4 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Karsten=20Ball=C3=BCder?= Date: Sun, 16 May 1999 23:10:40 +0000 Subject: [PATCH 1/1] Many, many updates. Almost perfect. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@2476 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- user/wxLayout/TODO | 13 +- user/wxLayout/wxLayout.cpp | 2 +- user/wxLayout/wxllist.cpp | 271 +++++++++++++++++++++++++++++++++--- user/wxLayout/wxllist.h | 72 ++++++++-- user/wxLayout/wxlparser.cpp | 8 +- user/wxLayout/wxlwindow.cpp | 99 +++++++++---- user/wxLayout/wxlwindow.h | 24 +++- 7 files changed, 412 insertions(+), 77 deletions(-) diff --git a/user/wxLayout/TODO b/user/wxLayout/TODO index 36c27bcfce..932d6e93d4 100644 --- a/user/wxLayout/TODO +++ b/user/wxLayout/TODO @@ -16,8 +16,8 @@ BUGS TODO ===================================================================== -Inserting NL in empty line sometimes doesn't move cursor down. -Line numbers go a bit berserk, too. :-) + - UNDO!! + - replacement of llist in window The following two probs can probably be fixed by adding the RecalculateLayout() method: @@ -25,11 +25,8 @@ RecalculateLayout() method: Printing works again, but layout at begin of new page is corrupted. -Selections: - - moving in negative direction doesn't work - - selection state not properly reset, only works once - - selecting non-text objects is strange - +- The import of a private data object does not work yet, we need to get + the objects back from the string. - Changing default settings in Clear() or changing/inserting/deleting a wxLayoutObject needs to update the m_StyleInfo in all lines, only then can we start using that one. @@ -39,8 +36,6 @@ Selections: some code bits are commented out in wxlwindow.cpp offset handling seems a bit dodgy, white shadow to top/left of cursor - - replacement of llist in window - - UNDO - DragNDrop - Update docs, do full rtf/html editing. diff --git a/user/wxLayout/wxLayout.cpp b/user/wxLayout/wxLayout.cpp index 4266562924..b7df97f28a 100644 --- a/user/wxLayout/wxLayout.cpp +++ b/user/wxLayout/wxLayout.cpp @@ -126,7 +126,7 @@ MyFrame::AddSampleText(wxLayoutList *llist) llist->SetFont(wxROMAN,16,wxNORMAL,wxNORMAL, false); llist->Insert("--"); llist->LineBreak(); - + llist->SetFont(wxROMAN); llist->Insert("The quick brown fox jumps over the lazy dog."); llist->LineBreak(); diff --git a/user/wxLayout/wxllist.cpp b/user/wxLayout/wxllist.cpp index a56aad668d..9d55127fdd 100644 --- a/user/wxLayout/wxllist.cpp +++ b/user/wxLayout/wxllist.cpp @@ -24,6 +24,7 @@ #ifdef M_BASEDIR # include "gui/wxllist.h" +# include "gui/wxlparser.h" # define SHOW_SELECTIONS 1 #else # include "wxllist.h" @@ -37,6 +38,7 @@ # include # include # include +# include #endif #include @@ -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 @@ -145,6 +186,23 @@ wxLayoutObjectText::Copy(void) 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 wxLayoutObjectText::GetSize(CoordType *top, CoordType *bottom) const { @@ -158,7 +216,7 @@ wxLayoutObjectText::Draw(wxDC &dc, wxPoint const &coords, wxLayoutList *wxllist, CoordType begin, CoordType end) { - if(begin == -1) + if( end <= 0) dc.DrawText(m_Text, coords.x, coords.y-m_Top); else { @@ -168,6 +226,10 @@ wxLayoutObjectText::Draw(wxDC &dc, wxPoint const &coords, xpos = coords.x, ypos = coords.y-m_Top; long width, height, descent; + + if(begin < 0) begin = 0; + if(end > m_Text.Length()) end = m_Text.Length(); + str = m_Text.Mid(0, begin); dc.DrawText(str, xpos, ypos); @@ -219,6 +281,7 @@ wxLayoutObjectText::Layout(wxDC &dc, class wxLayoutList * ) m_Top = m_Height - m_Bottom; } + #ifdef WXLAYOUT_DEBUG void wxLayoutObjectText::Debug(void) @@ -239,6 +302,38 @@ wxLayoutObjectIcon::wxLayoutObjectIcon(wxBitmap const &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 * wxLayoutObjectIcon::Copy(void) { @@ -351,6 +446,76 @@ wxLayoutObjectCmd::Copy(void) 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() { @@ -765,6 +930,7 @@ wxLayoutLine::Draw(wxDC &dc, { // parts of the line need highlighting tempto = xpos+(**i).GetLength(); +#if 0 if(tempto >= from && xpos <= to) { tempto = to-xpos; @@ -772,13 +938,16 @@ wxLayoutLine::Draw(wxDC &dc, tempto = (**i).GetLength(); CoordType tmp = from-xpos; 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 { llist->EndHighlighting(dc); // FIXME! inefficient (**i).Draw(dc, pos, llist); } +#endif } else (**i).Draw(dc, pos, llist); @@ -916,8 +1085,11 @@ wxLayoutLine::Break(CoordType xpos, wxLayoutList *llist) wxASSERT(xpos >= 0); //FIXME: this could be optimised, for now be prudent: 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 wxLayoutLine *prev = new wxLayoutLine(m_Previous, llist); if(m_Previous == NULL) @@ -925,12 +1097,11 @@ wxLayoutLine::Break(CoordType xpos, wxLayoutList *llist) // before this. prev->m_Next = this; 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) m_Next->RecalculatePositions(1, llist); - return this; + return m_Previous; } CoordType offset; @@ -1127,6 +1298,7 @@ wxLayoutLine::Copy(wxLayoutList *llist, } } + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * The wxLayoutList object @@ -1398,6 +1570,29 @@ wxLayoutList::Insert(wxLayoutObject *obj) 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 wxLayoutList::LineBreak(void) { @@ -1408,7 +1603,8 @@ wxLayoutList::LineBreak(void) m_CursorLine = m_CursorLine->Break(m_CursorPos.x, this); if(setFirst) // we were at beginning of first line m_FirstLine = m_CursorLine->GetPreviousLine(); - m_CursorPos.y++; + if(m_CursorPos.x != 0) + m_CursorPos.y++; m_CursorPos.x = 0; // doesn't help m_CursorLine.MarkDirty(); 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); else line->Layout(dc, this); - line->RecalculatePosition(this); // little condition to speed up redrawing: if(bottom != -1 && line->GetPosition().y > bottom) break; } + line->RecalculatePosition(this); line = line->GetNextLine(); } @@ -1596,6 +1792,8 @@ wxLayoutList::Draw(wxDC &dc, // only draw if between top and bottom: if((top == -1 || line->GetPosition().y + line->GetHeight() >= top)) line->Draw(dc, this, offset); + else + line->Layout(dc, this); // little condition to speed up redrawing: if(bottom != -1 && line->GetPosition().y > bottom) break; line = line->GetNextLine(); @@ -1720,22 +1918,29 @@ wxLayoutList::SetUpdateRect(CoordType x, CoordType y) } void -wxLayoutList::StartSelection(void) +wxLayoutList::StartSelection(wxPoint cpos) { - 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; + if(cpos.x == -1) + cpos = 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_valid = false; } 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_valid == false); - WXLO_DEBUG(("Continuing selection at %ld/%ld", m_CursorPos.x, m_CursorPos.y)); - m_Selection.m_CursorB = m_CursorPos; + WXLO_DEBUG(("Continuing selection at %ld/%ld", cpos.x, cpos.y)); + if(m_Selection.m_CursorB <= cpos) + m_Selection.m_CursorB = cpos; + else + m_Selection.m_CursorA = cpos; // We always want m_CursorA <= m_CursorB! if(! (m_Selection.m_CursorA <= m_Selection.m_CursorB)) { @@ -1746,10 +1951,12 @@ wxLayoutList::ContinueSelection(void) } void -wxLayoutList::EndSelection(void) +wxLayoutList::EndSelection(wxPoint cpos) { - ContinueSelection(); - WXLO_DEBUG(("Ending selection at %ld/%ld", m_CursorPos.x, m_CursorPos.y)); + if(cpos.x == -1) + cpos = m_CursorPos; + ContinueSelection(cpos); + WXLO_DEBUG(("Ending selection at %ld/%ld", cpos.x, cpos.y)); m_Selection.m_selecting = false; m_Selection.m_valid = true; } @@ -1943,7 +2150,7 @@ wxLayoutList::Copy(const wxPoint &from, } wxLayoutList * -wxLayoutList::GetSelection(void) +wxLayoutList::GetSelection(wxLayoutDataObject *wxlo, bool invalidate) { if(! m_Selection.m_valid) { @@ -1953,8 +2160,28 @@ wxLayoutList::GetSelection(void) return NULL; } - m_Selection.m_valid = false; - return Copy( m_Selection.m_CursorA, m_Selection.m_CursorB ); + if(invalidate) m_Selection.m_valid = false; + + 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; } diff --git a/user/wxLayout/wxllist.h b/user/wxLayout/wxllist.h index a9cf311850..7edbcbbdff 100644 --- a/user/wxLayout/wxllist.h +++ b/user/wxLayout/wxllist.h @@ -21,6 +21,7 @@ #include "wx/printdlg.h" #include "wx/generic/printps.h" #include "wx/generic/prntdlgg.h" +#include "wx/dataobj.h" // skip the following defines if embedded in M application #ifndef M_BASEDIR @@ -46,6 +47,12 @@ # define WXLO_DEFAULTFONTSIZE 12 #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. enum wxLayoutObjectType @@ -160,7 +167,8 @@ public: if(m_UserData) m_UserData->DecRef(); m_UserData = data; - m_UserData->IncRef(); + if(m_UserData) + m_UserData->IncRef(); } /** Return the user data. */ @@ -169,6 +177,18 @@ public: /** Makes a copy of this object. */ 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: /// optional data for application's use UserData *m_UserData; @@ -192,8 +212,8 @@ KBLIST_DEFINE(wxLayoutObjectList, wxLayoutObject); class wxLayoutObjectText : public wxLayoutObject { public: - wxLayoutObjectText(const wxString &txt); - + wxLayoutObjectText(const wxString &txt = ""); + virtual wxLayoutObjectType GetType(void) const { return WXLO_TYPE_TEXT; } virtual void Layout(wxDC &dc, class wxLayoutList *llist); virtual void Draw(wxDC &dc, wxPoint const &coords, @@ -216,6 +236,8 @@ public: */ virtual CoordType GetOffsetScreen(wxDC &dc, CoordType xpos) const; + virtual void Write(wxString &ostr); + static wxLayoutObjectText *Read(wxString &istr); #ifdef WXLAYOUT_DEBUG virtual void Debug(void); @@ -249,10 +271,10 @@ private: class wxLayoutObjectIcon : public wxLayoutObject { public: - wxLayoutObjectIcon(wxBitmap *icon); + wxLayoutObjectIcon(wxBitmap *icon = NULL); 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 void Layout(wxDC &dc, class wxLayoutList *llist); @@ -274,6 +296,8 @@ public: /** Makes a copy of this object. */ virtual wxLayoutObject *Copy(void); + virtual void Write(wxString &ostr); + static wxLayoutObjectIcon *Read(wxString &istr); private: wxBitmap *m_Icon; }; @@ -299,7 +323,7 @@ struct wxLayoutStyleInfo int size, family, style, weight, underline; /// Colours 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. */ virtual wxLayoutObject *Copy(void); + virtual void Write(wxString &ostr); + static wxLayoutObjectCmd *Read(wxString &istr); private: wxLayoutStyleInfo *m_StyleInfo; }; @@ -732,6 +758,9 @@ public: bool Insert(wxString const &text); /// Insert some other object at current cursor position. bool Insert(wxLayoutObject *obj); + /// Inserts objects at current cursor positions + bool Insert(wxLayoutList *llist); + /// Inserts a linebreak at current cursor position. bool LineBreak(void); /** Wraps the current line. Searches to the left of the cursor to @@ -925,23 +954,26 @@ public: //@} /// Begin selecting text. - void StartSelection(void); + void StartSelection(wxPoint cpos = wxPoint(-1,-1)); // Continue selecting text - void ContinueSelection(void); + void ContinueSelection(wxPoint cpos = wxPoint(-1,-1)); /// End selecting text. - void EndSelection(void); + void EndSelection(wxPoint cpos = wxPoint(-1,-1)); /// Are we still selecting text? bool IsSelecting(void); bool IsSelected(const wxPoint &cursor); - /// Return the selection as a wxLayoutList: - wxLayoutList *GetSelection(void); + /** Return the selection as a wxLayoutList. + @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 void DeleteSelection(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 @@ -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); + } +}; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * diff --git a/user/wxLayout/wxlparser.cpp b/user/wxLayout/wxlparser.cpp index ebd8be4aee..b93f39e473 100644 --- a/user/wxLayout/wxlparser.cpp +++ b/user/wxLayout/wxlparser.cpp @@ -237,11 +237,9 @@ wxLayoutExportObject *wxLayoutExport(wxLayoutExportStatus *status, *str += ((wxLayoutObjectText *)*status->m_iterator)->GetText(); break; case WXLO_TYPE_CMD: - wxASSERT_MSG( mode == WXLO_EXPORT_AS_HTML, - "reached cmd object in text mode" ); - - *str += wxLayoutExportCmdAsHTML(*(wxLayoutObjectCmd const - *)*status->m_iterator, & status->m_si); + if(mode == WXLO_EXPORT_AS_HTML) + *str += wxLayoutExportCmdAsHTML(*(wxLayoutObjectCmd const + *)*status->m_iterator, & status->m_si); break; default: // ignore icons ; diff --git a/user/wxLayout/wxlwindow.cpp b/user/wxLayout/wxlwindow.cpp index c60e6d11c8..cc63534cb7 100644 --- a/user/wxLayout/wxlwindow.cpp +++ b/user/wxLayout/wxlwindow.cpp @@ -92,6 +92,7 @@ wxLayoutWindow::wxLayoutWindow(wxWindow *parent) EnableScrolling(true,true); m_maxx = max.x; m_maxy = max.y; m_Selecting = false; + SetCursorVisibility(-1); SetCursor(wxCURSOR_IBEAM); SetDirty(); } @@ -177,6 +178,26 @@ wxLayoutWindow::OnMouse(int eventId, wxMouseEvent& event) SetCursor(wxCURSOR_IBEAM); 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; } @@ -184,8 +205,10 @@ wxLayoutWindow::OnMouse(int eventId, wxMouseEvent& event) if(obj && eventId == WXLOWIN_MENU_LCLICK) { m_llist->MoveCursorTo(cursorPos); + if(m_CursorVisibility == -1) + m_CursorVisibility = 1; ScrollToCursor(); - Refresh(FALSE); // DoPaint suppresses flicker under GTK + DoPaint(FALSE); // DoPaint suppresses flicker under GTK } if(!m_doSendEvents) // nothing to do 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: The first one processes all non-editing keycodes, to move the 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(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()) { 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: */ #if WXLO_DEBUG_URECT - 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)); + } #endif // 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 // needed to erase it): m_llist->InvalidateUpdateRect(); - m_llist->DrawCursor(*m_memDC, - m_HaveFocus && IsEditable(), // draw a thick - // cursor for editable windows with focus - offset); + if(m_CursorVisibility == 1) + m_llist->DrawCursor(*m_memDC, + m_HaveFocus && IsEditable(), // draw a thick + // cursor for editable windows with focus + offset); // Now copy everything to the screen: #if 0 @@ -600,16 +634,29 @@ wxLayoutWindow::ResizeScrollbars(bool exact) void wxLayoutWindow::Paste(void) { - wxString text; // Read some text if (wxTheClipboard->Open()) { - wxTextDataObject data; - if (wxTheClipboard->IsSupported( data.GetFormat() )) +#if wxUSE_PRIVATE_CLIPBOARD_FORMAT + wxLayoutDataObject wxldo; + if (wxTheClipboard->IsSupported( wxldo.GetFormat() )) { - wxTheClipboard->GetData(&data); - text += data.GetText(); + wxTheClipboard->GetData(&wxldo); + { + } + //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(); } #if 0 @@ -622,11 +669,10 @@ wxLayoutWindow::Paste(void) text += tmp_tctrl.GetValue(); } #endif - wxLayoutImportText( m_llist, text); } bool -wxLayoutWindow::Copy(void) +wxLayoutWindow::Copy(bool invalidate) { // Calling GetSelection() will automatically do an EndSelection() // on the list, but we need to take a note of it, too: @@ -635,10 +681,12 @@ wxLayoutWindow::Copy(void) m_Selecting = false; m_llist->EndSelection(); } - wxLayoutList *llist = m_llist->GetSelection(); + + wxLayoutDataObject wldo; + wxLayoutList *llist = m_llist->GetSelection(&wldo, invalidate); if(! llist) return FALSE; - + // Export selection as text: wxString text; wxLayoutExportObject *export; wxLayoutExportStatus status(llist); @@ -660,11 +708,14 @@ wxLayoutWindow::Copy(void) text = text.Mid(0,len-1); } - // Read some text + if (wxTheClipboard->Open()) { wxTextDataObject *data = new wxTextDataObject( text ); bool rc = wxTheClipboard->SetData( data ); +#if wxUSE_PRIVATE_CLIPBOARD_FORMAT + rc |= wxTheClipboard->AddData( &wldo ); +#endif wxTheClipboard->Close(); return rc; } @@ -674,7 +725,7 @@ wxLayoutWindow::Copy(void) bool wxLayoutWindow::Cut(void) { - if(Copy()) + if(Copy(false)) // do not invalidate selection after copy { m_llist->DeleteSelection(); return TRUE; diff --git a/user/wxLayout/wxlwindow.h b/user/wxLayout/wxlwindow.h index 00b50ed3a7..fd913824c8 100644 --- a/user/wxLayout/wxlwindow.h +++ b/user/wxLayout/wxlwindow.h @@ -22,6 +22,9 @@ # define WXLOWIN_MENU_FIRST 12000 #endif + +#define wxUSE_PRIVATE_CLIPBOARD_FORMAT 0 + enum { WXLOWIN_MENU_LARGER = WXLOWIN_MENU_FIRST, @@ -78,10 +81,21 @@ public: void SetEditable(bool toggle) { m_Editable = toggle; } /// Query whether list can be edited by user. 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. void Paste(void); - /// Copies selection to clipboard. - bool Copy(void); + /** Copies selection to clipboard. + @param invalidate used internally, see wxllist.h for details + */ + bool Copy(bool invalidate = true); /// Copies selection to clipboard and deletes it. bool Cut(void); //@} @@ -100,7 +114,7 @@ public: Internally, this stores the parameter and calls a refresh on wxMSW, draws directly on wxGTK. */ - void DoPaint(const wxRect *updateRect); + void DoPaint(const wxRect *updateRect = NULL); #ifdef __WXMSW__ virtual long MSWGetDlgCode(); @@ -177,6 +191,10 @@ protected: int m_maxx; int m_maxy; int m_lineHeight; + /** Visibility parameter for cursor. 0/1 as expected, -1: visible + on demand. + */ + int m_CursorVisibility; private: /// The layout list to be displayed. wxLayoutList *m_llist; -- 2.45.2