1 22 23 package org.gjt.sp.jedit.browser; 24 25 import javax.swing.border.EmptyBorder ; 27 import javax.swing.event.*; 28 import javax.swing.*; 29 30 import java.awt.event.*; 31 import java.awt.*; 32 import java.io.File ; 33 import java.util.*; 34 35 import org.gjt.sp.jedit.gui.DockableWindowManager; 36 import org.gjt.sp.jedit.io.*; 37 import org.gjt.sp.jedit.*; 38 40 45 class BrowserView extends JPanel 46 { 47 BrowserView(final VFSBrowser browser) 49 { 50 this.browser = browser; 51 52 tmpExpanded = new HashSet(); 53 DockableWindowManager dwm = jEdit.getActiveView().getDockableWindowManager(); 54 KeyListener keyListener = dwm.closeListener(VFSBrowser.NAME); 55 56 parentDirectories = new ParentDirectoryList(); 57 parentDirectories.addKeyListener(keyListener); 58 59 parentDirectories.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 60 parentDirectories.setCellRenderer(new ParentDirectoryRenderer()); 61 parentDirectories.setVisibleRowCount(5); 62 parentDirectories.addMouseListener(new ParentMouseHandler()); 63 64 final JScrollPane parentScroller = new JScrollPane(parentDirectories); 65 parentScroller.setMinimumSize(new Dimension(0,0)); 66 67 table = new VFSDirectoryEntryTable(this); 68 table.addMouseListener(new TableMouseHandler()); 69 JScrollPane tableScroller = new JScrollPane(table); 70 tableScroller.setMinimumSize(new Dimension(0,0)); 71 tableScroller.getViewport().setBackground(table.getBackground()); 72 tableScroller.getViewport().addMouseListener(new TableMouseHandler()); 73 splitPane = new JSplitPane( 74 browser.isHorizontalLayout() 75 ? JSplitPane.HORIZONTAL_SPLIT : JSplitPane.VERTICAL_SPLIT, 76 jEdit.getBooleanProperty("appearance.continuousLayout"), 77 parentScroller,tableScroller); 78 splitPane.setOneTouchExpandable(true); 79 80 SwingUtilities.invokeLater(new Runnable () 81 { 82 public void run() 83 { 84 String prop = browser.isHorizontalLayout() ? "vfs.browser.horizontalSplitter" : "vfs.browser.splitter"; 85 int loc = jEdit.getIntegerProperty(prop,-1); 86 if(loc == -1) 87 loc = parentScroller.getPreferredSize().height; 88 89 splitPane.setDividerLocation(loc); 90 parentDirectories.ensureIndexIsVisible( 91 parentDirectories.getModel() 92 .getSize()); 93 } 94 }); 95 96 if(browser.isMultipleSelectionEnabled()) 97 table.getSelectionModel().setSelectionMode( 98 ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); 99 else 100 table.getSelectionModel().setSelectionMode( 101 ListSelectionModel.SINGLE_SELECTION); 102 103 setLayout(new BorderLayout()); 104 105 add(BorderLayout.CENTER,splitPane); 106 107 propertiesChanged(); 108 } 110 public void focusOnFileView() 112 { 113 table.requestFocus(); 114 } 116 public void removeNotify() 118 { 119 String prop = browser.isHorizontalLayout() ? "vfs.browser.horizontalSplitter" : "vfs.browser.splitter"; 120 jEdit.setIntegerProperty(prop,splitPane.getDividerLocation()); 121 122 super.removeNotify(); 123 } 125 public VFSFile[] getSelectedFiles() 127 { 128 return table.getSelectedFiles(); 129 } 131 public void selectNone() 133 { 134 table.clearSelection(); 135 } 137 public void saveExpansionState() 139 { 140 tmpExpanded.clear(); 141 table.getExpandedDirectories(tmpExpanded); 142 } 144 public void clearExpansionState() 146 { 147 tmpExpanded.clear(); 148 } 150 public void loadDirectory(Object node, String path, 152 boolean addToHistory) 153 { 154 path = MiscUtilities.constructPath(browser.getDirectory(),path); 155 VFS vfs = VFSManager.getVFSForPath(path); 156 157 Object session = vfs.createVFSSession(path,this); 158 if(session == null) 159 return; 160 161 if(node == null) 162 { 163 parentDirectories.setListData(new Object [] { 164 new LoadingPlaceholder() }); 165 } 166 167 Object [] loadInfo = new Object [2]; 168 169 VFSManager.runInWorkThread(new BrowserIORequest( 170 BrowserIORequest.LIST_DIRECTORY,browser, 171 session,vfs,path,null,loadInfo)); 172 browser.directoryLoaded(node,loadInfo,addToHistory); 173 } 175 public void directoryLoaded(Object node, String path, ArrayList directory) 177 { 178 if(node == null) 180 { 181 DefaultListModel parentList = new DefaultListModel(); 182 183 String parent = path; 184 185 for(;;) 186 { 187 VFS _vfs = VFSManager.getVFSForPath( 188 parent); 189 parentList.insertElementAt(new VFSFile( 194 _vfs.getFileName(parent), 195 parent,parent, 196 VFSFile.DIRECTORY, 197 0L,false),0); 198 String newParent = _vfs.getParentOfPath(parent); 199 200 if(newParent == null || 201 MiscUtilities.pathsEqual(parent,newParent)) 202 break; 203 else 204 parent = newParent; 205 } 206 207 parentDirectories.setModel(parentList); 208 int index = parentList.getSize() - 1; 209 parentDirectories.setSelectedIndex(index); 210 parentDirectories.ensureIndexIsVisible(index); 211 } 213 table.setDirectory(VFSManager.getVFSForPath(path), 214 node,directory,tmpExpanded); 215 } 217 public void updateFileView() 219 { 220 table.repaint(); 221 } 223 public void maybeReloadDirectory(String path) 225 { 226 String browserDir = browser.getDirectory(); 227 String symlinkBrowserDir; 228 if(MiscUtilities.isURL(browserDir)) 229 { 230 symlinkBrowserDir = browserDir; 231 } 232 else 233 { 234 symlinkBrowserDir = MiscUtilities.resolveSymlinks( 235 browserDir); 236 } 237 238 if(MiscUtilities.pathsEqual(path,symlinkBrowserDir)) 239 { 240 saveExpansionState(); 241 loadDirectory(null,browserDir,false); 242 } 243 244 256 if(!browserDir.startsWith(FavoritesVFS.PROTOCOL) 257 && !browserDir.startsWith(FileRootsVFS.PROTOCOL) 258 && !path.startsWith(symlinkBrowserDir)) 259 return; 260 261 if(browserDir.startsWith(FileRootsVFS.PROTOCOL) 262 && MiscUtilities.isURL(path) 263 && !MiscUtilities.getProtocolOfURL(path) 264 .equals("file")) 265 return; 266 267 table.maybeReloadDirectory(path); 268 } 270 public void propertiesChanged() 272 { 273 showIcons = jEdit.getBooleanProperty("vfs.browser.showIcons"); 274 table.propertiesChanged(); 275 GUIUtilities.initContinuousLayout(splitPane); 276 splitPane.setBorder(null); 277 } 279 284 public VFSBrowser getBrowser() 285 { 286 return browser; 287 } 289 public VFSDirectoryEntryTable getTable() 291 { 292 return table; 293 } 295 public JList getParentDirectoryList() 297 { 298 return parentDirectories; 299 } 301 303 private VFSBrowser browser; 305 306 private JSplitPane splitPane; 307 private JList parentDirectories; 308 private VFSDirectoryEntryTable table; 309 private Set tmpExpanded; 310 private BrowserCommandsMenu popup; 311 private boolean showIcons; 312 314 private void showFilePopup(VFSFile[] files, Component comp, 316 Point point) 317 { 318 popup = new BrowserCommandsMenu(browser,files); 319 popup.addPopupMenuListener(new PopupMenuListener() 323 { 324 public void popupMenuCanceled(PopupMenuEvent e) {} 325 326 public void popupMenuWillBecomeVisible(PopupMenuEvent e) {} 327 328 public void popupMenuWillBecomeInvisible(PopupMenuEvent e) 329 { 330 SwingUtilities.invokeLater(new Runnable () 334 { 335 public void run() 336 { 337 int index = parentDirectories 338 .getModel() 339 .getSize() - 1; 340 parentDirectories.setSelectedIndex(index); 341 } 342 }); 343 } 344 }); 345 GUIUtilities.showPopupMenu(popup,comp,point.x,point.y); 346 } 348 350 352 class ParentDirectoryRenderer extends DefaultListCellRenderer 354 { 355 Font plainFont, boldFont; 356 357 ParentDirectoryRenderer() 358 { 359 plainFont = UIManager.getFont("Tree.font"); 360 if(plainFont == null) 361 plainFont = jEdit.getFontProperty("metal.secondary.font"); 362 boldFont = new Font(plainFont.getName(),Font.BOLD,plainFont.getSize()); 363 } 364 365 public Component getListCellRendererComponent( 366 JList list, 367 Object value, 368 int index, 369 boolean isSelected, 370 boolean cellHasFocus) 371 { 372 super.getListCellRendererComponent(list,value,index, 373 isSelected,cellHasFocus); 374 375 ParentDirectoryRenderer.this.setBorder(new EmptyBorder ( 376 1,index * 5 + 1,1,1)); 377 378 if(value instanceof LoadingPlaceholder) 379 { 380 ParentDirectoryRenderer.this.setFont(plainFont); 381 382 setIcon(showIcons ? FileCellRenderer.loadingIcon : null); 383 setText(jEdit.getProperty("vfs.browser.tree.loading")); 384 } 385 else if(value instanceof VFSFile) 386 { 387 VFSFile dirEntry = (VFSFile)value; 388 ParentDirectoryRenderer.this.setFont(boldFont); 389 390 setIcon(showIcons ? FileCellRenderer.getIconForFile(dirEntry,true) 391 : null); 392 setText(dirEntry.getName()); 393 } 394 else if(value == null) 395 setText("VFS does not follow VFS API"); 396 397 return this; 398 } 399 } 401 class ParentMouseHandler extends MouseAdapter 403 { 404 public void mousePressed(MouseEvent evt) 405 { 406 int row = parentDirectories.locationToIndex(evt.getPoint()); 407 if(row != -1) 408 { 409 Object obj = parentDirectories.getModel() 410 .getElementAt(row); 411 if(obj instanceof VFSFile) 412 { 413 VFSFile dirEntry = ((VFSFile)obj); 414 if(GUIUtilities.isPopupTrigger(evt)) 415 { 416 if(popup != null && popup.isVisible()) 417 { 418 popup.setVisible(false); 419 popup = null; 420 } 421 else 422 { 423 parentDirectories.setSelectedIndex(row); 424 showFilePopup(new VFSFile[] { 425 dirEntry },parentDirectories, 426 evt.getPoint()); 427 } 428 } 429 } 430 } 431 } 432 433 public void mouseReleased(MouseEvent evt) 434 { 435 if(evt.getClickCount() % 2 != 0 && 436 !GUIUtilities.isMiddleButton(evt.getModifiers())) 437 return; 438 439 int row = parentDirectories.locationToIndex(evt.getPoint()); 440 if(row != -1) 441 { 442 Object obj = parentDirectories.getModel() 443 .getElementAt(row); 444 if(obj instanceof VFSFile) 445 { 446 VFSFile dirEntry = ((VFSFile)obj); 447 if(!GUIUtilities.isPopupTrigger(evt)) 448 { 449 browser.setDirectory(dirEntry.getPath()); 450 if(browser.getMode() == VFSBrowser.BROWSER) 451 focusOnFileView(); 452 } 453 } 454 } 455 } 456 } 458 class TableMouseHandler extends MouseAdapter 460 { 461 public void mouseClicked(MouseEvent evt) 463 { 464 Point p = evt.getPoint(); 465 int row = table.rowAtPoint(p); 466 int column = table.columnAtPoint(p); 467 if(row == -1) 468 return; 469 if(column == 0) 470 { 471 VFSDirectoryEntryTableModel.Entry entry 472 = (VFSDirectoryEntryTableModel.Entry) 473 table.getModel().getValueAt(row,0); 474 if(FileCellRenderer.ExpansionToggleBorder 475 .isExpansionToggle(entry.level,p.x)) 476 { 477 return; 478 } 479 } 480 481 if((evt.getModifiers() & InputEvent.BUTTON1_MASK) != 0 482 && evt.getClickCount() % 2 == 0) 483 { 484 browser.filesActivated((evt.isShiftDown() 485 ? VFSBrowser.M_OPEN_NEW_VIEW 486 : VFSBrowser.M_OPEN),true); 487 } 488 else if(GUIUtilities.isMiddleButton(evt.getModifiers())) 489 { 490 if(evt.isShiftDown()) 491 table.getSelectionModel().addSelectionInterval(row,row); 492 else 493 table.getSelectionModel().setSelectionInterval(row,row); 494 browser.filesActivated((evt.isShiftDown() 495 ? VFSBrowser.M_OPEN_NEW_VIEW 496 : VFSBrowser.M_OPEN),true); 497 } 498 } 500 public void mousePressed(MouseEvent evt) 502 { 503 Point p = evt.getPoint(); 504 if(evt.getSource() != table) 505 { 506 p.x -= table.getX(); 507 p.y -= table.getY(); 508 } 509 510 int row = table.rowAtPoint(p); 511 int column = table.columnAtPoint(p); 512 if(column == 0 && row != -1) 513 { 514 VFSDirectoryEntryTableModel.Entry entry 515 = (VFSDirectoryEntryTableModel.Entry) 516 table.getModel().getValueAt(row,0); 517 if(FileCellRenderer.ExpansionToggleBorder 518 .isExpansionToggle(entry.level,p.x)) 519 { 520 table.toggleExpanded(row); 521 return; 522 } 523 } 524 525 if(GUIUtilities.isMiddleButton(evt.getModifiers())) 526 { 527 if(row == -1) 528 ; 529 else if(evt.isShiftDown()) 530 table.getSelectionModel().addSelectionInterval(row,row); 531 else 532 table.getSelectionModel().setSelectionInterval(row,row); 533 } 534 else if(GUIUtilities.isPopupTrigger(evt)) 535 { 536 if(popup != null && popup.isVisible()) 537 { 538 popup.setVisible(false); 539 popup = null; 540 return; 541 } 542 543 if(row == -1) 544 showFilePopup(null,table,evt.getPoint()); 545 else 546 { 547 if(!table.getSelectionModel().isSelectedIndex(row)) 548 table.getSelectionModel().setSelectionInterval(row,row); 549 showFilePopup(getSelectedFiles(),table,evt.getPoint()); 550 } 551 } 552 } 554 public void mouseReleased(MouseEvent evt) 556 { 557 if(!GUIUtilities.isPopupTrigger(evt) 558 && table.getSelectedRow() != -1) 559 { 560 browser.filesSelected(); 561 } 562 } } 565 static class LoadingPlaceholder {} 566 568 class ParentDirectoryList extends JList 569 { 570 571 public String getPath(int row) { 572 LinkedList<String > components = new LinkedList<String >(); 573 for (int i=1; i<=row; ++i) components.add(getModel().getElementAt(i).toString()); 574 return getModel().getElementAt(0) + TextUtilities.join(components, File.separator); 575 } 576 protected void processKeyEvent(KeyEvent evt) 577 { 578 if (evt.getID() == KeyEvent.KEY_PRESSED) { 579 ActionContext ac = VFSBrowser.getActionContext(); 580 int row = parentDirectories.getSelectedIndex(); 581 switch(evt.getKeyCode()) { 582 case KeyEvent.VK_DOWN: 583 evt.consume(); 584 if (row < parentDirectories.getSize().height-1) 585 parentDirectories.setSelectedIndex(++row); 586 break; 587 case KeyEvent.VK_TAB: 588 table.requestFocus(); 589 evt.consume(); 590 break; 591 case KeyEvent.VK_UP : 592 evt.consume(); 593 if (row > 0) 594 parentDirectories.setSelectedIndex(--row); 595 break; 596 case KeyEvent.VK_BACK_SPACE: 597 evt.consume(); 598 EditAction ea = ac.getAction("vfs.browser.up"); 599 ac.invokeAction(evt, ea); 600 break; 601 case KeyEvent.VK_F5: 602 evt.consume(); 603 ac = VFSBrowser.getActionContext(); 604 ea = ac.getAction("vfs.browser.reload"); 605 ac.invokeAction(evt, ea); 606 break; 607 case KeyEvent.VK_ENTER: 608 evt.consume(); 609 String path = getPath(row); 610 getBrowser().setDirectory(path); 611 table.requestFocus(); 612 break; 613 631 } 632 } 633 else if(evt.getID() == KeyEvent.KEY_TYPED) { 634 if(evt.isControlDown() || evt.isAltDown() 635 || evt.isMetaDown()) 636 { 637 evt.consume(); 638 return; 639 } 640 switch(evt.getKeyChar()) 641 { 642 case '~': 643 evt.consume(); 644 if(browser.getMode() == VFSBrowser.BROWSER) 645 browser.setDirectory(System.getProperty( 646 "user.home")); 647 break; 648 case '/': 649 evt.consume(); 650 if(browser.getMode() == VFSBrowser.BROWSER) 651 browser.rootDirectory(); 652 break; 653 case '-': 654 evt.consume(); 655 if(browser.getMode() == VFSBrowser.BROWSER) 656 { 657 browser.setDirectory( 658 browser.getView().getBuffer() 659 .getDirectory()); 660 } 661 break; } 662 } 663 if (!evt.isConsumed()) super.processKeyEvent(evt); 664 } 665 } 666 667 } 668 | Popular Tags |