Lines 44-57
Link Here
|
44 |
package org.netbeans.modules.refactoring.spi.impl; |
44 |
package org.netbeans.modules.refactoring.spi.impl; |
45 |
|
45 |
|
46 |
import java.awt.*; |
46 |
import java.awt.*; |
|
|
47 |
import java.awt.datatransfer.DataFlavor; |
48 |
import java.awt.datatransfer.Transferable; |
49 |
import java.awt.datatransfer.UnsupportedFlavorException; |
47 |
import java.awt.event.ActionEvent; |
50 |
import java.awt.event.ActionEvent; |
48 |
import java.awt.event.ActionListener; |
51 |
import java.awt.event.ActionListener; |
|
|
52 |
import java.io.IOException; |
53 |
import java.io.InputStream; |
54 |
import java.io.Reader; |
55 |
import java.io.StringBufferInputStream; |
56 |
import java.io.StringReader; |
49 |
import java.lang.ref.WeakReference; |
57 |
import java.lang.ref.WeakReference; |
50 |
import java.util.*; |
58 |
import java.util.*; |
51 |
import java.util.Collection; |
59 |
import java.util.Collection; |
52 |
import javax.swing.*; |
60 |
import javax.swing.*; |
53 |
import javax.swing.border.EmptyBorder; |
61 |
import javax.swing.border.EmptyBorder; |
|
|
62 |
import javax.swing.text.html.HTMLEditorKit; |
63 |
import javax.swing.text.html.parser.ParserDelegator; |
54 |
import javax.swing.tree.DefaultTreeModel; |
64 |
import javax.swing.tree.DefaultTreeModel; |
|
|
65 |
import javax.swing.tree.TreePath; |
55 |
import org.netbeans.api.progress.ProgressHandle; |
66 |
import org.netbeans.api.progress.ProgressHandle; |
56 |
import org.netbeans.api.progress.ProgressHandleFactory; |
67 |
import org.netbeans.api.progress.ProgressHandleFactory; |
57 |
import org.netbeans.api.project.*; |
68 |
import org.netbeans.api.project.*; |
Lines 697-702
Link Here
|
697 |
tree.addMouseListener(l); |
708 |
tree.addMouseListener(l); |
698 |
tree.addKeyListener(l); |
709 |
tree.addKeyListener(l); |
699 |
tree.setToggleClickCount(0); |
710 |
tree.setToggleClickCount(0); |
|
|
711 |
tree.setTransferHandler(new TransferHandlerImpl()); |
700 |
scrollPane = new JScrollPane(tree); |
712 |
scrollPane = new JScrollPane(tree); |
701 |
RefactoringPanel.this.left.add(scrollPane, BorderLayout.CENTER); |
713 |
RefactoringPanel.this.left.add(scrollPane, BorderLayout.CENTER); |
702 |
RefactoringPanel.this.validate(); |
714 |
RefactoringPanel.this.validate(); |
Lines 983-986
Link Here
|
983 |
}); |
995 |
}); |
984 |
} |
996 |
} |
985 |
} |
997 |
} |
|
|
998 |
|
999 |
private static class TransferHandlerImpl extends TransferHandler { |
1000 |
@Override |
1001 |
protected Transferable createTransferable(JComponent c) { |
1002 |
if (c instanceof JTree) { |
1003 |
JTree tree = (JTree) c; |
1004 |
TreePath[] paths = tree.getSelectionPaths(); |
1005 |
|
1006 |
if (paths == null || paths.length == 0) { |
1007 |
return null; |
1008 |
} |
1009 |
|
1010 |
Html2Text html2Text = new Html2Text(); |
1011 |
StringBuilder plain = new StringBuilder(); |
1012 |
StringBuilder html = new StringBuilder("<html><ul>"); |
1013 |
int depth = 1; |
1014 |
for(TreePath path: paths) { |
1015 |
for(; depth < path.getPathCount(); depth++) { |
1016 |
html.append("<ul>"); |
1017 |
} |
1018 |
for(; depth > path.getPathCount(); depth--) { |
1019 |
html.append("</ul>"); |
1020 |
} |
1021 |
Object o = path.getLastPathComponent(); |
1022 |
if(o instanceof CheckNode) { |
1023 |
CheckNode node = (CheckNode) o; |
1024 |
String label = node.getLabel(); |
1025 |
try { |
1026 |
html2Text.parse(new StringReader(label)); |
1027 |
} catch (IOException ex) { |
1028 |
assert false : ex; |
1029 |
} |
1030 |
|
1031 |
plain.append(html2Text.getText()); |
1032 |
plain.append("\n"); |
1033 |
html.append("<li>"); |
1034 |
html.append(label); |
1035 |
html.append("</li>"); |
1036 |
} |
1037 |
} |
1038 |
for(; depth > 1; depth--) { |
1039 |
html.append("</ul>"); |
1040 |
} |
1041 |
html.append("</ul></html>"); |
1042 |
|
1043 |
return new ResultTransferable(plain.toString(), html.toString()); |
1044 |
} |
1045 |
return null; |
1046 |
} |
1047 |
|
1048 |
@Override |
1049 |
public int getSourceActions(JComponent c) { |
1050 |
return COPY; |
1051 |
} |
1052 |
} |
1053 |
/** |
1054 |
* Transferable implementation for ResultPanel. |
1055 |
*/ |
1056 |
private static class ResultTransferable implements Transferable { |
1057 |
private static DataFlavor[] stringFlavors; |
1058 |
private static DataFlavor[] plainFlavors; |
1059 |
private static DataFlavor[] htmlFlavors; |
1060 |
|
1061 |
static { |
1062 |
try { |
1063 |
htmlFlavors = new DataFlavor[3]; |
1064 |
htmlFlavors[0] = new DataFlavor("text/html;class=java.lang.String"); // NOI18N |
1065 |
htmlFlavors[1] = new DataFlavor("text/html;class=java.io.Reader"); // NOI18N |
1066 |
htmlFlavors[2] = new DataFlavor("text/html;charset=unicode;class=java.io.InputStream"); // NOI18N |
1067 |
|
1068 |
plainFlavors = new DataFlavor[3]; |
1069 |
plainFlavors[0] = new DataFlavor("text/plain;class=java.lang.String"); // NOI18N |
1070 |
plainFlavors[1] = new DataFlavor("text/plain;class=java.io.Reader"); // NOI18N |
1071 |
// XXX isn't this just DataFlavor.plainTextFlavor? |
1072 |
plainFlavors[2] = new DataFlavor("text/plain;charset=unicode;class=java.io.InputStream"); // NOI18N |
1073 |
|
1074 |
stringFlavors = new DataFlavor[2]; |
1075 |
stringFlavors[0] = new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType + ";class=java.lang.String"); // NOI18N |
1076 |
stringFlavors[1] = DataFlavor.stringFlavor; |
1077 |
} catch (ClassNotFoundException cle) { |
1078 |
assert false : cle; |
1079 |
} |
1080 |
} |
1081 |
|
1082 |
protected String plainData; |
1083 |
protected String htmlData; |
1084 |
|
1085 |
public ResultTransferable(String plainData, String htmlData) { |
1086 |
this.plainData = plainData; |
1087 |
this.htmlData = htmlData; |
1088 |
} |
1089 |
|
1090 |
@Override |
1091 |
public DataFlavor[] getTransferDataFlavors() { |
1092 |
int nHtml = (isHtmlSupported()) ? htmlFlavors.length : 0; |
1093 |
int nPlain = (isPlainSupported()) ? plainFlavors.length : 0; |
1094 |
int nString = (isPlainSupported()) ? stringFlavors.length : 0; |
1095 |
int nFlavors = nHtml + nPlain + nString; |
1096 |
DataFlavor[] flavors = new DataFlavor[nFlavors]; |
1097 |
|
1098 |
// fill in the array |
1099 |
int nDone = 0; |
1100 |
if (nHtml > 0) { |
1101 |
System.arraycopy(htmlFlavors, 0, flavors, nDone, nHtml); |
1102 |
nDone += nHtml; |
1103 |
} |
1104 |
if (nPlain > 0) { |
1105 |
System.arraycopy(plainFlavors, 0, flavors, nDone, nPlain); |
1106 |
nDone += nPlain; |
1107 |
} |
1108 |
if (nString > 0) { |
1109 |
System.arraycopy(stringFlavors, 0, flavors, nDone, nString); |
1110 |
nDone += nString; |
1111 |
} |
1112 |
return flavors; |
1113 |
} |
1114 |
|
1115 |
@Override |
1116 |
public boolean isDataFlavorSupported(DataFlavor flavor) { |
1117 |
DataFlavor[] flavors = getTransferDataFlavors(); |
1118 |
for (int i = 0; i < flavors.length; i++) { |
1119 |
if (flavors[i].equals(flavor)) { |
1120 |
return true; |
1121 |
} |
1122 |
} |
1123 |
return false; |
1124 |
} |
1125 |
|
1126 |
@Override |
1127 |
public Object getTransferData(DataFlavor flavor) |
1128 |
throws UnsupportedFlavorException, IOException { |
1129 |
if (isHtmlFlavor(flavor)) { |
1130 |
String html = getHtmlData(); |
1131 |
html = (html == null) ? "" : html; |
1132 |
if (String.class.equals(flavor.getRepresentationClass())) { |
1133 |
return html; |
1134 |
} else if (Reader.class.equals(flavor.getRepresentationClass())) { |
1135 |
return new StringReader(html); |
1136 |
} else if (InputStream.class.equals(flavor.getRepresentationClass())) { |
1137 |
// XXX should this enforce UTF-8 encoding? |
1138 |
return new StringBufferInputStream(html); |
1139 |
} |
1140 |
// fall through to unsupported |
1141 |
} else if (isPlainFlavor(flavor)) { |
1142 |
String data = getPlainData(); |
1143 |
data = (data == null) ? "" : data; |
1144 |
if (String.class.equals(flavor.getRepresentationClass())) { |
1145 |
return data; |
1146 |
} else if (Reader.class.equals(flavor.getRepresentationClass())) { |
1147 |
return new StringReader(data); |
1148 |
} else if (InputStream.class.equals(flavor.getRepresentationClass())) { |
1149 |
// XXX should this enforce UTF-8 encoding? |
1150 |
return new StringBufferInputStream(data); |
1151 |
} |
1152 |
// fall through to unsupported |
1153 |
} else if (isStringFlavor(flavor)) { |
1154 |
String data = getPlainData(); |
1155 |
data = (data == null) ? "" : data; |
1156 |
|
1157 |
return data; |
1158 |
} |
1159 |
|
1160 |
throw new UnsupportedFlavorException(flavor); |
1161 |
} |
1162 |
|
1163 |
// --- plain text flavors ---------------------------------------------- |
1164 |
|
1165 |
/** |
1166 |
* Returns whether or not the specified data flavor is an plain flavor |
1167 |
* that is supported. |
1168 |
* |
1169 |
* @param flavor the requested flavor for the data |
1170 |
* @return boolean indicating whether or not the data flavor is supported |
1171 |
*/ |
1172 |
protected boolean isPlainFlavor(DataFlavor flavor) { |
1173 |
DataFlavor[] flavors = plainFlavors; |
1174 |
|
1175 |
for (int i = 0; i < flavors.length; i++) { |
1176 |
if (flavors[i].equals(flavor)) { |
1177 |
return true; |
1178 |
} |
1179 |
} |
1180 |
return false; |
1181 |
} |
1182 |
|
1183 |
/** |
1184 |
* Should the plain text flavors be offered? If so, the method |
1185 |
* getPlainData should be implemented to provide something reasonable. |
1186 |
*/ |
1187 |
protected boolean isPlainSupported() { |
1188 |
return plainData != null; |
1189 |
} |
1190 |
|
1191 |
/** |
1192 |
* Fetch the data in a text/plain format. |
1193 |
*/ |
1194 |
protected String getPlainData() { |
1195 |
return plainData; |
1196 |
} |
1197 |
|
1198 |
// --- string flavors -------------------------------------------------- |
1199 |
|
1200 |
/** |
1201 |
* Returns whether or not the specified data flavor is a String flavor |
1202 |
* that is supported. |
1203 |
* |
1204 |
* @param flavor the requested flavor for the data |
1205 |
* @return boolean indicating whether or not the data flavor is supported |
1206 |
*/ |
1207 |
protected boolean isStringFlavor(DataFlavor flavor) { |
1208 |
DataFlavor[] flavors = stringFlavors; |
1209 |
|
1210 |
for (int i = 0; i < flavors.length; i++) { |
1211 |
if (flavors[i].equals(flavor)) { |
1212 |
return true; |
1213 |
} |
1214 |
} |
1215 |
return false; |
1216 |
} |
1217 |
|
1218 |
// --- html flavors ---------------------------------------------------- |
1219 |
|
1220 |
/** |
1221 |
* Returns whether or not the specified data flavor is a html flavor |
1222 |
* that is supported. |
1223 |
* |
1224 |
* @param flavor the requested flavor for the data |
1225 |
* @return boolean indicating whether or not the data flavor is supported |
1226 |
*/ |
1227 |
protected boolean isHtmlFlavor(DataFlavor flavor) { |
1228 |
DataFlavor[] flavors = htmlFlavors; |
1229 |
|
1230 |
for (int i = 0; i < flavors.length; i++) { |
1231 |
if (flavors[i].equals(flavor)) { |
1232 |
return true; |
1233 |
} |
1234 |
} |
1235 |
return false; |
1236 |
} |
1237 |
|
1238 |
/** |
1239 |
* Should the html text flavors be offered? If so, the method |
1240 |
* getHtmlData should be implemented to provide something reasonable. |
1241 |
*/ |
1242 |
protected boolean isHtmlSupported() { |
1243 |
return htmlData != null; |
1244 |
} |
1245 |
|
1246 |
/** |
1247 |
* Fetch the data in text/html format. |
1248 |
*/ |
1249 |
protected String getHtmlData() { |
1250 |
return htmlData; |
1251 |
} |
1252 |
} |
1253 |
|
1254 |
private static class Html2Text extends HTMLEditorKit.ParserCallback { |
1255 |
StringBuffer s; |
1256 |
|
1257 |
public Html2Text() { |
1258 |
} |
1259 |
|
1260 |
public void parse(Reader in) throws IOException { |
1261 |
s = new StringBuffer(); |
1262 |
ParserDelegator delegator = new ParserDelegator(); |
1263 |
// the third parameter is TRUE to ignore charset directive |
1264 |
delegator.parse(in, this, Boolean.TRUE); |
1265 |
} |
1266 |
|
1267 |
@Override |
1268 |
public void handleText(char[] text, int pos) { |
1269 |
s.append(text); |
1270 |
} |
1271 |
|
1272 |
public String getText() { |
1273 |
return s.toString(); |
1274 |
} |
1275 |
} |
986 |
} // end Refactor Panel |
1276 |
} // end Refactor Panel |