]> git.saurik.com Git - wxWidgets.git/commitdiff
Many, many updates. Almost perfect.
authorKarsten Ballüder <ballueder@usa.net>
Sun, 16 May 1999 23:10:40 +0000 (23:10 +0000)
committerKarsten Ballüder <ballueder@usa.net>
Sun, 16 May 1999 23:10:40 +0000 (23:10 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@2476 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

user/wxLayout/TODO
user/wxLayout/wxLayout.cpp
user/wxLayout/wxllist.cpp
user/wxLayout/wxllist.h
user/wxLayout/wxlparser.cpp
user/wxLayout/wxlwindow.cpp
user/wxLayout/wxlwindow.h

index 36c27bcfce3f095470720da131936c18d94d16d9..932d6e93d47953955f20555da983ac5437d4cdbd 100644 (file)
@@ -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. 
index 42665629241b789b6322173d26a42510aae433ad..b7df97f28afc35e1f3dd68b91ad4f65c68ee10af 100644 (file)
@@ -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();
index a56aad668dba31291d8c81179b69cd5dfd87997b..9d55127fdd5ac5c35fb8ef9f68f1d17a1bd8f4bf 100644 (file)
@@ -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   <wx/dcps.h>
 #   include   <wx/print.h>
 #   include   <wx/log.h>
+#   include   <wx/filefn.h>
 #endif
 
 #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
@@ -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;
 }
 
 
index a9cf311850f7bd06edaad384f286f7ef62e28711..7edbcbbdff0e06c9861b3ded03548b06e22131da 100644 (file)
@@ -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
 #   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);
+      }
+};
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    
index ebd8be4aeef1e4459b8bfaabc9d59c7603ee3668..b93f39e473ad8ac892e2ddb5fc0c9586c677e07a 100644 (file)
@@ -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
          ;
index c60e6d11c84f1562fdddb0214e5d18f881444aad..cc63534cb7654499e71aee39cd813400a0a01cf1 100644 (file)
@@ -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;
index 00b50ed3a7071b45b640137e97eada6ee580db30..fd913824c8c0443d0d494d4409444f0abf63682b 100644 (file)
@@ -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;