1 22 23 package org.gjt.sp.jedit.browser; 24 25 import javax.swing.event.*; 27 import javax.swing.table.*; 28 import javax.swing.*; 29 import java.awt.event.*; 30 import java.awt.font.*; 31 import java.awt.*; 32 import java.util.ArrayList ; 33 import java.util.LinkedList ; 34 import java.util.Set ; 35 import org.gjt.sp.jedit.io.VFS; 36 import org.gjt.sp.jedit.io.VFSFile; 37 import org.gjt.sp.jedit.io.VFSManager; 38 import org.gjt.sp.jedit.ActionContext; 39 import org.gjt.sp.jedit.EditAction; 40 import org.gjt.sp.jedit.MiscUtilities; 41 import org.gjt.sp.jedit.GUIUtilities; 42 import org.gjt.sp.jedit.jEdit; 43 import org.gjt.sp.util.Log; 44 46 51 public class VFSDirectoryEntryTable extends JTable 52 { 53 public VFSDirectoryEntryTable(BrowserView browserView) 55 { 56 super(new VFSDirectoryEntryTableModel()); 57 this.browserView = browserView; 58 setShowGrid(false); 59 60 setIntercellSpacing(new Dimension(0,0)); 61 62 setDefaultRenderer(VFSDirectoryEntryTableModel.Entry.class, 63 renderer = new FileCellRenderer()); 64 65 header = getTableHeader(); 66 header.setReorderingAllowed(false); 67 header.addMouseListener(new MouseHandler()); 68 header.setDefaultRenderer(new HeaderRenderer( 69 (DefaultTableCellRenderer)header.getDefaultRenderer())); 70 71 setRowSelectionAllowed(true); 72 73 getColumnModel().addColumnModelListener(new ColumnHandler()); 74 75 setAutoResizeMode(AUTO_RESIZE_OFF); 76 } 78 public boolean selectFile(String path) 80 { 81 for(int i = 0; i < getRowCount(); i++) 82 { 83 VFSDirectoryEntryTableModel.Entry entry = 84 (VFSDirectoryEntryTableModel.Entry) 85 getValueAt(i,1); 86 if(entry.dirEntry.getPath().equals(path)) 87 { 88 setSelectedRow(i); 89 return true; 90 } 91 } 92 93 return false; 94 } 96 public void doTypeSelect(String str, boolean dirsOnly) 98 { 99 if(str.length() == 0) 100 clearSelection(); 101 else if(getSelectedRow() == -1) 102 doTypeSelect(str,0,getRowCount(),dirsOnly); 103 else 104 { 105 int start = getSelectionModel().getMaxSelectionIndex(); 106 boolean retVal = doTypeSelect(str,start,getRowCount(), 107 dirsOnly); 108 109 if(!retVal) 110 { 111 doTypeSelect(str,0,start,dirsOnly); 114 } 115 } 116 } 118 public VFSFile[] getSelectedFiles() 120 { 121 VFSDirectoryEntryTableModel model 122 = (VFSDirectoryEntryTableModel)getModel(); 123 124 LinkedList returnValue = new LinkedList (); 125 int[] selectedRows = getSelectedRows(); 126 for(int i = 0; i < selectedRows.length; i++) 127 { 128 returnValue.add(model.files[selectedRows[i]].dirEntry); 129 } 130 return (VFSFile[])returnValue.toArray(new 131 VFSFile[returnValue.size()]); 132 } 134 public void getExpandedDirectories(Set set) 136 { 137 VFSDirectoryEntryTableModel model 138 = (VFSDirectoryEntryTableModel)getModel(); 139 140 if(model.files != null) 141 { 142 for(int i = 0; i < model.files.length; i++) 143 { 144 if(model.files[i].expanded) 145 set.add(model.files[i].dirEntry.getPath()); 146 } 147 } 148 } 150 public void toggleExpanded(final int row) 152 { 153 VFSDirectoryEntryTableModel model 154 = (VFSDirectoryEntryTableModel)getModel(); 155 156 VFSDirectoryEntryTableModel.Entry entry = model.files[row]; 157 if(entry.dirEntry.getType() == VFSFile.FILE) 158 return; 159 160 if(entry.expanded) 161 { 162 model.collapse(VFSManager.getVFSForPath( 163 entry.dirEntry.getPath()),row); 164 resizeColumns(); 165 } 166 else 167 { 168 browserView.clearExpansionState(); 169 browserView.loadDirectory(entry,entry.dirEntry.getPath(), 170 false); 171 } 172 173 VFSManager.runInAWTThread(new Runnable () 174 { 175 public void run() 176 { 177 setSelectedRow(row); 178 } 179 }); 180 } 182 public void setDirectory(VFS vfs, Object node, ArrayList list, 184 Set tmpExpanded) 185 { 186 timer.stop(); 187 typeSelectBuffer.setLength(0); 188 189 VFSDirectoryEntryTableModel model = ((VFSDirectoryEntryTableModel)getModel()); 190 int startIndex; 191 if(node == null) 192 { 193 startIndex = 0; 194 model.setRoot(vfs,list); 195 } 196 else 197 { 198 startIndex = 199 model.expand( 200 vfs, 201 (VFSDirectoryEntryTableModel.Entry)node, 202 list); 203 startIndex++; 204 } 205 206 for(int i = 0; i < list.size(); i++) 207 { 208 VFSDirectoryEntryTableModel.Entry e 209 = model.files[startIndex + i]; 210 String path = e.dirEntry.getPath(); 211 if(tmpExpanded.contains(path)) 212 { 213 browserView.loadDirectory(e,path,false); 214 tmpExpanded.remove(path); 215 } 216 } 217 218 resizeColumns(); 219 } 221 public void maybeReloadDirectory(String path) 223 { 224 VFSDirectoryEntryTableModel model 225 = (VFSDirectoryEntryTableModel)getModel(); 226 227 for(int i = 0; i < model.files.length; i++) 228 { 229 VFSDirectoryEntryTableModel.Entry e = model.files[i]; 230 if(!e.expanded || e.dirEntry.getType() == VFSFile.FILE) 231 continue; 232 233 VFSFile dirEntry = e.dirEntry; 234 String otherPath; 236 if(dirEntry.getSymlinkPath() == null) 237 otherPath = dirEntry.getPath(); 238 else 239 otherPath = dirEntry.getSymlinkPath(); 240 if(MiscUtilities.pathsEqual(path,otherPath)) 241 { 242 browserView.saveExpansionState(); 243 browserView.loadDirectory(e,path,false); 244 return; 245 } 246 } 247 } 249 public void propertiesChanged() 251 { 252 renderer.propertiesChanged(); 253 254 VFSFile template = new VFSFile( 255 "foo","foo","foo",VFSFile.FILE,0L,false); 256 setRowHeight(renderer.getTableCellRendererComponent( 257 this,new VFSDirectoryEntryTableModel.Entry(template,0), 258 false,false,0,0).getPreferredSize().height); 259 Dimension prefSize = getPreferredSize(); 260 setPreferredScrollableViewportSize(new Dimension(prefSize.width, 261 getRowHeight() * 12)); 262 } 264 public void scrollRectToVisible(Rectangle rect) 266 { 267 rect.width = 0; 269 super.scrollRectToVisible(rect); 270 } 272 public void processKeyEvent(KeyEvent evt) 274 { 275 if(evt.getID() == KeyEvent.KEY_PRESSED) 276 { 277 VFSDirectoryEntryTableModel model = 278 (VFSDirectoryEntryTableModel)getModel(); 279 int row = getSelectedRow(); 280 ActionContext ac = VFSBrowser.getActionContext(); 281 ActionContext jac = jEdit.getActionContext(); 282 VFSBrowser browser = browserView.getBrowser(); 283 switch(evt.getKeyCode()) 284 { 285 case KeyEvent.VK_LEFT: 286 evt.consume(); 287 if(row != -1) 288 { 289 if(model.files[row].expanded) 290 { 291 toggleExpanded(row); 292 return; 293 } 294 295 for(int i = row - 1; i >= 0; i--) 296 { 297 if((model.files[i].expanded) && (model.files[i].level < model.files[row].level)) 298 { 299 setSelectedRow(i); 300 return; 301 } 302 } 303 } 304 305 String dir = browserView.getBrowser() 306 .getDirectory(); 307 dir = MiscUtilities.getParentOfPath(dir); 308 browserView.getBrowser().setDirectory(dir); 309 break; 310 case KeyEvent.VK_BACK_SPACE: 311 evt.consume(); 312 EditAction ea = ac.getAction("vfs.browser.up"); 313 ac.invokeAction(evt, ea); 314 break; 315 case KeyEvent.VK_DELETE: 316 evt.consume(); 317 ea = ac.getAction("vfs.browser.delete"); 318 ac.invokeAction(evt, ea); 319 break; 320 case KeyEvent.CTRL_MASK | KeyEvent.VK_N: 321 evt.consume(); 322 ea = ac.getAction("vfs.browser.new-file"); 323 ac.invokeAction(evt, ea); 324 break; 325 case KeyEvent.VK_INSERT: 326 evt.consume(); 327 ea = ac.getAction("vfs.browser.new-directory"); 328 ac.invokeAction(evt, ea); 329 break; 330 case KeyEvent.VK_ESCAPE: 331 ea = jac.getAction("close-docking-area"); 332 ea.invoke(jEdit.getActiveView()); 333 evt.consume(); 334 break; 335 case KeyEvent.VK_F2: 336 ea = ac.getAction("vfs.browser.rename"); 337 evt.consume(); 338 ac.invokeAction(evt, ea); 339 break; 340 case KeyEvent.VK_F5: 341 evt.consume(); 342 ea = ac.getAction("vfs.browser.reload"); 343 ac.invokeAction(evt, ea); 344 break; 345 case KeyEvent.VK_F6: 346 case KeyEvent.VK_TAB: 347 browser.focusOnDefaultComponent(); 348 evt.consume(); 349 break; 350 case KeyEvent.VK_RIGHT: 351 evt.consume(); 352 if(row != -1) 353 { 354 if(!model.files[row].expanded) 355 toggleExpanded(row); 356 } 357 358 break; 359 case KeyEvent.VK_ENTER: 360 evt.consume(); 361 browserView.getBrowser().filesActivated( 362 (evt.isShiftDown() 363 ? VFSBrowser.M_OPEN_NEW_VIEW 364 : VFSBrowser.M_OPEN),false); 365 366 break; 367 } 368 } 369 else if(evt.getID() == KeyEvent.KEY_TYPED) 370 { 371 372 if(evt.isControlDown() || evt.isAltDown() 373 || evt.isMetaDown()) 374 { 375 evt.consume(); 376 return; 377 } 378 379 if(evt.isShiftDown() && evt.getKeyChar() == '\n') { 381 evt.consume(); 382 return; 383 } 384 385 386 VFSBrowser browser = browserView.getBrowser(); 387 388 switch(evt.getKeyChar()) 389 { 390 case '~': 391 evt.consume(); 392 if(browser.getMode() == VFSBrowser.BROWSER) 393 browser.setDirectory(System.getProperty( 394 "user.home")); 395 break; 396 case '/': 397 evt.consume(); 398 if(browser.getMode() == VFSBrowser.BROWSER) 399 browser.rootDirectory(); 400 break; 401 case '-': 402 evt.consume(); 403 if(browser.getMode() == VFSBrowser.BROWSER) 404 { 405 browser.setDirectory( 406 browser.getView().getBuffer() 407 .getDirectory()); 408 } 409 break; 410 default: 411 evt.consume(); 412 typeSelectBuffer.append(evt.getKeyChar()); 413 doTypeSelect(typeSelectBuffer.toString(), 414 browser.getMode() == VFSBrowser 415 .CHOOSE_DIRECTORY_DIALOG); 416 417 timer.stop(); 418 timer.setInitialDelay(750); 419 timer.setRepeats(false); 420 timer.start(); 421 return; 422 } 423 } 424 425 if(!evt.isConsumed()) 426 super.processKeyEvent(evt); 427 } 429 public void setSelectedRow(int row) 431 { 432 getSelectionModel().setSelectionInterval(row,row); 433 scrollRectToVisible(getCellRect(row,0,true)); 434 } 436 private BrowserView browserView; 438 private JTableHeader header; 439 private FileCellRenderer renderer; 440 private StringBuffer typeSelectBuffer = new StringBuffer (); 441 private Timer timer = new Timer(0,new ClearTypeSelect()); 442 private boolean resizingColumns; 443 444 private boolean doTypeSelect(String str, int start, int end, 446 boolean dirsOnly) 447 { 448 VFSFile[] files = ((VFSDirectoryEntryTableModel) 449 getModel()).getFiles(); 450 451 int index = VFSFile.findCompletion(files,start,end,str,dirsOnly); 452 if(index != -1) 453 { 454 setSelectedRow(index); 455 return true; 456 } 457 else 458 return false; 459 } 461 private void resizeColumns() 463 { 464 VFSDirectoryEntryTableModel model = (VFSDirectoryEntryTableModel)getModel(); 465 466 FontRenderContext fontRenderContext = new FontRenderContext( 467 null,false,false); 468 int[] widths = new int[model.getColumnCount()]; 469 for(int i = 0; i < widths.length; i++) 470 { 471 String columnName = model.getColumnName(i); 472 if(columnName != null) 473 { 474 widths[i] = (int)renderer.plainFont 475 .getStringBounds(columnName, 476 fontRenderContext).getWidth(); 477 } 478 } 479 480 for(int i = 1; i < widths.length; i++) 481 { 482 String extAttr = model.getExtendedAttribute(i); 483 widths[i] = Math.max(widths[i],model.getColumnWidth(i)); 484 } 485 486 for(int i = 0; i < model.files.length; i++) 487 { 488 VFSDirectoryEntryTableModel.Entry entry 489 = model.files[i]; 490 Font font = (entry.dirEntry.getType() 491 == VFSFile.FILE 492 ? renderer.plainFont : renderer.boldFont); 493 494 widths[0] = Math.max(widths[0],renderer.getEntryWidth( 495 entry,font,fontRenderContext)); 496 } 497 498 widths[0] += 10; 499 500 TableColumnModel columns = getColumnModel(); 501 502 try 503 { 504 resizingColumns = true; 505 for(int i = 0; i < widths.length; i++) 506 { 507 columns.getColumn(i).setPreferredWidth(widths[i]); 508 columns.getColumn(i).setWidth(widths[i]); 509 } 510 } 511 finally 512 { 513 resizingColumns = false; 514 } 515 516 doLayout(); 517 } 519 private void saveWidths() 521 { 522 if(resizingColumns) 523 return; 524 525 VFSDirectoryEntryTableModel model = (VFSDirectoryEntryTableModel)getModel(); 526 TableColumnModel columns = getColumnModel(); 527 528 for(int i = 1; i < model.getColumnCount(); i++) 529 model.setColumnWidth(i,columns.getColumn(i).getWidth()); 530 } 532 534 class ClearTypeSelect implements ActionListener 536 { 537 public void actionPerformed(ActionEvent evt) 538 { 539 typeSelectBuffer.setLength(0); 540 } 541 } 543 class ColumnHandler implements TableColumnModelListener 545 { 546 public void columnAdded(TableColumnModelEvent e) {} 547 public void columnRemoved(TableColumnModelEvent e) {} 548 public void columnMoved(TableColumnModelEvent e) {} 549 public void columnSelectionChanged(ListSelectionEvent e) {} 550 551 public void columnMarginChanged(ChangeEvent e) 552 { 553 saveWidths(); 554 } 555 } 557 class MouseHandler extends MouseInputAdapter 559 { 560 public void mousePressed(MouseEvent evt) 561 { 562 if (evt.getSource() == header && evt.getClickCount() == 2) 564 { 565 VFSDirectoryEntryTableModel model = (VFSDirectoryEntryTableModel) header.getTable().getModel(); 566 TableColumnModel columnModel = header.getColumnModel(); 567 int viewColumn = columnModel.getColumnIndexAtX(evt.getX()); 568 int column = columnModel.getColumn(viewColumn).getModelIndex(); 569 if(model.sortByColumn(column)) 570 resizeColumns(); 571 Log.log(Log.DEBUG,this,"VFSDirectoryEntryTable sorted by " + model.getColumnName(column) 572 + (model.getAscending() ? " ascending" : " descending") ); 573 return; 574 } 575 } 576 } 578 static class HeaderRenderer extends DefaultTableCellRenderer 580 { 581 private DefaultTableCellRenderer tcr; 582 583 public HeaderRenderer(DefaultTableCellRenderer tcr) 584 { 585 this.tcr = tcr; 586 } 587 588 public Component getTableCellRendererComponent(JTable table, Object value, 589 boolean isSelected, boolean hasFocus, int row, int column) 590 { 591 JLabel l = (JLabel)tcr.getTableCellRendererComponent(table,value,isSelected,hasFocus,row,column); 592 VFSDirectoryEntryTableModel model = (VFSDirectoryEntryTableModel)table.getModel(); 593 Icon icon = (column == model.getSortColumn()) 594 ? model.getAscending() ? ASC_ICON : DESC_ICON 595 : null; 596 l.setIcon(icon); 597 return l; 599 } 600 } 602 604 static final Icon ASC_ICON = GUIUtilities.loadIcon("arrow-asc.png"); 605 static final Icon DESC_ICON = GUIUtilities.loadIcon("arrow-desc.png"); 606 607 609 } 610 | Popular Tags |