1:
37:
38:
39: package ;
40:
41: import ;
42:
43: import ;
44:
45: import ;
46: import ;
47: import ;
48: import ;
49: import ;
50: import ;
51:
52: import ;
53: import ;
54: import ;
55: import ;
56: import ;
57: import ;
58: import ;
59: import ;
60:
61: import ;
62: import ;
63:
64: public class GtkClipboard extends Clipboard
65: {
66:
69: final static GtkClipboard clipboard = new GtkClipboard("System Clipboard");
70:
71:
74: final static GtkClipboard selection = new GtkClipboard("System Selection");
75:
76:
77:
78: static final String stringMimeType
79: = DataFlavor.stringFlavor.getMimeType();
80: static final String imageMimeType
81: = DataFlavor.imageFlavor.getMimeType();
82: static final String filesMimeType
83: = DataFlavor.javaFileListFlavor.getMimeType();
84:
85:
86:
87:
88: static final boolean canCache = initNativeState(clipboard, selection,
89: stringMimeType,
90: imageMimeType,
91: filesMimeType);
92:
93:
97: private GtkClipboard(String name)
98: {
99: super(name);
100: setContents(new GtkSelection(this), null);
101: }
102:
103:
107: static GtkClipboard getClipboardInstance()
108: {
109: return clipboard;
110: }
111:
112:
116: static GtkClipboard getSelectionInstance()
117: {
118: return selection;
119: }
120:
121:
129: private synchronized void setSystemContents(boolean cleared)
130: {
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141: boolean owner = ! (contents instanceof GtkSelection);
142: boolean needNotification = (cleared && owner) || (! cleared && ! owner);
143: if (needNotification)
144: GtkClipboardNotifier.announce(this);
145: }
146:
147:
151: public synchronized void setContents(Transferable contents,
152: ClipboardOwner owner)
153: {
154: super.setContents(contents, owner);
155:
156: if (contents == null)
157: {
158: advertiseContent(null, false, false, false);
159: return;
160: }
161:
162:
163: if (contents instanceof GtkSelection)
164: return;
165:
166: boolean text = false;
167: boolean images = false;
168: boolean files = false;
169:
170: if (contents instanceof StringSelection
171: || contents.isDataFlavorSupported(DataFlavor.stringFlavor)
172: || contents.isDataFlavorSupported(DataFlavor.plainTextFlavor)
173: || contents.isDataFlavorSupported(DataFlavor.getTextPlainUnicodeFlavor()))
174: text = true;
175:
176: DataFlavor[] flavors = contents.getTransferDataFlavors();
177: String[] mimeTargets = new String[flavors.length];
178: for (int i = 0; i < flavors.length; i++)
179: {
180: DataFlavor flavor = flavors[i];
181: String mimeType = flavor.getMimeType();
182: mimeTargets[i] = mimeType;
183:
184: if (! text)
185: if ("text".equals(flavor.getPrimaryType())
186: || flavor.isRepresentationClassReader())
187: text = true;
188:
189: if (! images && flavors[i].equals(DataFlavor.imageFlavor))
190: {
191: try
192: {
193: Object o = contents.getTransferData(DataFlavor.imageFlavor);
194: if (o instanceof Image)
195: images = true;
196: }
197: catch (UnsupportedFlavorException ufe)
198: {
199: }
200: catch (IOException ioe)
201: {
202: }
203: catch (ClassCastException cce)
204: {
205: }
206: }
207:
208: if (flavors[i].equals(DataFlavor.javaFileListFlavor))
209: files = true;
210: }
211:
212: advertiseContent(mimeTargets, text, images, files);
213: }
214:
215:
223: private native void advertiseContent(String[] targets,
224: boolean text,
225: boolean images,
226: boolean files);
227:
228:
233: private String provideText()
234: {
235: Transferable contents = this.contents;
236: if (contents == null || contents instanceof GtkSelection)
237: return null;
238:
239:
240: if (contents instanceof StringSelection)
241: {
242: try
243: {
244: return (String) contents.getTransferData(DataFlavor.stringFlavor);
245: }
246: catch (UnsupportedFlavorException ufe)
247: {
248: }
249: catch (IOException ioe)
250: {
251: }
252: catch (ClassCastException cce)
253: {
254: }
255: }
256:
257:
258:
259: try
260: {
261: DataFlavor plainText = DataFlavor.getTextPlainUnicodeFlavor();
262: Reader r = plainText.getReaderForText(contents);
263: if (r != null)
264: {
265: CPStringBuilder sb = new CPStringBuilder();
266: char[] cs = new char[1024];
267: int l = r.read(cs);
268: while (l != -1)
269: {
270: sb.append(cs, 0, l);
271: l = r.read(cs);
272: }
273: return sb.toString();
274: }
275: }
276: catch (IllegalArgumentException iae)
277: {
278: }
279: catch (UnsupportedEncodingException iee)
280: {
281: }
282: catch (UnsupportedFlavorException ufe)
283: {
284: }
285: catch (IOException ioe)
286: {
287: }
288:
289: return null;
290: }
291:
292:
297: private GtkImage provideImage()
298: {
299: Transferable contents = this.contents;
300: if (contents == null || contents instanceof GtkSelection)
301: return null;
302:
303: try
304: {
305: Object o = contents.getTransferData(DataFlavor.imageFlavor);
306: if( o instanceof GtkImage )
307: return (GtkImage) o;
308: else
309: return new GtkImage(((Image)o).getSource());
310: }
311: catch (UnsupportedFlavorException ufe)
312: {
313: }
314: catch (IOException ioe)
315: {
316: }
317: catch (ClassCastException cce)
318: {
319: }
320:
321: return null;
322: }
323:
324:
330: private String[] provideURIs()
331: {
332: Transferable contents = this.contents;
333: if (contents == null || contents instanceof GtkSelection)
334: return null;
335:
336: try
337: {
338: List list = (List) contents.getTransferData(DataFlavor.javaFileListFlavor);
339: String[] uris = new String[list.size()];
340: int u = 0;
341: Iterator it = list.iterator();
342: while (it.hasNext())
343: uris[u++] = ((File) it.next()).toURI().toString();
344: return uris;
345: }
346: catch (UnsupportedFlavorException ufe)
347: {
348: }
349: catch (IOException ioe)
350: {
351: }
352: catch (ClassCastException cce)
353: {
354: }
355:
356: return null;
357: }
358:
359:
366: private byte[] provideContent(String target)
367: {
368:
369:
370: Transferable contents = this.contents;
371: if (contents == null || contents instanceof GtkSelection)
372: return null;
373:
374:
375:
376:
377:
378:
379: try
380: {
381: DataFlavor flavor = new DataFlavor(target);
382: Object o = contents.getTransferData(flavor);
383:
384: if (o instanceof byte[])
385: return (byte[]) o;
386:
387: if (o instanceof InputStream)
388: {
389: InputStream is = (InputStream) o;
390: ByteArrayOutputStream baos = new ByteArrayOutputStream();
391: byte[] bs = new byte[1024];
392: int l = is.read(bs);
393: while (l != -1)
394: {
395: baos.write(bs, 0, l);
396: l = is.read(bs);
397: }
398: return baos.toByteArray();
399: }
400:
401: if (o instanceof Serializable)
402: {
403: ByteArrayOutputStream baos = new ByteArrayOutputStream();
404: ObjectOutputStream oos = new ObjectOutputStream(baos);
405: oos.writeObject(o);
406: oos.close();
407: return baos.toByteArray();
408: }
409: }
410: catch (ClassNotFoundException cnfe)
411: {
412: }
413: catch (UnsupportedFlavorException ufe)
414: {
415: }
416: catch (IOException ioe)
417: {
418: }
419: catch (ClassCastException cce)
420: {
421: }
422:
423: return null;
424: }
425:
426:
431: private static native boolean initNativeState(GtkClipboard clipboard,
432: GtkClipboard selection,
433: String stringTarget,
434: String imageTarget,
435: String filesTarget);
436: }