]> git.saurik.com Git - wxWidgets.git/blame - src/mac/carbon/clipbrd.cpp
cleanup
[wxWidgets.git] / src / mac / carbon / clipbrd.cpp
CommitLineData
e9576ca5 1/////////////////////////////////////////////////////////////////////////////
3e822cd8 2// Name: src/mac/carbon/clipbrd.cpp
e9576ca5 3// Purpose: Clipboard functionality
3e822cd8 4// Author: Stefan Csomor;
de6185e2 5// Generalized clipboard implementation by Matthew Flatt
e9576ca5 6// Modified by:
a31a5f85 7// Created: 1998-01-01
e9576ca5 8// RCS-ID: $Id$
a31a5f85 9// Copyright: (c) Stefan Csomor
65571936 10// Licence: wxWindows licence
e9576ca5
SC
11/////////////////////////////////////////////////////////////////////////////
12
a8e9860d
SC
13#include "wx/wxprec.h"
14
179e085f
RN
15#if wxUSE_CLIPBOARD
16
88a7a4e1
WS
17#include "wx/clipbrd.h"
18
19#ifndef WX_PRECOMP
20 #include "wx/intl.h"
e4db172a 21 #include "wx/log.h"
670f9935 22 #include "wx/app.h"
de6185e2 23 #include "wx/utils.h"
76b49cf4 24 #include "wx/frame.h"
0bca0373 25 #include "wx/bitmap.h"
88a7a4e1
WS
26#endif
27
e9576ca5 28#include "wx/metafile.h"
e9576ca5 29
9c3c5849 30#include "wx/mac/uma.h"
76a5e5d2 31
2f1ae414
SC
32#define wxUSE_DATAOBJ 1
33
e9576ca5
SC
34#include <string.h>
35
3e822cd8 36
f0822896
SC
37// the trace mask we use with wxLogTrace() - call
38// wxLog::AddTraceMask(TRACE_CLIPBOARD) to enable the trace messages from here
39// (there will be a *lot* of them!)
3e822cd8
DS
40static const wxChar *TRACE_CLIPBOARD = wxT("clipboard");
41
6239ee05
SC
42IMPLEMENT_DYNAMIC_CLASS(wxClipboard, wxObject)
43
44// in order to keep the binary interface the same this class
45// serves just to have a few additional member variables inside
46// the clipboard class
2f1ae414 47
6239ee05 48class wxMacBinaryCompatHelper : public wxDataObject
e9576ca5 49{
6239ee05
SC
50public :
51 wxMacBinaryCompatHelper()
2f1ae414 52 {
6239ee05 53 m_trueData = NULL;
97af5088 54 }
e135f093 55
6239ee05 56 ~wxMacBinaryCompatHelper()
ed60b502 57 {
6239ee05
SC
58 if (m_trueData != NULL)
59 {
60 delete m_trueData;
61 m_trueData = NULL;
62 }
63 }
e135f093 64
6239ee05 65 virtual wxDataFormat GetPreferredFormat(Direction dir = Get) const
ed60b502 66 {
6239ee05
SC
67 return wxDataFormat();
68 }
e135f093 69
6239ee05 70 virtual size_t GetFormatCount(Direction dir = Get) const
e40298d5 71 {
6239ee05 72 return 0;
99b62b5f 73 }
6239ee05
SC
74
75 virtual void GetAllFormats(wxDataFormat *formats,
76 Direction dir = Get) const
e40298d5 77 {
ed60b502 78 }
e135f093 79
6239ee05 80 virtual size_t GetDataSize(const wxDataFormat& format) const
ed60b502 81 {
6239ee05 82 return 0;
ed60b502 83 }
3e822cd8 84
6239ee05 85 virtual bool GetDataHere(const wxDataFormat& format, void *buf) const
97af5088 86 {
6239ee05 87 return false;
97af5088 88 }
427ff662 89
6239ee05 90 // only relevant from here on
427ff662 91
6239ee05
SC
92 wxDataObject* m_trueData;
93 wxCFRef<PasteboardRef> m_pasteboard;
94};
2f1ae414 95
6239ee05 96#define M_CLIPBOARD ((wxMacBinaryCompatHelper*)m_data)
7c74e7fe 97
e7549107
SC
98wxClipboard::wxClipboard()
99{
3e822cd8 100 m_open = false;
6239ee05
SC
101 m_data = new wxMacBinaryCompatHelper() ;
102 PasteboardRef clipboard = 0;
103 OSStatus err = PasteboardCreate( kPasteboardClipboard, &clipboard );
104 if (err != noErr)
105 {
106 wxLogSysError( wxT("Failed to create the clipboard.") );
107 }
108 M_CLIPBOARD->m_pasteboard.reset(clipboard);
e7549107 109}
e9576ca5 110
e7549107 111wxClipboard::~wxClipboard()
e9576ca5 112{
6239ee05 113 M_CLIPBOARD->m_pasteboard.reset((PasteboardRef)0);
f0822896 114 delete m_data;
e9576ca5
SC
115}
116
e7549107 117void wxClipboard::Clear()
e9576ca5 118{
6239ee05 119 if (M_CLIPBOARD->m_trueData != NULL)
f0822896 120 {
6239ee05
SC
121 delete M_CLIPBOARD->m_trueData;
122 M_CLIPBOARD->m_trueData = NULL;
f0822896 123 }
3e822cd8 124
6239ee05 125 OSStatus err = PasteboardClear( M_CLIPBOARD->m_pasteboard );
3e822cd8 126 if (err != noErr)
ed60b502 127 {
3e822cd8 128 wxLogSysError( wxT("Failed to empty the clipboard.") );
ed60b502 129 }
e9576ca5
SC
130}
131
e7549107 132bool wxClipboard::Flush()
e9576ca5 133{
3dee36ae 134 return false;
e7549107
SC
135}
136
137bool wxClipboard::Open()
138{
3dee36ae 139 wxCHECK_MSG( !m_open, false, wxT("clipboard already open") );
3e822cd8
DS
140
141 m_open = true;
142
143 return true;
e7549107
SC
144}
145
146bool wxClipboard::IsOpened() const
147{
f0822896 148 return m_open;
e9576ca5
SC
149}
150
f0822896 151bool wxClipboard::SetData( wxDataObject *data )
e9576ca5 152{
9005f2ed
VZ
153 if ( IsUsingPrimarySelection() )
154 return false;
155
3dee36ae 156 wxCHECK_MSG( m_open, false, wxT("clipboard not open") );
3dee36ae 157 wxCHECK_MSG( data, false, wxT("data is invalid") );
634bafa9
SC
158
159 Clear();
3e822cd8
DS
160
161 // as we can only store one wxDataObject,
162 // this is the same in this implementation
f0822896 163 return AddData( data );
e7549107
SC
164}
165
166bool wxClipboard::AddData( wxDataObject *data )
167{
9005f2ed
VZ
168 if ( IsUsingPrimarySelection() )
169 return false;
170
3dee36ae 171 wxCHECK_MSG( m_open, false, wxT("clipboard not open") );
3dee36ae 172 wxCHECK_MSG( data, false, wxT("data is invalid") );
e7549107 173
3e822cd8 174 // we can only store one wxDataObject
f0822896 175 Clear();
e7549107 176
6239ee05
SC
177 PasteboardSyncFlags syncFlags = PasteboardSynchronize( M_CLIPBOARD->m_pasteboard );
178 wxCHECK_MSG( !(syncFlags&kPasteboardModified), false, wxT("clipboard modified after clear") );
179 wxCHECK_MSG( (syncFlags&kPasteboardClientIsOwner), false, wxT("client couldn't own clipboard") );
3e822cd8 180
6239ee05 181 M_CLIPBOARD->m_trueData = data;
e9576ca5 182
6239ee05 183 data->AddToPasteboard( M_CLIPBOARD->m_pasteboard, 1 );
e9576ca5 184
3e822cd8 185 return true;
e9576ca5
SC
186}
187
f0822896 188void wxClipboard::Close()
e9576ca5 189{
634bafa9
SC
190 wxCHECK_RET( m_open, wxT("clipboard not open") );
191
3e822cd8 192 m_open = false;
3dee36ae 193
3e822cd8
DS
194 // Get rid of cached object.
195 // If this is not done, copying data from
196 // another application will only work once
6239ee05 197 if (M_CLIPBOARD->m_trueData)
89a69c60 198 {
6239ee05
SC
199 delete M_CLIPBOARD->m_trueData;
200 M_CLIPBOARD->m_trueData = (wxDataObject*) NULL;
3dee36ae 201 }
e9576ca5
SC
202}
203
f0822896 204bool wxClipboard::IsSupported( const wxDataFormat &dataFormat )
e7549107 205{
6239ee05
SC
206 if ( M_CLIPBOARD->m_trueData )
207 return M_CLIPBOARD->m_trueData->IsSupported( dataFormat );
208 return wxDataObject::IsFormatInPasteboard( M_CLIPBOARD->m_pasteboard, dataFormat );
e9576ca5 209}
f0822896
SC
210
211bool wxClipboard::GetData( wxDataObject& data )
e9576ca5 212{
9005f2ed
VZ
213 if ( IsUsingPrimarySelection() )
214 return false;
215
3dee36ae 216 wxCHECK_MSG( m_open, false, wxT("clipboard not open") );
e9576ca5 217
3e822cd8
DS
218 size_t formatcount = data.GetFormatCount() + 1;
219 wxDataFormat *array = new wxDataFormat[ formatcount ];
f0822896
SC
220 array[0] = data.GetPreferredFormat();
221 data.GetAllFormats( &array[1] );
e9576ca5 222
3e822cd8 223 bool transferred = false;
e9576ca5 224
6239ee05 225 if ( M_CLIPBOARD->m_trueData )
f0822896 226 {
3e822cd8 227 for (size_t i = 0; !transferred && i < formatcount; i++)
21ec3bf9 228 {
3e822cd8 229 wxDataFormat format = array[ i ];
6239ee05 230 if ( M_CLIPBOARD->m_trueData->IsSupported( format ) )
f0822896 231 {
6239ee05 232 int dataSize = M_CLIPBOARD->m_trueData->GetDataSize( format );
3e822cd8 233 transferred = true;
21ec3bf9 234
3e822cd8 235 if (dataSize == 0)
21ec3bf9 236 {
3e822cd8 237 data.SetData( format, 0, 0 );
21ec3bf9
SC
238 }
239 else
240 {
3e822cd8 241 char *d = new char[ dataSize ];
6239ee05 242 M_CLIPBOARD->m_trueData->GetDataHere( format, (void*)d );
3e822cd8
DS
243 data.SetData( format, dataSize, d );
244 delete [] d;
21ec3bf9 245 }
f0822896 246 }
21ec3bf9 247 }
f0822896 248 }
3e822cd8
DS
249
250 // get formats from wxDataObjects
e135f093 251 if ( !transferred )
f0822896 252 {
6239ee05 253 transferred = data.GetFromPasteboard( M_CLIPBOARD->m_pasteboard ) ;
f0822896 254 }
e9576ca5 255
3e822cd8 256 delete [] array;
e542ecc6 257
3e822cd8 258 return transferred;
f0822896 259}
179e085f
RN
260
261#endif