Implemented copy-on-demand for wxClipboard.
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@20612 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -19,9 +19,12 @@
|
|||||||
#if wxUSE_CLIPBOARD
|
#if wxUSE_CLIPBOARD
|
||||||
|
|
||||||
class wxDataObject;
|
class wxDataObject;
|
||||||
|
struct wxDataIdToDataObject;
|
||||||
|
|
||||||
#include "wx/list.h"
|
#include "wx/list.h"
|
||||||
|
|
||||||
WX_DECLARE_LIST(wxDataObject, wxDataObjectList);
|
WX_DECLARE_LIST(wxDataObject, wxDataObjectList);
|
||||||
|
WX_DECLARE_LIST(wxDataIdToDataObject, wxDataIdToDataObjectList);
|
||||||
|
|
||||||
bool WXDLLEXPORT wxOpenClipboard();
|
bool WXDLLEXPORT wxOpenClipboard();
|
||||||
bool WXDLLEXPORT wxClipboardOpen();
|
bool WXDLLEXPORT wxClipboardOpen();
|
||||||
@@ -72,11 +75,11 @@ public:
|
|||||||
{ m_usePrimary = primary; }
|
{ m_usePrimary = primary; }
|
||||||
|
|
||||||
// implementation from now on
|
// implementation from now on
|
||||||
|
|
||||||
bool m_open;
|
bool m_open;
|
||||||
wxDataObjectList m_data;
|
wxDataObjectList m_data;
|
||||||
bool m_usePrimary;
|
bool m_usePrimary;
|
||||||
|
wxDataIdToDataObjectList m_idToObject;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DECLARE_DYNAMIC_CLASS(wxClipboard)
|
DECLARE_DYNAMIC_CLASS(wxClipboard)
|
||||||
};
|
};
|
||||||
|
@@ -25,9 +25,6 @@
|
|||||||
#include "wx/dataobj.h"
|
#include "wx/dataobj.h"
|
||||||
#include "wx/ptr_scpd.h"
|
#include "wx/ptr_scpd.h"
|
||||||
|
|
||||||
#include "wx/listimpl.cpp"
|
|
||||||
WX_DEFINE_LIST(wxDataObjectList);
|
|
||||||
|
|
||||||
#ifdef __VMS__
|
#ifdef __VMS__
|
||||||
#pragma message disable nosimpint
|
#pragma message disable nosimpint
|
||||||
#endif
|
#endif
|
||||||
@@ -151,6 +148,25 @@ bool wxGetClipboardFormatName(wxDataFormat dataFormat, char *formatName,
|
|||||||
// wxClipboard
|
// 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);
|
||||||
|
|
||||||
|
static void wxClipboardCallback( Widget widget, long* data_id,
|
||||||
|
long* priv, int* reason );
|
||||||
|
|
||||||
|
|
||||||
IMPLEMENT_DYNAMIC_CLASS(wxClipboard,wxObject)
|
IMPLEMENT_DYNAMIC_CLASS(wxClipboard,wxObject)
|
||||||
|
|
||||||
wxClipboard::wxClipboard()
|
wxClipboard::wxClipboard()
|
||||||
@@ -168,11 +184,15 @@ void wxClipboard::Clear()
|
|||||||
wxDataObjectList::Node* node = m_data.GetFirst();
|
wxDataObjectList::Node* node = m_data.GetFirst();
|
||||||
while (node)
|
while (node)
|
||||||
{
|
{
|
||||||
wxDataObject* data = node->GetData();
|
delete node->GetData();
|
||||||
delete data;
|
|
||||||
node = node->GetNext();
|
node = node->GetNext();
|
||||||
}
|
}
|
||||||
m_data.Clear();
|
m_data.Clear();
|
||||||
|
|
||||||
|
for( wxDataIdToDataObjectList::Node* node2 = m_idToObject.GetFirst();
|
||||||
|
node2; node2 = node2->GetNext() )
|
||||||
|
delete node->GetData();
|
||||||
|
m_idToObject.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxClipboard::Open()
|
bool wxClipboard::Open()
|
||||||
@@ -197,6 +217,42 @@ bool wxClipboard::SetData( wxDataObject *data )
|
|||||||
wxDECLARE_SCOPED_ARRAY( wxDataFormat, wxDataFormatScopedArray );
|
wxDECLARE_SCOPED_ARRAY( wxDataFormat, wxDataFormatScopedArray );
|
||||||
wxDEFINE_SCOPED_ARRAY( wxDataFormat, wxDataFormatScopedArray );
|
wxDEFINE_SCOPED_ARRAY( wxDataFormat, wxDataFormatScopedArray );
|
||||||
|
|
||||||
|
void wxClipboardCallback( Widget xwidget, long* data_id,
|
||||||
|
long* priv, int* reason )
|
||||||
|
{
|
||||||
|
Display* xdisplay = XtDisplay( xwidget );
|
||||||
|
Window xwindow = XtWindow( xwidget );
|
||||||
|
wxDataObject* dobj = NULL;
|
||||||
|
size_t size = 0;
|
||||||
|
|
||||||
|
for( wxDataIdToDataObjectList::Node* 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 )
|
bool wxClipboard::AddData( wxDataObject *data )
|
||||||
{
|
{
|
||||||
wxCHECK_MSG( data, false, "data is invalid" );
|
wxCHECK_MSG( data, false, "data is invalid" );
|
||||||
@@ -205,7 +261,8 @@ bool wxClipboard::AddData( wxDataObject *data )
|
|||||||
m_data.Append( data );
|
m_data.Append( data );
|
||||||
|
|
||||||
Display* xdisplay = wxGlobalDisplay();
|
Display* xdisplay = wxGlobalDisplay();
|
||||||
Window xwindow = XtWindow( (Widget)wxTheApp->GetTopLevelWidget() );
|
Widget xwidget = (Widget)wxTheApp->GetTopLevelWidget();
|
||||||
|
Window xwindow = XtWindow( xwidget );
|
||||||
wxXmString label( wxTheApp->GetAppName() );
|
wxXmString label( wxTheApp->GetAppName() );
|
||||||
Time timestamp = XtLastTimestampProcessed( xdisplay );
|
Time timestamp = XtLastTimestampProcessed( xdisplay );
|
||||||
long itemId;
|
long itemId;
|
||||||
@@ -213,8 +270,8 @@ bool wxClipboard::AddData( wxDataObject *data )
|
|||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
while( ( retval = XmClipboardStartCopy( xdisplay, xwindow, label(),
|
while( ( retval = XmClipboardStartCopy( xdisplay, xwindow, label(),
|
||||||
timestamp, (Widget)NULL,
|
timestamp, xwidget,
|
||||||
(XmCutPasteProc)NULL,
|
wxClipboardCallback,
|
||||||
&itemId ) )
|
&itemId ) )
|
||||||
== XmClipboardLocked );
|
== XmClipboardLocked );
|
||||||
if( retval != XmClipboardSuccess )
|
if( retval != XmClipboardSuccess )
|
||||||
@@ -227,17 +284,15 @@ bool wxClipboard::AddData( wxDataObject *data )
|
|||||||
for( size_t i = 0; i < count; ++i )
|
for( size_t i = 0; i < count; ++i )
|
||||||
{
|
{
|
||||||
size_t size = data->GetDataSize( dfarr[i] );
|
size_t size = data->GetDataSize( dfarr[i] );
|
||||||
wxCharBuffer buffer(size);
|
long data_id;
|
||||||
|
|
||||||
if( !data->GetDataHere( dfarr[i], buffer.data() ) )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
wxString id = dfarr[i].GetId();
|
wxString id = dfarr[i].GetId();
|
||||||
|
|
||||||
while( ( retval = XmClipboardCopy( xdisplay, xwindow, itemId,
|
while( ( retval = XmClipboardCopy( xdisplay, xwindow, itemId,
|
||||||
wxConstCast(id.c_str(), char),
|
wxConstCast(id.c_str(), char),
|
||||||
buffer.data(), size, 0, NULL ) )
|
NULL, size, i, &data_id ) )
|
||||||
== XmClipboardLocked );
|
== XmClipboardLocked );
|
||||||
|
|
||||||
|
m_idToObject.Append( new wxDataIdToDataObject( data, data_id, size ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
while( XmClipboardEndCopy( xdisplay, xwindow, itemId )
|
while( XmClipboardEndCopy( xdisplay, xwindow, itemId )
|
||||||
|
Reference in New Issue
Block a user