001: /*
002: * (C) Copyright IBM Corp. 1998-2004. All Rights Reserved.
003: *
004: * The program is provided "as is" without any warranty express or
005: * implied, including the warranty of non-infringement and the implied
006: * warranties of merchantibility and fitness for a particular purpose.
007: * IBM will not be liable for any damages suffered by you as a result
008: * of using the Program. In no event will IBM be liable for any
009: * special, indirect or consequential damages or lost profits even if
010: * IBM has been advised of the possibility of their occurrence. IBM
011: * will not be liable for any third party claims against you.
012: */
013: package com.ibm.richtext.textpanel;
014:
015: import java.awt.datatransfer.Clipboard;
016: import java.awt.datatransfer.ClipboardOwner;
017: import java.awt.datatransfer.Transferable;
018: import java.awt.datatransfer.DataFlavor;
019: import java.awt.datatransfer.UnsupportedFlavorException;
020: import java.io.IOException;
021: import java.io.InputStream;
022:
023: import java.awt.Toolkit;
024:
025: import com.ibm.richtext.textlayout.attributes.AttributeMap;
026:
027: import com.ibm.richtext.styledtext.MConstText;
028: import com.ibm.richtext.styledtext.StyledText;
029:
030: /**
031: * Wrapper for java.awt.datatransfer.Clipboard
032: * Packages an MConstText in a transferable, and puts it on the clipboard.
033: */
034:
035: class StyledTextClipboard implements ClipboardOwner {
036:
037: static final String COPYRIGHT = "(C) Copyright IBM Corp. 1998-1999 - All Rights Reserved";
038: // This class has a workaround for a bug in the Windows system clipboard.
039: // The system clipboard will only return String content, even
040: // though it has a reference to the contents. So if our
041: // clipboard is the system clipboard, we'll keep a reference
042: // to the content and use that instead of what the Clipboard returns.
043:
044: private static Clipboard SYSTEM = null;
045: static {
046: try {
047: SYSTEM = Toolkit.getDefaultToolkit().getSystemClipboard();
048: } catch (Throwable th) {
049: }
050: }
051:
052: private static StyledTextClipboard fgSystemClipboard = null;
053:
054: public static StyledTextClipboard getClipboardFor(
055: Clipboard clipboard) {
056:
057: if (clipboard == SYSTEM && SYSTEM != null) {
058: synchronized (SYSTEM) {
059: if (fgSystemClipboard == null) {
060: fgSystemClipboard = new StyledTextClipboard(SYSTEM,
061: true);
062: }
063: }
064: return fgSystemClipboard;
065: } else {
066: return new StyledTextClipboard(clipboard, false);
067: }
068: }
069:
070: private Clipboard fClipboard;
071: private boolean fUseLocalContents;
072: private Transferable fContents = null;
073:
074: private StyledTextClipboard(Clipboard clipboard,
075: boolean useLocalContents) {
076:
077: if (clipboard == null) {
078: fClipboard = new Clipboard("TextPanel clipboard");
079: } else {
080: fClipboard = clipboard;
081: }
082:
083: fUseLocalContents = useLocalContents;
084: }
085:
086: public void lostOwnership(Clipboard clipboard, Transferable contents) {
087: if (contents == fContents) {
088: this .fContents = null;
089: }
090: }
091:
092: public void setContents(MConstText newContents) {
093:
094: TransferableText contents = new TransferableText(newContents);
095: if (fClipboard == SYSTEM) {
096: fContents = contents;
097: }
098: fClipboard.setContents(contents, this );
099: }
100:
101: private Transferable getClipboardContents() {
102:
103: if (fUseLocalContents && fContents != null) {
104: return fContents;
105: }
106:
107: return fClipboard.getContents(this );
108: }
109:
110: /**
111: * Has contents - faster than getContents for finding out whether the
112: * clipboard has text.
113: */
114: public boolean hasContents() {
115:
116: Transferable contents = getClipboardContents();
117:
118: if (contents == null) {
119: return false;
120: }
121:
122: return contents
123: .isDataFlavorSupported(MConstText.styledTextFlavor)
124: || contents
125: .isDataFlavorSupported(DataFlavor.stringFlavor)
126: || contents
127: .isDataFlavorSupported(DataFlavor.plainTextFlavor);
128: }
129:
130: private String getString(InputStream inStream) throws IOException {
131:
132: String value = new String();
133: int bytesRead;
134:
135: do {
136: byte inBytes[] = new byte[inStream.available()];
137: bytesRead = inStream.read(inBytes);
138:
139: if (bytesRead != -1)
140: value = value + new String(inBytes);
141:
142: } while (bytesRead != -1);
143:
144: return value;
145: }
146:
147: /**
148: * If the Clipboard has text content, return it as an
149: * MConstText. Otherwise return null.
150: * @param defaultStyle the style to apply to unstyled
151: * text (such as a String). If the clipboard
152: * has styled text this parameter is not used.
153: */
154: public MConstText getContents(AttributeMap defaultStyle) {
155:
156: Transferable contents = getClipboardContents();
157:
158: if (contents == null) {
159: return null;
160: }
161:
162: DataFlavor flavors[] = contents.getTransferDataFlavors();
163:
164: // search flavors for our flavor, String flavor and raw text flavor
165:
166: Exception ex = null;
167:
168: try {
169: int i;
170:
171: for (i = 0; i < flavors.length; i++) {
172: if (flavors[i].equals(MConstText.styledTextFlavor))
173: break;
174: }
175:
176: if (i < flavors.length) {
177:
178: Object data = contents
179: .getTransferData(MConstText.styledTextFlavor);
180: if (data == null)
181: System.out.println("Data is null.");
182: return (MConstText) data;
183: }
184:
185: for (i = 0; i < flavors.length; i++) {
186: if (flavors[i].equals(DataFlavor.stringFlavor))
187: break;
188: }
189:
190: if (i < flavors.length) {
191:
192: Object data = contents
193: .getTransferData(DataFlavor.stringFlavor);
194: return new StyledText((String) data, defaultStyle);
195: }
196:
197: for (i = 0; i < flavors.length; i++) {
198: if (flavors[i].equals(DataFlavor.plainTextFlavor))
199: break;
200: }
201:
202: if (i < flavors.length) {
203:
204: Object data = contents
205: .getTransferData(DataFlavor.plainTextFlavor);
206:
207: String textString = getString((InputStream) data);
208: return new StyledText(textString, defaultStyle);
209: }
210: } catch (UnsupportedFlavorException e) {
211: ex = e;
212: } catch (IOException e) {
213: ex = e;
214: }
215:
216: System.out
217: .println("Exception when retrieving data. Exception:"
218: + ex);
219: return null;
220: }
221: }
|