/plugins/TaskList/tags/TaskList_0_4_0/TaskList.java

# · Java · 398 lines · 243 code · 32 blank · 123 comment · 38 complexity · 90284c3408ca850c57076356267ad954 MD5 · raw file

  1. /*
  2. * TaskList.java - TaskList plugin
  3. * Copyright (C) 2001,2002 Oliver Rutherfurd
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License
  7. * as published by the Free Software Foundation; either version 2
  8. * of the License, or any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  18. */
  19. //{{{ imports
  20. import java.awt.*;
  21. import java.awt.event.*;
  22. import java.util.Vector;
  23. import javax.swing.*;
  24. import javax.swing.event.*;
  25. import javax.swing.table.*;
  26. import org.gjt.sp.jedit.*;
  27. import org.gjt.sp.jedit.msg.*;
  28. import org.gjt.sp.jedit.textarea.JEditTextArea;
  29. import org.gjt.sp.util.Log;
  30. //}}}
  31. /**
  32. * A dockable component contaning a scrollable table; the table contains
  33. * data on task items found by parsing one or more buffers.
  34. *
  35. * @author Oliver Rutherfurd
  36. */
  37. public class TaskList extends JPanel implements EBComponent
  38. {
  39. //{{{ constructor
  40. /**
  41. * Constructor
  42. *
  43. * @param view The view in which the TaskList component will appear
  44. */
  45. public TaskList(View view)
  46. {
  47. super(new BorderLayout());
  48. this.view = view;
  49. this.taskListModel = new TaskListModel(view);
  50. table = new TaskListTable();
  51. add(BorderLayout.CENTER, new JScrollPane(table));
  52. }//}}}
  53. //{{{ TaskListTable class
  54. /**
  55. * The table containing data on task items
  56. */
  57. class TaskListTable extends JTable
  58. {
  59. private boolean init = false;
  60. //{{{ constructor
  61. TaskListTable()
  62. {
  63. setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
  64. setCellSelectionEnabled(false);
  65. setRowSelectionAllowed(true);
  66. // NOTE: a single cell renderer that does not indicate cell focus
  67. setDefaultRenderer(Object.class, new DefaultTableCellRenderer() {
  68. public Component getTableCellRendererComponent(JTable table, Object value,
  69. boolean isSelected, boolean hasFocus, int row, int column) {
  70. Component c = super.getTableCellRendererComponent(table, value,
  71. isSelected, false, row, column);
  72. int horizAlignment = SwingConstants.LEFT;
  73. if(column == 0)
  74. horizAlignment = SwingConstants.CENTER;
  75. else if(column == 1)
  76. horizAlignment = SwingConstants.RIGHT;
  77. ((JLabel)c).setHorizontalAlignment(horizAlignment);
  78. return c;
  79. }
  80. });
  81. setDefaultRenderer(Image.class, null);
  82. setDefaultRenderer(Number.class, null);
  83. setModel(TaskList.this.taskListModel);
  84. //setRowHeight(18);
  85. setShowVerticalLines(jEdit.getBooleanProperty("tasklist.table.vertical-lines"));
  86. setShowHorizontalLines(jEdit.getBooleanProperty("tasklist.table.horizontal-lines"));
  87. //setIntercellSpacing(new Dimension(0,1));
  88. MouseHandler handler = new MouseHandler();
  89. addMouseListener(handler);
  90. // TODO: Fix height of header using Windows L&F
  91. if(getTableHeader() != null)
  92. {
  93. getTableHeader().setReorderingAllowed(false);
  94. getTableHeader().setResizingAllowed(true);
  95. getTableHeader().addMouseListener(handler);
  96. Dimension dim = getTableHeader().getPreferredSize();
  97. dim.height = getRowHeight();
  98. getTableHeader().setPreferredSize(dim);
  99. }
  100. init = true;
  101. resizeTable();
  102. sort();
  103. }//}}}
  104. //{{{ getTaskListModel() method
  105. public TaskListModel getTaskListModel()
  106. {
  107. return (TaskListModel)getModel();
  108. }//}}}
  109. //{{{ tableChanged() method
  110. /**
  111. * Calls resizeTable() when the number of table columns change
  112. *
  113. * @param e The TableModelEvent represeting the change in the table's state
  114. */
  115. public void tableChanged(TableModelEvent e)
  116. {
  117. super.tableChanged(e);
  118. if(e.getFirstRow() == e.HEADER_ROW && init)
  119. {
  120. try
  121. {
  122. resizeTable();
  123. }
  124. catch(Exception ex)
  125. {
  126. Log.log(Log.ERROR, TaskList.class, ex);
  127. }
  128. }
  129. }//}}}
  130. //{{{ resizeTable() method
  131. /**
  132. * Re-sizes the columns in the table - called when cols are
  133. * added or removed.
  134. */
  135. void resizeTable()
  136. {
  137. TableColumnModel columnModel = getColumnModel();
  138. columnModel.getColumn(0).setMinWidth(20);
  139. columnModel.getColumn(0).setPreferredWidth(20);
  140. columnModel.getColumn(0).setMaxWidth(20);
  141. columnModel.getColumn(0).setResizable(false);
  142. columnModel.getColumn(1).setMinWidth(50);
  143. columnModel.getColumn(1).setMaxWidth(80);
  144. columnModel.getColumn(1).sizeWidthToFit();
  145. columnModel.getColumn(1).setResizable(false);
  146. columnModel.getColumn(2).setMinWidth(200);
  147. columnModel.getColumn(2).setPreferredWidth(1000);
  148. if(columnModel.getColumnCount() == 4)
  149. {
  150. columnModel.getColumn(3).setMinWidth(100);
  151. columnModel.getColumn(3).setPreferredWidth(500);
  152. }
  153. getTableHeader().resizeAndRepaint();
  154. }//}}}
  155. //{{{ sort() method
  156. private void sort()
  157. {
  158. getTaskListModel().sort();
  159. }//}}}
  160. //{{{ sort(int col, boolean ascending) method
  161. private void sort(int col, boolean ascending)
  162. {
  163. getTaskListModel().sort(col, ascending);
  164. }//}}}
  165. }//}}}
  166. //{{{ MouseHandler class
  167. /**
  168. * Responds to mouse clicks in the table or its header row
  169. */
  170. class MouseHandler extends MouseAdapter
  171. {
  172. //{{{ mouseClicked() method
  173. /**
  174. * Calls handling routine based on number, type and location
  175. * of mouse clicks
  176. * @param e The MouseEvent being handled
  177. */
  178. public void mouseClicked(MouseEvent e)
  179. {
  180. Buffer buffer = view.getBuffer();
  181. if(buffer.isDirty() && e.getClickCount() == 1)
  182. {
  183. TaskListPlugin.extractTasks(view.getBuffer());
  184. }
  185. Point p = e.getPoint();
  186. final int rowNum = table.rowAtPoint(p);
  187. if(e.getClickCount() == 1 &&
  188. (e.getModifiers() & InputEvent.BUTTON3_MASK) != 0)
  189. {
  190. e.consume();
  191. showPopup(view, rowNum, p);
  192. }
  193. else if(e.getClickCount() > 1)
  194. {
  195. if(e.getComponent() == table.getTableHeader())
  196. {
  197. TaskListModel model = table.getTaskListModel();
  198. int sortCol = table.columnAtPoint(p);
  199. switch(sortCol)
  200. {
  201. case 0:
  202. sortCol = 2;
  203. case 1:
  204. case 2:
  205. {
  206. if(model.getSortCol() == sortCol)
  207. model.setSortAscending(!model.getSortAscending());
  208. else
  209. model.setSortCol(sortCol);
  210. break;
  211. }
  212. default:
  213. {
  214. return;
  215. }
  216. }
  217. model.sort();
  218. }
  219. else if(rowNum > -1)
  220. {
  221. table.setRowSelectionInterval(rowNum, rowNum);
  222. showTaskText(rowNum);
  223. }
  224. }
  225. else if(e.getClickCount() == 1)
  226. {
  227. if(e.getComponent() == table.getTableHeader())
  228. return;
  229. if(TaskListPlugin.getAllowSingleClickSelection())
  230. {
  231. table.setRowSelectionInterval(rowNum,rowNum);
  232. showTaskText(rowNum);
  233. }
  234. }
  235. }//}}}
  236. //{{{ showPopup(View view, int row, Point p) method
  237. /**
  238. * Causes a popup context menu to be shown
  239. * @param view he View in which the TaskList component appears
  240. * @param row The table row clicked by the mouse
  241. * @param p The Point within the TaskList's table object clicked by the mouse
  242. */
  243. private void showPopup(final View view, final int row, Point p)
  244. {
  245. TaskListPopup popup = new TaskListPopup(view, TaskList.this, row);
  246. // NOTE: keep within screen limits; use task list panel, not table
  247. SwingUtilities.convertPointToScreen(p, table);
  248. SwingUtilities.convertPointFromScreen(p, TaskList.this);
  249. Dimension dt = TaskList.this.getSize();
  250. Dimension dp = popup.getPreferredSize();
  251. if (p.x + dp.width > dt.width)
  252. p.x = dt.width - dp.width;
  253. if (p.y + dp.height > dt.height)
  254. p.y = dt.height - dp.height;
  255. popup.show(TaskList.this, p.x+1, p.y+1);
  256. }//}}}
  257. //{{{ showTaskText(int row) method
  258. /**
  259. * Locates and displays buffer text corresponding to the selected row of the TaskList's table component
  260. *
  261. * @param row The selected row of the TaskList table
  262. */
  263. private void showTaskText(final int row)
  264. {
  265. // NOTE: get EditPane of buffer clicked, goto selection
  266. SwingUtilities.invokeLater(new Runnable()
  267. {
  268. public void run()
  269. {
  270. Task task = (Task)taskListModel.elementAt(row);
  271. EditPane[] editPanes = view.getEditPanes();
  272. Buffer buffer = task.getBuffer();
  273. for(int i = 0; i < editPanes.length; i++)
  274. {
  275. if(editPanes[i].getBuffer() == buffer)
  276. {
  277. JEditTextArea textArea = editPanes[i].getTextArea();
  278. textArea.setCaretPosition(textArea.getLineStartOffset(task.getLineNumber()) + task.getStartOffset());
  279. textArea.scrollToCaret(true);
  280. textArea.grabFocus();
  281. break;
  282. }
  283. }
  284. }
  285. });
  286. }//}}}
  287. }//}}}
  288. //{{{ getName() method
  289. /**
  290. * Property accessor required by jEdit Plugin API
  291. * @return The plugin's name property
  292. */
  293. public String getName()
  294. {
  295. return TaskListPlugin.NAME;
  296. }//}}}
  297. //{{{ getComponent() method
  298. /**
  299. * Property accessor required by jEdit Plugin API
  300. * @return A reference to the TaskList object
  301. */
  302. public Component getComponent()
  303. {
  304. return this;
  305. }//}}}
  306. //{{{ handleMessage(EBMessage msg) method
  307. /**
  308. * Message handling routine required by the jEdit Plugin API
  309. *
  310. * @param message The EBMessage received from the EditBus
  311. */
  312. public void handleMessage(EBMessage message)
  313. {
  314. if(message instanceof PropertiesChanged)
  315. {
  316. table.setShowVerticalLines(
  317. jEdit.getBooleanProperty("tasklist.table.vertical-lines"));
  318. table.setShowHorizontalLines(
  319. jEdit.getBooleanProperty("tasklist.table.horizontal-lines"));
  320. }
  321. }//}}}
  322. //{{{ addNotify() method
  323. /**
  324. * Adds the TaskList and its table's data model to the EditBus
  325. * to listen for messages; registers the data model to be notified when
  326. * tasks are added or removed.
  327. */
  328. public void addNotify()
  329. {
  330. super.addNotify();
  331. EditBus.addToBus(this);
  332. EditBus.addToBus(taskListModel);
  333. TaskListPlugin.addTaskListener(taskListModel);
  334. }//}}}
  335. //{{{ removeNotify() method
  336. /**
  337. * Removes the TaskList and its table's data model from the EditBus;
  338. * removes the data model form the list of components that listen for
  339. * the addition or removal of tasks items
  340. */
  341. public void removeNotify()
  342. {
  343. super.removeNotify();
  344. EditBus.removeFromBus(this);
  345. EditBus.removeFromBus(taskListModel);
  346. // table model doesn't need to be notified when task are added/removed
  347. TaskListPlugin.removeTaskListener(taskListModel);
  348. }//}}}
  349. //{{{ members
  350. /**
  351. * The view in which the TaskList component appears
  352. */
  353. private View view;
  354. /**
  355. * The table display task items; given package access
  356. * to allow for calls by a TaskListPopup object.
  357. */
  358. TaskListTable table;
  359. /**
  360. * The data model for the TaskList's table; given package access
  361. * to allow for calls by a TaskListPopup object.
  362. */
  363. TaskListModel taskListModel;
  364. //}}}
  365. }
  366. // :collapseFolds=1:folding=explicit:indentSize=4:lineSeparator=\n:noTabs=false:tabSize=4: