]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/clipbrd.cpp
Applied patch [ 709618 ] fixes drawing position in wxPrinterDC::DoBlit()
[wxWidgets.git] / src / gtk / clipbrd.cpp
CommitLineData
dc86cb34 1/////////////////////////////////////////////////////////////////////////////
61b04ac6 2// Name: gtk/clipbrd.cpp
dc86cb34
RR
3// Purpose:
4// Author: Robert Roebling
5// Id: $Id$
6// Copyright: (c) 1998 Robert Roebling
61b04ac6 7// Licence: wxWindows licence
dc86cb34
RR
8/////////////////////////////////////////////////////////////////////////////
9
10#ifdef __GNUG__
11#pragma implementation "clipbrd.h"
12#endif
13
14#include "wx/clipbrd.h"
15
06cfab17 16#if wxUSE_CLIPBOARD
ac57418f 17
e1ee679c 18#include "wx/dataobj.h"
034be888 19#include "wx/utils.h"
b068c4e8 20#include "wx/log.h"
034be888 21
071a2d78
RR
22#include <glib.h>
23#include <gdk/gdk.h>
24#include <gtk/gtk.h>
83624f79 25
b453e1b2
RR
26//-----------------------------------------------------------------------------
27// thread system
28//-----------------------------------------------------------------------------
29
30#if wxUSE_THREADS
b453e1b2
RR
31#endif
32
dc86cb34
RR
33//-----------------------------------------------------------------------------
34// data
35//-----------------------------------------------------------------------------
36
fd0eed64 37GdkAtom g_clipboardAtom = 0;
b527aac5 38GdkAtom g_targetsAtom = 0;
fd0eed64 39
61b04ac6
VZ
40// the trace mask we use with wxLogTrace() - call
41// wxLog::AddTraceMask(TRACE_CLIPBOARD) to enable the trace messages from here
42// (there will be a *lot* of them!)
cbf97a6c 43static const wxChar *TRACE_CLIPBOARD = _T("clipboard");
61b04ac6 44
dc86cb34 45//-----------------------------------------------------------------------------
b527aac5 46// reminder
dc86cb34
RR
47//-----------------------------------------------------------------------------
48
b527aac5 49/* The contents of a selection are returned in a GtkSelectionData
270c23f7 50 structure. selection/target identify the request.
b527aac5
RR
51 type specifies the type of the return; if length < 0, and
52 the data should be ignored. This structure has object semantics -
53 no fields should be modified directly, they should not be created
54 directly, and pointers to them should not be stored beyond the duration of
55 a callback. (If the last is changed, we'll need to add reference
56 counting)
57
58struct _GtkSelectionData
dc86cb34 59{
b527aac5
RR
60 GdkAtom selection;
61 GdkAtom target;
62 GdkAtom type;
61b04ac6 63 gint format;
b527aac5 64 guchar *data;
61b04ac6 65 gint length;
b527aac5
RR
66};
67
68*/
dc86cb34 69
b527aac5
RR
70//-----------------------------------------------------------------------------
71// "selection_received" for targets
72//-----------------------------------------------------------------------------
73
74static void
270c23f7
VZ
75targets_selection_received( GtkWidget *WXUNUSED(widget),
76 GtkSelectionData *selection_data,
034be888 77 guint32 WXUNUSED(time),
66633398 78 wxClipboard *clipboard )
dc86cb34 79{
270c23f7 80 if ( wxTheClipboard && selection_data->length > 0 )
034be888 81 {
ca11abde 82 // make sure we got the data in the correct form
270c23f7
VZ
83 GdkAtom type = selection_data->type;
84 if ( type != GDK_SELECTION_TYPE_ATOM )
85 {
61b04ac6
VZ
86 if ( strcmp(gdk_atom_name(type), "TARGETS") )
87 {
88 wxLogTrace( TRACE_CLIPBOARD,
89 _T("got unsupported clipboard target") );
90
91 clipboard->m_waiting = FALSE;
92 return;
93 }
270c23f7 94 }
b527aac5 95
61b04ac6 96#ifdef __WXDEBUG__
270c23f7 97 wxDataFormat clip( selection_data->selection );
61b04ac6
VZ
98 wxLogTrace( TRACE_CLIPBOARD,
99 wxT("selection received for targets, clipboard %s"),
100 clip.GetId().c_str() );
101#endif // __WXDEBUG__
270c23f7
VZ
102
103 // the atoms we received, holding a list of targets (= formats)
104 GdkAtom *atoms = (GdkAtom *)selection_data->data;
11e1c70d 105
270c23f7 106 for (unsigned int i=0; i<selection_data->length/sizeof(GdkAtom); i++)
8b53e5a2 107 {
270c23f7
VZ
108 wxDataFormat format( atoms[i] );
109
61b04ac6
VZ
110 wxLogTrace( TRACE_CLIPBOARD,
111 wxT("selection received for targets, format %s"),
112 format.GetId().c_str() );
270c23f7 113
ca11abde
RR
114// printf( "format %s requested %s\n",
115// gdk_atom_name( atoms[i] ),
116// gdk_atom_name( clipboard->m_targetRequested ) );
117
270c23f7
VZ
118 if (format == clipboard->m_targetRequested)
119 {
120 clipboard->m_waiting = FALSE;
121 clipboard->m_formatSupported = TRUE;
122 return;
123 }
8b53e5a2
RR
124 }
125 }
b527aac5 126
034be888 127 clipboard->m_waiting = FALSE;
dc86cb34
RR
128}
129
130//-----------------------------------------------------------------------------
b527aac5 131// "selection_received" for the actual data
dc86cb34
RR
132//-----------------------------------------------------------------------------
133
270c23f7
VZ
134static void
135selection_received( GtkWidget *WXUNUSED(widget),
136 GtkSelectionData *selection_data,
034be888 137 guint32 WXUNUSED(time),
66633398 138 wxClipboard *clipboard )
dc86cb34 139{
034be888
RR
140 if (!wxTheClipboard)
141 {
142 clipboard->m_waiting = FALSE;
143 return;
144 }
270c23f7 145
8b53e5a2 146 wxDataObject *data_object = clipboard->m_receivedData;
1dd989e1 147
034be888
RR
148 if (!data_object)
149 {
150 clipboard->m_waiting = FALSE;
151 return;
152 }
270c23f7 153
034be888
RR
154 if (selection_data->length <= 0)
155 {
156 clipboard->m_waiting = FALSE;
157 return;
158 }
270c23f7 159
b068c4e8 160 wxDataFormat format( selection_data->target );
270c23f7 161
ca11abde 162 // make sure we got the data in the correct format
b068c4e8 163 if (!data_object->IsSupportedFormat( format ) )
034be888
RR
164 {
165 clipboard->m_waiting = FALSE;
166 return;
167 }
e2acb9ae 168
034be888
RR
169 /* make sure we got the data in the correct form (selection type).
170 if so, copy data to target object */
e5d6aa22 171 if (selection_data->type != GDK_SELECTION_TYPE_STRING)
8b53e5a2 172 {
e5d6aa22
RR
173 clipboard->m_waiting = FALSE;
174 return;
8b53e5a2 175 }
270c23f7 176
e5d6aa22 177 data_object->SetData( format, (size_t) selection_data->length, (const char*) selection_data->data );
270c23f7 178
8b53e5a2 179 wxTheClipboard->m_formatSupported = TRUE;
034be888 180 clipboard->m_waiting = FALSE;
dc86cb34 181}
fd0eed64
RR
182
183//-----------------------------------------------------------------------------
184// "selection_clear"
185//-----------------------------------------------------------------------------
186
187static gint
aeeb6a44 188selection_clear_clip( GtkWidget *WXUNUSED(widget), GdkEventSelection *event )
fd0eed64 189{
8b53e5a2 190 if (!wxTheClipboard) return TRUE;
270c23f7 191
aeeb6a44
RR
192 if (event->selection == GDK_SELECTION_PRIMARY)
193 {
194 wxTheClipboard->m_ownsPrimarySelection = FALSE;
195 }
196 else
197 if (event->selection == g_clipboardAtom)
198 {
199 wxTheClipboard->m_ownsClipboard = FALSE;
200 }
201 else
202 {
e5ea3f7a 203 wxTheClipboard->m_waiting = FALSE;
aeeb6a44
RR
204 return FALSE;
205 }
270c23f7 206
aeeb6a44
RR
207 if ((!wxTheClipboard->m_ownsPrimarySelection) &&
208 (!wxTheClipboard->m_ownsClipboard))
209 {
db2d879a 210 /* the clipboard is no longer in our hands. we can the delete clipboard data. */
1dd989e1 211 if (wxTheClipboard->m_data)
66633398 212 {
47cf53ef 213 wxLogTrace(TRACE_CLIPBOARD, wxT("wxClipboard will get cleared" ));
270c23f7 214
66633398
VZ
215 delete wxTheClipboard->m_data;
216 wxTheClipboard->m_data = (wxDataObject*) NULL;
217 }
aeeb6a44 218 }
270c23f7 219
e5ea3f7a 220 wxTheClipboard->m_waiting = FALSE;
8b53e5a2 221 return TRUE;
fd0eed64
RR
222}
223
224//-----------------------------------------------------------------------------
225// selection handler for supplying data
226//-----------------------------------------------------------------------------
227
228static void
19d89516
VZ
229selection_handler( GtkWidget *WXUNUSED(widget),
230 GtkSelectionData *selection_data,
231 guint WXUNUSED(info),
232 guint WXUNUSED(time),
233 gpointer WXUNUSED(data) )
fd0eed64 234{
8b53e5a2 235 if (!wxTheClipboard) return;
270c23f7 236
1dd989e1 237 if (!wxTheClipboard->m_data) return;
270c23f7 238
1dd989e1 239 wxDataObject *data = wxTheClipboard->m_data;
270c23f7 240
b068c4e8
RR
241 wxDataFormat format( selection_data->target );
242
243 if (!data->IsSupportedFormat( format )) return;
270c23f7 244
b068c4e8 245 int size = data->GetDataSize( format );
270c23f7 246
1dd989e1 247 if (size == 0) return;
270c23f7 248
33754c4d
VZ
249 void *d = malloc(size);
250
ca11abde 251 // Text data will be in UTF8 in Unicode mode.
33754c4d 252 data->GetDataHere( selection_data->target, d );
270c23f7 253
270c23f7
VZ
254 gtk_selection_data_set(
255 selection_data,
256 GDK_SELECTION_TYPE_STRING,
257 8*sizeof(gchar),
66633398 258 (unsigned char*) d,
270c23f7 259 size );
33754c4d
VZ
260
261 free(d);
fd0eed64 262}
dc86cb34
RR
263
264//-----------------------------------------------------------------------------
265// wxClipboard
266//-----------------------------------------------------------------------------
267
268IMPLEMENT_DYNAMIC_CLASS(wxClipboard,wxObject)
269
270wxClipboard::wxClipboard()
271{
8b53e5a2
RR
272 m_open = FALSE;
273
aeeb6a44
RR
274 m_ownsClipboard = FALSE;
275 m_ownsPrimarySelection = FALSE;
276
1dd989e1 277 m_data = (wxDataObject*) NULL;
8b53e5a2 278 m_receivedData = (wxDataObject*) NULL;
99c67c77 279
034be888 280 /* we use m_targetsWidget to query what formats are available */
270c23f7 281
034be888
RR
282 m_targetsWidget = gtk_window_new( GTK_WINDOW_POPUP );
283 gtk_widget_realize( m_targetsWidget );
284
270c23f7 285 gtk_signal_connect( GTK_OBJECT(m_targetsWidget),
034be888 286 "selection_received",
270c23f7 287 GTK_SIGNAL_FUNC( targets_selection_received ),
66633398 288 (gpointer) this );
270c23f7 289
034be888 290 /* we use m_clipboardWidget to get and to offer data */
270c23f7 291
8b53e5a2
RR
292 m_clipboardWidget = gtk_window_new( GTK_WINDOW_POPUP );
293 gtk_widget_realize( m_clipboardWidget );
294
270c23f7 295 gtk_signal_connect( GTK_OBJECT(m_clipboardWidget),
034be888 296 "selection_received",
270c23f7 297 GTK_SIGNAL_FUNC( selection_received ),
66633398 298 (gpointer) this );
034be888 299
270c23f7 300 gtk_signal_connect( GTK_OBJECT(m_clipboardWidget),
8b53e5a2 301 "selection_clear_event",
270c23f7 302 GTK_SIGNAL_FUNC( selection_clear_clip ),
66633398 303 (gpointer) NULL );
270c23f7 304
8b53e5a2 305 if (!g_clipboardAtom) g_clipboardAtom = gdk_atom_intern( "CLIPBOARD", FALSE );
8b53e5a2 306 if (!g_targetsAtom) g_targetsAtom = gdk_atom_intern ("TARGETS", FALSE);
270c23f7 307
8b53e5a2
RR
308 m_formatSupported = FALSE;
309 m_targetRequested = 0;
270c23f7 310
7e2c43b8 311 m_usePrimary = FALSE;
dc86cb34
RR
312}
313
314wxClipboard::~wxClipboard()
b527aac5 315{
270c23f7
VZ
316 Clear();
317
8b53e5a2 318 if (m_clipboardWidget) gtk_widget_destroy( m_clipboardWidget );
034be888 319 if (m_targetsWidget) gtk_widget_destroy( m_targetsWidget );
b527aac5
RR
320}
321
322void wxClipboard::Clear()
dc86cb34 323{
1dd989e1
RR
324 if (m_data)
325 {
b453e1b2
RR
326#if wxUSE_THREADS
327 /* disable GUI threads */
b453e1b2 328#endif
270c23f7 329
ca11abde
RR
330 // As we have data we also own the clipboard. Once we no longer own
331 // it, clear_selection is called which will set m_data to zero
aeeb6a44 332 if (gdk_selection_owner_get( g_clipboardAtom ) == m_clipboardWidget->window)
8b53e5a2 333 {
e5ea3f7a 334 m_waiting = TRUE;
270c23f7 335
b02da6b1
VZ
336 gtk_selection_owner_set( (GtkWidget*) NULL, g_clipboardAtom,
337 (guint32) GDK_CURRENT_TIME );
270c23f7 338
e5ea3f7a 339 while (m_waiting) gtk_main_iteration();
8b53e5a2 340 }
270c23f7 341
aeeb6a44
RR
342 if (gdk_selection_owner_get( GDK_SELECTION_PRIMARY ) == m_clipboardWidget->window)
343 {
e5ea3f7a 344 m_waiting = TRUE;
270c23f7 345
b02da6b1
VZ
346 gtk_selection_owner_set( (GtkWidget*) NULL, GDK_SELECTION_PRIMARY,
347 (guint32) GDK_CURRENT_TIME );
270c23f7 348
e5ea3f7a 349 while (m_waiting) gtk_main_iteration();
aeeb6a44 350 }
270c23f7 351
1dd989e1 352 if (m_data)
270c23f7 353 {
66633398
VZ
354 delete m_data;
355 m_data = (wxDataObject*) NULL;
356 }
270c23f7 357
b453e1b2
RR
358#if wxUSE_THREADS
359 /* re-enable GUI threads */
b453e1b2 360#endif
8b53e5a2 361 }
270c23f7 362
8b53e5a2 363 m_targetRequested = 0;
8b53e5a2
RR
364 m_formatSupported = FALSE;
365}
366
367bool wxClipboard::Open()
368{
223d09f6 369 wxCHECK_MSG( !m_open, FALSE, wxT("clipboard already open") );
270c23f7 370
8b53e5a2 371 m_open = TRUE;
270c23f7 372
8b53e5a2 373 return TRUE;
dc86cb34
RR
374}
375
75ce0581 376bool wxClipboard::SetData( wxDataObject *data )
dc86cb34 377{
223d09f6 378 wxCHECK_MSG( m_open, FALSE, wxT("clipboard not open") );
270c23f7 379
223d09f6 380 wxCHECK_MSG( data, FALSE, wxT("data is invalid") );
270c23f7 381
0d2a2b60 382 Clear();
75ce0581
RR
383
384 return AddData( data );
385}
386
387bool wxClipboard::AddData( wxDataObject *data )
388{
223d09f6 389 wxCHECK_MSG( m_open, FALSE, wxT("clipboard not open") );
270c23f7 390
223d09f6 391 wxCHECK_MSG( data, FALSE, wxT("data is invalid") );
270c23f7 392
ca11abde 393 // we can only store one wxDataObject
1dd989e1 394 Clear();
270c23f7 395
1dd989e1
RR
396 m_data = data;
397
ca11abde 398 // get formats from wxDataObjects
b068c4e8
RR
399 wxDataFormat *array = new wxDataFormat[ m_data->GetFormatCount() ];
400 m_data->GetAllFormats( array );
11e1c70d 401
ca11abde 402 // primary selection or clipboard
11e1c70d
RR
403 GdkAtom clipboard = m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY
404 : g_clipboardAtom;
405
270c23f7 406
b068c4e8
RR
407 for (size_t i = 0; i < m_data->GetFormatCount(); i++)
408 {
61b04ac6
VZ
409 wxLogTrace( TRACE_CLIPBOARD,
410 wxT("wxClipboard now supports atom %s"),
411 array[i].GetId().c_str() );
11e1c70d 412
ca11abde
RR
413// printf( "added %s\n",
414// gdk_atom_name( array[i].GetFormatId() ) );
415
11e1c70d 416 gtk_selection_add_target( GTK_WIDGET(m_clipboardWidget),
270c23f7
VZ
417 clipboard,
418 array[i],
11e1c70d 419 0 ); /* what is info ? */
b068c4e8
RR
420 }
421
422 delete[] array;
270c23f7
VZ
423
424 gtk_signal_connect( GTK_OBJECT(m_clipboardWidget),
d345e841 425 "selection_get",
270c23f7 426 GTK_SIGNAL_FUNC(selection_handler),
66633398 427 (gpointer) NULL );
d345e841 428
b453e1b2 429#if wxUSE_THREADS
11e1c70d 430 /* disable GUI threads */
b453e1b2 431#endif
270c23f7 432
75ce0581 433 /* Tell the world we offer clipboard data */
11e1c70d
RR
434 bool res = (gtk_selection_owner_set( m_clipboardWidget,
435 clipboard,
b02da6b1 436 (guint32) GDK_CURRENT_TIME ));
270c23f7 437
11e1c70d
RR
438 if (m_usePrimary)
439 m_ownsPrimarySelection = res;
440 else
441 m_ownsClipboard = res;
270c23f7 442
b453e1b2
RR
443#if wxUSE_THREADS
444 /* re-enable GUI threads */
b453e1b2 445#endif
270c23f7 446
11e1c70d 447 return res;
8b53e5a2 448}
db1b4961 449
8b53e5a2
RR
450void wxClipboard::Close()
451{
223d09f6 452 wxCHECK_RET( m_open, wxT("clipboard not open") );
270c23f7 453
8b53e5a2 454 m_open = FALSE;
dc86cb34
RR
455}
456
f536e0f2
VZ
457bool wxClipboard::IsOpened() const
458{
459 return m_open;
460}
461
e1ee679c 462bool wxClipboard::IsSupported( const wxDataFormat& format )
b527aac5 463{
e5d6aa22 464 /* reentrance problems */
eff869aa 465 if (m_waiting) return FALSE;
270c23f7 466
e5d6aa22 467 /* store requested format to be asked for by callbacks */
1dd989e1 468 m_targetRequested = format;
270c23f7 469
72a7edf0 470#if 0
61b04ac6
VZ
471 wxLogTrace( TRACE_CLIPBOARD,
472 wxT("wxClipboard:IsSupported: requested format: %s"),
473 format.GetId().c_str() );
72a7edf0 474#endif
eff869aa 475
223d09f6 476 wxCHECK_MSG( m_targetRequested, FALSE, wxT("invalid clipboard format") );
270c23f7 477
8b53e5a2 478 m_formatSupported = FALSE;
270c23f7
VZ
479
480 /* perform query. this will set m_formatSupported to
034be888 481 TRUE if m_targetRequested is supported.
270c23f7 482 also, we have to wait for the "answer" from the
034be888
RR
483 clipboard owner which is an asynchronous process.
484 therefore we set m_waiting = TRUE here and wait
270c23f7 485 until the callback "targets_selection_received"
034be888
RR
486 sets it to FALSE */
487
488 m_waiting = TRUE;
ca35e608 489
034be888 490 gtk_selection_convert( m_targetsWidget,
66633398 491 m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY
270c23f7 492 : g_clipboardAtom,
66633398 493 g_targetsAtom,
b02da6b1 494 (guint32) GDK_CURRENT_TIME );
ca35e608 495
034be888 496 while (m_waiting) gtk_main_iteration();
270c23f7 497
8b53e5a2 498 if (!m_formatSupported) return FALSE;
270c23f7 499
75ce0581 500 return TRUE;
270c23f7
VZ
501}
502
e1ee679c 503bool wxClipboard::GetData( wxDataObject& data )
75ce0581 504{
223d09f6 505 wxCHECK_MSG( m_open, FALSE, wxT("clipboard not open") );
270c23f7 506
b068c4e8
RR
507 /* get formats from wxDataObjects */
508 wxDataFormat *array = new wxDataFormat[ data.GetFormatCount() ];
509 data.GetAllFormats( array );
270c23f7 510
b068c4e8
RR
511 for (size_t i = 0; i < data.GetFormatCount(); i++)
512 {
e5d6aa22 513 wxDataFormat format( array[i] );
270c23f7 514
61b04ac6
VZ
515 wxLogTrace( TRACE_CLIPBOARD,
516 wxT("wxClipboard::GetData: requested format: %s"),
517 format.GetId().c_str() );
270c23f7 518
b068c4e8 519 /* is data supported by clipboard ? */
270c23f7 520
11e1c70d
RR
521 /* store requested format to be asked for by callbacks */
522 m_targetRequested = format;
270c23f7 523
11e1c70d 524 wxCHECK_MSG( m_targetRequested, FALSE, wxT("invalid clipboard format") );
270c23f7 525
11e1c70d 526 m_formatSupported = FALSE;
270c23f7
VZ
527
528 /* perform query. this will set m_formatSupported to
11e1c70d 529 TRUE if m_targetRequested is supported.
270c23f7 530 also, we have to wait for the "answer" from the
11e1c70d
RR
531 clipboard owner which is an asynchronous process.
532 therefore we set m_waiting = TRUE here and wait
270c23f7 533 until the callback "targets_selection_received"
11e1c70d
RR
534 sets it to FALSE */
535
536 m_waiting = TRUE;
537
538 gtk_selection_convert( m_targetsWidget,
539 m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY
270c23f7 540 : g_clipboardAtom,
11e1c70d 541 g_targetsAtom,
b02da6b1 542 (guint32) GDK_CURRENT_TIME );
11e1c70d
RR
543
544 while (m_waiting) gtk_main_iteration();
270c23f7 545
11e1c70d 546 if (!m_formatSupported) continue;
270c23f7 547
b068c4e8
RR
548 /* store pointer to data object to be filled up by callbacks */
549 m_receivedData = &data;
270c23f7 550
b068c4e8 551 /* store requested format to be asked for by callbacks */
e5d6aa22 552 m_targetRequested = format;
270c23f7 553
b068c4e8 554 wxCHECK_MSG( m_targetRequested, FALSE, wxT("invalid clipboard format") );
270c23f7 555
b068c4e8
RR
556 /* start query */
557 m_formatSupported = FALSE;
270c23f7
VZ
558
559 /* ask for clipboard contents. this will set
560 m_formatSupported to TRUE if m_targetRequested
b068c4e8 561 is supported.
270c23f7 562 also, we have to wait for the "answer" from the
b068c4e8
RR
563 clipboard owner which is an asynchronous process.
564 therefore we set m_waiting = TRUE here and wait
270c23f7 565 until the callback "targets_selection_received"
b068c4e8
RR
566 sets it to FALSE */
567
568 m_waiting = TRUE;
569
47cf53ef
VZ
570 wxLogTrace( TRACE_CLIPBOARD,
571 wxT("wxClipboard::GetData: format found, start convert") );
270c23f7 572
b068c4e8 573 gtk_selection_convert( m_clipboardWidget,
66633398 574 m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY
270c23f7 575 : g_clipboardAtom,
66633398 576 m_targetRequested,
b02da6b1 577 (guint32) GDK_CURRENT_TIME );
270c23f7 578
b068c4e8 579 while (m_waiting) gtk_main_iteration();
b527aac5 580
b068c4e8
RR
581 /* this is a true error as we checked for the presence of such data before */
582 wxCHECK_MSG( m_formatSupported, FALSE, wxT("error retrieving data from clipboard") );
270c23f7 583
66633398 584 /* return success */
b068c4e8
RR
585 delete[] array;
586 return TRUE;
587 }
270c23f7 588
47cf53ef
VZ
589 wxLogTrace( TRACE_CLIPBOARD,
590 wxT("wxClipboard::GetData: format not found") );
270c23f7 591
b068c4e8
RR
592 /* return failure */
593 delete[] array;
594 return FALSE;
b527aac5
RR
595}
596
ac57418f 597#endif
ac57418f
RR
598 // wxUSE_CLIPBOARD
599