1 19 20 package org.netbeans.modules.form; 21 22 import java.awt.datatransfer.DataFlavor ; 23 import java.awt.datatransfer.Transferable ; 24 import java.awt.datatransfer.UnsupportedFlavorException ; 25 import java.io.IOException ; 26 import org.netbeans.modules.form.layoutdesign.LayoutComponent; 27 import org.netbeans.modules.form.layoutdesign.LayoutModel; 28 import org.netbeans.modules.form.palette.BeanInstaller; 29 import org.netbeans.modules.form.project.ClassPathUtils; 30 import org.netbeans.modules.form.project.ClassSource; 31 import org.openide.DialogDisplayer; 32 import org.openide.ErrorManager; 33 import org.openide.NotifyDescriptor; 34 import org.openide.filesystems.FileObject; 35 import org.openide.loaders.DataObject; 36 import org.openide.nodes.Node; 37 import org.openide.nodes.NodeTransfer; 38 import org.openide.util.Mutex; 39 import org.openide.util.MutexException; 40 import org.openide.util.datatransfer.ExTransferable; 41 import org.openide.util.datatransfer.PasteType; 42 43 48 49 class CopySupport { 50 51 private static final String flavorMimeType = 52 "application/x-form-metacomponent;class=java.lang.Object"; 54 private static DataFlavor copyFlavor; 55 private static DataFlavor cutFlavor; 56 57 static DataFlavor getComponentCopyFlavor() { 58 if (copyFlavor == null) { 59 copyFlavor = new DataFlavor (flavorMimeType, 60 "COMPONENT_COPY_FLAVOR"); } 62 return copyFlavor; 63 } 64 65 static DataFlavor getComponentCutFlavor() { 66 if (cutFlavor == null) { 67 cutFlavor = new DataFlavor (flavorMimeType, 68 "COMPONENT_CUT_FLAVOR"); } 70 return cutFlavor; 71 } 72 73 75 static class RADTransferable implements Transferable { 76 private RADComponent radComponent; 77 private DataFlavor [] flavors; 78 79 RADTransferable(DataFlavor flavor, RADComponent radComponent) { 80 this(new DataFlavor [] { flavor }, radComponent); 81 } 82 83 RADTransferable(DataFlavor [] flavors, RADComponent radComponent) { 84 this.flavors = flavors; 85 this.radComponent = radComponent; 86 } 87 88 public DataFlavor [] getTransferDataFlavors() { 89 return flavors; 90 } 91 92 public boolean isDataFlavorSupported(DataFlavor flavor) { 93 for (int i = 0; i < flavors.length; i++) { 94 if (flavors[i] == flavor) { 95 return true; 96 } 97 } 98 return false; 99 } 100 101 public Object getTransferData(DataFlavor flavor) 102 throws UnsupportedFlavorException , IOException 103 { 104 if ("x-form-metacomponent".equals(flavor.getSubType())) return radComponent; 106 107 throw new UnsupportedFlavorException (flavor); 108 } 109 } 110 111 113 115 public static boolean canPasteCut(RADComponent sourceComponent, 116 FormModel targetForm, 117 RADComponent targetComponent) 118 { 119 if (!sourceComponent.isInModel()) 120 return false; 121 if (sourceComponent.getFormModel() != targetForm) 122 return true; 123 124 if (targetComponent == null) 125 return targetForm.getModelContainer().getIndexOf(sourceComponent) < 0; 126 127 return sourceComponent != targetComponent 128 && sourceComponent.getParentComponent() != targetComponent 129 && !sourceComponent.isParentComponent(targetComponent); 130 } 131 132 134 136 static class RADPaste extends PasteType implements Mutex.ExceptionAction { 137 private Transferable transferable; 138 private FormModel targetForm; 139 private RADComponent targetComponent; 140 141 public RADPaste(Transferable t, 142 FormModel targetForm, 143 RADComponent targetComponent) 144 { 145 this.transferable = t; 146 this.targetForm = targetForm; 147 this.targetComponent = targetComponent; 148 } 149 150 public String getName() { 151 return FormUtils.getBundleString(isComponentCut() ? 152 "CTL_CutPaste" : "CTL_CopyPaste"); } 154 155 public Transferable paste() throws IOException { 156 if (java.awt.EventQueue.isDispatchThread()) 157 return doPaste(); 158 else { try { 160 return (Transferable ) Mutex.EVENT.readAccess(this); 161 } 162 catch (MutexException ex) { 163 Exception e = ex.getException(); 164 if (e instanceof IOException ) 165 throw (IOException ) e; 166 else { ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); 168 return ExTransferable.EMPTY; 169 } 170 } 171 } 172 } 173 174 public Object run() throws Exception { 175 return doPaste(); 176 } 177 178 private Transferable doPaste() throws IOException { 179 boolean fromCut = isComponentCut(); 180 RADComponent sourceComponent = getSourceComponent(fromCut); 181 182 if (sourceComponent == null) 183 return null; 184 185 if (!fromCut || sourceComponent.getCodeExpression() == null) { 186 targetForm.getComponentCreator() 188 .copyComponent(sourceComponent, targetComponent); 189 return null; 190 } 193 194 FormModel sourceForm = sourceComponent.getFormModel(); 196 if (sourceForm != targetForm 197 || (targetComponent != null 198 && !sourceComponent.getClass().isAssignableFrom( 199 targetComponent.getClass()))) 200 { if (targetForm.getComponentCreator() 202 .copyComponent(sourceComponent, targetComponent) 203 != null) 204 { 205 Node sourceNode = sourceComponent.getNodeReference(); 206 if (sourceNode != null) 208 sourceNode.destroy(); 209 else throw new IllegalStateException (); 210 } 211 else return null; } 213 else { if (!canPasteCut(sourceComponent, targetForm, targetComponent) 215 || !MetaComponentCreator.canAddComponent( 216 sourceComponent.getBeanClass(), 217 targetComponent)) 218 return null; 220 sourceForm.startCompoundEdit(true); 221 boolean resetConstraintProperties = false; 222 LayoutModel layoutModel = sourceForm.getLayoutModel(); 223 LayoutComponent layoutComponent = null; 224 if (layoutModel != null) { 225 layoutComponent = layoutModel.getLayoutComponent(sourceComponent.getId()); 226 if (layoutComponent != null) { 227 resetConstraintProperties = true; 228 Object layoutUndoMark = layoutModel.getChangeMark(); 229 javax.swing.undo.UndoableEdit ue = layoutModel.getUndoableEdit(); 230 boolean autoUndo = true; 231 boolean fromModel = (!(targetComponent instanceof RADVisualContainer) 232 || ((RADVisualContainer)targetComponent).getLayoutSupport() != null) 233 && !layoutComponent.isLayoutContainer(); 234 try { 235 layoutModel.removeComponent(sourceComponent.getId(), fromModel); 236 autoUndo = false; 237 } finally { 238 if (!layoutUndoMark.equals(layoutModel.getChangeMark())) { 239 sourceForm.addUndoableEdit(ue); 240 } 241 if (autoUndo) { 242 sourceForm.forceUndoOfCompoundEdit(); 243 } 244 } 245 } 246 } 247 248 sourceForm.removeComponent(sourceComponent, false); 250 251 if (sourceComponent instanceof RADVisualComponent 252 && targetComponent instanceof RADVisualContainer) 253 { 254 RADVisualComponent visualComp = (RADVisualComponent) sourceComponent; 255 RADVisualContainer visualCont = (RADVisualContainer) targetComponent; 256 257 if (visualCont.getLayoutSupport() == null) { 258 targetForm.addComponent(visualComp, visualCont, false); 259 LayoutComponent parent = layoutModel.getLayoutComponent(visualCont.getId()); 260 Object layoutUndoMark = layoutModel.getChangeMark(); 261 javax.swing.undo.UndoableEdit ue = layoutModel.getUndoableEdit(); 262 boolean autoUndo = true; 263 if (layoutComponent == null) { 264 layoutComponent = new LayoutComponent(visualComp.getId(), 265 MetaComponentCreator.shouldBeLayoutContainer(visualComp)); 266 } 267 resetConstraintProperties = true; 268 try { 269 layoutModel.addNewComponent(layoutComponent, parent, null); 270 autoUndo = false; 271 } finally { 272 if (!layoutUndoMark.equals(layoutModel.getChangeMark())) { 273 sourceForm.addUndoableEdit(ue); 274 } 275 if (autoUndo) { 276 sourceForm.forceUndoOfCompoundEdit(); 277 } 278 } 279 } 280 else { 281 try { 282 targetForm.addVisualComponent(visualComp, visualCont, 283 visualCont.getLayoutSupport().getStoredConstraints(visualComp), 284 false); 285 } 286 catch (RuntimeException ex) { 287 org.openide.ErrorManager.getDefault().notify(org.openide.ErrorManager.INFORMATIONAL, ex); 289 return transferable; 290 } 291 } 292 } 293 else { 294 ComponentContainer targetContainer = 295 targetComponent instanceof ComponentContainer ? 296 (ComponentContainer) targetComponent : null; 297 298 targetForm.addComponent(sourceComponent, targetContainer, false); 300 } 301 if (resetConstraintProperties) { 302 ((RADVisualComponent)sourceComponent).resetConstraintsProperties(); 303 } 304 } 305 306 return ExTransferable.EMPTY; 307 } 308 309 boolean isComponentCut() { 310 return transferable.isDataFlavorSupported(getComponentCutFlavor()); 311 } 312 313 RADComponent getSourceComponent(boolean fromCut) throws IOException { 314 RADComponent sourceComponent = null; 315 try { 316 Object obj = transferable.getTransferData( 317 fromCut ? getComponentCutFlavor() : 318 getComponentCopyFlavor()); 319 if (obj instanceof RADComponent) 320 sourceComponent = (RADComponent) obj; 321 } 322 catch (UnsupportedFlavorException e) { } 324 325 return sourceComponent; 326 } 327 } 328 329 331 333 static class ClassPaste extends PasteType implements Mutex.ExceptionAction { 334 335 private Transferable transferable; 336 private ClassSource classSource; 337 private FormModel targetForm; 338 private RADComponent targetComponent; 340 public ClassPaste(Transferable t, 341 ClassSource classSource, 342 FormModel targetForm, 343 RADComponent targetComponent) 344 { 345 this.transferable = t; 346 this.classSource = classSource; 347 this.targetForm = targetForm; 348 this.targetComponent = targetComponent; 349 } 350 351 public Transferable paste() throws IOException { 352 if (java.awt.EventQueue.isDispatchThread()) { 353 return doPaste(); 354 } 355 else { try { 357 return (Transferable ) Mutex.EVENT.readAccess(this); 358 } 359 catch (MutexException ex) { 360 Exception e = ex.getException(); 361 if (e instanceof IOException ) 362 throw (IOException ) e; 363 else { ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); 365 return transferable; 366 } 367 } 368 } 369 } 370 371 public Object run() throws Exception { 372 return doPaste(); 373 } 374 375 private Transferable doPaste() throws IOException { 376 if ((classSource.getClassName().indexOf('.') == -1) && !FormJavaSource.isInDefaultPackage(targetForm)) { 378 String message = FormUtils.getBundleString("MSG_DefaultPackageBean"); NotifyDescriptor nd = new NotifyDescriptor.Message(message, NotifyDescriptor.WARNING_MESSAGE); 380 DialogDisplayer.getDefault().notify(nd); 381 } else { 382 targetForm.getComponentCreator().createComponent( 383 classSource, targetComponent, null); 384 } 385 return transferable; 386 } 387 } 388 389 static String getCopiedBeanClassName(final FileObject fo) { 390 return BeanInstaller.findJavaBeanName(fo); 391 } 392 393 static ClassSource getCopiedBeanClassSource(Transferable t) { 394 DataObject dobj = (DataObject) 395 NodeTransfer.cookie(t, NodeTransfer.COPY, DataObject.class); 396 FileObject fo = dobj != null ? dobj.getPrimaryFile() : null; 397 if (fo == null) 398 return null; 399 400 String clsName = getCopiedBeanClassName(fo); 401 if (clsName == null) 402 return null; 403 404 return ClassPathUtils.getProjectClassSource(fo, clsName); 405 } 406 407 } 408 | Popular Tags |