1 19 20 package org.netbeans.modules.tasklist.usertasks; 21 22 import java.awt.datatransfer.DataFlavor ; 23 import java.awt.datatransfer.Transferable ; 24 import java.awt.datatransfer.UnsupportedFlavorException ; 25 import java.beans.PropertyChangeEvent ; 26 import java.beans.PropertyChangeListener ; 27 import java.io.IOException ; 28 import java.lang.reflect.InvocationTargetException ; 29 import java.net.MalformedURLException ; 30 import java.net.URL ; 31 import java.util.Date ; 32 import java.util.List ; 33 import java.util.logging.Level ; 34 35 import javax.swing.Action ; 36 import javax.swing.SwingUtilities ; 37 import javax.swing.tree.TreePath ; 38 39 import org.netbeans.modules.tasklist.core.TaskNode; 40 import org.netbeans.modules.tasklist.core.export.ExportAction; 41 import org.netbeans.modules.tasklist.core.export.ImportAction; 42 import org.netbeans.modules.tasklist.core.filter.FilterAction; 43 import org.netbeans.modules.tasklist.core.filter.RemoveFilterAction; 44 import org.netbeans.modules.tasklist.usertasks.actions.CollapseAllAction; 45 import org.netbeans.modules.tasklist.usertasks.actions.ExpandAllUserTasksAction; 46 import org.netbeans.modules.tasklist.usertasks.actions.GoToUserTaskAction; 47 import org.netbeans.modules.tasklist.usertasks.actions.PauseAction; 48 import org.netbeans.modules.tasklist.usertasks.actions.ScheduleAction; 49 import org.netbeans.modules.tasklist.usertasks.actions.StartTaskAction; 50 import org.netbeans.modules.tasklist.usertasks.editors.DateEditor; 51 import org.netbeans.modules.tasklist.usertasks.editors.DurationPropertyEditor; 52 import org.netbeans.modules.tasklist.usertasks.editors.PercentsPropertyEditor; 53 import org.netbeans.modules.tasklist.usertasks.editors.PriorityPropertyEditor; 54 import org.netbeans.modules.tasklist.usertasks.transfer.UserTasksTransferable; 55 import org.netbeans.modules.tasklist.usertasks.treetable.AdvancedTreeTableNode; 56 import org.netbeans.modules.tasklist.usertasks.util.UTUtils; 57 import org.openide.actions.CopyAction; 58 import org.openide.actions.CutAction; 59 import org.openide.actions.PasteAction; 60 import org.openide.nodes.AbstractNode; 61 import org.openide.nodes.Children; 62 import org.openide.nodes.PropertySupport; 63 import org.openide.nodes.Sheet; 64 import org.openide.nodes.Sheet.Set; 65 import org.openide.util.HelpCtx; 66 import org.openide.util.NbBundle; 67 import org.openide.util.actions.SystemAction; 68 import org.openide.util.datatransfer.ExTransferable; 69 import org.openide.util.datatransfer.MultiTransferObject; 70 import org.openide.util.datatransfer.PasteType; 71 import org.netbeans.modules.tasklist.usertasks.model.UserTask; 72 import org.netbeans.modules.tasklist.usertasks.model.UserTaskList; 73 import org.openide.actions.DeleteAction; 74 import org.openide.nodes.Node; 75 76 81 public final class UserTaskNode extends AbstractNode { 82 private UserTask item; 83 private UserTaskList utl; 84 private UserTaskTreeTableNode node; 85 private UserTasksTreeTable tt; 86 87 96 public UserTaskNode(UserTaskTreeTableNode node, UserTask item, UserTaskList utl, 97 UserTasksTreeTable tt) { 98 super(Children.LEAF); 99 assert item != null; 100 101 this.utl = utl; 102 this.item = item; 103 this.node = node; 104 this.tt = tt; 105 106 setName(item.getSummary()); 107 108 item.addPropertyChangeListener(new PropertyChangeListener () { 109 public void propertyChange(PropertyChangeEvent e) { 110 String n = e.getPropertyName(); 111 if (n == UserTask.PROP_PROGRESS) { int old = Math.round(((Float ) e.getOldValue()).floatValue()); 113 int new_ = Math.round(((Float ) e.getNewValue()).floatValue()); 114 UserTaskNode.this.firePropertyChange( 115 "percentComplete", new Integer (old), new Integer (new_)); 117 } else if (n == UserTask.PROP_LINE || 118 n == "started") { } else { 122 UserTaskNode.this.firePropertyChange(e.getPropertyName(), 123 e.getOldValue(), e.getNewValue()); 124 } 125 if (n == "started" || n == UserTask.PROP_VALUES_COMPUTED || 127 n == UserTask.PROP_LINE) { fireCookieChange(); 129 } 130 } 131 }); 132 } 133 134 138 public UserTask getTask() { 139 return item; 140 } 141 142 public Action [] getActions(boolean empty) { 143 UserTaskView utv = (UserTaskView) 144 SwingUtilities.getAncestorOfClass(UserTaskView.class, tt); 145 if (empty) { 146 return new Action [] { 147 null, 149 PauseAction.getInstance(), 150 null, 151 SystemAction.get(PasteAction.class), 152 null, 153 SystemAction.get(FilterAction.class), 154 utv.purgeTasksAction, 155 SystemAction.get(ScheduleAction.class), 156 null, 157 SystemAction.get(ExpandAllUserTasksAction.class), 158 SystemAction.get(CollapseAllAction.class), 159 null, 160 SystemAction.get(ImportAction.class), 161 SystemAction.get(ExportAction.class), 162 }; 163 } else { 164 return new Action [] { 165 utv.newTaskAction, 166 null, 168 new StartTaskAction(utv), 169 PauseAction.getInstance(), 170 null, 171 utv.showTaskAction, 172 new GoToUserTaskAction(utv), 173 null, 174 SystemAction.get(CutAction.class), 175 SystemAction.get(CopyAction.class), 176 SystemAction.get(PasteAction.class), 177 null, 178 SystemAction.get(DeleteAction.class), 179 null, 180 utv.moveUpAction, 181 utv.moveDownAction, 182 utv.moveLeftAction, 183 utv.moveRightAction, 184 null, 185 SystemAction.get(FilterAction.class), 186 SystemAction.get(RemoveFilterAction.class), 187 null, 188 utv.purgeTasksAction, 189 utv.clearCompletedAction, 190 SystemAction.get(ScheduleAction.class), 191 null, 192 SystemAction.get(ExpandAllUserTasksAction.class), 193 SystemAction.get(CollapseAllAction.class), 194 null, 195 SystemAction.get(ImportAction.class), 196 SystemAction.get(ExportAction.class), 197 198 null, 200 utv.propertiesAction 201 }; 202 } 203 } 204 205 protected Sheet createSheet() { 206 Sheet s = Sheet.createDefault(); 207 Set ss = s.get(Sheet.PROPERTIES); 208 209 try { 210 PropertySupport.Reflection p; 211 p = new PropertySupport.Reflection(item, String .class, "getSummary", "setSummary"); p.setName(UserTask.PROP_SUMMARY); 213 p.setDisplayName(NbBundle.getMessage(TaskNode.class, "Description")); p.setShortDescription(NbBundle.getMessage(TaskNode.class, "DescriptionHint")); ss.put(p); 216 217 p = new PropertySupport.Reflection(item, Integer.TYPE, "getPriority", "setPriority"); p.setName(UserTask.PROP_PRIORITY); 219 p.setPropertyEditorClass(PriorityPropertyEditor.class); 220 p.setDisplayName(NbBundle.getMessage(UserTaskNode.class, "LBL_priorityProperty")); p.setShortDescription(NbBundle.getMessage(UserTaskNode.class, "HNT_priorityProperty")); ss.put(p); 223 224 225 p = new PropertySupport.Reflection(item, Boolean.TYPE, "isDone", "setDone"); p.setName("done"); p.setDisplayName(NbBundle.getMessage(UserTaskNode.class, "LBL_doneProperty")); p.setShortDescription(NbBundle.getMessage(UserTaskNode.class, "HNT_doneProperty")); ss.put(p); 230 231 p = new PropertySupport.Reflection(item, Integer.TYPE, 232 "getPercentComplete", "setPercentComplete"); p.setName("percentComplete"); p.setPropertyEditorClass(PercentsPropertyEditor.class); 235 p.setDisplayName(NbBundle.getMessage(UserTaskNode.class, "LBL_percentCompleteProperty")); p.setShortDescription(NbBundle.getMessage(UserTaskNode.class, "HNT_percentCompleteProperty")); ss.put(p); 238 239 p = new PropertySupport.Reflection(item, Boolean.TYPE, 240 "isValuesComputed", "setValuesComputed"); p.setName("valuesComputed"); p.setDisplayName(org.openide.util.NbBundle.getMessage(UserTaskNode.class, "LBL_valuesComputed")); p.setShortDescription(org.openide.util.NbBundle.getMessage(UserTaskNode.class, "HNT_valuesComputed")); ss.put(p); 245 246 p = new PropertySupport.Reflection(item, Integer.TYPE, "getEffort", "setEffort"); p.setName("effort"); p.setDisplayName(NbBundle.getMessage(UserTaskNode.class, "LBL_effortProperty")); p.setShortDescription(NbBundle.getMessage(UserTaskNode.class, "HNT_effortProperty")); p.setPropertyEditorClass(DurationPropertyEditor.class); 251 ss.put(p); 252 253 p = new PropertySupport.Reflection(item, Integer.TYPE, "getRemainingEffort", null); p.setName("remainingEffort"); p.setValue("canEditAsText", Boolean.FALSE); p.setValue("suppressCustomEditor", Boolean.TRUE); p.setDisplayName(NbBundle.getMessage(UserTaskNode.class, "LBL_remainingEffortProperty")); p.setShortDescription(NbBundle.getMessage(UserTaskNode.class, "HNT_remainingEffortProperty")); p.setPropertyEditorClass(DurationPropertyEditor.class); 260 ss.put(p); 261 262 p = new PropertySupport.Reflection(item, Integer.TYPE, "getSpentTime", "setSpentTime"); p.setName("spentTime"); p.setDisplayName(NbBundle.getMessage(UserTaskNode.class, "LBL_spentTimeProperty")); p.setShortDescription(NbBundle.getMessage(UserTaskNode.class, "HNT_spentTimeProperty")); p.setPropertyEditorClass(DurationPropertyEditor.class); 267 ss.put(p); 268 269 p = new PropertySupport.Reflection(item, Integer.TYPE, "getSpentTimeToday", null); p.setName("spentTimeToday"); p.setDisplayName(NbBundle.getMessage(UserTaskNode.class, "LBL_spentTimeTodayProperty")); p.setShortDescription(NbBundle.getMessage(UserTaskNode.class, "HNT_spentTimeTodayProperty")); p.setPropertyEditorClass(DurationPropertyEditor.class); 274 ss.put(p); 275 276 p = new PropertySupport.Reflection(item, String .class, "getDetails", "setDetails"); p.setName(UserTask.PROP_DETAILS); 278 p.setDisplayName(NbBundle.getMessage(UserTaskNode.class, "LBL_detailsProperty")); p.setShortDescription(NbBundle.getMessage(UserTaskNode.class, "HNT_detailsProperty")); ss.put(p); 281 282 p = new PropertySupport.Reflection(item, String .class, (String ) null, null) { public boolean canRead() { 284 return true; 285 } 286 public boolean canWrite() { 287 return true; 288 } 289 public Object getValue () throws 290 IllegalAccessException , IllegalArgumentException , InvocationTargetException { 291 URL url = ((UserTask) instance).getUrl(); 292 if (url == null) 293 return ""; else 295 return url.toExternalForm(); 296 } 297 public void setValue (Object val) throws 298 IllegalAccessException , IllegalArgumentException , InvocationTargetException { 299 try { 300 URL url = new URL ((String ) val); 301 ((UserTask) instance).setUrl(url); 302 } catch (MalformedURLException e) { 303 throw new IllegalArgumentException (e.getMessage()); 304 } 305 } 306 }; 307 p.setName(UserTask.PROP_URL); 308 p.setDisplayName(NbBundle.getMessage(UserTaskNode.class, "LBL_urlProperty")); p.setShortDescription(NbBundle.getMessage(UserTaskNode.class, "HNT_urlProperty")); ss.put(p); 312 313 p = new PropertySupport.Reflection(item, Integer.TYPE, (String ) null, null) { public boolean canRead() { 315 return true; 316 } 317 public boolean canWrite() { 318 return true; 319 } 320 public Object getValue () throws 321 IllegalAccessException , IllegalArgumentException , InvocationTargetException { 322 return new Integer (((UserTask) instance).getLineNumber() + 1); 323 } 324 public void setValue (Object val) throws 325 IllegalAccessException , IllegalArgumentException , InvocationTargetException { 326 int n = ((Integer ) val).intValue(); 327 if (n < 1) 328 throw new IllegalArgumentException (); 329 ((UserTask) instance).setLineNumber(n - 1); 330 } 331 }; 332 p.setName(UserTask.PROP_LINE_NUMBER); 333 p.setDisplayName(NbBundle.getMessage(UserTaskNode.class, "LBL_lineProperty")); p.setShortDescription(NbBundle.getMessage(UserTaskNode.class, "HNT_lineProperty")); ss.put(p); 336 337 p = new PropertySupport.Reflection(item, String .class, "getCategory", "setCategory"); p.setName(UserTask.PROP_CATEGORY); 339 p.setDisplayName(NbBundle.getMessage(UserTaskNode.class, "LBL_categoryProperty")); p.setShortDescription(NbBundle.getMessage(UserTaskNode.class, "HNT_categoryProperty")); p.setValue("canEditAsText", Boolean.TRUE); p.setValue("suppressCustomEditor", Boolean.TRUE); ss.put(p); 344 345 p = new PropertySupport.Reflection(item, Date .class, "getCreatedDate", null); p.setPropertyEditorClass(DateEditor.class); 347 p.setName("created"); p.setDisplayName(NbBundle.getMessage(UserTaskNode.class, "LBL_createdProperty")); p.setShortDescription(NbBundle.getMessage(UserTaskNode.class, "HNT_createdProperty")); p.setValue("suppressCustomEditor", Boolean.TRUE); ss.put(p); 352 353 p = new PropertySupport.Reflection(item, Date .class, "getLastEditedDate", null); p.setPropertyEditorClass(DateEditor.class); 355 p.setName("edited"); p.setDisplayName(NbBundle.getMessage(UserTaskNode.class, "LBL_editedProperty")); p.setShortDescription(NbBundle.getMessage(UserTaskNode.class, "HNT_editedProperty")); p.setValue("suppressCustomEditor", Boolean.TRUE); ss.put(p); 360 361 p = new PropertySupport.Reflection(item, Date .class, "getCompletedDate", null); p.setPropertyEditorClass(DateEditor.class); 363 p.setName("completedDate"); p.setDisplayName(NbBundle.getMessage(UserTaskNode.class, "LBL_completedDateProperty")); p.setShortDescription(NbBundle.getMessage(UserTaskNode.class, "HNT_completedDateProperty")); p.setValue("suppressCustomEditor", Boolean.TRUE); ss.put(p); 368 369 p = new PropertySupport.Reflection(item, Date .class, "getDueDate", "setDueDate"); p.setPropertyEditorClass(DateEditor.class); 371 p.setName(UserTask.PROP_DUE_DATE); 372 p.setDisplayName(NbBundle.getMessage(UserTaskNode.class, "LBL_dueDateProperty")); p.setShortDescription(NbBundle.getMessage(UserTaskNode.class, "HNT_dueDateProperty")); ss.put(p); 375 376 p = new PropertySupport.Reflection(item, String .class, "getOwner", "setOwner"); p.setName(UserTask.PROP_OWNER); 378 p.setDisplayName(NbBundle.getMessage(UserTaskNode.class, "LBL_ownerProperty")); p.setShortDescription(NbBundle.getMessage(UserTaskNode.class, "HNT_ownerProperty")); ss.put(p); 381 382 p = new PropertySupport.Reflection(item, Date .class, "getStartDate", "setStartDate"); p.setPropertyEditorClass(DateEditor.class); 384 p.setName(UserTask.PROP_START); 385 p.setDisplayName(NbBundle.getMessage(UserTaskNode.class, "LBL_startProperty")); p.setShortDescription(NbBundle.getMessage(UserTaskNode.class, "HNT_startProperty")); ss.put(p); 388 } catch (NoSuchMethodException nsme) { 389 UTUtils.LOGGER.log(Level.WARNING, "", nsme); } 391 return s; 392 } 393 394 public boolean canDestroy() { 395 return true; 396 } 397 398 401 public boolean canCopy () { 402 return true; 403 } 404 405 408 public boolean canCut () { 409 return true; 410 } 411 412 public javax.swing.Action getPreferredAction() { 413 return null; } 415 416 public boolean canRename() { 417 return true; 418 } 419 420 @SuppressWarnings ("unchecked") 421 protected void createPasteTypes(java.awt.datatransfer.Transferable t, 422 List s) { 423 super.createPasteTypes(t, s); 424 PasteType p = createTodoPasteType(this, t); 425 if (p != null) { 426 s.add(p); } 428 } 429 430 437 public static PasteType createTodoPasteType( 438 Node target, Transferable t) { 439 if (t.isDataFlavorSupported(ExTransferable.multiFlavor)) { 440 try { 441 final MultiTransferObject mto = (MultiTransferObject) 443 t.getTransferData(ExTransferable.multiFlavor); 444 if (mto.areDataFlavorsSupported( 445 new DataFlavor [] {UserTasksTransferable.USER_TASKS_FLAVOR})) { 446 return new UserTaskNode.TodoPaste(target, t); 447 } 448 } catch (UnsupportedFlavorException e) { 449 UTUtils.LOGGER.log(Level.WARNING, "", e); } catch (IOException e) { 451 UTUtils.LOGGER.log(Level.WARNING, "", e); } 453 } 454 455 if (t.isDataFlavorSupported(UserTasksTransferable.USER_TASKS_FLAVOR)) { 456 return new TodoPaste(target, t); 457 } 458 return null; 459 } 460 461 public org.openide.nodes.Node.Cookie getCookie(Class type) { 462 UserTask uitem = (UserTask) item; 463 if (type == UserTask.class) { 464 return item; 465 } else { 466 return super.getCookie(type); 467 } 468 } 469 470 public void setName(String nue) { 471 super.setName(nue); 472 if (!nue.equals(item.getSummary())) { 473 item.setSummary(nue); 474 } 475 } 476 477 public Transferable clipboardCopy() throws IOException { 478 final UserTask copy = (UserTask) item.clone(); 479 return new ExTransferable.Single(UserTasksTransferable.USER_TASKS_FLAVOR) { 480 protected Object getData() { 481 return copy; 482 } 483 }; 484 } 485 486 public Transferable clipboardCut() throws IOException { 487 destroy(); 488 return clipboardCopy(); 489 } 490 491 public void destroy() throws IOException { 492 AdvancedTreeTableNode n = 493 (AdvancedTreeTableNode) this.node.findNextNodeAfterDelete(); 494 item.destroy(); 495 if (item.getParent() != null) 496 item.getParent().getSubtasks().remove(item); 497 else 498 utl.getSubtasks().remove(item); 499 super.destroy(); 500 if (n != null) { 501 TreePath tp = new TreePath (n.getPathToRoot()); 502 tt.select(tp); 503 tt.scrollTo(tp); 504 } 505 } 506 507 512 public void pasteTask(UserTask t) { 513 t = (UserTask) t.clone(); 514 item.getSubtasks().add(t); 515 int index = this.node.getIndexOfObject(t); 516 if (index >= 0) { 517 AdvancedTreeTableNode n = 518 (AdvancedTreeTableNode) this.node.getChildAt(index); 519 TreePath tp = new TreePath (n.getPathToRoot()); 520 tt.expandAllPath(tp); 521 tt.select(tp); 522 tt.scrollTo(tp); 523 } 524 } 525 526 529 private static final class TodoPaste extends PasteType { 530 private final Transferable t; 531 private final Node target; 532 533 539 public TodoPaste(Node target, Transferable t) { 540 this.t = t; 541 this.target = target; 542 } 543 544 public String getName() { 545 return NbBundle.getMessage(UserTasksTransferable.class, 546 "LBL_todo_paste_as_subtask"); } 548 549 public HelpCtx getHelpCtx() { 550 return new HelpCtx("org.netbeans.modules.todo"); } 552 553 public Transferable paste() throws IOException { 554 try { 555 if (t.isDataFlavorSupported(ExTransferable.multiFlavor)) { 556 final MultiTransferObject mto = (MultiTransferObject) 558 t.getTransferData(ExTransferable.multiFlavor); 559 if (mto.areDataFlavorsSupported( 560 new DataFlavor [] {UserTasksTransferable.USER_TASKS_FLAVOR})) { 561 for (int i = 0; i < mto.getCount(); i++) { 562 UserTask item = (UserTask) 563 mto.getTransferData(i, UserTasksTransferable.USER_TASKS_FLAVOR); 564 addTask(item); 565 } 566 return null; 567 } 568 } 569 570 if (t.isDataFlavorSupported(UserTasksTransferable.USER_TASKS_FLAVOR)) { 571 UserTask item = 572 (UserTask) t.getTransferData(UserTasksTransferable.USER_TASKS_FLAVOR); 573 addTask(item); 574 } 575 } catch (UnsupportedFlavorException ufe) { 576 IOException ioe = (IOException ) new IOException ( 578 ufe.toString()).initCause(ufe); 579 throw ioe; 580 } 581 return null; 582 } 583 584 589 private void addTask(UserTask item) { 590 UserTask ut; 591 if (item instanceof UserTask) { 592 ut = (UserTask) item; 593 } else { 594 ut = new UserTask(item.getSummary(), item.getList()); 595 ut.setDetails(item.getDetails()); 596 ut.setLine(item.getLine()); 597 ut.setPriority(item.getPriority()); 598 } 599 ((UserTaskNode) target).pasteTask(ut); 600 } 601 } 602 } 603 604 | Popular Tags |