/jEdit/tags/jedit-4-2-pre1/org/gjt/sp/jedit/browser/VFSDirectoryEntryTable.java

# · Java · 411 lines · 308 code · 48 blank · 55 comment · 67 complexity · ec26e0009b24e27d4af64aa3e252764e MD5 · raw file

  1. /*
  2. * VFSDirectoryEntryTable.java - VFS directory entry table
  3. * :tabSize=8:indentSize=8:noTabs=false:
  4. * :folding=explicit:collapseFolds=1:
  5. *
  6. * Copyright (C) 2003 Slava Pestov
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License
  10. * as published by the Free Software Foundation; either version 2
  11. * of the License, or any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  21. */
  22. package org.gjt.sp.jedit.browser;
  23. //{{{ Imports
  24. import javax.swing.table.*;
  25. import javax.swing.*;
  26. import java.awt.event.*;
  27. import java.awt.*;
  28. import java.util.ArrayList;
  29. import java.util.HashSet;
  30. import java.util.LinkedList;
  31. import java.util.Set;
  32. import org.gjt.sp.jedit.io.VFS;
  33. import org.gjt.sp.jedit.MiscUtilities;
  34. import org.gjt.sp.util.Log;
  35. //}}}
  36. /**
  37. * @author Slava Pestov
  38. * @version $Id: VFSDirectoryEntryTable.java 4665 2003-04-30 05:28:55Z spestov $
  39. * @since jEdit 4.2pre1
  40. */
  41. public class VFSDirectoryEntryTable extends JTable
  42. {
  43. //{{{ VFSDirectoryEntryTable constructor
  44. public VFSDirectoryEntryTable(BrowserView browserView)
  45. {
  46. super(new VFSDirectoryEntryTableModel());
  47. this.browserView = browserView;
  48. setShowGrid(false);
  49. setIntercellSpacing(new Dimension(0,0));
  50. /* TableColumn col1 = getColumnModel().getColumn(0);
  51. col1.setMinWidth(20);
  52. col1.setMaxWidth(20);
  53. col1.setPreferredWidth(20); */
  54. setDefaultRenderer(VFSDirectoryEntryTableModel.Entry.class,
  55. renderer = new FileCellRenderer());
  56. JTableHeader header = getTableHeader();
  57. header.setReorderingAllowed(false);
  58. setRowSelectionAllowed(true);
  59. //setColumnSelectionAllowed(true);
  60. //setCellSelectionEnabled(false);
  61. setAutoResizeMode(AUTO_RESIZE_OFF);
  62. } //}}}
  63. //{{{ doTypeSelect() method
  64. public void doTypeSelect(String str, boolean ignoreCase)
  65. {
  66. if(str.length() == 0)
  67. clearSelection();
  68. else if(getSelectedRow() == -1)
  69. doTypeSelect(str,0,getRowCount(),ignoreCase);
  70. else
  71. {
  72. int start = getSelectionModel().getMaxSelectionIndex();
  73. boolean retVal = doTypeSelect(str,start,getRowCount(),
  74. ignoreCase);
  75. if(!retVal)
  76. {
  77. // scan from selection to end failed, so
  78. // scan from start to selection
  79. doTypeSelect(str,0,start,ignoreCase);
  80. }
  81. }
  82. } //}}}
  83. //{{{ getSelectedFiles() method
  84. public VFS.DirectoryEntry[] getSelectedFiles()
  85. {
  86. VFSDirectoryEntryTableModel model
  87. = (VFSDirectoryEntryTableModel)getModel();
  88. LinkedList returnValue = new LinkedList();
  89. int[] selectedRows = getSelectedRows();
  90. for(int i = 0; i < selectedRows.length; i++)
  91. {
  92. returnValue.add(model.files[selectedRows[i]].dirEntry);
  93. }
  94. return (VFS.DirectoryEntry[])returnValue.toArray(new
  95. VFS.DirectoryEntry[returnValue.size()]);
  96. } //}}}
  97. //{{{ getExpandedDirectories() method
  98. public void getExpandedDirectories(Set set)
  99. {
  100. VFSDirectoryEntryTableModel model
  101. = (VFSDirectoryEntryTableModel)getModel();
  102. if(model.files != null)
  103. {
  104. for(int i = 0; i < model.files.length; i++)
  105. {
  106. if(model.files[i].expanded)
  107. set.add(model.files[i].dirEntry.path);
  108. }
  109. }
  110. } //}}}
  111. //{{{ toggleExpanded() method
  112. public void toggleExpanded(int row)
  113. {
  114. VFSDirectoryEntryTableModel model
  115. = (VFSDirectoryEntryTableModel)getModel();
  116. VFSDirectoryEntryTableModel.Entry entry = model.files[row];
  117. if(entry.dirEntry.type == VFS.DirectoryEntry.FILE)
  118. return;
  119. if(entry.expanded)
  120. model.collapse(row);
  121. else
  122. browserView.loadDirectory(entry,entry.dirEntry.path);
  123. } //}}}
  124. //{{{ setDirectory() method
  125. public void setDirectory(Object node, ArrayList list, Set tmpExpanded)
  126. {
  127. timer.stop();
  128. typeSelectBuffer.setLength(0);
  129. VFSDirectoryEntryTableModel model = ((VFSDirectoryEntryTableModel)getModel());
  130. int startIndex;
  131. if(node == null)
  132. {
  133. startIndex = 0;
  134. model.setRoot(list);
  135. }
  136. else
  137. {
  138. startIndex =
  139. model.expand(
  140. (VFSDirectoryEntryTableModel.Entry)node,
  141. list);
  142. startIndex++;
  143. }
  144. for(int i = 0; i < list.size(); i++)
  145. {
  146. VFSDirectoryEntryTableModel.Entry e
  147. = model.files[startIndex + i];
  148. String path = e.dirEntry.path;
  149. if(tmpExpanded.contains(path))
  150. {
  151. browserView.loadDirectory(e,path);
  152. tmpExpanded.remove(path);
  153. }
  154. }
  155. resizeColumnsAppropriately();
  156. } //}}}
  157. //{{{ maybeReloadDirectory() method
  158. public void maybeReloadDirectory(String path)
  159. {
  160. VFSDirectoryEntryTableModel model
  161. = (VFSDirectoryEntryTableModel)getModel();
  162. for(int i = 0; i < model.files.length; i++)
  163. {
  164. VFSDirectoryEntryTableModel.Entry e = model.files[i];
  165. if(!e.expanded || e.dirEntry.type == VFS.DirectoryEntry.FILE)
  166. continue;
  167. if(path.equals(e.dirEntry.path))
  168. browserView.loadDirectory(e,path);
  169. }
  170. } //}}}
  171. //{{{ propertiesChanged() method
  172. public void propertiesChanged()
  173. {
  174. renderer.propertiesChanged();
  175. VFS.DirectoryEntry template = new VFS.DirectoryEntry(
  176. "foo","foo","foo",VFS.DirectoryEntry.FILE,0L,false);
  177. setRowHeight(renderer.getTableCellRendererComponent(
  178. this,new VFSDirectoryEntryTableModel.Entry(template,0),
  179. false,false,0,1).getPreferredSize().height);
  180. Dimension prefSize = getPreferredSize();
  181. setPreferredScrollableViewportSize(new Dimension(prefSize.width,
  182. getRowHeight() * 12));
  183. } //}}}
  184. //{{{ scrollRectToVisible() method
  185. public void scrollRectToVisible(Rectangle rect)
  186. {
  187. // avoid scrolling to the right
  188. rect.width = 0;
  189. super.scrollRectToVisible(rect);
  190. } //}}}
  191. //{{{ processKeyEvent() method
  192. public void processKeyEvent(KeyEvent evt)
  193. {
  194. if(evt.getID() == KeyEvent.KEY_PRESSED)
  195. {
  196. VFSDirectoryEntryTableModel model =
  197. (VFSDirectoryEntryTableModel)getModel();
  198. int row = getSelectedRow();
  199. switch(evt.getKeyCode())
  200. {
  201. case KeyEvent.VK_LEFT:
  202. evt.consume();
  203. if(row != -1)
  204. {
  205. if(model.files[row].expanded)
  206. {
  207. model.collapse(row);
  208. break;
  209. }
  210. for(int i = row - 1; i >= 0; i--)
  211. {
  212. if(model.files[i].expanded)
  213. {
  214. setSelectedRow(i);
  215. break;
  216. }
  217. }
  218. }
  219. String dir = browserView.getBrowser()
  220. .getDirectory();
  221. dir = MiscUtilities.getParentOfPath(dir);
  222. browserView.getBrowser().setDirectory(dir);
  223. break;
  224. case KeyEvent.VK_RIGHT:
  225. if(row != -1)
  226. {
  227. if(!model.files[row].expanded)
  228. toggleExpanded(row);
  229. }
  230. evt.consume();
  231. break;
  232. case KeyEvent.VK_DOWN:
  233. // stupid Swing
  234. if(row == -1 && getModel().getRowCount() != 0)
  235. {
  236. setSelectedRow(0);
  237. evt.consume();
  238. }
  239. break;
  240. case KeyEvent.VK_ENTER:
  241. browserView.getBrowser().filesActivated(
  242. (evt.isShiftDown()
  243. ? VFSBrowser.M_OPEN_NEW_VIEW
  244. : VFSBrowser.M_OPEN),false);
  245. evt.consume();
  246. break;
  247. }
  248. }
  249. else if(evt.getID() == KeyEvent.KEY_TYPED)
  250. {
  251. if(evt.isControlDown() || evt.isAltDown()
  252. || evt.isMetaDown())
  253. {
  254. return;
  255. }
  256. // hack...
  257. if(evt.isShiftDown() && evt.getKeyChar() == '\n')
  258. return;
  259. VFSBrowser browser = browserView.getBrowser();
  260. switch(evt.getKeyChar())
  261. {
  262. case '~':
  263. if(browser.getMode() == VFSBrowser.BROWSER)
  264. browser.setDirectory(System.getProperty(
  265. "user.home"));
  266. break;
  267. case '/':
  268. if(browser.getMode() == VFSBrowser.BROWSER)
  269. browser.rootDirectory();
  270. break;
  271. case '-':
  272. if(browser.getMode() == VFSBrowser.BROWSER)
  273. {
  274. browser.setDirectory(
  275. browser.getView().getBuffer()
  276. .getDirectory());
  277. }
  278. break;
  279. default:
  280. typeSelectBuffer.append(evt.getKeyChar());
  281. doTypeSelect(typeSelectBuffer.toString(),true);
  282. timer.stop();
  283. timer.setInitialDelay(750);
  284. timer.setRepeats(false);
  285. timer.start();
  286. return;
  287. }
  288. }
  289. if(!evt.isConsumed())
  290. super.processKeyEvent(evt);
  291. } //}}}
  292. //{{{ setSelectedRow() method
  293. public void setSelectedRow(int row)
  294. {
  295. getSelectionModel().setSelectionInterval(row,row);
  296. scrollRectToVisible(getCellRect(row,0,true));
  297. } //}}}
  298. //{{{ Private members
  299. private BrowserView browserView;
  300. private FileCellRenderer renderer;
  301. private StringBuffer typeSelectBuffer = new StringBuffer();
  302. private Timer timer = new Timer(0,new ClearTypeSelect());
  303. //{{{ doTypeSelect() method
  304. private boolean doTypeSelect(String str, int start, int end,
  305. boolean ignoreCase)
  306. {
  307. for(int i = start; i < end; i++)
  308. {
  309. VFSDirectoryEntryTableModel.Entry entry =
  310. (VFSDirectoryEntryTableModel.Entry)getValueAt(i,1);
  311. String matchAgainst = (MiscUtilities.isAbsolutePath(str)
  312. ? entry.dirEntry.path : entry.dirEntry.name);
  313. if(matchAgainst.regionMatches(ignoreCase,
  314. 0,str,0,str.length()))
  315. {
  316. setSelectedRow(i);
  317. return true;
  318. }
  319. }
  320. return false;
  321. } //}}}
  322. //{{{ resizeColumnsAppropriately() method
  323. private void resizeColumnsAppropriately()
  324. {
  325. VFSDirectoryEntryTableModel model
  326. = (VFSDirectoryEntryTableModel)getModel();
  327. FontMetrics fm = getFontMetrics(getFont());
  328. int[] widths = new int[model.getColumnCount()];
  329. for(int i = 0; i < widths.length; i++)
  330. {
  331. String columnName = model.getColumnName(i);
  332. if(columnName != null)
  333. widths[i] = fm.stringWidth(columnName);
  334. }
  335. for(int i = 0; i < model.files.length; i++)
  336. {
  337. for(int j = 0; j < widths.length; j++)
  338. {
  339. int width = renderer.getTableCellRendererComponent(
  340. this,model.files[i],false,false,i,j)
  341. .getPreferredSize().width;
  342. widths[j] = Math.max(widths[j],width);
  343. }
  344. }
  345. for(int i = 0; i < widths.length; i++)
  346. {
  347. int width = widths[i];
  348. if(i != 0 && i != widths.length - 1 && width != 0)
  349. width += 10;
  350. getColumnModel().getColumn(i).setPreferredWidth(width);
  351. }
  352. doLayout();
  353. } //}}}
  354. //}}}
  355. //{{{ ClearTypeSelect class
  356. class ClearTypeSelect implements ActionListener
  357. {
  358. public void actionPerformed(ActionEvent evt)
  359. {
  360. typeSelectBuffer.setLength(0);
  361. }
  362. } //}}}
  363. }