]> git.saurik.com Git - wxWidgets.git/blob - src/osx/carbon/clipbrd.cpp
fix wxDataObjectComposite::GetFormatCount and add some comments to explain the reason...
[wxWidgets.git] / src / osx / carbon / clipbrd.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/carbon/clipbrd.cpp
3 // Purpose: Clipboard functionality
4 // Author: Stefan Csomor;
5 // Generalized clipboard implementation by Matthew Flatt
6 // Modified by:
7 // Created: 1998-01-01
8 // RCS-ID: $Id$
9 // Copyright: (c) Stefan Csomor
10 // Licence: wxWindows licence
11 /////////////////////////////////////////////////////////////////////////////
12
13 #include "wx/wxprec.h"
14
15 #if wxUSE_CLIPBOARD
16
17 #include "wx/clipbrd.h"
18
19 #ifndef WX_PRECOMP
20 #include "wx/intl.h"
21 #include "wx/log.h"
22 #include "wx/app.h"
23 #include "wx/utils.h"
24 #include "wx/frame.h"
25 #include "wx/bitmap.h"
26 #endif
27
28 #include "wx/metafile.h"
29
30 #include "wx/osx/private.h"
31
32 #define wxUSE_DATAOBJ 1
33
34 #include <string.h>
35
36 // the trace mask we use with wxLogTrace() - call
37 // wxLog::AddTraceMask(TRACE_CLIPBOARD) to enable the trace messages from here
38 // (there will be a *lot* of them!)
39 #define TRACE_CLIPBOARD _T("clipboard")
40
41 IMPLEMENT_DYNAMIC_CLASS(wxClipboard, wxObject)
42
43 wxClipboard::wxClipboard()
44 {
45 m_open = false;
46 m_data = NULL ;
47 PasteboardRef clipboard = 0;
48 OSStatus err = PasteboardCreate( kPasteboardClipboard, &clipboard );
49 if (err != noErr)
50 {
51 wxLogSysError( wxT("Failed to create the clipboard.") );
52 }
53 m_pasteboard.reset(clipboard);
54 }
55
56 wxClipboard::~wxClipboard()
57 {
58 m_pasteboard.reset((PasteboardRef)0);
59 delete m_data;
60 }
61
62 void wxClipboard::Clear()
63 {
64 if (m_data != NULL)
65 {
66 delete m_data;
67 m_data = NULL;
68 }
69
70 OSStatus err = PasteboardClear( m_pasteboard );
71 if (err != noErr)
72 {
73 wxLogSysError( wxT("Failed to empty the clipboard.") );
74 }
75 }
76
77 bool wxClipboard::Flush()
78 {
79 return false;
80 }
81
82 bool wxClipboard::Open()
83 {
84 wxCHECK_MSG( !m_open, false, wxT("clipboard already open") );
85
86 m_open = true;
87
88 return true;
89 }
90
91 bool wxClipboard::IsOpened() const
92 {
93 return m_open;
94 }
95
96 bool wxClipboard::SetData( wxDataObject *data )
97 {
98 if ( IsUsingPrimarySelection() )
99 return false;
100
101 wxCHECK_MSG( m_open, false, wxT("clipboard not open") );
102 wxCHECK_MSG( data, false, wxT("data is invalid") );
103
104 Clear();
105
106 // as we can only store one wxDataObject,
107 // this is the same in this implementation
108 return AddData( data );
109 }
110
111 bool wxClipboard::AddData( wxDataObject *data )
112 {
113 if ( IsUsingPrimarySelection() )
114 return false;
115
116 wxCHECK_MSG( m_open, false, wxT("clipboard not open") );
117 wxCHECK_MSG( data, false, wxT("data is invalid") );
118
119 // we can only store one wxDataObject
120 Clear();
121
122 PasteboardSyncFlags syncFlags = PasteboardSynchronize( m_pasteboard );
123 wxCHECK_MSG( !(syncFlags&kPasteboardModified), false, wxT("clipboard modified after clear") );
124 wxCHECK_MSG( (syncFlags&kPasteboardClientIsOwner), false, wxT("client couldn't own clipboard") );
125
126 m_data = data;
127
128 data->AddToPasteboard( m_pasteboard, 1 );
129
130 return true;
131 }
132
133 void wxClipboard::Close()
134 {
135 wxCHECK_RET( m_open, wxT("clipboard not open") );
136
137 m_open = false;
138
139 // Get rid of cached object.
140 // If this is not done, copying data from
141 // another application will only work once
142 if (m_data)
143 {
144 delete m_data;
145 m_data = NULL;
146 }
147 }
148
149 bool wxClipboard::IsSupported( const wxDataFormat &dataFormat )
150 {
151 wxLogTrace(TRACE_CLIPBOARD, wxT("Checking if format %s is available"),
152 dataFormat.GetId().c_str());
153
154 if ( m_data )
155 return m_data->IsSupported( dataFormat );
156 return wxDataObject::IsFormatInPasteboard( m_pasteboard, dataFormat );
157 }
158
159 bool wxClipboard::GetData( wxDataObject& data )
160 {
161 if ( IsUsingPrimarySelection() )
162 return false;
163
164 wxCHECK_MSG( m_open, false, wxT("clipboard not open") );
165
166 size_t formatcount = data.GetFormatCount() + 1;
167 wxDataFormat *array = new wxDataFormat[ formatcount ];
168 array[0] = data.GetPreferredFormat();
169 data.GetAllFormats( &array[1] );
170
171 bool transferred = false;
172
173 if ( m_data )
174 {
175 for (size_t i = 0; !transferred && i < formatcount; i++)
176 {
177 wxDataFormat format = array[ i ];
178 if ( m_data->IsSupported( format ) )
179 {
180 int dataSize = m_data->GetDataSize( format );
181 transferred = true;
182
183 if (dataSize == 0)
184 {
185 data.SetData( format, 0, 0 );
186 }
187 else
188 {
189 char *d = new char[ dataSize ];
190 m_data->GetDataHere( format, (void*)d );
191 data.SetData( format, dataSize, d );
192 delete [] d;
193 }
194 }
195 }
196 }
197
198 // get formats from wxDataObjects
199 if ( !transferred )
200 {
201 transferred = data.GetFromPasteboard( m_pasteboard ) ;
202 }
203
204 delete [] array;
205
206 return transferred;
207 }
208
209 #endif