core.Task-independent UserTask BLD200409191800
authorlebedkov@netbeans.org
Sun, 19 Sep 2004 12:14:27 +0000
changeset 5244f5a1d4cf3d14
parent 5243 db42970bbfd4
child 5245 41fa375e36c9
core.Task-independent UserTask
tasklist.usertasks/src/org/netbeans/modules/tasklist/usertasks/Bundle.properties
tasklist.usertasks/src/org/netbeans/modules/tasklist/usertasks/DateSelectionPanel.form
tasklist.usertasks/src/org/netbeans/modules/tasklist/usertasks/DateSelectionPanel.java
tasklist.usertasks/src/org/netbeans/modules/tasklist/usertasks/DurationPanel.java
tasklist.usertasks/src/org/netbeans/modules/tasklist/usertasks/EditTaskPanel.java
tasklist.usertasks/src/org/netbeans/modules/tasklist/usertasks/TaskListLoader.java
tasklist.usertasks/src/org/netbeans/modules/tasklist/usertasks/UserTaskDuePanel.java
tasklist.usertasks/src/org/netbeans/modules/tasklist/usertasks/UserTaskNode.java
tasklist.usertasks/src/org/netbeans/modules/tasklist/usertasks/UserTaskView.java
tasklist.usertasks/src/org/netbeans/modules/tasklist/usertasks/UserTaskViewListener.java
tasklist.usertasks/src/org/netbeans/modules/tasklist/usertasks/translators/ICalImportFormat.java
tasklist.usertasks/src/org/netbeans/modules/tasklist/usertasks/translators/XmlExportFormat.java
tasklist.usertasks/src/org/netbeans/modules/tasklist/usertasks/treetable/AdvancedTreeTableNode.java
tasklist.usertasks/src/org/netbeans/modules/tasklist/usertasks/treetable/SortingHeaderRenderer.java
tasklist.usertasks/test/qa-functional/testCases.html
     1.1 --- a/tasklist.usertasks/src/org/netbeans/modules/tasklist/usertasks/Bundle.properties	Sat Sep 18 08:44:49 2004 +0000
     1.2 +++ b/tasklist.usertasks/src/org/netbeans/modules/tasklist/usertasks/Bundle.properties	Sun Sep 19 12:14:27 2004 +0000
     1.3 @@ -22,6 +22,9 @@
     1.4  OpenIDE-Module-Short-Description=This module helps you track your tasks
     1.5  OpenIDE-Module-Long-Description=This module provides a table list where you can enter your tasks and their subtasks, sort them, etc.
     1.6  
     1.7 +## UserTaskView
     1.8 +default-filter-name=Default Filter
     1.9 +
    1.10  LBL_ViewTodoList=&User Tasks
    1.11  TaskViewName=User Tasks
    1.12  
    1.13 @@ -203,4 +206,18 @@
    1.14  PurgeTasks=Do you want to permanently delete all completed subtasks?
    1.15  
    1.16  ## NewTaskAction
    1.17 -BTN_AddAnother=Add Another
    1.18 \ No newline at end of file
    1.19 +BTN_AddAnother=Add Another
    1.20 +
    1.21 +## MoveUpAction
    1.22 +MoveUp=Move Up
    1.23 +
    1.24 +## GotoUserTaskAction.java
    1.25 +LBL_Goto=Go To Source
    1.26 +
    1.27 +## UserTaskTransfer.java
    1.28 +LBL_todo_flavor=Tasks
    1.29 +
    1.30 +## ExpandAllUserTasksAction.java
    1.31 +LBL_ExpandAll=Expand All
    1.32 +
    1.33 +
     2.1 --- a/tasklist.usertasks/src/org/netbeans/modules/tasklist/usertasks/DateSelectionPanel.form	Sat Sep 18 08:44:49 2004 +0000
     2.2 +++ b/tasklist.usertasks/src/org/netbeans/modules/tasklist/usertasks/DateSelectionPanel.form	Sun Sep 19 12:14:27 2004 +0000
     2.3 @@ -101,9 +101,6 @@
     2.4                    <Connection code="new DateSelectionTableModel()" type="code"/>
     2.5                  </Property>
     2.6                  <Property name="cellSelectionEnabled" type="boolean" value="true"/>
     2.7 -                <Property name="preferredScrollableViewportSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
     2.8 -                  <Dimension value="[450, 150]"/>
     2.9 -                </Property>
    2.10                  <Property name="showHorizontalLines" type="boolean" value="false"/>
    2.11                  <Property name="showVerticalLines" type="boolean" value="false"/>
    2.12                </Properties>
     3.1 --- a/tasklist.usertasks/src/org/netbeans/modules/tasklist/usertasks/DateSelectionPanel.java	Sat Sep 18 08:44:49 2004 +0000
     3.2 +++ b/tasklist.usertasks/src/org/netbeans/modules/tasklist/usertasks/DateSelectionPanel.java	Sun Sep 19 12:14:27 2004 +0000
     3.3 @@ -86,9 +86,9 @@
     3.4          calendar = new GregorianCalendar();
     3.5          yearFld.setText(Integer.toString(calendar.get(calendar.YEAR)));
     3.6          
     3.7 -        format = new SimpleDateFormat("HH:mm:ss");
     3.8 +        format = new SimpleDateFormat("HH:mm:ss"); // NOI18N
     3.9          timeFld.setText(format.format(date));        
    3.10 -        format.applyPattern("MMMM");
    3.11 +        format.applyPattern("MMMM"); // NOI18N
    3.12          
    3.13          int curr = calendar.get(calendar.MONTH);
    3.14          calendar.set(calendar.MONTH,
    3.15 @@ -118,7 +118,7 @@
    3.16      public Date getDate() {
    3.17          Date ret;
    3.18          try {
    3.19 -            format.applyPattern("HH:mm:ss");
    3.20 +            format.applyPattern("HH:mm:ss"); // NOI18N
    3.21              calendar.setTime(format.parse(timeFld.getText()));
    3.22              calendar.set(calendar.MONTH, monthNameCmb.getSelectedIndex());
    3.23              calendar.set(calendar.YEAR, Integer.parseInt(yearFld.getText()));
    3.24 @@ -156,7 +156,7 @@
    3.25          monthNameCmb.setMaximumRowCount(12);
    3.26          monthNameCmb.addActionListener(new java.awt.event.ActionListener() {
    3.27              public void actionPerformed(java.awt.event.ActionEvent evt) {
    3.28 -                DateSelectionPanel.this.monthNameCmbActionPerformed(evt);
    3.29 +                monthNameCmbActionPerformed(evt);
    3.30              }
    3.31          });
    3.32  
    3.33 @@ -165,7 +165,7 @@
    3.34          prevYearBtn.setText("<");
    3.35          prevYearBtn.addActionListener(new java.awt.event.ActionListener() {
    3.36              public void actionPerformed(java.awt.event.ActionEvent evt) {
    3.37 -                DateSelectionPanel.this.prevYearBtnActionPerformed(evt);
    3.38 +                prevYearBtnActionPerformed(evt);
    3.39              }
    3.40          });
    3.41  
    3.42 @@ -187,7 +187,7 @@
    3.43          });
    3.44          yearFld.addFocusListener(new java.awt.event.FocusAdapter() {
    3.45              public void focusLost(java.awt.event.FocusEvent evt) {
    3.46 -                DateSelectionPanel.this.yearFldFocusLost(evt);
    3.47 +                yearFldFocusLost(evt);
    3.48              }
    3.49          });
    3.50  
    3.51 @@ -196,7 +196,7 @@
    3.52          nextYearBtn.setText(">");
    3.53          nextYearBtn.addActionListener(new java.awt.event.ActionListener() {
    3.54              public void actionPerformed(java.awt.event.ActionEvent evt) {
    3.55 -                DateSelectionPanel.this.nextYearBtnActionPerformed(evt);
    3.56 +                nextYearBtnActionPerformed(evt);
    3.57              }
    3.58          });
    3.59  
    3.60 @@ -285,16 +285,16 @@
    3.61      
    3.62      
    3.63      // Variables declaration - do not modify//GEN-BEGIN:variables
    3.64 -    private javax.swing.JScrollPane jScrollPane1;
    3.65      private javax.swing.JTable calendarTable;
    3.66      private javax.swing.JLabel jLabel1;
    3.67 +    private javax.swing.JPanel jPanel1;
    3.68 +    private javax.swing.JPanel jPanel2;
    3.69 +    private javax.swing.JScrollPane jScrollPane1;
    3.70 +    private javax.swing.JComboBox monthNameCmb;
    3.71 +    private javax.swing.JButton nextYearBtn;
    3.72 +    private javax.swing.JButton prevYearBtn;
    3.73      private javax.swing.JTextField timeFld;
    3.74 -    private javax.swing.JButton prevYearBtn;
    3.75 -    private javax.swing.JPanel jPanel2;
    3.76      private javax.swing.JTextField yearFld;
    3.77 -    private javax.swing.JComboBox monthNameCmb;
    3.78 -    private javax.swing.JPanel jPanel1;
    3.79 -    private javax.swing.JButton nextYearBtn;
    3.80      // End of variables declaration//GEN-END:variables
    3.81      
    3.82      /**
    3.83 @@ -314,7 +314,7 @@
    3.84          public DateSelectionTableModel() {
    3.85              columnNames = new Object[7];
    3.86              calendar = new GregorianCalendar();
    3.87 -            SimpleDateFormat format = new SimpleDateFormat("EEEE");
    3.88 +            SimpleDateFormat format = new SimpleDateFormat("EEEE"); // NOI18N
    3.89              
    3.90              calendar.set(calendar.DAY_OF_WEEK,             
    3.91                           calendar.getFirstDayOfWeek());
    3.92 @@ -584,7 +584,10 @@
    3.93                  c.set(Calendar.DAY_OF_MONTH, panel.tablemodel.days[1][0].intValue());
    3.94                  
    3.95                  if (c.get(Calendar.DAY_OF_WEEK) != c.getFirstDayOfWeek()) {
    3.96 -                    System.err.println("The assignment of day of week is incorrect for year: " + c.get(Calendar.YEAR) + " and month: " + c.get(Calendar.MONTH));
    3.97 +                    System.err.println(
    3.98 +                        "The assignment of day of week is incorrect for year: " + // NOI18N
    3.99 +                        c.get(Calendar.YEAR) + 
   3.100 +                        " and month: " + c.get(Calendar.MONTH)); // NOI18N
   3.101                  }
   3.102              }
   3.103          }
     4.1 --- a/tasklist.usertasks/src/org/netbeans/modules/tasklist/usertasks/DurationPanel.java	Sat Sep 18 08:44:49 2004 +0000
     4.2 +++ b/tasklist.usertasks/src/org/netbeans/modules/tasklist/usertasks/DurationPanel.java	Sun Sep 19 12:14:27 2004 +0000
     4.3 @@ -108,8 +108,8 @@
     4.4      gridBagConstraints = new java.awt.GridBagConstraints();
     4.5      gridBagConstraints.gridx = 0;
     4.6      gridBagConstraints.gridy = 1;
     4.7 +    gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
     4.8      gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 12);
     4.9 -    gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
    4.10      add(jSpinnerDays, gridBagConstraints);
    4.11  
    4.12      org.openide.awt.Mnemonics.setLocalizedText(jLabel2, org.openide.util.NbBundle.getMessage(DurationPanel.class, "Hours")); // NOI18N);
    4.13 @@ -123,8 +123,8 @@
    4.14      gridBagConstraints = new java.awt.GridBagConstraints();
    4.15      gridBagConstraints.gridx = 1;
    4.16      gridBagConstraints.gridy = 1;
    4.17 +    gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
    4.18      gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 12);
    4.19 -    gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
    4.20      add(jSpinnerHours, gridBagConstraints);
    4.21  
    4.22      org.openide.awt.Mnemonics.setLocalizedText(jLabel3, org.openide.util.NbBundle.getMessage(DurationPanel.class, "Minutes")); // NOI18N);
    4.23 @@ -138,8 +138,8 @@
    4.24      gridBagConstraints = new java.awt.GridBagConstraints();
    4.25      gridBagConstraints.gridx = 2;
    4.26      gridBagConstraints.gridy = 1;
    4.27 +    gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
    4.28      gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 12);
    4.29 -    gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
    4.30      add(jSpinnerMinutes, gridBagConstraints);
    4.31  
    4.32      jPanelPlaceholder.setPreferredSize(new java.awt.Dimension(0, 0));
     5.1 --- a/tasklist.usertasks/src/org/netbeans/modules/tasklist/usertasks/EditTaskPanel.java	Sat Sep 18 08:44:49 2004 +0000
     5.2 +++ b/tasklist.usertasks/src/org/netbeans/modules/tasklist/usertasks/EditTaskPanel.java	Sun Sep 19 12:14:27 2004 +0000
     5.3 @@ -89,7 +89,7 @@
     5.4                  parsePercents(p);
     5.5                  return true;
     5.6              } catch (NumberFormatException e) {
     5.7 -                UTUtils.LOGGER.fine("wrong format");
     5.8 +                UTUtils.LOGGER.fine("wrong format"); // NOI18N
     5.9                  return false;
    5.10              }
    5.11          }
    5.12 @@ -360,8 +360,8 @@
    5.13                  loadClass("org.netbeans.api.javahelp.Help"); // NOI18N
    5.14                  Object o = Lookup.getDefault().lookup(c);
    5.15                  if (o != null) {
    5.16 -                    Method m = c.getMethod("showHelp",
    5.17 -                    new Class[] {HelpCtx.class}); // NOI18N
    5.18 +                    Method m = c.getMethod("showHelp", // NOI18N
    5.19 +                        new Class[] {HelpCtx.class});
    5.20                      m.invoke(o, new Object[] {help});
    5.21                      return;
    5.22                  }
     6.1 --- a/tasklist.usertasks/src/org/netbeans/modules/tasklist/usertasks/TaskListLoader.java	Sat Sep 18 08:44:49 2004 +0000
     6.2 +++ b/tasklist.usertasks/src/org/netbeans/modules/tasklist/usertasks/TaskListLoader.java	Sun Sep 19 12:14:27 2004 +0000
     6.3 @@ -49,7 +49,7 @@
     6.4      protected static SystemAction[] standardActions;
     6.5  
     6.6      public TaskListLoader() {
     6.7 -        super("org.netbeans.modules.tasklist.usertasks.TaskListDataObject");//NOI18N
     6.8 +        super("org.netbeans.modules.tasklist.usertasks.TaskListDataObject"); // NOI18N
     6.9  
    6.10  	// These extensions MUST match the ones in the editor kits...
    6.11  	ExtensionList extensions = new ExtensionList();
     7.1 --- a/tasklist.usertasks/src/org/netbeans/modules/tasklist/usertasks/UserTaskDuePanel.java	Sat Sep 18 08:44:49 2004 +0000
     7.2 +++ b/tasklist.usertasks/src/org/netbeans/modules/tasklist/usertasks/UserTaskDuePanel.java	Sun Sep 19 12:14:27 2004 +0000
     7.3 @@ -64,16 +64,16 @@
     7.4          */
     7.5          gridBagConstraints = new java.awt.GridBagConstraints();
     7.6          gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
     7.7 +        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
     7.8          gridBagConstraints.insets = new java.awt.Insets(12, 12, 0, 12);
     7.9 -        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
    7.10          add(jLabel1, gridBagConstraints);
    7.11  
    7.12          descriptionFld.setEnabled(false);
    7.13          gridBagConstraints = new java.awt.GridBagConstraints();
    7.14          gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
    7.15          gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
    7.16 +        gridBagConstraints.weightx = 1.0;
    7.17          gridBagConstraints.insets = new java.awt.Insets(2, 12, 0, 12);
    7.18 -        gridBagConstraints.weightx = 1.0;
    7.19          add(descriptionFld, gridBagConstraints);
    7.20  
    7.21          jLabel2.setLabelFor(detailsArea);
    7.22 @@ -82,8 +82,8 @@
    7.23          */
    7.24          gridBagConstraints = new java.awt.GridBagConstraints();
    7.25          gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
    7.26 +        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
    7.27          gridBagConstraints.insets = new java.awt.Insets(12, 12, 0, 12);
    7.28 -        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
    7.29          add(jLabel2, gridBagConstraints);
    7.30  
    7.31          detailsArea.setPreferredSize(new java.awt.Dimension(400, 200));
    7.32 @@ -93,9 +93,9 @@
    7.33          gridBagConstraints = new java.awt.GridBagConstraints();
    7.34          gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
    7.35          gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
    7.36 -        gridBagConstraints.insets = new java.awt.Insets(2, 12, 11, 11);
    7.37          gridBagConstraints.weightx = 1.0;
    7.38          gridBagConstraints.weighty = 1.0;
    7.39 +        gridBagConstraints.insets = new java.awt.Insets(2, 12, 11, 11);
    7.40          add(jScrollPane1, gridBagConstraints);
    7.41  
    7.42      }//GEN-END:initComponents
    7.43 @@ -130,11 +130,11 @@
    7.44  
    7.45      
    7.46      // Variables declaration - do not modify//GEN-BEGIN:variables
    7.47 -    private javax.swing.JScrollPane jScrollPane1;
    7.48 -    private javax.swing.JLabel jLabel1;
    7.49      private javax.swing.JTextField descriptionFld;
    7.50      private javax.swing.JTextArea detailsArea;
    7.51 +    private javax.swing.JLabel jLabel1;
    7.52      private javax.swing.JLabel jLabel2;
    7.53 +    private javax.swing.JScrollPane jScrollPane1;
    7.54      // End of variables declaration//GEN-END:variables
    7.55      
    7.56  }
     8.1 --- a/tasklist.usertasks/src/org/netbeans/modules/tasklist/usertasks/UserTaskNode.java	Sat Sep 18 08:44:49 2004 +0000
     8.2 +++ b/tasklist.usertasks/src/org/netbeans/modules/tasklist/usertasks/UserTaskNode.java	Sun Sep 19 12:14:27 2004 +0000
     8.3 @@ -29,11 +29,8 @@
     8.4  import org.netbeans.modules.tasklist.client.SuggestionPriority;
     8.5  
     8.6  import org.netbeans.modules.tasklist.core.ExpandAllAction;
     8.7 -import org.netbeans.modules.tasklist.core.GoToTaskAction;
     8.8  import org.netbeans.modules.tasklist.core.TLUtils;
     8.9 -import org.netbeans.modules.tasklist.core.Task;
    8.10  import org.netbeans.modules.tasklist.core.TaskNode;
    8.11 -import org.netbeans.modules.tasklist.core.TaskTransfer;
    8.12  import org.netbeans.modules.tasklist.core.editors.LineNumberPropertyEditor;
    8.13  import org.netbeans.modules.tasklist.core.editors.PriorityPropertyEditor;
    8.14  import org.netbeans.modules.tasklist.core.export.ExportAction;
    8.15 @@ -128,7 +125,7 @@
    8.16              null,
    8.17              SystemAction.get(StartTaskAction.class),
    8.18              SystemAction.get(ShowTaskAction.class),
    8.19 -            SystemAction.get(GoToTaskAction.class),
    8.20 +            SystemAction.get(GoToUserTaskAction.class),
    8.21              null,
    8.22              SystemAction.get(CutAction.class),
    8.23              SystemAction.get(CopyAction.class),
    8.24 @@ -140,7 +137,7 @@
    8.25              null,
    8.26              SystemAction.get(FilterAction.class),
    8.27              SystemAction.get(PurgeTasksAction.class),
    8.28 -            SystemAction.get(ExpandAllAction.class),
    8.29 +            SystemAction.get(ExpandAllUserTasksAction.class),
    8.30              null,
    8.31              SystemAction.get(ImportAction.class),
    8.32              SystemAction.get(ExportAction.class),
    8.33 @@ -163,7 +160,7 @@
    8.34                  null,
    8.35                  SystemAction.get(FilterAction.class),
    8.36                  SystemAction.get(PurgeTasksAction.class),
    8.37 -                SystemAction.get(ExpandAllAction.class),
    8.38 +                SystemAction.get(ExpandAllUserTasksAction.class),
    8.39                  null,
    8.40                  SystemAction.get(ImportAction.class),
    8.41                  SystemAction.get(ExportAction.class),
    8.42 @@ -335,7 +332,7 @@
    8.43      }
    8.44      
    8.45      protected void createPasteTypes(java.awt.datatransfer.Transferable t, List s) {
    8.46 -        UTUtils.LOGGER.fine("entering");
    8.47 +        // UTUtils.LOGGER.fine("entering"); // NOI18N
    8.48          super.createPasteTypes(t, s);
    8.49          PasteType p = createTodoPasteType(this, t);
    8.50          if (p != null) {
    8.51 @@ -359,7 +356,7 @@
    8.52                  final MultiTransferObject mto = (MultiTransferObject)
    8.53                      t.getTransferData(ExTransferable.multiFlavor);
    8.54                  if (mto.areDataFlavorsSupported(
    8.55 -                    new DataFlavor[] {TaskTransfer.TODO_FLAVOR})) {
    8.56 +                    new DataFlavor[] {UserTaskTransfer.TODO_FLAVOR})) {
    8.57                      return new UserTaskNode.TodoPaste(target, t);
    8.58                  }
    8.59              } catch (UnsupportedFlavorException e) {
    8.60 @@ -369,7 +366,7 @@
    8.61              }
    8.62          } 
    8.63          
    8.64 -        if (t.isDataFlavorSupported(TaskTransfer.TODO_FLAVOR)) {
    8.65 +        if (t.isDataFlavorSupported(UserTaskTransfer.TODO_FLAVOR)) {
    8.66              return new TodoPaste(target, t);
    8.67          } 
    8.68          return null;
    8.69 @@ -383,7 +380,7 @@
    8.70              } else {
    8.71                  return new StartCookie(uitem);
    8.72              }
    8.73 -        } else if (type == Task.class) {
    8.74 +        } else if (type == UserTask.class) {
    8.75              return item;
    8.76          } else {
    8.77              return super.getCookie(type);
    8.78 @@ -400,7 +397,7 @@
    8.79      public Transferable clipboardCopy() throws IOException {
    8.80          UTUtils.LOGGER.fine("entering");
    8.81          final UserTask copy = (UserTask) item.clone();
    8.82 -        return new ExTransferable.Single(TaskTransfer.TODO_FLAVOR) {
    8.83 +        return new ExTransferable.Single(UserTaskTransfer.TODO_FLAVOR) {
    8.84              protected Object getData() {
    8.85                  return copy;
    8.86              }
    8.87 @@ -466,7 +463,7 @@
    8.88          }
    8.89          
    8.90          public String getName() {
    8.91 -            return NbBundle.getMessage(TaskTransfer.class, 
    8.92 +            return NbBundle.getMessage(UserTaskTransfer.class, 
    8.93                  "LBL_todo_paste_as_subtask"); // NOI18N
    8.94          }
    8.95          
    8.96 @@ -481,21 +478,21 @@
    8.97                      final MultiTransferObject mto = (MultiTransferObject)
    8.98                          t.getTransferData(ExTransferable.multiFlavor);
    8.99                      if (mto.areDataFlavorsSupported(
   8.100 -                        new DataFlavor[] {TaskTransfer.TODO_FLAVOR})) {
   8.101 +                        new DataFlavor[] {UserTaskTransfer.TODO_FLAVOR})) {
   8.102                          for (int i = 0; i < mto.getCount(); i++) {
   8.103                              UserTask item = (UserTask)
   8.104 -                                mto.getTransferData(i, TaskTransfer.TODO_FLAVOR);
   8.105 +                                mto.getTransferData(i, UserTaskTransfer.TODO_FLAVOR);
   8.106                              addTask(item);
   8.107                          }
   8.108                          return null;
   8.109                      }
   8.110                  } 
   8.111                  
   8.112 -                if (t.isDataFlavorSupported(TaskTransfer.TODO_FLAVOR)) {
   8.113 +                if (t.isDataFlavorSupported(UserTaskTransfer.TODO_FLAVOR)) {
   8.114                      UTUtils.LOGGER.fine(t.getTransferData(
   8.115 -                        TaskTransfer.TODO_FLAVOR).getClass().getName());
   8.116 +                        UserTaskTransfer.TODO_FLAVOR).getClass().getName());
   8.117                      UserTask item = 
   8.118 -                        (UserTask) t.getTransferData(TaskTransfer.TODO_FLAVOR);
   8.119 +                        (UserTask) t.getTransferData(UserTaskTransfer.TODO_FLAVOR);
   8.120                      addTask(item);
   8.121                  } 
   8.122              } catch (UnsupportedFlavorException ufe) {
     9.1 --- a/tasklist.usertasks/src/org/netbeans/modules/tasklist/usertasks/UserTaskView.java	Sat Sep 18 08:44:49 2004 +0000
     9.2 +++ b/tasklist.usertasks/src/org/netbeans/modules/tasklist/usertasks/UserTaskView.java	Sun Sep 19 12:14:27 2004 +0000
     9.3 @@ -13,16 +13,31 @@
     9.4  
     9.5  package org.netbeans.modules.tasklist.usertasks;
     9.6  
     9.7 +import java.awt.BorderLayout;
     9.8  import java.awt.Component;
     9.9 +import java.awt.Dimension;
    9.10 +import java.awt.FlowLayout;
    9.11 +import java.awt.Font;
    9.12 +import java.awt.FontMetrics;
    9.13 +import java.awt.Graphics2D;
    9.14 +import java.awt.Image;
    9.15  import java.awt.Window;
    9.16  import java.awt.event.MouseEvent;
    9.17 +import java.awt.image.BufferedImage;
    9.18  import java.io.IOException;
    9.19  import java.io.ObjectInput;
    9.20  import java.io.ObjectOutput;
    9.21 +import java.lang.ref.Reference;
    9.22 +import java.lang.ref.WeakReference;
    9.23  import java.net.URL;
    9.24  import java.util.ArrayList;
    9.25 +import java.util.Collection;
    9.26 +import java.util.Collections;
    9.27  import java.util.Date;
    9.28 +import java.util.HashMap;
    9.29  import java.util.Iterator;
    9.30 +import java.util.List;
    9.31 +import java.util.Map;
    9.32  import java.util.logging.Level;
    9.33  import java.util.logging.Logger;
    9.34  
    9.35 @@ -31,27 +46,29 @@
    9.36  import javax.swing.InputMap;
    9.37  import javax.swing.JComponent;
    9.38  import javax.swing.JFrame;
    9.39 +import javax.swing.JLabel;
    9.40 +import javax.swing.JPanel;
    9.41  import javax.swing.JPopupMenu;
    9.42  import javax.swing.JScrollPane;
    9.43 +import javax.swing.JTable;
    9.44 +import javax.swing.JToolBar;
    9.45  import javax.swing.KeyStroke;
    9.46  import javax.swing.SwingUtilities;
    9.47 +import javax.swing.UIDefaults;
    9.48 +import javax.swing.UIManager;
    9.49 +import javax.swing.table.TableColumnModel;
    9.50  import javax.swing.text.DefaultEditorKit;
    9.51  import javax.swing.tree.TreePath;
    9.52  
    9.53  import org.netbeans.modules.tasklist.client.SuggestionPriority;
    9.54 -import org.netbeans.modules.tasklist.core.ColumnProperty;
    9.55 -import org.netbeans.modules.tasklist.core.GoToTaskAction;
    9.56 -import org.netbeans.modules.tasklist.core.ObservableList;
    9.57  import org.netbeans.modules.tasklist.core.TLUtils;
    9.58 -import org.netbeans.modules.tasklist.core.Task;
    9.59 -import org.netbeans.modules.tasklist.core.TaskAnnotation;
    9.60 -import org.netbeans.modules.tasklist.core.TaskListView;
    9.61 -import org.netbeans.modules.tasklist.core.TaskListener;
    9.62  import org.netbeans.modules.tasklist.core.columns.ColumnsConfiguration;
    9.63  import org.netbeans.modules.tasklist.core.export.ExportAction;
    9.64  import org.netbeans.modules.tasklist.core.export.ExportImportFormat;
    9.65  import org.netbeans.modules.tasklist.core.export.ExportImportProvider;
    9.66 +import org.netbeans.modules.tasklist.core.filter.Filter;
    9.67  import org.netbeans.modules.tasklist.core.filter.FilterAction;
    9.68 +import org.netbeans.modules.tasklist.core.filter.FilterRepository;
    9.69  import org.netbeans.modules.tasklist.core.filter.RemoveFilterAction;
    9.70  import org.netbeans.modules.tasklist.usertasks.translators.HtmlExportFormat;
    9.71  import org.netbeans.modules.tasklist.usertasks.translators.ICalExportFormat;
    9.72 @@ -59,12 +76,22 @@
    9.73  import org.netbeans.modules.tasklist.usertasks.translators.XmlExportFormat;
    9.74  import org.netbeans.modules.tasklist.usertasks.treetable.ChooseColumnsPanel;
    9.75  import org.netbeans.modules.tasklist.usertasks.treetable.TreeTableModel;
    9.76 +import org.openide.ErrorManager;
    9.77  import org.openide.actions.DeleteAction;
    9.78 +import org.openide.actions.FindAction;
    9.79  import org.openide.awt.MouseUtils;
    9.80 +import org.openide.cookies.InstanceCookie;
    9.81 +import org.openide.explorer.ExplorerManager;
    9.82 +import org.openide.explorer.ExplorerUtils;
    9.83  import org.openide.filesystems.FileObject;
    9.84 +import org.openide.filesystems.FileSystem;
    9.85 +import org.openide.filesystems.Repository;
    9.86  import org.openide.filesystems.URLMapper;
    9.87 +import org.openide.loaders.DataObject;
    9.88 +import org.openide.loaders.DataObjectNotFoundException;
    9.89  import org.openide.nodes.Node;
    9.90  import org.openide.util.HelpCtx;
    9.91 +import org.openide.util.Lookup;
    9.92  import org.openide.util.NbBundle;
    9.93  import org.openide.util.Utilities;
    9.94  import org.openide.util.actions.SystemAction;
    9.95 @@ -77,8 +104,8 @@
    9.96   *
    9.97   * @author Tor Norbye
    9.98   */
    9.99 -public class UserTaskView extends TaskListView implements TaskListener,
   9.100 -ExportImportProvider {
   9.101 +public class UserTaskView extends TopComponent implements UserTaskListener, 
   9.102 +ExplorerManager.Provider, ExportImportProvider {
   9.103      // TODO: replace these constants with the equivalents from UserTaskProperties
   9.104      public static final String PROP_TASK_DONE = UserTaskProperties.PROPID_DONE;
   9.105      public static final String PROP_TASK_DUE = UserTaskProperties.PROPID_DUE_DATE;
   9.106 @@ -98,8 +125,8 @@
   9.107  
   9.108      private static UserTaskView defview = null;
   9.109      
   9.110 -    /** contains also the default view */
   9.111 -    private static ArrayList views = null; // leak??? YES! Remove in componentClosed!
   9.112 +    /** Keeps track of all UserTaskViews */
   9.113 +    private transient static List views = new ArrayList();
   9.114  
   9.115      /** 
   9.116       * Returns the view with the default task list. The view will be opened if
   9.117 @@ -123,7 +150,9 @@
   9.118  	return defview;
   9.119      }
   9.120  
   9.121 -    /** Return true iff the default view has been created already */
   9.122 +    /** 
   9.123 +     * Return true iff the default view has been created already 
   9.124 +     */
   9.125      static boolean defaultViewCreated() {
   9.126          return defview != null;
   9.127      }
   9.128 @@ -133,33 +162,22 @@
   9.129       *
   9.130       * @return current view
   9.131       */
   9.132 -    public static TaskListView getCurrent() {
   9.133 -	// Try to figure out which view is current. If none is found to
   9.134 -	// be visible, guess one.
   9.135 -        if (views == null) {
   9.136 -            return defview;
   9.137 -        }
   9.138 -	Iterator it = views.iterator();
   9.139 -        while (it.hasNext()) {
   9.140 -	    UserTaskView tlv = (UserTaskView)it.next();
   9.141 -            if (tlv.isShowing()) {
   9.142 -		return tlv;
   9.143 -	    }
   9.144 -	}
   9.145 -        return defview;
   9.146 +    public static UserTaskView getCurrent() {
   9.147 +        TopComponent activated = WindowManager.getDefault().getRegistry().getActivated();
   9.148 +        if (activated instanceof UserTaskView)
   9.149 +            return (UserTaskView) activated;
   9.150 +        else 
   9.151 +            return null;
   9.152      }    
   9.153  
   9.154      /** Locate a particular view showing the given list */
   9.155      static UserTaskView findListView(FileObject file) {
   9.156 -        if (views == null) {
   9.157 -            return null;
   9.158 -        }
   9.159   	Iterator it = views.iterator();
   9.160          while (it.hasNext()) {
   9.161 -	    UserTaskView tlv = (UserTaskView)it.next();
   9.162 -            if (((UserTaskList)tlv.getList()).getFile() == file) {
   9.163 +            WeakReference wr = (WeakReference) it.next();
   9.164 +	    UserTaskView tlv = (UserTaskView) wr.get();
   9.165 +            if (tlv != null && tlv.getList().getFile() == file) 
   9.166                  return tlv;
   9.167 -            }
   9.168          }
   9.169          return null;
   9.170      }
   9.171 @@ -179,6 +197,25 @@
   9.172          this(UserTaskList.getDefault(), true);
   9.173      }
   9.174  
   9.175 +    /**
   9.176 +     * @param category view's category. This value will be used as the name
   9.177 +     * for a subdirectory of "SystemFileSystem/TaskList/" for columns settings
   9.178 +     */
   9.179 +    private UserTaskView(String category, String title, Image icon,
   9.180 +                        boolean persistent, UserTaskList tasklist) {
   9.181 +        init_();
   9.182 +
   9.183 +        assert category != null : "category == null";
   9.184 +
   9.185 +        this.category = category;
   9.186 +        setName(title);
   9.187 +        this.persistent = persistent;
   9.188 +        setIcon(icon);
   9.189 +
   9.190 +        registerTaskListView(this);
   9.191 +        setModel(tasklist);
   9.192 +    }
   9.193 +
   9.194      /** 
   9.195       * Construct a new UserTaskView showing a given list. Most work
   9.196       * is deferred to componentOpened. NOTE: this is only for use by
   9.197 @@ -189,7 +226,7 @@
   9.198       * constructor to finalize construction of the window.
   9.199       */
   9.200      public UserTaskView(UserTaskList list, boolean isDefault) {
   9.201 -	super(UserTaskList.USER_CATEGORY,
   9.202 +	this(UserTaskList.USER_CATEGORY,
   9.203                isDefault ?
   9.204                NbBundle.getMessage(UserTaskView.class,
   9.205                      "TaskViewName") : // NOI18N
   9.206 @@ -202,18 +239,17 @@
   9.207  	if (isDefault && (defview == null)) {
   9.208  	    defview = this;
   9.209  	}
   9.210 -	synchronized (TaskListView.class) {
   9.211 -	    if (views == null) {
   9.212 -		views = new ArrayList();
   9.213 -	    }
   9.214 -	    views.add(this);
   9.215 -	}
   9.216      }
   9.217  
   9.218 +    /**
   9.219 +     * Returns actions for the toolbar.
   9.220 +     *
   9.221 +     * @return actions for the toolbar or null
   9.222 +     */
   9.223      public SystemAction[] getToolBarActions() {
   9.224          return new SystemAction[] {
   9.225              SystemAction.get(NewTaskAction.class),
   9.226 -            SystemAction.get(GoToTaskAction.class),
   9.227 +            SystemAction.get(GoToUserTaskAction.class),
   9.228              SystemAction.get(FilterAction.class),
   9.229              SystemAction.get(RemoveFilterAction.class),
   9.230              SystemAction.get(StartTaskAction.class)
   9.231 @@ -246,6 +282,13 @@
   9.232      
   9.233      public void componentActivated() {
   9.234          super.componentActivated();
   9.235 +        assert initialized : 
   9.236 +            "#37438 dangling componentActivated event, no componentOpened()" + 
   9.237 +            " called at " + this;
   9.238 +        ExplorerUtils.activateActions(manager, true);
   9.239 +        RemoveFilterAction removeFilter =
   9.240 +                (RemoveFilterAction) SystemAction.get(RemoveFilterAction.class);
   9.241 +        removeFilter.enable();
   9.242  
   9.243          // it's strange I'd expect live listener based solution
   9.244          Iterator it = getModel().getTasks().iterator();
   9.245 @@ -297,10 +340,131 @@
   9.246       * @todo Use a more robust serialization format (not int uid based)
   9.247       * @throws IOException
   9.248       * @throws ClassNotFoundException  
   9.249 +     */
   9.250 +    public void readExternalCore(ObjectInput objectInput) throws IOException, java.lang.ClassNotFoundException {
   9.251 +        // Don't call super!
   9.252 +        // See writeExternal for justification
   9.253 +        //super.readExternal(objectInput);
   9.254 +
   9.255 +        int ver = objectInput.read();
   9.256 +        //assert ver <= 4 : "serialization version incorrect; should be 1 to 4";
   9.257 +
   9.258 +        // Read in the UID of the currently selected task, or null if none
   9.259 +        // TODO: Not yet implemented
   9.260 +        String selUID = (String) objectInput.readObject();
   9.261 +
   9.262 +        if (ver == 4)
   9.263 +            return;
   9.264 +
   9.265 +        int sortingColumn = objectInput.read();
   9.266 +        int sortAscendingInt = objectInput.read();
   9.267 +        boolean ascending = (sortAscendingInt != 0);
   9.268 +        int numVisible = objectInput.read();
   9.269 +
   9.270 +        // Account for conversion to unsigned byte in writeExternal
   9.271 +        if (sortingColumn == 255) {
   9.272 +            sortingColumn = -1;
   9.273 +        }
   9.274 +
   9.275 +        /*
   9.276 +        System.out.println("readExternal: " + getClass().getName()); // NOI18N
   9.277 +        System.out.println("numVisible is " + numVisible); // NOI18N
   9.278 +        System.out.println("sortingColumn is " + sortingColumn); // NOI18N
   9.279 +        System.out.println("ascending is " + ascending); // NOI18N
   9.280 +        */
   9.281 +
   9.282 +        if (numVisible > 0) {
   9.283 +            String[] columns = new String[0];
   9.284 +            int numColumns = columns.length;
   9.285 +            boolean[] columnVisible = new boolean[numColumns];
   9.286 +            for (int i = 0; i < numColumns; i++) {
   9.287 +                columnVisible[i] = false;
   9.288 +            }
   9.289 +            for (int i = 0; i < numVisible; i++) {
   9.290 +                int uid = objectInput.read();
   9.291 +                /* don't do anything. we just read the bytes
   9.292 +                int index;
   9.293 +                if ((uid < numColumns) && (columns[uid].uid == uid)) {
   9.294 +                    // UID == column index. This is the scenario for now
   9.295 +                    // until we delete columns in the middle etc.
   9.296 +                    index = uid;
   9.297 +                } else {
   9.298 +                    // Have to search for the uid
   9.299 +                    index = -1;
   9.300 +                    for (int j = 0; j < numColumns; j++) {
   9.301 +                        if (columns[j].uid == uid) {
   9.302 +                            index = j;
   9.303 +                            break;
   9.304 +                        }
   9.305 +                    }
   9.306 +                }
   9.307 +
   9.308 +    if (index != -1) {
   9.309 +                    columnVisible[index] = true;
   9.310 +
   9.311 +                    // Set sorting attribute
   9.312 +                    if (sortingColumn == uid) {
   9.313 +                    columns[index].setValue("SortingColumnTTV", // NOI18N
   9.314 +                                Boolean.TRUE);
   9.315 +                    // Descending sort?
   9.316 +                    if (!ascending) {
   9.317 +                        columns[index].setValue("DescendingOrderTTV", // NOI18N
   9.318 +                                    Boolean.TRUE);
   9.319 +                    }
   9.320 +                    }
   9.321 +                }
   9.322 +    */
   9.323 +            }
   9.324 +
   9.325 +            //System.out.print("Column visibility: {");
   9.326 +            /* we don't do anything. we just read the bytes
   9.327 +for (int i = 0; i < columns.length; i++) {
   9.328 +//System.out.print(" " + columnVisible[i]);
   9.329 +
   9.330 +            // Is this column visible?
   9.331 +            if (columnVisible[i]) {
   9.332 +                columns[i].setValue("InvisibleInTreeTableView", // NOI18N
   9.333 +                        // NOTE reverse logic: this is INvisible
   9.334 +                        Boolean.FALSE);
   9.335 +            } else {
   9.336 +                // Necessary because by default some columns
   9.337 +                // set invisible by default, so I have to
   9.338 +                // override these
   9.339 +                columns[i].setValue("InvisibleInTreeTableView", // NOI18N
   9.340 +                        // NOTE reverse logic: this is INvisible
   9.341 +                        Boolean.TRUE);
   9.342 +            }
   9.343 +            }
   9.344 +*/
   9.345 +//System.out.println(" }");
   9.346 +        }
   9.347 +
   9.348 +        if (ver >= 2) {
   9.349 +            category = (String) objectInput.readObject();
   9.350 +            objectInput.readObject(); // ignoring title
   9.351 +            int persistentInt = objectInput.read();
   9.352 +            persistent = (persistentInt != 0);
   9.353 +        } else {
   9.354 +            category = UserTaskList.USER_CATEGORY; // for compatibility only
   9.355 +        }
   9.356 +
   9.357 +        synchronized (UserTaskView.class) {
   9.358 +            views.add(new WeakReference(this));
   9.359 +        }
   9.360 +    }
   9.361 +    
   9.362 +    /** 
   9.363 +     * Read in a serialized version of the tasklist
   9.364 +     * and reads in sorting preferences etc. such that
   9.365 +     * we use the same preferences now.
   9.366 +     * @param objectInput object stream to read from
   9.367 +     * @todo Use a more robust serialization format (not int uid based)
   9.368 +     * @throws IOException
   9.369 +     * @throws ClassNotFoundException  
   9.370       */    
   9.371      public void readExternal(ObjectInput objectInput) throws IOException, java.lang.ClassNotFoundException {
   9.372          try {
   9.373 -        super.readExternal(objectInput);
   9.374 +        readExternalCore(objectInput);
   9.375  	int ver = objectInput.read();
   9.376  
   9.377          if (ver >= 2) {
   9.378 @@ -337,6 +501,63 @@
   9.379       * columns, sorting order, etc.) such that they can
   9.380       * be reconstructed the next time the IDE is started.
   9.381       * @todo Use a more robust serialization format (not int uid based)
   9.382 +     * @param objectOutput Object stream to write to
   9.383 +     * @throws IOException  
   9.384 +     */
   9.385 +    public void writeExternalCore(ObjectOutput objectOutput) throws IOException {
   9.386 +        if (!persistent) {
   9.387 +            ErrorManager.getDefault().log(
   9.388 +                    ErrorManager.INFORMATIONAL,
   9.389 +                    "Warning: This tasklist window (" + getName() + ") should not have been persisted!");
   9.390 +            return;
   9.391 +        }
   9.392 +
   9.393 +        // Don't call super.writeExternal.
   9.394 +        // Our parents are ExplorerPanel and TopComponent.
   9.395 +        // ExplorerPanel writes out the ExplorerManager, which tries
   9.396 +        //  to write out the node selection, explored content, etc.
   9.397 +        //  We don't want that. Specific tasklist children, such as
   9.398 +        //  the usertasklist, may want to persist the selection but
   9.399 +        //  most (such as the suggestions view, source scan etc,
   9.400 +        //  don't want this.)
   9.401 +        // TopComponent persists the name and tooltip text; we
   9.402 +        //  don't care about that either.
   9.403 +        //super.writeExternal(objectOutput);
   9.404 +
   9.405 +        // Version 1 format:
   9.406 +        // String: selected uid
   9.407 +        // byte: sortingColumn (255: no sort, otherwise, sorting id)
   9.408 +        // byte: sort ascending (0:false or 1:true)
   9.409 +        // byte: number of visible columns (N)
   9.410 +        // N bytes: visible column uids
   9.411 +
   9.412 +        // Version 4 format:
   9.413 +        // String: selected UID
   9.414 +        // String: category
   9.415 +        // String: title
   9.416 +        // byte: persistent
   9.417 +
   9.418 +        // TODO Additional:
   9.419 +        // String Object: selected task? (should this be a multi-selection?)
   9.420 +
   9.421 +        // Write out the UID of the currently selected task, or null if none
   9.422 +        objectOutput.write(4); // SERIAL VERSION
   9.423 +
   9.424 +        // Write out the UID of the currently selected task, or null if none
   9.425 +        objectOutput.writeObject(null); // Not yet implemented
   9.426 +
   9.427 +        // Write out the window's properties:
   9.428 +        // TODO: do we really need these properties?
   9.429 +        // objectOutput.writeObject(category);
   9.430 +        // objectOutput.writeObject(title);
   9.431 +        // objectOutput.write(persistent ? 1 : 0);
   9.432 +    }
   9.433 +
   9.434 +    /** 
   9.435 +     * Write out relevant settings in the window (visible
   9.436 +     * columns, sorting order, etc.) such that they can
   9.437 +     * be reconstructed the next time the IDE is started.
   9.438 +     * @todo Use a more robust serialization format (not int uid based)
   9.439       *
   9.440       * @param objectOutput Object stream to write to
   9.441       * @throws IOException  
   9.442 @@ -348,7 +569,7 @@
   9.443  	    return;
   9.444  	}
   9.445  
   9.446 -        super.writeExternal(objectOutput);
   9.447 +        writeExternalCore(objectOutput);
   9.448  
   9.449          UserTaskList tl = (UserTaskList)getList();
   9.450          tl.save(); // Only does something if the todolist has changed...        
   9.451 @@ -370,10 +591,11 @@
   9.452          }
   9.453      }
   9.454  
   9.455 -    protected ColumnProperty[] createColumns() {
   9.456 -        return new ColumnProperty[0];
   9.457 -    }
   9.458 -    
   9.459 +    /** 
   9.460 +     * Create the root node to be used in this view 
   9.461 +     *
   9.462 +     * @return created node
   9.463 +     */
   9.464      protected Node createRootNode() {
   9.465          return new UserTaskListNode((UserTaskList) getModel(), null);
   9.466      }
   9.467 @@ -381,9 +603,13 @@
   9.468      /** Show the given task. "Showing" means getting the editor to
   9.469       * show the associated file position, and open up an area in the
   9.470       * tasklist view where the details of the task can be fully read.
   9.471 +     *
   9.472 +     * @param item selected task (or null for hiding last)
   9.473 +     * @param annotation annotation to use or null for
   9.474 +     *        default view provided annotation.
   9.475       */
   9.476 -    public void showTaskInEditor(Task item, TaskAnnotation annotation) {
   9.477 -        UserTask task = (UserTask)item;
   9.478 +    public void showTaskInEditor(UserTask item, UserTaskAnnotation annotation) {
   9.479 +        UserTask task = item;
   9.480          UserTask prevTask = null;
   9.481          if ((taskMarker != null) &&
   9.482              (taskMarker.getTask() instanceof UserTask)) {
   9.483 @@ -393,17 +619,23 @@
   9.484              task.getAnnotation().detach();
   9.485              task.setAnnotation(null);
   9.486          }
   9.487 -        super.showTaskInEditor(item, annotation);
   9.488 +        if (annotation == null) annotation = getAnnotation(item);
   9.489 +        annotationManager.showTask(item, annotation);
   9.490          if (prevTask != null) {
   9.491              if ((prevTask.getLine() != null) && (task.getAnnotation() == null)) {
   9.492 -                TaskAnnotation anno = new TaskAnnotation(prevTask, false);
   9.493 +                UserTaskAnnotation anno = new UserTaskAnnotation(prevTask, false);
   9.494                  anno.attach(prevTask.getLine());
   9.495                  prevTask.setAnnotation(anno);                
   9.496              }
   9.497          }
   9.498      }
   9.499  
   9.500 -    protected void setModel(ObservableList list) {
   9.501 +    /**
   9.502 +     * Start showing new tasklist.
   9.503 +     *
   9.504 +     * @param list new tree
   9.505 +     */
   9.506 +    protected void setModel(UserTaskList list) {
   9.507          hideList();
   9.508          tasklist = list;
   9.509          getModel().addTaskListener(this);
   9.510 @@ -412,7 +644,10 @@
   9.511      }
   9.512      
   9.513      protected void hideList() {
   9.514 -        super.hideList();
   9.515 +        UserTaskList prev = getModel();
   9.516 +        if (prev != null) {
   9.517 +            prev.removeTaskListener(this);
   9.518 +        }
   9.519          UserTaskList utl = (UserTaskList) this.getModel();
   9.520          if (utl != null)
   9.521              utl.hideAnnotations(utl.getTasks().iterator());
   9.522 @@ -422,6 +657,11 @@
   9.523          return "UserTaskView(" + getName() + ", " + category + ", " + getModel() + ")"; // NOI18N
   9.524      }
   9.525      
   9.526 +    /** 
   9.527 +     * Create filter template. 
   9.528 +     *
   9.529 +     * @return created filter
   9.530 +     */
   9.531      public org.netbeans.modules.tasklist.core.filter.Filter createFilter() {
   9.532          return new UserTaskFilter("Simple"); // NOI18N
   9.533      }
   9.534 @@ -443,6 +683,9 @@
   9.535              tt.getSortingModel(), getFilter()));
   9.536      }
   9.537  
   9.538 +    /**
   9.539 +     * Store current column configuration to settings
   9.540 +     */
   9.541      protected void storeColumnsConfiguration() {
   9.542          if (tt == null)
   9.543              return;
   9.544 @@ -451,6 +694,9 @@
   9.545          tt.storeColumns(columns);
   9.546      }
   9.547  
   9.548 +    /**
   9.549 +     * Restore column configuration from settings
   9.550 +     */
   9.551      protected void loadColumnsConfiguration() {
   9.552          if (UTUtils.LOGGER.isLoggable(Level.FINER))
   9.553              Thread.dumpStack();
   9.554 @@ -465,11 +711,19 @@
   9.555          tt.expandAll();
   9.556      }
   9.557      
   9.558 -    public void select(Task task) {
   9.559 +    /** 
   9.560 +     * Expand nodes and select the particular item, IF the list
   9.561 +     * view is showing
   9.562 +     *
   9.563 +     * @param item The item to be shown
   9.564 +     */
   9.565 +    public void select(UserTask task) {
   9.566          if (isShowing() == false) return;
   9.567          
   9.568 -        TreePath tp = tt.findPath((UserTask) task);
   9.569 -        tt.expandPath(tp);
   9.570 +        assert tt != null : "tt == null"; // NOI18N
   9.571 +        TreePath tp = tt.findPath(task);
   9.572 +        assert tp != null : "tp == null"; // NOI18N
   9.573 +        tt.expandPath(tp.getParentPath());
   9.574          tt.select(tp);
   9.575      }
   9.576      
   9.577 @@ -508,4 +762,746 @@
   9.578              new ICalImportFormat()
   9.579          };
   9.580      }    
   9.581 +    
   9.582 +    // copied from org.netbeans.modules.tasklist.core.TaskListView
   9.583 +
   9.584 +    /** Expected border height */
   9.585 +    private static int TOOLBAR_HEIGHT_ADJUSTMENT = 4;
   9.586 +
   9.587 +    /** Cached toolbar height */
   9.588 +    private static int toolbarHeight = -1;
   9.589 +
   9.590 +    public static final String DEFAULT_FILTER_NAME = 
   9.591 +        NbBundle.getMessage(UserTaskView.class, "default-filter-name");
   9.592 +
   9.593 +
   9.594 +    /**
   9.595 +     * Registers a view
   9.596 +     *
   9.597 +     * @param view a view to be registered
   9.598 +     */
   9.599 +    protected static void registerTaskListView(UserTaskView view) {
   9.600 +        synchronized (UserTaskView.class) {
   9.601 +            views.add(new WeakReference(view));
   9.602 +        }
   9.603 +    }
   9.604 +    
   9.605 +    /** Property "task summary" */
   9.606 +    public static final String PROP_TASK_SUMMARY = "taskDesc"; // NOI18N
   9.607 +
   9.608 +    /** String (category of a view) -> ColumnsConfiguration */
   9.609 +    private static Map defColumns = new HashMap();
   9.610 +
   9.611 +    transient protected Node rootNode = null;
   9.612 +    
   9.613 +    transient private boolean initialized = false;
   9.614 +
   9.615 +    transient protected String category = null;
   9.616 +
   9.617 +    protected transient UserTaskList tasklist = null;
   9.618 +
   9.619 +    transient protected FilterRepository filters = null;
   9.620 +    transient protected Filter activeFilter = null;
   9.621 +    
   9.622 +    /** Annotation showing the current position */
   9.623 +    transient protected UserTaskAnnotation taskMarker = null;
   9.624 +
   9.625 +    private transient Component centerCmp;
   9.626 +
   9.627 +    transient private JPanel centerPanel;
   9.628 +    transient private Component northCmp;
   9.629 +    transient private boolean northCmpCreated;
   9.630 +    transient private JLabel miniStatus;
   9.631 +
   9.632 +    private transient ExplorerManager manager;
   9.633 +
   9.634 +    protected boolean persistent = false;
   9.635 +    
   9.636 +    /**
   9.637 +     * Construct a new TaskListView. Most work is deferred to
   9.638 +     * componentOpened. NOTE: this is only for use by the window
   9.639 +     * system when deserializing windows. Client code should not call
   9.640 +     * it; use the constructor which takes category, title and icon
   9.641 +     * parameters. But the code relies on
   9.642 +     * readExternal getting called after this constructor to finalize
   9.643 +     * construction of the window.
   9.644 +     *
   9.645 +     * todo make private
   9.646 +     */
   9.647 +    public void createTaskListView() {
   9.648 +        init_();
   9.649 +    }
   9.650 +
   9.651 +    /**
   9.652 +     * Common part for all constructors
   9.653 +     */
   9.654 +    private void init_() {
   9.655 +        manager = new ExplorerManager();
   9.656 +        ActionMap map = getActionMap();
   9.657 +        map.put(javax.swing.text.DefaultEditorKit.copyAction, 
   9.658 +            ExplorerUtils.actionCopy(manager));
   9.659 +        map.put(javax.swing.text.DefaultEditorKit.cutAction, 
   9.660 +            ExplorerUtils.actionCut(manager));
   9.661 +        map.put(javax.swing.text.DefaultEditorKit.pasteAction, 
   9.662 +            ExplorerUtils.actionPaste(manager));
   9.663 +        map.put("delete", ExplorerUtils.actionDelete(manager, true));  // NOI18N
   9.664 +
   9.665 +        // following line tells the top component which lookup should be associated with it
   9.666 +        associateLookup(ExplorerUtils.createLookup(manager, map));
   9.667 +    }
   9.668 +
   9.669 +    public ExplorerManager getExplorerManager() {
   9.670 +        return manager;
   9.671 +    }
   9.672 +
   9.673 +    /**
   9.674 +     * Updates the label showing the number of filtered tasks
   9.675 +     */
   9.676 +    public void updateFilterCount() {
   9.677 +        JLabel filterLabel = (JLabel) getMiniStatus();
   9.678 +        if (getFilter() == null) {
   9.679 +            filterLabel.setText("");
   9.680 +        } else {
   9.681 +            int all = TLUtils.getChildrenCountRecursively(rootNode);
   9.682 +            int shown = TLUtils.getChildrenCountRecursively(
   9.683 +                    getExplorerManager().getExploredContext());
   9.684 +            filterLabel.setText(NbBundle.getMessage(UserTaskView.class,
   9.685 +                    "FilterCount", new Integer(shown), new Integer(all))); // NOI18N
   9.686 +        }
   9.687 +    }
   9.688 +
   9.689 +    /**
   9.690 +     * Hides/shows component that will be shown over the TTV
   9.691 +     *
   9.692 +     * @param v true = visible
   9.693 +     */
   9.694 +    protected void setNorthComponentVisible(boolean v) {
   9.695 +        if (v) {
   9.696 +            Component cmp = getNorthComponent();
   9.697 +            if (cmp != null) {
   9.698 +                centerPanel.add(cmp, BorderLayout.NORTH);
   9.699 +                centerPanel.validate();
   9.700 +            }
   9.701 +        } else {
   9.702 +            if (northCmp != null && northCmp.getParent() != null) {
   9.703 +                northCmp.getParent().remove(northCmp);
   9.704 +            }
   9.705 +        }
   9.706 +    }
   9.707 +
   9.708 +    /**
   9.709 +     * Is the component above the tree table visible?
   9.710 +     * Visible means it is in the TopComponent
   9.711 +     *
   9.712 +     * @return true = yes
   9.713 +     */
   9.714 +    public boolean isNorthComponentVisible() {
   9.715 +        return northCmp != null && northCmp.getParent() != null;
   9.716 +    }
   9.717 +
   9.718 +    /**
   9.719 +     * Returns component that will be shown over the TTV
   9.720 +     *
   9.721 +     * @return component or null
   9.722 +     */
   9.723 +    protected Component getNorthComponent() {
   9.724 +        if (!northCmpCreated) {
   9.725 +            northCmp = createNorthComponent();
   9.726 +            northCmpCreated = true;
   9.727 +        }
   9.728 +        return northCmp;
   9.729 +    }
   9.730 +
   9.731 +    /**
   9.732 +     * Creates component that will be shown over the TTV
   9.733 +     *
   9.734 +     * @return created component or null
   9.735 +     */
   9.736 +    protected Component createNorthComponent() {
   9.737 +        return new JLabel(""); // NOI18N
   9.738 +    }
   9.739 +
   9.740 +    /**
   9.741 +     * Returns component visualizing view status messages.
   9.742 +     */
   9.743 +    protected JLabel getMiniStatus() {
   9.744 +        if (miniStatus == null) {
   9.745 +            miniStatus = createMiniStatus();
   9.746 +        }
   9.747 +        return miniStatus;
   9.748 +    }
   9.749 +
   9.750 +    private JLabel createMiniStatus() {
   9.751 +        JLabel ret =  new JLabel();
   9.752 +        Dimension dim = ret.getPreferredSize();
   9.753 +        dim.height = getToolbarHeight();
   9.754 +        ret.setPreferredSize(dim);
   9.755 +        return ret;
   9.756 +    }
   9.757 +
   9.758 +    protected final void setMiniStatus(String text) {
   9.759 +        getMiniStatus().setText(text);
   9.760 +    }
   9.761 +
   9.762 +    /**
   9.763 +     * Computes vertical toolbar components height that can used for layout manager hinting.
   9.764 +     * @return size based on font size and expected border.
   9.765 +     */
   9.766 +    public static int getToolbarHeight() {
   9.767 +
   9.768 +        if (toolbarHeight == -1) {
   9.769 +            BufferedImage image = new BufferedImage(1,1,BufferedImage.TYPE_BYTE_GRAY);
   9.770 +            Graphics2D g = image.createGraphics();
   9.771 +            UIDefaults def = UIManager.getLookAndFeelDefaults();
   9.772 +
   9.773 +            int height = 0;
   9.774 +            String[] fonts = {"Label.font", "Button.font", "ToggleButton.font"};      // NOI18N
   9.775 +            for (int i=0; i<fonts.length; i++) {
   9.776 +                Font f = def.getFont(fonts[i]);
   9.777 +                FontMetrics fm = g.getFontMetrics(f);
   9.778 +                height = Math.max(height, fm.getHeight());
   9.779 +            }
   9.780 +            toolbarHeight = height + TOOLBAR_HEIGHT_ADJUSTMENT;
   9.781 +        }
   9.782 +
   9.783 +        return toolbarHeight;
   9.784 +    }
   9.785 +
   9.786 +
   9.787 +    // XXX probably new instance per view would be better
   9.788 +    // or explicit hideTaskInEditor should not hide foreign annotations
   9.789 +    // but showTaskInEditor's call to hideTaskInEditor should hide them
   9.790 +    private UserTaskEditorListener annotationManager = 
   9.791 +        UserTaskEditorListener.getDefault();
   9.792 +
   9.793 +    /**
   9.794 +     * Called to indicate that a particular task should be hidden.
   9.795 +     * This typically means that the task was deleted so it should
   9.796 +     * no longer have any visual cues. The task referred to is the
   9.797 +     * most recent task passed to showTaskInEditor.
   9.798 +     */
   9.799 +    public void hideTaskInEditor() {
   9.800 +        annotationManager.hideTask();
   9.801 +    }
   9.802 +
   9.803 +    /**
   9.804 +     * Could be overriden to change actions on second toolbar row.
   9.805 +     * @return
   9.806 +     */
   9.807 +    protected SystemAction[] getGlobalToolBarActions() {
   9.808 +        return null;
   9.809 +    }
   9.810 +
   9.811 +    /**
   9.812 +     * Returns default configuration for visible columns
   9.813 +     *
   9.814 +     * @return default columns configuration
   9.815 +     */
   9.816 +    protected ColumnsConfiguration getDefaultColumns() {
   9.817 +        ColumnsConfiguration cc = (ColumnsConfiguration) defColumns.get(category);
   9.818 +        if (cc != null)
   9.819 +            return cc;
   9.820 +
   9.821 +        FileSystem fs = Repository.getDefault().getDefaultFileSystem();
   9.822 +        FileObject fo = fs.findResource("TaskList/" + category + "/columns.settings"); // NOI18N
   9.823 +        assert fo != null : "Missing config TaskList/" + category + "/columns.settings";  // NOI18N
   9.824 +
   9.825 +        try {
   9.826 +            DataObject dobj = DataObject.find(fo);
   9.827 +            InstanceCookie ic = (InstanceCookie) dobj.getCookie(InstanceCookie.class);
   9.828 +            cc = (ColumnsConfiguration) ic.instanceCreate();
   9.829 +        } catch (ClassNotFoundException e) {
   9.830 +            ErrorManager.getDefault().notify(e);
   9.831 +        } catch (DataObjectNotFoundException e) {
   9.832 +            ErrorManager.getDefault().notify(e);
   9.833 +        } catch (IOException e) {
   9.834 +            ErrorManager.getDefault().notify(e);
   9.835 +        }
   9.836 +        return cc;
   9.837 +    }
   9.838 +
   9.839 +
   9.840 +
   9.841 +    protected void loadFilters() {
   9.842 +        FileSystem fs = Repository.getDefault().getDefaultFileSystem();
   9.843 +        FileObject fo = fs.findResource("TaskList/" + category + "/filters.settings"); // NOI18N
   9.844 +        assert fo != null : "Missing config TaskList/" + category + "/filters.settings";  // NOI18N
   9.845 +        
   9.846 +        try {
   9.847 +            DataObject dobj = DataObject.find(fo);
   9.848 +            InstanceCookie ic = (InstanceCookie) dobj.getCookie(InstanceCookie.class);
   9.849 +            filters = (FilterRepository) ic.instanceCreate();
   9.850 +            
   9.851 +            // 	filters.addPropertyChangeListener(new PropertyChangeListener() {
   9.852 +            // 	    public void propertyChange(PropertyChangeEvent evt) {
   9.853 +            // 	      if (evt.getPropertyName().equals(FilterRepository.PROP_ACTIVE_FILTER)) {
   9.854 +            // 		setFilter(filters.getActive());
   9.855 +            // 		//		setFiltered();
   9.856 +            // 	      }
   9.857 +            // 	    }
   9.858 +            // 	  });
   9.859 +            filters.setActive(null);
   9.860 +            
   9.861 +            // create a default filter if there is none
   9.862 +            if (filters.size() == 0) {
   9.863 +                Filter f = createFilter();
   9.864 +                f.setName(DEFAULT_FILTER_NAME);
   9.865 +                filters.add(f);
   9.866 +            }
   9.867 +            
   9.868 +        } catch (ClassNotFoundException e) {
   9.869 +            ErrorManager.getDefault().notify(e);
   9.870 +        } catch (DataObjectNotFoundException e) {
   9.871 +            ErrorManager.getDefault().notify(e);
   9.872 +        } catch (IOException e) {
   9.873 +            ErrorManager.getDefault().notify(e);
   9.874 +        }
   9.875 +        
   9.876 +    }
   9.877 +    
   9.878 +    /** 
   9.879 +     * Called when the object is opened. Add the GUI.
   9.880 +     * @todo Trigger source listening on window getting VISIBLE instead
   9.881 +     * of getting opened.
   9.882 +     */
   9.883 +    protected void componentOpened() {
   9.884 +        // Register listeningViews, such as the editor support bridge module
   9.885 +        // TODO: Listeners from Lookup will not be collected
   9.886 +        // registerListeners();
   9.887 +
   9.888 +        if (initialized) {
   9.889 +            return;
   9.890 +        }
   9.891 +        initialized = true;
   9.892 +
   9.893 +        FindAction find = (FindAction) FindAction.get(FindAction.class);
   9.894 +        FilterAction filter = (FilterAction) FilterAction.get(FilterAction.class);
   9.895 +        getActionMap().put(find.getActionMapKey(), filter);
   9.896 +
   9.897 +        setLayout(new BorderLayout());
   9.898 +
   9.899 +        centerPanel = new JPanel();
   9.900 +        centerPanel.setLayout(new BorderLayout());
   9.901 +        centerCmp = createCenterComponent();
   9.902 +        
   9.903 +        centerPanel.add(centerCmp, BorderLayout.CENTER);
   9.904 +        add(centerPanel, BorderLayout.CENTER);
   9.905 +
   9.906 +        loadColumnsConfiguration();
   9.907 +        
   9.908 +        JPanel toolbars = new JPanel();
   9.909 +        toolbars.setLayout(new FlowLayout(FlowLayout.LEADING, 0, 0));
   9.910 +
   9.911 +        SystemAction[] actions = getGlobalToolBarActions();
   9.912 +        if (actions != null) {
   9.913 +            JToolBar toolbar = SystemAction.createToolbarPresenter(actions);
   9.914 +            toolbar.setFloatable(false);
   9.915 +            toolbar.putClientProperty("JToolBar.isRollover", Boolean.TRUE);  // NOI18N
   9.916 +            toolbar.setOrientation(JToolBar.VERTICAL);
   9.917 +            toolbars.add(toolbar);
   9.918 +        }
   9.919 +
   9.920 +        actions = getToolBarActions();
   9.921 +        if (actions != null) {
   9.922 +            JToolBar toolbar = SystemAction.createToolbarPresenter(actions);
   9.923 +            toolbar.setFloatable(false);
   9.924 +            toolbar.putClientProperty("JToolBar.isRollover", Boolean.TRUE);  // NOI18N
   9.925 +            toolbar.setOrientation(JToolBar.VERTICAL);
   9.926 +            toolbars.add(toolbar);
   9.927 +        }
   9.928 +
   9.929 +
   9.930 +        add(toolbars, BorderLayout.WEST);
   9.931 +
   9.932 +        // Populate the view
   9.933 +        setModel(tasklist);
   9.934 +    }
   9.935 +
   9.936 +
   9.937 +    /** Called when the window is closed. Cleans up. */
   9.938 +    protected void componentClosed() {
   9.939 +        hideTaskInEditor();
   9.940 +        hideList();
   9.941 +
   9.942 +        // Remove any task markers we've added to the editor
   9.943 +        if (unshowItem != null) {
   9.944 +            removedTask(null, unshowItem, 0); // TODO cannot find the parent of unshowItem
   9.945 +        }
   9.946 +
   9.947 +        // Unregister listeningViews
   9.948 +        unregisterListeners();
   9.949 +        
   9.950 +        storeColumnsConfiguration();
   9.951 +    }
   9.952 +
   9.953 +    protected void componentDeactivated() {
   9.954 +        super.componentDeactivated();
   9.955 +        assert initialized : "#37438 dangling componentDeactivated event, no componentOpened() called at " + this;
   9.956 +        ExplorerUtils.activateActions(manager, false);
   9.957 +        storeColumnsConfiguration();
   9.958 +    }
   9.959 +
   9.960 +    private void setRoot() {
   9.961 +        /* TODO: remove
   9.962 +         rootNode = createRootNode();
   9.963 +	// TODO: usertasks module sets the display name of the root node to
   9.964 +        // "Task List"
   9.965 +        rootNode.setDisplayName(getMainColumn(-1).getDisplayName());
   9.966 +
   9.967 +        LOGGER.fine("root created " + rootNode);
   9.968 +
   9.969 +        Node prevRoot = getExplorerManager().getRootContext();
   9.970 +
   9.971 +        if (isFiltered()) {
   9.972 +            // Create filtered view of the tasklist
   9.973 +            FilteredTaskChildren children =
   9.974 +                new FilteredTaskChildren(this, rootNode, getFilter());
   9.975 +            FilterNode n = new FilterTaskNode(rootNode, children, false);
   9.976 +            getExplorerManager().setRootContext(n);
   9.977 +        } else {
   9.978 +            getExplorerManager().setRootContext(rootNode);
   9.979 +        }
   9.980 +
   9.981 +        try {
   9.982 +            if (prevRoot != null) prevRoot.destroy();
   9.983 +        } catch (IOException ex) {
   9.984 +            throw new IllegalStateException("Unexpected IOex in " + prevRoot);  // NOI18N
   9.985 +        }
   9.986 +         **/
   9.987 +    }
   9.988 +
   9.989 +    /**
   9.990 +     * Returns the root node. It is never a filtered node.
   9.991 +     *
   9.992 +     * @return root node
   9.993 +     */
   9.994 +    public Node getRootNode() {
   9.995 +        return rootNode;
   9.996 +    }
   9.997 +
   9.998 +    // XXX #37543 copied from ExplorerPanel ast was deprecated without replacement
   9.999 +    private static HelpCtx getHelpCtx(Node[] sel, HelpCtx def) {
  9.1000 +        HelpCtx result = null;
  9.1001 +        for (int i = 0; i < sel.length; i++) {
  9.1002 +            HelpCtx attempt = sel[i].getHelpCtx();
  9.1003 +            if (attempt != null && !attempt.equals(HelpCtx.DEFAULT_HELP)) {
  9.1004 +                if (result == null || result.equals(attempt)) {
  9.1005 +                    result = attempt;
  9.1006 +                } else {
  9.1007 +                    // More than one found, and they conflict. Get general help on the Explorer instead.
  9.1008 +                    result = null;
  9.1009 +                    break;
  9.1010 +                }
  9.1011 +            }
  9.1012 +        }
  9.1013 +        if (result != null)
  9.1014 +            return result;
  9.1015 +        else
  9.1016 +            return def;
  9.1017 +    }
  9.1018 +
  9.1019 +    private UserTask unshowItem = null;
  9.1020 +
  9.1021 +    /** Show the given todolist item. "Showing" means getting the
  9.1022 +     * editor to show the associated file position, and open up an
  9.1023 +     * area in the todolist view where the details of the todolist
  9.1024 +     * item can be fully read.
  9.1025 +     */
  9.1026 +    /*
  9.1027 +    public void show(Task item, Annotation anno) {
  9.1028 +	if (listeningViews != null) {
  9.1029 +	    // Stash item so I can notify of deletion -- see TaskViewListener
  9.1030 +	    // doc
  9.1031 +	    unshowItem = item;
  9.1032 +	    int n = listeningViews.size();
  9.1033 +	    for (int i = 0; i < n; i++) {
  9.1034 +		TaskViewListener tl = (TaskViewListener)listeningViews.get(i);
  9.1035 +		tl.showTaskInEditor(item, anno);
  9.1036 +	    }
  9.1037 +	}
  9.1038 +    }
  9.1039 +    */
  9.1040 +
  9.1041 +    /** Unshow the given task, if it's the one currently showing */
  9.1042 +    /*
  9.1043 +    public void unshow(Task item) {
  9.1044 +        if (item != unshowItem) {
  9.1045 +            return;
  9.1046 +        }
  9.1047 +	if (listeningViews != null) {
  9.1048 +	    // Stash item so I can notify of deletion -- see TaskViewListener
  9.1049 +	    // doc
  9.1050 +	    unshowItem = null;
  9.1051 +	    int n = listeningViews.size();
  9.1052 +	    for (int i = 0; i < n; i++) {
  9.1053 +		TaskViewListener tl = (TaskViewListener)listeningViews.get(i);
  9.1054 +		tl.hideTaskInEditor();
  9.1055 +	    }
  9.1056 +	}
  9.1057 +    }
  9.1058 +    */
  9.1059 +
  9.1060 +    /** List of TaskViewListener object listening on the tasklist view
  9.1061 +     for visibility, selection, etc. */
  9.1062 +    private List listeningViews = null;
  9.1063 +
  9.1064 +    protected final List getListeningViews() {
  9.1065 +        return (listeningViews == null) ? Collections.EMPTY_LIST : listeningViews;
  9.1066 +    }
  9.1067 +
  9.1068 +    /** 
  9.1069 +     * Locate all tasklist listeningViews and add them to our property
  9.1070 +     * change listener setup.
  9.1071 +     * @todo Decide whether to unregister and reregister repeatedly;
  9.1072 +     * this has the advantage of working with dynamic module
  9.1073 +     * installs/uninstalls.
  9.1074 +     * @todo Consider using a lookup listener such that I'm notified of
  9.1075 +     * later additions/removals
  9.1076 +     * @todo Consider doing a factory lookup instead of creating a new
  9.1077 +     * instance each time. Would allow better coordination between
  9.1078 +     * the listener instance and ScanView in the editor package.
  9.1079 +     */
  9.1080 +    void registerListeners() {
  9.1081 +        // TODO Ensure that this doesn't get called from other windows...
  9.1082 +        // find TaskViewListeners
  9.1083 +        Lookup l = Lookup.getDefault();
  9.1084 +        Lookup.Template template = new Lookup.Template(
  9.1085 +            UserTaskViewListener.class);
  9.1086 +        Iterator it = l.lookup(template).allInstances().iterator();
  9.1087 +        if (it.hasNext()) {
  9.1088 +            listeningViews = new ArrayList(4);
  9.1089 +        }
  9.1090 +        while (it.hasNext()) {
  9.1091 +            UserTaskViewListener tl = (UserTaskViewListener) it.next();
  9.1092 +            listeningViews.add(tl);
  9.1093 +        }
  9.1094 +    }
  9.1095 +
  9.1096 +    /** Unregister the listeningViews registered in registerListener such
  9.1097 +     that they are no longer notified of changes */
  9.1098 +    private void unregisterListeners() {
  9.1099 +        listeningViews = null;
  9.1100 +    }
  9.1101 +
  9.1102 +    // TODO Pick a better name!
  9.1103 +    // TODO make method package private! Can't yet - used in editor/
  9.1104 +    public void showInMode() {
  9.1105 +        if (!isOpened()) {
  9.1106 +            Mode mode = WindowManager.getDefault().findMode("output"); // NOI18N
  9.1107 +            if (mode != null) {
  9.1108 +                mode.dockInto(UserTaskView.this);
  9.1109 +            }
  9.1110 +        }
  9.1111 +        open();
  9.1112 +        requestVisible();
  9.1113 +        requestActive();
  9.1114 +    }
  9.1115 +
  9.1116 +    /** 
  9.1117 +     * Called to indicate that a particular task is made current.
  9.1118 +     * Do what you can to "select" this task.
  9.1119 +     *
  9.1120 +     * <p>
  9.1121 +     * Dispatches {@link TaskViewListener#showTask} to all registered views.
  9.1122 +     */
  9.1123 +    public void selectedTask(UserTask item) {
  9.1124 +        if (listeningViews != null) {
  9.1125 +            // Stash item so I can notify of deletion -- see TaskViewListener
  9.1126 +            // doc
  9.1127 +            unshowItem = item;
  9.1128 +            int n = listeningViews.size();
  9.1129 +            for (int i = 0; i < n; i++) {
  9.1130 +                UserTaskViewListener tl = (UserTaskViewListener) listeningViews.get(i);
  9.1131 +                tl.showTask(item, getAnnotation(item));
  9.1132 +            }
  9.1133 +        }
  9.1134 +    }
  9.1135 +
  9.1136 +    /** 
  9.1137 +     * Called to indicate that a particular task has been "warped to".
  9.1138 +     * Do what you can to "warp to" this task. Typically means show
  9.1139 +     * associated fileposition in the editor.
  9.1140 +     */
  9.1141 +    public void warpedTask(UserTask item) {
  9.1142 +        // XXX currently identical to selectedTask above!
  9.1143 +        if (listeningViews != null) {
  9.1144 +            // Stash item so I can notify of deletion -- see TaskViewListener
  9.1145 +            // doc
  9.1146 +            unshowItem = item;
  9.1147 +            int n = listeningViews.size();
  9.1148 +            for (int i = 0; i < n; i++) {
  9.1149 +                UserTaskViewListener tl = (UserTaskViewListener) listeningViews.get(i);
  9.1150 +                tl.showTask(item, null);
  9.1151 +            }
  9.1152 +        }
  9.1153 +    }
  9.1154 +
  9.1155 +    public void addedTask(UserTask t) {
  9.1156 +        // Nothing to do?
  9.1157 +    }
  9.1158 +
  9.1159 +    public void removedTask(UserTask pt, UserTask task, int index) {
  9.1160 +        if ((task == unshowItem) && (listeningViews != null)) {
  9.1161 +            unshowItem = null;
  9.1162 +            int n = listeningViews.size();
  9.1163 +            for (int i = 0; i < n; i++) {
  9.1164 +                UserTaskViewListener tl = (UserTaskViewListener) listeningViews.get(i);
  9.1165 +                tl.hideTask();
  9.1166 +            }
  9.1167 +        }
  9.1168 +    }
  9.1169 +
  9.1170 +    public void structureChanged(UserTask t) {
  9.1171 +    }
  9.1172 +
  9.1173 +    /**  
  9.1174 +     * Return the tasklist shown in this view 
  9.1175 +     */
  9.1176 +    public UserTaskList getList() {
  9.1177 +        // XXX  FilteredTasksList may appear here for TODOs Current File
  9.1178 +        UserTaskList model = getModel();
  9.1179 +        return model;
  9.1180 +    }
  9.1181 +
  9.1182 +    public UserTaskList getModel() {
  9.1183 +        return tasklist;
  9.1184 +    }
  9.1185 +
  9.1186 +    // End of stuff taken from TreeTableView
  9.1187 +
  9.1188 +    /**
  9.1189 +     * Get the toggle filter for this view. It's
  9.1190 +     * applied if {@link #isFiltered} returns true.
  9.1191 +     *
  9.1192 +     * @return The toggle filter or <code>null</code> if not defined.
  9.1193 +     */
  9.1194 +    public final Filter getFilter() {
  9.1195 +      //      return getFilters().getActive();
  9.1196 +      return activeFilter;
  9.1197 +    }
  9.1198 +
  9.1199 +    /** 
  9.1200 +     * Returns the collection of filters assiciated with this view.
  9.1201 +     * @return FilterRepository, never null
  9.1202 +     */
  9.1203 +    public FilterRepository getFilters() {
  9.1204 +        if (filters == null) loadFilters();
  9.1205 +        assert filters != null : "Missing FilterRepository";  // NOI18N
  9.1206 +
  9.1207 +        return filters;
  9.1208 +    }
  9.1209 +    
  9.1210 +    /** Tests if any real filter is applied. */
  9.1211 +    public final boolean isFiltered() {
  9.1212 +        return getFilter() != null;
  9.1213 +    }
  9.1214 +
  9.1215 +    /**
  9.1216 +     * Set the filter to be used (determined by isFiltered) in this view.
  9.1217 +     * @param filter The filter to be set, or null, to remove filtering.
  9.1218 +     */
  9.1219 +    public void setFilter(Filter filter) {         
  9.1220 +        if (filter == null || getFilters().contains(filter)) {
  9.1221 +            getFilters().setActive(filter);  
  9.1222 +        } 
  9.1223 +
  9.1224 +        this.activeFilter = filter;
  9.1225 +        setFiltered();
  9.1226 +    }
  9.1227 +
  9.1228 +    private boolean lookupAttempted = false;
  9.1229 +
  9.1230 +    private static void invokeLater(Runnable runnable) {
  9.1231 +        if (SwingUtilities.isEventDispatchThread()) {
  9.1232 +            runnable.run();
  9.1233 +        } else {
  9.1234 +            SwingUtilities.invokeLater(runnable);
  9.1235 +        }
  9.1236 +    }
  9.1237 +
  9.1238 +    /** When true, we've already warned about the need to wrap */
  9.1239 +    private boolean wrapWarned = false;
  9.1240 +
  9.1241 +    /** Try to select nodes in all known views. */
  9.1242 +    private void selectNode(Node node) {
  9.1243 +        if (node != null) {
  9.1244 +            UserTask nextTask = ((UserTaskNode) node).getTask();
  9.1245 +            if (nextTask.getLine() != null) {
  9.1246 +                UserTaskAnnotation anno = getAnnotation(nextTask);
  9.1247 +                if (anno != null) {
  9.1248 +                    showTaskInEditor(nextTask, anno);
  9.1249 +                }
  9.1250 +            }
  9.1251 +            select(nextTask); // XXX call EM directly
  9.1252 +        }
  9.1253 +    }
  9.1254 +
  9.1255 +    /**
  9.1256 +     * @param tail if true take the last one from multiple selection
  9.1257 +     *        othervise the first one
  9.1258 +     * @return last selected or null
  9.1259 +     */
  9.1260 +    private Node currentlySelected(boolean tail) {
  9.1261 +        Node[] selected = getExplorerManager().getSelectedNodes();
  9.1262 +        if (selected != null && selected.length != 0) {
  9.1263 +            if (tail) {
  9.1264 +                return selected[selected.length -1];
  9.1265 +            } else {
  9.1266 +                return selected[0];
  9.1267 +            }
  9.1268 +        } else {
  9.1269 +            return null;
  9.1270 +        }
  9.1271 +    }
  9.1272 +
  9.1273 +    /**
  9.1274 +     * Return an editor annotation to use to show the given task
  9.1275 +     *
  9.1276 +     * @return created annotation or null
  9.1277 +     */
  9.1278 +    protected UserTaskAnnotation getAnnotation(UserTask task) {
  9.1279 +        return new UserTaskAnnotation(task, this);
  9.1280 +    }
  9.1281 +
  9.1282 +    protected void componentHidden() {
  9.1283 +        hideTaskInEditor();
  9.1284 +    }
  9.1285 +
  9.1286 +    // TODO - get rid of this when you clean up TaskListView.getRootNode() to
  9.1287 +    // do the Right Thing(tm) - always return effective explorer context
  9.1288 +    /** Return the actual root of the node tree shown in this view.
  9.1289 +     * May be a filternode when Filtering is in place.
  9.1290 +     */
  9.1291 +    public final Node getEffectiveRoot() {
  9.1292 +        return getExplorerManager().getRootContext();
  9.1293 +    }
  9.1294 +
  9.1295 +    public void requestActive() {
  9.1296 +        super.requestActive();
  9.1297 +        if (tt != null) {
  9.1298 +            tt.requestFocus();
  9.1299 +        }
  9.1300 +    }
  9.1301 +
  9.1302 +    /**
  9.1303 +     * Returns visible columns
  9.1304 +     *
  9.1305 +     * @return visible columns
  9.1306 +     */
  9.1307 +    /*public final ColumnProperty[] getVisibleColumns() {
  9.1308 +        TableColumnModel tcm = getTable().getColumnModel();
  9.1309 +        ColumnProperty[] all = getColumns();
  9.1310 +        List ret = new ArrayList();
  9.1311 +        ret.add(all[0]);
  9.1312 +        for (int i = 0; i < tcm.getColumnCount(); i++) {
  9.1313 +            String title = tcm.getColumn(i).getHeaderValue().toString();
  9.1314 +            for (int j = 1; j < all.length; j++) {
  9.1315 +                if (title.equalsIgnoreCase(all[j].getDisplayName())) {
  9.1316 +                    ret.add(all[j]);
  9.1317 +                    break;
  9.1318 +                }
  9.1319 +            }
  9.1320 +        }
  9.1321 +        return (ColumnProperty[]) ret.toArray(new ColumnProperty[ret.size()]);
  9.1322 +    } TODO: remove*/
  9.1323  }
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/tasklist.usertasks/src/org/netbeans/modules/tasklist/usertasks/UserTaskViewListener.java	Sun Sep 19 12:14:27 2004 +0000
    10.3 @@ -0,0 +1,52 @@
    10.4 +/*
    10.5 + *                 Sun Public License Notice
    10.6 + *
    10.7 + * The contents of this file are subject to the Sun Public License
    10.8 + * Version 1.0 (the "License"). You may not use this file except in
    10.9 + * compliance with the License. A copy of the License is available at
   10.10 + * http://www.sun.com/
   10.11 + *
   10.12 + * The Original Code is NetBeans. The Initial Developer of the Original
   10.13 + * Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun
   10.14 + * Microsystems, Inc. All Rights Reserved.
   10.15 + */
   10.16 +
   10.17 +package org.netbeans.modules.tasklist.usertasks;
   10.18 +
   10.19 +import org.openide.text.Annotation;
   10.20 +
   10.21 +
   10.22 +/**
   10.23 + * Listener which when notified off changes in current task
   10.24 + * updates in all views. Registations are done using default lookup.
   10.25 + * <p>
   10.26 + * For editor only selection use
   10.27 + * {@link TaskListView#showTaskInEditor} aad {@link TaskListView#hideTaskInEditor}
   10.28 + *
   10.29 + * @author Tor Norbye
   10.30 + *
   10.31 + * @todo Instead of having showTask, hideTask, consider generalizing
   10.32 + *        this to communicating the current selection. Obviously
   10.33 + *        deleting a task will cause it to be unselected. Single-click
   10.34 + *        vs. double click issue.
   10.35 + */
   10.36 +public interface UserTaskViewListener  {
   10.37 +
   10.38 +    /** Called to indicate that a particular task is made current.
   10.39 +     * Do what you can to "select" this task. 
   10.40 +     * @param task The task to be shown
   10.41 +     * @param annotation Annotation to be used to show the task, or
   10.42 +     *    null to use the default
   10.43 +     */
   10.44 +    void showTask(UserTask task, Annotation annotation);
   10.45 +
   10.46 +    /** Called to indicate that a particular task should be hidden.
   10.47 +	This typically means that the task was deleted so it should
   10.48 +	no longer have any visual cues. The task referred to is the
   10.49 +	most recent task passed to showTask.
   10.50 +        NOTE: hideTaskInEditor is NOT called before every new call to showTask.
   10.51 +        If your task viewer implements a "singleton" marker, you'll
   10.52 +        want to call hideTask yourself before showing the new marker.
   10.53 +    */
   10.54 +    void hideTask();
   10.55 +}
    11.1 --- a/tasklist.usertasks/src/org/netbeans/modules/tasklist/usertasks/translators/ICalImportFormat.java	Sat Sep 18 08:44:49 2004 +0000
    11.2 +++ b/tasklist.usertasks/src/org/netbeans/modules/tasklist/usertasks/translators/ICalImportFormat.java	Sun Sep 19 12:14:27 2004 +0000
    11.3 @@ -415,7 +415,7 @@
    11.4       * @param formatter A date formatter object used to parse dates.
    11.5       * @return the complete VTODO entry or null
    11.6       */
    11.7 -    private Task readVTODO(UserTaskList list, UserTask prev, SimpleDateFormat formatter) throws IOException {
    11.8 +    private UserTask readVTODO(UserTaskList list, UserTask prev, SimpleDateFormat formatter) throws IOException {
    11.9          UserTask task = new UserTask("", list); // NOI18N
   11.10          task.setSilentUpdate(true, false);
   11.11          task.setLastEditedDate(System.currentTimeMillis());
   11.12 @@ -618,13 +618,13 @@
   11.13          UserTask alreadyExists = list.findItem(list.getTasks().iterator(), task.getUID());
   11.14          if (alreadyExists != null) {
   11.15              // I should replace alreadyexists with task...
   11.16 -            Task parent = alreadyExists.getParent();
   11.17 +            UserTask parent = alreadyExists.getParent();
   11.18              parent.removeSubtask(alreadyExists);
   11.19              parent.addSubtask(task);
   11.20              
   11.21              Iterator li = alreadyExists.subtasksIterator();
   11.22              while (li.hasNext()) {
   11.23 -                Task c = (Task)li.next();
   11.24 +                UserTask c = (UserTask)li.next();
   11.25                  alreadyExists.removeSubtask(c);
   11.26                  task.addSubtask(c);
   11.27              }
   11.28 @@ -688,7 +688,7 @@
   11.29                  
   11.30                  if (value.equals("VTODO")) { // NOI18N
   11.31                      // Call a sub-function to process this line!!!
   11.32 -                    Task task = readVTODO(ulist, prev, formatter);
   11.33 +                    UserTask task = readVTODO(ulist, prev, formatter);
   11.34                      
   11.35                      if (task != null) {
   11.36                          if (task.getParent() == null) {
    12.1 --- a/tasklist.usertasks/src/org/netbeans/modules/tasklist/usertasks/translators/XmlExportFormat.java	Sat Sep 18 08:44:49 2004 +0000
    12.2 +++ b/tasklist.usertasks/src/org/netbeans/modules/tasklist/usertasks/translators/XmlExportFormat.java	Sun Sep 19 12:14:27 2004 +0000
    12.3 @@ -160,7 +160,7 @@
    12.4       * @param list task list
    12.5       * @return created XML
    12.6       */
    12.7 -    public Document createXml(TaskList list) 
    12.8 +    public Document createXml(UserTaskList list) 
    12.9      throws ParserConfigurationException, SAXException {
   12.10          DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
   12.11          Document doc = db.newDocument();
    13.1 --- a/tasklist.usertasks/src/org/netbeans/modules/tasklist/usertasks/treetable/AdvancedTreeTableNode.java	Sat Sep 18 08:44:49 2004 +0000
    13.2 +++ b/tasklist.usertasks/src/org/netbeans/modules/tasklist/usertasks/treetable/AdvancedTreeTableNode.java	Sun Sep 19 12:14:27 2004 +0000
    13.3 @@ -238,24 +238,34 @@
    13.4       */
    13.5      protected void fireChildObjectAdded(Object obj) {
    13.6          if (children != null) {
    13.7 +            AdvancedTreeTableNode cn = createChildNode(obj);
    13.8 +            
    13.9 +            int index;
   13.10              if (getComparator() != null) {
   13.11 -                AdvancedTreeTableNode cn = createChildNode(obj);
   13.12 -                int index = Arrays.binarySearch(children, cn, getComparator());
   13.13 +                index = Arrays.binarySearch(children, cn, getComparator());
   13.14                  assert index < 0;
   13.15                  
   13.16                  index = -(index + 1);
   13.17 -                AdvancedTreeTableNode[] newch = 
   13.18 -                    new AdvancedTreeTableNode[children.length + 1];
   13.19 -                System.arraycopy(children, 0, newch, 0, index);
   13.20 -                newch[index] = cn;
   13.21 -                System.arraycopy(children, index, newch, index + 1, 
   13.22 -                    children.length - index);
   13.23 -                this.children = newch;
   13.24 -                model.fireTreeNodesInserted(model, getPathToRoot(), 
   13.25 -                    new int[] {index}, new Object[] {cn});
   13.26              } else {
   13.27 -                refreshChildren();
   13.28 +                index = -1;
   13.29 +                Iterator it = getChildrenObjectsIterator();
   13.30 +                while (it.hasNext()) {
   13.31 +                    index++;
   13.32 +                    Object next = it.next();
   13.33 +                    if (next == obj)
   13.34 +                        break;
   13.35 +                }
   13.36              }
   13.37 +            
   13.38 +            AdvancedTreeTableNode[] newch = 
   13.39 +                new AdvancedTreeTableNode[children.length + 1];
   13.40 +            System.arraycopy(children, 0, newch, 0, index);
   13.41 +            newch[index] = cn;
   13.42 +            System.arraycopy(children, index, newch, index + 1, 
   13.43 +                children.length - index);
   13.44 +            this.children = newch;
   13.45 +            model.fireTreeNodesInserted(model, getPathToRoot(), 
   13.46 +                new int[] {index}, new Object[] {cn});
   13.47          }
   13.48      }
   13.49      
    14.1 --- a/tasklist.usertasks/src/org/netbeans/modules/tasklist/usertasks/treetable/SortingHeaderRenderer.java	Sat Sep 18 08:44:49 2004 +0000
    14.2 +++ b/tasklist.usertasks/src/org/netbeans/modules/tasklist/usertasks/treetable/SortingHeaderRenderer.java	Sun Sep 19 12:14:27 2004 +0000
    14.3 @@ -105,9 +105,11 @@
    14.4              if (iconPref.width != 0)
    14.5                  x = x + iconPref.width + 2;
    14.6              label.setBounds(x, 0, w, parent.getHeight());
    14.7 -            
    14.8 -            UTUtils.LOGGER.fine("icon " + icon.getBounds().toString());
    14.9 -            UTUtils.LOGGER.fine("label" + label.getBounds().toString());
   14.10 +
   14.11 +            /*
   14.12 +            UTUtils.LOGGER.fine("icon " + icon.getBounds().toString()); // NOI18N
   14.13 +            UTUtils.LOGGER.fine("label" + label.getBounds().toString()); // NOI18N
   14.14 +            */
   14.15          }
   14.16          
   14.17          public java.awt.Dimension minimumLayoutSize(java.awt.Container parent) {
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/tasklist.usertasks/test/qa-functional/testCases.html	Sun Sep 19 12:14:27 2004 +0000
    15.3 @@ -0,0 +1,40 @@
    15.4 +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    15.5 +<html>
    15.6 +<head>
    15.7 +  <meta http-equiv="content-type"
    15.8 + content="text/html; charset=ISO-8859-1">
    15.9 +  <title>Test Cases</title>
   15.10 +</head>
   15.11 +<body>
   15.12 +<h3>Test Cases</h3>
   15.13 +<ol>
   15.14 +  <li>Adding a task should select the added task.</li>
   15.15 +  <ol>
   15.16 +    <li>Open test1.ics.</li>
   15.17 +    <li>Select "A".</li>
   15.18 +    <li>Local Menu. <br>
   15.19 +    </li>
   15.20 +    <li>Add Subtask.</li>
   15.21 +    <li>Enter a summary.</li>
   15.22 +    <li>OK</li>
   15.23 +    <li>The new subtask should be selected.</li>
   15.24 +  </ol>
   15.25 +  <li>Select next task after cut.</li>
   15.26 +  <ol>
   15.27 +    <li>Open test2.ics.</li>
   15.28 +    <li>Select "A"</li>
   15.29 +    <li>Local Menu</li>
   15.30 +    <li>Cut</li>
   15.31 +    <li>C should be selected</li>
   15.32 +  </ol>
   15.33 +  <li>Adding a task should not collapse the tree.</li>
   15.34 +  <ol>
   15.35 +    <li>Open test3.ics.</li>
   15.36 +    <li>Expand All.</li>
   15.37 +    <li>Create a new task under the task list node.</li>
   15.38 +    <li>"A" should not collapse.<br>
   15.39 +    </li>
   15.40 +  </ol>
   15.41 +</ol>
   15.42 +</body>
   15.43 +</html>