]> git.saurik.com Git - wxWidgets.git/blobdiff - src/motif/clipbrd.cpp
Use type safe list for model notifiers, sample corrected
[wxWidgets.git] / src / motif / clipbrd.cpp
index 17f2e17e277dd7fbfc5a3d3d6d776635ec2b9f2c..df66c9c41759704e59ff2c85370d56c5440fcaa5 100644 (file)
@@ -1,35 +1,42 @@
 /////////////////////////////////////////////////////////////////////////////
-// Name:        clipbrd.cpp
+// Name:        src/motif/clipbrd.cpp
 // Purpose:     Clipboard functionality
 // Author:      Julian Smart
 // Modified by: Mattia Barbon (added support for generic wxDataObjects)
 // Created:     17/09/98
 // RCS-ID:      $Id$
 // Copyright:   (c) Julian Smart
-// Licence:    wxWindows licence
+// Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
-#ifdef __GNUG__
-#pragma implementation
-#pragma implementation "clipbrd.h"
-#endif
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
 
-#include "wx/defs.h"
+#ifdef __VMS
+#include "wx/vms_x_fix.h"
+#define XtWindow XTWINDOW
+#define XtScreen XTSCREEN
+#define XtParent XTPARENT
+#define XtIsRealized XTISREALIZED
+#define XtDisplay XTDISPLAY
+#endif
 
 #if wxUSE_CLIPBOARD
 
-#include "wx/app.h"
-#include "wx/bitmap.h"
-#include "wx/utils.h"
 #include "wx/clipbrd.h"
-#include "wx/dataobj.h"
-#include "wx/ptr_scpd.h"
 
-#include "wx/listimpl.cpp"
-WX_DEFINE_LIST(wxDataObjectList);
+#ifndef WX_PRECOMP
+    #include "wx/app.h"
+    #include "wx/utils.h"
+    #include "wx/bitmap.h"
+    #include "wx/dataobj.h"
+#endif
+
+#include "wx/ptr_scpd.h"
 
 #ifdef __VMS__
 #pragma message disable nosimpint
+
 #endif
 #include <Xm/Xm.h>
 #include <Xm/CutPaste.h>
@@ -62,7 +69,7 @@ bool wxClipboardOpen()
     return wxTheClipboard->IsOpened();
 }
 
-bool wxIsClipboardFormatAvailable(wxDataFormat dataFormat)
+bool wxIsClipboardFormatAvailable(const wxDataFormat& dataFormat)
 {
     return wxTheClipboard->IsSupported( dataFormat );
 }
@@ -124,7 +131,7 @@ wxObject *wxGetClipboardData(wxDataFormat dataFormat, long *len)
     return NULL; // just in case...
 }
 
-wxDataFormat wxEnumClipboardFormats(wxDataFormat dataFormat)
+wxDataFormat wxEnumClipboardFormats(const wxDataFormat& dataFormat)
 {
     // Only wxDF_TEXT supported
     if (dataFormat == wxDF_TEXT)
@@ -139,7 +146,7 @@ wxDataFormat wxRegisterClipboardFormat(char *WXUNUSED(formatName))
     return wxDF_INVALID;
 }
 
-bool wxGetClipboardFormatName(wxDataFormat dataFormat, char *formatName,
+bool wxGetClipboardFormatName(const wxDataFormat& dataFormat, char *formatName,
                               int maxCount)
 {
     wxStrncpy( formatName, dataFormat.GetId().c_str(), maxCount );
@@ -151,6 +158,32 @@ bool wxGetClipboardFormatName(wxDataFormat dataFormat, char *formatName,
 // wxClipboard
 //-----------------------------------------------------------------------------
 
+struct wxDataIdToDataObject
+{
+    wxDataIdToDataObject( wxDataObject* o, long d, size_t s )
+        : object( o ), size( s ), dataId( d ) { }
+
+    wxDataObject* object;
+    size_t        size;
+    long          dataId;
+};
+
+#include "wx/listimpl.cpp"
+
+WX_DEFINE_LIST(wxDataObjectList)
+WX_DEFINE_LIST(wxDataIdToDataObjectList)
+
+extern "C"
+{
+#if wxCHECK_LESSTIF()
+static void wxClipboardCallback( Widget widget, int* data_id,
+                                 int* priv, int* reason );
+#else // Motif
+static void wxClipboardCallback( Widget widget, long* data_id,
+                                 long* priv, int* reason );
+#endif // Less/Motif
+}
+
 IMPLEMENT_DYNAMIC_CLASS(wxClipboard,wxObject)
 
 wxClipboard::wxClipboard()
@@ -160,25 +193,31 @@ wxClipboard::wxClipboard()
 
 wxClipboard::~wxClipboard()
 {
-    Clear();  
+    Clear();
 }
 
 void wxClipboard::Clear()
 {
-    wxDataObjectList::Node* node = m_data.GetFirst();
+    wxDataObjectList::compatibility_iterator node = m_data.GetFirst();
     while (node)
     {
-        wxDataObject* data = node->GetData();
-        delete data;
+        delete node->GetData();
         node = node->GetNext();
     }
     m_data.Clear();
+
+    for( wxDataIdToDataObjectList::compatibility_iterator node2 = m_idToObject.GetFirst();
+         node2; node2 = node2->GetNext() )
+    {
+        delete node2->GetData();
+    }
+    m_idToObject.Clear();
 }
 
 bool wxClipboard::Open()
 {
     wxCHECK_MSG( !m_open, false, "clipboard already open" );
-  
+
     m_open = true;
 
     return true;
@@ -194,8 +233,49 @@ bool wxClipboard::SetData( wxDataObject *data )
     return AddData( data );
 }
 
-wxDECLARE_SCOPED_ARRAY( wxDataFormat, wxDataFormatScopedArray );
-wxDEFINE_SCOPED_ARRAY( wxDataFormat, wxDataFormatScopedArray );
+wxDECLARE_SCOPED_ARRAY( wxDataFormat, wxDataFormatScopedArray )
+wxDEFINE_SCOPED_ARRAY( wxDataFormat, wxDataFormatScopedArray )
+
+#if wxCHECK_LESSTIF()
+void wxClipboardCallback( Widget xwidget, int* data_id,
+                          int* priv, int* WXUNUSED(reason) )
+#else
+void wxClipboardCallback( Widget xwidget, long* data_id,
+                          long* priv, int* WXUNUSED(reason) )
+#endif
+{
+    Display* xdisplay = XtDisplay( xwidget );
+    Window xwindow = XtWindow( xwidget );
+    wxDataObject* dobj = NULL;
+    size_t size = 0;
+
+    for( wxDataIdToDataObjectList::compatibility_iterator node2 =
+             wxTheClipboard->m_idToObject.GetFirst();
+         node2; node2 = node2->GetNext() )
+    {
+        wxDataIdToDataObject* dido = node2->GetData();
+        if( dido->dataId == *data_id )
+        {
+            dobj = dido->object;
+            size = dido->size;
+            break;
+        }
+    }
+
+    if( !dobj ) return;
+
+    wxCharBuffer buffer(size);
+    size_t count = dobj->GetFormatCount( wxDataObject::Get );
+    wxDataFormatScopedArray dfarr( new wxDataFormat[count] );
+    dobj->GetAllFormats( dfarr.get(), wxDataObject::Get );
+
+    if( !dobj->GetDataHere( dfarr[*priv], buffer.data() ) )
+        return;
+
+    while( XmClipboardCopyByName( xdisplay, xwindow, *data_id,
+                                  buffer.data(), size, 0 )
+           == XmClipboardLocked );
+}
 
 bool wxClipboard::AddData( wxDataObject *data )
 {
@@ -205,7 +285,8 @@ bool wxClipboard::AddData( wxDataObject *data )
     m_data.Append( data );
 
     Display* xdisplay = wxGlobalDisplay();
-    Window xwindow = XtWindow( (Widget)wxTheApp->GetTopLevelWidget() );
+    Widget xwidget = (Widget)wxTheApp->GetTopLevelRealizedWidget();
+    Window xwindow = XtWindow( xwidget );
     wxXmString label( wxTheApp->GetAppName() );
     Time timestamp = XtLastTimestampProcessed( xdisplay );
     long itemId;
@@ -213,8 +294,8 @@ bool wxClipboard::AddData( wxDataObject *data )
     int retval;
 
     while( ( retval = XmClipboardStartCopy( xdisplay, xwindow, label(),
-                                            timestamp, (Widget)NULL,
-                                            (XmCutPasteProc)NULL,
+                                            timestamp, xwidget,
+                                            wxClipboardCallback,
                                             &itemId ) )
            == XmClipboardLocked );
     if( retval != XmClipboardSuccess )
@@ -227,17 +308,15 @@ bool wxClipboard::AddData( wxDataObject *data )
     for( size_t i = 0; i < count; ++i )
     {
         size_t size = data->GetDataSize( dfarr[i] );
-        wxCharBuffer buffer(size);
-
-        if( !data->GetDataHere( dfarr[i], buffer.data() ) )
-            continue;
-
+        long data_id;
         wxString id = dfarr[i].GetId();
 
         while( ( retval = XmClipboardCopy( xdisplay, xwindow, itemId,
-                                           wxConstCast(id.c_str(), char),
-                                           buffer.data(), size, 0, NULL ) )
+                                           id.char_str(),
+                                           NULL, size, i, &data_id ) )
                == XmClipboardLocked );
+
+        m_idToObject.Append( new wxDataIdToDataObject( data, data_id, size ) );
     }
 
     while( XmClipboardEndCopy( xdisplay, xwindow, itemId )
@@ -249,14 +328,14 @@ bool wxClipboard::AddData( wxDataObject *data )
 void wxClipboard::Close()
 {
     wxCHECK_RET( m_open, "clipboard not open" );
-    
+
     m_open = false;
 }
 
 bool wxClipboard::IsSupported(const wxDataFormat& format)
 {
     Display* xdisplay = wxGlobalDisplay();
-    Window xwindow = XtWindow( (Widget)wxTheApp->GetTopLevelWidget() );
+    Window xwindow = XtWindow( (Widget)wxTheApp->GetTopLevelRealizedWidget() );
     bool isSupported = false;
     int retval, count;
     unsigned long  max_name_length;
@@ -316,7 +395,7 @@ bool wxClipboard::GetData( wxDataObject& data )
     wxCHECK_MSG( m_open, false, "clipboard not open" );
 
     Display* xdisplay = wxGlobalDisplay();
-    Window xwindow = XtWindow( (Widget)wxTheApp->GetTopLevelWidget() );
+    Window xwindow = XtWindow( (Widget)wxTheApp->GetTopLevelRealizedWidget() );
     Time timestamp = XtLastTimestampProcessed( xdisplay );
 
     wxDataFormat chosenFormat;
@@ -338,7 +417,7 @@ bool wxClipboard::GetData( wxDataObject& data )
     size_t dfcount = data.GetFormatCount( wxDataObject::Set );
     wxDataFormatScopedArray dfarr( new wxDataFormat[dfcount] );
     data.GetAllFormats( dfarr.get(), wxDataObject::Set );
-    
+
     if( XmClipboardInquireCount( xdisplay, xwindow, &count, &max_name_length )
         == XmClipboardSuccess )
     {
@@ -382,7 +461,7 @@ bool wxClipboard::GetData( wxDataObject& data )
     wxString id = chosenFormat.GetId();
 
     while( ( retval = XmClipboardInquireLength( xdisplay, xwindow,
-                                                wxConstCast(id.c_str(), char),
+                                                id.char_str(),
                                                 &length ) )
            == XmClipboardLocked );
     if( retval != XmClipboardSuccess )
@@ -391,7 +470,7 @@ bool wxClipboard::GetData( wxDataObject& data )
     wxCharBuffer buf(length);
 
     while( ( retval = XmClipboardRetrieve( xdisplay, xwindow,
-                                           wxConstCast(id.c_str(), char),
+                                           id.char_str(),
                                            (XtPointer)buf.data(),
                                            length, &dummy1, &dummy2 ) )
            == XmClipboardLocked );